Skip to content

Commit 68803c1

Browse files
committed
[lld][WebAssembly] Report undefined symbols by default -shared/-pie builds
Previously we would ignore/import all undefined symbols when using `-shared` or `-pie`. With this change we now track symbol in shared libraries and report undefined symbols by default. This can be a breaking change for any users of dyanmic linking. However, the old behaviour is still available using `--unresolved-symbols=import-dynamic`. This rationale for allowing this type of breaking change is that `-pie` and `-shared` are both still experimental will warn as such, unless `--experimental-pic` is passed. See emscripten-core/emscripten#18198
1 parent 5828b04 commit 68803c1

23 files changed

+276
-59
lines changed

lld/test/wasm/Inputs/ret32.s

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
.hidden ret32
21
.globl ret32
32
ret32:
43
.functype ret32 (f32) -> (i32)

lld/test/wasm/dylink.s

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten -o %t.o %s
2+
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten %p/Inputs/ret32.s -o %t.ret32.o
3+
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten %p/Inputs/libsearch-dyn.s -o %t.dyn.o
4+
# RUN: wasm-ld --experimental-pic -shared %t.ret32.o %t.dyn.o -o %t.lib.so
5+
# RUN: not wasm-ld --experimental-pic -pie -o %t.wasm %t.o 2>&1 | FileCheck --check-prefix=ERROR %s
6+
# RUN: wasm-ld --experimental-pic -pie -o %t.wasm %t.o %t.lib.so
7+
# RUN: obj2yaml %t.wasm | FileCheck %s
8+
9+
# ERROR: error: {{.*}}: undefined symbol: ret32
10+
# ERROR: error: {{.*}}: undefined symbol: _dynamic
11+
.functype ret32 (f32) -> (i32)
12+
13+
.globl _start
14+
_start:
15+
.functype _start () -> ()
16+
f32.const 0.0
17+
call ret32
18+
drop
19+
i32.const _dynamic@GOT
20+
drop
21+
end_function
22+
23+
# CHECK: Sections:
24+
# CHECK-NEXT: - Type: CUSTOM
25+
# CHECK-NEXT: Name: dylink.0
26+
# CHECK-NEXT: MemorySize: 0
27+
# CHECK-NEXT: MemoryAlignment: 0
28+
# CHECK-NEXT: TableSize: 0
29+
# CHECK-NEXT: TableAlignment: 0
30+
# CHECK-NEXT: Needed:
31+
# CHECK-NEXT: - {{.*}}.lib.so

lld/test/wasm/emit-relocs.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ foo:
5454
# CHECK-NEXT: - Index: 1
5555
# CHECK-NEXT: Kind: FUNCTION
5656
# CHECK-NEXT: Name: ret32
57-
# CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
57+
# CHECK-NEXT: Flags: [ ]
5858
# CHECK-NEXT: Function: 1
5959
# CHECK-NEXT: - Index: 2
6060
# CHECK-NEXT: Kind: DATA

lld/test/wasm/pie.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten -o %t.o %s
22
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten %S/Inputs/internal_func.s -o %t.internal_func.o
3-
# RUN: wasm-ld --no-gc-sections --experimental-pic -pie -o %t.wasm %t.o %t.internal_func.o
3+
# RUN: wasm-ld --no-gc-sections --experimental-pic -pie --unresolved-symbols=import-dynamic -o %t.wasm %t.o %t.internal_func.o
44
# RUN: obj2yaml %t.wasm | FileCheck %s
55
# RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DISASSEM
66

@@ -150,7 +150,7 @@ _start:
150150
# instruction in the InitExpr. We also, therefore, do not need these globals
151151
# to be mutable.
152152

153-
# RUN: wasm-ld --no-gc-sections --experimental-pic -pie --extra-features=extended-const -o %t.extended.wasm %t.o %t.internal_func.o
153+
# RUN: wasm-ld --no-gc-sections --experimental-pic -pie --unresolved-symbols=import-dynamic --extra-features=extended-const -o %t.extended.wasm %t.o %t.internal_func.o
154154
# RUN: obj2yaml %t.extended.wasm | FileCheck %s --check-prefix=EXTENDED-CONST
155155

156156
# EXTENDED-CONST-NOT: __wasm_apply_global_relocs
@@ -207,7 +207,7 @@ _start:
207207
# to be generated along with __wasm_start as the start
208208
# function.
209209

210-
# RUN: wasm-ld --no-gc-sections --shared-memory --experimental-pic -pie -o %t.shmem.wasm %t.o %t.internal_func.o
210+
# RUN: wasm-ld --no-gc-sections --shared-memory --experimental-pic -pie --unresolved-symbols=import-dynamic -o %t.shmem.wasm %t.o %t.internal_func.o
211211
# RUN: obj2yaml %t.shmem.wasm | FileCheck %s --check-prefix=SHMEM
212212
# RUN: llvm-objdump --disassemble-symbols=__wasm_start --no-show-raw-insn --no-leading-addr %t.shmem.wasm | FileCheck %s --check-prefix DISASSEM-SHMEM
213213

lld/test/wasm/shared-needed.s

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
11
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
22
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/ret32.s -o %t.ret32.o
33

4-
# RUN: wasm-ld -shared --experimental-pic -o %t1.so %t.o
5-
# RUN: obj2yaml %t1.so | FileCheck %s -check-prefix=SO1
4+
# RUN: wasm-ld -shared --experimental-pic -o %t.ret32.so %t.ret32.o
5+
# RUN: obj2yaml %t.ret32.so | FileCheck %s -check-prefix=SO1
6+
7+
# Without linking against the ret32.so shared object we expect and undefined
8+
# symbol error
9+
10+
# RUN: not wasm-ld -shared --experimental-pic -o %t.so %t.o 2>&1 | FileCheck %s --check-prefix=ERROR
11+
# ERROR: undefined symbol: ret32
12+
13+
# RUN: wasm-ld -shared --experimental-pic -o %t.so %t.o %t.ret32.so
14+
# RUN: obj2yaml %t.so | FileCheck %s -check-prefix=SO2
615

7-
# RUN: wasm-ld -shared --experimental-pic -o %t2.so %t1.so %t.ret32.o
8-
# RUN: obj2yaml %t2.so | FileCheck %s -check-prefix=SO2
916

1017
.globl foo
1118
.globl data
1219

20+
.functype ret32 (f32) -> (i32)
21+
1322
foo:
14-
.functype foo () -> ()
23+
.functype foo (f32) -> (i32)
24+
local.get 0
25+
call ret32
1526
end_function
1627

1728
.section .data,"",@
@@ -24,8 +35,8 @@ data:
2435
# SO1: Sections:
2536
# SO1-NEXT: - Type: CUSTOM
2637
# SO1-NEXT: Name: dylink.0
27-
# SO1-NEXT: MemorySize: 4
28-
# SO1-NEXT: MemoryAlignment: 2
38+
# SO1-NEXT: MemorySize: 0
39+
# SO1-NEXT: MemoryAlignment: 0
2940
# SO1-NEXT: TableSize: 0
3041
# SO1-NEXT: TableAlignment: 0
3142
# SO1-NEXT: Needed: []
@@ -34,10 +45,10 @@ data:
3445
# SO2: Sections:
3546
# SO2-NEXT: - Type: CUSTOM
3647
# SO2-NEXT: Name: dylink.0
37-
# SO2-NEXT: MemorySize: 0
38-
# SO2-NEXT: MemoryAlignment: 0
48+
# SO2-NEXT: MemorySize: 4
49+
# SO2-NEXT: MemoryAlignment: 2
3950
# SO2-NEXT: TableSize: 0
4051
# SO2-NEXT: TableAlignment: 0
4152
# SO2-NEXT: Needed:
42-
# SO2-NEXT: - shared-needed.s.tmp1.so
53+
# SO2-NEXT: - shared-needed.s.tmp.ret32.so
4354
# SO2-NEXT: - Type: TYPE

lld/test/wasm/shared.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
2-
# RUN: wasm-ld --experimental-pic -shared -o %t.wasm %t.o
2+
# RUN: wasm-ld --experimental-pic --unresolved-symbols=import-dynamic -shared -o %t.wasm %t.o
33
# RUN: obj2yaml %t.wasm | FileCheck %s
44
# RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DIS
55

66
.functype func_external () -> ()
77

88
# Linker-synthesized globals
99
.globaltype __stack_pointer, i32
10-
.globaltype __table_base, i32, immutable
11-
.globaltype __memory_base, i32, immutable
10+
.globaltype __table_base, i32, immutable
11+
.globaltype __memory_base, i32, immutable
1212

1313
.section .data.data,"",@
1414
data:

lld/test/wasm/shared64.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# RUN: llvm-mc -filetype=obj -triple=wasm64-unknown-unknown -o %t.o %s
2-
# RUN: wasm-ld -mwasm64 --experimental-pic -shared -o %t.wasm %t.o
2+
# RUN: wasm-ld -mwasm64 --experimental-pic --unresolved-symbols=import-dynamic -shared -o %t.wasm %t.o
33
# RUN: obj2yaml %t.wasm | FileCheck %s
44
# RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DIS
55

lld/test/wasm/signature-mismatch.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ ret32_address_main:
9393
# RELOC-NEXT: - Index: 1
9494
# RELOC-NEXT: Kind: FUNCTION
9595
# RELOC-NEXT: Name: ret32
96-
# RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
96+
# RELOC-NEXT: Flags: [ ]
9797
# RELOC-NEXT: Function: 2
9898
# RELOC-NEXT: - Index: 2
9999
# RELOC-NEXT: Kind: DATA

lld/test/wasm/tag-section.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling -relocation-model=pic %p/Inputs/tag-section1.ll -o %t1.o
1212
; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling -relocation-model=pic %p/Inputs/tag-section2.ll -o %t2.o
1313
; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling -relocation-model=pic %s -o %t.o
14-
; RUN: wasm-ld --import-undefined --experimental-pic -pie -o %t.wasm %t.o %t1.o %t2.o
14+
; RUN: wasm-ld --import-undefined --experimental-pic --unresolved-symbols=import-dynamic -pie -o %t.wasm %t.o %t1.o %t2.o
1515
; RUN: obj2yaml %t.wasm | FileCheck %s --check-prefix=PIC
1616

1717
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"

lld/test/wasm/undef-shared.s

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
2+
# RUN: not wasm-ld --experimental-pic %t.o -o /dev/null -shared 2>&1 | FileCheck %s
3+
4+
# CHECK: error: {{.*}}: undefined symbol: hidden
5+
.global hidden
6+
.hidden hidden
7+
8+
.global foo
9+
.section .data,"",@
10+
foo:
11+
.int32 hidden
12+
.size foo,4

lld/test/wasm/undefined-data.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
22
# RUN: not wasm-ld -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=UNDEF
33
# RUN: wasm-ld --allow-undefined -o %t.wasm %t.o
4-
# RUN: not wasm-ld --shared -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=SHARED
4+
# RUN: not wasm-ld --experimental-pic -shared --unresolved-symbols=import-dynamic -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=SHARED
55

66
.globl _start
77
_start:

lld/test/wasm/unresolved-symbols.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
# RUN: llvm-readobj %t4.wasm > /dev/null 2>&1
8686

8787
## import-dynamic should fail due to incompatible relocations.
88-
# RUN: not wasm-ld %t/main.o -o %t5.wasm --unresolved-symbols=import-dynamic 2>&1 | FileCheck -check-prefix=ERRNOPIC %s
88+
# RUN: not wasm-ld %t/main.o -o %t5.wasm --experimental-pic --unresolved-symbols=import-dynamic 2>&1 | FileCheck -check-prefix=ERRNOPIC %s
8989
# ERRNOPIC: relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `undef_data`; recompile with -fPIC
9090
# ERRNOPIC: relocation R_WASM_TABLE_INDEX_SLEB cannot be used against symbol `undef_func`; recompile with -fPIC
9191

lld/wasm/InputFiles.cpp

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc, uint64_t tombstone,
175175
case R_WASM_MEMORY_ADDR_TLS_SLEB:
176176
case R_WASM_MEMORY_ADDR_TLS_SLEB64:
177177
case R_WASM_MEMORY_ADDR_LOCREL_I32: {
178-
if (isa<UndefinedData>(sym) || sym->isUndefWeak())
178+
if (isa<UndefinedData>(sym) || sym->isShared() || sym->isUndefWeak())
179179
return 0;
180180
auto D = cast<DefinedData>(sym);
181181
uint64_t value = D->getVA() + reloc.Addend;
@@ -388,7 +388,7 @@ static bool shouldMerge(const WasmSegment &seg) {
388388
}
389389

390390
void ObjFile::parseLazy() {
391-
LLVM_DEBUG(dbgs() << "ObjFile::parseLazy: " << toString(this) << "\n");
391+
LLVM_DEBUG(dbgs() << "ObjFile::parseLazy: " << toString(this) << " " << wasmObj.get() << "\n");
392392
for (const SymbolRef &sym : wasmObj->symbols()) {
393393
const WasmSymbol &wasmSym = wasmObj->getWasmSymbol(sym.getRawDataRefImpl());
394394
if (!wasmSym.isDefined())
@@ -403,21 +403,51 @@ void ObjFile::parseLazy() {
403403
}
404404

405405
ObjFile::ObjFile(MemoryBufferRef m, StringRef archiveName, bool lazy)
406-
: InputFile(ObjectKind, m) {
406+
: WasmFileBase(ObjectKind, m) {
407407
this->lazy = lazy;
408408
this->archiveName = std::string(archiveName);
409409

410410
// If this isn't part of an archive, it's eagerly linked, so mark it live.
411411
if (archiveName.empty())
412412
markLive();
413+
}
414+
415+
void SharedFile::parse() {
416+
assert(wasmObj->isSharedObject());
413417

418+
for (const SymbolRef &sym : wasmObj->symbols()) {
419+
const WasmSymbol &wasmSym = wasmObj->getWasmSymbol(sym.getRawDataRefImpl());
420+
if (wasmSym.isDefined()) {
421+
StringRef name = wasmSym.Info.Name;
422+
uint32_t flags = wasmSym.Info.Flags;
423+
Symbol *s;
424+
LLVM_DEBUG(dbgs() << "shared symbol: " << name << "\n");
425+
switch (wasmSym.Info.Kind) {
426+
case WASM_SYMBOL_TYPE_FUNCTION:
427+
if (name == "__wasm_apply_data_relocs" || name == "__wasm_call_ctors") {
428+
continue;
429+
}
430+
s = symtab->addSharedFunction(name, flags, this, wasmSym.Signature);
431+
break;
432+
case WASM_SYMBOL_TYPE_DATA:
433+
s = symtab->addSharedData(name, flags, this);
434+
break;
435+
default:
436+
continue;
437+
}
438+
symbols.push_back(s);
439+
}
440+
}
441+
}
442+
443+
WasmFileBase::WasmFileBase(Kind k, MemoryBufferRef m) : InputFile(k, m) {
444+
// Parse a memory buffer as a wasm file.
445+
LLVM_DEBUG(dbgs() << "Reading object: " << toString(this) << "\n");
414446
std::unique_ptr<Binary> bin = CHECK(createBinary(mb), toString(this));
415447

416448
auto *obj = dyn_cast<WasmObjectFile>(bin.get());
417449
if (!obj)
418450
fatal(toString(this) + ": not a wasm file");
419-
if (!obj->isRelocatableObject())
420-
fatal(toString(this) + ": not a relocatable wasm file");
421451

422452
bin.release();
423453
wasmObj.reset(obj);
@@ -429,6 +459,9 @@ void ObjFile::parse(bool ignoreComdats) {
429459
// Parse a memory buffer as a wasm file.
430460
LLVM_DEBUG(dbgs() << "ObjFile::parse: " << toString(this) << "\n");
431461

462+
if (!wasmObj->isRelocatableObject())
463+
fatal(toString(this) + ": not a relocatable wasm file");
464+
432465
// Build up a map of function indices to table indices for use when
433466
// verifying the existing table index relocations
434467
uint32_t totalFunctions =

lld/wasm/InputFiles.h

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,26 @@ class InputFile {
8787
bool live;
8888
};
8989

90+
class WasmFileBase : public InputFile {
91+
public:
92+
explicit WasmFileBase(Kind k, MemoryBufferRef m);
93+
94+
// Returns the underlying wasm file.
95+
const WasmObjectFile *getWasmObj() const { return wasmObj.get(); }
96+
97+
protected:
98+
std::unique_ptr<WasmObjectFile> wasmObj;
99+
};
100+
90101
// .o file (wasm object file)
91-
class ObjFile : public InputFile {
102+
class ObjFile : public WasmFileBase {
92103
public:
93104
ObjFile(MemoryBufferRef m, StringRef archiveName, bool lazy = false);
94105
static bool classof(const InputFile *f) { return f->kind() == ObjectKind; }
95106

96107
void parse(bool ignoreComdats = false);
97108
void parseLazy();
98109

99-
// Returns the underlying wasm file.
100-
const WasmObjectFile *getWasmObj() const { return wasmObj.get(); }
101-
102110
uint32_t calcNewIndex(const WasmRelocation &reloc) const;
103111
uint64_t calcNewValue(const WasmRelocation &reloc, uint64_t tombstone,
104112
const InputChunk *chunk) const;
@@ -139,14 +147,15 @@ class ObjFile : public InputFile {
139147

140148
bool isExcludedByComdat(const InputChunk *chunk) const;
141149
void addLegacyIndirectFunctionTableIfNeeded(uint32_t tableSymbolCount);
142-
143-
std::unique_ptr<WasmObjectFile> wasmObj;
144150
};
145151

146152
// .so file.
147-
class SharedFile : public InputFile {
153+
class SharedFile : public WasmFileBase {
148154
public:
149-
explicit SharedFile(MemoryBufferRef m) : InputFile(SharedKind, m) {}
155+
explicit SharedFile(MemoryBufferRef m) : WasmFileBase(SharedKind, m) {}
156+
157+
void parse();
158+
150159
static bool classof(const InputFile *f) { return f->kind() == SharedKind; }
151160
};
152161

lld/wasm/MarkLive.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,15 @@ void MarkLive::enqueue(Symbol *sym) {
6363
sym->markLive();
6464

6565
if (markImplicitDeps) {
66-
// Mark ctor functions in the object that defines this symbol live.
67-
// The ctor functions are all referenced by the synthetic callCtors
68-
// function. However, this function does not contain relocations so we
69-
// have to manually mark the ctors as live.
70-
enqueueInitFunctions(cast<ObjFile>(file));
71-
// Mark retained segments in the object that defines this symbol live.
72-
enqueueRetainedSegments(cast<ObjFile>(file));
66+
if (auto obj = dyn_cast<ObjFile>(file)) {
67+
// Mark as live the ctor functions in the object that defines this symbol.
68+
// The ctor functions are all referenced by the synthetic callCtors
69+
// function. However, this function does not contain relocations so we
70+
// have to manually mark the ctors as live.
71+
enqueueInitFunctions(obj);
72+
// Mark retained segments in the object that defines this symbol live.
73+
enqueueRetainedSegments(obj);
74+
}
7375
}
7476

7577
if (InputChunk *chunk = sym->getChunk())

lld/wasm/Relocations.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ using namespace llvm::wasm;
1919
namespace lld::wasm {
2020

2121
static bool requiresGOTAccess(const Symbol *sym) {
22+
if (sym->isShared())
23+
return true;
2224
if (!ctx.isPic &&
2325
config->unresolvedSymbols != UnresolvedPolicy::ImportDynamic)
2426
return false;
@@ -142,9 +144,12 @@ void scanRelocations(InputChunk *chunk) {
142144
break;
143145
}
144146

145-
if (ctx.isPic ||
147+
bool shouldImport =
148+
sym->isShared() ||
146149
(sym->isUndefined() &&
147-
config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic)) {
150+
config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic);
151+
152+
if (shouldImport) {
148153
switch (reloc.Type) {
149154
case R_WASM_TABLE_INDEX_SLEB:
150155
case R_WASM_TABLE_INDEX_SLEB64:
@@ -163,8 +168,8 @@ void scanRelocations(InputChunk *chunk) {
163168
case R_WASM_MEMORY_ADDR_I32:
164169
case R_WASM_MEMORY_ADDR_I64:
165170
// These relocation types are only present in the data section and
166-
// will be converted into code by `generateRelocationCode`. This code
167-
// requires the symbols to have GOT entries.
171+
// will be converted into code by `generateRelocationCode`. This
172+
// code requires the symbols to have GOT entries.
168173
if (requiresGOTAccess(sym))
169174
addGOTEntry(sym);
170175
break;

0 commit comments

Comments
 (0)