reloc_aarch64.c (9480B)
1 /* RelocKind <-> AArch64 ELF reloc-type mapping. 2 * 3 * Kit's RelocKind enum is arch-agnostic at its top (R_ABS, R_REL, R_PC 4 * variants) and arch-specific in its lower entries. On AArch64, R_REL and 5 * R_PC collapse to ELF_R_AARCH64_PREL32 / ELF_R_AARCH64_PREL64 — both 6 * mean "PC-relative relative to the symbol" once the linker has resolved 7 * final addresses. 8 * 9 * Returning 0 (ELF_R_AARCH64_NONE) for an unsupported kind is the signal 10 * to the caller to either panic (emit) or panic (read with diagnostic). */ 11 12 #include "obj/elf/elf.h" 13 14 u32 elf_aarch64_reloc_to(u32 kind /* RelocKind */) { 15 switch (kind) { 16 case R_NONE: 17 return ELF_R_AARCH64_NONE; 18 case R_ABS64: 19 return ELF_R_AARCH64_ABS64; 20 case R_ABS32: 21 return ELF_R_AARCH64_ABS32; 22 case R_PC64: 23 return ELF_R_AARCH64_PREL64; 24 case R_PC32: 25 return ELF_R_AARCH64_PREL32; 26 case R_REL64: 27 return ELF_R_AARCH64_PREL64; 28 case R_REL32: 29 return ELF_R_AARCH64_PREL32; 30 case R_AARCH64_JUMP26: 31 return ELF_R_AARCH64_JUMP26; 32 case R_AARCH64_CALL26: 33 return ELF_R_AARCH64_CALL26; 34 case R_AARCH64_CONDBR19: 35 return ELF_R_AARCH64_CONDBR19; 36 case R_AARCH64_TSTBR14: 37 return ELF_R_AARCH64_TSTBR14; 38 case R_AARCH64_LD_PREL_LO19: 39 return ELF_R_AARCH64_LD_PREL_LO19; 40 case R_AARCH64_ADR_PREL_LO21: 41 return ELF_R_AARCH64_ADR_PREL_LO21; 42 case R_AARCH64_ADR_PREL_PG_HI21: 43 return ELF_R_AARCH64_ADR_PREL_PG_HI21; 44 case R_AARCH64_ADR_PREL_PG_HI21_NC: 45 return ELF_R_AARCH64_ADR_PREL_PG_HI21_NC; 46 case R_AARCH64_ADD_ABS_LO12_NC: 47 return ELF_R_AARCH64_ADD_ABS_LO12_NC; 48 case R_ABS16: 49 return ELF_R_AARCH64_ABS16; 50 case R_PREL16: 51 return ELF_R_AARCH64_PREL16; 52 case R_AARCH64_LDST8_ABS_LO12_NC: 53 return ELF_R_AARCH64_LDST8_ABS_LO12_NC; 54 case R_AARCH64_LDST16_ABS_LO12_NC: 55 return ELF_R_AARCH64_LDST16_ABS_LO12_NC; 56 case R_AARCH64_LDST32_ABS_LO12_NC: 57 return ELF_R_AARCH64_LDST32_ABS_LO12_NC; 58 case R_AARCH64_LDST64_ABS_LO12_NC: 59 return ELF_R_AARCH64_LDST64_ABS_LO12_NC; 60 case R_AARCH64_LDST128_ABS_LO12_NC: 61 return ELF_R_AARCH64_LDST128_ABS_LO12_NC; 62 case R_AARCH64_ADR_GOT_PAGE: 63 return ELF_R_AARCH64_ADR_GOT_PAGE; 64 case R_AARCH64_LD64_GOT_LO12_NC: 65 return ELF_R_AARCH64_LD64_GOT_LO12_NC; 66 case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 67 return ELF_R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21; 68 case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 69 return ELF_R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC; 70 case R_AARCH64_TLSLE_ADD_TPREL_HI12: 71 return ELF_R_AARCH64_TLSLE_ADD_TPREL_HI12; 72 case R_AARCH64_TLSLE_ADD_TPREL_LO12: 73 return ELF_R_AARCH64_TLSLE_ADD_TPREL_LO12; 74 case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 75 return ELF_R_AARCH64_TLSLE_ADD_TPREL_LO12_NC; 76 case R_AARCH64_TLSLE_LDST8_TPREL_LO12: 77 return ELF_R_AARCH64_TLSLE_LDST8_TPREL_LO12; 78 case R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: 79 return ELF_R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC; 80 case R_AARCH64_TLSLE_LDST16_TPREL_LO12: 81 return ELF_R_AARCH64_TLSLE_LDST16_TPREL_LO12; 82 case R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: 83 return ELF_R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC; 84 case R_AARCH64_TLSLE_LDST32_TPREL_LO12: 85 return ELF_R_AARCH64_TLSLE_LDST32_TPREL_LO12; 86 case R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: 87 return ELF_R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC; 88 case R_AARCH64_TLSLE_LDST64_TPREL_LO12: 89 return ELF_R_AARCH64_TLSLE_LDST64_TPREL_LO12; 90 case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: 91 return ELF_R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC; 92 case R_AARCH64_GLOB_DAT: 93 return ELF_R_AARCH64_GLOB_DAT; 94 case R_AARCH64_JUMP_SLOT: 95 return ELF_R_AARCH64_JUMP_SLOT; 96 case R_AARCH64_RELATIVE: 97 return ELF_R_AARCH64_RELATIVE; 98 case R_AARCH64_COPY: 99 return ELF_R_AARCH64_COPY; 100 default: 101 return ELF_R_AARCH64_NONE; 102 } 103 } 104 105 u32 elf_aarch64_reloc_from(u32 elf_type) { 106 switch (elf_type) { 107 case ELF_R_AARCH64_NONE: 108 return R_NONE; 109 case ELF_R_AARCH64_ABS64: 110 return R_ABS64; 111 case ELF_R_AARCH64_ABS32: 112 return R_ABS32; 113 case ELF_R_AARCH64_PREL64: 114 return R_PC64; 115 case ELF_R_AARCH64_PREL32: 116 return R_PC32; 117 case ELF_R_AARCH64_JUMP26: 118 return R_AARCH64_JUMP26; 119 case ELF_R_AARCH64_CALL26: 120 return R_AARCH64_CALL26; 121 case ELF_R_AARCH64_CONDBR19: 122 return R_AARCH64_CONDBR19; 123 case ELF_R_AARCH64_TSTBR14: 124 return R_AARCH64_TSTBR14; 125 case ELF_R_AARCH64_LD_PREL_LO19: 126 return R_AARCH64_LD_PREL_LO19; 127 case ELF_R_AARCH64_ADR_PREL_LO21: 128 return R_AARCH64_ADR_PREL_LO21; 129 case ELF_R_AARCH64_ADR_PREL_PG_HI21: 130 return R_AARCH64_ADR_PREL_PG_HI21; 131 case ELF_R_AARCH64_ADR_PREL_PG_HI21_NC: 132 return R_AARCH64_ADR_PREL_PG_HI21_NC; 133 case ELF_R_AARCH64_ADD_ABS_LO12_NC: 134 return R_AARCH64_ADD_ABS_LO12_NC; 135 case ELF_R_AARCH64_ABS16: 136 return R_ABS16; 137 case ELF_R_AARCH64_PREL16: 138 return R_PREL16; 139 case ELF_R_AARCH64_LDST8_ABS_LO12_NC: 140 return R_AARCH64_LDST8_ABS_LO12_NC; 141 case ELF_R_AARCH64_LDST16_ABS_LO12_NC: 142 return R_AARCH64_LDST16_ABS_LO12_NC; 143 case ELF_R_AARCH64_LDST32_ABS_LO12_NC: 144 return R_AARCH64_LDST32_ABS_LO12_NC; 145 case ELF_R_AARCH64_LDST64_ABS_LO12_NC: 146 return R_AARCH64_LDST64_ABS_LO12_NC; 147 case ELF_R_AARCH64_LDST128_ABS_LO12_NC: 148 return R_AARCH64_LDST128_ABS_LO12_NC; 149 case ELF_R_AARCH64_ADR_GOT_PAGE: 150 return R_AARCH64_ADR_GOT_PAGE; 151 case ELF_R_AARCH64_LD64_GOT_LO12_NC: 152 return R_AARCH64_LD64_GOT_LO12_NC; 153 case ELF_R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 154 return R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21; 155 case ELF_R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 156 return R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC; 157 case ELF_R_AARCH64_TLSLE_ADD_TPREL_HI12: 158 return R_AARCH64_TLSLE_ADD_TPREL_HI12; 159 case ELF_R_AARCH64_TLSLE_ADD_TPREL_LO12: 160 return R_AARCH64_TLSLE_ADD_TPREL_LO12; 161 case ELF_R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 162 return R_AARCH64_TLSLE_ADD_TPREL_LO12_NC; 163 case ELF_R_AARCH64_TLSLE_LDST8_TPREL_LO12: 164 return R_AARCH64_TLSLE_LDST8_TPREL_LO12; 165 case ELF_R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: 166 return R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC; 167 case ELF_R_AARCH64_TLSLE_LDST16_TPREL_LO12: 168 return R_AARCH64_TLSLE_LDST16_TPREL_LO12; 169 case ELF_R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: 170 return R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC; 171 case ELF_R_AARCH64_TLSLE_LDST32_TPREL_LO12: 172 return R_AARCH64_TLSLE_LDST32_TPREL_LO12; 173 case ELF_R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: 174 return R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC; 175 case ELF_R_AARCH64_TLSLE_LDST64_TPREL_LO12: 176 return R_AARCH64_TLSLE_LDST64_TPREL_LO12; 177 case ELF_R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: 178 return R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC; 179 case ELF_R_AARCH64_GLOB_DAT: 180 return R_AARCH64_GLOB_DAT; 181 case ELF_R_AARCH64_JUMP_SLOT: 182 return R_AARCH64_JUMP_SLOT; 183 case ELF_R_AARCH64_RELATIVE: 184 return R_AARCH64_RELATIVE; 185 case ELF_R_AARCH64_COPY: 186 return R_AARCH64_COPY; 187 default: 188 return (u32)-1; /* sentinel */ 189 } 190 } 191 192 /* Diagnostic spelling for an AArch64 ELF reloc *wire* type. Returns a 193 * static literal, or NULL for an unknown type (caller falls back to the 194 * format-neutral reloc_kind_name). Mirrors the wire-type set the reader 195 * recognizes. */ 196 const char* elf_aarch64_reloc_name(u32 elf_type) { 197 switch (elf_type) { 198 case ELF_R_AARCH64_NONE: 199 return "R_AARCH64_NONE"; 200 case ELF_R_AARCH64_ABS64: 201 return "R_AARCH64_ABS64"; 202 case ELF_R_AARCH64_ABS32: 203 return "R_AARCH64_ABS32"; 204 case ELF_R_AARCH64_ABS16: 205 return "R_AARCH64_ABS16"; 206 case ELF_R_AARCH64_PREL64: 207 return "R_AARCH64_PREL64"; 208 case ELF_R_AARCH64_PREL32: 209 return "R_AARCH64_PREL32"; 210 case ELF_R_AARCH64_PREL16: 211 return "R_AARCH64_PREL16"; 212 case ELF_R_AARCH64_JUMP26: 213 return "R_AARCH64_JUMP26"; 214 case ELF_R_AARCH64_CALL26: 215 return "R_AARCH64_CALL26"; 216 case ELF_R_AARCH64_CONDBR19: 217 return "R_AARCH64_CONDBR19"; 218 case ELF_R_AARCH64_TSTBR14: 219 return "R_AARCH64_TSTBR14"; 220 case ELF_R_AARCH64_LD_PREL_LO19: 221 return "R_AARCH64_LD_PREL_LO19"; 222 case ELF_R_AARCH64_ADR_PREL_LO21: 223 return "R_AARCH64_ADR_PREL_LO21"; 224 case ELF_R_AARCH64_ADR_PREL_PG_HI21: 225 return "R_AARCH64_ADR_PREL_PG_HI21"; 226 case ELF_R_AARCH64_ADR_PREL_PG_HI21_NC: 227 return "R_AARCH64_ADR_PREL_PG_HI21_NC"; 228 case ELF_R_AARCH64_ADD_ABS_LO12_NC: 229 return "R_AARCH64_ADD_ABS_LO12_NC"; 230 case ELF_R_AARCH64_LDST8_ABS_LO12_NC: 231 return "R_AARCH64_LDST8_ABS_LO12_NC"; 232 case ELF_R_AARCH64_LDST16_ABS_LO12_NC: 233 return "R_AARCH64_LDST16_ABS_LO12_NC"; 234 case ELF_R_AARCH64_LDST32_ABS_LO12_NC: 235 return "R_AARCH64_LDST32_ABS_LO12_NC"; 236 case ELF_R_AARCH64_LDST64_ABS_LO12_NC: 237 return "R_AARCH64_LDST64_ABS_LO12_NC"; 238 case ELF_R_AARCH64_LDST128_ABS_LO12_NC: 239 return "R_AARCH64_LDST128_ABS_LO12_NC"; 240 case ELF_R_AARCH64_ADR_GOT_PAGE: 241 return "R_AARCH64_ADR_GOT_PAGE"; 242 case ELF_R_AARCH64_LD64_GOT_LO12_NC: 243 return "R_AARCH64_LD64_GOT_LO12_NC"; 244 case ELF_R_AARCH64_GLOB_DAT: 245 return "R_AARCH64_GLOB_DAT"; 246 case ELF_R_AARCH64_JUMP_SLOT: 247 return "R_AARCH64_JUMP_SLOT"; 248 case ELF_R_AARCH64_RELATIVE: 249 return "R_AARCH64_RELATIVE"; 250 case ELF_R_AARCH64_COPY: 251 return "R_AARCH64_COPY"; 252 default: 253 return NULL; 254 } 255 }