mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-28 04:00:06 +08:00
Add address of GOT + 8 in PLT + 16 and fix PLT0
On ARM targets, the jump to ld.so resolution routine is done in PLT0 by loading the offset to the GOT found in PLT+16 and from there loading the address in GOT+8 and jumping to it. Currently tcc starts the first regular PLT entry at PLT+16 which thus does not contain the offset to the GOT. This commit fixes that. Note that calls via PLT still worked nonetheless because of some missing dynamic tag which makes ld.so behaves as if RTLD_BIND_NOW was specified in the environment for all executable created by tcc.
This commit is contained in:
parent
f924d0ca96
commit
60374d01ae
8
tccelf.c
8
tccelf.c
@ -1421,11 +1421,12 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||
/* empty PLT: create PLT0 entry that push address of call site and
|
||||
jump to ld.so resolution routine (GOT + 8) */
|
||||
if (plt->data_offset == 0) {
|
||||
p = section_ptr_add(plt, 16);
|
||||
p = section_ptr_add(plt, 20);
|
||||
write32le(p, 0xe52de004); /* push {lr} */
|
||||
write32le(p+4, 0xe59fe010); /* ldr lr, [pc, #16] */
|
||||
write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */
|
||||
write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */
|
||||
write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
|
||||
/* p+16 is set in relocate_plt */
|
||||
}
|
||||
|
||||
symattr->plt_offset = plt->data_offset;
|
||||
@ -2151,7 +2152,8 @@ ST_FUNC void relocate_plt(TCCState *s1)
|
||||
}
|
||||
#elif defined(TCC_TARGET_ARM)
|
||||
int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
|
||||
p += 16;
|
||||
write32le(s1->plt->data + 16, x - 16);
|
||||
p += 20;
|
||||
while (p < p_end) {
|
||||
if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
|
||||
p += 4;
|
||||
|
Loading…
Reference in New Issue
Block a user