Skip to content

Commit d72c6b3

Browse files
cjacekSquallATF
authored andcommitted
[LLD][COFF] Support alternate names in both symbol tables on ARM64X (llvm#127619)
The `.drectve` directive applies only to the namespace in which it is defined, while the command-line argument applies only to the EC namespace.
1 parent b91db3a commit d72c6b3

File tree

7 files changed

+81
-40
lines changed

7 files changed

+81
-40
lines changed

lld/COFF/Config.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,6 @@ struct Configuration {
220220
// Used for /failifmismatch.
221221
std::map<StringRef, std::pair<StringRef, InputFile *>> mustMatch;
222222

223-
// Used for /alternatename.
224-
std::map<StringRef, StringRef> alternateNames;
225-
226223
// Used for /order.
227224
llvm::StringMap<int> order;
228225

lld/COFF/Driver.cpp

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ void LinkerDriver::parseDirectives(InputFile *file) {
490490
parseAligncomm(arg->getValue());
491491
break;
492492
case OPT_alternatename:
493-
parseAlternateName(arg->getValue());
493+
file->symtab.parseAlternateName(arg->getValue());
494494
break;
495495
case OPT_defaultlib:
496496
if (std::optional<StringRef> path = findLibIfNew(arg->getValue()))
@@ -1896,7 +1896,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
18961896

18971897
// Handle /alternatename
18981898
for (auto *arg : args.filtered(OPT_alternatename))
1899-
parseAlternateName(arg->getValue());
1899+
mainSymtab.parseAlternateName(arg->getValue());
19001900

19011901
// Handle /include
19021902
for (auto *arg : args.filtered(OPT_incl))
@@ -2515,32 +2515,30 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
25152515
if (e.source != ExportSource::Directives)
25162516
e.symbolName = symtab.mangleMaybe(e.sym);
25172517
}
2518-
});
25192518

2520-
// Add weak aliases. Weak aliases is a mechanism to give remaining
2521-
// undefined symbols final chance to be resolved successfully.
2522-
for (auto pair : config->alternateNames) {
2523-
StringRef from = pair.first;
2524-
StringRef to = pair.second;
2525-
Symbol *sym = ctx.symtab.find(from);
2526-
if (!sym)
2527-
continue;
2528-
if (auto *u = dyn_cast<Undefined>(sym)) {
2529-
if (u->weakAlias) {
2530-
// On ARM64EC, anti-dependency aliases are treated as undefined
2531-
// symbols unless a demangled symbol aliases a defined one, which is
2532-
// part of the implementation.
2533-
if (!isArm64EC(ctx.config.machine) || !u->isAntiDep)
2534-
continue;
2535-
if (!isa<Undefined>(u->weakAlias) &&
2536-
!isArm64ECMangledFunctionName(u->getName()))
2537-
continue;
2519+
// Add weak aliases. Weak aliases is a mechanism to give remaining
2520+
// undefined symbols final chance to be resolved successfully.
2521+
for (auto pair : symtab.alternateNames) {
2522+
StringRef from = pair.first;
2523+
StringRef to = pair.second;
2524+
Symbol *sym = symtab.find(from);
2525+
if (!sym)
2526+
continue;
2527+
if (auto *u = dyn_cast<Undefined>(sym)) {
2528+
if (u->weakAlias) {
2529+
// On ARM64EC, anti-dependency aliases are treated as undefined
2530+
// symbols unless a demangled symbol aliases a defined one, which
2531+
// is part of the implementation.
2532+
if (!symtab.isEC() || !u->isAntiDep)
2533+
continue;
2534+
if (!isa<Undefined>(u->weakAlias) &&
2535+
!isArm64ECMangledFunctionName(u->getName()))
2536+
continue;
2537+
}
2538+
u->setWeakAlias(symtab.addUndefined(to));
25382539
}
2539-
u->setWeakAlias(ctx.symtab.addUndefined(to));
25402540
}
2541-
}
25422541

2543-
ctx.forEachSymtab([&](SymbolTable &symtab) {
25442542
// If any inputs are bitcode files, the LTO code generator may create
25452543
// references to library functions that are not explicit in the bitcode
25462544
// file's symbol table. If any of those library functions are defined in

lld/COFF/Driver.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ class LinkerDriver {
209209
void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major,
210210
uint32_t *minor, bool *gotVersion = nullptr);
211211

212-
void parseAlternateName(StringRef);
213212
void parseMerge(StringRef);
214213
void parsePDBPageSize(StringRef);
215214
void parseSection(StringRef);

lld/COFF/DriverUtils.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,18 +145,6 @@ void LinkerDriver::parseSubsystem(StringRef arg, WindowsSubsystem *sys,
145145
*gotVersion = !ver.empty();
146146
}
147147

148-
// Parse a string of the form of "<from>=<to>".
149-
// Results are directly written to Config.
150-
void LinkerDriver::parseAlternateName(StringRef s) {
151-
auto [from, to] = s.split('=');
152-
if (from.empty() || to.empty())
153-
Fatal(ctx) << "/alternatename: invalid argument: " << s;
154-
auto it = ctx.config.alternateNames.find(from);
155-
if (it != ctx.config.alternateNames.end() && it->second != to)
156-
Fatal(ctx) << "/alternatename: conflicts: " << s;
157-
ctx.config.alternateNames.insert(it, std::make_pair(from, to));
158-
}
159-
160148
// Parse a string of the form of "<from>=<to>".
161149
// Results are directly written to Config.
162150
void LinkerDriver::parseMerge(StringRef s) {

lld/COFF/SymbolTable.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,17 @@ void SymbolTable::parseModuleDefs(StringRef path) {
13201320
}
13211321
}
13221322

1323+
// Parse a string of the form of "<from>=<to>".
1324+
void SymbolTable::parseAlternateName(StringRef s) {
1325+
auto [from, to] = s.split('=');
1326+
if (from.empty() || to.empty())
1327+
Fatal(ctx) << "/alternatename: invalid argument: " << s;
1328+
auto it = alternateNames.find(from);
1329+
if (it != alternateNames.end() && it->second != to)
1330+
Fatal(ctx) << "/alternatename: conflicts: " << s;
1331+
alternateNames.insert(it, std::make_pair(from, to));
1332+
}
1333+
13231334
Symbol *SymbolTable::addUndefined(StringRef name) {
13241335
return addUndefined(name, nullptr, false);
13251336
}

lld/COFF/SymbolTable.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,13 @@ class SymbolTable {
171171
// A list of wrapped symbols.
172172
std::vector<WrappedSymbol> wrapped;
173173

174+
// Used for /alternatename.
175+
std::map<StringRef, StringRef> alternateNames;
176+
174177
void fixupExports();
175178
void assignExportOrdinals();
176179
void parseModuleDefs(StringRef path);
180+
void parseAlternateName(StringRef);
177181

178182
// Iterates symbols in non-determinstic hash table order.
179183
template <typename T> void forEachSymbol(T callback) {

lld/test/COFF/arm64x-altnames.s

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// REQUIRES: aarch64
2+
// RUN: split-file %s %t.dir && cd %t.dir
3+
4+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows test.s -o test-arm64.obj
5+
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows test.s -o test-arm64ec.obj
6+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows drectve.s -o drectve-arm64.obj
7+
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows drectve.s -o drectve-arm64ec.obj
8+
9+
// Check that the -alternatename command-line argument applies only to the EC namespace.
10+
11+
// RUN: not lld-link -out:out.dll -machine:arm64x -dll -noentry test-arm64.obj test-arm64ec.obj -alternatename:sym=altsym \
12+
// RUN: 2>&1 | FileCheck --check-prefix=ERR-NATIVE %s
13+
14+
// ERR-NATIVE-NOT: test-arm64ec.obj
15+
// ERR-NATIVE: lld-link: error: undefined symbol: sym
16+
// ERR-NATIVE-NEXT: >>> referenced by test-arm64.obj:(.test)
17+
// ERR-NATIVE-NOT: test-arm64ec.obj
18+
19+
// Check that the -alternatename .drectve directive applies only to the namespace in which it is defined.
20+
21+
// RUN: not lld-link -out:out.dll -machine:arm64x -dll -noentry test-arm64.obj test-arm64ec.obj drectve-arm64ec.obj \
22+
// RUN: 2>&1 | FileCheck --check-prefix=ERR-NATIVE %s
23+
24+
// RUN: not lld-link -out:out.dll -machine:arm64x -dll -noentry test-arm64.obj test-arm64ec.obj drectve-arm64.obj \
25+
// RUN: 2>&1 | FileCheck --check-prefix=ERR-EC %s
26+
27+
// ERR-EC-NOT: test-arm64.obj
28+
// ERR-EC: lld-link: error: undefined symbol: sym
29+
// ERR-EC-NEXT: >>> referenced by test-arm64ec.obj:(.test)
30+
// ERR-EC-NOT: test-arm64.obj
31+
32+
// RUN: lld-link -out:out.dll -machine:arm64x -dll -noentry test-arm64.obj test-arm64ec.obj drectve-arm64.obj drectve-arm64ec.obj
33+
34+
#--- test.s
35+
.section .test,"dr"
36+
.rva sym
37+
.data
38+
.globl altsym
39+
altsym:
40+
.word 0
41+
42+
#--- drectve.s
43+
.section .drectve
44+
.ascii "-alternatename:sym=altsym"

0 commit comments

Comments
 (0)