1#include "pedigree/kernel/Log.h"
2#include "pedigree/kernel/linker/Elf.h"
3#include "pedigree/kernel/linker/KernelElf.h"
19 uintptr_t destinationAddress, uintptr_t destinationEnd) {
20 if ((section && !section->addr) || R_TYPE(rel.info) == R_ARM_NONE) {
23 if (!loadBase && section) {
24 loadBase = section->addr - section->offset;
27 ERROR(
"ARM relocation has no load base");
30 const uintptr_t place = loadBase + rel.offset;
31 const uintptr_t destination = destinationAddress ? destinationAddress : place;
32 if (destinationEnd && (destination > destinationEnd || destinationEnd - destination < 4)) {
33 ERROR(
"ARM REL relocation crosses the demand-page staging boundary");
36 const intptr_t addend = *
reinterpret_cast<const int32_t*
>(destination);
37 return applyArmRelocation(R_TYPE(rel.info), R_SYM(rel.info), rel.offset, addend, section, symbols,
38 loadBase, policy, destinationAddress, destinationEnd);
43 uintptr_t destinationAddress, uintptr_t destinationEnd) {
44 return applyArmRelocation(R_TYPE(rel.info), R_SYM(rel.info), rel.offset, rel.addend, section,
45 symbols, loadBase, policy, destinationAddress, destinationEnd);
48bool Elf::applyArmRelocation(Elf_Word type, Elf_Word symbolIndex, uintptr_t offset, intptr_t addend,
51 uintptr_t destinationEnd) {
52 if (section && !section->addr) {
55 if (type == R_ARM_NONE) {
59 loadBase = section ? section->addr - section->offset : 0;
61 ERROR(
"ARM relocation has no load base");
66 const uintptr_t place = loadBase + offset;
67 const uintptr_t destination = destinationAddress ? destinationAddress : place;
68 ElfSymbol_t* elfSymbols = m_pDynamicSymbolTable ? m_pDynamicSymbolTable : m_pSymbolTable;
69 const char* strings = m_pDynamicStringTable ? m_pDynamicStringTable : m_pStringTable;
71 size_t symbolSize = 0;
73 if (type != R_ARM_RELATIVE) {
75 ERROR(
"ARM relocation has no symbol table");
79 symbolSize = entry.size;
80 if (ST_TYPE(entry.info) == 3) {
81 if (!m_pSectionHeaders || entry.shndx >= m_nSectionHeaders) {
84 symbol = m_pSectionHeaders[entry.shndx].addr;
89 const char* name = strings + entry.name;
90 if (type == R_ARM_COPY) {
94 symbols = &m_SymbolTable;
100 if (!
symbol && ST_BIND(entry.info) != 2) {
101 WARNING(
"ARM relocation failed for symbol \"" << name <<
"\"");
107 const size_t writeSize = type == R_ARM_COPY ? symbolSize :
sizeof(uint32_t);
108 if (destinationEnd &&
109 (destination > destinationEnd || destinationEnd - destination < writeSize)) {
110 ERROR(
"ARM relocation crosses the demand-page staging boundary");
116 *
reinterpret_cast<uint32_t*
>(destination) =
symbol + addend;
119 *
reinterpret_cast<uint32_t*
>(destination) =
symbol + addend - place;
122 case R_ARM_JUMP_SLOT:
123 *
reinterpret_cast<uint32_t*
>(destination) =
symbol;
126 *
reinterpret_cast<uint32_t*
>(destination) = loadBase + addend;
130 ERROR(
"ARM COPY relocation has no source");
133 for (
size_t i = 0; i < symbolSize; ++i) {
134 reinterpret_cast<uint8_t*
>(destination)[i] =
reinterpret_cast<const uint8_t*
>(
symbol)[i];
138 ERROR(
"Unsupported ARM ELF relocation " <<
Dec << type);
bool applyRelocation(ElfRel_t rel, ElfSectionHeader_t *pSh, SymbolTable *pSymtab=0, uintptr_t loadBase=0, SymbolTable::Policy policy=SymbolTable::LocalFirst, uintptr_t destinationAddress=0, uintptr_t destinationEnd=0)
static KernelElf & instance()
uintptr_t EXPORTED_PUBLIC lookup(const HashedStringView &name, Elf *pElf, Policy policy=LocalFirst, Binding *pBinding=0)