[Lldb-commits] [lldb] [lldb] [debugserver] address preprocessor warning, extra arg (PR #90808)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/90808 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 954d00e - [lldb] MachO delay-init binaries don't load as dependent
Author: Jason Molenda Date: 2024-05-02T15:20:17-07:00 New Revision: 954d00e87cdd77d0e9e367be52e62340467bd779 URL: https://github.com/llvm/llvm-project/commit/954d00e87cdd77d0e9e367be52e62340467bd779 DIFF: https://github.com/llvm/llvm-project/commit/954d00e87cdd77d0e9e367be52e62340467bd779.diff LOG: [lldb] MachO delay-init binaries don't load as dependent Added: Modified: lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Removed: diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 1caf93659956b4..4dd23bb1e4dbec 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -5140,8 +5140,17 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList ) { case LC_LOADFVMLIB: case LC_LOAD_UPWARD_DYLIB: { uint32_t name_offset = cmd_offset + m_data.GetU32(); +bool is_delayed_init = false; +uint32_t use_command_marker = m_data.GetU32(); +if (use_command_marker == 0x1a741800 /* DYLIB_USE_MARKER */) { + offset += 4; /* uint32_t current_version */ + offset += 4; /* uint32_t compat_version */ + uint32_t flags = m_data.GetU32(); + if (flags & 0x08 /* DYLIB_USE_DELAYED_INIT */) +is_delayed_init = true; +} const char *path = m_data.PeekCStr(name_offset); -if (path) { +if (path && !is_delayed_init) { if (load_cmd.cmd == LC_RPATH) rpath_paths.push_back(path); else { ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [debugserver] address preprocessor warning, extra arg (PR #90808)
@@ -169,25 +173,28 @@ kern_return_t DNBArchMachARM64::GetGPRState(bool force) { (thread_state_t)_state.context.gpr, ); if (DNBLogEnabledForAny(LOG_THREAD)) { uint64_t *x = _state.context.gpr.__x[0]; + +#if defined(DEBUGSERVER_IS_ARM64E) DNBLogThreaded("thread_get_state signed regs " "\n fp=%16.16llx" "\n lr=%16.16llx" "\n sp=%16.16llx" "\n pc=%16.16llx", -#if __has_feature(ptrauth_calls) && defined(__LP64__) reinterpret_cast(m_state.context.gpr.__opaque_fp), reinterpret_cast(m_state.context.gpr.__opaque_lr), reinterpret_cast(m_state.context.gpr.__opaque_sp), - reinterpret_cast(m_state.context.gpr.__opaque_pc) + reinterpret_cast(m_state.context.gpr.__opaque_pc)); #else - m_state.context.gpr.__fp, - m_state.context.gpr.__lr, - m_state.context.gpr.__sp, - m_state.context.gpr.__pc +DNBLogThreaded("thread_get_state signed regs " + "\n fp=%16.16llx" + "\n lr=%16.16llx" + "\n sp=%16.16llx" + "\n pc=%16.16llx", + m_state.context.gpr.__fp, m_state.context.gpr.__lr, + m_state.context.gpr.__sp, m_state.context.gpr.__pc); jasonmolenda wrote: good idea, done. https://github.com/llvm/llvm-project/pull/90808 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [debugserver] address preprocessor warning, extra arg (PR #90808)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/90808 >From 8145e9faaa52209f9800d473fb75f7cfbd2a1185 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Wed, 1 May 2024 18:06:50 -0700 Subject: [PATCH 1/2] [lldb] [debugserver] address preprocessor warning, extra arg In DNBArchImplARM64.cpp I'm doing And the preprocessor warns that this is not defined behavior. This checks if ptrauth_calls is available and if this is being compiled 64-bit (i.e. arm64e), and defines a single DEBUGSERVER_IS_ARM64E when those are both true. I did have to duplicate one DNBLogThreaded() call which itself is a macro, and using an ifdef in the middle of macro arguments also got me a warning from the preprocessor. While testing this for all the different targets, I found a DNBError initialization that accepts a c-string but I'm passing in a printf-style formatter c-string and an argument. Create the string before the call and pass in the constructed string. rdar://127129242 --- .../debugserver/source/MacOSX/MachProcess.mm | 8 ++--- .../source/MacOSX/arm64/DNBArchImplARM64.cpp | 31 --- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm index 70b4564a027b1b..cbe3c5459e91fc 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm @@ -4070,10 +4070,10 @@ static CFStringRef CopyBundleIDForPath(const char *app_bundle_path, m_flags |= eMachProcessFlagsAttached; DNBLog("[LaunchAttach] successfully attached to pid %d", m_pid); } else { - launch_err.SetErrorString( - "Failed to attach to pid %d, BoardServiceLaunchForDebug() unable to " - "ptrace(PT_ATTACHEXC)", - m_pid); + std::string errmsg = "Failed to attach to pid "; + errmsg += std::to_string(m_pid); + errmsg += ", BoardServiceLaunchForDebug() unable to ptrace(PT_ATTACHEXC)"; + launch_err.SetErrorString(errmsg.c_str()); SetState(eStateExited); DNBLog("[LaunchAttach] END (%d) error: failed to attach to pid %d", getpid(), m_pid); diff --git a/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp b/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp index 57dd2dce6bf5ad..3b1147c69c666b 100644 --- a/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp +++ b/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp @@ -26,8 +26,12 @@ #include #include +#undef DEBUGSERVER_IS_ARM64E #if __has_feature(ptrauth_calls) #include +#if defined(__LP64__) +#define DEBUGSERVER_IS_ARM64E 1 +#endif #endif // Break only in privileged or user mode @@ -115,7 +119,7 @@ static uint64_t clear_pac_bits(uint64_t value) { uint64_t DNBArchMachARM64::GetPC(uint64_t failValue) { // Get program counter if (GetGPRState(false) == KERN_SUCCESS) -#if __has_feature(ptrauth_calls) && defined(__LP64__) +#if defined(DEBUGSERVER_IS_ARM64E) return clear_pac_bits( reinterpret_cast(m_state.context.gpr.__opaque_pc)); #else @@ -147,7 +151,7 @@ kern_return_t DNBArchMachARM64::SetPC(uint64_t value) { uint64_t DNBArchMachARM64::GetSP(uint64_t failValue) { // Get stack pointer if (GetGPRState(false) == KERN_SUCCESS) -#if __has_feature(ptrauth_calls) && defined(__LP64__) +#if defined(DEBUGSERVER_IS_ARM64E) return clear_pac_bits( reinterpret_cast(m_state.context.gpr.__opaque_sp)); #else @@ -169,25 +173,28 @@ kern_return_t DNBArchMachARM64::GetGPRState(bool force) { (thread_state_t)_state.context.gpr, ); if (DNBLogEnabledForAny(LOG_THREAD)) { uint64_t *x = _state.context.gpr.__x[0]; + +#if defined(DEBUGSERVER_IS_ARM64E) DNBLogThreaded("thread_get_state signed regs " "\n fp=%16.16llx" "\n lr=%16.16llx" "\n sp=%16.16llx" "\n pc=%16.16llx", -#if __has_feature(ptrauth_calls) && defined(__LP64__) reinterpret_cast(m_state.context.gpr.__opaque_fp), reinterpret_cast(m_state.context.gpr.__opaque_lr), reinterpret_cast(m_state.context.gpr.__opaque_sp), - reinterpret_cast(m_state.context.gpr.__opaque_pc) + reinterpret_cast(m_state.context.gpr.__opaque_pc)); #else - m_state.context.gpr.__fp, - m_state.context.gpr.__lr, - m_state.context.gpr.__sp, - m_state.context.gpr.__pc +DNBLogThreaded("thread_get_state signed regs " + "\n fp=%16.16llx" + "\n lr=%16.16llx" + "\n sp=%16.16llx" + "\n pc=%16.16llx", + m_state.context.gpr.__fp, m_state.context.gpr.__lr, + m_state.context.gpr.__sp,
[Lldb-commits] [lldb] [lldb] [debugserver] address preprocessor warning, extra arg (PR #90808)
https://github.com/jasonmolenda edited https://github.com/llvm/llvm-project/pull/90808 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [debugserver] address preprocessor warning, extra arg (PR #90808)
https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/90808 In DNBArchImplARM64.cpp I'm doing And the preprocessor warns that this is not defined behavior. This checks if ptrauth_calls is available and if this is being compiled 64-bit (i.e. arm64e), and defines a single DEBUGSERVER_IS_ARM64E when those are both true. I did have to duplicate one DNBLogThreaded() call which itself is a macro, and using an ifdef in the middle of macro arguments also got me a warning from the preprocessor. While testing this for all the different targets, I found a DNBError initialization that accepts a c-string but I'm passing in a printf-style formatter c-string and an argument. Create the string before the call and pass in the constructed string. rdar://127129242 >From 8145e9faaa52209f9800d473fb75f7cfbd2a1185 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Wed, 1 May 2024 18:06:50 -0700 Subject: [PATCH] [lldb] [debugserver] address preprocessor warning, extra arg In DNBArchImplARM64.cpp I'm doing And the preprocessor warns that this is not defined behavior. This checks if ptrauth_calls is available and if this is being compiled 64-bit (i.e. arm64e), and defines a single DEBUGSERVER_IS_ARM64E when those are both true. I did have to duplicate one DNBLogThreaded() call which itself is a macro, and using an ifdef in the middle of macro arguments also got me a warning from the preprocessor. While testing this for all the different targets, I found a DNBError initialization that accepts a c-string but I'm passing in a printf-style formatter c-string and an argument. Create the string before the call and pass in the constructed string. rdar://127129242 --- .../debugserver/source/MacOSX/MachProcess.mm | 8 ++--- .../source/MacOSX/arm64/DNBArchImplARM64.cpp | 31 --- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm index 70b4564a027b1b..cbe3c5459e91fc 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm @@ -4070,10 +4070,10 @@ static CFStringRef CopyBundleIDForPath(const char *app_bundle_path, m_flags |= eMachProcessFlagsAttached; DNBLog("[LaunchAttach] successfully attached to pid %d", m_pid); } else { - launch_err.SetErrorString( - "Failed to attach to pid %d, BoardServiceLaunchForDebug() unable to " - "ptrace(PT_ATTACHEXC)", - m_pid); + std::string errmsg = "Failed to attach to pid "; + errmsg += std::to_string(m_pid); + errmsg += ", BoardServiceLaunchForDebug() unable to ptrace(PT_ATTACHEXC)"; + launch_err.SetErrorString(errmsg.c_str()); SetState(eStateExited); DNBLog("[LaunchAttach] END (%d) error: failed to attach to pid %d", getpid(), m_pid); diff --git a/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp b/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp index 57dd2dce6bf5ad..3b1147c69c666b 100644 --- a/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp +++ b/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp @@ -26,8 +26,12 @@ #include #include +#undef DEBUGSERVER_IS_ARM64E #if __has_feature(ptrauth_calls) #include +#if defined(__LP64__) +#define DEBUGSERVER_IS_ARM64E 1 +#endif #endif // Break only in privileged or user mode @@ -115,7 +119,7 @@ static uint64_t clear_pac_bits(uint64_t value) { uint64_t DNBArchMachARM64::GetPC(uint64_t failValue) { // Get program counter if (GetGPRState(false) == KERN_SUCCESS) -#if __has_feature(ptrauth_calls) && defined(__LP64__) +#if defined(DEBUGSERVER_IS_ARM64E) return clear_pac_bits( reinterpret_cast(m_state.context.gpr.__opaque_pc)); #else @@ -147,7 +151,7 @@ kern_return_t DNBArchMachARM64::SetPC(uint64_t value) { uint64_t DNBArchMachARM64::GetSP(uint64_t failValue) { // Get stack pointer if (GetGPRState(false) == KERN_SUCCESS) -#if __has_feature(ptrauth_calls) && defined(__LP64__) +#if defined(DEBUGSERVER_IS_ARM64E) return clear_pac_bits( reinterpret_cast(m_state.context.gpr.__opaque_sp)); #else @@ -169,25 +173,28 @@ kern_return_t DNBArchMachARM64::GetGPRState(bool force) { (thread_state_t)_state.context.gpr, ); if (DNBLogEnabledForAny(LOG_THREAD)) { uint64_t *x = _state.context.gpr.__x[0]; + +#if defined(DEBUGSERVER_IS_ARM64E) DNBLogThreaded("thread_get_state signed regs " "\n fp=%16.16llx" "\n lr=%16.16llx" "\n sp=%16.16llx" "\n pc=%16.16llx", -#if __has_feature(ptrauth_calls) && defined(__LP64__) reinterpret_cast(m_state.context.gpr.__opaque_fp), reinterpret_cast(m_state.context.gpr.__opaque_lr),
[Lldb-commits] [lldb] [lldb] Be conversative about setting highmem address masks (PR #90533)
jasonmolenda wrote: > On the face of it > > > When we have an unset high memory address mask, and we are told to set low- > > and high-memory to the same new address mask, maintain the high memory mask > > as unset in Process. The same thing is done with the > > SBProcess::SetAddressMask API when the user specifies > > lldb.eAddressMaskRangeAll. > > Seems to itself be confusing and if you're doing this to address > > > When high memory has a different set of masks, those become active in > > Process and the user can use highmem-virtual-addressable-bits to override > > only the highmem value, if it is wrong. > > You're adding one gotcha to avoid another. > > However, I think the result of the highmem mask being unset is the same as > setting both masks to the same value. Except that `virtual-addressable-bits` > will now effectively apply to both masks, until the user sets _only_ the high > mask to some value. At that point, `highmem-virtual-addressable-bits` must be > used to modify the high mem value. > > Correct? > > So this doesn't actually change anything for an API user that was setting > address masks for high and low all at once. They'll still think both are the > same value, but _internally_, lldb tries high, sees that it's unset, and > falls back to the low mask. I'm not thrilled about where I'm ending up. For the vast majority of our users, the separate address masks for high and low memory will never occur, it's an unusual environment that sets up the MMU this way, and operates in both halves of memory. The goal of this patch is to keep the high memory masks unset (set to LLDB_INVALID_MASK) unless someone sets them to a value distinct from the "low memory" masks. I almost think about changing these masks in Process to be a class which holds either {code, data} or {low code, low data, high code, high data} internally, with methods to get/set the masks and the requirement that high and low be set simultaneously when they're both going to be specified so we can detect if it's genuinely a split-address space situation. https://github.com/llvm/llvm-project/pull/90533 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Be conversative about setting highmem address masks (PR #90533)
@@ -1465,6 +1465,20 @@ class Process : public std::enable_shared_from_this, /// platforms where there is a difference (only Arm Thumb at this time). lldb::addr_t FixAnyAddress(lldb::addr_t pc); + /// Retrieve the actual address masks for high memory code/data, + /// without the normal fallbacks of returning the low-memory masks + /// or the user settings. Needed by SBProcess to determine if + /// the high address masks have actually been set, and should + /// be updated when "set all masks" is requested. In most cases, + /// the highmem masks should be left to have LLDB_INVALID_ADDRESS_MASK, + /// unset. + lldb::addr_t GetConcreteHighmemCodeAddressMask() { jasonmolenda wrote: I think I also thought about moving to a std::optional for all the masks, but in the SB API I need a way to say "no mask available" and without creating an SBAddressMask object with an IsValid() method, I can't represent that without a magic invalid value. https://github.com/llvm/llvm-project/pull/90533 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Be conversative about setting highmem address masks (PR #90533)
@@ -1465,6 +1465,20 @@ class Process : public std::enable_shared_from_this, /// platforms where there is a difference (only Arm Thumb at this time). lldb::addr_t FixAnyAddress(lldb::addr_t pc); + /// Retrieve the actual address masks for high memory code/data, + /// without the normal fallbacks of returning the low-memory masks + /// or the user settings. Needed by SBProcess to determine if + /// the high address masks have actually been set, and should + /// be updated when "set all masks" is requested. In most cases, + /// the highmem masks should be left to have LLDB_INVALID_ADDRESS_MASK, + /// unset. + lldb::addr_t GetConcreteHighmemCodeAddressMask() { jasonmolenda wrote: Yeah this is a weird API I almost thought to make it a protected method because the only user should be SBFrame where we need to distinguish between the "currently in-effect high memory mask" and "the current Process mask setting, which may be unset". For the effective high memory mask, if the user hasn't specified a high memory addressable bits setting, and the process doesn't have a mask set, then we are in a "one-mask-for-all-addresses" mode and we return the low memory address mask. https://github.com/llvm/llvm-project/pull/90533 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Be conversative about setting highmem address masks (PR #90533)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/90533 >From 3c272e99326a287f0a61c1f8c2c7ee790e1aeb48 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 29 Apr 2024 16:45:36 -0700 Subject: [PATCH 1/2] [lldb] Be conversative about setting highmem address masks The most common case with address masks/addressable bits is that we have one value/mask that applies across the entire address space, for code and data. On AArch64, we can have separate masks for high and low address spaces. In the normal "one mask for all memory" case, we use the low memory masks in Process, and we use the `virtual-addressable-bits` setting for the user to override that value. When high memory has a different set of masks, those become active in Process and the user can use `highmem-virtual-addressable-bits` to override only the highmem value, if it is wrong. This patch is handling a case where a gdb stub sent incorrect address masks, for both high and low memory: ``` (lldb) process plugin packet send qHostInfo packet: qHostInfo response: cputype:16777228;cpusubtype:0;endian:little;ptrsize:8;low_mem_addressing_bits:64;high_mem_addressing_bits:64; ``` When in fact this target was using 47 bits of addressing. This qHostInfo response set the Process low and high address masks for code and data so that no bit-clearing is performed. The user tried to override this with the virtual-addressable-bits setting, and was surprised when it had no affect on code running in high memory. Because the high memory code mask now has a setting (all bits are addressable) and they needed to use the very-uncommon highmem-virtual-addressable-bits setting. When we have an *unset* high memory address mask, and we are told to set low- and high-memory to the same new address mask, maintain the high memory mask as unset in Process. The same thing is done with the SBProcess::SetAddressMask API when the user specifies lldb.eAddressMaskRangeAll. Added a new test case to TestAddressMasks.py to test that the low-memory override works correctly. Also fixed a bug in the testsuite that I did where I added `@skipIf(archs=["arm"])` to avoid a problem on the Linaro 32-bit arm Ubuntu CI bot. I forgot that this is a regex, and so the tests were being skipped entirely on any arm.* system. --- lldb/source/API/SBProcess.cpp | 26 --- lldb/source/Target/Process.cpp| 20 +++--- .../process/address-masks/TestAddressMasks.py | 21 --- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index c37c111c5a58e0..a0654d23e67efd 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -1298,7 +1298,12 @@ void SBProcess::SetAddressMask(AddressMaskType type, addr_t mask, case eAddressMaskTypeCode: if (addr_range == eAddressMaskRangeAll) { process_sp->SetCodeAddressMask(mask); -process_sp->SetHighmemCodeAddressMask(mask); +// If the highmem mask is the default-invalid, +// don't change it, keep everything consistently +// using the lowmem all-address-space mask. +if (process_sp->GetHighmemCodeAddressMask() != +LLDB_INVALID_ADDRESS_MASK) + process_sp->SetHighmemCodeAddressMask(mask); } else if (addr_range == eAddressMaskRangeHigh) { process_sp->SetHighmemCodeAddressMask(mask); } else { @@ -1308,7 +1313,12 @@ void SBProcess::SetAddressMask(AddressMaskType type, addr_t mask, case eAddressMaskTypeData: if (addr_range == eAddressMaskRangeAll) { process_sp->SetDataAddressMask(mask); -process_sp->SetHighmemDataAddressMask(mask); +// If the highmem mask is the default-invalid, +// don't change it, keep everything consistently +// using the lowmem all-address-space mask. +if (process_sp->GetHighmemDataAddressMask() != +LLDB_INVALID_ADDRESS_MASK) + process_sp->SetHighmemDataAddressMask(mask); } else if (addr_range == eAddressMaskRangeHigh) { process_sp->SetHighmemDataAddressMask(mask); } else { @@ -1319,8 +1329,16 @@ void SBProcess::SetAddressMask(AddressMaskType type, addr_t mask, if (addr_range == eAddressMaskRangeAll) { process_sp->SetCodeAddressMask(mask); process_sp->SetDataAddressMask(mask); -process_sp->SetHighmemCodeAddressMask(mask); -process_sp->SetHighmemDataAddressMask(mask); +// If the highmem masks are the default-invalid, +// don't change them, keep everything consistently +// using the lowmem all-address-space masks. +if (process_sp->GetHighmemDataAddressMask() != +LLDB_INVALID_ADDRESS_MASK || +process_sp->GetHighmemCodeAddressMask() != +LLDB_INVALID_ADDRESS_MASK) { + process_sp->SetHighmemCodeAddressMask(mask); +
[Lldb-commits] [lldb] [lldb] Be conversative about setting highmem address masks (PR #90533)
https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/90533 The most common case with address masks/addressable bits is that we have one value/mask that applies across the entire address space, for code and data. On AArch64, we can have separate masks for high and low address spaces. In the normal "one mask for all memory" case, we use the low memory masks in Process, and we use the `virtual-addressable-bits` setting for the user to override that value. When high memory has a different set of masks, those become active in Process and the user can use `highmem-virtual-addressable-bits` to override only the highmem value, if it is wrong. This patch is handling a case where a gdb stub sent incorrect address masks, for both high and low memory: ``` (lldb) process plugin packet send qHostInfo packet: qHostInfo response: cputype:16777228;cpusubtype:0;endian:little;ptrsize:8;low_mem_addressing_bits:64;high_mem_addressing_bits:64; ``` When in fact this target was using 47 bits of addressing. This qHostInfo response set the Process low and high address masks for code and data so that no bit-clearing is performed. The user tried to override this with the virtual-addressable-bits setting, and was surprised when it had no affect on code running in high memory. Because the high memory code mask now has a setting (all bits are addressable) and they needed to use the very-uncommon highmem-virtual-addressable-bits setting. When we have an *unset* high memory address mask, and we are told to set low- and high-memory to the same new address mask, maintain the high memory mask as unset in Process. The same thing is done with the SBProcess::SetAddressMask API when the user specifies lldb.eAddressMaskRangeAll. Added a new test case to TestAddressMasks.py to test that the low-memory override works correctly. Also fixed a bug in the testsuite that I did where I added `@skipIf(archs=["arm"])` to avoid a problem on the Linaro 32-bit arm Ubuntu CI bot. I forgot that this is a regex, and so the tests were being skipped entirely on any arm.* system. >From 3c272e99326a287f0a61c1f8c2c7ee790e1aeb48 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 29 Apr 2024 16:45:36 -0700 Subject: [PATCH] [lldb] Be conversative about setting highmem address masks The most common case with address masks/addressable bits is that we have one value/mask that applies across the entire address space, for code and data. On AArch64, we can have separate masks for high and low address spaces. In the normal "one mask for all memory" case, we use the low memory masks in Process, and we use the `virtual-addressable-bits` setting for the user to override that value. When high memory has a different set of masks, those become active in Process and the user can use `highmem-virtual-addressable-bits` to override only the highmem value, if it is wrong. This patch is handling a case where a gdb stub sent incorrect address masks, for both high and low memory: ``` (lldb) process plugin packet send qHostInfo packet: qHostInfo response: cputype:16777228;cpusubtype:0;endian:little;ptrsize:8;low_mem_addressing_bits:64;high_mem_addressing_bits:64; ``` When in fact this target was using 47 bits of addressing. This qHostInfo response set the Process low and high address masks for code and data so that no bit-clearing is performed. The user tried to override this with the virtual-addressable-bits setting, and was surprised when it had no affect on code running in high memory. Because the high memory code mask now has a setting (all bits are addressable) and they needed to use the very-uncommon highmem-virtual-addressable-bits setting. When we have an *unset* high memory address mask, and we are told to set low- and high-memory to the same new address mask, maintain the high memory mask as unset in Process. The same thing is done with the SBProcess::SetAddressMask API when the user specifies lldb.eAddressMaskRangeAll. Added a new test case to TestAddressMasks.py to test that the low-memory override works correctly. Also fixed a bug in the testsuite that I did where I added `@skipIf(archs=["arm"])` to avoid a problem on the Linaro 32-bit arm Ubuntu CI bot. I forgot that this is a regex, and so the tests were being skipped entirely on any arm.* system. --- lldb/source/API/SBProcess.cpp | 26 --- lldb/source/Target/Process.cpp| 20 +++--- .../process/address-masks/TestAddressMasks.py | 21 --- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index c37c111c5a58e0..a0654d23e67efd 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -1298,7 +1298,12 @@ void SBProcess::SetAddressMask(AddressMaskType type, addr_t mask, case eAddressMaskTypeCode: if (addr_range == eAddressMaskRangeAll) {
[Lldb-commits] [lldb] [lldb] Recognize DW_TAG_LLVM_ptrauth_type as a type qual (PR #90140)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/90140 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add SBValue::GetValueAsAddress API (PR #90144)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/90144 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add SBValue::GetValueAsAddress API (PR #90144)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/90144 >From 3b66943d9c49fd5e71c2eb136b5bb3311e932bbc Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Thu, 25 Apr 2024 15:51:44 -0700 Subject: [PATCH 1/2] [lldb] Add SBValue::GetValueAsAddress API I previously added this API via https://reviews.llvm.org/D142792 in 2023, along with changes to the ValueObject class to treat pointer types as addresses, and to annotate those ValueObjects with the original uint64_t byte sequence AND the name of the symbol once stripped, if that points to a symbol. I did this unconditionally for all pointer type ValueObjects, and it caused several regressions in the Objective-C data formatters which have a ValueObject of an object, it has the address of its class -- but with ObjC, sometimes it is a "tagged pointer" which is metadata, not an actual pointer. (e.g. a small NSInteger value is stored entirely in the tagged pointer, instead of a separate object) Treating these not-addresses as addresses -- clearing the non-addressable-bits -- is invalid. The original version of this patch we're using downstream only does this bits clearing for pointer types that are specifically decorated with the pointerauth typequal, but not all of those clang changes are upstreamed to github main yet, so I tried this simpler approach and hit the tagged pointer issue and bailed on the whole patch. This patch, however, is simply adding SBValue::GetValueAsAddress so script writers who know that an SBValue has an address in memory, can strip off any metadata. It's an important API to have for script writers when AArch64 ptrauth is in use, so I'm going to put this part of the patch back on github main now until we can get the rest of that original patch upstreamed. --- lldb/bindings/interface/SBValueDocstrings.i | 20 +++ lldb/include/lldb/API/SBValue.h | 2 + lldb/source/API/SBValue.cpp | 20 +++ .../Makefile | 3 + .../TestClearSBValueNonAddressableBits.py | 60 +++ .../clear-sbvalue-nonaddressable-bits/main.c | 27 + 6 files changed, 132 insertions(+) create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/Makefile create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/TestClearSBValueNonAddressableBits.py create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/main.c diff --git a/lldb/bindings/interface/SBValueDocstrings.i b/lldb/bindings/interface/SBValueDocstrings.i index 6bab923e8b35a6..59fa807f5ec95c 100644 --- a/lldb/bindings/interface/SBValueDocstrings.i +++ b/lldb/bindings/interface/SBValueDocstrings.i @@ -135,6 +135,26 @@ linked list." %feature("docstring", "Expands nested expressions like .a->b[0].c[1]->d." ) lldb::SBValue::GetValueForExpressionPath; +%feature("docstring", " + Return the value as an address. On failure, LLDB_INVALID_ADDRESS + will be returned. On architectures like AArch64, where the + top (unaddressable) bits can be used for authentication, + memory tagging, or top byte ignore, this method will return + the value with those top bits cleared. + + GetValueAsUnsigned returns the actual value, with the + authentication/Top Byte Ignore/Memory Tagging Extension bits. + + Calling this on a random value which is not a pointer is + incorrect. Call GetType().IsPointerType() if in doubt. + + An SB API program may want to show both the literal byte value + and the address it refers to in memory. These two SBValue + methods allow SB API writers to behave appropriately for their + interface." +) lldb::SBValue::GetValueAsAddress; + + %feature("doctstring", " Returns the number for children. diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index bbcccaab51aaee..6fac0961910540 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -68,6 +68,8 @@ class LLDB_API SBValue { uint64_t GetValueAsUnsigned(uint64_t fail_value = 0); + lldb::addr_t GetValueAsAddress(); + ValueType GetValueType(); // If you call this on a newly created ValueObject, it will always return diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 94a8f3ea319e89..c8b664c86ec2d9 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -909,6 +909,26 @@ uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) { return fail_value; } +lldb::addr_t SBValue::GetValueAsAddress() { + addr_t fail_value = LLDB_INVALID_ADDRESS; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) { +bool success = true; +uint64_t ret_val = fail_value; +ret_val = value_sp->GetValueAsUnsigned(fail_value, ); +if (!success) { + return fail_value; +} +ProcessSP process_sp = m_opaque_sp->GetProcessSP(); +if (!process_sp) + return ret_val; +
[Lldb-commits] [lldb] [lldb] Add SBValue::GetValueAsAddress API (PR #90144)
https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/90144 I previously added this API via https://reviews.llvm.org/D142792 in 2023, along with changes to the ValueObject class to treat pointer types as addresses, and to annotate those ValueObjects with the original uint64_t byte sequence AND the name of the symbol once stripped, if that points to a symbol. I did this unconditionally for all pointer type ValueObjects, and it caused several regressions in the Objective-C data formatters which have a ValueObject of an object, it has the address of its class -- but with ObjC, sometimes it is a "tagged pointer" which is metadata, not an actual pointer. (e.g. a small NSInteger value is stored entirely in the tagged pointer, instead of a separate object) Treating these not-addresses as addresses -- clearing the non-addressable-bits -- is invalid. The original version of this patch we're using downstream only does this bits clearing for pointer types that are specifically decorated with the pointerauth typequal, but not all of those clang changes are upstreamed to github main yet, so I tried this simpler approach and hit the tagged pointer issue and bailed on the whole patch. This patch, however, is simply adding SBValue::GetValueAsAddress so script writers who know that an SBValue has an address in memory, can strip off any metadata. It's an important API to have for script writers when AArch64 ptrauth is in use, so I'm going to put this part of the patch back on github main now until we can get the rest of that original patch upstreamed. >From 3b66943d9c49fd5e71c2eb136b5bb3311e932bbc Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Thu, 25 Apr 2024 15:51:44 -0700 Subject: [PATCH] [lldb] Add SBValue::GetValueAsAddress API I previously added this API via https://reviews.llvm.org/D142792 in 2023, along with changes to the ValueObject class to treat pointer types as addresses, and to annotate those ValueObjects with the original uint64_t byte sequence AND the name of the symbol once stripped, if that points to a symbol. I did this unconditionally for all pointer type ValueObjects, and it caused several regressions in the Objective-C data formatters which have a ValueObject of an object, it has the address of its class -- but with ObjC, sometimes it is a "tagged pointer" which is metadata, not an actual pointer. (e.g. a small NSInteger value is stored entirely in the tagged pointer, instead of a separate object) Treating these not-addresses as addresses -- clearing the non-addressable-bits -- is invalid. The original version of this patch we're using downstream only does this bits clearing for pointer types that are specifically decorated with the pointerauth typequal, but not all of those clang changes are upstreamed to github main yet, so I tried this simpler approach and hit the tagged pointer issue and bailed on the whole patch. This patch, however, is simply adding SBValue::GetValueAsAddress so script writers who know that an SBValue has an address in memory, can strip off any metadata. It's an important API to have for script writers when AArch64 ptrauth is in use, so I'm going to put this part of the patch back on github main now until we can get the rest of that original patch upstreamed. --- lldb/bindings/interface/SBValueDocstrings.i | 20 +++ lldb/include/lldb/API/SBValue.h | 2 + lldb/source/API/SBValue.cpp | 20 +++ .../Makefile | 3 + .../TestClearSBValueNonAddressableBits.py | 60 +++ .../clear-sbvalue-nonaddressable-bits/main.c | 27 + 6 files changed, 132 insertions(+) create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/Makefile create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/TestClearSBValueNonAddressableBits.py create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/main.c diff --git a/lldb/bindings/interface/SBValueDocstrings.i b/lldb/bindings/interface/SBValueDocstrings.i index 6bab923e8b35a6..59fa807f5ec95c 100644 --- a/lldb/bindings/interface/SBValueDocstrings.i +++ b/lldb/bindings/interface/SBValueDocstrings.i @@ -135,6 +135,26 @@ linked list." %feature("docstring", "Expands nested expressions like .a->b[0].c[1]->d." ) lldb::SBValue::GetValueForExpressionPath; +%feature("docstring", " + Return the value as an address. On failure, LLDB_INVALID_ADDRESS + will be returned. On architectures like AArch64, where the + top (unaddressable) bits can be used for authentication, + memory tagging, or top byte ignore, this method will return + the value with those top bits cleared. + + GetValueAsUnsigned returns the actual value, with the + authentication/Top Byte Ignore/Memory Tagging Extension bits. + + Calling this on a random value which is not a pointer is + incorrect. Call GetType().IsPointerType() if in doubt. + + An SB
[Lldb-commits] [lldb] [lldb] Recognize DW_TAG_LLVM_ptrauth_type as a type qual (PR #90140)
https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/90140 Jonas upstreamed recognition of DW_TAG_LLVM_ptrauth_type https://reviews.llvm.org/D130215 but it isn't recognized as a type qualifier tag in DWARFASTParserClang::ParseTypeFromDWARF. >From b5e6f50797ddde235dde86f8e2f15a9fd6632092 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Thu, 25 Apr 2024 15:31:51 -0700 Subject: [PATCH] [lldb] Recognize DW_TAG_LLVM_ptrauth_type as a type qual Jonas upstreamed recognition of DW_TAG_LLVM_ptrauth_type https://reviews.llvm.org/D130215 but it isn't recognized as a type qualifier tag in DWARFASTParserClang::ParseTypeFromDWARF. --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 41d81fbcf1b087..12dafd3f5d5d51 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -495,6 +495,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext , case DW_TAG_const_type: case DW_TAG_restrict_type: case DW_TAG_volatile_type: + case DW_TAG_LLVM_ptrauth_type: case DW_TAG_atomic_type: case DW_TAG_unspecified_type: { type_sp = ParseTypeModifier(sc, die, attrs); ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][Docs] Make formatting regular in lldb-gdb-remote.txt (PR #89587)
https://github.com/jasonmolenda approved this pull request. Yes please, very long overdue, I've felt bad about not trying to do something here myself. https://github.com/llvm/llvm-project/pull/89587 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DynamicLoader] Fix lldb unable to stop at _dl_debug_state if user set it before the process launched. (PR #88792)
https://github.com/jasonmolenda approved this pull request. This looks good, thanks for the revisions. https://github.com/llvm/llvm-project/pull/88792 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DynamicLoader] Fix lldb unable to stop at _dl_debug_state if user set it before the process launched. (PR #88792)
jasonmolenda wrote: Skimming DynamicLoaderPOSIXDYLD (as it is written today), it looks like attach/launch call `SetRendezvousBreakpoint()` which (1) loads ld.so into lldb if it isn't already there, and (2) sets the breakpoint to be notified about future binaries loading. It loads ld.so via `LoadInterpreterModule` which Finds It somehow (I stopped reading), adds it to the Target, and sets the section load addresses, returns the module_sp. Then it sets breakpoints on a half dozen notification function names in the ld.so Module. This is all special-cased for ld.so, and we do not evaluate user breakpoints because we didn't call `Target::ModulesDidLoad` for ld.so. The code path for other binaries goes through `DynamicLoaderPOSIXDYLD::RefreshModules` which does the normal approach of adding binaries to the Target, setting the load addresses, then calling ModulesDidLoad which will evaluate breakpoints that may need to be set in the new binaries. It seems like a simpler fix would be to have `DynamicLoaderPOSIXDYLD::LoadInterpreterModule` create a ModuleList with the ModuleSP of ld.so that it has just added to Target and set its section load addresses, then call `ModulesDidLoad` on it so that user breakpoints are evaluated and inserted. The patch as it is written right now is taking one part of ModulesDidLoad and putting it in a separate method that `DynamicLoaderPOSIXDYLD::LoadInterpreterModule` is calling -- why not just call ModulesDidLoad and delegate this (and possibly other binary-just-loaded) behaviors to it? https://github.com/llvm/llvm-project/pull/88792 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix nullptr dereference on running x86 binary with x86-disabled llvm (PR #82603)
https://github.com/jasonmolenda approved this pull request. Looks good, please land it. Thanks for the pings and rewriting the test case! https://github.com/llvm/llvm-project/pull/82603 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][MinidumpFileBuilder] Fix addition of MemoryList steam (PR #88564)
@@ -655,9 +655,10 @@ MinidumpFileBuilder::AddMemoryList(const lldb::ProcessSP _sp, const addr_t addr = core_range.range.start(); const addr_t size = core_range.range.size(); auto data_up = std::make_unique(size, 0); +Status read_error; jasonmolenda wrote: I don't work on this plugin myself, I'm sure the way you expressed the idea is fine, it's little more than a style difference. https://github.com/llvm/llvm-project/pull/88564 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][MinidumpFileBuilder] Fix addition of MemoryList steam (PR #88564)
@@ -655,9 +655,10 @@ MinidumpFileBuilder::AddMemoryList(const lldb::ProcessSP _sp, const addr_t addr = core_range.range.start(); const addr_t size = core_range.range.size(); auto data_up = std::make_unique(size, 0); +Status read_error; jasonmolenda wrote: The goal is to skip memory ranges that couldn't be read, without surfacing an error about them, right. I don't mind it that much, but another way to be to use the existing `error` Status object (which we know is state==Success at this point), and if our memory read does fail, we could do ``` if (error.Fail() || bytes_read == 0) { error.Clear(); continue; } ``` To make it clear that we don't want to surface a memory read failure for a region to the caller. But this is more of a style preference I think. https://github.com/llvm/llvm-project/pull/88564 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [libcxx] [lldb] [libc++][CI] Tests LLDB libc++ data formatters. (PR #88312)
jasonmolenda wrote: The lldb change part of this PR looks good to me. https://github.com/llvm/llvm-project/pull/88312 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix nullptr dereference on running x86 binary with x86-disabled llvm (PR #82603)
jasonmolenda wrote: Hi sorry @kovdan01 I missed this one in the emails. You're using an lldb which was built without the `LLVM_TARGETS_TO_BUILD` including X86, and running that lldb on an x86 corefile, got it. I have low confidence how well lldb will work in this situation, e.g. inferior function calls are obviously going to fail completely, and possibly not in a graceful way, but that doesn't impact corefiles. I'm less thrilled about adding a 570kb corefile to the repository to check this combination doesn't crash the unwinder. In lldb/unittest/UnwindAssembly we build the `x86` directory when ``` if ("X86" IN_LIST LLVM_TARGETS_TO_BUILD) add_subdirectory(x86) endif() ``` In Testx86AssemblyInspectionEngine.cpp we initialize llvm state in `Testx86AssemblyInspectionEngine::SetUpTestCase` and then run individual tests in the `TEST_F()` entries, creating a byte stream of prologues like ``` // 'int main() { }' compiled for x86_64-apple-macosx with clang uint8_t data[] = { 0x55, // offset 0 -- pushq %rbp 0x48, 0x89, 0xe5, // offset 1 -- movq %rsp, %rbp 0x31, 0xc0, // offset 4 -- xorl %eax, %eax 0x5d, // offset 6 -- popq %rbp 0xc3 // offset 7 -- retq }; ``` and run the unwind engine on those bytes. Could we add a `x86-but-no-x86-target` directory, write one test to see that the unwind engine can run against a byte buffer like this and not crash instead maybe? https://github.com/llvm/llvm-project/pull/82603 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reland "[lldb][lit] Add MallocNanoZone envvar to Darwin ASan builds" … (PR #88442)
https://github.com/jasonmolenda approved this pull request. This looks good to me. https://github.com/llvm/llvm-project/pull/88442 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix error in unrecognized register name handling for "SBFrame.register" (PR #88047)
https://github.com/jasonmolenda approved this pull request. Looks good. https://github.com/llvm/llvm-project/pull/88047 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 41dc04e - [lldb] Add swig doc for SBProcess address mask methods
Author: Jason Molenda Date: 2024-04-08T18:56:39-07:00 New Revision: 41dc04e5283adef9979cad2b126ab3e6c156034a URL: https://github.com/llvm/llvm-project/commit/41dc04e5283adef9979cad2b126ab3e6c156034a DIFF: https://github.com/llvm/llvm-project/commit/41dc04e5283adef9979cad2b126ab3e6c156034a.diff LOG: [lldb] Add swig doc for SBProcess address mask methods Add descriptions of `GetAddressMask`, `SetAddressMask`, `SetAddressableBits`, and `FixAddress` SBProcess methods. Added: Modified: lldb/bindings/interface/SBProcessDocstrings.i Removed: diff --git a/lldb/bindings/interface/SBProcessDocstrings.i b/lldb/bindings/interface/SBProcessDocstrings.i index c20ef3e4655bd4..1b98a79e4f6d36 100644 --- a/lldb/bindings/interface/SBProcessDocstrings.i +++ b/lldb/bindings/interface/SBProcessDocstrings.i @@ -199,6 +199,47 @@ SBProcess supports thread iteration. For example (from test/lldbutil.py), :: process_info.GetProcessID()" ) lldb::SBProcess::GetProcessInfo; +%feature("docstring", " +Get the current address mask in this Process of a given type. +There are lldb.eAddressMaskTypeCode and lldb.eAddressMaskTypeData address +masks, and on most Targets, the the Data address mask is more general +because there are no alignment restrictions, as there can be with Code +addresses. +lldb.eAddressMaskTypeAny may be used to get the most general mask. +The bits which are not used for addressing are set to 1 in the returned +mask. +In an unusual environment with diff erent address masks for high and low +memory, this may also be specified. This is uncommon, default is +lldb.eAddressMaskRangeLow." +) lldb::SBProcess::GetAddressMask; + +%feature("docstring", " +Set the current address mask in this Process for a given type, +lldb.eAddressMaskTypeCode or lldb.eAddressMaskTypeData. Bits that are not +used for addressing should be set to 1 in the mask. +When setting all masks, lldb.eAddressMaskTypeAll may be specified. +In an unusual environment with diff erent address masks for high and low +memory, this may also be specified. This is uncommon, default is +lldb.eAddressMaskRangeLow." +) lldb::SBProcess::SetAddressMask; + +%feature("docstring", " +Set the number of low bits relevant for addressing in this Process +for a given type, lldb.eAddressMaskTypeCode or lldb.eAddressMaskTypeData. +When setting all masks, lldb.eAddressMaskTypeAll may be specified. +In an unusual environment with diff erent address masks for high and low +memory, the address range may also be specified. This is uncommon, +default is lldb.eAddressMaskRangeLow." +) lldb::SBProcess::SetAddressableBits; + +%feature("docstring", " +Given a virtual address, clear the bits that are not used for addressing +(and may be used for metadata, memory tagging, point authentication, etc). +By default the most general mask, lldb.eAddressMaskTypeAny is used to +process the address, but lldb.eAddressMaskTypeData and +lldb.eAddressMaskTypeCode may be specified if the type of address is known." +) lldb::SBProcess::FixAddress; + %feature("docstring", " Allocates a block of memory within the process, with size and access permissions specified in the arguments. The permissions ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [NFC] Fix swig docstring annotations (PR #88073)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/88073 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [NFC] Fix swig docstring annotations (PR #88073)
jasonmolenda wrote: An example of the difference in the output this makes for `script help (lldb.SBProcess)`. Old: ``` | PutSTDIN(self, src) | Writes data into the current process's stdin. API client specifies a Python | string as the only argument. ``` new: ``` | PutSTDIN(self, src) | PutSTDIN(SBProcess self, char const * src) -> size_t | | Writes data into the current process's stdin. API client specifies a Python | string as the only argument. ``` https://github.com/llvm/llvm-project/pull/88073 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [NFC] Fix swig docstring annotations (PR #88073)
https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/88073 Some of the SB API method description docstrings for swing are annotated as `%feature("autodoc")` - but `"autodoc"` annotations are only to substitute a string showing the arguments and return variables - either in a single line, or in multiple lines. SBMemoryRegionInfo used `"autodoc"` correctly describing the parameters and return type, but then it added a description too which is not correct either. Change all of these that are adding a method description to use `%feature("docstring")` instead. There were a half dozen instances where `"autodoc"` was correctly being used and we have overriden the parameter and return types with a more readable version. >From 97f8f87fc4b14a973eb0bb0ac67ff36f1f4ef08a Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 8 Apr 2024 17:17:16 -0700 Subject: [PATCH] [lldb] [NFC] Fix swig docstring annotations Some of the SB API method description docstrings for swing are annotated as `%feature("autodoc")` - but `"autodoc"` annotations are only to substitute a string showing the arguments and return variables - either in a single line, or in multiple lines. SBMemoryRegionInfo used `"autodoc"` correctly describing the parameters and return type, but then it added a description too which is not correct either. Change all of these that are adding a method description to use `%feature("docstring")` instead. There were a half dozen instances where `"autodoc"` was correctly being used and we have overriden the parameter and return types with a more readable version. --- .../interface/SBMemoryRegionInfoDocstrings.i | 12 ++--- lldb/bindings/interface/SBProcessDocstrings.i | 50 +-- lldb/bindings/interface/SBQueueDocstrings.i | 4 +- lldb/bindings/interface/SBThreadDocstrings.i | 36 +++-- 4 files changed, 48 insertions(+), 54 deletions(-) diff --git a/lldb/bindings/interface/SBMemoryRegionInfoDocstrings.i b/lldb/bindings/interface/SBMemoryRegionInfoDocstrings.i index bd80740f3fdd3b..d7c68baf100e27 100644 --- a/lldb/bindings/interface/SBMemoryRegionInfoDocstrings.i +++ b/lldb/bindings/interface/SBMemoryRegionInfoDocstrings.i @@ -2,8 +2,7 @@ "API clients can get information about memory regions in processes." ) lldb::SBMemoryRegionInfo; -%feature("autodoc", " -GetRegionEnd(SBMemoryRegionInfo self) -> lldb::addr_t +%feature("docstring", " Returns whether this memory region has a list of modified (dirty) pages available or not. When calling GetNumDirtyPages(), you will have 0 returned for both \"dirty page list is not known\" and @@ -11,8 +10,7 @@ memory region). You must use this method to disambiguate." ) lldb::SBMemoryRegionInfo::HasDirtyMemoryPageList; -%feature("autodoc", " -GetNumDirtyPages(SBMemoryRegionInfo self) -> uint32_t +%feature("docstring", " Return the number of dirty (modified) memory pages in this memory region, if available. You must use the SBMemoryRegionInfo::HasDirtyMemoryPageList() method to @@ -20,16 +18,14 @@ on the target system can provide this information." ) lldb::SBMemoryRegionInfo::GetNumDirtyPages; -%feature("autodoc", " -GetDirtyPageAddressAtIndex(SBMemoryRegionInfo self, uint32_t idx) -> lldb::addr_t +%feature("docstring", " Return the address of a modified, or dirty, page of memory. If the provided index is out of range, or this memory region does not have dirty page information, LLDB_INVALID_ADDRESS is returned." ) lldb::SBMemoryRegionInfo::GetDirtyPageAddressAtIndex; -%feature("autodoc", " -GetPageSize(SBMemoryRegionInfo self) -> int +%feature("docstring", " Return the size of pages in this memory region. 0 will be returned if this information was unavailable." ) lldb::SBMemoryRegionInfo::GetPageSize(); diff --git a/lldb/bindings/interface/SBProcessDocstrings.i b/lldb/bindings/interface/SBProcessDocstrings.i index 3ee17e0c7f2fbb..c20ef3e4655bd4 100644 --- a/lldb/bindings/interface/SBProcessDocstrings.i +++ b/lldb/bindings/interface/SBProcessDocstrings.i @@ -20,18 +20,18 @@ SBProcess supports thread iteration. For example (from test/lldbutil.py), :: " ) lldb::SBProcess; -%feature("autodoc", " +%feature("docstring", " Writes data into the current process's stdin. API client specifies a Python string as the only argument." ) lldb::SBProcess::PutSTDIN; -%feature("autodoc", " +%feature("docstring", " Reads data from the current process's stdout stream. API client specifies the size of the buffer to read data into. It returns the byte buffer in a Python string." ) lldb::SBProcess::GetSTDOUT; -%feature("autodoc", " +%feature("docstring", " Reads data from the current process's stderr stream. API client specifies the size of the buffer to read data into. It returns the byte buffer in a Python
[Lldb-commits] [lldb] [lldb] [ObjC runtime] Don't cast to signed when left shifting (PR #86605)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/86605 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Revive shell test after updating UnwindTable (PR #86770)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/86770 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Revive shell test after updating UnwindTable (PR #86770)
https://github.com/jasonmolenda edited https://github.com/llvm/llvm-project/pull/86770 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Revive shell test after updating UnwindTable (PR #86770)
https://github.com/jasonmolenda edited https://github.com/llvm/llvm-project/pull/86770 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Revive shell test after updating UnwindTable (PR #86770)
jasonmolenda wrote: I developed & tested this on aarch64 linux, the only system I have here that runs this shell test. It's a little trickier to test on macOS, we basically only use compact_unwind and it's in the executable binary, not the dSYM SymbolFile. https://github.com/llvm/llvm-project/pull/86770 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Revive shell test after updating UnwindTable (PR #86770)
https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/86770 In commit 2f63718f8567413a1c596bda803663eb58d6da5a Author: Jason Molenda Date: Tue Mar 26 09:07:15 2024 -0700 [lldb] Don't clear a Module's UnwindTable when adding a SymbolFile (#86603) I stopped clearing a Module's UnwindTable when we add a SymbolFile to avoid the memory management problems with adding a symbol file asynchronously while the UnwindTable is being accessed on another thread. This broke the target-symbols-add-unwind.test shell test on Linux which removes the DWARF debub_frame section from a binary, loads it, then loads the unstripped binary with the DWARF debug_frame section and checks that the UnwindPlans for a function include debug_frame. I originally decided that I was willing to sacrifice the possiblity of additional unwind sources from a symbol file because we rely on assembly emulation so heavily, they're rarely critical. But there are targets where we we don't have emluation and rely on things like DWARF debug_frame a lot more, so this probably wasn't a good choice. This patch adds a new UnwindTable::Update method which looks for any new sources of unwind information and adds it to the UnwindTable, and calls that after a new SymbolFile has been added to a Module. >From 450f75c9fcc68bc3590afd21e6eb1abb85d987eb Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Tue, 26 Mar 2024 22:48:58 -0700 Subject: [PATCH] [lldb] Revive shell test after updating UnwindTable In commit 2f63718f8567413a1c596bda803663eb58d6da5a Author: Jason Molenda Date: Tue Mar 26 09:07:15 2024 -0700 [lldb] Don't clear a Module's UnwindTable when adding a SymbolFile (#86603) I stopped clearing a Module's UnwindTable when we add a SymbolFile to avoid the memory management problems with adding a symbol file asynchronously while the UnwindTable is being accessed on another thread. This broke the target-symbols-add-unwind.test shell test on Linux which removes the DWARF debub_frame section from a binary, loads it, then loads the unstripped binary with the DWARF debug_frame section and checks that the UnwindPlans for a function include debug_frame. I originally decided that I was willing to sacrifice the possiblity of additional unwind sources from a symbol file because we rely on assembly emulation so heavily, they're rarely critical. But there are targets where we we don't have emluation and rely on things like DWARF debug_frame a lot more, so this probably wasn't a good choice. This patch adds a new UnwindTable::Update method which looks for any new sources of unwind information and adds it to the UnwindTable, and calls that after a new SymbolFile has been added to a Module. --- lldb/include/lldb/Symbol/UnwindTable.h| 4 ++ lldb/source/Core/Module.cpp | 2 + lldb/source/Symbol/UnwindTable.cpp| 45 +++ .../SymbolFile/target-symbols-add-unwind.test | 27 +++ 4 files changed, 78 insertions(+) create mode 100644 lldb/test/Shell/SymbolFile/target-symbols-add-unwind.test diff --git a/lldb/include/lldb/Symbol/UnwindTable.h b/lldb/include/lldb/Symbol/UnwindTable.h index f0ce7047de2d1e..26826e5d1b497c 100644 --- a/lldb/include/lldb/Symbol/UnwindTable.h +++ b/lldb/include/lldb/Symbol/UnwindTable.h @@ -57,6 +57,10 @@ class UnwindTable { ArchSpec GetArchitecture(); + /// Called after a SymbolFile has been added to a Module to add any new + /// unwind sections that may now be available. + void Update(); + private: void Dump(Stream ); diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index a520523a96521a..9c105b3f0e57a1 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -1009,6 +1009,8 @@ SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) { m_symfile_up.reset( SymbolVendor::FindPlugin(shared_from_this(), feedback_strm)); m_did_load_symfile = true; +if (m_unwind_table) + m_unwind_table->Update(); } } } diff --git a/lldb/source/Symbol/UnwindTable.cpp b/lldb/source/Symbol/UnwindTable.cpp index 3c1a5187b11054..11bedf3d6052e7 100644 --- a/lldb/source/Symbol/UnwindTable.cpp +++ b/lldb/source/Symbol/UnwindTable.cpp @@ -84,6 +84,51 @@ void UnwindTable::Initialize() { } } +void UnwindTable::Update() { + if (!m_initialized) +return Initialize(); + + std::lock_guard guard(m_mutex); + + ObjectFile *object_file = m_module.GetObjectFile(); + if (!object_file) +return; + + if (!m_object_file_unwind_up) +m_object_file_unwind_up = object_file->CreateCallFrameInfo(); + + SectionList *sl = m_module.GetSectionList(); + if (!sl) +return; + + SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true); + if (!m_eh_frame_up && sect) { +m_eh_frame_up = std::make_unique( +*object_file, sect, DWARFCallFrameInfo::EH); + } + + sect =
[Lldb-commits] [lldb] 29318ab - [lldb] Remove test for add-symbol-file adds unwind source
Author: Jason Molenda Date: 2024-03-26T10:54:26-07:00 New Revision: 29318abe1d2c55e8543255d70f26ac93261b74a4 URL: https://github.com/llvm/llvm-project/commit/29318abe1d2c55e8543255d70f26ac93261b74a4 DIFF: https://github.com/llvm/llvm-project/commit/29318abe1d2c55e8543255d70f26ac93261b74a4.diff LOG: [lldb] Remove test for add-symbol-file adds unwind source In commit 2f63718f8567413a1c596bda803663eb58d6da5a Author: Jason Molenda Date: Tue Mar 26 09:07:15 2024 -0700 [lldb] Don't clear a Module's UnwindTable when adding a SymbolFile (#86603) I changed lldb to not clear a Module's UnwindTable when we add a SymbolFile to a binary, because the added benefit is marginal, and handling this reconstruction correctly is difficult. This test was written to explicitly create a test without unwind info in the binary, then add a symbol file with the unwind info, and check that it is present. I've intentionally broken this, so I'm removing the test. Added: Modified: Removed: lldb/test/Shell/SymbolFile/target-symbols-add-unwind.test diff --git a/lldb/test/Shell/SymbolFile/target-symbols-add-unwind.test b/lldb/test/Shell/SymbolFile/target-symbols-add-unwind.test deleted file mode 100644 index 5420213d405e86..00 --- a/lldb/test/Shell/SymbolFile/target-symbols-add-unwind.test +++ /dev/null @@ -1,27 +0,0 @@ -# TODO: When it's possible to run "image show-unwind" without a running -# process, we can remove the unsupported line below, and hard-code an ELF -# triple in the test. -# UNSUPPORTED: system-windows, system-darwin - -# RUN: cd %T -# RUN: %clang_host %S/Inputs/target-symbols-add-unwind.c -g \ -# RUN: -fno-unwind-tables -fno-asynchronous-unwind-tables \ -# RUN: -o target-symbols-add-unwind.debug -# RUN: llvm-objcopy --strip-debug target-symbols-add-unwind.debug \ -# RUN: target-symbols-add-unwind.stripped -# RUN: %lldb target-symbols-add-unwind.stripped -s %s -o quit | FileCheck %s - -process launch --stop-at-entry -image show-unwind -n main -# CHECK-LABEL: image show-unwind -n main -# CHECK-NOT: debug_frame UnwindPlan: - -target symbols add -s target-symbols-add-unwind.stripped target-symbols-add-unwind.debug -# CHECK-LABEL: target symbols add -# CHECK: symbol file {{.*}} has been added to {{.*}} - -image show-unwind -n main -# CHECK-LABEL: image show-unwind -n main -# CHECK: debug_frame UnwindPlan: -# CHECK-NEXT: This UnwindPlan originally sourced from DWARF CFI -# CHECK-NEXT: This UnwindPlan is sourced from the compiler: yes. ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [ObjC runtime] Don't cast to signed when left shifting (PR #86605)
https://github.com/jasonmolenda edited https://github.com/llvm/llvm-project/pull/86605 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [ObjC runtime] Don't cast to signed when left shifting (PR #86605)
@@ -3154,7 +3154,7 @@ AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor( << m_objc_debug_taggedpointer_ext_payload_lshift) >> m_objc_debug_taggedpointer_ext_payload_rshift); int64_t data_payload_signed = - ((int64_t)((int64_t)unobfuscated + ((int64_t)((uint64_t)unobfuscated << m_objc_debug_taggedpointer_ext_payload_lshift) >> jasonmolenda wrote: e.g. ``` (lldb) p (-5LL <<60) >> 60 (long long) -5 ``` if the bit slice we're pulling out has its high bit set, that'll shfit down and be sign extended. https://github.com/llvm/llvm-project/pull/86605 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [ObjC runtime] Don't cast to signed when left shifting (PR #86605)
@@ -3154,7 +3154,7 @@ AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor( << m_objc_debug_taggedpointer_ext_payload_lshift) >> m_objc_debug_taggedpointer_ext_payload_rshift); int64_t data_payload_signed = - ((int64_t)((int64_t)unobfuscated + ((int64_t)((uint64_t)unobfuscated << m_objc_debug_taggedpointer_ext_payload_lshift) >> jasonmolenda wrote: Probably the one interesting thing is that the value we're slicing out is, apparently, signed, so we want it to sign extend to Int64 when it is done. That would take a little more care with a bit slice approach. https://github.com/llvm/llvm-project/pull/86605 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [ObjC runtime] Don't cast to signed when left shifting (PR #86605)
@@ -3154,7 +3154,7 @@ AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor( << m_objc_debug_taggedpointer_ext_payload_lshift) >> m_objc_debug_taggedpointer_ext_payload_rshift); int64_t data_payload_signed = - ((int64_t)((int64_t)unobfuscated + ((int64_t)((uint64_t)unobfuscated << m_objc_debug_taggedpointer_ext_payload_lshift) >> jasonmolenda wrote: I suspect the runtime gave us these "left & right shift" values, and the person who wrote this used the obvious implementation. It could be expressed as a bit slice with a little subtraction, true. Just to be clear, we're not fixing a real bug here, we were saying a UInt64 was signed and then ubsan got all shirty when we shifted away some bits that would indicate sign. https://github.com/llvm/llvm-project/pull/86605 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Don't clear a Module's UnwindTable when adding a SymbolFile (PR #86603)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/86603 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Don't clear a Module's UnwindTable when adding a SymbolFile (PR #86603)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/86603 >From b6fcac7d6bb48b7fb665034712407c9ad7e4053a Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 25 Mar 2024 16:47:11 -0700 Subject: [PATCH] [lldb] Don't clear a Module's UnwindTable when adding a SymbolFile Fixing a crash in lldb when `symbols.auto-download` setting is enabled. When doing a backtrace, this feature has lldb search for a SymbolFile for stack frames when we are backtracing, and add them either synchoronously or asynchronously, depending on the specific setting used. Module::SetSymbolFileFileSpec clears the Module's UnwindTable, once we find a new SymbolFile. We may be adding a source of unwind information that we did not have when lldb was working only with the executable binary. What happens in practice is that we're using a reference to the Module's UnwindTable, and then the other thread getting the SymbolFile clears it and now the first thread is referring to freed memory and we can crash. When built with address sanitizer, it crashes much more reliably. Given that unwind information used for exception handling -- eh_frame, compact unwind -- is present in executable binaries, the only thing we're likely to *add* would be DWARF's `debug_frame` if that was also available. The actual value of re-creating the UnwindTable when we have added a SymbolFile is not large. I also tried fixing this by changing the Module to have a shared_ptr to the UnwindTable, so we could have two different UnwindTable's in use simultaneously for a brief period. This would be fine TODAY, but it introduces a very subtle bug that someone will have a heck of a time figuring out in the future. In the end, I believe the safest approach is to sacrifice the possible marginal gain of reconstructing the UnwindTable once a SymbolFile has been added, to sidestep this whole problem area. --- lldb/source/Core/Module.cpp | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 8ffa35518b3c36..a520523a96521a 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -1239,9 +1239,9 @@ void Module::SectionFileAddressesChanged() { UnwindTable ::GetUnwindTable() { if (!m_unwind_table) { -m_unwind_table.emplace(*this); if (!m_symfile_spec) SymbolLocator::DownloadSymbolFileAsync(GetUUID()); +m_unwind_table.emplace(*this); } return *m_unwind_table; } @@ -1359,15 +1359,10 @@ void Module::SetSymbolFileFileSpec(const FileSpec ) { // one obj_file->ClearSymtab(); -// Clear the unwind table too, as that may also be affected by the -// symbol file information. -m_unwind_table.reset(); - // The symbol file might be a directory bundle ("/tmp/a.out.dSYM") // instead of a full path to the symbol file within the bundle // ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to // check this - if (FileSystem::Instance().IsDirectory(file)) { std::string new_path(file.GetPath()); std::string old_path(obj_file->GetFileSpec().GetPath()); ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [ObjC runtime] Don't cast to signed when left shifting (PR #86605)
jasonmolenda wrote: I've seen this ubsan error every time I run the testsuite for years, i just finally sat down and figured out what was going on. https://github.com/llvm/llvm-project/pull/86605 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [ObjectFileMachO] LLVM_COV is not mapped into firmware memory (PR #86359)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/86359 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [ObjectFileMachO] LLVM_COV is not mapped into firmware memory (PR #86359)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/86359 >From 47bf1259289986cdc0df706aa40a18e58e94eee5 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Fri, 22 Mar 2024 16:31:07 -0700 Subject: [PATCH] [lldb] [ObjectFileMachO] LLVM_COV is not mapped into firmware memory It is possible to gather code coverage in a firmware environment, where the __LLVM_COV segment will not be mapped in memory but does exist in the binary, see https://llvm.org/devmtg/2020-09/slides/PhippsAlan_EmbeddedCodeCoverage_LLVM_Conf_Talk_final.pdf The __LLVM_COV segment in the binary happens to be at the same address as the __DATA segment, so if lldb treats this segment as loaded, it shadows the __DATA segment and address->symbol resolution can fail. For these non-userland code cases, we need to mark __LLVM_COV as not a loadable segment. rdar://124475661 --- .../Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp| 12 .../Plugins/ObjectFile/Mach-O/ObjectFileMachO.h | 1 + 2 files changed, 13 insertions(+) diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index bcf3a3274cf3a0..1caf93659956b4 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -905,6 +905,11 @@ ConstString ObjectFileMachO::GetSegmentNameDWARF() { return g_section_name; } +ConstString ObjectFileMachO::GetSegmentNameLLVM_COV() { + static ConstString g_section_name("__LLVM_COV"); + return g_section_name; +} + ConstString ObjectFileMachO::GetSectionNameEHFrame() { static ConstString g_section_name_eh_frame("__eh_frame"); return g_section_name_eh_frame; @@ -6145,6 +6150,13 @@ bool ObjectFileMachO::SectionIsLoadable(const Section *section) { return false; if (GetModule().get() != section->GetModule().get()) return false; + // firmware style binaries with llvm gcov segment do + // not have that segment mapped into memory. + if (section->GetName() == GetSegmentNameLLVM_COV()) { +const Strata strata = GetStrata(); +if (strata == eStrataKernel || strata == eStrataRawImage) + return false; + } // Be careful with __LINKEDIT and __DWARF segments if (section->GetName() == GetSegmentNameLINKEDIT() || section->GetName() == GetSegmentNameDWARF()) { diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index 0a47f3a7dd1861..55bc688126eb36 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -271,6 +271,7 @@ class ObjectFileMachO : public lldb_private::ObjectFile { static lldb_private::ConstString GetSegmentNameOBJC(); static lldb_private::ConstString GetSegmentNameLINKEDIT(); static lldb_private::ConstString GetSegmentNameDWARF(); + static lldb_private::ConstString GetSegmentNameLLVM_COV(); static lldb_private::ConstString GetSectionNameEHFrame(); llvm::MachO::dysymtab_command m_dysymtab; ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [ObjectFileMachO] LLVM_COV is not mapped into firmware memory (PR #86359)
https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/86359 It is possible to gather code coverage in a firmware environment, where the __LLVM_COV segment will not be mapped in memory but does exist in the binary, see https://llvm.org/devmtg/2020-09/slides/PhippsAlan_EmbeddedCodeCoverage_LLVM_Conf_Talk_final.pdf The __LLVM_COV segment in the binary happens to be at the same address as the __DATA segment, so if lldb treats this segment as loaded, it shadows the __DATA segment and address->symbol resolution can fail. For these non-userland code cases, we need to mark __LLVM_COV as not a loadable segment. rdar://124475661 >From 47bf1259289986cdc0df706aa40a18e58e94eee5 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Fri, 22 Mar 2024 16:31:07 -0700 Subject: [PATCH] [lldb] [ObjectFileMachO] LLVM_COV is not mapped into firmware memory It is possible to gather code coverage in a firmware environment, where the __LLVM_COV segment will not be mapped in memory but does exist in the binary, see https://llvm.org/devmtg/2020-09/slides/PhippsAlan_EmbeddedCodeCoverage_LLVM_Conf_Talk_final.pdf The __LLVM_COV segment in the binary happens to be at the same address as the __DATA segment, so if lldb treats this segment as loaded, it shadows the __DATA segment and address->symbol resolution can fail. For these non-userland code cases, we need to mark __LLVM_COV as not a loadable segment. rdar://124475661 --- .../Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp| 12 .../Plugins/ObjectFile/Mach-O/ObjectFileMachO.h | 1 + 2 files changed, 13 insertions(+) diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index bcf3a3274cf3a0..1caf93659956b4 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -905,6 +905,11 @@ ConstString ObjectFileMachO::GetSegmentNameDWARF() { return g_section_name; } +ConstString ObjectFileMachO::GetSegmentNameLLVM_COV() { + static ConstString g_section_name("__LLVM_COV"); + return g_section_name; +} + ConstString ObjectFileMachO::GetSectionNameEHFrame() { static ConstString g_section_name_eh_frame("__eh_frame"); return g_section_name_eh_frame; @@ -6145,6 +6150,13 @@ bool ObjectFileMachO::SectionIsLoadable(const Section *section) { return false; if (GetModule().get() != section->GetModule().get()) return false; + // firmware style binaries with llvm gcov segment do + // not have that segment mapped into memory. + if (section->GetName() == GetSegmentNameLLVM_COV()) { +const Strata strata = GetStrata(); +if (strata == eStrataKernel || strata == eStrataRawImage) + return false; + } // Be careful with __LINKEDIT and __DWARF segments if (section->GetName() == GetSegmentNameLINKEDIT() || section->GetName() == GetSegmentNameDWARF()) { diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index 0a47f3a7dd1861..55bc688126eb36 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -271,6 +271,7 @@ class ObjectFileMachO : public lldb_private::ObjectFile { static lldb_private::ConstString GetSegmentNameOBJC(); static lldb_private::ConstString GetSegmentNameLINKEDIT(); static lldb_private::ConstString GetSegmentNameDWARF(); + static lldb_private::ConstString GetSegmentNameLLVM_COV(); static lldb_private::ConstString GetSectionNameEHFrame(); llvm::MachO::dysymtab_command m_dysymtab; ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Invert relationship between Process and AddressableBits (PR #85858)
https://github.com/jasonmolenda approved this pull request. Thanks for fixing this, I hadn't been paying attention to the separation when I added this method. https://github.com/llvm/llvm-project/pull/85858 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [Mach-O] ProcessMachCore needs to strip TBI data from addrs (PR #84998)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/84998 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [Mach-O] ProcessMachCore needs to strip TBI data from addrs (PR #84998)
jasonmolenda wrote: Thanks for all the helpful comments as always, David. I updated the test case to fix the issues you identified and added comments that I think make it clearer that it is testing both a live process and a corefile. https://github.com/llvm/llvm-project/pull/84998 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [Mach-O] ProcessMachCore needs to strip TBI data from addrs (PR #84998)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/84998 >From 4278537c262b01b1d6432391bd9d8017eb96c60a Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Tue, 12 Mar 2024 17:09:30 -0700 Subject: [PATCH 1/2] [lldb] [Mach-O] ProcessMachCore needs to strip TBI data from addrs Darwin AArch64 application processors are run with Top Byte Ignore mode enabled so metadata may be stored in the top byte, it needs to be ignored when reading/writing memory. David Spickett handled this already in the base class Process::ReadMemory but ProcessMachCore overrides that method (to avoid the memory cache) and did not pick up the same change. I add a test case that creates a pointer with metadata in the top byte and dereferences it with a live process and with a corefile. rdar://123784501 --- .../Process/mach-core/ProcessMachCore.cpp | 2 +- lldb/test/API/macosx/tbi-honored/Makefile | 3 ++ .../API/macosx/tbi-honored/TestTBIHonored.py | 49 +++ lldb/test/API/macosx/tbi-honored/main.c | 13 + 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 lldb/test/API/macosx/tbi-honored/Makefile create mode 100644 lldb/test/API/macosx/tbi-honored/TestTBIHonored.py create mode 100644 lldb/test/API/macosx/tbi-honored/main.c diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index 3961dcf0fbcc0e..7b9938d4f02020 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -652,7 +652,7 @@ size_t ProcessMachCore::ReadMemory(addr_t addr, void *buf, size_t size, Status ) { // Don't allow the caching that lldb_private::Process::ReadMemory does since // in core files we have it all cached our our core file anyway. - return DoReadMemory(addr, buf, size, error); + return DoReadMemory(FixAnyAddress(addr), buf, size, error); } size_t ProcessMachCore::DoReadMemory(addr_t addr, void *buf, size_t size, diff --git a/lldb/test/API/macosx/tbi-honored/Makefile b/lldb/test/API/macosx/tbi-honored/Makefile new file mode 100644 index 00..10495940055b63 --- /dev/null +++ b/lldb/test/API/macosx/tbi-honored/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/macosx/tbi-honored/TestTBIHonored.py b/lldb/test/API/macosx/tbi-honored/TestTBIHonored.py new file mode 100644 index 00..d38685359af6d1 --- /dev/null +++ b/lldb/test/API/macosx/tbi-honored/TestTBIHonored.py @@ -0,0 +1,49 @@ +"""Test that lldb on Darwin ignores metadata in the top byte of addresses.""" + +import os +import re +import subprocess + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestTBIHonored(TestBase): +@no_debug_info_test +@skipUnlessDarwin +@skipIf(archs=no_match(["arm64", "arm64e"])) +@skipIfRemote +def do_variable_access_tests(self, frame): +self.assertEqual( +frame.variables["pb"][0] +.GetChildMemberWithName("p") +.Dereference() +.GetValueAsUnsigned(), +15, +) +addr = frame.variables["pb"][0].GetChildMemberWithName("p").GetValueAsUnsigned() +self.expect("expr -- *pb.p", substrs=["15"]) +self.expect("frame variable *pb.p", substrs=["15"]) +self.expect("expr -- *(int*)0x%x" % addr, substrs=["15"]) + +def test(self): +corefile = self.getBuildArtifact("process.core") +self.build() +(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( +self, "// break here", lldb.SBFileSpec("main.c") +) + +self.do_variable_access_tests(thread.GetFrameAtIndex(0)) + +self.runCmd("process save-core -s stack " + corefile) +self.dbg.DeleteTarget(target) + +# Now load the corefile +target = self.dbg.CreateTarget("") +process = target.LoadCore(corefile) +thread = process.GetSelectedThread() +self.assertTrue(process.GetSelectedThread().IsValid()) + +self.do_variable_access_tests(thread.GetFrameAtIndex(0)) diff --git a/lldb/test/API/macosx/tbi-honored/main.c b/lldb/test/API/macosx/tbi-honored/main.c new file mode 100644 index 00..3d7ad0b04cd664 --- /dev/null +++ b/lldb/test/API/macosx/tbi-honored/main.c @@ -0,0 +1,13 @@ +#include +#include +union ptrbytes { + int *p; + uint8_t bytes[8]; +}; +int main() { + int c = 15; + union ptrbytes pb; + pb.p = + pb.bytes[7] = 0xfe; + printf("%d\n", *pb.p); // break here +} >From 145e4161a311956ee15c4631667f332d50ef4e0b Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Wed, 13 Mar 2024 15:40:08 -0700 Subject: [PATCH 2/2] Address David Spickett's feedback on the testcase Lots of fixes to the test case for correctness and to make it
[Lldb-commits] [lldb] e2468bf - [lldb][debugserver] Update flags past to app launch request
Author: Jason Molenda Date: 2024-03-12T17:19:46-07:00 New Revision: e2468bf16a0c1f63a39aa417c15c03ebd77fab9e URL: https://github.com/llvm/llvm-project/commit/e2468bf16a0c1f63a39aa417c15c03ebd77fab9e DIFF: https://github.com/llvm/llvm-project/commit/e2468bf16a0c1f63a39aa417c15c03ebd77fab9e.diff LOG: [lldb][debugserver] Update flags past to app launch request rdar://117421999 Added: Modified: lldb/tools/debugserver/source/MacOSX/MachProcess.mm Removed: diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm index 87bdbf835bfd10..70b4564a027b1b 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm @@ -472,6 +472,8 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options, // And there are some other options at the top level in this dictionary: [options setObject:[NSNumber numberWithBool:YES] forKey:FBSOpenApplicationOptionKeyUnlockDevice]; + [options setObject:[NSNumber numberWithBool:YES] + forKey:FBSOpenApplicationOptionKeyPromptUnlockDevice]; // We have to get the "sequence ID & UUID" for this app bundle path and send // them to FBS: ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [Mach-O] ProcessMachCore needs to strip TBI data from addrs (PR #84998)
https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/84998 Darwin AArch64 application processors are run with Top Byte Ignore mode enabled so metadata may be stored in the top byte, it needs to be ignored when reading/writing memory. David Spickett handled this already in the base class Process::ReadMemory but ProcessMachCore overrides that method (to avoid the memory cache) and did not pick up the same change. I add a test case that creates a pointer with metadata in the top byte and dereferences it with a live process and with a corefile. rdar://123784501 >From 4278537c262b01b1d6432391bd9d8017eb96c60a Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Tue, 12 Mar 2024 17:09:30 -0700 Subject: [PATCH] [lldb] [Mach-O] ProcessMachCore needs to strip TBI data from addrs Darwin AArch64 application processors are run with Top Byte Ignore mode enabled so metadata may be stored in the top byte, it needs to be ignored when reading/writing memory. David Spickett handled this already in the base class Process::ReadMemory but ProcessMachCore overrides that method (to avoid the memory cache) and did not pick up the same change. I add a test case that creates a pointer with metadata in the top byte and dereferences it with a live process and with a corefile. rdar://123784501 --- .../Process/mach-core/ProcessMachCore.cpp | 2 +- lldb/test/API/macosx/tbi-honored/Makefile | 3 ++ .../API/macosx/tbi-honored/TestTBIHonored.py | 49 +++ lldb/test/API/macosx/tbi-honored/main.c | 13 + 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 lldb/test/API/macosx/tbi-honored/Makefile create mode 100644 lldb/test/API/macosx/tbi-honored/TestTBIHonored.py create mode 100644 lldb/test/API/macosx/tbi-honored/main.c diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index 3961dcf0fbcc0e..7b9938d4f02020 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -652,7 +652,7 @@ size_t ProcessMachCore::ReadMemory(addr_t addr, void *buf, size_t size, Status ) { // Don't allow the caching that lldb_private::Process::ReadMemory does since // in core files we have it all cached our our core file anyway. - return DoReadMemory(addr, buf, size, error); + return DoReadMemory(FixAnyAddress(addr), buf, size, error); } size_t ProcessMachCore::DoReadMemory(addr_t addr, void *buf, size_t size, diff --git a/lldb/test/API/macosx/tbi-honored/Makefile b/lldb/test/API/macosx/tbi-honored/Makefile new file mode 100644 index 00..10495940055b63 --- /dev/null +++ b/lldb/test/API/macosx/tbi-honored/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/macosx/tbi-honored/TestTBIHonored.py b/lldb/test/API/macosx/tbi-honored/TestTBIHonored.py new file mode 100644 index 00..d38685359af6d1 --- /dev/null +++ b/lldb/test/API/macosx/tbi-honored/TestTBIHonored.py @@ -0,0 +1,49 @@ +"""Test that lldb on Darwin ignores metadata in the top byte of addresses.""" + +import os +import re +import subprocess + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestTBIHonored(TestBase): +@no_debug_info_test +@skipUnlessDarwin +@skipIf(archs=no_match(["arm64", "arm64e"])) +@skipIfRemote +def do_variable_access_tests(self, frame): +self.assertEqual( +frame.variables["pb"][0] +.GetChildMemberWithName("p") +.Dereference() +.GetValueAsUnsigned(), +15, +) +addr = frame.variables["pb"][0].GetChildMemberWithName("p").GetValueAsUnsigned() +self.expect("expr -- *pb.p", substrs=["15"]) +self.expect("frame variable *pb.p", substrs=["15"]) +self.expect("expr -- *(int*)0x%x" % addr, substrs=["15"]) + +def test(self): +corefile = self.getBuildArtifact("process.core") +self.build() +(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( +self, "// break here", lldb.SBFileSpec("main.c") +) + +self.do_variable_access_tests(thread.GetFrameAtIndex(0)) + +self.runCmd("process save-core -s stack " + corefile) +self.dbg.DeleteTarget(target) + +# Now load the corefile +target = self.dbg.CreateTarget("") +process = target.LoadCore(corefile) +thread = process.GetSelectedThread() +self.assertTrue(process.GetSelectedThread().IsValid()) + +self.do_variable_access_tests(thread.GetFrameAtIndex(0)) diff --git a/lldb/test/API/macosx/tbi-honored/main.c b/lldb/test/API/macosx/tbi-honored/main.c new file mode 100644 index 00..3d7ad0b04cd664 --- /dev/null +++
[Lldb-commits] [lldb] [lldb] [debugserver] Handle interrupted reads correctly (PR #84872)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/84872 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [debugserver] Handle interrupted reads correctly (PR #84872)
https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/84872 The first half of this patch is a long-standing annoyance, if I attach to debugserver with lldb while it is waiting for an lldb connection, the syscall is interrupted and it doesn't retry, debugserver exits immediately. The second half is a request from another tool that is communicating with debugserver, that we retry reads on our sockets in the same way. I haven't dug in to the details of how they're communicating that this is necessary, but the best I've been able to find reading the POSIX API docs, this is fine. rdar://117113298 >From b2ed63b985c2509594ef647f8258a0854ff404a7 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 11 Mar 2024 22:19:49 -0700 Subject: [PATCH] [lldb] [debugserver] Handle interrupted reads correctly The first half of this patch is a long-standing annoyance, if I attach to debugserver with lldb while it is waiting for an lldb connection, the syscall is interrupted and it doesn't retry, debugserver exits immediately. The second half is a request from another tool that is communicating with debugserver, that we retry reads on our sockets in the same way. I haven't dug in to the details of how they're communicating that this is necessary, but the best I've been able to find reading the POSIX API docs, this is fine. rdar://117113298 --- lldb/tools/debugserver/source/RNBSocket.cpp | 16 +--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lldb/tools/debugserver/source/RNBSocket.cpp b/lldb/tools/debugserver/source/RNBSocket.cpp index 1282ea221625a0..fc55dbf2e1f1b0 100644 --- a/lldb/tools/debugserver/source/RNBSocket.cpp +++ b/lldb/tools/debugserver/source/RNBSocket.cpp @@ -120,8 +120,13 @@ rnb_err_t RNBSocket::Listen(const char *listen_host, uint16_t port, while (!accept_connection) { struct kevent event_list[4]; -int num_events = -kevent(queue_id, events.data(), events.size(), event_list, 4, NULL); +int num_events; +do { + errno = 0; + num_events = + kevent(queue_id, events.data(), events.size(), event_list, 4, NULL); +} while (num_events == -1 && + (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)); if (num_events < 0) { err.SetError(errno, DNBError::MachKernel); @@ -291,7 +296,12 @@ rnb_err_t RNBSocket::Read(std::string ) { // DNBLogThreadedIf(LOG_RNB_COMM, "%8u RNBSocket::%s calling read()", // (uint32_t)m_timer.ElapsedMicroSeconds(true), __FUNCTION__); DNBError err; - ssize_t bytesread = read(m_fd, buf, sizeof(buf)); + ssize_t bytesread; + do { +errno = 0; +bytesread = read(m_fd, buf, sizeof(buf)); + } while (bytesread == -1 && + (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)); if (bytesread <= 0) err.SetError(errno, DNBError::POSIX); else ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Turn off instruction flow control annotations by default (PR #84607)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/84607 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][doc] Updates build instructions. (PR #84630)
https://github.com/jasonmolenda approved this pull request. Looks good. I see the PR test for "Test documentation build" is failing, but that's an issue with the bot and pexpect. https://github.com/llvm/llvm-project/pull/84630 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Turn off instruction flow control annotations by default (PR #84607)
https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/84607 Walter Erquinigo added optional instruction annotations for x86 instructions in 2022 for the `thread trace dump instruction` command, and code to DisassemblerLLVMC to add annotations for instructions that change flow control, v. https://reviews.llvm.org/D128477 This was added as an option to `disassemble`, and the trace dump command enables it by default, but several other instruction dumpers were changed to display them by default as well. These are only implemented for Intel instructions, so our disassembly on other targets ends up looking like ``` (lldb) x/5i 0x186e4 0x186e4: 0xa9be6ffc unknown stpx28, x27, [sp, #-0x20]! 0x186e8: 0xa9017bfd unknown stpx29, x30, [sp, #0x10] 0x186ec: 0x910043fd unknown addx29, sp, #0x10 0x186f0: 0xd11843ff unknown subsp, sp, #0x610 0x186f4: 0x910c63e8 unknown addx8, sp, #0x318 ``` instead of `disassemble`'s output style of ``` lldb`main: lldb[0x186e4] <+0>: stpx28, x27, [sp, #-0x20]! lldb[0x186e8] <+4>: stpx29, x30, [sp, #0x10] lldb[0x186ec] <+8>: addx29, sp, #0x10 lldb[0x186f0] <+12>: subsp, sp, #0x610 lldb[0x186f4] <+16>: addx8, sp, #0x318 ``` Adding symbolic annotations for assembly instructions is something I'm interested in too, because we may have users investigating a crash or apparent-incorrect behavior who must debug optimized assembly and they may not be familiar with the ISA they're using, so short of flipping through a many-thousand-page PDF to understand each instruction, they're lost. They don't write assembly or work at that level, but to understand a bug, they have to understand what the instructions are actually doing. But the annotations that exist today don't move us forward much on that front - I'd argue that the flow control instructions on Intel are not hard to understand from their names, but that might just be my personal bias. Much trickier instructions exist in any event. Displaying this information by default for all targets when we only have one class of instructions on one target is not a good default. Also, in 2011 when Greg implemented the `memory read -f i` (aka `x/i`) command ``` commit 5009f9d5010a7e34ae15f962dac8505ea11a8716 Author: Greg Clayton Date: Thu Oct 27 17:55:14 2011 + [...] eFormatInstruction will print out disassembly with bytes and it will use the current target's architecture. The format character for this is "i" (which used to be being used for the integer format, but the integer format also has "d", so we gave the "i" format to disassembly), the long format is "instruction". ``` he had DumpDataExtractor's DumpInstructions print the bytes of the instruction -- that's the first field we see above for the `x/5i` after the address -- and this is only useful for people who are debugging the disassembler itself, I would argue. I don't want this displayed by default either. tl;dr this patch removes both fields from `memory read -f -i` and I think this is the right call today. While I'm really interested in instruction annotation, I don't think `x/i` is the right place to have it enabled by default unless it's really compelling on at least some of our major targets. >From 3969aaf70b22e2551e5d30a87cc80fa45ca83080 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Fri, 8 Mar 2024 21:50:28 -0800 Subject: [PATCH] Turn off instruction flow control annotations by default Walter Erquinigo added optional instruction annotations for x86 instructions in 2022 for the `thread trace dump instruction` command, and code to DisassemblerLLVMC to add annotations for instructions that change flow control, v. https://reviews.llvm.org/D128477 This was added as an option to `disassemble`, and the trace dump command enables it by default, but several other instruction dumpers were changed to display them by default as well. These are only implemented for Intel instructions, so our disassembly on other targets ends up looking like ``` (lldb) x/5i 0x186e4 0x186e4: 0xa9be6ffc unknown stpx28, x27, [sp, #-0x20]! 0x186e8: 0xa9017bfd unknown stpx29, x30, [sp, #0x10] 0x186ec: 0x910043fd unknown addx29, sp, #0x10 0x186f0: 0xd11843ff unknown subsp, sp, #0x610 0x186f4: 0x910c63e8 unknown addx8, sp, #0x318 ``` instead of `disassemble`'s output style of ``` lldb`main: lldb[0x186e4] <+0>: stpx28, x27, [sp, #-0x20]! lldb[0x186e8] <+4>: stpx29, x30, [sp, #0x10] lldb[0x186ec] <+8>: addx29, sp, #0x10 lldb[0x186f0] <+12>: subsp, sp, #0x610 lldb[0x186f4] <+16>: addx8, sp, #0x318 ``` Adding symbolic annotations for assembly instructions is something I'm interested in too, because we may have users investigating a crash or apparent-incorrect behavior who must debug optimized
[Lldb-commits] [lldb] [lldb] Address mask sbprocess apis and new mask invalid const (PR #83663)
jasonmolenda wrote: nb: this got a bot failure on the arm-linux-ubuntu bot, ``` mask = process.GetAddressMask(lldb.eAddressMaskTypeAny) process.SetAddressMask(lldb.eAddressMaskTypeCode, mask | 0x3) self.assertEqual( 0x02950001F694, process.FixAddress(0x00265E950001F697, lldb.eAddressMaskTypeCode), ) The API returned 0x02950001f694 instead of the expected 0x00265e950001f696. The low bits differ because ABISysV_arm hardcodes the Code address mask to clear the 0th bit, it doesn't use the Process code mask. I didn't debug why some of the high bytes were dropped. ``` I'm skipping TestAddressMasks for arch=arm now, but I don't even know if we should be able to set a mask which preserves the high 32-bits of an addr_t on a 32-bit host; all masks have to mask off the high word of addr_t to be a valid addresss, at a minimum. I don't have access to a 32-bit host that lldb runs on myself so my position is that I'll skip this API test entirely on 32-bit targets, I don't think the concepts make much sense there. https://github.com/llvm/llvm-project/pull/83663 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 04bbbba - Skip TestAddressMasks API tests on 32-bit arm
Author: Jason Molenda Date: 2024-03-06T10:58:03-08:00 New Revision: 04a271ebe4c2421f34a4fbf34c328df9f111 URL: https://github.com/llvm/llvm-project/commit/04a271ebe4c2421f34a4fbf34c328df9f111 DIFF: https://github.com/llvm/llvm-project/commit/04a271ebe4c2421f34a4fbf34c328df9f111.diff LOG: Skip TestAddressMasks API tests on 32-bit arm TestAddressMasks failed on the lldb-arm-buntu bot with the Code address mask test, mask = process.GetAddressMask(lldb.eAddressMaskTypeAny) process.SetAddressMask(lldb.eAddressMaskTypeCode, mask | 0x3) self.assertEqual( 0x02950001F694, process.FixAddress(0x00265E950001F697, lldb.eAddressMaskTypeCode), ) The API returned 0x02950001f694 instead of the expected 0x00265e950001f696. The low bits differ because ABISysV_arm hardcodes the Code address mask to clear the 0th bit, it doesn't use the Process code mask. I didn't debug why some of the high bytes were dropped. The address mask APIs are only important on 64-bit targets, where many of the bits are not used for addressing and are used for metadata instead, so I'm going to skip these tests on 32-bit arm instead of debugging. Added: Modified: lldb/test/API/python_api/process/address-masks/TestAddressMasks.py Removed: diff --git a/lldb/test/API/python_api/process/address-masks/TestAddressMasks.py b/lldb/test/API/python_api/process/address-masks/TestAddressMasks.py index e0a570c15961c2..152776efc726f2 100644 --- a/lldb/test/API/python_api/process/address-masks/TestAddressMasks.py +++ b/lldb/test/API/python_api/process/address-masks/TestAddressMasks.py @@ -19,6 +19,7 @@ def reset_all_masks(self, process): self.runCmd("settings set target.process.virtual-addressable-bits 0") self.runCmd("settings set target.process.highmem-virtual-addressable-bits 0") +@skipIf(archs=["arm"]) # 32-bit arm ABI hardcodes Code mask, is 32-bit def test_address_masks(self): self.build() (target, process, t, bp) = lldbutil.run_to_source_breakpoint( @@ -79,6 +80,7 @@ def test_address_masks(self): # AArch64 can have diff erent address masks for high and low memory, when diff erent # page tables are set up. @skipIf(archs=no_match(["arm64", "arm64e", "aarch64"])) +@skipIf(archs=["arm"]) # 32-bit arm ABI hardcodes Code mask, is 32-bit def test_address_masks_target_supports_highmem_tests(self): self.build() (target, process, t, bp) = lldbutil.run_to_source_breakpoint( @@ -111,6 +113,7 @@ def test_address_masks_target_supports_highmem_tests(self): # On most targets where we have a single mask for all address range, confirm # that the high memory masks are ignored. @skipIf(archs=["arm64", "arm64e", "aarch64"]) +@skipIf(archs=["arm"]) # 32-bit arm ABI hardcodes Code mask, is 32-bit def test_address_masks_target_no_highmem(self): self.build() (target, process, t, bp) = lldbutil.run_to_source_breakpoint( ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Address mask sbprocess apis and new mask invalid const (PR #83663)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/83663 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Address mask sbprocess apis and new mask invalid const (PR #83663)
jasonmolenda wrote: > Still not sure this is the ideal API but we can't know that until someone > (aka you :) ) has used it for a bit, so let's get this in. Thanks for all the help in finishing this one. I think this approach with enums to select the different types/ranges, with defaulted arguments so the most frequent use case is easy, is not bad. My original patch had a lot of different methods for the different operations and that was a lot less clear for script writers I think. https://github.com/llvm/llvm-project/pull/83663 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Address mask sbprocess apis and new mask invalid const (PR #83663)
@@ -0,0 +1,130 @@ +"""Test Python APIs for setting, getting, and using address masks.""" + +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class AddressMasksTestCase(TestBase): +NO_DEBUG_INFO_TESTCASE = True + +def reset_all_masks(self, process): +process.SetAddressMask( +lldb.eAddressMaskTypeAll, +lldb.LLDB_INVALID_ADDRESS_MASK, +lldb.eAddressMaskRangeAll, +) + +def test_address_masks(self): +self.build() +(target, process, t, bp) = lldbutil.run_to_source_breakpoint( +self, "break here", lldb.SBFileSpec("main.c") +) + +process.SetAddressableBits(lldb.eAddressMaskTypeAll, 42) +self.assertEqual(0x02953F94, process.FixAddress(0x00265E953F94)) +self.reset_all_masks(process) + +# ~((1ULL<<42)-1) == 0xfc00 +process.SetAddressMask(lldb.eAddressMaskTypeAll, 0xFC00) +self.assertEqual(0x02953F94, process.FixAddress(0x00265E953F94)) +self.reset_all_masks(process) + +# Check that all bits can pass through unmodified +process.SetAddressableBits(lldb.eAddressMaskTypeAll, 64) +self.assertEqual(0x00265E953F94, process.FixAddress(0x00265E953F94)) +self.reset_all_masks(process) + +process.SetAddressableBits( +lldb.eAddressMaskTypeAll, 42, lldb.eAddressMaskRangeAll +) +self.assertEqual(0x02950001F694, process.FixAddress(0x00265E950001F694)) +self.assertEqual(0xFE95F694, process.FixAddress(0xFFA65E95F694)) +self.reset_all_masks(process) + +# Set a eAddressMaskTypeCode which has the low 3 bits marked as non-address +# bits, confirm that they're cleared by FixAddress. +process.SetAddressableBits( +lldb.eAddressMaskTypeAll, 42, lldb.eAddressMaskRangeAll +) +mask = process.GetAddressMask(lldb.eAddressMaskTypeAny) +process.SetAddressMask(lldb.eAddressMaskTypeCode, mask | 0x3) +process.SetAddressMask(lldb.eAddressMaskTypeCode, 0xFC03) jasonmolenda wrote: Ah, thanks for spotting that. I originally wrote it as a hex literal and then I thought "Oh it would be clearer to bitmask in the 0b111" and forgot to remove the lit. https://github.com/llvm/llvm-project/pull/83663 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Address mask sbprocess apis and new mask invalid const (PR #83663)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/83663 >From c993c7cc7c1669ca7d06e52f1a1ff8dbefe9ebc9 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Thu, 29 Feb 2024 17:02:42 -0800 Subject: [PATCH 1/5] [lldb] Add SBProcess methods for get/set/use address masks (#83095) I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. rdar://123530562 --- lldb/include/lldb/API/SBProcess.h | 114 ++ lldb/include/lldb/Utility/AddressableBits.h | 3 + lldb/include/lldb/lldb-defines.h | 5 + lldb/include/lldb/lldb-enumerations.h | 16 +++ lldb/source/API/SBProcess.cpp | 92 ++ lldb/source/Target/Process.cpp| 10 +- lldb/source/Utility/AddressableBits.cpp | 12 +- .../python_api/process/address-masks/Makefile | 3 + .../process/address-masks/TestAddressMasks.py | 74 .../python_api/process/address-masks/main.c | 5 + 10 files changed, 328 insertions(+), 6 deletions(-) create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py create mode 100644 lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4f92a41f3028a2..7da3335a7234b7 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,6 +407,120 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// \{ + /// \group Mask Address Methods + /// + /// \a type + /// All of the methods in this group take \a type argument + /// which is an AddressMaskType enum value. + /// There can be different address masks for code addresses and + /// data addresses, this argument can select which to get/set, + /// or to use when clearing non-addressable bits from an address. + /// This choice of mask can be important for example on AArch32 + /// systems. Where instructions where instructions start on even addresses, + /// the 0th bit may be used to indicate that a function is thumb code. On + /// such a target, the eAddressMaskTypeCode may clear the 0th bit from an + /// address to get the actual address Whereas eAddressMaskTypeData would not. + /// + /// \a addr_range + /// Many of the methods in this group take an \a addr_range argument + /// which is an AddressMaskRange enum value. + /// Needing to specify the address range is highly unusual, and the + /// default argument can be used in nearly all circumstances. + /// On some architectures (e.g., AArch64), it is possible to have + /// different page table setups for low and high memory, so different + /// numbers of bits relevant to addressing. It is possible to have + /// a program running in one half of memory and accessing the other + /// as heap, so we need to maintain two different sets of address masks + /// to debug this correctly. + + /// Get the current address mask that will be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// See \ref Mask Address Methods description of this argument. + /// eAddressMaskTypeAny is often a suitable value when code and + /// data masks are the same on a given target. + /// + /// \param[in] addr_range + /// See \ref Mask Address Methods description of this argument. + /// This will default to eAddressMaskRangeLow which is the + /// only set of masks used normally. + /// + /// \return + /// The address mask currently in use. Bits which are not used + /// for addressing will be set to 1 in the mask. + lldb::addr_t GetAddressMask( + lldb::AddressMaskType type, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// See \ref Mask Address Methods description of this argument. + /// eAddressMaskTypeAll is often a suitable value when the + /// same mask is being set for both code and data. + /// + /// \param[in] mask + /// The address mask to set. Bits which are not used for addressing +
[Lldb-commits] [lldb] Address mask sbprocess apis and new mask invalid const (PR #83663)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/83663 >From c993c7cc7c1669ca7d06e52f1a1ff8dbefe9ebc9 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Thu, 29 Feb 2024 17:02:42 -0800 Subject: [PATCH 1/4] [lldb] Add SBProcess methods for get/set/use address masks (#83095) I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. rdar://123530562 --- lldb/include/lldb/API/SBProcess.h | 114 ++ lldb/include/lldb/Utility/AddressableBits.h | 3 + lldb/include/lldb/lldb-defines.h | 5 + lldb/include/lldb/lldb-enumerations.h | 16 +++ lldb/source/API/SBProcess.cpp | 92 ++ lldb/source/Target/Process.cpp| 10 +- lldb/source/Utility/AddressableBits.cpp | 12 +- .../python_api/process/address-masks/Makefile | 3 + .../process/address-masks/TestAddressMasks.py | 74 .../python_api/process/address-masks/main.c | 5 + 10 files changed, 328 insertions(+), 6 deletions(-) create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py create mode 100644 lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4f92a41f3028a2..7da3335a7234b7 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,6 +407,120 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// \{ + /// \group Mask Address Methods + /// + /// \a type + /// All of the methods in this group take \a type argument + /// which is an AddressMaskType enum value. + /// There can be different address masks for code addresses and + /// data addresses, this argument can select which to get/set, + /// or to use when clearing non-addressable bits from an address. + /// This choice of mask can be important for example on AArch32 + /// systems. Where instructions where instructions start on even addresses, + /// the 0th bit may be used to indicate that a function is thumb code. On + /// such a target, the eAddressMaskTypeCode may clear the 0th bit from an + /// address to get the actual address Whereas eAddressMaskTypeData would not. + /// + /// \a addr_range + /// Many of the methods in this group take an \a addr_range argument + /// which is an AddressMaskRange enum value. + /// Needing to specify the address range is highly unusual, and the + /// default argument can be used in nearly all circumstances. + /// On some architectures (e.g., AArch64), it is possible to have + /// different page table setups for low and high memory, so different + /// numbers of bits relevant to addressing. It is possible to have + /// a program running in one half of memory and accessing the other + /// as heap, so we need to maintain two different sets of address masks + /// to debug this correctly. + + /// Get the current address mask that will be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// See \ref Mask Address Methods description of this argument. + /// eAddressMaskTypeAny is often a suitable value when code and + /// data masks are the same on a given target. + /// + /// \param[in] addr_range + /// See \ref Mask Address Methods description of this argument. + /// This will default to eAddressMaskRangeLow which is the + /// only set of masks used normally. + /// + /// \return + /// The address mask currently in use. Bits which are not used + /// for addressing will be set to 1 in the mask. + lldb::addr_t GetAddressMask( + lldb::AddressMaskType type, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// See \ref Mask Address Methods description of this argument. + /// eAddressMaskTypeAll is often a suitable value when the + /// same mask is being set for both code and data. + /// + /// \param[in] mask + /// The address mask to set. Bits which are not used for addressing +
[Lldb-commits] [lldb] Address mask sbprocess apis and new mask invalid const (PR #83663)
jasonmolenda wrote: I pushed an update to this PR where I have the base class Fix methods in ABI.cpp ignore the highmem masks completely, I added highmem mask use when it's a highmem address and they are set to the AArch64ABI class so all the AArch64 ABI plugins are checking this. I changed the API test to only do highmem tests on AArch64 targets, and on other targets they will test that highmem masks are ignored. If any target wants this feature, I would like them to have to explicitly declare it in the TestAddressMasks.py so things don't kinda-work/fail unintentionally. https://github.com/llvm/llvm-project/pull/83663 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Address mask sbprocess apis and new mask invalid const (PR #83663)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/83663 >From c993c7cc7c1669ca7d06e52f1a1ff8dbefe9ebc9 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Thu, 29 Feb 2024 17:02:42 -0800 Subject: [PATCH 1/3] [lldb] Add SBProcess methods for get/set/use address masks (#83095) I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. rdar://123530562 --- lldb/include/lldb/API/SBProcess.h | 114 ++ lldb/include/lldb/Utility/AddressableBits.h | 3 + lldb/include/lldb/lldb-defines.h | 5 + lldb/include/lldb/lldb-enumerations.h | 16 +++ lldb/source/API/SBProcess.cpp | 92 ++ lldb/source/Target/Process.cpp| 10 +- lldb/source/Utility/AddressableBits.cpp | 12 +- .../python_api/process/address-masks/Makefile | 3 + .../process/address-masks/TestAddressMasks.py | 74 .../python_api/process/address-masks/main.c | 5 + 10 files changed, 328 insertions(+), 6 deletions(-) create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py create mode 100644 lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4f92a41f3028a2..7da3335a7234b7 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,6 +407,120 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// \{ + /// \group Mask Address Methods + /// + /// \a type + /// All of the methods in this group take \a type argument + /// which is an AddressMaskType enum value. + /// There can be different address masks for code addresses and + /// data addresses, this argument can select which to get/set, + /// or to use when clearing non-addressable bits from an address. + /// This choice of mask can be important for example on AArch32 + /// systems. Where instructions where instructions start on even addresses, + /// the 0th bit may be used to indicate that a function is thumb code. On + /// such a target, the eAddressMaskTypeCode may clear the 0th bit from an + /// address to get the actual address Whereas eAddressMaskTypeData would not. + /// + /// \a addr_range + /// Many of the methods in this group take an \a addr_range argument + /// which is an AddressMaskRange enum value. + /// Needing to specify the address range is highly unusual, and the + /// default argument can be used in nearly all circumstances. + /// On some architectures (e.g., AArch64), it is possible to have + /// different page table setups for low and high memory, so different + /// numbers of bits relevant to addressing. It is possible to have + /// a program running in one half of memory and accessing the other + /// as heap, so we need to maintain two different sets of address masks + /// to debug this correctly. + + /// Get the current address mask that will be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// See \ref Mask Address Methods description of this argument. + /// eAddressMaskTypeAny is often a suitable value when code and + /// data masks are the same on a given target. + /// + /// \param[in] addr_range + /// See \ref Mask Address Methods description of this argument. + /// This will default to eAddressMaskRangeLow which is the + /// only set of masks used normally. + /// + /// \return + /// The address mask currently in use. Bits which are not used + /// for addressing will be set to 1 in the mask. + lldb::addr_t GetAddressMask( + lldb::AddressMaskType type, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// See \ref Mask Address Methods description of this argument. + /// eAddressMaskTypeAll is often a suitable value when the + /// same mask is being set for both code and data. + /// + /// \param[in] mask + /// The address mask to set. Bits which are not used for addressing +
[Lldb-commits] [lldb] [lldb] Use sort-ordering for indexes when sorting by size (PR #83889)
https://github.com/jasonmolenda approved this pull request. https://github.com/llvm/llvm-project/pull/83889 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Address mask sbprocess apis and new mask invalid const (PR #83663)
jasonmolenda wrote: > > is about how TestAddressMasks.py assumes all Fix*Address implementations > > will handle a low and high memory address mask. The test currently assumes > > they do > > I'm not sure it makes much difference unless handling low/high produces a > large amount of boilerplate in every plugin. > > It is a bit of a foot gun to be able to tell the plugin for, for example, Arm > 32, that it has high/low mem masks. Since they won't make any sense, but it's > pretty well hidden. I agree, the more I think about this the less I'm delighted by making every plugin support high/low address masks when it may not make any sense there. I like keeping the support in the SysV AArch64 ABI even though it's not used on Linux in case this ABI were used for generic AArch64 firmware debug scenario where someone might try to use that ABI plugin. In the API test, I can have a dedicated test for the highmem checks an only run it on aarch64/arm64 targets. I can add a test for the non-aarch64/arm64 targets which tests that setting the highmem mask has no effect (and remove the highmem support from the base ABI method impl). https://github.com/llvm/llvm-project/pull/83663 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add support for sorting by size to `target module dump symtab` (PR #83527)
@@ -138,6 +134,21 @@ void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order, } } break; +case eSortOrderBySize: { + s->PutCString(" (sorted by size):\n"); + DumpSymbolHeader(s); + + std::multimap> size_map; + for (const Symbol : m_symbols) +size_map.emplace(symbol.GetByteSize(), ); + + for (const auto _to_symbol : size_map) { +const Symbol *symbol = size_to_symbol.second; +s->Indent(); +symbol->Dump(s, target, symbol - _symbols[0], name_preference); jasonmolenda wrote: I don't have a strong opinion here but when it's sorted by address, the index is still sorted-ordering. This is showing the original symtab index numbers. I think it should show the sorted index ordering, if someone wants to correspond a symbol to the original symtab, they can search for the symbol name. https://github.com/llvm/llvm-project/pull/83527 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
jasonmolenda wrote: After debugging, updating, and testing on aarch64-unbuntu, x86_64-macos, and arm64-macos, I have created a new PR with this commit plus an additional commit to fix the issues I found on the different platforms. https://github.com/llvm/llvm-project/pull/83663 https://github.com/llvm/llvm-project/pull/83095 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Address mask sbprocess apis and new mask invalid const (PR #83663)
jasonmolenda wrote: @DavidSpickett I spent a little time debugging this on aarch64-ubuntu and also testing on x86_64-macos (which has no address masks at all). This PR has the original commit from https://github.com/llvm/llvm-project/pull/83095 and then a second commit with the changes I needed to make as I debugged this in the full environment, so you only need to look at the second commit for the new changes. The main question I have (beyond feedback on how I describe things in comments of course ;) ) is about how TestAddressMasks.py assumes all Fix*Address implementations will handle a low and high memory address mask. The test currently assumes they do, but that means all people writing these methods need to get the highmem mask if it is a high-mem addr_t and apply that mask if it is set. I think it's the right choice, but I'm not wedded to it; maybe the right choice is narrowing that part of TestAddressMasks.py to only run on darwin systems. I also added a base class ABI::Fix*Address so these tests can be used on targets with no address masks at all, if someone wants to manipulate them via SB API for some reason (of course, the real reason is to make the test runnable). Maybe the test should be limited to only running on aarch64-linux and arm64-apple, I also am not convinced my choice is best here. https://github.com/llvm/llvm-project/pull/83663 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Address mask sbprocess apis and new mask invalid const (PR #83663)
https://github.com/jasonmolenda edited https://github.com/llvm/llvm-project/pull/83663 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Address mask sbprocess apis and new mask invalid const (PR #83663)
https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/83663 [lldb] Add SBProcess methods for get/set/use address masks (#83095) I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. This patch changes the value of "no mask set" from 0 to LLDB_INVALID_ADDRESS_MASK, which is UINT64_MAX. A mask of all 1's means "no bits are used for addressing" which is an impossible mask, whereas a mask of 0 means "all bits are used for addressing" which is possible. I added a base class implementation of ABI::FixCodeAddress and ABI::FixDataAddress that will apply the Process mask values if they are set to a value other than LLDB_INVALID_ADDRESS_MASK. I updated all the callers/users of the Mask methods which were handling a value of 0 to mean invalid mask to use LLDB_INVALID_ADDRESS_MASK. I added code to the ABISysV_arm64 Fix override methods to apply the Highmem masks if they have been set. These will not be set on a Linux environment, but I have tests in TestAddressMasks.py which set the highmem masks and I need all Fix*Mask implementations to check & use them for the tests to pass. rdar://123530562 >From c993c7cc7c1669ca7d06e52f1a1ff8dbefe9ebc9 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Thu, 29 Feb 2024 17:02:42 -0800 Subject: [PATCH 1/2] [lldb] Add SBProcess methods for get/set/use address masks (#83095) I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. rdar://123530562 --- lldb/include/lldb/API/SBProcess.h | 114 ++ lldb/include/lldb/Utility/AddressableBits.h | 3 + lldb/include/lldb/lldb-defines.h | 5 + lldb/include/lldb/lldb-enumerations.h | 16 +++ lldb/source/API/SBProcess.cpp | 92 ++ lldb/source/Target/Process.cpp| 10 +- lldb/source/Utility/AddressableBits.cpp | 12 +- .../python_api/process/address-masks/Makefile | 3 + .../process/address-masks/TestAddressMasks.py | 74 .../python_api/process/address-masks/main.c | 5 + 10 files changed, 328 insertions(+), 6 deletions(-) create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py create mode 100644 lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4f92a41f3028a2..7da3335a7234b7 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,6 +407,120 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// \{ + /// \group Mask Address Methods + /// + /// \a type + /// All of the methods in this group take \a type argument + /// which is an AddressMaskType enum value. + /// There can be different address masks for code addresses and + /// data addresses, this argument can select which to get/set, + /// or to use when clearing non-addressable bits from an address. + /// This choice of mask can be important for example on AArch32 + /// systems. Where instructions where instructions start on even addresses, + /// the 0th bit may be used to indicate that a function is thumb code. On + /// such a target, the eAddressMaskTypeCode may clear the 0th bit from an + /// address to get the actual address Whereas eAddressMaskTypeData would not. + /// + /// \a addr_range + /// Many of the methods in this group take an \a addr_range argument + /// which is an AddressMaskRange enum value. + /// Needing to specify the address range is highly unusual, and the + /// default argument
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
jasonmolenda wrote: I think I'm going open a new PR with the base class address masking added to the patch. I think having these API and the unwritten caveat is "they may be no-ops if you're using an ABI that doesn't do FixAddress" is going to confuse people. I still want to investigate why my API test failed on aarch64 linux because I didn't expect that, it's possible there's something else going on. But the ABI thing is definitely something I think should be addressed. https://github.com/llvm/llvm-project/pull/83095 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
jasonmolenda wrote: It does occur to me that I'm going to need to only run this API test on targets which have a FixAddress method in their ABI, the base class own't do it. Maybe it should have a base class impl that can be overridden, and use the Process masks if they are set. (they're all initialized to 0 which is an impossible mask value (no address bits)) The base class impl would need to be overridden for different architectures, e.g. on AArch64 where TBI or MTE are used, in addition to clearing/setting the top byte, we need to use b55 to determine if the non-address bits are set to 1 or 0. On armv7 the 0th bit can be used for metadata on TypeCode fixes, etc. But still I'd expect the lldb-aarch64-ubuntu bot to have had a FixAddress impl in its ABI. will check out when I build it up. https://github.com/llvm/llvm-project/pull/83095 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [debugserver] fix qLaunchSuccess error, add QErrorStringInPacketSupported (PR #82593)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/82593 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [debugserver] fix qLaunchSuccess error, add QErrorStringInPacketSupported (PR #82593)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/82593 >From 0ba4e6402969028fa6152c366a56063a56acded1 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Wed, 21 Feb 2024 22:48:36 -0800 Subject: [PATCH 1/3] [lldb] [debugserver] fix qLaunchSuccess error, add QErrorStringInPacketSupported Pavel added an extension to lldb's gdb remote serial protocol that allows the debug stub to append an error message (ascii hex encoded) after an error response packet Exx. This was added in 2017 in https://reviews.llvm.org/D34945 . lldb sends the QErrorStringInPacketSupported packet and then the remote stub may add these error strings. debugserver has added these strings to the vAttach family of packets to explain why an attach failed, without waiting to see the QErrorStringInPacketSupported packet to enable the mode. debugserver also has a bad implementation of this for the qLaunchSuccess packet, where "E" is sent followed by the literal characters of the error, instead of Exx;, which lldb can have problems parsing. This patch moves three utility functions earlier in RNBRemote.cpp, it accepts the QErrorStringInPacketSupported packet and only appends the expanded error messages when that has been sent (lldb always sends it at the beginning of a connection), fixes the error string returned by qLaunchSuccess and changes the vAttach error returns to only add the error string when the mode is enabled. --- lldb/tools/debugserver/source/RNBRemote.cpp | 157 lldb/tools/debugserver/source/RNBRemote.h | 5 + 2 files changed, 103 insertions(+), 59 deletions(-) diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index feea4c914ec536..8338e4d0032870 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -143,6 +143,39 @@ uint64_t decode_uint64(const char *p, int base, char **end = nullptr, return addr; } +void append_hex_value(std::ostream , const void *buf, size_t buf_size, + bool swap) { + int i; + const uint8_t *p = (const uint8_t *)buf; + if (swap) { +for (i = static_cast(buf_size) - 1; i >= 0; i--) + ostrm << RAWHEX8(p[i]); + } else { +for (size_t i = 0; i < buf_size; i++) + ostrm << RAWHEX8(p[i]); + } +} + +std::string cstring_to_asciihex_string(const char *str) { + std::string hex_str; + hex_str.reserve(strlen(str) * 2); + while (str && *str) { +uint8_t c = *str++; +char hexbuf[5]; +snprintf(hexbuf, sizeof(hexbuf), "%02x", c); +hex_str += hexbuf; + } + return hex_str; +} + +void append_hexified_string(std::ostream , const std::string ) { + size_t string_size = string.size(); + const char *string_buf = string.c_str(); + for (size_t i = 0; i < string_size; i++) { +ostrm << RAWHEX8(*(string_buf + i)); + } +} + extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args); @@ -171,7 +204,8 @@ RNBRemote::RNBRemote() m_extended_mode(false), m_noack_mode(false), m_thread_suffix_supported(false), m_list_threads_in_stop_reply(false), m_compression_minsize(384), m_enable_compression_next_send_packet(false), - m_compression_mode(compression_types::none) { + m_compression_mode(compression_types::none), + m_enable_error_strings(false) { DNBLogThreadedIf(LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__); CreatePacketTable(); } @@ -365,6 +399,11 @@ void RNBRemote::CreatePacketTable() { t.push_back(Packet( query_symbol_lookup, ::HandlePacket_qSymbol, NULL, "qSymbol:", "Notify that host debugger is ready to do symbol lookups")); + t.push_back(Packet(enable_error_strings, + ::HandlePacket_QEnableErrorStrings, NULL, + "QEnableErrorStrings", + "Tell " DEBUGSERVER_PROGRAM_NAME + " it can append descriptive error messages in replies.")); t.push_back(Packet(json_query_thread_extended_info, ::HandlePacket_jThreadExtendedInfo, NULL, "jThreadExtendedInfo", @@ -1566,11 +1605,13 @@ rnb_err_t RNBRemote::HandlePacket_qLaunchSuccess(const char *p) { if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Status() == 0) return SendPacket("OK"); std::ostringstream ret_str; - std::string status_str; - std::string error_quoted = binary_encode_string - (m_ctx.LaunchStatusAsString(status_str)); - ret_str << "E" << error_quoted; - + ret_str << "E89"; + if (m_enable_error_strings) { +std::string status_str; +std::string error_quoted = +cstring_to_asciihex_string(m_ctx.LaunchStatusAsString(status_str)); +ret_str << ";" << error_quoted; + } return SendPacket(ret_str.str()); } @@ -2534,39 +2575,6 @@ rnb_err_t RNBRemote::HandlePacket_QSetProcessEvent(const char *p) { return SendPacket("OK"); } -void
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
jasonmolenda wrote: Temporarily reverted this change while I investigate why the tests failed on all the linux bots (lldb-x86_64-debian, lldb-arm-ubuntu, lldb-aarch64-ubuntu), I'll build up in a VM and debug. https://github.com/llvm/llvm-project/pull/83095 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] e8ce864 - Revert "[lldb] Add SBProcess methods for get/set/use address masks (#83095)"
Author: Jason Molenda Date: 2024-02-29T17:29:24-08:00 New Revision: e8ce864a36ba02ddb63877905d49f1e9ac60b544 URL: https://github.com/llvm/llvm-project/commit/e8ce864a36ba02ddb63877905d49f1e9ac60b544 DIFF: https://github.com/llvm/llvm-project/commit/e8ce864a36ba02ddb63877905d49f1e9ac60b544.diff LOG: Revert "[lldb] Add SBProcess methods for get/set/use address masks (#83095)" This reverts commit 9a12b0a60084b2b92f728e1bddec884a47458459. TestAddressMasks fails its first test on lldb-x86_64-debian, lldb-arm-ubuntu, lldb-aarch64-ubuntu bots. Reverting while investigating. Added: Modified: lldb/include/lldb/API/SBProcess.h lldb/include/lldb/Utility/AddressableBits.h lldb/include/lldb/lldb-defines.h lldb/include/lldb/lldb-enumerations.h lldb/source/API/SBProcess.cpp lldb/source/Target/Process.cpp lldb/source/Utility/AddressableBits.cpp Removed: lldb/test/API/python_api/process/address-masks/Makefile lldb/test/API/python_api/process/address-masks/TestAddressMasks.py lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 7da3335a7234b7..4f92a41f3028a2 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,120 +407,6 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); - /// \{ - /// \group Mask Address Methods - /// - /// \a type - /// All of the methods in this group take \a type argument - /// which is an AddressMaskType enum value. - /// There can be diff erent address masks for code addresses and - /// data addresses, this argument can select which to get/set, - /// or to use when clearing non-addressable bits from an address. - /// This choice of mask can be important for example on AArch32 - /// systems. Where instructions where instructions start on even addresses, - /// the 0th bit may be used to indicate that a function is thumb code. On - /// such a target, the eAddressMaskTypeCode may clear the 0th bit from an - /// address to get the actual address Whereas eAddressMaskTypeData would not. - /// - /// \a addr_range - /// Many of the methods in this group take an \a addr_range argument - /// which is an AddressMaskRange enum value. - /// Needing to specify the address range is highly unusual, and the - /// default argument can be used in nearly all circumstances. - /// On some architectures (e.g., AArch64), it is possible to have - /// diff erent page table setups for low and high memory, so diff erent - /// numbers of bits relevant to addressing. It is possible to have - /// a program running in one half of memory and accessing the other - /// as heap, so we need to maintain two diff erent sets of address masks - /// to debug this correctly. - - /// Get the current address mask that will be applied to addresses - /// before reading from memory. - /// - /// \param[in] type - /// See \ref Mask Address Methods description of this argument. - /// eAddressMaskTypeAny is often a suitable value when code and - /// data masks are the same on a given target. - /// - /// \param[in] addr_range - /// See \ref Mask Address Methods description of this argument. - /// This will default to eAddressMaskRangeLow which is the - /// only set of masks used normally. - /// - /// \return - /// The address mask currently in use. Bits which are not used - /// for addressing will be set to 1 in the mask. - lldb::addr_t GetAddressMask( - lldb::AddressMaskType type, - lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); - - /// Set the current address mask that can be applied to addresses - /// before reading from memory. - /// - /// \param[in] type - /// See \ref Mask Address Methods description of this argument. - /// eAddressMaskTypeAll is often a suitable value when the - /// same mask is being set for both code and data. - /// - /// \param[in] mask - /// The address mask to set. Bits which are not used for addressing - /// should be set to 1 in the mask. - /// - /// \param[in] addr_range - /// See \ref Mask Address Methods description of this argument. - /// This will default to eAddressMaskRangeLow which is the - /// only set of masks used normally. - void SetAddressMask( - lldb::AddressMaskType type, lldb::addr_t mask, - lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); - - /// Set the number of bits used for addressing in this Process. - /// - /// On Darwin and similar systems, the addressable bits are expressed - /// as the number of low order bits that are relevant to addressing, - /// instead of a more general address mask. - /// This method calculates the correct mask value for a given number - /// of
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
https://github.com/jasonmolenda closed https://github.com/llvm/llvm-project/pull/83095 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [debugserver] fix qLaunchSuccess error, add QErrorStringInPacketSupported (PR #82593)
jasonmolenda wrote: Going back to this PR, @bulbazord @clayborg and I agreed that having a single method for sending error reply packets, which correctly encode the error string it if is available and extended-error-responses has been enabled, would be worth modifying all the error returns, so I did that. I found an additional bad error response in HandlePacket_D where it did not include hex digits on its error response. I think we're good to land this now. https://github.com/llvm/llvm-project/pull/82593 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [debugserver] fix qLaunchSuccess error, add QErrorStringInPacketSupported (PR #82593)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/82593 >From 0ba4e6402969028fa6152c366a56063a56acded1 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Wed, 21 Feb 2024 22:48:36 -0800 Subject: [PATCH 1/3] [lldb] [debugserver] fix qLaunchSuccess error, add QErrorStringInPacketSupported Pavel added an extension to lldb's gdb remote serial protocol that allows the debug stub to append an error message (ascii hex encoded) after an error response packet Exx. This was added in 2017 in https://reviews.llvm.org/D34945 . lldb sends the QErrorStringInPacketSupported packet and then the remote stub may add these error strings. debugserver has added these strings to the vAttach family of packets to explain why an attach failed, without waiting to see the QErrorStringInPacketSupported packet to enable the mode. debugserver also has a bad implementation of this for the qLaunchSuccess packet, where "E" is sent followed by the literal characters of the error, instead of Exx;, which lldb can have problems parsing. This patch moves three utility functions earlier in RNBRemote.cpp, it accepts the QErrorStringInPacketSupported packet and only appends the expanded error messages when that has been sent (lldb always sends it at the beginning of a connection), fixes the error string returned by qLaunchSuccess and changes the vAttach error returns to only add the error string when the mode is enabled. --- lldb/tools/debugserver/source/RNBRemote.cpp | 157 lldb/tools/debugserver/source/RNBRemote.h | 5 + 2 files changed, 103 insertions(+), 59 deletions(-) diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index feea4c914ec536..8338e4d0032870 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -143,6 +143,39 @@ uint64_t decode_uint64(const char *p, int base, char **end = nullptr, return addr; } +void append_hex_value(std::ostream , const void *buf, size_t buf_size, + bool swap) { + int i; + const uint8_t *p = (const uint8_t *)buf; + if (swap) { +for (i = static_cast(buf_size) - 1; i >= 0; i--) + ostrm << RAWHEX8(p[i]); + } else { +for (size_t i = 0; i < buf_size; i++) + ostrm << RAWHEX8(p[i]); + } +} + +std::string cstring_to_asciihex_string(const char *str) { + std::string hex_str; + hex_str.reserve(strlen(str) * 2); + while (str && *str) { +uint8_t c = *str++; +char hexbuf[5]; +snprintf(hexbuf, sizeof(hexbuf), "%02x", c); +hex_str += hexbuf; + } + return hex_str; +} + +void append_hexified_string(std::ostream , const std::string ) { + size_t string_size = string.size(); + const char *string_buf = string.c_str(); + for (size_t i = 0; i < string_size; i++) { +ostrm << RAWHEX8(*(string_buf + i)); + } +} + extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args); @@ -171,7 +204,8 @@ RNBRemote::RNBRemote() m_extended_mode(false), m_noack_mode(false), m_thread_suffix_supported(false), m_list_threads_in_stop_reply(false), m_compression_minsize(384), m_enable_compression_next_send_packet(false), - m_compression_mode(compression_types::none) { + m_compression_mode(compression_types::none), + m_enable_error_strings(false) { DNBLogThreadedIf(LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__); CreatePacketTable(); } @@ -365,6 +399,11 @@ void RNBRemote::CreatePacketTable() { t.push_back(Packet( query_symbol_lookup, ::HandlePacket_qSymbol, NULL, "qSymbol:", "Notify that host debugger is ready to do symbol lookups")); + t.push_back(Packet(enable_error_strings, + ::HandlePacket_QEnableErrorStrings, NULL, + "QEnableErrorStrings", + "Tell " DEBUGSERVER_PROGRAM_NAME + " it can append descriptive error messages in replies.")); t.push_back(Packet(json_query_thread_extended_info, ::HandlePacket_jThreadExtendedInfo, NULL, "jThreadExtendedInfo", @@ -1566,11 +1605,13 @@ rnb_err_t RNBRemote::HandlePacket_qLaunchSuccess(const char *p) { if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Status() == 0) return SendPacket("OK"); std::ostringstream ret_str; - std::string status_str; - std::string error_quoted = binary_encode_string - (m_ctx.LaunchStatusAsString(status_str)); - ret_str << "E" << error_quoted; - + ret_str << "E89"; + if (m_enable_error_strings) { +std::string status_str; +std::string error_quoted = +cstring_to_asciihex_string(m_ctx.LaunchStatusAsString(status_str)); +ret_str << ";" << error_quoted; + } return SendPacket(ret_str.str()); } @@ -2534,39 +2575,6 @@ rnb_err_t RNBRemote::HandlePacket_QSetProcessEvent(const char *p) { return SendPacket("OK"); } -void
[Lldb-commits] [lldb] [lldb] [debugserver] fix qLaunchSuccess error, add QErrorStringInPacketSupported (PR #82593)
https://github.com/jasonmolenda edited https://github.com/llvm/llvm-project/pull/82593 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/83095 >From dae16776e8c97158e8965e4d0e950cd2ce836f75 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 26 Feb 2024 18:05:27 -0800 Subject: [PATCH 1/9] [lldb] Add SBProcess methods for get/set/use address masks I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. rdar://123530562 --- lldb/include/lldb/API/SBProcess.h | 123 ++ lldb/include/lldb/Utility/AddressableBits.h | 3 + lldb/include/lldb/lldb-enumerations.h | 14 ++ lldb/source/API/SBProcess.cpp | 89 + lldb/source/Utility/AddressableBits.cpp | 12 +- .../python_api/process/address-masks/Makefile | 3 + .../process/address-masks/TestAddressMasks.py | 64 + .../python_api/process/address-masks/main.c | 5 + 8 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py create mode 100644 lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4f92a41f3028a2..7e9ad7d9a274f2 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,6 +407,129 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// Get the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be requested, or most commonly, + /// eAddressMaskTypeAny can be requested and the least specific + /// mask will be fetched. e.g. on a target where instructions + /// are word aligned, the Code mask might clear the low 2 bits. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is requested. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + /// numbers of bits relevant to addressing, and it is possible to have + /// a program running in one half of memory and accessing the other + /// as heap, etc. In that case the eAddressMaskRangeLow and + /// eAddressMaskRangeHigh will have different masks that must be handled. + /// + /// \return + /// The address mask currently in use. Bits which are not used + /// for addressing will be set to 1 in the mask. + lldb::addr_t GetAddressMask( + lldb::AddressMaskType type, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be set, or most commonly, + /// eAddressMaskTypeAll can be set for both types of addresses. + /// An example where they could be different is a target where + /// instructions are word aligned, so the low 2 bits are always + /// zero. + /// + /// \param[in] mask + /// The address mask to set. Bits which are not used for addressing + /// should be set to 1 in the mask. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is being set. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + ///
[Lldb-commits] [lldb] [lldb] [debugserver] fix qLaunchSuccess error, add QErrorStringInPacketSupported (PR #82593)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/82593 >From 0ba4e6402969028fa6152c366a56063a56acded1 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Wed, 21 Feb 2024 22:48:36 -0800 Subject: [PATCH 1/2] [lldb] [debugserver] fix qLaunchSuccess error, add QErrorStringInPacketSupported Pavel added an extension to lldb's gdb remote serial protocol that allows the debug stub to append an error message (ascii hex encoded) after an error response packet Exx. This was added in 2017 in https://reviews.llvm.org/D34945 . lldb sends the QErrorStringInPacketSupported packet and then the remote stub may add these error strings. debugserver has added these strings to the vAttach family of packets to explain why an attach failed, without waiting to see the QErrorStringInPacketSupported packet to enable the mode. debugserver also has a bad implementation of this for the qLaunchSuccess packet, where "E" is sent followed by the literal characters of the error, instead of Exx;, which lldb can have problems parsing. This patch moves three utility functions earlier in RNBRemote.cpp, it accepts the QErrorStringInPacketSupported packet and only appends the expanded error messages when that has been sent (lldb always sends it at the beginning of a connection), fixes the error string returned by qLaunchSuccess and changes the vAttach error returns to only add the error string when the mode is enabled. --- lldb/tools/debugserver/source/RNBRemote.cpp | 157 lldb/tools/debugserver/source/RNBRemote.h | 5 + 2 files changed, 103 insertions(+), 59 deletions(-) diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index feea4c914ec536..8338e4d0032870 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -143,6 +143,39 @@ uint64_t decode_uint64(const char *p, int base, char **end = nullptr, return addr; } +void append_hex_value(std::ostream , const void *buf, size_t buf_size, + bool swap) { + int i; + const uint8_t *p = (const uint8_t *)buf; + if (swap) { +for (i = static_cast(buf_size) - 1; i >= 0; i--) + ostrm << RAWHEX8(p[i]); + } else { +for (size_t i = 0; i < buf_size; i++) + ostrm << RAWHEX8(p[i]); + } +} + +std::string cstring_to_asciihex_string(const char *str) { + std::string hex_str; + hex_str.reserve(strlen(str) * 2); + while (str && *str) { +uint8_t c = *str++; +char hexbuf[5]; +snprintf(hexbuf, sizeof(hexbuf), "%02x", c); +hex_str += hexbuf; + } + return hex_str; +} + +void append_hexified_string(std::ostream , const std::string ) { + size_t string_size = string.size(); + const char *string_buf = string.c_str(); + for (size_t i = 0; i < string_size; i++) { +ostrm << RAWHEX8(*(string_buf + i)); + } +} + extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args); @@ -171,7 +204,8 @@ RNBRemote::RNBRemote() m_extended_mode(false), m_noack_mode(false), m_thread_suffix_supported(false), m_list_threads_in_stop_reply(false), m_compression_minsize(384), m_enable_compression_next_send_packet(false), - m_compression_mode(compression_types::none) { + m_compression_mode(compression_types::none), + m_enable_error_strings(false) { DNBLogThreadedIf(LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__); CreatePacketTable(); } @@ -365,6 +399,11 @@ void RNBRemote::CreatePacketTable() { t.push_back(Packet( query_symbol_lookup, ::HandlePacket_qSymbol, NULL, "qSymbol:", "Notify that host debugger is ready to do symbol lookups")); + t.push_back(Packet(enable_error_strings, + ::HandlePacket_QEnableErrorStrings, NULL, + "QEnableErrorStrings", + "Tell " DEBUGSERVER_PROGRAM_NAME + " it can append descriptive error messages in replies.")); t.push_back(Packet(json_query_thread_extended_info, ::HandlePacket_jThreadExtendedInfo, NULL, "jThreadExtendedInfo", @@ -1566,11 +1605,13 @@ rnb_err_t RNBRemote::HandlePacket_qLaunchSuccess(const char *p) { if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Status() == 0) return SendPacket("OK"); std::ostringstream ret_str; - std::string status_str; - std::string error_quoted = binary_encode_string - (m_ctx.LaunchStatusAsString(status_str)); - ret_str << "E" << error_quoted; - + ret_str << "E89"; + if (m_enable_error_strings) { +std::string status_str; +std::string error_quoted = +cstring_to_asciihex_string(m_ctx.LaunchStatusAsString(status_str)); +ret_str << ";" << error_quoted; + } return SendPacket(ret_str.str()); } @@ -2534,39 +2575,6 @@ rnb_err_t RNBRemote::HandlePacket_QSetProcessEvent(const char *p) { return SendPacket("OK"); } -void
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/83095 >From dae16776e8c97158e8965e4d0e950cd2ce836f75 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 26 Feb 2024 18:05:27 -0800 Subject: [PATCH 1/8] [lldb] Add SBProcess methods for get/set/use address masks I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. rdar://123530562 --- lldb/include/lldb/API/SBProcess.h | 123 ++ lldb/include/lldb/Utility/AddressableBits.h | 3 + lldb/include/lldb/lldb-enumerations.h | 14 ++ lldb/source/API/SBProcess.cpp | 89 + lldb/source/Utility/AddressableBits.cpp | 12 +- .../python_api/process/address-masks/Makefile | 3 + .../process/address-masks/TestAddressMasks.py | 64 + .../python_api/process/address-masks/main.c | 5 + 8 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py create mode 100644 lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4f92a41f3028a2..7e9ad7d9a274f2 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,6 +407,129 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// Get the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be requested, or most commonly, + /// eAddressMaskTypeAny can be requested and the least specific + /// mask will be fetched. e.g. on a target where instructions + /// are word aligned, the Code mask might clear the low 2 bits. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is requested. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + /// numbers of bits relevant to addressing, and it is possible to have + /// a program running in one half of memory and accessing the other + /// as heap, etc. In that case the eAddressMaskRangeLow and + /// eAddressMaskRangeHigh will have different masks that must be handled. + /// + /// \return + /// The address mask currently in use. Bits which are not used + /// for addressing will be set to 1 in the mask. + lldb::addr_t GetAddressMask( + lldb::AddressMaskType type, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be set, or most commonly, + /// eAddressMaskTypeAll can be set for both types of addresses. + /// An example where they could be different is a target where + /// instructions are word aligned, so the low 2 bits are always + /// zero. + /// + /// \param[in] mask + /// The address mask to set. Bits which are not used for addressing + /// should be set to 1 in the mask. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is being set. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + ///
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
https://github.com/jasonmolenda edited https://github.com/llvm/llvm-project/pull/83095 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
@@ -33,18 +33,26 @@ void AddressableBits::SetHighmemAddressableBits( m_high_memory_addr_bits = highmem_addressing_bits; } +addr_t AddressableBits::AddressableBitToMask(uint32_t addressable_bits) { + assert(addressable_bits <= sizeof(addr_t) * 8); jasonmolenda wrote: I forgot that I was duplicating the addressable-bits-to-mask calculation in Process.cpp when I read the settings values. I pushed a change to use the new static method in AddressableBits which includes the assert. https://github.com/llvm/llvm-project/pull/83095 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/83095 >From dae16776e8c97158e8965e4d0e950cd2ce836f75 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 26 Feb 2024 18:05:27 -0800 Subject: [PATCH 1/7] [lldb] Add SBProcess methods for get/set/use address masks I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. rdar://123530562 --- lldb/include/lldb/API/SBProcess.h | 123 ++ lldb/include/lldb/Utility/AddressableBits.h | 3 + lldb/include/lldb/lldb-enumerations.h | 14 ++ lldb/source/API/SBProcess.cpp | 89 + lldb/source/Utility/AddressableBits.cpp | 12 +- .../python_api/process/address-masks/Makefile | 3 + .../process/address-masks/TestAddressMasks.py | 64 + .../python_api/process/address-masks/main.c | 5 + 8 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py create mode 100644 lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4f92a41f3028a2..7e9ad7d9a274f2 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,6 +407,129 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// Get the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be requested, or most commonly, + /// eAddressMaskTypeAny can be requested and the least specific + /// mask will be fetched. e.g. on a target where instructions + /// are word aligned, the Code mask might clear the low 2 bits. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is requested. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + /// numbers of bits relevant to addressing, and it is possible to have + /// a program running in one half of memory and accessing the other + /// as heap, etc. In that case the eAddressMaskRangeLow and + /// eAddressMaskRangeHigh will have different masks that must be handled. + /// + /// \return + /// The address mask currently in use. Bits which are not used + /// for addressing will be set to 1 in the mask. + lldb::addr_t GetAddressMask( + lldb::AddressMaskType type, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be set, or most commonly, + /// eAddressMaskTypeAll can be set for both types of addresses. + /// An example where they could be different is a target where + /// instructions are word aligned, so the low 2 bits are always + /// zero. + /// + /// \param[in] mask + /// The address mask to set. Bits which are not used for addressing + /// should be set to 1 in the mask. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is being set. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + ///
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/83095 >From dae16776e8c97158e8965e4d0e950cd2ce836f75 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 26 Feb 2024 18:05:27 -0800 Subject: [PATCH 1/6] [lldb] Add SBProcess methods for get/set/use address masks I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. rdar://123530562 --- lldb/include/lldb/API/SBProcess.h | 123 ++ lldb/include/lldb/Utility/AddressableBits.h | 3 + lldb/include/lldb/lldb-enumerations.h | 14 ++ lldb/source/API/SBProcess.cpp | 89 + lldb/source/Utility/AddressableBits.cpp | 12 +- .../python_api/process/address-masks/Makefile | 3 + .../process/address-masks/TestAddressMasks.py | 64 + .../python_api/process/address-masks/main.c | 5 + 8 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py create mode 100644 lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4f92a41f3028a2..7e9ad7d9a274f2 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,6 +407,129 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// Get the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be requested, or most commonly, + /// eAddressMaskTypeAny can be requested and the least specific + /// mask will be fetched. e.g. on a target where instructions + /// are word aligned, the Code mask might clear the low 2 bits. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is requested. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + /// numbers of bits relevant to addressing, and it is possible to have + /// a program running in one half of memory and accessing the other + /// as heap, etc. In that case the eAddressMaskRangeLow and + /// eAddressMaskRangeHigh will have different masks that must be handled. + /// + /// \return + /// The address mask currently in use. Bits which are not used + /// for addressing will be set to 1 in the mask. + lldb::addr_t GetAddressMask( + lldb::AddressMaskType type, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be set, or most commonly, + /// eAddressMaskTypeAll can be set for both types of addresses. + /// An example where they could be different is a target where + /// instructions are word aligned, so the low 2 bits are always + /// zero. + /// + /// \param[in] mask + /// The address mask to set. Bits which are not used for addressing + /// should be set to 1 in the mask. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is being set. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + ///
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/83095 >From dae16776e8c97158e8965e4d0e950cd2ce836f75 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 26 Feb 2024 18:05:27 -0800 Subject: [PATCH 1/5] [lldb] Add SBProcess methods for get/set/use address masks I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. rdar://123530562 --- lldb/include/lldb/API/SBProcess.h | 123 ++ lldb/include/lldb/Utility/AddressableBits.h | 3 + lldb/include/lldb/lldb-enumerations.h | 14 ++ lldb/source/API/SBProcess.cpp | 89 + lldb/source/Utility/AddressableBits.cpp | 12 +- .../python_api/process/address-masks/Makefile | 3 + .../process/address-masks/TestAddressMasks.py | 64 + .../python_api/process/address-masks/main.c | 5 + 8 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py create mode 100644 lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4f92a41f3028a2..7e9ad7d9a274f2 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,6 +407,129 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// Get the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be requested, or most commonly, + /// eAddressMaskTypeAny can be requested and the least specific + /// mask will be fetched. e.g. on a target where instructions + /// are word aligned, the Code mask might clear the low 2 bits. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is requested. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + /// numbers of bits relevant to addressing, and it is possible to have + /// a program running in one half of memory and accessing the other + /// as heap, etc. In that case the eAddressMaskRangeLow and + /// eAddressMaskRangeHigh will have different masks that must be handled. + /// + /// \return + /// The address mask currently in use. Bits which are not used + /// for addressing will be set to 1 in the mask. + lldb::addr_t GetAddressMask( + lldb::AddressMaskType type, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be set, or most commonly, + /// eAddressMaskTypeAll can be set for both types of addresses. + /// An example where they could be different is a target where + /// instructions are word aligned, so the low 2 bits are always + /// zero. + /// + /// \param[in] mask + /// The address mask to set. Bits which are not used for addressing + /// should be set to 1 in the mask. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is being set. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + ///
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/83095 >From dae16776e8c97158e8965e4d0e950cd2ce836f75 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 26 Feb 2024 18:05:27 -0800 Subject: [PATCH 1/4] [lldb] Add SBProcess methods for get/set/use address masks I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. rdar://123530562 --- lldb/include/lldb/API/SBProcess.h | 123 ++ lldb/include/lldb/Utility/AddressableBits.h | 3 + lldb/include/lldb/lldb-enumerations.h | 14 ++ lldb/source/API/SBProcess.cpp | 89 + lldb/source/Utility/AddressableBits.cpp | 12 +- .../python_api/process/address-masks/Makefile | 3 + .../process/address-masks/TestAddressMasks.py | 64 + .../python_api/process/address-masks/main.c | 5 + 8 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py create mode 100644 lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4f92a41f3028a2..7e9ad7d9a274f2 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,6 +407,129 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// Get the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be requested, or most commonly, + /// eAddressMaskTypeAny can be requested and the least specific + /// mask will be fetched. e.g. on a target where instructions + /// are word aligned, the Code mask might clear the low 2 bits. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is requested. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + /// numbers of bits relevant to addressing, and it is possible to have + /// a program running in one half of memory and accessing the other + /// as heap, etc. In that case the eAddressMaskRangeLow and + /// eAddressMaskRangeHigh will have different masks that must be handled. + /// + /// \return + /// The address mask currently in use. Bits which are not used + /// for addressing will be set to 1 in the mask. + lldb::addr_t GetAddressMask( + lldb::AddressMaskType type, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be set, or most commonly, + /// eAddressMaskTypeAll can be set for both types of addresses. + /// An example where they could be different is a target where + /// instructions are word aligned, so the low 2 bits are always + /// zero. + /// + /// \param[in] mask + /// The address mask to set. Bits which are not used for addressing + /// should be set to 1 in the mask. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is being set. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + ///
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
@@ -1255,6 +1255,95 @@ lldb::SBFileSpec SBProcess::GetCoreFile() { return SBFileSpec(core_file); } +addr_t SBProcess::GetAddressMask(AddressMaskType type, + AddressMaskRange addr_range) { + LLDB_INSTRUMENT_VA(this, type, addr_range); + addr_t default_mask = 0; jasonmolenda wrote: A mask value of 0 would be an invalid address mask -- no bits are used for addressing. The variable name "default_mask" was a poor choice. But explicitly returning LLDB_INVALID_ADDRESS_MASK if we don't find any value might be the correct choice, it would mean you passed an invalid enum argument (or the SBProcess can't access its Process) https://github.com/llvm/llvm-project/pull/83095 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
jasonmolenda wrote: Thanks for the second round of feedback @hawkinsw . Let me try to read the Doxygen docs a little more closely tonight and see if the references I threw in there might actually do what I hoped they would. I briefly looked at the Doxygen docs to see the Grouping feature and got a little overwhelmed and wasn't sure what the expected formatting would be. https://github.com/llvm/llvm-project/pull/83095 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/83095 >From dae16776e8c97158e8965e4d0e950cd2ce836f75 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 26 Feb 2024 18:05:27 -0800 Subject: [PATCH 1/3] [lldb] Add SBProcess methods for get/set/use address masks I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. rdar://123530562 --- lldb/include/lldb/API/SBProcess.h | 123 ++ lldb/include/lldb/Utility/AddressableBits.h | 3 + lldb/include/lldb/lldb-enumerations.h | 14 ++ lldb/source/API/SBProcess.cpp | 89 + lldb/source/Utility/AddressableBits.cpp | 12 +- .../python_api/process/address-masks/Makefile | 3 + .../process/address-masks/TestAddressMasks.py | 64 + .../python_api/process/address-masks/main.c | 5 + 8 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py create mode 100644 lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4f92a41f3028a2..7e9ad7d9a274f2 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,6 +407,129 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// Get the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be requested, or most commonly, + /// eAddressMaskTypeAny can be requested and the least specific + /// mask will be fetched. e.g. on a target where instructions + /// are word aligned, the Code mask might clear the low 2 bits. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is requested. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + /// numbers of bits relevant to addressing, and it is possible to have + /// a program running in one half of memory and accessing the other + /// as heap, etc. In that case the eAddressMaskRangeLow and + /// eAddressMaskRangeHigh will have different masks that must be handled. + /// + /// \return + /// The address mask currently in use. Bits which are not used + /// for addressing will be set to 1 in the mask. + lldb::addr_t GetAddressMask( + lldb::AddressMaskType type, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be set, or most commonly, + /// eAddressMaskTypeAll can be set for both types of addresses. + /// An example where they could be different is a target where + /// instructions are word aligned, so the low 2 bits are always + /// zero. + /// + /// \param[in] mask + /// The address mask to set. Bits which are not used for addressing + /// should be set to 1 in the mask. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is being set. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + ///
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
@@ -407,6 +407,117 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// \{ + /// \group Mask Address Methods + /// + /// \a type + /// All of the methods in this group take \a type argument + /// which is an AddressMaskType enum value. jasonmolenda wrote: I need to read the Doxygen documentation more closely, I just made this up when I was trying to update to having references to these two documentation paragraphs, I don't know if it would render as anything meaningful. https://github.com/llvm/llvm-project/pull/83095 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
@@ -407,6 +407,117 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// \{ + /// \group Mask Address Methods + /// + /// \a type + /// All of the methods in this group take \a type argument + /// which is an AddressMaskType enum value. + /// There can be different address masks for code addresses and + /// data addresses, this argument can select which to get/set, + /// or to use when clearing non-addressable bits from an address. + /// On AArch32 code with arm+thumb code, where instructions start + /// on even addresses, the 0th bit may be used to indicate that + /// a function is thumb code. On such a target, the eAddressMaskTypeCode + /// may clear the 0th bit from an address to get the actual address. + /// + /// \a addr_range + /// Many of the methods in this group take an \a addr_range argument + /// which is an AddressMaskRange enum value. + /// Needing to specify the address range is highly unusual, and the + /// default argument can be used in nearly all circumstances. + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + /// numbers of bits relevant to addressing. It is possible to have + /// a program running in one half of memory and accessing the other + /// as heap, so we need to maintain two different sets of address masks + /// to debug this correctly. + + /// Get the current address mask that will be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// See \ref Mask Address Methods descripton of this argument. + /// eAddressMaskTypeAny is often a suitable value when code and + /// data masks are the same on a given target. + /// + /// \param[in] addr_range + /// See \ref Mask Address Methods descripton of this argument. + /// This will default to eAddressMaskRangeLow which is the + /// only set of masks used normally. + /// + /// \return + /// The address mask currently in use. Bits which are not used + /// for addressing will be set to 1 in the mask. + lldb::addr_t GetAddressMask( + lldb::AddressMaskType type, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// See \ref Mask Address Methods descripton of this argument. + /// eAddressMaskTypeAll is often a suitable value when the + /// same mask is being set for both code and data. + /// + /// \param[in] mask + /// The address mask to set. Bits which are not used for addressing + /// should be set to 1 in the mask. + /// + /// \param[in] addr_range + /// See \ref Mask Address Methods descripton of this argument. + /// This will default to eAddressMaskRangeLow which is the + /// only set of masks used normally. + void SetAddressMask( + lldb::AddressMaskType type, lldb::addr_t mask, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the number of bits used for addressing in this Process. + /// + /// In some environments, the number of bits that are used for addressing + /// is the natural representation instead of a mask, but lldb + /// internally represents this as a mask. This method calculates + /// the addressing mask that lldb uses that number of addressable bits. jasonmolenda wrote: Thanks, let me rewrite it to say "darwin likes addressable bits" directly :) On Linux the kernel provides a mask to apply to addresses to remove metadata, it's the most general representation so that's what we use internally in lldb. But with Darwin on AArch64, we're only concerned with the low order number of bits that are used for addressing -- the addressable bits. It's possible to calculate the mask incorrectly (I'm fixing my own bug with addressable-bits==64 in this patch), so I want to provide API for environments like Darwin where that's what the data they'll have from the OS etc. https://github.com/llvm/llvm-project/pull/83095 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
jasonmolenda wrote: Thanks so much for reading through these @DavidSpickett and @hawkinsw ! @adrian-prantl and @JDevlieghere suggested using a doxygen group for this set of methods and having the long definitions of `type` and `addr_range` a single time, referring back to them from the individual methods, I wasn't thrilled with all that duplicated text either. I think I did this well enough? https://github.com/llvm/llvm-project/pull/83095 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/83095 >From dae16776e8c97158e8965e4d0e950cd2ce836f75 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 26 Feb 2024 18:05:27 -0800 Subject: [PATCH 1/2] [lldb] Add SBProcess methods for get/set/use address masks I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905 which was approved but I wasn't thrilled with all the API I was adding to SBProcess for all of the address mask types / memory regions. In this update, I added enums to control type address mask type (code, data, any) and address space specifiers (low, high, all) with defaulted arguments for the most common case. This patch is also fixing a bug in the "addressable bits to address mask" calculation I added in AddressableBits::SetProcessMasks. If lldb were told that 64 bits are valid for addressing, this method would overflow the calculation and set an invalid mask. Added tests to check this specific bug while I was adding these APIs. rdar://123530562 --- lldb/include/lldb/API/SBProcess.h | 123 ++ lldb/include/lldb/Utility/AddressableBits.h | 3 + lldb/include/lldb/lldb-enumerations.h | 14 ++ lldb/source/API/SBProcess.cpp | 89 + lldb/source/Utility/AddressableBits.cpp | 12 +- .../python_api/process/address-masks/Makefile | 3 + .../process/address-masks/TestAddressMasks.py | 64 + .../python_api/process/address-masks/main.c | 5 + 8 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py create mode 100644 lldb/test/API/python_api/process/address-masks/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4f92a41f3028a2..7e9ad7d9a274f2 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -407,6 +407,129 @@ class LLDB_API SBProcess { /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); + /// Get the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be requested, or most commonly, + /// eAddressMaskTypeAny can be requested and the least specific + /// mask will be fetched. e.g. on a target where instructions + /// are word aligned, the Code mask might clear the low 2 bits. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is requested. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + /// numbers of bits relevant to addressing, and it is possible to have + /// a program running in one half of memory and accessing the other + /// as heap, etc. In that case the eAddressMaskRangeLow and + /// eAddressMaskRangeHigh will have different masks that must be handled. + /// + /// \return + /// The address mask currently in use. Bits which are not used + /// for addressing will be set to 1 in the mask. + lldb::addr_t GetAddressMask( + lldb::AddressMaskType type, + lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow); + + /// Set the current address mask that can be applied to addresses + /// before reading from memory. + /// + /// \param[in] type + /// lldb may have different address masks for code and data + /// addresses. Either can be set, or most commonly, + /// eAddressMaskTypeAll can be set for both types of addresses. + /// An example where they could be different is a target where + /// instructions are word aligned, so the low 2 bits are always + /// zero. + /// + /// \param[in] mask + /// The address mask to set. Bits which are not used for addressing + /// should be set to 1 in the mask. + /// + /// \param[in] addr_range + /// Specify whether the address mask for high or low address spaces + /// is being set. + /// It is highly unusual to have different address masks in high + /// or low memory, and by default the eAddressMaskRangeLow is the + /// only one used for both types of addresses, the default value for + /// this argument is the correct one. + /// + /// On some architectures like AArch64, it is possible to have + /// different page table setups for low and high memory, so different + ///