Move Host::GetLLDBPath to HostInfo.

This continues the effort to get Host code moved over to HostInfo,
and removes many more instances of preprocessor defines along the
way.

llvm-svn: 216195
This commit is contained in:
Zachary Turner 2014-08-21 17:29:12 +00:00
parent 4262828132
commit 42ff0ad882
21 changed files with 495 additions and 398 deletions

View File

@ -340,28 +340,6 @@ public:
static bool
ResolveExecutableInBundle (FileSpec &file);
//------------------------------------------------------------------
/// Find a resource files that are related to LLDB.
///
/// Operating systems have different ways of storing shared
/// libraries and related resources. This function abstracts the
/// access to these paths.
///
/// @param[in] path_type
/// The type of LLDB resource path you are looking for. If the
/// enumeration ends with "Dir", then only the \a file_spec's
/// directory member gets filled in.
///
/// @param[in] file_spec
/// A file spec that gets filled in with the appropriate path.
///
/// @return
/// \b true if \a resource_path was resolved, \a false otherwise.
//------------------------------------------------------------------
static bool
GetLLDBPath (lldb::PathType path_type,
FileSpec &file_spec);
//------------------------------------------------------------------
/// Set a string that can be displayed if host application crashes.
///

View File

@ -11,6 +11,8 @@
#define lldb_Host_HostInfoBase_h_
#include "lldb/Core/ArchSpec.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/lldb-enumerations.h"
#include "llvm/ADT/StringRef.h"
@ -21,6 +23,8 @@
namespace lldb_private
{
class FileSpec;
class HostInfoBase
{
private:
@ -78,7 +82,34 @@ class HostInfoBase
static const ArchSpec &GetArchitecture(ArchitectureKind arch_kind = eArchKindDefault);
//------------------------------------------------------------------
/// Find a resource files that are related to LLDB.
///
/// Operating systems have different ways of storing shared
/// libraries and related resources. This function abstracts the
/// access to these paths.
///
/// @param[in] path_type
/// The type of LLDB resource path you are looking for. If the
/// enumeration ends with "Dir", then only the \a file_spec's
/// directory member gets filled in.
///
/// @param[in] file_spec
/// A file spec that gets filled in with the appropriate path.
///
/// @return
/// \b true if \a resource_path was resolved, \a false otherwise.
//------------------------------------------------------------------
static bool GetLLDBPath(lldb::PathType type, FileSpec &file_spec);
protected:
static bool ComputeSharedLibraryDirectory(FileSpec &file_spec);
static bool ComputeSupportExeDirectory(FileSpec &file_spec);
static bool ComputeTempFileDirectory(FileSpec &file_spec);
static bool ComputeHeaderDirectory(FileSpec &file_spec);
static bool ComputeSystemPluginsDirectory(FileSpec &file_spec);
static bool ComputeUserPluginsDirectory(FileSpec &file_spec);
static void ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64);
static uint32_t m_number_cpus;
@ -88,6 +119,14 @@ class HostInfoBase
static ArchSpec m_host_arch_32;
static ArchSpec m_host_arch_64;
static FileSpec m_lldb_so_dir;
static FileSpec m_lldb_support_exe_dir;
static FileSpec m_lldb_headers_dir;
static FileSpec m_lldb_python_dir;
static FileSpec m_lldb_system_plugin_dir;
static FileSpec m_lldb_user_plugin_dir;
static FileSpec m_lldb_tmp_dir;
};
}

View File

@ -32,6 +32,8 @@ class HostInfoLinux : public HostInfoPosix
static llvm::StringRef GetDistributionId();
protected:
static bool ComputeSystemPluginsDirectory(FileSpec &file_spec);
static bool ComputeUserPluginsDirectory(FileSpec &file_spec);
static void ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64);
static std::string m_distribution_id;

View File

@ -32,7 +32,12 @@ class HostInfoMacOSX : public HostInfoPosix
static bool GetOSKernelDescription(std::string &s);
protected:
static bool ComputeSupportExeDirectory(FileSpec &file_spec);
static void ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64);
static bool ComputeHeaderDirectory(FileSpec &file_spec);
static bool ComputePythonDirectory(FileSpec &file_spec);
static bool ComputeSystemPluginsDirectory(FileSpec &file_spec);
static bool ComputeUserPluginsDirectory(FileSpec &file_spec);
};
}

View File

@ -17,9 +17,16 @@ namespace lldb_private
class HostInfoPosix : public HostInfoBase
{
friend class HostInfoBase;
public:
static size_t GetPageSize();
static bool GetHostname(std::string &s);
protected:
static bool ComputeSupportExeDirectory(FileSpec &file_spec);
static bool ComputeHeaderDirectory(FileSpec &file_spec);
static bool ComputePythonDirectory(FileSpec &file_spec);
};
}

View File

@ -17,6 +17,8 @@ namespace lldb_private
class HostInfoWindows : public HostInfoBase
{
friend class HostInfoBase;
private:
// Static class, unconstructable.
HostInfoWindows();
@ -29,6 +31,9 @@ class HostInfoWindows : public HostInfoBase
static bool GetOSBuildString(std::string &s);
static bool GetOSKernelDescription(std::string &s);
static bool GetHostname(std::string &s);
protected:
static bool ComputePythonDirectory(FileSpec &file_spec);
};
}

View File

@ -12,6 +12,7 @@
#include "lldb/Host/FileSpec.h"
#include "lldb/Core/Log.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
using namespace lldb;
using namespace lldb_private;
@ -31,7 +32,7 @@ SBHostOS::GetLLDBPythonPath ()
{
SBFileSpec sb_lldb_python_filespec;
FileSpec lldb_python_spec;
if (Host::GetLLDBPath (ePathTypePythonDir, lldb_python_spec))
if (HostInfo::GetLLDBPath(ePathTypePythonDir, lldb_python_spec))
{
sb_lldb_python_filespec.SetFileSpec (lldb_python_spec);
}
@ -44,7 +45,7 @@ SBHostOS::GetLLDBPath (lldb::PathType path_type)
{
SBFileSpec sb_fspec;
FileSpec fspec;
if (Host::GetLLDBPath (path_type, fspec))
if (HostInfo::GetLLDBPath(path_type, fspec))
sb_fspec.SetFileSpec (fspec);
return sb_fspec;
}

View File

@ -35,6 +35,7 @@
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/Host/DynamicLibrary.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Terminal.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionValueSInt64.h"
@ -492,7 +493,7 @@ Debugger::InstanceInitialize ()
const bool find_files = true;
const bool find_other = true;
char dir_path[PATH_MAX];
if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
{
if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
{
@ -504,8 +505,8 @@ Debugger::InstanceInitialize ()
this);
}
}
if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
{
if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
{

View File

@ -20,6 +20,7 @@
#include "lldb/Core/Error.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Interpreter/OptionValueProperties.h"
@ -185,7 +186,7 @@ PluginManager::Initialize ()
const bool find_files = true;
const bool find_other = true;
char dir_path[PATH_MAX];
if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
{
if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
{
@ -198,7 +199,7 @@ PluginManager::Initialize ()
}
}
if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
{
if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
{

View File

@ -26,6 +26,7 @@
#include "lldb/Expression/IRDynamicChecks.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Host/File.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
@ -309,7 +310,7 @@ ClangExpressionParser::Parse (Stream &stream)
std::string temp_source_path;
FileSpec tmpdir_file_spec;
if (Host::GetLLDBPath (lldb::ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
{
tmpdir_file_spec.GetFilename().SetCString("expr.XXXXXX");
temp_source_path = std::move(tmpdir_file_spec.GetPath());

View File

@ -865,346 +865,6 @@ Host::GetModuleFileSpecForHostAddress (const void *host_addr)
#endif
static void CleanupProcessSpecificLLDBTempDir ()
{
// Get the process specific LLDB temporary directory and delete it.
FileSpec tmpdir_file_spec;
if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
{
// Remove the LLDB temporary directory if we have one. Set "recurse" to
// true to all files that were created for the LLDB process can be cleaned up.
const bool recurse = true;
FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), recurse);
}
}
bool
Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
{
// To get paths related to LLDB we get the path to the executable that
// contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
// on linux this is assumed to be the "lldb" main executable. If LLDB on
// linux is actually in a shared library (liblldb.so) then this function will
// need to be modified to "do the right thing".
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST);
switch (path_type)
{
case ePathTypeLLDBShlibDir:
{
static ConstString g_lldb_so_dir;
if (!g_lldb_so_dir)
{
FileSpec lldb_file_spec(Host::GetModuleFileSpecForHostAddress(
reinterpret_cast<void *>(reinterpret_cast<intptr_t>(Host::GetLLDBPath))));
g_lldb_so_dir = lldb_file_spec.GetDirectory();
if (log)
log->Printf("Host::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_lldb_so_dir.GetCString());
}
file_spec.GetDirectory() = g_lldb_so_dir;
return (bool)file_spec.GetDirectory();
}
break;
case ePathTypeSupportExecutableDir:
{
static ConstString g_lldb_support_exe_dir;
if (!g_lldb_support_exe_dir)
{
FileSpec lldb_file_spec;
if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
{
char raw_path[PATH_MAX];
lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
#if defined (__APPLE__)
char *framework_pos = ::strstr (raw_path, "LLDB.framework");
if (framework_pos)
{
framework_pos += strlen("LLDB.framework");
#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
// Shallow bundle
*framework_pos = '\0';
#else
// Normal bundle
::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path));
#endif
}
#elif defined (__linux__) || defined (__FreeBSD__) || defined (__NetBSD__)
// Linux/*BSD will attempt to replace a */lib with */bin as the base directory for
// helper exe programs. This will fail if the /lib and /bin directories are rooted in entirely
// different trees.
if (log)
log->Printf ("Host::%s() attempting to derive the bin path (ePathTypeSupportExecutableDir) from this path: %s", __FUNCTION__, raw_path);
char *lib_pos = ::strstr (raw_path, "/lib");
if (lib_pos != nullptr)
{
// First terminate the raw path at the start of lib.
*lib_pos = '\0';
// Now write in bin in place of lib.
::strncpy (lib_pos, "/bin", PATH_MAX - (lib_pos - raw_path));
if (log)
log->Printf ("Host::%s() derived the bin path as: %s", __FUNCTION__, raw_path);
}
else
{
if (log)
log->Printf ("Host::%s() failed to find /lib/liblldb within the shared lib path, bailing on bin path construction", __FUNCTION__);
}
#endif // #if defined (__APPLE__)
llvm::SmallString<64> resolved_path(raw_path);
FileSpec::Resolve (resolved_path);
g_lldb_support_exe_dir.SetCString(resolved_path.c_str());
}
if (log)
log->Printf("Host::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", g_lldb_support_exe_dir.GetCString());
}
file_spec.GetDirectory() = g_lldb_support_exe_dir;
return (bool)file_spec.GetDirectory();
}
break;
case ePathTypeHeaderDir:
{
static ConstString g_lldb_headers_dir;
if (!g_lldb_headers_dir)
{
#if defined (__APPLE__)
FileSpec lldb_file_spec;
if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
{
char raw_path[PATH_MAX];
lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
char *framework_pos = ::strstr (raw_path, "LLDB.framework");
if (framework_pos)
{
framework_pos += strlen("LLDB.framework");
::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path));
}
llvm::SmallString<64> resolved_path(raw_path);
FileSpec::Resolve (resolved_path);
g_lldb_headers_dir.SetCString(resolved_path.c_str());
}
#else
// TODO: Anyone know how we can determine this for linux? Other systems??
g_lldb_headers_dir.SetCString ("/opt/local/include/lldb");
#endif
if (log)
log->Printf("Host::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_lldb_headers_dir.GetCString());
}
file_spec.GetDirectory() = g_lldb_headers_dir;
return (bool)file_spec.GetDirectory();
}
break;
#ifdef LLDB_DISABLE_PYTHON
case ePathTypePythonDir:
return false;
#else
case ePathTypePythonDir:
{
static ConstString g_lldb_python_dir;
if (!g_lldb_python_dir)
{
FileSpec lldb_file_spec;
if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
{
char raw_path[PATH_MAX];
#if defined(_WIN32)
lldb_file_spec.AppendPathComponent("../lib/site-packages");
lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
#else
lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
#if defined (__APPLE__)
char *framework_pos = ::strstr (raw_path, "LLDB.framework");
if (framework_pos)
{
framework_pos += strlen("LLDB.framework");
::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path));
}
else
{
#endif
llvm::SmallString<256> python_version_dir;
llvm::raw_svector_ostream os(python_version_dir);
os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages";
os.flush();
// We may get our string truncated. Should we protect
// this with an assert?
::strncat(raw_path, python_version_dir.c_str(),
sizeof(raw_path) - strlen(raw_path) - 1);
#endif
#if defined (__APPLE__)
}
#endif
llvm::SmallString<64> resolved_path(raw_path);
FileSpec::Resolve (resolved_path);
g_lldb_python_dir.SetCString(resolved_path.c_str());
}
if (log)
log->Printf("Host::GetLLDBPath(ePathTypePythonDir) => '%s'", g_lldb_python_dir.GetCString());
}
file_spec.GetDirectory() = g_lldb_python_dir;
return (bool)file_spec.GetDirectory();
}
break;
#endif
case ePathTypeLLDBSystemPlugins: // System plug-ins directory
{
#if defined (__APPLE__) || defined(__linux__)
static ConstString g_lldb_system_plugin_dir;
static bool g_lldb_system_plugin_dir_located = false;
if (!g_lldb_system_plugin_dir_located)
{
g_lldb_system_plugin_dir_located = true;
#if defined (__APPLE__)
FileSpec lldb_file_spec;
if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
{
char raw_path[PATH_MAX];
lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
char *framework_pos = ::strstr (raw_path, "LLDB.framework");
if (framework_pos)
{
framework_pos += strlen("LLDB.framework");
::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path));
llvm::SmallString<64> resolved_path(raw_path);
FileSpec::Resolve (resolved_path);
g_lldb_system_plugin_dir.SetCString(resolved_path.c_str());
}
return false;
}
#elif defined (__linux__)
FileSpec lldb_file_spec("/usr/lib/lldb", true);
if (lldb_file_spec.Exists())
{
g_lldb_system_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str());
}
#endif // __APPLE__ || __linux__
if (log)
log->Printf("Host::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", g_lldb_system_plugin_dir.GetCString());
}
if (g_lldb_system_plugin_dir)
{
file_spec.GetDirectory() = g_lldb_system_plugin_dir;
return true;
}
#else
// TODO: where would system LLDB plug-ins be located on other systems?
return false;
#endif
}
break;
case ePathTypeLLDBUserPlugins: // User plug-ins directory
{
#if defined (__APPLE__)
static ConstString g_lldb_user_plugin_dir;
if (!g_lldb_user_plugin_dir)
{
llvm::SmallString<64> user_plugin_path("~/Library/Application Support/LLDB/PlugIns");
FileSpec::Resolve (user_plugin_path);
if (user_plugin_path.size())
{
g_lldb_user_plugin_dir.SetCString(user_plugin_path.c_str());
}
}
file_spec.GetDirectory() = g_lldb_user_plugin_dir;
return (bool)file_spec.GetDirectory();
#elif defined (__linux__)
static ConstString g_lldb_user_plugin_dir;
if (!g_lldb_user_plugin_dir)
{
// XDG Base Directory Specification
// http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
// If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
FileSpec lldb_file_spec;
const char *xdg_data_home = getenv("XDG_DATA_HOME");
if (xdg_data_home && xdg_data_home[0])
{
std::string user_plugin_dir (xdg_data_home);
user_plugin_dir += "/lldb";
lldb_file_spec.SetFile (user_plugin_dir.c_str(), true);
}
else
{
const char *home_dir = getenv("HOME");
if (home_dir && home_dir[0])
{
std::string user_plugin_dir (home_dir);
user_plugin_dir += "/.local/share/lldb";
lldb_file_spec.SetFile (user_plugin_dir.c_str(), true);
}
}
if (lldb_file_spec.Exists())
g_lldb_user_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str());
if (log)
log->Printf("Host::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", g_lldb_user_plugin_dir.GetCString());
}
file_spec.GetDirectory() = g_lldb_user_plugin_dir;
return (bool)file_spec.GetDirectory();
#endif
// TODO: where would user LLDB plug-ins be located on other systems?
return false;
}
case ePathTypeLLDBTempSystemDir:
{
static ConstString g_lldb_tmp_dir;
if (!g_lldb_tmp_dir)
{
const char *tmpdir_cstr = getenv("TMPDIR");
if (tmpdir_cstr == NULL)
{
tmpdir_cstr = getenv("TMP");
if (tmpdir_cstr == NULL)
tmpdir_cstr = getenv("TEMP");
}
if (tmpdir_cstr)
{
StreamString pid_tmpdir;
pid_tmpdir.Printf("%s/lldb", tmpdir_cstr);
if (FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault)
.Success())
{
pid_tmpdir.Printf("/%" PRIu64, Host::GetCurrentProcessID());
if (FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault)
.Success())
{
// Make an atexit handler to clean up the process specify LLDB temp dir
// and all of its contents.
::atexit (CleanupProcessSpecificLLDBTempDir);
g_lldb_tmp_dir.SetCString(pid_tmpdir.GetString().c_str());
if (log)
log->Printf("Host::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_lldb_tmp_dir.GetCString());
}
}
}
}
file_spec.GetDirectory() = g_lldb_tmp_dir;
return (bool)file_spec.GetDirectory();
}
}
return false;
}
#ifndef _WIN32
const char *
@ -1425,7 +1085,7 @@ Host::RunShellCommand (const char *command,
// output of the command into this file. We will later read this file
// if all goes well and fill the data into "command_output_ptr"
FileSpec tmpdir_file_spec;
if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
{
tmpdir_file_spec.GetFilename().SetCString("lldb-shell-output.XXXXXX");
strncpy(output_file_path_buffer, tmpdir_file_spec.GetPath().c_str(), sizeof(output_file_path_buffer));

View File

@ -10,6 +10,9 @@
#include "lldb/Host/Config.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostInfoBase.h"
@ -22,6 +25,35 @@
using namespace lldb;
using namespace lldb_private;
namespace
{
void
CleanupProcessSpecificLLDBTempDir()
{
// Get the process specific LLDB temporary directory and delete it.
FileSpec tmpdir_file_spec;
if (!HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
return;
// Remove the LLDB temporary directory if we have one. Set "recurse" to
// true to all files that were created for the LLDB process can be cleaned up.
FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), true);
}
}
#define COMPUTE_LLDB_PATH(compute_function, member_var) \
{ \
static bool is_initialized = false; \
static bool success = false; \
if (!is_initialized) \
{ \
is_initialized = true; \
success = HostInfo::compute_function(member_var); \
} \
if (success) \
result = &member_var; \
}
uint32_t HostInfoBase::m_number_cpus = 0;
std::string HostInfoBase::m_vendor_string;
std::string HostInfoBase::m_os_string;
@ -29,6 +61,14 @@ std::string HostInfoBase::m_host_triple;
ArchSpec HostInfoBase::m_host_arch_32;
ArchSpec HostInfoBase::m_host_arch_64;
FileSpec HostInfoBase::m_lldb_so_dir;
FileSpec HostInfoBase::m_lldb_support_exe_dir;
FileSpec HostInfoBase::m_lldb_headers_dir;
FileSpec HostInfoBase::m_lldb_python_dir;
FileSpec HostInfoBase::m_lldb_system_plugin_dir;
FileSpec HostInfoBase::m_lldb_user_plugin_dir;
FileSpec HostInfoBase::m_lldb_tmp_dir;
uint32_t
HostInfoBase::GetNumberCPUS()
{
@ -103,6 +143,137 @@ HostInfoBase::GetArchitecture(ArchitectureKind arch_kind)
return (m_host_arch_64.IsValid()) ? m_host_arch_64 : m_host_arch_32;
}
bool
HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec)
{
file_spec.Clear();
#if defined(LLDB_DISABLE_PYTHON)
if (type == lldb::ePathTypePythonDir)
return false;
#endif
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
FileSpec *result = nullptr;
switch (type)
{
case lldb::ePathTypeLLDBShlibDir:
COMPUTE_LLDB_PATH(ComputeSharedLibraryDirectory, m_lldb_so_dir)
if (log)
log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", m_lldb_so_dir.GetPath().c_str());
break;
case lldb::ePathTypeSupportExecutableDir:
COMPUTE_LLDB_PATH(ComputeSupportExeDirectory, m_lldb_support_exe_dir)
if (log)
log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", m_lldb_support_exe_dir.GetPath().c_str());
break;
case lldb::ePathTypeHeaderDir:
COMPUTE_LLDB_PATH(ComputeHeaderDirectory, m_lldb_headers_dir)
if (log)
log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", m_lldb_headers_dir.GetPath().c_str());
break;
case lldb::ePathTypePythonDir:
COMPUTE_LLDB_PATH(ComputePythonDirectory, m_lldb_python_dir)
if (log)
log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", m_lldb_python_dir.GetPath().c_str());
break;
case lldb::ePathTypeLLDBSystemPlugins:
COMPUTE_LLDB_PATH(ComputeSystemPluginsDirectory, m_lldb_system_plugin_dir)
if (log)
log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", m_lldb_system_plugin_dir.GetPath().c_str());
break;
case lldb::ePathTypeLLDBUserPlugins:
COMPUTE_LLDB_PATH(ComputeUserPluginsDirectory, m_lldb_user_plugin_dir)
if (log)
log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", m_lldb_user_plugin_dir.GetPath().c_str());
break;
case lldb::ePathTypeLLDBTempSystemDir:
COMPUTE_LLDB_PATH(ComputeTempFileDirectory, m_lldb_tmp_dir)
if (log)
log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", m_lldb_tmp_dir.GetPath().c_str());
break;
}
if (!result)
return false;
file_spec = *result;
return true;
}
bool
HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec)
{
// To get paths related to LLDB we get the path to the executable that
// contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
// on linux this is assumed to be the "lldb" main executable. If LLDB on
// linux is actually in a shared library (liblldb.so) then this function will
// need to be modified to "do the right thing".
FileSpec lldb_file_spec(
Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>(reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath))));
// Remove the filename so that this FileSpec only represents the directory.
file_spec.SetFile(lldb_file_spec.GetDirectory().AsCString(), true);
return (bool)file_spec.GetDirectory();
}
bool
HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec)
{
return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec);
}
bool
HostInfoBase::ComputeTempFileDirectory(FileSpec &file_spec)
{
const char *tmpdir_cstr = getenv("TMPDIR");
if (tmpdir_cstr == NULL)
{
tmpdir_cstr = getenv("TMP");
if (tmpdir_cstr == NULL)
tmpdir_cstr = getenv("TEMP");
}
if (!tmpdir_cstr)
return false;
StreamString pid_tmpdir;
pid_tmpdir.Printf("%s/lldb", tmpdir_cstr);
if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success())
return false;
pid_tmpdir.Printf("/%" PRIu64, Host::GetCurrentProcessID());
if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success())
return false;
// Make an atexit handler to clean up the process specify LLDB temp dir
// and all of its contents.
::atexit(CleanupProcessSpecificLLDBTempDir);
file_spec.SetFile(pid_tmpdir.GetString().c_str(), false);
return true;
}
bool
HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec)
{
// TODO(zturner): Figure out how to compute the header directory for all platforms.
return false;
}
bool
HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec)
{
// TODO(zturner): Figure out how to compute the system plugins directory for all platforms.
return false;
}
bool
HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec)
{
// TODO(zturner): Figure out how to compute the user plugins directory for all platforms.
return false;
}
void
HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64)
{

View File

@ -148,6 +148,33 @@ HostInfoLinux::GetDistributionId()
return m_distribution_id.c_str();
}
bool
HostInfoLinux::ComputeSystemPluginsDirectory(FileSpec &file_spec)
{
file_spec.SetFile("/usr/lib/lldb", true);
return true;
}
bool
HostInfoLinux::ComputeUserPluginsDirectory(FileSpec &file_spec)
{
// XDG Base Directory Specification
// http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
// If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
FileSpec lldb_file_spec;
const char *xdg_data_home = getenv("XDG_DATA_HOME");
if (xdg_data_home && xdg_data_home[0])
{
std::string user_plugin_dir(xdg_data_home);
user_plugin_dir += "/lldb";
lldb_file_spec.SetFile(user_plugin_dir.c_str(), true);
}
else
lldb_file_spec.SetFile("~/.local/share/lldb", true);
return true;
}
void
HostInfoLinux::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64)
{

View File

@ -47,6 +47,7 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Host/Endian.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/CleanUp.h"
@ -366,19 +367,19 @@ WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds)
// return LLDB_INVALID_PROCESS_ID;
//
// FileSpec darwin_debug_file_spec;
// if (!Host::GetLLDBPath (ePathTypeSupportExecutableDir, darwin_debug_file_spec))
// if (!HostInfo::GetLLDBPath (ePathTypeSupportExecutableDir, darwin_debug_file_spec))
// return LLDB_INVALID_PROCESS_ID;
// darwin_debug_file_spec.GetFilename().SetCString("darwin-debug");
//
//
// if (!darwin_debug_file_spec.Exists())
// return LLDB_INVALID_PROCESS_ID;
//
//
// char launcher_path[PATH_MAX];
// darwin_debug_file_spec.GetPath(launcher_path, sizeof(launcher_path));
// command_file.Printf("\"%s\" ", launcher_path);
//
//
// command_file.Printf("--unix-socket=%s ", unix_socket_name.c_str());
//
//
// if (arch_spec && arch_spec->IsValid())
// {
// command_file.Printf("--arch=%s ", arch_spec->GetArchitectureName());
@ -388,7 +389,7 @@ WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds)
// {
// command_file.PutCString("--disable-aslr ");
// }
//
//
// command_file.PutCString("-- ");
//
// if (argv)
@ -402,15 +403,15 @@ WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds)
// command_file.GetFile().Close();
// if (::chmod (temp_file_path, S_IRWXU | S_IRWXG) != 0)
// return LLDB_INVALID_PROCESS_ID;
//
//
// CFCMutableDictionary cf_env_dict;
//
//
// const bool can_create = true;
// if (envp)
// {
// for (size_t i=0; envp[i] != NULL; ++i)
// {
// const char *env_entry = envp[i];
// const char *env_entry = envp[i];
// const char *equal_pos = strchr(env_entry, '=');
// if (equal_pos)
// {
@ -422,20 +423,20 @@ WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds)
// }
// }
// }
//
//
// LSApplicationParameters app_params;
// ::memset (&app_params, 0, sizeof (app_params));
// app_params.flags = kLSLaunchDontAddToRecents | kLSLaunchAsync;
// app_params.argv = NULL;
// app_params.environment = (CFDictionaryRef)cf_env_dict.get();
//
// CFCReleaser<CFURLRef> command_file_url (::CFURLCreateFromFileSystemRepresentation (NULL,
// (const UInt8 *)temp_file_path,
// CFCReleaser<CFURLRef> command_file_url (::CFURLCreateFromFileSystemRepresentation (NULL,
// (const UInt8 *)temp_file_path,
// strlen(temp_file_path),
// false));
//
//
// CFCMutableArray urls;
//
//
// // Terminal.app will open the ".command" file we have created
// // and run our process inside it which will wait at the entry point
// // for us to attach.
@ -455,7 +456,7 @@ WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds)
// AcceptPIDFromInferior,
// connect_url,
// &lldb_error);
//
//
// ProcessSerialNumber psn;
// error = LSOpenURLsWithRole(urls.get(), kLSRolesShell, NULL, &app_params, &psn, 1);
// if (error == noErr)
@ -466,7 +467,7 @@ WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds)
// if (accept_thread_result)
// {
// pid = (intptr_t)accept_thread_result;
//
//
// // Wait for process to be stopped the the entry point by watching
// // for the process status to be set to SSTOP which indicates it it
// // SIGSTOP'ed at the entry point
@ -521,7 +522,7 @@ LaunchInNewTerminalWithAppleScript (const char *exe_path, ProcessLaunchInfo &lau
StreamString command;
FileSpec darwin_debug_file_spec;
if (!Host::GetLLDBPath (ePathTypeSupportExecutableDir, darwin_debug_file_spec))
if (!HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir, darwin_debug_file_spec))
{
error.SetErrorString ("can't locate the 'darwin-debug' executable");
return error;

View File

@ -7,11 +7,16 @@
//
//===----------------------------------------------------------------------===//
#include "lldb/lldb-python.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/macosx/HostInfoMacOSX.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Utility/SafeMachO.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
// C++ Includes
#include <string>
@ -86,6 +91,107 @@ HostInfoMacOSX::GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update)
return false;
}
bool
HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec)
{
FileSpec lldb_file_spec;
if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
return false;
char raw_path[PATH_MAX];
lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
char *framework_pos = ::strstr(raw_path, "LLDB.framework");
if (framework_pos)
{
framework_pos += strlen("LLDB.framework");
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
// Shallow bundle
*framework_pos = '\0';
#else
// Normal bundle
::strncpy(framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path));
#endif
}
file_spec.SetFile(raw_path, true);
return (bool)file_spec.GetDirectory();
}
bool
HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec)
{
FileSpec lldb_file_spec;
if (!HostInfo::GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
return false;
char raw_path[PATH_MAX];
lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
char *framework_pos = ::strstr(raw_path, "LLDB.framework");
if (framework_pos)
{
framework_pos += strlen("LLDB.framework");
::strncpy(framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path));
}
file_spec.SetFile(raw_path, true);
return true;
}
bool
HostInfoMacOSX::ComputePythonDirectory(FileSpec &file_spec)
{
FileSpec lldb_file_spec;
if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
return false;
char raw_path[PATH_MAX];
lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
char *framework_pos = ::strstr(raw_path, "LLDB.framework");
if (framework_pos)
{
framework_pos += strlen("LLDB.framework");
::strncpy(framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path));
}
else
{
llvm::SmallString<256> python_version_dir;
llvm::raw_svector_ostream os(python_version_dir);
os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages";
os.flush();
// We may get our string truncated. Should we protect this with an assert?
::strncat(raw_path, python_version_dir.c_str(), sizeof(raw_path) - strlen(raw_path) - 1);
}
file_spec.SetFile(raw_path, true);
return true;
}
bool
HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec)
{
FileSpec lldb_file_spec;
if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
return false;
char raw_path[PATH_MAX];
lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
char *framework_pos = ::strstr(raw_path, "LLDB.framework");
if (!framework_pos)
return false;
framework_pos += strlen("LLDB.framework");
::strncpy(framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path));
file_spec.SetFile(raw_path, true);
return true;
}
bool
HostInfoMacOSX::ComputeUserPluginsDirectory(FileSpec &file_spec)
{
file_spec.SetFile("~/Library/Application Support/LLDB/PlugIns", true);
return true;
}
void
HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64)
{

View File

@ -7,8 +7,14 @@
//
//===----------------------------------------------------------------------===//
#include "lldb/lldb-python.h"
#include "lldb/Core/Log.h"
#include "lldb/Host/posix/HostInfoPosix.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
#include <netdb.h>
#include <limits.h>
#include <unistd.h>
@ -37,3 +43,73 @@ HostInfoPosix::GetHostname(std::string &s)
}
return false;
}
bool
HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec)
{
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
FileSpec lldb_file_spec;
if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
return false;
char raw_path[PATH_MAX];
lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
// Most Posix systems (e.g. Linux/*BSD) will attempt to replace a */lib with */bin as the base
// directory for helper exe programs. This will fail if the /lib and /bin directories are
// rooted in entirely different trees.
if (log)
log->Printf("HostInfoPosix::ComputeSupportExeDirectory() attempting to derive the bin path (ePathTypeSupportExecutableDir) from "
"this path: %s",
raw_path);
char *lib_pos = ::strstr(raw_path, "/lib");
if (lib_pos != nullptr)
{
// First terminate the raw path at the start of lib.
*lib_pos = '\0';
// Now write in bin in place of lib.
::strncpy(lib_pos, "/bin", PATH_MAX - (lib_pos - raw_path));
if (log)
log->Printf("Host::%s() derived the bin path as: %s", __FUNCTION__, raw_path);
}
else
{
if (log)
log->Printf("Host::%s() failed to find /lib/liblldb within the shared lib path, bailing on bin path construction",
__FUNCTION__);
}
file_spec.SetFile(raw_path, true);
return (bool)file_spec.GetDirectory();
}
bool
HostInfoPosix::ComputeHeaderDirectory(FileSpec &file_spec)
{
file_spec.SetFile("/opt/local/include/lldb", false);
return true;
}
bool
HostInfoPosix::ComputePythonDirectory(FileSpec &file_spec)
{
FileSpec lldb_file_spec;
if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
return false;
char raw_path[PATH_MAX];
lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
llvm::SmallString<256> python_version_dir;
llvm::raw_svector_ostream os(python_version_dir);
os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages";
os.flush();
// We may get our string truncated. Should we protect this with an assert?
::strncat(raw_path, python_version_dir.c_str(), sizeof(raw_path) - strlen(raw_path) - 1);
file_spec.SetFile(raw_path, true);
return true;
}

View File

@ -78,3 +78,18 @@ HostInfoWindows::GetHostname(std::string &s)
s.assign(buffer, buffer + dwSize);
return true;
}
bool
HostInfoWindows::ComputePythonDirectory(FileSpec &file_spec)
{
FileSpec lldb_file_spec;
if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
return false;
char raw_path[PATH_MAX];
lldb_file_spec.AppendPathComponent("../lib/site-packages");
lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
file_spec.SetFile(raw_path, true);
return true;
}

View File

@ -31,7 +31,7 @@
#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@ -2601,7 +2601,7 @@ ScriptInterpreterPython::InitializePrivate ()
FileSpec file_spec;
char python_dir_path[PATH_MAX];
if (Host::GetLLDBPath (ePathTypePythonDir, file_spec))
if (HostInfo::GetLLDBPath(ePathTypePythonDir, file_spec))
{
std::string python_path("sys.path.insert(0,\"");
size_t orig_len = python_path.length();
@ -2612,8 +2612,8 @@ ScriptInterpreterPython::InitializePrivate ()
PyRun_SimpleString (python_path.c_str());
python_path.resize (orig_len);
}
if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, file_spec))
if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, file_spec))
{
if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
{

View File

@ -1069,7 +1069,7 @@ PlatformDarwin::GetDeveloperDirectory()
bool developer_dir_path_valid = false;
char developer_dir_path[PATH_MAX];
FileSpec temp_file_spec;
if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, temp_file_spec))
if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, temp_file_spec))
{
if (temp_file_spec.GetPath (developer_dir_path, sizeof(developer_dir_path)))
{

View File

@ -178,7 +178,7 @@ PlatformMacOSX::GetSDKDirectory (lldb_private::Target &target)
uint32_t versions[2];
if (objfile->GetSDKVersion(versions, sizeof(versions)))
{
if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, fspec))
if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, fspec))
{
std::string path;
xcode_contents_path = fspec.GetPath();

View File

@ -24,6 +24,7 @@
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Process.h"
@ -683,8 +684,8 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
if (!debugserver_exists)
{
// The debugserver binary is in the LLDB.framework/Resources
// directory.
if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec))
// directory.
if (HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir, debugserver_file_spec))
{
debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME);
debugserver_exists = debugserver_file_spec.Exists();
@ -750,7 +751,7 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
// Binding to port zero, we need to figure out what port it ends up
// using using a named pipe...
FileSpec tmpdir_file_spec;
if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
{
tmpdir_file_spec.GetFilename().SetCString("debugserver-named-pipe.XXXXXX");
strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path));