mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[WebAssembly] Fix PIC/GOT codegen for wasm64
__table_base is know 64-bit, since in LLVM it represents a function pointer offset __table_base32 is a copy in wasm32 for use in elem init expr, since no truncation may be used there. New reloc R_WASM_TABLE_INDEX_REL_SLEB64 added Differential Revision: https://reviews.llvm.org/D101784
This commit is contained in:
parent
0da7fd24df
commit
1184fb03b6
@ -26,3 +26,4 @@ WASM_RELOC(R_WASM_TABLE_NUMBER_LEB, 20)
|
||||
WASM_RELOC(R_WASM_MEMORY_ADDR_TLS_SLEB, 21)
|
||||
WASM_RELOC(R_WASM_FUNCTION_OFFSET_I64, 22)
|
||||
WASM_RELOC(R_WASM_MEMORY_ADDR_LOCREL_I32, 23)
|
||||
WASM_RELOC(R_WASM_TABLE_INDEX_REL_SLEB64, 24)
|
||||
|
@ -528,6 +528,7 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
|
||||
}
|
||||
|
||||
if (Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB ||
|
||||
Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB64 ||
|
||||
Type == wasm::R_WASM_TABLE_INDEX_SLEB ||
|
||||
Type == wasm::R_WASM_TABLE_INDEX_SLEB64 ||
|
||||
Type == wasm::R_WASM_TABLE_INDEX_I32 ||
|
||||
@ -590,6 +591,7 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry,
|
||||
|
||||
switch (RelEntry.Type) {
|
||||
case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
|
||||
case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:
|
||||
case wasm::R_WASM_TABLE_INDEX_SLEB:
|
||||
case wasm::R_WASM_TABLE_INDEX_SLEB64:
|
||||
case wasm::R_WASM_TABLE_INDEX_I32:
|
||||
@ -598,7 +600,8 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry,
|
||||
const MCSymbolWasm *Base =
|
||||
cast<MCSymbolWasm>(Layout.getBaseSymbol(*RelEntry.Symbol));
|
||||
assert(Base->isFunction());
|
||||
if (RelEntry.Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB)
|
||||
if (RelEntry.Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB ||
|
||||
RelEntry.Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB64)
|
||||
return TableIndices[Base] - InitialTableOffset;
|
||||
else
|
||||
return TableIndices[Base];
|
||||
@ -742,6 +745,7 @@ void WasmObjectWriter::applyRelocations(
|
||||
writePatchableSLEB<5>(Stream, Value, Offset);
|
||||
break;
|
||||
case wasm::R_WASM_TABLE_INDEX_SLEB64:
|
||||
case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:
|
||||
case wasm::R_WASM_MEMORY_ADDR_SLEB64:
|
||||
case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
|
||||
writePatchableSLEB<10>(Stream, Value, Offset);
|
||||
@ -1757,7 +1761,8 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
|
||||
Rel.Type != wasm::R_WASM_TABLE_INDEX_I64 &&
|
||||
Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB &&
|
||||
Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB64 &&
|
||||
Rel.Type != wasm::R_WASM_TABLE_INDEX_REL_SLEB)
|
||||
Rel.Type != wasm::R_WASM_TABLE_INDEX_REL_SLEB &&
|
||||
Rel.Type != wasm::R_WASM_TABLE_INDEX_REL_SLEB64)
|
||||
return;
|
||||
assert(Rel.Symbol->isFunction());
|
||||
const MCSymbolWasm *Base =
|
||||
|
@ -870,6 +870,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
|
||||
case wasm::R_WASM_TABLE_INDEX_I32:
|
||||
case wasm::R_WASM_TABLE_INDEX_I64:
|
||||
case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
|
||||
case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:
|
||||
if (!isValidFunctionSymbol(Reloc.Index))
|
||||
return make_error<GenericBinaryError>(
|
||||
"invalid relocation function index", object_error::parse_failed);
|
||||
|
@ -76,7 +76,8 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
|
||||
return wasm::R_WASM_GLOBAL_INDEX_LEB;
|
||||
case MCSymbolRefExpr::VK_WASM_TBREL:
|
||||
assert(SymA.isFunction());
|
||||
return wasm::R_WASM_TABLE_INDEX_REL_SLEB;
|
||||
return is64Bit() ? wasm::R_WASM_TABLE_INDEX_REL_SLEB64
|
||||
: wasm::R_WASM_TABLE_INDEX_REL_SLEB;
|
||||
case MCSymbolRefExpr::VK_WASM_TLSREL:
|
||||
return wasm::R_WASM_MEMORY_ADDR_TLS_SLEB;
|
||||
case MCSymbolRefExpr::VK_WASM_MBREL:
|
||||
|
@ -107,9 +107,8 @@ MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol(
|
||||
strcmp(Name, "__stack_pointer") == 0 || strcmp(Name, "__tls_base") == 0;
|
||||
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
|
||||
WasmSym->setGlobalType(wasm::WasmGlobalType{
|
||||
uint8_t(Subtarget.hasAddr64() && strcmp(Name, "__table_base") != 0
|
||||
? wasm::WASM_TYPE_I64
|
||||
: wasm::WASM_TYPE_I32),
|
||||
uint8_t(Subtarget.hasAddr64() ? wasm::WASM_TYPE_I64
|
||||
: wasm::WASM_TYPE_I32),
|
||||
Mutable});
|
||||
return WasmSym;
|
||||
}
|
||||
|
209
test/MC/WebAssembly/reloc-pic64.s
Normal file
209
test/MC/WebAssembly/reloc-pic64.s
Normal file
@ -0,0 +1,209 @@
|
||||
# RUN: llvm-mc -triple=wasm64-unknown-unknown -filetype=obj < %s | obj2yaml | FileCheck %s
|
||||
# RUN: llvm-mc -triple=wasm64-unknown-unknown -mattr=+reference-types -filetype=obj < %s | obj2yaml | FileCheck --check-prefix=REF %s
|
||||
|
||||
# Verify that @GOT relocation entries result in R_WASM_GLOBAL_INDEX_LEB against
|
||||
# against the corrsponding function or data symbol and that the corresponding
|
||||
# data symbols are imported as a wasm globals.
|
||||
|
||||
load_default_data:
|
||||
.functype load_default_data () -> (i32)
|
||||
global.get default_data@GOT
|
||||
i32.load 0
|
||||
end_function
|
||||
|
||||
load_default_func:
|
||||
.functype load_default_func () -> (i32)
|
||||
global.get default_func@GOT
|
||||
i32.load 0
|
||||
end_function
|
||||
|
||||
load_hidden_data:
|
||||
.functype load_hidden_data () -> (i64)
|
||||
global.get __memory_base
|
||||
i64.const .L.hidden_data@MBREL
|
||||
i64.add
|
||||
end_function
|
||||
|
||||
load_hidden_func:
|
||||
.functype load_hidden_func () -> (i64)
|
||||
global.get __table_base
|
||||
i64.const hidden_func@TBREL
|
||||
i64.add
|
||||
end_function
|
||||
|
||||
hidden_func:
|
||||
.functype hidden_func () -> (i32)
|
||||
i32.const 0
|
||||
end_function
|
||||
|
||||
.section .rodata.hidden_data,"",@
|
||||
.L.hidden_data:
|
||||
.int8 100
|
||||
.size .L.hidden_data, 1
|
||||
|
||||
#.hidden hidden_func
|
||||
#.hidden hidden_data
|
||||
.size default_data, 4
|
||||
.functype default_func () -> (i32)
|
||||
|
||||
# CHECK: --- !WASM
|
||||
# CHECK-NEXT: FileHeader:
|
||||
# CHECK-NEXT: Version: 0x1
|
||||
# CHECK-NEXT: Sections:
|
||||
# CHECK-NEXT: - Type: TYPE
|
||||
# CHECK-NEXT: Signatures:
|
||||
# CHECK-NEXT: - Index: 0
|
||||
# CHECK-NEXT: ParamTypes: []
|
||||
# CHECK-NEXT: ReturnTypes:
|
||||
# CHECK-NEXT: - I32
|
||||
# CHECK-NEXT: - Index: 1
|
||||
# CHECK-NEXT: ParamTypes: []
|
||||
# CHECK-NEXT: ReturnTypes:
|
||||
# CHECK-NEXT: - I64
|
||||
# CHECK-NEXT: - Type: IMPORT
|
||||
# CHECK-NEXT: Imports:
|
||||
# CHECK-NEXT: - Module: env
|
||||
# CHECK-NEXT: Field: __linear_memory
|
||||
# CHECK-NEXT: Kind: MEMORY
|
||||
# CHECK-NEXT: Memory:
|
||||
# CHECK-NEXT: Flags: [ IS_64 ]
|
||||
# CHECK-NEXT: Minimum: 0x1
|
||||
# CHECK-NEXT: - Module: env
|
||||
# CHECK-NEXT: Field: default_func
|
||||
# CHECK-NEXT: Kind: FUNCTION
|
||||
# CHECK-NEXT: SigIndex: 0
|
||||
# CHECK-NEXT: - Module: env
|
||||
# CHECK-NEXT: Field: __indirect_function_table
|
||||
# CHECK-NEXT: Kind: TABLE
|
||||
# CHECK-NEXT: Table:
|
||||
# CHECK-NEXT: Index: 0
|
||||
# CHECK-NEXT: ElemType: FUNCREF
|
||||
# CHECK-NEXT: Limits:
|
||||
# CHECK-NEXT: Minimum: 0x1
|
||||
# CHECK-NEXT: - Module: GOT.mem
|
||||
# CHECK-NEXT: Field: default_data
|
||||
# CHECK-NEXT: Kind: GLOBAL
|
||||
# CHECK-NEXT: GlobalType: I32
|
||||
# CHECK-NEXT: GlobalMutable: true
|
||||
# CHECK-NEXT: - Module: GOT.func
|
||||
# CHECK-NEXT: Field: default_func
|
||||
# CHECK-NEXT: Kind: GLOBAL
|
||||
# CHECK-NEXT: GlobalType: I32
|
||||
# CHECK-NEXT: GlobalMutable: true
|
||||
# CHECK-NEXT: - Type: FUNCTION
|
||||
# CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 0 ]
|
||||
# CHECK-NEXT: - Type: ELEM
|
||||
# CHECK-NEXT: Segments:
|
||||
# CHECK-NEXT: Offset:
|
||||
# CHECK-NEXT: Opcode: I32_CONST
|
||||
# CHECK-NEXT: Value: 1
|
||||
# CHECK-NEXT: Functions: [ 5 ]
|
||||
# CHECK-NEXT: - Type: DATACOUNT
|
||||
# CHECK-NEXT: Count: 1
|
||||
# CHECK-NEXT: - Type: CODE
|
||||
# CHECK-NEXT: Relocations:
|
||||
# CHECK-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
|
||||
# CHECK-NEXT: Index: 1
|
||||
# CHECK-NEXT: Offset: 0x4
|
||||
# CHECK-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
|
||||
# CHECK-NEXT: Index: 3
|
||||
# CHECK-NEXT: Offset: 0x10
|
||||
# CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
|
||||
# CHECK-NEXT: Index: 5
|
||||
# CHECK-NEXT: Offset: 0x1C
|
||||
# CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_REL_SLEB
|
||||
# CHECK-NEXT: Index: 6
|
||||
# CHECK-NEXT: Offset: 0x22
|
||||
# CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
|
||||
# CHECK-NEXT: Index: 8
|
||||
# CHECK-NEXT: Offset: 0x31
|
||||
# CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_REL_SLEB
|
||||
# CHECK-NEXT: Index: 9
|
||||
# CHECK-NEXT: Offset: 0x37
|
||||
# CHECK-NEXT: Functions:
|
||||
# CHECK-NEXT: - Index: 1
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 2380808080002802000B
|
||||
# CHECK-NEXT: - Index: 2
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 2381808080002802000B
|
||||
# CHECK-NEXT: - Index: 3
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 23808080800042808080808080808080007C0B
|
||||
# CHECK-NEXT: - Index: 4
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 23808080800042808080808080808080007C0B
|
||||
# CHECK-NEXT: - Index: 5
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 41000B
|
||||
# CHECK-NEXT: - Type: DATA
|
||||
# CHECK-NEXT: Segments:
|
||||
# CHECK-NEXT: - SectionOffset: 6
|
||||
# CHECK-NEXT: InitFlags: 0
|
||||
# CHECK-NEXT: Offset:
|
||||
# CHECK-NEXT: Opcode: I64_CONST
|
||||
# CHECK-NEXT: Value: 0
|
||||
# CHECK-NEXT: Content: '64'
|
||||
# CHECK-NEXT: - Type: CUSTOM
|
||||
# CHECK-NEXT: Name: linking
|
||||
# CHECK-NEXT: Version: 2
|
||||
# CHECK-NEXT: SymbolTable:
|
||||
# CHECK-NEXT: - Index: 0
|
||||
# CHECK-NEXT: Kind: FUNCTION
|
||||
# CHECK-NEXT: Name: load_default_data
|
||||
# CHECK-NEXT: Flags: [ BINDING_LOCAL ]
|
||||
# CHECK-NEXT: Function: 1
|
||||
# CHECK-NEXT: - Index: 1
|
||||
# CHECK-NEXT: Kind: DATA
|
||||
# CHECK-NEXT: Name: default_data
|
||||
# CHECK-NEXT: Flags: [ UNDEFINED ]
|
||||
# CHECK-NEXT: - Index: 2
|
||||
# CHECK-NEXT: Kind: FUNCTION
|
||||
# CHECK-NEXT: Name: load_default_func
|
||||
# CHECK-NEXT: Flags: [ BINDING_LOCAL ]
|
||||
# CHECK-NEXT: Function: 2
|
||||
# CHECK-NEXT: - Index: 3
|
||||
# CHECK-NEXT: Kind: FUNCTION
|
||||
# CHECK-NEXT: Name: default_func
|
||||
# CHECK-NEXT: Flags: [ UNDEFINED ]
|
||||
# CHECK-NEXT: Function: 0
|
||||
# CHECK-NEXT: - Index: 4
|
||||
# CHECK-NEXT: Kind: FUNCTION
|
||||
# CHECK-NEXT: Name: load_hidden_data
|
||||
# CHECK-NEXT: Flags: [ BINDING_LOCAL ]
|
||||
# CHECK-NEXT: Function: 3
|
||||
# CHECK-NEXT: - Index: 5
|
||||
# CHECK-NEXT: Kind: DATA
|
||||
# CHECK-NEXT: Name: __memory_base
|
||||
# CHECK-NEXT: Flags: [ UNDEFINED ]
|
||||
# CHECK-NEXT: - Index: 6
|
||||
# CHECK-NEXT: Kind: DATA
|
||||
# CHECK-NEXT: Name: .L.hidden_data
|
||||
# CHECK-NEXT: Flags: [ BINDING_LOCAL ]
|
||||
# CHECK-NEXT: Segment: 0
|
||||
# CHECK-NEXT: Size: 1
|
||||
# CHECK-NEXT: - Index: 7
|
||||
# CHECK-NEXT: Kind: FUNCTION
|
||||
# CHECK-NEXT: Name: load_hidden_func
|
||||
# CHECK-NEXT: Flags: [ BINDING_LOCAL ]
|
||||
# CHECK-NEXT: Function: 4
|
||||
# CHECK-NEXT: - Index: 8
|
||||
# CHECK-NEXT: Kind: DATA
|
||||
# CHECK-NEXT: Name: __table_base
|
||||
# CHECK-NEXT: Flags: [ UNDEFINED ]
|
||||
# CHECK-NEXT: - Index: 9
|
||||
# CHECK-NEXT: Kind: FUNCTION
|
||||
# CHECK-NEXT: Name: hidden_func
|
||||
# CHECK-NEXT: Flags: [ BINDING_LOCAL ]
|
||||
# CHECK-NEXT: Function: 5
|
||||
# REF: - Index: 10
|
||||
# REF-NEXT: Kind: TABLE
|
||||
# REF-NEXT: Name: __indirect_function_table
|
||||
# REF-NEXT: Flags: [ UNDEFINED, NO_STRIP ]
|
||||
# REF-NEXT: Table: 0
|
||||
# CHECK-NEXT: SegmentInfo:
|
||||
# CHECK-NEXT: - Index: 0
|
||||
# CHECK-NEXT: Name: .rodata.hidden_data
|
||||
# CHECK-NEXT: Alignment: 0
|
||||
# CHECK-NEXT: Flags: [ ]
|
||||
# CHECK-NEXT: ...
|
Loading…
Reference in New Issue
Block a user