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:
parent
d55a3f3362
commit
1da7159689
2 changed files with 43 additions and 6 deletions
40
arm64-link.c
40
arm64-link.c
|
@ -88,9 +88,6 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
unsigned plt_offset;
|
unsigned plt_offset;
|
||||||
|
|
||||||
if (s1->output_type == TCC_OUTPUT_DLL)
|
|
||||||
tcc_error("DLLs unimplemented!");
|
|
||||||
|
|
||||||
if (plt->data_offset == 0) {
|
if (plt->data_offset == 0) {
|
||||||
section_ptr_add(plt, 32);
|
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)
|
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
|
#ifdef DEBUG_RELOC
|
||||||
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case R_AARCH64_ABS64:
|
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);
|
add64le(ptr, val);
|
||||||
return;
|
return;
|
||||||
case R_AARCH64_ABS32:
|
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);
|
add32le(ptr, val);
|
||||||
return;
|
return;
|
||||||
case R_AARCH64_PREL32:
|
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);
|
write32le(ptr, val - addr);
|
||||||
return;
|
return;
|
||||||
case R_AARCH64_MOVW_UABS_G0_NC:
|
case R_AARCH64_MOVW_UABS_G0_NC:
|
||||||
|
|
9
tccelf.c
9
tccelf.c
|
@ -1028,7 +1028,7 @@ static void relocate_rel(TCCState *s1, Section *sr)
|
||||||
static int prepare_dynamic_rel(TCCState *s1, Section *sr)
|
static int prepare_dynamic_rel(TCCState *s1, Section *sr)
|
||||||
{
|
{
|
||||||
int count = 0;
|
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;
|
ElfW_Rel *rel;
|
||||||
for_each_elem(sr, 0, rel, ElfW_Rel) {
|
for_each_elem(sr, 0, rel, ElfW_Rel) {
|
||||||
int sym_index = ELFW(R_SYM)(rel->r_info);
|
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_32:
|
||||||
case R_X86_64_32S:
|
case R_X86_64_32S:
|
||||||
case R_X86_64_64:
|
case R_X86_64_64:
|
||||||
|
#elif defined(TCC_TARGET_ARM64)
|
||||||
|
case R_AARCH64_ABS32:
|
||||||
|
case R_AARCH64_ABS64:
|
||||||
#endif
|
#endif
|
||||||
count++;
|
count++;
|
||||||
break;
|
break;
|
||||||
|
@ -1053,6 +1056,8 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
|
||||||
case R_386_PC32:
|
case R_386_PC32:
|
||||||
#elif defined(TCC_TARGET_X86_64)
|
#elif defined(TCC_TARGET_X86_64)
|
||||||
case R_X86_64_PC32:
|
case R_X86_64_PC32:
|
||||||
|
#elif defined(TCC_TARGET_ARM64)
|
||||||
|
case R_AARCH64_PREL32:
|
||||||
#endif
|
#endif
|
||||||
if (get_sym_attr(s1, sym_index, 0)->dyn_index)
|
if (get_sym_attr(s1, sym_index, 0)->dyn_index)
|
||||||
count++;
|
count++;
|
||||||
|
@ -1553,7 +1558,7 @@ ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
|
||||||
if (0 == offset)
|
if (0 == offset)
|
||||||
return;
|
return;
|
||||||
section_reserve(s1->got, offset + PTR_SIZE);
|
section_reserve(s1->got, offset + PTR_SIZE);
|
||||||
#ifdef TCC_TARGET_X86_64
|
#if PTR_SIZE == 8
|
||||||
write64le(s1->got->data + offset, sym->st_value);
|
write64le(s1->got->data + offset, sym->st_value);
|
||||||
#else
|
#else
|
||||||
write32le(s1->got->data + offset, sym->st_value);
|
write32le(s1->got->data + offset, sym->st_value);
|
||||||
|
|
Loading…
Add table
Reference in a new issue