History

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.

Thomas Preud'homme committed 10 years ago

Commit 60374d01 parent f924d0c1 file · +5 −3Browse files

Unified · Split

tccelf.c+5−3
@@ -1421,11 +1421,12 @@ static unsigned long put_got_entry(TCCState *s1, · 1420 unmodified lines
1421 /* empty PLT: create PLT0 entry that push address of call site and1421 /* empty PLT: create PLT0 entry that push address of call site and
1422 jump to ld.so resolution routine (GOT + 8) */1422 jump to ld.so resolution routine (GOT + 8) */
1423 if (plt->data_offset == 0) {1423 if (plt->data_offset == 0) {
1424 p = section_ptr_add(plt, 16);1424 p = section_ptr_add(plt, 20);
1425 write32le(p, 0xe52de004); /* push {lr} */1425 write32le(p, 0xe52de004); /* push {lr} */
1426 write32le(p+4, 0xe59fe010); /* ldr lr, [pc, #16] */1426 write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */
1427 write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */1427 write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */
1428 write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */1428 write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
1429 /* p+16 is set in relocate_plt */
1429 }1430 }
1430 1431
1431 symattr->plt_offset = plt->data_offset;1432 symattr->plt_offset = plt->data_offset;
@@ -2151,7 +2152,8 @@ ST_FUNC void relocate_plt(TCCState *s1) · 719 unmodified lines
2151 }2152 }
2152#elif defined(TCC_TARGET_ARM)2153#elif defined(TCC_TARGET_ARM)
2153 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;2154 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
2154 p += 16;2155 write32le(s1->plt->data + 16, x - 16);
2156 p += 20;
2155 while (p < p_end) {2157 while (p < p_end) {
2156 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */2158 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
2157 p += 4;2159 p += 4;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t