[WebAssembly] Update to match llvm changes to TABLE relocations
TABLE relocations now store the function that is being refered to indirectly. See rL323165. Also extend the call-indirect.ll a little. Based on a patch by Nicholas Wilson! llvm-svn: 323168
This commit is contained in:
parent
ac904d0e3a
commit
ab604a9882
|
@ -1,17 +1,18 @@
|
||||||
@indirect_bar = internal local_unnamed_addr global i32 ()* @bar, align 4
|
@indirect_bar = internal local_unnamed_addr global i64 ()* @bar, align 4
|
||||||
@indirect_foo = internal local_unnamed_addr global i32 ()* @foo, align 4
|
@indirect_foo = internal local_unnamed_addr global i32 ()* @foo, align 4
|
||||||
|
|
||||||
declare i32 @foo() local_unnamed_addr
|
declare i32 @foo() local_unnamed_addr
|
||||||
|
|
||||||
define i32 @bar() {
|
define i64 @bar() {
|
||||||
entry:
|
entry:
|
||||||
ret i32 1
|
ret i64 1
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @call_bar_indirect() local_unnamed_addr #1 {
|
define void @call_bar_indirect() local_unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
%0 = load i32 ()*, i32 ()** @indirect_bar, align 4
|
%0 = load i64 ()*, i64 ()** @indirect_bar, align 4
|
||||||
%1 = load i32 ()*, i32 ()** @indirect_foo, align 4
|
%1 = load i32 ()*, i32 ()** @indirect_foo, align 4
|
||||||
%call = tail call i32 %0() #2
|
%call0 = tail call i64 %0() #2
|
||||||
|
%call1 = tail call i32 %1() #2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,21 +38,24 @@ define void @call_ptr(i64 (i64)* %arg) {
|
||||||
; CHECK-NEXT: - Type: TYPE
|
; CHECK-NEXT: - Type: TYPE
|
||||||
; CHECK-NEXT: Signatures:
|
; CHECK-NEXT: Signatures:
|
||||||
; CHECK-NEXT: - Index: 0
|
; CHECK-NEXT: - Index: 0
|
||||||
; CHECK-NEXT: ReturnType: I32
|
; CHECK-NEXT: ReturnType: I64
|
||||||
; CHECK-NEXT: ParamTypes:
|
; CHECK-NEXT: ParamTypes:
|
||||||
; CHECK-NEXT: - Index: 1
|
; CHECK-NEXT: - Index: 1
|
||||||
; CHECK-NEXT: ReturnType: NORESULT
|
; CHECK-NEXT: ReturnType: NORESULT
|
||||||
; CHECK-NEXT: ParamTypes:
|
; CHECK-NEXT: ParamTypes:
|
||||||
; CHECK-NEXT: - Index: 2
|
; CHECK-NEXT: - Index: 2
|
||||||
|
; CHECK-NEXT: ReturnType: I32
|
||||||
|
; CHECK-NEXT: ParamTypes:
|
||||||
|
; CHECK-NEXT: - Index: 3
|
||||||
; CHECK-NEXT: ReturnType: NORESULT
|
; CHECK-NEXT: ReturnType: NORESULT
|
||||||
; CHECK-NEXT: ParamTypes:
|
; CHECK-NEXT: ParamTypes:
|
||||||
; CHECK-NEXT: - I32
|
; CHECK-NEXT: - I32
|
||||||
; CHECK-NEXT: - Index: 3
|
; CHECK-NEXT: - Index: 4
|
||||||
; CHECK-NEXT: ReturnType: I64
|
; CHECK-NEXT: ReturnType: I64
|
||||||
; CHECK-NEXT: ParamTypes:
|
; CHECK-NEXT: ParamTypes:
|
||||||
; CHECK-NEXT: - I64
|
; CHECK-NEXT: - I64
|
||||||
; CHECK-NEXT: - Type: FUNCTION
|
; CHECK-NEXT: - Type: FUNCTION
|
||||||
; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 0, 2, 1 ]
|
; CHECK-NEXT: FunctionTypes: [ 0, 1, 2, 2, 3, 1 ]
|
||||||
; CHECK-NEXT: - Type: TABLE
|
; CHECK-NEXT: - Type: TABLE
|
||||||
; CHECK-NEXT: Tables:
|
; CHECK-NEXT: Tables:
|
||||||
; CHECK-NEXT: - ElemType: ANYFUNC
|
; CHECK-NEXT: - ElemType: ANYFUNC
|
||||||
|
@ -110,19 +113,21 @@ define void @call_ptr(i64 (i64)* %arg) {
|
||||||
; CHECK-NEXT: Functions:
|
; CHECK-NEXT: Functions:
|
||||||
; CHECK-NEXT: - Index: 0
|
; CHECK-NEXT: - Index: 0
|
||||||
; CHECK-NEXT: Locals:
|
; CHECK-NEXT: Locals:
|
||||||
; CHECK-NEXT: Body: 41010B
|
; CHECK-NEXT: Body: 42010B
|
||||||
; CHECK-NEXT: - Index: 1
|
; CHECK-NEXT: - Index: 1
|
||||||
; CHECK-NEXT: Locals:
|
; CHECK-NEXT: Locals:
|
||||||
; CHECK-NEXT: Body: 410028028088808000118080808000001A0B
|
; CHECK-NEXT: - Type: I32
|
||||||
|
; CHECK-NEXT: Count: 1
|
||||||
|
; CHECK-NEXT: Body: 4100280284888080002100410028028088808000118080808000001A2000118280808000001A0B
|
||||||
; CHECK-NEXT: - Index: 2
|
; CHECK-NEXT: - Index: 2
|
||||||
; CHECK-NEXT: Locals:
|
; CHECK-NEXT: Locals:
|
||||||
; CHECK-NEXT: Body: 41020B
|
; CHECK-NEXT: Body: 41020B
|
||||||
; CHECK-NEXT: - Index: 3
|
; CHECK-NEXT: - Index: 3
|
||||||
; CHECK-NEXT: Locals:
|
; CHECK-NEXT: Locals:
|
||||||
; CHECK-NEXT: Body: 410028028888808000118080808000001A41000B
|
; CHECK-NEXT: Body: 410028028888808000118280808000001A41000B
|
||||||
; CHECK-NEXT: - Index: 4
|
; CHECK-NEXT: - Index: 4
|
||||||
; CHECK-NEXT: Locals:
|
; CHECK-NEXT: Locals:
|
||||||
; CHECK-NEXT: Body: 42012000118380808000001A0B
|
; CHECK-NEXT: Body: 42012000118480808000001A0B
|
||||||
; CHECK-NEXT: - Index: 5
|
; CHECK-NEXT: - Index: 5
|
||||||
; CHECK-NEXT: Locals:
|
; CHECK-NEXT: Locals:
|
||||||
; CHECK-NEXT: Body: 0B
|
; CHECK-NEXT: Body: 0B
|
||||||
|
|
|
@ -385,13 +385,13 @@
|
||||||
; RELOC-NEXT: Index: 5
|
; RELOC-NEXT: Index: 5
|
||||||
; RELOC-NEXT: Offset: 0x0000006A
|
; RELOC-NEXT: Offset: 0x0000006A
|
||||||
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
|
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
|
||||||
; RELOC-NEXT: Index: 3
|
; RELOC-NEXT: Index: 9
|
||||||
; RELOC-NEXT: Offset: 0x00000073
|
; RELOC-NEXT: Offset: 0x00000073
|
||||||
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
|
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
|
||||||
; RELOC-NEXT: Index: 4
|
; RELOC-NEXT: Index: 10
|
||||||
; RELOC-NEXT: Offset: 0x0000007C
|
; RELOC-NEXT: Offset: 0x0000007C
|
||||||
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
|
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
|
||||||
; RELOC-NEXT: Index: 5
|
; RELOC-NEXT: Index: 11
|
||||||
; RELOC-NEXT: Offset: 0x00000085
|
; RELOC-NEXT: Offset: 0x00000085
|
||||||
; RELOC-NEXT: Functions:
|
; RELOC-NEXT: Functions:
|
||||||
; RELOC-NEXT: - Index: 0
|
; RELOC-NEXT: - Index: 0
|
||||||
|
|
|
@ -177,7 +177,7 @@ entry:
|
||||||
; CHECK-NEXT: - Type: DATA
|
; CHECK-NEXT: - Type: DATA
|
||||||
; CHECK-NEXT: Relocations:
|
; CHECK-NEXT: Relocations:
|
||||||
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
|
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
|
||||||
; CHECK-NEXT: Index: 0
|
; CHECK-NEXT: Index: 4
|
||||||
; CHECK-NEXT: Offset: 0x00000012
|
; CHECK-NEXT: Offset: 0x00000012
|
||||||
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
|
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
|
||||||
; CHECK-NEXT: Index: 1
|
; CHECK-NEXT: Index: 1
|
||||||
|
|
|
@ -48,23 +48,19 @@ static void applyRelocation(uint8_t *Buf, const OutputRelocation &Reloc) {
|
||||||
switch (Reloc.Reloc.Type) {
|
switch (Reloc.Reloc.Type) {
|
||||||
case R_WEBASSEMBLY_TYPE_INDEX_LEB:
|
case R_WEBASSEMBLY_TYPE_INDEX_LEB:
|
||||||
case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
|
case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
|
||||||
|
case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
|
||||||
ExistingValue = decodeULEB128(Buf);
|
ExistingValue = decodeULEB128(Buf);
|
||||||
|
// Additional check to verify that the existing value that the location
|
||||||
|
// matches our expectations.
|
||||||
if (ExistingValue != Reloc.Reloc.Index) {
|
if (ExistingValue != Reloc.Reloc.Index) {
|
||||||
DEBUG(dbgs() << "existing value: " << decodeULEB128(Buf) << "\n");
|
DEBUG(dbgs() << "existing value: " << decodeULEB128(Buf) << "\n");
|
||||||
assert(decodeULEB128(Buf) == Reloc.Reloc.Index);
|
assert(decodeULEB128(Buf) == Reloc.Reloc.Index);
|
||||||
}
|
}
|
||||||
LLVM_FALLTHROUGH;
|
LLVM_FALLTHROUGH;
|
||||||
case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
||||||
case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
|
|
||||||
encodeULEB128(Reloc.Value, Buf, 5);
|
encodeULEB128(Reloc.Value, Buf, 5);
|
||||||
break;
|
break;
|
||||||
case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
|
case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
|
||||||
ExistingValue = decodeSLEB128(Buf);
|
|
||||||
if (ExistingValue != Reloc.Reloc.Index) {
|
|
||||||
DEBUG(dbgs() << "existing value: " << decodeSLEB128(Buf) << "\n");
|
|
||||||
assert(decodeSLEB128(Buf) == Reloc.Reloc.Index);
|
|
||||||
}
|
|
||||||
LLVM_FALLTHROUGH;
|
|
||||||
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
||||||
encodeSLEB128(static_cast<int32_t>(Reloc.Value), Buf, 5);
|
encodeSLEB128(static_cast<int32_t>(Reloc.Value), Buf, 5);
|
||||||
break;
|
break;
|
||||||
|
@ -111,17 +107,7 @@ void InputChunk::calcRelocations() {
|
||||||
if (Config->Relocatable)
|
if (Config->Relocatable)
|
||||||
NewReloc.NewIndex = File->calcNewIndex(Reloc);
|
NewReloc.NewIndex = File->calcNewIndex(Reloc);
|
||||||
|
|
||||||
switch (Reloc.Type) {
|
NewReloc.Value = File->calcNewValue(Reloc);
|
||||||
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
|
||||||
case R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
|
||||||
case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
|
||||||
NewReloc.Value = File->getRelocatedAddress(Reloc.Index) + Reloc.Addend;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NewReloc.Value = File->calcNewIndex(Reloc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
OutRelocations.emplace_back(NewReloc);
|
OutRelocations.emplace_back(NewReloc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getOutputOffset() const { return OutputOffset; }
|
uint32_t getOutputOffset() const { return OutputOffset; }
|
||||||
|
ArrayRef<WasmRelocation> getRelocations() const { return Relocations; }
|
||||||
|
|
||||||
virtual StringRef getComdat() const = 0;
|
virtual StringRef getComdat() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -47,11 +47,10 @@ void ObjFile::dumpInfo() const {
|
||||||
" Total Functions : " + Twine(FunctionSymbols.size()) + "\n" +
|
" Total Functions : " + Twine(FunctionSymbols.size()) + "\n" +
|
||||||
" Total Globals : " + Twine(GlobalSymbols.size()) + "\n" +
|
" Total Globals : " + Twine(GlobalSymbols.size()) + "\n" +
|
||||||
" Function Imports : " + Twine(NumFunctionImports) + "\n" +
|
" Function Imports : " + Twine(NumFunctionImports) + "\n" +
|
||||||
" Global Imports : " + Twine(NumGlobalImports) + "\n" +
|
" Global Imports : " + Twine(NumGlobalImports) + "\n");
|
||||||
" Table Entries : " + Twine(TableSymbols.size()) + "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ObjFile::getRelocatedAddress(uint32_t GlobalIndex) const {
|
uint32_t ObjFile::relocateVirtualAddress(uint32_t GlobalIndex) const {
|
||||||
return GlobalSymbols[GlobalIndex]->getVirtualAddress();
|
return GlobalSymbols[GlobalIndex]->getVirtualAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +67,7 @@ uint32_t ObjFile::relocateTypeIndex(uint32_t Original) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ObjFile::relocateTableIndex(uint32_t Original) const {
|
uint32_t ObjFile::relocateTableIndex(uint32_t Original) const {
|
||||||
Symbol *Sym = TableSymbols[Original];
|
Symbol *Sym = FunctionSymbols[Original];
|
||||||
uint32_t Index = Sym->hasTableIndex() ? Sym->getTableIndex() : 0;
|
uint32_t Index = Sym->hasTableIndex() ? Sym->getTableIndex() : 0;
|
||||||
DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " << Original
|
DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " << Original
|
||||||
<< " -> " << Index << "\n");
|
<< " -> " << Index << "\n");
|
||||||
|
@ -92,10 +91,9 @@ uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
|
||||||
case R_WEBASSEMBLY_TYPE_INDEX_LEB:
|
case R_WEBASSEMBLY_TYPE_INDEX_LEB:
|
||||||
return relocateTypeIndex(Reloc.Index);
|
return relocateTypeIndex(Reloc.Index);
|
||||||
case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
|
case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
|
||||||
return relocateFunctionIndex(Reloc.Index);
|
|
||||||
case R_WEBASSEMBLY_TABLE_INDEX_I32:
|
case R_WEBASSEMBLY_TABLE_INDEX_I32:
|
||||||
case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
|
case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
|
||||||
return relocateTableIndex(Reloc.Index);
|
return relocateFunctionIndex(Reloc.Index);
|
||||||
case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
|
case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
|
||||||
case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
||||||
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
||||||
|
@ -106,6 +104,27 @@ uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Translate from the relocation's index into the final linked output value.
|
||||||
|
uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
|
||||||
|
switch (Reloc.Type) {
|
||||||
|
case R_WEBASSEMBLY_TABLE_INDEX_I32:
|
||||||
|
case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
|
||||||
|
return relocateTableIndex(Reloc.Index);
|
||||||
|
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
||||||
|
case R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
||||||
|
case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
||||||
|
return relocateVirtualAddress(Reloc.Index) + Reloc.Addend;
|
||||||
|
case R_WEBASSEMBLY_TYPE_INDEX_LEB:
|
||||||
|
return relocateTypeIndex(Reloc.Index);
|
||||||
|
case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
|
||||||
|
return relocateFunctionIndex(Reloc.Index);
|
||||||
|
case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
|
||||||
|
return relocateGlobalIndex(Reloc.Index);
|
||||||
|
default:
|
||||||
|
llvm_unreachable("unknown relocation type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ObjFile::parse() {
|
void ObjFile::parse() {
|
||||||
// Parse a memory buffer as a wasm file.
|
// Parse a memory buffer as a wasm file.
|
||||||
DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");
|
DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");
|
||||||
|
@ -271,24 +290,6 @@ void ObjFile::initializeSymbols() {
|
||||||
for (size_t I = 0; I < GlobalSymbols.size(); ++I)
|
for (size_t I = 0; I < GlobalSymbols.size(); ++I)
|
||||||
assert(GlobalSymbols[I] != nullptr););
|
assert(GlobalSymbols[I] != nullptr););
|
||||||
|
|
||||||
// Populate `TableSymbols` with all symbols that are called indirectly
|
|
||||||
uint32_t SegmentCount = WasmObj->elements().size();
|
|
||||||
if (SegmentCount) {
|
|
||||||
if (SegmentCount > 1)
|
|
||||||
fatal(getName() + ": contains more than one element segment");
|
|
||||||
const WasmElemSegment &Segment = WasmObj->elements()[0];
|
|
||||||
if (Segment.Offset.Opcode != WASM_OPCODE_I32_CONST)
|
|
||||||
fatal(getName() + ": unsupported element segment");
|
|
||||||
if (Segment.TableIndex != 0)
|
|
||||||
fatal(getName() + ": unsupported table index in elem segment");
|
|
||||||
uint32_t Offset = Segment.Offset.Value.Int32;
|
|
||||||
TableSymbols.resize(Offset);
|
|
||||||
TableSymbols.reserve(Offset + Segment.Functions.size());
|
|
||||||
for (uint64_t FunctionIndex : Segment.Functions)
|
|
||||||
TableSymbols.push_back(FunctionSymbols[FunctionIndex]);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG(dbgs() << "TableSymbols: " << TableSymbols.size() << "\n");
|
|
||||||
DEBUG(dbgs() << "Functions : " << FunctionSymbols.size() << "\n");
|
DEBUG(dbgs() << "Functions : " << FunctionSymbols.size() << "\n");
|
||||||
DEBUG(dbgs() << "Globals : " << GlobalSymbols.size() << "\n");
|
DEBUG(dbgs() << "Globals : " << GlobalSymbols.size() << "\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,8 +94,8 @@ public:
|
||||||
void dumpInfo() const;
|
void dumpInfo() const;
|
||||||
|
|
||||||
uint32_t relocateFunctionIndex(uint32_t Original) const;
|
uint32_t relocateFunctionIndex(uint32_t Original) const;
|
||||||
uint32_t getRelocatedAddress(uint32_t Index) const;
|
|
||||||
uint32_t calcNewIndex(const WasmRelocation &Reloc) const;
|
uint32_t calcNewIndex(const WasmRelocation &Reloc) const;
|
||||||
|
uint32_t calcNewValue(const WasmRelocation &Reloc) const;
|
||||||
|
|
||||||
const WasmSection *CodeSection = nullptr;
|
const WasmSection *CodeSection = nullptr;
|
||||||
const WasmSection *DataSection = nullptr;
|
const WasmSection *DataSection = nullptr;
|
||||||
|
@ -104,10 +104,14 @@ public:
|
||||||
std::vector<InputSegment *> Segments;
|
std::vector<InputSegment *> Segments;
|
||||||
std::vector<InputFunction *> Functions;
|
std::vector<InputFunction *> Functions;
|
||||||
|
|
||||||
ArrayRef<Symbol *> getSymbols() { return Symbols; }
|
ArrayRef<Symbol *> getSymbols() const { return Symbols; }
|
||||||
ArrayRef<Symbol *> getTableSymbols() { return TableSymbols; }
|
|
||||||
|
Symbol *getFunctionSymbol(uint32_t Index) const {
|
||||||
|
return FunctionSymbols[Index];
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint32_t relocateVirtualAddress(uint32_t Index) const;
|
||||||
uint32_t relocateTypeIndex(uint32_t Original) const;
|
uint32_t relocateTypeIndex(uint32_t Original) const;
|
||||||
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;
|
||||||
|
@ -134,9 +138,6 @@ private:
|
||||||
// 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 *> GlobalSymbols;
|
||||||
|
|
||||||
// List of all indirect symbols indexed by table index space.
|
|
||||||
std::vector<Symbol *> TableSymbols;
|
|
||||||
|
|
||||||
uint32_t NumGlobalImports = 0;
|
uint32_t NumGlobalImports = 0;
|
||||||
uint32_t NumFunctionImports = 0;
|
uint32_t NumFunctionImports = 0;
|
||||||
std::unique_ptr<WasmObjectFile> WasmObj;
|
std::unique_ptr<WasmObjectFile> WasmObj;
|
||||||
|
|
|
@ -744,12 +744,26 @@ void Writer::assignIndexes() {
|
||||||
|
|
||||||
for (ObjFile *File : Symtab->ObjectFiles) {
|
for (ObjFile *File : Symtab->ObjectFiles) {
|
||||||
DEBUG(dbgs() << "Table Indexes: " << File->getName() << "\n");
|
DEBUG(dbgs() << "Table Indexes: " << File->getName() << "\n");
|
||||||
for (Symbol *Sym : File->getTableSymbols()) {
|
auto HandleTableRelocs = [&](InputChunk *Chunk) {
|
||||||
if (!Sym || Sym->hasTableIndex() || !Sym->hasOutputIndex())
|
if (Chunk->Discarded)
|
||||||
|
return;
|
||||||
|
for (const WasmRelocation& Reloc : Chunk->getRelocations()) {
|
||||||
|
if (Reloc.Type != R_WEBASSEMBLY_TABLE_INDEX_I32 &&
|
||||||
|
Reloc.Type != R_WEBASSEMBLY_TABLE_INDEX_SLEB)
|
||||||
|
continue;
|
||||||
|
DEBUG(dbgs() << "getFunctionSymbol: " << Reloc.Index << "\n");
|
||||||
|
Symbol *Sym = File->getFunctionSymbol(Reloc.Index);
|
||||||
|
DEBUG(dbgs() << "gotFunctionSymbol: " << Sym->getName() << "\n");
|
||||||
|
if (Sym->hasTableIndex() || !Sym->hasOutputIndex())
|
||||||
continue;
|
continue;
|
||||||
Sym->setTableIndex(TableIndex++);
|
Sym->setTableIndex(TableIndex++);
|
||||||
IndirectFunctions.emplace_back(Sym);
|
IndirectFunctions.emplace_back(Sym);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
for (InputFunction* Function : File->Functions)
|
||||||
|
HandleTableRelocs(Function);
|
||||||
|
for (InputSegment* Segment : File->Segments)
|
||||||
|
HandleTableRelocs(Segment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue