[lld] r320001 - [WebAssembly] Fix symbol exports under -r/--relocatable
Sam Clegg via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 6 17:51:24 PST 2017
Author: sbc
Date: Wed Dec 6 17:51:24 2017
New Revision: 320001
URL: http://llvm.org/viewvc/llvm-project?rev=320001&view=rev
Log:
[WebAssembly] Fix symbol exports under -r/--relocatable
This change cleans up the way wasm exports and globals
are generated, particualrly for -r/--relocatable where
globals need to be created and exported in order for
output relocations which reference them.
Remove the need for a per file GlobalIndexOffset and
instead set the output index for each symbol directly.
This simplifies the code in several places.
Differential Revision: https://reviews.llvm.org/D40859
Modified:
lld/trunk/test/wasm/data-layout.ll
lld/trunk/test/wasm/relocatable.ll
lld/trunk/wasm/Driver.cpp
lld/trunk/wasm/InputFiles.cpp
lld/trunk/wasm/InputFiles.h
lld/trunk/wasm/OutputSections.cpp
lld/trunk/wasm/SymbolTable.cpp
lld/trunk/wasm/SymbolTable.h
lld/trunk/wasm/Writer.cpp
Modified: lld/trunk/test/wasm/data-layout.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/data-layout.ll?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/test/wasm/data-layout.ll (original)
+++ lld/trunk/test/wasm/data-layout.ll Wed Dec 6 17:51:24 2017
@@ -23,27 +23,27 @@ target triple = "wasm32-unknown-unknown-
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 1024
+; CHECK-NEXT: Value: 1052
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 1040
+; CHECK-NEXT: Value: 1024
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 1048
+; CHECK-NEXT: Value: 1040
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 1052
+; CHECK-NEXT: Value: 1048
; CHECK: - Type: DATA
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
-; CHECK-NEXT: Index: 4
+; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000001F
; CHECK-NEXT: Segments:
; CHECK-NEXT: - SectionOffset: 7
Modified: lld/trunk/test/wasm/relocatable.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/relocatable.ll?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/test/wasm/relocatable.ll (original)
+++ lld/trunk/test/wasm/relocatable.ll Wed Dec 6 17:51:24 2017
@@ -93,6 +93,18 @@ declare i32 @foo_import() local_unnamed_
; CHECK-NEXT: - Name: my_func
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 3
+; CHECK-NEXT: - Name: hello_str
+; CHECK-NEXT: Kind: GLOBAL
+; CHECK-NEXT: Index: 1
+; CHECK-NEXT: - Name: func_addr1
+; CHECK-NEXT: Kind: GLOBAL
+; CHECK-NEXT: Index: 2
+; CHECK-NEXT: - Name: func_addr2
+; CHECK-NEXT: Kind: GLOBAL
+; CHECK-NEXT: Index: 3
+; CHECK-NEXT: - Name: data_addr1
+; CHECK-NEXT: Kind: GLOBAL
+; CHECK-NEXT: Index: 4
; CHECK-NEXT: - Type: ELEM
; CHECK-NEXT: Segments:
; CHECK-NEXT: - Offset:
Modified: lld/trunk/wasm/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Driver.cpp?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/Driver.cpp (original)
+++ lld/trunk/wasm/Driver.cpp Wed Dec 6 17:51:24 2017
@@ -142,7 +142,6 @@ static Symbol* addSyntheticGlobal(String
log("injecting global: " + Name);
Symbol *S = Symtab->addDefinedGlobal(Name);
S->setVirtualAddress(Value);
- S->setOutputIndex(Config->SyntheticGlobals.size());
Config->SyntheticGlobals.emplace_back(S);
return S;
}
Modified: lld/trunk/wasm/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.cpp?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.cpp (original)
+++ lld/trunk/wasm/InputFiles.cpp Wed Dec 6 17:51:24 2017
@@ -47,7 +47,6 @@ void ObjFile::dumpInfo() const {
" FunctionIndexOffset : " + Twine(FunctionIndexOffset) + "\n" +
" NumFunctionImports : " + Twine(NumFunctionImports()) + "\n" +
" TableIndexOffset : " + Twine(TableIndexOffset) + "\n" +
- " GlobalIndexOffset : " + Twine(GlobalIndexOffset) + "\n" +
" NumGlobalImports : " + Twine(NumGlobalImports()) + "\n");
}
@@ -68,15 +67,10 @@ uint32_t ObjFile::getRelocatedAddress(ui
}
uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const {
- DEBUG(dbgs() << "relocateFunctionIndex: " << Original);
const Symbol *Sym = getFunctionSymbol(Original);
- uint32_t Index;
- if (Sym)
- Index = Sym->getOutputIndex();
- else
- Index = Original + FunctionIndexOffset;
-
- DEBUG(dbgs() << " -> " << Index << "\n");
+ uint32_t Index = Sym->getOutputIndex();
+ DEBUG(dbgs() << "relocateFunctionIndex: " << toString(*Sym) << ": "
+ << Original << " -> " << Index << "\n");
return Index;
}
@@ -89,15 +83,10 @@ uint32_t ObjFile::relocateTableIndex(uin
}
uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const {
- DEBUG(dbgs() << "relocateGlobalIndex: " << Original);
- uint32_t Index;
const Symbol *Sym = getGlobalSymbol(Original);
- if (Sym)
- Index = Sym->getOutputIndex();
- else
- Index = Original + GlobalIndexOffset;
-
- DEBUG(dbgs() << " -> " << Index << "\n");
+ uint32_t Index = Sym->getOutputIndex();
+ DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original
+ << " -> " << Index << "\n");
return Index;
}
Modified: lld/trunk/wasm/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.h?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.h (original)
+++ lld/trunk/wasm/InputFiles.h Wed Dec 6 17:51:24 2017
@@ -103,7 +103,6 @@ public:
size_t NumGlobalImports() const { return GlobalImports; }
int32_t FunctionIndexOffset = 0;
- int32_t GlobalIndexOffset = 0;
int32_t TableIndexOffset = 0;
const WasmSection *CodeSection = nullptr;
std::vector<OutputRelocation> CodeRelocations;
Modified: lld/trunk/wasm/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/OutputSections.cpp?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/OutputSections.cpp (original)
+++ lld/trunk/wasm/OutputSections.cpp Wed Dec 6 17:51:24 2017
@@ -72,9 +72,8 @@ std::string lld::toString(OutputSection
static void applyRelocation(uint8_t *Buf, const OutputRelocation &Reloc) {
DEBUG(dbgs() << "write reloc: type=" << Reloc.Reloc.Type
- << " index=" << Reloc.Reloc.Index << " new=" << Reloc.NewIndex
- << " value=" << Reloc.Value << " offset=" << Reloc.Reloc.Offset
- << "\n");
+ << " index=" << Reloc.Reloc.Index << " value=" << Reloc.Value
+ << " offset=" << Reloc.Reloc.Offset << "\n");
Buf += Reloc.Reloc.Offset;
int64_t ExistingValue;
switch (Reloc.Reloc.Type) {
@@ -149,15 +148,18 @@ static void calcRelocations(const ObjFil
int32_t OutputOffset) {
log("calcRelocations: " + File.getName() + " offset=" + Twine(OutputOffset));
for (const WasmRelocation &Reloc : Relocs) {
- int64_t NewIndex = calcNewIndex(File, Reloc);
OutputRelocation NewReloc;
NewReloc.Reloc = Reloc;
NewReloc.Reloc.Offset += OutputOffset;
- NewReloc.NewIndex = NewIndex;
DEBUG(dbgs() << "reloc: type=" << Reloc.Type << " index=" << Reloc.Index
- << " offset=" << Reloc.Offset << " new=" << NewIndex
+ << " offset=" << Reloc.Offset
<< " newOffset=" << NewReloc.Reloc.Offset << "\n");
+ if (Config->EmitRelocs)
+ NewReloc.NewIndex = calcNewIndex(File, Reloc);
+ else
+ NewReloc.NewIndex = UINT32_MAX;
+
switch (Reloc.Type) {
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
case R_WEBASSEMBLY_MEMORY_ADDR_I32:
@@ -167,7 +169,8 @@ static void calcRelocations(const ObjFil
NewReloc.Value += Reloc.Addend;
break;
default:
- NewReloc.Value = NewIndex;
+ NewReloc.Value = calcNewIndex(File, Reloc);
+ break;
}
OutputRelocs.emplace_back(NewReloc);
Modified: lld/trunk/wasm/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.cpp?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.cpp (original)
+++ lld/trunk/wasm/SymbolTable.cpp Wed Dec 6 17:51:24 2017
@@ -34,8 +34,7 @@ void SymbolTable::addFile(InputFile *Fil
void SymbolTable::reportRemainingUndefines() {
std::unordered_set<Symbol *> Undefs;
- for (auto &I : SymMap) {
- Symbol *Sym = I.second;
+ for (Symbol *Sym : SymVector) {
if (Sym->isUndefined() && !Sym->isWeak() &&
Config->AllowUndefinedSymbols.count(Sym->getName()) == 0) {
Undefs.insert(Sym);
@@ -67,6 +66,7 @@ std::pair<Symbol *, bool> SymbolTable::i
if (Sym)
return {Sym, false};
Sym = make<Symbol>(Name, false);
+ SymVector.emplace_back(Sym);
return {Sym, true};
}
Modified: lld/trunk/wasm/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.h?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.h (original)
+++ lld/trunk/wasm/SymbolTable.h Wed Dec 6 17:51:24 2017
@@ -47,6 +47,7 @@ public:
void reportDuplicate(Symbol *Existing, InputFile *NewFile);
void reportRemainingUndefines();
+ ArrayRef<Symbol *> getSymbols() const { return SymVector; }
Symbol *find(StringRef Name);
Symbol *addDefined(InputFile *F, const WasmSymbol *Sym,
@@ -60,6 +61,7 @@ private:
std::pair<Symbol *, bool> insert(StringRef Name);
llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;
+ std::vector<Symbol *> SymVector;
};
extern SymbolTable *Symtab;
Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Wed Dec 6 17:51:24 2017
@@ -111,8 +111,9 @@ private:
std::vector<const WasmSignature *> Types;
DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices;
- std::vector<Symbol *> FunctionImports;
- std::vector<Symbol *> GlobalImports;
+ std::vector<const Symbol *> FunctionImports;
+ std::vector<const Symbol *> GlobalImports;
+ std::vector<const Symbol *> DefinedGlobals;
// Elements that are used to construct the final output
std::string Header;
@@ -217,11 +218,14 @@ void Writer::createMemorySection() {
}
void Writer::createGlobalSection() {
+ if (DefinedGlobals.empty())
+ return;
+
SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL);
raw_ostream &OS = Section->getStream();
- writeUleb128(OS, NumGlobals, "global count");
- for (const Symbol *Sym : Config->SyntheticGlobals) {
+ writeUleb128(OS, DefinedGlobals.size(), "global count");
+ for (const Symbol *Sym : DefinedGlobals) {
WasmGlobal Global;
Global.Type = WASM_TYPE_I32;
Global.Mutable = Sym == Config->StackPointerSymbol;
@@ -229,24 +233,6 @@ void Writer::createGlobalSection() {
Global.InitExpr.Value.Int32 = Sym->getVirtualAddress();
writeGlobal(OS, Global);
}
-
- if (Config->EmitRelocs) {
- for (ObjFile *File : Symtab->ObjectFiles) {
- uint32_t GlobalIndex = File->NumGlobalImports();
- for (const WasmGlobal &Global : File->getWasmObj()->globals()) {
- WasmGlobal RelocatedGlobal(Global);
- if (Global.Type != WASM_TYPE_I32)
- fatal("unsupported global type: " + Twine(Global.Type));
- if (Global.InitExpr.Opcode != WASM_OPCODE_I32_CONST)
- fatal("unsupported global init opcode: " +
- Twine(Global.InitExpr.Opcode));
- RelocatedGlobal.InitExpr.Value.Int32 =
- File->getRelocatedAddress(GlobalIndex);
- writeGlobal(OS, RelocatedGlobal);
- ++GlobalIndex;
- }
- }
- }
}
void Writer::createTableSection() {
@@ -261,35 +247,36 @@ void Writer::createTableSection() {
}
void Writer::createExportSection() {
- // Memory is and main function are exported for executables.
bool ExportMemory = !Config->Relocatable && !Config->ImportMemory;
- bool ExportOther = true; // ??? TODO Config->Relocatable;
- bool ExportHidden = Config->Relocatable;
Symbol *EntrySym = Symtab->find(Config->Entry);
bool ExportEntry = !Config->Relocatable && EntrySym && EntrySym->isDefined();
+ bool ExportHidden = Config->EmitRelocs;
- uint32_t NumExports = 0;
-
- if (ExportMemory)
- ++NumExports;
+ uint32_t NumExports = ExportMemory ? 1 : 0;
+ std::vector<const Symbol *> SymbolExports;
if (ExportEntry)
- ++NumExports;
+ SymbolExports.emplace_back(EntrySym);
- if (ExportOther) {
- for (ObjFile *File : Symtab->ObjectFiles) {
- for (Symbol *Sym : File->getSymbols()) {
- if (!Sym->isFunction() || Sym->isLocal() || Sym->isUndefined() ||
- (Sym->isHidden() && !ExportHidden) || Sym->WrittenToSymtab)
- continue;
- if (Sym == EntrySym)
- continue;
- Sym->WrittenToSymtab = true;
- ++NumExports;
- }
- }
+ for (const Symbol *Sym : Symtab->getSymbols()) {
+ if (Sym->isUndefined() || Sym->isGlobal())
+ continue;
+ if (Sym->isHidden() && !ExportHidden)
+ continue;
+ if (ExportEntry && Sym == EntrySym)
+ continue;
+ SymbolExports.emplace_back(Sym);
+ }
+
+ for (const Symbol *Sym : DefinedGlobals) {
+ // Can't export the SP right now because it mutable and mutable globals
+ // connot be exported.
+ if (Sym == Config->StackPointerSymbol)
+ continue;
+ SymbolExports.emplace_back(Sym);
}
+ NumExports += SymbolExports.size();
if (!NumExports)
return;
@@ -306,34 +293,16 @@ void Writer::createExportSection() {
writeExport(OS, MemoryExport);
}
- if (ExportEntry) {
- WasmExport EntryExport;
- EntryExport.Name = Config->Entry;
- EntryExport.Kind = WASM_EXTERNAL_FUNCTION;
- EntryExport.Index = EntrySym->getOutputIndex();
- writeExport(OS, EntryExport);
- }
-
- if (ExportOther) {
- for (ObjFile *File : Symtab->ObjectFiles) {
- for (Symbol *Sym : File->getSymbols()) {
- if (!Sym->isFunction() || Sym->isLocal() || Sym->isUndefined() ||
- (Sym->isHidden() && !ExportHidden) || !Sym->WrittenToSymtab)
- continue;
- if (Sym == EntrySym)
- continue;
- Sym->WrittenToSymtab = false;
- log("Export: " + Sym->getName());
- WasmExport Export;
- Export.Name = Sym->getName();
- Export.Index = Sym->getOutputIndex();
- if (Sym->isFunction())
- Export.Kind = WASM_EXTERNAL_FUNCTION;
- else
- Export.Kind = WASM_EXTERNAL_GLOBAL;
- writeExport(OS, Export);
- }
- }
+ for (const Symbol *Sym : SymbolExports) {
+ log("Export: " + Sym->getName());
+ WasmExport Export;
+ Export.Name = Sym->getName();
+ Export.Index = Sym->getOutputIndex();
+ if (Sym->isFunction())
+ Export.Kind = WASM_EXTERNAL_FUNCTION;
+ else
+ Export.Kind = WASM_EXTERNAL_GLOBAL;
+ writeExport(OS, Export);
}
}
@@ -557,7 +526,6 @@ void Writer::createSections() {
}
void Writer::calculateOffsets() {
- NumGlobals = Config->SyntheticGlobals.size();
NumTableElems = InitialTableOffset;
for (ObjFile *File : Symtab->ObjectFiles) {
@@ -568,13 +536,6 @@ void Writer::calculateOffsets() {
FunctionImports.size() - File->NumFunctionImports() + NumFunctions;
NumFunctions += WasmFile->functions().size();
- // Global Index
- if (Config->EmitRelocs) {
- File->GlobalIndexOffset =
- GlobalImports.size() - File->NumGlobalImports() + NumGlobals;
- NumGlobals += WasmFile->globals().size();
- }
-
// Memory
if (WasmFile->memories().size()) {
if (WasmFile->memories().size() > 1) {
@@ -640,19 +601,31 @@ void Writer::calculateTypes() {
}
void Writer::assignSymbolIndexes() {
+ uint32_t GlobalIndex = GlobalImports.size();
+
+ if (Config->StackPointerSymbol) {
+ DefinedGlobals.emplace_back(Config->StackPointerSymbol);
+ Config->StackPointerSymbol->setOutputIndex(GlobalIndex++);
+ }
+
+ if (Config->EmitRelocs)
+ DefinedGlobals.reserve(Symtab->getSymbols().size());
+
for (ObjFile *File : Symtab->ObjectFiles) {
DEBUG(dbgs() << "assignSymbolIndexes: " << File->getName() << "\n");
for (Symbol *Sym : File->getSymbols()) {
if (Sym->hasOutputIndex() || !Sym->isDefined())
continue;
- if (Sym->getFile() && isa<ObjFile>(Sym->getFile())) {
- auto *Obj = cast<ObjFile>(Sym->getFile());
- if (Sym->isFunction())
+ if (Sym->isFunction()) {
+ if (Sym->getFile() && isa<ObjFile>(Sym->getFile())) {
+ auto *Obj = cast<ObjFile>(Sym->getFile());
Sym->setOutputIndex(Obj->FunctionIndexOffset +
Sym->getFunctionIndex());
- else
- Sym->setOutputIndex(Obj->GlobalIndexOffset + Sym->getGlobalIndex());
+ }
+ } else if (Config->EmitRelocs) {
+ DefinedGlobals.emplace_back(Sym);
+ Sym->setOutputIndex(GlobalIndex++);
}
}
}
More information about the llvm-commits
mailing list