//===- 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 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(Sym)); break; case R_WASM_GLOBAL_INDEX_LEB: if (!isa(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; } } } }