aboutsummaryrefslogtreecommitdiff
path: root/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'wasm')
-rw-r--r--wasm/InputFiles.cpp9
-rw-r--r--wasm/InputSegment.h2
-rw-r--r--wasm/OutputSections.cpp57
-rw-r--r--wasm/OutputSections.h18
-rw-r--r--wasm/OutputSegment.h2
-rw-r--r--wasm/SymbolTable.cpp10
-rw-r--r--wasm/SymbolTable.h1
-rw-r--r--wasm/Writer.cpp43
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;
}