diff options
author | Sam Clegg <sbc@chromium.org> | 2018-04-26 19:27:28 +0000 |
---|---|---|
committer | Sam Clegg <sbc@chromium.org> | 2018-04-26 19:27:28 +0000 |
commit | 6a31a0d694a65f5cb11ae6d49c7fdb3f08b0d262 (patch) | |
tree | 80ffd86a99679f42be9cb191dcd65305be55e03a /llvm/lib | |
parent | 540512c29719dc98429961c38fa882bcfef1de40 (diff) | |
download | bcm5719-llvm-6a31a0d694a65f5cb11ae6d49c7fdb3f08b0d262.tar.gz bcm5719-llvm-6a31a0d694a65f5cb11ae6d49c7fdb3f08b0d262.zip |
[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
llvm-svn: 330982
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/WasmObjectWriter.cpp | 189 | ||||
-rw-r--r-- | llvm/lib/Object/WasmObjectFile.cpp | 36 | ||||
-rw-r--r-- | llvm/lib/ObjectYAML/WasmYAML.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp | 29 |
4 files changed, 230 insertions, 27 deletions
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 0e122708504..88bd046ec6e 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -48,7 +48,9 @@ static const uint32_t kInitialTableOffset = 1; struct SectionBookkeeping { // Where the size of the section is written. uint64_t SizeOffset; - // Where the contents of the section starts (after the header). + // Where the section header ends (without custom section name). + uint64_t PayloadOffset; + // Where the contents of the section starts. uint64_t ContentsOffset; uint32_t Index; }; @@ -151,6 +153,8 @@ struct WasmRelocationEntry { case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: + case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: + case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: return true; default: return false; @@ -169,11 +173,17 @@ struct WasmRelocationEntry { }; struct WasmCustomSection { + const uint32_t INVALID_INDEX = -1; + StringRef Name; - const SmallVectorImpl<char> &Contents; + MCSectionWasm *Section; + + uint32_t OutputContentsOffset; + uint32_t OutputIndex; - WasmCustomSection(StringRef Name, const SmallVectorImpl<char> &Contents) - : Name(Name), Contents(Contents) {} + WasmCustomSection(StringRef Name, MCSectionWasm *Section) + : Name(Name), Section(Section), OutputContentsOffset(0), + OutputIndex(INVALID_INDEX) {} }; #if !defined(NDEBUG) @@ -207,13 +217,21 @@ class WasmObjectWriter : public MCObjectWriter { DenseMap<const MCSymbolWasm *, uint32_t> WasmIndices; // Maps data symbols to the Wasm segment and offset/size with the segment. DenseMap<const MCSymbolWasm *, wasm::WasmDataReference> DataLocations; + // Maps section symbols to the section. + DenseMap<const MCSymbolWasm *, const MCSectionWasm *> CustomSectionSymbols; + + // Stores output data (index, relocations, content offset) for custom + // section. + std::vector<WasmCustomSection> CustomSections; + // Relocations for fixing up references in the custom sections. + DenseMap<const MCSectionWasm *, std::vector<WasmRelocationEntry>> + CustomSectionsRelocations; DenseMap<WasmFunctionType, int32_t, WasmFunctionTypeDenseMapInfo> FunctionTypeIndices; SmallVector<WasmFunctionType, 4> FunctionTypes; SmallVector<WasmGlobal, 4> Globals; SmallVector<WasmDataSegment, 4> DataSegments; - std::vector<WasmCustomSection> CustomSections; unsigned NumFunctionImports = 0; unsigned NumGlobalImports = 0; uint32_t SectionCount = 0; @@ -245,10 +263,12 @@ private: WasmIndices.clear(); TableIndices.clear(); DataLocations.clear(); + CustomSectionsRelocations.clear(); FunctionTypeIndices.clear(); FunctionTypes.clear(); Globals.clear(); DataSegments.clear(); + CustomSectionSymbols.clear(); MCObjectWriter::reset(); NumFunctionImports = 0; NumGlobalImports = 0; @@ -290,7 +310,11 @@ private: ArrayRef<wasm::WasmSymbolInfo> SymbolInfos, ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs, const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats); - void writeUserCustomSections(ArrayRef<WasmCustomSection> CustomSections); + void writeCustomSections(const MCAssembler &Asm, const MCAsmLayout &Layout); + void writeCustomRelocSections(); + void + updateCustomSectionRelocations(const SmallVector<WasmFunction, 4> &Functions, + const MCAsmLayout &Layout); uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry); void applyRelocations(ArrayRef<WasmRelocationEntry> Relocations, @@ -319,6 +343,7 @@ void WasmObjectWriter::startSection(SectionBookkeeping &Section, // The position where the section starts, for measuring its size. Section.ContentsOffset = getStream().tell(); + Section.PayloadOffset = getStream().tell(); Section.Index = SectionCount++; } @@ -326,14 +351,21 @@ void WasmObjectWriter::startCustomSection(SectionBookkeeping &Section, StringRef Name) { DEBUG(dbgs() << "startCustomSection " << Name << "\n"); startSection(Section, wasm::WASM_SEC_CUSTOM); + + // The position where the section header ends, for measuring its size. + Section.PayloadOffset = getStream().tell(); + // Custom sections in wasm also have a string identifier. writeString(Name); + + // The position where the custom section starts. + Section.ContentsOffset = getStream().tell(); } // Now that the section is complete and we know how big it is, patch up the // section size field at the start of the section. void WasmObjectWriter::endSection(SectionBookkeeping &Section) { - uint64_t Size = getStream().tell() - Section.ContentsOffset; + uint64_t Size = getStream().tell() - Section.PayloadOffset; if (uint32_t(Size) != Size) report_fatal_error("section size does not fit in a uint32_t"); @@ -374,8 +406,9 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, if (FixupSection.getSectionName().startswith(".init_array")) return; - // TODO(sbc): Add support for debug sections. - if (FixupSection.getKind().isMetadata()) + // TODO: Add support for non-debug metadata sections? + if (FixupSection.getKind().isMetadata() && + !FixupSection.getSectionName().startswith(".debug_")) return; if (const MCSymbolRefExpr *RefB = Target.getSymB()) { @@ -446,21 +479,29 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection); DEBUG(dbgs() << "WasmReloc: " << Rec << "\n"); - // Relocation other than R_WEBASSEMBLY_TYPE_INDEX_LEB are currently required - // to be against a named symbol. + // Relocation other than R_WEBASSEMBLY_TYPE_INDEX_LEB, + // R_WEBASSEMBLY_SECTION_OFFSET_I32 or R_WEBASSEMBLY_FUNCTION_OFFSET_I32 + // are currently required to be against a named symbol. // TODO(sbc): Add support for relocations against unnamed temporaries such // as those generated by llvm's `blockaddress`. // See: test/MC/WebAssembly/blockaddress.ll - if (SymA->getName().empty() && Type != wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB) + if (SymA->getName().empty() && + !(Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB || + Type == wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32 || + Type == wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32)) report_fatal_error("relocations against un-named temporaries are not yet " "supported by wasm"); - if (FixupSection.isWasmData()) + if (FixupSection.isWasmData()) { DataRelocations.push_back(Rec); - else if (FixupSection.getKind().isText()) + } else if (FixupSection.getKind().isText()) { CodeRelocations.push_back(Rec); - else + } else if (FixupSection.getKind().isMetadata()) { + assert(FixupSection.getSectionName().startswith(".debug_")); + CustomSectionsRelocations[&FixupSection].push_back(Rec); + } else { llvm_unreachable("unexpected section type"); + } } // Write X as an (unsigned) LEB value at offset Offset in Stream, padded @@ -523,6 +564,15 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) { report_fatal_error("symbol not found in wasm index space: " + RelEntry.Symbol->getName()); return WasmIndices[RelEntry.Symbol]; + case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: { + const auto &Section = + static_cast<const MCSectionWasm &>(RelEntry.Symbol->getSection()); + return Section.getSectionOffset() + RelEntry.Addend; + } + case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: { + const auto &Section = *CustomSectionSymbols.find(RelEntry.Symbol)->second; + return Section.getSectionOffset() + RelEntry.Addend; + } case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: { @@ -614,6 +664,8 @@ void WasmObjectWriter::applyRelocations( break; case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: + case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: + case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: WriteI32(Stream, Value, Offset); break; case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB: @@ -851,6 +903,13 @@ void WasmObjectWriter::writeRelocSection( endSection(Section); } +void WasmObjectWriter::writeCustomRelocSections() { + for (const auto &Sec : CustomSections) { + auto &Relocations = CustomSectionsRelocations[Sec.Section]; + writeRelocSection(Sec.OutputIndex, Sec.Name, Relocations); + } +} + void WasmObjectWriter::writeLinkingMetaDataSection( ArrayRef<wasm::WasmSymbolInfo> SymbolInfos, ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs, @@ -881,6 +940,12 @@ void WasmObjectWriter::writeLinkingMetaDataSection( encodeULEB128(Sym.DataRef.Size, getStream()); } break; + case wasm::WASM_SYMBOL_TYPE_SECTION: { + const uint32_t SectionIndex = + CustomSections[Sym.ElementIndex].OutputIndex; + encodeULEB128(SectionIndex, getStream()); + break; + } default: llvm_unreachable("unexpected kind"); } @@ -927,16 +992,66 @@ void WasmObjectWriter::writeLinkingMetaDataSection( endSection(Section); } -void WasmObjectWriter::writeUserCustomSections( - ArrayRef<WasmCustomSection> CustomSections) { - for (const auto &CustomSection : CustomSections) { +void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm, + const MCAsmLayout &Layout) { + for (auto &CustomSection : CustomSections) { SectionBookkeeping Section; + auto *Sec = CustomSection.Section; startCustomSection(Section, CustomSection.Name); - writeBytes(CustomSection.Contents); + + Sec->setSectionOffset(getStream().tell() - Section.ContentsOffset); + Asm.writeSectionData(Sec, Layout); + + CustomSection.OutputContentsOffset = Section.ContentsOffset; + CustomSection.OutputIndex = Section.Index; + endSection(Section); } } +void WasmObjectWriter::updateCustomSectionRelocations( + const SmallVector<WasmFunction, 4> &Functions, const MCAsmLayout &Layout) { + std::map<const MCSection *, const MCSymbolWasm *> SectionSymbols; + for (const auto &P : CustomSectionSymbols) + SectionSymbols[P.second] = P.first; + std::map<const MCSection *, const MCSymbolWasm *> FuncSymbols; + for (const auto &FuncInfo : Functions) + FuncSymbols[&FuncInfo.Sym->getSection()] = FuncInfo.Sym; + + // Patch relocation records for R_WEBASSEMBLY_FUNCTION_OFFSET_I32 and + // R_WEBASSEMBLY_SECTION_OFFSET_I32. The Addend is stuffed the offset from + // the beginning of the function or custom section -- all such relocations + // target the function or custom section starts. + for (auto &Section : CustomSections) { + auto &Relocations = CustomSectionsRelocations[Section.Section]; + for (WasmRelocationEntry &RelEntry : Relocations) { + switch (RelEntry.Type) { + case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: { + assert(RelEntry.hasAddend()); + auto &Section = + static_cast<MCSectionWasm &>(RelEntry.Symbol->getSection()); + RelEntry.Addend += Layout.getSymbolOffset(*RelEntry.Symbol); + RelEntry.Symbol = FuncSymbols[&Section]; + break; + } + case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: { + assert(RelEntry.hasAddend()); + auto &Section = + static_cast<MCSectionWasm &>(RelEntry.Symbol->getSection()); + RelEntry.Addend += Layout.getSymbolOffset(*RelEntry.Symbol); + RelEntry.Symbol = SectionSymbols[&Section]; + break; + } + default: + break; + } + } + + // Apply fixups. + applyRelocations(Relocations, Section.OutputContentsOffset); + } +} + uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm& Symbol) { assert(Symbol.isFunction()); assert(TypeIndices.count(&Symbol)); @@ -1043,8 +1158,7 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm, for (MCSection &Sec : Asm) { auto &Section = static_cast<MCSectionWasm &>(Sec); - if (cast<MCSectionWasm>(Sec).getSectionName().startswith( - ".custom_section.")) { + if (Section.getSectionName().startswith(".custom_section.")) { if (Section.getFragmentList().empty()) continue; if (Section.getFragmentList().size() != 1) @@ -1057,8 +1171,7 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm, if (!DataFrag.getFixups().empty()) report_fatal_error("fixups not supported in .custom_section section"); StringRef UserName = Section.getSectionName().substr(16); - const SmallVectorImpl<char> &Contents = DataFrag.getContents(); - CustomSections.push_back(WasmCustomSection(UserName, Contents)); + CustomSections.emplace_back(UserName, &Section); continue; } @@ -1088,6 +1201,31 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm, } } + // Create symbols for debug/custom sections. + for (MCSection &Sec : Asm) { + auto &DebugSection = static_cast<MCSectionWasm &>(Sec); + StringRef SectionName = DebugSection.getSectionName(); + + // TODO: Add support for non-debug metadata sections? + if (!Sec.getKind().isMetadata() || !SectionName.startswith(".debug_")) + continue; + + uint32_t ElementIndex = CustomSections.size(); + CustomSections.emplace_back(SectionName, &DebugSection); + + MCSymbolWasm *SectionSym = + cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SectionName)); + CustomSectionSymbols[SectionSym] = &DebugSection; + + wasm::WasmSymbolInfo Info; + Info.Name = SectionSym->getName(); + Info.Kind = wasm::WASM_SYMBOL_TYPE_SECTION; + Info.Flags = 0; + Info.ElementIndex = ElementIndex; + SymbolIndices[SectionSym] = SymbolInfos.size(); + SymbolInfos.emplace_back(Info); + } + // Populate WasmIndices and DataLocations for defined symbols. for (const MCSymbol &S : Asm.symbols()) { // Ignore unnamed temporary symbols, which aren't ever exported, imported, @@ -1331,13 +1469,14 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm, writeElemSection(TableElems); writeCodeSection(Asm, Layout, Functions); writeDataSection(); - writeUserCustomSections(CustomSections); + writeCustomSections(Asm, Layout); + updateCustomSectionRelocations(Functions, Layout); writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats); writeRelocSection(CodeSectionIndex, "CODE", CodeRelocations); writeRelocSection(DataSectionIndex, "DATA", DataRelocations); + writeCustomRelocSections(); // TODO: Translate the .comment section to the output. - // TODO: Translate debug sections to the output. } std::unique_ptr<MCObjectWriter> diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index 61db5d2468a..121e1f98f3e 100644 --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -465,6 +465,14 @@ Error WasmObjectFile::parseLinkingSectionSymtab(const uint8_t *&Ptr, } break; + case wasm::WASM_SYMBOL_TYPE_SECTION: { + Info.ElementIndex = readVaruint32(Ptr); + // Use somewhat unique section name as symbol name. + StringRef SectionName = Sections[Info.ElementIndex].Name; + Info.Name = SectionName; + break; + } + default: return make_error<GenericBinaryError>("Invalid symbol type", object_error::parse_failed); @@ -573,6 +581,18 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr, object_error::parse_failed); Reloc.Addend = readVarint32(Ptr); break; + case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: + if (!isValidFunctionSymbol(Reloc.Index)) + return make_error<GenericBinaryError>("Bad relocation function index", + object_error::parse_failed); + Reloc.Addend = readVarint32(Ptr); + break; + case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: + if (!isValidSectionSymbol(Reloc.Index)) + return make_error<GenericBinaryError>("Bad relocation section index", + object_error::parse_failed); + Reloc.Addend = readVarint32(Ptr); + break; default: return make_error<GenericBinaryError>("Bad relocation type: " + Twine(Reloc.Type), @@ -584,7 +604,9 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr, // to check that. uint64_t Size = 5; if (Reloc.Type == wasm::R_WEBASSEMBLY_TABLE_INDEX_I32 || - Reloc.Type == wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32) + Reloc.Type == wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32 || + Reloc.Type == wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32 || + Reloc.Type == wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32) Size = 4; if (Reloc.Offset + Size > EndOffset) return make_error<GenericBinaryError>("Bad relocation offset", @@ -811,6 +833,10 @@ bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const { return Index < Symbols.size() && Symbols[Index].isTypeData(); } +bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const { + return Index < Symbols.size() && Symbols[Index].isTypeSection(); +} + wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) { assert(isDefinedFunctionIndex(Index)); return Functions[Index - NumImportedFunctions]; @@ -991,6 +1017,8 @@ uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol& Sym) const { assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST); return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset; } + case wasm::WASM_SYMBOL_TYPE_SECTION: + return 0; } llvm_unreachable("invalid symbol type"); } @@ -1020,6 +1048,8 @@ WasmObjectFile::getSymbolType(DataRefImpl Symb) const { return SymbolRef::ST_Other; case wasm::WASM_SYMBOL_TYPE_DATA: return SymbolRef::ST_Data; + case wasm::WASM_SYMBOL_TYPE_SECTION: + return SymbolRef::ST_Debug; } llvm_unreachable("Unknown WasmSymbol::SymbolType"); @@ -1043,6 +1073,10 @@ WasmObjectFile::getSymbolSection(DataRefImpl Symb) const { case wasm::WASM_SYMBOL_TYPE_DATA: Ref.d.a = DataSection; break; + case wasm::WASM_SYMBOL_TYPE_SECTION: { + Ref.d.a = Sym.Info.ElementIndex; + break; + } default: llvm_unreachable("Unknown WasmSymbol::SymbolType"); } diff --git a/llvm/lib/ObjectYAML/WasmYAML.cpp b/llvm/lib/ObjectYAML/WasmYAML.cpp index ff75bfc7676..3c20bb74d50 100644 --- a/llvm/lib/ObjectYAML/WasmYAML.cpp +++ b/llvm/lib/ObjectYAML/WasmYAML.cpp @@ -405,6 +405,8 @@ void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO, IO.mapOptional("Offset", Info.DataRef.Offset, 0u); IO.mapRequired("Size", Info.DataRef.Size); } + } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION) { + IO.mapRequired("Section", Info.ElementIndex); } else { llvm_unreachable("unsupported symbol kind"); } @@ -439,6 +441,7 @@ void ScalarEnumerationTraits<WasmYAML::SymbolKind>::enumeration( ECase(FUNCTION); ECase(DATA); ECase(GLOBAL); + ECase(SECTION); #undef ECase } diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp index 39abde26df7..ab0125e7c28 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp @@ -20,9 +20,10 @@ #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSectionWasm.h" #include "llvm/MC/MCSymbolWasm.h" -#include "llvm/MC/MCWasmObjectWriter.h" #include "llvm/MC/MCValue.h" +#include "llvm/MC/MCWasmObjectWriter.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" @@ -61,6 +62,25 @@ static bool IsFunctionType(const MCValue &Target) { return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX; } +static const MCSection *GetFixupSection(const MCExpr *Expr) { + if (auto SyExp = dyn_cast<MCSymbolRefExpr>(Expr)) { + if (SyExp->getSymbol().isInSection()) + return &SyExp->getSymbol().getSection(); + return nullptr; + } + + if (auto BinOp = dyn_cast<MCBinaryExpr>(Expr)) { + auto SectionLHS = GetFixupSection(BinOp->getLHS()); + auto SectionRHS = GetFixupSection(BinOp->getRHS()); + return SectionLHS == SectionRHS ? nullptr : SectionLHS; + } + + if (auto UnOp = dyn_cast<MCUnaryExpr>(Expr)) + return GetFixupSection(UnOp->getSubExpr()); + + return nullptr; +} + unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target, const MCFixup &Fixup) const { @@ -86,6 +106,13 @@ WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target, case FK_Data_4: if (IsFunction) return wasm::R_WEBASSEMBLY_TABLE_INDEX_I32; + if (auto Section = static_cast<const MCSectionWasm *>( + GetFixupSection(Fixup.getValue()))) { + if (Section->getKind().isText()) + return wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32; + else if (!Section->isWasmData()) + return wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32; + } return wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32; case FK_Data_8: llvm_unreachable("FK_Data_8 not implemented yet"); |