blob: afff6fb747daff920ab05c2e32ab093cd297f609 [file] [log] [blame]
//===- Relocations.cpp ----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "Relocations.h"
#include "InputChunks.h"
#include "SyntheticSections.h"
using namespace llvm;
using namespace llvm::wasm;
using namespace lld;
using namespace lld::wasm;
static bool requiresGOTAccess(const Symbol *Sym) {
return Config->Pic && !Sym->isHidden() && !Sym->isLocal();
}
void lld::wasm::scanRelocations(InputChunk *Chunk) {
if (!Chunk->Live)
return;
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] =
Out.TypeSec->registerType(Types[Reloc.Index]);
File->TypeIsUsed[Reloc.Index] = true;
continue;
}
// Other relocation types all have a corresponding symbol
Symbol *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:
if (requiresGOTAccess(Sym))
break;
Out.ElemSec->addEntry(cast<FunctionSymbol>(Sym));
break;
case R_WASM_GLOBAL_INDEX_LEB:
if (!isa<GlobalSymbol>(Sym))
Out.ImportSec->addGOTEntry(Sym);
break;
case R_WASM_MEMORY_ADDR_SLEB:
case R_WASM_MEMORY_ADDR_LEB:
case R_WASM_MEMORY_ADDR_REL_SLEB:
if (!Config->Relocatable && Sym->isUndefined() && !Sym->isWeak()) {
error(toString(File) + ": cannot resolve relocation of type " +
relocTypeToString(Reloc.Type) +
" against undefined (non-weak) data symbol: " + toString(*Sym));
}
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:
// Certain relocation types can't be used when building PIC output,
// since they would require absolute symbol addresses at link time.
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.
if (requiresGOTAccess(Sym))
Out.ImportSec->addGOTEntry(Sym);
break;
}
}
}
}