Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 48c6c7f

Browse files
authored
[lld][WebAssembly] Fix symbol type for __memory_base/__table_base. (#178773)
When linking PIC code as non-PIC we internally define `__memory_base` and `__table_base`. However we were defining these incorrectly as data symbols and not global symbols (as in Wasm globals). This happened to work incidentally as long as there was a live reference to the symbol. This is because the live reference would cause a GOT entry to be created for these symbol and then they could be referenced via via `R_WASM_GLOBAL_INDEX_LEB` or `R_WASM_GLOBAL_INDEX_I32`. However, when no live reference existed there could still be references from debug sections, and in that case the relocation code was crashing. Fixes: #174676
1 parent 05e9086 commit 48c6c7f

7 files changed

Lines changed: 79 additions & 51 deletions

File tree

lld/test/wasm/export-all.s

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,35 +30,35 @@ foo:
3030
# CHECK-NEXT: Index: 1
3131
# CHECK-NEXT: - Name: __dso_handle
3232
# CHECK-NEXT: Kind: GLOBAL
33-
# CHECK-NEXT: Index: 2
33+
# CHECK-NEXT: Index: 4
3434
# CHECK-NEXT: - Name: __data_end
3535
# CHECK-NEXT: Kind: GLOBAL
36-
# CHECK-NEXT: Index: 3
36+
# CHECK-NEXT: Index: 5
3737
# CHECK-NEXT: - Name: __stack_low
3838
# CHECK-NEXT: Kind: GLOBAL
39-
# CHECK-NEXT: Index: 4
39+
# CHECK-NEXT: Index: 6
4040
# CHECK-NEXT: - Name: __stack_high
4141
# CHECK-NEXT: Kind: GLOBAL
42-
# CHECK-NEXT: Index: 5
42+
# CHECK-NEXT: Index: 7
4343
# CHECK-NEXT: - Name: __global_base
4444
# CHECK-NEXT: Kind: GLOBAL
45-
# CHECK-NEXT: Index: 6
45+
# CHECK-NEXT: Index: 8
4646
# CHECK-NEXT: - Name: __heap_base
4747
# CHECK-NEXT: Kind: GLOBAL
48-
# CHECK-NEXT: Index: 7
48+
# CHECK-NEXT: Index: 9
4949
# CHECK-NEXT: - Name: __heap_end
5050
# CHECK-NEXT: Kind: GLOBAL
51-
# CHECK-NEXT: Index: 8
51+
# CHECK-NEXT: Index: 10
5252
# CHECK-NEXT: - Name: __memory_base
5353
# CHECK-NEXT: Kind: GLOBAL
54-
# CHECK-NEXT: Index: 9
54+
# CHECK-NEXT: Index: 1
5555
# CHECK-NEXT: - Name: __table_base
5656
# CHECK-NEXT: Kind: GLOBAL
57-
# CHECK-NEXT: Index: 10
57+
# CHECK-NEXT: Index: 2
5858
# CHECK-NEXT: - Name: __wasm_first_page_end
5959
# CHECK-NEXT: Kind: GLOBAL
6060
# CHECK-NEXT: Index: 11
6161
# CHECK-NEXT: - Name: __tls_base
6262
# CHECK-NEXT: Kind: GLOBAL
63-
# CHECK-NEXT: Index: 1
63+
# CHECK-NEXT: Index: 3
6464
# CHECK-NEXT: - Type: CODE

lld/test/wasm/mutable-global-exports.s

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,43 +81,43 @@ _start:
8181
# CHECK-ALL-NEXT: Index: 1
8282
# CHECK-ALL-NEXT: - Name: foo_global
8383
# CHECK-ALL-NEXT: Kind: GLOBAL
84-
# CHECK-ALL-NEXT: Index: 2
84+
# CHECK-ALL-NEXT: Index: 4
8585
# CHECK-ALL-NEXT: - Name: bar_global
8686
# CHECK-ALL-NEXT: Kind: GLOBAL
87-
# CHECK-ALL-NEXT: Index: 3
87+
# CHECK-ALL-NEXT: Index: 5
8888
# CHECK-ALL-NEXT: - Name: __dso_handle
8989
# CHECK-ALL-NEXT: Kind: GLOBAL
90-
# CHECK-ALL-NEXT: Index: 4
90+
# CHECK-ALL-NEXT: Index: 6
9191
# CHECK-ALL-NEXT: - Name: __data_end
9292
# CHECK-ALL-NEXT: Kind: GLOBAL
93-
# CHECK-ALL-NEXT: Index: 5
93+
# CHECK-ALL-NEXT: Index: 7
9494
# CHECK-ALL-NEXT: - Name: __stack_low
9595
# CHECK-ALL-NEXT: Kind: GLOBAL
96-
# CHECK-ALL-NEXT: Index: 6
96+
# CHECK-ALL-NEXT: Index: 8
9797
# CHECK-ALL-NEXT: - Name: __stack_high
9898
# CHECK-ALL-NEXT: Kind: GLOBAL
99-
# CHECK-ALL-NEXT: Index: 7
99+
# CHECK-ALL-NEXT: Index: 9
100100
# CHECK-ALL-NEXT: - Name: __global_base
101101
# CHECK-ALL-NEXT: Kind: GLOBAL
102-
# CHECK-ALL-NEXT: Index: 8
102+
# CHECK-ALL-NEXT: Index: 10
103103
# CHECK-ALL-NEXT: - Name: __heap_base
104104
# CHECK-ALL-NEXT: Kind: GLOBAL
105-
# CHECK-ALL-NEXT: Index: 9
105+
# CHECK-ALL-NEXT: Index: 11
106106
# CHECK-ALL-NEXT: - Name: __heap_end
107107
# CHECK-ALL-NEXT: Kind: GLOBAL
108-
# CHECK-ALL-NEXT: Index: 10
108+
# CHECK-ALL-NEXT: Index: 12
109109
# CHECK-ALL-NEXT: - Name: __memory_base
110110
# CHECK-ALL-NEXT: Kind: GLOBAL
111-
# CHECK-ALL-NEXT: Index: 11
111+
# CHECK-ALL-NEXT: Index: 1
112112
# CHECK-ALL-NEXT: - Name: __table_base
113113
# CHECK-ALL-NEXT: Kind: GLOBAL
114-
# CHECK-ALL-NEXT: Index: 12
114+
# CHECK-ALL-NEXT: Index: 2
115115
# CHECK-ALL-NEXT: - Name: __wasm_first_page_end
116116
# CHECK-ALL-NEXT: Kind: GLOBAL
117117
# CHECK-ALL-NEXT: Index: 13
118118
# CHECK-ALL-NEXT: - Name: __tls_base
119119
# CHECK-ALL-NEXT: Kind: GLOBAL
120-
# CHECK-ALL-NEXT: Index: 1
120+
# CHECK-ALL-NEXT: Index: 3
121121
# CHECK-ALL-NEXT: - Type: CODE
122122

123123
# CHECK-ALL: Name: target_features

lld/test/wasm/pic-static-unused.s

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
2+
# RUN: wasm-ld -o %t.wasm %t.o
3+
# RUN: obj2yaml %t.wasm | FileCheck %s
4+
5+
.globaltype __memory_base, i32, immutable
6+
.globaltype __table_base, i32, immutable
7+
8+
.globl _start
9+
_start:
10+
.functype _start () -> ()
11+
end_function
12+
13+
.section .debug_info,"",@
14+
.int32 __memory_base
15+
.int32 __table_base
16+
17+
## Check that relocations against unused __memory_base and __table_base
18+
## work in non-pic mode.
19+
20+
# CHECK: Name: .debug_info
21+
# CHECK-NEXT: Payload: FFFFFFFFFFFFFFFF

lld/test/wasm/pic-static.s

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -102,56 +102,64 @@ ret32_ptr:
102102
# CHECK-NEXT: Opcode: I32_CONST
103103
# CHECK-NEXT: Value: 65536
104104

105-
# __tls_base
105+
# __memory_base
106106
# CHECK-NEXT: - Index: 1
107107
# CHECK-NEXT: Type: I32
108108
# CHECK-NEXT: Mutable: false
109109
# CHECK-NEXT: InitExpr:
110110
# CHECK-NEXT: Opcode: I32_CONST
111111
# CHECK-NEXT: Value: 0
112112

113-
# GOT.func.internal.ret32
113+
# __table_base
114114
# CHECK-NEXT: - Index: 2
115115
# CHECK-NEXT: Type: I32
116116
# CHECK-NEXT: Mutable: false
117117
# CHECK-NEXT: InitExpr:
118118
# CHECK-NEXT: Opcode: I32_CONST
119-
# CHECK-NEXT: Value: 1
119+
# CHECK-NEXT: Value: 1
120120

121-
# GOT.func.missing_function
121+
# __tls_base
122122
# CHECK-NEXT: - Index: 3
123123
# CHECK-NEXT: Type: I32
124124
# CHECK-NEXT: Mutable: false
125125
# CHECK-NEXT: InitExpr:
126126
# CHECK-NEXT: Opcode: I32_CONST
127-
# CHECK-NEXT: Value: 2
127+
# CHECK-NEXT: Value: 0
128128

129-
# GOT.data.internal.__table_base
129+
# GOT.func.internal.ret32
130130
# CHECK-NEXT: - Index: 4
131131
# CHECK-NEXT: Type: I32
132132
# CHECK-NEXT: Mutable: false
133133
# CHECK-NEXT: InitExpr:
134134
# CHECK-NEXT: Opcode: I32_CONST
135-
# CHECK-NEXT: Value: 1
135+
# CHECK-NEXT: Value: 1
136136

137-
# GOT.mem.missing_float
137+
# GOT.func.missing_function
138138
# CHECK-NEXT: - Index: 5
139139
# CHECK-NEXT: Type: I32
140140
# CHECK-NEXT: Mutable: false
141141
# CHECK-NEXT: InitExpr:
142142
# CHECK-NEXT: Opcode: I32_CONST
143+
# CHECK-NEXT: Value: 2
144+
145+
# GOT.mem.missing_float
146+
# CHECK-NEXT: - Index: 6
147+
# CHECK-NEXT: Type: I32
148+
# CHECK-NEXT: Mutable: false
149+
# CHECK-NEXT: InitExpr:
150+
# CHECK-NEXT: Opcode: I32_CONST
143151
# CHECK-NEXT: Value: 0
144152

145153
# GOT.mem.global_float
146-
# CHECK-NEXT: - Index: 6
154+
# CHECK-NEXT: - Index: 7
147155
# CHECK-NEXT: Type: I32
148156
# CHECK-NEXT: Mutable: false
149157
# CHECK-NEXT: InitExpr:
150158
# CHECK-NEXT: Opcode: I32_CONST
151159
# CHECK-NEXT: Value: 65536
152160

153161
# GOT.mem.ret32_ptr
154-
# CHECK-NEXT: - Index: 7
162+
# CHECK-NEXT: - Index: 8
155163
# CHECK-NEXT: Type: I32
156164
# CHECK-NEXT: Mutable: false
157165
# CHECK-NEXT: InitExpr:
@@ -162,19 +170,19 @@ ret32_ptr:
162170
# CHECK-NEXT: - Index: 0
163171
# CHECK-NEXT: Name: __stack_pointer
164172
# CHECK-NEXT: - Index: 1
165-
# CHECK-NEXT: Name: __tls_base
173+
# CHECK-NEXT: Name: __memory_base
166174
# CHECK-NEXT: - Index: 2
167-
# CHECK-NEXT: Name: GOT.func.internal.ret32
175+
# CHECK-NEXT: Name: __table_base
168176
# CHECK-NEXT: - Index: 3
169-
# CHECK-NEXT: Name: GOT.func.internal.missing_function
177+
# CHECK-NEXT: Name: __tls_base
170178
# CHECK-NEXT: - Index: 4
171-
# CHECK-NEXT: Name: GOT.data.internal.__table_base
179+
# CHECK-NEXT: Name: GOT.func.internal.ret32
172180
# CHECK-NEXT: - Index: 5
173-
# CHECK-NEXT: Name: GOT.data.internal.missing_float
181+
# CHECK-NEXT: Name: GOT.func.internal.missing_function
174182
# CHECK-NEXT: - Index: 6
175-
# CHECK-NEXT: Name: GOT.data.internal.global_float
183+
# CHECK-NEXT: Name: GOT.data.internal.missing_float
176184
# CHECK-NEXT: - Index: 7
177-
# CHECK-NEXT: Name: GOT.data.internal.ret32_ptr
185+
# CHECK-NEXT: Name: GOT.data.internal.global_float
178186
# CHECK-NEXT: - Index: 8
179-
# CHECK-NEXT: Name: GOT.data.internal.__memory_base
187+
# CHECK-NEXT: Name: GOT.data.internal.ret32_ptr
180188
# CHECK-NEXT: DataSegmentNames:

lld/wasm/Config.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class Symbol;
3535
class DefinedData;
3636
class GlobalSymbol;
3737
class DefinedFunction;
38+
class DefinedGlobal;
3839
class UndefinedGlobal;
3940
class TableSymbol;
4041

@@ -236,13 +237,11 @@ struct Ctx {
236237

237238
// __table_base
238239
// Used in PIC code for offset of indirect function table
239-
UndefinedGlobal *tableBase;
240-
DefinedData *definedTableBase;
240+
GlobalSymbol *tableBase;
241241

242242
// __memory_base
243243
// Used in PIC code for offset of global data
244-
UndefinedGlobal *memoryBase;
245-
DefinedData *definedMemoryBase;
244+
GlobalSymbol *memoryBase;
246245

247246
// __indirect_function_table
248247
// Used as an address space for function pointers, with each function that

lld/wasm/Driver.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -915,13 +915,13 @@ static InputGlobal *createGlobal(StringRef name, bool isMutable) {
915915
return make<InputGlobal>(wasmGlobal, nullptr);
916916
}
917917

918-
static GlobalSymbol *createGlobalVariable(StringRef name, bool isMutable,
919-
uint32_t flags = 0) {
918+
static DefinedGlobal *createGlobalVariable(StringRef name, bool isMutable,
919+
uint32_t flags = 0) {
920920
InputGlobal *g = createGlobal(name, isMutable);
921921
return symtab->addSyntheticGlobal(name, flags, g);
922922
}
923923

924-
static GlobalSymbol *createOptionalGlobal(StringRef name, bool isMutable) {
924+
static DefinedGlobal *createOptionalGlobal(StringRef name, bool isMutable) {
925925
InputGlobal *g = createGlobal(name, isMutable);
926926
return symtab->addOptionalGlobalSymbol(name, g);
927927
}
@@ -997,8 +997,8 @@ static void createOptionalSymbols() {
997997
ctx.sym.globalBase = symtab->addOptionalDataSymbol("__global_base");
998998
ctx.sym.heapBase = symtab->addOptionalDataSymbol("__heap_base");
999999
ctx.sym.heapEnd = symtab->addOptionalDataSymbol("__heap_end");
1000-
ctx.sym.definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
1001-
ctx.sym.definedTableBase = symtab->addOptionalDataSymbol("__table_base");
1000+
ctx.sym.memoryBase = createOptionalGlobal("__memory_base", false);
1001+
ctx.sym.tableBase = createOptionalGlobal("__table_base", false);
10021002
}
10031003

10041004
ctx.sym.firstPageEnd = symtab->addOptionalDataSymbol("__wasm_first_page_end");

lld/wasm/Writer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,8 +1713,8 @@ void Writer::createSyntheticSectionsPostLayout() {
17131713
void Writer::run() {
17141714
// For PIC code the table base is assigned dynamically by the loader.
17151715
// For non-PIC, we start at 1 so that accessing table index 0 always traps.
1716-
if (!ctx.isPic && ctx.sym.definedTableBase)
1717-
ctx.sym.definedTableBase->setVA(ctx.arg.tableBase);
1716+
if (!ctx.isPic && ctx.sym.tableBase)
1717+
setGlobalPtr(cast<DefinedGlobal>(ctx.sym.tableBase), ctx.arg.tableBase);
17181718

17191719
log("-- createOutputSegments");
17201720
createOutputSegments();

0 commit comments

Comments
 (0)