1 #ifdef TARGET_DEFS_ONLY
3 #define EM_TCC_TARGET EM_AARCH64
5 #define R_DATA_32 R_AARCH64_ABS32
6 #define R_DATA_PTR R_AARCH64_ABS64
7 #define R_JMP_SLOT R_AARCH64_JUMP_SLOT
8 #define R_GLOB_DAT R_AARCH64_GLOB_DAT
9 #define R_COPY R_AARCH64_COPY
11 #define R_NUM R_AARCH64_NUM
13 #define ELF_START_ADDR 0x00400000
14 #define ELF_PAGE_SIZE 0x1000
16 #define HAVE_SECTION_RELOC
18 #else /* !TARGET_DEFS_ONLY */
22 ST_DATA
struct reloc_info relocs_info
[R_NUM
] = {
23 INIT_RELOC_INFO (R_AARCH64_ABS32
, 0, NO_GOTPLT_ENTRY
, 0)
24 INIT_RELOC_INFO (R_AARCH64_ABS64
, 0, NO_GOTPLT_ENTRY
, 0)
25 INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G0_NC
, 0, NO_GOTPLT_ENTRY
, 0)
26 INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G1_NC
, 0, NO_GOTPLT_ENTRY
, 0)
27 INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G2_NC
, 0, NO_GOTPLT_ENTRY
, 0)
28 INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G3
, 0, NO_GOTPLT_ENTRY
, 0)
29 INIT_RELOC_INFO (R_AARCH64_ADR_PREL_PG_HI21
, 0, NO_GOTPLT_ENTRY
, 0)
30 INIT_RELOC_INFO (R_AARCH64_ADD_ABS_LO12_NC
, 0, NO_GOTPLT_ENTRY
, 0)
31 INIT_RELOC_INFO (R_AARCH64_JUMP26
, 1, AUTO_GOTPLT_ENTRY
, 1)
32 INIT_RELOC_INFO (R_AARCH64_CALL26
, 1, AUTO_GOTPLT_ENTRY
, 1)
33 INIT_RELOC_INFO (R_AARCH64_ADR_GOT_PAGE
, 0, ALWAYS_GOTPLT_ENTRY
, 0)
34 INIT_RELOC_INFO (R_AARCH64_LD64_GOT_LO12_NC
, 0, ALWAYS_GOTPLT_ENTRY
, 0)
35 INIT_RELOC_INFO (R_AARCH64_GLOB_DAT
, 0, NO_GOTPLT_ENTRY
, 0)
36 INIT_RELOC_INFO (R_AARCH64_JUMP_SLOT
, 1, NO_GOTPLT_ENTRY
, 0)
39 void relocate_init(Section
*sr
) {}
41 void relocate(TCCState
*s1
, ElfW_Rel
*rel
, int type
, char *ptr
, addr_t addr
, addr_t val
)
46 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
47 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
56 case R_AARCH64_MOVW_UABS_G0_NC
:
57 write32le(ptr
, ((read32le(ptr
) & 0xffe0001f) |
58 (val
& 0xffff) << 5));
60 case R_AARCH64_MOVW_UABS_G1_NC
:
61 write32le(ptr
, ((read32le(ptr
) & 0xffe0001f) |
62 (val
>> 16 & 0xffff) << 5));
64 case R_AARCH64_MOVW_UABS_G2_NC
:
65 write32le(ptr
, ((read32le(ptr
) & 0xffe0001f) |
66 (val
>> 32 & 0xffff) << 5));
68 case R_AARCH64_MOVW_UABS_G3
:
69 write32le(ptr
, ((read32le(ptr
) & 0xffe0001f) |
70 (val
>> 48 & 0xffff) << 5));
72 case R_AARCH64_ADR_PREL_PG_HI21
: {
73 uint64_t off
= (val
>> 12) - (addr
>> 12);
74 if ((off
+ ((uint64_t)1 << 20)) >> 21)
75 tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
76 write32le(ptr
, ((read32le(ptr
) & 0x9f00001f) |
77 (off
& 0x1ffffc) << 3 | (off
& 3) << 29));
80 case R_AARCH64_ADD_ABS_LO12_NC
:
81 write32le(ptr
, ((read32le(ptr
) & 0xffc003ff) |
82 (val
& 0xfff) << 10));
84 case R_AARCH64_JUMP26
:
85 case R_AARCH64_CALL26
:
87 printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type
, addr
, val
,
88 (char *) symtab_section
->link
->data
+ sym
->st_name
);
90 if (((val
- addr
) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
91 tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed"
92 " (val=%lx, addr=%lx)", val
, addr
);
93 write32le(ptr
, (0x14000000 |
94 (uint32_t)(type
== R_AARCH64_CALL26
) << 31 |
95 ((val
- addr
) >> 2 & 0x3ffffff)));
97 case R_AARCH64_ADR_GOT_PAGE
: {
100 s1
->sym_attrs
[sym_index
].got_offset
) >> 12) - (addr
>> 12));
101 if ((off
+ ((uint64_t)1 << 20)) >> 21)
102 tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");
103 write32le(ptr
, ((read32le(ptr
) & 0x9f00001f) |
104 (off
& 0x1ffffc) << 3 | (off
& 3) << 29));
107 case R_AARCH64_LD64_GOT_LO12_NC
:
109 ((read32le(ptr
) & 0xfff803ff) |
111 s1
->sym_attrs
[sym_index
].got_offset
) & 0xff8) << 7));
115 case R_AARCH64_GLOB_DAT
:
116 case R_AARCH64_JUMP_SLOT
:
117 /* They don't need addend */
119 printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type
, addr
,
121 (char *) symtab_section
->link
->data
+ sym
->st_name
);
123 write64le(ptr
, val
- rel
->r_addend
);
126 fprintf(stderr
, "FIXME: handle reloc type %x at %x [%p] to %x\n",
127 type
, (unsigned)addr
, ptr
, (unsigned)val
);
132 #endif /* !TARGET_DEFS_ONLY */