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
@ -267,9 +269,10 @@ 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_LO12_I), RELOC_TYPE_MAP(R_RISCV_LO12_S), 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),
}; };
static const char * static const char *
@ -369,13 +372,29 @@ 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 */
{ {
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend); 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);
}
CHECK_RELOC_OFFSET(sizeof(uint32)); CHECK_RELOC_OFFSET(sizeof(uint32));
if (val != ((intptr_t)symbol_addr + (intptr_t)reloc_addend)) { if (reloc_type == R_RISCV_PCREL_HI20) {
goto fail_addr_out_of_range; 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)) {
goto fail_addr_out_of_range;
}
} }
addr = target_section_addr + reloc_offset; addr = target_section_addr + reloc_offset;
@ -386,13 +405,27 @@ 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 */
{ {
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend); 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);
}
CHECK_RELOC_OFFSET(sizeof(uint32)); CHECK_RELOC_OFFSET(sizeof(uint32));
if (val != (intptr_t)symbol_addr + (intptr_t)reloc_addend) { if (reloc_type == R_RISCV_PCREL_LO12_I) {
goto fail_addr_out_of_range; 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) {
goto fail_addr_out_of_range;
}
} }
addr = target_section_addr + reloc_offset; addr = target_section_addr + reloc_offset;