[Lldb-commits] [PATCH] D42917: Adapt some tests to work with PPC64le architecture
anajuliapc created this revision. Merge branch 'master' into adaptPPC64tests https://reviews.llvm.org/D42917 Files: packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_hits/TestMultipleHits.py packages/Python/lldbsuite/test/lang/c/register_variables/test.c packages/Python/lldbsuite/test/lldbplatformutil.py packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py source/Host/common/HostInfoBase.cpp Index: source/Host/common/HostInfoBase.cpp === --- source/Host/common/HostInfoBase.cpp +++ source/Host/common/HostInfoBase.cpp @@ -373,6 +373,7 @@ case llvm::Triple::aarch64: case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: case llvm::Triple::x86_64: arch_64.SetTriple(triple); arch_32.SetTriple(triple.get32BitArchVariant()); Index: packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py === --- packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py +++ packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py @@ -330,8 +330,9 @@ # Ensure we have a program counter register. self.assertTrue('pc' in generic_regs) -# Ensure we have a frame pointer register. -self.assertTrue('fp' in generic_regs) +# Ensure we have a frame pointer register. PPC64le's FP is the same as SP +if(self.getArchitecture() != 'powerpc64le'): +self.assertTrue('fp' in generic_regs) # Ensure we have a stack pointer register. self.assertTrue('sp' in generic_regs) Index: packages/Python/lldbsuite/test/lldbplatformutil.py === --- packages/Python/lldbsuite/test/lldbplatformutil.py +++ packages/Python/lldbsuite/test/lldbplatformutil.py @@ -33,6 +33,8 @@ test_case.expect("register read zero", substrs=['zero = 0x']) elif arch in ['s390x']: test_case.expect("register read r0", substrs=['r0 = 0x']) +elif arch in ['powerpc64le']: +test_case.expect("register read r0", substrs=['r0 = 0x']) else: # TODO: Add check for other architectures test_case.fail( Index: packages/Python/lldbsuite/test/lang/c/register_variables/test.c === --- packages/Python/lldbsuite/test/lang/c/register_variables/test.c +++ packages/Python/lldbsuite/test/lang/c/register_variables/test.c @@ -1,6 +1,6 @@ #include -#if defined(__arm__) || defined(__aarch64__) || defined (__mips__) +#if defined(__arm__) || defined(__aarch64__) || defined (__mips__) || defined(__powerpc64__) // Clang does not accept regparm attribute on these platforms. // Fortunately, the default calling convention passes arguments in registers // anyway. Index: packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_hits/TestMultipleHits.py === --- packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_hits/TestMultipleHits.py +++ packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_hits/TestMultipleHits.py @@ -21,7 +21,7 @@ @expectedFailureAll( oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows") -@skipIf(bugnumber="llvm.org/pr30758", oslist=["linux"], archs=["arm", "aarch64"]) +@skipIf(bugnumber="llvm.org/pr30758", oslist=["linux"], archs=["arm", "aarch64", "powerpc64le"]) def test(self): self.build() exe = self.getBuildArtifact("a.out") Index: source/Host/common/HostInfoBase.cpp === --- source/Host/common/HostInfoBase.cpp +++ source/Host/common/HostInfoBase.cpp @@ -373,6 +373,7 @@ case llvm::Triple::aarch64: case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: case llvm::Triple::x86_64: arch_64.SetTriple(triple); arch_32.SetTriple(triple.get32BitArchVariant()); Index: packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py === --- packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py +++ packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py @@ -330,8 +330,9 @@ # Ensure we have a program counter register. self.assertTrue('pc' in generic_regs) -# Ensure we have a frame pointer register. -self.assertTrue('fp' in generic_regs) +# Ensure we have a frame pointer register. PPC64le's FP is the same as SP +if(self.getArchitecture() != 'powerpc64le'): +self.assertTrue('fp' in generic_regs) # Ensure we have a stack pointer register. self.assertTrue('sp' in generic_regs) Index: packages/Python/lldbsuite/test/lldbplatformutil.
[Lldb-commits] [PATCH] D38897: Add specific ppc64le hardware watchpoint handler
anajuliapc added inline comments. Comment at: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp:374 + uint32_t tempControl = m_hwp_regs[wp_index].control; + long * tempSlot = reinterpret_cast(m_hwp_regs[wp_index].slot); + zturner wrote: > `reinterpret_cast` from `long*` to `long`? Is this correct? Yes, It's strange but is the only way it works without changing `NativeProcessLinux::PtraceWrapper`. `PPC_PTRACE_DELHWDEBUG` works different from other PPC ptrace requests, because it must pass the return of `PPC_PTRACE_SETHWDEBUG` to [[ https://github.com/torvalds/linux/blob/master/Documentation/powerpc/ptrace.txt#L147 | ptrace ]] instead of a data structure. If you pass it as `long`, PtraceWrapper fails because it must receive a `void*`. I'll check the other points, thanks for the comments. https://reviews.llvm.org/D38897 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D38897: Add specific ppc64le hardware watchpoint handler
anajuliapc updated this revision to Diff 119336. anajuliapc marked 6 inline comments as done. anajuliapc added a comment. - Add values to header file - Use std::array to declare m_hwp_regs - Use llvm's mask - Remove switch and use assert instead - Remove unnecessary 'else' - Change return https://reviews.llvm.org/D38897 Files: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp === --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1601,21 +1601,24 @@ // and we only want to override this behavior if we have explicitly // received a qHostInfo telling us otherwise if (m_qHostInfo_is_valid != eLazyBoolYes) { -// On targets like MIPS, watchpoint exceptions are always generated -// before the instruction is executed. The connected target may not -// support qHostInfo or qWatchpointSupportInfo packets. +// On targets like MIPS and ppc64le, watchpoint exceptions are always +// generated before the instruction is executed. The connected target +// may not support qHostInfo or qWatchpointSupportInfo packets. if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || -atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el) +atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el || +atype == llvm::Triple::ppc64le) after = false; else after = true; } else { -// For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo -// if it is not calculated before. -if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate && +// For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to +// eLazyBoolNo if it is not calculated before. +if ((m_watchpoints_trigger_after_instruction == eLazyBoolCalculate && (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || - atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) + atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) || +atype == llvm::Triple::ppc64le) { m_watchpoints_trigger_after_instruction = eLazyBoolNo; +} after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo); } Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h === --- source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h +++ source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextLinux_ppc64le.h -*- C++ -*-===// +//===-- NativeRegisterContextLinux_ppc64le.h *- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -49,6 +49,28 @@ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + //-- + // Hardware watchpoint mangement functions + //-- + + uint32_t NumSupportedHardwareWatchpoints() override; + + uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, + uint32_t watch_flags) override; + + bool ClearHardwareWatchpoint(uint32_t hw_index) override; + + Status GetWatchpointHitIndex(uint32_t &wp_index, + lldb::addr_t trap_addr) override; + + lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override; + + lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override; + + uint32_t GetWatchpointSize(uint32_t wp_index); + + bool WatchpointIsEnabled(uint32_t wp_index); + protected: Status DoReadGPR(void *buf, size_t buf_size) override; @@ -60,6 +82,29 @@ GPR m_gpr_ppc64le; // 64-bit general purpose registers. bool IsGPR(unsigned reg) const; + + Status ReadHardwareDebugInfo(); + + Status WriteHardwareDebugRegs(); + + // Debug register info for hardware watchpoints management. + struct DREG { +lldb::addr_t address; // Breakpoint/watchpoint address value. +lldb::addr_t hit_addr; // Address at which last watchpoint trigger +// exception occurred. +lldb::addr_t real_addr; // Address value that should cause target to stop. +uint32_t control; // Breakpoint/watchpoint control value. +uint32_t refcount; // Serves as enable/disable and reference counter. +long slot; // Saves the value returned from PTRACE_SETHWDEBUG. +int mode; // Defines if watchpoint is read/write/access. + }; + + std::array m_hwp_regs; + + // 16 is jus
[Lldb-commits] [PATCH] D38897: Add specific ppc64le hardware watchpoint handler
anajuliapc added a comment. I applied some of the suggestions. I'm still working on the others, since I may need to change some logic Thanks for the comments https://reviews.llvm.org/D38897 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D38897: Add specific ppc64le hardware watchpoint handler
anajuliapc updated this revision to Diff 119567. anajuliapc marked 2 inline comments as done. anajuliapc added a comment. - Change numeric values to enum - Use llvm's functions to align addresses https://reviews.llvm.org/D38897 Files: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp === --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1601,21 +1601,24 @@ // and we only want to override this behavior if we have explicitly // received a qHostInfo telling us otherwise if (m_qHostInfo_is_valid != eLazyBoolYes) { -// On targets like MIPS, watchpoint exceptions are always generated -// before the instruction is executed. The connected target may not -// support qHostInfo or qWatchpointSupportInfo packets. +// On targets like MIPS and ppc64le, watchpoint exceptions are always +// generated before the instruction is executed. The connected target +// may not support qHostInfo or qWatchpointSupportInfo packets. if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || -atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el) +atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el || +atype == llvm::Triple::ppc64le) after = false; else after = true; } else { -// For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo -// if it is not calculated before. -if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate && +// For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to +// eLazyBoolNo if it is not calculated before. +if ((m_watchpoints_trigger_after_instruction == eLazyBoolCalculate && (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || - atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) + atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) || +atype == llvm::Triple::ppc64le) { m_watchpoints_trigger_after_instruction = eLazyBoolNo; +} after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo); } Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h === --- source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h +++ source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextLinux_ppc64le.h -*- C++ -*-===// +//===-- NativeRegisterContextLinux_ppc64le.h *- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -49,6 +49,28 @@ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + //-- + // Hardware watchpoint mangement functions + //-- + + uint32_t NumSupportedHardwareWatchpoints() override; + + uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, + uint32_t watch_flags) override; + + bool ClearHardwareWatchpoint(uint32_t hw_index) override; + + Status GetWatchpointHitIndex(uint32_t &wp_index, + lldb::addr_t trap_addr) override; + + lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override; + + lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override; + + uint32_t GetWatchpointSize(uint32_t wp_index); + + bool WatchpointIsEnabled(uint32_t wp_index); + protected: Status DoReadGPR(void *buf, size_t buf_size) override; @@ -60,6 +82,29 @@ GPR m_gpr_ppc64le; // 64-bit general purpose registers. bool IsGPR(unsigned reg) const; + + Status ReadHardwareDebugInfo(); + + Status WriteHardwareDebugRegs(); + + // Debug register info for hardware watchpoints management. + struct DREG { +lldb::addr_t address; // Breakpoint/watchpoint address value. +lldb::addr_t hit_addr; // Address at which last watchpoint trigger +// exception occurred. +lldb::addr_t real_addr; // Address value that should cause target to stop. +uint32_t control; // Breakpoint/watchpoint control value. +uint32_t refcount; // Serves as enable/disable and reference counter. +long slot; // Saves the value returned from PTRACE_SETHWDEBUG. +int mode; // Defines if watchpoint is read/write/access. + }; + + std::array m_hwp_regs; + + // 16 is just a maximum value, query hardware for actual watchpoint count + uint32_t m_max_hwp_supported
[Lldb-commits] [PATCH] D38897: Add specific ppc64le hardware watchpoint handler
anajuliapc added inline comments. Comment at: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp:327-333 + for (uint32_t i = 0; i < m_max_hwp_supported; i++) { +if ((m_hwp_regs[i].control & 1) == 0) { + wp_index = i; // Mark last free slot +} else if (m_hwp_regs[i].address == addr) { + return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints. +} + } zturner wrote: > Can we use a range-based for here? > > ``` > DREG *reg = nullptr; > for (auto &dr : m_hwp_regs) { > if (dr.control & 1) == 0) > reg = &dr; > else if (dr.address == addr) > return LLDB_INVALID_INDEX32; > } > > if (!reg) > return LLDB_INVALID_INDEX32; > > reg->real_addr = real_addr; > reg->address = addr; > reg->control = control_value; > reg->mode = rw_mode; > ``` > > etc I don't think it's worth the effort to do it like that. This function returns `wp_index` anyway, and it's easier to limit the number of watchpoints to PowerPC's actual limit, which is given by ptrace. Comment at: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp:416-417 + +bool NativeRegisterContextLinux_ppc64le::WatchpointIsEnabled( +uint32_t wp_index) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); zturner wrote: > Can this function accept a `const DREG&` instead of an index? No because it's called by `NativeProcessLinux.`, I would have to change it too and I don't think I should since is a common file. Comment at: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h:70-72 + uint32_t GetWatchpointSize(uint32_t wp_index); + + bool WatchpointIsEnabled(uint32_t wp_index); zturner wrote: > Can these two functions take `const DREG&` instead of indices? Also, it > seems like they could be raised out of the class and into global static > functions in the cpp file. I had some ideas while implementing your sugestions... I'm thinking about removing these functions and put these information in `m_hwp_regs` struct. Do you think I should do it in a new patch? https://reviews.llvm.org/D38897 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D38897: Add specific ppc64le hardware watchpoint handler
anajuliapc added inline comments. Comment at: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp:284 + switch (watch_flags) { + case write_mode: +rw_mode = PPC_BREAKPOINT_TRIGGER_WRITE; clayborg wrote: > We should use the lldb::WatchpointKind from lldb-enumerations.h: > > ``` > //-- > // Watchpoint Kind > // Indicates what types of events cause the watchpoint to fire. > // Used by Native*Protocol-related classes. > //-- > FLAGS_ENUM(WatchpointKind){eWatchpointKindRead = (1u << 0), >eWatchpointKindWrite = (1u << 1)}; > ``` > > The you look at the bits and do the right thing. "access_mode" used below > will just be if read and write are set. Variable `watch_flags` is set in [[ https://github.com/llvm-mirror/lldb/blob/master/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp#L2561 | GDBRemoteCommunicationServerLLGS ]] with `read = 2` and `write = 1`. Where do you think I should change it? https://reviews.llvm.org/D38897 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D38897: Add specific ppc64le hardware watchpoint handler
anajuliapc updated this revision to Diff 119835. anajuliapc added a comment. - Switch over read and write eWatchpointKind to match with watch_flags https://reviews.llvm.org/D38897 Files: include/lldb/lldb-enumerations.h source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp === --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1601,21 +1601,24 @@ // and we only want to override this behavior if we have explicitly // received a qHostInfo telling us otherwise if (m_qHostInfo_is_valid != eLazyBoolYes) { -// On targets like MIPS, watchpoint exceptions are always generated -// before the instruction is executed. The connected target may not -// support qHostInfo or qWatchpointSupportInfo packets. +// On targets like MIPS and ppc64le, watchpoint exceptions are always +// generated before the instruction is executed. The connected target +// may not support qHostInfo or qWatchpointSupportInfo packets. if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || -atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el) +atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el || +atype == llvm::Triple::ppc64le) after = false; else after = true; } else { -// For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo -// if it is not calculated before. -if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate && +// For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to +// eLazyBoolNo if it is not calculated before. +if ((m_watchpoints_trigger_after_instruction == eLazyBoolCalculate && (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || - atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) + atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) || +atype == llvm::Triple::ppc64le) { m_watchpoints_trigger_after_instruction = eLazyBoolNo; +} after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo); } Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h === --- source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h +++ source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextLinux_ppc64le.h -*- C++ -*-===// +//===-- NativeRegisterContextLinux_ppc64le.h *- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -49,6 +49,28 @@ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + //-- + // Hardware watchpoint mangement functions + //-- + + uint32_t NumSupportedHardwareWatchpoints() override; + + uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, + uint32_t watch_flags) override; + + bool ClearHardwareWatchpoint(uint32_t hw_index) override; + + Status GetWatchpointHitIndex(uint32_t &wp_index, + lldb::addr_t trap_addr) override; + + lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override; + + lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override; + + uint32_t GetWatchpointSize(uint32_t wp_index); + + bool WatchpointIsEnabled(uint32_t wp_index); + protected: Status DoReadGPR(void *buf, size_t buf_size) override; @@ -60,6 +82,29 @@ GPR m_gpr_ppc64le; // 64-bit general purpose registers. bool IsGPR(unsigned reg) const; + + Status ReadHardwareDebugInfo(); + + Status WriteHardwareDebugRegs(); + + // Debug register info for hardware watchpoints management. + struct DREG { +lldb::addr_t address; // Breakpoint/watchpoint address value. +lldb::addr_t hit_addr; // Address at which last watchpoint trigger +// exception occurred. +lldb::addr_t real_addr; // Address value that should cause target to stop. +uint32_t control; // Breakpoint/watchpoint control value. +uint32_t refcount; // Serves as enable/disable and reference counter. +long slot; // Saves the value returned from PTRACE_SETHWDEBUG. +int mode; // Defines if watchpoint is read/write/access. + }; + + std::array m_hwp_regs; + + // 16 is just a maximum value, query hardware for actual watchpoint count + uint32_t m_max_hwp_supported = 16; + uint
[Lldb-commits] [PATCH] D38897: Add specific ppc64le hardware watchpoint handler
anajuliapc updated this revision to Diff 119847. anajuliapc marked an inline comment as done. anajuliapc added a comment. - Use bitwise OR operator https://reviews.llvm.org/D38897 Files: include/lldb/lldb-enumerations.h source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp === --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1601,21 +1601,24 @@ // and we only want to override this behavior if we have explicitly // received a qHostInfo telling us otherwise if (m_qHostInfo_is_valid != eLazyBoolYes) { -// On targets like MIPS, watchpoint exceptions are always generated -// before the instruction is executed. The connected target may not -// support qHostInfo or qWatchpointSupportInfo packets. +// On targets like MIPS and ppc64le, watchpoint exceptions are always +// generated before the instruction is executed. The connected target +// may not support qHostInfo or qWatchpointSupportInfo packets. if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || -atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el) +atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el || +atype == llvm::Triple::ppc64le) after = false; else after = true; } else { -// For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo -// if it is not calculated before. -if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate && +// For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to +// eLazyBoolNo if it is not calculated before. +if ((m_watchpoints_trigger_after_instruction == eLazyBoolCalculate && (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || - atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) + atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) || +atype == llvm::Triple::ppc64le) { m_watchpoints_trigger_after_instruction = eLazyBoolNo; +} after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo); } Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h === --- source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h +++ source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextLinux_ppc64le.h -*- C++ -*-===// +//===-- NativeRegisterContextLinux_ppc64le.h *- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -49,6 +49,28 @@ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + //-- + // Hardware watchpoint mangement functions + //-- + + uint32_t NumSupportedHardwareWatchpoints() override; + + uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, + uint32_t watch_flags) override; + + bool ClearHardwareWatchpoint(uint32_t hw_index) override; + + Status GetWatchpointHitIndex(uint32_t &wp_index, + lldb::addr_t trap_addr) override; + + lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override; + + lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override; + + uint32_t GetWatchpointSize(uint32_t wp_index); + + bool WatchpointIsEnabled(uint32_t wp_index); + protected: Status DoReadGPR(void *buf, size_t buf_size) override; @@ -60,6 +82,29 @@ GPR m_gpr_ppc64le; // 64-bit general purpose registers. bool IsGPR(unsigned reg) const; + + Status ReadHardwareDebugInfo(); + + Status WriteHardwareDebugRegs(); + + // Debug register info for hardware watchpoints management. + struct DREG { +lldb::addr_t address; // Breakpoint/watchpoint address value. +lldb::addr_t hit_addr; // Address at which last watchpoint trigger +// exception occurred. +lldb::addr_t real_addr; // Address value that should cause target to stop. +uint32_t control; // Breakpoint/watchpoint control value. +uint32_t refcount; // Serves as enable/disable and reference counter. +long slot; // Saves the value returned from PTRACE_SETHWDEBUG. +int mode; // Defines if watchpoint is read/write/access. + }; + + std::array m_hwp_regs; + + // 16 is just a maximum value, query hardware for actual watchpoint count + uint32_t m_max_hwp_supported = 16; + uint
[Lldb-commits] [PATCH] D38897: Add specific ppc64le hardware watchpoint handler
anajuliapc added inline comments. Comment at: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp:59 + + enum watch_mode { +write_mode = 1, I just realized I forgot to remove the enum I've created before. I know you already accepted this patch, but may I update it anyway? https://reviews.llvm.org/D38897 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D38897: Add specific ppc64le hardware watchpoint handler
anajuliapc updated this revision to Diff 119885. anajuliapc added a comment. - Remove unused enum https://reviews.llvm.org/D38897 Files: include/lldb/lldb-enumerations.h source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp === --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1601,21 +1601,24 @@ // and we only want to override this behavior if we have explicitly // received a qHostInfo telling us otherwise if (m_qHostInfo_is_valid != eLazyBoolYes) { -// On targets like MIPS, watchpoint exceptions are always generated -// before the instruction is executed. The connected target may not -// support qHostInfo or qWatchpointSupportInfo packets. +// On targets like MIPS and ppc64le, watchpoint exceptions are always +// generated before the instruction is executed. The connected target +// may not support qHostInfo or qWatchpointSupportInfo packets. if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || -atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el) +atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el || +atype == llvm::Triple::ppc64le) after = false; else after = true; } else { -// For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo -// if it is not calculated before. -if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate && +// For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to +// eLazyBoolNo if it is not calculated before. +if ((m_watchpoints_trigger_after_instruction == eLazyBoolCalculate && (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || - atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) + atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) || +atype == llvm::Triple::ppc64le) { m_watchpoints_trigger_after_instruction = eLazyBoolNo; +} after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo); } Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h === --- source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h +++ source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextLinux_ppc64le.h -*- C++ -*-===// +//===-- NativeRegisterContextLinux_ppc64le.h *- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -49,6 +49,28 @@ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + //-- + // Hardware watchpoint mangement functions + //-- + + uint32_t NumSupportedHardwareWatchpoints() override; + + uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, + uint32_t watch_flags) override; + + bool ClearHardwareWatchpoint(uint32_t hw_index) override; + + Status GetWatchpointHitIndex(uint32_t &wp_index, + lldb::addr_t trap_addr) override; + + lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override; + + lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override; + + uint32_t GetWatchpointSize(uint32_t wp_index); + + bool WatchpointIsEnabled(uint32_t wp_index); + protected: Status DoReadGPR(void *buf, size_t buf_size) override; @@ -60,6 +82,29 @@ GPR m_gpr_ppc64le; // 64-bit general purpose registers. bool IsGPR(unsigned reg) const; + + Status ReadHardwareDebugInfo(); + + Status WriteHardwareDebugRegs(); + + // Debug register info for hardware watchpoints management. + struct DREG { +lldb::addr_t address; // Breakpoint/watchpoint address value. +lldb::addr_t hit_addr; // Address at which last watchpoint trigger +// exception occurred. +lldb::addr_t real_addr; // Address value that should cause target to stop. +uint32_t control; // Breakpoint/watchpoint control value. +uint32_t refcount; // Serves as enable/disable and reference counter. +long slot; // Saves the value returned from PTRACE_SETHWDEBUG. +int mode; // Defines if watchpoint is read/write/access. + }; + + std::array m_hwp_regs; + + // 16 is just a maximum value, query hardware for actual watchpoint count + uint32_t m_max_hwp_supported = 16; + uint32_t m_max_hbp_supported = 16; + bool m_refresh_h