aot: Implement a few more relocation types for riscv (#2318)

This PR partly fixes #2312. Lightly tested on qemu riscv64.
This commit is contained in:
YAMAMOTO Takashi 2023-06-27 17:33:05 +09:00 committed by GitHub
parent 5831531449
commit 0a0739ef23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -9,6 +9,8 @@
#define R_RISCV_64 2 #define R_RISCV_64 2
#define R_RISCV_CALL 18 #define R_RISCV_CALL 18
#define R_RISCV_CALL_PLT 19 #define R_RISCV_CALL_PLT 19
#define R_RISCV_PCREL_HI20 23
#define R_RISCV_PCREL_LO12_I 24
#define R_RISCV_HI20 26 #define R_RISCV_HI20 26
#define R_RISCV_LO12_I 27 #define R_RISCV_LO12_I 27
#define R_RISCV_LO12_S 28 #define R_RISCV_LO12_S 28
@ -268,7 +270,8 @@ typedef struct RelocTypeStrMap {
static RelocTypeStrMap reloc_type_str_maps[] = { static RelocTypeStrMap reloc_type_str_maps[] = {
RELOC_TYPE_MAP(R_RISCV_32), RELOC_TYPE_MAP(R_RISCV_CALL), RELOC_TYPE_MAP(R_RISCV_32), RELOC_TYPE_MAP(R_RISCV_CALL),
RELOC_TYPE_MAP(R_RISCV_CALL_PLT), RELOC_TYPE_MAP(R_RISCV_HI20), RELOC_TYPE_MAP(R_RISCV_CALL_PLT), RELOC_TYPE_MAP(R_RISCV_PCREL_HI20),
RELOC_TYPE_MAP(R_RISCV_PCREL_LO12_I), RELOC_TYPE_MAP(R_RISCV_HI20),
RELOC_TYPE_MAP(R_RISCV_LO12_I), RELOC_TYPE_MAP(R_RISCV_LO12_S), RELOC_TYPE_MAP(R_RISCV_LO12_I), RELOC_TYPE_MAP(R_RISCV_LO12_S),
}; };
@ -369,14 +372,30 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
break; break;
} }
case R_RISCV_HI20: case R_RISCV_HI20: /* S + A */
case R_RISCV_PCREL_HI20: /* S + A - P */
{ {
if (reloc_type == R_RISCV_PCREL_HI20) {
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend
- (intptr_t)addr);
}
else {
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend); val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend);
}
CHECK_RELOC_OFFSET(sizeof(uint32)); CHECK_RELOC_OFFSET(sizeof(uint32));
if (reloc_type == R_RISCV_PCREL_HI20) {
if (val
!= ((intptr_t)symbol_addr + (intptr_t)reloc_addend
- (intptr_t)addr)) {
goto fail_addr_out_of_range;
}
}
else {
if (val != ((intptr_t)symbol_addr + (intptr_t)reloc_addend)) { if (val != ((intptr_t)symbol_addr + (intptr_t)reloc_addend)) {
goto fail_addr_out_of_range; goto fail_addr_out_of_range;
} }
}
addr = target_section_addr + reloc_offset; addr = target_section_addr + reloc_offset;
insn = rv_get_val((uint16 *)addr); insn = rv_get_val((uint16 *)addr);
@ -386,14 +405,28 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
break; break;
} }
case R_RISCV_LO12_I: case R_RISCV_LO12_I: /* S + A */
case R_RISCV_PCREL_LO12_I: /* S - P */
{ {
if (reloc_type == R_RISCV_PCREL_LO12_I) {
/* A = 0 */
val = (int32)((intptr_t)symbol_addr - (intptr_t)addr);
}
else {
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend); val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend);
}
CHECK_RELOC_OFFSET(sizeof(uint32)); CHECK_RELOC_OFFSET(sizeof(uint32));
if (reloc_type == R_RISCV_PCREL_LO12_I) {
if (val != (intptr_t)symbol_addr - (intptr_t)addr) {
goto fail_addr_out_of_range;
}
}
else {
if (val != (intptr_t)symbol_addr + (intptr_t)reloc_addend) { if (val != (intptr_t)symbol_addr + (intptr_t)reloc_addend) {
goto fail_addr_out_of_range; goto fail_addr_out_of_range;
} }
}
addr = target_section_addr + reloc_offset; addr = target_section_addr + reloc_offset;
insn = rv_get_val((uint16 *)addr); insn = rv_get_val((uint16 *)addr);