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
638 case R_ARM_THM_JUMP24:638 case R_ARM_THM_JUMP24:
639 {639 {
640 int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;640 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;
642 643
643 /* weak reference */644 /* weak reference */
644 if (sym->st_shndx == SHN_UNDEF &&645 if (sym->st_shndx == SHN_UNDEF &&
@@ -662,9 +663,14 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 17 unmodified lines
662 663
663 /* Relocation infos */664 /* Relocation infos */
664 to_thumb = val & 1;665 to_thumb = val & 1;
666 plt = s1->plt;
667 to_plt = (val >= plt->sh_addr) &&
668 (val < plt->sh_addr + plt->data_offset);
665 is_call = (type == R_ARM_THM_CALL);669 is_call = (type == R_ARM_THM_CALL);
666 670
667 /* Compute final offset */671 /* Compute final offset */
672 if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */
673 x -= 4;
668 x += val - addr;674 x += val - addr;
669 if (!to_thumb && is_call) {675 if (!to_thumb && is_call) {
670 blx_bit = 0; /* bl -> blx */676 blx_bit = 0; /* bl -> blx */
@@ -675,9 +681,9 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 4 unmodified lines
675 * offset must not be out of range681 * offset must not be out of range
676 * if target is to be entered in arm mode:682 * if target is to be entered in arm mode:
677 - bit 1 must not set683 - bit 1 must not set
678 - instruction must be a call (bl) */684 - instruction must be a call (bl) or a jump to PLT */
679 if (!to_thumb || x >= 0x1000000 || x < -0x1000000)685 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))
681 tcc_error("can't relocate value at %x",addr);687 tcc_error("can't relocate value at %x",addr);
682 688
683 /* Compute and store final offset */689 /* Compute and store final offset */
@@ -1096,10 +1102,13 @@ static void put_got_entry(TCCState *s1, · 412 unmodified lines
1096 put32(p + 12, 0xe5bef008);1102 put32(p + 12, 0xe5bef008);
1097 }1103 }
1098 1104
1099 p = section_ptr_add(plt, 16);1105 p = section_ptr_add(plt, 20);
1100 put32(p , 0xe59fc004);1106 put32(p , 0x4778); // bx pc
1101 put32(p+4, 0xe08fc00c);1107 put32(p+2, 0x46c0); // nop
1102 put32(p+8, 0xe59cf000);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
1103 put32(p+12, s1->got->data_offset);1112 put32(p+12, s1->got->data_offset);
1104 1113
1105 /* the symbol is modified so that it will be relocated to1114 /* 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
2057#elif defined(TCC_TARGET_ARM)2066#elif defined(TCC_TARGET_ARM)
2058 int x;2067 int x;
2059 x=s1->got->sh_addr - s1->plt->sh_addr - 12;2068 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
2060 p +=16;2069 p += 16;
2061 while (p < p_end) {2070 while (p < p_end) {
2071 p += 4;
2062 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);2072 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
2063 p += 16;2073 p += 16;
2064 }2074 }

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