Add arm64 dll support

Most support was already present.

arm64-link.c:
- create_plt_entry:
 - remove DLLs unimplemented!
- relocate:
 - Add TCC_OUTPUT_DLL for R_AARCH64_ABS64/R_AARCH64_ABS32/R_AARCH64_PREL32

tccelf.c:
- prepare_dynamic_rel:
 - Add R_AARCH64_ABS64/R_AARCH64_ABS32/R_AARCH64_PREL32
- fill_got_entry:
 - Change 'TCC_TARGET_X86_64' into 'PTR_SIZE == 8'
This commit is contained in:
herman ten brugge 2020-08-01 19:44:49 +02:00
parent d55a3f3362
commit 1da7159689
2 changed files with 43 additions and 6 deletions

View File

@ -88,9 +88,6 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_
uint8_t *p;
unsigned plt_offset;
if (s1->output_type == TCC_OUTPUT_DLL)
tcc_error("DLLs unimplemented!");
if (plt->data_offset == 0) {
section_ptr_add(plt, 32);
}
@ -152,19 +149,54 @@ ST_FUNC void relocate_plt(TCCState *s1)
void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
{
int sym_index = ELFW(R_SYM)(rel->r_info);
int sym_index = ELFW(R_SYM)(rel->r_info), esym_index;
#ifdef DEBUG_RELOC
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
#endif
switch(type) {
case R_AARCH64_ABS64:
if (s1->output_type == TCC_OUTPUT_DLL) {
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
qrel->r_offset = rel->r_offset;
if (esym_index) {
qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_ABS64);
qrel->r_addend = rel->r_addend;
qrel++;
break;
} else {
qrel->r_info = ELFW(R_INFO)(0, R_AARCH64_RELATIVE);
qrel->r_addend = read64le(ptr) + val;
qrel++;
}
}
add64le(ptr, val);
return;
case R_AARCH64_ABS32:
if (s1->output_type == TCC_OUTPUT_DLL) {
/* XXX: this logic may depend on TCC's codegen
now TCC uses R_AARCH64_RELATIVE even for a 64bit pointer */
qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(0, R_AARCH64_RELATIVE);
/* Use sign extension! */
qrel->r_addend = (int)read32le(ptr) + val;
qrel++;
}
add32le(ptr, val);
return;
case R_AARCH64_PREL32:
if (s1->output_type == TCC_OUTPUT_DLL) {
/* DLL relocation */
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
if (esym_index) {
qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_PREL32);
/* Use sign extension! */
qrel->r_addend = (int)read32le(ptr) + rel->r_addend;
qrel++;
break;
}
}
write32le(ptr, val - addr);
return;
case R_AARCH64_MOVW_UABS_G0_NC:

View File

@ -1028,7 +1028,7 @@ static void relocate_rel(TCCState *s1, Section *sr)
static int prepare_dynamic_rel(TCCState *s1, Section *sr)
{
int count = 0;
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
ElfW_Rel *rel;
for_each_elem(sr, 0, rel, ElfW_Rel) {
int sym_index = ELFW(R_SYM)(rel->r_info);
@ -1046,6 +1046,9 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
case R_X86_64_32:
case R_X86_64_32S:
case R_X86_64_64:
#elif defined(TCC_TARGET_ARM64)
case R_AARCH64_ABS32:
case R_AARCH64_ABS64:
#endif
count++;
break;
@ -1053,6 +1056,8 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
case R_386_PC32:
#elif defined(TCC_TARGET_X86_64)
case R_X86_64_PC32:
#elif defined(TCC_TARGET_ARM64)
case R_AARCH64_PREL32:
#endif
if (get_sym_attr(s1, sym_index, 0)->dyn_index)
count++;
@ -1553,7 +1558,7 @@ ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
if (0 == offset)
return;
section_reserve(s1->got, offset + PTR_SIZE);
#ifdef TCC_TARGET_X86_64
#if PTR_SIZE == 8
write64le(s1->got->data + offset, sym->st_value);
#else
write32le(s1->got->data + offset, sym->st_value);