Index: wasm/InputChunks.h =================================================================== --- wasm/InputChunks.h +++ wasm/InputChunks.h @@ -50,14 +50,15 @@ uint32_t getSize() const { return data().size(); } - void copyRelocations(const WasmSection &Section); void writeTo(uint8_t *SectionStart) const; ArrayRef getRelocations() const { return Relocations; } + void setRelocations(ArrayRef Rs) { Relocations = Rs; } virtual StringRef getComdat() const = 0; virtual StringRef getName() const = 0; + virtual uint32_t getInputSectionOffset() const = 0; size_t NumRelocations() const { return Relocations.size(); } void writeRelocations(llvm::raw_ostream &OS) const; @@ -75,9 +76,8 @@ : File(F), Live(!Config->GcSections), SectionKind(K) {} virtual ~InputChunk() = default; virtual ArrayRef data() const = 0; - virtual uint32_t getInputSectionOffset() const = 0; - std::vector Relocations; + ArrayRef Relocations; Kind SectionKind; }; @@ -110,14 +110,14 @@ uint32_t getAlignment() const { return Segment.Data.Alignment; } StringRef getName() const override { return Segment.Data.Name; } StringRef getComdat() const override { return Segment.Data.Comdat; } + uint32_t getInputSectionOffset() const override { + return Segment.SectionOffset; + } int32_t OutputSegmentOffset = 0; protected: ArrayRef data() const override { return Segment.Data.Content; } - uint32_t getInputSectionOffset() const override { - return Segment.SectionOffset; - } const WasmSegment &Segment; const OutputSegment *OutputSeg = nullptr; @@ -137,6 +137,9 @@ StringRef getName() const override { return Function->Name; } StringRef getComdat() const override { return Function->Comdat; } + uint32_t getInputSectionOffset() const override { + return Function->CodeSectionOffset; + } uint32_t getOutputIndex() const { return OutputIndex.getValue(); } bool hasOutputIndex() const { return OutputIndex.hasValue(); } void setOutputIndex(uint32_t Index); @@ -151,9 +154,6 @@ return File->CodeSection->Content.slice(getInputSectionOffset(), Function->Size); } - uint32_t getInputSectionOffset() const override { - return Function->CodeSectionOffset; - } const WasmFunction *Function; llvm::Optional OutputIndex; Index: wasm/InputChunks.cpp =================================================================== --- wasm/InputChunks.cpp +++ wasm/InputChunks.cpp @@ -33,16 +33,6 @@ return OutputSeg->StartVA + OutputSegmentOffset + Offset; } -void InputChunk::copyRelocations(const WasmSection &Section) { - if (Section.Relocations.empty()) - return; - size_t Start = getInputSectionOffset(); - size_t Size = getSize(); - for (const WasmRelocation &R : Section.Relocations) - if (R.Offset >= Start && R.Offset < Start + Size) - Relocations.push_back(R); -} - // Copy this input chunk to an mmap'ed output file and apply relocations. void InputChunk::writeTo(uint8_t *Buf) const { // Copy contents Index: wasm/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ wasm/InputFiles.cpp @@ -191,6 +191,39 @@ return cast(Symbols[Index]); } +template +static void setRelocs(const std::vector &Chunks, + const WasmSection *Section) { + if (!Section) + return; + + ArrayRef Relocs = Section->Relocations; + assert(std::is_sorted( + Relocs.begin(), Relocs.end(), + [](const WasmRelocation &R1, const WasmRelocation &R2) { + return R1.Offset < R2.Offset; + })); + assert(std::is_sorted( + Chunks.begin(), Chunks.end(), + [](InputChunk *C1, InputChunk *C2) { + return C1->getInputSectionOffset() < C2->getInputSectionOffset(); + })); + + auto RelocsNext = Relocs.begin(); + auto RelocsEnd = Relocs.end(); + auto RelocLess = [](const WasmRelocation &R, uint32_t Val) { + return R.Offset < Val; + }; + for (InputChunk *C : Chunks) { + auto RelocsStart = std::lower_bound(RelocsNext, RelocsEnd, + C->getInputSectionOffset(), RelocLess); + RelocsNext = std::lower_bound(RelocsStart, RelocsEnd, + C->getInputSectionOffset() + C->getSize(), + RelocLess); + C->setRelocations(ArrayRef(RelocsStart, RelocsNext)); + } +} + void ObjFile::initializeSymbols() { Symbols.reserve(WasmObj->getNumberOfSymbols()); @@ -204,11 +237,9 @@ for (const auto &C : WasmObj->comdats()) Symtab->addComdat(C, this); - for (const WasmSegment &S : WasmObj->dataSegments()) { - InputSegment *Seg = make(S, this); - Seg->copyRelocations(*DataSection); - Segments.emplace_back(Seg); - } + for (const WasmSegment &S : WasmObj->dataSegments()) + Segments.emplace_back(make(S, this)); + setRelocs(Segments, DataSection); for (const WasmGlobal &G : WasmObj->globals()) Globals.emplace_back(make(G)); @@ -216,10 +247,9 @@ for (size_t I = 0; I < Funcs.size(); ++I) { const WasmFunction &Func = Funcs[I]; const WasmSignature &Sig = Types[FuncTypes[I]]; - InputFunction *F = make(Sig, &Func, this); - F->copyRelocations(*CodeSection); - Functions.emplace_back(F); + Functions.emplace_back(make(Sig, &Func, this)); } + setRelocs(Functions, CodeSection); // Populate `Symbols` based on the WasmSymbols in the object for (const SymbolRef &Sym : WasmObj->symbols()) {