diff options
-rw-r--r-- | lldb/source/Core/ArchSpec.cpp | 32 | ||||
-rw-r--r-- | lldb/source/Core/Module.cpp | 46 | ||||
-rw-r--r-- | lldb/source/Host/macosx/Host.mm | 38 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | 143 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h | 6 | ||||
-rw-r--r-- | lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp | 59 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp | 3 | ||||
-rw-r--r-- | lldb/tools/debugserver/source/RNBRemote.cpp | 56 |
8 files changed, 302 insertions, 81 deletions
diff --git a/lldb/source/Core/ArchSpec.cpp b/lldb/source/Core/ArchSpec.cpp index 6d708f158ed..82764699b8c 100644 --- a/lldb/source/Core/ArchSpec.cpp +++ b/lldb/source/Core/ArchSpec.cpp @@ -844,10 +844,34 @@ ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const if (rhs_os_specified && lhs_os_specified) return false; } - // Only fail if both os types are not unknown - if (lhs_triple_os != llvm::Triple::UnknownOS && - rhs_triple_os != llvm::Triple::UnknownOS) - return false; + + bool ios_simulator_compatible = false; + // Check for iOS desktop simulator matches where: + // x86_64-apple-ios is compatible with x86_64-apple-macosx + // i386-apple-ios is compatible with i386-apple-macosx + if (lhs_triple_vendor == llvm::Triple::Apple) + { + const llvm::Triple::ArchType lhs_arch = lhs_triple.getArch(); + if (lhs_arch == llvm::Triple::x86_64 || + lhs_arch == llvm::Triple::x86) + { + if ((lhs_triple_os == llvm::Triple::MacOSX && rhs_triple_os == llvm::Triple::IOS ) || + (lhs_triple_os == llvm::Triple::IOS && rhs_triple_os == llvm::Triple::MacOSX )) + { + ios_simulator_compatible = true; + } + + } + } + + // Only fail if both os types are not unknown or if we determined the triples + // match for x86_64 or x86 iOS simulator + if (!ios_simulator_compatible) + { + if (lhs_triple_os != llvm::Triple::UnknownOS && + rhs_triple_os != llvm::Triple::UnknownOS) + return false; + } } const llvm::Triple::EnvironmentType lhs_triple_env = lhs_triple.getEnvironment(); diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index cda6f277847..6a725474921 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -187,16 +187,46 @@ Module::Module (const ModuleSpec &module_spec) : ModuleSpec matching_module_spec; if (modules_specs.FindMatchingModuleSpec(module_spec, matching_module_spec) == 0) return; - m_mod_time = module_spec.GetFileSpec().GetModificationTime(); - if (module_spec.GetArchitecture().IsValid()) + + if (module_spec.GetFileSpec()) + m_mod_time = module_spec.GetFileSpec().GetModificationTime(); + else if (matching_module_spec.GetFileSpec()) + m_mod_time = matching_module_spec.GetFileSpec().GetModificationTime(); + + // Copy the architecture from the actual spec if we got one back, else use the one that was specified + if (matching_module_spec.GetArchitecture().IsValid()) + m_arch = matching_module_spec.GetArchitecture(); + else if (module_spec.GetArchitecture().IsValid()) m_arch = module_spec.GetArchitecture(); + + // Copy the file spec over and use the specfied one (if there was one) so we + // don't use a path that might have gotten resolved a path in 'matching_module_spec' + if (module_spec.GetFileSpec()) + m_file = module_spec.GetFileSpec(); + else if (matching_module_spec.GetFileSpec()) + m_file = matching_module_spec.GetFileSpec(); + + // Copy the platform file spec over + if (module_spec.GetPlatformFileSpec()) + m_platform_file = module_spec.GetPlatformFileSpec(); + else if (matching_module_spec.GetPlatformFileSpec()) + m_platform_file = matching_module_spec.GetPlatformFileSpec(); + + // Copy the symbol file spec over + if (module_spec.GetSymbolFileSpec()) + m_symfile_spec = module_spec.GetSymbolFileSpec(); + else if (matching_module_spec.GetSymbolFileSpec()) + m_symfile_spec = matching_module_spec.GetSymbolFileSpec(); + + // Copy the object name over + if (matching_module_spec.GetObjectName()) + m_object_name = matching_module_spec.GetObjectName(); else - m_arch = matching_module_spec.GetArchitecture(); - m_mod_time = module_spec.GetFileSpec().GetModificationTime(); - m_file = module_spec.GetFileSpec(); - m_platform_file = module_spec.GetPlatformFileSpec(); - m_symfile_spec = module_spec.GetSymbolFileSpec(); - m_object_name = module_spec.GetObjectName(); + m_object_name = module_spec.GetObjectName(); + + // Always trust the object offset (file offset) and object modification + // time (for mod time in a BSD static archive) of from the matching + // module specification m_object_offset = matching_module_spec.GetObjectOffset(); m_object_mod_time = matching_module_spec.GetObjectModificationTime(); diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm index 4817f412e0b..d32a1d6817b 100644 --- a/lldb/source/Host/macosx/Host.mm +++ b/lldb/source/Host/macosx/Host.mm @@ -1151,6 +1151,11 @@ GetMacOSXProcessArgs (const ProcessInstanceInfoMatch *match_info_ptr, uint32_t argc = data.GetU32 (&offset); const char *cstr; + + llvm::Triple &triple = process_info.GetArchitecture().GetTriple(); + const llvm::Triple::ArchType triple_arch = triple.getArch(); + const bool check_for_ios_simulator = (triple_arch == llvm::Triple::x86 || triple_arch == llvm::Triple::x86_64); + cstr = data.GetCStr (&offset); if (cstr) { @@ -1177,6 +1182,21 @@ GetMacOSXProcessArgs (const ProcessInstanceInfoMatch *match_info_ptr, if (cstr) proc_args.AppendArgument(cstr); } + + Args &proc_env = process_info.GetEnvironmentEntries (); + while ((cstr = data.GetCStr(&offset))) + { + if (cstr[0] == '\0') + break; + + if (check_for_ios_simulator) + { + if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 0) + process_info.GetArchitecture().GetTriple().setOS(llvm::Triple::IOS); + } + + proc_env.AppendArgument(cstr); + } return true; } } @@ -1285,11 +1305,14 @@ Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstance // Make sure our info matches before we go fetch the name and cpu type if (match_info.Matches (process_info)) { - if (GetMacOSXProcessArgs (&match_info, process_info)) + // Get CPU type first so we can know to look for iOS simulator is we have x86 or x86_64 + if (GetMacOSXProcessCPUType (process_info)) { - GetMacOSXProcessCPUType (process_info); - if (match_info.Matches (process_info)) - process_infos.Append (process_info); + if (GetMacOSXProcessArgs (&match_info, process_info)) + { + if (match_info.Matches (process_info)) + process_infos.Append (process_info); + } } } } @@ -1301,11 +1324,12 @@ Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) { process_info.SetProcessID(pid); bool success = false; - - if (GetMacOSXProcessArgs (NULL, process_info)) + + // Get CPU type first so we can know to look for iOS simulator is we have x86 or x86_64 + if (GetMacOSXProcessCPUType (process_info)) success = true; - if (GetMacOSXProcessCPUType (process_info)) + if (GetMacOSXProcessArgs (NULL, process_info)) success = true; if (GetMacOSXProcessUserAndGroup (process_info)) diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 6866a068ef7..dc31eba5576 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -647,18 +647,15 @@ ObjectFileMachO::GetModuleSpecifications (const lldb_private::FileSpec& file, { ModuleSpec spec; spec.GetFileSpec() = file; - spec.GetArchitecture().SetArchitecture(eArchTypeMachO, - header.cputype, - header.cpusubtype); - if (header.filetype == MH_PRELOAD) // 0x5u - { - // Set OS to "unknown" - this is a standalone binary with no dyld et al - spec.GetArchitecture().GetTriple().setOS (llvm::Triple::UnknownOS); - } - if (spec.GetArchitecture().IsValid()) + spec.SetObjectOffset(file_offset); + + if (GetArchitecture (header, data, data_offset, spec.GetArchitecture())) { - GetUUID (header, data, data_offset, spec.GetUUID()); - specs.Append(spec); + if (spec.GetArchitecture().IsValid()) + { + GetUUID (header, data, data_offset, spec.GetUUID()); + specs.Append(spec); + } } } } @@ -854,36 +851,40 @@ ObjectFileMachO::ParseHeader () { m_data.GetU32(&offset, &m_header.cputype, 6); - ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype); - - // Check if the module has a required architecture - const ArchSpec &module_arch = module_sp->GetArchitecture(); - if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch)) - return false; - - if (SetModulesArchitecture (mach_arch)) + + ArchSpec mach_arch; + + if (GetArchitecture (mach_arch)) { - const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic); - if (m_data.GetByteSize() < header_and_lc_size) + // Check if the module has a required architecture + const ArchSpec &module_arch = module_sp->GetArchitecture(); + if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch)) + return false; + + if (SetModulesArchitecture (mach_arch)) { - DataBufferSP data_sp; - ProcessSP process_sp (m_process_wp.lock()); - if (process_sp) - { - data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size); - } - else + const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic); + if (m_data.GetByteSize() < header_and_lc_size) { - // Read in all only the load command data from the file on disk - data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size); - if (data_sp->GetByteSize() != header_and_lc_size) - return false; + DataBufferSP data_sp; + ProcessSP process_sp (m_process_wp.lock()); + if (process_sp) + { + data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size); + } + else + { + // Read in all only the load command data from the file on disk + data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size); + if (data_sp->GetByteSize() != header_and_lc_size) + return false; + } + if (data_sp) + m_data.SetData (data_sp); } - if (data_sp) - m_data.SetData (data_sp); } + return true; } - return true; } else { @@ -2182,7 +2183,8 @@ ObjectFileMachO::ParseSymtab () // Next we need to determine the correct path for the dyld shared cache. - ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype); + ArchSpec header_arch; + GetArchitecture(header_arch); char dsc_path[PATH_MAX]; snprintf(dsc_path, sizeof(dsc_path), "%s%s%s", @@ -4098,7 +4100,8 @@ ObjectFileMachO::Dump (Stream *s) else s->PutCString("ObjectFileMachO32"); - ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype); + ArchSpec header_arch; + GetArchitecture(header_arch); *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; @@ -4155,6 +4158,61 @@ ObjectFileMachO::GetUUID (const llvm::MachO::mach_header &header, return false; } + +bool +ObjectFileMachO::GetArchitecture (const llvm::MachO::mach_header &header, + const lldb_private::DataExtractor &data, + lldb::offset_t lc_offset, + ArchSpec &arch) +{ + arch.SetArchitecture (eArchTypeMachO, header.cputype, header.cpusubtype); + + if (arch.IsValid()) + { + llvm::Triple &triple = arch.GetTriple(); + if (header.filetype == MH_PRELOAD) + { + // Set OS to "unknown" - this is a standalone binary with no dyld et al + triple.setOS(llvm::Triple::UnknownOS); + return true; + } + else + { + struct load_command load_cmd; + + lldb::offset_t offset = lc_offset; + for (uint32_t i=0; i<header.ncmds; ++i) + { + const lldb::offset_t cmd_offset = offset; + if (data.GetU32(&offset, &load_cmd, 2) == NULL) + break; + + switch (load_cmd.cmd) + { + case LC_VERSION_MIN_IPHONEOS: + triple.setOS (llvm::Triple::IOS); + return true; + + case LC_VERSION_MIN_MACOSX: + triple.setOS (llvm::Triple::MacOSX); + return true; + + default: + break; + } + + offset = cmd_offset + load_cmd.cmdsize; + } + + if (header.cputype == CPU_TYPE_ARM || header.cputype == CPU_TYPE_ARM64) + triple.setOS (llvm::Triple::IOS); + else + triple.setOS (llvm::Triple::MacOSX); + } + } + return arch.IsValid(); +} + bool ObjectFileMachO::GetUUID (lldb_private::UUID* uuid) { @@ -4627,16 +4685,7 @@ ObjectFileMachO::GetArchitecture (ArchSpec &arch) if (module_sp) { lldb_private::Mutex::Locker locker(module_sp->GetMutex()); - arch.SetArchitecture (eArchTypeMachO, m_header.cputype, m_header.cpusubtype); - - // Files with type MH_PRELOAD are currently used in cases where the image - // debugs at the addresses in the file itself. Below we set the OS to - // unknown to make sure we use the DynamicLoaderStatic()... - if (m_header.filetype == MH_PRELOAD) - { - arch.GetTriple().setOS (llvm::Triple::UnknownOS); - } - return true; + return GetArchitecture (m_header, m_data, MachHeaderSizeFromMagic(m_header.magic), arch); } return false; } diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index dff0b21be80..7b09e5f8bdd 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -182,6 +182,12 @@ protected: lldb::offset_t lc_offset, // Offset to the first load command lldb_private::UUID& uuid); + static bool + GetArchitecture (const llvm::MachO::mach_header &header, + const lldb_private::DataExtractor &data, + lldb::offset_t lc_offset, + lldb_private::ArchSpec &arch); + // Intended for same-host arm device debugging where lldb needs to // detect libraries in the shared cache and augment the nlist entries // with an on-disk dyld_shared_cache file. The process will record diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp index 0a809503d1e..0803f64710e 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp @@ -397,30 +397,63 @@ uint32_t PlatformiOSSimulator::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { - // TODO: if connected, send a packet to get the remote process infos by name - process_infos.Clear(); - return 0; + ProcessInstanceInfoList all_osx_process_infos; + // First we get all OSX processes + const uint32_t n = Host::FindProcesses (match_info, all_osx_process_infos); + + // Now we filter them down to only the iOS triples + for (uint32_t i=0; i<n; ++i) + { + const ProcessInstanceInfo &proc_info = all_osx_process_infos.GetProcessInfoAtIndex(i); + if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::IOS) { + process_infos.Append(proc_info); + } + } + return process_infos.GetSize(); } bool PlatformiOSSimulator::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) { + static const ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture)); + static const ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64)); + if (idx == 0) { - arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture); - return arch.IsValid(); + arch = platform_arch; + if (arch.IsValid()) + { + arch.GetTriple().setOS (llvm::Triple::IOS); + return true; + } } - else if (idx == 1) + else { - ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture)); - ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64)); if (platform_arch.IsExactMatch(platform_arch64)) { - // This macosx platform supports both 32 and 64 bit. Since we already - // returned the 64 bit arch for idx == 0, return the 32 bit arch - // for idx == 1 - arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); - return arch.IsValid(); + // This macosx platform supports both 32 and 64 bit. + if (idx == 1) + { + // 32/64: return "x86_64-apple-macosx" for architecture 1 + arch = platform_arch64; + } + else if (idx == 2 || idx == 3) + { + arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); + if (arch.IsValid()) + { + if (idx == 2) + arch.GetTriple().setOS (llvm::Triple::IOS); + // 32/64: return "i386-apple-ios" for architecture 2 + // 32/64: return "i386-apple-macosx" for architecture 3 + return true; + } + } + } + else if (idx == 1) + { + // This macosx platform supports only 32 bit, so return the *-apple-macosx version + arch = platform_arch; } } return false; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index ab4ed4c5932..9b9fef98c74 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -2440,10 +2440,11 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo () { assert (pointer_byte_size == m_process_arch.GetAddressByteSize()); } + m_process_arch.GetTriple().setOSName(llvm::StringRef (os_name)); m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name)); m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name)); - return true; } + return true; } } else diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index 8d2c913ae22..ccc0a9ceaa5 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -21,6 +21,7 @@ #include <sys/sysctl.h> #include "DNB.h" +#include "DNBDataRef.h" #include "DNBLog.h" #include "DNBThreadResumeActions.h" #include "RNBContext.h" @@ -4047,7 +4048,60 @@ RNBRemote::HandlePacket_qProcessInfo (const char *p) if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) rep << "ostype:ios;"; else - rep << "ostype:macosx;"; + { + bool is_ios_simulator = false; + if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64) + { + // Check for iOS simulator binaries by getting the process argument + // and environment and checking for SIMULATOR_UDID in the environment + int proc_args_mib[3] = { CTL_KERN, KERN_PROCARGS2, (int)pid }; + + uint8_t arg_data[8192]; + size_t arg_data_size = sizeof(arg_data); + if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0) + { + DNBDataRef data (arg_data, arg_data_size, false); + DNBDataRef::offset_t offset = 0; + uint32_t argc = data.Get32 (&offset); + const char *cstr; + + cstr = data.GetCStr (&offset); + if (cstr) + { + // Skip NULLs + while (1) + { + const char *p = data.PeekCStr(offset); + if ((p == NULL) || (*p != '\0')) + break; + ++offset; + } + // Now skip all arguments + for (int i=0; i<static_cast<int>(argc); ++i) + { + cstr = data.GetCStr(&offset); + } + + // Now iterate across all environment variables + while ((cstr = data.GetCStr(&offset))) + { + if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 0) + { + is_ios_simulator = true; + break; + } + if (cstr[0] == '\0') + break; + + } + } + } + } + if (is_ios_simulator) + rep << "ostype:ios;"; + else + rep << "ostype:macosx;"; + } rep << "vendor:apple;"; |