Unified · Split
| @@ -30,18 +30,23 @@ int code_reloc (int reloc_type) · 29 unmodified lines | ||
| 30 | 30 | case R_X86_64_32: |
| 31 | 31 | case R_X86_64_32S: |
| 32 | 32 | case R_X86_64_64: |
| 33 | + case R_X86_64_GOTPC32: | |
| 34 | + case R_X86_64_GOTPC64: | |
| 33 | 35 | case R_X86_64_GOTPCREL: |
| 34 | 36 | case R_X86_64_GOTPCRELX: |
| 35 | 37 | case R_X86_64_REX_GOTPCRELX: |
| 36 | 38 | case R_X86_64_GOTTPOFF: |
| 37 | 39 | case R_X86_64_GOT32: |
| 40 | + case R_X86_64_GOT64: | |
| 38 | 41 | case R_X86_64_GLOB_DAT: |
| 39 | 42 | case R_X86_64_COPY: |
| 40 | − case R_X86_64_RELATIVE: | |
| 43 | + case R_X86_64_RELATIVE: | |
| 41 | 44 | return 0; |
| 42 | 45 | |
| 43 | 46 | case R_X86_64_PC32: |
| 47 | + case R_X86_64_PC64: | |
| 44 | 48 | case R_X86_64_PLT32: |
| 49 | + case R_X86_64_PLTOFF64: | |
| 45 | 50 | case R_X86_64_JUMP_SLOT: |
| 46 | 51 | return 1; |
| 47 | 52 | } |
| @@ -59,7 +64,7 @@ int gotplt_entry_type (int reloc_type) · 11 unmodified lines | ||
| 59 | 64 | case R_X86_64_GLOB_DAT: |
| 60 | 65 | case R_X86_64_JUMP_SLOT: |
| 61 | 66 | case R_X86_64_COPY: |
| 62 | − case R_X86_64_RELATIVE: | |
| 67 | + case R_X86_64_RELATIVE: | |
| 63 | 68 | return NO_GOTPLT_ENTRY; |
| 64 | 69 | |
| 65 | 70 | /* The following relocs wouldn't normally need GOT or PLT |
| @@ -69,16 +74,21 @@ int gotplt_entry_type (int reloc_type) · 3 unmodified lines | ||
| 69 | 74 | case R_X86_64_32S: |
| 70 | 75 | case R_X86_64_64: |
| 71 | 76 | case R_X86_64_PC32: |
| 77 | + case R_X86_64_PC64: | |
| 72 | 78 | return AUTO_GOTPLT_ENTRY; |
| 73 | 79 | |
| 74 | 80 | case R_X86_64_GOTTPOFF: |
| 75 | 81 | return BUILD_GOT_ONLY; |
| 76 | 82 | |
| 77 | 83 | case R_X86_64_GOT32: |
| 84 | + case R_X86_64_GOT64: | |
| 85 | + case R_X86_64_GOTPC32: | |
| 86 | + case R_X86_64_GOTPC64: | |
| 78 | 87 | case R_X86_64_GOTPCREL: |
| 79 | 88 | case R_X86_64_GOTPCRELX: |
| 80 | − case R_X86_64_REX_GOTPCRELX: | |
| 89 | + case R_X86_64_REX_GOTPCRELX: | |
| 81 | 90 | case R_X86_64_PLT32: |
| 91 | + case R_X86_64_PLTOFF64: | |
| 82 | 92 | return ALWAYS_GOTPLT_ENTRY; |
| 83 | 93 | } |
| 84 | 94 | |
| @@ -171,12 +181,12 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 86 unmodified lines | ||
| 171 | 181 | qrel->r_offset = rel->r_offset; |
| 172 | 182 | if (esym_index) { |
| 173 | 183 | qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64); |
| 174 | − qrel->r_addend = rel->r_addend; | |
| 184 | + qrel->r_addend = rel->r_addend; | |
| 175 | 185 | qrel++; |
| 176 | 186 | break; |
| 177 | 187 | } else { |
| 178 | − qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); | |
| 179 | − qrel->r_addend = read64le(ptr) + val; | |
| 188 | + qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); | |
| 189 | + qrel->r_addend = read64le(ptr) + val; | |
| 180 | 190 | qrel++; |
| 181 | 191 | } |
| 182 | 192 | } |
| @@ -211,10 +221,10 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 28 unmodified lines | ||
| 211 | 221 | goto plt32pc32; |
| 212 | 222 | |
| 213 | 223 | case R_X86_64_PLT32: |
| 214 | − /* fallthrough: val already holds the PLT slot address */ | |
| 224 | + /* fallthrough: val already holds the PLT slot address */ | |
| 215 | 225 | |
| 216 | − plt32pc32: | |
| 217 | − { | |
| 226 | + plt32pc32: | |
| 227 | + { | |
| 218 | 228 | long long diff; |
| 219 | 229 | diff = (long long)val - addr; |
| 220 | 230 | if (diff < -2147483648LL || diff > 2147483647LL) { |
| @@ -223,17 +233,43 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 2 unmodified lines | ||
| 223 | 233 | add32le(ptr, diff); |
| 224 | 234 | } |
| 225 | 235 | break; |
| 236 | + | |
| 237 | + case R_X86_64_PLTOFF64: | |
| 238 | + add64le(ptr, val - s1->got->sh_addr + rel->r_addend); | |
| 239 | + break; | |
| 240 | + | |
| 241 | + case R_X86_64_PC64: | |
| 242 | + if (s1->output_type == TCC_OUTPUT_DLL) { | |
| 243 | + /* DLL relocation */ | |
| 244 | + esym_index = s1->sym_attrs[sym_index].dyn_index; | |
| 245 | + if (esym_index) { | |
| 246 | + qrel->r_offset = rel->r_offset; | |
| 247 | + qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC64); | |
| 248 | + qrel->r_addend = read64le(ptr) + rel->r_addend; | |
| 249 | + qrel++; | |
| 250 | + break; | |
| 251 | + } | |
| 252 | + } | |
| 253 | + add64le(ptr, val - addr); | |
| 254 | + break; | |
| 255 | + | |
| 226 | 256 | case R_X86_64_GLOB_DAT: |
| 227 | 257 | case R_X86_64_JUMP_SLOT: |
| 228 | 258 | /* They don't need addend */ |
| 229 | 259 | write64le(ptr, val - rel->r_addend); |
| 230 | 260 | break; |
| 231 | 261 | case R_X86_64_GOTPCREL: |
| 232 | − case R_X86_64_GOTPCRELX: | |
| 233 | − case R_X86_64_REX_GOTPCRELX: | |
| 262 | + case R_X86_64_GOTPCRELX: | |
| 263 | + case R_X86_64_REX_GOTPCRELX: | |
| 234 | 264 | add32le(ptr, s1->got->sh_addr - addr + |
| 235 | 265 | s1->sym_attrs[sym_index].got_offset - 4); |
| 236 | 266 | break; |
| 267 | + case R_X86_64_GOTPC32: | |
| 268 | + add32le(ptr, s1->got->sh_addr - addr + rel->r_addend); | |
| 269 | + break; | |
| 270 | + case R_X86_64_GOTPC64: | |
| 271 | + add64le(ptr, s1->got->sh_addr - addr + rel->r_addend); | |
| 272 | + break; | |
| 237 | 273 | case R_X86_64_GOTTPOFF: |
| 238 | 274 | add32le(ptr, val - s1->got->sh_addr); |
| 239 | 275 | break; |
| @@ -241,6 +277,10 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 1 unmodified line | ||
| 241 | 277 | /* we load the got offset */ |
| 242 | 278 | add32le(ptr, s1->sym_attrs[sym_index].got_offset); |
| 243 | 279 | break; |
| 280 | + case R_X86_64_GOT64: | |
| 281 | + /* we load the got offset */ | |
| 282 | + add64le(ptr, s1->sym_attrs[sym_index].got_offset); | |
| 283 | + break; | |
| 244 | 284 | case R_X86_64_RELATIVE: |
| 245 | 285 | /* do nothing */ |
| 246 | 286 | break; |