[lld] [lld][WebAssembly] Report Unsupported PIC Relocations in Code Segment (PR #104926)

Luc Blaeser via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 20 06:04:02 PDT 2024


https://github.com/luc-blaeser created https://github.com/llvm/llvm-project/pull/104926

`WASM_MEMORY_ADDR_REL_` and `WASM_TABLE_INDEX_REL_` relocations against **undefined symbols** are not supported and, except for `UnresolvedPolicy::ReportError`, lead to incorrect Wasm code, such as invalid data address or invalid table index that cannot be patched during later dynamic Wasm linking with modules declaring those symbols. This is different to other relocations that support undefined symbols by declaring correspond Wasm imports.

For more robust behavior, `wasm-ld` should probably report an error for such unsupported PIC relocations, independent of the `UnresolvedPolicy`.


>From 020ba6c601061ac982a4be24d2a49e34da5d5706 Mon Sep 17 00:00:00 2001
From: luc-blaeser <luc.blaeser at dfinity.org>
Date: Tue, 20 Aug 2024 14:35:37 +0200
Subject: [PATCH] Report unsupported PIC relocations in code segment

---
 lld/test/wasm/unsupported-pic-relocations.s   | 47 ++++++++++++++++++
 lld/test/wasm/unsupported-pic-relocations64.s | 48 +++++++++++++++++++
 lld/wasm/Relocations.cpp                      | 13 +++++
 3 files changed, 108 insertions(+)
 create mode 100644 lld/test/wasm/unsupported-pic-relocations.s
 create mode 100644 lld/test/wasm/unsupported-pic-relocations64.s

diff --git a/lld/test/wasm/unsupported-pic-relocations.s b/lld/test/wasm/unsupported-pic-relocations.s
new file mode 100644
index 00000000000000..81b9fdde83e677
--- /dev/null
+++ b/lld/test/wasm/unsupported-pic-relocations.s
@@ -0,0 +1,47 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+
+# RUN: not wasm-ld --experimental-pic -shared %t.o -o /dev/null 2>&1 | \
+# RUN:   FileCheck %s
+
+# RUN: not wasm-ld --experimental-pic -shared %t.o -o /dev/null  --unresolved-symbols=report-all 2>&1 | \
+# RUN:   FileCheck %s
+
+# RUN: not wasm-ld --experimental-pic -shared %t.o -o /dev/null  --warn-unresolved-symbols 2>&1 | \
+# RUN:   FileCheck %s
+
+# RUN: not wasm-ld --experimental-pic -shared %t.o -o /dev/null  --unresolved-symbols=ignore-all 2>&1 | \
+# RUN:   FileCheck %s
+
+# RUN: not wasm-ld --experimental-pic -shared %t.o -o /dev/null  --unresolved-symbols=import-dynamic 2>&1 | \
+# RUN:   FileCheck %s
+
+.globaltype __memory_base, i32, immutable
+.globaltype	__table_base, i32, immutable
+
+.functype external_func () -> ()
+
+call_undefined_function:
+    .functype call_undefined_function () -> ()
+    global.get  __table_base
+    i32.const external_func at TBREL
+    # CHECK: error: {{.*}}.o: relocation R_WASM_TABLE_INDEX_REL_SLEB is not supported against an undefined symbol `external_func`
+    i32.add
+    call_indirect () -> ()
+    end_function
+    
+access_undefined_data:
+    .functype access_undefined_data () -> ()
+    global.get  __memory_base
+    i32.const external_data at MBREL
+    # CHECK: error: {{.*}}.o: relocation R_WASM_MEMORY_ADDR_REL_SLEB is not supported against an undefined symbol `external_data`
+    i32.add
+    i32.load 0
+    drop
+    end_function
+
+.globl _start
+_start:
+    .functype _start () -> ()
+    call call_undefined_function
+    call access_undefined_data
+    end_function
diff --git a/lld/test/wasm/unsupported-pic-relocations64.s b/lld/test/wasm/unsupported-pic-relocations64.s
new file mode 100644
index 00000000000000..cae78d95862b48
--- /dev/null
+++ b/lld/test/wasm/unsupported-pic-relocations64.s
@@ -0,0 +1,48 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm64-unknown-unknown -o %t.o %s
+
+# RUN: not wasm-ld -mwasm64 --experimental-pic -shared %t.o -o /dev/null 2>&1 | \
+# RUN:   FileCheck %s
+
+# RUN: not wasm-ld -mwasm64 --experimental-pic -shared %t.o -o /dev/null  --unresolved-symbols=report-all 2>&1 | \
+# RUN:   FileCheck %s
+
+# RUN: not wasm-ld -mwasm64 --experimental-pic -shared %t.o -o /dev/null  --warn-unresolved-symbols 2>&1 | \
+# RUN:   FileCheck %s
+
+# RUN: not wasm-ld -mwasm64 --experimental-pic -shared %t.o -o /dev/null  --unresolved-symbols=ignore-all 2>&1 | \
+# RUN:   FileCheck %s
+
+# RUN: not wasm-ld -mwasm64 --experimental-pic -shared %t.o -o /dev/null  --unresolved-symbols=import-dynamic 2>&1 | \
+# RUN:   FileCheck %s
+
+.globaltype __memory_base, i64, immutable
+.globaltype	__table_base, i64, immutable
+
+.functype external_func () -> ()
+
+call_undefined_function:
+    .functype call_undefined_function () -> ()
+    global.get  __table_base
+    i64.const external_func at TBREL
+    # CHECK: error: {{.*}}.o: relocation R_WASM_TABLE_INDEX_REL_SLEB64 is not supported against an undefined symbol `external_func`
+    i64.add
+    i32.wrap_i64 # Remove when table64 is supported
+    call_indirect () -> ()
+    end_function
+    
+access_undefined_data:
+    .functype access_undefined_data () -> ()
+    global.get  __memory_base
+    i64.const external_data at MBREL
+    # CHECK: error: {{.*}}.o: relocation R_WASM_MEMORY_ADDR_REL_SLEB64 is not supported against an undefined symbol `external_data`
+    i64.add
+    i64.load 0
+    drop
+    end_function
+
+.globl _start
+_start:
+    .functype _start () -> ()
+    call call_undefined_function
+    call access_undefined_data
+    end_function
diff --git a/lld/wasm/Relocations.cpp b/lld/wasm/Relocations.cpp
index 6f33a4f28a9d09..6b177f4f34bb6f 100644
--- a/lld/wasm/Relocations.cpp
+++ b/lld/wasm/Relocations.cpp
@@ -170,6 +170,19 @@ void scanRelocations(InputChunk *chunk) {
         if (requiresGOTAccess(sym))
           addGOTEntry(sym);
         break;
+      case R_WASM_TABLE_INDEX_REL_SLEB:
+      case R_WASM_TABLE_INDEX_REL_SLEB64:
+      case R_WASM_MEMORY_ADDR_REL_SLEB:
+      case R_WASM_MEMORY_ADDR_REL_SLEB64:
+        // These relocation types are only present in the code section and
+        // are not supported. It would require replacing the constant by using
+        // a GOT global.
+        if (sym->isUndefined())
+          error(toString(file) + ": relocation " +
+                relocTypeToString(reloc.Type) +
+                " is not supported against an undefined symbol `" +
+                toString(*sym) + "`");
+        break;
       }
     }
 



More information about the llvm-commits mailing list