forked from OSchip/llvm-project
87 lines
2.9 KiB
C++
87 lines
2.9 KiB
C++
|
//===- 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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|