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
451 if (addr) {451 if (addr) {
452 sym->st_value = (addr_t)addr;452 sym->st_value = (addr_t)addr;
453#ifdef DEBUG_RELOC453#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);
455#endif455#endif
456 goto found;456 goto found;
457 }457 }
@@ -797,8 +797,21 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 339 unmodified lines
797 break;797 break;
798 case R_AARCH64_JUMP26:798 case R_AARCH64_JUMP26:
799 case R_AARCH64_CALL26:799 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
800 if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)811 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 }
802 *(uint32_t *)ptr = 0x14000000 | (type == R_AARCH64_CALL26) << 31 |815 *(uint32_t *)ptr = 0x14000000 | (type == R_AARCH64_CALL26) << 31 |
803 ((val - addr) >> 2 & 0x3ffffff);816 ((val - addr) >> 2 & 0x3ffffff);
804 break;817 break;
@@ -818,7 +831,17 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 13 unmodified lines
818 & 0xff8) << 7;831 & 0xff8) << 7;
819 break;832 break;
820 case R_AARCH64_COPY:833 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;
822 default:845 default:
823 fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",846 fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
824 type, (unsigned)addr, ptr, (unsigned)val);847 type, (unsigned)addr, ptr, (unsigned)val);
@@ -1211,6 +1234,7 @@ static unsigned long put_got_entry(TCCState *s1, · 386 unmodified lines
1211 plt = s1->plt;1234 plt = s1->plt;
1212 if (plt->data_offset == 0)1235 if (plt->data_offset == 0)
1213 section_ptr_add(plt, 32);1236 section_ptr_add(plt, 32);
1237 symattr->plt_offset = plt->data_offset;
1214 p = section_ptr_add(plt, 16);1238 p = section_ptr_add(plt, 16);
1215 put32(p, s1->got->data_offset);1239 put32(p, s1->got->data_offset);
1216 put32(p + 4, (uint64_t)s1->got->data_offset >> 32);1240 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
1372 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,1396 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1373 sym_index);1397 sym_index);
1374 break;1398 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;
1375#elif defined(TCC_TARGET_C67)1416#elif defined(TCC_TARGET_C67)
1376 case R_C60_GOT32:1417 case R_C60_GOT32:
1377 case R_C60_GOTOFF:1418 case R_C60_GOTOFF:
@@ -1895,8 +1936,8 @@ ST_FUNC void relocate_plt(TCCState *s1) · 517 unmodified lines
1895 uint64_t plt = s1->plt->sh_addr;1936 uint64_t plt = s1->plt->sh_addr;
1896 uint64_t got = s1->got->sh_addr;1937 uint64_t got = s1->got->sh_addr;
1897 uint64_t off = (got >> 12) - (plt >> 12);1938 uint64_t off = (got >> 12) - (plt >> 12);
1898 if ((off + ((uint64_t)1 << 20)) >> 21)1939 if ((off + ((uint32_t)1 << 20)) >> 21)
1899 tcc_error("Failed relocating PLT");1940 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
1900 put32(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!1941 put32(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
1901 put32(p + 4, (0x90000010 | // adrp x16,...1942 put32(p + 4, (0x90000010 | // adrp x16,...
1902 (off & 0x1ffffc) << 3 | (off & 3) << 29));1943 (off & 0x1ffffc) << 3 | (off & 3) << 29));
@@ -1914,8 +1955,8 @@ ST_FUNC void relocate_plt(TCCState *s1) · 11 unmodified lines
1914 uint64_t addr = got +1955 uint64_t addr = got +
1915 (get32(p) | (uint64_t)get32(p + 4) << 32);1956 (get32(p) | (uint64_t)get32(p + 4) << 32);
1916 uint32_t off = (addr >> 12) - (pc >> 12);1957 uint32_t off = (addr >> 12) - (pc >> 12);
1917 if ((off + ((uint64_t)1 << 20)) >> 21)1958 if ((off + ((uint32_t)1 << 20)) >> 21)
1918 tcc_error("Failed relocating PLT");1959 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
1919 put32(p, (0x90000010 | // adrp x16,...1960 put32(p, (0x90000010 | // adrp x16,...
1920 (off & 0x1ffffc) << 3 | (off & 3) << 29));1961 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1921 put32(p + 4, (0xf9400211 | // ldr x17,[x16,#...]1962 put32(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
@@ -2590,9 +2631,12 @@ static int elf_output_file(TCCState *s1, const char *filename) · 668 unmodified lines
2590 2631
2591 /* relocate symbols in .dynsym now that final addresses are known */2632 /* relocate symbols in .dynsym now that final addresses are known */
2592 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {2633 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2593 /* relocate to PLT if symbol corresponds to a PLT entry */
2594 if (sym->st_shndx == SHN_UNDEF) {2634 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)
2596 sym->st_value += s1->plt->sh_addr;2640 sym->st_value += s1->plt->sh_addr;
2597 } else if (sym->st_shndx < SHN_LORESERVE) {2641 } else if (sym->st_shndx < SHN_LORESERVE) {
2598 /* do symbol relocation */2642 /* do symbol relocation */
tccrun.c+1−1
@@ -196,7 +196,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr) · 195 unmodified lines
196 if (0 == (s->sh_flags & SHF_ALLOC))196 if (0 == (s->sh_flags & SHF_ALLOC))
197 continue;197 continue;
198 length = s->data_offset;198 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);
200 ptr = (void*)s->sh_addr;200 ptr = (void*)s->sh_addr;
201 if (NULL == s->data || s->sh_type == SHT_NOBITS)201 if (NULL == s->data || s->sh_type == SHT_NOBITS)
202 memset(ptr, 0, length);202 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