summaryrefslogtreecommitdiffstats
path: root/lld/wasm/Writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/wasm/Writer.cpp')
-rw-r--r--lld/wasm/Writer.cpp373
1 files changed, 208 insertions, 165 deletions
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index b176e448080..88813828dc7 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -10,6 +10,7 @@
#include "Writer.h"
#include "Config.h"
#include "InputChunks.h"
+#include "InputGlobal.h"
#include "OutputSections.h"
#include "OutputSegment.h"
#include "SymbolTable.h"
@@ -18,6 +19,7 @@
#include "lld/Common/Memory.h"
#include "lld/Common/Threads.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
@@ -62,10 +64,11 @@ struct WasmSignatureDenseMapInfo {
}
};
-// A Wasm export to be written into the export section.
-struct WasmExportEntry {
+// An init entry to be written to either the synthetic init func or the
+// linking metadata.
+struct WasmInitEntry {
const Symbol *Sym;
- StringRef FieldName; // may not match the Symbol name
+ uint32_t Priority;
};
// The writer writes a SymbolTable result to a file.
@@ -78,11 +81,13 @@ private:
uint32_t lookupType(const WasmSignature &Sig);
uint32_t registerType(const WasmSignature &Sig);
+
void createCtorFunction();
void calculateInitFunctions();
void assignIndexes();
void calculateImports();
void calculateExports();
+ void assignSymtab();
void calculateTypes();
void createOutputSegments();
void layoutMemory();
@@ -118,13 +123,16 @@ private:
std::vector<const WasmSignature *> Types;
DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices;
- std::vector<const FunctionSymbol *> ImportedFunctions;
- std::vector<const DataSymbol *> ImportedGlobals;
- std::vector<WasmExportEntry> ExportedSymbols;
- std::vector<const DefinedData *> DefinedDataSymbols;
+ std::vector<const Symbol *> ImportedSymbols;
+ unsigned NumImportedFunctions = 0;
+ unsigned NumImportedGlobals = 0;
+ std::vector<Symbol *> ExportedSymbols;
+ std::vector<const DefinedData *> DefinedFakeGlobals;
+ std::vector<InputGlobal *> InputGlobals;
std::vector<InputFunction *> InputFunctions;
std::vector<const FunctionSymbol *> IndirectFunctions;
- std::vector<WasmInitFunc> InitFunctions;
+ std::vector<const Symbol *> SymtabEntries;
+ std::vector<WasmInitEntry> InitFunctions;
// Elements that are used to construct the final output
std::string Header;
@@ -150,7 +158,7 @@ static void debugPrint(const char *fmt, ...) {
}
void Writer::createImportSection() {
- uint32_t NumImports = ImportedFunctions.size() + ImportedGlobals.size();
+ uint32_t NumImports = ImportedSymbols.size();
if (Config->ImportMemory)
++NumImports;
@@ -162,15 +170,6 @@ void Writer::createImportSection() {
writeUleb128(OS, NumImports, "import count");
- for (const FunctionSymbol *Sym : ImportedFunctions) {
- WasmImport Import;
- Import.Module = "env";
- Import.Field = Sym->getName();
- Import.Kind = WASM_EXTERNAL_FUNCTION;
- Import.SigIndex = lookupType(*Sym->getFunctionType());
- writeImport(OS, Import);
- }
-
if (Config->ImportMemory) {
WasmImport Import;
Import.Module = "env";
@@ -181,13 +180,18 @@ void Writer::createImportSection() {
writeImport(OS, Import);
}
- for (const Symbol *Sym : ImportedGlobals) {
+ for (const Symbol *Sym : ImportedSymbols) {
WasmImport Import;
Import.Module = "env";
Import.Field = Sym->getName();
- Import.Kind = WASM_EXTERNAL_GLOBAL;
- Import.Global.Mutable = false;
- Import.Global.Type = WASM_TYPE_I32;
+ if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
+ Import.Kind = WASM_EXTERNAL_FUNCTION;
+ Import.SigIndex = lookupType(*FunctionSym->getFunctionType());
+ } else {
+ auto *GlobalSym = cast<GlobalSymbol>(Sym);
+ Import.Kind = WASM_EXTERNAL_GLOBAL;
+ Import.Global = *GlobalSym->getGlobalType();
+ }
writeImport(OS, Import);
}
}
@@ -225,17 +229,19 @@ void Writer::createMemorySection() {
}
void Writer::createGlobalSection() {
- if (DefinedDataSymbols.empty())
+ unsigned NumGlobals = InputGlobals.size() + DefinedFakeGlobals.size();
+ if (NumGlobals == 0)
return;
SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL);
raw_ostream &OS = Section->getStream();
- writeUleb128(OS, DefinedDataSymbols.size(), "global count");
- for (const DefinedData *Sym : DefinedDataSymbols) {
+ writeUleb128(OS, NumGlobals, "global count");
+ for (const InputGlobal *G : InputGlobals)
+ writeGlobal(OS, G->Global);
+ for (const DefinedData *Sym : DefinedFakeGlobals) {
WasmGlobal Global;
- Global.Type.Type = WASM_TYPE_I32;
- Global.Type.Mutable = Sym == WasmSym::StackPointer;
+ Global.Type = {WASM_TYPE_I32, false};
Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
Global.InitExpr.Value.Int32 = Sym->getVirtualAddress();
writeGlobal(OS, Global);
@@ -283,15 +289,23 @@ void Writer::createExportSection() {
writeExport(OS, MemoryExport);
}
- for (const WasmExportEntry &E : ExportedSymbols) {
- DEBUG(dbgs() << "Export: " << E.Sym->getName() << "\n");
+ unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size();
+ for (const Symbol *Sym : ExportedSymbols) {
+ DEBUG(dbgs() << "Export: " << Sym->getName() << "\n");
WasmExport Export;
- Export.Name = E.FieldName;
- Export.Index = E.Sym->getOutputIndex();
- if (isa<FunctionSymbol>(E.Sym))
+ Export.Name = Sym->getName();
+ if (isa<FunctionSymbol>(Sym)) {
+ Export.Index = Sym->getOutputIndex();
Export.Kind = WASM_EXTERNAL_FUNCTION;
- else
+ } else if (isa<GlobalSymbol>(Sym)) {
+ Export.Index = Sym->getOutputIndex();
Export.Kind = WASM_EXTERNAL_GLOBAL;
+ } else if (isa<DataSymbol>(Sym)) {
+ Export.Index = FakeGlobalIndex++;
+ Export.Kind = WASM_EXTERNAL_GLOBAL;
+ } else {
+ llvm_unreachable("unexpected symbol type");
+ }
writeExport(OS, Export);
}
}
@@ -383,28 +397,39 @@ void Writer::createLinkingSection() {
if (!Config->Relocatable)
return;
- std::vector<std::pair<StringRef, uint32_t>> SymbolInfo;
- auto addSymInfo = [&](const Symbol *Sym, StringRef ExternalName) {
- uint32_t Flags =
- (Sym->isLocal() ? WASM_SYMBOL_BINDING_LOCAL :
- Sym->isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0) |
- (Sym->isHidden() ? WASM_SYMBOL_VISIBILITY_HIDDEN : 0);
- if (Flags)
- SymbolInfo.emplace_back(ExternalName, Flags);
- };
- // (Imports can't have internal linkage, their names don't need to be budged.)
- for (const Symbol *Sym : ImportedFunctions)
- addSymInfo(Sym, Sym->getName());
- for (const Symbol *Sym : ImportedGlobals)
- addSymInfo(Sym, Sym->getName());
- for (const WasmExportEntry &E : ExportedSymbols)
- addSymInfo(E.Sym, E.FieldName);
- if (!SymbolInfo.empty()) {
- SubSection SubSection(WASM_SYMBOL_INFO);
- writeUleb128(SubSection.getStream(), SymbolInfo.size(), "num sym info");
- for (auto Pair: SymbolInfo) {
- writeStr(SubSection.getStream(), Pair.first, "sym name");
- writeUleb128(SubSection.getStream(), Pair.second, "sym flags");
+ if (!SymtabEntries.empty()) {
+ SubSection SubSection(WASM_SYMBOL_TABLE);
+ writeUleb128(SubSection.getStream(), SymtabEntries.size(), "num symbols");
+ for (const Symbol *Sym : SymtabEntries) {
+ assert(Sym->isDefined() || Sym->isUndefined());
+ WasmSymbolType Kind = Sym->getWasmType();
+ uint32_t Flags = Sym->isLocal() ? WASM_SYMBOL_BINDING_LOCAL : 0;
+ if (Sym->isWeak())
+ Flags |= WASM_SYMBOL_BINDING_WEAK;
+ if (Sym->isHidden())
+ Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
+ if (Sym->isUndefined())
+ Flags |= WASM_SYMBOL_UNDEFINED;
+ writeUleb128(SubSection.getStream(), Kind, "sym kind");
+ writeUleb128(SubSection.getStream(), Flags, "sym flags");
+ switch (Kind) {
+ case llvm::wasm::WASM_SYMBOL_TYPE_FUNCTION:
+ case llvm::wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ writeUleb128(SubSection.getStream(), Sym->getOutputIndex(), "index");
+ if (Sym->isDefined())
+ writeStr(SubSection.getStream(), Sym->getName(), "sym name");
+ break;
+ case llvm::wasm::WASM_SYMBOL_TYPE_DATA:
+ writeStr(SubSection.getStream(), Sym->getName(), "sym name");
+ if (auto *DataSym = dyn_cast<DefinedData>(Sym)) {
+ writeUleb128(SubSection.getStream(), DataSym->getOutputSegmentIndex(),
+ "index");
+ writeUleb128(SubSection.getStream(),
+ DataSym->getOutputSegmentOffset(), "data offset");
+ writeUleb128(SubSection.getStream(), DataSym->getSize(), "data size");
+ }
+ break;
+ }
}
SubSection.finalizeContents();
SubSection.writeToStream(OS);
@@ -426,9 +451,10 @@ void Writer::createLinkingSection() {
SubSection SubSection(WASM_INIT_FUNCS);
writeUleb128(SubSection.getStream(), InitFunctions.size(),
"num init functions");
- for (const WasmInitFunc &F : InitFunctions) {
+ for (const WasmInitEntry &F : InitFunctions) {
writeUleb128(SubSection.getStream(), F.Priority, "priority");
- writeUleb128(SubSection.getStream(), F.FunctionIndex, "function index");
+ writeUleb128(SubSection.getStream(), F.Sym->getOutputSymbolIndex(),
+ "function index");
}
SubSection.finalizeContents();
SubSection.writeToStream(OS);
@@ -475,7 +501,7 @@ void Writer::createLinkingSection() {
// Create the custom "name" section containing debug symbol names.
void Writer::createNameSection() {
- unsigned NumNames = ImportedFunctions.size();
+ unsigned NumNames = NumImportedFunctions;
for (const InputFunction *F : InputFunctions)
if (!F->getName().empty())
++NumNames;
@@ -489,10 +515,12 @@ void Writer::createNameSection() {
raw_ostream &OS = FunctionSubsection.getStream();
writeUleb128(OS, NumNames, "name count");
- // Names must appear in function index order. As it happens ImportedFunctions
- // and InputFunctions are numbers in order with imported functions coming
+ // Names must appear in function index order. As it happens ImportedSymbols
+ // and InputFunctions are numbered in order with imported functions coming
// first.
- for (const Symbol *S : ImportedFunctions) {
+ for (const Symbol *S : ImportedSymbols) {
+ if (!isa<FunctionSymbol>(S))
+ continue;
writeUleb128(OS, S->getOutputIndex(), "import index");
writeStr(OS, S->getName(), "symbol name");
}
@@ -562,8 +590,9 @@ void Writer::layoutMemory() {
debugPrint("mem: stack size = %d\n", Config->ZStackSize);
debugPrint("mem: stack base = %d\n", MemoryPtr);
MemoryPtr += Config->ZStackSize;
- WasmSym::StackPointer->setVirtualAddress(MemoryPtr);
+ WasmSym::StackPointer->Global->Global.InitExpr.Value.Int32 = MemoryPtr;
debugPrint("mem: stack top = %d\n", MemoryPtr);
+
// Set `__heap_base` to directly follow the end of the stack. We don't
// allocate any heap memory up front, but instead really on the malloc/brk
// implementation growing the memory at runtime.
@@ -614,69 +643,85 @@ void Writer::createSections() {
void Writer::calculateImports() {
for (Symbol *Sym : Symtab->getSymbols()) {
- if (!Sym->isUndefined() || (Sym->isWeak() && !Config->Relocatable))
+ if (!Sym->isUndefined())
+ continue;
+ if (isa<DataSymbol>(Sym))
+ continue;
+ if (Sym->isWeak() && !Config->Relocatable)
continue;
- if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {
- F->setOutputIndex(ImportedFunctions.size());
- ImportedFunctions.push_back(F);
- } else if (auto *G = dyn_cast<DataSymbol>(Sym)) {
- G->setOutputIndex(ImportedGlobals.size());
- ImportedGlobals.push_back(G);
- }
+ DEBUG(dbgs() << "import: " << Sym->getName() << "\n");
+ Sym->setOutputIndex(ImportedSymbols.size());
+ ImportedSymbols.emplace_back(Sym);
+ if (isa<FunctionSymbol>(Sym))
+ ++NumImportedFunctions;
+ else
+ ++NumImportedGlobals;
}
}
void Writer::calculateExports() {
- bool ExportHidden = Config->Relocatable;
- StringSet<> UsedNames;
-
- auto BudgeLocalName = [&](const Symbol *Sym) {
- StringRef SymName = Sym->getName();
- // We can't budge non-local names.
- if (!Sym->isLocal())
- return SymName;
- // We must budge local names that have a collision with a symbol that we
- // haven't yet processed.
- if (!Symtab->find(SymName) && UsedNames.insert(SymName).second)
- return SymName;
- for (unsigned I = 1; ; ++I) {
- std::string NameBuf = (SymName + "." + Twine(I)).str();
- if (!UsedNames.count(NameBuf)) {
- StringRef Name = Saver.save(NameBuf);
- UsedNames.insert(Name); // Insert must use safe StringRef from save()
- return Name;
- }
+ if (Config->Relocatable)
+ return;
+
+ auto ExportSym = [&](Symbol *Sym) {
+ if (!Sym->isDefined())
+ return;
+ if (Sym->isHidden() || Sym->isLocal())
+ return;
+ if (!Sym->isLive())
+ return;
+
+ DEBUG(dbgs() << "exporting sym: " << Sym->getName() << "\n");
+
+ if (auto *D = dyn_cast<DefinedData>(Sym)) {
+ // TODO Remove this check here; for non-relocatable output we actually
+ // used only to create fake-global exports for the synthetic symbols. Fix
+ // this in a future commit
+ if (Sym != WasmSym::DataEnd && Sym != WasmSym::HeapBase)
+ return;
+ DefinedFakeGlobals.emplace_back(D);
}
+ ExportedSymbols.emplace_back(Sym);
};
- if (WasmSym::CallCtors && (!WasmSym::CallCtors->isHidden() || ExportHidden))
- ExportedSymbols.emplace_back(
- WasmExportEntry{WasmSym::CallCtors, WasmSym::CallCtors->getName()});
+ // TODO The two loops below should be replaced with this single loop, with
+ // ExportSym inlined:
+ // for (Symbol *Sym : Symtab->getSymbols())
+ // ExportSym(Sym);
+ // Making that change would reorder the output though, so it should be done as
+ // a separate commit.
+
+ for (ObjFile *File : Symtab->ObjectFiles)
+ for (Symbol *Sym : File->getSymbols())
+ if (File == Sym->getFile())
+ ExportSym(Sym);
+ for (Symbol *Sym : Symtab->getSymbols())
+ if (Sym->getFile() == nullptr)
+ ExportSym(Sym);
+}
+
+void Writer::assignSymtab() {
+ if (!Config->Relocatable)
+ return;
+
+ unsigned SymbolIndex = SymtabEntries.size();
for (ObjFile *File : Symtab->ObjectFiles) {
+ DEBUG(dbgs() << "Symtab entries: " << File->getName() << "\n");
for (Symbol *Sym : File->getSymbols()) {
- if (!Sym->isDefined() || File != Sym->getFile())
- continue;
- if (!isa<FunctionSymbol>(Sym))
- continue;
- if (!Sym->getChunk()->Live)
+ if (Sym->getFile() != File)
continue;
-
- if ((Sym->isHidden() || Sym->isLocal()) && !ExportHidden)
- continue;
- ExportedSymbols.emplace_back(WasmExportEntry{Sym, BudgeLocalName(Sym)});
+ if (!Sym->isLive())
+ return;
+ Sym->setOutputSymbolIndex(SymbolIndex++);
+ SymtabEntries.emplace_back(Sym);
}
}
- for (const Symbol *Sym : DefinedDataSymbols) {
- // Can't export the SP right now because its mutable, and mutuable globals
- // are yet supported in the official binary format.
- // TODO(sbc): Remove this if/when the "mutable global" proposal is accepted.
- if (Sym == WasmSym::StackPointer)
- continue;
- ExportedSymbols.emplace_back(WasmExportEntry{Sym, BudgeLocalName(Sym)});
- }
+ // For the moment, relocatable output doesn't contain any synthetic functions,
+ // so no need to look through the Symtab for symbols not referenced by
+ // Symtab->ObjectFiles.
}
uint32_t Writer::lookupType(const WasmSignature &Sig) {
@@ -710,45 +755,16 @@ void Writer::calculateTypes() {
File->TypeMap[I] = registerType(Types[I]);
}
- for (const FunctionSymbol *Sym : ImportedFunctions)
- registerType(*Sym->getFunctionType());
+ for (const Symbol *Sym : ImportedSymbols)
+ if (auto *F = dyn_cast<FunctionSymbol>(Sym))
+ registerType(*F->getFunctionType());
for (const InputFunction *F : InputFunctions)
registerType(F->Signature);
}
void Writer::assignIndexes() {
- uint32_t GlobalIndex = ImportedGlobals.size() + DefinedDataSymbols.size();
- uint32_t FunctionIndex = ImportedFunctions.size() + InputFunctions.size();
-
- auto AddDefinedData = [&](DefinedData *Sym) {
- if (Sym) {
- DefinedDataSymbols.emplace_back(Sym);
- Sym->setOutputIndex(GlobalIndex++);
- }
- };
- AddDefinedData(WasmSym::StackPointer);
- AddDefinedData(WasmSym::HeapBase);
- AddDefinedData(WasmSym::DataEnd);
-
- if (Config->Relocatable)
- DefinedDataSymbols.reserve(Symtab->getSymbols().size());
-
- uint32_t TableIndex = kInitialTableOffset;
-
- if (Config->Relocatable) {
- for (ObjFile *File : Symtab->ObjectFiles) {
- DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
- for (Symbol *Sym : File->getSymbols()) {
- // Create wasm globals for data symbols defined in this file
- if (File != Sym->getFile())
- continue;
- if (auto *G = dyn_cast<DefinedData>(Sym))
- AddDefinedData(G);
- }
- }
- }
-
+ uint32_t FunctionIndex = NumImportedFunctions + InputFunctions.size();
for (ObjFile *File : Symtab->ObjectFiles) {
DEBUG(dbgs() << "Functions: " << File->getName() << "\n");
for (InputFunction *Func : File->Functions) {
@@ -759,12 +775,13 @@ void Writer::assignIndexes() {
}
}
+ uint32_t TableIndex = kInitialTableOffset;
auto HandleRelocs = [&](InputChunk *Chunk) {
if (!Chunk->Live)
return;
ObjFile *File = Chunk->File;
ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
- for (const WasmRelocation& Reloc : Chunk->getRelocations()) {
+ for (const WasmRelocation &Reloc : Chunk->getRelocations()) {
if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 ||
Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB) {
FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
@@ -773,20 +790,45 @@ void Writer::assignIndexes() {
Sym->setTableIndex(TableIndex++);
IndirectFunctions.emplace_back(Sym);
} else if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
+ // Mark target type as live
File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
File->TypeIsUsed[Reloc.Index] = true;
+ } else if (Reloc.Type == R_WEBASSEMBLY_GLOBAL_INDEX_LEB) {
+ // Mark target global as live
+ GlobalSymbol *Sym = File->getGlobalSymbol(Reloc.Index);
+ if (auto *G = dyn_cast<DefinedGlobal>(Sym)) {
+ DEBUG(dbgs() << "marking global live: " << Sym->getName() << "\n");
+ G->Global->Live = true;
+ }
}
}
};
for (ObjFile *File : Symtab->ObjectFiles) {
DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n");
-
- for (InputChunk* Chunk : File->Functions)
+ for (InputChunk *Chunk : File->Functions)
HandleRelocs(Chunk);
- for (InputChunk* Chunk : File->Segments)
+ for (InputChunk *Chunk : File->Segments)
HandleRelocs(Chunk);
}
+
+ uint32_t GlobalIndex = NumImportedGlobals + InputGlobals.size();
+ auto AddDefinedGlobal = [&](InputGlobal *Global) {
+ if (Global->Live) {
+ DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n");
+ Global->setOutputIndex(GlobalIndex++);
+ InputGlobals.push_back(Global);
+ }
+ };
+
+ if (WasmSym::StackPointer)
+ AddDefinedGlobal(WasmSym::StackPointer->Global);
+
+ for (ObjFile *File : Symtab->ObjectFiles) {
+ DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
+ for (InputGlobal *Global : File->Globals)
+ AddDefinedGlobal(Global);
+ }
}
static StringRef getOutputDataSegmentName(StringRef Name) {
@@ -814,7 +856,7 @@ void Writer::createOutputSegments() {
OutputSegment *&S = SegmentMap[Name];
if (S == nullptr) {
DEBUG(dbgs() << "new segment: " << Name << "\n");
- S = make<OutputSegment>(Name);
+ S = make<OutputSegment>(Name, Segments.size());
Segments.push_back(S);
}
S->addInputSegment(Segment);
@@ -829,18 +871,18 @@ static const int OPCODE_END = 0xb;
// Create synthetic "__wasm_call_ctors" function based on ctor functions
// in input object.
void Writer::createCtorFunction() {
- uint32_t FunctionIndex = ImportedFunctions.size() + InputFunctions.size();
+ uint32_t FunctionIndex = NumImportedFunctions + InputFunctions.size();
WasmSym::CallCtors->setOutputIndex(FunctionIndex);
// First write the body bytes to a string.
std::string FunctionBody;
- static WasmSignature Signature = {{}, WASM_TYPE_NORESULT};
+ const WasmSignature *Signature = WasmSym::CallCtors->getFunctionType();
{
raw_string_ostream OS(FunctionBody);
writeUleb128(OS, 0, "num locals");
- for (const WasmInitFunc &F : InitFunctions) {
+ for (const WasmInitEntry &F : InitFunctions) {
writeU8(OS, OPCODE_CALL, "CALL");
- writeUleb128(OS, F.FunctionIndex, "function index");
+ writeUleb128(OS, F.Sym->getOutputIndex(), "function index");
}
writeU8(OS, OPCODE_END, "END");
}
@@ -853,9 +895,11 @@ void Writer::createCtorFunction() {
ArrayRef<uint8_t> BodyArray(
reinterpret_cast<const uint8_t *>(CtorFunctionBody.data()),
CtorFunctionBody.size());
- SyntheticFunction *F = make<SyntheticFunction>(Signature, BodyArray,
+ SyntheticFunction *F = make<SyntheticFunction>(*Signature, BodyArray,
WasmSym::CallCtors->getName());
F->setOutputIndex(FunctionIndex);
+ F->Live = true;
+ WasmSym::CallCtors->Function = F;
InputFunctions.emplace_back(F);
}
@@ -867,13 +911,13 @@ void Writer::calculateInitFunctions() {
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)});
+ InitFunctions.emplace_back(
+ WasmInitEntry{File->getFunctionSymbol(F.Symbol), F.Priority});
}
// Sort in order of priority (lowest first) so that they are called
// in the correct order.
std::stable_sort(InitFunctions.begin(), InitFunctions.end(),
- [](const WasmInitFunc &L, const WasmInitFunc &R) {
+ [](const WasmInitEntry &L, const WasmInitEntry &R) {
return L.Priority < R.Priority;
});
}
@@ -883,29 +927,28 @@ void Writer::run() {
calculateImports();
log("-- assignIndexes");
assignIndexes();
- log("-- calculateExports");
- calculateExports();
log("-- calculateInitFunctions");
calculateInitFunctions();
if (!Config->Relocatable)
createCtorFunction();
log("-- calculateTypes");
calculateTypes();
+ log("-- layoutMemory");
+ layoutMemory();
+ log("-- calculateExports");
+ calculateExports();
+ log("-- assignSymtab");
+ assignSymtab();
if (errorHandler().Verbose) {
log("Defined Functions: " + Twine(InputFunctions.size()));
- log("Defined Data Syms: " + Twine(DefinedDataSymbols.size()));
- log("Function Imports : " + Twine(ImportedFunctions.size()));
- log("Global Imports : " + Twine(ImportedGlobals.size()));
- log("Total Imports : " +
- Twine(ImportedFunctions.size() + ImportedGlobals.size()));
+ log("Defined Globals : " + Twine(InputGlobals.size()));
+ log("Function Imports : " + Twine(NumImportedFunctions));
+ log("Global Imports : " + Twine(NumImportedGlobals));
for (ObjFile *File : Symtab->ObjectFiles)
File->dumpInfo();
}
- log("-- layoutMemory");
- layoutMemory();
-
createHeader();
log("-- createSections");
createSections();
OpenPOWER on IntegriCloud