2 #define HAVE_SECTION_RELOC
4 ST_DATA
struct reloc_info relocs_info
[] = {
5 INIT_RELOC_INFO (R_AARCH64_ABS32
, 0, NO_GOTPLT_ENTRY
, 0)
6 INIT_RELOC_INFO (R_AARCH64_ABS64
, 0, NO_GOTPLT_ENTRY
, 0)
7 INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G0_NC
, 0, NO_GOTPLT_ENTRY
, 0)
8 INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G1_NC
, 0, NO_GOTPLT_ENTRY
, 0)
9 INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G2_NC
, 0, NO_GOTPLT_ENTRY
, 0)
10 INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G3
, 0, NO_GOTPLT_ENTRY
, 0)
11 INIT_RELOC_INFO (R_AARCH64_ADR_PREL_PG_HI21
, 0, NO_GOTPLT_ENTRY
, 0)
12 INIT_RELOC_INFO (R_AARCH64_ADD_ABS_LO12_NC
, 0, NO_GOTPLT_ENTRY
, 0)
13 INIT_RELOC_INFO (R_AARCH64_JUMP26
, 1, AUTO_GOTPLT_ENTRY
, 1)
14 INIT_RELOC_INFO (R_AARCH64_CALL26
, 1, AUTO_GOTPLT_ENTRY
, 1)
15 INIT_RELOC_INFO (R_AARCH64_ADR_GOT_PAGE
, 0, ALWAYS_GOTPLT_ENTRY
, 0)
16 INIT_RELOC_INFO (R_AARCH64_LD64_GOT_LO12_NC
, 0, ALWAYS_GOTPLT_ENTRY
, 0)
17 INIT_RELOC_INFO (R_AARCH64_GLOB_DAT
, 0, NO_GOTPLT_ENTRY
, 0)
18 INIT_RELOC_INFO (R_AARCH64_JUMP_SLOT
, 1, NO_GOTPLT_ENTRY
, 0)
21 void relocate_init(Section
*sr
) {}
23 void relocate(TCCState
*s1
, ElfW_Rel
*rel
, int type
, char *ptr
, addr_t addr
, addr_t val
)
28 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
29 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
38 case R_AARCH64_MOVW_UABS_G0_NC
:
39 write32le(ptr
, ((read32le(ptr
) & 0xffe0001f) |
40 (val
& 0xffff) << 5));
42 case R_AARCH64_MOVW_UABS_G1_NC
:
43 write32le(ptr
, ((read32le(ptr
) & 0xffe0001f) |
44 (val
>> 16 & 0xffff) << 5));
46 case R_AARCH64_MOVW_UABS_G2_NC
:
47 write32le(ptr
, ((read32le(ptr
) & 0xffe0001f) |
48 (val
>> 32 & 0xffff) << 5));
50 case R_AARCH64_MOVW_UABS_G3
:
51 write32le(ptr
, ((read32le(ptr
) & 0xffe0001f) |
52 (val
>> 48 & 0xffff) << 5));
54 case R_AARCH64_ADR_PREL_PG_HI21
: {
55 uint64_t off
= (val
>> 12) - (addr
>> 12);
56 if ((off
+ ((uint64_t)1 << 20)) >> 21)
57 tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
58 write32le(ptr
, ((read32le(ptr
) & 0x9f00001f) |
59 (off
& 0x1ffffc) << 3 | (off
& 3) << 29));
62 case R_AARCH64_ADD_ABS_LO12_NC
:
63 write32le(ptr
, ((read32le(ptr
) & 0xffc003ff) |
64 (val
& 0xfff) << 10));
66 case R_AARCH64_JUMP26
:
67 case R_AARCH64_CALL26
:
69 printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type
, addr
, val
,
70 (char *) symtab_section
->link
->data
+ sym
->st_name
);
72 if (((val
- addr
) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
74 tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr
, val
);
76 write32le(ptr
, (0x14000000 |
77 (uint32_t)(type
== R_AARCH64_CALL26
) << 31 |
78 ((val
- addr
) >> 2 & 0x3ffffff)));
80 case R_AARCH64_ADR_GOT_PAGE
: {
83 s1
->sym_attrs
[sym_index
].got_offset
) >> 12) - (addr
>> 12));
84 if ((off
+ ((uint64_t)1 << 20)) >> 21)
85 tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");
86 write32le(ptr
, ((read32le(ptr
) & 0x9f00001f) |
87 (off
& 0x1ffffc) << 3 | (off
& 3) << 29));
90 case R_AARCH64_LD64_GOT_LO12_NC
:
92 ((read32le(ptr
) & 0xfff803ff) |
94 s1
->sym_attrs
[sym_index
].got_offset
) & 0xff8) << 7));
98 case R_AARCH64_GLOB_DAT
:
99 case R_AARCH64_JUMP_SLOT
:
100 /* They don't need addend */
102 printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type
, addr
,
104 (char *) symtab_section
->link
->data
+ sym
->st_name
);
106 write64le(ptr
, val
- rel
->r_addend
);
109 fprintf(stderr
, "FIXME: handle reloc type %x at %x [%p] to %x\n",
110 type
, (unsigned)addr
, ptr
, (unsigned)val
);