[debugger] Fix ARM DWARF register mapping.

The DWARF registers for ARM were off-by-one and would cause an assertion
of the "SP" register was referenced from a DWARF expression (common).

Adds tests.

DX-1549

Change-Id: Iffeeb20ae7d8958db0538fb9e45e202fde08525a
diff --git a/src/developer/debug/ipc/BUILD.gn b/src/developer/debug/ipc/BUILD.gn
index 00631e7..ec7ca56 100644
--- a/src/developer/debug/ipc/BUILD.gn
+++ b/src/developer/debug/ipc/BUILD.gn
@@ -70,6 +70,7 @@
     "message_unittests.cc",
     "protocol_unittests.cc",
     "records_unittest.cc",
+    "register_desc_unittest.cc",
   ]
 
   deps = [
diff --git a/src/developer/debug/ipc/register_desc.cc b/src/developer/debug/ipc/register_desc.cc
index b85625a..76e359f 100644
--- a/src/developer/debug/ipc/register_desc.cc
+++ b/src/developer/debug/ipc/register_desc.cc
@@ -388,24 +388,19 @@
 
   // http://infocenter.arm.com/help/topic/com.arm.doc.ecm0665627/abi_sve_aadwarf_100985_0000_00_en.pdf
   // Page 6
-  if (dwarf_reg_id <= 29) {
+  if (dwarf_reg_id <= 31) {
     auto base = static_cast<uint32_t>(RegisterID::kARMv8_x0);
     return static_cast<RegisterID>(base + dwarf_reg_id);
   }
 
-  switch (dwarf_reg_id) {
-    case 32:
-      return RegisterID::kARMv8_sp;
-      // 31: Reserved
-      // TODO(donosoc): 33 -> ELR_mode
-      // 34-45: Reserved
-      // TODO(donosoc): 46 -> VG 64-bit SVE Vector granule pseudo register
-      // TODO(donosoc): 47 -> FFR VG´8-bit SVE first fault register
-      // TODO(donosoc): 48-63 -> P0-P15 VG´8-bit SVE predicate registers
-      // TODO(donosoc): 64-95 -> V0-V31 128-bit FP/Advanced SIMD registers
-      // TODO(donosoc): 96-127 -> Z0-Z31 VG´64-bit SVE vector registers
-  }
-
+  // 32: Reserved
+  // TODO(donosoc): 33 -> ELR_mode
+  // 34-45: Reserved
+  // TODO(donosoc): 46 -> VG 64-bit SVE Vector granule pseudo register
+  // TODO(donosoc): 47 -> FFR VG´8-bit SVE first fault register
+  // TODO(donosoc): 48-63 -> P0-P15 VG´8-bit SVE predicate registers
+  // TODO(donosoc): 64-95 -> V0-V31 128-bit FP/Advanced SIMD registers
+  // TODO(donosoc): 96-127 -> Z0-Z31 VG´64-bit SVE vector registers
   return RegisterID::kUnknown;
 }
 
diff --git a/src/developer/debug/ipc/register_desc_unittest.cc b/src/developer/debug/ipc/register_desc_unittest.cc
new file mode 100644
index 0000000..bb47274
--- /dev/null
+++ b/src/developer/debug/ipc/register_desc_unittest.cc
@@ -0,0 +1,38 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/developer/debug/ipc/register_desc.h"
+
+#include "gtest/gtest.h"
+#include "src/developer/debug/ipc/protocol.h"
+
+namespace debug_ipc {
+
+TEST(RegisterDesc, DWARFToRegisterID_Arm) {
+  EXPECT_EQ(debug_ipc::RegisterID::kARMv8_x0,
+            DWARFToRegisterID(Arch::kArm64, 0));
+  EXPECT_EQ(debug_ipc::RegisterID::kARMv8_x29,
+            DWARFToRegisterID(Arch::kArm64, 29));
+  EXPECT_EQ(debug_ipc::RegisterID::kARMv8_lr,
+            DWARFToRegisterID(Arch::kArm64, 30));
+  EXPECT_EQ(debug_ipc::RegisterID::kARMv8_sp,
+            DWARFToRegisterID(Arch::kArm64, 31));
+
+  // DWARF ID 32 is "reserved".
+  EXPECT_EQ(debug_ipc::RegisterID::kUnknown,
+            DWARFToRegisterID(Arch::kArm64, 32));
+}
+
+TEST(RegisterDesc, DWARFToRegisterID_x64) {
+  EXPECT_EQ(debug_ipc::RegisterID::kX64_rax,
+            DWARFToRegisterID(Arch::kX64, 0));
+  EXPECT_EQ(debug_ipc::RegisterID::kX64_rsp,
+            DWARFToRegisterID(Arch::kX64, 7));
+  EXPECT_EQ(debug_ipc::RegisterID::kX64_r8,
+            DWARFToRegisterID(Arch::kX64, 8));
+  EXPECT_EQ(debug_ipc::RegisterID::kX64_rflags,
+            DWARFToRegisterID(Arch::kX64, 49));
+}
+
+}  // namespace debug_ipc
diff --git a/src/developer/debug/zxdb/client/frame_symbol_data_provider.cc b/src/developer/debug/zxdb/client/frame_symbol_data_provider.cc
index ac1087e..df328e0 100644
--- a/src/developer/debug/zxdb/client/frame_symbol_data_provider.cc
+++ b/src/developer/debug/zxdb/client/frame_symbol_data_provider.cc
@@ -38,6 +38,8 @@
 
 bool FrameSymbolDataProvider::GetRegister(debug_ipc::RegisterID id,
                                           std::optional<uint64_t>* value) {
+  FXL_DCHECK(id != debug_ipc::RegisterID::kUnknown);
+
   *value = std::nullopt;
   if (!frame_)
     return true;  // Synchronously know we don't have the value.