[lld] 497060f - [lld][WebAssembly] Add missing relocation types to the --compress-relocations path (#144578)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 2 13:57:45 PDT 2025
Author: SingleAccretion
Date: 2025-07-02T13:57:42-07:00
New Revision: 497060fae5c3a93978306eb565e8d0ebc116f6c7
URL: https://github.com/llvm/llvm-project/commit/497060fae5c3a93978306eb565e8d0ebc116f6c7
DIFF: https://github.com/llvm/llvm-project/commit/497060fae5c3a93978306eb565e8d0ebc116f6c7.diff
LOG: [lld][WebAssembly] Add missing relocation types to the --compress-relocations path (#144578)
Fixes https://github.com/llvm/llvm-project/issues/110045.
Reloc list reference:
```
+ Already handled
A Added in this change
= Not applicable / expected (though technically legal, e. g. you can relocate v128.const...)
+ R_WASM_FUNCTION_INDEX_LEB, 0
+ R_WASM_TABLE_INDEX_SLEB, 1
= R_WASM_TABLE_INDEX_I32, 2
+ R_WASM_MEMORY_ADDR_LEB, 3
+ R_WASM_MEMORY_ADDR_SLEB, 4
= R_WASM_MEMORY_ADDR_I32, 5
+ R_WASM_TYPE_INDEX_LEB, 6
+ R_WASM_GLOBAL_INDEX_LEB, 7
= R_WASM_FUNCTION_OFFSET_I32, 8
= R_WASM_SECTION_OFFSET_I32, 9
+ R_WASM_TAG_INDEX_LEB, 10
A R_WASM_MEMORY_ADDR_REL_SLEB, 11
A R_WASM_TABLE_INDEX_REL_SLEB, 12
= R_WASM_GLOBAL_INDEX_I32, 13
+ R_WASM_MEMORY_ADDR_LEB64, 14
+ R_WASM_MEMORY_ADDR_SLEB64, 15
= R_WASM_MEMORY_ADDR_I64, 16
A R_WASM_MEMORY_ADDR_REL_SLEB64, 17
+ R_WASM_TABLE_INDEX_SLEB64, 18
= R_WASM_TABLE_INDEX_I64, 19
+ R_WASM_TABLE_NUMBER_LEB, 20
A R_WASM_MEMORY_ADDR_TLS_SLEB, 21
= R_WASM_FUNCTION_OFFSET_I64, 22
= R_WASM_MEMORY_ADDR_LOCREL_I32, 23
A R_WASM_TABLE_INDEX_REL_SLEB64, 24
A R_WASM_MEMORY_ADDR_TLS_SLEB64, 25
= R_WASM_FUNCTION_INDEX_I32, 26
```
Added:
lld/test/wasm/compress-relocs.s
lld/test/wasm/compress-relocs64.s
Modified:
lld/wasm/InputChunks.cpp
llvm/include/llvm/BinaryFormat/Wasm.h
Removed:
lld/test/wasm/compress-relocs.ll
################################################################################
diff --git a/lld/test/wasm/compress-relocs.ll b/lld/test/wasm/compress-relocs.ll
deleted file mode 100644
index cea9f3476e996..0000000000000
--- a/lld/test/wasm/compress-relocs.ll
+++ /dev/null
@@ -1,26 +0,0 @@
-; RUN: llc -filetype=obj %s -o %t.o
-; RUN: llvm-mc -mattr=+call-indirect-overlong -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/call-indirect.s -o %t2.o
-; RUN: wasm-ld --export-dynamic -o %t.wasm %t2.o %t.o
-; RUN: obj2yaml %t.wasm | FileCheck %s
-; RUN: wasm-ld --export-dynamic -O2 -o %t-opt.wasm %t2.o %t.o
-; RUN: obj2yaml %t-opt.wasm | FileCheck %s
-; RUN: not wasm-ld --compress-relocations -o %t-compressed.wasm %t2.o %t.o 2>&1 | FileCheck %s -check-prefix=ERROR
-; RUN: wasm-ld --export-dynamic --strip-debug --compress-relocations -o %t-compressed.wasm %t2.o %t.o
-; RUN: obj2yaml %t-compressed.wasm | FileCheck %s -check-prefix=COMPRESS
-
-target triple = "wasm32-unknown-unknown-wasm"
-
-define i32 @foo() {
-entry:
- ret i32 2
-}
-
-define void @_start() local_unnamed_addr {
-entry:
- ret void
-}
-
-; ERROR: wasm-ld: error: --compress-relocations is incompatible with output debug information. Please pass --strip-debug or --strip-all
-
-; CHECK: Body: 41002802808880800011808080800080808080001A41002802848880800011818080800080808080001A0B
-; COMPRESS: Body: 4100280280081100001A4100280284081101001A0B
diff --git a/lld/test/wasm/compress-relocs.s b/lld/test/wasm/compress-relocs.s
new file mode 100644
index 0000000000000..41d4ff567d501
--- /dev/null
+++ b/lld/test/wasm/compress-relocs.s
@@ -0,0 +1,129 @@
+# RUN: llvm-mc -mattr=+reference-types,+exception-handling -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
+# RUN: wasm-ld --export-dynamic -o %t.wasm %t.o
+# RUN: llvm-objdump -d %t.wasm | FileCheck %s
+# RUN: wasm-ld --export-dynamic -O2 -o %t-opt.wasm %t.o
+# RUN: llvm-objdump -d %t-opt.wasm | FileCheck %s
+# RUN: not wasm-ld --compress-relocations -o %t-compressed.wasm %t.o 2>&1 | FileCheck %s -check-prefix=ERROR
+# RUN: wasm-ld --export-dynamic --strip-debug --compress-relocations -o %t-compressed.wasm %t.o
+# RUN: llvm-objdump -d %t-compressed.wasm | FileCheck %s -check-prefix=COMPRESS
+
+ .globl _start
+_start:
+ .functype _start () -> ()
+ end_function
+
+ .globl func_ret_i64
+func_ret_i64:
+ .functype func_ret_i64 () -> (i64)
+ i64.const 1
+ end_function
+
+ .globl func_ret_i32
+func_ret_i32:
+ .functype func_ret_i32 () -> (i32)
+ i32.const 2
+ end_function
+
+i32_global:
+ .globaltype i32_global, i32
+
+i32_tag:
+ .tagtype i32_tag i32
+
+ .globl test_memory_and_indirect_call_relocs
+test_memory_and_indirect_call_relocs:
+ .functype test_memory_and_indirect_call_relocs () -> ()
+ i32.const indirect_func_ret_i64 # R_WASM_MEMORY_ADDR_SLEB
+ i32.load 0
+ call_indirect () -> (i64) # R_WASM_TYPE_INDEX_LEB, R_WASM_TABLE_NUMBER_LEB
+ drop
+ i32.const 0
+ i32.load indirect_func_ret_i32 # R_WASM_MEMORY_ADDR_LEB
+ call_indirect () -> (i32)
+ drop
+ i32.const func_ret_i64 # R_WASM_TABLE_INDEX_SLEB
+ call_indirect () -> (i64)
+ drop
+ end_function
+
+# CHECK: test_memory_and_indirect_call_relocs
+# CHECK: 41 90 88 80 80 00 i32.const 1040
+# CHECK: 11 80 80 80 80 00 80 80 80 80 00 call_indirect 0
+# CHECK: 28 02 94 88 80 80 00 i32.load 1044
+# CHECK: 11 81 80 80 80 00 80 80 80 80 00 call_indirect 1
+# CHECK: 41 81 80 80 80 00 i32.const 1
+# CHECK: 11 80 80 80 80 00 80 80 80 80 00 call_indirect 0
+# COMPRESS: test_memory_and_indirect_call_relocs
+# COMPRESS: 41 90 08 i32.const 1040
+# COMPRESS: 11 00 00 call_indirect 0
+# COMPRESS: 28 02 94 08 i32.load 1044
+# COMPRESS: 11 01 00 call_indirect 1
+# COMPRESS: 41 01 i32.const 1
+# COMPRESS: 11 00 00 call_indirect 0
+
+ .globl test_simple_index_relocs
+test_simple_index_relocs:
+ .functype test_simple_index_relocs () -> ()
+ call func_ret_i32 # R_WASM_FUNCTION_INDEX_LEB
+ global.set i32_global # R_WASM_GLOBAL_INDEX_LEB
+ i32.const 0
+ throw i32_tag # R_WASM_TAG_INDEX_LEB
+ end_function
+
+# CHECK: test_simple_index_relocs
+# CHECK: 10 82 80 80 80 00 call 2
+# CHECK: 24 81 80 80 80 00 global.set 1
+# CHECK: 08 80 80 80 80 00 throw 0
+# COMPRESS: test_simple_index_relocs
+# COMPRESS: 10 02 call 2
+# COMPRESS: 24 01 global.set 1
+# COMPRESS: 08 00 throw 0
+
+ .globl test_relative_relocs
+test_relative_relocs:
+ .functype test_relative_relocs () -> ()
+ i32.const indirect_func_ret_i64 at MBREL # R_WASM_MEMORY_ADDR_REL_SLEB
+ drop
+ i32.const func_ret_i32 at TBREL # R_WASM_TABLE_INDEX_REL_SLEB
+ drop
+ i32.const i32_tls_data at TLSREL # R_WASM_MEMORY_ADDR_TLS_SLEB
+ drop
+ end_function
+
+# CHECK: test_relative_relocs
+# CHECK: 41 90 88 80 80 00 i32.const 1040
+# CHECK: 41 81 80 80 80 00 i32.const 1
+# CHECK: 41 83 80 80 80 00 i32.const 3
+# COMPRESS: test_relative_relocs
+# COMPRESS: 41 90 08 i32.const 1040
+# COMPRESS: 41 01 i32.const 1
+# COMPRESS: 41 03 i32.const 3
+
+# ERROR: wasm-ld: error: --compress-relocations is incompatible with output debug information. Please pass --strip-debug or --strip-all
+
+ .section .tdata,"T",@
+ .int8 0
+ .int8 0
+ .int8 0
+i32_tls_data:
+ .int32 65
+ .size i32_tls_data, 4
+
+ .section .data,"",@
+ .p2align 4
+indirect_func_ret_i64:
+ .int32 func_ret_i64
+ .size indirect_func_ret_i64, 4
+
+indirect_func_ret_i32:
+ .int32 func_ret_i32
+ .size indirect_func_ret_i32, 4
+
+.section .custom_section.target_features,"",@
+ .int8 2
+ .int8 43
+ .int8 7
+ .ascii "atomics"
+ .int8 43
+ .int8 11
+ .ascii "bulk-memory"
diff --git a/lld/test/wasm/compress-relocs64.s b/lld/test/wasm/compress-relocs64.s
new file mode 100644
index 0000000000000..44e7a089275bb
--- /dev/null
+++ b/lld/test/wasm/compress-relocs64.s
@@ -0,0 +1,92 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm64-unknown-unknown %s -o %t.o
+# RUN: wasm-ld -mwasm64 --export-dynamic -o %t.wasm %t.o
+# RUN: llvm-objdump -d %t.wasm | FileCheck %s
+# RUN: wasm-ld -mwasm64 --export-dynamic -O2 -o %t-opt.wasm %t.o
+# RUN: llvm-objdump -d %t-opt.wasm | FileCheck %s
+# RUN: wasm-ld -mwasm64 --export-dynamic --strip-debug --compress-relocations -o %t-compressed.wasm %t.o
+# RUN: llvm-objdump -d %t-compressed.wasm | FileCheck %s -check-prefix=COMPRESS
+
+ .globl _start
+_start:
+ .functype _start () -> ()
+ end_function
+
+ .globl func_ret_i64
+func_ret_i64:
+ .functype func_ret_i64 () -> (i64)
+ i64.const 1
+ end_function
+
+ .globl func_ret_i32
+func_ret_i32:
+ .functype func_ret_i32 () -> (i32)
+ i32.const 2
+ end_function
+
+ .globl test_memory_and_indirect_call_relocs
+test_memory_and_indirect_call_relocs:
+ .functype test_memory_and_indirect_call_relocs () -> ()
+ i64.const indirect_func_ret_i64 # R_WASM_MEMORY_ADDR_SLEB64
+ drop
+ i64.const 0
+ i64.load indirect_func_ret_i32 # R_WASM_MEMORY_ADDR_LEB64
+ drop
+ i64.const func_ret_i64 # R_WASM_TABLE_INDEX_SLEB64
+ drop
+ end_function
+
+# CHECK: test_memory_and_indirect_call_relocs
+# CHECK: 42 90 88 80 80 80 80 80 80 80 00 i64.const 1040
+# CHECK: 29 03 98 88 80 80 80 80 80 80 80 00 i64.load 1048
+# CHECK: 42 81 80 80 80 80 80 80 80 80 00 i64.const 1
+# COMPRESS: test_memory_and_indirect_call_relocs
+# COMPRESS: 42 90 08 i64.const 1040
+# COMPRESS: 29 03 98 08 i64.load 1048
+# COMPRESS: 42 01 i64.const 1
+
+ .globl test_relative_relocs
+test_relative_relocs:
+ .functype test_relative_relocs () -> ()
+ i64.const indirect_func_ret_i64 at MBREL # R_WASM_MEMORY_ADDR_REL_SLEB64
+ drop
+ i64.const func_ret_i32 at TBREL # R_WASM_TABLE_INDEX_REL_SLEB64
+ drop
+ i64.const i32_tls_data at TLSREL # R_WASM_MEMORY_ADDR_TLS_SLEB64
+ drop
+ end_function
+
+# CHECK: test_relative_relocs
+# CHECK: 42 90 88 80 80 80 80 80 80 80 00 i64.const 1040
+# CHECK: 42 81 80 80 80 80 80 80 80 80 00 i64.const 1
+# CHECK: 42 83 80 80 80 80 80 80 80 80 00 i64.const 3
+# COMPRESS: test_relative_relocs
+# COMPRESS: 42 90 08 i64.const 1040
+# COMPRESS: 42 01 i64.const 1
+# COMPRESS: 42 03 i64.const 3
+
+ .section .tdata,"T",@
+ .int8 0
+ .int8 0
+ .int8 0
+i32_tls_data:
+ .int32 65
+ .size i32_tls_data, 4
+
+ .section .data,"",@
+ .p2align 4
+indirect_func_ret_i64:
+ .int64 func_ret_i64
+ .size indirect_func_ret_i64, 8
+
+indirect_func_ret_i32:
+ .int64 func_ret_i32
+ .size indirect_func_ret_i32, 8
+
+.section .custom_section.target_features,"",@
+ .int8 2
+ .int8 43
+ .int8 7
+ .ascii "atomics"
+ .int8 43
+ .int8 11
+ .ascii "bulk-memory"
diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp
index 855589353e4f6..181221a77b106 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -228,7 +228,7 @@ void InputFunction::setTableIndex(uint32_t index) {
// witten.
static unsigned writeCompressedReloc(uint8_t *buf, const WasmRelocation &rel,
uint64_t value) {
- switch (rel.Type) {
+ switch (rel.getType()) {
case R_WASM_TYPE_INDEX_LEB:
case R_WASM_FUNCTION_INDEX_LEB:
case R_WASM_GLOBAL_INDEX_LEB:
@@ -239,16 +239,33 @@ static unsigned writeCompressedReloc(uint8_t *buf, const WasmRelocation &rel,
return encodeULEB128(value, buf);
case R_WASM_TABLE_INDEX_SLEB:
case R_WASM_TABLE_INDEX_SLEB64:
+ case R_WASM_TABLE_INDEX_REL_SLEB64:
case R_WASM_MEMORY_ADDR_SLEB:
case R_WASM_MEMORY_ADDR_SLEB64:
+ case R_WASM_MEMORY_ADDR_REL_SLEB:
+ case R_WASM_MEMORY_ADDR_REL_SLEB64:
+ case R_WASM_MEMORY_ADDR_TLS_SLEB:
+ case R_WASM_MEMORY_ADDR_TLS_SLEB64:
+ case R_WASM_TABLE_INDEX_REL_SLEB:
return encodeSLEB128(static_cast<int64_t>(value), buf);
- default:
- llvm_unreachable("unexpected relocation type");
+ case R_WASM_TABLE_INDEX_I32:
+ case R_WASM_MEMORY_ADDR_I32:
+ case R_WASM_FUNCTION_OFFSET_I32:
+ case R_WASM_SECTION_OFFSET_I32:
+ case R_WASM_GLOBAL_INDEX_I32:
+ case R_WASM_MEMORY_ADDR_I64:
+ case R_WASM_TABLE_INDEX_I64:
+ case R_WASM_FUNCTION_OFFSET_I64:
+ case R_WASM_MEMORY_ADDR_LOCREL_I32:
+ case R_WASM_FUNCTION_INDEX_I32:
+ fatal("relocation compression not supported for " +
+ relocTypeToString(rel.Type));
}
+ llvm_unreachable("unhandled relocation type");
}
static unsigned getRelocWidthPadded(const WasmRelocation &rel) {
- switch (rel.Type) {
+ switch (rel.getType()) {
case R_WASM_TYPE_INDEX_LEB:
case R_WASM_FUNCTION_INDEX_LEB:
case R_WASM_GLOBAL_INDEX_LEB:
@@ -256,15 +273,32 @@ static unsigned getRelocWidthPadded(const WasmRelocation &rel) {
case R_WASM_MEMORY_ADDR_LEB:
case R_WASM_TABLE_NUMBER_LEB:
case R_WASM_TABLE_INDEX_SLEB:
+ case R_WASM_TABLE_INDEX_REL_SLEB:
case R_WASM_MEMORY_ADDR_SLEB:
+ case R_WASM_MEMORY_ADDR_REL_SLEB:
+ case R_WASM_MEMORY_ADDR_TLS_SLEB:
return 5;
case R_WASM_TABLE_INDEX_SLEB64:
+ case R_WASM_TABLE_INDEX_REL_SLEB64:
case R_WASM_MEMORY_ADDR_LEB64:
case R_WASM_MEMORY_ADDR_SLEB64:
+ case R_WASM_MEMORY_ADDR_REL_SLEB64:
+ case R_WASM_MEMORY_ADDR_TLS_SLEB64:
return 10;
- default:
- llvm_unreachable("unexpected relocation type");
+ case R_WASM_TABLE_INDEX_I32:
+ case R_WASM_MEMORY_ADDR_I32:
+ case R_WASM_FUNCTION_OFFSET_I32:
+ case R_WASM_SECTION_OFFSET_I32:
+ case R_WASM_GLOBAL_INDEX_I32:
+ case R_WASM_MEMORY_ADDR_I64:
+ case R_WASM_TABLE_INDEX_I64:
+ case R_WASM_FUNCTION_OFFSET_I64:
+ case R_WASM_MEMORY_ADDR_LOCREL_I32:
+ case R_WASM_FUNCTION_INDEX_I32:
+ fatal("relocation compression not supported for " +
+ relocTypeToString(rel.Type));
}
+ llvm_unreachable("unhandled relocation type");
}
static unsigned getRelocWidth(const WasmRelocation &rel, uint64_t value) {
diff --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h
index 604104ff3cca3..cf90a43d0d7e8 100644
--- a/llvm/include/llvm/BinaryFormat/Wasm.h
+++ b/llvm/include/llvm/BinaryFormat/Wasm.h
@@ -253,7 +253,7 @@ const unsigned WASM_SYMBOL_ABSOLUTE = 0x200;
#define WASM_RELOC(name, value) name = value,
-enum : unsigned {
+enum WasmRelocType : unsigned {
#include "WasmRelocs.def"
};
@@ -452,6 +452,8 @@ struct WasmRelocation {
uint32_t Index; // Index into either symbol or type index space.
uint64_t Offset; // Offset from the start of the section.
int64_t Addend; // A value to add to the symbol.
+
+ WasmRelocType getType() const { return static_cast<WasmRelocType>(Type); }
};
struct WasmInitFunc {
More information about the llvm-commits
mailing list