/* dwarf.c -- display DWARF contents of a BFD binary file
- Copyright (C) 2005-2015 Free Software Foundation, Inc.
+ Copyright (C) 2005-2016 Free Software Foundation, Inc.
This file is part of GNU Binutils.
*length_return = num_read;
if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
- result |= (dwarf_vma) -1 << shift;
+ result |= -((dwarf_vma) 1 << shift);
return result;
}
#define SAFE_BYTE_GET(VAL, PTR, AMOUNT, END) \
do \
{ \
- int dummy [sizeof (VAL) < (AMOUNT) ? -1 : 1] ATTRIBUTE_UNUSED ; \
unsigned int amount = (AMOUNT); \
+ if (sizeof (VAL) < amount) \
+ { \
+ error (_("internal error: attempt to read %d bytes of data in to %d sized variable"),\
+ amount, (int) sizeof (VAL)); \
+ amount = sizeof (VAL); \
+ } \
if (((PTR) + amount) >= (END)) \
{ \
if ((PTR) < (END)) \
return 1;
}
+/* Return true when ADDR is the maximum address, when addresses are
+ POINTER_SIZE bytes long. */
+
+static bfd_boolean
+is_max_address (dwarf_vma addr, unsigned int pointer_size)
+{
+ dwarf_vma mask = ~(~(dwarf_vma) 1 << (pointer_size * 8 - 1));
+ return ((addr & mask) == mask);
+}
+
/* Display a location list from a normal (ie, non-dwo) .debug_loc section. */
static void
printf (" %8.8lx ", off);
- /* Note: we use sign extension here in order to be sure that we can detect
- the -1 escape value. Sign extension into the top 32 bits of a 32-bit
- address will not affect the values that we display since we always show
- hex values, and always the bottom 32-bits. */
SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, section_end);
SAFE_BYTE_GET_AND_INC (end, start, pointer_size, section_end);
}
/* Check base address specifiers. */
- if (begin == (dwarf_vma) -1 && end != (dwarf_vma) -1)
+ if (is_max_address (begin, pointer_size)
+ && !is_max_address (end, pointer_size))
{
base_address = end;
print_dwarf_vma (begin, pointer_size);
if (arange.ar_version != 2 && arange.ar_version != 3)
{
- warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
+ /* PR 19872: A version number of 0 probably means that there is
+ padding at the end of the .debug_aranges section. Gold puts
+ it there when performing an incremental link, for example.
+ So do not generate a warning in this case. */
+ if (arange.ar_version)
+ warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
break;
}
dwarf_vma begin;
dwarf_vma end;
- /* Note: we use sign extension here in order to be sure that
- we can detect the -1 escape value. Sign extension into the
- top 32 bits of a 32-bit address will not affect the values
- that we display since we always show hex values, and always
- the bottom 32-bits. */
SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, finish);
if (start >= finish)
break;
}
/* Check base address specifiers. */
- if (begin == (dwarf_vma) -1 && end != (dwarf_vma) -1)
+ if (is_max_address (begin, pointer_size)
+ && !is_max_address (end, pointer_size))
{
base_address = end;
print_dwarf_vma (begin, pointer_size);
dwarf_regnames_count = ARRAY_SIZE (dwarf_regnames_aarch64);
}
+static const char *const dwarf_regnames_s390[] =
+{
+ /* Avoid saying "r5 (r5)", so omit the names of r0-r15. */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "f0", "f2", "f4", "f6", "f1", "f3", "f5", "f7",
+ "f8", "f10", "f12", "f14", "f9", "f11", "f13", "f15",
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
+ "cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14", "cr15",
+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
+ "a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15",
+ "pswm", "pswa",
+ NULL, NULL,
+ "v16", "v18", "v20", "v22", "v17", "v19", "v21", "v23",
+ "v24", "v26", "v28", "v30", "v25", "v27", "v29", "v31",
+};
+
+void
+init_dwarf_regnames_s390 (void)
+{
+ dwarf_regnames = dwarf_regnames_s390;
+ dwarf_regnames_count = ARRAY_SIZE (dwarf_regnames_s390);
+}
+
void
init_dwarf_regnames (unsigned int e_machine)
{
init_dwarf_regnames_aarch64 ();
break;
+ case EM_S390:
+ init_dwarf_regnames_s390 ();
+ break;
+
default:
break;
}
unsigned int encoded_ptr_size = saved_eh_addr_size;
unsigned int offset_size;
unsigned int initial_length_size;
+ bfd_boolean all_nops;
saved_start = start;
start = tmp;
}
+ all_nops = TRUE;
+
/* Now we know what registers are used, make a second pass over
the chunk, this time actually printing out the info. */
if (op & 0xc0)
op &= 0xc0;
+ /* Make a note if something other than DW_CFA_nop happens. */
+ if (op != DW_CFA_nop)
+ all_nops = FALSE;
+
/* Warning: if you add any more cases to this switch, be
sure to add them to the corresponding switch above. */
switch (op)
case DW_CFA_def_cfa_expression:
ul = LEB ();
- if (start >= block_end || start + ul > block_end || start + ul < start)
+ if (start >= block_end || ul > (unsigned long) (block_end - start))
{
printf (_(" DW_CFA_def_cfa_expression: <corrupt len %lu>\n"), ul);
break;
}
}
- if (do_debug_frames_interp)
+ /* Interpret the CFA - as long as it is not completely full of NOPs. */
+ if (do_debug_frames_interp && ! all_nops)
frame_display_row (fc, &need_col_headers, &max_regs);
start = block_end;