History

aarch64: Fix -run.

This adds some more support for properly transfering some offsets over the different stages of a relocations life. Still not at all psABI compliant and DSOs can't yet be generated. But it runs the testsuite in qemu-arm64.

Michael Matz committed 11 years ago

Commit 6d055311 parent b14ef0e2 files · +54 −10Browse files

Unified · Split

2 files
  1. tccelf.c +53 −9
  2. tccrun.c +1 −1
tccelf.c+53−9
@@ -451,7 +451,7 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve) · 450 unmodified lines
451451 if (addr) {
452452 sym->st_value = (addr_t)addr;
453453 #ifdef DEBUG_RELOC
454− printf ("relocate_sym: %s -> 0x%x\n", name, sym->st_value);
454+ printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
455455 #endif
456456 goto found;
457457 }
@@ -797,8 +797,21 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 339 unmodified lines
797797 break;
798798 case R_AARCH64_JUMP26:
799799 case R_AARCH64_CALL26:
800+ /* This check must match the one in build_got_entries, testing
801+ if we really need a PLT slot. */
802+ if (sym->st_shndx == SHN_UNDEF)
803+ /* We've put the PLT slot offset into r_addend when generating
804+ it, and that's what we must use as relocation value (adjusted
805+ by section offset of course). */
806+ val = s1->plt->sh_addr + rel->r_addend;
807+#ifdef DEBUG_RELOC
808+ printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
809+ (char *) symtab_section->link->data + sym->st_name);
810+#endif
800811 if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
801− tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed");
812+ {
813+ tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val);
814+ }
802815 *(uint32_t *)ptr = 0x14000000 | (type == R_AARCH64_CALL26) << 31 |
803816 ((val - addr) >> 2 & 0x3ffffff);
804817 break;
@@ -818,7 +831,17 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 13 unmodified lines
818831 & 0xff8) << 7;
819832 break;
820833 case R_AARCH64_COPY:
821− break;
834+ break;
835+ case R_AARCH64_GLOB_DAT:
836+ case R_AARCH64_JUMP_SLOT:
837+ /* They don't need addend */
838+#ifdef DEBUG_RELOC
839+ printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
840+ val - rel->r_addend,
841+ (char *) symtab_section->link->data + sym->st_name);
842+#endif
843+ *(addr_t *)ptr = val - rel->r_addend;
844+ break;
822845 default:
823846 fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
824847 type, (unsigned)addr, ptr, (unsigned)val);
@@ -1211,6 +1234,7 @@ static unsigned long put_got_entry(TCCState *s1, · 386 unmodified lines
12111234 plt = s1->plt;
12121235 if (plt->data_offset == 0)
12131236 section_ptr_add(plt, 32);
1237+ symattr->plt_offset = plt->data_offset;
12141238 p = section_ptr_add(plt, 16);
12151239 put32(p, s1->got->data_offset);
12161240 put32(p + 4, (uint64_t)s1->got->data_offset >> 32);
@@ -1372,6 +1396,23 @@ ST_FUNC void build_got_entries(TCCState *s1) · 155 unmodified lines
13721396 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
13731397 sym_index);
13741398 break;
1399+
1400+ case R_AARCH64_JUMP26:
1401+ case R_AARCH64_CALL26:
1402+ if (!s1->got)
1403+ build_got(s1);
1404+ sym_index = ELFW(R_SYM)(rel->r_info);
1405+ sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1406+ if (sym->st_shndx == SHN_UNDEF) {
1407+ unsigned long ofs;
1408+ reloc_type = R_AARCH64_JUMP_SLOT;
1409+ ofs = put_got_entry(s1, reloc_type, sym->st_size,
1410+ sym->st_info, sym_index);
1411+ /* We store the place of the generated PLT slot
1412+ in our addend. */
1413+ rel->r_addend += ofs;
1414+ }
1415+ break;
13751416 #elif defined(TCC_TARGET_C67)
13761417 case R_C60_GOT32:
13771418 case R_C60_GOTOFF:
@@ -1895,8 +1936,8 @@ ST_FUNC void relocate_plt(TCCState *s1) · 517 unmodified lines
18951936 uint64_t plt = s1->plt->sh_addr;
18961937 uint64_t got = s1->got->sh_addr;
18971938 uint64_t off = (got >> 12) - (plt >> 12);
1898− if ((off + ((uint64_t)1 << 20)) >> 21)
1899− tcc_error("Failed relocating PLT");
1939+ if ((off + ((uint32_t)1 << 20)) >> 21)
1940+ tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
19001941 put32(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
19011942 put32(p + 4, (0x90000010 | // adrp x16,...
19021943 (off & 0x1ffffc) << 3 | (off & 3) << 29));
@@ -1914,8 +1955,8 @@ ST_FUNC void relocate_plt(TCCState *s1) · 11 unmodified lines
19141955 uint64_t addr = got +
19151956 (get32(p) | (uint64_t)get32(p + 4) << 32);
19161957 uint32_t off = (addr >> 12) - (pc >> 12);
1917− if ((off + ((uint64_t)1 << 20)) >> 21)
1918− tcc_error("Failed relocating PLT");
1958+ if ((off + ((uint32_t)1 << 20)) >> 21)
1959+ tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
19191960 put32(p, (0x90000010 | // adrp x16,...
19201961 (off & 0x1ffffc) << 3 | (off & 3) << 29));
19211962 put32(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
@@ -2590,9 +2631,12 @@ static int elf_output_file(TCCState *s1, const char *filename) · 668 unmodified lines
25902631
25912632 /* relocate symbols in .dynsym now that final addresses are known */
25922633 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2593− /* relocate to PLT if symbol corresponds to a PLT entry */
25942634 if (sym->st_shndx == SHN_UNDEF) {
2595− if (sym->st_value)
2635+ /* relocate to PLT if symbol corresponds to a PLT entry,
2636+ but not if it's a weak symbol */
2637+ if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
2638+ sym->st_value = 0;
2639+ else if (sym->st_value)
25962640 sym->st_value += s1->plt->sh_addr;
25972641 } else if (sym->st_shndx < SHN_LORESERVE) {
25982642 /* do symbol relocation */
tccrun.c+1−1
@@ -196,7 +196,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr) · 195 unmodified lines
196196 if (0 == (s->sh_flags & SHF_ALLOC))
197197 continue;
198198 length = s->data_offset;
199− // printf("%-12s %08x %04x\n", s->name, s->sh_addr, length);
199+ // printf("%-12s %08lx %04x\n", s->name, s->sh_addr, length);
200200 ptr = (void*)s->sh_addr;
201201 if (NULL == s->data || s->sh_type == SHT_NOBITS)
202202 memset(ptr, 0, length);

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