20 #include "pedigree/kernel/linker/Elf.h" 21 #include "pedigree/kernel/Log.h" 22 #include "pedigree/kernel/linker/KernelElf.h" 24 #define VERBOSE_X64_ELF 0 27 #define VERBOSE_NOTICE(x) NOTICE(x) 29 #define VERBOSE_NOTICE(x) 34 #define R_X86_64_NONE 0 36 #define R_X86_64_PC32 2 37 #define R_X86_64_GOT32 3 38 #define R_X86_64_PLT32 4 39 #define R_X86_64_COPY 5 40 #define R_X86_64_GLOB_DAT 6 41 #define R_X86_64_JUMP_SLOT 7 42 #define R_X86_64_RELATIVE 8 43 #define R_X86_64_GOTPCREL 9 44 #define R_X86_64_32 10 45 #define R_X86_64_32S 11 46 #define R_X86_64_PC64 24 47 #define R_X86_64_GOTOFF64 25 48 #define R_X86_64_GOTPC32 26 49 #define R_X86_64_GOT64 27 50 #define R_X86_64_GOTPCREL64 28 51 #define R_X86_64_GOTPC64 29 52 #define R_X86_64_GOTPLT64 30 53 #define R_X86_64_PLTOFF64 31 59 ERROR(
"The X64 architecture does not use REL entries!");
68 if (pSh && pSh->addr == 0)
74 if (R_TYPE(rel.info) == R_X86_64_NONE)
81 loadBase = pSh ? pSh->addr - pSh->offset : 0;
84 ERROR(
"Cannot apply relocation, no load base given.");
91 uint64_t address = loadBase + rel.offset;
94 Elf_Sxword A = rel.addend;
102 if (!m_pDynamicSymbolTable)
104 pSymbols = m_pSymbolTable;
108 pSymbols = m_pDynamicSymbolTable;
111 const char *pStringTable = 0;
112 if (!m_pDynamicStringTable)
114 pStringTable =
reinterpret_cast<const char *
>(m_pStringTable);
118 pStringTable = m_pDynamicStringTable;
121 String symbolName(
"(unknown)");
123 size_t symbolSize = 0;
126 if (pSymbols && ST_TYPE(pSymbols[R_SYM(rel.info)].info) == 3)
130 int shndx = pSymbols[R_SYM(rel.info)].shndx;
132 S = pReferencedSh->addr;
133 symbolSize = pSymbols[R_SYM(rel.info)].size;
135 else if (pSymbols && R_TYPE(rel.info) != R_X86_64_RELATIVE)
139 const char *pStr = pStringTable + pSymbols[R_SYM(rel.info)].name;
142 pSymtab = &m_SymbolTable;
144 if (R_TYPE(rel.info) == R_X86_64_COPY)
151 String(pStr),
this, policy);
154 if (S == 0 && ST_BIND(pSymbols[R_SYM(rel.info)].info) == 2)
163 "Relocation failed for symbol \"" 164 << pStr <<
"\" (relocation=" << R_TYPE(rel.info) <<
")");
166 "Relocation at " <<
Hex << address <<
" (offset=" << rel.offset
171 symbolSize = pSymbols[R_SYM(rel.info)].size;
174 if (S == 0 && (R_TYPE(rel.info) != R_X86_64_RELATIVE))
180 uint64_t B = loadBase;
182 uint64_t *pResult =
reinterpret_cast<uint64_t *
>(address);
183 uint64_t result = *pResult;
186 uint8_t r_type = R_TYPE(rel.info);
189 VERBOSE_NOTICE(
"Relocation for " << symbolName);
190 VERBOSE_NOTICE(
"A=" <<
Hex << A <<
" B=" << B <<
" S=" << S <<
" P=" << P);
195 VERBOSE_NOTICE(
"R_X86_64_NONE");
198 VERBOSE_NOTICE(
"R_X86_64_64");
202 VERBOSE_NOTICE(
"R_X86_64_PC32");
203 result = (result & 0xFFFFFFFF00000000) | ((S + A - P) & 0xFFFFFFFF);
206 VERBOSE_NOTICE(
"R_X86_64_COPY");
209 ERROR(
"Cannot perform a R_X86_64_COPY relocation for a weak " 214 NOTICE(
"Copy needed, " << symbolSize <<
" bytes wanted");
215 result = *
reinterpret_cast<uintptr_t *
>(S);
217 case R_X86_64_JUMP_SLOT:
218 case R_X86_64_GLOB_DAT:
219 VERBOSE_NOTICE(
"R_X86_64_JUMP_SLOT/R_X86_64_GLOB_DAT");
223 case R_X86_64_RELATIVE:
224 VERBOSE_NOTICE(
"R_X86_64_RELATIVE");
229 VERBOSE_NOTICE(
"R_X86_64_32(S)");
232 if ((r_type == R_X86_64_32) && ((tmp & 0xFFFFFFFF00000000ULL) != 0))
235 "Relocation for symbol '" << symbolName
236 <<
"' will be truncated to fit!");
238 else if (r_type == R_X86_64_32S)
241 uint64_t sign = (tmp & 0x80000000ULL) >> 31ULL;
242 uint64_t top = (tmp & 0xFFFFFFFF00000000ULL) >> 32ULL;
243 if ((sign * 0xFFFFFFFFUL) != top)
246 "Relocation for symbol '" 248 <<
"' will be truncated to fit (sign-extension was " 253 result = (result & 0xFFFFFFFF00000000) | (tmp & 0xFFFFFFFFUL);
257 "Relocation not supported for symbol \"" 258 << symbolName <<
"\": " <<
Dec << R_TYPE(rel.info));
261 VERBOSE_NOTICE(
"result=" <<
Hex << result);
uintptr_t EXPORTED_PUBLIC lookup(const HashedStringView &name, Elf *pElf, Policy policy=LocalFirst, Binding *pBinding=0)
static KernelElf & instance()
bool applyRelocation(ElfRel_t rel, ElfSectionHeader_t *pSh, SymbolTable *pSymtab=0, uintptr_t loadBase=0, SymbolTable::Policy policy=SymbolTable::LocalFirst)