[WebAssembly] Don't generate unused table entries.
When generating PIC output only relocations of type R_WASM_TABLE_INDEX_REL_SLEB should generate table entries. R_WASM_TABLE_INDEX_I32 get resolved at runtime via the auto-generated __wasm_apply_relocs functions. R_WASM_TABLE_INDEX_SLEB are not allowed in PIC code. Differential Revision: https://reviews.llvm.org/D61539 llvm-svn: 360165
This commit is contained in:
parent
3044ac058b
commit
b33fdb7768
|
@ -38,7 +38,7 @@ define void @_start() {
|
|||
; CHECK-NEXT: Table:
|
||||
; CHECK-NEXT: ElemType: FUNCREF
|
||||
; CHECK-NEXT: Limits:
|
||||
; CHECK-NEXT: Initial: 0x00000001
|
||||
; CHECK-NEXT: Initial: 0x00000000
|
||||
; CHECK-NEXT: - Module: env
|
||||
; CHECK-NEXT: Field: __memory_base
|
||||
; CHECK-NEXT: Kind: GLOBAL
|
||||
|
|
|
@ -54,7 +54,7 @@ declare void @func_external()
|
|||
; CHECK-NEXT: Name: dylink
|
||||
; CHECK-NEXT: MemorySize: 24
|
||||
; CHECK-NEXT: MemoryAlignment: 2
|
||||
; CHECK-NEXT: TableSize: 3
|
||||
; CHECK-NEXT: TableSize: 1
|
||||
; CHECK-NEXT: TableAlignment: 0
|
||||
; CHECK-NEXT: Needed: []
|
||||
; CHECK-NEXT: - Type: TYPE
|
||||
|
@ -74,7 +74,7 @@ declare void @func_external()
|
|||
; CHECK-NEXT: Table:
|
||||
; CHECK-NEXT: ElemType: FUNCREF
|
||||
; CHECK-NEXT: Limits:
|
||||
; CHECK-NEXT: Initial: 0x00000003
|
||||
; CHECK-NEXT: Initial: 0x00000001
|
||||
; CHECK-NEXT: - Module: env
|
||||
; CHECK-NEXT: Field: __stack_pointer
|
||||
; CHECK-NEXT: Kind: GLOBAL
|
||||
|
@ -124,7 +124,7 @@ declare void @func_external()
|
|||
; CHECK-NEXT: - Offset:
|
||||
; CHECK-NEXT: Opcode: GLOBAL_GET
|
||||
; CHECK-NEXT: Index: 2
|
||||
; CHECK-NEXT: Functions: [ 5, 3, 0 ]
|
||||
; CHECK-NEXT: Functions: [ 5 ]
|
||||
|
||||
; check the generated code in __wasm_call_ctors and __wasm_apply_relocs functions
|
||||
; TODO(sbc): Disassemble and verify instructions.
|
||||
|
@ -136,7 +136,7 @@ declare void @func_external()
|
|||
; CHECK-NEXT: Body: 10020B
|
||||
; CHECK-NEXT: - Index: 2
|
||||
; CHECK-NEXT: Locals: []
|
||||
; CHECK-NEXT: Body: 230141046A230241016A360200230141086A23043602002301410C6A230141006A360200230141106A2303360200230141146A230541046A3602000B
|
||||
; CHECK-NEXT: Body: 230141046A230241006A360200230141086A23043602002301410C6A230141006A360200230141106A2303360200230141146A230541046A3602000B
|
||||
|
||||
; check the data segment initialized with __memory_base global as offset
|
||||
|
||||
|
@ -147,4 +147,4 @@ declare void @func_external()
|
|||
; CHECK-NEXT: Offset:
|
||||
; CHECK-NEXT: Opcode: GLOBAL_GET
|
||||
; CHECK-NEXT: Index: 1
|
||||
; CHECK-NEXT: Content: '020000000100000002000000000000000000000000000000'
|
||||
; CHECK-NEXT: Content: '020000000000000000000000000000000000000000000000'
|
||||
|
|
|
@ -171,6 +171,8 @@ uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
|
|||
case R_WASM_TABLE_INDEX_I32:
|
||||
case R_WASM_TABLE_INDEX_SLEB:
|
||||
case R_WASM_TABLE_INDEX_REL_SLEB:
|
||||
if (Config->Pic && !getFunctionSymbol(Reloc.Index)->hasTableIndex())
|
||||
return 0;
|
||||
return getFunctionSymbol(Reloc.Index)->getTableIndex();
|
||||
case R_WASM_MEMORY_ADDR_SLEB:
|
||||
case R_WASM_MEMORY_ADDR_I32:
|
||||
|
|
|
@ -1148,35 +1148,40 @@ void Writer::processRelocations(InputChunk *Chunk) {
|
|||
ObjFile *File = Chunk->File;
|
||||
ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
|
||||
for (const WasmRelocation &Reloc : Chunk->getRelocations()) {
|
||||
if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) {
|
||||
// Mark target type as live
|
||||
File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
|
||||
File->TypeIsUsed[Reloc.Index] = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Other relocation types all have a corresponding symbol
|
||||
auto *Sym = File->getSymbols()[Reloc.Index];
|
||||
switch (Reloc.Type) {
|
||||
case R_WASM_TABLE_INDEX_I32:
|
||||
case R_WASM_TABLE_INDEX_SLEB:
|
||||
case R_WASM_TABLE_INDEX_REL_SLEB: {
|
||||
FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
|
||||
if (Sym->hasTableIndex() || !Sym->hasFunctionIndex())
|
||||
continue;
|
||||
Sym->setTableIndex(TableBase + IndirectFunctions.size());
|
||||
IndirectFunctions.emplace_back(Sym);
|
||||
if (Config->Pic && Reloc.Type != R_WASM_TABLE_INDEX_REL_SLEB)
|
||||
break;
|
||||
auto *F = cast<FunctionSymbol>(Sym);
|
||||
if (F->hasTableIndex() || !F->hasFunctionIndex())
|
||||
break;
|
||||
F->setTableIndex(TableBase + IndirectFunctions.size());
|
||||
IndirectFunctions.emplace_back(F);
|
||||
break;
|
||||
}
|
||||
case R_WASM_TYPE_INDEX_LEB:
|
||||
// Mark target type as live
|
||||
File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
|
||||
File->TypeIsUsed[Reloc.Index] = true;
|
||||
break;
|
||||
case R_WASM_GLOBAL_INDEX_LEB: {
|
||||
auto* Sym = File->getSymbols()[Reloc.Index];
|
||||
case R_WASM_GLOBAL_INDEX_LEB:
|
||||
if (!isa<GlobalSymbol>(Sym) && !Sym->isInGOT()) {
|
||||
Sym->setGOTIndex(NumImportedGlobals++);
|
||||
GOTSymbols.push_back(Sym);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R_WASM_MEMORY_ADDR_SLEB:
|
||||
case R_WASM_MEMORY_ADDR_LEB:
|
||||
case R_WASM_MEMORY_ADDR_REL_SLEB: {
|
||||
case R_WASM_MEMORY_ADDR_REL_SLEB:
|
||||
if (!Config->Relocatable) {
|
||||
auto* Sym = File->getSymbols()[Reloc.Index];
|
||||
if (Sym->isUndefined() && !Sym->isWeak()) {
|
||||
error(toString(File) + ": cannot resolve relocation of type " +
|
||||
relocTypeToString(Reloc.Type) +
|
||||
|
@ -1185,34 +1190,29 @@ void Writer::processRelocations(InputChunk *Chunk) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Config->Pic) {
|
||||
switch (Reloc.Type) {
|
||||
case R_WASM_TABLE_INDEX_SLEB:
|
||||
case R_WASM_MEMORY_ADDR_SLEB:
|
||||
case R_WASM_MEMORY_ADDR_LEB: {
|
||||
case R_WASM_MEMORY_ADDR_LEB:
|
||||
// Certain relocation types can't be used when building PIC output, since
|
||||
// they would require absolute symbol addresses at link time.
|
||||
Symbol *Sym = File->getSymbols()[Reloc.Index];
|
||||
error(toString(File) + ": relocation " +
|
||||
relocTypeToString(Reloc.Type) + " cannot be used againt symbol " +
|
||||
toString(*Sym) + "; recompile with -fPIC");
|
||||
break;
|
||||
}
|
||||
case R_WASM_TABLE_INDEX_I32:
|
||||
case R_WASM_MEMORY_ADDR_I32: {
|
||||
case R_WASM_MEMORY_ADDR_I32:
|
||||
// These relocation types are only present in the data section and
|
||||
// will be converted into code by `generateRelocationCode`. This code
|
||||
// requires the symbols to have GOT entires.
|
||||
auto* Sym = File->getSymbols()[Reloc.Index];
|
||||
if (!Sym->isHidden() && !Sym->isLocal() && !Sym->isInGOT()) {
|
||||
Sym->setGOTIndex(NumImportedGlobals++);
|
||||
GOTSymbols.push_back(Sym);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue