diff options
Diffstat (limited to 'source/Target/TargetList.cpp')
-rw-r--r-- | source/Target/TargetList.cpp | 1154 |
1 files changed, 510 insertions, 644 deletions
diff --git a/source/Target/TargetList.cpp b/source/Target/TargetList.cpp index 349544676919..0637cffddcc1 100644 --- a/source/Target/TargetList.cpp +++ b/source/Target/TargetList.cpp @@ -32,734 +32,600 @@ using namespace lldb; using namespace lldb_private; -ConstString & -TargetList::GetStaticBroadcasterClass () -{ - static ConstString class_name ("lldb.targetList"); - return class_name; +ConstString &TargetList::GetStaticBroadcasterClass() { + static ConstString class_name("lldb.targetList"); + return class_name; } //---------------------------------------------------------------------- // TargetList constructor //---------------------------------------------------------------------- TargetList::TargetList(Debugger &debugger) - : Broadcaster(debugger.GetBroadcasterManager(), TargetList::GetStaticBroadcasterClass().AsCString()), - m_target_list(), - m_target_list_mutex(), - m_selected_target_idx(0) -{ - CheckInWithManager(); + : Broadcaster(debugger.GetBroadcasterManager(), + TargetList::GetStaticBroadcasterClass().AsCString()), + m_target_list(), m_target_list_mutex(), m_selected_target_idx(0) { + CheckInWithManager(); } //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- -TargetList::~TargetList() -{ - std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); - m_target_list.clear(); +TargetList::~TargetList() { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + m_target_list.clear(); } -Error -TargetList::CreateTarget (Debugger &debugger, - const char *user_exe_path, - const char *triple_cstr, - bool get_dependent_files, - const OptionGroupPlatform *platform_options, - TargetSP &target_sp) -{ - return CreateTargetInternal (debugger, - user_exe_path, - triple_cstr, - get_dependent_files, - platform_options, - target_sp, - false); +Error TargetList::CreateTarget(Debugger &debugger, + llvm::StringRef user_exe_path, + llvm::StringRef triple_str, + bool get_dependent_files, + const OptionGroupPlatform *platform_options, + TargetSP &target_sp) { + return CreateTargetInternal(debugger, user_exe_path, triple_str, + get_dependent_files, platform_options, target_sp, + false); } -Error -TargetList::CreateTarget (Debugger &debugger, - const char *user_exe_path, - const ArchSpec& specified_arch, - bool get_dependent_files, - PlatformSP &platform_sp, - TargetSP &target_sp) -{ - return CreateTargetInternal (debugger, - user_exe_path, - specified_arch, - get_dependent_files, - platform_sp, - target_sp, - false); +Error TargetList::CreateTarget(Debugger &debugger, + llvm::StringRef user_exe_path, + const ArchSpec &specified_arch, + bool get_dependent_files, + PlatformSP &platform_sp, TargetSP &target_sp) { + return CreateTargetInternal(debugger, user_exe_path, specified_arch, + get_dependent_files, platform_sp, target_sp, + false); } -Error -TargetList::CreateTargetInternal (Debugger &debugger, - const char *user_exe_path, - const char *triple_cstr, - bool get_dependent_files, - const OptionGroupPlatform *platform_options, - TargetSP &target_sp, - bool is_dummy_target) -{ - Error error; - PlatformSP platform_sp; - - // This is purposely left empty unless it is specified by triple_cstr. - // If not initialized via triple_cstr, then the currently selected platform - // will set the architecture correctly. - const ArchSpec arch(triple_cstr); - if (triple_cstr && triple_cstr[0]) - { - if (!arch.IsValid()) - { - error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr); - return error; - } +Error TargetList::CreateTargetInternal( + Debugger &debugger, llvm::StringRef user_exe_path, + llvm::StringRef triple_str, bool get_dependent_files, + const OptionGroupPlatform *platform_options, TargetSP &target_sp, + bool is_dummy_target) { + Error error; + PlatformSP platform_sp; + + // This is purposely left empty unless it is specified by triple_cstr. + // If not initialized via triple_cstr, then the currently selected platform + // will set the architecture correctly. + const ArchSpec arch(triple_str); + if (!triple_str.empty()) { + if (!arch.IsValid()) { + error.SetErrorStringWithFormat("invalid triple '%s'", + triple_str.str().c_str()); + return error; } - - ArchSpec platform_arch(arch); + } - bool prefer_platform_arch = false; - - CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); + ArchSpec platform_arch(arch); - // let's see if there is already an existing plaform before we go creating another... - platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); + bool prefer_platform_arch = false; - if (platform_options && platform_options->PlatformWasSpecified ()) - { - // Create a new platform if it doesn't match the selected platform - if (!platform_options->PlatformMatches(platform_sp)) - { - const bool select_platform = true; - platform_sp = platform_options->CreatePlatformWithOptions (interpreter, - arch, - select_platform, - error, - platform_arch); - if (!platform_sp) - return error; - } + CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); + + // let's see if there is already an existing plaform before we go creating + // another... + platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); + + if (platform_options && platform_options->PlatformWasSpecified()) { + // Create a new platform if it doesn't match the selected platform + if (!platform_options->PlatformMatches(platform_sp)) { + const bool select_platform = true; + platform_sp = platform_options->CreatePlatformWithOptions( + interpreter, arch, select_platform, error, platform_arch); + if (!platform_sp) + return error; } - - if (user_exe_path && user_exe_path[0]) - { - ModuleSpecList module_specs; - ModuleSpec module_spec; - module_spec.GetFileSpec().SetFile(user_exe_path, true); - - // Resolve the executable in case we are given a path to a application bundle - // like a .app bundle on MacOSX - Host::ResolveExecutableInBundle (module_spec.GetFileSpec()); - - lldb::offset_t file_offset = 0; - lldb::offset_t file_size = 0; - const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs); - if (num_specs > 0) - { - ModuleSpec matching_module_spec; - - if (num_specs == 1) - { - if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) - { - if (platform_arch.IsValid()) - { - if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture())) - { - // If the OS or vendor weren't specified, then adopt the module's - // architecture so that the platform matching can be more accurate - if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified()) - { - prefer_platform_arch = true; - platform_arch = matching_module_spec.GetArchitecture(); - } - } - else - { - StreamString platform_arch_strm; - StreamString module_arch_strm; - - platform_arch.DumpTriple(platform_arch_strm); - matching_module_spec.GetArchitecture().DumpTriple(module_arch_strm); - error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'", - platform_arch_strm.GetString().c_str(), - module_arch_strm.GetString().c_str(), - module_spec.GetFileSpec().GetPath().c_str()); - return error; - } - } - else - { - // Only one arch and none was specified - prefer_platform_arch = true; - platform_arch = matching_module_spec.GetArchitecture(); - } - } + } + + if (!user_exe_path.empty()) { + ModuleSpecList module_specs; + ModuleSpec module_spec; + module_spec.GetFileSpec().SetFile(user_exe_path, true); + + // Resolve the executable in case we are given a path to a application + // bundle + // like a .app bundle on MacOSX + Host::ResolveExecutableInBundle(module_spec.GetFileSpec()); + + lldb::offset_t file_offset = 0; + lldb::offset_t file_size = 0; + const size_t num_specs = ObjectFile::GetModuleSpecifications( + module_spec.GetFileSpec(), file_offset, file_size, module_specs); + if (num_specs > 0) { + ModuleSpec matching_module_spec; + + if (num_specs == 1) { + if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) { + if (platform_arch.IsValid()) { + if (platform_arch.IsCompatibleMatch( + matching_module_spec.GetArchitecture())) { + // If the OS or vendor weren't specified, then adopt the module's + // architecture so that the platform matching can be more accurate + if (!platform_arch.TripleOSWasSpecified() || + !platform_arch.TripleVendorWasSpecified()) { + prefer_platform_arch = true; + platform_arch = matching_module_spec.GetArchitecture(); + } + } else { + StreamString platform_arch_strm; + StreamString module_arch_strm; + + platform_arch.DumpTriple(platform_arch_strm); + matching_module_spec.GetArchitecture().DumpTriple( + module_arch_strm); + error.SetErrorStringWithFormat( + "the specified architecture '%s' is not compatible with '%s' " + "in '%s'", + platform_arch_strm.GetData(), module_arch_strm.GetData(), + module_spec.GetFileSpec().GetPath().c_str()); + return error; } - else - { - if (arch.IsValid()) - { - module_spec.GetArchitecture() = arch; - if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec)) - { - prefer_platform_arch = true; - platform_arch = matching_module_spec.GetArchitecture(); - } + } else { + // Only one arch and none was specified + prefer_platform_arch = true; + platform_arch = matching_module_spec.GetArchitecture(); + } + } + } else { + if (arch.IsValid()) { + module_spec.GetArchitecture() = arch; + if (module_specs.FindMatchingModuleSpec(module_spec, + matching_module_spec)) { + prefer_platform_arch = true; + platform_arch = matching_module_spec.GetArchitecture(); + } + } else { + // No architecture specified, check if there is only one platform for + // all of the architectures. + + typedef std::vector<PlatformSP> PlatformList; + PlatformList platforms; + PlatformSP host_platform_sp = Platform::GetHostPlatform(); + for (size_t i = 0; i < num_specs; ++i) { + ModuleSpec module_spec; + if (module_specs.GetModuleSpecAtIndex(i, module_spec)) { + // See if there was a selected platform and check that first + // since the user may have specified it. + if (platform_sp) { + if (platform_sp->IsCompatibleArchitecture( + module_spec.GetArchitecture(), false, nullptr)) { + platforms.push_back(platform_sp); + continue; } - else - { - // No architecture specified, check if there is only one platform for - // all of the architectures. - - typedef std::vector<PlatformSP> PlatformList; - PlatformList platforms; - PlatformSP host_platform_sp = Platform::GetHostPlatform(); - for (size_t i=0; i<num_specs; ++i) - { - ModuleSpec module_spec; - if (module_specs.GetModuleSpecAtIndex(i, module_spec)) - { - // See if there was a selected platform and check that first - // since the user may have specified it. - if (platform_sp) - { - if (platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, nullptr)) - { - platforms.push_back(platform_sp); - continue; - } - } - - // Next check the host platform it if wasn't already checked above - if (host_platform_sp && (!platform_sp || host_platform_sp->GetName() != platform_sp->GetName())) - { - if (host_platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, nullptr)) - { - platforms.push_back(host_platform_sp); - continue; - } - } - - // Just find a platform that matches the architecture in the executable file - PlatformSP fallback_platform_sp (Platform::GetPlatformForArchitecture(module_spec.GetArchitecture(), nullptr)); - if (fallback_platform_sp) - { - platforms.push_back(fallback_platform_sp); - } - } - } - - Platform *platform_ptr = nullptr; - bool more_than_one_platforms = false; - for (const auto &the_platform_sp : platforms) - { - if (platform_ptr) - { - if (platform_ptr->GetName() != the_platform_sp->GetName()) - { - more_than_one_platforms = true; - platform_ptr = nullptr; - break; - } - } - else - { - platform_ptr = the_platform_sp.get(); - } - } - - if (platform_ptr) - { - // All platforms for all modules in the exectuable match, so we can select this platform - platform_sp = platforms.front(); - } - else if (more_than_one_platforms == false) - { - // No platforms claim to support this file - error.SetErrorString ("No matching platforms found for this file, specify one with the --platform option"); - return error; - } - else - { - // More than one platform claims to support this file, so the --platform option must be specified - StreamString error_strm; - std::set<Platform *> platform_set; - error_strm.Printf ("more than one platform supports this executable ("); - for (const auto &the_platform_sp : platforms) - { - if (platform_set.find(the_platform_sp.get()) == platform_set.end()) - { - if (!platform_set.empty()) - error_strm.PutCString(", "); - error_strm.PutCString(the_platform_sp->GetName().GetCString()); - platform_set.insert(the_platform_sp.get()); - } - } - error_strm.Printf("), use the --platform option to specify a platform"); - error.SetErrorString(error_strm.GetString().c_str()); - return error; - } + } + + // Next check the host platform it if wasn't already checked above + if (host_platform_sp && + (!platform_sp || + host_platform_sp->GetName() != platform_sp->GetName())) { + if (host_platform_sp->IsCompatibleArchitecture( + module_spec.GetArchitecture(), false, nullptr)) { + platforms.push_back(host_platform_sp); + continue; } + } + + // Just find a platform that matches the architecture in the + // executable file + PlatformSP fallback_platform_sp( + Platform::GetPlatformForArchitecture( + module_spec.GetArchitecture(), nullptr)); + if (fallback_platform_sp) { + platforms.push_back(fallback_platform_sp); + } + } + } + + Platform *platform_ptr = nullptr; + bool more_than_one_platforms = false; + for (const auto &the_platform_sp : platforms) { + if (platform_ptr) { + if (platform_ptr->GetName() != the_platform_sp->GetName()) { + more_than_one_platforms = true; + platform_ptr = nullptr; + break; + } + } else { + platform_ptr = the_platform_sp.get(); } + } + + if (platform_ptr) { + // All platforms for all modules in the exectuable match, so we can + // select this platform + platform_sp = platforms.front(); + } else if (more_than_one_platforms == false) { + // No platforms claim to support this file + error.SetErrorString("No matching platforms found for this file, " + "specify one with the --platform option"); + return error; + } else { + // More than one platform claims to support this file, so the + // --platform option must be specified + StreamString error_strm; + std::set<Platform *> platform_set; + error_strm.Printf( + "more than one platform supports this executable ("); + for (const auto &the_platform_sp : platforms) { + if (platform_set.find(the_platform_sp.get()) == + platform_set.end()) { + if (!platform_set.empty()) + error_strm.PutCString(", "); + error_strm.PutCString(the_platform_sp->GetName().GetCString()); + platform_set.insert(the_platform_sp.get()); + } + } + error_strm.Printf( + "), use the --platform option to specify a platform"); + error.SetErrorString(error_strm.GetString()); + return error; + } } + } } - - // If we have a valid architecture, make sure the current platform is - // compatible with that architecture - if (!prefer_platform_arch && arch.IsValid()) - { - if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) - { - platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); - if (!is_dummy_target && platform_sp) - debugger.GetPlatformList().SetSelectedPlatform(platform_sp); - } + } + + // If we have a valid architecture, make sure the current platform is + // compatible with that architecture + if (!prefer_platform_arch && arch.IsValid()) { + if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) { + platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); + if (!is_dummy_target && platform_sp) + debugger.GetPlatformList().SetSelectedPlatform(platform_sp); } - else if (platform_arch.IsValid()) - { - // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with - // a single architecture which should be used - ArchSpec fixed_platform_arch; - if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch)) - { - platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch); - if (!is_dummy_target && platform_sp) - debugger.GetPlatformList().SetSelectedPlatform(platform_sp); - } + } else if (platform_arch.IsValid()) { + // if "arch" isn't valid, yet "platform_arch" is, it means we have an + // executable file with + // a single architecture which should be used + ArchSpec fixed_platform_arch; + if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, + &fixed_platform_arch)) { + platform_sp = Platform::GetPlatformForArchitecture(platform_arch, + &fixed_platform_arch); + if (!is_dummy_target && platform_sp) + debugger.GetPlatformList().SetSelectedPlatform(platform_sp); } - - if (!platform_arch.IsValid()) - platform_arch = arch; - - error = TargetList::CreateTargetInternal (debugger, - user_exe_path, - platform_arch, - get_dependent_files, - platform_sp, - target_sp, - is_dummy_target); - return error; -} + } -lldb::TargetSP -TargetList::GetDummyTarget (lldb_private::Debugger &debugger) -{ - // FIXME: Maybe the dummy target should be per-Debugger - if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid()) - { - ArchSpec arch(Target::GetDefaultArchitecture()); - if (!arch.IsValid()) - arch = HostInfo::GetArchitecture(); - Error err = CreateDummyTarget(debugger, - arch.GetTriple().getTriple().c_str(), - m_dummy_target_sp); - } + if (!platform_arch.IsValid()) + platform_arch = arch; - return m_dummy_target_sp; + error = TargetList::CreateTargetInternal( + debugger, user_exe_path, platform_arch, get_dependent_files, platform_sp, + target_sp, is_dummy_target); + return error; } -Error -TargetList::CreateDummyTarget (Debugger &debugger, - const char *specified_arch_name, - lldb::TargetSP &target_sp) -{ - PlatformSP host_platform_sp(Platform::GetHostPlatform()); - return CreateTargetInternal (debugger, - (const char *) nullptr, - specified_arch_name, - false, - (const OptionGroupPlatform *) nullptr, - target_sp, - true); +lldb::TargetSP TargetList::GetDummyTarget(lldb_private::Debugger &debugger) { + // FIXME: Maybe the dummy target should be per-Debugger + if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid()) { + ArchSpec arch(Target::GetDefaultArchitecture()); + if (!arch.IsValid()) + arch = HostInfo::GetArchitecture(); + Error err = CreateDummyTarget( + debugger, arch.GetTriple().getTriple().c_str(), m_dummy_target_sp); + } + + return m_dummy_target_sp; } -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, nullptr)) - platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); - } - - if (!platform_sp) - platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); +Error TargetList::CreateDummyTarget(Debugger &debugger, + llvm::StringRef specified_arch_name, + lldb::TargetSP &target_sp) { + PlatformSP host_platform_sp(Platform::GetHostPlatform()); + return CreateTargetInternal( + debugger, (const char *)nullptr, specified_arch_name, false, + (const OptionGroupPlatform *)nullptr, target_sp, true); +} - 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); - } +Error TargetList::CreateTargetInternal(Debugger &debugger, + llvm::StringRef 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(LLVM_PRETTY_FUNCTION, + "TargetList::CreateTarget (file = '%s', arch = '%s')", + user_exe_path.str().c_str(), + specified_arch.GetArchitectureName()); + Error error; + + ArchSpec arch(specified_arch); + + if (arch.IsValid()) { + if (!platform_sp || + !platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) + platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); + } + + if (!platform_sp) + platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); - 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; - } - } - } + if (!arch.IsValid()) + arch = specified_arch; - 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 : nullptr); - } + FileSpec file(user_exe_path, false); + if (!file.Exists() && user_exe_path.startswith("~")) { + // 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 (error.Success() && exe_module_sp) - { - if (exe_module_sp->GetObjectFile() == nullptr) - { - 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)); + 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.empty()) { + // Ignore paths that start with "./" and "../" + if (!user_exe_path.startswith("./") && !user_exe_path.startswith("../")) { + 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, false); + if (cwd_file.Exists()) + file = cwd_file; } + } } - 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)); + + 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 + : nullptr); } - 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); + if (error.Success() && exe_module_sp) { + if (exe_module_sp->GetObjectFile() == nullptr) { + 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.empty()) { + // 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) - { - std::lock_guard<std::recursive_mutex> guard(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; - } + // Don't put the dummy target in the target list, it's held separately. + if (!is_dummy_target) { + std::lock_guard<std::recursive_mutex> guard(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; + return error; } -bool -TargetList::DeleteTarget (TargetSP &target_sp) -{ - std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); - collection::iterator pos, end = m_target_list.end(); +bool TargetList::DeleteTarget(TargetSP &target_sp) { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + collection::iterator pos, end = m_target_list.end(); - for (pos = m_target_list.begin(); pos != end; ++pos) - { - if (pos->get() == target_sp.get()) - { - m_target_list.erase(pos); - return true; - } + for (pos = m_target_list.begin(); pos != end; ++pos) { + if (pos->get() == target_sp.get()) { + m_target_list.erase(pos); + return true; } - return false; + } + return false; } -TargetSP -TargetList::FindTargetWithExecutableAndArchitecture(const FileSpec &exe_file_spec, - const ArchSpec *exe_arch_ptr) const -{ - std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); - TargetSP target_sp; - bool full_match = (bool)exe_file_spec.GetDirectory(); - - collection::const_iterator pos, end = m_target_list.end(); - for (pos = m_target_list.begin(); pos != end; ++pos) - { - Module *exe_module = (*pos)->GetExecutableModulePointer(); - - if (exe_module) - { - if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) - { - if (exe_arch_ptr) - { - if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) - continue; - } - target_sp = *pos; - break; - } +TargetSP TargetList::FindTargetWithExecutableAndArchitecture( + const FileSpec &exe_file_spec, const ArchSpec *exe_arch_ptr) const { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + TargetSP target_sp; + bool full_match = (bool)exe_file_spec.GetDirectory(); + + collection::const_iterator pos, end = m_target_list.end(); + for (pos = m_target_list.begin(); pos != end; ++pos) { + Module *exe_module = (*pos)->GetExecutableModulePointer(); + + if (exe_module) { + if (FileSpec::Equal(exe_file_spec, exe_module->GetFileSpec(), + full_match)) { + if (exe_arch_ptr) { + if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) + continue; } + target_sp = *pos; + break; + } } - return target_sp; + } + return target_sp; } -TargetSP -TargetList::FindTargetWithProcessID (lldb::pid_t pid) const -{ - std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); - TargetSP target_sp; - collection::const_iterator pos, end = m_target_list.end(); - for (pos = m_target_list.begin(); pos != end; ++pos) - { - Process* process = (*pos)->GetProcessSP().get(); - if (process && process->GetID() == pid) - { - target_sp = *pos; - break; - } +TargetSP TargetList::FindTargetWithProcessID(lldb::pid_t pid) const { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + TargetSP target_sp; + collection::const_iterator pos, end = m_target_list.end(); + for (pos = m_target_list.begin(); pos != end; ++pos) { + Process *process = (*pos)->GetProcessSP().get(); + if (process && process->GetID() == pid) { + target_sp = *pos; + break; } - return target_sp; + } + return target_sp; } -TargetSP -TargetList::FindTargetWithProcess (Process *process) const -{ - TargetSP target_sp; - if (process) - { - std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); - collection::const_iterator pos, end = m_target_list.end(); - for (pos = m_target_list.begin(); pos != end; ++pos) - { - if (process == (*pos)->GetProcessSP().get()) - { - target_sp = *pos; - break; - } - } +TargetSP TargetList::FindTargetWithProcess(Process *process) const { + TargetSP target_sp; + if (process) { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + collection::const_iterator pos, end = m_target_list.end(); + for (pos = m_target_list.begin(); pos != end; ++pos) { + if (process == (*pos)->GetProcessSP().get()) { + target_sp = *pos; + break; + } } - return target_sp; + } + return target_sp; } -TargetSP -TargetList::GetTargetSP (Target *target) const -{ - TargetSP target_sp; - if (target) - { - std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); - collection::const_iterator pos, end = m_target_list.end(); - for (pos = m_target_list.begin(); pos != end; ++pos) - { - if (target == (*pos).get()) - { - target_sp = *pos; - break; - } - } +TargetSP TargetList::GetTargetSP(Target *target) const { + TargetSP target_sp; + if (target) { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + collection::const_iterator pos, end = m_target_list.end(); + for (pos = m_target_list.begin(); pos != end; ++pos) { + if (target == (*pos).get()) { + target_sp = *pos; + break; + } } - return target_sp; + } + return target_sp; } -uint32_t -TargetList::SendAsyncInterrupt (lldb::pid_t pid) -{ - uint32_t num_async_interrupts_sent = 0; - - if (pid != LLDB_INVALID_PROCESS_ID) - { - TargetSP target_sp(FindTargetWithProcessID (pid)); - if (target_sp) - { - Process* process = target_sp->GetProcessSP().get(); - if (process) - { - process->SendAsyncInterrupt(); - ++num_async_interrupts_sent; - } - } - } - else - { - // We don't have a valid pid to broadcast to, so broadcast to the target - // list's async broadcaster... - BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr); +uint32_t TargetList::SendAsyncInterrupt(lldb::pid_t pid) { + uint32_t num_async_interrupts_sent = 0; + + if (pid != LLDB_INVALID_PROCESS_ID) { + TargetSP target_sp(FindTargetWithProcessID(pid)); + if (target_sp) { + Process *process = target_sp->GetProcessSP().get(); + if (process) { + process->SendAsyncInterrupt(); + ++num_async_interrupts_sent; + } } + } else { + // We don't have a valid pid to broadcast to, so broadcast to the target + // list's async broadcaster... + BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr); + } - return num_async_interrupts_sent; + return num_async_interrupts_sent; } -uint32_t -TargetList::SignalIfRunning (lldb::pid_t pid, int signo) -{ - uint32_t num_signals_sent = 0; - Process *process = nullptr; - if (pid == LLDB_INVALID_PROCESS_ID) - { - // Signal all processes with signal - std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); - collection::iterator pos, end = m_target_list.end(); - for (pos = m_target_list.begin(); pos != end; ++pos) - { - process = (*pos)->GetProcessSP().get(); - if (process) - { - if (process->IsAlive()) - { - ++num_signals_sent; - process->Signal (signo); - } - } +uint32_t TargetList::SignalIfRunning(lldb::pid_t pid, int signo) { + uint32_t num_signals_sent = 0; + Process *process = nullptr; + if (pid == LLDB_INVALID_PROCESS_ID) { + // Signal all processes with signal + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + collection::iterator pos, end = m_target_list.end(); + for (pos = m_target_list.begin(); pos != end; ++pos) { + process = (*pos)->GetProcessSP().get(); + if (process) { + if (process->IsAlive()) { + ++num_signals_sent; + process->Signal(signo); } + } } - else - { - // Signal a specific process with signal - TargetSP target_sp(FindTargetWithProcessID (pid)); - if (target_sp) - { - process = target_sp->GetProcessSP().get(); - if (process) - { - if (process->IsAlive()) - { - ++num_signals_sent; - process->Signal (signo); - } - } + } else { + // Signal a specific process with signal + TargetSP target_sp(FindTargetWithProcessID(pid)); + if (target_sp) { + process = target_sp->GetProcessSP().get(); + if (process) { + if (process->IsAlive()) { + ++num_signals_sent; + process->Signal(signo); } + } } - return num_signals_sent; + } + return num_signals_sent; } -int -TargetList::GetNumTargets () const -{ - std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); - return m_target_list.size(); +int TargetList::GetNumTargets() const { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + return m_target_list.size(); } -lldb::TargetSP -TargetList::GetTargetAtIndex (uint32_t idx) const -{ - TargetSP target_sp; - std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); - if (idx < m_target_list.size()) - target_sp = m_target_list[idx]; - return target_sp; +lldb::TargetSP TargetList::GetTargetAtIndex(uint32_t idx) const { + TargetSP target_sp; + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + if (idx < m_target_list.size()) + target_sp = m_target_list[idx]; + return target_sp; } -uint32_t -TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const -{ - std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); - size_t num_targets = m_target_list.size(); - for (size_t idx = 0; idx < num_targets; idx++) - { - if (target_sp == m_target_list[idx]) - return idx; - } - return UINT32_MAX; +uint32_t TargetList::GetIndexOfTarget(lldb::TargetSP target_sp) const { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + size_t num_targets = m_target_list.size(); + for (size_t idx = 0; idx < num_targets; idx++) { + if (target_sp == m_target_list[idx]) + return idx; + } + return UINT32_MAX; } -uint32_t -TargetList::SetSelectedTarget (Target* target) -{ - std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); - collection::const_iterator pos, - begin = m_target_list.begin(), - end = m_target_list.end(); - for (pos = begin; pos != end; ++pos) - { - if (pos->get() == target) - { - m_selected_target_idx = std::distance (begin, pos); - return m_selected_target_idx; - } +uint32_t TargetList::SetSelectedTarget(Target *target) { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + collection::const_iterator pos, begin = m_target_list.begin(), + end = m_target_list.end(); + for (pos = begin; pos != end; ++pos) { + if (pos->get() == target) { + m_selected_target_idx = std::distance(begin, pos); + return m_selected_target_idx; } - m_selected_target_idx = 0; - return m_selected_target_idx; + } + m_selected_target_idx = 0; + return m_selected_target_idx; } -lldb::TargetSP -TargetList::GetSelectedTarget () -{ - std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); - if (m_selected_target_idx >= m_target_list.size()) - m_selected_target_idx = 0; - return GetTargetAtIndex (m_selected_target_idx); +lldb::TargetSP TargetList::GetSelectedTarget() { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + if (m_selected_target_idx >= m_target_list.size()) + m_selected_target_idx = 0; + return GetTargetAtIndex(m_selected_target_idx); } |