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_CALL 18
#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_LO12_I 27
#define R_RISCV_LO12_S 28
@ -267,9 +269,10 @@ typedef struct RelocTypeStrMap {
}
static RelocTypeStrMap reloc_type_str_maps[] = {
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_LO12_I), RELOC_TYPE_MAP(R_RISCV_LO12_S),
RELOC_TYPE_MAP(R_RISCV_32), RELOC_TYPE_MAP(R_RISCV_CALL),
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),
};
static const char *
@ -369,13 +372,29 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
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));
if (val != ((intptr_t)symbol_addr + (intptr_t)reloc_addend)) {
goto fail_addr_out_of_range;
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)) {
goto fail_addr_out_of_range;
}
}
addr = target_section_addr + reloc_offset;
@ -386,13 +405,27 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
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));
if (val != (intptr_t)symbol_addr + (intptr_t)reloc_addend) {
goto fail_addr_out_of_range;
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) {
goto fail_addr_out_of_range;
}
}
addr = target_section_addr + reloc_offset;