20 #include "pedigree/kernel/linker/Elf.h" 21 #include "pedigree/kernel/Log.h" 22 #include "pedigree/kernel/linker/KernelElf.h" 23 #include "pedigree/kernel/utilities/utility.h" 30 #define R_X86_64_NONE 0 32 #define R_X86_64_PC32 2 33 #define R_X86_64_GOT32 3 34 #define R_X86_64_PLT32 4 35 #define R_X86_64_COPY 5 36 #define R_X86_64_GLOB_DAT 6 37 #define R_X86_64_JUMP_SLOT 7 38 #define R_X86_64_RELATIVE 8 39 #define R_X86_64_GOTPCREL 9 40 #define R_X86_64_32 10 41 #define R_X86_64_32S 11 42 #define R_X86_64_PC64 24 43 #define R_X86_64_GOTOFF64 25 44 #define R_X86_64_GOTPC32 26 45 #define R_X86_64_GOT64 27 46 #define R_X86_64_GOTPCREL64 28 47 #define R_X86_64_GOTPC64 29 48 #define R_X86_64_GOTPLT64 30 49 #define R_X86_64_PLTOFF64 31 51 #define TWO_GIGABYTES 0x80000000ULL 54 checkPc32Displacement(uint64_t S, uint64_t A, uint64_t P, uint64_t &diff)
56 if (abs_difference(S + A, P) >= 0x80000000ULL)
61 diff = (((S + A) - P) & 0xFFFFFFFFULL);
77 if (pSh && pSh->addr == 0)
81 if (R_TYPE(rel.info) == R_X86_64_NONE)
85 uint64_t address = ((pSh) ? pSh->addr : loadBase) + rel.offset;
88 uint64_t A = rel.addend;
96 if (!m_pDynamicSymbolTable)
97 pSymbols = m_pSymbolTable;
99 pSymbols = m_pDynamicSymbolTable;
101 const char *pStringTable = 0;
102 if (!m_pDynamicStringTable)
103 pStringTable =
reinterpret_cast<const char *
>(m_pStringTable);
105 pStringTable = m_pDynamicStringTable;
107 String symbolName(
"(unknown)");
110 if (pSymbols && ST_TYPE(pSymbols[R_SYM(rel.info)].info) == 3)
114 int shndx = pSymbols[R_SYM(rel.info)].shndx;
118 else if (R_TYPE(rel.info) != R_X86_64_RELATIVE)
121 const char *pStr = pStringTable + pSymbols[R_SYM(rel.info)].name;
126 if (R_TYPE(rel.info) == R_X86_64_COPY)
133 void *pSym = __pedigree_hosted::dlsym(RTLD_DEFAULT, pStr);
136 S =
reinterpret_cast<uint64_t
>(pSym);
143 "Relocation failed for symbol \"" 144 << pStr <<
"\" (relocation=" << R_TYPE(rel.info) <<
")");
146 "Relocation at " << address <<
" (offset=" << rel.offset
152 WARNING(
"Weak relocation == 0 [undefined] for \"" << pStr <<
"\".");
157 if (S == 0 && (R_TYPE(rel.info) != R_X86_64_RELATIVE))
163 uint64_t B = loadBase;
165 uint64_t *pResult =
reinterpret_cast<uint64_t *
>(address);
166 uint64_t result = *pResult;
168 switch (R_TYPE(rel.info))
178 if (!checkPc32Displacement(S, A, P, diff))
180 ERROR(
"PC32 relocation with >2GB displacement - not possible.");
181 ERROR(
"Symbol is " << symbolName <<
" at " <<
Hex << S);
184 result = (result & 0xFFFFFFFF00000000ULL) | diff;
188 result = (S + A) - P;
191 result = *
reinterpret_cast<uintptr_t *
>(S);
193 case R_X86_64_JUMP_SLOT:
194 case R_X86_64_GLOB_DAT:
197 case R_X86_64_RELATIVE:
203 (result & 0xFFFFFFFF00000000ULL) | ((S + A) & 0xFFFFFFFFULL);
207 "Relocation not supported for symbol \"" 208 << symbolName <<
"\": " <<
Dec << R_TYPE(rel.info));
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)