Skip to content

Commit 23a961e

Browse files
cjacekIcohedron
authored andcommitted
[LLD][MinGW] Add support for wrapped symbols on ARM64X (llvm#126296)
Apply `-wrap` arguments to both symbol tables.
1 parent d055209 commit 23a961e

File tree

5 files changed

+66
-30
lines changed

5 files changed

+66
-30
lines changed

lld/COFF/Driver.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2573,11 +2573,13 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
25732573
ctx.symtab.addUndefinedGlob(pat);
25742574

25752575
// Create wrapped symbols for -wrap option.
2576-
std::vector<WrappedSymbol> wrapped = addWrappedSymbols(ctx, args);
2577-
// Load more object files that might be needed for wrapped symbols.
2578-
if (!wrapped.empty())
2579-
while (run())
2580-
;
2576+
ctx.forEachSymtab([&](SymbolTable &symtab) {
2577+
addWrappedSymbols(symtab, args);
2578+
// Load more object files that might be needed for wrapped symbols.
2579+
if (!symtab.wrapped.empty())
2580+
while (run())
2581+
;
2582+
});
25812583

25822584
if (config->autoImport || config->stdcallFixup) {
25832585
// MinGW specific.
@@ -2647,8 +2649,10 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
26472649
run();
26482650

26492651
// Apply symbol renames for -wrap.
2650-
if (!wrapped.empty())
2651-
wrapSymbols(ctx, wrapped);
2652+
ctx.forEachSymtab([](SymbolTable &symtab) {
2653+
if (!symtab.wrapped.empty())
2654+
wrapSymbols(symtab);
2655+
});
26522656

26532657
if (isArm64EC(config->machine))
26542658
createECExportThunks();

lld/COFF/MinGW.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ static StringRef mangle(Twine sym, MachineTypes machine) {
207207
// This function instantiates wrapper symbols. At this point, they seem
208208
// like they are not being used at all, so we explicitly set some flags so
209209
// that LTO won't eliminate them.
210-
std::vector<WrappedSymbol>
211-
lld::coff::addWrappedSymbols(COFFLinkerContext &ctx, opt::InputArgList &args) {
210+
void lld::coff::addWrappedSymbols(SymbolTable &symtab,
211+
opt::InputArgList &args) {
212212
std::vector<WrappedSymbol> v;
213213
DenseSet<StringRef> seen;
214214

@@ -217,14 +217,14 @@ lld::coff::addWrappedSymbols(COFFLinkerContext &ctx, opt::InputArgList &args) {
217217
if (!seen.insert(name).second)
218218
continue;
219219

220-
Symbol *sym = ctx.symtab.findUnderscore(name);
220+
Symbol *sym = symtab.findUnderscore(name);
221221
if (!sym)
222222
continue;
223223

224224
Symbol *real =
225-
ctx.symtab.addUndefined(mangle("__real_" + name, ctx.config.machine));
225+
symtab.addUndefined(mangle("__real_" + name, symtab.machine));
226226
Symbol *wrap =
227-
ctx.symtab.addUndefined(mangle("__wrap_" + name, ctx.config.machine));
227+
symtab.addUndefined(mangle("__wrap_" + name, symtab.machine));
228228
v.push_back({sym, real, wrap});
229229

230230
// These symbols may seem undefined initially, but don't bail out
@@ -243,37 +243,36 @@ lld::coff::addWrappedSymbols(COFFLinkerContext &ctx, opt::InputArgList &args) {
243243
if (!isa<Undefined>(wrap))
244244
wrap->isUsedInRegularObj = true;
245245
}
246-
return v;
246+
symtab.wrapped = std::move(v);
247247
}
248248

249249
// Do renaming for -wrap by updating pointers to symbols.
250250
//
251251
// When this function is executed, only InputFiles and symbol table
252252
// contain pointers to symbol objects. We visit them to replace pointers,
253253
// so that wrapped symbols are swapped as instructed by the command line.
254-
void lld::coff::wrapSymbols(COFFLinkerContext &ctx,
255-
ArrayRef<WrappedSymbol> wrapped) {
254+
void lld::coff::wrapSymbols(SymbolTable &symtab) {
256255
DenseMap<Symbol *, Symbol *> map;
257-
for (const WrappedSymbol &w : wrapped) {
256+
for (const WrappedSymbol &w : symtab.wrapped) {
258257
map[w.sym] = w.wrap;
259258
map[w.real] = w.sym;
260259
if (Defined *d = dyn_cast<Defined>(w.wrap)) {
261-
Symbol *imp = ctx.symtab.find(("__imp_" + w.sym->getName()).str());
260+
Symbol *imp = symtab.find(("__imp_" + w.sym->getName()).str());
262261
// Create a new defined local import for the wrap symbol. If
263262
// no imp prefixed symbol existed, there's no need for it.
264263
// (We can't easily distinguish whether any object file actually
265264
// referenced it or not, though.)
266265
if (imp) {
267266
DefinedLocalImport *wrapimp = make<DefinedLocalImport>(
268-
ctx, saver().save("__imp_" + w.wrap->getName()), d);
269-
ctx.symtab.localImportChunks.push_back(wrapimp->getChunk());
267+
symtab.ctx, saver().save("__imp_" + w.wrap->getName()), d);
268+
symtab.localImportChunks.push_back(wrapimp->getChunk());
270269
map[imp] = wrapimp;
271270
}
272271
}
273272
}
274273

275274
// Update pointers in input files.
276-
parallelForEach(ctx.objFileInstances, [&](ObjFile *file) {
275+
parallelForEach(symtab.ctx.objFileInstances, [&](ObjFile *file) {
277276
MutableArrayRef<Symbol *> syms = file->getMutableSymbols();
278277
for (auto &sym : syms)
279278
if (Symbol *s = map.lookup(sym))

lld/COFF/MinGW.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,9 @@ void writeDefFile(COFFLinkerContext &, StringRef name,
5555
// symbol becomes accessible as `__real_foo`, so you can call that from your
5656
// wrapper.
5757
//
58-
// This data structure is instantiated for each -wrap option.
59-
struct WrappedSymbol {
60-
Symbol *sym;
61-
Symbol *real;
62-
Symbol *wrap;
63-
};
64-
65-
std::vector<WrappedSymbol> addWrappedSymbols(COFFLinkerContext &ctx,
66-
llvm::opt::InputArgList &args);
58+
void addWrappedSymbols(SymbolTable &symtab, llvm::opt::InputArgList &args);
6759

68-
void wrapSymbols(COFFLinkerContext &ctx, ArrayRef<WrappedSymbol> wrapped);
60+
void wrapSymbols(SymbolTable &symtab);
6961

7062
} // namespace lld::coff
7163

lld/COFF/SymbolTable.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ class LazyArchive;
3434
class SectionChunk;
3535
class Symbol;
3636

37+
// This data structure is instantiated for each -wrap option.
38+
struct WrappedSymbol {
39+
Symbol *sym;
40+
Symbol *real;
41+
Symbol *wrap;
42+
};
43+
3744
// SymbolTable is a bucket of all known symbols, including defined,
3845
// undefined, or lazy symbols (the last one is symbols in archive
3946
// files whose archive members are not yet loaded).
@@ -161,6 +168,9 @@ class SymbolTable {
161168
Symbol *delayLoadHelper = nullptr;
162169
Chunk *tailMergeUnwindInfoChunk = nullptr;
163170

171+
// A list of wrapped symbols.
172+
std::vector<WrappedSymbol> wrapped;
173+
164174
void fixupExports();
165175
void assignExportOrdinals();
166176
void parseModuleDefs(StringRef path);

lld/test/COFF/arm64x-wrap.s

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// REQUIRES: aarch64
2+
// RUN: split-file %s %t.dir && cd %t.dir
3+
4+
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows test.s -o test-arm64ec.obj
5+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows test.s -o test-arm64.obj
6+
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows other.s -o other-arm64ec.obj
7+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows other.s -o other-arm64.obj
8+
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
9+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/loadconfig-arm64.s -o loadconfig-arm64.obj
10+
11+
// RUN: lld-link -machine:arm64x -dll -noentry test-arm64.obj test-arm64ec.obj other-arm64.obj other-arm64ec.obj \
12+
// RUN: loadconfig-arm64.obj loadconfig-arm64ec.obj -out:out.dll -wrap:sym -wrap:nosuchsym
13+
14+
// RUN: llvm-readobj --hex-dump=.test out.dll | FileCheck %s
15+
// CHECK: 0x180004000 02000000 02000000 01000000 02000000
16+
// CHECK: 0x180004010 02000000 01000000
17+
18+
#--- test.s
19+
.section .test,"dr"
20+
.word sym
21+
.word __wrap_sym
22+
.word __real_sym
23+
24+
#--- other.s
25+
.global sym
26+
.global __wrap_sym
27+
.global __real_sym
28+
29+
sym = 1
30+
__wrap_sym = 2
31+
__real_sym = 3

0 commit comments

Comments
 (0)