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
Unified · Split
| @@ -101,9 +101,6 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 100 unmodified lines | ||
| 101 | 101 | uint8_t *p; |
| 102 | 102 | unsigned plt_offset; |
| 103 | 103 | |
| 104 | − if (s1->output_type == TCC_OUTPUT_DLL) | |
| 105 | − tcc_error("DLLs unimplemented!"); | |
| 106 | − | |
| 107 | 104 | if (plt->data_offset == 0) |
| 108 | 105 | section_ptr_add(plt, 32); |
| 109 | 106 | plt_offset = plt->data_offset; |
| @@ -168,7 +165,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 58 unmodified lines | ||
| 168 | 165 | { |
| 169 | 166 | uint64_t off64; |
| 170 | 167 | uint32_t off32; |
| 171 | − int sym_index = ELFW(R_SYM)(rel->r_info); | |
| 168 | + int sym_index = ELFW(R_SYM)(rel->r_info), esym_index; | |
| 172 | 169 | ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; |
| 173 | 170 | |
| 174 | 171 | switch(type) { |
| @@ -284,10 +281,33 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 109 unmodified lines | ||
| 284 | 281 | return; |
| 285 | 282 | |
| 286 | 283 | case R_RISCV_32: |
| 284 | + if (s1->output_type == TCC_OUTPUT_DLL) { | |
| 285 | + /* XXX: this logic may depend on TCC's codegen | |
| 286 | + now TCC uses R_RISCV_RELATIVE even for a 64bit pointer */ | |
| 287 | + qrel->r_offset = rel->r_offset; | |
| 288 | + qrel->r_info = ELFW(R_INFO)(0, R_RISCV_RELATIVE); | |
| 289 | + /* Use sign extension! */ | |
| 290 | + qrel->r_addend = (int)read32le(ptr) + val; | |
| 291 | + qrel++; | |
| 292 | + } | |
| 287 | 293 | add32le(ptr, val); |
| 288 | 294 | return; |
| 289 | − case R_RISCV_JUMP_SLOT: | |
| 290 | 295 | case R_RISCV_64: |
| 296 | + if (s1->output_type == TCC_OUTPUT_DLL) { | |
| 297 | + esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index; | |
| 298 | + qrel->r_offset = rel->r_offset; | |
| 299 | + if (esym_index) { | |
| 300 | + qrel->r_info = ELFW(R_INFO)(esym_index, R_RISCV_64); | |
| 301 | + qrel->r_addend = rel->r_addend; | |
| 302 | + qrel++; | |
| 303 | + break; | |
| 304 | + } else { | |
| 305 | + qrel->r_info = ELFW(R_INFO)(0, R_RISCV_RELATIVE); | |
| 306 | + qrel->r_addend = read64le(ptr) + val; | |
| 307 | + qrel++; | |
| 308 | + } | |
| 309 | + } | |
| 310 | + case R_RISCV_JUMP_SLOT: | |
| 291 | 311 | add64le(ptr, val); |
| 292 | 312 | return; |
| 293 | 313 | case R_RISCV_ADD64: |
| @@ -1029,7 +1029,8 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 1028 unmodified lines | ||
| 1029 | 1029 | { |
| 1030 | 1030 | int count = 0; |
| 1031 | 1031 | #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \ |
| 1032 | − defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) | |
| 1032 | + defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \ | |
| 1033 | + defined(TCC_TARGET_RISCV64) | |
| 1033 | 1034 | ElfW_Rel *rel; |
| 1034 | 1035 | for_each_elem(sr, 0, rel, ElfW_Rel) { |
| 1035 | 1036 | int sym_index = ELFW(R_SYM)(rel->r_info); |
| @@ -1052,6 +1053,9 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 16 unmodified lines | ||
| 1052 | 1053 | #elif defined(TCC_TARGET_ARM64) |
| 1053 | 1054 | case R_AARCH64_ABS32: |
| 1054 | 1055 | case R_AARCH64_ABS64: |
| 1056 | +#elif defined(TCC_TARGET_RISCV64) | |
| 1057 | + case R_RISCV_32: | |
| 1058 | + case R_RISCV_64: | |
| 1055 | 1059 | #endif |
| 1056 | 1060 | count++; |
| 1057 | 1061 | break; |