diff options
Diffstat (limited to 'wasm')
-rw-r--r-- | wasm/InputFiles.cpp | 9 | ||||
-rw-r--r-- | wasm/InputSegment.h | 2 | ||||
-rw-r--r-- | wasm/OutputSections.cpp | 57 | ||||
-rw-r--r-- | wasm/OutputSections.h | 18 | ||||
-rw-r--r-- | wasm/OutputSegment.h | 2 | ||||
-rw-r--r-- | wasm/SymbolTable.cpp | 10 | ||||
-rw-r--r-- | wasm/SymbolTable.h | 1 | ||||
-rw-r--r-- | wasm/Writer.cpp | 43 |
8 files changed, 89 insertions, 53 deletions
diff --git a/wasm/InputFiles.cpp b/wasm/InputFiles.cpp index e7463da39db9..1a1a6812c48e 100644 --- a/wasm/InputFiles.cpp +++ b/wasm/InputFiles.cpp @@ -198,13 +198,22 @@ void ObjFile::initializeSymbols() { DEBUG(dbgs() << "Function: " << WasmSym.ElementIndex << " -> " << toString(*S) << "\n"); FunctionSymbols[WasmSym.ElementIndex] = S; + if (WasmSym.HasAltIndex) + FunctionSymbols[WasmSym.AltIndex] = S; } else { DEBUG(dbgs() << "Global: " << WasmSym.ElementIndex << " -> " << toString(*S) << "\n"); GlobalSymbols[WasmSym.ElementIndex] = S; + if (WasmSym.HasAltIndex) + GlobalSymbols[WasmSym.AltIndex] = S; } } + DEBUG(for (size_t I = 0; I < FunctionSymbols.size(); ++I) + assert(FunctionSymbols[I] != nullptr); + for (size_t I = 0; I < GlobalSymbols.size(); ++I) + assert(GlobalSymbols[I] != nullptr);); + // Populate `TableSymbols` with all symbols that are called indirectly uint32_t SegmentCount = WasmObj->elements().size(); if (SegmentCount) { diff --git a/wasm/InputSegment.h b/wasm/InputSegment.h index 64124b1ebc2c..f70a3ded895e 100644 --- a/wasm/InputSegment.h +++ b/wasm/InputSegment.h @@ -21,6 +21,7 @@ #ifndef LLD_WASM_INPUT_SEGMENT_H #define LLD_WASM_INPUT_SEGMENT_H +#include "WriterUtils.h" #include "lld/Common/ErrorHandler.h" #include "llvm/Object/Wasm.h" @@ -62,6 +63,7 @@ public: const WasmSegment *Segment; const ObjFile *File; std::vector<WasmRelocation> Relocations; + std::vector<OutputRelocation> OutRelocations; protected: const OutputSegment *OutputSeg = nullptr; diff --git a/wasm/OutputSections.cpp b/wasm/OutputSections.cpp index e5253640b9db..a55538269065 100644 --- a/wasm/OutputSections.cpp +++ b/wasm/OutputSections.cpp @@ -63,10 +63,10 @@ static StringRef sectionTypeToString(uint32_t SectionType) { } } -std::string lld::toString(OutputSection *Section) { - std::string rtn = sectionTypeToString(Section->Type); - if (!Section->Name.empty()) - rtn += "(" + Section->Name + ")"; +std::string lld::toString(const OutputSection &Section) { + std::string rtn = Section.getSectionName(); + if (!Section.Name.empty()) + rtn += "(" + Section.Name + ")"; return rtn; } @@ -108,12 +108,12 @@ static void applyRelocation(uint8_t *Buf, const OutputRelocation &Reloc) { } } -static void applyRelocations(uint8_t *Buf, - ArrayRef<OutputRelocation> Relocs) { +static void applyRelocations(uint8_t *Buf, ArrayRef<OutputRelocation> Relocs) { + if (!Relocs.size()) + return; log("applyRelocations: count=" + Twine(Relocs.size())); - for (const OutputRelocation &Reloc : Relocs) { + for (const OutputRelocation &Reloc : Relocs) applyRelocation(Buf, Reloc); - } } // Relocations contain an index into the function, global or table index @@ -177,14 +177,21 @@ static void calcRelocations(const ObjFile &File, } } +std::string OutputSection::getSectionName() const { + return sectionTypeToString(Type); +} + +std::string SubSection::getSectionName() const { + return std::string("subsection <type=") + std::to_string(Type) + ">"; +} + void OutputSection::createHeader(size_t BodySize) { raw_string_ostream OS(Header); - debugWrite(OS.tell(), - "section type [" + Twine(sectionTypeToString(Type)) + "]"); + debugWrite(OS.tell(), "section type [" + Twine(getSectionName()) + "]"); writeUleb128(OS, Type, nullptr); writeUleb128(OS, BodySize, "section size"); OS.flush(); - log("createHeader: " + toString(this) + " body=" + Twine(BodySize) + + log("createHeader: " + toString(*this) + " body=" + Twine(BodySize) + " total=" + Twine(getSize())); } @@ -215,7 +222,7 @@ CodeSection::CodeSection(uint32_t NumFunctions, ArrayRef<ObjFile *> Objs) } void CodeSection::writeTo(uint8_t *Buf) { - log("writing " + toString(this)); + log("writing " + toString(*this)); log(" size=" + Twine(getSize())); Buf += Offset; @@ -245,8 +252,7 @@ void CodeSection::writeTo(uint8_t *Buf) { PayloadSize); log("applying relocations for: " + File->getName()); - if (File->CodeRelocations.size()) - applyRelocations(ContentsStart, File->CodeRelocations); + applyRelocations(ContentsStart, File->CodeRelocations); }); } @@ -282,13 +288,13 @@ DataSection::DataSection(ArrayRef<OutputSegment *> Segments) Segment->setSectionOffset(BodySize); BodySize += Segment->Header.size(); log("Data segment: size=" + Twine(Segment->Size)); - for (const InputSegment *InputSeg : Segment->InputSegments) { + for (InputSegment *InputSeg : Segment->InputSegments) { uint32_t InputOffset = InputSeg->getInputSectionOffset(); uint32_t OutputOffset = Segment->getSectionOffset() + Segment->Header.size() + InputSeg->getOutputSegmentOffset(); - calcRelocations(*InputSeg->File, InputSeg->Relocations, Relocations, - OutputOffset - InputOffset); + calcRelocations(*InputSeg->File, InputSeg->Relocations, + InputSeg->OutRelocations, OutputOffset - InputOffset); } BodySize += Segment->Size; } @@ -297,7 +303,7 @@ DataSection::DataSection(ArrayRef<OutputSegment *> Segments) } void DataSection::writeTo(uint8_t *Buf) { - log("writing " + toString(this) + " size=" + Twine(getSize()) + + log("writing " + toString(*this) + " size=" + Twine(getSize()) + " body=" + Twine(BodySize)); Buf += Offset; @@ -321,13 +327,22 @@ void DataSection::writeTo(uint8_t *Buf) { memcpy(SegStart + Segment->Header.size() + Input->getOutputSegmentOffset(), Content.data(), Content.size()); + applyRelocations(ContentsStart, Input->OutRelocations); } }); +} - applyRelocations(ContentsStart, Relocations); +uint32_t DataSection::numRelocations() const { + uint32_t Count = 0; + for (const OutputSegment *Seg : Segments) + for (const InputSegment *InputSeg : Seg->InputSegments) + Count += InputSeg->OutRelocations.size(); + return Count; } void DataSection::writeRelocations(raw_ostream &OS) const { - for (const OutputRelocation &Reloc : Relocations) - writeReloc(OS, Reloc); + for (const OutputSegment *Seg : Segments) + for (const InputSegment *InputSeg : Seg->InputSegments) + for (const OutputRelocation &Reloc : InputSeg->OutRelocations) + writeReloc(OS, Reloc); } diff --git a/wasm/OutputSections.h b/wasm/OutputSections.h index 926101710cdf..fc73f36ad286 100644 --- a/wasm/OutputSections.h +++ b/wasm/OutputSections.h @@ -23,7 +23,7 @@ namespace lld { namespace wasm { class OutputSection; } -std::string toString(wasm::OutputSection *Section); +std::string toString(const wasm::OutputSection &Section); namespace wasm { @@ -34,26 +34,24 @@ class OutputSection { public: OutputSection(uint32_t Type, std::string Name = "") : Type(Type), Name(Name) {} - virtual ~OutputSection() = default; + std::string getSectionName() const; void setOffset(size_t NewOffset) { - log("setOffset: " + toString(this) + " -> " + Twine(NewOffset)); + log("setOffset: " + toString(*this) + ": " + Twine(NewOffset)); Offset = NewOffset; } - void createHeader(size_t BodySize); virtual size_t getSize() const = 0; virtual void writeTo(uint8_t *Buf) = 0; virtual void finalizeContents() {} + virtual uint32_t numRelocations() const { return 0; } + virtual void writeRelocations(raw_ostream &OS) const {} std::string Header; uint32_t Type; std::string Name; - virtual uint32_t numRelocations() const { return 0; } - virtual void writeRelocations(raw_ostream &OS) const {} - protected: size_t Offset = 0; }; @@ -68,7 +66,7 @@ public: void writeTo(uint8_t *Buf) override { assert(Offset); - log("writing " + toString(this)); + log("writing " + toString(*this)); memcpy(Buf + Offset, Header.data(), Header.size()); memcpy(Buf + Offset + Header.size(), Body.data(), Body.size()); } @@ -97,6 +95,7 @@ class SubSection : public SyntheticSection { public: explicit SubSection(uint32_t Type) : SyntheticSection(Type) {} + std::string getSectionName() const; void writeToStream(raw_ostream &OS) { writeBytes(OS, Header.data(), Header.size()); writeBytes(OS, Body.data(), Body.size()); @@ -122,11 +121,10 @@ public: explicit DataSection(ArrayRef<OutputSegment *> Segments); size_t getSize() const override { return Header.size() + BodySize; } void writeTo(uint8_t *Buf) override; - uint32_t numRelocations() const override { return Relocations.size(); } + uint32_t numRelocations() const override; void writeRelocations(raw_ostream &OS) const override; protected: - std::vector<OutputRelocation> Relocations; ArrayRef<OutputSegment *> Segments; std::string DataSectionHeader; size_t BodySize = 0; diff --git a/wasm/OutputSegment.h b/wasm/OutputSegment.h index 1375aefae92f..a22c80234420 100644 --- a/wasm/OutputSegment.h +++ b/wasm/OutputSegment.h @@ -38,7 +38,7 @@ public: StringRef Name; uint32_t Alignment = 0; uint32_t StartVA = 0; - std::vector<const InputSegment *> InputSegments; + std::vector<InputSegment *> InputSegments; // Sum of the size of the all the input segments uint32_t Size = 0; diff --git a/wasm/SymbolTable.cpp b/wasm/SymbolTable.cpp index d9a6fa1f04f5..751008da0536 100644 --- a/wasm/SymbolTable.cpp +++ b/wasm/SymbolTable.cpp @@ -83,15 +83,7 @@ static const WasmSignature *getFunctionSig(const ObjFile &Obj, const WasmSymbol &Sym) { DEBUG(dbgs() << "getFunctionSig: " << Sym.Name << "\n"); const WasmObjectFile *WasmObj = Obj.getWasmObj(); - uint32_t FunctionType; - if (Obj.isImportedFunction(Sym.ElementIndex)) { - const WasmImport &Import = WasmObj->imports()[Sym.ImportIndex]; - FunctionType = Import.SigIndex; - } else { - uint32_t FuntionIndex = Sym.ElementIndex - Obj.NumFunctionImports(); - FunctionType = WasmObj->functionTypes()[FuntionIndex]; - } - return &WasmObj->types()[FunctionType]; + return &WasmObj->types()[Sym.FunctionType]; } // Check the type of new symbol matches that of the symbol is replacing. diff --git a/wasm/SymbolTable.h b/wasm/SymbolTable.h index e1e7da120b93..fbb74ed14796 100644 --- a/wasm/SymbolTable.h +++ b/wasm/SymbolTable.h @@ -42,7 +42,6 @@ public: void addFile(InputFile *File); std::vector<ObjFile *> ObjectFiles; - std::vector<Symbol *> SyntheticSymbols; void reportDuplicate(Symbol *Existing, InputFile *NewFile); void reportRemainingUndefines(); diff --git a/wasm/Writer.cpp b/wasm/Writer.cpp index 61ac54a3e4b3..e7dd49d52213 100644 --- a/wasm/Writer.cpp +++ b/wasm/Writer.cpp @@ -174,7 +174,7 @@ void Writer::createImportSection() { Import.Field = Sym->getName(); Import.Kind = WASM_EXTERNAL_GLOBAL; Import.Global.Mutable = false; - Import.Global.Type = WASM_TYPE_I32; // Sym->getGlobalType(); + Import.Global.Type = WASM_TYPE_I32; writeImport(OS, Import); } } @@ -183,9 +183,8 @@ void Writer::createTypeSection() { SyntheticSection *Section = createSyntheticSection(WASM_SEC_TYPE); raw_ostream &OS = Section->getStream(); writeUleb128(OS, Types.size(), "type count"); - for (const WasmSignature *Sig : Types) { + for (const WasmSignature *Sig : Types) writeSig(OS, *Sig); - } } void Writer::createFunctionSection() { @@ -196,11 +195,9 @@ void Writer::createFunctionSection() { raw_ostream &OS = Section->getStream(); writeUleb128(OS, NumFunctions, "function count"); - for (ObjFile *File : Symtab->ObjectFiles) { - for (uint32_t Sig : File->getWasmObj()->functionTypes()) { + for (ObjFile *File : Symtab->ObjectFiles) + for (uint32_t Sig : File->getWasmObj()->functionTypes()) writeUleb128(OS, File->relocateTypeIndex(Sig), "sig index"); - } - } } void Writer::createMemorySection() { @@ -358,7 +355,7 @@ void Writer::createDataSection() { OutputSections.push_back(Section); } -// Create reloctions sections in the final output. +// Create relocations sections in the final output. // These are only created when relocatable output is requested. void Writer::createRelocSections() { log("createRelocSections"); @@ -376,7 +373,7 @@ void Writer::createRelocSections() { else if (S->Type == WASM_SEC_CODE) name = "reloc.CODE"; else - llvm_unreachable("relocations only support for code and data"); + llvm_unreachable("relocations only supported for code and data"); SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, name); raw_ostream &OS = Section->getStream(); @@ -398,7 +395,10 @@ void Writer::createLinkingSection() { DataSizeSubSection.finalizeContents(); DataSizeSubSection.writeToStream(OS); - if (Segments.size() && Config->Relocatable) { + if (!Config->Relocatable) + return; + + if (Segments.size()) { SubSection SubSection(WASM_SEGMENT_INFO); writeUleb128(SubSection.getStream(), Segments.size(), "num data segments"); for (const OutputSegment *S : Segments) { @@ -409,6 +409,27 @@ void Writer::createLinkingSection() { SubSection.finalizeContents(); SubSection.writeToStream(OS); } + + std::vector<WasmInitFunc> InitFunctions; + for (ObjFile *File : Symtab->ObjectFiles) { + const WasmLinkingData &L = File->getWasmObj()->linkingData(); + InitFunctions.reserve(InitFunctions.size() + L.InitFunctions.size()); + for (const WasmInitFunc &F : L.InitFunctions) + InitFunctions.emplace_back(WasmInitFunc{ + F.Priority, File->relocateFunctionIndex(F.FunctionIndex)}); + } + + if (!InitFunctions.empty()) { + SubSection SubSection(WASM_INIT_FUNCS); + writeUleb128(SubSection.getStream(), InitFunctions.size(), + "num init functionsw"); + for (const WasmInitFunc &F : InitFunctions) { + writeUleb128(SubSection.getStream(), F.Priority, "priority"); + writeUleb128(SubSection.getStream(), F.FunctionIndex, "function index"); + } + SubSection.finalizeContents(); + SubSection.writeToStream(OS); + } } // Create the custom "name" section containing debug symbol names. @@ -501,7 +522,7 @@ void Writer::layoutMemory() { SyntheticSection *Writer::createSyntheticSection(uint32_t Type, std::string Name) { auto Sec = make<SyntheticSection>(Type, Name); - log("createSection: " + toString(Sec)); + log("createSection: " + toString(*Sec)); OutputSections.push_back(Sec); return Sec; } |