aykevl created this revision.
aykevl added reviewers: MaskRay, rsmith.
Herald added subscribers: StephenFan, arphaman.
Herald added a project: All.
aykevl requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
musl-libc doesn't support dladdr in statically linked binaries:
> Are you using static or dynamic linking? If static, dladdr is just a
> stub that always fails. It could be implemented to work under some
> conditions, but it would be highly dependent on what options you
> compile the binary with, since by default static binaries do not
> contain the bloat that would be needed to perform introspection.
Source: https://www.openwall.com/lists/musl/2013/01/15/25 (in response to a bug
report).
Libclang unfortunately uses dladdr to find the ResourcesPath so will fail if it
is linked statically on Alpine Linux. This patch fixes this issue by falling
back to getMainExecutable if dladdr returns an error.
Reference:
https://github.com/llvm/llvm-project/issues/40641#issuecomment-981011427
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D124815
Files:
clang/tools/libclang/CIndexer.cpp
Index: clang/tools/libclang/CIndexer.cpp
===================================================================
--- clang/tools/libclang/CIndexer.cpp
+++ clang/tools/libclang/CIndexer.cpp
@@ -125,13 +125,23 @@
#elif defined(_AIX)
getClangResourcesPathImplAIX(LibClangPath);
#else
- // This silly cast below avoids a C++ warning.
Dl_info info;
- if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
- llvm_unreachable("Call to dladdr() failed");
+ std::string Path;
+ // This silly cast below avoids a C++ warning.
+ if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) != 0) {
+ // We now have the CIndex directory, locate clang relative to it.
+ LibClangPath += info.dli_fname;
+ } else if (!(Path = llvm::sys::fs::getMainExecutable(nullptr,
nullptr)).empty()) {
+ // If we can't get the path using dladdr, try to get the main executable
+ // path. This may be needed when we're statically linking libclang with
+ // musl libc, for example.
+ LibClangPath += Path;
+ } else {
+ // It's rather unlikely we end up here. But it could happen, so report an
+ // error instead of crashing.
+ llvm::report_fatal_error("Could not locate Clang resource path");
+ }
- // We now have the CIndex directory, locate clang relative to it.
- LibClangPath += info.dli_fname;
#endif
// Cache our result.
Index: clang/tools/libclang/CIndexer.cpp
===================================================================
--- clang/tools/libclang/CIndexer.cpp
+++ clang/tools/libclang/CIndexer.cpp
@@ -125,13 +125,23 @@
#elif defined(_AIX)
getClangResourcesPathImplAIX(LibClangPath);
#else
- // This silly cast below avoids a C++ warning.
Dl_info info;
- if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
- llvm_unreachable("Call to dladdr() failed");
+ std::string Path;
+ // This silly cast below avoids a C++ warning.
+ if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) != 0) {
+ // We now have the CIndex directory, locate clang relative to it.
+ LibClangPath += info.dli_fname;
+ } else if (!(Path = llvm::sys::fs::getMainExecutable(nullptr, nullptr)).empty()) {
+ // If we can't get the path using dladdr, try to get the main executable
+ // path. This may be needed when we're statically linking libclang with
+ // musl libc, for example.
+ LibClangPath += Path;
+ } else {
+ // It's rather unlikely we end up here. But it could happen, so report an
+ // error instead of crashing.
+ llvm::report_fatal_error("Could not locate Clang resource path");
+ }
- // We now have the CIndex directory, locate clang relative to it.
- LibClangPath += info.dli_fname;
#endif
// Cache our result.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits