r356843 - libclang/CIndexer.cpp: Use loadquery() on AIX for path to library
Hubert Tong via cfe-commits
cfe-commits at lists.llvm.org
Sat Mar 23 11:10:45 PDT 2019
Author: hubert.reinterpretcast
Date: Sat Mar 23 11:10:45 2019
New Revision: 356843
URL: http://llvm.org/viewvc/llvm-project?rev=356843&view=rev
Log:
libclang/CIndexer.cpp: Use loadquery() on AIX for path to library
Summary:
`dladdr` is not available on AIX. Similar functionality is presented
through `loadquery`. This patch replaces a use of `dladdr` with a
version based on `loadquery`.
Reviewers: sfertile, xingxue, jasonliu
Reviewed By: xingxue
Subscribers: jsji, lhames, majnemer, asb, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59233
Modified:
cfe/trunk/tools/libclang/CIndexer.cpp
Modified: cfe/trunk/tools/libclang/CIndexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexer.cpp?rev=356843&r1=356842&r2=356843&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexer.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexer.cpp Sat Mar 23 11:10:45 2019
@@ -32,12 +32,69 @@
#ifdef _WIN32
#include <windows.h>
+#elif defined(_AIX)
+#include <errno.h>
+#include <sys/ldr.h>
#else
#include <dlfcn.h>
#endif
using namespace clang;
+#ifdef _AIX
+namespace clang {
+namespace {
+
+template <typename LibClangPathType>
+void getClangResourcesPathImplAIX(LibClangPathType &LibClangPath) {
+ int PrevErrno = errno;
+
+ size_t BufSize = 2048u;
+ std::unique_ptr<char[]> Buf;
+ while (true) {
+ Buf = llvm::make_unique<char []>(BufSize);
+ errno = 0;
+ int Ret = loadquery(L_GETXINFO, Buf.get(), (unsigned int)BufSize);
+ if (Ret != -1)
+ break; // loadquery() was successful.
+ if (errno != ENOMEM)
+ llvm_unreachable("Encountered an unexpected loadquery() failure");
+
+ // errno == ENOMEM; try to allocate more memory.
+ if ((BufSize & ~((-1u) >> 1u)) != 0u)
+ llvm::report_fatal_error("BufSize needed for loadquery() too large");
+
+ Buf.release();
+ BufSize <<= 1u;
+ }
+
+ // Extract the function entry point from the function descriptor.
+ uint64_t EntryAddr =
+ reinterpret_cast<uintptr_t &>(clang_createTranslationUnit);
+
+ // Loop to locate the function entry point in the loadquery() results.
+ ld_xinfo *CurInfo = reinterpret_cast<ld_xinfo *>(Buf.get());
+ while (true) {
+ uint64_t CurTextStart = (uint64_t)CurInfo->ldinfo_textorg;
+ uint64_t CurTextEnd = CurTextStart + CurInfo->ldinfo_textsize;
+ if (CurTextStart <= EntryAddr && EntryAddr < CurTextEnd)
+ break; // Successfully located.
+
+ if (CurInfo->ldinfo_next == 0u)
+ llvm::report_fatal_error("Cannot locate entry point in "
+ "the loadquery() results");
+ CurInfo = reinterpret_cast<ld_xinfo *>(reinterpret_cast<char *>(CurInfo) +
+ CurInfo->ldinfo_next);
+ }
+
+ LibClangPath += reinterpret_cast<char *>(CurInfo) + CurInfo->ldinfo_filename;
+ errno = PrevErrno;
+}
+
+} // end anonymous namespace
+} // end namespace clang
+#endif
+
const std::string &CIndexer::getClangResourcesPath() {
// Did we already compute the path?
if (!ResourcesPath.empty())
@@ -64,6 +121,8 @@ const std::string &CIndexer::getClangRes
#endif
LibClangPath += path;
+#elif defined(_AIX)
+ getClangResourcesPathImplAIX(LibClangPath);
#else
// This silly cast below avoids a C++ warning.
Dl_info info;
More information about the cfe-commits
mailing list