[WebAssembly] Assign GOT entries symbols used in data relocations

Differential Revision: https://reviews.llvm.org/D60492

llvm-svn: 358090
This commit is contained in:
Sam Clegg 2019-04-10 15:06:17 +00:00
parent ae6c9403d1
commit 0d9f609d82
3 changed files with 22 additions and 10 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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() {