27 uintptr_t destinationAddress, uintptr_t destinationEnd) {
28 if (section && !section->addr) {
32 const auto type =
static_cast<AArch64Relocation
>(R_TYPE(rel.info));
33 if (type == R_AARCH64_NONE) {
37 loadBase = section ? section->addr - section->offset : 0;
39 ERROR(
"AArch64 relocation has no load base");
44 const uintptr_t place = loadBase + rel.offset;
45 const uintptr_t destination = destinationAddress ? destinationAddress : place;
46 const size_t symbolIndex = R_SYM(rel.info);
47 ElfSymbol_t* elfSymbols = m_pDynamicSymbolTable ? m_pDynamicSymbolTable : m_pSymbolTable;
48 const char* strings = m_pDynamicStringTable ? m_pDynamicStringTable : m_pStringTable;
50 size_t symbolSize = 0;
52 if (type != R_AARCH64_RELATIVE) {
54 ERROR(
"AArch64 relocation has no symbol table");
58 symbolSize = entry.size;
59 if (ST_TYPE(entry.info) == 3) {
60 if (!m_pSectionHeaders || entry.shndx >= m_nSectionHeaders) {
63 symbol = m_pSectionHeaders[entry.shndx].addr;
68 const char* name = strings + entry.name;
69 if (type == R_AARCH64_COPY) {
73 symbols = &m_SymbolTable;
79 if (!
symbol && ST_BIND(entry.info) != 2) {
80 WARNING(
"AArch64 relocation failed for symbol \"" << name <<
"\"");
86 size_t writeSize =
sizeof(uint64_t);
87 if (type == R_AARCH64_ABS32 || type == R_AARCH64_PREL32) {
88 writeSize =
sizeof(uint32_t);
89 }
else if (type == R_AARCH64_COPY) {
90 writeSize = symbolSize;
93 (destination > destinationEnd || destinationEnd - destination < writeSize)) {
94 ERROR(
"AArch64 relocation crosses the demand-page staging boundary");
98 const uint64_t addend =
static_cast<uint64_t
>(rel.addend);
101 case R_AARCH64_ABS64:
104 case R_AARCH64_ABS32:
107 ERROR(
"AArch64 ABS32 relocation overflows");
111 case R_AARCH64_PREL64:
112 value =
symbol + addend - place;
114 case R_AARCH64_PREL32:
115 value =
symbol + addend - place;
116 if (
static_cast<int64_t
>(value) < INT32_MIN ||
static_cast<int64_t
>(value) > INT32_MAX) {
117 ERROR(
"AArch64 PREL32 relocation overflows");
121 case R_AARCH64_GLOB_DAT:
122 case R_AARCH64_JUMP_SLOT:
125 case R_AARCH64_RELATIVE:
126 value = loadBase + addend;
130 ERROR(
"AArch64 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 AArch64 ELF relocation " <<
Dec << R_TYPE(rel.info));
142 if (writeSize ==
sizeof(uint32_t)) {
143 *
reinterpret_cast<uint32_t*
>(destination) =
static_cast<uint32_t
>(value);
145 *
reinterpret_cast<uint64_t*
>(destination) = value;
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)