[libunwindstack] Let registers be marked undefined in Regs

Undefined registers are excluded from iteration.

Change-Id: I7b3243582618971166820549595d550cb616db67
diff --git a/garnet/third_party/libunwindstack/DwarfSection.cpp b/garnet/third_party/libunwindstack/DwarfSection.cpp
index 57a780e..c1f0bc7 100644
--- a/garnet/third_party/libunwindstack/DwarfSection.cpp
+++ b/garnet/third_party/libunwindstack/DwarfSection.cpp
@@ -413,9 +413,13 @@
 
 template <typename AddressType>
 bool DwarfSectionImpl<AddressType>::EvalRegister(const DwarfLocation* loc, uint32_t reg,
-                                                 AddressType* reg_ptr, void* info) {
+                                                 AddressType* reg_ptr, bool* defined, void* info) {
   EvalInfo<AddressType>* eval_info = reinterpret_cast<EvalInfo<AddressType>*>(info);
   Memory* regular_memory = eval_info->regular_memory;
+  if (defined) {
+    *defined = false;
+  }
+
   switch (loc->type) {
     case DWARF_LOCATION_OFFSET:
       if (!regular_memory->ReadFully(eval_info->cfa + loc->values[0], reg_ptr, sizeof(AddressType))) {
@@ -461,11 +465,14 @@
       if (reg == eval_info->cie->return_address_register) {
         eval_info->return_address_undefined = true;
       }
-      break;
+      return true;
     default:
-      break;
+      return true;
   }
 
+  if (defined) {
+    *defined = true;
+  }
   return true;
 }
 
@@ -530,9 +537,12 @@
     }
 
     reg_ptr = eval_info.regs_info.Save(reg);
-    if (!EvalRegister(&entry.second, reg, reg_ptr, &eval_info)) {
+    bool defined;
+    if (!EvalRegister(&entry.second, reg, reg_ptr, &defined, &eval_info)) {
       return false;
     }
+
+    eval_info.regs_info.regs->SetDefined(reg, defined);
   }
 
   // Find the return address location.
diff --git a/garnet/third_party/libunwindstack/RegsArm.cpp b/garnet/third_party/libunwindstack/RegsArm.cpp
index de22bde..af058b3 100644
--- a/garnet/third_party/libunwindstack/RegsArm.cpp
+++ b/garnet/third_party/libunwindstack/RegsArm.cpp
@@ -92,22 +92,38 @@
 }
 
 void RegsArm::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
-  fn("r0", regs_[ARM_REG_R0]);
-  fn("r1", regs_[ARM_REG_R1]);
-  fn("r2", regs_[ARM_REG_R2]);
-  fn("r3", regs_[ARM_REG_R3]);
-  fn("r4", regs_[ARM_REG_R4]);
-  fn("r5", regs_[ARM_REG_R5]);
-  fn("r6", regs_[ARM_REG_R6]);
-  fn("r7", regs_[ARM_REG_R7]);
-  fn("r8", regs_[ARM_REG_R8]);
-  fn("r9", regs_[ARM_REG_R9]);
-  fn("r10", regs_[ARM_REG_R10]);
-  fn("r11", regs_[ARM_REG_R11]);
-  fn("ip", regs_[ARM_REG_R12]);
-  fn("sp", regs_[ARM_REG_SP]);
-  fn("lr", regs_[ARM_REG_LR]);
-  fn("pc", regs_[ARM_REG_PC]);
+  if (IsDefined(ARM_REG_R0))
+    fn("r0", regs_[ARM_REG_R0]);
+  if (IsDefined(ARM_REG_R1))
+    fn("r1", regs_[ARM_REG_R1]);
+  if (IsDefined(ARM_REG_R2))
+    fn("r2", regs_[ARM_REG_R2]);
+  if (IsDefined(ARM_REG_R3))
+    fn("r3", regs_[ARM_REG_R3]);
+  if (IsDefined(ARM_REG_R4))
+    fn("r4", regs_[ARM_REG_R4]);
+  if (IsDefined(ARM_REG_R5))
+    fn("r5", regs_[ARM_REG_R5]);
+  if (IsDefined(ARM_REG_R6))
+    fn("r6", regs_[ARM_REG_R6]);
+  if (IsDefined(ARM_REG_R7))
+    fn("r7", regs_[ARM_REG_R7]);
+  if (IsDefined(ARM_REG_R8))
+    fn("r8", regs_[ARM_REG_R8]);
+  if (IsDefined(ARM_REG_R9))
+    fn("r9", regs_[ARM_REG_R9]);
+  if (IsDefined(ARM_REG_R10))
+    fn("r10", regs_[ARM_REG_R10]);
+  if (IsDefined(ARM_REG_R11))
+    fn("r11", regs_[ARM_REG_R11]);
+  if (IsDefined(ARM_REG_R12))
+    fn("ip", regs_[ARM_REG_R12]);
+  if (IsDefined(ARM_REG_SP))
+    fn("sp", regs_[ARM_REG_SP]);
+  if (IsDefined(ARM_REG_LR))
+    fn("lr", regs_[ARM_REG_LR]);
+  if (IsDefined(ARM_REG_PC))
+    fn("pc", regs_[ARM_REG_PC]);
 }
 
 Regs* RegsArm::Read(void* remote_data) {
diff --git a/garnet/third_party/libunwindstack/RegsArm64.cpp b/garnet/third_party/libunwindstack/RegsArm64.cpp
index a68f6e0..04ecaf7 100644
--- a/garnet/third_party/libunwindstack/RegsArm64.cpp
+++ b/garnet/third_party/libunwindstack/RegsArm64.cpp
@@ -69,39 +69,72 @@
 }
 
 void RegsArm64::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
-  fn("x0", regs_[ARM64_REG_R0]);
-  fn("x1", regs_[ARM64_REG_R1]);
-  fn("x2", regs_[ARM64_REG_R2]);
-  fn("x3", regs_[ARM64_REG_R3]);
-  fn("x4", regs_[ARM64_REG_R4]);
-  fn("x5", regs_[ARM64_REG_R5]);
-  fn("x6", regs_[ARM64_REG_R6]);
-  fn("x7", regs_[ARM64_REG_R7]);
-  fn("x8", regs_[ARM64_REG_R8]);
-  fn("x9", regs_[ARM64_REG_R9]);
-  fn("x10", regs_[ARM64_REG_R10]);
-  fn("x11", regs_[ARM64_REG_R11]);
-  fn("x12", regs_[ARM64_REG_R12]);
-  fn("x13", regs_[ARM64_REG_R13]);
-  fn("x14", regs_[ARM64_REG_R14]);
-  fn("x15", regs_[ARM64_REG_R15]);
-  fn("x16", regs_[ARM64_REG_R16]);
-  fn("x17", regs_[ARM64_REG_R17]);
-  fn("x18", regs_[ARM64_REG_R18]);
-  fn("x19", regs_[ARM64_REG_R19]);
-  fn("x20", regs_[ARM64_REG_R20]);
-  fn("x21", regs_[ARM64_REG_R21]);
-  fn("x22", regs_[ARM64_REG_R22]);
-  fn("x23", regs_[ARM64_REG_R23]);
-  fn("x24", regs_[ARM64_REG_R24]);
-  fn("x25", regs_[ARM64_REG_R25]);
-  fn("x26", regs_[ARM64_REG_R26]);
-  fn("x27", regs_[ARM64_REG_R27]);
-  fn("x28", regs_[ARM64_REG_R28]);
-  fn("x29", regs_[ARM64_REG_R29]);
-  fn("sp", regs_[ARM64_REG_SP]);
-  fn("lr", regs_[ARM64_REG_LR]);
-  fn("pc", regs_[ARM64_REG_PC]);
+  if (IsDefined(ARM64_REG_R0))
+    fn("x0", regs_[ARM64_REG_R0]);
+  if (IsDefined(ARM64_REG_R1))
+    fn("x1", regs_[ARM64_REG_R1]);
+  if (IsDefined(ARM64_REG_R2))
+    fn("x2", regs_[ARM64_REG_R2]);
+  if (IsDefined(ARM64_REG_R3))
+    fn("x3", regs_[ARM64_REG_R3]);
+  if (IsDefined(ARM64_REG_R4))
+    fn("x4", regs_[ARM64_REG_R4]);
+  if (IsDefined(ARM64_REG_R5))
+    fn("x5", regs_[ARM64_REG_R5]);
+  if (IsDefined(ARM64_REG_R6))
+    fn("x6", regs_[ARM64_REG_R6]);
+  if (IsDefined(ARM64_REG_R7))
+    fn("x7", regs_[ARM64_REG_R7]);
+  if (IsDefined(ARM64_REG_R8))
+    fn("x8", regs_[ARM64_REG_R8]);
+  if (IsDefined(ARM64_REG_R9))
+    fn("x9", regs_[ARM64_REG_R9]);
+  if (IsDefined(ARM64_REG_R10))
+    fn("x10", regs_[ARM64_REG_R10]);
+  if (IsDefined(ARM64_REG_R11))
+    fn("x11", regs_[ARM64_REG_R11]);
+  if (IsDefined(ARM64_REG_R12))
+    fn("x12", regs_[ARM64_REG_R12]);
+  if (IsDefined(ARM64_REG_R13))
+    fn("x13", regs_[ARM64_REG_R13]);
+  if (IsDefined(ARM64_REG_R14))
+    fn("x14", regs_[ARM64_REG_R14]);
+  if (IsDefined(ARM64_REG_R15))
+    fn("x15", regs_[ARM64_REG_R15]);
+  if (IsDefined(ARM64_REG_R16))
+    fn("x16", regs_[ARM64_REG_R16]);
+  if (IsDefined(ARM64_REG_R17))
+    fn("x17", regs_[ARM64_REG_R17]);
+  if (IsDefined(ARM64_REG_R18))
+    fn("x18", regs_[ARM64_REG_R18]);
+  if (IsDefined(ARM64_REG_R19))
+    fn("x19", regs_[ARM64_REG_R19]);
+  if (IsDefined(ARM64_REG_R20))
+    fn("x20", regs_[ARM64_REG_R20]);
+  if (IsDefined(ARM64_REG_R21))
+    fn("x21", regs_[ARM64_REG_R21]);
+  if (IsDefined(ARM64_REG_R22))
+    fn("x22", regs_[ARM64_REG_R22]);
+  if (IsDefined(ARM64_REG_R23))
+    fn("x23", regs_[ARM64_REG_R23]);
+  if (IsDefined(ARM64_REG_R24))
+    fn("x24", regs_[ARM64_REG_R24]);
+  if (IsDefined(ARM64_REG_R25))
+    fn("x25", regs_[ARM64_REG_R25]);
+  if (IsDefined(ARM64_REG_R26))
+    fn("x26", regs_[ARM64_REG_R26]);
+  if (IsDefined(ARM64_REG_R27))
+    fn("x27", regs_[ARM64_REG_R27]);
+  if (IsDefined(ARM64_REG_R28))
+    fn("x28", regs_[ARM64_REG_R28]);
+  if (IsDefined(ARM64_REG_R29))
+    fn("x29", regs_[ARM64_REG_R29]);
+  if (IsDefined(ARM64_REG_SP))
+    fn("sp", regs_[ARM64_REG_SP]);
+  if (IsDefined(ARM64_REG_LR))
+    fn("lr", regs_[ARM64_REG_LR]);
+  if (IsDefined(ARM64_REG_PC))
+    fn("pc", regs_[ARM64_REG_PC]);
 }
 
 Regs* RegsArm64::Read(void* remote_data) {
diff --git a/garnet/third_party/libunwindstack/RegsMips.cpp b/garnet/third_party/libunwindstack/RegsMips.cpp
index 2e6908c..b001869 100644
--- a/garnet/third_party/libunwindstack/RegsMips.cpp
+++ b/garnet/third_party/libunwindstack/RegsMips.cpp
@@ -70,39 +70,72 @@
 }
 
 void RegsMips::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
-  fn("r0", regs_[MIPS_REG_R0]);
-  fn("r1", regs_[MIPS_REG_R1]);
-  fn("r2", regs_[MIPS_REG_R2]);
-  fn("r3", regs_[MIPS_REG_R3]);
-  fn("r4", regs_[MIPS_REG_R4]);
-  fn("r5", regs_[MIPS_REG_R5]);
-  fn("r6", regs_[MIPS_REG_R6]);
-  fn("r7", regs_[MIPS_REG_R7]);
-  fn("r8", regs_[MIPS_REG_R8]);
-  fn("r9", regs_[MIPS_REG_R9]);
-  fn("r10", regs_[MIPS_REG_R10]);
-  fn("r11", regs_[MIPS_REG_R11]);
-  fn("r12", regs_[MIPS_REG_R12]);
-  fn("r13", regs_[MIPS_REG_R13]);
-  fn("r14", regs_[MIPS_REG_R14]);
-  fn("r15", regs_[MIPS_REG_R15]);
-  fn("r16", regs_[MIPS_REG_R16]);
-  fn("r17", regs_[MIPS_REG_R17]);
-  fn("r18", regs_[MIPS_REG_R18]);
-  fn("r19", regs_[MIPS_REG_R19]);
-  fn("r20", regs_[MIPS_REG_R20]);
-  fn("r21", regs_[MIPS_REG_R21]);
-  fn("r22", regs_[MIPS_REG_R22]);
-  fn("r23", regs_[MIPS_REG_R23]);
-  fn("r24", regs_[MIPS_REG_R24]);
-  fn("r25", regs_[MIPS_REG_R25]);
-  fn("r26", regs_[MIPS_REG_R26]);
-  fn("r27", regs_[MIPS_REG_R27]);
-  fn("r28", regs_[MIPS_REG_R28]);
-  fn("sp", regs_[MIPS_REG_SP]);
-  fn("r30", regs_[MIPS_REG_R30]);
-  fn("ra", regs_[MIPS_REG_RA]);
-  fn("pc", regs_[MIPS_REG_PC]);
+  if (IsDefined(MIPS_REG_R0))
+    fn("r0", regs_[MIPS_REG_R0]);
+  if (IsDefined(MIPS_REG_R1))
+    fn("r1", regs_[MIPS_REG_R1]);
+  if (IsDefined(MIPS_REG_R2))
+    fn("r2", regs_[MIPS_REG_R2]);
+  if (IsDefined(MIPS_REG_R3))
+    fn("r3", regs_[MIPS_REG_R3]);
+  if (IsDefined(MIPS_REG_R4))
+    fn("r4", regs_[MIPS_REG_R4]);
+  if (IsDefined(MIPS_REG_R5))
+    fn("r5", regs_[MIPS_REG_R5]);
+  if (IsDefined(MIPS_REG_R6))
+    fn("r6", regs_[MIPS_REG_R6]);
+  if (IsDefined(MIPS_REG_R7))
+    fn("r7", regs_[MIPS_REG_R7]);
+  if (IsDefined(MIPS_REG_R8))
+    fn("r8", regs_[MIPS_REG_R8]);
+  if (IsDefined(MIPS_REG_R9))
+    fn("r9", regs_[MIPS_REG_R9]);
+  if (IsDefined(MIPS_REG_R10))
+    fn("r10", regs_[MIPS_REG_R10]);
+  if (IsDefined(MIPS_REG_R11))
+    fn("r11", regs_[MIPS_REG_R11]);
+  if (IsDefined(MIPS_REG_R12))
+    fn("r12", regs_[MIPS_REG_R12]);
+  if (IsDefined(MIPS_REG_R13))
+    fn("r13", regs_[MIPS_REG_R13]);
+  if (IsDefined(MIPS_REG_R14))
+    fn("r14", regs_[MIPS_REG_R14]);
+  if (IsDefined(MIPS_REG_R15))
+    fn("r15", regs_[MIPS_REG_R15]);
+  if (IsDefined(MIPS_REG_R16))
+    fn("r16", regs_[MIPS_REG_R16]);
+  if (IsDefined(MIPS_REG_R17))
+    fn("r17", regs_[MIPS_REG_R17]);
+  if (IsDefined(MIPS_REG_R18))
+    fn("r18", regs_[MIPS_REG_R18]);
+  if (IsDefined(MIPS_REG_R19))
+    fn("r19", regs_[MIPS_REG_R19]);
+  if (IsDefined(MIPS_REG_R20))
+    fn("r20", regs_[MIPS_REG_R20]);
+  if (IsDefined(MIPS_REG_R21))
+    fn("r21", regs_[MIPS_REG_R21]);
+  if (IsDefined(MIPS_REG_R22))
+    fn("r22", regs_[MIPS_REG_R22]);
+  if (IsDefined(MIPS_REG_R23))
+    fn("r23", regs_[MIPS_REG_R23]);
+  if (IsDefined(MIPS_REG_R24))
+    fn("r24", regs_[MIPS_REG_R24]);
+  if (IsDefined(MIPS_REG_R25))
+    fn("r25", regs_[MIPS_REG_R25]);
+  if (IsDefined(MIPS_REG_R26))
+    fn("r26", regs_[MIPS_REG_R26]);
+  if (IsDefined(MIPS_REG_R27))
+    fn("r27", regs_[MIPS_REG_R27]);
+  if (IsDefined(MIPS_REG_R28))
+    fn("r28", regs_[MIPS_REG_R28]);
+  if (IsDefined(MIPS_REG_SP))
+    fn("sp", regs_[MIPS_REG_SP]);
+  if (IsDefined(MIPS_REG_R30))
+    fn("r30", regs_[MIPS_REG_R30]);
+  if (IsDefined(MIPS_REG_RA))
+    fn("ra", regs_[MIPS_REG_RA]);
+  if (IsDefined(MIPS_REG_PC))
+    fn("pc", regs_[MIPS_REG_PC]);
 }
 
 Regs* RegsMips::Read(void* remote_data) {
diff --git a/garnet/third_party/libunwindstack/RegsMips64.cpp b/garnet/third_party/libunwindstack/RegsMips64.cpp
index 0b835a1..41a7391 100644
--- a/garnet/third_party/libunwindstack/RegsMips64.cpp
+++ b/garnet/third_party/libunwindstack/RegsMips64.cpp
@@ -70,39 +70,72 @@
 }
 
 void RegsMips64::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
-  fn("r0", regs_[MIPS64_REG_R0]);
-  fn("r1", regs_[MIPS64_REG_R1]);
-  fn("r2", regs_[MIPS64_REG_R2]);
-  fn("r3", regs_[MIPS64_REG_R3]);
-  fn("r4", regs_[MIPS64_REG_R4]);
-  fn("r5", regs_[MIPS64_REG_R5]);
-  fn("r6", regs_[MIPS64_REG_R6]);
-  fn("r7", regs_[MIPS64_REG_R7]);
-  fn("r8", regs_[MIPS64_REG_R8]);
-  fn("r9", regs_[MIPS64_REG_R9]);
-  fn("r10", regs_[MIPS64_REG_R10]);
-  fn("r11", regs_[MIPS64_REG_R11]);
-  fn("r12", regs_[MIPS64_REG_R12]);
-  fn("r13", regs_[MIPS64_REG_R13]);
-  fn("r14", regs_[MIPS64_REG_R14]);
-  fn("r15", regs_[MIPS64_REG_R15]);
-  fn("r16", regs_[MIPS64_REG_R16]);
-  fn("r17", regs_[MIPS64_REG_R17]);
-  fn("r18", regs_[MIPS64_REG_R18]);
-  fn("r19", regs_[MIPS64_REG_R19]);
-  fn("r20", regs_[MIPS64_REG_R20]);
-  fn("r21", regs_[MIPS64_REG_R21]);
-  fn("r22", regs_[MIPS64_REG_R22]);
-  fn("r23", regs_[MIPS64_REG_R23]);
-  fn("r24", regs_[MIPS64_REG_R24]);
-  fn("r25", regs_[MIPS64_REG_R25]);
-  fn("r26", regs_[MIPS64_REG_R26]);
-  fn("r27", regs_[MIPS64_REG_R27]);
-  fn("r28", regs_[MIPS64_REG_R28]);
-  fn("sp", regs_[MIPS64_REG_SP]);
-  fn("r30", regs_[MIPS64_REG_R30]);
-  fn("ra", regs_[MIPS64_REG_RA]);
-  fn("pc", regs_[MIPS64_REG_PC]);
+  if (IsDefined(MIPS64_REG_R0))
+    fn("r0", regs_[MIPS64_REG_R0]);
+  if (IsDefined(MIPS64_REG_R1))
+    fn("r1", regs_[MIPS64_REG_R1]);
+  if (IsDefined(MIPS64_REG_R2))
+    fn("r2", regs_[MIPS64_REG_R2]);
+  if (IsDefined(MIPS64_REG_R3))
+    fn("r3", regs_[MIPS64_REG_R3]);
+  if (IsDefined(MIPS64_REG_R4))
+    fn("r4", regs_[MIPS64_REG_R4]);
+  if (IsDefined(MIPS64_REG_R5))
+    fn("r5", regs_[MIPS64_REG_R5]);
+  if (IsDefined(MIPS64_REG_R6))
+    fn("r6", regs_[MIPS64_REG_R6]);
+  if (IsDefined(MIPS64_REG_R7))
+    fn("r7", regs_[MIPS64_REG_R7]);
+  if (IsDefined(MIPS64_REG_R8))
+    fn("r8", regs_[MIPS64_REG_R8]);
+  if (IsDefined(MIPS64_REG_R9))
+    fn("r9", regs_[MIPS64_REG_R9]);
+  if (IsDefined(MIPS64_REG_R10))
+    fn("r10", regs_[MIPS64_REG_R10]);
+  if (IsDefined(MIPS64_REG_R11))
+    fn("r11", regs_[MIPS64_REG_R11]);
+  if (IsDefined(MIPS64_REG_R12))
+    fn("r12", regs_[MIPS64_REG_R12]);
+  if (IsDefined(MIPS64_REG_R13))
+    fn("r13", regs_[MIPS64_REG_R13]);
+  if (IsDefined(MIPS64_REG_R14))
+    fn("r14", regs_[MIPS64_REG_R14]);
+  if (IsDefined(MIPS64_REG_R15))
+    fn("r15", regs_[MIPS64_REG_R15]);
+  if (IsDefined(MIPS64_REG_R16))
+    fn("r16", regs_[MIPS64_REG_R16]);
+  if (IsDefined(MIPS64_REG_R17))
+    fn("r17", regs_[MIPS64_REG_R17]);
+  if (IsDefined(MIPS64_REG_R18))
+    fn("r18", regs_[MIPS64_REG_R18]);
+  if (IsDefined(MIPS64_REG_R19))
+    fn("r19", regs_[MIPS64_REG_R19]);
+  if (IsDefined(MIPS64_REG_R20))
+    fn("r20", regs_[MIPS64_REG_R20]);
+  if (IsDefined(MIPS64_REG_R21))
+    fn("r21", regs_[MIPS64_REG_R21]);
+  if (IsDefined(MIPS64_REG_R22))
+    fn("r22", regs_[MIPS64_REG_R22]);
+  if (IsDefined(MIPS64_REG_R23))
+    fn("r23", regs_[MIPS64_REG_R23]);
+  if (IsDefined(MIPS64_REG_R24))
+    fn("r24", regs_[MIPS64_REG_R24]);
+  if (IsDefined(MIPS64_REG_R25))
+    fn("r25", regs_[MIPS64_REG_R25]);
+  if (IsDefined(MIPS64_REG_R26))
+    fn("r26", regs_[MIPS64_REG_R26]);
+  if (IsDefined(MIPS64_REG_R27))
+    fn("r27", regs_[MIPS64_REG_R27]);
+  if (IsDefined(MIPS64_REG_R28))
+    fn("r28", regs_[MIPS64_REG_R28]);
+  if (IsDefined(MIPS64_REG_SP))
+    fn("sp", regs_[MIPS64_REG_SP]);
+  if (IsDefined(MIPS64_REG_R30))
+    fn("r30", regs_[MIPS64_REG_R30]);
+  if (IsDefined(MIPS64_REG_RA))
+    fn("ra", regs_[MIPS64_REG_RA]);
+  if (IsDefined(MIPS64_REG_PC))
+    fn("pc", regs_[MIPS64_REG_PC]);
 }
 
 Regs* RegsMips64::Read(void* remote_data) {
diff --git a/garnet/third_party/libunwindstack/RegsX86.cpp b/garnet/third_party/libunwindstack/RegsX86.cpp
index 9bb39d1..710279b 100644
--- a/garnet/third_party/libunwindstack/RegsX86.cpp
+++ b/garnet/third_party/libunwindstack/RegsX86.cpp
@@ -70,15 +70,24 @@
 }
 
 void RegsX86::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
-  fn("eax", regs_[X86_REG_EAX]);
-  fn("ebx", regs_[X86_REG_EBX]);
-  fn("ecx", regs_[X86_REG_ECX]);
-  fn("edx", regs_[X86_REG_EDX]);
-  fn("ebp", regs_[X86_REG_EBP]);
-  fn("edi", regs_[X86_REG_EDI]);
-  fn("esi", regs_[X86_REG_ESI]);
-  fn("esp", regs_[X86_REG_ESP]);
-  fn("eip", regs_[X86_REG_EIP]);
+  if (IsDefined(X86_REG_EAX))
+    fn("eax", regs_[X86_REG_EAX]);
+  if (IsDefined(X86_REG_EBX))
+    fn("ebx", regs_[X86_REG_EBX]);
+  if (IsDefined(X86_REG_ECX))
+    fn("ecx", regs_[X86_REG_ECX]);
+  if (IsDefined(X86_REG_EDX))
+    fn("edx", regs_[X86_REG_EDX]);
+  if (IsDefined(X86_REG_EBP))
+    fn("ebp", regs_[X86_REG_EBP]);
+  if (IsDefined(X86_REG_EDI))
+    fn("edi", regs_[X86_REG_EDI]);
+  if (IsDefined(X86_REG_ESI))
+    fn("esi", regs_[X86_REG_ESI]);
+  if (IsDefined(X86_REG_ESP))
+    fn("esp", regs_[X86_REG_ESP]);
+  if (IsDefined(X86_REG_EIP))
+    fn("eip", regs_[X86_REG_EIP]);
 }
 
 Regs* RegsX86::Read(void* user_data) {
diff --git a/garnet/third_party/libunwindstack/RegsX86_64.cpp b/garnet/third_party/libunwindstack/RegsX86_64.cpp
index ebad3f4..cd3a9bc 100644
--- a/garnet/third_party/libunwindstack/RegsX86_64.cpp
+++ b/garnet/third_party/libunwindstack/RegsX86_64.cpp
@@ -70,23 +70,40 @@
 }
 
 void RegsX86_64::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
-  fn("rax", regs_[X86_64_REG_RAX]);
-  fn("rbx", regs_[X86_64_REG_RBX]);
-  fn("rcx", regs_[X86_64_REG_RCX]);
-  fn("rdx", regs_[X86_64_REG_RDX]);
-  fn("r8", regs_[X86_64_REG_R8]);
-  fn("r9", regs_[X86_64_REG_R9]);
-  fn("r10", regs_[X86_64_REG_R10]);
-  fn("r11", regs_[X86_64_REG_R11]);
-  fn("r12", regs_[X86_64_REG_R12]);
-  fn("r13", regs_[X86_64_REG_R13]);
-  fn("r14", regs_[X86_64_REG_R14]);
-  fn("r15", regs_[X86_64_REG_R15]);
-  fn("rdi", regs_[X86_64_REG_RDI]);
-  fn("rsi", regs_[X86_64_REG_RSI]);
-  fn("rbp", regs_[X86_64_REG_RBP]);
-  fn("rsp", regs_[X86_64_REG_RSP]);
-  fn("rip", regs_[X86_64_REG_RIP]);
+  if (IsDefined(X86_64_REG_RAX))
+    fn("rax", regs_[X86_64_REG_RAX]);
+  if (IsDefined(X86_64_REG_RBX))
+    fn("rbx", regs_[X86_64_REG_RBX]);
+  if (IsDefined(X86_64_REG_RCX))
+    fn("rcx", regs_[X86_64_REG_RCX]);
+  if (IsDefined(X86_64_REG_RDX))
+    fn("rdx", regs_[X86_64_REG_RDX]);
+  if (IsDefined(X86_64_REG_R8))
+    fn("r8", regs_[X86_64_REG_R8]);
+  if (IsDefined(X86_64_REG_R9))
+    fn("r9", regs_[X86_64_REG_R9]);
+  if (IsDefined(X86_64_REG_R10))
+    fn("r10", regs_[X86_64_REG_R10]);
+  if (IsDefined(X86_64_REG_R11))
+    fn("r11", regs_[X86_64_REG_R11]);
+  if (IsDefined(X86_64_REG_R12))
+    fn("r12", regs_[X86_64_REG_R12]);
+  if (IsDefined(X86_64_REG_R13))
+    fn("r13", regs_[X86_64_REG_R13]);
+  if (IsDefined(X86_64_REG_R14))
+    fn("r14", regs_[X86_64_REG_R14]);
+  if (IsDefined(X86_64_REG_R15))
+    fn("r15", regs_[X86_64_REG_R15]);
+  if (IsDefined(X86_64_REG_RDI))
+    fn("rdi", regs_[X86_64_REG_RDI]);
+  if (IsDefined(X86_64_REG_RSI))
+    fn("rsi", regs_[X86_64_REG_RSI]);
+  if (IsDefined(X86_64_REG_RBP))
+    fn("rbp", regs_[X86_64_REG_RBP]);
+  if (IsDefined(X86_64_REG_RSP))
+    fn("rsp", regs_[X86_64_REG_RSP]);
+  if (IsDefined(X86_64_REG_RIP))
+    fn("rip", regs_[X86_64_REG_RIP]);
 }
 
 Regs* RegsX86_64::Read(void* remote_data) {
diff --git a/garnet/third_party/libunwindstack/fuchsia/RegsFuchsiaArm64.cpp b/garnet/third_party/libunwindstack/fuchsia/RegsFuchsiaArm64.cpp
index a7a1677..c61bd22 100644
--- a/garnet/third_party/libunwindstack/fuchsia/RegsFuchsiaArm64.cpp
+++ b/garnet/third_party/libunwindstack/fuchsia/RegsFuchsiaArm64.cpp
@@ -101,39 +101,72 @@
 
 void RegsFuchsia::IterateRegisters(
     std::function<void(const char*, uint64_t)> fn) {
-  fn("x0", regs_[ARM64_REG_R0]);
-  fn("x1", regs_[ARM64_REG_R1]);
-  fn("x2", regs_[ARM64_REG_R2]);
-  fn("x3", regs_[ARM64_REG_R3]);
-  fn("x4", regs_[ARM64_REG_R4]);
-  fn("x5", regs_[ARM64_REG_R5]);
-  fn("x6", regs_[ARM64_REG_R6]);
-  fn("x7", regs_[ARM64_REG_R7]);
-  fn("x8", regs_[ARM64_REG_R8]);
-  fn("x9", regs_[ARM64_REG_R9]);
-  fn("x10", regs_[ARM64_REG_R10]);
-  fn("x11", regs_[ARM64_REG_R11]);
-  fn("x12", regs_[ARM64_REG_R12]);
-  fn("x13", regs_[ARM64_REG_R13]);
-  fn("x14", regs_[ARM64_REG_R14]);
-  fn("x15", regs_[ARM64_REG_R15]);
-  fn("x16", regs_[ARM64_REG_R16]);
-  fn("x17", regs_[ARM64_REG_R17]);
-  fn("x18", regs_[ARM64_REG_R18]);
-  fn("x19", regs_[ARM64_REG_R19]);
-  fn("x20", regs_[ARM64_REG_R20]);
-  fn("x21", regs_[ARM64_REG_R21]);
-  fn("x22", regs_[ARM64_REG_R22]);
-  fn("x23", regs_[ARM64_REG_R23]);
-  fn("x24", regs_[ARM64_REG_R24]);
-  fn("x25", regs_[ARM64_REG_R25]);
-  fn("x26", regs_[ARM64_REG_R26]);
-  fn("x27", regs_[ARM64_REG_R27]);
-  fn("x28", regs_[ARM64_REG_R28]);
-  fn("x29", regs_[ARM64_REG_R29]);
-  fn("sp", regs_[ARM64_REG_SP]);
-  fn("lr", regs_[ARM64_REG_LR]);
-  fn("pc", regs_[ARM64_REG_PC]);
+  if (IsDefined(ARM64_REG_R0))
+    fn("x0", regs_[ARM64_REG_R0]);
+  if (IsDefined(ARM64_REG_R1))
+    fn("x1", regs_[ARM64_REG_R1]);
+  if (IsDefined(ARM64_REG_R2))
+    fn("x2", regs_[ARM64_REG_R2]);
+  if (IsDefined(ARM64_REG_R3))
+    fn("x3", regs_[ARM64_REG_R3]);
+  if (IsDefined(ARM64_REG_R4))
+    fn("x4", regs_[ARM64_REG_R4]);
+  if (IsDefined(ARM64_REG_R5))
+    fn("x5", regs_[ARM64_REG_R5]);
+  if (IsDefined(ARM64_REG_R6))
+    fn("x6", regs_[ARM64_REG_R6]);
+  if (IsDefined(ARM64_REG_R7))
+    fn("x7", regs_[ARM64_REG_R7]);
+  if (IsDefined(ARM64_REG_R8))
+    fn("x8", regs_[ARM64_REG_R8]);
+  if (IsDefined(ARM64_REG_R9))
+    fn("x9", regs_[ARM64_REG_R9]);
+  if (IsDefined(ARM64_REG_R10))
+    fn("x10", regs_[ARM64_REG_R10]);
+  if (IsDefined(ARM64_REG_R11))
+    fn("x11", regs_[ARM64_REG_R11]);
+  if (IsDefined(ARM64_REG_R12))
+    fn("x12", regs_[ARM64_REG_R12]);
+  if (IsDefined(ARM64_REG_R13))
+    fn("x13", regs_[ARM64_REG_R13]);
+  if (IsDefined(ARM64_REG_R14))
+    fn("x14", regs_[ARM64_REG_R14]);
+  if (IsDefined(ARM64_REG_R15))
+    fn("x15", regs_[ARM64_REG_R15]);
+  if (IsDefined(ARM64_REG_R16))
+    fn("x16", regs_[ARM64_REG_R16]);
+  if (IsDefined(ARM64_REG_R17))
+    fn("x17", regs_[ARM64_REG_R17]);
+  if (IsDefined(ARM64_REG_R18))
+    fn("x18", regs_[ARM64_REG_R18]);
+  if (IsDefined(ARM64_REG_R19))
+    fn("x19", regs_[ARM64_REG_R19]);
+  if (IsDefined(ARM64_REG_R20))
+    fn("x20", regs_[ARM64_REG_R20]);
+  if (IsDefined(ARM64_REG_R21))
+    fn("x21", regs_[ARM64_REG_R21]);
+  if (IsDefined(ARM64_REG_R22))
+    fn("x22", regs_[ARM64_REG_R22]);
+  if (IsDefined(ARM64_REG_R23))
+    fn("x23", regs_[ARM64_REG_R23]);
+  if (IsDefined(ARM64_REG_R24))
+    fn("x24", regs_[ARM64_REG_R24]);
+  if (IsDefined(ARM64_REG_R25))
+    fn("x25", regs_[ARM64_REG_R25]);
+  if (IsDefined(ARM64_REG_R26))
+    fn("x26", regs_[ARM64_REG_R26]);
+  if (IsDefined(ARM64_REG_R27))
+    fn("x27", regs_[ARM64_REG_R27]);
+  if (IsDefined(ARM64_REG_R28))
+    fn("x28", regs_[ARM64_REG_R28]);
+  if (IsDefined(ARM64_REG_R29))
+    fn("x29", regs_[ARM64_REG_R29]);
+  if (IsDefined(ARM64_REG_SP))
+    fn("sp", regs_[ARM64_REG_SP]);
+  if (IsDefined(ARM64_REG_LR))
+    fn("lr", regs_[ARM64_REG_LR]);
+  if (IsDefined(ARM64_REG_PC))
+    fn("pc", regs_[ARM64_REG_PC]);
 }
 
 uint64_t RegsFuchsia::pc() { return regs_[ARM64_REG_PC]; }
diff --git a/garnet/third_party/libunwindstack/include/unwindstack/DwarfSection.h b/garnet/third_party/libunwindstack/include/unwindstack/DwarfSection.h
index e9942de..8681c6c 100644
--- a/garnet/third_party/libunwindstack/include/unwindstack/DwarfSection.h
+++ b/garnet/third_party/libunwindstack/include/unwindstack/DwarfSection.h
@@ -129,7 +129,7 @@
 
   const DwarfFde* GetFdeFromOffset(uint64_t offset);
 
-  bool EvalRegister(const DwarfLocation* loc, uint32_t reg, AddressType* reg_ptr, void* info);
+  bool EvalRegister(const DwarfLocation* loc, uint32_t reg, AddressType* reg_ptr, bool* defined, void* info);
 
   bool Eval(const DwarfCie* cie, Memory* regular_memory, const dwarf_loc_regs_t& loc_regs,
             Regs* regs, bool* finished) override;
diff --git a/garnet/third_party/libunwindstack/include/unwindstack/Regs.h b/garnet/third_party/libunwindstack/include/unwindstack/Regs.h
index 9d6c48d..5ef3a53 100644
--- a/garnet/third_party/libunwindstack/include/unwindstack/Regs.h
+++ b/garnet/third_party/libunwindstack/include/unwindstack/Regs.h
@@ -96,23 +96,37 @@
 class RegsImpl : public Regs {
  public:
   RegsImpl(uint16_t total_regs, Location return_loc)
-      : Regs(total_regs, return_loc), regs_(total_regs) {}
+      : Regs(total_regs, return_loc), regs_(total_regs), regs_undefined_(total_regs) {}
   virtual ~RegsImpl() = default;
 
   bool Is32Bit() override { return sizeof(AddressType) == sizeof(uint32_t); }
 
   inline AddressType& operator[](size_t reg) { return regs_[reg]; }
 
+  inline void SetDefined(size_t reg, bool value) { regs_undefined_[reg] = !value; }
+
+  inline bool IsDefined(size_t reg) { return !regs_undefined_[reg]; }
+
   void* RawData() override { return regs_.data(); }
 
   virtual void IterateRegisters(std::function<void(const char*, uint64_t)> fn) override {
     for (size_t i = 0; i < regs_.size(); ++i) {
+      if (regs_undefined_[i]) {
+        continue;
+      }
+
       fn(std::to_string(i).c_str(), regs_[i]);
     }
   }
 
  protected:
   std::vector<AddressType> regs_;
+
+  // We store true if a register is undefined rather than defined, even though
+  // the interface exposes a bool for whether the register is defined rather
+  // than undefined, because we want to take advantage of the default
+  // initializer to set all registers to defined by default.
+  std::vector<bool> regs_undefined_;
 };
 
 }  // namespace unwindstack