print_debug_sections |= section_aranges;
else if (strcmp (arg, "ranges") == 0)
print_debug_sections |= section_ranges;
- else if (strcmp (arg, "frame") == 0)
+ else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
print_debug_sections |= section_frame;
else if (strcmp (arg, "info") == 0)
print_debug_sections |= section_info;
{
char *a = format_dwarf_addr (dwflmod, 0, addr);
printf ("%*s[%4" PRIuMAX "] %s %s\n",
- indent, "", (uintmax_t) offset,
- known[op] ?: "???", a);
+ indent, "", (uintmax_t) offset, known[op], a);
free (a);
}
else
printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
indent, "", (uintmax_t) offset,
- known[op] ?: "???", (uintmax_t) addr);
+ known[op], (uintmax_t) addr);
offset += 1 + addrsize;
break;
case DW_OP_xderef_size:
case DW_OP_pick:
case DW_OP_const1u:
+ // XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
indent, "", (uintmax_t) offset,
- known[op] ?: "???", *((uint8_t *) data));
+ known[op], *((uint8_t *) data));
++data;
--len;
offset += 2;
break;
case DW_OP_const2u:
+ // XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
indent, "", (uintmax_t) offset,
- known[op] ?: "???", read_2ubyte_unaligned (dbg, data));
+ known[op], read_2ubyte_unaligned (dbg, data));
len -= 2;
data += 2;
offset += 3;
break;
case DW_OP_const4u:
+ // XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
indent, "", (uintmax_t) offset,
- known[op] ?: "???", read_4ubyte_unaligned (dbg, data));
+ known[op], read_4ubyte_unaligned (dbg, data));
len -= 4;
data += 4;
offset += 5;
break;
case DW_OP_const8u:
+ // XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
indent, "", (uintmax_t) offset,
- known[op] ?: "???", read_8ubyte_unaligned (dbg, data));
+ known[op], read_8ubyte_unaligned (dbg, data));
len -= 8;
data += 8;
offset += 9;
break;
case DW_OP_const1s:
+ // XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
indent, "", (uintmax_t) offset,
- known[op] ?: "???", *((int8_t *) data));
+ known[op], *((int8_t *) data));
++data;
--len;
offset += 2;
break;
case DW_OP_const2s:
+ // XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
indent, "", (uintmax_t) offset,
- known[op] ?: "???", read_2sbyte_unaligned (dbg, data));
+ known[op], read_2sbyte_unaligned (dbg, data));
len -= 2;
data += 2;
offset += 3;
break;
case DW_OP_const4s:
+ // XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
indent, "", (uintmax_t) offset,
- known[op] ?: "???", read_4sbyte_unaligned (dbg, data));
+ known[op], read_4sbyte_unaligned (dbg, data));
len -= 4;
data += 4;
offset += 5;
break;
case DW_OP_const8s:
+ // XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
indent, "", (uintmax_t) offset,
- known[op] ?: "???", read_8sbyte_unaligned (dbg, data));
+ known[op], read_8sbyte_unaligned (dbg, data));
len -= 8;
data += 8;
offset += 9;
unsigned int uleb;
get_uleb128 (uleb, data);
printf ("%*s[%4" PRIuMAX "] %s %u\n",
- indent, "", (uintmax_t) offset,
- known[op] ?: "???", uleb);
+ indent, "", (uintmax_t) offset, known[op], uleb);
len -= data - start;
offset += 1 + (data - start);
break;
get_uleb128 (uleb, data);
get_uleb128 (uleb2, data);
printf ("%*s[%4" PRIuMAX "] %s %u, %u\n",
- indent, "", (uintmax_t) offset,
- known[op] ?: "???", uleb, uleb2);
+ indent, "", (uintmax_t) offset, known[op], uleb, uleb2);
len -= data - start;
offset += 1 + (data - start);
break;
unsigned int sleb;
get_sleb128 (sleb, data);
printf ("%*s[%4" PRIuMAX "] %s %d\n",
- indent, "", (uintmax_t) offset,
- known[op] ?: "???", sleb);
+ indent, "", (uintmax_t) offset, known[op], sleb);
len -= data - start;
offset += 1 + (data - start);
break;
get_uleb128 (uleb, data);
get_sleb128 (sleb, data);
printf ("%*s[%4" PRIuMAX "] %s %u %d\n",
- indent, "", (uintmax_t) offset,
- known[op] ?: "???", uleb, sleb);
+ indent, "", (uintmax_t) offset, known[op], uleb, sleb);
len -= data - start;
offset += 1 + (data - start);
break;
case DW_OP_skip:
case DW_OP_bra:
printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
- indent, "", (uintmax_t) offset,
- known[op] ?: "???",
+ indent, "", (uintmax_t) offset, known[op],
(uintmax_t) (offset + read_2sbyte_unaligned (dbg, data)));
len -= 2;
data += 2;
static void
-print_debug_frame_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
- Ebl *ebl __attribute__ ((unused)),
- GElf_Ehdr *ehdr __attribute__ ((unused)),
- Elf_Scn *scn __attribute__ ((unused)),
- GElf_Shdr *shdr __attribute__ ((unused)),
- Dwarf *dbg __attribute__ ((unused)))
+print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
+ Dwarf_Word vma_base, unsigned int code_align,
+ int data_align, unsigned int ptr_size, Dwfl_Module *dwflmod,
+ Ebl *ebl, Dwarf *dbg)
{
+ char regnamebuf[16];
+ const char *regname (unsigned int regno)
+ {
+ const char *str;
+ int i;
+ return (ebl_register_info (ebl, regno, regnamebuf, sizeof (regnamebuf),
+ &str, &str, &i, &i) < 0
+ ? "???" : regnamebuf);
+ }
+
+ puts ("\n Program:");
+ Dwarf_Word pc = vma_base;
+ while (readp < endp)
+ {
+ unsigned int opcode = *readp++;
+
+ if (opcode < DW_CFA_advance_loc)
+ /* Extended opcode. */
+ switch (opcode)
+ {
+ uint64_t op1;
+ int64_t sop1;
+ uint64_t op2;
+ int64_t sop2;
+
+ case DW_CFA_nop:
+ puts (" nop");
+ break;
+ case DW_CFA_set_loc:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ op1 += vma_base;
+ printf (" set_loc %" PRIu64 "\n", op1 * code_align);
+ break;
+ case DW_CFA_advance_loc1:
+ printf (" advance_loc1 %u to %#" PRIx64 "\n",
+ *readp, pc += *readp * code_align);
+ ++readp;
+ break;
+ case DW_CFA_advance_loc2:
+ op1 = read_2ubyte_unaligned_inc (dbg, readp);
+ printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
+ op1, pc += op1 * code_align);
+ break;
+ case DW_CFA_advance_loc4:
+ op1 = read_4ubyte_unaligned_inc (dbg, readp);
+ printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
+ op1, pc += op1 * code_align);
+ break;
+ case DW_CFA_offset_extended:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ get_uleb128 (op2, readp);
+ printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
+ "\n",
+ op1, regname (op1), op2 * data_align);
+ break;
+ case DW_CFA_restore_extended:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ printf (" restore_extended r%" PRIu64 " (%s)\n",
+ op1, regname (op1));
+ break;
+ case DW_CFA_undefined:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
+ break;
+ case DW_CFA_same_value:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
+ break;
+ case DW_CFA_register:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ get_uleb128 (op2, readp);
+ printf (" same_value r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
+ op1, regname (op1), op2, regname (op2));
+ break;
+ case DW_CFA_remember_state:
+ puts (" remember_state");
+ break;
+ case DW_CFA_restore_state:
+ puts (" restore_state");
+ break;
+ case DW_CFA_def_cfa:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ get_uleb128 (op2, readp);
+ printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
+ op1, regname (op1), op2);
+ break;
+ case DW_CFA_def_cfa_register:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ printf (" def_cfa_register r%" PRIu64 " (%s)\n",
+ op1, regname (op1));
+ break;
+ case DW_CFA_def_cfa_offset:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ printf (" def_cfa_offset %" PRIu64 "\n", op1);
+ break;
+ case DW_CFA_def_cfa_expression:
+ // XXX overflow check
+ get_uleb128 (op1, readp); /* Length of DW_FORM_block. */
+ printf (" val_expression %" PRIu64 "\n", op1);
+ print_ops (dwflmod, dbg, 10, 10, ptr_size, op1, readp);
+ readp += op1;
+ error (1,0,"need to implement BLOCK reading");
+ break;
+ case DW_CFA_expression:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
+ printf (" val_expression %" PRIu64 "\n", op1);
+ print_ops (dwflmod, dbg, 10, 10, ptr_size, op2, readp);
+ readp += op2;
+ break;
+ case DW_CFA_offset_extended_sf:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ get_sleb128 (sop2, readp);
+ printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
+ PRId64 "\n",
+ op1, regname (op1), sop2 * data_align);
+ break;
+ case DW_CFA_def_cfa_sf:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ get_sleb128 (sop2, readp);
+ printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
+ op1, regname (op1), sop2 * data_align);
+ break;
+ case DW_CFA_def_cfa_offset_sf:
+ // XXX overflow check
+ get_sleb128 (sop1, readp);
+ printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
+ break;
+ case DW_CFA_val_offset:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ get_uleb128 (op2, readp);
+ printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
+ op1, op2 * data_align);
+ break;
+ case DW_CFA_val_offset_sf:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ get_sleb128 (sop2, readp);
+ printf (" val_offset %" PRIu64 " at offset %" PRId64 "\n",
+ op1, sop2 * data_align);
+ break;
+ case DW_CFA_val_expression:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
+ printf (" val_expression %" PRIu64 "\n", op1);
+ print_ops (dwflmod, dbg, 10, 10, ptr_size, op2, readp);
+ readp += op2;
+ break;
+ case DW_CFA_MIPS_advance_loc8:
+ op1 = read_8ubyte_unaligned_inc (dbg, readp);
+ printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
+ op1, pc += op1 * code_align);
+ break;
+ case DW_CFA_GNU_window_save:
+ puts (" window_save");
+ break;
+ case DW_CFA_GNU_args_size:
+ // XXX overflow check
+ get_uleb128 (op1, readp);
+ printf (" args_size %" PRIu64 "\n", op1);
+ break;
+ default:
+ printf (" ??? (%u)\n", opcode);
+ break;
+ }
+ else if (opcode < DW_CFA_offset)
+ printf (" advance_loc %u to %#" PRIx64 "\n",
+ opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
+ else if (opcode < DW_CFA_restore)
+ {
+ unsigned int offset;
+ // XXX overflow check
+ get_uleb128 (offset, readp);
+ printf (" offset r%u (%s) at cfa%+d\n",
+ opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
+ }
+ else
+ printf (" restore r%u (%s)\n",
+ opcode & 0x3f, regname (opcode & 0x3f));
+ }
+}
+
+
+static unsigned int
+encoded_ptr_size (int encoding, unsigned int ptr_size)
+{
+ switch (encoding & 7)
+ {
+ case 2:
+ return 2;
+ case 3:
+ return 4;
+ case 4:
+ return 8;
+ default:
+ return ptr_size;
+ }
+}
+
+
+static void
+print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
+ Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+ size_t shstrndx;
+ /* We know this call will succeed since it did in the caller. */
+ (void) elf_getshstrndx (ebl->elf, &shstrndx);
+ const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
+
+ Elf_Data *data = elf_rawdata (scn, NULL);
+
+ if (unlikely (data == NULL))
+ {
+ error (0, 0, gettext ("cannot get %s content: %s"),
+ scnname, elf_errmsg (-1));
+ return;
+ }
+
+ printf (gettext ("\
+\nDWARF section '%s' at offset %#" PRIx64 ":\n"),
+ scnname, (uint64_t) shdr->sh_offset);
+
+ struct cieinfo
+ {
+ ptrdiff_t cie_offset;
+ const char *augmentation;
+ unsigned int code_alignment_factor;
+ unsigned int data_alignment_factor;
+ unsigned int fde_encoding;
+ struct cieinfo *next;
+ } *cies = NULL;
+
+ const unsigned char *readp = data->d_buf;
+ const unsigned char *const dataend = ((unsigned char *) data->d_buf
+ + data->d_size);
+ bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
+ while (readp < dataend)
+ {
+ /* At the beginning there must be a CIE. There can be multiple,
+ hence we test tis in a loop. */
+ ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
+
+ if (unlikely (readp + 12 > dataend))
+ {
+ invalid_data:
+ error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
+ elf_ndxscn (scn), scnname);
+ return;
+ }
+
+ unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+
+ Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
+ unsigned int length = 4;
+ if (unlikely (unit_length == 0xffffffff))
+ {
+ unit_length = read_8ubyte_unaligned_inc (dbg, readp);
+ length = 8;
+
+ if (unlikely (readp + 12 > dataend))
+ goto invalid_data;
+ }
+ ptrdiff_t start = readp - (unsigned char *) data->d_buf;
+ const unsigned char *const cieend = readp + unit_length;
+ if (unlikely (cieend > dataend))
+ goto invalid_data;
+
+ Dwarf_Word cie_id;
+ if (length == 4)
+ cie_id = read_4ubyte_unaligned_inc (dbg, readp);
+ else
+ cie_id = read_8ubyte_unaligned_inc (dbg, readp);
+
+ unsigned int code_alignment_factor;
+ int data_alignment_factor;
+ unsigned int fde_encoding = 0;
+ Dwarf_Word initial_location = 0;
+
+ if ((is_eh_frame && cie_id == 0)
+ || (! is_eh_frame && cie_id == DW_CIE_ID))
+ {
+ uint_fast8_t version = *readp++;
+ const char *const augmentation = (const char *) readp;
+ readp = memchr (readp, '\0', cieend - readp);
+ if (unlikely (readp == NULL))
+ goto invalid_data;
+ ++readp;
+ // XXX Check overflow
+ get_uleb128 (code_alignment_factor, readp);
+ // XXX Check overflow
+ get_sleb128 (data_alignment_factor, readp);
+
+ /* In some variant for unwind data there is another field. */
+ if (strcmp (augmentation, "eh") == 0)
+ readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+
+ unsigned int return_address_register;
+ if (unlikely (version == 1))
+ return_address_register = *readp++;
+ else
+ // XXX Check overflow
+ get_uleb128 (return_address_register, readp);
+
+ printf (" [%6jx] CIE length=%" PRIu64 "\n"
+ " CIE_id: %" PRIu64 "\n"
+ " version: %u\n"
+ " augmentation: \"%s\"\n"
+ " code_alignment_factor: %u\n"
+ " data_alignment_factor: %d\n"
+ " return_address_register: %u\n",
+ offset, (uint64_t) unit_length, (uint64_t) cie_id,
+ version, augmentation, code_alignment_factor,
+ data_alignment_factor, return_address_register);
+
+ if (augmentation[0] == 'z')
+ {
+ unsigned int print_encoding (unsigned int val)
+ {
+ switch (val & 0xf)
+ {
+ case DW_EH_PE_absptr:
+ fputs ("absptr", stdout);
+ break;
+ case DW_EH_PE_uleb128:
+ fputs ("uleb128", stdout);
+ break;
+ case DW_EH_PE_udata2:
+ fputs ("udata2", stdout);
+ break;
+ case DW_EH_PE_udata4:
+ fputs ("udata4", stdout);
+ break;
+ case DW_EH_PE_udata8:
+ fputs ("udata8", stdout);
+ break;
+ case DW_EH_PE_sleb128:
+ fputs ("sleb128", stdout);
+ break;
+ case DW_EH_PE_sdata2:
+ fputs ("sdata2", stdout);
+ break;
+ case DW_EH_PE_sdata4:
+ fputs ("sdata4", stdout);
+ break;
+ case DW_EH_PE_sdata8:
+ fputs ("sdata8", stdout);
+ break;
+ default:
+ /* We did not use any of the bits after all. */
+ return val;
+ }
+
+ return val & ~0xf;
+ }
+
+ unsigned int print_relinfo (unsigned int val)
+ {
+ switch (val & 0x70)
+ {
+ case DW_EH_PE_pcrel:
+ fputs ("pcrel", stdout);
+ break;
+ case DW_EH_PE_textrel:
+ fputs ("textrel", stdout);
+ break;
+ case DW_EH_PE_datarel:
+ fputs ("datarel", stdout);
+ break;
+ case DW_EH_PE_funcrel:
+ fputs ("funcrel", stdout);
+ break;
+ case DW_EH_PE_aligned:
+ fputs ("aligned", stdout);
+ break;
+ default:
+ return val;
+ }
+
+ return val & ~0x70;
+ }
+
+ unsigned int augmentationlen;
+ get_uleb128 (augmentationlen, readp);
+
+ const char *hdr = "Augmentation data:";
+ const char *cp = augmentation + 1;
+ while (*cp != '\0')
+ {
+ printf (" %-26s%#x ", hdr, *readp);
+ hdr = "";
+
+ if (*cp == 'R')
+ {
+ putchar_unlocked ('(');
+
+ unsigned int w = fde_encoding = *readp++;
+
+ if (w & 0xf)
+ w = print_encoding (w);
+
+ if (w & 0x70)
+ {
+ if (w != fde_encoding)
+ fputc_unlocked (' ', stdout);
+
+ w = print_relinfo (w);
+ }
+
+ if (w != 0)
+ printf ("(%s%x", w != fde_encoding ? " " : "", w);
+
+ puts (")");
+ }
+ else if (*cp == 'P')
+ {
+ const unsigned char *startp = readp;
+ unsigned int encoding = *readp++;
+ uint64_t val = 0;
+ int64_t sval = 0;
+ bool is_signed;
+
+ switch (encoding & 0xf)
+ {
+ case DW_EH_PE_uleb128:
+ get_uleb128 (val, readp);
+ is_signed = false;
+ break;
+ case DW_EH_PE_sleb128:
+ get_sleb128 (sval, readp);
+ is_signed = true;
+ break;
+ case DW_EH_PE_udata2:
+ val = read_2ubyte_unaligned_inc (dbg, readp);
+ is_signed = false;
+ break;
+ case DW_EH_PE_udata4:
+ val = read_4ubyte_unaligned_inc (dbg, readp);
+ is_signed = false;
+ break;
+ case DW_EH_PE_udata8:
+ val = read_8ubyte_unaligned_inc (dbg, readp);
+ is_signed = false;
+ break;
+ case DW_EH_PE_sdata2:
+ val = read_2sbyte_unaligned_inc (dbg, readp);
+ is_signed = true;
+ break;
+ case DW_EH_PE_sdata4:
+ val = read_4sbyte_unaligned_inc (dbg, readp);
+ is_signed = true;
+ break;
+ case DW_EH_PE_sdata8:
+ val = read_8sbyte_unaligned_inc (dbg, readp);
+ is_signed = true;
+ break;
+ default:
+ error (1, 0,
+ gettext ("invalid augmentation encoding"));
+ }
+
+ while (++startp < readp)
+ printf ("%#x ", *startp);
+
+ if (is_signed)
+ printf ("(%" PRId64 ")\n", sval);
+ else
+ printf ("(%" PRIu64 ")\n", val);
+ }
+ else
+ printf ("(%x)\n", *readp++);
+
+ ++cp;
+ }
+ readp += augmentationlen;
+ }
+
+ struct cieinfo *newp = alloca (sizeof (*newp));
+ newp->cie_offset = offset;
+ newp->augmentation = augmentation;
+ newp->fde_encoding = fde_encoding;
+ newp->code_alignment_factor = code_alignment_factor;
+ newp->data_alignment_factor = data_alignment_factor;
+ newp->next = cies;
+ cies = newp;
+ }
+ else
+ {
+ struct cieinfo *cie = cies;
+ while (cie != NULL)
+ if (start - (ptrdiff_t) cie_id == cie->cie_offset)
+ break;
+ else
+ cie = cie->next;
+ if (unlikely (cie == NULL))
+ {
+ puts ("invalid CIE reference in FDE");
+ return;
+ }
+
+ /* Initialize from CIE data. */
+ ptr_size = encoded_ptr_size (cie->fde_encoding, ptr_size);
+ code_alignment_factor = cie->code_alignment_factor;
+ data_alignment_factor = cie->data_alignment_factor;
+ fde_encoding = cie->fde_encoding;
+
+ initial_location = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
+ Dwarf_Word address_range
+ = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
+
+ printf ("\n [%6jx] FDE length=%" PRIu64 " cie=[%6jx]\n"
+ " CIE_pointer: %" PRIu64 "\n"
+ " initial_location: %#" PRIx64 "\n"
+ " address_range: %#" PRIx64 "\n",
+ offset, (uint64_t) unit_length,
+ cie->cie_offset, (uint64_t) cie_id,
+ (uint64_t) initial_location, (uint64_t) address_range);
+
+ if (cie->augmentation[0] == 'z')
+ {
+ unsigned int augmentationlen;
+ get_uleb128 (augmentationlen, readp);
+
+ const char *hdr = "Augmentation data:";
+ const char *cp = cie->augmentation + 1;
+ for (unsigned int u = 0; u < augmentationlen; ++cp, ++u)
+ {
+ printf (" %-26s%#x (", hdr, readp[u]);
+ hdr = "";
+ }
+ }
+ }
+
+ /* To print correct addresses compute the base address. */
+ Dwarf_Word vma_base;
+ if ((fde_encoding & 0x70) == DW_EH_PE_pcrel && ehdr->e_type != ET_REL)
+ vma_base = shdr->sh_addr + initial_location;
+ else
+ vma_base = 0;
+
+ /* Handle the initialization instructions. */
+ print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
+ data_alignment_factor, ptr_size, dwflmod, ebl, dbg);
+ readp = cieend;
+ }
}