forked from OSchip/llvm-project
[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
This commit is contained in:
parent
c88fedef2a
commit
91f8aacc04
|
@ -929,9 +929,12 @@ ToolChain::UnwindLibType ToolChain::GetUnwindLibType(
|
|||
unwindLibType = ToolChain::UNW_None;
|
||||
else if (LibName == "platform" || LibName == "") {
|
||||
ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args);
|
||||
if (RtLibType == ToolChain::RLT_CompilerRT)
|
||||
unwindLibType = ToolChain::UNW_None;
|
||||
else if (RtLibType == ToolChain::RLT_Libgcc)
|
||||
if (RtLibType == ToolChain::RLT_CompilerRT) {
|
||||
if (getTriple().isAndroid())
|
||||
unwindLibType = ToolChain::UNW_CompilerRT;
|
||||
else
|
||||
unwindLibType = ToolChain::UNW_None;
|
||||
} else if (RtLibType == ToolChain::RLT_Libgcc)
|
||||
unwindLibType = ToolChain::UNW_Libgcc;
|
||||
} else if (LibName == "libunwind") {
|
||||
if (GetRuntimeLibType(Args) == RLT_Libgcc)
|
||||
|
|
|
@ -1366,11 +1366,17 @@ bool tools::isObjCAutoRefCount(const ArgList &Args) {
|
|||
|
||||
enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc };
|
||||
|
||||
static LibGccType getLibGccType(const Driver &D, const ArgList &Args) {
|
||||
static LibGccType getLibGccType(const ToolChain &TC, const Driver &D,
|
||||
const ArgList &Args) {
|
||||
if (Args.hasArg(options::OPT_static_libgcc) ||
|
||||
Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_static_pie))
|
||||
return LibGccType::StaticLibGcc;
|
||||
if (Args.hasArg(options::OPT_shared_libgcc) || D.CCCIsCXX())
|
||||
if (Args.hasArg(options::OPT_shared_libgcc))
|
||||
return LibGccType::SharedLibGcc;
|
||||
// The Android NDK only provides libunwind.a, not libunwind.so.
|
||||
if (TC.getTriple().isAndroid())
|
||||
return LibGccType::StaticLibGcc;
|
||||
if (D.CCCIsCXX())
|
||||
return LibGccType::SharedLibGcc;
|
||||
return LibGccType::UnspecifiedLibGcc;
|
||||
}
|
||||
|
@ -1392,12 +1398,12 @@ static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
|
|||
ArgStringList &CmdArgs, const ArgList &Args) {
|
||||
ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args);
|
||||
// Targets that don't use unwind libraries.
|
||||
if (TC.getTriple().isAndroid() || TC.getTriple().isOSIAMCU() ||
|
||||
TC.getTriple().isOSBinFormatWasm() ||
|
||||
if ((TC.getTriple().isAndroid() && UNW == ToolChain::UNW_Libgcc) ||
|
||||
TC.getTriple().isOSIAMCU() || TC.getTriple().isOSBinFormatWasm() ||
|
||||
UNW == ToolChain::UNW_None)
|
||||
return;
|
||||
|
||||
LibGccType LGT = getLibGccType(D, Args);
|
||||
LibGccType LGT = getLibGccType(TC, D, Args);
|
||||
bool AsNeeded = LGT == LibGccType::UnspecifiedLibGcc &&
|
||||
!TC.getTriple().isAndroid() && !TC.getTriple().isOSCygMing();
|
||||
if (AsNeeded)
|
||||
|
@ -1434,20 +1440,12 @@ static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
|
|||
|
||||
static void AddLibgcc(const ToolChain &TC, const Driver &D,
|
||||
ArgStringList &CmdArgs, const ArgList &Args) {
|
||||
LibGccType LGT = getLibGccType(D, Args);
|
||||
LibGccType LGT = getLibGccType(TC, D, Args);
|
||||
if (LGT != LibGccType::SharedLibGcc)
|
||||
CmdArgs.push_back("-lgcc");
|
||||
AddUnwindLibrary(TC, D, CmdArgs, Args);
|
||||
if (LGT == LibGccType::SharedLibGcc)
|
||||
CmdArgs.push_back("-lgcc");
|
||||
|
||||
// According to Android ABI, we have to link with libdl if we are
|
||||
// linking with non-static libgcc.
|
||||
//
|
||||
// NOTE: This fixes a link error on Android MIPS as well. The non-static
|
||||
// libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
|
||||
if (TC.getTriple().isAndroid() && LGT != LibGccType::StaticLibGcc)
|
||||
CmdArgs.push_back("-ldl");
|
||||
}
|
||||
|
||||
void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
|
||||
|
@ -1473,6 +1471,13 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
|
|||
AddLibgcc(TC, D, CmdArgs, Args);
|
||||
break;
|
||||
}
|
||||
|
||||
// On Android, the unwinder uses dl_iterate_phdr (or one of
|
||||
// dl_unwind_find_exidx/__gnu_Unwind_Find_exidx on arm32) from libdl.so. For
|
||||
// statically-linked executables, these functions come from libc.a instead.
|
||||
if (TC.getTriple().isAndroid() && !Args.hasArg(options::OPT_static) &&
|
||||
!Args.hasArg(options::OPT_static_pie))
|
||||
CmdArgs.push_back("-ldl");
|
||||
}
|
||||
|
||||
SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args,
|
||||
|
|
Loading…
Reference in New Issue