diff --git a/src/developer/debug/debug_agent/arch_x64.cc b/src/developer/debug/debug_agent/arch_x64.cc
index 5054e66c6851e5384a274a420aef86029af1178e..5084e6c0a7cfa7489d8512f1b78f1b3e45c22899 100644
--- a/src/developer/debug/debug_agent/arch_x64.cc
+++ b/src/developer/debug/debug_agent/arch_x64.cc
@@ -10,6 +10,7 @@
 #include "src/developer/debug/debug_agent/arch_x64_helpers.h"
 #include "src/developer/debug/debug_agent/debugged_thread.h"
 #include "src/developer/debug/ipc/register_desc.h"
+#include "src/developer/debug/shared/arch_x86.h"
 #include "src/developer/debug/shared/logging/logging.h"
 
 namespace debug_agent {
@@ -252,12 +253,12 @@ debug_ipc::NotifyException::Type ArchProvider::DecodeExceptionType(
                        << DR6ToString(debug_regs.dr6);
 
     // HW breakpoints have priority over single-step.
-    if (FLAG_VALUE(debug_regs.dr6, kDR6B0) ||
-        FLAG_VALUE(debug_regs.dr6, kDR6B1) ||
-        FLAG_VALUE(debug_regs.dr6, kDR6B2) ||
-        FLAG_VALUE(debug_regs.dr6, kDR6B3)) {
+    if (X86_FLAG_VALUE(debug_regs.dr6, DR6B0) ||
+        X86_FLAG_VALUE(debug_regs.dr6, DR6B1) ||
+        X86_FLAG_VALUE(debug_regs.dr6, DR6B2) ||
+        X86_FLAG_VALUE(debug_regs.dr6, DR6B3)) {
       return debug_ipc::NotifyException::Type::kHardware;
-    } else if (FLAG_VALUE(debug_regs.dr6, kDR6BS)) {
+    } else if (X86_FLAG_VALUE(debug_regs.dr6, DR6BS)) {
       return debug_ipc::NotifyException::Type::kSingleStep;
     } else {
       FXL_NOTREACHED() << "x86: No known hw exception set in DR6";
diff --git a/src/developer/debug/debug_agent/arch_x64.h b/src/developer/debug/debug_agent/arch_x64.h
index a5cb05cb194bcbe5e50560725b103cba25744bc7..b6008b2603e78d09ef6f89297dd1e01a9979c1a6 100644
--- a/src/developer/debug/debug_agent/arch_x64.h
+++ b/src/developer/debug/debug_agent/arch_x64.h
@@ -15,44 +15,5 @@ namespace arch {
 // The type that is large enough to hold the debug breakpoint CPU instruction.
 using BreakInstructionType = uint8_t;
 
-#define FLAG_VALUE(val, shift) ((val) & (shift))
-
-// DR6 -------------------------------------------------------------------------
-
-constexpr uint64_t kDR6B0 = (1 << 0);
-constexpr uint64_t kDR6B1 = (1 << 1);
-constexpr uint64_t kDR6B2 = (1 << 2);
-constexpr uint64_t kDR6B3 = (1 << 3);
-constexpr uint64_t kDR6BD = (1 << 13);
-constexpr uint64_t kDR6BS = (1 << 14);
-constexpr uint64_t kDR6BT = (1 << 15);
-
-constexpr uint64_t kDR6Mask(0xffff0ff0ul);
-
-// DR7 -------------------------------------------------------------------------
-
-constexpr uint64_t kDR7L0 = (1 << 0);
-constexpr uint64_t kDR7G0 = (1 << 1);
-constexpr uint64_t kDR7L1 = (1 << 2);
-constexpr uint64_t kDR7G1 = (1 << 3);
-constexpr uint64_t kDR7L2 = (1 << 4);
-constexpr uint64_t kDR7G2 = (1 << 5);
-constexpr uint64_t kDR7L3 = (1 << 6);
-constexpr uint64_t kDR7G3 = (1 << 7);
-// Not used for now.
-constexpr uint64_t kDR7LE = (1 << 8);
-constexpr uint64_t kDR7GE = (1 << 9);
-constexpr uint64_t kDR7GD = (1 << 13);
-constexpr uint64_t kDR7RW0 = (1 << 16);
-constexpr uint64_t kDR7LEN0 = (1 << 18);
-constexpr uint64_t kDR7RW1 = (1 << 20);
-constexpr uint64_t kDR7LEN1 = (1 << 22);
-constexpr uint64_t kDR7RW2 = (1 << 24);
-constexpr uint64_t kDR7LEN2 = (1 << 26);
-constexpr uint64_t kDR7RW3 = (1 << 28);
-constexpr uint64_t kDR7LEN3 = (1 << 30);
-
-constexpr uint64_t kDR7Mask((1ul << 10) | kDR7LE | kDR7GE);
-
 }  // namespace arch
 }  // namespace debug_agent
diff --git a/src/developer/debug/debug_agent/arch_x64_helpers.cc b/src/developer/debug/debug_agent/arch_x64_helpers.cc
index 032f5dfed4d800c553d6966f3a47011e82392943..2424ff1f9a5de9103c8eb63749ea98f60382e2cd 100644
--- a/src/developer/debug/debug_agent/arch_x64_helpers.cc
+++ b/src/developer/debug/debug_agent/arch_x64_helpers.cc
@@ -16,81 +16,85 @@ namespace arch {
 
 namespace {
 
-struct DebugRegMask {
-  int index = -1;
-  uint64_t bp_mask = 0;   // Enable mask within DR7
-  uint64_t rw_mask = 0;   // RW mask within DR7
-  uint64_t len_mask = 0;  // LEN mask within DR7
-};
-
-const DebugRegMask* GetDebugRegisterMasks(size_t index) {
-  static std::vector<DebugRegMask> masks = {
-      {0, kDR7L0, kDR7RW0 | (kDR7RW0 << 1), kDR7LEN0 | (kDR7LEN0 << 1)},
-      {1, kDR7L1, kDR7RW1 | (kDR7RW1 << 1), kDR7LEN1 | (kDR7LEN1 << 1)},
-      {2, kDR7L2, kDR7RW2 | (kDR7RW2 << 1), kDR7LEN2 | (kDR7LEN2 << 1)},
-      {3, kDR7L3, kDR7RW3 | (kDR7RW3 << 1), kDR7LEN3 | (kDR7LEN3 << 1)},
+uint64_t HWBreakpointEnabled(uint64_t dr7, size_t index) {
+  FXL_DCHECK(index < 4);
+  static uint64_t masks[4] = {
+      X86_FLAG_MASK(DR7L0),
+      X86_FLAG_MASK(DR7L1),
+      X86_FLAG_MASK(DR7L2),
+      X86_FLAG_MASK(DR7L3)
   };
-  FXL_DCHECK(index < masks.size());
-  return &masks[index];
+
+  return (dr7 & masks[index]) != 0;
+}
+
+// Mask needed to clear a particular HW breakpoint.
+uint64_t HWBreakpointD7ClearMask(size_t index) {
+  FXL_DCHECK(index < 4);
+  static uint64_t masks[4] = {
+    ~(X86_FLAG_MASK(DR7L0) | X86_FLAG_MASK(DR7RW0) | X86_FLAG_MASK(DR7LEN0)),
+    ~(X86_FLAG_MASK(DR7L1) | X86_FLAG_MASK(DR7RW1) | X86_FLAG_MASK(DR7LEN1)),
+    ~(X86_FLAG_MASK(DR7L2) | X86_FLAG_MASK(DR7RW2) | X86_FLAG_MASK(DR7LEN2)),
+    ~(X86_FLAG_MASK(DR7L3) | X86_FLAG_MASK(DR7RW3) | X86_FLAG_MASK(DR7LEN3)),
+  };
+  return masks[index];
+}
+
+// Mask needed to set a particular HW breakpoint.
+uint64_t HWBreakpointDR7SetMask(size_t index) {
+  FXL_DCHECK(index < 4);
+  // Mask is: L = 1, RW = 00, LEN = 10
+  static uint64_t dr_masks[4] = {
+      X86_FLAG_MASK(DR7L0),
+      X86_FLAG_MASK(DR7L1),
+      X86_FLAG_MASK(DR7L2),
+      X86_FLAG_MASK(DR7L3),
+  };
+  return dr_masks[index];
 }
 
 }  // namespace
 
 zx_status_t SetupHWBreakpoint(uint64_t address,
                               zx_thread_state_debug_regs_t* debug_regs) {
-  // Search for an unset register.
-  // TODO(donosoc): This doesn't check that the address is already set.
-  const DebugRegMask* slot = nullptr;
+  // Search for a free slot.
+  int slot = -1;
   for (size_t i = 0; i < 4; i++) {
-    const DebugRegMask* mask = GetDebugRegisterMasks(i);
-    // If it's the same address or it's free, we found our slot.
-    bool active = FLAG_VALUE(debug_regs->dr7, mask->bp_mask);
-    if (debug_regs->dr[i] == address || !active) {
-      slot = mask;
+    if (HWBreakpointEnabled(debug_regs->dr7, i)) {
+      // If it's already bound there, we don't need to do anything.
+      if (debug_regs->dr[i] == address)
+        return ZX_ERR_ALREADY_BOUND;
+    } else {
+      slot = i;
       break;
     }
   }
 
-  if (!slot)
+  if (slot == -1)
     return ZX_ERR_NO_RESOURCES;
 
-  debug_regs->dr[slot->index] = address;
-  // Modify the DR7 register.
-  // TODO(donosoc): For now only add execution breakpoints.
-  uint64_t dr7 = debug_regs->dr7;
-  dr7 |= slot->bp_mask;  // Activate the breakpoint.
-  uint64_t mask = ~(slot->rw_mask);
-  // TODO(donosoc): Handle LEN properties of the breakpoint.
-  dr7 &= mask;
-  debug_regs->dr7 = dr7;
-
+  // We found a slot, we bind the address.
+  debug_regs->dr[slot] = address;
+  debug_regs->dr7 &= HWBreakpointD7ClearMask(slot);
+  debug_regs->dr7 |= HWBreakpointDR7SetMask(slot);
   return ZX_OK;
 }
 
 zx_status_t RemoveHWBreakpoint(uint64_t address,
                                zx_thread_state_debug_regs_t* debug_regs) {
-  // Search for the address.
-  bool found = false;
-  for (size_t i = 0; i < 4; i++) {
+  // Search for the slot.
+  for (int i = 0; i < 4; i++) {
     if (address != debug_regs->dr[i])
       continue;
 
-    const DebugRegMask* mask = GetDebugRegisterMasks(i);
-    // Only unset the
-    uint64_t dr7 = debug_regs->dr7;
-    dr7 &= ~(mask->bp_mask);  // Disable the breakpoint.
-
+    // Clear this breakpoint.
     debug_regs->dr[i] = 0;
-    debug_regs->dr7 = dr7;
-
-    found = true;
+    debug_regs->dr7 &= HWBreakpointD7ClearMask(i);
+    return ZX_OK;
   }
 
-  // No register found, we warn the caller. No change was issued.
-  if (!found)
-    return ZX_ERR_OUT_OF_RANGE;
-
-  return ZX_OK;
+  // We didn't find the address.
+  return ZX_ERR_OUT_OF_RANGE;
 }
 
 zx_status_t WriteGeneralRegisters(const std::vector<debug_ipc::Register>& regs,
@@ -152,7 +156,7 @@ std::string DebugRegistersToString(const zx_thread_state_debug_regs_t& regs) {
      << "DR2: 0x" << std::hex << regs.dr[2] << std::endl
      << "DR3: 0x" << std::hex << regs.dr[3] << std::endl
      << "DR6: " << DR6ToString(regs.dr6) << std::endl
-     << "DR7: 0x" << std::hex << regs.dr7 << std::endl;
+     << "DR7: " << DR7ToString(regs.dr7) << std::endl;
 
   return ss.str();
 }
@@ -160,10 +164,27 @@ std::string DebugRegistersToString(const zx_thread_state_debug_regs_t& regs) {
 std::string DR6ToString(uint64_t dr6) {
   return fxl::StringPrintf(
       "0x%lx: B0=%d, B1=%d, B2=%d, B3=%d, BD=%d, BS=%d, BT=%d", dr6,
-      X86_FLAG_VALUE(dr6, Dr6B0), X86_FLAG_VALUE(dr6, Dr6B1),
-      X86_FLAG_VALUE(dr6, Dr6B2), X86_FLAG_VALUE(dr6, Dr6B3),
-      X86_FLAG_VALUE(dr6, Dr6BD), X86_FLAG_VALUE(dr6, Dr6BS),
-      X86_FLAG_VALUE(dr6, Dr6BT));
+      X86_FLAG_VALUE(dr6, DR6B0), X86_FLAG_VALUE(dr6, DR6B1),
+      X86_FLAG_VALUE(dr6, DR6B2), X86_FLAG_VALUE(dr6, DR6B3),
+      X86_FLAG_VALUE(dr6, DR6BD), X86_FLAG_VALUE(dr6, DR6BS),
+      X86_FLAG_VALUE(dr6, DR6BT));
+}
+
+std::string DR7ToString(uint64_t dr7) {
+  return fxl::StringPrintf(
+      "0x%lx: L0=%d, G0=%d, L1=%d, G1=%d, L2=%d, G2=%d, L3=%d, G4=%d, LE=%d, "
+      "GE=%d, GD=%d, R/W0=%d, LEN0=%d, R/W1=%d, LEN1=%d, R/W2=%d, LEN2=%d, "
+      "R/W3=%d, LEN3=%d",
+      dr7, X86_FLAG_VALUE(dr7, DR7L0), X86_FLAG_VALUE(dr7, DR7G0),
+      X86_FLAG_VALUE(dr7, DR7L1), X86_FLAG_VALUE(dr7, DR7G1),
+      X86_FLAG_VALUE(dr7, DR7L2), X86_FLAG_VALUE(dr7, DR7G2),
+      X86_FLAG_VALUE(dr7, DR7L3), X86_FLAG_VALUE(dr7, DR7G3),
+      X86_FLAG_VALUE(dr7, DR7LE), X86_FLAG_VALUE(dr7, DR7GE),
+      X86_FLAG_VALUE(dr7, DR7GD), X86_FLAG_VALUE(dr7, DR7RW0),
+      X86_FLAG_VALUE(dr7, DR7LEN0), X86_FLAG_VALUE(dr7, DR7RW1),
+      X86_FLAG_VALUE(dr7, DR7LEN1), X86_FLAG_VALUE(dr7, DR7RW2),
+      X86_FLAG_VALUE(dr7, DR7LEN2), X86_FLAG_VALUE(dr7, DR7RW3),
+      X86_FLAG_VALUE(dr7, DR7LEN3));
 }
 
 }  // namespace arch
diff --git a/src/developer/debug/debug_agent/arch_x64_helpers.h b/src/developer/debug/debug_agent/arch_x64_helpers.h
index 9d1730d046ad3abd145fcd9e977c81462a15f7d8..0c1b0577e4e96afafa43a9312c7142c9a8d90f64 100644
--- a/src/developer/debug/debug_agent/arch_x64_helpers.h
+++ b/src/developer/debug/debug_agent/arch_x64_helpers.h
@@ -43,5 +43,7 @@ std::string DebugRegistersToString(const zx_thread_state_debug_regs_t&);
 
 std::string DR6ToString(uint64_t dr6);
 
+std::string DR7ToString(uint64_t dr7);
+
 }  // namespace arch
 }  // namespace debug_agent
diff --git a/src/developer/debug/debug_agent/arch_x64_helpers_unittest.cc b/src/developer/debug/debug_agent/arch_x64_helpers_unittest.cc
index 9bca06515523b7a38448a0d659df29a252acfbcb..6ef6f758cf31571f461d55a48458cf3f5c5930a6 100644
--- a/src/developer/debug/debug_agent/arch_x64_helpers_unittest.cc
+++ b/src/developer/debug/debug_agent/arch_x64_helpers_unittest.cc
@@ -7,24 +7,18 @@
 #include <gtest/gtest.h>
 
 #include "src/developer/debug/ipc/register_test_support.h"
+#include "src/developer/debug/shared/arch_x86.h"
 #include "src/developer/debug/shared/logging/file_line_function.h"
 #include "src/developer/debug/shared/zx_status.h"
-
 #include "src/lib/fxl/logging.h"
 
+using namespace debug_ipc;
+
 namespace debug_agent {
 namespace arch {
 
 namespace {
 
-zx_thread_state_debug_regs_t GetDefaultRegs() {
-  zx_thread_state_debug_regs_t debug_regs = {};
-  debug_regs.dr6 = kDR6Mask;
-  debug_regs.dr7 = kDR7Mask;
-
-  return debug_regs;
-}
-
 void SetupHWBreakpointTest(debug_ipc::FileLineFunction file_line,
                            zx_thread_state_debug_regs_t* debug_regs,
                            uint64_t address, zx_status_t expected_result) {
@@ -45,6 +39,28 @@ void RemoveHWBreakpointTest(debug_ipc::FileLineFunction file_line,
       << ", expected: " << debug_ipc::ZxStatusToString(expected_result);
 }
 
+uint64_t GetHWBreakpointDR7Mask(size_t index) {
+  FXL_DCHECK(index < 4);
+  // Mask is: L = 1, RW = 00, LEN = 10
+  static uint64_t dr_masks[4] = {
+    X86_FLAG_MASK(DR7L0),
+    X86_FLAG_MASK(DR7L1),
+    X86_FLAG_MASK(DR7L2),
+    X86_FLAG_MASK(DR7L3),
+  };
+  return dr_masks[index];
+}
+
+uint64_t JoinDR7Masks(std::initializer_list<size_t> indices = {}) {
+  uint64_t result = 0;
+  for (size_t index : indices) {
+    FXL_DCHECK(index < 4);
+    result |= GetHWBreakpointDR7Mask(index);
+  }
+
+  return result;
+}
+
 constexpr uint64_t kAddress1 = 0x0123;
 constexpr uint64_t kAddress2 = 0x4567;
 constexpr uint64_t kAddress3 = 0x89ab;
@@ -54,24 +70,25 @@ constexpr uint64_t kAddress5 = 0xdeadbeef;
 }  // namespace
 
 TEST(x64Helpers, SettingHWBreakpoints) {
-  auto debug_regs = GetDefaultRegs();
+  zx_thread_state_debug_regs_t debug_regs = {};
 
   SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress1, ZX_OK);
   EXPECT_EQ(debug_regs.dr[0], kAddress1);
   EXPECT_EQ(debug_regs.dr[1], 0u);
   EXPECT_EQ(debug_regs.dr[2], 0u);
   EXPECT_EQ(debug_regs.dr[3], 0u);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | 0 | 0 | 0);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0}));
 
   // Adding the same breakpoint should detect that the same already exists.
-  SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress1, ZX_OK);
+  SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress1,
+                        ZX_ERR_ALREADY_BOUND);
   EXPECT_EQ(debug_regs.dr[0], kAddress1);
   EXPECT_EQ(debug_regs.dr[1], 0u);
   EXPECT_EQ(debug_regs.dr[2], 0u);
   EXPECT_EQ(debug_regs.dr[3], 0u);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | 0 | 0 | 0);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0}));
 
   // Continuing adding should append.
   SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress2, ZX_OK);
@@ -79,24 +96,24 @@ TEST(x64Helpers, SettingHWBreakpoints) {
   EXPECT_EQ(debug_regs.dr[1], kAddress2);
   EXPECT_EQ(debug_regs.dr[2], 0u);
   EXPECT_EQ(debug_regs.dr[3], 0u);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | kDR7L1 | 0 | 0);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0, 1}));
 
   SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress3, ZX_OK);
   EXPECT_EQ(debug_regs.dr[0], kAddress1);
   EXPECT_EQ(debug_regs.dr[1], kAddress2);
   EXPECT_EQ(debug_regs.dr[2], kAddress3);
   EXPECT_EQ(debug_regs.dr[3], 0u);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | kDR7L1 | kDR7L2 | 0);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0, 1, 2}));
 
   SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress4, ZX_OK);
   EXPECT_EQ(debug_regs.dr[0], kAddress1);
   EXPECT_EQ(debug_regs.dr[1], kAddress2);
   EXPECT_EQ(debug_regs.dr[2], kAddress3);
   EXPECT_EQ(debug_regs.dr[3], kAddress4);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | kDR7L1 | kDR7L2 | kDR7L3);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0, 1, 2, 3}));
 
   // No more registers left should not change anything.
   SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress5,
@@ -105,12 +122,12 @@ TEST(x64Helpers, SettingHWBreakpoints) {
   EXPECT_EQ(debug_regs.dr[1], kAddress2);
   EXPECT_EQ(debug_regs.dr[2], kAddress3);
   EXPECT_EQ(debug_regs.dr[3], kAddress4);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | kDR7L1 | kDR7L2 | kDR7L3);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0, 1, 2, 3}));
 }
 
 TEST(x64Helpers, RemovingHWBreakpoint) {
-  auto debug_regs = GetDefaultRegs();
+  zx_thread_state_debug_regs_t debug_regs = {};
 
   // Previous state verifies the state of this calls.
   SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress1, ZX_OK);
@@ -125,8 +142,8 @@ TEST(x64Helpers, RemovingHWBreakpoint) {
   EXPECT_EQ(debug_regs.dr[1], kAddress2);
   EXPECT_EQ(debug_regs.dr[2], 0u);
   EXPECT_EQ(debug_regs.dr[3], kAddress4);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | kDR7L1 | 0 | kDR7L3);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0, 1, 3}));
 
   // Removing same breakpoint should not work.
   RemoveHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress3,
@@ -135,8 +152,8 @@ TEST(x64Helpers, RemovingHWBreakpoint) {
   EXPECT_EQ(debug_regs.dr[1], kAddress2);
   EXPECT_EQ(debug_regs.dr[2], 0u);
   EXPECT_EQ(debug_regs.dr[3], kAddress4);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | kDR7L1 | 0 | kDR7L3);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0, 1, 3}));
 
   // Removing an unknown address should warn and change nothing.
   RemoveHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, 0xaaaaaaa,
@@ -145,16 +162,16 @@ TEST(x64Helpers, RemovingHWBreakpoint) {
   EXPECT_EQ(debug_regs.dr[1], kAddress2);
   EXPECT_EQ(debug_regs.dr[2], 0u);
   EXPECT_EQ(debug_regs.dr[3], kAddress4);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | kDR7L1 | 0 | kDR7L3);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0, 1, 3}));
 
   RemoveHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress1, ZX_OK);
   EXPECT_EQ(debug_regs.dr[0], 0u);
   EXPECT_EQ(debug_regs.dr[1], kAddress2);
   EXPECT_EQ(debug_regs.dr[2], 0u);
   EXPECT_EQ(debug_regs.dr[3], kAddress4);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | 0 | kDR7L1 | 0 | kDR7L3);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({1, 3}));
 
   // Adding again should work.
   SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress5, ZX_OK);
@@ -162,25 +179,26 @@ TEST(x64Helpers, RemovingHWBreakpoint) {
   EXPECT_EQ(debug_regs.dr[1], kAddress2);
   EXPECT_EQ(debug_regs.dr[2], 0u);
   EXPECT_EQ(debug_regs.dr[3], kAddress4);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | kDR7L1 | 0 | kDR7L3);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0, 1, 3}));
 
   SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress1, ZX_OK);
   EXPECT_EQ(debug_regs.dr[0], kAddress5);
   EXPECT_EQ(debug_regs.dr[1], kAddress2);
   EXPECT_EQ(debug_regs.dr[2], kAddress1);
   EXPECT_EQ(debug_regs.dr[3], kAddress4);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | kDR7L1 | kDR7L2 | kDR7L3);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0, 1, 2, 3}));
 
   // Already exists should not change.
-  SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress5, ZX_OK);
+  SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress5,
+                        ZX_ERR_ALREADY_BOUND);
   EXPECT_EQ(debug_regs.dr[0], kAddress5);
   EXPECT_EQ(debug_regs.dr[1], kAddress2);
   EXPECT_EQ(debug_regs.dr[2], kAddress1);
   EXPECT_EQ(debug_regs.dr[3], kAddress4);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | kDR7L1 | kDR7L2 | kDR7L3);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0, 1, 2, 3}));
 
   // No more resources.
   SetupHWBreakpointTest(FROM_HERE_NO_FUNC, &debug_regs, kAddress3,
@@ -189,8 +207,8 @@ TEST(x64Helpers, RemovingHWBreakpoint) {
   EXPECT_EQ(debug_regs.dr[1], kAddress2);
   EXPECT_EQ(debug_regs.dr[2], kAddress1);
   EXPECT_EQ(debug_regs.dr[3], kAddress4);
-  EXPECT_EQ(debug_regs.dr6, kDR6Mask);
-  EXPECT_EQ(debug_regs.dr7, kDR7Mask | kDR7L0 | kDR7L1 | kDR7L2 | kDR7L3);
+  EXPECT_EQ(debug_regs.dr6, 0u);
+  EXPECT_EQ(debug_regs.dr7, JoinDR7Masks({0, 1, 2, 3}));
 }
 
 TEST(x64Helpers, WritingGeneralRegs) {
diff --git a/src/developer/debug/debug_agent/integration_tests/breakpoint_test.cc b/src/developer/debug/debug_agent/integration_tests/breakpoint_test.cc
index 9533bf50901c8ec7f744bc3c4e833d2bcd61735e..1a70af13c6e5c88808a2209961975210360c85b8 100644
--- a/src/developer/debug/debug_agent/integration_tests/breakpoint_test.cc
+++ b/src/developer/debug/debug_agent/integration_tests/breakpoint_test.cc
@@ -190,10 +190,6 @@ TEST(BreakpointIntegration, SWBreakpoint) {
   }
 }
 
-// TODO(DX-909): Some HW capabilities (like HW breakpoints) are not well
-//               emulated by QEMU without KVM. This will sometimes make tests
-//               fail or even crash QEMU. The bot configuration should avoid
-//               running this test on QEMU.
 TEST(BreakpointIntegration, HWBreakpoint) {
   // We attempt to load the pre-made .so.
   SoWrapper so_wrapper;
@@ -279,7 +275,8 @@ TEST(BreakpointIntegration, HWBreakpoint) {
     // We should have received an exception now.
     debug_ipc::NotifyException exception = mock_stream_backend.exception();
     EXPECT_EQ(exception.thread.process_koid, launch_reply.process_id);
-    EXPECT_EQ(exception.type, debug_ipc::NotifyException::Type::kHardware);
+    EXPECT_EQ(exception.type, debug_ipc::NotifyException::Type::kHardware)
+        << "Got: " << debug_ipc::NotifyException::TypeToString(exception.type);
     ASSERT_EQ(exception.hit_breakpoints.size(), 1u);
 
     // Verify that the correct breakpoint was hit.
diff --git a/src/developer/debug/shared/arch_x86.h b/src/developer/debug/shared/arch_x86.h
index df76a919b3af2aaeed32d23514dcda993bdacf5f..4137df52a030021a0384b51e17b7e847c446c3cd 100644
--- a/src/developer/debug/shared/arch_x86.h
+++ b/src/developer/debug/shared/arch_x86.h
@@ -27,96 +27,96 @@ namespace debug_ipc {
   _X86_FLAG_VALUE(value, ::debug_ipc::k##flag##Shift, \
                   ::debug_ipc::k##flag##Mask)
 
-constexpr uint64_t kRflagsCFShift = 0;  // Carry Flag.
+constexpr uint64_t kRflagsCFShift = 0;    // Carry Flag.
 constexpr uint64_t kRflagsCFMask = 0x1;
-constexpr uint64_t kRflagsPFShift = 2;  // Parity Flag.
+constexpr uint64_t kRflagsPFShift = 2;    // Parity Flag.
 constexpr uint64_t kRflagsPFMask = 0x1;
-constexpr uint64_t kRflagsAFShift = 4;  // Aux Carry Flag.
+constexpr uint64_t kRflagsAFShift = 4;    // Aux Carry Flag.
 constexpr uint64_t kRflagsAFMask = 0x1;
-constexpr uint64_t kRflagsZFShift = 6;  // Zero Flag.
+constexpr uint64_t kRflagsZFShift = 6;    // Zero Flag.
 constexpr uint64_t kRflagsZFMask = 0x1;
-constexpr uint64_t kRflagsSFShift = 7;  // Sign Flag.
+constexpr uint64_t kRflagsSFShift = 7;    // Sign Flag.
 constexpr uint64_t kRflagsSFMask = 0x1;
-constexpr uint64_t kRflagsTFShift = 8;  // Trap Flag.
+constexpr uint64_t kRflagsTFShift = 8;    // Trap Flag.
 constexpr uint64_t kRflagsTFMask = 0x1;
 
-constexpr uint64_t kRflagsIFShift = 9;  // Interrupt Enable Flag.
+constexpr uint64_t kRflagsIFShift = 9;    // Interrupt Enable Flag.
 constexpr uint64_t kRflagsIFMask = 0x1;
-constexpr uint64_t kRflagsDFShift = 10;  // Direction Flag.
+constexpr uint64_t kRflagsDFShift = 10;   // Direction Flag.
 constexpr uint64_t kRflagsDFMask = 0x1;
-constexpr uint64_t kRflagsOFShift = 11;  // Overflow Flag.
+constexpr uint64_t kRflagsOFShift = 11;   // Overflow Flag.
 constexpr uint64_t kRflagsOFMask = 0x1;
 
-constexpr uint64_t kRflagsIOPLShift = 12;  // IO Priviledge Level.
+constexpr uint64_t kRflagsIOPLShift = 12; // IO Priviledge Level.
 constexpr uint64_t kRflagsIOPLMask = 0x3;
-constexpr uint64_t kRflagsNTShift = 14;  // Nested Task.
+constexpr uint64_t kRflagsNTShift = 14;   // Nested Task.
 constexpr uint64_t kRflagsNTMask = 0x1;
-constexpr uint64_t kRflagsRFShift = 16;  // Resume Flag.
+constexpr uint64_t kRflagsRFShift = 16;   // Resume Flag.
 constexpr uint64_t kRflagsRFMask = 0x1;
-constexpr uint64_t kRflagsVMShift = 17;  // Virtual-8086 Mode.
+constexpr uint64_t kRflagsVMShift = 17;   // Virtual-8086 Mode.
 constexpr uint64_t kRflagsVMMask = 0x1;
-constexpr uint64_t kRflagsACShift = 18;  // Alignment Check/ Access Control.
+constexpr uint64_t kRflagsACShift = 18;   // Alignment Check/ Access Control.
 constexpr uint64_t kRflagsACMask = 0x1;
 constexpr uint64_t kRflagsVIFShift = 19;  // Virtual Interrupt Flag.
 constexpr uint64_t kRflagsVIFMask = 0x1;
 constexpr uint64_t kRflagsVIPShift = 20;  // Virtual Interrupt Pending.
 constexpr uint64_t kRflagsVIPMask = 0x1;
-constexpr uint64_t kRflagsIDShift = 21;  // ID Flag.
+constexpr uint64_t kRflagsIDShift = 21;   // ID Flag.
 constexpr uint64_t kRflagsIDMask = 0x1;
 
-constexpr uint64_t kDr6B0Shift = 0;  // HW Breakpoint 0.
-constexpr uint64_t kDr6B0Mask = 0x1;
-constexpr uint64_t kDr6B1Shift = 1;  // HW Breakpoint 1.
-constexpr uint64_t kDr6B1Mask = 0x1;
-constexpr uint64_t kDr6B2Shift = 2;  // HW Breakpoint 2.
-constexpr uint64_t kDr6B2Mask = 0x1;
-constexpr uint64_t kDr6B3Shift = 3;  // HW Breakpoint 3.
-constexpr uint64_t kDr6B3Mask = 0x1;
-constexpr uint64_t kDr6BDShift = 13;  // Breakpoint Debug Access Detected.
-constexpr uint64_t kDr6BDMask = 0x1;
-constexpr uint64_t kDr6BSShift = 14;  // Single Step.
-constexpr uint64_t kDr6BSMask = 0x1;
-constexpr uint64_t kDr6BTShift = 15;  // Breakpoint Task.
-constexpr uint64_t kDr6BTMask = 0x1;
+constexpr uint64_t kDR6B0Shift = 0;   // HW Breakpoint 0.
+constexpr uint64_t kDR6B0Mask = 0x1;
+constexpr uint64_t kDR6B1Shift = 1;   // HW Breakpoint 1.
+constexpr uint64_t kDR6B1Mask = 0x1;
+constexpr uint64_t kDR6B2Shift = 2;   // HW Breakpoint 2.
+constexpr uint64_t kDR6B2Mask = 0x1;
+constexpr uint64_t kDR6B3Shift = 3;   // HW Breakpoint 3.
+constexpr uint64_t kDR6B3Mask = 0x1;
+constexpr uint64_t kDR6BDShift = 13;  // Breakpoint Debug Access Detected.
+constexpr uint64_t kDR6BDMask = 0x1;
+constexpr uint64_t kDR6BSShift = 14;  // Single Step.
+constexpr uint64_t kDR6BSMask = 0x1;
+constexpr uint64_t kDR6BTShift = 15;  // Breakpoint Task.
+constexpr uint64_t kDR6BTMask = 0x1;
 
-constexpr uint64_t kDr7L0Shift = 0;  // HW Breakpoint 0 enabled.
-constexpr uint64_t kDr7L0Mask = 0x1;
-constexpr uint64_t kDr7G0Shift = 1;  // Global Breakpoint 0 enabled (not used).
-constexpr uint64_t kDr7G0Mask = 0x1;
-constexpr uint64_t kDr7L1Shift = 2;  // HW Breakpoint 1 enabled.
-constexpr uint64_t kDr7L1Mask = 0x1;
-constexpr uint64_t kDr7G1Shift = 3;  // Global Breakpoint 1 enabled (not used).
-constexpr uint64_t kDr7G1Mask = 0x1;
-constexpr uint64_t kDr7L2Shift = 4;  // HW Breakpoint 2 enabled.
-constexpr uint64_t kDr7L2Mask = 0x1;
-constexpr uint64_t kDr7G2Shift = 5;  // Global Breakpoint 2 enabled (not used).
-constexpr uint64_t kDr7G2Mask = 0x1;
-constexpr uint64_t kDr7L3Shift = 6;  // HW Breakpoint 3 enabled.
-constexpr uint64_t kDr7L3Mask = 0x1;
-constexpr uint64_t kDr7G3Shift = 7;  // Global Breakpoint 3 enabled (not used).
-constexpr uint64_t kDr7G3Mask = 0x1;
-constexpr uint64_t kDr7LEShift = 8;  // Local Exact enabled (not used).
-constexpr uint64_t kDr7LEMask = 0x1;
-constexpr uint64_t kDr7GEShift = 9;  // Global Exact enabled (not used).
-constexpr uint64_t kDr7GEMask = 0x1;
-constexpr uint64_t kDr7GDShift = 13;  // General Detect Enabled.
-constexpr uint64_t kDr7GDMask = 0x1;
+constexpr uint64_t kDR7L0Shift = 0;   // HW Breakpoint 0 enabled.
+constexpr uint64_t kDR7L0Mask = 0x1;
+constexpr uint64_t kDR7G0Shift = 1;   // Global Breakpoint 0 enabled (not used).
+constexpr uint64_t kDR7G0Mask = 0x1;
+constexpr uint64_t kDR7L1Shift = 2;   // HW Breakpoint 1 enabled.
+constexpr uint64_t kDR7L1Mask = 0x1;
+constexpr uint64_t kDR7G1Shift = 3;   // Global Breakpoint 1 enabled (not used).
+constexpr uint64_t kDR7G1Mask = 0x1;
+constexpr uint64_t kDR7L2Shift = 4;   // HW Breakpoint 2 enabled.
+constexpr uint64_t kDR7L2Mask = 0x1;
+constexpr uint64_t kDR7G2Shift = 5;   // Global Breakpoint 2 enabled (not used).
+constexpr uint64_t kDR7G2Mask = 0x1;
+constexpr uint64_t kDR7L3Shift = 6;   // HW Breakpoint 3 enabled.
+constexpr uint64_t kDR7L3Mask = 0x1;
+constexpr uint64_t kDR7G3Shift = 7;   // Global Breakpoint 3 enabled (not used).
+constexpr uint64_t kDR7G3Mask = 0x1;
+constexpr uint64_t kDR7LEShift = 8;   // Local Exact enabled (not used).
+constexpr uint64_t kDR7LEMask = 0x1;
+constexpr uint64_t kDR7GEShift = 9;   // Global Exact enabled (not used).
+constexpr uint64_t kDR7GEMask = 0x1;
+constexpr uint64_t kDR7GDShift = 13;  // General Detect Enabled.
+constexpr uint64_t kDR7GDMask = 0x1;
 
-constexpr uint64_t kDr7RW0Shift = 16;  // Bkpt 0 R/W (which exception to trap).
-constexpr uint64_t kDr7RW0Mask = 0x3;
-constexpr uint64_t kDr7LEN0Shift = 18;  // Bkpt 0 LEN (len of address to match).
-constexpr uint64_t kDr7LEN0Mask = 0x3;
-constexpr uint64_t kDr7RW1Shift = 20;  // Bkpt 1 R/W (exception type).
-constexpr uint64_t kDr7RW1Mask = 0x3;
-constexpr uint64_t kDr7LEN1Shift = 22;  // Bkpt 1 LEN (len of address to match).
-constexpr uint64_t kDr7LEN1Mask = 0x3;
-constexpr uint64_t kDr7RW2Shift = 24;  // Bkpt 2 R/W (exception type).
-constexpr uint64_t kDr7RW2Mask = 0x3;
-constexpr uint64_t kDr7LEN2Shift = 26;  // Bkpt 2 LEN (len of address to match).
-constexpr uint64_t kDr7LEN2Mask = 0x3;
-constexpr uint64_t kDr7RW3Shift = 28;  // Bkpt 3 R/W (exception type).
-constexpr uint64_t kDr7RW3Mask = 0x3;
-constexpr uint64_t kDr7LEN3Shift = 30;  // Bkpt 3 LEN (len of address to match).
-constexpr uint64_t kDr7LEN3Mask = 0x3;
+constexpr uint64_t kDR7RW0Shift = 16;   // Bkpt 0 R/W (which exception to trap).
+constexpr uint64_t kDR7RW0Mask = 0x3;
+constexpr uint64_t kDR7LEN0Shift = 18;  // Bkpt 0 LEN (len of address to match).
+constexpr uint64_t kDR7LEN0Mask = 0x3;
+constexpr uint64_t kDR7RW1Shift = 20;   // Bkpt 1 R/W (exception type).
+constexpr uint64_t kDR7RW1Mask = 0x3;
+constexpr uint64_t kDR7LEN1Shift = 22;  // Bkpt 1 LEN (len of address to match).
+constexpr uint64_t kDR7LEN1Mask = 0x3;
+constexpr uint64_t kDR7RW2Shift = 24;   // Bkpt 2 R/W (exception type).
+constexpr uint64_t kDR7RW2Mask = 0x3;
+constexpr uint64_t kDR7LEN2Shift = 26;  // Bkpt 2 LEN (len of address to match).
+constexpr uint64_t kDR7LEN2Mask = 0x3;
+constexpr uint64_t kDR7RW3Shift = 28;   // Bkpt 3 R/W (exception type).
+constexpr uint64_t kDR7RW3Mask = 0x3;
+constexpr uint64_t kDR7LEN3Shift = 30;  // Bkpt 3 LEN (len of address to match).
+constexpr uint64_t kDR7LEN3Mask = 0x3;
 
 }  // namespace debug_ipc
diff --git a/src/developer/debug/zxdb/console/format_register_x64.cc b/src/developer/debug/zxdb/console/format_register_x64.cc
index 4583ffb89b3910f76b7befb671adc526948da2c4..fbf16fb0b6bb9dbf93dfa376b252f448077e50d8 100644
--- a/src/developer/debug/zxdb/console/format_register_x64.cc
+++ b/src/developer/debug/zxdb/console/format_register_x64.cc
@@ -247,10 +247,10 @@ std::vector<OutputBuffer> FormatDr6(const Register& dr6,
   result.emplace_back(
       fxl::StringPrintf(
           "B0=%d, B1=%d, B2=%d, B3=%d, BD=%d, BS=%d, BT=%d",
-          X86_FLAG_VALUE(value, Dr6B0), X86_FLAG_VALUE(value, Dr6B1),
-          X86_FLAG_VALUE(value, Dr6B2), X86_FLAG_VALUE(value, Dr6B3),
-          X86_FLAG_VALUE(value, Dr6BD), X86_FLAG_VALUE(value, Dr6BS),
-          X86_FLAG_VALUE(value, Dr6BT)),
+          X86_FLAG_VALUE(value, DR6B0), X86_FLAG_VALUE(value, DR6B1),
+          X86_FLAG_VALUE(value, DR6B2), X86_FLAG_VALUE(value, DR6B3),
+          X86_FLAG_VALUE(value, DR6BD), X86_FLAG_VALUE(value, DR6BS),
+          X86_FLAG_VALUE(value, DR6BT)),
       color);
 
   return result;
@@ -273,12 +273,12 @@ void FormatDr7(const Register& dr7, TextForegroundColor color,
           "L0=%d, G0=%d, L1=%d, G1=%d, L2=%d, G2=%d, L3=%d, G4=%d, LE=%d, "
           "GE=%d, "
           "GD=%d",
-          X86_FLAG_VALUE(value, Dr7L0), X86_FLAG_VALUE(value, Dr7G0),
-          X86_FLAG_VALUE(value, Dr7L1), X86_FLAG_VALUE(value, Dr7G1),
-          X86_FLAG_VALUE(value, Dr7L2), X86_FLAG_VALUE(value, Dr7G2),
-          X86_FLAG_VALUE(value, Dr7L3), X86_FLAG_VALUE(value, Dr7G3),
-          X86_FLAG_VALUE(value, Dr7LE), X86_FLAG_VALUE(value, Dr7GE),
-          X86_FLAG_VALUE(value, Dr7GD)),
+          X86_FLAG_VALUE(value, DR7L0), X86_FLAG_VALUE(value, DR7G0),
+          X86_FLAG_VALUE(value, DR7L1), X86_FLAG_VALUE(value, DR7G1),
+          X86_FLAG_VALUE(value, DR7L2), X86_FLAG_VALUE(value, DR7G2),
+          X86_FLAG_VALUE(value, DR7L3), X86_FLAG_VALUE(value, DR7G3),
+          X86_FLAG_VALUE(value, DR7LE), X86_FLAG_VALUE(value, DR7GE),
+          X86_FLAG_VALUE(value, DR7GD)),
       color);
 
   // Second row only gets decoded values in the 3rd column.
@@ -290,10 +290,10 @@ void FormatDr7(const Register& dr7, TextForegroundColor color,
       fxl::StringPrintf(
           "R/W0=%d, LEN0=%d, R/W1=%d, LEN1=%d, R/W2=%d, "
           "LEN2=%d, R/W3=%d, LEN3=%d",
-          X86_FLAG_VALUE(value, Dr7RW0), X86_FLAG_VALUE(value, Dr7LEN0),
-          X86_FLAG_VALUE(value, Dr7RW1), X86_FLAG_VALUE(value, Dr7LEN1),
-          X86_FLAG_VALUE(value, Dr7RW2), X86_FLAG_VALUE(value, Dr7LEN2),
-          X86_FLAG_VALUE(value, Dr7RW3), X86_FLAG_VALUE(value, Dr7LEN3)),
+          X86_FLAG_VALUE(value, DR7RW0), X86_FLAG_VALUE(value, DR7LEN0),
+          X86_FLAG_VALUE(value, DR7RW1), X86_FLAG_VALUE(value, DR7LEN1),
+          X86_FLAG_VALUE(value, DR7RW2), X86_FLAG_VALUE(value, DR7LEN2),
+          X86_FLAG_VALUE(value, DR7RW3), X86_FLAG_VALUE(value, DR7LEN3)),
       color);
 }