History

Support R_ARM_THM_JUMP24 relocation to plt

Add thumb stubs switching from thumb mode to arm mode to *all* PLT entries so that R_ARM_THM_JUMP24 relocations to PLT entries can be satisfied.

Thomas Preud'homme committed 14 years ago

Commit e07802e1 parent b0f08ac1 file · +18 −8Browse files

Unified · Split

tccelf.c+18−8
@@ -638,7 +638,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 637 unmodified lines
638638 case R_ARM_THM_JUMP24:
639639 {
640640 int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
641− int to_thumb, is_call, blx_bit = 1 << 12;
641+ int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
642+ Section *plt;
642643
643644 /* weak reference */
644645 if (sym->st_shndx == SHN_UNDEF &&
@@ -662,9 +663,14 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 17 unmodified lines
662663
663664 /* Relocation infos */
664665 to_thumb = val & 1;
666+ plt = s1->plt;
667+ to_plt = (val >= plt->sh_addr) &&
668+ (val < plt->sh_addr + plt->data_offset);
665669 is_call = (type == R_ARM_THM_CALL);
666670
667671 /* Compute final offset */
672+ if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */
673+ x -= 4;
668674 x += val - addr;
669675 if (!to_thumb && is_call) {
670676 blx_bit = 0; /* bl -> blx */
@@ -675,9 +681,9 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 4 unmodified lines
675681 * offset must not be out of range
676682 * if target is to be entered in arm mode:
677683 - bit 1 must not set
678− - instruction must be a call (bl) */
684+ - instruction must be a call (bl) or a jump to PLT */
679685 if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
680− if (to_thumb || (val & 2) || !is_call)
686+ if (to_thumb || (val & 2) || (!is_call && !to_plt))
681687 tcc_error("can't relocate value at %x",addr);
682688
683689 /* Compute and store final offset */
@@ -1096,10 +1102,13 @@ static void put_got_entry(TCCState *s1, · 412 unmodified lines
10961102 put32(p + 12, 0xe5bef008);
10971103 }
10981104
1099− p = section_ptr_add(plt, 16);
1100− put32(p , 0xe59fc004);
1101− put32(p+4, 0xe08fc00c);
1102− put32(p+8, 0xe59cf000);
1105+ p = section_ptr_add(plt, 20);
1106+ put32(p , 0x4778); // bx pc
1107+ put32(p+2, 0x46c0); // nop
1108+ p += 4;
1109+ put32(p , 0xe59fc004); // ldr ip, [pc, #4] // offset in GOT
1110+ put32(p+4, 0xe08fc00c); // add ip, pc, ip // absolute address or offset
1111+ put32(p+8, 0xe59cf000); // ldr pc, [ip] // load absolute address or load offset
11031112 put32(p+12, s1->got->data_offset);
11041113
11051114 /* the symbol is modified so that it will be relocated to
@@ -2057,8 +2066,9 @@ static int elf_output_file(TCCState *s1, const char *filename) · 951 unmodified lines
20572066 #elif defined(TCC_TARGET_ARM)
20582067 int x;
20592068 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
2060− p +=16;
2069+ p += 16;
20612070 while (p < p_end) {
2071+ p += 4;
20622072 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
20632073 p += 16;
20642074 }

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