forked from OSchip/llvm-project
[WebAssembly] Rename GlobalSymbol types. NFC.
Purely a rename in preparation for adding new global symbol type. We want to use GlobalSymbol to represent real wasm globals and DataSymbol for pointers to things in linear memory (what ELF would call STT_OBJECT). This reduces the size the patch to add the explicit symbol table which is coming soon! Differential Revision: https://reviews.llvm.org/D43476 llvm-svn: 325645
This commit is contained in:
parent
8357371861
commit
00245539b6
|
@ -7,5 +7,5 @@ target triple = "wasm32-unknown-unknown-wasm"
|
||||||
@ret32 = extern_weak global i32, align 4
|
@ret32 = extern_weak global i32, align 4
|
||||||
|
|
||||||
; CHECK: error: symbol type mismatch: ret32
|
; CHECK: error: symbol type mismatch: ret32
|
||||||
; CHECK: >>> defined as Global in {{.*}}symbol-type-mismatch.ll.tmp.o
|
; CHECK: >>> defined as Data in {{.*}}symbol-type-mismatch.ll.tmp.o
|
||||||
; CHECK: >>> defined as Function in {{.*}}.ret32.o
|
; CHECK: >>> defined as Function in {{.*}}.ret32.o
|
||||||
|
|
|
@ -301,10 +301,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||||
// Add synthetic symbols before any others
|
// Add synthetic symbols before any others
|
||||||
WasmSym::CallCtors = Symtab->addSyntheticFunction(
|
WasmSym::CallCtors = Symtab->addSyntheticFunction(
|
||||||
"__wasm_call_ctors", &NullSignature, WASM_SYMBOL_VISIBILITY_HIDDEN);
|
"__wasm_call_ctors", &NullSignature, WASM_SYMBOL_VISIBILITY_HIDDEN);
|
||||||
WasmSym::StackPointer = Symtab->addSyntheticGlobal("__stack_pointer");
|
WasmSym::StackPointer = Symtab->addSyntheticDataSymbol("__stack_pointer");
|
||||||
WasmSym::HeapBase = Symtab->addSyntheticGlobal("__heap_base");
|
WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base");
|
||||||
WasmSym::DsoHandle = Symtab->addSyntheticGlobal("__dso_handle");
|
WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol("__dso_handle");
|
||||||
WasmSym::DataEnd = Symtab->addSyntheticGlobal("__data_end");
|
WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end");
|
||||||
|
|
||||||
if (!Config->Entry.empty())
|
if (!Config->Entry.empty())
|
||||||
EntrySym = addUndefinedFunction(Config->Entry, &NullSignature);
|
EntrySym = addUndefinedFunction(Config->Entry, &NullSignature);
|
||||||
|
|
|
@ -44,13 +44,13 @@ Optional<MemoryBufferRef> lld::wasm::readFile(StringRef Path) {
|
||||||
void ObjFile::dumpInfo() const {
|
void ObjFile::dumpInfo() const {
|
||||||
log("info for: " + getName() + "\n" +
|
log("info for: " + getName() + "\n" +
|
||||||
" Total Functions : " + Twine(FunctionSymbols.size()) + "\n" +
|
" Total Functions : " + Twine(FunctionSymbols.size()) + "\n" +
|
||||||
" Total Globals : " + Twine(GlobalSymbols.size()) + "\n" +
|
" Total Data Symbols : " + Twine(DataSymbols.size()) + "\n" +
|
||||||
" Function Imports : " + Twine(NumFunctionImports) + "\n" +
|
" Function Imports : " + Twine(NumFunctionImports) + "\n" +
|
||||||
" Global Imports : " + Twine(NumGlobalImports) + "\n");
|
" Global Imports : " + Twine(NumGlobalImports) + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ObjFile::relocateVirtualAddress(uint32_t GlobalIndex) const {
|
uint32_t ObjFile::relocateVirtualAddress(uint32_t GlobalIndex) const {
|
||||||
if (auto *DG = dyn_cast<DefinedGlobal>(getGlobalSymbol(GlobalIndex)))
|
if (auto *DG = dyn_cast<DefinedData>(getDataSymbol(GlobalIndex)))
|
||||||
return DG->getVirtualAddress();
|
return DG->getVirtualAddress();
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -78,7 +78,7 @@ uint32_t ObjFile::relocateTableIndex(uint32_t Original) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const {
|
uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const {
|
||||||
const Symbol *Sym = getGlobalSymbol(Original);
|
const Symbol *Sym = getDataSymbol(Original);
|
||||||
uint32_t Index = Sym->getOutputIndex();
|
uint32_t Index = Sym->getOutputIndex();
|
||||||
DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original
|
DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original
|
||||||
<< " -> " << Index << "\n");
|
<< " -> " << Index << "\n");
|
||||||
|
@ -215,7 +215,7 @@ void ObjFile::initializeSymbols() {
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionSymbols.resize(NumFunctionImports + WasmObj->functions().size());
|
FunctionSymbols.resize(NumFunctionImports + WasmObj->functions().size());
|
||||||
GlobalSymbols.resize(NumGlobalImports + WasmObj->globals().size());
|
DataSymbols.resize(NumGlobalImports + WasmObj->globals().size());
|
||||||
|
|
||||||
ArrayRef<WasmFunction> Funcs = WasmObj->functions();
|
ArrayRef<WasmFunction> Funcs = WasmObj->functions();
|
||||||
ArrayRef<uint32_t> FuncTypes = WasmObj->functionTypes();
|
ArrayRef<uint32_t> FuncTypes = WasmObj->functionTypes();
|
||||||
|
@ -226,7 +226,7 @@ void ObjFile::initializeSymbols() {
|
||||||
Symtab->addComdat(C, this);
|
Symtab->addComdat(C, this);
|
||||||
|
|
||||||
FunctionSymbols.resize(NumFunctionImports + Funcs.size());
|
FunctionSymbols.resize(NumFunctionImports + Funcs.size());
|
||||||
GlobalSymbols.resize(NumGlobalImports + Globals.size());
|
DataSymbols.resize(NumGlobalImports + Globals.size());
|
||||||
|
|
||||||
for (const WasmSegment &S : WasmObj->dataSegments()) {
|
for (const WasmSegment &S : WasmObj->dataSegments()) {
|
||||||
InputSegment *Seg = make<InputSegment>(S, this);
|
InputSegment *Seg = make<InputSegment>(S, this);
|
||||||
|
@ -242,7 +242,7 @@ void ObjFile::initializeSymbols() {
|
||||||
Functions.emplace_back(F);
|
Functions.emplace_back(F);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate `FunctionSymbols` and `GlobalSymbols` based on the WasmSymbols
|
// Populate `FunctionSymbols` and `DataSymbols` based on the WasmSymbols
|
||||||
// in the object
|
// in the object
|
||||||
for (const SymbolRef &Sym : WasmObj->symbols()) {
|
for (const SymbolRef &Sym : WasmObj->symbols()) {
|
||||||
const WasmSymbol &WasmSym = WasmObj->getWasmSymbol(Sym.getRawDataRefImpl());
|
const WasmSymbol &WasmSym = WasmObj->getWasmSymbol(Sym.getRawDataRefImpl());
|
||||||
|
@ -264,14 +264,14 @@ void ObjFile::initializeSymbols() {
|
||||||
case WasmSymbol::SymbolType::GLOBAL_EXPORT: {
|
case WasmSymbol::SymbolType::GLOBAL_EXPORT: {
|
||||||
InputSegment *Segment = getSegment(WasmSym);
|
InputSegment *Segment = getSegment(WasmSym);
|
||||||
if (!isExcludedByComdat(Segment)) {
|
if (!isExcludedByComdat(Segment)) {
|
||||||
S = createDefinedGlobal(WasmSym, Segment, getGlobalValue(WasmSym));
|
S = createDefinedData(WasmSym, Segment, getGlobalValue(WasmSym));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Segment->Live = false;
|
Segment->Live = false;
|
||||||
LLVM_FALLTHROUGH; // Exclude global, and add the symbol as undefined
|
LLVM_FALLTHROUGH; // Exclude global, and add the symbol as undefined
|
||||||
}
|
}
|
||||||
case WasmSymbol::SymbolType::GLOBAL_IMPORT:
|
case WasmSymbol::SymbolType::GLOBAL_IMPORT:
|
||||||
S = createUndefined(WasmSym, Symbol::Kind::UndefinedGlobalKind);
|
S = createUndefined(WasmSym, Symbol::Kind::UndefinedDataKind);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,19 +281,19 @@ void ObjFile::initializeSymbols() {
|
||||||
if (WasmSym.HasAltIndex)
|
if (WasmSym.HasAltIndex)
|
||||||
FunctionSymbols[WasmSym.AltIndex] = S;
|
FunctionSymbols[WasmSym.AltIndex] = S;
|
||||||
} else {
|
} else {
|
||||||
GlobalSymbols[WasmSym.ElementIndex] = S;
|
DataSymbols[WasmSym.ElementIndex] = S;
|
||||||
if (WasmSym.HasAltIndex)
|
if (WasmSym.HasAltIndex)
|
||||||
GlobalSymbols[WasmSym.AltIndex] = S;
|
DataSymbols[WasmSym.AltIndex] = S;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(for (size_t I = 0; I < FunctionSymbols.size(); ++I)
|
DEBUG(for (size_t I = 0; I < FunctionSymbols.size(); ++I)
|
||||||
assert(FunctionSymbols[I] != nullptr);
|
assert(FunctionSymbols[I] != nullptr);
|
||||||
for (size_t I = 0; I < GlobalSymbols.size(); ++I)
|
for (size_t I = 0; I < DataSymbols.size(); ++I)
|
||||||
assert(GlobalSymbols[I] != nullptr););
|
assert(DataSymbols[I] != nullptr););
|
||||||
|
|
||||||
DEBUG(dbgs() << "Functions : " << FunctionSymbols.size() << "\n");
|
DEBUG(dbgs() << "Functions : " << FunctionSymbols.size() << "\n");
|
||||||
DEBUG(dbgs() << "Globals : " << GlobalSymbols.size() << "\n");
|
DEBUG(dbgs() << "Globals : " << DataSymbols.size() << "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol *ObjFile::createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind,
|
Symbol *ObjFile::createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind,
|
||||||
|
@ -308,11 +308,11 @@ Symbol *ObjFile::createDefinedFunction(const WasmSymbol &Sym,
|
||||||
return Symtab->addDefinedFunction(Sym.Name, Sym.Flags, this, Function);
|
return Symtab->addDefinedFunction(Sym.Name, Sym.Flags, this, Function);
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol *ObjFile::createDefinedGlobal(const WasmSymbol &Sym,
|
Symbol *ObjFile::createDefinedData(const WasmSymbol &Sym, InputSegment *Segment,
|
||||||
InputSegment *Segment, uint32_t Address) {
|
uint32_t Address) {
|
||||||
if (Sym.isBindingLocal())
|
if (Sym.isBindingLocal())
|
||||||
return make<DefinedGlobal>(Sym.Name, Sym.Flags, this, Segment, Address);
|
return make<DefinedData>(Sym.Name, Sym.Flags, this, Segment, Address);
|
||||||
return Symtab->addDefinedGlobal(Sym.Name, Sym.Flags, this, Segment, Address);
|
return Symtab->addDefinedData(Sym.Name, Sym.Flags, this, Segment, Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArchiveFile::parse() {
|
void ArchiveFile::parse() {
|
||||||
|
|
|
@ -108,8 +108,8 @@ public:
|
||||||
return cast<FunctionSymbol>(FunctionSymbols[Index]);
|
return cast<FunctionSymbol>(FunctionSymbols[Index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalSymbol *getGlobalSymbol(uint32_t Index) const {
|
DataSymbol *getDataSymbol(uint32_t Index) const {
|
||||||
return cast<GlobalSymbol>(GlobalSymbols[Index]);
|
return cast<DataSymbol>(DataSymbols[Index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -118,8 +118,8 @@ private:
|
||||||
uint32_t relocateGlobalIndex(uint32_t Original) const;
|
uint32_t relocateGlobalIndex(uint32_t Original) const;
|
||||||
uint32_t relocateTableIndex(uint32_t Original) const;
|
uint32_t relocateTableIndex(uint32_t Original) const;
|
||||||
|
|
||||||
Symbol *createDefinedGlobal(const WasmSymbol &Sym, InputSegment *Segment,
|
Symbol *createDefinedData(const WasmSymbol &Sym, InputSegment *Segment,
|
||||||
uint32_t Address);
|
uint32_t Address);
|
||||||
Symbol *createDefinedFunction(const WasmSymbol &Sym, InputFunction *Function);
|
Symbol *createDefinedFunction(const WasmSymbol &Sym, InputFunction *Function);
|
||||||
Symbol *createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind,
|
Symbol *createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind,
|
||||||
const WasmSignature *Signature = nullptr);
|
const WasmSignature *Signature = nullptr);
|
||||||
|
@ -137,7 +137,7 @@ private:
|
||||||
std::vector<Symbol *> FunctionSymbols;
|
std::vector<Symbol *> FunctionSymbols;
|
||||||
|
|
||||||
// List of all global symbols indexed by the global index space
|
// List of all global symbols indexed by the global index space
|
||||||
std::vector<Symbol *> GlobalSymbols;
|
std::vector<Symbol *> DataSymbols;
|
||||||
|
|
||||||
uint32_t NumGlobalImports = 0;
|
uint32_t NumGlobalImports = 0;
|
||||||
uint32_t NumFunctionImports = 0;
|
uint32_t NumFunctionImports = 0;
|
||||||
|
|
|
@ -83,7 +83,7 @@ void lld::wasm::markLive() {
|
||||||
case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
||||||
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
||||||
case R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
case R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
||||||
Enqueue(C->File->getGlobalSymbol(Reloc.Index));
|
Enqueue(C->File->getDataSymbol(Reloc.Index));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,9 @@ static void checkSymbolTypes(const Symbol &Existing, const InputFile &F,
|
||||||
// symbols or both are data symbols).
|
// symbols or both are data symbols).
|
||||||
if (isa<FunctionSymbol>(Existing) != NewIsFunction) {
|
if (isa<FunctionSymbol>(Existing) != NewIsFunction) {
|
||||||
error("symbol type mismatch: " + Existing.getName() + "\n>>> defined as " +
|
error("symbol type mismatch: " + Existing.getName() + "\n>>> defined as " +
|
||||||
(isa<FunctionSymbol>(Existing) ? "Function" : "Global") + " in " +
|
(isa<FunctionSymbol>(Existing) ? "Function" : "Data") + " in " +
|
||||||
toString(Existing.getFile()) + "\n>>> defined as " +
|
toString(Existing.getFile()) + "\n>>> defined as " +
|
||||||
(NewIsFunction ? "Function" : "Global") + " in " + F.getName());
|
(NewIsFunction ? "Function" : "Data") + " in " + F.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,13 +130,14 @@ DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
|
||||||
return replaceSymbol<DefinedFunction>(S, Name, Flags, Type);
|
return replaceSymbol<DefinedFunction>(S, Name, Flags, Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags) {
|
DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,
|
||||||
DEBUG(dbgs() << "addSyntheticGlobal: " << Name << "\n");
|
uint32_t Flags) {
|
||||||
|
DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");
|
||||||
Symbol *S;
|
Symbol *S;
|
||||||
bool WasInserted;
|
bool WasInserted;
|
||||||
std::tie(S, WasInserted) = insert(Name);
|
std::tie(S, WasInserted) = insert(Name);
|
||||||
assert(WasInserted);
|
assert(WasInserted);
|
||||||
return replaceSymbol<DefinedGlobal>(S, Name, Flags);
|
return replaceSymbol<DefinedData>(S, Name, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool shouldReplace(const Symbol &Existing, InputFile *NewFile,
|
static bool shouldReplace(const Symbol &Existing, InputFile *NewFile,
|
||||||
|
@ -192,15 +193,15 @@ Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
|
||||||
return S;
|
return S;
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,
|
Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,
|
||||||
InputFile *F, InputSegment *Segment,
|
InputFile *F, InputSegment *Segment,
|
||||||
uint32_t Address) {
|
uint32_t Address) {
|
||||||
DEBUG(dbgs() << "addDefinedGlobal:" << Name << " addr:" << Address << "\n");
|
DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address << "\n");
|
||||||
Symbol *S;
|
Symbol *S;
|
||||||
bool WasInserted;
|
bool WasInserted;
|
||||||
std::tie(S, WasInserted) = insert(Name);
|
std::tie(S, WasInserted) = insert(Name);
|
||||||
if (WasInserted || shouldReplace(*S, F, Flags, Segment, false))
|
if (WasInserted || shouldReplace(*S, F, Flags, Segment, false))
|
||||||
replaceSymbol<DefinedGlobal>(S, Name, Flags, F, Segment, Address);
|
replaceSymbol<DefinedData>(S, Name, Flags, F, Segment, Address);
|
||||||
return S;
|
return S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +219,7 @@ Symbol *SymbolTable::addUndefined(StringRef Name, Symbol::Kind Kind,
|
||||||
if (IsFunction)
|
if (IsFunction)
|
||||||
replaceSymbol<UndefinedFunction>(S, Name, Flags, F, Type);
|
replaceSymbol<UndefinedFunction>(S, Name, Flags, F, Type);
|
||||||
else
|
else
|
||||||
replaceSymbol<UndefinedGlobal>(S, Name, Flags, F);
|
replaceSymbol<UndefinedData>(S, Name, Flags, F);
|
||||||
return S;
|
return S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,16 +49,15 @@ public:
|
||||||
|
|
||||||
Symbol *addDefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
|
Symbol *addDefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
|
||||||
InputFunction *Function = nullptr);
|
InputFunction *Function = nullptr);
|
||||||
Symbol *addDefinedGlobal(StringRef Name, uint32_t Flags, InputFile *F,
|
Symbol *addDefinedData(StringRef Name, uint32_t Flags, InputFile *F,
|
||||||
InputSegment *Segment = nullptr,
|
InputSegment *Segment = nullptr, uint32_t Address = 0);
|
||||||
uint32_t Address = 0);
|
|
||||||
Symbol *addUndefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags,
|
Symbol *addUndefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags,
|
||||||
InputFile *F, const WasmSignature *Signature = nullptr);
|
InputFile *F, const WasmSignature *Signature = nullptr);
|
||||||
Symbol *addUndefinedFunction(StringRef Name, const WasmSignature *Type);
|
Symbol *addUndefinedFunction(StringRef Name, const WasmSignature *Type);
|
||||||
void addLazy(ArchiveFile *F, const Archive::Symbol *Sym);
|
void addLazy(ArchiveFile *F, const Archive::Symbol *Sym);
|
||||||
bool addComdat(StringRef Name, ObjFile *);
|
bool addComdat(StringRef Name, ObjFile *);
|
||||||
|
|
||||||
DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags = 0);
|
DefinedData *addSyntheticDataSymbol(StringRef Name, uint32_t Flags = 0);
|
||||||
DefinedFunction *addSyntheticFunction(StringRef Name,
|
DefinedFunction *addSyntheticFunction(StringRef Name,
|
||||||
const WasmSignature *Type,
|
const WasmSignature *Type,
|
||||||
uint32_t Flags = 0);
|
uint32_t Flags = 0);
|
||||||
|
|
|
@ -22,10 +22,10 @@ using namespace lld;
|
||||||
using namespace lld::wasm;
|
using namespace lld::wasm;
|
||||||
|
|
||||||
DefinedFunction *WasmSym::CallCtors;
|
DefinedFunction *WasmSym::CallCtors;
|
||||||
DefinedGlobal *WasmSym::DsoHandle;
|
DefinedData *WasmSym::DsoHandle;
|
||||||
DefinedGlobal *WasmSym::DataEnd;
|
DefinedData *WasmSym::DataEnd;
|
||||||
DefinedGlobal *WasmSym::HeapBase;
|
DefinedData *WasmSym::HeapBase;
|
||||||
DefinedGlobal *WasmSym::StackPointer;
|
DefinedData *WasmSym::StackPointer;
|
||||||
|
|
||||||
bool Symbol::hasOutputIndex() const {
|
bool Symbol::hasOutputIndex() const {
|
||||||
if (auto *F = dyn_cast<DefinedFunction>(this))
|
if (auto *F = dyn_cast<DefinedFunction>(this))
|
||||||
|
@ -45,7 +45,7 @@ uint32_t Symbol::getOutputIndex() const {
|
||||||
InputChunk *Symbol::getChunk() const {
|
InputChunk *Symbol::getChunk() const {
|
||||||
if (auto *F = dyn_cast<DefinedFunction>(this))
|
if (auto *F = dyn_cast<DefinedFunction>(this))
|
||||||
return F->Function;
|
return F->Function;
|
||||||
if (auto *G = dyn_cast<DefinedGlobal>(this))
|
if (auto *G = dyn_cast<DefinedData>(this))
|
||||||
return G->Segment;
|
return G->Segment;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -109,12 +109,12 @@ DefinedFunction::DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
|
||||||
Function ? &Function->Signature : nullptr),
|
Function ? &Function->Signature : nullptr),
|
||||||
Function(Function) {}
|
Function(Function) {}
|
||||||
|
|
||||||
uint32_t DefinedGlobal::getVirtualAddress() const {
|
uint32_t DefinedData::getVirtualAddress() const {
|
||||||
DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
|
DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
|
||||||
return Segment ? Segment->translateVA(VirtualAddress) : VirtualAddress;
|
return Segment ? Segment->translateVA(VirtualAddress) : VirtualAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinedGlobal::setVirtualAddress(uint32_t Value) {
|
void DefinedData::setVirtualAddress(uint32_t Value) {
|
||||||
DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
|
DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
|
||||||
VirtualAddress = Value;
|
VirtualAddress = Value;
|
||||||
}
|
}
|
||||||
|
@ -130,12 +130,12 @@ std::string lld::toString(wasm::Symbol::Kind Kind) {
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
case wasm::Symbol::DefinedFunctionKind:
|
case wasm::Symbol::DefinedFunctionKind:
|
||||||
return "DefinedFunction";
|
return "DefinedFunction";
|
||||||
case wasm::Symbol::DefinedGlobalKind:
|
case wasm::Symbol::DefinedDataKind:
|
||||||
return "DefinedGlobal";
|
return "DefinedData";
|
||||||
case wasm::Symbol::UndefinedFunctionKind:
|
case wasm::Symbol::UndefinedFunctionKind:
|
||||||
return "UndefinedFunction";
|
return "UndefinedFunction";
|
||||||
case wasm::Symbol::UndefinedGlobalKind:
|
case wasm::Symbol::UndefinedDataKind:
|
||||||
return "UndefinedGlobal";
|
return "UndefinedData";
|
||||||
case wasm::Symbol::LazyKind:
|
case wasm::Symbol::LazyKind:
|
||||||
return "LazyKind";
|
return "LazyKind";
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,13 +32,13 @@ class Symbol {
|
||||||
public:
|
public:
|
||||||
enum Kind {
|
enum Kind {
|
||||||
DefinedFunctionKind,
|
DefinedFunctionKind,
|
||||||
DefinedGlobalKind,
|
DefinedDataKind,
|
||||||
|
|
||||||
LazyKind,
|
LazyKind,
|
||||||
UndefinedFunctionKind,
|
UndefinedFunctionKind,
|
||||||
UndefinedGlobalKind,
|
UndefinedDataKind,
|
||||||
|
|
||||||
LastDefinedKind = DefinedGlobalKind,
|
LastDefinedKind = DefinedDataKind,
|
||||||
InvalidKind,
|
InvalidKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public:
|
||||||
bool isLazy() const { return SymbolKind == LazyKind; }
|
bool isLazy() const { return SymbolKind == LazyKind; }
|
||||||
bool isDefined() const { return SymbolKind <= LastDefinedKind; }
|
bool isDefined() const { return SymbolKind <= LastDefinedKind; }
|
||||||
bool isUndefined() const {
|
bool isUndefined() const {
|
||||||
return SymbolKind == UndefinedGlobalKind ||
|
return SymbolKind == UndefinedDataKind ||
|
||||||
SymbolKind == UndefinedFunctionKind;
|
SymbolKind == UndefinedFunctionKind;
|
||||||
}
|
}
|
||||||
bool isLocal() const;
|
bool isLocal() const;
|
||||||
|
@ -136,26 +136,26 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class GlobalSymbol : public Symbol {
|
class DataSymbol : public Symbol {
|
||||||
public:
|
public:
|
||||||
static bool classof(const Symbol *S) {
|
static bool classof(const Symbol *S) {
|
||||||
return S->kind() == DefinedGlobalKind || S->kind() == UndefinedGlobalKind;
|
return S->kind() == DefinedDataKind || S->kind() == UndefinedDataKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GlobalSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
|
DataSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
|
||||||
: Symbol(Name, K, Flags, F) {}
|
: Symbol(Name, K, Flags, F) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DefinedGlobal : public GlobalSymbol {
|
class DefinedData : public DataSymbol {
|
||||||
public:
|
public:
|
||||||
DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *F = nullptr,
|
DefinedData(StringRef Name, uint32_t Flags, InputFile *F = nullptr,
|
||||||
InputSegment *Segment = nullptr, uint32_t Address = 0)
|
InputSegment *Segment = nullptr, uint32_t Address = 0)
|
||||||
: GlobalSymbol(Name, DefinedGlobalKind, Flags, F), Segment(Segment),
|
: DataSymbol(Name, DefinedDataKind, Flags, F), Segment(Segment),
|
||||||
VirtualAddress(Address) {}
|
VirtualAddress(Address) {}
|
||||||
|
|
||||||
static bool classof(const Symbol *S) {
|
static bool classof(const Symbol *S) {
|
||||||
return S->kind() == DefinedGlobalKind;
|
return S->kind() == DefinedDataKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getVirtualAddress() const;
|
uint32_t getVirtualAddress() const;
|
||||||
|
@ -167,12 +167,12 @@ protected:
|
||||||
uint32_t VirtualAddress;
|
uint32_t VirtualAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UndefinedGlobal : public GlobalSymbol {
|
class UndefinedData : public DataSymbol {
|
||||||
public:
|
public:
|
||||||
UndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File = nullptr)
|
UndefinedData(StringRef Name, uint32_t Flags, InputFile *File = nullptr)
|
||||||
: GlobalSymbol(Name, UndefinedGlobalKind, Flags, File) {}
|
: DataSymbol(Name, UndefinedDataKind, Flags, File) {}
|
||||||
static bool classof(const Symbol *S) {
|
static bool classof(const Symbol *S) {
|
||||||
return S->kind() == UndefinedGlobalKind;
|
return S->kind() == UndefinedDataKind;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,25 +194,25 @@ struct WasmSym {
|
||||||
// __stack_pointer
|
// __stack_pointer
|
||||||
// Global that holds the address of the top of the explicit value stack in
|
// Global that holds the address of the top of the explicit value stack in
|
||||||
// linear memory.
|
// linear memory.
|
||||||
static DefinedGlobal *StackPointer;
|
static DefinedData *StackPointer;
|
||||||
|
|
||||||
// __data_end
|
// __data_end
|
||||||
// Symbol marking the end of the data and bss.
|
// Symbol marking the end of the data and bss.
|
||||||
static DefinedGlobal *DataEnd;
|
static DefinedData *DataEnd;
|
||||||
|
|
||||||
// __heap_base
|
// __heap_base
|
||||||
// Symbol marking the end of the data, bss and explicit stack. Any linear
|
// Symbol marking the end of the data, bss and explicit stack. Any linear
|
||||||
// memory following this address is not used by the linked code and can
|
// memory following this address is not used by the linked code and can
|
||||||
// therefore be used as a backing store for brk()/malloc() implementations.
|
// therefore be used as a backing store for brk()/malloc() implementations.
|
||||||
static DefinedGlobal *HeapBase;
|
static DefinedData *HeapBase;
|
||||||
|
|
||||||
// __wasm_call_ctors
|
// __wasm_call_ctors
|
||||||
// Function that directly calls all ctors in priority order.
|
// Function that directly calls all ctors in priority order.
|
||||||
static DefinedFunction *CallCtors;
|
static DefinedFunction *CallCtors;
|
||||||
|
|
||||||
// __dso_handle
|
// __dso_handle
|
||||||
// Global used in calls to __cxa_atexit to determine current DLL
|
// Symbol used in calls to __cxa_atexit to determine current DLL
|
||||||
static DefinedGlobal *DsoHandle;
|
static DefinedData *DsoHandle;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A buffer class that is large enough to hold any Symbol-derived
|
// A buffer class that is large enough to hold any Symbol-derived
|
||||||
|
@ -220,10 +220,10 @@ struct WasmSym {
|
||||||
// using the placement new.
|
// using the placement new.
|
||||||
union SymbolUnion {
|
union SymbolUnion {
|
||||||
alignas(DefinedFunction) char A[sizeof(DefinedFunction)];
|
alignas(DefinedFunction) char A[sizeof(DefinedFunction)];
|
||||||
alignas(DefinedGlobal) char B[sizeof(DefinedGlobal)];
|
alignas(DefinedData) char B[sizeof(DefinedData)];
|
||||||
alignas(LazySymbol) char C[sizeof(LazySymbol)];
|
alignas(LazySymbol) char C[sizeof(LazySymbol)];
|
||||||
alignas(UndefinedFunction) char D[sizeof(UndefinedFunction)];
|
alignas(UndefinedFunction) char D[sizeof(UndefinedFunction)];
|
||||||
alignas(UndefinedGlobal) char E[sizeof(UndefinedFunction)];
|
alignas(UndefinedData) char E[sizeof(UndefinedFunction)];
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename... ArgT>
|
template <typename T, typename... ArgT>
|
||||||
|
|
|
@ -119,9 +119,9 @@ private:
|
||||||
std::vector<const WasmSignature *> Types;
|
std::vector<const WasmSignature *> Types;
|
||||||
DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices;
|
DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices;
|
||||||
std::vector<const FunctionSymbol *> ImportedFunctions;
|
std::vector<const FunctionSymbol *> ImportedFunctions;
|
||||||
std::vector<const GlobalSymbol *> ImportedGlobals;
|
std::vector<const DataSymbol *> ImportedGlobals;
|
||||||
std::vector<WasmExportEntry> ExportedSymbols;
|
std::vector<WasmExportEntry> ExportedSymbols;
|
||||||
std::vector<const DefinedGlobal *> DefinedGlobals;
|
std::vector<const DefinedData *> DefinedDataSymbols;
|
||||||
std::vector<InputFunction *> DefinedFunctions;
|
std::vector<InputFunction *> DefinedFunctions;
|
||||||
std::vector<const FunctionSymbol *> IndirectFunctions;
|
std::vector<const FunctionSymbol *> IndirectFunctions;
|
||||||
std::vector<WasmInitFunc> InitFunctions;
|
std::vector<WasmInitFunc> InitFunctions;
|
||||||
|
@ -226,14 +226,14 @@ void Writer::createMemorySection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Writer::createGlobalSection() {
|
void Writer::createGlobalSection() {
|
||||||
if (DefinedGlobals.empty())
|
if (DefinedDataSymbols.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL);
|
SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL);
|
||||||
raw_ostream &OS = Section->getStream();
|
raw_ostream &OS = Section->getStream();
|
||||||
|
|
||||||
writeUleb128(OS, DefinedGlobals.size(), "global count");
|
writeUleb128(OS, DefinedDataSymbols.size(), "global count");
|
||||||
for (const DefinedGlobal *Sym : DefinedGlobals) {
|
for (const DefinedData *Sym : DefinedDataSymbols) {
|
||||||
WasmGlobal Global;
|
WasmGlobal Global;
|
||||||
Global.Type.Type = WASM_TYPE_I32;
|
Global.Type.Type = WASM_TYPE_I32;
|
||||||
Global.Type.Mutable = Sym == WasmSym::StackPointer;
|
Global.Type.Mutable = Sym == WasmSym::StackPointer;
|
||||||
|
@ -621,7 +621,7 @@ void Writer::calculateImports() {
|
||||||
if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {
|
if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {
|
||||||
F->setOutputIndex(ImportedFunctions.size());
|
F->setOutputIndex(ImportedFunctions.size());
|
||||||
ImportedFunctions.push_back(F);
|
ImportedFunctions.push_back(F);
|
||||||
} else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) {
|
} else if (auto *G = dyn_cast<DataSymbol>(Sym)) {
|
||||||
G->setOutputIndex(ImportedGlobals.size());
|
G->setOutputIndex(ImportedGlobals.size());
|
||||||
ImportedGlobals.push_back(G);
|
ImportedGlobals.push_back(G);
|
||||||
}
|
}
|
||||||
|
@ -659,7 +659,7 @@ void Writer::calculateExports() {
|
||||||
for (Symbol *Sym : File->getSymbols()) {
|
for (Symbol *Sym : File->getSymbols()) {
|
||||||
if (!Sym->isDefined() || File != Sym->getFile())
|
if (!Sym->isDefined() || File != Sym->getFile())
|
||||||
continue;
|
continue;
|
||||||
if (isa<GlobalSymbol>(Sym))
|
if (!isa<FunctionSymbol>(Sym))
|
||||||
continue;
|
continue;
|
||||||
if (!Sym->getChunk()->Live)
|
if (!Sym->getChunk()->Live)
|
||||||
continue;
|
continue;
|
||||||
|
@ -670,7 +670,7 @@ void Writer::calculateExports() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const Symbol *Sym : DefinedGlobals) {
|
for (const Symbol *Sym : DefinedDataSymbols) {
|
||||||
// Can't export the SP right now because its mutable, and mutuable globals
|
// Can't export the SP right now because its mutable, and mutuable globals
|
||||||
// are yet supported in the official binary format.
|
// are yet supported in the official binary format.
|
||||||
// TODO(sbc): Remove this if/when the "mutable global" proposal is accepted.
|
// TODO(sbc): Remove this if/when the "mutable global" proposal is accepted.
|
||||||
|
@ -719,21 +719,21 @@ void Writer::calculateTypes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Writer::assignIndexes() {
|
void Writer::assignIndexes() {
|
||||||
uint32_t GlobalIndex = ImportedGlobals.size() + DefinedGlobals.size();
|
uint32_t GlobalIndex = ImportedGlobals.size() + DefinedDataSymbols.size();
|
||||||
uint32_t FunctionIndex = ImportedFunctions.size() + DefinedFunctions.size();
|
uint32_t FunctionIndex = ImportedFunctions.size() + DefinedFunctions.size();
|
||||||
|
|
||||||
auto AddDefinedGlobal = [&](DefinedGlobal *Sym) {
|
auto AddDefinedData = [&](DefinedData *Sym) {
|
||||||
if (Sym) {
|
if (Sym) {
|
||||||
DefinedGlobals.emplace_back(Sym);
|
DefinedDataSymbols.emplace_back(Sym);
|
||||||
Sym->setOutputIndex(GlobalIndex++);
|
Sym->setOutputIndex(GlobalIndex++);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
AddDefinedGlobal(WasmSym::StackPointer);
|
AddDefinedData(WasmSym::StackPointer);
|
||||||
AddDefinedGlobal(WasmSym::HeapBase);
|
AddDefinedData(WasmSym::HeapBase);
|
||||||
AddDefinedGlobal(WasmSym::DataEnd);
|
AddDefinedData(WasmSym::DataEnd);
|
||||||
|
|
||||||
if (Config->Relocatable)
|
if (Config->Relocatable)
|
||||||
DefinedGlobals.reserve(Symtab->getSymbols().size());
|
DefinedDataSymbols.reserve(Symtab->getSymbols().size());
|
||||||
|
|
||||||
uint32_t TableIndex = kInitialTableOffset;
|
uint32_t TableIndex = kInitialTableOffset;
|
||||||
|
|
||||||
|
@ -744,8 +744,8 @@ void Writer::assignIndexes() {
|
||||||
// Create wasm globals for data symbols defined in this file
|
// Create wasm globals for data symbols defined in this file
|
||||||
if (File != Sym->getFile())
|
if (File != Sym->getFile())
|
||||||
continue;
|
continue;
|
||||||
if (auto *G = dyn_cast<DefinedGlobal>(Sym))
|
if (auto *G = dyn_cast<DefinedData>(Sym))
|
||||||
AddDefinedGlobal(G);
|
AddDefinedData(G);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -893,7 +893,7 @@ void Writer::run() {
|
||||||
|
|
||||||
if (errorHandler().Verbose) {
|
if (errorHandler().Verbose) {
|
||||||
log("Defined Functions: " + Twine(DefinedFunctions.size()));
|
log("Defined Functions: " + Twine(DefinedFunctions.size()));
|
||||||
log("Defined Globals : " + Twine(DefinedGlobals.size()));
|
log("Defined Data Syms: " + Twine(DefinedDataSymbols.size()));
|
||||||
log("Function Imports : " + Twine(ImportedFunctions.size()));
|
log("Function Imports : " + Twine(ImportedFunctions.size()));
|
||||||
log("Global Imports : " + Twine(ImportedGlobals.size()));
|
log("Global Imports : " + Twine(ImportedGlobals.size()));
|
||||||
log("Total Imports : " +
|
log("Total Imports : " +
|
||||||
|
|
Loading…
Reference in New Issue