20 #include "pedigree/kernel/Log.h" 21 #include "pedigree/kernel/linker/Elf.h" 22 #include "pedigree/kernel/linker/KernelElf.h" 23 #include "pedigree/kernel/processor/Processor.h" 28 #define R_PPC_ADDR32 1 29 #define R_PPC_ADDR24 2 30 #define R_PPC_ADDR16 3 31 #define R_PPC_ADDR16_LO 4 32 #define R_PPC_ADDR16_HI 5 33 #define R_PPC_ADDR16_HA 6 34 #define R_PPC_ADDR14 7 35 #define R_PPC_ADDR14_BRTAKEN 8 36 #define R_PPC_ADDR14_BRNTAKEN 9 37 #define R_PPC_REL24 10 38 #define R_PPC_REL14 11 39 #define R_PPC_REL14_BRTAKEN 12 40 #define R_PPC_REL14_BRNTAKEN 13 41 #define R_PPC_PLTREL24 18 43 #define R_PPC_JMP_SLOT 21 44 #define R_PPC_RELATIVE 22 45 #define R_PPC_REL32 26 46 #define R_PPC_PLT32 27 47 #define R_PPC_PLTREL32 28 48 #define R_PPC_UADDR32 24 49 #define R_PPC_UADDR16 25 50 #define R_PPC_REL32 26 51 #define R_PPC_SECTOFF 33 52 #define R_PPC_SECTOFF_LO 34 53 #define R_PPC_SECTOFF_HI 35 54 #define R_PPC_SECTOFF_HA 36 55 #define R_PPC_ADDR30 37 57 #define HA(x) (((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xFFFF) 58 #define WORD32(r, x) (x) 59 #define LOW24(r, x) (r | ((x << 2) & 0x03FFFFFC)) 60 #define HALF16(r, x) \ 61 ((x << 16) | (r & 0xFFFF)) // We deal with 32bit numbers, so we must keep 63 #define LOW14(r, x) (r | ((x << 2) & 0x0000FFFC)) 64 #define WORD30(r, x) (r | ((x << 2) & 0xFFFFFFFC)) 71 if (pSh && pSh->addr == 0)
75 uint32_t address = ((pSh) ? pSh->addr : loadBase) + rel.offset;
78 uint32_t A = rel.addend;
86 if (!m_pDynamicSymbolTable)
87 pSymbols =
reinterpret_cast<ElfSymbol_t *
>(m_pSymbolTable);
89 pSymbols = m_pDynamicSymbolTable;
91 const char *pStringTable = 0;
92 if (!m_pDynamicStringTable)
93 pStringTable =
reinterpret_cast<const char *
>(m_pStringTable);
95 pStringTable = m_pDynamicStringTable;
98 if (pSymbols && ELF32_ST_TYPE(pSymbols[ELF32_R_SYM(rel.info)].info) == 3)
102 int shndx = pSymbols[ELF32_R_SYM(rel.info)].shndx;
106 else if (ELF32_R_TYPE(rel.info) != R_PPC_RELATIVE)
109 const char *pStr = pStringTable + pSymbols[ELF32_R_SYM(rel.info)].name;
114 if (ELF32_R_TYPE(rel.info) == R_PPC_COPY)
119 WARNING(
"Relocation failed for symbol \"" << pStr <<
"\"");
122 if (S == 0 && (ELF32_R_TYPE(rel.info) != R_PPC_RELATIVE))
126 uint32_t B = loadBase;
128 uint32_t *pResult =
reinterpret_cast<uint32_t *
>(address);
129 uint32_t result = *pResult;
131 switch (ELF32_R_TYPE(rel.info))
137 result = WORD32(result, S + A);
140 result = LOW24(result, (S + A) >> 2);
144 result = HALF16(result, (S + A));
146 case R_PPC_ADDR16_LO:
147 result = HALF16(result, ((S + A) & 0xFFFF));
149 case R_PPC_ADDR16_HI:
150 result = HALF16(result, ((S + A) >> 16) & 0xFFFF);
152 case R_PPC_ADDR16_HA:
153 result = HALF16(result, HA((S + A)));
156 result = LOW14(result, (S + A) >> 2);
157 result &= ~(1 >> 10);
159 case R_PPC_ADDR14_BRTAKEN:
160 result = LOW14(result, (S + A) >> 2);
163 case R_PPC_ADDR14_BRNTAKEN:
164 result = LOW14(result, (S + A) >> 2);
165 result &= ~(1 >> 10);
168 result = *pResult + B;
171 result = LOW24(result, (S + A - P) >> 2);
174 result = LOW14(result, (S + A - P) >> 2);
175 result &= ~(1 >> 10);
177 case R_PPC_REL14_BRTAKEN:
178 result = LOW14(result, (S + A - P) >> 2);
181 case R_PPC_REL14_BRNTAKEN:
182 result = LOW14(result, (S + A - P) >> 2);
183 result &= ~(1 >> 10);
186 result = WORD32(result, S + A - P);
189 result = WORD30(result, (S + A - P) >> 2);
192 result = *
reinterpret_cast<uintptr_t *
>(S);
196 "Relocation not supported: " <<
Dec << ELF32_R_TYPE(rel.info));
203 Processor::flushDCacheAndInvalidateICache(
204 reinterpret_cast<uintptr_t>(pResult),
205 reinterpret_cast<uintptr_t>(pResult) + 4);
214 ERROR(
"The PPC architecture does not use REL entries!");
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)