2 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
3 * Distributed under the terms of the MIT License.
7 #include "runtime_loader_private.h"
9 #include <runtime_loader.h>
17 relocate_rela(image_t
* rootImage
, image_t
* image
, Elf64_Rela
* rel
,
18 size_t relLength
, SymbolLookupCache
* cache
)
20 for (size_t i
= 0; i
< relLength
/ sizeof(Elf64_Rela
); i
++) {
21 int type
= ELF64_R_TYPE(rel
[i
].r_info
);
22 int symIndex
= ELF64_R_SYM(rel
[i
].r_info
);
23 Elf64_Addr symAddr
= 0;
24 image_t
* symbolImage
= NULL
;
26 // Resolve the symbol, if any.
28 Elf64_Sym
* sym
= SYMBOL(image
, symIndex
);
30 status_t status
= resolve_symbol(rootImage
, image
, sym
, cache
,
31 &symAddr
, &symbolImage
);
33 TRACE(("resolve symbol \"%s\" returned: %" B_PRId32
"\n",
34 SYMNAME(image
, sym
), status
));
35 printf("resolve symbol \"%s\" returned: %" B_PRId32
"\n",
36 SYMNAME(image
, sym
), status
);
41 // Address of the relocation.
42 Elf64_Addr relocAddr
= image
->regions
[0].delta
+ rel
[i
].r_offset
;
44 // Calculate the relocation value.
45 Elf64_Addr relocValue
;
50 case R_X86_64_GLOB_DAT
:
51 case R_X86_64_JUMP_SLOT
:
52 relocValue
= symAddr
+ rel
[i
].r_addend
;
55 relocValue
= symAddr
+ rel
[i
].r_addend
- rel
[i
].r_offset
;
57 case R_X86_64_RELATIVE
:
58 relocValue
= image
->regions
[0].delta
+ rel
[i
].r_addend
;
60 case R_X86_64_DTPMOD64
:
61 relocValue
= symbolImage
== NULL
62 ? image
->dso_tls_id
: symbolImage
->dso_tls_id
;
64 case R_X86_64_DTPOFF32
:
65 case R_X86_64_DTPOFF64
:
69 TRACE(("unhandled relocation type %d\n", type
));
73 *(Elf64_Addr
*)relocAddr
= relocValue
;
81 arch_relocate_image(image_t
* rootImage
, image_t
* image
,
82 SymbolLookupCache
* cache
)
88 // Perform RELA relocations.
90 status
= relocate_rela(rootImage
, image
, image
->rela
, image
->rela_len
,
96 // PLT relocations (they are RELA on x86_64).
98 status
= relocate_rela(rootImage
, image
, (Elf64_Rela
*)image
->pltrel
,
99 image
->pltrel_len
, cache
);