File indexing completed on 2024-05-12 05:43:31
0001 /* 0002 Copyright (C) 2015 Volker Krause <vkrause@kde.org> 0003 0004 This program is free software; you can redistribute it and/or modify it 0005 under the terms of the GNU Library General Public License as published by 0006 the Free Software Foundation; either version 2 of the License, or (at your 0007 option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, but WITHOUT 0010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0012 License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program. If not, see <https://www.gnu.org/licenses/>. 0016 */ 0017 0018 #include "relocationprinter.h" 0019 0020 #include <elf/elfrelocationentry.h> 0021 #include <elf/elfrelocationsection.h> 0022 #include <elf/elffile.h> 0023 #include <elf/elfheader.h> 0024 0025 #include <QByteArray> 0026 0027 #include <elf.h> 0028 0029 // Fix build on FreeBSD 12, which does not include these ELF relocation 0030 // types; they're standard, and were added to FreeBSD 13 in 0031 // https://cgit.freebsd.org/src/commit/?id=f7d181543fd96a89b84878ddb2d5ac010fadd9b8 0032 #ifndef R_386_32PLT 0033 #define R_386_32PLT 11 0034 #define R_386_16 20 0035 #define R_386_PC16 21 0036 #define R_386_8 22 0037 #define R_386_PC8 23 0038 #define R_386_SIZE32 38 0039 #define R_386_TLS_GOTDESC 39 0040 #define R_386_TLS_DESC_CALL 40 0041 #define R_386_TLS_DESC 41 0042 #define R_386_GOT32X 43 0043 #define R_X86_64_RELATIVE64 38 0044 /* 39 and 40 were BND-related, already decomissioned */ 0045 #define R_X86_64_GOTPCRELX 41 0046 #define R_X86_64_REX_GOTPCRELX 42 0047 #endif 0048 0049 struct RelocType 0050 { 0051 uint32_t id; 0052 const char* label; 0053 const char* desc; 0054 }; 0055 0056 #define RT(type, desc) { type, #type, desc } 0057 0058 static const RelocType reloc_types_i386[] { 0059 RT(R_386_NONE, "No reloc"), 0060 RT(R_386_32, "Direct 32 bit"), 0061 RT(R_386_PC32, "PC relative 32 bit"), 0062 RT(R_386_GOT32, "32 bit GOT entry"), 0063 RT(R_386_PLT32, "32 bit PLT address"), 0064 RT(R_386_COPY, "Copy symbol at runtime"), 0065 RT(R_386_GLOB_DAT, "Create GOT entry"), 0066 RT(R_386_JMP_SLOT, "Create PLT entry"), 0067 RT(R_386_RELATIVE, "Adjust by program base"), 0068 RT(R_386_GOTOFF, "32 bit offset to GOT"), 0069 RT(R_386_GOTPC, "32 bit PC relative offset to GOT"), 0070 RT(R_386_32PLT, ""), 0071 RT(R_386_TLS_TPOFF, "Offset in static TLS block"), 0072 RT(R_386_TLS_IE, "Address of GOT entry for static TLS block offset"), 0073 RT(R_386_TLS_GOTIE, "GOT entry for static TLS block offset"), 0074 RT(R_386_TLS_LE, "Offset relative to static TLS block"), 0075 RT(R_386_TLS_GD, "Direct 32 bit for GNU version of general dynamic thread local data"), 0076 RT(R_386_TLS_LDM, "Direct 32 bit for GNU version of local dynamic thread local data in LE code"), 0077 RT(R_386_16, ""), 0078 RT(R_386_PC16, ""), 0079 RT(R_386_8, ""), 0080 RT(R_386_PC8, ""), 0081 RT(R_386_TLS_GD_32, "Direct 32 bit for general dynamic thread local data"), 0082 RT(R_386_TLS_GD_PUSH, "Tag for pushl in GD TLS code"), 0083 RT(R_386_TLS_GD_CALL, "Relocation for call to __tls_get_addr()"), 0084 RT(R_386_TLS_GD_POP, "Tag for popl in GD TLS code"), 0085 RT(R_386_TLS_LDM_32, "Direct 32 bit for local dynamic thread local data in LE code"), 0086 RT(R_386_TLS_LDM_PUSH, "Tag for pushl in LDM TLS code"), 0087 RT(R_386_TLS_LDM_CALL, "Relocation for call to __tls_get_addr() in LDM code"), 0088 RT(R_386_TLS_LDM_POP, "Tag for popl in LDM TLS code"), 0089 RT(R_386_TLS_LDO_32, "Offset relative to TLS block"), 0090 RT(R_386_TLS_IE_32, "GOT entry for negated static TLS block offset"), 0091 RT(R_386_TLS_LE_32, "Negated offset relative to static TLS block"), 0092 RT(R_386_TLS_DTPMOD32, "ID of module containing symbol"), 0093 RT(R_386_TLS_DTPOFF32, "Offset in TLS block"), 0094 RT(R_386_TLS_TPOFF32, "Negated offset in static TLS block"), 0095 #ifdef R_386_SIZE32 0096 RT(R_386_SIZE32, "32-bit symbol size"), 0097 #endif 0098 RT(R_386_TLS_GOTDESC, "GOT offset for TLS descriptor."), 0099 RT(R_386_TLS_DESC_CALL, "Marker of call through TLS descriptor for relaxation."), 0100 RT(R_386_TLS_DESC, "TLS descriptor containing pointer to code and to argument, returning the TLS offset for the symbol."), 0101 RT(R_386_IRELATIVE, "Adjust indirectly by program base") 0102 }; 0103 0104 static const RelocType reloc_types_arm[] { 0105 RT(R_ARM_NONE, "No reloc"), 0106 RT(R_ARM_PC24, "Deprecated PC relative 26 bit branch"), 0107 RT(R_ARM_ABS32, "Direct 32 bit"), 0108 RT(R_ARM_REL32, "PC relative 32 bit"), 0109 RT(R_ARM_PC13, "PC13"), 0110 RT(R_ARM_ABS16, "Direct 16 bit"), 0111 RT(R_ARM_ABS12, "Direct 12 bit"), 0112 RT(R_ARM_THM_ABS5, "Direct & 0x7C (LDR, STR)"), 0113 RT(R_ARM_ABS8, "Direct 8 bit"), 0114 RT(R_ARM_SBREL32, "SBREL32"), 0115 RT(R_ARM_THM_PC22, "PC relative 24 bit (Thumb32 BL)"), 0116 RT(R_ARM_THM_PC8, "PC relative & 0x3FC (Thumb16 LDR, ADD, ADR)"), 0117 RT(R_ARM_AMP_VCALL9, "VCALL9"), 0118 #ifndef R_ARM_TLS_DESC 0119 RT(R_ARM_SWI24, "Obsolete static relocation"), 0120 #else 0121 RT(R_ARM_TLS_DESC, "Dynamic relocation"), 0122 #endif 0123 RT(R_ARM_THM_SWI8, "SWI8"), 0124 RT(R_ARM_XPC25, "XPC25"), 0125 RT(R_ARM_THM_XPC22, "XPC22 (Thumb)"), 0126 RT(R_ARM_TLS_DTPMOD32, "ID of module containing symbol"), 0127 RT(R_ARM_TLS_DTPOFF32, "Offset in TLS block"), 0128 RT(R_ARM_TLS_TPOFF32, "Offset in static TLS block"), 0129 RT(R_ARM_COPY, "Copy symbol at runtime"), 0130 RT(R_ARM_GLOB_DAT, "Create GOT entry"), 0131 RT(R_ARM_JUMP_SLOT, "Create PLT entry"), 0132 RT(R_ARM_RELATIVE, "Adjust by program base"), 0133 RT(R_ARM_GOTOFF, "32 bit offset to GOT"), 0134 RT(R_ARM_GOTPC, "32 bit PC relative offset to GOT"), 0135 RT(R_ARM_GOT32, "32 bit GOT entry"), 0136 RT(R_ARM_PLT32, "Deprecated, 32 bit PLT address"), 0137 #ifdef __GLIBC_PREREQ 0138 #if __GLIBC_PREREQ(2, 18) 0139 RT(R_ARM_CALL, "PC relative 24 bit (BL, BLX)"), 0140 RT(R_ARM_JUMP24, "PC relative 24 bit (B, BL<cond>)"), 0141 RT(R_ARM_THM_JUMP24, "PC relative 24 bit (Thumb32 B.W)"), 0142 RT(R_ARM_BASE_ABS, "Adjust by program base"), 0143 #endif 0144 #endif 0145 #ifdef R_ARM_ALU_PCREL_7_0 0146 RT(R_ARM_ALU_PCREL_7_0, "ALU RCREL 7 0"), 0147 RT(R_ARM_ALU_PCREL_15_8, "ALU PCREL 15 8"), 0148 RT(R_ARM_ALU_PCREL_23_15, "ALU RCREL 23 15"), 0149 RT(R_ARM_LDR_SBREL_11_0, "Program base relative (LDR 11 0)"), 0150 RT(R_ARM_ALU_SBREL_19_12, "Program base relative (ALU 19 12)"), 0151 RT(R_ARM_ALU_SBREL_27_20, "Program base relative (ALU 27 20)"), 0152 #endif 0153 #ifdef __GLIBC_PREREQ 0154 #if __GLIBC_PREREQ(2, 18) 0155 RT(R_ARM_TARGET1, "TARGET1"), 0156 RT(R_ARM_SBREL31, "Program base relative"), 0157 RT(R_ARM_V4BX, "V4BX"), 0158 RT(R_ARM_TARGET2, "TARGET2"), 0159 RT(R_ARM_PREL31, "32 bit PC relative"), 0160 RT(R_ARM_MOVW_ABS_NC, "Direct 16-bit (MOVW)"), 0161 RT(R_ARM_MOVT_ABS, "Direct high 16-bit (MOVT)"), 0162 RT(R_ARM_MOVW_PREL_NC, "PC relative 16-bit (MOVW)"), 0163 RT(R_ARM_MOVT_PREL, "PC relative (MOVT)"), 0164 RT(R_ARM_THM_MOVW_ABS_NC, "Direct 16 bit (Thumb32 MOVW)"), 0165 RT(R_ARM_THM_MOVT_ABS, "Direct high 16 bit (Thumb32 MOVT)"), 0166 RT(R_ARM_THM_MOVW_PREL_NC, "PC relative 16 bit (Thumb32 MOVW)"), 0167 RT(R_ARM_THM_MOVT_PREL, "PC relative high 16 bit (Thumb32 MOVT)"), 0168 RT(R_ARM_THM_JUMP19, "PC relative 20 bit (Thumb32 B<cond>.W)"), 0169 RT(R_ARM_THM_JUMP6, "PC relative X & 0x7E (Thumb16 CBZ, CBNZ)"), 0170 RT(R_ARM_THM_ALU_PREL_11_0, "PC relative 12 bit (Thumb32 ADR.W)"), 0171 RT(R_ARM_THM_PC12, "PC relative 12 bit (Thumb32 LDR{D,SB,H,SH})"), 0172 RT(R_ARM_ABS32_NOI, "Direct 32-bit"), 0173 RT(R_ARM_REL32_NOI, "PC relative 32-bit"), 0174 RT(R_ARM_ALU_PC_G0_NC, "PC relative (ADD, SUB)"), 0175 RT(R_ARM_ALU_PC_G0, "PC relative (ADD, SUB)"), 0176 RT(R_ARM_ALU_PC_G1_NC, "PC relative (ADD, SUB)"), 0177 RT(R_ARM_ALU_PC_G1, "PC relative (ADD, SUB)"), 0178 RT(R_ARM_ALU_PC_G2, "PC relative (ADD, SUB)"), 0179 RT(R_ARM_LDR_PC_G1, "PC relative (LDR,STR,LDRB,STRB)"), 0180 RT(R_ARM_LDR_PC_G2, "PC relative (LDR,STR,LDRB,STRB)"), 0181 RT(R_ARM_LDRS_PC_G0, "PC relative (STR{D,H}, LDR{D,SB,H,SH})"), 0182 RT(R_ARM_LDRS_PC_G1, "PC relative (STR{D,H}, LDR{D,SB,H,SH})"), 0183 RT(R_ARM_LDRS_PC_G2, "PC relative (STR{D,H}, LDR{D,SB,H,SH})"), 0184 RT(R_ARM_LDC_PC_G0, "PC relative (LDC, STC)"), 0185 RT(R_ARM_LDC_PC_G1, "PC relative (LDC, STC)"), 0186 RT(R_ARM_LDC_PC_G2, "PC relative (LDC, STC)"), 0187 RT(R_ARM_ALU_SB_G0_NC, "Program base relative (ADD,SUB)"), 0188 RT(R_ARM_ALU_SB_G0, "Program base relative (ADD,SUB)"), 0189 RT(R_ARM_ALU_SB_G1_NC, "Program base relative (ADD,SUB)"), 0190 RT(R_ARM_ALU_SB_G1, "Program base relative (ADD,SUB)"), 0191 RT(R_ARM_ALU_SB_G2, "Program base relative (ADD,SUB)"), 0192 RT(R_ARM_LDR_SB_G0, "Program base relative (LDR, STR, LDRB, STRB)"), 0193 RT(R_ARM_LDR_SB_G1, "Program base relative (LDR, STR, LDRB, STRB)"), 0194 RT(R_ARM_LDR_SB_G2, "Program base relative (LDR, STR, LDRB, STRB)"), 0195 RT(R_ARM_LDRS_SB_G0, "Program base relative (LDR, STR, LDRB, STRB)"), 0196 RT(R_ARM_LDRS_SB_G1, "Program base relative (LDR, STR, LDRB, STRB)"), 0197 RT(R_ARM_LDRS_SB_G2, "Program base relative (LDR, STR, LDRB, STRB)"), 0198 RT(R_ARM_LDC_SB_G0, "Program base relative (LDC,STC)"), 0199 RT(R_ARM_LDC_SB_G1, "Program base relative (LDC,STC)"), 0200 RT(R_ARM_LDC_SB_G2, "Program base relative (LDC,STC)"), 0201 RT(R_ARM_MOVW_BREL_NC, "Program base relative 16 bit (MOVW)"), 0202 RT(R_ARM_MOVT_BREL, "Program base relative high 16 bit (MOVT)"), 0203 RT(R_ARM_MOVW_BREL, "Program base relative 16 bit (MOVW)"), 0204 RT(R_ARM_THM_MOVW_BREL_NC, "Program base relative 16 bit (Thumb32 MOVW)"), 0205 RT(R_ARM_THM_MOVT_BREL, "Program base relative high 16 bit (Thumb32 MOVT)"), 0206 RT(R_ARM_THM_MOVW_BREL, "Program base relative 16 bit (Thumb32 MOVW)"), 0207 #endif 0208 #if __GLIBC_PREREQ(2, 14) 0209 RT(R_ARM_TLS_GOTDESC, "TLS GOTDESC"), 0210 RT(R_ARM_TLS_CALL, "TLS CALL"), 0211 RT(R_ARM_TLS_DESCSEQ, "TLS relaxation"), 0212 RT(R_ARM_THM_TLS_CALL, "TLS CALL (Thumb)"), 0213 #endif 0214 #if __GLIBC_PREREQ(2, 18) 0215 RT(R_ARM_PLT32_ABS, "PLT32 ABS"), 0216 RT(R_ARM_GOT_ABS, "GOT entry"), 0217 RT(R_ARM_GOT_PREL, "PC relative GOT entry"), 0218 RT(R_ARM_GOT_BREL12, "GOT entry relative to GOT origin (LDR)"), 0219 RT(R_ARM_GOTOFF12, "12 bit, GOT entry relative to GOT origin (LDR, STR)"), 0220 RT(R_ARM_GOTRELAX, "GOTRELAX"), 0221 #endif 0222 #endif 0223 RT(R_ARM_GNU_VTENTRY, "GNU VTENTRY"), 0224 RT(R_ARM_GNU_VTINHERIT, "GNU VTINHERIT"), 0225 #ifdef R_ARM_THM_PC11 0226 RT(R_ARM_THM_PC11, "PC relative & 0xFFE (Thumb16 B)"), 0227 RT(R_ARM_THM_PC9, "PC relative & 0x1FE (Thumb16 B/B<cond>)"), 0228 RT(R_ARM_TLS_GD32, "PC-rel 32 bit for global dynamic thread local data"), 0229 RT(R_ARM_TLS_LDM32, "PC-rel 32 bit for local dynamic thread local data"), 0230 RT(R_ARM_TLS_LDO32, "32 bit offset relative to TLS block"), 0231 RT(R_ARM_TLS_IE32, "PC-rel 32 bit for GOT entry of static TLS block offset"), 0232 RT(R_ARM_TLS_LE32, "32 bit offset relative to static TLS block"), 0233 #endif 0234 #ifdef __GLIBC_PREREQ 0235 #if __GLIBC_PREREQ(2, 18) 0236 RT(R_ARM_TLS_LDO12, "12 bit relative to TLS block (LDR, STR)"), 0237 RT(R_ARM_TLS_LE12, "12 bit relative to static TLS block (LDR, STR)"), 0238 RT(R_ARM_TLS_IE12GP, "12 bit GOT entry relative to GOT origin (LDR)"), 0239 RT(R_ARM_ME_TOO, "ME TOO"), 0240 #endif 0241 #endif 0242 #ifdef R_ARM_THM_TLS_DESCSEQ 0243 RT(R_ARM_THM_TLS_DESCSEQ, "TLS DESCSEQ (Thumb)"), 0244 #endif 0245 #ifdef __GLIBC_PREREQ 0246 #if __GLIBC_PREREQ(2, 18) 0247 RT(R_ARM_THM_TLS_DESCSEQ16, "TLS DESCSEQ16 (Thumb)"), 0248 RT(R_ARM_THM_TLS_DESCSEQ32, "TLS DESCSEQ32 (Thumb)"), 0249 RT(R_ARM_THM_GOT_BREL12, "GOT entry relative to GOT origin, 12 bit (Thumb32 LDR)"), 0250 #endif 0251 #endif 0252 #ifdef R_ARM_IRELATIVE 0253 RT(R_ARM_IRELATIVE, "IRELATIVE"), 0254 #endif 0255 #ifdef R_ARM_RXPC25 0256 RT(R_ARM_RXPC25, "RXPC25"), 0257 #endif 0258 RT(R_ARM_RSBREL32, "RSBREL32"), 0259 #ifdef R_ARM_THM_RPC22 0260 RT(R_ARM_THM_RPC22, "RPC22 (Thumb)"), 0261 #endif 0262 RT(R_ARM_RREL32, "RREL32"), 0263 #ifdef R_ARM_RABS22 0264 RT(R_ARM_RABS22, "RABS22"), 0265 #endif 0266 RT(R_ARM_RPC24, "RPC24"), 0267 RT(R_ARM_RBASE, "RBASE") 0268 }; 0269 0270 static const RelocType reloc_types_x86_64[] { 0271 RT(R_X86_64_NONE, "No reloc"), 0272 RT(R_X86_64_64, "Direct 64 bit "), 0273 RT(R_X86_64_PC32, "PC relative 32 bit signed"), 0274 RT(R_X86_64_GOT32, "32 bit GOT entry"), 0275 RT(R_X86_64_PLT32, "32 bit PLT address"), 0276 RT(R_X86_64_COPY, "Copy symbol at runtime"), 0277 RT(R_X86_64_GLOB_DAT, "Create GOT entry"), 0278 #ifdef R_X86_64_JUMP_SLOT 0279 RT(R_X86_64_JUMP_SLOT, "Create PLT entry"), 0280 #endif 0281 RT(R_X86_64_RELATIVE, "Adjust by program base"), 0282 RT(R_X86_64_GOTPCREL, "32 bit signed PC relative offset to GOT"), 0283 RT(R_X86_64_32, "Direct 32 bit zero extended"), 0284 RT(R_X86_64_32S, "Direct 32 bit sign extended"), 0285 RT(R_X86_64_16, "Direct 16 bit zero extended"), 0286 RT(R_X86_64_PC16, "16 bit sign extended pc relative"), 0287 RT(R_X86_64_8, "Direct 8 bit sign extended "), 0288 RT(R_X86_64_PC8, "8 bit sign extended pc relative"), 0289 RT(R_X86_64_DTPMOD64, "ID of module containing symbol"), 0290 RT(R_X86_64_DTPOFF64, "Offset in module's TLS block"), 0291 RT(R_X86_64_TPOFF64, "Offset in initial TLS block"), 0292 RT(R_X86_64_TLSGD, "32 bit signed PC relative offset to two GOT entries for GD symbol"), 0293 RT(R_X86_64_TLSLD, "32 bit signed PC relative offset to two GOT entries for LD symbol"), 0294 RT(R_X86_64_DTPOFF32, "Offset in TLS block"), 0295 RT(R_X86_64_GOTTPOFF, "32 bit signed PC relative offset to GOT entry for IE symbol"), 0296 RT(R_X86_64_TPOFF32, "Offset in initial TLS block"), 0297 RT(R_X86_64_PC64, "PC relative 64 bit"), 0298 RT(R_X86_64_GOTOFF64, "64 bit offset to GOT"), 0299 RT(R_X86_64_GOTPC32, "32 bit signed pc relative offset to GOT"), 0300 RT(R_X86_64_GOT64, "64-bit GOT entry offset"), 0301 RT(R_X86_64_GOTPCREL64, "64-bit PC relative offset to GOT entry"), 0302 RT(R_X86_64_GOTPC64, "64-bit PC relative offset to GOT"), 0303 RT(R_X86_64_GOTPLT64, "like GOT64, says PLT entry needed"), 0304 RT(R_X86_64_PLTOFF64, "64-bit GOT relative offset to PLT entry"), 0305 RT(R_X86_64_SIZE32, "Size of symbol plus 32-bit addend"), 0306 RT(R_X86_64_SIZE64, "Size of symbol plus 64-bit addend"), 0307 RT(R_X86_64_GOTPC32_TLSDESC, "GOT offset for TLS descriptor"), 0308 RT(R_X86_64_TLSDESC_CALL, "Marker for call through TLS descriptor"), 0309 RT(R_X86_64_TLSDESC, "TLS descriptor. "), 0310 RT(R_X86_64_IRELATIVE, "Adjust indirectly by program base"), 0311 #ifdef R_X86_64_RELATIVE64 0312 RT(R_X86_64_RELATIVE64, "64-bit adjust by program base") 0313 #endif 0314 }; 0315 0316 #ifdef EM_AARCH64 0317 static const RelocType reloc_types_aarch64[] = { 0318 RT(R_AARCH64_NONE, "No relocation"), 0319 #ifdef R_AARCH64_P32_ABS32 0320 RT(R_AARCH64_P32_ABS32, "Direct 32 bit"), 0321 RT(R_AARCH64_P32_COPY, "Copy symbol at runtime"), 0322 RT(R_AARCH64_P32_GLOB_DAT, "Create GOT entry"), 0323 RT(R_AARCH64_P32_JUMP_SLOT, "Create PLT entry"), 0324 RT(R_AARCH64_P32_RELATIVE, "Adjust by program base"), 0325 RT(R_AARCH64_P32_TLS_DTPMOD, "Module number, 32 bit"), 0326 RT(R_AARCH64_P32_TLS_DTPREL, "Module-relative offset, 32 bit"), 0327 RT(R_AARCH64_P32_TLS_TPREL, "TP-relative offset, 32 bit"), 0328 RT(R_AARCH64_P32_TLSDESC, " TLS Descriptor"), 0329 RT(R_AARCH64_P32_IRELATIVE, "STT_GNU_IFUNC relocation"), 0330 #endif 0331 RT(R_AARCH64_ABS64, "Direct 64 bit"), 0332 RT(R_AARCH64_ABS32, "Direct 32 bit"), 0333 RT(R_AARCH64_ABS16, " Direct 16-bit"), 0334 RT(R_AARCH64_PREL64, "PC-relative 64-bit"), 0335 RT(R_AARCH64_PREL32, " PC-relative 32-bit"), 0336 RT(R_AARCH64_PREL16, " PC-relative 16-bit"), 0337 #ifdef R_AARCH64_MOVW_UABS_G0 0338 RT(R_AARCH64_MOVW_UABS_G0, "Dir. MOVZ imm. from bits 15:0"), 0339 RT(R_AARCH64_MOVW_UABS_G0_NC, "Likewise for MOVK; no check"), 0340 RT(R_AARCH64_MOVW_UABS_G1, "Dir. MOVZ imm. from bits 31:16"), 0341 RT(R_AARCH64_MOVW_UABS_G1_NC, "Likewise for MOVK; no check"), 0342 RT(R_AARCH64_MOVW_UABS_G2, "Dir. MOVZ imm. from bits 47:32"), 0343 #endif 0344 RT(R_AARCH64_TSTBR14, "PC-rel. TBZ/TBNZ imm. from 15:2"), 0345 RT(R_AARCH64_CONDBR19, "PC-rel. cond. br. imm. from 20:2"), 0346 RT(R_AARCH64_JUMP26, "PC-rel. B imm. from bits 27:2"), 0347 RT(R_AARCH64_CALL26, "Likewise for CALL"), 0348 #ifdef R_AARCH64_LDST16_ABS_LO12_NC 0349 RT(R_AARCH64_LDST16_ABS_LO12_NC, "Dir. ADD imm. from bits 11:1"), 0350 RT(R_AARCH64_LDST32_ABS_LO12_NC, "Likewise for bits 11:2"), 0351 RT(R_AARCH64_LDST64_ABS_LO12_NC, "Likewise for bits 11:3"), 0352 RT(R_AARCH64_MOVW_PREL_G0, "PC-rel. MOV{N,Z} imm. from 15:0"), 0353 RT(R_AARCH64_MOVW_PREL_G0_NC, "Likewise for MOVK; no check"), 0354 RT(R_AARCH64_MOVW_UABS_G2_NC, "Likewise for MOVK; no check"), 0355 RT(R_AARCH64_MOVW_UABS_G3, "Dir. MOV{K,Z} imm. from 63:48"), 0356 RT(R_AARCH64_MOVW_SABS_G0, "Dir. MOV{N,Z} imm. from 15:0"), 0357 RT(R_AARCH64_MOVW_SABS_G1, "Dir. MOV{N,Z} imm. from 31:16"), 0358 RT(R_AARCH64_MOVW_SABS_G2, "Dir. MOV{N,Z} imm. from 47:32"), 0359 RT(R_AARCH64_LD_PREL_LO19, "PC-rel. LD imm. from bits 20:2"), 0360 RT(R_AARCH64_ADR_PREL_LO21, "PC-rel. ADR imm. from bits 20:0"), 0361 RT(R_AARCH64_ADR_PREL_PG_HI21, "Page-rel. ADRP imm. from 32:12"), 0362 RT(R_AARCH64_ADR_PREL_PG_HI21_NC, "Likewise; no overflow check"), 0363 RT(R_AARCH64_ADD_ABS_LO12_NC, "Dir. ADD imm. from bits 11:0"), 0364 RT(R_AARCH64_LDST8_ABS_LO12_NC, "Likewise for LD/ST; no check"), 0365 RT(R_AARCH64_MOVW_PREL_G1, "PC-rel. MOV{N,Z} imm. from 31:16"), 0366 RT(R_AARCH64_MOVW_PREL_G1_NC, "Likewise for MOVK; no check"), 0367 RT(R_AARCH64_MOVW_PREL_G2, "PC-rel. MOV{N,Z} imm. from 47:32"), 0368 RT(R_AARCH64_MOVW_PREL_G2_NC, "Likewise for MOVK; no check"), 0369 RT(R_AARCH64_MOVW_PREL_G3, "PC-rel. MOV{N,Z} imm. from 63:48"), 0370 RT(R_AARCH64_LDST128_ABS_LO12_NC, "Dir. ADD imm. from bits 11:4"), 0371 RT(R_AARCH64_MOVW_GOTOFF_G0, "GOT-rel. off. MOV{N,Z} imm. 15:0"), 0372 RT(R_AARCH64_MOVW_GOTOFF_G0_NC, "Likewise for MOVK; no check"), 0373 RT(R_AARCH64_MOVW_GOTOFF_G1, "GOT-rel. o. MOV{N,Z} imm. 31:16"), 0374 RT(R_AARCH64_MOVW_GOTOFF_G1_NC, "Likewise for MOVK; no check"), 0375 RT(R_AARCH64_MOVW_GOTOFF_G2, "GOT-rel. o. MOV{N,Z} imm. 47:32"), 0376 RT(R_AARCH64_MOVW_GOTOFF_G2_NC, "Likewise for MOVK; no check"), 0377 RT(R_AARCH64_MOVW_GOTOFF_G3, "GOT-rel. o. MOV{N,Z} imm. 63:48"), 0378 RT(R_AARCH64_GOTREL64, "GOT-relative 64-bit"), 0379 RT(R_AARCH64_GOTREL32, "GOT-relative 32-bit"), 0380 RT(R_AARCH64_GOT_LD_PREL19, "PC-rel. GOT off. load imm. 20:2"), 0381 RT(R_AARCH64_LD64_GOTOFF_LO15, "GOT-rel. off. LD/ST imm. 14:3"), 0382 RT(R_AARCH64_ADR_GOT_PAGE, "P-page-rel. GOT off. ADRP 32:12"), 0383 RT(R_AARCH64_LD64_GOT_LO12_NC, "Dir. GOT off. LD/ST imm. 11:3"), 0384 RT(R_AARCH64_LD64_GOTPAGE_LO15, "GOT-page-rel. GOT off. LD/ST 14:3"), 0385 RT(R_AARCH64_TLSGD_ADR_PREL21, "PC-relative ADR imm. 20:0"), 0386 RT(R_AARCH64_TLSGD_ADR_PAGE21, "page-rel. ADRP imm. 32:12"), 0387 RT(R_AARCH64_TLSGD_ADD_LO12_NC, "direct ADD imm. from 11:0"), 0388 RT(R_AARCH64_TLSGD_MOVW_G1, "GOT-rel. MOV{N,Z} 31:16"), 0389 RT(R_AARCH64_TLSGD_MOVW_G0_NC, "GOT-rel. MOVK imm. 15:0"), 0390 RT(R_AARCH64_TLSLD_ADR_PREL21, "Like 512; local dynamic model"), 0391 RT(R_AARCH64_TLSLD_ADR_PAGE21, "Like 513; local dynamic model"), 0392 RT(R_AARCH64_TLSLD_ADD_LO12_NC, "Like 514; local dynamic model"), 0393 RT(R_AARCH64_TLSLD_MOVW_G1, "Like 515; local dynamic model"), 0394 RT(R_AARCH64_TLSLD_MOVW_G0_NC, "Like 516; local dynamic model"), 0395 RT(R_AARCH64_TLSLD_LD_PREL19, "TLS PC-rel. load imm. 20:2"), 0396 RT(R_AARCH64_TLSLD_MOVW_DTPREL_G2, "TLS DTP-rel. MOV{N,Z} 47:32"), 0397 RT(R_AARCH64_TLSLD_MOVW_DTPREL_G1, "TLS DTP-rel. MOV{N,Z} 31:16"), 0398 RT(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC, "Likewise; MOVK; no check"), 0399 RT(R_AARCH64_TLSLD_MOVW_DTPREL_G0, "TLS DTP-rel. MOV{N,Z} 15:0"), 0400 RT(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC, "Likewise; MOVK; no check"), 0401 RT(R_AARCH64_TLSLD_ADD_DTPREL_HI12, "DTP-rel. ADD imm. from 23:12"), 0402 RT(R_AARCH64_TLSLD_ADD_DTPREL_LO12, "DTP-rel. ADD imm. from 11:0"), 0403 RT(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC, "Likewise; no ovfl. check"), 0404 RT(R_AARCH64_TLSLD_LDST8_DTPREL_LO12, "DTP-rel. LD/ST imm. 11:0"), 0405 RT(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC, "Likewise; no check"), 0406 RT(R_AARCH64_TLSLD_LDST16_DTPREL_LO12, "DTP-rel. LD/ST imm. 11:1"), 0407 RT(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC, "Likewise; no check"), 0408 RT(R_AARCH64_TLSLD_LDST32_DTPREL_LO12, "DTP-rel. LD/ST imm. 11:2"), 0409 RT(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC, "Likewise; no check"), 0410 RT(R_AARCH64_TLSLD_LDST64_DTPREL_LO12, "DTP-rel. LD/ST imm. 11:3"), 0411 RT(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC, "Likewise; no check"), 0412 RT(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1, "GOT-rel. MOV{N,Z} 31:16"), 0413 RT(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC, "GOT-rel. MOVK 15:0"), 0414 RT(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, "Page-rel. ADRP 32:12"), 0415 RT(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, "Direct LD off. 11:3"), 0416 RT(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19, "PC-rel. load imm. 20:2"), 0417 RT(R_AARCH64_TLSLE_MOVW_TPREL_G2, "TLS TP-rel. MOV{N,Z} 47:32"), 0418 RT(R_AARCH64_TLSLE_MOVW_TPREL_G1, "TLS TP-rel. MOV{N,Z} 31:16"), 0419 RT(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC, "Likewise; MOVK; no check"), 0420 RT(R_AARCH64_TLSLE_MOVW_TPREL_G0, "TLS TP-rel. MOV{N,Z} 15:0"), 0421 RT(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC, "Likewise; MOVK; no check"), 0422 RT(R_AARCH64_TLSLE_ADD_TPREL_HI12, "TP-rel. ADD imm. 23:12"), 0423 RT(R_AARCH64_TLSLE_ADD_TPREL_LO12, "TP-rel. ADD imm. 11:0"), 0424 RT(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC, "Likewise; no ovfl. check"), 0425 RT(R_AARCH64_TLSLE_LDST8_TPREL_LO12, "TP-rel. LD/ST off. 11:0"), 0426 RT(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC, "Likewise; no ovfl. check"), 0427 RT(R_AARCH64_TLSLE_LDST16_TPREL_LO12, "TP-rel. LD/ST off. 11:1"), 0428 RT(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC, "Likewise; no check"), 0429 RT(R_AARCH64_TLSLE_LDST32_TPREL_LO12, "TP-rel. LD/ST off. 11:2"), 0430 RT(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC, "Likewise; no check"), 0431 RT(R_AARCH64_TLSLE_LDST64_TPREL_LO12, "TP-rel. LD/ST off. 11:3"), 0432 RT(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC, "Likewise; no check"), 0433 RT(R_AARCH64_TLSDESC_LD_PREL19, "PC-rel. load immediate 20:2"), 0434 RT(R_AARCH64_TLSDESC_ADR_PREL21, "PC-rel. ADR immediate 20:0"), 0435 RT(R_AARCH64_TLSDESC_ADR_PAGE21, "Page-rel. ADRP imm. 32:12"), 0436 RT(R_AARCH64_TLSDESC_LD64_LO12, "Direct LD off. from 11:3"), 0437 RT(R_AARCH64_TLSDESC_ADD_LO12, "Direct ADD imm. from 11:0"), 0438 RT(R_AARCH64_TLSDESC_OFF_G1, "GOT-rel. MOV{N,Z} imm. 31:16"), 0439 RT(R_AARCH64_TLSDESC_OFF_G0_NC, "GOT-rel. MOVK imm. 15:0; no ck"), 0440 RT(R_AARCH64_TLSDESC_LDR, "Relax LDR"), 0441 RT(R_AARCH64_TLSDESC_ADD, "Relax ADD"), 0442 RT(R_AARCH64_TLSDESC_CALL, "Relax BLR"), 0443 RT(R_AARCH64_TLSLE_LDST128_TPREL_LO12, "TP-rel. LD/ST off. 11:4"), 0444 RT(R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC, "Likewise; no check"), 0445 RT(R_AARCH64_TLSLD_LDST128_DTPREL_LO12, "DTP-rel. LD/ST imm. 11:4"), 0446 RT(R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC, "Likewise; no check"), 0447 #endif 0448 RT(R_AARCH64_COPY, "Copy symbol at runtime"), 0449 RT(R_AARCH64_GLOB_DAT, "Create GOT entry"), 0450 RT(R_AARCH64_JUMP_SLOT, "Create PLT entry"), 0451 RT(R_AARCH64_RELATIVE, "Adjust by program base"), 0452 #ifdef R_AARCH64_TLS_DTPMOD 0453 RT(R_AARCH64_TLS_DTPMOD, "Module number, 64 bit"), 0454 RT(R_AARCH64_TLS_DTPREL, "Module-relative offset, 64 bit"), 0455 RT(R_AARCH64_TLS_TPREL, "TP-relative offset, 64 bit"), 0456 #endif 0457 RT(R_AARCH64_TLSDESC, "TLS Descriptor"), 0458 RT(R_AARCH64_IRELATIVE, "STT_GNU_IFUNC relocation"), 0459 }; 0460 #endif 0461 0462 #undef RT 0463 0464 struct RelocTypeRepository 0465 { 0466 int machine; 0467 int typeInfosSize; 0468 const RelocType* typeInfos; 0469 }; 0470 0471 #define RTR(mach, typeInfo) { mach, sizeof(typeInfo) / sizeof(RelocType), typeInfo } 0472 static const RelocTypeRepository reloc_type_repository[] { 0473 RTR(EM_386, reloc_types_i386), 0474 RTR(EM_ARM, reloc_types_arm), 0475 RTR(EM_X86_64, reloc_types_x86_64), 0476 #ifdef EM_AARCH64 0477 RTR(EM_AARCH64, reloc_types_aarch64), 0478 #endif 0479 }; 0480 #undef RTR 0481 0482 static const int reloc_type_repository_size = sizeof(reloc_type_repository) / sizeof(RelocTypeRepository); 0483 0484 static const RelocType* relocTypeInfo(uint16_t machine, uint32_t type) 0485 { 0486 // TODO can be optimized, tables are sorted 0487 for (int i = 0; i < reloc_type_repository_size; ++i) { 0488 if (reloc_type_repository[i].machine != machine) 0489 continue; 0490 for (int j = 0; j < reloc_type_repository[i].typeInfosSize; ++j) { 0491 if (reloc_type_repository[i].typeInfos[j].id == type) 0492 return &reloc_type_repository[i].typeInfos[j]; 0493 } 0494 } 0495 0496 return nullptr; 0497 } 0498 0499 static const RelocType* relocTypeInfo(ElfRelocationEntry* entry) 0500 { 0501 return relocTypeInfo(entry->relocationTable()->file()->header()->machine(), entry->type()); 0502 } 0503 0504 namespace RelocationPrinter { 0505 0506 QByteArray label(ElfRelocationEntry* entry) 0507 { 0508 const auto info = relocTypeInfo(entry); 0509 if (!info) 0510 return QByteArray("unknown relocation type ") + QByteArray::number(entry->type()); 0511 return QByteArray::fromRawData(info->label, strlen(info->label)); 0512 } 0513 0514 QByteArray label(uint16_t machine, uint32_t type) 0515 { 0516 const auto info = relocTypeInfo(machine, type); 0517 if (!info) 0518 return QByteArray("unknown relocation type ") + QByteArray::number(type); 0519 return QByteArray::fromRawData(info->label, strlen(info->label)); 0520 } 0521 0522 QByteArray description(ElfRelocationEntry* entry) 0523 { 0524 const auto info = relocTypeInfo(entry); 0525 if (!info) 0526 return QByteArray("unknown relocation type ") + QByteArray::number(entry->type()); 0527 return QByteArray::fromRawData(info->desc, strlen(info->desc)); 0528 } 0529 0530 }