Skip to content

Commit e16c0a9

Browse files
committed
clang+lld: Improve clang+ld.darwinnew.lld interaction, pass -demangle
This patch: - adds an ld64.lld.darwinnew symlink for lld, to go with f2710d4, so that `clang -fuse-ld=lld.darwinnew` can be used to test new Mach-O lld while it's in bring-up. (The expectation is that we'll remove this again once new Mach-O lld is the defauld and only Mach-O lld.) - lets the clang driver know if the linker is lld (currently only triggered if `-fuse-ld=lld` or `-fuse-ld=lld.darwinnew` is passed). Currently only used for the next point, but could be used to implement other features that need close coordination between compiler and linker, e.g. having a diag for calling `clang++` instead of `clang` when link errors are caused by a missing C++ stdlib. - lets the clang driver pass `-demangle` to Mach-O lld (both old and new), in addition to ld64 - implements -demangle for new Mach-O lld - changes demangleItanium() to accept _Z, __Z, ___Z, ____Z prefixes (and updates one test added in D68014). Mach-O has an extra underscore for symbols, and the three (or, on Mach-O, four) underscores are used for block names. Differential Revision: https://reviews.llvm.org/D91884
1 parent 32d9a38 commit e16c0a9

File tree

16 files changed

+62
-25
lines changed

16 files changed

+62
-25
lines changed

clang/include/clang/Driver/ToolChain.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,11 @@ class ToolChain {
327327

328328
/// Returns the linker path, respecting the -fuse-ld= argument to determine
329329
/// the linker suffix or name.
330-
std::string GetLinkerPath() const;
330+
/// If LinkerIsLLD is non-nullptr, it is set to true if the returned linker
331+
/// is LLD. If it's set, it can be assumed that the linker is LLD built
332+
/// at the same revision as clang, and clang can make assumptions about
333+
/// LLD's supported flags, error output, etc.
334+
std::string GetLinkerPath(bool *LinkerIsLLD = nullptr) const;
331335

332336
/// Returns the linker path for emitting a static library.
333337
std::string GetStaticLibToolPath() const;

clang/lib/Driver/ToolChain.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,10 @@ std::string ToolChain::GetProgramPath(const char *Name) const {
548548
return D.GetProgramPath(Name, *this);
549549
}
550550

551-
std::string ToolChain::GetLinkerPath() const {
551+
std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const {
552+
if (LinkerIsLLD)
553+
*LinkerIsLLD = false;
554+
552555
// Get -fuse-ld= first to prevent -Wunused-command-line-argument. -fuse-ld= is
553556
// considered as the linker flavor, e.g. "bfd", "gold", or "lld".
554557
const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);
@@ -599,8 +602,12 @@ std::string ToolChain::GetLinkerPath() const {
599602
LinkerName.append(UseLinker);
600603

601604
std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
602-
if (llvm::sys::fs::can_execute(LinkerPath))
605+
if (llvm::sys::fs::can_execute(LinkerPath)) {
606+
if (LinkerIsLLD)
607+
// FIXME: Remove lld.darwinnew here once it's the only MachO lld.
608+
*LinkerIsLLD = UseLinker == "lld" || UseLinker == "lld.darwinnew";
603609
return LinkerPath;
610+
}
604611
}
605612

606613
if (A)

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,15 +204,18 @@ static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) {
204204
void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
205205
ArgStringList &CmdArgs,
206206
const InputInfoList &Inputs,
207-
unsigned Version[5]) const {
207+
unsigned Version[5], bool LinkerIsLLD) const {
208208
const Driver &D = getToolChain().getDriver();
209209
const toolchains::MachO &MachOTC = getMachOToolChain();
210210

211211
// Newer linkers support -demangle. Pass it if supported and not disabled by
212212
// the user.
213-
if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
213+
if ((Version[0] >= 100 || LinkerIsLLD) &&
214+
!Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
214215
CmdArgs.push_back("-demangle");
215216

217+
// FIXME: Pass most of the flags below that check Version if LinkerIsLLD too.
218+
216219
if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137)
217220
CmdArgs.push_back("-export_dynamic");
218221

@@ -533,9 +536,13 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
533536
<< A->getAsString(Args);
534537
}
535538

539+
bool LinkerIsLLD = false;
540+
const char *Exec =
541+
Args.MakeArgString(getToolChain().GetLinkerPath(&LinkerIsLLD));
542+
536543
// I'm not sure why this particular decomposition exists in gcc, but
537544
// we follow suite for ease of comparison.
538-
AddLinkArgs(C, Args, CmdArgs, Inputs, Version);
545+
AddLinkArgs(C, Args, CmdArgs, Inputs, Version, LinkerIsLLD);
539546

540547
if (willEmitRemarks(Args) &&
541548
checkRemarksOptions(getToolChain().getDriver(), Args,
@@ -693,7 +700,6 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
693700
"-filelist"};
694701
}
695702

696-
const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
697703
std::unique_ptr<Command> Cmd = std::make_unique<Command>(
698704
JA, *this, ResponseSupport, Exec, CmdArgs, Inputs, Output);
699705
Cmd->setInputFileList(std::move(InputFileList));

clang/lib/Driver/ToolChains/Darwin.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool {
6363
bool NeedsTempPath(const InputInfoList &Inputs) const;
6464
void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args,
6565
llvm::opt::ArgStringList &CmdArgs,
66-
const InputInfoList &Inputs, unsigned Version[5]) const;
66+
const InputInfoList &Inputs, unsigned Version[5],
67+
bool LinkerIsLLD) const;
6768

6869
public:
6970
Linker(const ToolChain &TC) : MachOTool("darwin::Linker", "linker", TC) {}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// With -fuse-ld=lld, -demangle is always passed to the linker on Darwin.
2+
3+
// RUN: %clang -### -fuse-ld=lld %s 2>&1 | FileCheck %s
4+
// FIXME: Remove ld.darwinnew once it's the default (and only) mach-o lld.
5+
// RUN: %clang -### -fuse-ld=lld.darwinnew %s 2>&1 | FileCheck %s
6+
// CHECK: -demangle

lld/Common/Strings.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ using namespace lld;
2121

2222
// Returns the demangled C++ symbol name for name.
2323
std::string lld::demangleItanium(StringRef name) {
24-
// itaniumDemangle can be used to demangle strings other than symbol
25-
// names which do not necessarily start with "_Z". Name can be
26-
// either a C or C++ symbol. Don't call demangle if the name
27-
// does not look like a C++ symbol name to avoid getting unexpected
28-
// result for a C symbol that happens to match a mangled type name.
29-
if (!name.startswith("_Z"))
24+
// demangleItanium() can be called for all symbols. Only demangle C++ symbols,
25+
// to avoid getting unexpected result for a C symbol that happens to match a
26+
// mangled type name such as "Pi" (which would demangle to "int*").
27+
if (!name.startswith("_Z") && !name.startswith("__Z") &&
28+
!name.startswith("___Z") && !name.startswith("____Z"))
3029
return std::string(name);
3130

3231
return demangle(std::string(name));

lld/MachO/Config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ struct Configuration {
4343
uint32_t headerPad;
4444
llvm::StringRef installName;
4545
llvm::StringRef outputFile;
46+
bool demangle = false;
4647
llvm::MachO::Architecture arch;
4748
PlatformInfo platform;
4849
llvm::MachO::HeaderFileType outputType;

lld/MachO/Driver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,7 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
584584
config->runtimePaths = args::getStrings(args, OPT_rpath);
585585
config->allLoad = args.hasArg(OPT_all_load);
586586
config->forceLoadObjC = args.hasArg(OPT_ObjC);
587+
config->demangle = args.hasArg(OPT_demangle);
587588

588589
if (const opt::Arg *arg = args.getLastArg(OPT_static, OPT_dynamic))
589590
config->staticLink = (arg->getOption().getID() == OPT_static);

lld/MachO/Options.td

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,9 +1107,7 @@ def debug_snapshot : Flag<["-"], "debug_snapshot">,
11071107
Flags<[HelpHidden]>,
11081108
Group<grp_undocumented>;
11091109
def demangle : Flag<["-"], "demangle">,
1110-
HelpText<"This option is undocumented in ld64">,
1111-
Flags<[HelpHidden]>,
1112-
Group<grp_undocumented>;
1110+
HelpText<"Demangle symbol names in diagnostics">;
11131111
def dyld_env : Flag<["-"], "dyld_env">,
11141112
HelpText<"This option is undocumented in ld64">,
11151113
Flags<[HelpHidden]>,

lld/MachO/Symbols.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ void LazySymbol::fetchArchiveMember() { file->fetch(sym); }
3333

3434
// Returns a symbol for an error message.
3535
std::string lld::toString(const Symbol &sym) {
36-
if (Optional<std::string> s = demangleItanium(sym.getName()))
37-
return *s;
36+
if (config->demangle)
37+
return demangleItanium(sym.getName());
3838
return std::string(sym.getName());
3939
}
4040

lld/MachO/Writer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ void Writer::scanRelocations() {
379379
for (Reloc &r : isec->relocs) {
380380
if (auto *s = r.referent.dyn_cast<lld::macho::Symbol *>()) {
381381
if (isa<Undefined>(s))
382-
error("undefined symbol " + s->getName() + ", referenced from " +
382+
error("undefined symbol " + toString(*s) + ", referenced from " +
383383
sys::path::filename(isec->file->getName()));
384384
else
385385
target->prepareSymbolRelocation(s, isec, r);

lld/test/ELF/undef.s

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@
2727
# CHECK-NEXT: >>> {{.*}}:(.text+0x15)
2828
# CHECK-NEXT: >>> the vtable symbol may be undefined because the class is missing its key function (see https://lld.llvm.org/missingkeyfunction)
2929

30-
# Check that this symbol isn't demangled
31-
32-
# CHECK: error: undefined symbol: __Z3fooi
30+
# CHECK: error: undefined symbol: foo(int)
3331
# CHECK-NEXT: >>> referenced by undef.s
3432
# CHECK-NEXT: >>> {{.*}}:(.text+0x1A)
3533

lld/test/MachO/demangle.s

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# REQUIRES: x86
2+
3+
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
4+
5+
# RUN: not %lld %t.o -o /dev/null 2>&1 | FileCheck %s
6+
# RUN: not %lld -demangle %t.o -o /dev/null 2>&1 | \
7+
# RUN: FileCheck --check-prefix=DEMANGLE %s
8+
9+
# CHECK: undefined symbol __Z1fv
10+
# DEMANGLE: undefined symbol f()
11+
12+
.globl _main
13+
_main:
14+
callq __Z1fv
15+
ret

lld/test/MachO/silent-ignore.test

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
RUN: %lld -v \
2-
RUN: -demangle \
32
RUN: -dynamic \
43
RUN: -no_deduplicate \
54
RUN: -lto_library /lib/foo \

lld/tools/lld/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ install(TARGETS lld
2424
RUNTIME DESTINATION bin)
2525

2626
if(NOT LLD_SYMLINKS_TO_CREATE)
27-
set(LLD_SYMLINKS_TO_CREATE lld-link ld.lld ld64.lld wasm-ld)
27+
set(LLD_SYMLINKS_TO_CREATE
28+
lld-link ld.lld ld64.lld ld64.darwinnew.lld wasm-ld)
2829
endif()
2930

3031
foreach(link ${LLD_SYMLINKS_TO_CREATE})

llvm/utils/gn/secondary/lld/tools/lld/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ symlinks = [
44
"lld-link",
55
"ld.lld",
66
"ld64.lld",
7+
"ld64.darwinnew.lld",
78
"wasm-ld",
89
]
910
foreach(target, symlinks) {

0 commit comments

Comments
 (0)