diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/Commands/CommandCompletions.cpp | 8 | ||||
-rw-r--r-- | lldb/source/Core/FileSpec.cpp | 10 | ||||
-rw-r--r-- | lldb/source/Core/PluginManager.cpp | 6 | ||||
-rw-r--r-- | lldb/source/Core/StreamFile.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Host/common/Host.cpp | 109 | ||||
-rw-r--r-- | lldb/source/Host/common/Terminal.cpp | 18 |
6 files changed, 112 insertions, 43 deletions
diff --git a/lldb/source/Commands/CommandCompletions.cpp b/lldb/source/Commands/CommandCompletions.cpp index 675bd53f275..fd372661d99 100644 --- a/lldb/source/Commands/CommandCompletions.cpp +++ b/lldb/source/Commands/CommandCompletions.cpp @@ -153,7 +153,7 @@ DiskFilesOrDirectories 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 @@ DiskFilesOrDirectories 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 @@ DiskFilesOrDirectories // 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 @@ DiskFilesOrDirectories 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 de8a15be5bb..f141fe839b3 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 @@ GetFileStats (const FileSpec *file_spec, struct stat *stats_ptr) return false; } -#if LLDB_CONFIG_TILDE_RESOLVES_TO_USER +#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER static const char* GetCachedGlobTildeSlash() @@ -134,7 +134,7 @@ FileSpec::ResolveUsername (const char *src_path, char *dst_path, size_t dst_len) 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 @@ FileSpec::Resolve (const char *src_path, char *dst_path, size_t dst_len) // 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 @@ FileSpec::Resolve (const char *src_path, char *dst_path, size_t dst_len) ::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 9117754fa2f..3f6315d420b 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -95,7 +95,11 @@ LoadPluginCallback 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 f422f8ad04c..90959105494 100644 --- a/lldb/source/Core/StreamFile.cpp +++ b/lldb/source/Core/StreamFile.cpp @@ -98,10 +98,10 @@ StreamFile::Open (const char *path, const char *permissions) 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 061a31eef59..9c4b61fcc04 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 @@ Host::ResolveExecutableInBundle (FileSpec &file) } #endif +// Opaque info that tracks a dynamic library that was loaded +struct DynamicLibraryInfo +{ + 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, Error &error) +Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error) { - void *dynamic_library_handle = NULL; 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 @@ Host::DynamicLibraryOpen (const FileSpec &file_spec, Error &error) { 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 0511b73586b..61cedb7b298 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 @@ Terminal::SetEcho (bool enabled) { if (FileDescriptorIsValid()) { -#if LLDB_CONFIG_TERMIOS_SUPPORTED +#ifdef LLDB_CONFIG_TERMIOS_SUPPORTED if (IsATerminal ()) { struct termios fd_termios; @@ -60,7 +60,7 @@ Terminal::SetEcho (bool enabled) return ::tcsetattr (m_fd, TCSANOW, &fd_termios) == 0; } } -#endif +#endif // #ifdef LLDB_CONFIG_TERMIOS_SUPPORTED } return false; } @@ -70,7 +70,7 @@ Terminal::SetCanonical (bool enabled) { if (FileDescriptorIsValid()) { -#if LLDB_CONFIG_TERMIOS_SUPPORTED +#ifdef LLDB_CONFIG_TERMIOS_SUPPORTED if (IsATerminal ()) { struct termios fd_termios; @@ -97,7 +97,7 @@ Terminal::SetCanonical (bool enabled) return ::tcsetattr (m_fd, TCSANOW, &fd_termios) == 0; } } -#endif +#endif // #ifdef LLDB_CONFIG_TERMIOS_SUPPORTED } return false; } @@ -132,13 +132,13 @@ TerminalState::Save (int fd, bool save_process_group) 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 @@ TerminalState::Restore () const 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()) { |