PowerPC64 tls_get_addr_desc static support
authorAlan Modra <amodra@gmail.com>
Wed, 22 Jan 2020 01:54:56 +0000 (12:24 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 22 Jan 2020 06:44:08 +0000 (17:14 +1030)
This provides a linker generated __tls_get_addr_desc wrapper function
preserving registers around a __tls_get_addr call.  The idea being to
support __tls_get_addr_desc without requiring a glibc update.

bfd/
* elf64-ppc.c (struct ppc_link_hash_table): Add tga_group.
(ppc64_elf_archive_symbol_lookup): Extract __tls_get_addr_opt for
__tls_get_addr_desc.
(ppc64_elf_size_stubs): Add section for linker generated
__tls_get_addr_desc wrapper function.  Loop at least once if
generating this function.
(emit_tga_desc, emit_tga_desc_eh_frame): New functions.
(ppc64_elf_build_stubs): Generate __tls_get_addr_desc.
ld/
* testsuite/ld-powerpc/tlsdesc3.d,
* testsuite/ld-powerpc/tlsdesc3.wf,
* testsuite/ld-powerpc/tlsdesc4.d,
* testsuite/ld-powerpc/tlsdesc4.s,
* testsuite/ld-powerpc/tlsdesc4.wf: New tests.
* testsuite/ld-powerpc/powerpc.exp: Run them.

bfd/ChangeLog
bfd/elf64-ppc.c
ld/ChangeLog
ld/testsuite/ld-powerpc/powerpc.exp
ld/testsuite/ld-powerpc/tlsdesc3.d [new file with mode: 0644]
ld/testsuite/ld-powerpc/tlsdesc3.wf [new file with mode: 0644]
ld/testsuite/ld-powerpc/tlsdesc4.d [new file with mode: 0644]
ld/testsuite/ld-powerpc/tlsdesc4.s [new file with mode: 0644]
ld/testsuite/ld-powerpc/tlsdesc4.wf [new file with mode: 0644]

index 1bd9b5f979a1a91f3bc8c9ead32d361baf38a8e2..f20b2c0dac8809e53e03cddf061942ff8628fb12 100644 (file)
@@ -1,3 +1,14 @@
+2020-01-22  Alan Modra  <amodra@gmail.com>
+
+       * elf64-ppc.c (struct ppc_link_hash_table): Add tga_group.
+       (ppc64_elf_archive_symbol_lookup): Extract __tls_get_addr_opt for
+       __tls_get_addr_desc.
+       (ppc64_elf_size_stubs): Add section for linker generated
+       __tls_get_addr_desc wrapper function.  Loop at least once if
+       generating this function.
+       (emit_tga_desc, emit_tga_desc_eh_frame): New functions.
+       (ppc64_elf_build_stubs): Generate __tls_get_addr_desc.
+
 2020-01-22  Alan Modra  <amodra@gmail.com>
 
        * elf64-ppc.h (struct ppc64_elf_params): Add no_tls_get_addr_regsave.
index 6b11a11018d0e30bd8c3dc626dbde917a14b28d8..b3f8f6b359e5781cfdbd5302b46249afefbfae66 100644 (file)
@@ -3182,6 +3182,7 @@ struct ppc_link_hash_table
   struct ppc_link_hash_entry *tls_get_addr_fd;
   struct ppc_link_hash_entry *tga_desc;
   struct ppc_link_hash_entry *tga_desc_fd;
+  struct map_stub *tga_group;
 
   /* The size of reliplt used by got entry relocs.  */
   bfd_size_type got_reli_size;
@@ -4150,6 +4151,11 @@ ppc64_elf_archive_symbol_lookup (bfd *abfd,
   memcpy (dot_name + 1, name, len + 1);
   h = _bfd_elf_archive_symbol_lookup (abfd, info, dot_name);
   bfd_release (abfd, dot_name);
+  if (h != NULL)
+    return h;
+
+  if (strcmp (name, "__tls_get_addr_opt") == 0)
+    h = _bfd_elf_archive_symbol_lookup (abfd, info, "__tls_get_addr_desc");
   return h;
 }
 
@@ -13088,6 +13094,40 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
   if (!group_sections (info, stub_group_size, stubs_always_before_branch))
     return FALSE;
 
+  htab->tga_group = NULL;
+  if (!htab->params->no_tls_get_addr_regsave
+      && htab->tga_desc_fd != NULL
+      && (htab->tga_desc_fd->elf.root.type == bfd_link_hash_undefined
+         || htab->tga_desc_fd->elf.root.type == bfd_link_hash_undefweak)
+      && htab->tls_get_addr_fd != NULL
+      && is_static_defined (&htab->tls_get_addr_fd->elf))
+    {
+      asection *sym_sec, *code_sec, *stub_sec;
+      bfd_vma sym_value;
+      struct _opd_sec_data *opd;
+
+      sym_sec = htab->tls_get_addr_fd->elf.root.u.def.section;
+      sym_value = defined_sym_val (&htab->tls_get_addr_fd->elf);
+      code_sec = sym_sec;
+      opd = get_opd_info (sym_sec);
+      if (opd != NULL)
+       opd_entry_value (sym_sec, sym_value, &code_sec, NULL, FALSE);
+      htab->tga_group = htab->sec_info[code_sec->id].u.group;
+      stub_sec = (*htab->params->add_stub_section) (".tga_desc.stub",
+                                                   htab->tga_group->link_sec);
+      if (stub_sec == NULL)
+       return FALSE;
+      htab->tga_group->stub_sec = stub_sec;
+
+      htab->tga_desc_fd->elf.root.type = bfd_link_hash_defined;
+      htab->tga_desc_fd->elf.root.u.def.section = stub_sec;
+      htab->tga_desc_fd->elf.root.u.def.value = 0;
+      htab->tga_desc_fd->elf.type = STT_FUNC;
+      htab->tga_desc_fd->elf.def_regular = 1;
+      htab->tga_desc_fd->elf.non_elf = 0;
+      _bfd_elf_link_hash_hide_symbol (info, &htab->tga_desc_fd->elf, TRUE);
+    }
+
 #define STUB_SHRINK_ITER 20
   /* Loop until no stubs added.  After iteration 20 of this loop we may
      exit on a stub section shrinking.  This is to break out of a
@@ -13517,6 +13557,14 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
              stub_sec->flags &= ~SEC_RELOC;
            }
        }
+      if (htab->tga_group != NULL)
+       {
+         /* See emit_tga_desc and emit_tga_desc_eh_frame.  */
+         htab->tga_group->eh_size
+           = 1 + 2 + (htab->opd_abi != 0) + 3 + 8 * 2 + 3 + 8 + 3;
+         htab->tga_group->lr_restore = 23 * 4;
+         htab->tga_group->stub_sec->size = 24 * 4;
+       }
 
       if (htab->stub_iteration <= STUB_SHRINK_ITER
          || htab->brlt->rawsize < htab->brlt->size)
@@ -13580,7 +13628,9 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
              || (htab->stub_iteration > STUB_SHRINK_ITER
                  && htab->brlt->rawsize > htab->brlt->size))
          && (htab->glink_eh_frame == NULL
-             || htab->glink_eh_frame->rawsize == htab->glink_eh_frame->size))
+             || htab->glink_eh_frame->rawsize == htab->glink_eh_frame->size)
+         && (htab->tga_group == NULL
+             || htab->stub_iteration > 1))
        break;
 
       /* Ask the linker to do its stuff.  */
@@ -14086,6 +14136,74 @@ write_plt_relocs_for_local_syms (struct bfd_link_info *info)
   return TRUE;
 }
 
+/* Emit the static wrapper function preserving registers around a
+   __tls_get_addr_opt call.  */
+
+static bfd_boolean
+emit_tga_desc (struct ppc_link_hash_table *htab)
+{
+  asection *stub_sec = htab->tga_group->stub_sec;
+  unsigned int cfa_updt = 11 * 4;
+  bfd_byte *p;
+  bfd_vma to, from, delta;
+
+  BFD_ASSERT (htab->tga_desc_fd->elf.root.type == bfd_link_hash_defined
+             && htab->tga_desc_fd->elf.root.u.def.section == stub_sec
+             && htab->tga_desc_fd->elf.root.u.def.value == 0);
+  to = defined_sym_val (&htab->tls_get_addr_fd->elf);
+  from = defined_sym_val (&htab->tga_desc_fd->elf) + cfa_updt;
+  delta = to - from;
+  if (delta + (1 << 25) >= 1 << 26)
+    {
+      _bfd_error_handler (_("__tls_get_addr call offset overflow"));
+      htab->stub_error = TRUE;
+      return FALSE;
+    }
+
+  p = stub_sec->contents;
+  p = tls_get_addr_prologue (htab->elf.dynobj, p, htab);
+  bfd_put_32 (stub_sec->owner, B_DOT | 1 | (delta & 0x3fffffc), p);
+  p += 4;
+  p = tls_get_addr_epilogue (htab->elf.dynobj, p, htab);
+  return stub_sec->size == (bfd_size_type) (p - stub_sec->contents);
+}
+
+/* Emit eh_frame describing the static wrapper function.  */
+
+static bfd_byte *
+emit_tga_desc_eh_frame (struct ppc_link_hash_table *htab, bfd_byte *p)
+{
+  unsigned int cfa_updt = 11 * 4;
+  unsigned int i;
+
+  *p++ = DW_CFA_advance_loc + cfa_updt / 4;
+  *p++ = DW_CFA_def_cfa_offset;
+  if (htab->opd_abi)
+    {
+      *p++ = 128;
+      *p++ = 1;
+    }
+  else
+    *p++ = 96;
+  *p++ = DW_CFA_offset_extended_sf;
+  *p++ = 65;
+  *p++ = (-16 / 8) & 0x7f;
+  for (i = 4; i < 12; i++)
+    {
+      *p++ = DW_CFA_offset + i;
+      *p++ = (htab->opd_abi ? 13 : 12) - i;
+    }
+  *p++ = DW_CFA_advance_loc + 10;
+  *p++ = DW_CFA_def_cfa_offset;
+  *p++ = 0;
+  for (i = 4; i < 12; i++)
+    *p++ = DW_CFA_restore + i;
+  *p++ = DW_CFA_advance_loc + 2;
+  *p++ = DW_CFA_restore_extended;
+  *p++ = 65;
+  return p;
+}
+
 /* Build all the stubs associated with the current output file.
    The stubs are kept in a hash table attached to the main linker
    hash table.  This function is called via gldelf64ppc_finish.  */
@@ -14245,6 +14363,24 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
        }
     }
 
+  if (htab->tga_group != NULL)
+    {
+      htab->tga_group->lr_restore = 23 * 4;
+      htab->tga_group->stub_sec->size = 24 * 4;
+      if (!emit_tga_desc (htab))
+       return FALSE;
+      if (htab->glink_eh_frame != NULL
+         && htab->glink_eh_frame->size != 0)
+       {
+         size_t align = 4;
+
+         p = htab->glink_eh_frame->contents;
+         p += (sizeof (glink_eh_frame_cie) + align - 1) & -align;
+         p += 17;
+         htab->tga_group->eh_size = emit_tga_desc_eh_frame (htab, p) - p;
+       }
+    }
+
   /* Build .glink global entry stubs, and PLT relocs for globals.  */
   elf_link_hash_traverse (&htab->elf, build_global_entry_stubs_and_plt, info);
 
index edfc0903921aba5e465f3726e4be236501b195ac..b196d2167f12311124ab3dab71cd309ae4ca9493 100644 (file)
@@ -1,3 +1,12 @@
+2020-01-22  Alan Modra  <amodra@gmail.com>
+
+       * testsuite/ld-powerpc/tlsdesc3.d,
+       * testsuite/ld-powerpc/tlsdesc3.wf,
+       * testsuite/ld-powerpc/tlsdesc4.d,
+       * testsuite/ld-powerpc/tlsdesc4.s,
+       * testsuite/ld-powerpc/tlsdesc4.wf: New tests.
+       * testsuite/ld-powerpc/powerpc.exp: Run them.
+
 2020-01-22  Alan Modra  <amodra@gmail.com>
 
        * emultempl/ppc64elf.em (ppc64_opt, PARSE_AND_LIST_LONGOPTS),
index d50846c806a32ad8e461c1e737867256fa690b2d..94b2fac6fbe12f3eaf81a9dba3f0e78ad8f1b263 100644 (file)
@@ -280,6 +280,12 @@ set ppc64elftests {
     {"TLSdesc2" "-melf64ppc -shared --hash-style=both --no-plt-localentry tmpdir/tlsdll.so" "" "-a64"  {tlsdesc.s}
      {{objdump -dr tlsdesc2.d} {readelf -wf tlsdesc2.wf}}
      "tlsdesc2"}
+    {"TLSdesc3" "-melf64ppc --no-tls-optimize tmpdir/tlsdll.o" "" "-a64"  {tlsdesc.s}
+     {{objdump -dr tlsdesc3.d} {readelf -wf tlsdesc3.wf}}
+     "tlsdesc3"}
+    {"TLSdesc4" "-melf64ppc --no-tls-optimize tmpdir/tlsdll.o" "" "-a64"  {tlsdesc4.s}
+     {{objdump -dr tlsdesc4.d} {readelf -wf tlsdesc4.wf}}
+     "tlsdesc4"}
     {"sym@tocbase" "-shared -melf64ppc" "" "-a64" {symtocbase-1.s symtocbase-2.s}
        {{objdump -dj.data symtocbase.d}} "symtocbase.so"}
     {"TOC opt" "-melf64ppc" "" "-a64"  {tocopt.s}
diff --git a/ld/testsuite/ld-powerpc/tlsdesc3.d b/ld/testsuite/ld-powerpc/tlsdesc3.d
new file mode 100644 (file)
index 0000000..360dcff
--- /dev/null
@@ -0,0 +1,38 @@
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0+10000100 <__tls_get_addr_desc>:
+.*:    (7c 08 02 a6|a6 02 08 7c)       mflr    r0
+.*:    (f8 01 00 10|10 00 01 f8)       std     r0,16\(r1\)
+.*:    (f8 81 ff c0|c0 ff 81 f8)       std     r4,-64\(r1\)
+.*:    (f8 a1 ff c8|c8 ff a1 f8)       std     r5,-56\(r1\)
+.*:    (f8 c1 ff d0|d0 ff c1 f8)       std     r6,-48\(r1\)
+.*:    (f8 e1 ff d8|d8 ff e1 f8)       std     r7,-40\(r1\)
+.*:    (f9 01 ff e0|e0 ff 01 f9)       std     r8,-32\(r1\)
+.*:    (f9 21 ff e8|e8 ff 21 f9)       std     r9,-24\(r1\)
+.*:    (f9 41 ff f0|f0 ff 41 f9)       std     r10,-16\(r1\)
+.*:    (f9 61 ff f8|f8 ff 61 f9)       std     r11,-8\(r1\)
+.*:    (f8 21 ff a1|a1 ff 21 f8)       stdu    r1,-96\(r1\)
+.*:    (48 00 00 35|35 00 00 48)       bl      .* <__tls_get_addr>
+.*:    (e8 81 00 20|20 00 81 e8)       ld      r4,32\(r1\)
+.*:    (e8 a1 00 28|28 00 a1 e8)       ld      r5,40\(r1\)
+.*:    (e8 c1 00 30|30 00 c1 e8)       ld      r6,48\(r1\)
+.*:    (e8 e1 00 38|38 00 e1 e8)       ld      r7,56\(r1\)
+.*:    (e9 01 00 40|40 00 01 e9)       ld      r8,64\(r1\)
+.*:    (e9 21 00 48|48 00 21 e9)       ld      r9,72\(r1\)
+.*:    (e9 41 00 50|50 00 41 e9)       ld      r10,80\(r1\)
+.*:    (e9 61 00 58|58 00 61 e9)       ld      r11,88\(r1\)
+.*:    (38 21 00 60|60 00 21 38)       addi    r1,r1,96
+.*:    (e8 01 00 10|10 00 01 e8)       ld      r0,16\(r1\)
+.*:    (7c 08 03 a6|a6 03 08 7c)       mtlr    r0
+.*:    (4e 80 00 20|20 00 80 4e)       blr
+
+0+10000160 <__tls_get_addr>:
+.*:    (4e 80 00 20|20 00 80 4e)       blr
+
+0+10000164 <_start>:
+.*:    (38 62 80 08|08 80 62 38)       addi    r3,r2,-32760
+.*:    (4b ff ff 99|99 ff ff 4b)       bl      .* <__tls_get_addr_desc>
+.*:    (60 00 00 00|00 00 00 60)       nop
diff --git a/ld/testsuite/ld-powerpc/tlsdesc3.wf b/ld/testsuite/ld-powerpc/tlsdesc3.wf
new file mode 100644 (file)
index 0000000..af5a6b4
--- /dev/null
@@ -0,0 +1,43 @@
+Contents of the \.eh_frame section:
+
+0+ 0+10 0+ CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 4
+  Data alignment factor: -8
+  Return address column: 65
+  Augmentation data:     1b
+  DW_CFA_def_cfa: r1 ofs 0
+
+0+14 0+34 0+18 FDE cie=0+ pc=0+10000100\.\.0+10000160
+  DW_CFA_advance_loc: 44 to 0+1000012c
+  DW_CFA_def_cfa_offset: 96
+  DW_CFA_offset_extended_sf: r65 at cfa\+16
+  DW_CFA_offset: r4 at cfa-64
+  DW_CFA_offset: r5 at cfa-56
+  DW_CFA_offset: r6 at cfa-48
+  DW_CFA_offset: r7 at cfa-40
+  DW_CFA_offset: r8 at cfa-32
+  DW_CFA_offset: r9 at cfa-24
+  DW_CFA_offset: r10 at cfa-16
+  DW_CFA_offset: r11 at cfa-8
+  DW_CFA_advance_loc: 40 to 0+10000154
+  DW_CFA_def_cfa_offset: 0
+  DW_CFA_restore: r4
+  DW_CFA_restore: r5
+  DW_CFA_restore: r6
+  DW_CFA_restore: r7
+  DW_CFA_restore: r8
+  DW_CFA_restore: r9
+  DW_CFA_restore: r10
+  DW_CFA_restore: r11
+  DW_CFA_advance_loc: 8 to 0+1000015c
+  DW_CFA_restore_extended: r65
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+4c 0+10 0+50 FDE cie=0+ pc=0+10000164\.\.0+10000170
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
diff --git a/ld/testsuite/ld-powerpc/tlsdesc4.d b/ld/testsuite/ld-powerpc/tlsdesc4.d
new file mode 100644 (file)
index 0000000..eb162bb
--- /dev/null
@@ -0,0 +1,46 @@
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0+10000100 <__tls_get_addr_desc>:
+.*:    (7c 08 02 a6|a6 02 08 7c)       mflr    r0
+.*:    (f8 01 00 10|10 00 01 f8)       std     r0,16\(r1\)
+.*:    (f8 81 ff c0|c0 ff 81 f8)       std     r4,-64\(r1\)
+.*:    (f8 a1 ff c8|c8 ff a1 f8)       std     r5,-56\(r1\)
+.*:    (f8 c1 ff d0|d0 ff c1 f8)       std     r6,-48\(r1\)
+.*:    (f8 e1 ff d8|d8 ff e1 f8)       std     r7,-40\(r1\)
+.*:    (f9 01 ff e0|e0 ff 01 f9)       std     r8,-32\(r1\)
+.*:    (f9 21 ff e8|e8 ff 21 f9)       std     r9,-24\(r1\)
+.*:    (f9 41 ff f0|f0 ff 41 f9)       std     r10,-16\(r1\)
+.*:    (f9 61 ff f8|f8 ff 61 f9)       std     r11,-8\(r1\)
+.*:    (f8 21 ff a1|a1 ff 21 f8)       stdu    r1,-96\(r1\)
+.*:    (48 00 00 35|35 00 00 48)       bl      .* <__tls_get_addr>
+.*:    (e8 81 00 20|20 00 81 e8)       ld      r4,32\(r1\)
+.*:    (e8 a1 00 28|28 00 a1 e8)       ld      r5,40\(r1\)
+.*:    (e8 c1 00 30|30 00 c1 e8)       ld      r6,48\(r1\)
+.*:    (e8 e1 00 38|38 00 e1 e8)       ld      r7,56\(r1\)
+.*:    (e9 01 00 40|40 00 01 e9)       ld      r8,64\(r1\)
+.*:    (e9 21 00 48|48 00 21 e9)       ld      r9,72\(r1\)
+.*:    (e9 41 00 50|50 00 41 e9)       ld      r10,80\(r1\)
+.*:    (e9 61 00 58|58 00 61 e9)       ld      r11,88\(r1\)
+.*:    (38 21 00 60|60 00 21 38)       addi    r1,r1,96
+.*:    (e8 01 00 10|10 00 01 e8)       ld      r0,16\(r1\)
+.*:    (7c 08 03 a6|a6 03 08 7c)       mtlr    r0
+.*:    (4e 80 00 20|20 00 80 4e)       blr
+
+0+10000160 <__tls_get_addr>:
+.*:    (4e 80 00 20|20 00 80 4e)       blr
+
+0+10000164 <_start>:
+.*:    (38 62 80 08|08 80 62 38)       addi    r3,r2,-32760
+.*:    (4b ff ff 99|99 ff ff 4b)       bl      .* <__tls_get_addr_desc>
+.*:    (60 00 00 00|00 00 00 60)       nop
+       \.\.\.
+
+0+12000100 <.*\.long_branch\.__tls_get_addr_desc>:
+.*:    (4a 00 00 00|00 00 00 4a)       b       .* <__tls_get_addr_desc>
+       \.\.\.
+.*:    (38 62 80 08|08 80 62 38)       addi    r3,r2,-32760
+.*:    (4b ff ff dd|dd ff ff 4b)       bl      .* <.*\.long_branch\.__tls_get_addr_desc>
+.*:    (60 00 00 00|00 00 00 60)       nop
diff --git a/ld/testsuite/ld-powerpc/tlsdesc4.s b/ld/testsuite/ld-powerpc/tlsdesc4.s
new file mode 100644 (file)
index 0000000..6dc3082
--- /dev/null
@@ -0,0 +1,18 @@
+ .text
+ .globl _start
+_start:
+ .cfi_startproc
+ addi 3,2,gd@got@tlsgd
+ bl __tls_get_addr_desc(gd@tlsgd)
+ nop
+ .cfi_endproc
+
+ .section .text.pad1,"ax"
+ .space 0x1ffff90
+
+ .section .text.far,"ax"
+ .cfi_startproc
+ addi 3,2,gd@got@tlsgd
+ bl __tls_get_addr_desc(gd@tlsgd)
+ nop
+ .cfi_endproc
diff --git a/ld/testsuite/ld-powerpc/tlsdesc4.wf b/ld/testsuite/ld-powerpc/tlsdesc4.wf
new file mode 100644 (file)
index 0000000..8d24979
--- /dev/null
@@ -0,0 +1,49 @@
+Contents of the \.eh_frame section:
+
+0+ 0+10 0+ CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 4
+  Data alignment factor: -8
+  Return address column: 65
+  Augmentation data:     1b
+  DW_CFA_def_cfa: r1 ofs 0
+
+0+14 0+34 0+18 FDE cie=0+ pc=0+10000100..0+10000160
+  DW_CFA_advance_loc: 44 to 0+1000012c
+  DW_CFA_def_cfa_offset: 96
+  DW_CFA_offset_extended_sf: r65 at cfa\+16
+  DW_CFA_offset: r4 at cfa-64
+  DW_CFA_offset: r5 at cfa-56
+  DW_CFA_offset: r6 at cfa-48
+  DW_CFA_offset: r7 at cfa-40
+  DW_CFA_offset: r8 at cfa-32
+  DW_CFA_offset: r9 at cfa-24
+  DW_CFA_offset: r10 at cfa-16
+  DW_CFA_offset: r11 at cfa-8
+  DW_CFA_advance_loc: 40 to 0+10000154
+  DW_CFA_def_cfa_offset: 0
+  DW_CFA_restore: r4
+  DW_CFA_restore: r5
+  DW_CFA_restore: r6
+  DW_CFA_restore: r7
+  DW_CFA_restore: r8
+  DW_CFA_restore: r9
+  DW_CFA_restore: r10
+  DW_CFA_restore: r11
+  DW_CFA_advance_loc: 8 to 0+1000015c
+  DW_CFA_restore_extended: r65
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+4c 0+10 0+50 FDE cie=0+ pc=0+10000164..0+10000170
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+60 0+10 0+64 FDE cie=0+ pc=0+12000120..0+1200012c
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+