diff options
author | Frederic Riss <friss@apple.com> | 2018-04-06 04:28:12 +0000 |
---|---|---|
committer | Frederic Riss <friss@apple.com> | 2018-04-06 04:28:12 +0000 |
commit | cd90f878d4156ef1a732cdd64bc67aa88e7ac2ec (patch) | |
tree | d3f7ce21fce68fe4c55bb70b8556b8a6f93fdd0b /lldb/tools/debugserver/source/MacOSX | |
parent | 1e989deadd26698a3c6f463aad8d636533835cd2 (diff) | |
download | bcm5719-llvm-cd90f878d4156ef1a732cdd64bc67aa88e7ac2ec.tar.gz bcm5719-llvm-cd90f878d4156ef1a732cdd64bc67aa88e7ac2ec.zip |
[debugserver] Fix LC_BUILD_VERSION load command handling.
Summary:
In one of the 2 places the LC_BUILD_VERSION load command is handled, there
is a bug preventing us from actually handling them (the address where to
read the load command was not updated). This patch factors reading the
deployment target load commands into a helper and adds testing for the 2
code paths calling the helper.
The testing is a little bit complicated because the only times those load
commands matter is when debugging a simulator process. I added a new
decorator to check that a specific SDK is available. The actual testing was
fairly easy once I knew how to run a simulated process.
Reviewers: jasonmolenda, labath
Subscribers: lldb-commits
Differential Revision: https://reviews.llvm.org/D45298
llvm-svn: 329374
Diffstat (limited to 'lldb/tools/debugserver/source/MacOSX')
-rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachProcess.h | 5 | ||||
-rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachProcess.mm | 153 |
2 files changed, 77 insertions, 81 deletions
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h index 9ab06bcda9c..2fb4dc5dbb6 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h @@ -246,7 +246,10 @@ public: uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size); - + const char * + GetDeploymentInfo(const struct load_command&, uint64_t load_command_address, + uint32_t& major_version, uint32_t& minor_version, + uint32_t& patch_version); bool GetMachOInformationFromMemory(nub_addr_t mach_o_header_addr, int wordsize, struct mach_o_information &inf); diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm index 96225543fe8..c1689521e30 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm @@ -572,6 +572,68 @@ nub_addr_t MachProcess::GetTSDAddressForThread( plo_pthread_tsd_entry_size); } + +const char *MachProcess::GetDeploymentInfo(const struct load_command& lc, + uint64_t load_command_address, + uint32_t& major_version, + uint32_t& minor_version, + uint32_t& patch_version) { + uint32_t cmd = lc.cmd & ~LC_REQ_DYLD; + bool lc_cmd_known = + cmd == LC_VERSION_MIN_IPHONEOS || cmd == LC_VERSION_MIN_MACOSX || + cmd == LC_VERSION_MIN_TVOS || cmd == LC_VERSION_MIN_WATCHOS; + + if (lc_cmd_known) { + struct version_min_command vers_cmd; + if (ReadMemory(load_command_address, sizeof(struct version_min_command), + &vers_cmd) != sizeof(struct version_min_command)) { + return nullptr; + } + major_version = vers_cmd.sdk >> 16; + minor_version = (vers_cmd.sdk >> 8) & 0xffu; + patch_version = vers_cmd.sdk & 0xffu; + + switch (cmd) { + case LC_VERSION_MIN_IPHONEOS: + return "iphoneos"; + case LC_VERSION_MIN_MACOSX: + return "macosx"; + case LC_VERSION_MIN_TVOS: + return "tvos"; + case LC_VERSION_MIN_WATCHOS: + return "watchos"; + default: + return nullptr; + } + } +#if defined (LC_BUILD_VERSION) + if (cmd == LC_BUILD_VERSION) { + struct build_version_command build_vers; + if (ReadMemory(load_command_address, sizeof(struct build_version_command), + &build_vers) != sizeof(struct build_version_command)) { + return nullptr; + } + major_version = build_vers.sdk >> 16;; + minor_version = (build_vers.sdk >> 8) & 0xffu; + patch_version = build_vers.sdk & 0xffu; + + switch (build_vers.platform) { + case PLATFORM_MACOS: + return "macosx"; + case PLATFORM_IOS: + return "iphoneos"; + case PLATFORM_TVOS: + return "tvos"; + case PLATFORM_WATCHOS: + return "watchos"; + case PLATFORM_BRIDGEOS: + return "bridgeos"; + } + } +#endif + return nullptr; +} + // Given an address, read the mach-o header and load commands out of memory to // fill in // the mach_o_information "inf" object. @@ -670,91 +732,22 @@ bool MachProcess::GetMachOInformationFromMemory( sizeof(struct uuid_command)) uuid_copy(inf.uuid, uuidcmd.uuid); } - bool lc_cmd_known = - lc.cmd == LC_VERSION_MIN_IPHONEOS || lc.cmd == LC_VERSION_MIN_MACOSX; -#if defined(LC_VERSION_MIN_TVOS) - lc_cmd_known |= lc.cmd == LC_VERSION_MIN_TVOS; -#endif -#if defined(LC_VERSION_MIN_WATCHOS) - lc_cmd_known |= lc.cmd == LC_VERSION_MIN_WATCHOS; -#endif - if (lc_cmd_known) { - struct version_min_command vers_cmd; - if (ReadMemory(load_cmds_p, sizeof(struct version_min_command), - &vers_cmd) != sizeof(struct version_min_command)) { - return false; - } - switch (lc.cmd) { - case LC_VERSION_MIN_IPHONEOS: - inf.min_version_os_name = "iphoneos"; - break; - case LC_VERSION_MIN_MACOSX: - inf.min_version_os_name = "macosx"; - break; -#if defined(LC_VERSION_MIN_TVOS) - case LC_VERSION_MIN_TVOS: - inf.min_version_os_name = "tvos"; - break; -#endif -#if defined(LC_VERSION_MIN_WATCHOS) - case LC_VERSION_MIN_WATCHOS: - inf.min_version_os_name = "watchos"; - break; -#endif - default: - return false; - } - uint32_t xxxx = vers_cmd.sdk >> 16; - uint32_t yy = (vers_cmd.sdk >> 8) & 0xffu; - uint32_t zz = vers_cmd.sdk & 0xffu; + + uint32_t major_version, minor_version, patch_version; + if (const char *platform = GetDeploymentInfo(lc, load_cmds_p, + major_version, minor_version, + patch_version)) { + inf.min_version_os_name = platform; inf.min_version_os_version = ""; - inf.min_version_os_version += std::to_string(xxxx); + inf.min_version_os_version += std::to_string(major_version); inf.min_version_os_version += "."; - inf.min_version_os_version += std::to_string(yy); - if (zz != 0) { + inf.min_version_os_version += std::to_string(minor_version); + if (patch_version != 0) { inf.min_version_os_version += "."; - inf.min_version_os_version += std::to_string(zz); + inf.min_version_os_version += std::to_string(patch_version); } } -#if defined (LC_BUILD_VERSION) - if (lc.cmd == LC_BUILD_VERSION) - { - struct build_version_command build_vers; - if (ReadMemory(load_cmds_p, sizeof(struct build_version_command), - &build_vers) != sizeof(struct build_version_command)) { - return false; - } - switch (build_vers.platform) - { - case PLATFORM_MACOS: - inf.min_version_os_name = "macosx"; - break; - case PLATFORM_IOS: - inf.min_version_os_name = "iphoneos"; - break; - case PLATFORM_TVOS: - inf.min_version_os_name = "tvos"; - break; - case PLATFORM_WATCHOS: - inf.min_version_os_name = "watchos"; - break; - case PLATFORM_BRIDGEOS: - inf.min_version_os_name = "bridgeos"; - break; - } - uint32_t xxxx = build_vers.sdk >> 16;; - uint32_t yy = (build_vers.sdk >> 8) & 0xffu; - uint32_t zz = build_vers.sdk & 0xffu; - inf.min_version_os_version = ""; - inf.min_version_os_version += std::to_string(xxxx); - inf.min_version_os_version += "."; - inf.min_version_os_version += std::to_string(yy); - if (zz != 0) { - inf.min_version_os_version += "."; - inf.min_version_os_version += std::to_string(zz); - } - } -#endif + load_cmds_p += lc.cmdsize; } return true; |