Add riscv dll support

Most support was already present.

riscv64-link.c:
- create_plt_entry:
 - remove DLLs unimplemented!
- relocate:
 - Add TCC_OUTPUT_DLL for R_RISCV_32, R_RISCV_64

tccelf.c:
- prepare_dynamic_rel:
 - Add R_RISCV_32, R_RISCV_64
This commit is contained in:
herman ten brugge 2020-08-04 10:36:47 +02:00
parent b8fb2b02d9
commit a0a0f4d029
2 changed files with 30 additions and 6 deletions

View File

@ -101,9 +101,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);
plt_offset = plt->data_offset;
@ -168,7 +165,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
{
uint64_t off64;
uint32_t off32;
int sym_index = ELFW(R_SYM)(rel->r_info);
int sym_index = ELFW(R_SYM)(rel->r_info), esym_index;
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
switch(type) {
@ -284,10 +281,33 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
return;
case R_RISCV_32:
if (s1->output_type == TCC_OUTPUT_DLL) {
/* XXX: this logic may depend on TCC's codegen
now TCC uses R_RISCV_RELATIVE even for a 64bit pointer */
qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(0, R_RISCV_RELATIVE);
/* Use sign extension! */
qrel->r_addend = (int)read32le(ptr) + val;
qrel++;
}
add32le(ptr, val);
return;
case R_RISCV_JUMP_SLOT:
case R_RISCV_64:
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_RISCV_64);
qrel->r_addend = rel->r_addend;
qrel++;
break;
} else {
qrel->r_info = ELFW(R_INFO)(0, R_RISCV_RELATIVE);
qrel->r_addend = read64le(ptr) + val;
qrel++;
}
}
case R_RISCV_JUMP_SLOT:
add64le(ptr, val);
return;
case R_RISCV_ADD64:

View File

@ -1029,7 +1029,8 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
{
int count = 0;
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64)
defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
defined(TCC_TARGET_RISCV64)
ElfW_Rel *rel;
for_each_elem(sr, 0, rel, ElfW_Rel) {
int sym_index = ELFW(R_SYM)(rel->r_info);
@ -1052,6 +1053,9 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
#elif defined(TCC_TARGET_ARM64)
case R_AARCH64_ABS32:
case R_AARCH64_ABS64:
#elif defined(TCC_TARGET_RISCV64)
case R_RISCV_32:
case R_RISCV_64:
#endif
count++;
break;