Cleaned up the dynamic library open/getsymbol/close code to use abstracted
flags such that symbols can be searched for within a shared library if desired.
Platforms that support the RTLD_FIRST flag can still take advantage of their
quicker lookups, and other platforms can still get the same fucntionality
with a little extra work.
Also changed LLDB_CONFIG flags over to either being defined, or not being
defined to stay in line with current open source practices and to prepare for
using autoconf or cmake to configure LLDB builds.
llvm-svn: 125064
diff --git a/lldb/source/Commands/CommandCompletions.cpp b/lldb/source/Commands/CommandCompletions.cpp
index 675bd53..fd37266 100644
--- a/lldb/source/Commands/CommandCompletions.cpp
+++ b/lldb/source/Commands/CommandCompletions.cpp
@@ -153,7 +153,7 @@
if (end_ptr == NULL)
{
-#if LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
// There's no directory. If the thing begins with a "~" then this is a bare
// user name.
@@ -207,7 +207,7 @@
return matches.GetSize();
}
else
-#endif // LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#endif // #ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
{
// The containing part is the CWD, and the whole string is the remainder.
@@ -239,7 +239,7 @@
// Look for a user name in the containing part, and if it's there, resolve it and stick the
// result back into the containing_part:
-#if LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
if (*partial_name_copy == '~')
{
size_t resolved_username_len = FileSpec::ResolveUsername(containing_part, containing_part, sizeof (containing_part));
@@ -247,7 +247,7 @@
if (resolved_username_len == 0 || resolved_username_len >= sizeof (containing_part))
return matches.GetSize();
}
-#endif // #if LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#endif // #ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
// Okay, containing_part is now the directory we want to open and look for files:
diff --git a/lldb/source/Core/FileSpec.cpp b/lldb/source/Core/FileSpec.cpp
index de8a15b..f141fe8 100644
--- a/lldb/source/Core/FileSpec.cpp
+++ b/lldb/source/Core/FileSpec.cpp
@@ -16,7 +16,7 @@
#include <fstream>
#include "lldb/Host/Config.h" // Have to include this before we test the define...
-#if LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
#include <pwd.h>
#endif
@@ -44,7 +44,7 @@
return false;
}
-#if LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
static const char*
GetCachedGlobTildeSlash()
@@ -134,7 +134,7 @@
else
return ::snprintf (dst_path, dst_len, "%s%s", home_dir, remainder);
}
-#endif // #if LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#endif // #ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
size_t
FileSpec::Resolve (const char *src_path, char *dst_path, size_t dst_len)
@@ -144,7 +144,7 @@
// Glob if needed for ~/, otherwise copy in case src_path is same as dst_path...
char unglobbed_path[PATH_MAX];
-#if LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
if (src_path[0] == '~')
{
size_t return_count = ResolveUsername(src_path, unglobbed_path, sizeof(unglobbed_path));
@@ -155,7 +155,7 @@
::snprintf (unglobbed_path, sizeof(unglobbed_path), "%s", src_path);
}
else
-#endif // LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#endif // #ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
{
::snprintf(unglobbed_path, sizeof(unglobbed_path), "%s", src_path);
}
diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index 9117754..3f6315d 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp
@@ -95,7 +95,11 @@
else
{
PluginInfo plugin_info = { NULL, NULL, NULL };
- plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, error);
+ uint32_t flags = Host::eDynamicLibraryOpenOptionLazy |
+ Host::eDynamicLibraryOpenOptionLocal |
+ Host::eDynamicLibraryOpenOptionLimitGetSymbol;
+
+ plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, flags, error);
if (plugin_info.plugin_handle)
{
bool success = false;
diff --git a/lldb/source/Core/StreamFile.cpp b/lldb/source/Core/StreamFile.cpp
index f422f8a..9095910 100644
--- a/lldb/source/Core/StreamFile.cpp
+++ b/lldb/source/Core/StreamFile.cpp
@@ -98,10 +98,10 @@
void
StreamFile::SetLineBuffered ()
{
-#if LLDB_CONFIG_SUPPORTS_SETLINEBUFFERED
+#ifdef LLDB_CONFIG_SUPPORTS_SETLINEBUFFERED
if (m_file != NULL)
setlinebuf (m_file);
-#endif // #if LLDB_CONFIG_SUPPORTS_SETLINEBUFFERED
+#endif // #ifdef LLDB_CONFIG_SUPPORTS_SETLINEBUFFERED
}
void
diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp
index 061a31e..9c4b61f 100644
--- a/lldb/source/Host/common/Host.cpp
+++ b/lldb/source/Host/common/Host.cpp
@@ -14,6 +14,7 @@
#include "lldb/Core/FileSpec.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Host/Config.h"
#include "lldb/Host/Endian.h"
#include "lldb/Host/Mutex.h"
@@ -21,12 +22,16 @@
#include <errno.h>
#if defined (__APPLE__)
+
#include <dispatch/dispatch.h>
#include <libproc.h>
#include <mach-o/dyld.h>
#include <sys/sysctl.h>
+
#elif defined (__linux__)
+
#include <sys/wait.h>
+
#endif
using namespace lldb;
@@ -643,21 +648,48 @@
}
#endif
-void *
-Host::DynamicLibraryOpen (const FileSpec &file_spec, Error &error)
+// Opaque info that tracks a dynamic library that was loaded
+struct DynamicLibraryInfo
{
- void *dynamic_library_handle = NULL;
+ DynamicLibraryInfo (const FileSpec &fs, int o, void *h) :
+ file_spec (fs),
+ open_options (o),
+ handle (h)
+ {
+ }
+
+ const FileSpec file_spec;
+ uint32_t open_options;
+ void * handle;
+};
+
+void *
+Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error)
+{
char path[PATH_MAX];
if (file_spec.GetPath(path, sizeof(path)))
{
-#if defined (__linux__)
- dynamic_library_handle = ::dlopen (path, RTLD_LAZY | RTLD_GLOBAL);
-#else
- dynamic_library_handle = ::dlopen (path, RTLD_LAZY | RTLD_GLOBAL | RTLD_FIRST);
+ int mode = 0;
+
+ if (options & eDynamicLibraryOpenOptionLazy)
+ mode |= RTLD_LAZY;
+
+ if (options & eDynamicLibraryOpenOptionLocal)
+ mode |= RTLD_LOCAL;
+ else
+ mode |= RTLD_GLOBAL;
+
+#ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
+ if (options & eDynamicLibraryOpenOptionLimitGetSymbol)
+ mode |= RTLD_FIRST;
#endif
- if (dynamic_library_handle)
+
+ void * opaque = ::dlopen (path, mode);
+
+ if (opaque)
{
error.Clear();
+ return new DynamicLibraryInfo (file_spec, options, opaque);
}
else
{
@@ -668,40 +700,73 @@
{
error.SetErrorString("failed to extract path");
}
-
- return dynamic_library_handle;
+ return NULL;
}
Error
-Host::DynamicLibraryClose (void *dynamic_library_handle)
+Host::DynamicLibraryClose (void *opaque)
{
Error error;
- if (dynamic_library_handle == NULL)
+ if (opaque == NULL)
{
error.SetErrorString ("invalid dynamic library handle");
}
- else if (::dlclose(dynamic_library_handle) != 0)
+ else
{
- error.SetErrorString(::dlerror());
+ DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
+ if (::dlclose (dylib_info->handle) != 0)
+ {
+ error.SetErrorString(::dlerror());
+ }
+
+ dylib_info->open_options = 0;
+ dylib_info->handle = 0;
+ delete dylib_info;
}
return error;
}
void *
-Host::DynamicLibraryGetSymbol (void *dynamic_library_handle, const char *symbol_name, Error &error)
+Host::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error)
{
- if (dynamic_library_handle == NULL)
+ if (opaque == NULL)
{
error.SetErrorString ("invalid dynamic library handle");
- return NULL;
}
-
- void *symbol_addr = ::dlsym (dynamic_library_handle, symbol_name);
- if (symbol_addr == NULL)
- error.SetErrorString(::dlerror());
else
- error.Clear();
- return symbol_addr;
+ {
+ DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
+
+ void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name);
+ if (symbol_addr)
+ {
+#ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
+ // This host doesn't support limiting searches to this shared library
+ // so we need to verify that the match came from this shared library
+ // if it was requested in the Host::DynamicLibraryOpen() function.
+ if (dylib_info->options & eDynamicLibraryOpenOptionLimitGetSymbol)
+ {
+ FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr));
+ if (match_dylib_spec != dylib_info->file_spec)
+ {
+ char dylib_path[PATH_MAX];
+ if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path)))
+ error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path);
+ else
+ error.SetErrorString ("symbol not found");
+ return NULL;
+ }
+ }
+#endif
+ error.Clear();
+ return symbol_addr;
+ }
+ else
+ {
+ error.SetErrorString(::dlerror());
+ }
+ }
+ return NULL;
}
bool
diff --git a/lldb/source/Host/common/Terminal.cpp b/lldb/source/Host/common/Terminal.cpp
index 0511b73..61cedb7 100644
--- a/lldb/source/Host/common/Terminal.cpp
+++ b/lldb/source/Host/common/Terminal.cpp
@@ -14,7 +14,7 @@
#include <unistd.h>
#include <signal.h>
-#if LLDB_CONFIG_TERMIOS_SUPPORTED
+#ifdef LLDB_CONFIG_TERMIOS_SUPPORTED
#include <termios.h>
#endif
@@ -33,7 +33,7 @@
{
if (FileDescriptorIsValid())
{
-#if LLDB_CONFIG_TERMIOS_SUPPORTED
+#ifdef LLDB_CONFIG_TERMIOS_SUPPORTED
if (IsATerminal ())
{
struct termios fd_termios;
@@ -60,7 +60,7 @@
return ::tcsetattr (m_fd, TCSANOW, &fd_termios) == 0;
}
}
-#endif
+#endif // #ifdef LLDB_CONFIG_TERMIOS_SUPPORTED
}
return false;
}
@@ -70,7 +70,7 @@
{
if (FileDescriptorIsValid())
{
-#if LLDB_CONFIG_TERMIOS_SUPPORTED
+#ifdef LLDB_CONFIG_TERMIOS_SUPPORTED
if (IsATerminal ())
{
struct termios fd_termios;
@@ -97,7 +97,7 @@
return ::tcsetattr (m_fd, TCSANOW, &fd_termios) == 0;
}
}
-#endif
+#endif // #ifdef LLDB_CONFIG_TERMIOS_SUPPORTED
}
return false;
}
@@ -132,13 +132,13 @@
if (m_tty.IsATerminal())
{
m_tflags = ::fcntl (fd, F_GETFL, 0);
-#if LLDB_CONFIG_TERMIOS_SUPPORTED
+#ifdef LLDB_CONFIG_TERMIOS_SUPPORTED
if (m_termios_ap.get() == NULL)
m_termios_ap.reset (new struct termios);
int err = ::tcgetattr (fd, m_termios_ap.get());
if (err != 0)
m_termios_ap.reset();
-#endif // #if LLDB_CONFIG_TERMIOS_SUPPORTED
+#endif // #ifdef LLDB_CONFIG_TERMIOS_SUPPORTED
if (save_process_group)
m_process_group = ::tcgetpgrp (0);
else
@@ -168,10 +168,10 @@
if (TFlagsIsValid())
result = fcntl (fd, F_SETFL, m_tflags);
-#if LLDB_CONFIG_TERMIOS_SUPPORTED
+#ifdef LLDB_CONFIG_TERMIOS_SUPPORTED
if (TTYStateIsValid())
result = tcsetattr (fd, TCSANOW, m_termios_ap.get());
-#endif // #if LLDB_CONFIG_TERMIOS_SUPPORTED
+#endif // #ifdef LLDB_CONFIG_TERMIOS_SUPPORTED
if (ProcessGroupIsValid())
{