summaryrefslogtreecommitdiff
path: root/source/Host/common
diff options
context:
space:
mode:
Diffstat (limited to 'source/Host/common')
-rw-r--r--source/Host/common/File.cpp30
-rw-r--r--source/Host/common/FileSpec.cpp32
-rw-r--r--source/Host/common/Host.cpp192
-rw-r--r--source/Host/common/OptionParser.cpp58
-rw-r--r--source/Host/common/Symbols.cpp8
5 files changed, 280 insertions, 40 deletions
diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp
index addd435154051..bbd11858aaba0 100644
--- a/source/Host/common/File.cpp
+++ b/source/Host/common/File.cpp
@@ -1,4 +1,4 @@
-//===-- FileSpec.cpp --------------------------------------------*- C++ -*-===//
+//===-- File.cpp ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "lldb/Host/File.h"
#include <errno.h>
@@ -237,6 +236,11 @@ File::Open (const char *path, uint32_t options, uint32_t permissions)
else if (read)
{
oflag |= O_RDONLY;
+
+#ifndef _WIN32
+ if (options & eOpenoptionDontFollowSymlinks)
+ oflag |= O_NOFOLLOW;
+#endif
}
#ifndef _WIN32
@@ -249,15 +253,15 @@ File::Open (const char *path, uint32_t options, uint32_t permissions)
mode_t mode = 0;
if (oflag & O_CREAT)
{
- if (permissions & ePermissionsUserRead) mode |= S_IRUSR;
- if (permissions & ePermissionsUserWrite) mode |= S_IWUSR;
- if (permissions & ePermissionsUserExecute) mode |= S_IXUSR;
- if (permissions & ePermissionsGroupRead) mode |= S_IRGRP;
- if (permissions & ePermissionsGroupWrite) mode |= S_IWGRP;
- if (permissions & ePermissionsGroupExecute) mode |= S_IXGRP;
- if (permissions & ePermissionsWorldRead) mode |= S_IROTH;
- if (permissions & ePermissionsWorldWrite) mode |= S_IWOTH;
- if (permissions & ePermissionsWorldExecute) mode |= S_IXOTH;
+ if (permissions & lldb::eFilePermissionsUserRead) mode |= S_IRUSR;
+ if (permissions & lldb::eFilePermissionsUserWrite) mode |= S_IWUSR;
+ if (permissions & lldb::eFilePermissionsUserExecute) mode |= S_IXUSR;
+ if (permissions & lldb::eFilePermissionsGroupRead) mode |= S_IRGRP;
+ if (permissions & lldb::eFilePermissionsGroupWrite) mode |= S_IWGRP;
+ if (permissions & lldb::eFilePermissionsGroupExecute) mode |= S_IXGRP;
+ if (permissions & lldb::eFilePermissionsWorldRead) mode |= S_IROTH;
+ if (permissions & lldb::eFilePermissionsWorldWrite) mode |= S_IWOTH;
+ if (permissions & lldb::eFilePermissionsWorldExecute) mode |= S_IXOTH;
}
do
@@ -284,7 +288,7 @@ File::GetPermissions (const char *path, Error &error)
else
{
error.Clear();
- return file_stats.st_mode; // All bits from lldb_private::File::Permissions match those in POSIX mode bits
+ return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
}
}
else
@@ -309,7 +313,7 @@ File::GetPermissions(Error &error) const
else
{
error.Clear();
- return file_stats.st_mode; // All bits from lldb_private::File::Permissions match those in POSIX mode bits
+ return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
}
}
else
diff --git a/source/Host/common/FileSpec.cpp b/source/Host/common/FileSpec.cpp
index 33de198072dc3..48f1ac78d9274 100644
--- a/source/Host/common/FileSpec.cpp
+++ b/source/Host/common/FileSpec.cpp
@@ -34,6 +34,7 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Host/File.h"
#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataBufferMemoryMap.h"
#include "lldb/Core/RegularExpression.h"
@@ -646,6 +647,15 @@ FileSpec::GetFileType () const
return eFileTypeInvalid;
}
+uint32_t
+FileSpec::GetPermissions () const
+{
+ uint32_t file_permissions = 0;
+ if (*this)
+ Host::GetFilePermissions(GetPath().c_str(), file_permissions);
+ return file_permissions;
+}
+
TimeValue
FileSpec::GetModificationTime () const
{
@@ -1161,26 +1171,26 @@ FileSpec::CopyByRemovingLastPathComponent () const
return FileSpec(m_directory.GetCString(),resolve);
}
-const char*
+ConstString
FileSpec::GetLastPathComponent () const
{
- if (m_filename.IsEmpty() && m_directory.IsEmpty())
- return NULL;
- if (m_filename.IsEmpty())
+ if (m_filename)
+ return m_filename;
+ if (m_directory)
{
const char* dir_cstr = m_directory.GetCString();
const char* last_slash_ptr = ::strrchr(dir_cstr, '/');
if (last_slash_ptr == NULL)
- return m_directory.GetCString();
+ return m_directory;
if (last_slash_ptr == dir_cstr)
{
if (last_slash_ptr[1] == 0)
- return last_slash_ptr;
+ return ConstString(last_slash_ptr);
else
- return last_slash_ptr+1;
+ return ConstString(last_slash_ptr+1);
}
if (last_slash_ptr[1] != 0)
- return last_slash_ptr+1;
+ return ConstString(last_slash_ptr+1);
const char* penultimate_slash_ptr = last_slash_ptr;
while (*penultimate_slash_ptr)
{
@@ -1190,10 +1200,10 @@ FileSpec::GetLastPathComponent () const
if (*penultimate_slash_ptr == '/')
break;
}
- ConstString new_path(penultimate_slash_ptr+1,last_slash_ptr-penultimate_slash_ptr);
- return new_path.AsCString();
+ ConstString result(penultimate_slash_ptr+1,last_slash_ptr-penultimate_slash_ptr);
+ return result;
}
- return m_filename.GetCString();
+ return ConstString();
}
void
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index 296e4b40bf014..262776f6c7190 100644
--- a/source/Host/common/Host.cpp
+++ b/source/Host/common/Host.cpp
@@ -22,6 +22,7 @@
#include <grp.h>
#include <netdb.h>
#include <pwd.h>
+#include <sys/stat.h>
#endif
#if !defined (__GNU__) && !defined (_WIN32)
@@ -33,6 +34,7 @@
#include <mach/mach_port.h>
#include <mach/mach_init.h>
#include <mach-o/dyld.h>
+#include <AvailabilityMacros.h>
#endif
#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
@@ -978,6 +980,7 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
// 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)
{
@@ -988,6 +991,8 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
{
FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)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();
@@ -1011,7 +1016,11 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
if (framework_pos)
{
framework_pos += strlen("LLDB.framework");
-#if !defined (__arm__)
+#if defined (__arm__)
+ // Shallow bundle
+ *framework_pos = '\0';
+#else
+ // Normal bundle
::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path));
#endif
}
@@ -1019,6 +1028,8 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
g_lldb_support_exe_dir.SetCString(resolved_path);
}
+ 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();
@@ -1051,6 +1062,8 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
// 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();
@@ -1096,6 +1109,10 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
g_lldb_python_dir.SetCString(resolved_path);
}
+
+ 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();
@@ -1136,6 +1153,10 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
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)
@@ -1194,6 +1215,8 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
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();
@@ -1546,7 +1569,7 @@ Host::RunShellCommand (const char *command,
return error;
}
-#if defined(__linux__) or defined(__FreeBSD__)
+#if defined(__linux__) || defined(__FreeBSD__)
// The functions below implement process launching via posix_spawn() for Linux
// and FreeBSD.
@@ -1826,11 +1849,168 @@ Host::LaunchApplication (const FileSpec &app_file_spec)
return LLDB_INVALID_PROCESS_ID;
}
-uint32_t
-Host::MakeDirectory (const char* path, mode_t mode)
+#endif
+
+
+#ifdef LLDB_DISABLE_POSIX
+
+Error
+Host::MakeDirectory (const char* path, uint32_t mode)
+{
+ Error error;
+ error.SetErrorStringWithFormat("%s in not implemented on this host", __PRETTY_FUNCTION__);
+ return error;
+}
+
+Error
+Host::GetFilePermissions (const char* path, uint32_t &file_permissions)
{
- return UINT32_MAX;
+ Error error;
+ error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__);
+ return error;
}
+
+Error
+Host::SetFilePermissions (const char* path, uint32_t file_permissions)
+{
+ Error error;
+ error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__);
+ return error;
+}
+
+Error
+Host::Symlink (const char *src, const char *dst)
+{
+ Error error;
+ error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__);
+ return error;
+}
+
+Error
+Host::Readlink (const char *path, char *buf, size_t buf_len)
+{
+ Error error;
+ error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__);
+ return error;
+}
+
+Error
+Host::Unlink (const char *path)
+{
+ Error error;
+ error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__);
+ return error;
+}
+
+#else
+
+Error
+Host::MakeDirectory (const char* path, uint32_t file_permissions)
+{
+ Error error;
+ if (path && path[0])
+ {
+ if (::mkdir(path, file_permissions) != 0)
+ {
+ error.SetErrorToErrno();
+ switch (error.GetError())
+ {
+ case ENOENT:
+ {
+ // Parent directory doesn't exist, so lets make it if we can
+ FileSpec spec(path, false);
+ if (spec.GetDirectory() && spec.GetFilename())
+ {
+ // Make the parent directory and try again
+ Error error2 = Host::MakeDirectory(spec.GetDirectory().GetCString(), file_permissions);
+ if (error2.Success())
+ {
+ // Try and make the directory again now that the parent directory was made successfully
+ if (::mkdir(path, file_permissions) == 0)
+ error.Clear();
+ else
+ error.SetErrorToErrno();
+ }
+ }
+ }
+ break;
+ case EEXIST:
+ {
+ FileSpec path_spec(path, false);
+ if (path_spec.IsDirectory())
+ error.Clear(); // It is a directory and it already exists
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ error.SetErrorString("empty path");
+ }
+ return error;
+}
+
+Error
+Host::GetFilePermissions (const char* path, uint32_t &file_permissions)
+{
+ Error error;
+ struct stat file_stats;
+ if (::stat (path, &file_stats) == 0)
+ {
+ // The bits in "st_mode" currently match the definitions
+ // for the file mode bits in unix.
+ file_permissions = file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+ }
+ else
+ {
+ error.SetErrorToErrno();
+ }
+ return error;
+}
+
+Error
+Host::SetFilePermissions (const char* path, uint32_t file_permissions)
+{
+ Error error;
+ if (::chmod(path, file_permissions) != 0)
+ error.SetErrorToErrno();
+ return error;
+}
+
+Error
+Host::Symlink (const char *src, const char *dst)
+{
+ Error error;
+ if (::symlink(dst, src) == -1)
+ error.SetErrorToErrno();
+ return error;
+}
+
+Error
+Host::Unlink (const char *path)
+{
+ Error error;
+ if (::unlink(path) == -1)
+ error.SetErrorToErrno();
+ return error;
+}
+
+Error
+Host::Readlink (const char *path, char *buf, size_t buf_len)
+{
+ Error error;
+ ssize_t count = ::readlink(path, buf, buf_len);
+ if (count < 0)
+ error.SetErrorToErrno();
+ else if (count < (buf_len-1))
+ buf[count] = '\0'; // Success
+ else
+ error.SetErrorString("'buf' buffer is too small to contain link contents");
+ return error;
+}
+
+
#endif
typedef std::map<lldb::user_id_t, lldb::FileSP> FDToFileMap;
@@ -1843,7 +2023,7 @@ FDToFileMap& GetFDToFileMap()
lldb::user_id_t
Host::OpenFile (const FileSpec& file_spec,
uint32_t flags,
- mode_t mode,
+ uint32_t mode,
Error &error)
{
std::string path (file_spec.GetPath());
diff --git a/source/Host/common/OptionParser.cpp b/source/Host/common/OptionParser.cpp
index 287292ee74af0..ead044f53cf17 100644
--- a/source/Host/common/OptionParser.cpp
+++ b/source/Host/common/OptionParser.cpp
@@ -38,24 +38,70 @@ OptionParser::EnableError(bool error)
}
int
-OptionParser::Parse(int argc, char * const argv [],
- const char *optstring,
- const Option *longopts, int *longindex)
+OptionParser::Parse (int argc,
+ char * const argv [],
+ const char *optstring,
+ const Option *longopts,
+ int *longindex)
{
return getopt_long_only(argc, argv, optstring, (const option*)longopts, longindex);
}
-char* OptionParser::GetOptionArgument()
+char*
+OptionParser::GetOptionArgument()
{
return optarg;
}
-int OptionParser::GetOptionIndex()
+int
+OptionParser::GetOptionIndex()
{
return optind;
}
-int OptionParser::GetOptionErrorCause()
+int
+OptionParser::GetOptionErrorCause()
{
return optopt;
}
+
+std::string
+OptionParser::GetShortOptionString(struct option *long_options)
+{
+ std::string s;
+ int i=0;
+ bool done = false;
+ while (!done)
+ {
+ if (long_options[i].name == 0 &&
+ long_options[i].has_arg == 0 &&
+ long_options[i].flag == 0 &&
+ long_options[i].val == 0)
+ {
+ done = true;
+ }
+ else
+ {
+ if (long_options[i].flag == NULL &&
+ isalpha(long_options[i].val))
+ {
+ s.append(1, (char)long_options[i].val);
+ switch (long_options[i].has_arg)
+ {
+ default:
+ case no_argument:
+ break;
+
+ case optional_argument:
+ s.append(2, ':');
+ break;
+ case required_argument:
+ s.append(1, ':');
+ break;
+ }
+ }
+ ++i;
+ }
+ }
+ return s;
+}
diff --git a/source/Host/common/Symbols.cpp b/source/Host/common/Symbols.cpp
index 7189269677d9d..41f465abc8366 100644
--- a/source/Host/common/Symbols.cpp
+++ b/source/Host/common/Symbols.cpp
@@ -61,9 +61,9 @@ Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)
uuid_str = uuid_str + ".debug";
}
- // Get full path to our module. Needed to check debug files like this:
- // /usr/lib/debug/usr/lib/libboost_date_time.so.1.46.1
- std::string module_filename = module_spec.GetFileSpec().GetPath();
+ // Get directory of our module. Needed to check debug files like this:
+ // /usr/lib/debug/usr/lib/library.so.debug
+ std::string module_directory = module_spec.GetFileSpec().GetDirectory().AsCString();
size_t num_directories = debug_file_search_paths.GetSize();
for (size_t idx = 0; idx < num_directories; ++idx)
@@ -79,7 +79,7 @@ Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)
files.push_back (dirname + "/" + symbol_filename);
files.push_back (dirname + "/.debug/" + symbol_filename);
files.push_back (dirname + "/.build-id/" + uuid_str);
- files.push_back (dirname + module_filename);
+ files.push_back (dirname + module_directory + "/" + symbol_filename);
const uint32_t num_files = files.size();
for (size_t idx_file = 0; idx_file < num_files; ++idx_file)