Skip to content

Commit 497060f

Browse files
[lld][WebAssembly] Add missing relocation types to the --compress-relocations path (#144578)
Fixes #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 ```
1 parent 2725765 commit 497060f

File tree

5 files changed

+264
-33
lines changed

5 files changed

+264
-33
lines changed

lld/test/wasm/compress-relocs.ll

Lines changed: 0 additions & 26 deletions
This file was deleted.

lld/test/wasm/compress-relocs.s

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# RUN: llvm-mc -mattr=+reference-types,+exception-handling -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
2+
# RUN: wasm-ld --export-dynamic -o %t.wasm %t.o
3+
# RUN: llvm-objdump -d %t.wasm | FileCheck %s
4+
# RUN: wasm-ld --export-dynamic -O2 -o %t-opt.wasm %t.o
5+
# RUN: llvm-objdump -d %t-opt.wasm | FileCheck %s
6+
# RUN: not wasm-ld --compress-relocations -o %t-compressed.wasm %t.o 2>&1 | FileCheck %s -check-prefix=ERROR
7+
# RUN: wasm-ld --export-dynamic --strip-debug --compress-relocations -o %t-compressed.wasm %t.o
8+
# RUN: llvm-objdump -d %t-compressed.wasm | FileCheck %s -check-prefix=COMPRESS
9+
10+
.globl _start
11+
_start:
12+
.functype _start () -> ()
13+
end_function
14+
15+
.globl func_ret_i64
16+
func_ret_i64:
17+
.functype func_ret_i64 () -> (i64)
18+
i64.const 1
19+
end_function
20+
21+
.globl func_ret_i32
22+
func_ret_i32:
23+
.functype func_ret_i32 () -> (i32)
24+
i32.const 2
25+
end_function
26+
27+
i32_global:
28+
.globaltype i32_global, i32
29+
30+
i32_tag:
31+
.tagtype i32_tag i32
32+
33+
.globl test_memory_and_indirect_call_relocs
34+
test_memory_and_indirect_call_relocs:
35+
.functype test_memory_and_indirect_call_relocs () -> ()
36+
i32.const indirect_func_ret_i64 # R_WASM_MEMORY_ADDR_SLEB
37+
i32.load 0
38+
call_indirect () -> (i64) # R_WASM_TYPE_INDEX_LEB, R_WASM_TABLE_NUMBER_LEB
39+
drop
40+
i32.const 0
41+
i32.load indirect_func_ret_i32 # R_WASM_MEMORY_ADDR_LEB
42+
call_indirect () -> (i32)
43+
drop
44+
i32.const func_ret_i64 # R_WASM_TABLE_INDEX_SLEB
45+
call_indirect () -> (i64)
46+
drop
47+
end_function
48+
49+
# CHECK: test_memory_and_indirect_call_relocs
50+
# CHECK: 41 90 88 80 80 00 i32.const 1040
51+
# CHECK: 11 80 80 80 80 00 80 80 80 80 00 call_indirect 0
52+
# CHECK: 28 02 94 88 80 80 00 i32.load 1044
53+
# CHECK: 11 81 80 80 80 00 80 80 80 80 00 call_indirect 1
54+
# CHECK: 41 81 80 80 80 00 i32.const 1
55+
# CHECK: 11 80 80 80 80 00 80 80 80 80 00 call_indirect 0
56+
# COMPRESS: test_memory_and_indirect_call_relocs
57+
# COMPRESS: 41 90 08 i32.const 1040
58+
# COMPRESS: 11 00 00 call_indirect 0
59+
# COMPRESS: 28 02 94 08 i32.load 1044
60+
# COMPRESS: 11 01 00 call_indirect 1
61+
# COMPRESS: 41 01 i32.const 1
62+
# COMPRESS: 11 00 00 call_indirect 0
63+
64+
.globl test_simple_index_relocs
65+
test_simple_index_relocs:
66+
.functype test_simple_index_relocs () -> ()
67+
call func_ret_i32 # R_WASM_FUNCTION_INDEX_LEB
68+
global.set i32_global # R_WASM_GLOBAL_INDEX_LEB
69+
i32.const 0
70+
throw i32_tag # R_WASM_TAG_INDEX_LEB
71+
end_function
72+
73+
# CHECK: test_simple_index_relocs
74+
# CHECK: 10 82 80 80 80 00 call 2
75+
# CHECK: 24 81 80 80 80 00 global.set 1
76+
# CHECK: 08 80 80 80 80 00 throw 0
77+
# COMPRESS: test_simple_index_relocs
78+
# COMPRESS: 10 02 call 2
79+
# COMPRESS: 24 01 global.set 1
80+
# COMPRESS: 08 00 throw 0
81+
82+
.globl test_relative_relocs
83+
test_relative_relocs:
84+
.functype test_relative_relocs () -> ()
85+
i32.const indirect_func_ret_i64@MBREL # R_WASM_MEMORY_ADDR_REL_SLEB
86+
drop
87+
i32.const func_ret_i32@TBREL # R_WASM_TABLE_INDEX_REL_SLEB
88+
drop
89+
i32.const i32_tls_data@TLSREL # R_WASM_MEMORY_ADDR_TLS_SLEB
90+
drop
91+
end_function
92+
93+
# CHECK: test_relative_relocs
94+
# CHECK: 41 90 88 80 80 00 i32.const 1040
95+
# CHECK: 41 81 80 80 80 00 i32.const 1
96+
# CHECK: 41 83 80 80 80 00 i32.const 3
97+
# COMPRESS: test_relative_relocs
98+
# COMPRESS: 41 90 08 i32.const 1040
99+
# COMPRESS: 41 01 i32.const 1
100+
# COMPRESS: 41 03 i32.const 3
101+
102+
# ERROR: wasm-ld: error: --compress-relocations is incompatible with output debug information. Please pass --strip-debug or --strip-all
103+
104+
.section .tdata,"T",@
105+
.int8 0
106+
.int8 0
107+
.int8 0
108+
i32_tls_data:
109+
.int32 65
110+
.size i32_tls_data, 4
111+
112+
.section .data,"",@
113+
.p2align 4
114+
indirect_func_ret_i64:
115+
.int32 func_ret_i64
116+
.size indirect_func_ret_i64, 4
117+
118+
indirect_func_ret_i32:
119+
.int32 func_ret_i32
120+
.size indirect_func_ret_i32, 4
121+
122+
.section .custom_section.target_features,"",@
123+
.int8 2
124+
.int8 43
125+
.int8 7
126+
.ascii "atomics"
127+
.int8 43
128+
.int8 11
129+
.ascii "bulk-memory"

lld/test/wasm/compress-relocs64.s

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# RUN: llvm-mc -filetype=obj -triple=wasm64-unknown-unknown %s -o %t.o
2+
# RUN: wasm-ld -mwasm64 --export-dynamic -o %t.wasm %t.o
3+
# RUN: llvm-objdump -d %t.wasm | FileCheck %s
4+
# RUN: wasm-ld -mwasm64 --export-dynamic -O2 -o %t-opt.wasm %t.o
5+
# RUN: llvm-objdump -d %t-opt.wasm | FileCheck %s
6+
# RUN: wasm-ld -mwasm64 --export-dynamic --strip-debug --compress-relocations -o %t-compressed.wasm %t.o
7+
# RUN: llvm-objdump -d %t-compressed.wasm | FileCheck %s -check-prefix=COMPRESS
8+
9+
.globl _start
10+
_start:
11+
.functype _start () -> ()
12+
end_function
13+
14+
.globl func_ret_i64
15+
func_ret_i64:
16+
.functype func_ret_i64 () -> (i64)
17+
i64.const 1
18+
end_function
19+
20+
.globl func_ret_i32
21+
func_ret_i32:
22+
.functype func_ret_i32 () -> (i32)
23+
i32.const 2
24+
end_function
25+
26+
.globl test_memory_and_indirect_call_relocs
27+
test_memory_and_indirect_call_relocs:
28+
.functype test_memory_and_indirect_call_relocs () -> ()
29+
i64.const indirect_func_ret_i64 # R_WASM_MEMORY_ADDR_SLEB64
30+
drop
31+
i64.const 0
32+
i64.load indirect_func_ret_i32 # R_WASM_MEMORY_ADDR_LEB64
33+
drop
34+
i64.const func_ret_i64 # R_WASM_TABLE_INDEX_SLEB64
35+
drop
36+
end_function
37+
38+
# CHECK: test_memory_and_indirect_call_relocs
39+
# CHECK: 42 90 88 80 80 80 80 80 80 80 00 i64.const 1040
40+
# CHECK: 29 03 98 88 80 80 80 80 80 80 80 00 i64.load 1048
41+
# CHECK: 42 81 80 80 80 80 80 80 80 80 00 i64.const 1
42+
# COMPRESS: test_memory_and_indirect_call_relocs
43+
# COMPRESS: 42 90 08 i64.const 1040
44+
# COMPRESS: 29 03 98 08 i64.load 1048
45+
# COMPRESS: 42 01 i64.const 1
46+
47+
.globl test_relative_relocs
48+
test_relative_relocs:
49+
.functype test_relative_relocs () -> ()
50+
i64.const indirect_func_ret_i64@MBREL # R_WASM_MEMORY_ADDR_REL_SLEB64
51+
drop
52+
i64.const func_ret_i32@TBREL # R_WASM_TABLE_INDEX_REL_SLEB64
53+
drop
54+
i64.const i32_tls_data@TLSREL # R_WASM_MEMORY_ADDR_TLS_SLEB64
55+
drop
56+
end_function
57+
58+
# CHECK: test_relative_relocs
59+
# CHECK: 42 90 88 80 80 80 80 80 80 80 00 i64.const 1040
60+
# CHECK: 42 81 80 80 80 80 80 80 80 80 00 i64.const 1
61+
# CHECK: 42 83 80 80 80 80 80 80 80 80 00 i64.const 3
62+
# COMPRESS: test_relative_relocs
63+
# COMPRESS: 42 90 08 i64.const 1040
64+
# COMPRESS: 42 01 i64.const 1
65+
# COMPRESS: 42 03 i64.const 3
66+
67+
.section .tdata,"T",@
68+
.int8 0
69+
.int8 0
70+
.int8 0
71+
i32_tls_data:
72+
.int32 65
73+
.size i32_tls_data, 4
74+
75+
.section .data,"",@
76+
.p2align 4
77+
indirect_func_ret_i64:
78+
.int64 func_ret_i64
79+
.size indirect_func_ret_i64, 8
80+
81+
indirect_func_ret_i32:
82+
.int64 func_ret_i32
83+
.size indirect_func_ret_i32, 8
84+
85+
.section .custom_section.target_features,"",@
86+
.int8 2
87+
.int8 43
88+
.int8 7
89+
.ascii "atomics"
90+
.int8 43
91+
.int8 11
92+
.ascii "bulk-memory"

lld/wasm/InputChunks.cpp

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ void InputFunction::setTableIndex(uint32_t index) {
228228
// witten.
229229
static unsigned writeCompressedReloc(uint8_t *buf, const WasmRelocation &rel,
230230
uint64_t value) {
231-
switch (rel.Type) {
231+
switch (rel.getType()) {
232232
case R_WASM_TYPE_INDEX_LEB:
233233
case R_WASM_FUNCTION_INDEX_LEB:
234234
case R_WASM_GLOBAL_INDEX_LEB:
@@ -239,32 +239,66 @@ static unsigned writeCompressedReloc(uint8_t *buf, const WasmRelocation &rel,
239239
return encodeULEB128(value, buf);
240240
case R_WASM_TABLE_INDEX_SLEB:
241241
case R_WASM_TABLE_INDEX_SLEB64:
242+
case R_WASM_TABLE_INDEX_REL_SLEB64:
242243
case R_WASM_MEMORY_ADDR_SLEB:
243244
case R_WASM_MEMORY_ADDR_SLEB64:
245+
case R_WASM_MEMORY_ADDR_REL_SLEB:
246+
case R_WASM_MEMORY_ADDR_REL_SLEB64:
247+
case R_WASM_MEMORY_ADDR_TLS_SLEB:
248+
case R_WASM_MEMORY_ADDR_TLS_SLEB64:
249+
case R_WASM_TABLE_INDEX_REL_SLEB:
244250
return encodeSLEB128(static_cast<int64_t>(value), buf);
245-
default:
246-
llvm_unreachable("unexpected relocation type");
251+
case R_WASM_TABLE_INDEX_I32:
252+
case R_WASM_MEMORY_ADDR_I32:
253+
case R_WASM_FUNCTION_OFFSET_I32:
254+
case R_WASM_SECTION_OFFSET_I32:
255+
case R_WASM_GLOBAL_INDEX_I32:
256+
case R_WASM_MEMORY_ADDR_I64:
257+
case R_WASM_TABLE_INDEX_I64:
258+
case R_WASM_FUNCTION_OFFSET_I64:
259+
case R_WASM_MEMORY_ADDR_LOCREL_I32:
260+
case R_WASM_FUNCTION_INDEX_I32:
261+
fatal("relocation compression not supported for " +
262+
relocTypeToString(rel.Type));
247263
}
264+
llvm_unreachable("unhandled relocation type");
248265
}
249266

250267
static unsigned getRelocWidthPadded(const WasmRelocation &rel) {
251-
switch (rel.Type) {
268+
switch (rel.getType()) {
252269
case R_WASM_TYPE_INDEX_LEB:
253270
case R_WASM_FUNCTION_INDEX_LEB:
254271
case R_WASM_GLOBAL_INDEX_LEB:
255272
case R_WASM_TAG_INDEX_LEB:
256273
case R_WASM_MEMORY_ADDR_LEB:
257274
case R_WASM_TABLE_NUMBER_LEB:
258275
case R_WASM_TABLE_INDEX_SLEB:
276+
case R_WASM_TABLE_INDEX_REL_SLEB:
259277
case R_WASM_MEMORY_ADDR_SLEB:
278+
case R_WASM_MEMORY_ADDR_REL_SLEB:
279+
case R_WASM_MEMORY_ADDR_TLS_SLEB:
260280
return 5;
261281
case R_WASM_TABLE_INDEX_SLEB64:
282+
case R_WASM_TABLE_INDEX_REL_SLEB64:
262283
case R_WASM_MEMORY_ADDR_LEB64:
263284
case R_WASM_MEMORY_ADDR_SLEB64:
285+
case R_WASM_MEMORY_ADDR_REL_SLEB64:
286+
case R_WASM_MEMORY_ADDR_TLS_SLEB64:
264287
return 10;
265-
default:
266-
llvm_unreachable("unexpected relocation type");
288+
case R_WASM_TABLE_INDEX_I32:
289+
case R_WASM_MEMORY_ADDR_I32:
290+
case R_WASM_FUNCTION_OFFSET_I32:
291+
case R_WASM_SECTION_OFFSET_I32:
292+
case R_WASM_GLOBAL_INDEX_I32:
293+
case R_WASM_MEMORY_ADDR_I64:
294+
case R_WASM_TABLE_INDEX_I64:
295+
case R_WASM_FUNCTION_OFFSET_I64:
296+
case R_WASM_MEMORY_ADDR_LOCREL_I32:
297+
case R_WASM_FUNCTION_INDEX_I32:
298+
fatal("relocation compression not supported for " +
299+
relocTypeToString(rel.Type));
267300
}
301+
llvm_unreachable("unhandled relocation type");
268302
}
269303

270304
static unsigned getRelocWidth(const WasmRelocation &rel, uint64_t value) {

llvm/include/llvm/BinaryFormat/Wasm.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ const unsigned WASM_SYMBOL_ABSOLUTE = 0x200;
253253

254254
#define WASM_RELOC(name, value) name = value,
255255

256-
enum : unsigned {
256+
enum WasmRelocType : unsigned {
257257
#include "WasmRelocs.def"
258258
};
259259

@@ -452,6 +452,8 @@ struct WasmRelocation {
452452
uint32_t Index; // Index into either symbol or type index space.
453453
uint64_t Offset; // Offset from the start of the section.
454454
int64_t Addend; // A value to add to the symbol.
455+
456+
WasmRelocType getType() const { return static_cast<WasmRelocType>(Type); }
455457
};
456458

457459
struct WasmInitFunc {

0 commit comments

Comments
 (0)