Skip to content

Commit 1f6d9e4

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 18dbdfb commit 1f6d9e4

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_arm64xsameaddress:
496496
if (!file->symtab.isEC())
@@ -1902,7 +1902,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
19021902

19031903
// Handle /alternatename
19041904
for (auto *arg : args.filtered(OPT_alternatename))
1905-
parseAlternateName(arg->getValue());
1905+
mainSymtab.parseAlternateName(arg->getValue());
19061906

19071907
// Handle /include
19081908
for (auto *arg : args.filtered(OPT_incl))
@@ -2521,32 +2521,30 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
25212521
if (e.source != ExportSource::Directives)
25222522
e.symbolName = symtab.mangleMaybe(e.sym);
25232523
}
2524-
});
25252524

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

2549-
ctx.forEachSymtab([&](SymbolTable &symtab) {
25502548
// If any inputs are bitcode files, the LTO code generator may create
25512549
// references to library functions that are not explicit in the bitcode
25522550
// 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
@@ -1325,6 +1325,17 @@ void SymbolTable::parseModuleDefs(StringRef path) {
13251325
}
13261326
}
13271327

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

lld/COFF/SymbolTable.h

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

171+
// Used for /alternatename.
172+
std::map<StringRef, StringRef> alternateNames;
173+
171174
void fixupExports();
172175
void assignExportOrdinals();
173176
void parseModuleDefs(StringRef path);
177+
void parseAlternateName(StringRef);
174178

175179
// Iterates symbols in non-determinstic hash table order.
176180
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)