bool PlatformRemoteDarwinDevice::GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx, lldb_private::FileSpec &local_file) { Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); if (sdk_idx < m_sdk_directory_infos.size()) { std::string sdkroot_path = m_sdk_directory_infos[sdk_idx].directory.GetPath(); local_file.Clear(); if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) { // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between // the // SDK root directory and the file path. const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr}; for (size_t i = 0; paths_to_try[i] != nullptr; i++) { local_file.SetFile(sdkroot_path, FileSpec::Style::native); if (paths_to_try[i][0] != '\0') local_file.AppendPathComponent(paths_to_try[i]); local_file.AppendPathComponent(platform_file_path); FileSystem::Instance().Resolve(local_file); if (FileSystem::Instance().Exists(local_file)) { if (log) log->Printf("Found a copy of %s in the SDK dir %s/%s", platform_file_path, sdkroot_path.c_str(), paths_to_try[i]); return true; } local_file.Clear(); } } } return false; }
uint32_t SymbolFilePDB::ResolveSymbolContext( const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) { if (resolve_scope & lldb::eSymbolContextCompUnit) { // Locate all compilation units with line numbers referencing the specified // file. For example, if // `file_spec` is <vector>, then this should return all source files and // header files that reference // <vector>, either directly or indirectly. auto compilands = m_session_up->findCompilandsForSourceFile( file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive); // For each one, either find get its previously parsed data, or parse it // afresh and add it to // the symbol context list. while (auto compiland = compilands->getNext()) { // If we're not checking inlines, then don't add line information for this // file unless the FileSpec // matches. if (!check_inlines) { // `getSourceFileName` returns the basename of the original source file // used to generate this compiland. // It does not return the full path. Currently the only way to get that // is to do a basename lookup to // get the IPDBSourceFile, but this is ambiguous in the case of two // source files with the same name // contributing to the same compiland. This is a moderately extreme // edge case, so we consider this ok // for now, although we need to find a long term solution. std::string source_file = compiland->getSourceFileName(); auto pdb_file = m_session_up->findOneSourceFile( compiland.get(), source_file, PDB_NameSearchFlags::NS_CaseInsensitive); source_file = pdb_file->getFileName(); FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows); if (!file_spec.FileEquals(this_spec)) continue; } SymbolContext sc; auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId()); sc.comp_unit = cu.get(); sc.module_sp = cu->GetModule(); sc_list.Append(sc); // If we were asked to resolve line entries, add all entries to the line // table that match the requested // line (or all lines if `line` == 0) if (resolve_scope & lldb::eSymbolContextLineEntry) ParseCompileUnitLineTable(sc, line); } } return sc_list.GetSize(); }
PlatformRemoteDarwinDevice::SDKDirectoryInfo::SDKDirectoryInfo( const lldb_private::FileSpec &sdk_dir) : directory(sdk_dir), build(), user_cached(false) { llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef(); llvm::StringRef build_str; std::tie(version, build_str) = ParseVersionBuildDir(dirname_str); build.SetString(build_str); }
PlatformRemoteAppleWatch::SDKDirectoryInfo::SDKDirectoryInfo( const lldb_private::FileSpec &sdk_dir) : directory(sdk_dir), build(), version_major(0), version_minor(0), version_update(0), user_cached(false) { llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef(); llvm::StringRef build_str; std::tie(version_major, version_minor, version_update, build_str) = ParseVersionBuildDir(dirname_str); build.SetString(build_str); }
lldb_private::Error PlatformMacOSX::GetFileWithUUID (const lldb_private::FileSpec &platform_file, const lldb_private::UUID *uuid_ptr, lldb_private::FileSpec &local_file) { if (IsRemote() && m_remote_platform_sp) { std::string local_os_build; #if !defined(__linux__) HostInfo::GetOSBuildString(local_os_build); #endif std::string remote_os_build; m_remote_platform_sp->GetOSBuildString(remote_os_build); if (local_os_build.compare(remote_os_build) == 0) { // same OS version: the local file is good enough local_file = platform_file; return Error(); } else { // try to find the file in the cache std::string cache_path(GetLocalCacheDirectory()); std::string module_path (platform_file.GetPath()); cache_path.append(module_path); FileSpec module_cache_spec(cache_path.c_str(),false); if (module_cache_spec.Exists()) { local_file = module_cache_spec; return Error(); } // bring in the remote module file FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent(); // try to make the local directory first Error err = FileSystem::MakeDirectory(module_cache_folder, eFilePermissionsDirectoryDefault); if (err.Fail()) return err; err = GetFile(platform_file, module_cache_spec); if (err.Fail()) return err; if (module_cache_spec.Exists()) { local_file = module_cache_spec; return Error(); } else return Error("unable to obtain valid module file"); } } local_file = platform_file; return Error(); }
PlatformRemoteAppleWatch::SDKDirectoryInfo::SDKDirectoryInfo( const lldb_private::FileSpec &sdk_dir) : directory(sdk_dir), build(), version_major(0), version_minor(0), version_update(0), user_cached(false) { const char *dirname_cstr = sdk_dir.GetFilename().GetCString(); const char *pos = Args::StringToVersion(dirname_cstr, version_major, version_minor, version_update); if (pos && pos[0] == ' ' && pos[1] == '(') { const char *build_start = pos + 2; const char *end_paren = strchr(build_start, ')'); if (end_paren && build_start < end_paren) build.SetCStringWithLength(build_start, end_paren - build_start); } }
bool PlatformRemoteiOS::GetFileInSDKRoot (const char *platform_file_path, const char *sdkroot_path, bool symbols_dirs_only, lldb_private::FileSpec &local_file) { if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0]) { char resolved_path[PATH_MAX]; if (!symbols_dirs_only) { ::snprintf (resolved_path, sizeof(resolved_path), "%s/%s", sdkroot_path, platform_file_path); local_file.SetFile(resolved_path, true); if (local_file.Exists()) return true; } ::snprintf (resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s", sdkroot_path, platform_file_path); local_file.SetFile(resolved_path, true); if (local_file.Exists()) return true; ::snprintf (resolved_path, sizeof(resolved_path), "%s/Symbols/%s", sdkroot_path, platform_file_path); local_file.SetFile(resolved_path, true); if (local_file.Exists()) return true; } return false; }
bool PlatformRemoteiOS::GetFileInSDKRoot (const char *platform_file_path, const char *sdkroot_path, bool symbols_dirs_only, lldb_private::FileSpec &local_file) { Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0]) { char resolved_path[PATH_MAX]; if (!symbols_dirs_only) { ::snprintf (resolved_path, sizeof(resolved_path), "%s%s", sdkroot_path, platform_file_path); local_file.SetFile(resolved_path, true); if (local_file.Exists()) { if (log) { log->Printf ("Found a copy of %s in the SDK dir %s", platform_file_path, sdkroot_path); } return true; } } ::snprintf (resolved_path, sizeof(resolved_path), "%s/Symbols.Internal%s", sdkroot_path, platform_file_path); local_file.SetFile(resolved_path, true); if (local_file.Exists()) { if (log) { log->Printf ("Found a copy of %s in the SDK dir %s/Symbols.Internal", platform_file_path, sdkroot_path); } return true; } ::snprintf (resolved_path, sizeof(resolved_path), "%s/Symbols%s", sdkroot_path, platform_file_path); local_file.SetFile(resolved_path, true); if (local_file.Exists()) { if (log) { log->Printf ("Found a copy of %s in the SDK dir %s/Symbols", platform_file_path, sdkroot_path); } return true; } } return false; }
lldb_private::Error PlatformPOSIX::GetFile(const lldb_private::FileSpec &source, // remote file path const lldb_private::FileSpec &destination) // local file path { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); // Check the args, first. std::string src_path (source.GetPath()); if (src_path.empty()) return Error("unable to get file path for source"); std::string dst_path (destination.GetPath()); if (dst_path.empty()) return Error("unable to get file path for destination"); if (IsHost()) { if (FileSpec::Equal(source, destination, true)) return Error("local scenario->source and destination are the same file path: no operation performed"); // cp src dst StreamString cp_command; cp_command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str()); int status; RunShellCommand(cp_command.GetData(), NULL, &status, NULL, NULL, 10); if (status != 0) return Error("unable to perform copy"); return Error(); } else if (m_remote_platform_sp) { if (GetSupportsRSync()) { StreamString command; if (GetIgnoresRemoteHostname()) { if (!GetRSyncPrefix()) command.Printf("rsync %s %s %s", GetRSyncOpts(), src_path.c_str(), dst_path.c_str()); else command.Printf("rsync %s %s%s %s", GetRSyncOpts(), GetRSyncPrefix(), src_path.c_str(), dst_path.c_str()); } else command.Printf("rsync %s %s:%s %s", GetRSyncOpts(), m_remote_platform_sp->GetHostname(), src_path.c_str(), dst_path.c_str()); if (log) log->Printf("[GetFile] Running command: %s\n", command.GetData()); int retcode; Host::RunShellCommand(command.GetData(), NULL, &retcode, NULL, NULL, 60); if (retcode == 0) return Error(); // If we are here, rsync has failed - let's try the slow way before giving up } // open src and dst // read/write, read/write, read/write, ... // close src // close dst if (log) log->Printf("[GetFile] Using block by block transfer....\n"); Error error; user_id_t fd_src = OpenFile (source, File::eOpenOptionRead, lldb::eFilePermissionsFileDefault, error); if (fd_src == UINT64_MAX) return Error("unable to open source file"); uint32_t permissions = 0; error = GetFilePermissions(source, permissions); if (permissions == 0) permissions = lldb::eFilePermissionsFileDefault; user_id_t fd_dst = FileCache::GetInstance().OpenFile( destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate, permissions, error); if (fd_dst == UINT64_MAX) { if (error.Success()) error.SetErrorString("unable to open destination file"); } if (error.Success()) { lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); uint64_t offset = 0; error.Clear(); while (error.Success()) { const uint64_t n_read = ReadFile (fd_src, offset, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), error); if (error.Fail()) break; if (n_read == 0) break; if (FileCache::GetInstance().WriteFile(fd_dst, offset, buffer_sp->GetBytes(), n_read, error) != n_read) { if (!error.Fail()) error.SetErrorString("unable to write to destination file"); break; } offset += n_read; } } // Ignore the close error of src. if (fd_src != UINT64_MAX) CloseFile(fd_src, error); // And close the dst file descriptot. if (fd_dst != UINT64_MAX && !FileCache::GetInstance().CloseFile(fd_dst, error)) { if (!error.Fail()) error.SetErrorString("unable to close destination file"); } return error; } return Platform::GetFile(source,destination); }
lldb_private::Error PlatformPOSIX::PutFile (const lldb_private::FileSpec& source, const lldb_private::FileSpec& destination, uint32_t uid, uint32_t gid) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); if (IsHost()) { if (FileSpec::Equal(source, destination, true)) return Error(); // cp src dst // chown uid:gid dst std::string src_path (source.GetPath()); if (src_path.empty()) return Error("unable to get file path for source"); std::string dst_path (destination.GetPath()); if (dst_path.empty()) return Error("unable to get file path for destination"); StreamString command; command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str()); int status; RunShellCommand(command.GetData(), NULL, &status, NULL, NULL, 10); if (status != 0) return Error("unable to perform copy"); if (uid == UINT32_MAX && gid == UINT32_MAX) return Error(); if (chown_file(this,dst_path.c_str(),uid,gid) != 0) return Error("unable to perform chown"); return Error(); } else if (m_remote_platform_sp) { if (GetSupportsRSync()) { std::string src_path (source.GetPath()); if (src_path.empty()) return Error("unable to get file path for source"); std::string dst_path (destination.GetPath()); if (dst_path.empty()) return Error("unable to get file path for destination"); StreamString command; if (GetIgnoresRemoteHostname()) { if (!GetRSyncPrefix()) command.Printf("rsync %s %s %s", GetRSyncOpts(), src_path.c_str(), dst_path.c_str()); else command.Printf("rsync %s %s %s%s", GetRSyncOpts(), src_path.c_str(), GetRSyncPrefix(), dst_path.c_str()); } else command.Printf("rsync %s %s %s:%s", GetRSyncOpts(), src_path.c_str(), GetHostname(), dst_path.c_str()); if (log) log->Printf("[PutFile] Running command: %s\n", command.GetData()); int retcode; Host::RunShellCommand(command.GetData(), NULL, &retcode, NULL, NULL, 60); if (retcode == 0) { // Don't chown a local file for a remote system // if (chown_file(this,dst_path.c_str(),uid,gid) != 0) // return Error("unable to perform chown"); return Error(); } // if we are still here rsync has failed - let's try the slow way before giving up } } return Platform::PutFile(source,destination,uid,gid); }