Skip to content

Commit 91f8aac

Browse files
committed
[Android] Use -l:libunwind.a with --rtlib=compiler-rt
On Android, the unwinder isn't part of the C++ STL and isn't (in older versions) exported from libc.so. Instead, the driver links the static unwinder archive implicitly. Currently, the Android NDK implicitly links libgcc.a to provide both builtins and the unwinder. To support switching to compiler-rt builtins and libunwind, make --rtlib=compiler-rt behave the same way on Android, and implicitly pass -l:libunwind.a to the linker. Adjust the -ldl logic. For the Android NDK, the unwinder (whether libgcc.a or libunwind.a) is linked statically and calls a function in the dynamic loader for finding unwind tables (e.g. dl_iterate_phdr). On Android, this function is in libc.a for static executables and libdl.so otherwise, so -ldl is needed. (glibc doesn't need -ldl because its libc.so exports dl_iterate_phdr.) Differential Revision: https://reviews.llvm.org/D96403
1 parent c88fede commit 91f8aac

File tree

2 files changed

+25
-17
lines changed

2 files changed

+25
-17
lines changed

clang/lib/Driver/ToolChain.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -929,9 +929,12 @@ ToolChain::UnwindLibType ToolChain::GetUnwindLibType(
929929
unwindLibType = ToolChain::UNW_None;
930930
else if (LibName == "platform" || LibName == "") {
931931
ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args);
932-
if (RtLibType == ToolChain::RLT_CompilerRT)
933-
unwindLibType = ToolChain::UNW_None;
934-
else if (RtLibType == ToolChain::RLT_Libgcc)
932+
if (RtLibType == ToolChain::RLT_CompilerRT) {
933+
if (getTriple().isAndroid())
934+
unwindLibType = ToolChain::UNW_CompilerRT;
935+
else
936+
unwindLibType = ToolChain::UNW_None;
937+
} else if (RtLibType == ToolChain::RLT_Libgcc)
935938
unwindLibType = ToolChain::UNW_Libgcc;
936939
} else if (LibName == "libunwind") {
937940
if (GetRuntimeLibType(Args) == RLT_Libgcc)

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,11 +1366,17 @@ bool tools::isObjCAutoRefCount(const ArgList &Args) {
13661366

13671367
enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc };
13681368

1369-
static LibGccType getLibGccType(const Driver &D, const ArgList &Args) {
1369+
static LibGccType getLibGccType(const ToolChain &TC, const Driver &D,
1370+
const ArgList &Args) {
13701371
if (Args.hasArg(options::OPT_static_libgcc) ||
13711372
Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_static_pie))
13721373
return LibGccType::StaticLibGcc;
1373-
if (Args.hasArg(options::OPT_shared_libgcc) || D.CCCIsCXX())
1374+
if (Args.hasArg(options::OPT_shared_libgcc))
1375+
return LibGccType::SharedLibGcc;
1376+
// The Android NDK only provides libunwind.a, not libunwind.so.
1377+
if (TC.getTriple().isAndroid())
1378+
return LibGccType::StaticLibGcc;
1379+
if (D.CCCIsCXX())
13741380
return LibGccType::SharedLibGcc;
13751381
return LibGccType::UnspecifiedLibGcc;
13761382
}
@@ -1392,12 +1398,12 @@ static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
13921398
ArgStringList &CmdArgs, const ArgList &Args) {
13931399
ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args);
13941400
// Targets that don't use unwind libraries.
1395-
if (TC.getTriple().isAndroid() || TC.getTriple().isOSIAMCU() ||
1396-
TC.getTriple().isOSBinFormatWasm() ||
1401+
if ((TC.getTriple().isAndroid() && UNW == ToolChain::UNW_Libgcc) ||
1402+
TC.getTriple().isOSIAMCU() || TC.getTriple().isOSBinFormatWasm() ||
13971403
UNW == ToolChain::UNW_None)
13981404
return;
13991405

1400-
LibGccType LGT = getLibGccType(D, Args);
1406+
LibGccType LGT = getLibGccType(TC, D, Args);
14011407
bool AsNeeded = LGT == LibGccType::UnspecifiedLibGcc &&
14021408
!TC.getTriple().isAndroid() && !TC.getTriple().isOSCygMing();
14031409
if (AsNeeded)
@@ -1434,20 +1440,12 @@ static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
14341440

14351441
static void AddLibgcc(const ToolChain &TC, const Driver &D,
14361442
ArgStringList &CmdArgs, const ArgList &Args) {
1437-
LibGccType LGT = getLibGccType(D, Args);
1443+
LibGccType LGT = getLibGccType(TC, D, Args);
14381444
if (LGT != LibGccType::SharedLibGcc)
14391445
CmdArgs.push_back("-lgcc");
14401446
AddUnwindLibrary(TC, D, CmdArgs, Args);
14411447
if (LGT == LibGccType::SharedLibGcc)
14421448
CmdArgs.push_back("-lgcc");
1443-
1444-
// According to Android ABI, we have to link with libdl if we are
1445-
// linking with non-static libgcc.
1446-
//
1447-
// NOTE: This fixes a link error on Android MIPS as well. The non-static
1448-
// libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
1449-
if (TC.getTriple().isAndroid() && LGT != LibGccType::StaticLibGcc)
1450-
CmdArgs.push_back("-ldl");
14511449
}
14521450

14531451
void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
@@ -1473,6 +1471,13 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
14731471
AddLibgcc(TC, D, CmdArgs, Args);
14741472
break;
14751473
}
1474+
1475+
// On Android, the unwinder uses dl_iterate_phdr (or one of
1476+
// dl_unwind_find_exidx/__gnu_Unwind_Find_exidx on arm32) from libdl.so. For
1477+
// statically-linked executables, these functions come from libc.a instead.
1478+
if (TC.getTriple().isAndroid() && !Args.hasArg(options::OPT_static) &&
1479+
!Args.hasArg(options::OPT_static_pie))
1480+
CmdArgs.push_back("-ldl");
14761481
}
14771482

14781483
SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args,

0 commit comments

Comments
 (0)