diff options
Diffstat (limited to 'source/Host/common')
-rw-r--r-- | source/Host/common/File.cpp | 30 | ||||
-rw-r--r-- | source/Host/common/FileSpec.cpp | 32 | ||||
-rw-r--r-- | source/Host/common/Host.cpp | 192 | ||||
-rw-r--r-- | source/Host/common/OptionParser.cpp | 58 | ||||
-rw-r--r-- | source/Host/common/Symbols.cpp | 8 |
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) |