Przeglądaj źródła

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

This PR partly fixes #2312. Lightly tested on qemu riscv64.
YAMAMOTO Takashi 2 lat temu
rodzic
commit
0a0739ef23
1 zmienionych plików z 44 dodań i 11 usunięć
  1. 44 11
      core/iwasm/aot/arch/aot_reloc_riscv.c

+ 44 - 11
core/iwasm/aot/arch/aot_reloc_riscv.c

@@ -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;