1 //===- Relocations.cpp ----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "Relocations.h" 10 11 #include "InputChunks.h" 12 #include "SyntheticSections.h" 13 14 using namespace llvm; 15 using namespace llvm::wasm; 16 17 using namespace lld; 18 using namespace lld::wasm; 19 20 static bool requiresGOTAccess(const Symbol *Sym) { 21 return Config->Pic && !Sym->isHidden() && !Sym->isLocal(); 22 } 23 24 void lld::wasm::scanRelocations(InputChunk *Chunk) { 25 if (!Chunk->Live) 26 return; 27 ObjFile *File = Chunk->File; 28 ArrayRef<WasmSignature> Types = File->getWasmObj()->types(); 29 for (const WasmRelocation &Reloc : Chunk->getRelocations()) { 30 if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) { 31 // Mark target type as live 32 File->TypeMap[Reloc.Index] = 33 Out.TypeSec->registerType(Types[Reloc.Index]); 34 File->TypeIsUsed[Reloc.Index] = true; 35 continue; 36 } 37 38 // Other relocation types all have a corresponding symbol 39 Symbol *Sym = File->getSymbols()[Reloc.Index]; 40 41 switch (Reloc.Type) { 42 case R_WASM_TABLE_INDEX_I32: 43 case R_WASM_TABLE_INDEX_SLEB: 44 case R_WASM_TABLE_INDEX_REL_SLEB: 45 if (requiresGOTAccess(Sym)) 46 break; 47 Out.ElemSec->addEntry(cast<FunctionSymbol>(Sym)); 48 break; 49 case R_WASM_GLOBAL_INDEX_LEB: 50 if (!isa<GlobalSymbol>(Sym)) 51 Out.ImportSec->addGOTEntry(Sym); 52 break; 53 case R_WASM_MEMORY_ADDR_SLEB: 54 case R_WASM_MEMORY_ADDR_LEB: 55 case R_WASM_MEMORY_ADDR_REL_SLEB: 56 if (!Config->Relocatable && Sym->isUndefined() && !Sym->isWeak()) { 57 error(toString(File) + ": cannot resolve relocation of type " + 58 relocTypeToString(Reloc.Type) + 59 " against undefined (non-weak) data symbol: " + toString(*Sym)); 60 } 61 break; 62 } 63 64 if (Config->Pic) { 65 switch (Reloc.Type) { 66 case R_WASM_TABLE_INDEX_SLEB: 67 case R_WASM_MEMORY_ADDR_SLEB: 68 case R_WASM_MEMORY_ADDR_LEB: 69 // Certain relocation types can't be used when building PIC output, 70 // since they would require absolute symbol addresses at link time. 71 error(toString(File) + ": relocation " + relocTypeToString(Reloc.Type) + 72 " cannot be used againt symbol " + toString(*Sym) + 73 "; recompile with -fPIC"); 74 break; 75 case R_WASM_TABLE_INDEX_I32: 76 case R_WASM_MEMORY_ADDR_I32: 77 // These relocation types are only present in the data section and 78 // will be converted into code by `generateRelocationCode`. This code 79 // requires the symbols to have GOT entires. 80 if (requiresGOTAccess(Sym)) 81 Out.ImportSec->addGOTEntry(Sym); 82 break; 83 } 84 } 85 } 86 } 87