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: