[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 llvm-svn: 320001
This commit is contained in:
parent
c325d30d2c
commit
74fe0ba105
|
@ -23,6 +23,11 @@ target triple = "wasm32-unknown-unknown-wasm"
|
||||||
; CHECK-NEXT: Mutable: false
|
; CHECK-NEXT: Mutable: false
|
||||||
; CHECK-NEXT: InitExpr:
|
; CHECK-NEXT: InitExpr:
|
||||||
; CHECK-NEXT: Opcode: I32_CONST
|
; CHECK-NEXT: Opcode: I32_CONST
|
||||||
|
; CHECK-NEXT: Value: 1052
|
||||||
|
; CHECK-NEXT: - Type: I32
|
||||||
|
; CHECK-NEXT: Mutable: false
|
||||||
|
; CHECK-NEXT: InitExpr:
|
||||||
|
; CHECK-NEXT: Opcode: I32_CONST
|
||||||
; CHECK-NEXT: Value: 1024
|
; CHECK-NEXT: Value: 1024
|
||||||
; CHECK-NEXT: - Type: I32
|
; CHECK-NEXT: - Type: I32
|
||||||
; CHECK-NEXT: Mutable: false
|
; CHECK-NEXT: Mutable: false
|
||||||
|
@ -34,16 +39,11 @@ target triple = "wasm32-unknown-unknown-wasm"
|
||||||
; CHECK-NEXT: InitExpr:
|
; CHECK-NEXT: InitExpr:
|
||||||
; CHECK-NEXT: Opcode: I32_CONST
|
; CHECK-NEXT: Opcode: I32_CONST
|
||||||
; CHECK-NEXT: Value: 1048
|
; CHECK-NEXT: Value: 1048
|
||||||
; CHECK-NEXT: - Type: I32
|
|
||||||
; CHECK-NEXT: Mutable: false
|
|
||||||
; CHECK-NEXT: InitExpr:
|
|
||||||
; CHECK-NEXT: Opcode: I32_CONST
|
|
||||||
; CHECK-NEXT: Value: 1052
|
|
||||||
|
|
||||||
; CHECK: - Type: DATA
|
; CHECK: - Type: DATA
|
||||||
; CHECK-NEXT: Relocations:
|
; CHECK-NEXT: Relocations:
|
||||||
; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
|
; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
|
||||||
; CHECK-NEXT: Index: 4
|
; CHECK-NEXT: Index: 1
|
||||||
; CHECK-NEXT: Offset: 0x0000001F
|
; CHECK-NEXT: Offset: 0x0000001F
|
||||||
; CHECK-NEXT: Segments:
|
; CHECK-NEXT: Segments:
|
||||||
; CHECK-NEXT: - SectionOffset: 7
|
; CHECK-NEXT: - SectionOffset: 7
|
||||||
|
|
|
@ -93,6 +93,18 @@ declare i32 @foo_import() local_unnamed_addr
|
||||||
; CHECK-NEXT: - Name: my_func
|
; CHECK-NEXT: - Name: my_func
|
||||||
; CHECK-NEXT: Kind: FUNCTION
|
; CHECK-NEXT: Kind: FUNCTION
|
||||||
; CHECK-NEXT: Index: 3
|
; 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: - Type: ELEM
|
||||||
; CHECK-NEXT: Segments:
|
; CHECK-NEXT: Segments:
|
||||||
; CHECK-NEXT: - Offset:
|
; CHECK-NEXT: - Offset:
|
||||||
|
|
|
@ -142,7 +142,6 @@ static Symbol* addSyntheticGlobal(StringRef Name, int32_t Value) {
|
||||||
log("injecting global: " + Name);
|
log("injecting global: " + Name);
|
||||||
Symbol *S = Symtab->addDefinedGlobal(Name);
|
Symbol *S = Symtab->addDefinedGlobal(Name);
|
||||||
S->setVirtualAddress(Value);
|
S->setVirtualAddress(Value);
|
||||||
S->setOutputIndex(Config->SyntheticGlobals.size());
|
|
||||||
Config->SyntheticGlobals.emplace_back(S);
|
Config->SyntheticGlobals.emplace_back(S);
|
||||||
return S;
|
return S;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,6 @@ void ObjFile::dumpInfo() const {
|
||||||
" FunctionIndexOffset : " + Twine(FunctionIndexOffset) + "\n" +
|
" FunctionIndexOffset : " + Twine(FunctionIndexOffset) + "\n" +
|
||||||
" NumFunctionImports : " + Twine(NumFunctionImports()) + "\n" +
|
" NumFunctionImports : " + Twine(NumFunctionImports()) + "\n" +
|
||||||
" TableIndexOffset : " + Twine(TableIndexOffset) + "\n" +
|
" TableIndexOffset : " + Twine(TableIndexOffset) + "\n" +
|
||||||
" GlobalIndexOffset : " + Twine(GlobalIndexOffset) + "\n" +
|
|
||||||
" NumGlobalImports : " + Twine(NumGlobalImports()) + "\n");
|
" NumGlobalImports : " + Twine(NumGlobalImports()) + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,15 +67,10 @@ uint32_t ObjFile::getRelocatedAddress(uint32_t Index) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const {
|
uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const {
|
||||||
DEBUG(dbgs() << "relocateFunctionIndex: " << Original);
|
|
||||||
const Symbol *Sym = getFunctionSymbol(Original);
|
const Symbol *Sym = getFunctionSymbol(Original);
|
||||||
uint32_t Index;
|
uint32_t Index = Sym->getOutputIndex();
|
||||||
if (Sym)
|
DEBUG(dbgs() << "relocateFunctionIndex: " << toString(*Sym) << ": "
|
||||||
Index = Sym->getOutputIndex();
|
<< Original << " -> " << Index << "\n");
|
||||||
else
|
|
||||||
Index = Original + FunctionIndexOffset;
|
|
||||||
|
|
||||||
DEBUG(dbgs() << " -> " << Index << "\n");
|
|
||||||
return Index;
|
return Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,15 +83,10 @@ uint32_t ObjFile::relocateTableIndex(uint32_t Original) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const {
|
uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const {
|
||||||
DEBUG(dbgs() << "relocateGlobalIndex: " << Original);
|
|
||||||
uint32_t Index;
|
|
||||||
const Symbol *Sym = getGlobalSymbol(Original);
|
const Symbol *Sym = getGlobalSymbol(Original);
|
||||||
if (Sym)
|
uint32_t Index = Sym->getOutputIndex();
|
||||||
Index = Sym->getOutputIndex();
|
DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original
|
||||||
else
|
<< " -> " << Index << "\n");
|
||||||
Index = Original + GlobalIndexOffset;
|
|
||||||
|
|
||||||
DEBUG(dbgs() << " -> " << Index << "\n");
|
|
||||||
return Index;
|
return Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,6 @@ public:
|
||||||
size_t NumGlobalImports() const { return GlobalImports; }
|
size_t NumGlobalImports() const { return GlobalImports; }
|
||||||
|
|
||||||
int32_t FunctionIndexOffset = 0;
|
int32_t FunctionIndexOffset = 0;
|
||||||
int32_t GlobalIndexOffset = 0;
|
|
||||||
int32_t TableIndexOffset = 0;
|
int32_t TableIndexOffset = 0;
|
||||||
const WasmSection *CodeSection = nullptr;
|
const WasmSection *CodeSection = nullptr;
|
||||||
std::vector<OutputRelocation> CodeRelocations;
|
std::vector<OutputRelocation> CodeRelocations;
|
||||||
|
|
|
@ -72,9 +72,8 @@ std::string lld::toString(OutputSection *Section) {
|
||||||
|
|
||||||
static void applyRelocation(uint8_t *Buf, const OutputRelocation &Reloc) {
|
static void applyRelocation(uint8_t *Buf, const OutputRelocation &Reloc) {
|
||||||
DEBUG(dbgs() << "write reloc: type=" << Reloc.Reloc.Type
|
DEBUG(dbgs() << "write reloc: type=" << Reloc.Reloc.Type
|
||||||
<< " index=" << Reloc.Reloc.Index << " new=" << Reloc.NewIndex
|
<< " index=" << Reloc.Reloc.Index << " value=" << Reloc.Value
|
||||||
<< " value=" << Reloc.Value << " offset=" << Reloc.Reloc.Offset
|
<< " offset=" << Reloc.Reloc.Offset << "\n");
|
||||||
<< "\n");
|
|
||||||
Buf += Reloc.Reloc.Offset;
|
Buf += Reloc.Reloc.Offset;
|
||||||
int64_t ExistingValue;
|
int64_t ExistingValue;
|
||||||
switch (Reloc.Reloc.Type) {
|
switch (Reloc.Reloc.Type) {
|
||||||
|
@ -149,15 +148,18 @@ static void calcRelocations(const ObjFile &File,
|
||||||
int32_t OutputOffset) {
|
int32_t OutputOffset) {
|
||||||
log("calcRelocations: " + File.getName() + " offset=" + Twine(OutputOffset));
|
log("calcRelocations: " + File.getName() + " offset=" + Twine(OutputOffset));
|
||||||
for (const WasmRelocation &Reloc : Relocs) {
|
for (const WasmRelocation &Reloc : Relocs) {
|
||||||
int64_t NewIndex = calcNewIndex(File, Reloc);
|
|
||||||
OutputRelocation NewReloc;
|
OutputRelocation NewReloc;
|
||||||
NewReloc.Reloc = Reloc;
|
NewReloc.Reloc = Reloc;
|
||||||
NewReloc.Reloc.Offset += OutputOffset;
|
NewReloc.Reloc.Offset += OutputOffset;
|
||||||
NewReloc.NewIndex = NewIndex;
|
|
||||||
DEBUG(dbgs() << "reloc: type=" << Reloc.Type << " index=" << Reloc.Index
|
DEBUG(dbgs() << "reloc: type=" << Reloc.Type << " index=" << Reloc.Index
|
||||||
<< " offset=" << Reloc.Offset << " new=" << NewIndex
|
<< " offset=" << Reloc.Offset
|
||||||
<< " newOffset=" << NewReloc.Reloc.Offset << "\n");
|
<< " newOffset=" << NewReloc.Reloc.Offset << "\n");
|
||||||
|
|
||||||
|
if (Config->EmitRelocs)
|
||||||
|
NewReloc.NewIndex = calcNewIndex(File, Reloc);
|
||||||
|
else
|
||||||
|
NewReloc.NewIndex = UINT32_MAX;
|
||||||
|
|
||||||
switch (Reloc.Type) {
|
switch (Reloc.Type) {
|
||||||
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
||||||
case R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
case R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
||||||
|
@ -167,7 +169,8 @@ static void calcRelocations(const ObjFile &File,
|
||||||
NewReloc.Value += Reloc.Addend;
|
NewReloc.Value += Reloc.Addend;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
NewReloc.Value = NewIndex;
|
NewReloc.Value = calcNewIndex(File, Reloc);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputRelocs.emplace_back(NewReloc);
|
OutputRelocs.emplace_back(NewReloc);
|
||||||
|
|
|
@ -34,8 +34,7 @@ void SymbolTable::addFile(InputFile *File) {
|
||||||
|
|
||||||
void SymbolTable::reportRemainingUndefines() {
|
void SymbolTable::reportRemainingUndefines() {
|
||||||
std::unordered_set<Symbol *> Undefs;
|
std::unordered_set<Symbol *> Undefs;
|
||||||
for (auto &I : SymMap) {
|
for (Symbol *Sym : SymVector) {
|
||||||
Symbol *Sym = I.second;
|
|
||||||
if (Sym->isUndefined() && !Sym->isWeak() &&
|
if (Sym->isUndefined() && !Sym->isWeak() &&
|
||||||
Config->AllowUndefinedSymbols.count(Sym->getName()) == 0) {
|
Config->AllowUndefinedSymbols.count(Sym->getName()) == 0) {
|
||||||
Undefs.insert(Sym);
|
Undefs.insert(Sym);
|
||||||
|
@ -67,6 +66,7 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
|
||||||
if (Sym)
|
if (Sym)
|
||||||
return {Sym, false};
|
return {Sym, false};
|
||||||
Sym = make<Symbol>(Name, false);
|
Sym = make<Symbol>(Name, false);
|
||||||
|
SymVector.emplace_back(Sym);
|
||||||
return {Sym, true};
|
return {Sym, true};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
void reportDuplicate(Symbol *Existing, InputFile *NewFile);
|
void reportDuplicate(Symbol *Existing, InputFile *NewFile);
|
||||||
void reportRemainingUndefines();
|
void reportRemainingUndefines();
|
||||||
|
|
||||||
|
ArrayRef<Symbol *> getSymbols() const { return SymVector; }
|
||||||
Symbol *find(StringRef Name);
|
Symbol *find(StringRef Name);
|
||||||
|
|
||||||
Symbol *addDefined(InputFile *F, const WasmSymbol *Sym,
|
Symbol *addDefined(InputFile *F, const WasmSymbol *Sym,
|
||||||
|
@ -60,6 +61,7 @@ private:
|
||||||
std::pair<Symbol *, bool> insert(StringRef Name);
|
std::pair<Symbol *, bool> insert(StringRef Name);
|
||||||
|
|
||||||
llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;
|
llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;
|
||||||
|
std::vector<Symbol *> SymVector;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SymbolTable *Symtab;
|
extern SymbolTable *Symtab;
|
||||||
|
|
|
@ -111,8 +111,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<Symbol *> FunctionImports;
|
std::vector<const Symbol *> FunctionImports;
|
||||||
std::vector<Symbol *> GlobalImports;
|
std::vector<const Symbol *> GlobalImports;
|
||||||
|
std::vector<const Symbol *> DefinedGlobals;
|
||||||
|
|
||||||
// Elements that are used to construct the final output
|
// Elements that are used to construct the final output
|
||||||
std::string Header;
|
std::string Header;
|
||||||
|
@ -217,11 +218,14 @@ void Writer::createMemorySection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Writer::createGlobalSection() {
|
void Writer::createGlobalSection() {
|
||||||
|
if (DefinedGlobals.empty())
|
||||||
|
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, NumGlobals, "global count");
|
writeUleb128(OS, DefinedGlobals.size(), "global count");
|
||||||
for (const Symbol *Sym : Config->SyntheticGlobals) {
|
for (const Symbol *Sym : DefinedGlobals) {
|
||||||
WasmGlobal Global;
|
WasmGlobal Global;
|
||||||
Global.Type = WASM_TYPE_I32;
|
Global.Type = WASM_TYPE_I32;
|
||||||
Global.Mutable = Sym == Config->StackPointerSymbol;
|
Global.Mutable = Sym == Config->StackPointerSymbol;
|
||||||
|
@ -229,24 +233,6 @@ void Writer::createGlobalSection() {
|
||||||
Global.InitExpr.Value.Int32 = Sym->getVirtualAddress();
|
Global.InitExpr.Value.Int32 = Sym->getVirtualAddress();
|
||||||
writeGlobal(OS, Global);
|
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() {
|
void Writer::createTableSection() {
|
||||||
|
@ -261,35 +247,36 @@ void Writer::createTableSection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Writer::createExportSection() {
|
void Writer::createExportSection() {
|
||||||
// Memory is and main function are exported for executables.
|
|
||||||
bool ExportMemory = !Config->Relocatable && !Config->ImportMemory;
|
bool ExportMemory = !Config->Relocatable && !Config->ImportMemory;
|
||||||
bool ExportOther = true; // ??? TODO Config->Relocatable;
|
|
||||||
bool ExportHidden = Config->Relocatable;
|
|
||||||
Symbol *EntrySym = Symtab->find(Config->Entry);
|
Symbol *EntrySym = Symtab->find(Config->Entry);
|
||||||
bool ExportEntry = !Config->Relocatable && EntrySym && EntrySym->isDefined();
|
bool ExportEntry = !Config->Relocatable && EntrySym && EntrySym->isDefined();
|
||||||
|
bool ExportHidden = Config->EmitRelocs;
|
||||||
|
|
||||||
uint32_t NumExports = 0;
|
uint32_t NumExports = ExportMemory ? 1 : 0;
|
||||||
|
|
||||||
if (ExportMemory)
|
|
||||||
++NumExports;
|
|
||||||
|
|
||||||
|
std::vector<const Symbol *> SymbolExports;
|
||||||
if (ExportEntry)
|
if (ExportEntry)
|
||||||
++NumExports;
|
SymbolExports.emplace_back(EntrySym);
|
||||||
|
|
||||||
if (ExportOther) {
|
for (const Symbol *Sym : Symtab->getSymbols()) {
|
||||||
for (ObjFile *File : Symtab->ObjectFiles) {
|
if (Sym->isUndefined() || Sym->isGlobal())
|
||||||
for (Symbol *Sym : File->getSymbols()) {
|
continue;
|
||||||
if (!Sym->isFunction() || Sym->isLocal() || Sym->isUndefined() ||
|
if (Sym->isHidden() && !ExportHidden)
|
||||||
(Sym->isHidden() && !ExportHidden) || Sym->WrittenToSymtab)
|
continue;
|
||||||
continue;
|
if (ExportEntry && Sym == EntrySym)
|
||||||
if (Sym == EntrySym)
|
continue;
|
||||||
continue;
|
SymbolExports.emplace_back(Sym);
|
||||||
Sym->WrittenToSymtab = true;
|
|
||||||
++NumExports;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
if (!NumExports)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -306,34 +293,16 @@ void Writer::createExportSection() {
|
||||||
writeExport(OS, MemoryExport);
|
writeExport(OS, MemoryExport);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExportEntry) {
|
for (const Symbol *Sym : SymbolExports) {
|
||||||
WasmExport EntryExport;
|
log("Export: " + Sym->getName());
|
||||||
EntryExport.Name = Config->Entry;
|
WasmExport Export;
|
||||||
EntryExport.Kind = WASM_EXTERNAL_FUNCTION;
|
Export.Name = Sym->getName();
|
||||||
EntryExport.Index = EntrySym->getOutputIndex();
|
Export.Index = Sym->getOutputIndex();
|
||||||
writeExport(OS, EntryExport);
|
if (Sym->isFunction())
|
||||||
}
|
Export.Kind = WASM_EXTERNAL_FUNCTION;
|
||||||
|
else
|
||||||
if (ExportOther) {
|
Export.Kind = WASM_EXTERNAL_GLOBAL;
|
||||||
for (ObjFile *File : Symtab->ObjectFiles) {
|
writeExport(OS, Export);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,7 +526,6 @@ void Writer::createSections() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Writer::calculateOffsets() {
|
void Writer::calculateOffsets() {
|
||||||
NumGlobals = Config->SyntheticGlobals.size();
|
|
||||||
NumTableElems = InitialTableOffset;
|
NumTableElems = InitialTableOffset;
|
||||||
|
|
||||||
for (ObjFile *File : Symtab->ObjectFiles) {
|
for (ObjFile *File : Symtab->ObjectFiles) {
|
||||||
|
@ -568,13 +536,6 @@ void Writer::calculateOffsets() {
|
||||||
FunctionImports.size() - File->NumFunctionImports() + NumFunctions;
|
FunctionImports.size() - File->NumFunctionImports() + NumFunctions;
|
||||||
NumFunctions += WasmFile->functions().size();
|
NumFunctions += WasmFile->functions().size();
|
||||||
|
|
||||||
// Global Index
|
|
||||||
if (Config->EmitRelocs) {
|
|
||||||
File->GlobalIndexOffset =
|
|
||||||
GlobalImports.size() - File->NumGlobalImports() + NumGlobals;
|
|
||||||
NumGlobals += WasmFile->globals().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Memory
|
// Memory
|
||||||
if (WasmFile->memories().size()) {
|
if (WasmFile->memories().size()) {
|
||||||
if (WasmFile->memories().size() > 1) {
|
if (WasmFile->memories().size() > 1) {
|
||||||
|
@ -640,19 +601,31 @@ void Writer::calculateTypes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Writer::assignSymbolIndexes() {
|
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) {
|
for (ObjFile *File : Symtab->ObjectFiles) {
|
||||||
DEBUG(dbgs() << "assignSymbolIndexes: " << File->getName() << "\n");
|
DEBUG(dbgs() << "assignSymbolIndexes: " << File->getName() << "\n");
|
||||||
for (Symbol *Sym : File->getSymbols()) {
|
for (Symbol *Sym : File->getSymbols()) {
|
||||||
if (Sym->hasOutputIndex() || !Sym->isDefined())
|
if (Sym->hasOutputIndex() || !Sym->isDefined())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (Sym->getFile() && isa<ObjFile>(Sym->getFile())) {
|
if (Sym->isFunction()) {
|
||||||
auto *Obj = cast<ObjFile>(Sym->getFile());
|
if (Sym->getFile() && isa<ObjFile>(Sym->getFile())) {
|
||||||
if (Sym->isFunction())
|
auto *Obj = cast<ObjFile>(Sym->getFile());
|
||||||
Sym->setOutputIndex(Obj->FunctionIndexOffset +
|
Sym->setOutputIndex(Obj->FunctionIndexOffset +
|
||||||
Sym->getFunctionIndex());
|
Sym->getFunctionIndex());
|
||||||
else
|
}
|
||||||
Sym->setOutputIndex(Obj->GlobalIndexOffset + Sym->getGlobalIndex());
|
} else if (Config->EmitRelocs) {
|
||||||
|
DefinedGlobals.emplace_back(Sym);
|
||||||
|
Sym->setOutputIndex(GlobalIndex++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue