Support dwarf 4 in libunwind.

This patch may not contain all changes needed to support dwarf 4,
but it fixes unit tests in libbacktrace.

Bug: 25372413
Bug: 23951479
Change-Id: Id15ad290812f1f0e4d39879015b13cc7778872a6
diff --git a/src/dwarf/Gfde.c b/src/dwarf/Gfde.c
index 4c89967..f4f9998 100644
--- a/src/dwarf/Gfde.c
+++ b/src/dwarf/Gfde.c
@@ -118,10 +118,9 @@
   if ((ret = dwarf_readu8 (as, a, &addr, &version, arg)) < 0)
     return ret;
 
-  if (version != 1 && version != DWARF_CIE_VERSION)
+  if (version != 1 && version != 3 && version != 4)
     {
-      Debug (1, "Got CIE version %u, expected version 1 or "
-	     STR (DWARF_CIE_VERSION) "\n", version);
+      Debug (1, "Got CIE version %u, expected version 1, 3 or 4\n", version);
       return -UNW_EBADVERSION;
     }
 
@@ -139,6 +138,23 @@
 	augstr[i++] = ch;
     }
 
+  if (version == 4) {
+    uint8_t address_size;
+    if ((ret = dwarf_readu8(as, a, &addr, &address_size, arg)) < 0) {
+      return ret;
+    }
+    if (address_size != sizeof(unw_word_t)) {
+      return -UNW_EBADVERSION;
+    }
+    uint8_t segment_size;
+    if ((ret = dwarf_readu8(as, a, &addr, &segment_size, arg)) < 0) {
+      return ret;
+    }
+    // We don't support non-zero segment size.
+    if (segment_size != 0) {
+      return -UNW_EBADVERSION;
+    }
+  }
   if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->code_align, arg)) < 0
       || (ret = dwarf_read_sleb128 (as, a, &addr, &dci->data_align, arg)) < 0)
     return ret;