mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-04-01 12:43:47 +00:00
[WebAssembly] Assign GOT entries symbols used in data relocations
Differential Revision: https://reviews.llvm.org/D60492 llvm-svn: 358090
This commit is contained in:
parent
ae6c9403d1
commit
0d9f609d82
@ -12,7 +12,7 @@ target triple = "wasm32-unknown-unknown"
|
||||
@data_addr = local_unnamed_addr global i32* @data, align 4
|
||||
@data_addr_external = local_unnamed_addr global i32* @data_external, align 4
|
||||
|
||||
define default i32 @foo() {
|
||||
define hidden i32 @foo() {
|
||||
entry:
|
||||
; To ensure we use __stack_pointer
|
||||
%ptr = alloca i32
|
||||
|
@ -327,17 +327,18 @@ void InputSegment::generateRelocationCode(raw_ostream &OS) const {
|
||||
break;
|
||||
case R_WASM_MEMORY_ADDR_I32: {
|
||||
Symbol *Sym = File->getSymbol(Rel);
|
||||
if (Sym->isUndefined()) {
|
||||
// Undefined addresses are accessed via imported GOT globals
|
||||
writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
|
||||
writeUleb128(OS, Sym->getGOTIndex(), "global index");
|
||||
} else {
|
||||
// Defined global data is accessed via known offset from __memory_base
|
||||
if (Sym->isLocal() || Sym->isHidden()) {
|
||||
// Hidden/Local data symbols are accessed via known offset from
|
||||
// __memory_base
|
||||
writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
|
||||
writeUleb128(OS, WasmSym::MemoryBase->getGlobalIndex(), "memory_base");
|
||||
writeU8(OS, WASM_OPCODE_I32_CONST, "CONST");
|
||||
writeSleb128(OS, File->calcNewValue(Rel), "new memory offset");
|
||||
writeU8(OS, WASM_OPCODE_I32_ADD, "ADD");
|
||||
} else {
|
||||
// Default data symbols are accessed via imported GOT globals
|
||||
writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
|
||||
writeUleb128(OS, Sym->getGOTIndex(), "global index");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1162,22 +1162,33 @@ void Writer::processRelocations(InputChunk *Chunk) {
|
||||
}
|
||||
|
||||
if (Config->Pic) {
|
||||
// Certain relocation types can't be used when building PIC output, since
|
||||
// they would require absolute symbol addresses at link time.
|
||||
switch (Reloc.Type) {
|
||||
case R_WASM_TABLE_INDEX_SLEB:
|
||||
case R_WASM_MEMORY_ADDR_SLEB:
|
||||
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: {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Writer::assignIndexes() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user