llvm.org GIT mirror llvm / db15975
[WebAssembly] Write DWARF data into wasm object file - Writes ".debug_XXX" into corresponding custom sections. - Writes relocation records into "reloc.debug_XXX" sections. Patch by Yury Delendik! Differential Revision: https://reviews.llvm.org/D44184 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@330982 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Clegg 1 year, 4 months ago
13 changed file(s) with 546 addition(s) and 38 deletion(s). Raw diff Collapse all Expand all
249249 // Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE
250250 enum WasmSymbolType : unsigned {
251251 WASM_SYMBOL_TYPE_FUNCTION = 0x0,
252 WASM_SYMBOL_TYPE_DATA = 0x1,
253 WASM_SYMBOL_TYPE_GLOBAL = 0x2,
252 WASM_SYMBOL_TYPE_DATA = 0x1,
253 WASM_SYMBOL_TYPE_GLOBAL = 0x2,
254 WASM_SYMBOL_TYPE_SECTION = 0x3,
254255 };
255256
256257 const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
1010 WASM_RELOC(R_WEBASSEMBLY_MEMORY_ADDR_I32, 5)
1111 WASM_RELOC(R_WEBASSEMBLY_TYPE_INDEX_LEB, 6)
1212 WASM_RELOC(R_WEBASSEMBLY_GLOBAL_INDEX_LEB, 7)
13 WASM_RELOC(R_WEBASSEMBLY_FUNCTION_OFFSET_I32, 8)
14 WASM_RELOC(R_WEBASSEMBLY_SECTION_OFFSET_I32, 9)
2222 #include "llvm/Object/ELFObjectFile.h"
2323 #include "llvm/Object/MachO.h"
2424 #include "llvm/Object/ObjectFile.h"
25 #include "llvm/Object/Wasm.h"
2526 #include "llvm/Support/Casting.h"
2627 #include "llvm/Support/ErrorHandling.h"
2728 #include
4546 return visitCOFF(Rel, R, Value);
4647 if (isa(ObjToVisit))
4748 return visitMachO(Rel, R, Value);
49 if (isa(ObjToVisit))
50 return visitWasm(Rel, R, Value);
4851
4952 HasError = true;
5053 return 0;
315318 HasError = true;
316319 return 0;
317320 }
321
322 uint64_t visitWasm(uint32_t Rel, RelocationRef R, uint64_t Value) {
323 if (ObjToVisit.getArch() == Triple::wasm32) {
324 switch (Rel) {
325 case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
326 case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
327 case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
328 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
329 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
330 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
331 case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
332 case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
333 case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
334 case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
335 // For wasm section, its offset at 0 -- ignoring Value
336 return 0;
337 }
338 }
339 HasError = true;
340 return 0;
341 }
318342 };
319343
320344 } // end namespace object
5050
5151 bool isTypeGlobal() const {
5252 return Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL;
53 }
54
55 bool isTypeSection() const {
56 return Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION;
5357 }
5458
5559 bool isDefined() const { return !isUndefined(); }
205209 bool isValidFunctionSymbol(uint32_t Index) const;
206210 bool isValidGlobalSymbol(uint32_t Index) const;
207211 bool isValidDataSymbol(uint32_t Index) const;
212 bool isValidSectionSymbol(uint32_t Index) const;
208213 wasm::WasmFunction &getDefinedFunction(uint32_t Index);
209214 wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
210215
4747 struct SectionBookkeeping {
4848 // Where the size of the section is written.
4949 uint64_t SizeOffset;
50 // Where the contents of the section starts (after the header).
50 // Where the section header ends (without custom section name).
51 uint64_t PayloadOffset;
52 // Where the contents of the section starts.
5153 uint64_t ContentsOffset;
5254 uint32_t Index;
5355 };
150152 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
151153 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
152154 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
155 case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
156 case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
153157 return true;
154158 default:
155159 return false;
168172 };
169173
170174 struct WasmCustomSection {
175 const uint32_t INVALID_INDEX = -1;
176
171177 StringRef Name;
172 const SmallVectorImpl &Contents;
173
174 WasmCustomSection(StringRef Name, const SmallVectorImpl &Contents)
175 : Name(Name), Contents(Contents) {}
178 MCSectionWasm *Section;
179
180 uint32_t OutputContentsOffset;
181 uint32_t OutputIndex;
182
183 WasmCustomSection(StringRef Name, MCSectionWasm *Section)
184 : Name(Name), Section(Section), OutputContentsOffset(0),
185 OutputIndex(INVALID_INDEX) {}
176186 };
177187
178188 #if !defined(NDEBUG)
206216 DenseMap WasmIndices;
207217 // Maps data symbols to the Wasm segment and offset/size with the segment.
208218 DenseMap DataLocations;
219 // Maps section symbols to the section.
220 DenseMap CustomSectionSymbols;
221
222 // Stores output data (index, relocations, content offset) for custom
223 // section.
224 std::vector CustomSections;
225 // Relocations for fixing up references in the custom sections.
226 DenseMap>
227 CustomSectionsRelocations;
209228
210229 DenseMap
211230 FunctionTypeIndices;
212231 SmallVector FunctionTypes;
213232 SmallVector Globals;
214233 SmallVector DataSegments;
215 std::vector CustomSections;
216234 unsigned NumFunctionImports = 0;
217235 unsigned NumGlobalImports = 0;
218236 uint32_t SectionCount = 0;
244262 WasmIndices.clear();
245263 TableIndices.clear();
246264 DataLocations.clear();
265 CustomSectionsRelocations.clear();
247266 FunctionTypeIndices.clear();
248267 FunctionTypes.clear();
249268 Globals.clear();
250269 DataSegments.clear();
270 CustomSectionSymbols.clear();
251271 MCObjectWriter::reset();
252272 NumFunctionImports = 0;
253273 NumGlobalImports = 0;
289309 ArrayRef SymbolInfos,
290310 ArrayRef> InitFuncs,
291311 const std::map> &Comdats);
292 void writeUserCustomSections(ArrayRef CustomSections);
312 void writeCustomSections(const MCAssembler &Asm, const MCAsmLayout &Layout);
313 void writeCustomRelocSections();
314 void
315 updateCustomSectionRelocations(const SmallVector &Functions,
316 const MCAsmLayout &Layout);
293317
294318 uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry);
295319 void applyRelocations(ArrayRef Relocations,
318342
319343 // The position where the section starts, for measuring its size.
320344 Section.ContentsOffset = getStream().tell();
345 Section.PayloadOffset = getStream().tell();
321346 Section.Index = SectionCount++;
322347 }
323348
325350 StringRef Name) {
326351 DEBUG(dbgs() << "startCustomSection " << Name << "\n");
327352 startSection(Section, wasm::WASM_SEC_CUSTOM);
353
354 // The position where the section header ends, for measuring its size.
355 Section.PayloadOffset = getStream().tell();
356
328357 // Custom sections in wasm also have a string identifier.
329358 writeString(Name);
359
360 // The position where the custom section starts.
361 Section.ContentsOffset = getStream().tell();
330362 }
331363
332364 // Now that the section is complete and we know how big it is, patch up the
333365 // section size field at the start of the section.
334366 void WasmObjectWriter::endSection(SectionBookkeeping &Section) {
335 uint64_t Size = getStream().tell() - Section.ContentsOffset;
367 uint64_t Size = getStream().tell() - Section.PayloadOffset;
336368 if (uint32_t(Size) != Size)
337369 report_fatal_error("section size does not fit in a uint32_t");
338370
373405 if (FixupSection.getSectionName().startswith(".init_array"))
374406 return;
375407
376 // TODO(sbc): Add support for debug sections.
377 if (FixupSection.getKind().isMetadata())
408 // TODO: Add support for non-debug metadata sections?
409 if (FixupSection.getKind().isMetadata() &&
410 !FixupSection.getSectionName().startswith(".debug_"))
378411 return;
379412
380413 if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
445478 WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection);
446479 DEBUG(dbgs() << "WasmReloc: " << Rec << "\n");
447480
448 // Relocation other than R_WEBASSEMBLY_TYPE_INDEX_LEB are currently required
449 // to be against a named symbol.
481 // Relocation other than R_WEBASSEMBLY_TYPE_INDEX_LEB,
482 // R_WEBASSEMBLY_SECTION_OFFSET_I32 or R_WEBASSEMBLY_FUNCTION_OFFSET_I32
483 // are currently required to be against a named symbol.
450484 // TODO(sbc): Add support for relocations against unnamed temporaries such
451485 // as those generated by llvm's `blockaddress`.
452486 // See: test/MC/WebAssembly/blockaddress.ll
453 if (SymA->getName().empty() && Type != wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB)
487 if (SymA->getName().empty() &&
488 !(Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB ||
489 Type == wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32 ||
490 Type == wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32))
454491 report_fatal_error("relocations against un-named temporaries are not yet "
455492 "supported by wasm");
456493
457 if (FixupSection.isWasmData())
494 if (FixupSection.isWasmData()) {
458495 DataRelocations.push_back(Rec);
459 else if (FixupSection.getKind().isText())
496 } else if (FixupSection.getKind().isText()) {
460497 CodeRelocations.push_back(Rec);
461 else
498 } else if (FixupSection.getKind().isMetadata()) {
499 assert(FixupSection.getSectionName().startswith(".debug_"));
500 CustomSectionsRelocations[&FixupSection].push_back(Rec);
501 } else {
462502 llvm_unreachable("unexpected section type");
503 }
463504 }
464505
465506 // Write X as an (unsigned) LEB value at offset Offset in Stream, padded
522563 report_fatal_error("symbol not found in wasm index space: " +
523564 RelEntry.Symbol->getName());
524565 return WasmIndices[RelEntry.Symbol];
566 case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: {
567 const auto &Section =
568 static_cast(RelEntry.Symbol->getSection());
569 return Section.getSectionOffset() + RelEntry.Addend;
570 }
571 case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: {
572 const auto &Section = *CustomSectionSymbols.find(RelEntry.Symbol)->second;
573 return Section.getSectionOffset() + RelEntry.Addend;
574 }
525575 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
526576 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
527577 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: {
613663 break;
614664 case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
615665 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
666 case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
667 case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
616668 WriteI32(Stream, Value, Offset);
617669 break;
618670 case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
848900 }
849901
850902 endSection(Section);
903 }
904
905 void WasmObjectWriter::writeCustomRelocSections() {
906 for (const auto &Sec : CustomSections) {
907 auto &Relocations = CustomSectionsRelocations[Sec.Section];
908 writeRelocSection(Sec.OutputIndex, Sec.Name, Relocations);
909 }
851910 }
852911
853912 void WasmObjectWriter::writeLinkingMetaDataSection(
880939 encodeULEB128(Sym.DataRef.Size, getStream());
881940 }
882941 break;
942 case wasm::WASM_SYMBOL_TYPE_SECTION: {
943 const uint32_t SectionIndex =
944 CustomSections[Sym.ElementIndex].OutputIndex;
945 encodeULEB128(SectionIndex, getStream());
946 break;
947 }
883948 default:
884949 llvm_unreachable("unexpected kind");
885950 }
926991 endSection(Section);
927992 }
928993
929 void WasmObjectWriter::writeUserCustomSections(
930 ArrayRef CustomSections) {
931 for (const auto &CustomSection : CustomSections) {
994 void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm,
995 const MCAsmLayout &Layout) {
996 for (auto &CustomSection : CustomSections) {
932997 SectionBookkeeping Section;
998 auto *Sec = CustomSection.Section;
933999 startCustomSection(Section, CustomSection.Name);
934 writeBytes(CustomSection.Contents);
1000
1001 Sec->setSectionOffset(getStream().tell() - Section.ContentsOffset);
1002 Asm.writeSectionData(Sec, Layout);
1003
1004 CustomSection.OutputContentsOffset = Section.ContentsOffset;
1005 CustomSection.OutputIndex = Section.Index;
1006
9351007 endSection(Section);
1008 }
1009 }
1010
1011 void WasmObjectWriter::updateCustomSectionRelocations(
1012 const SmallVector &Functions, const MCAsmLayout &Layout) {
1013 std::map SectionSymbols;
1014 for (const auto &P : CustomSectionSymbols)
1015 SectionSymbols[P.second] = P.first;
1016 std::map FuncSymbols;
1017 for (const auto &FuncInfo : Functions)
1018 FuncSymbols[&FuncInfo.Sym->getSection()] = FuncInfo.Sym;
1019
1020 // Patch relocation records for R_WEBASSEMBLY_FUNCTION_OFFSET_I32 and
1021 // R_WEBASSEMBLY_SECTION_OFFSET_I32. The Addend is stuffed the offset from
1022 // the beginning of the function or custom section -- all such relocations
1023 // target the function or custom section starts.
1024 for (auto &Section : CustomSections) {
1025 auto &Relocations = CustomSectionsRelocations[Section.Section];
1026 for (WasmRelocationEntry &RelEntry : Relocations) {
1027 switch (RelEntry.Type) {
1028 case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: {
1029 assert(RelEntry.hasAddend());
1030 auto &Section =
1031 static_cast(RelEntry.Symbol->getSection());
1032 RelEntry.Addend += Layout.getSymbolOffset(*RelEntry.Symbol);
1033 RelEntry.Symbol = FuncSymbols[&Section];
1034 break;
1035 }
1036 case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: {
1037 assert(RelEntry.hasAddend());
1038 auto &Section =
1039 static_cast(RelEntry.Symbol->getSection());
1040 RelEntry.Addend += Layout.getSymbolOffset(*RelEntry.Symbol);
1041 RelEntry.Symbol = SectionSymbols[&Section];
1042 break;
1043 }
1044 default:
1045 break;
1046 }
1047 }
1048
1049 // Apply fixups.
1050 applyRelocations(Relocations, Section.OutputContentsOffset);
9361051 }
9371052 }
9381053
10421157 for (MCSection &Sec : Asm) {
10431158 auto &Section = static_cast(Sec);
10441159
1045 if (cast(Sec).getSectionName().startswith(
1046 ".custom_section.")) {
1160 if (Section.getSectionName().startswith(".custom_section.")) {
10471161 if (Section.getFragmentList().empty())
10481162 continue;
10491163 if (Section.getFragmentList().size() != 1)
10561170 if (!DataFrag.getFixups().empty())
10571171 report_fatal_error("fixups not supported in .custom_section section");
10581172 StringRef UserName = Section.getSectionName().substr(16);
1059 const SmallVectorImpl &Contents = DataFrag.getContents();
1060 CustomSections.push_back(WasmCustomSection(UserName, Contents));
1173 CustomSections.emplace_back(UserName, &Section);
10611174 continue;
10621175 }
10631176
10851198 Comdats[C->getName()].emplace_back(
10861199 WasmComdatEntry{wasm::WASM_COMDAT_DATA, SegmentIndex});
10871200 }
1201 }
1202
1203 // Create symbols for debug/custom sections.
1204 for (MCSection &Sec : Asm) {
1205 auto &DebugSection = static_cast(Sec);
1206 StringRef SectionName = DebugSection.getSectionName();
1207
1208 // TODO: Add support for non-debug metadata sections?
1209 if (!Sec.getKind().isMetadata() || !SectionName.startswith(".debug_"))
1210 continue;
1211
1212 uint32_t ElementIndex = CustomSections.size();
1213 CustomSections.emplace_back(SectionName, &DebugSection);
1214
1215 MCSymbolWasm *SectionSym =
1216 cast(Ctx.getOrCreateSymbol(SectionName));
1217 CustomSectionSymbols[SectionSym] = &DebugSection;
1218
1219 wasm::WasmSymbolInfo Info;
1220 Info.Name = SectionSym->getName();
1221 Info.Kind = wasm::WASM_SYMBOL_TYPE_SECTION;
1222 Info.Flags = 0;
1223 Info.ElementIndex = ElementIndex;
1224 SymbolIndices[SectionSym] = SymbolInfos.size();
1225 SymbolInfos.emplace_back(Info);
10881226 }
10891227
10901228 // Populate WasmIndices and DataLocations for defined symbols.
13301468 writeElemSection(TableElems);
13311469 writeCodeSection(Asm, Layout, Functions);
13321470 writeDataSection();
1333 writeUserCustomSections(CustomSections);
1471 writeCustomSections(Asm, Layout);
1472 updateCustomSectionRelocations(Functions, Layout);
13341473 writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats);
13351474 writeRelocSection(CodeSectionIndex, "CODE", CodeRelocations);
13361475 writeRelocSection(DataSectionIndex, "DATA", DataRelocations);
1476 writeCustomRelocSections();
13371477
13381478 // TODO: Translate the .comment section to the output.
1339 // TODO: Translate debug sections to the output.
13401479 }
13411480
13421481 std::unique_ptr
464464 }
465465 break;
466466
467 case wasm::WASM_SYMBOL_TYPE_SECTION: {
468 Info.ElementIndex = readVaruint32(Ptr);
469 // Use somewhat unique section name as symbol name.
470 StringRef SectionName = Sections[Info.ElementIndex].Name;
471 Info.Name = SectionName;
472 break;
473 }
474
467475 default:
468476 return make_error("Invalid symbol type",
469477 object_error::parse_failed);
572580 object_error::parse_failed);
573581 Reloc.Addend = readVarint32(Ptr);
574582 break;
583 case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
584 if (!isValidFunctionSymbol(Reloc.Index))
585 return make_error("Bad relocation function index",
586 object_error::parse_failed);
587 Reloc.Addend = readVarint32(Ptr);
588 break;
589 case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
590 if (!isValidSectionSymbol(Reloc.Index))
591 return make_error("Bad relocation section index",
592 object_error::parse_failed);
593 Reloc.Addend = readVarint32(Ptr);
594 break;
575595 default:
576596 return make_error("Bad relocation type: " +
577597 Twine(Reloc.Type),
583603 // to check that.
584604 uint64_t Size = 5;
585605 if (Reloc.Type == wasm::R_WEBASSEMBLY_TABLE_INDEX_I32 ||
586 Reloc.Type == wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32)
606 Reloc.Type == wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32 ||
607 Reloc.Type == wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32 ||
608 Reloc.Type == wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32)
587609 Size = 4;
588610 if (Reloc.Offset + Size > EndOffset)
589611 return make_error("Bad relocation offset",
808830
809831 bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
810832 return Index < Symbols.size() && Symbols[Index].isTypeData();
833 }
834
835 bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const {
836 return Index < Symbols.size() && Symbols[Index].isTypeSection();
811837 }
812838
813839 wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
9901016 assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST);
9911017 return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset;
9921018 }
1019 case wasm::WASM_SYMBOL_TYPE_SECTION:
1020 return 0;
9931021 }
9941022 llvm_unreachable("invalid symbol type");
9951023 }
10191047 return SymbolRef::ST_Other;
10201048 case wasm::WASM_SYMBOL_TYPE_DATA:
10211049 return SymbolRef::ST_Data;
1050 case wasm::WASM_SYMBOL_TYPE_SECTION:
1051 return SymbolRef::ST_Debug;
10221052 }
10231053
10241054 llvm_unreachable("Unknown WasmSymbol::SymbolType");
10421072 case wasm::WASM_SYMBOL_TYPE_DATA:
10431073 Ref.d.a = DataSection;
10441074 break;
1075 case wasm::WASM_SYMBOL_TYPE_SECTION: {
1076 Ref.d.a = Sym.Info.ElementIndex;
1077 break;
1078 }
10451079 default:
10461080 llvm_unreachable("Unknown WasmSymbol::SymbolType");
10471081 }
404404 IO.mapOptional("Offset", Info.DataRef.Offset, 0u);
405405 IO.mapRequired("Size", Info.DataRef.Size);
406406 }
407 } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION) {
408 IO.mapRequired("Section", Info.ElementIndex);
407409 } else {
408410 llvm_unreachable("unsupported symbol kind");
409411 }
438440 ECase(FUNCTION);
439441 ECase(DATA);
440442 ECase(GLOBAL);
443 ECase(SECTION);
441444 #undef ECase
442445 }
443446
1919 #include "llvm/MC/MCFixup.h"
2020 #include "llvm/MC/MCFixupKindInfo.h"
2121 #include "llvm/MC/MCObjectWriter.h"
22 #include "llvm/MC/MCSectionWasm.h"
2223 #include "llvm/MC/MCSymbolWasm.h"
24 #include "llvm/MC/MCValue.h"
2325 #include "llvm/MC/MCWasmObjectWriter.h"
24 #include "llvm/MC/MCValue.h"
2526 #include "llvm/Support/Casting.h"
2627 #include "llvm/Support/ErrorHandling.h"
2728
6061 return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX;
6162 }
6263
64 static const MCSection *GetFixupSection(const MCExpr *Expr) {
65 if (auto SyExp = dyn_cast(Expr)) {
66 if (SyExp->getSymbol().isInSection())
67 return &SyExp->getSymbol().getSection();
68 return nullptr;
69 }
70
71 if (auto BinOp = dyn_cast(Expr)) {
72 auto SectionLHS = GetFixupSection(BinOp->getLHS());
73 auto SectionRHS = GetFixupSection(BinOp->getRHS());
74 return SectionLHS == SectionRHS ? nullptr : SectionLHS;
75 }
76
77 if (auto UnOp = dyn_cast(Expr))
78 return GetFixupSection(UnOp->getSubExpr());
79
80 return nullptr;
81 }
82
6383 unsigned
6484 WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
6585 const MCFixup &Fixup) const {
85105 case FK_Data_4:
86106 if (IsFunction)
87107 return wasm::R_WEBASSEMBLY_TABLE_INDEX_I32;
108 if (auto Section = static_cast(
109 GetFixupSection(Fixup.getValue()))) {
110 if (Section->getKind().isText())
111 return wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32;
112 else if (!Section->isWasmData())
113 return wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32;
114 }
88115 return wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32;
89116 case FK_Data_8:
90117 llvm_unreachable("FK_Data_8 not implemented yet");
None ; RUN: llc -filetype=obj %s -o - | llvm-readobj -r -s -expand-relocs
0 ; RUN: llc -filetype=obj %s -o - | llvm-readobj -r -s | FileCheck %s
1
2 ; CHECK: Format: WASM
3 ; CHECK-NEXT:Arch: wasm32
4 ; CHECK-NEXT:AddressSize: 32bit
5 ; CHECK-NEXT:Sections [
6 ; CHECK-NEXT: Section {
7 ; CHECK-NEXT: Type: TYPE (0x1)
8 ; CHECK-NEXT: Size: 4
9 ; CHECK-NEXT: Offset: 8
10 ; CHECK-NEXT: }
11 ; CHECK-NEXT: Section {
12 ; CHECK-NEXT: Type: IMPORT (0x2)
13 ; CHECK-NEXT: Size: 58
14 ; CHECK-NEXT: Offset: 18
15 ; CHECK-NEXT: }
16 ; CHECK-NEXT: Section {
17 ; CHECK-NEXT: Type: FUNCTION (0x3)
18 ; CHECK-NEXT: Size: 2
19 ; CHECK-NEXT: Offset: 82
20 ; CHECK-NEXT: }
21 ; CHECK-NEXT: Section {
22 ; CHECK-NEXT: Type: ELEM (0x9)
23 ; CHECK-NEXT: Size: 7
24 ; CHECK-NEXT: Offset: 90
25 ; CHECK-NEXT: }
26 ; CHECK-NEXT: Section {
27 ; CHECK-NEXT: Type: CODE (0xA)
28 ; CHECK-NEXT: Size: 4
29 ; CHECK-NEXT: Offset: 103
30 ; CHECK-NEXT: }
31 ; CHECK-NEXT: Section {
32 ; CHECK-NEXT: Type: DATA (0xB)
33 ; CHECK-NEXT: Size: 19
34 ; CHECK-NEXT: Offset: 113
35 ; CHECK-NEXT: Segments [
36 ; CHECK-NEXT: Segment {
37 ; CHECK-NEXT: Name: .data.foo
38 ; CHECK-NEXT: Size: 4
39 ; CHECK-NEXT: Offset: 0
40 ; CHECK-NEXT: }
41 ; CHECK-NEXT: Segment {
42 ; CHECK-NEXT: Name: .data.ptr2
43 ; CHECK-NEXT: Size: 4
44 ; CHECK-NEXT: Offset: 4
45 ; CHECK-NEXT: }
46 ; CHECK-NEXT: ]
47 ; CHECK-NEXT: }
48 ; CHECK-NEXT: Section {
49 ; CHECK-NEXT: Type: CUSTOM (0x0)
50 ; CHECK-NEXT: Size: 121
51 ; CHECK-NEXT: Offset: 138
52 ; CHECK-NEXT: Name: .debug_str
53 ; CHECK-NEXT: }
54 ; CHECK-NEXT: Section {
55 ; CHECK-NEXT: Type: CUSTOM (0x0)
56 ; CHECK-NEXT: Size: 84
57 ; CHECK-NEXT: Offset: 276
58 ; CHECK-NEXT: Name: .debug_abbrev
59 ; CHECK-NEXT: }
60 ; CHECK-NEXT: Section {
61 ; CHECK-NEXT: Type: CUSTOM (0x0)
62 ; CHECK-NEXT: Size: 106
63 ; CHECK-NEXT: Offset: 380
64 ; CHECK-NEXT: Name: .debug_info
65 ; CHECK-NEXT: }
66 ; CHECK-NEXT: Section {
67 ; CHECK-NEXT: Type: CUSTOM (0x0)
68 ; CHECK-NEXT: Size: 0
69 ; CHECK-NEXT: Offset: 504
70 ; CHECK-NEXT: Name: .debug_ranges
71 ; CHECK-NEXT: }
72 ; CHECK-NEXT: Section {
73 ; CHECK-NEXT: Type: CUSTOM (0x0)
74 ; CHECK-NEXT: Size: 1
75 ; CHECK-NEXT: Offset: 524
76 ; CHECK-NEXT: Name: .debug_macinfo
77 ; CHECK-NEXT: }
78 ; CHECK-NEXT: Section {
79 ; CHECK-NEXT: Type: CUSTOM (0x0)
80 ; CHECK-NEXT: Size: 42
81 ; CHECK-NEXT: Offset: 546
82 ; CHECK-NEXT: Name: .debug_pubnames
83 ; CHECK-NEXT: }
84 ; CHECK-NEXT: Section {
85 ; CHECK-NEXT: Type: CUSTOM (0x0)
86 ; CHECK-NEXT: Size: 26
87 ; CHECK-NEXT: Offset: 610
88 ; CHECK-NEXT: Name: .debug_pubtypes
89 ; CHECK-NEXT: }
90 ; CHECK-NEXT: Section {
91 ; CHECK-NEXT: Type: CUSTOM (0x0)
92 ; CHECK-NEXT: Size: 57
93 ; CHECK-NEXT: Offset: 658
94 ; CHECK-NEXT: Name: .debug_line
95 ; CHECK-NEXT: }
96 ; CHECK-NEXT: Section {
97 ; CHECK-NEXT: Type: CUSTOM (0x0)
98 ; CHECK-NEXT: Size: 100
99 ; CHECK-NEXT: Offset: 733
100 ; CHECK-NEXT: Name: linking
101 ; CHECK-NEXT: }
102 ; CHECK-NEXT: Section {
103 ; CHECK-NEXT: Type: CUSTOM (0x0)
104 ; CHECK-NEXT: Size: 9
105 ; CHECK-NEXT: Offset: 847
106 ; CHECK-NEXT: Name: reloc.DATA
107 ; CHECK-NEXT: }
108 ; CHECK-NEXT: Section {
109 ; CHECK-NEXT: Type: CUSTOM (0x0)
110 ; CHECK-NEXT: Size: 58
111 ; CHECK-NEXT: Offset: 873
112 ; CHECK-NEXT: Name: reloc..debug_info
113 ; CHECK-NEXT: }
114 ; CHECK-NEXT: Section {
115 ; CHECK-NEXT: Type: CUSTOM (0x0)
116 ; CHECK-NEXT: Size: 6
117 ; CHECK-NEXT: Offset: 955
118 ; CHECK-NEXT: Name: reloc..debug_pubnames
119 ; CHECK-NEXT: }
120 ; CHECK-NEXT: Section {
121 ; CHECK-NEXT: Type: CUSTOM (0x0)
122 ; CHECK-NEXT: Size: 6
123 ; CHECK-NEXT: Offset: 989
124 ; CHECK-NEXT: Name: reloc..debug_pubtypes
125 ; CHECK-NEXT: }
126 ; CHECK-NEXT: Section {
127 ; CHECK-NEXT: Type: CUSTOM (0x0)
128 ; CHECK-NEXT: Size: 6
129 ; CHECK-NEXT: Offset: 1023
130 ; CHECK-NEXT: Name: reloc..debug_line
131 ; CHECK-NEXT: }
132 ; CHECK-NEXT:]
133 ; CHECK-NEXT:Relocations [
134 ; CHECK-NEXT: Section (6) DATA {
135 ; CHECK-NEXT: 0x6 R_WEBASSEMBLY_MEMORY_ADDR_I32[10] 0
136 ; CHECK-NEXT: 0xF R_WEBASSEMBLY_TABLE_INDEX_I32[8]
137 ; CHECK-NEXT: }
138 ; CHECK-NEXT: Section (9) .debug_info {
139 ; CHECK-NEXT: 0x6 R_WEBASSEMBLY_SECTION_OFFSET_I32[1] 0
140 ; CHECK-NEXT: 0xC R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 0
141 ; CHECK-NEXT: 0x12 R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 55
142 ; CHECK-NEXT: 0x16 R_WEBASSEMBLY_SECTION_OFFSET_I32[7] 0
143 ; CHECK-NEXT: 0x1A R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 62
144 ; CHECK-NEXT: 0x1E R_WEBASSEMBLY_FUNCTION_OFFSET_I32[8] 0
145 ; CHECK-NEXT: 0x27 R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 105
146 ; CHECK-NEXT: 0x33 R_WEBASSEMBLY_MEMORY_ADDR_I32[9] 0
147 ; CHECK-NEXT: 0x3D R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 109
148 ; CHECK-NEXT: 0x44 R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 113
149 ; CHECK-NEXT: 0x50 R_WEBASSEMBLY_MEMORY_ADDR_I32[11] 0
150 ; CHECK-NEXT: 0x5B R_WEBASSEMBLY_FUNCTION_OFFSET_I32[8] 0
151 ; CHECK-NEXT: 0x63 R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 118
152 ; CHECK-NEXT: }
153 ; CHECK-NEXT: Section (12) .debug_pubnames {
154 ; CHECK-NEXT: 0x6 R_WEBASSEMBLY_SECTION_OFFSET_I32[2] 0
155 ; CHECK-NEXT: }
156 ; CHECK-NEXT: Section (13) .debug_pubtypes {
157 ; CHECK-NEXT: 0x6 R_WEBASSEMBLY_SECTION_OFFSET_I32[2] 0
158 ; CHECK-NEXT: }
159 ; CHECK-NEXT: Section (14) .debug_line {
160 ; CHECK-NEXT: 0x2B R_WEBASSEMBLY_FUNCTION_OFFSET_I32[8] 0
161 ; CHECK-NEXT: }
162 ; CHECK-NEXT:]
1163
2164 target triple = "wasm32-unknown-unknown-wasm"
3165
4 ; Debug information is currently not supported. This test simply verifies that
5 ; a valid object generated.
6166 source_filename = "test.c"
7167
8168 @myextern = external global i32, align 4
0 ; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s
1
2 ; CHECK: .debug_info contents:
3 ; CHECK-NEXT: 0x00000000: Compile Unit: length = 0x00000066 version = 0x0004 abbr_offset = 0x0000 addr_size = 0x04 (next unit at 0x0000006a)
4
5 ; CHECK: 0x0000000b: DW_TAG_compile_unit
6 ; CHECK-NEXT: DW_AT_producer ("clang version 6.0.0 (trunk 315924) (llvm/trunk 315960)")
7 ; CHECK-NEXT: DW_AT_language (DW_LANG_C99)
8 ; CHECK-NEXT: DW_AT_name ("test.c")
9 ; CHECK-NEXT: DW_AT_stmt_list (0x00000000)
10 ; CHECK-NEXT: DW_AT_comp_dir ("/usr/local/google/home/sbc/dev/wasm/simple")
11 ; CHECK-NEXT: DW_AT_GNU_pubnames (true)
12 ; CHECK-NEXT: DW_AT_low_pc (0x0000000000000002)
13 ; CHECK-NEXT: DW_AT_high_pc (0x0000000000000004)
14
15 ; CHECK: 0x00000026: DW_TAG_variable
16 ; CHECK-NEXT: DW_AT_name ("foo")
17 ; CHECK-NEXT: DW_AT_type (0x00000037 "int*")
18 ; CHECK-NEXT: DW_AT_external (true)
19 ; CHECK-NEXT: DW_AT_decl_file ("/usr/local/google/home/sbc/dev/wasm/simple/test.c")
20 ; CHECK-NEXT: DW_AT_decl_line (4)
21 ; CHECK-NEXT: DW_AT_location (DW_OP_addr 0x0)
22
23 ; CHECK: 0x00000037: DW_TAG_pointer_type
24 ; CHECK-NEXT: DW_AT_type (0x0000003c "int")
25
26 ; CHECK: 0x0000003c: DW_TAG_base_type
27 ; CHECK-NEXT: DW_AT_name ("int")
28 ; CHECK-NEXT: DW_AT_encoding (DW_ATE_signed)
29 ; CHECK-NEXT: DW_AT_byte_size (0x04)
30
31 ; CHECK: 0x00000043: DW_TAG_variable
32 ; CHECK-NEXT: DW_AT_name ("ptr2")
33 ; CHECK-NEXT: DW_AT_type (0x00000054 "subroutine *")
34 ; CHECK-NEXT: DW_AT_external (true)
35 ; CHECK-NEXT: DW_AT_decl_file ("/usr/local/google/home/sbc/dev/wasm/simple/test.c")
36 ; CHECK-NEXT: DW_AT_decl_line (5)
37 ; CHECK-NEXT: DW_AT_location (DW_OP_addr 0x4)
38
39 ; CHECK: 0x00000054: DW_TAG_pointer_type
40 ; CHECK-NEXT: DW_AT_type (0x00000059 "subroutine ")
41
42 ; CHECK: 0x00000059: DW_TAG_subroutine_type
43 ; CHECK-NEXT: DW_AT_prototyped (true)
44
45 ; CHECK: 0x0000005a: DW_TAG_subprogram
46 ; CHECK-NEXT: DW_AT_low_pc (0x0000000000000002)
47 ; CHECK-NEXT: DW_AT_high_pc (0x0000000000000004)
48 ; CHECK-NEXT: DW_AT_name ("f2")
49 ; CHECK-NEXT: DW_AT_decl_file ("/usr/local/google/home/sbc/dev/wasm/simple/test.c")
50 ; CHECK-NEXT: DW_AT_decl_line (2)
51 ; CHECK-NEXT: DW_AT_prototyped (true)
52 ; CHECK-NEXT: DW_AT_external (true)
53
54 ; CHECK: 0x00000069: NULL
55
56 target triple = "wasm32-unknown-unknown-wasm"
57
58 source_filename = "test.c"
59
60 @myextern = external global i32, align 4
61 @foo = hidden global i32* @myextern, align 4, !dbg !0
62 @ptr2 = hidden global void ()* @f2, align 4, !dbg !6
63
64 ; Function Attrs: noinline nounwind optnone
65 define hidden void @f2() #0 !dbg !17 {
66 entry:
67 ret void, !dbg !18
68 }
69
70 attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
71
72 !llvm.dbg.cu = !{!2}
73 !llvm.module.flags = !{!13, !14, !15}
74 !llvm.ident = !{!16}
75
76 !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
77 !1 = distinct !DIGlobalVariable(name: "foo", scope: !2, file: !3, line: 4, type: !11, isLocal: false, isDefinition: true)
78 !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 6.0.0 (trunk 315924) (llvm/trunk 315960)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
79 !3 = !DIFile(filename: "test.c", directory: "/usr/local/google/home/sbc/dev/wasm/simple")
80 !4 = !{}
81 !5 = !{!0, !6}
82 !6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
83 !7 = distinct !DIGlobalVariable(name: "ptr2", scope: !2, file: !3, line: 5, type: !8, isLocal: false, isDefinition: true)
84 !8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 32)
85 !9 = !DISubroutineType(types: !10)
86 !10 = !{null}
87 !11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 32)
88 !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
89 !13 = !{i32 2, !"Dwarf Version", i32 4}
90 !14 = !{i32 2, !"Debug Info Version", i32 3}
91 !15 = !{i32 1, !"wchar_size", i32 4}
92 !16 = !{!"clang version 6.0.0 (trunk 315924) (llvm/trunk 315960)"}
93 !17 = distinct !DISubprogram(name: "f2", scope: !3, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !2, variables: !4)
94 !18 = !DILocation(line: 2, column: 16, scope: !17)
8383 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
8484 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
8585 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
86 case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
87 case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
8688 HasAddend = true;
8789 break;
8890 default:
103103 break;
104104 case wasm::WASM_SYMBOL_TYPE_FUNCTION:
105105 case wasm::WASM_SYMBOL_TYPE_GLOBAL:
106 Info.ElementIndex = Symbol.ElementIndex;
107 break;
108 case wasm::WASM_SYMBOL_TYPE_SECTION:
106109 Info.ElementIndex = Symbol.ElementIndex;
107110 break;
108111 }
164164 encodeULEB128(Info.DataRef.Size, SubSection.GetStream());
165165 }
166166 break;
167 case wasm::WASM_SYMBOL_TYPE_SECTION:
168 encodeULEB128(Info.ElementIndex, SubSection.GetStream());
169 break;
167170 default:
168171 llvm_unreachable("unexpected kind");
169172 }
423426
424427 int WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec,
425428 uint32_t SectionIndex) {
426 StringRef Name;
427429 switch (Sec.Type) {
428430 case wasm::WASM_SEC_CODE:
429 Name = "reloc.CODE";
431 writeStringRef("reloc.CODE", OS);
430432 break;
431433 case wasm::WASM_SEC_DATA:
432 Name = "reloc.DATA";
433 break;
434 writeStringRef("reloc.DATA", OS);
435 break;
436 case wasm::WASM_SEC_CUSTOM: {
437 auto CustomSection = dyn_cast(&Sec);
438 if (!CustomSection->Name.startswith(".debug_")) {
439 llvm_unreachable("not yet implemented (only for debug sections)");
440 return 1;
441 }
442
443 writeStringRef(("reloc." + CustomSection->Name).str(), OS);
444 break;
445 }
434446 default:
435447 llvm_unreachable("not yet implemented");
436448 return 1;
437449 }
438450
439 writeStringRef(Name, OS);
440451 encodeULEB128(SectionIndex, OS);
441452 encodeULEB128(Sec.Relocations.size(), OS);
442453
448459 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
449460 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
450461 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
462 case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
463 case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
451464 encodeULEB128(Reloc.Addend, OS);
452465 }
453466 }