Error PlatformDarwin::ResolveSymbolFile (Target &target, const ModuleSpec &sym_spec, FileSpec &sym_file) { Error error; sym_file = sym_spec.GetSymbolFileSpec(); if (sym_file.Exists()) { if (sym_file.GetFileType() == FileSpec::eFileTypeDirectory) { sym_file = Symbols::FindSymbolFileInBundle (sym_file, sym_spec.GetUUIDPtr(), sym_spec.GetArchitecturePtr()); } } else { if (sym_spec.GetUUID().IsValid()) { } } return error; }
Error Platform::Install (const FileSpec& src, const FileSpec& dst) { Error error; Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); if (log) log->Printf ("Platform::Install (src='%s', dst='%s')", src.GetPath().c_str(), dst.GetPath().c_str()); FileSpec fixed_dst(dst); if (!fixed_dst.GetFilename()) fixed_dst.GetFilename() = src.GetFilename(); ConstString working_dir = GetWorkingDirectory(); if (dst) { if (dst.GetDirectory()) { const char first_dst_dir_char = dst.GetDirectory().GetCString()[0]; if (first_dst_dir_char == '/' || first_dst_dir_char == '\\') { fixed_dst.GetDirectory() = dst.GetDirectory(); } // If the fixed destination file doesn't have a directory yet, // then we must have a relative path. We will resolve this relative // path against the platform's working directory if (!fixed_dst.GetDirectory()) { FileSpec relative_spec; std::string path; if (working_dir) { relative_spec.SetFile(working_dir.GetCString(), false); relative_spec.AppendPathComponent(dst.GetPath().c_str()); fixed_dst.GetDirectory() = relative_spec.GetDirectory(); } else { error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str()); return error; } } } else { if (working_dir) { fixed_dst.GetDirectory() = working_dir; } else { error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str()); return error; } } } else { if (working_dir) { fixed_dst.GetDirectory() = working_dir; } else { error.SetErrorStringWithFormat("platform working directory must be valid when destination directory is empty"); return error; } } if (log) log->Printf ("Platform::Install (src='%s', dst='%s') fixed_dst='%s'", src.GetPath().c_str(), dst.GetPath().c_str(), fixed_dst.GetPath().c_str()); if (GetSupportsRSync()) { error = PutFile(src, dst); } else { switch (src.GetFileType()) { case FileSpec::eFileTypeDirectory: { if (GetFileExists (fixed_dst)) Unlink (fixed_dst.GetPath().c_str()); uint32_t permissions = src.GetPermissions(); if (permissions == 0) permissions = eFilePermissionsDirectoryDefault; std::string dst_dir_path(fixed_dst.GetPath()); error = MakeDirectory(dst_dir_path.c_str(), permissions); if (error.Success()) { // Make a filespec that only fills in the directory of a FileSpec so // when we enumerate we can quickly fill in the filename for dst copies FileSpec recurse_dst; recurse_dst.GetDirectory().SetCString(dst_dir_path.c_str()); std::string src_dir_path (src.GetPath()); RecurseCopyBaton baton = { recurse_dst, this, Error() }; FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &baton); return baton.error; } } break; case FileSpec::eFileTypeRegular: if (GetFileExists (fixed_dst)) Unlink (fixed_dst.GetPath().c_str()); error = PutFile(src, fixed_dst); break; case FileSpec::eFileTypeSymbolicLink: { if (GetFileExists (fixed_dst)) Unlink (fixed_dst.GetPath().c_str()); char buf[PATH_MAX]; error = Host::Readlink(src.GetPath().c_str(), buf, sizeof(buf)); if (error.Success()) error = CreateSymlink(dst.GetPath().c_str(), buf); } break; case FileSpec::eFileTypePipe: error.SetErrorString("platform install doesn't handle pipes"); break; case FileSpec::eFileTypeSocket: error.SetErrorString("platform install doesn't handle sockets"); break; case FileSpec::eFileTypeInvalid: case FileSpec::eFileTypeUnknown: case FileSpec::eFileTypeOther: error.SetErrorString("platform install doesn't handle non file or directory items"); break; } } return error; }
Error TargetList::CreateTargetInternal (Debugger &debugger, const char *user_exe_path, const ArchSpec& specified_arch, bool get_dependent_files, lldb::PlatformSP &platform_sp, lldb::TargetSP &target_sp, bool is_dummy_target) { Timer scoped_timer (__PRETTY_FUNCTION__, "TargetList::CreateTarget (file = '%s', arch = '%s')", user_exe_path, specified_arch.GetArchitectureName()); Error error; ArchSpec arch(specified_arch); if (arch.IsValid()) { if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, NULL)) platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); } if (!platform_sp) platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); if (!arch.IsValid()) arch = specified_arch; FileSpec file (user_exe_path, false); if (!file.Exists() && user_exe_path && user_exe_path[0] == '~') { // we want to expand the tilde but we don't want to resolve any symbolic links // so we can't use the FileSpec constructor's resolve flag llvm::SmallString<64> unglobbed_path(user_exe_path); FileSpec::ResolveUsername(unglobbed_path); if (unglobbed_path.empty()) file = FileSpec(user_exe_path, false); else file = FileSpec(unglobbed_path.c_str(), false); } bool user_exe_path_is_bundle = false; char resolved_bundle_exe_path[PATH_MAX]; resolved_bundle_exe_path[0] = '\0'; if (file) { if (file.GetFileType() == FileSpec::eFileTypeDirectory) user_exe_path_is_bundle = true; if (file.IsRelative() && user_exe_path) { // Ignore paths that start with "./" and "../" if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) { char cwd[PATH_MAX]; if (getcwd (cwd, sizeof(cwd))) { std::string cwd_user_exe_path (cwd); cwd_user_exe_path += '/'; cwd_user_exe_path += user_exe_path; FileSpec cwd_file (cwd_user_exe_path.c_str(), false); if (cwd_file.Exists()) file = cwd_file; } } } ModuleSP exe_module_sp; if (platform_sp) { FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); ModuleSpec module_spec(file, arch); error = platform_sp->ResolveExecutable (module_spec, exe_module_sp, executable_search_paths.GetSize() ? &executable_search_paths : NULL); } if (error.Success() && exe_module_sp) { if (exe_module_sp->GetObjectFile() == NULL) { if (arch.IsValid()) { error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", file.GetPath().c_str(), arch.GetArchitectureName()); } else { error.SetErrorStringWithFormat("unsupported file type \"%s\"", file.GetPath().c_str()); } return error; } target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); if (user_exe_path_is_bundle) exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); } } else { // No file was specified, just create an empty target with any arch // if a valid arch was specified target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); } if (target_sp) { // Set argv0 with what the user typed, unless the user specified a // directory. If the user specified a directory, then it is probably a // bundle that was resolved and we need to use the resolved bundle path if (user_exe_path) { // Use exactly what the user typed as the first argument when we exec or posix_spawn if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) { target_sp->SetArg0 (resolved_bundle_exe_path); } else { // Use resolved path target_sp->SetArg0 (file.GetPath().c_str()); } } if (file.GetDirectory()) { FileSpec file_dir; file_dir.GetDirectory() = file.GetDirectory(); target_sp->GetExecutableSearchPaths ().Append (file_dir); } // Don't put the dummy target in the target list, it's held separately. if (!is_dummy_target) { Mutex::Locker locker(m_target_list_mutex); m_selected_target_idx = m_target_list.size(); m_target_list.push_back(target_sp); // Now prime this from the dummy target: target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget()); } else { m_dummy_target_sp = target_sp; } } return error; }