diff options
-rw-r--r-- | lld/wasm/Driver.cpp | 5 | ||||
-rw-r--r-- | lld/wasm/InputChunks.h | 18 | ||||
-rw-r--r-- | lld/wasm/SymbolTable.cpp | 9 | ||||
-rw-r--r-- | lld/wasm/SymbolTable.h | 7 | ||||
-rw-r--r-- | lld/wasm/Symbols.h | 5 | ||||
-rw-r--r-- | lld/wasm/Writer.cpp | 37 |
6 files changed, 45 insertions, 36 deletions
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index a97026d4df8..c3f53e5b136 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -9,6 +9,7 @@ #include "lld/Common/Driver.h" #include "Config.h" +#include "InputChunks.h" #include "InputGlobal.h" #include "MarkLive.h" #include "SymbolTable.h" @@ -295,9 +296,11 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { StackPointer->Live = true; static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT}; + // Add synthetic symbols before any others WasmSym::CallCtors = Symtab->addSyntheticFunction( - "__wasm_call_ctors", &NullSignature, WASM_SYMBOL_VISIBILITY_HIDDEN); + "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN, + make<SyntheticFunction>(NullSignature, "__wasm_call_ctors")); WasmSym::StackPointer = Symtab->addSyntheticGlobal( "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer); WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base", 0); diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h index 72203095918..2ef4d4005dd 100644 --- a/lld/wasm/InputChunks.h +++ b/lld/wasm/InputChunks.h @@ -44,7 +44,7 @@ class OutputSegment; class InputChunk { public: - enum Kind { DataSegment, Function }; + enum Kind { DataSegment, Function, SyntheticFunction }; Kind kind() const { return SectionKind; } @@ -120,7 +120,8 @@ public: : InputChunk(F, InputChunk::Function), Signature(S), Function(Func) {} static bool classof(const InputChunk *C) { - return C->kind() == InputChunk::Function; + return C->kind() == InputChunk::Function || + C->kind() == InputChunk::SyntheticFunction; } StringRef getName() const override { return Function->Name; } @@ -150,13 +151,20 @@ protected: class SyntheticFunction : public InputFunction { public: - SyntheticFunction(const WasmSignature &S, ArrayRef<uint8_t> Body, - StringRef Name) - : InputFunction(S, nullptr, nullptr), Name(Name), Body(Body) {} + SyntheticFunction(const WasmSignature &S, StringRef Name) + : InputFunction(S, nullptr, nullptr), Name(Name) { + SectionKind = InputChunk::SyntheticFunction; + } + + static bool classof(const InputChunk *C) { + return C->kind() == InputChunk::SyntheticFunction; + } StringRef getName() const override { return Name; } StringRef getComdat() const override { return StringRef(); } + void setBody(ArrayRef<uint8_t> Body_) { Body = Body_; } + protected: ArrayRef<uint8_t> data() const override { return Body; } diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp index 6375358b49e..a722472c291 100644 --- a/lld/wasm/SymbolTable.cpp +++ b/lld/wasm/SymbolTable.cpp @@ -119,11 +119,13 @@ static void checkDataType(const Symbol *Existing, const InputFile *File) { } DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name, - const WasmSignature *Type, - uint32_t Flags) { + uint32_t Flags, + InputFunction *Function) { DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n"); assert(!find(Name)); - return replaceSymbol<DefinedFunction>(insert(Name).first, Name, Flags, Type); + SyntheticFunctions.emplace_back(Function); + return replaceSymbol<DefinedFunction>(insert(Name).first, Name, Flags, + nullptr, Function); } DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name, @@ -137,6 +139,7 @@ DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags, InputGlobal *Global) { DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global << "\n"); assert(!find(Name)); + SyntheticGlobals.emplace_back(Global); return replaceSymbol<DefinedGlobal>(insert(Name).first, Name, Flags, nullptr, Global); } diff --git a/lld/wasm/SymbolTable.h b/lld/wasm/SymbolTable.h index a4d1851d4fc..17c5a3bb699 100644 --- a/lld/wasm/SymbolTable.h +++ b/lld/wasm/SymbolTable.h @@ -41,6 +41,8 @@ public: void addFile(InputFile *File); std::vector<ObjFile *> ObjectFiles; + std::vector<InputFunction *> SyntheticFunctions; + std::vector<InputGlobal *> SyntheticGlobals; void reportRemainingUndefines(); @@ -68,9 +70,8 @@ public: DefinedData *addSyntheticDataSymbol(StringRef Name, uint32_t Flags); DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags, InputGlobal *Global); - DefinedFunction *addSyntheticFunction(StringRef Name, - const WasmSignature *Type, - uint32_t Flags); + DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags, + InputFunction *Function); private: std::pair<Symbol *, bool> insert(StringRef Name); diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h index 103a301066a..76a7417780e 100644 --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -134,14 +134,9 @@ protected: class DefinedFunction : public FunctionSymbol { public: - // Primary constructor for file-defined functions. DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F, InputFunction *Function); - // Second constructor used when creating synthetic functions. - DefinedFunction(StringRef Name, uint32_t Flags, const WasmSignature *Type) - : FunctionSymbol(Name, DefinedFunctionKind, Flags, nullptr, Type) {} - static bool classof(const Symbol *S) { return S->kind() == DefinedFunctionKind; } diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index 5e645b66a48..488798fa18d 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -750,16 +750,24 @@ void Writer::calculateTypes() { void Writer::assignIndexes() { uint32_t FunctionIndex = NumImportedFunctions + InputFunctions.size(); + auto AddDefinedFunction = [&](InputFunction *Func) { + if (!Func->Live) + return; + InputFunctions.emplace_back(Func); + Func->setOutputIndex(FunctionIndex++); + }; + for (ObjFile *File : Symtab->ObjectFiles) { DEBUG(dbgs() << "Functions: " << File->getName() << "\n"); - for (InputFunction *Func : File->Functions) { - if (!Func->Live) - continue; - InputFunctions.emplace_back(Func); - Func->setOutputIndex(FunctionIndex++); - } + for (InputFunction *Func : File->Functions) + AddDefinedFunction(Func); } + // TODO Move synthetic functions to come before (so __wasm_call_ctors can be + // compiled immediately by the browser). Will reorder tests. + for (InputFunction *Func : Symtab->SyntheticFunctions) + AddDefinedFunction(Func); + uint32_t TableIndex = kInitialTableOffset; auto HandleRelocs = [&](InputChunk *Chunk) { if (!Chunk->Live) @@ -806,8 +814,8 @@ void Writer::assignIndexes() { } }; - if (WasmSym::StackPointer) - AddDefinedGlobal(WasmSym::StackPointer->Global); + for (InputGlobal *Global : Symtab->SyntheticGlobals) + AddDefinedGlobal(Global); for (ObjFile *File : Symtab->ObjectFiles) { DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); @@ -852,8 +860,6 @@ 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 = NumImportedFunctions + InputFunctions.size(); - // First write the body's contents to a string. std::string BodyContent; { @@ -874,15 +880,8 @@ void Writer::createCtorFunction() { OS << BodyContent; } - const WasmSignature *Sig = WasmSym::CallCtors->getFunctionType(); - SyntheticFunction *F = - make<SyntheticFunction>(*Sig, toArrayRef(Saver.save(FunctionBody)), - WasmSym::CallCtors->getName()); - - F->setOutputIndex(FunctionIndex); - F->Live = true; - WasmSym::CallCtors->Function = F; - InputFunctions.emplace_back(F); + ArrayRef<uint8_t> Body = toArrayRef(Saver.save(FunctionBody)); + cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body); } // Populate InitFunctions vector with init functions from all input objects. |