Error ModuleCache::Get (const FileSpec &root_dir_spec, const char *hostname, const UUID &uuid, const FileSpec &platform_module_spec, FileSpec &cached_module_spec) { cached_module_spec.Clear (); const auto module_spec_dir = GetModuleDirectory (root_dir_spec, uuid); const auto module_file_path = JoinPath (module_spec_dir, platform_module_spec.GetFilename ().AsCString ()); Error error; if (!module_file_path.Exists ()) { error.SetErrorStringWithFormat ("module %s not found", module_file_path.GetPath ().c_str ()); return error; } cached_module_spec = module_file_path; // We may have already cached module but downloaded from an another host - in this case let's create a symlink to it. const auto sysroot_module_path_spec = GetHostSysRootModulePath (root_dir_spec, hostname, platform_module_spec); if (!sysroot_module_path_spec.Exists ()) CreateHostSysRootModuleSymLink (sysroot_module_path_spec, cached_module_spec); return error; }
//------------------------------------------------------------------ // Find the index of the file in the file spec list that matches // "file_spec" starting "start_idx" entries into the file spec list. // // Returns the valid index of the file that matches "file_spec" if // it is found, else UINT32_MAX is returned. //------------------------------------------------------------------ uint32_t FileSpecList::FindFileIndex (uint32_t start_idx, const FileSpec &file_spec, bool full) const { const uint32_t num_files = m_files.size(); uint32_t idx; // When looking for files, we will compare only the filename if the // FILE_SPEC argument is empty bool compare_filename_only = file_spec.GetDirectory().IsEmpty(); for (idx = start_idx; idx < num_files; ++idx) { if (compare_filename_only) { if (m_files[idx].GetFilename() == file_spec.GetFilename()) return idx; } else { if (FileSpec::Equal (m_files[idx], file_spec, full)) return idx; } } // We didn't find the file, return an invalid index return UINT32_MAX; }
Error ModuleCache::Put (const FileSpec &root_dir_spec, const char *hostname, const UUID &uuid, const FileSpec &platform_module_spec, const FileSpec &tmp_file) { const auto module_spec_dir = GetModuleDirectory (root_dir_spec, uuid); auto error = MakeDirectory (module_spec_dir); if (error.Fail ()) return error; const auto module_file_path = JoinPath (module_spec_dir, platform_module_spec.GetFilename ().AsCString ()); const auto tmp_file_path = tmp_file.GetPath (); const auto err_code = llvm::sys::fs::copy_file (tmp_file_path.c_str (), module_file_path.GetPath ().c_str ()); if (err_code) { error.SetErrorStringWithFormat ("failed to copy file %s to %s: %s", tmp_file_path.c_str (), module_file_path.GetPath ().c_str (), err_code.message ().c_str ()); } // Create sysroot link to a module. const auto sysroot_module_path_spec = GetHostSysRootModulePath (root_dir_spec, hostname, platform_module_spec); return CreateHostSysRootModuleSymLink (sysroot_module_path_spec, module_file_path); }
FileSpec::EnumerateDirectoryResult DiskFilesOrDirectoriesCallback(void *baton, FileSpec::FileType file_type, const FileSpec &spec) { const char *name = spec.GetFilename().AsCString(); const DiskFilesOrDirectoriesBaton *parameters = (DiskFilesOrDirectoriesBaton*)baton; char *end_ptr = parameters->end_ptr; char *partial_name_copy = parameters->partial_name_copy; const char *remainder = parameters->remainder; // Omit ".", ".." and any . files if the match string doesn't start with . if (name[0] == '.') { if (name[1] == '\0') return FileSpec::eEnumerateDirectoryResultNext; else if (name[1] == '.' && name[2] == '\0') return FileSpec::eEnumerateDirectoryResultNext; else if (remainder[0] != '.') return FileSpec::eEnumerateDirectoryResultNext; } // If we found a directory, we put a "/" at the end of the name. if (remainder[0] == '\0' || strstr(name, remainder) == name) { if (strlen(name) + parameters->baselen >= PATH_MAX) return FileSpec::eEnumerateDirectoryResultNext; strcpy(end_ptr, name); bool isa_directory = false; if (file_type == FileSpec::eFileTypeDirectory) isa_directory = true; else if (file_type == FileSpec::eFileTypeSymbolicLink) { struct stat stat_buf; if ((stat(partial_name_copy, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) isa_directory = true; } if (isa_directory) { *parameters->saw_directory = true; size_t len = strlen(parameters->partial_name_copy); partial_name_copy[len] = '/'; partial_name_copy[len + 1] = '\0'; } if (parameters->only_directories && !isa_directory) return FileSpec::eEnumerateDirectoryResultNext; parameters->matches->AppendString(partial_name_copy); } return FileSpec::eEnumerateDirectoryResultNext; }
ModuleSP Target::GetSharedModule ( const FileSpec& file_spec, const ArchSpec& arch, const lldb_private::UUID *uuid_ptr, const ConstString *object_name, off_t object_offset, Error *error_ptr ) { // Don't pass in the UUID so we can tell if we have a stale value in our list ModuleSP old_module_sp; // This will get filled in if we have a new version of the library bool did_create_module = false; ModuleSP module_sp; // If there are image search path entries, try to use them first to acquire a suitable image. Error error; if (m_image_search_paths.GetSize()) { FileSpec transformed_spec; if (m_image_search_paths.RemapPath (file_spec.GetDirectory(), transformed_spec.GetDirectory())) { transformed_spec.GetFilename() = file_spec.GetFilename(); error = ModuleList::GetSharedModule (transformed_spec, arch, uuid_ptr, object_name, object_offset, module_sp, &old_module_sp, &did_create_module); } } // If a module hasn't been found yet, use the unmodified path. if (!module_sp) { error = (ModuleList::GetSharedModule (file_spec, arch, uuid_ptr, object_name, object_offset, module_sp, &old_module_sp, &did_create_module)); } if (module_sp) { m_images.Append (module_sp); if (did_create_module) { if (old_module_sp && m_images.GetIndexForModule (old_module_sp.get()) != LLDB_INVALID_INDEX32) ModuleUpdated(old_module_sp, module_sp); else ModuleAdded(module_sp); } } if (error_ptr) *error_ptr = error; return module_sp; }
static FileSpec::EnumerateDirectoryResult EnumerateDirectoryCallback(void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) { if (file_type == FileSpec::eFileTypeDirectory) { const char *filename = file_spec.GetFilename().GetCString(); if (filename && strncmp(filename, "iPhoneSimulator", strlen("iPhoneSimulator")) == 0) { ::snprintf((char *)baton, PATH_MAX, "%s", filename); return FileSpec::eEnumerateDirectoryResultQuit; } } return FileSpec::eEnumerateDirectoryResultNext; }
Error Platform::ResolveExecutable (const FileSpec &exe_file, const ArchSpec &exe_arch, lldb::ModuleSP &exe_module_sp) { Error error; if (exe_file.Exists()) { if (exe_arch.IsValid()) { error = ModuleList::GetSharedModule (exe_file, exe_arch, NULL, NULL, 0, exe_module_sp, NULL, NULL); } else { // No valid architecture was specified, ask the platform for // the architectures that we should be using (in the correct order) // and see if we can find a match that way ArchSpec platform_arch; for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx) { error = ModuleList::GetSharedModule (exe_file, platform_arch, NULL, NULL, 0, exe_module_sp, NULL, NULL); // Did we find an executable using one of the if (error.Success() && exe_module_sp) break; } } } else { error.SetErrorStringWithFormat ("'%s%s%s' does not exist", exe_file.GetDirectory().AsCString(""), exe_file.GetDirectory() ? "/" : "", exe_file.GetFilename().AsCString("")); } return error; }
Status HostProcessPosix::GetMainModule(FileSpec &file_spec) const { Status error; // Use special code here because proc/[pid]/exe is a symbolic link. char link_path[PATH_MAX]; if (snprintf(link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", m_process) != 1) { error.SetErrorString("Unable to build /proc/<pid>/exe string"); return error; } error = FileSystem::Instance().Readlink(FileSpec(link_path), file_spec); if (!error.Success()) return error; // If the binary has been deleted, the link name has " (deleted)" appended. // Remove if there. if (file_spec.GetFilename().GetStringRef().endswith(" (deleted)")) { const char *filename = file_spec.GetFilename().GetCString(); static const size_t deleted_len = strlen(" (deleted)"); const size_t len = file_spec.GetFilename().GetLength(); file_spec.GetFilename().SetCStringWithLength(filename, len - deleted_len); } return error; }
FileSpec::EnumerateDirectoryResult PlatformDarwinKernel::GetKernelsInDirectory (void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) { if (file_type == FileSpec::eFileTypeRegular || file_type == FileSpec::eFileTypeSymbolicLink) { ConstString filename = file_spec.GetFilename(); if (strncmp (filename.GetCString(), "kernel", 6) == 0 || strncmp (filename.GetCString(), "mach", 4) == 0) { // This is m_kernel_binaries but we're in a class method here ((std::vector<lldb_private::FileSpec> *)baton)->push_back(file_spec); } } return FileSpec::eEnumerateDirectoryResultNext; }
Error ModuleCache::Put (const FileSpec &root_dir_spec, const char *hostname, const ModuleSpec &module_spec, const FileSpec &tmp_file, const FileSpec &target_file) { const auto module_spec_dir = GetModuleDirectory (root_dir_spec, module_spec.GetUUID ()); const auto module_file_path = JoinPath (module_spec_dir, target_file.GetFilename ().AsCString ()); const auto tmp_file_path = tmp_file.GetPath (); const auto err_code = llvm::sys::fs::rename (tmp_file_path.c_str (), module_file_path.GetPath ().c_str ()); if (err_code) return Error ("Failed to rename file %s to %s: %s", tmp_file_path.c_str (), module_file_path.GetPath ().c_str (), err_code.message ().c_str ()); const auto error = CreateHostSysRootModuleLink(root_dir_spec, hostname, target_file, module_file_path); if (error.Fail ()) return Error ("Failed to create link to %s: %s", module_file_path.GetPath ().c_str (), error.AsCString ()); return Error (); }
uint32_t Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) { Mutex::Locker locker (m_mutex); Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveSymbolContextForFilePath (%s%s%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)", file_spec.GetDirectory().AsCString(""), file_spec.GetDirectory() ? "/" : "", file_spec.GetFilename().AsCString(""), line, check_inlines ? "yes" : "no", resolve_scope); const uint32_t initial_count = sc_list.GetSize(); SymbolVendor *symbols = GetSymbolVendor (); if (symbols) symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list); return sc_list.GetSize() - initial_count; }
OperatingSystemPython::OperatingSystemPython(lldb_private::Process *process, const FileSpec &python_module_path) : OperatingSystem(process), m_thread_list_valobj_sp(), m_register_info_ap(), m_interpreter(NULL), m_python_object_sp() { if (!process) return; TargetSP target_sp = process->CalculateTarget(); if (!target_sp) return; m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); if (m_interpreter) { std::string os_plugin_class_name( python_module_path.GetFilename().AsCString("")); if (!os_plugin_class_name.empty()) { const bool init_session = false; const bool allow_reload = true; char python_module_path_cstr[PATH_MAX]; python_module_path.GetPath(python_module_path_cstr, sizeof(python_module_path_cstr)); Error error; if (m_interpreter->LoadScriptingModule( python_module_path_cstr, allow_reload, init_session, error)) { // Strip the ".py" extension if there is one size_t py_extension_pos = os_plugin_class_name.rfind(".py"); if (py_extension_pos != std::string::npos) os_plugin_class_name.erase(py_extension_pos); // Add ".OperatingSystemPlugIn" to the module name to get a string like // "modulename.OperatingSystemPlugIn" os_plugin_class_name += ".OperatingSystemPlugIn"; StructuredData::ObjectSP object_sp = m_interpreter->OSPlugin_CreatePluginObject( os_plugin_class_name.c_str(), process->CalculateProcess()); if (object_sp && object_sp->IsValid()) m_python_object_sp = object_sp; } } } }
static FileSpec::EnumerateDirectoryResult RecurseCopy_Callback (void *baton, FileSpec::FileType file_type, const FileSpec &src) { RecurseCopyBaton* rc_baton = (RecurseCopyBaton*)baton; switch (file_type) { case FileSpec::eFileTypePipe: case FileSpec::eFileTypeSocket: // we have no way to copy pipes and sockets - ignore them and continue return FileSpec::eEnumerateDirectoryResultNext; break; case FileSpec::eFileTypeDirectory: { // make the new directory and get in there FileSpec dst_dir = rc_baton->dst; if (!dst_dir.GetFilename()) dst_dir.GetFilename() = src.GetLastPathComponent(); std::string dst_dir_path (dst_dir.GetPath()); Error error = rc_baton->platform_ptr->MakeDirectory(dst_dir_path.c_str(), lldb::eFilePermissionsDirectoryDefault); if (error.Fail()) { rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end", dst_dir_path.c_str()); return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out } // now recurse std::string src_dir_path (src.GetPath()); // 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.GetPath().c_str()); RecurseCopyBaton rc_baton2 = { recurse_dst, rc_baton->platform_ptr, Error() }; FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &rc_baton2); if (rc_baton2.error.Fail()) { rc_baton->error.SetErrorString(rc_baton2.error.AsCString()); return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out } return FileSpec::eEnumerateDirectoryResultNext; } break; case FileSpec::eFileTypeSymbolicLink: { // copy the file and keep going FileSpec dst_file = rc_baton->dst; if (!dst_file.GetFilename()) dst_file.GetFilename() = src.GetFilename(); char buf[PATH_MAX]; rc_baton->error = Host::Readlink (src.GetPath().c_str(), buf, sizeof(buf)); if (rc_baton->error.Fail()) return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out rc_baton->error = rc_baton->platform_ptr->CreateSymlink(dst_file.GetPath().c_str(), buf); if (rc_baton->error.Fail()) return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out return FileSpec::eEnumerateDirectoryResultNext; } break; case FileSpec::eFileTypeRegular: { // copy the file and keep going FileSpec dst_file = rc_baton->dst; if (!dst_file.GetFilename()) dst_file.GetFilename() = src.GetFilename(); Error err = rc_baton->platform_ptr->PutFile(src, dst_file); if (err.Fail()) { rc_baton->error.SetErrorString(err.AsCString()); return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out } return FileSpec::eEnumerateDirectoryResultNext; } break; case FileSpec::eFileTypeInvalid: case FileSpec::eFileTypeOther: case FileSpec::eFileTypeUnknown: rc_baton->error.SetErrorStringWithFormat("invalid file detected during copy: %s", src.GetPath().c_str()); return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out break; } }
static bool SkinnyMachOFileContainsArchAndUUID ( const FileSpec &file_spec, const ArchSpec *arch, const lldb_private::UUID *uuid, // the UUID we are looking for off_t file_offset, DataExtractor& data, uint32_t data_offset, const uint32_t magic ) { assert(magic == HeaderMagic32 || magic == HeaderMagic32Swapped || magic == HeaderMagic64 || magic == HeaderMagic64Swapped); if (magic == HeaderMagic32 || magic == HeaderMagic64) data.SetByteOrder (lldb::endian::InlHostByteOrder()); else if (lldb::endian::InlHostByteOrder() == eByteOrderBig) data.SetByteOrder (eByteOrderLittle); else data.SetByteOrder (eByteOrderBig); uint32_t i; const uint32_t cputype = data.GetU32(&data_offset); // cpu specifier const uint32_t cpusubtype = data.GetU32(&data_offset); // machine specifier data_offset+=4; // Skip mach file type const uint32_t ncmds = data.GetU32(&data_offset); // number of load commands const uint32_t sizeofcmds = data.GetU32(&data_offset); // the size of all the load commands data_offset+=4; // Skip flags // Check the architecture if we have a valid arch pointer if (arch) { ArchSpec file_arch(eArchTypeMachO, cputype, cpusubtype); if (file_arch != *arch) return false; } // The file exists, and if a valid arch pointer was passed in we know // if already matches, so we can return if we aren't looking for a specific // UUID if (uuid == NULL) return true; if (magic == HeaderMagic64Swapped || magic == HeaderMagic64) data_offset += 4; // Skip reserved field for in mach_header_64 // Make sure we have enough data for all the load commands if (magic == HeaderMagic64Swapped || magic == HeaderMagic64) { if (data.GetByteSize() < sizeof(struct mach_header_64) + sizeofcmds) { DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header_64) + sizeofcmds)); data.SetData (data_buffer_sp); } } else { if (data.GetByteSize() < sizeof(struct mach_header) + sizeofcmds) { DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header) + sizeofcmds)); data.SetData (data_buffer_sp); } } for (i=0; i<ncmds; i++) { const uint32_t cmd_offset = data_offset; // Save this data_offset in case parsing of the segment goes awry! uint32_t cmd = data.GetU32(&data_offset); uint32_t cmd_size = data.GetU32(&data_offset); if (cmd == LoadCommandUUID) { lldb_private::UUID file_uuid (data.GetData(&data_offset, 16), 16); if (file_uuid == *uuid) return true; // Emit some warning messages since the UUIDs do not match! char path_buf[PATH_MAX]; path_buf[0] = '\0'; const char *path = file_spec.GetPath(path_buf, PATH_MAX) ? path_buf : file_spec.GetFilename().AsCString(); Host::SystemLog (Host::eSystemLogWarning, "warning: UUID mismatch detected between binary and:\n\t'%s'\n", path); return false; } data_offset = cmd_offset + cmd_size; } return false; }
SourceManager::File::File(const FileSpec &file_spec, Target *target) : m_file_spec_orig (file_spec), m_file_spec(file_spec), m_mod_time (file_spec.GetModificationTime()), m_data_sp(), m_offsets() { if (!m_mod_time.IsValid()) { if (target) { if (!file_spec.GetDirectory() && file_spec.GetFilename()) { // If this is just a file name, lets see if we can find it in the target: bool check_inlines = false; SymbolContextList sc_list; size_t num_matches = target->GetImages().ResolveSymbolContextForFilePath (file_spec.GetFilename().AsCString(), 0, check_inlines, lldb::eSymbolContextModule | lldb::eSymbolContextCompUnit, sc_list); bool got_multiple = false; if (num_matches != 0) { if (num_matches > 1) { SymbolContext sc; FileSpec *test_cu_spec = NULL; for (unsigned i = 0; i < num_matches; i++) { sc_list.GetContextAtIndex(i, sc); if (sc.comp_unit) { if (test_cu_spec) { if (test_cu_spec != static_cast<FileSpec *> (sc.comp_unit)) got_multiple = true; break; } else test_cu_spec = sc.comp_unit; } } } if (!got_multiple) { SymbolContext sc; sc_list.GetContextAtIndex (0, sc); m_file_spec = sc.comp_unit; m_mod_time = m_file_spec.GetModificationTime(); } } } // Try remapping if m_file_spec does not correspond to an existing file. if (!m_file_spec.Exists()) { FileSpec new_file_spec; // Check target specific source remappings first, then fall back to // modules objects can have individual path remappings that were detected // when the debug info for a module was found. // then if (target->GetSourcePathMap().FindFile (m_file_spec, new_file_spec) || target->GetImages().FindSourceFile (m_file_spec, new_file_spec)) { m_file_spec = new_file_spec; m_mod_time = m_file_spec.GetModificationTime(); } } } } if (m_mod_time.IsValid()) m_data_sp = m_file_spec.ReadFileContents (); }
Error PlatformRemoteiOS::ResolveExecutable (const FileSpec &exe_file, const ArchSpec &exe_arch, lldb::ModuleSP &exe_module_sp) { Error error; // Nothing special to do here, just use the actual file and architecture FileSpec resolved_exe_file (exe_file); // If we have "ls" as the exe_file, resolve the executable loation based on // the current path variables // TODO: resolve bare executables in the Platform SDK // if (!resolved_exe_file.Exists()) // resolved_exe_file.ResolveExecutableLocation (); // Resolve any executable within a bundle on MacOSX // TODO: verify that this handles shallow bundles, if not then implement one ourselves Host::ResolveExecutableInBundle (resolved_exe_file); if (resolved_exe_file.Exists()) { if (exe_arch.IsValid()) { error = ModuleList::GetSharedModule (resolved_exe_file, exe_arch, NULL, NULL, 0, exe_module_sp, NULL, NULL); if (exe_module_sp->GetObjectFile()) return error; exe_module_sp.reset(); } // No valid architecture was specified or the exact ARM slice wasn't // found so ask the platform for the architectures that we should be // using (in the correct order) and see if we can find a match that way StreamString arch_names; ArchSpec platform_arch; for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx) { error = ModuleList::GetSharedModule (resolved_exe_file, platform_arch, NULL, NULL, 0, exe_module_sp, NULL, NULL); // Did we find an executable using one of the if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) break; else error.SetErrorToGenericError(); } if (idx > 0) arch_names.PutCString (", "); arch_names.PutCString (platform_arch.GetArchitectureName()); } if (error.Fail() || !exe_module_sp) { error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s", exe_file.GetDirectory().AsCString(""), exe_file.GetDirectory() ? "/" : "", exe_file.GetFilename().AsCString(""), GetShortPluginName(), arch_names.GetString().c_str()); } } else { error.SetErrorStringWithFormat ("'%s%s%s' does not exist", exe_file.GetDirectory().AsCString(""), exe_file.GetDirectory() ? "/" : "", exe_file.GetFilename().AsCString("")); } return error; }
Error PlatformFreeBSD::ResolveExecutable (const FileSpec &exe_file, const ArchSpec &exe_arch, lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr) { Error error; // Nothing special to do here, just use the actual file and architecture char exe_path[PATH_MAX]; FileSpec resolved_exe_file (exe_file); if (IsHost()) { // If we have "ls" as the exe_file, resolve the executable loation based on // the current path variables if (!resolved_exe_file.Exists()) { exe_file.GetPath(exe_path, sizeof(exe_path)); resolved_exe_file.SetFile(exe_path, true); } if (!resolved_exe_file.Exists()) resolved_exe_file.ResolveExecutableLocation (); // Resolve any executable within a bundle on MacOSX //Host::ResolveExecutableInBundle (resolved_exe_file); if (resolved_exe_file.Exists()) error.Clear(); else { exe_file.GetPath(exe_path, sizeof(exe_path)); error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path); } } else { if (m_remote_platform_sp) { error = m_remote_platform_sp->ResolveExecutable (exe_file, exe_arch, exe_module_sp, module_search_paths_ptr); } else { // We may connect to a process and use the provided executable (Don't use local $PATH). // Resolve any executable within a bundle on MacOSX Host::ResolveExecutableInBundle (resolved_exe_file); if (resolved_exe_file.Exists()) { error.Clear(); } else { exe_file.GetPath(exe_path, sizeof(exe_path)); error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path); } } } if (error.Success()) { ModuleSpec module_spec (resolved_exe_file, exe_arch); if (module_spec.GetArchitecture().IsValid()) { error = ModuleList::GetSharedModule (module_spec, exe_module_sp, module_search_paths_ptr, NULL, NULL); if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) { exe_module_sp.reset(); error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain the architecture %s", exe_file.GetDirectory().AsCString(""), exe_file.GetDirectory() ? "/" : "", exe_file.GetFilename().AsCString(""), exe_arch.GetArchitectureName()); } } else { // No valid architecture was specified, ask the platform for // the architectures that we should be using (in the correct order) // and see if we can find a match that way StreamString arch_names; ArchSpec platform_arch; for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx) { error = ModuleList::GetSharedModule (module_spec, exe_module_sp, module_search_paths_ptr, NULL, NULL); // Did we find an executable using one of the if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) break; else error.SetErrorToGenericError(); } if (idx > 0) arch_names.PutCString (", "); arch_names.PutCString (platform_arch.GetArchitectureName()); } if (error.Fail() || !exe_module_sp) { error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s", exe_file.GetDirectory().AsCString(""), exe_file.GetDirectory() ? "/" : "", exe_file.GetFilename().AsCString(""), GetShortPluginName(), arch_names.GetString().c_str()); } } } else { error.SetErrorStringWithFormat ("'%s%s%s' does not exist", exe_file.GetDirectory().AsCString(""), exe_file.GetDirectory() ? "/" : "", exe_file.GetFilename().AsCString("")); } return error; }
Error TargetList::CreateTarget ( Debugger &debugger, const FileSpec& file, const ArchSpec& arch, const UUID *uuid_ptr, bool get_dependent_files, TargetSP &target_sp ) { Timer scoped_timer (__PRETTY_FUNCTION__, "TargetList::CreateTarget (file = '%s/%s', arch = '%s', uuid = %p)", file.GetDirectory().AsCString(), file.GetFilename().AsCString(), arch.AsCString(), uuid_ptr); ModuleSP exe_module_sp; FileSpec resolved_file(file); if (!Host::ResolveExecutableInBundle (&resolved_file)) resolved_file = file; Error error = ModuleList::GetSharedModule(resolved_file, arch, uuid_ptr, NULL, 0, exe_module_sp, NULL, NULL); if (exe_module_sp) { target_sp.reset(new Target(debugger)); target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); if (target_sp.get()) { Mutex::Locker locker(m_target_list_mutex); m_current_target_idx = m_target_list.size(); m_target_list.push_back(target_sp); } // target_sp.reset(new Target); // // Let the target resolve any funky bundle paths before we try and get // // the object file... // target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); // if (exe_module_sp->GetObjectFile() == NULL) // { // error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s", // file.GetDirectory().AsCString(), // file.GetDirectory() ? "/" : "", // file.GetFilename().AsCString(), // arch.AsCString()); // } // else // { // if (target_sp.get()) // { // error.Clear(); // Mutex::Locker locker(m_target_list_mutex); // m_current_target_idx = m_target_list.size(); // m_target_list.push_back(target_sp); // } // } } else { target_sp.reset(); } 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::CreateTarget ( Debugger &debugger, const FileSpec& file, const ArchSpec& specified_arch, bool get_dependent_files, PlatformSP &platform_sp, TargetSP &target_sp ) { Timer scoped_timer (__PRETTY_FUNCTION__, "TargetList::CreateTarget (file = '%s/%s', arch = '%s')", file.GetDirectory().AsCString(), file.GetFilename().AsCString(), specified_arch.GetArchitectureName()); Error error; ArchSpec arch(specified_arch); if (platform_sp) { if (arch.IsValid()) { if (!platform_sp->IsCompatibleArchitecture(arch)) platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); } } else if (arch.IsValid()) { platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); } if (!platform_sp) platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); if (!arch.IsValid()) arch = specified_arch; if (file) { ModuleSP exe_module_sp; FileSpec resolved_file(file); if (platform_sp) { FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); error = platform_sp->ResolveExecutable (file, arch, 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%s%s\" doesn't contain architecture %s", file.GetDirectory().AsCString(), file.GetDirectory() ? "/" : "", file.GetFilename().AsCString(), arch.GetArchitectureName()); } else { error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"", file.GetDirectory().AsCString(), file.GetDirectory() ? "/" : "", file.GetFilename().AsCString()); } return error; } target_sp.reset(new Target(debugger, arch, platform_sp)); target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); } } 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)); } if (target_sp) { target_sp->UpdateInstanceName(); Mutex::Locker locker(m_target_list_mutex); m_selected_target_idx = m_target_list.size(); m_target_list.push_back(target_sp); } return error; }