This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: binutils pr 17531 for 2.25?


Hi Matthias, Hi Tristan,

I still see a lot of changes for 17531 in the bug report and on the trunk.

Patches for 17531 and 17512 have now gone in to the dwarf.c and dwarf.h sources.

Cheers
  Nick

binutils/ChangeLog
2015-03-24  Nick Clifton  <nickc@redhat.com>

	Apply from master:
	2015-02-26  Nick Clifton  <nickc@redhat.com>

	PR binutils/17512
	* dwarf.c (display_debug_loc): Pacify the undefined behaviour
	sanitizer by simplifying address difference calculation.
	(struct Frame_Chunk): Change type of cfa_offset to dwarf_vma in
	order to avoid arithmetic overflows.
	(frame_display_row): Cast cfa_offset before printing it.
	(display_debug_frames): Likewise.
	Check for an unexpected segment size.
	Chnage type of 'l' local to dwarf_vma and cast it back to an int
	when printing.
	(process_cu_tu_index): Tighten check for an invalid ncols value.
	* readelf.c (process_corefile_note_segment): Check for
	inote.descdata extending beyond the end of the section.
	(process_v850_notes): Likewise.

	2015-02-13  Nick Clifton  <nickc@redhat.com>

	PR binutils/17512
	* dwarf.c (read_leb128): Fix test for shift becoming too large.

	PR binutils/17531
	* dwarf.c (display_debug_aranges): Add check for an excessive
	ar_length value.
	(process_cu_tu_index): Check for a row * columns sum being too
	large.

	2015-02-13  Alan Modra  <amodra@gmail.com>

	* dwarf.c: Formatting, whitespace.
	(process_debug_info): Style fix.

	2015-02-11  Nick Clifton  <nickc@redhat.com>

	PR binutils/17531
	* dwarf.c (display_debug_pubnames_worker): Work around compiler
	bug checking address ranges.
	(display_debug_frames): Likewise.
	(display_gdb_index): Likewise.
	(process_cu_tu_index): Add range check on the ncols value.

	2015-02-10  Nick Clifton  <nickc@redhat.com>

	PR binutils/17512
	* dwarf.c (eh_addr_size): Use an unsigned type.
	(size_of_encoded_value): Return an unsigned type.
	(read_leb128): Break if the shift becomes too big.
	(process_extended_line_op): Do not read the address if the length
	is too long.
	(read_cie): Warn and fail if the pointer size or segment size are
	too big.
	* dwarf.h (DWARF2_External_LineInfo): Delete unused and incorrect
	structure definition.
	(DWARF2_External_PubNames): Likewise.
	(DWARF2_External_CompUnit): Likewise.
	(DWARF2_External_ARange): Likewise.
	(DWARF2_Internal_LineInfo): Use dwarf_vma type for
	li_prologue_length.
	(eh_addr_size): Update prototype.

	PR binutils/17531
	* dwarf.c (process_debug_info): Zero the debug information array
	since correct initialisation cannot be relied upon.
	(process_cu_tu_index): Improve range checks.

	PR binutils/17531
	* dwarf.c (display_debug_pubnames_worker): Use dwarf_vma type for
	offset.

	2015-02-06  Nick Clifton  <nickc@redhat.com>

	PR binutils/17512
	* dwarf.c (display_debug_frames): Fix range checks to work on
	32-bit binaries complied on a 64-bit host.

	PR binutils/17531
	* dwarf.c (xcmalloc): Fail if the arguments are too big.
	(xcrealloc): Likewise.
	(xcalloc2): Likewise.
	* readelf.c (process_mips_specific): Fail if an option has an
	invalid size.

	2015-02-05  Alan Modra  <amodra@gmail.com>

	PR binutils/17926
	* dwarf.c (dwarf_select_sections_by_letters): Don't refer to optarg.

	2015-02-04  Nick Clifton  <nickc@redhat.com>

	PR binutils/17531
	* dwarf.c (read_and_display_attr_value): Test for a block length
	being so long that it wraps around to before the start of the block.
	(process_debug_info): Test for section_begin wrapping around to
	before the start of the section.
	(display_gdb_index): Test for num_cus being so large that the end
	address wraps around to before the start of the section.
	(process_cu_tu_index): Test for j being so large that the section
	index pool wraps around to before the start of the section.

	2015-02-03  Nick Clifton  <nickc@redhat.com>

	PR binutils/17531
	* dwarf.c (process_debug_info): Add range check.
	(display_debug_pubnames_worker): Likewise.
	(display_gdb_index): Fix range check.
	(process_cu_tu_index): Add range check.
	* readelf.c (get_data): Change parameter types from size_t to
	bfd_size_type.  Add checks for loss of accuracy when casting from
	bfd_size_type to size_t.
	(get_dynamic_data): Likewise.
	(process_section_groups): Limit number of error messages.

	2015-01-12  H.J. Lu  <hongjiu.lu@intel.com>

	* dwarf.c (process_debug_info): Properly check abbrev size.

	2015-01-12  Nick Clifton  <nickc@redhat.com>

	PR binutils/17531
	* dwarf.c (process_debug_info): Check for abbrev_base being larger
	than the section size.
	(process_cu_tu_index): Use xcalloc2 to allocate the CU and TU
	arrays.
	(xcalloc2): New function.  Like xcalloc, but checks for overflow.
	(display_debug_addr): Use xcalloc to allocate the debug_addr_info
	array.  Check for an address_base that is too large.

	* dwarf.h (xcalloc2): Prototype.

	2015-01-05  Nick Clifton  <nickc@redhat.com>

	PR binutils/17531
	* dwarf.c (alloc_num_debug_info_entries): New variable.
	(process_debug_info): Set it.  Use it to avoid displaying
	attributes for which there is no info.
	(display_debug_abbrev): Check that the debug_info_entry index is
	valid before using it.
	(display_loc_list_dwo): Likewise.
	(process_cu_tu_index): Add range check for an overlarge dw_sect
	value.
	(free_debug_memory): Reset alloc_num_debug_info_entries.

	2014-12-22  Nick Clifton  <nickc@redhat.com>

	PR binutils/17531
	* dwarf.c (decode_location_expression): Check for an out of range
	value for a DW_OP_GNU_entry_value expression.
	(display_debug_lines_raw): Check for a partial
	.debug_line. section being encountered without a prior, full
	.debug.line section.
	(display_debug_lines_decoded): Likewise.  Also check for
	li_line_range being zero.
	(display_debug_pubnames_worker): Check for an invalid pn_length
	field.
	(read_cie): Add range checks.

	2014-12-11  Nick Clifton  <nickc@redhat.com>

	PR binutils/17512
	* dwarf.c (display_gdb_index): Add more range checks.

	2014-12-08  Nick Clifton  <nickc@redhat.com>

	PR binutils/17531
	* dwarf.c (display_debug_frames): Check for a negative
	augmentation data length.
	(display_gdb_index): Check for invalid offsets.

	2014-12-01  H.J. Lu  <hongjiu.lu@intel.com>

	* dwarf.c (process_cu_tu_index): Properly check for an out of
	range row index.

	2014-12-01  Nick Clifton  <nickc@redhat.com>

	PR binutils/17512
	* dwarf.h (struct dwarf_section): Add user_data field.
	* dwarf.c (frame_need_space): Check for an over large register
	number.
	(display_debug_frames): Check the return value from
	frame_need_space.  Check for a CFA expression that is so long the
	start address wraps around.
	(debug_displays): Initialise the user_data field.
	* objdump.c (load_specific_debug_section): Save the BFD section
	pointer in the user_data field of the dwarf_section structure.
	(free_debug_section): Update BFD section data when freeing section
	contents.
	* readelf.c (load_specific_debug_section): Initialise the
	user_data field.

	2014-12-01  Nick Clifton  <nickc@redhat.com>

	PR binutils/17531
	* dwarf.c (process_cu_tu_index): Check for an out of range row
	index.
	* elfcomm.c (adjust_relative_path): Change name_len parameter to
	an unsigned long.  Check for path length overflow.
	(process_archive_index_and_symbols): Check for invalid header
	size.
	(setup_archive): Add checks for invalid archives.
	(get_archive_member_name): Add range checks.
	* elfcomm.h (adjust_relative_path): Update prototyoe.
	* readelf.c (process_archive): Add range checks.

	2014-11-26  Nick Clifton  <nickc@redhat.com>

	PR binutils/17512
	* dwarf.c (display_block): Do nothing if the block starts after
	the end of the buffer.
	(read_and_display_attr_value): Add range checks.
	(struct Frame_Chunk): Make the ncols and ra fields unsigned.
	(frame_need_space): Test for an ncols of zero.
	(read_cie): Fail if the augmentation data extends off the end of
	the buffer.
	(display_debug_frames): Add checks for read_cie failing.  Add
	range checks.

	2014-11-21  Nick Clifton  <nickc@redhat.com>

	PR binutils/17512
	* dwarf.c (get_encoded_value): Check for an encoded size of 0.
	(display_debug_lines_raw): Check for an invalid line range value.
	(display_debug_frames): Check for corrupt augmentation data.

	2014-11-19  Jan-Benedict Glaw  <jbglaw@lug-owl.de>

	* dwarf.c (process_extended_line_op): Fix signedness warning.

	2014-11-18  Nick Clifton  <nickc@redhat.com>

	PR binutils/17512
	* dwarf.c (get_encoded_value): Warn and return if the encoded
	value is more than 64-bits long.
	(SAFE_BYTE_GET): Do not attempt to read more than 64-bits.
	(process_extended_line_op): Add more range checks.
	(decode_location_expression): Use the return value from
	display_block.  Add more range checks.
	(read_debug_line_header): Add range check.
	(display_debug_lines_raw): Add range checks.
	(display_debug_frames): Silently skip multiple zero terminators.
	Add range checks.
	(process_cu_tu_index): Check for non-existant or empty sections.
	Use SAFE_BYTE_GET instead of byte_get.

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index dde9066..5fe7e3e 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -38,12 +38,13 @@ static unsigned int last_pointer_size = 0;
 static int warned_about_missing_comp_units = FALSE;
 
 static unsigned int num_debug_info_entries = 0;
+static unsigned int alloc_num_debug_info_entries = 0;
 static debug_info *debug_information = NULL;
 /* Special value for num_debug_info_entries to indicate
    that the .debug_info section could not be loaded/parsed.  */
 #define DEBUG_INFO_UNAVAILABLE  (unsigned int) -1
 
-int eh_addr_size;
+unsigned int eh_addr_size;
 
 int do_debug_info;
 int do_debug_abbrevs;
@@ -104,7 +105,7 @@ static void load_cu_tu_indexes (void *file);
 #define FLAG_DEBUG_LINES_RAW	 1
 #define FLAG_DEBUG_LINES_DECODED 2
 
-static int
+static unsigned int
 size_of_encoded_value (int encoding)
 {
   switch (encoding & 0x7)
@@ -124,7 +125,7 @@ get_encoded_value (unsigned char **pdata,
 		   unsigned char * end)
 {
   unsigned char * data = * pdata;
-  int size = size_of_encoded_value (encoding);
+  unsigned int size = size_of_encoded_value (encoding);
   dwarf_vma val;
 
   if (data + size >= end)
@@ -134,6 +135,22 @@ get_encoded_value (unsigned char **pdata,
       return 0;
     }
 
+  /* PR 17512: file: 002-829853-0.004.  */
+  if (size > 8)
+    {
+      warn (_("Encoded size of %d is too large to read\n"), size);
+      * pdata = end;
+      return 0;
+    }
+
+  /* PR 17512: file: 1085-5603-0.004.  */
+  if (size == 0)
+    {
+      warn (_("Encoded size of 0 is too small to read\n"));
+      * pdata = end;
+      return 0;
+    }
+
   if (encoding & DW_EH_PE_signed)
     val = byte_get_signed (data, size);
   else
@@ -264,6 +281,11 @@ read_leb128 (unsigned char *data,
       shift += 7;
       if ((byte & 0x80) == 0)
 	break;
+
+      /* PR 17512: file: 0ca183b8.
+	 FIXME: Should we signal this error somehow ?  */
+      if (shift >= sizeof (result) * 8)
+	break;
     }
 
   if (length_return != NULL)
@@ -304,10 +326,10 @@ read_uleb128 (unsigned char * data,
 	  else					\
 	    amount = 0;				\
 	}					\
-      if (amount)				\
-	VAL = byte_get ((PTR), amount);		\
-      else					\
+      if (amount == 0 || amount > 8)		\
 	VAL = 0;				\
+      else					\
+	VAL = byte_get ((PTR), amount);		\
     }						\
   while (0)
 
@@ -408,7 +430,7 @@ process_extended_line_op (unsigned char * data,
   len = read_uleb128 (data, & bytes_read, end);
   data += bytes_read;
 
-  if (len == 0 || data == end)
+  if (len == 0 || data == end || len > (uintptr_t) (end - data))
     {
       warn (_("Badly formed extended line op encountered!\n"));
       return bytes_read;
@@ -427,7 +449,15 @@ process_extended_line_op (unsigned char * data,
       break;
 
     case DW_LNE_set_address:
-      SAFE_BYTE_GET (adr, data, len - bytes_read - 1, end);
+      /* PR 17512: file: 002-100480-0.004.  */
+      if (len - bytes_read - 1 > 8)
+	{
+	  warn (_("Length (%d) of DW_LNE_set_address op is too long\n"),
+		len - bytes_read - 1);
+	  adr = 0;
+	}
+      else
+	SAFE_BYTE_GET (adr, data, len - bytes_read - 1, end);
       printf (_("set Address to 0x%s\n"), dwarf_vmatoa ("x", adr));
       state_machine_regs.address = adr;
       state_machine_regs.op_index = 0;
@@ -449,7 +479,7 @@ process_extended_line_op (unsigned char * data,
       printf ("%s\n\n", name);
 
       if (((unsigned int) (data - orig_data) != len) || data == end)
-        warn (_("DW_LNE_define_file: Bad opcode length\n"));
+	warn (_("DW_LNE_define_file: Bad opcode length\n"));
       break;
 
     case DW_LNE_set_discriminator:
@@ -490,68 +520,68 @@ process_extended_line_op (unsigned char * data,
       break;
     case DW_LNE_HP_source_file_correlation:
       {
-        unsigned char *edata = data + len - bytes_read - 1;
-
-        printf ("DW_LNE_HP_source_file_correlation\n");
-
-        while (data < edata)
-          {
-            unsigned int opc;
-
-            opc = read_uleb128 (data, & bytes_read, edata);
-            data += bytes_read;
-
-            switch (opc)
-              {
-              case DW_LNE_HP_SFC_formfeed:
-                printf ("    DW_LNE_HP_SFC_formfeed\n");
-                break;
-              case DW_LNE_HP_SFC_set_listing_line:
-                printf ("    DW_LNE_HP_SFC_set_listing_line (%s)\n",
-                        dwarf_vmatoa ("u",
-                                      read_uleb128 (data, & bytes_read, edata)));
-                data += bytes_read;
-                break;
-              case DW_LNE_HP_SFC_associate:
-                printf ("    DW_LNE_HP_SFC_associate ");
-                printf ("(%s",
-                        dwarf_vmatoa ("u",
-                                      read_uleb128 (data, & bytes_read, edata)));
-                data += bytes_read;
-                printf (",%s",
-                        dwarf_vmatoa ("u",
-                                      read_uleb128 (data, & bytes_read, edata)));
-                data += bytes_read;
-                printf (",%s)\n",
-                        dwarf_vmatoa ("u",
-                                      read_uleb128 (data, & bytes_read, edata)));
-                data += bytes_read;
-                break;
-              default:
-                printf (_("    UNKNOWN DW_LNE_HP_SFC opcode (%u)\n"), opc);
-                data = edata;
-                break;
-              }
-          }
+	unsigned char *edata = data + len - bytes_read - 1;
+
+	printf ("DW_LNE_HP_source_file_correlation\n");
+
+	while (data < edata)
+	  {
+	    unsigned int opc;
+
+	    opc = read_uleb128 (data, & bytes_read, edata);
+	    data += bytes_read;
+
+	    switch (opc)
+	      {
+	      case DW_LNE_HP_SFC_formfeed:
+		printf ("    DW_LNE_HP_SFC_formfeed\n");
+		break;
+	      case DW_LNE_HP_SFC_set_listing_line:
+		printf ("    DW_LNE_HP_SFC_set_listing_line (%s)\n",
+			dwarf_vmatoa ("u",
+				      read_uleb128 (data, & bytes_read, edata)));
+		data += bytes_read;
+		break;
+	      case DW_LNE_HP_SFC_associate:
+		printf ("    DW_LNE_HP_SFC_associate ");
+		printf ("(%s",
+			dwarf_vmatoa ("u",
+				      read_uleb128 (data, & bytes_read, edata)));
+		data += bytes_read;
+		printf (",%s",
+			dwarf_vmatoa ("u",
+				      read_uleb128 (data, & bytes_read, edata)));
+		data += bytes_read;
+		printf (",%s)\n",
+			dwarf_vmatoa ("u",
+				      read_uleb128 (data, & bytes_read, edata)));
+		data += bytes_read;
+		break;
+	      default:
+		printf (_("    UNKNOWN DW_LNE_HP_SFC opcode (%u)\n"), opc);
+		data = edata;
+		break;
+	      }
+	  }
       }
       break;
 
     default:
       {
-        unsigned int rlen = len - bytes_read - 1;
-
-        if (op_code >= DW_LNE_lo_user
-            /* The test against DW_LNW_hi_user is redundant due to
-               the limited range of the unsigned char data type used
-               for op_code.  */
-            /*&& op_code <= DW_LNE_hi_user*/)
-          printf (_("user defined: "));
-        else
-          printf (_("UNKNOWN: "));
-        printf (_("length %d ["), rlen);
-        for (; rlen; rlen--)
-          printf (" %02x", *data++);
-        printf ("]\n");
+	unsigned int rlen = len - bytes_read - 1;
+
+	if (op_code >= DW_LNE_lo_user
+	    /* The test against DW_LNW_hi_user is redundant due to
+	       the limited range of the unsigned char data type used
+	       for op_code.  */
+	    /*&& op_code <= DW_LNE_hi_user*/)
+	  printf (_("user defined: "));
+	else
+	  printf (_("UNKNOWN: "));
+	printf (_("length %d ["), rlen);
+	for (; rlen; rlen--)
+	  printf (" %02x", *data++);
+	printf ("]\n");
       }
       break;
     }
@@ -628,7 +658,7 @@ fetch_indexed_value (dwarf_vma offset, dwarf_vma bytes)
   if (offset + bytes > section->size)
     {
       warn (_("Offset into section %s too big: %s\n"),
-            section->name, dwarf_vmatoa ("x", offset));
+	    section->name, dwarf_vmatoa ("x", offset));
       return "<offset too big>";
     }
 
@@ -841,6 +871,8 @@ display_block (unsigned char *data,
   dwarf_vma maxlen;
 
   printf (_(" %s byte block: "), dwarf_vmatoa ("u", length));
+  if (data > end)
+    return (unsigned char *) end;
 
   maxlen = (dwarf_vma) (end - data);
   length = length > maxlen ? maxlen : length;
@@ -1231,8 +1263,7 @@ decode_location_expression (unsigned char * data,
 	  printf ("DW_OP_implicit_value");
 	  uvalue = read_uleb128 (data, &bytes_read, end);
 	  data += bytes_read;
-	  display_block (data, uvalue, end);
-	  data += uvalue;
+	  data = display_block (data, uvalue, end);
 	  break;
 
 	  /* GNU extensions.  */
@@ -1245,10 +1276,11 @@ decode_location_expression (unsigned char * data,
 	  break;
 	case DW_OP_GNU_encoded_addr:
 	  {
-	    int encoding;
+	    int encoding = 0;
 	    dwarf_vma addr;
 
-	    encoding = *data++;
+	    if (data < end)
+	      encoding = *data++;
 	    addr = get_encoded_value (&data, encoding, section, end);
 
 	    printf ("DW_OP_GNU_encoded_addr: fmt:%02x addr:", encoding);
@@ -1281,6 +1313,9 @@ decode_location_expression (unsigned char * data,
 	case DW_OP_GNU_entry_value:
 	  uvalue = read_uleb128 (data, &bytes_read, end);
 	  data += bytes_read;
+	  /* PR 17531: file: 0cc9cd00.  */
+	  if (uvalue > (dwarf_vma) (end - data))
+	    uvalue = end - data;
 	  printf ("DW_OP_GNU_entry_value: (");
 	  if (decode_location_expression (data, pointer_size, offset_size,
 					  dwarf_version, uvalue,
@@ -1288,6 +1323,8 @@ decode_location_expression (unsigned char * data,
 	    need_frame_base = 1;
 	  putchar (')');
 	  data += uvalue;
+	  if (data > end)
+	    data = end;
 	  break;
 	case DW_OP_GNU_const_type:
 	  uvalue = read_uleb128 (data, &bytes_read, end);
@@ -1295,8 +1332,7 @@ decode_location_expression (unsigned char * data,
 	  printf ("DW_OP_GNU_const_type: <0x%s> ",
 		  dwarf_vmatoa ("x", cu_offset + uvalue));
 	  SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
-	  display_block (data, uvalue, end);
-	  data += uvalue;
+	  data = display_block (data, uvalue, end);
 	  break;
 	case DW_OP_GNU_regval_type:
 	  uvalue = read_uleb128 (data, &bytes_read, end);
@@ -1331,16 +1367,16 @@ decode_location_expression (unsigned char * data,
 	  printf ("DW_OP_GNU_parameter_ref: <0x%s>",
 		  dwarf_vmatoa ("x", cu_offset + uvalue));
 	  break;
-        case DW_OP_GNU_addr_index:
-          uvalue = read_uleb128 (data, &bytes_read, end);
-          data += bytes_read;
-          printf ("DW_OP_GNU_addr_index <0x%s>", dwarf_vmatoa ("x", uvalue));
-          break;
-        case DW_OP_GNU_const_index:
-          uvalue = read_uleb128 (data, &bytes_read, end);
-          data += bytes_read;
-          printf ("DW_OP_GNU_const_index <0x%s>", dwarf_vmatoa ("x", uvalue));
-          break;
+	case DW_OP_GNU_addr_index:
+	  uvalue = read_uleb128 (data, &bytes_read, end);
+	  data += bytes_read;
+	  printf ("DW_OP_GNU_addr_index <0x%s>", dwarf_vmatoa ("x", uvalue));
+	  break;
+	case DW_OP_GNU_const_index:
+	  uvalue = read_uleb128 (data, &bytes_read, end);
+	  data += bytes_read;
+	  printf ("DW_OP_GNU_const_index <0x%s>", dwarf_vmatoa ("x", uvalue));
+	  break;
 
 	  /* HP extensions.  */
 	case DW_OP_HP_is_value:
@@ -1633,8 +1669,18 @@ read_and_display_attr_value (unsigned long attribute,
     case DW_FORM_exprloc:
       uvalue = read_uleb128 (data, & bytes_read, end);
       block_start = data + bytes_read;
+      if (block_start >= end)
+	{
+	  warn (_("Block ends prematurely\n"));
+	  uvalue = 0;
+	  block_start = end;
+	}
+      /* FIXME: Testing "(block_start + uvalue) < block_start" miscompiles with
+	 gcc 4.8.3 running on an x86_64 host in 32-bit mode.  So we pre-compute
+	 block_start + uvalue here.  */
+      data = block_start + uvalue;
       /* PR 17512: file: 008-103549-0.001:0.1.  */
-      if (block_start + uvalue > end)
+      if (block_start + uvalue > end || data < block_start)
 	{
 	  warn (_("Corrupt attribute block length: %lx\n"), (long) uvalue);
 	  uvalue = end - block_start;
@@ -1648,7 +1694,14 @@ read_and_display_attr_value (unsigned long attribute,
     case DW_FORM_block1:
       SAFE_BYTE_GET (uvalue, data, 1, end);
       block_start = data + 1;
-      if (block_start + uvalue > end)
+      if (block_start >= end)
+	{
+	  warn (_("Block ends prematurely\n"));
+	  uvalue = 0;
+	  block_start = end;
+	}
+      data = block_start + uvalue;
+      if (block_start + uvalue > end || data < block_start)
 	{
 	  warn (_("Corrupt attribute block length: %lx\n"), (long) uvalue);
 	  uvalue = end - block_start;
@@ -1662,7 +1715,14 @@ read_and_display_attr_value (unsigned long attribute,
     case DW_FORM_block2:
       SAFE_BYTE_GET (uvalue, data, 2, end);
       block_start = data + 2;
-      if (block_start + uvalue > end)
+      if (block_start >= end)
+	{
+	  warn (_("Block ends prematurely\n"));
+	  uvalue = 0;
+	  block_start = end;
+	}
+      data = block_start + uvalue;
+      if (block_start + uvalue > end || data < block_start)
 	{
 	  warn (_("Corrupt attribute block length: %lx\n"), (long) uvalue);
 	  uvalue = end - block_start;
@@ -1676,7 +1736,17 @@ read_and_display_attr_value (unsigned long attribute,
     case DW_FORM_block4:
       SAFE_BYTE_GET (uvalue, data, 4, end);
       block_start = data + 4;
-      if (block_start + uvalue > end)
+      /* PR 17512: file: 3371-3907-0.004.  */
+      if (block_start >= end)
+	{
+	  warn (_("Block ends prematurely\n"));
+	  uvalue = 0;
+	  block_start = end;
+	}
+      data = block_start + uvalue;
+      if (block_start + uvalue > end
+	  /* PR 17531: file: 5b5f0592.  */
+	  || data < block_start)
 	{
 	  warn (_("Corrupt attribute block length: %lx\n"), (long) uvalue);
 	  uvalue = end - block_start;
@@ -1696,14 +1766,14 @@ read_and_display_attr_value (unsigned long attribute,
 
     case DW_FORM_GNU_str_index:
       if (!do_loc)
-        {
-          const char *suffix = strrchr (section->name, '.');
-          int dwo = (suffix && strcmp (suffix, ".dwo") == 0) ? 1 : 0;
-
-          printf (_(" (indexed string: 0x%s): %s"),
-                  dwarf_vmatoa ("x", uvalue),
-                  fetch_indexed_string (uvalue, this_set, offset_size, dwo));
-        }
+	{
+	  const char *suffix = strrchr (section->name, '.');
+	  int dwo = (suffix && strcmp (suffix, ".dwo") == 0) ? 1 : 0;
+
+	  printf (_(" (indexed string: 0x%s): %s"),
+		  dwarf_vmatoa ("x", uvalue),
+		  fetch_indexed_string (uvalue, this_set, offset_size, dwo));
+	}
       break;
 
     case DW_FORM_GNU_strp_alt:
@@ -1731,9 +1801,9 @@ read_and_display_attr_value (unsigned long attribute,
 
     case DW_FORM_GNU_addr_index:
       if (!do_loc)
-        printf (_(" (addr_index: 0x%s): %s"),
-                dwarf_vmatoa ("x", uvalue),
-                fetch_indexed_value (uvalue * pointer_size, pointer_size));
+	printf (_(" (addr_index: 0x%s): %s"),
+		dwarf_vmatoa ("x", uvalue),
+		fetch_indexed_value (uvalue * pointer_size, pointer_size));
       break;
 
     default:
@@ -1761,7 +1831,7 @@ read_and_display_attr_value (unsigned long attribute,
 	case DW_AT_GNU_call_site_data_value:
 	case DW_AT_GNU_call_site_target:
 	case DW_AT_GNU_call_site_target_clobbered:
-    	  if ((dwarf_version < 4
+	  if ((dwarf_version < 4
 	       && (form == DW_FORM_data4 || form == DW_FORM_data8))
 	      || form == DW_FORM_sec_offset)
 	    {
@@ -1773,15 +1843,15 @@ read_and_display_attr_value (unsigned long attribute,
 		{
 		  lmax += 1024;
 		  debug_info_p->loc_offsets = (dwarf_vma *)
-                      xcrealloc (debug_info_p->loc_offsets,
-				 lmax, sizeof (*debug_info_p->loc_offsets));
+		    xcrealloc (debug_info_p->loc_offsets,
+			       lmax, sizeof (*debug_info_p->loc_offsets));
 		  debug_info_p->have_frame_base = (int *)
-                      xcrealloc (debug_info_p->have_frame_base,
-				 lmax, sizeof (*debug_info_p->have_frame_base));
+		    xcrealloc (debug_info_p->have_frame_base,
+			       lmax, sizeof (*debug_info_p->have_frame_base));
 		  debug_info_p->max_loc_offsets = lmax;
 		}
 	      if (this_set != NULL)
-	        uvalue += this_set->section_offsets [DW_SECT_LOC];
+		uvalue += this_set->section_offsets [DW_SECT_LOC];
 	      debug_info_p->loc_offsets [num] = uvalue;
 	      debug_info_p->have_frame_base [num] = have_frame_base;
 	      debug_info_p->num_loc_offsets++;
@@ -1794,15 +1864,15 @@ read_and_display_attr_value (unsigned long attribute,
 	  break;
 
 	case DW_AT_GNU_addr_base:
-          debug_info_p->addr_base = uvalue;
+	  debug_info_p->addr_base = uvalue;
 	  break;
 
 	case DW_AT_GNU_ranges_base:
-          debug_info_p->ranges_base = uvalue;
+	  debug_info_p->ranges_base = uvalue;
 	  break;
 
 	case DW_AT_ranges:
-    	  if ((dwarf_version < 4
+	  if ((dwarf_version < 4
 	       && (form == DW_FORM_data4 || form == DW_FORM_data8))
 	      || form == DW_FORM_sec_offset)
 	    {
@@ -1814,8 +1884,8 @@ read_and_display_attr_value (unsigned long attribute,
 		{
 		  lmax += 1024;
 		  debug_info_p->range_lists = (dwarf_vma *)
-                      xcrealloc (debug_info_p->range_lists,
-				 lmax, sizeof (*debug_info_p->range_lists));
+		    xcrealloc (debug_info_p->range_lists,
+			       lmax, sizeof (*debug_info_p->range_lists));
 		  debug_info_p->max_range_lists = lmax;
 		}
 	      debug_info_p->range_lists [num] = uvalue;
@@ -1887,9 +1957,6 @@ read_and_display_attr_value (unsigned long attribute,
 	case DW_LANG_Python:		printf ("(Python)"); break;
 	  /* DWARF 5 values.  */
 	case DW_LANG_Go:		printf ("(Go)"); break;
-	case DW_LANG_C_plus_plus_11:	printf ("(C++11)"); break;
-	case DW_LANG_C11:		printf ("(C11)"); break;
-	case DW_LANG_C_plus_plus_14:	printf ("(C++14)"); break;
 	  /* MIPS extension.  */
 	case DW_LANG_Mips_Assembler:	printf ("(MIPS assembler)"); break;
 	  /* UPC extension.  */
@@ -2033,7 +2100,7 @@ read_and_display_attr_value (unsigned long attribute,
     case DW_AT_GNU_call_site_target:
     case DW_AT_GNU_call_site_target_clobbered:
       if ((dwarf_version < 4
-           && (form == DW_FORM_data4 || form == DW_FORM_data8))
+	   && (form == DW_FORM_data4 || form == DW_FORM_data8))
 	  || form == DW_FORM_sec_offset)
 	printf (_(" (location list)"));
       /* Fall through.  */
@@ -2064,7 +2131,7 @@ read_and_display_attr_value (unsigned long attribute,
       {
 	if (form == DW_FORM_ref_sig8
 	    || form == DW_FORM_GNU_ref_alt)
-          break;
+	  break;
 
 	if (form == DW_FORM_ref1
 	    || form == DW_FORM_ref2
@@ -2073,7 +2140,7 @@ read_and_display_attr_value (unsigned long attribute,
 	  uvalue += cu_offset;
 
 	if (uvalue >= section->size)
-	  warn (_("Offset %s used as value for DW_AT_import attribute of DIE at offset %lx is too big.\n"),
+	  warn (_("Offset %s used as value for DW_AT_import attribute of DIE at offset 0x%lx is too big.\n"),
 		dwarf_vmatoa ("x", uvalue),
 		(unsigned long) (orig_data - section->start));
 	else
@@ -2166,7 +2233,7 @@ read_and_display_attr (unsigned long attribute,
 static int
 process_debug_info (struct dwarf_section *section,
 		    void *file,
-                    enum dwarf_section_display_enum abbrev_sec,
+		    enum dwarf_section_display_enum abbrev_sec,
 		    int do_loc,
 		    int do_types)
 {
@@ -2207,8 +2274,8 @@ process_debug_info (struct dwarf_section *section,
 
 	  /* Negative values are illegal, they may even cause infinite
 	     looping.  This can happen if we can't accurately apply
-	     relocations to an object file.  */
-	  if ((signed long) length <= 0)
+	     relocations to an object file, or if the file is corrupt.  */
+	  if ((signed long) length <= 0 || section_begin < start)
 	    {
 	      warn (_("Corrupt unit length (0x%s) found in section %s\n"),
 		    dwarf_vmatoa ("x", length), section->name);
@@ -2224,13 +2291,22 @@ process_debug_info (struct dwarf_section *section,
 
       /* Then allocate an array to hold the information.  */
       debug_information = (debug_info *) cmalloc (num_units,
-                                                  sizeof (* debug_information));
+						  sizeof (* debug_information));
       if (debug_information == NULL)
 	{
 	  error (_("Not enough memory for a debug info array of %u entries\n"),
 		 num_units);
+	  alloc_num_debug_info_entries = num_debug_info_entries = 0;
 	  return 0;
 	}
+      /* PR 17531: file: 92ca3797.
+	 We cannot rely upon the debug_information array being initialised
+	 before it is used.  A corrupt file could easily contain references
+	 to a unit for which information has not been made available.  So
+	 we ensure that the array is zeroed here.  */
+      memset (debug_information, 0, num_units * sizeof (*debug_information));
+
+      alloc_num_debug_info_entries = num_units;
     }
 
   if (!do_loc)
@@ -2314,11 +2390,11 @@ process_debug_info (struct dwarf_section *section,
 	}
 
       if (do_types)
-        {
+	{
 	  SAFE_BYTE_GET64 (hdrptr, &signature_high, &signature_low, end);
 	  hdrptr += 8;
 	  SAFE_BYTE_GET_AND_INC (type_offset, hdrptr, offset_size, end);
-        }
+	}
 
       if ((do_loc || do_debug_loc || do_debug_ranges)
 	  && num_debug_info_entries == 0
@@ -2387,14 +2463,22 @@ process_debug_info (struct dwarf_section *section,
 	  > section->size)
 	{
 	  warn (_("Debug info is corrupted, length of CU at %s"
-	  	  " extends beyond end of section (length = %s)\n"),
+		  " extends beyond end of section (length = %s)\n"),
 		dwarf_vmatoa ("x", cu_offset),
 		dwarf_vmatoa ("x", compunit.cu_length));
+	  num_units = unit;
 	  break;
 	}
       tags = hdrptr;
       start += compunit.cu_length + initial_length_size;
 
+      if (start > end)
+	{
+	  warn (_("Debug info is corrupt.  CU at %s extends beyond end of section"),
+		dwarf_vmatoa ("x", cu_offset));
+	  start = end;
+	}
+
       if (compunit.cu_version != 2
 	  && compunit.cu_version != 3
 	  && compunit.cu_version != 4)
@@ -2412,6 +2496,12 @@ process_debug_info (struct dwarf_section *section,
 	warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than abbrev section size (%lx)\n"),
 	      (unsigned long) compunit.cu_abbrev_offset,
 	      (unsigned long) abbrev_size);
+      /* PR 17531: file:4bcd9ce9.  */
+      else if ((abbrev_base + abbrev_size)
+	       > debug_displays [abbrev_sec].section.size)
+	warn (_("Debug info is corrupted, abbrev size (%lx) is larger than abbrev section size (%lx)\n"),
+	      (unsigned long) abbrev_base + abbrev_size,
+	      (unsigned long) debug_displays [abbrev_sec].section.size);
       else
 	process_abbrev_section
 	  (((unsigned char *) debug_displays [abbrev_sec].section.start
@@ -2511,7 +2601,7 @@ process_debug_info (struct dwarf_section *section,
 		  printf ("\n");
 		  fflush (stdout);
 		}
-	      warn (_("DIE at offset %lx refers to abbreviation number %lu which does not exist\n"),
+	      warn (_("DIE at offset 0x%lx refers to abbreviation number %lu which does not exist\n"),
 		    die_offset, abbrev_number);
 	      return 0;
 	    }
@@ -2545,9 +2635,10 @@ process_debug_info (struct dwarf_section *section,
 		/* Show the offset from where the tag was extracted.  */
 		printf ("    <%lx>", (unsigned long)(tags - section_begin));
 
-	      arg = debug_information;
-	      if (debug_information)
-		arg += unit;
+	      if (debug_information && unit < alloc_num_debug_info_entries)
+		arg = debug_information + unit;
+	      else
+		arg = NULL;
 
 	      tags = read_and_display_attr (attr->attribute,
 					    attr->form,
@@ -2563,9 +2654,9 @@ process_debug_info (struct dwarf_section *section,
 					    this_set);
 	    }
 
- 	  if (entry->children)
- 	    ++level;
- 	}
+	  if (entry->children)
+	    ++level;
+	}
     }
 
   /* Set num_debug_info_entries here so that it can be used to check if
@@ -2573,7 +2664,12 @@ process_debug_info (struct dwarf_section *section,
   if ((do_loc || do_debug_loc || do_debug_ranges)
       && num_debug_info_entries == 0
       && ! do_types)
-    num_debug_info_entries = num_units;
+    {
+      if (num_units > alloc_num_debug_info_entries)
+	num_debug_info_entries = alloc_num_debug_info_entries;
+      else
+	num_debug_info_entries = num_units;
+    }
 
   if (!do_loc)
     printf ("\n");
@@ -2610,9 +2706,10 @@ load_debug_info (void * file)
   if (load_debug_section (info, file)
       && process_debug_info (&debug_displays [info].section, file, abbrev, 1, 0))
     return num_debug_info_entries;
-  else if (load_debug_section (info_dwo, file)
-           && process_debug_info (&debug_displays [info_dwo].section, file,
-                                  abbrev_dwo, 1, 0))
+
+  if (load_debug_section (info_dwo, file)
+      && process_debug_info (&debug_displays [info_dwo].section, file,
+			     abbrev_dwo, 1, 0))
     return num_debug_info_entries;
 
   num_debug_info_entries = DEBUG_INFO_UNAVAILABLE;
@@ -2637,7 +2734,7 @@ read_debug_line_header (struct dwarf_section * section,
 
   /* Extract information from the Line Number Program Header.
      (section 6.2.4 in the Dwarf3 doc).  */
-      hdrptr = data;
+  hdrptr = data;
 
   /* Get and check the length of the block.  */
   SAFE_BYTE_GET_AND_INC (linfo->li_length, hdrptr, 4, end);
@@ -2706,18 +2803,27 @@ read_debug_line_header (struct dwarf_section * section,
   SAFE_BYTE_GET_AND_INC (linfo->li_opcode_base, hdrptr, 1, end);
 
   * end_of_sequence = data + linfo->li_length + initial_length_size;
+  /* PR 17512: file:002-117414-0.004.  */
+  if (* end_of_sequence > end)
+    {
+      warn (_("Line length %s extends beyond end of section\n"),
+	    dwarf_vmatoa ("u", linfo->li_length));
+      * end_of_sequence = end;
+      return NULL;
+    }
+
   return hdrptr;
 }
 
 static int
 display_debug_lines_raw (struct dwarf_section *section,
 			 unsigned char *data,
-                         unsigned char *end)
+			 unsigned char *end)
 {
   unsigned char *start = section->start;
 
   printf (_("Raw dump of debug contents of section %s:\n\n"),
-          section->name);
+	  section->name);
 
   while (data < end)
     {
@@ -2746,6 +2852,12 @@ display_debug_lines_raw (struct dwarf_section *section,
 	  end_of_sequence = end;
 	  standard_opcodes = NULL;
 	  linfo = saved_linfo;
+	  /* PR 17531: file: 0522b371.  */
+	  if (linfo.li_line_range == 0)
+	    {
+	      warn (_("Partial .debug_line. section encountered without a prior full .debug_line section\n"));
+	      return 0;
+	    }
 	  reset_state_machine (linfo.li_default_is_stmt);
 	}
       else
@@ -2759,7 +2871,7 @@ display_debug_lines_raw (struct dwarf_section *section,
 	  printf (_("  Offset:                      0x%lx\n"), (long)(data - start));
 	  printf (_("  Length:                      %ld\n"), (long) linfo.li_length);
 	  printf (_("  DWARF Version:               %d\n"), linfo.li_version);
-	  printf (_("  Prologue Length:             %d\n"), linfo.li_prologue_length);
+	  printf (_("  Prologue Length:             %d\n"), (int) linfo.li_prologue_length);
 	  printf (_("  Minimum Instruction Length:  %d\n"), linfo.li_min_insn_length);
 	  if (linfo.li_version >= 4)
 	    printf (_("  Maximum Ops per Instruction: %d\n"), linfo.li_max_ops_per_insn);
@@ -2768,11 +2880,25 @@ display_debug_lines_raw (struct dwarf_section *section,
 	  printf (_("  Line Range:                  %d\n"), linfo.li_line_range);
 	  printf (_("  Opcode Base:                 %d\n"), linfo.li_opcode_base);
 
+	  /* PR 17512: file: 1665-6428-0.004.  */
+	  if (linfo.li_line_range == 0)
+	    {
+	      warn (_("Line range of 0 is invalid, using 1 instead\n"));
+	      linfo.li_line_range = 1;
+	    }
+
 	  reset_state_machine (linfo.li_default_is_stmt);
 
 	  /* Display the contents of the Opcodes table.  */
 	  standard_opcodes = hdrptr;
 
+	  /* PR 17512: file: 002-417945-0.004.  */
+	  if (standard_opcodes + linfo.li_opcode_base >= end)
+	    {
+	      warn (_("Line Base extends beyond end of section\n"));
+	      return 0;
+	    }
+
 	  printf (_("\n Opcodes:\n"));
 
 	  for (i = 1; i < linfo.li_opcode_base; i++)
@@ -2788,12 +2914,16 @@ display_debug_lines_raw (struct dwarf_section *section,
 	      printf (_("\n The Directory Table (offset 0x%lx):\n"),
 		      (long)(data - start));
 
-	      while (*data != 0)
+	      while (data < end && *data != 0)
 		{
-		  printf ("  %d\t%s\n", ++last_dir_entry, data);
+		  printf ("  %d\t%.*s\n", ++last_dir_entry, (int) (end - data), data);
 
 		  data += strnlen ((char *) data, end - data) + 1;
 		}
+
+	      /* PR 17512: file: 002-132094-0.004.  */
+	      if (data >= end - 1)
+		break;
 	    }
 
 	  /* Skip the NUL at the end of the table.  */
@@ -2808,7 +2938,7 @@ display_debug_lines_raw (struct dwarf_section *section,
 		      (long)(data - start));
 	      printf (_("  Entry\tDir\tTime\tSize\tName\n"));
 
-	      while (*data != 0)
+	      while (data < end && *data != 0)
 		{
 		  unsigned char *name;
 		  unsigned int bytes_read;
@@ -2826,7 +2956,7 @@ display_debug_lines_raw (struct dwarf_section *section,
 		  printf ("%s\t",
 			  dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
 		  data += bytes_read;
-		  printf ("%s\n", name);
+		  printf ("%.*s\n", (int)(end - name), name);
 
 		  if (data == end)
 		    {
@@ -3056,7 +3186,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
   static DWARF2_Internal_LineInfo saved_linfo;
 
   printf (_("Decoded dump of debug contents of section %s:\n\n"),
-          section->name);
+	  section->name);
 
   while (data < end)
     {
@@ -3074,21 +3204,33 @@ display_debug_lines_decoded (struct dwarf_section *section,
 	  /* Note: the following does not apply to .debug_line.dwo sections.
 	     These are full debug_line sections.  */
 	  && strcmp (section->name, ".debug_line.dwo") != 0)
-        {
+	{
 	  /* See comment in display_debug_lines_raw().  */
 	  end_of_sequence = end;
 	  standard_opcodes = NULL;
 	  linfo = saved_linfo;
+	  /* PR 17531: file: 0522b371.  */
+	  if (linfo.li_line_range == 0)
+	    {
+	      warn (_("Partial .debug_line. section encountered without a prior full .debug_line section\n"));
+	      return 0;
+	    }
 	  reset_state_machine (linfo.li_default_is_stmt);
-        }
+	}
       else
-        {
+	{
 	  unsigned char *hdrptr;
 
 	  if ((hdrptr = read_debug_line_header (section, data, end, & linfo,
 						& end_of_sequence)) == NULL)
 	      return 0;
 
+	  /* PR 17531: file: 0522b371.  */
+	  if (linfo.li_line_range == 0)
+	    {
+	      warn (_("Line range of 0 is invalid, using 1 instead\n"));
+	      linfo.li_line_range = 1;
+	    }
 	  reset_state_machine (linfo.li_default_is_stmt);
 
 	  /* Save a pointer to the contents of the Opcodes table.  */
@@ -3197,16 +3339,16 @@ display_debug_lines_decoded (struct dwarf_section *section,
 
       /* This loop iterates through the Dwarf Line Number Program.  */
       while (data < end_of_sequence)
-        {
+	{
 	  unsigned char op_code;
-          int adv;
-          unsigned long int uladv;
-          unsigned int bytes_read;
-          int is_special_opcode = 0;
+	  int adv;
+	  unsigned long int uladv;
+	  unsigned int bytes_read;
+	  int is_special_opcode = 0;
 
-          op_code = *data++;
+	  op_code = *data++;
 
-          if (op_code >= linfo.li_opcode_base)
+	  if (op_code >= linfo.li_opcode_base)
 	    {
 	      op_code -= linfo.li_opcode_base;
 	      uladv = (op_code / linfo.li_line_range);
@@ -3226,11 +3368,11 @@ display_debug_lines_decoded (struct dwarf_section *section,
 		    % linfo.li_max_ops_per_insn;
 		}
 
-              adv = (op_code % linfo.li_line_range) + linfo.li_line_base;
-              state_machine_regs.line += adv;
-              is_special_opcode = 1;
-            }
-          else switch (op_code)
+	      adv = (op_code % linfo.li_line_range) + linfo.li_line_base;
+	      state_machine_regs.line += adv;
+	      is_special_opcode = 1;
+	    }
+	  else switch (op_code)
 		 {
 		 case DW_LNS_extended_op:
 		   {
@@ -3420,15 +3562,15 @@ display_debug_lines_decoded (struct dwarf_section *section,
 		   break;
 		 }
 
-          /* Only Special opcodes, DW_LNS_copy and DW_LNE_end_sequence adds a row
-             to the DWARF address/line matrix.  */
-          if ((is_special_opcode) || (op_code == DW_LNE_end_sequence)
+	  /* Only Special opcodes, DW_LNS_copy and DW_LNE_end_sequence adds a row
+	     to the DWARF address/line matrix.  */
+	  if ((is_special_opcode) || (op_code == DW_LNE_end_sequence)
 	      || (op_code == DW_LNS_copy))
-            {
-              const unsigned int MAX_FILENAME_LENGTH = 35;
-              char *fileName;
-              char *newFileName = NULL;
-              size_t fileNameLength;
+	    {
+	      const unsigned int MAX_FILENAME_LENGTH = 35;
+	      char *fileName;
+	      char *newFileName = NULL;
+	      size_t fileNameLength;
 
 	      if (file_table)
 		fileName = (char *) file_table[state_machine_regs.file - 1].name;
@@ -3437,22 +3579,22 @@ display_debug_lines_decoded (struct dwarf_section *section,
 
 	      fileNameLength = strlen (fileName);
 
-              if ((fileNameLength > MAX_FILENAME_LENGTH) && (!do_wide))
-                {
-                  newFileName = (char *) xmalloc (MAX_FILENAME_LENGTH + 1);
-                  /* Truncate file name */
-                  strncpy (newFileName,
-                           fileName + fileNameLength - MAX_FILENAME_LENGTH,
-                           MAX_FILENAME_LENGTH + 1);
-                }
-              else
-                {
-                  newFileName = (char *) xmalloc (fileNameLength + 1);
-                  strncpy (newFileName, fileName, fileNameLength + 1);
-                }
-
-              if (!do_wide || (fileNameLength <= MAX_FILENAME_LENGTH))
-                {
+	      if ((fileNameLength > MAX_FILENAME_LENGTH) && (!do_wide))
+		{
+		  newFileName = (char *) xmalloc (MAX_FILENAME_LENGTH + 1);
+		  /* Truncate file name */
+		  strncpy (newFileName,
+			   fileName + fileNameLength - MAX_FILENAME_LENGTH,
+			   MAX_FILENAME_LENGTH + 1);
+		}
+	      else
+		{
+		  newFileName = (char *) xmalloc (fileNameLength + 1);
+		  strncpy (newFileName, fileName, fileNameLength + 1);
+		}
+
+	      if (!do_wide || (fileNameLength <= MAX_FILENAME_LENGTH))
+		{
 		  if (linfo.li_max_ops_per_insn == 1)
 		    printf ("%-35s  %11d  %#18" DWARF_VMA_FMT "x\n",
 			    newFileName, state_machine_regs.line,
@@ -3462,9 +3604,9 @@ display_debug_lines_decoded (struct dwarf_section *section,
 			    newFileName, state_machine_regs.line,
 			    state_machine_regs.address,
 			    state_machine_regs.op_index);
-                }
-              else
-                {
+		}
+	      else
+		{
 		  if (linfo.li_max_ops_per_insn == 1)
 		    printf ("%s  %11d  %#18" DWARF_VMA_FMT "x\n",
 			    newFileName, state_machine_regs.line,
@@ -3474,14 +3616,14 @@ display_debug_lines_decoded (struct dwarf_section *section,
 			    newFileName, state_machine_regs.line,
 			    state_machine_regs.address,
 			    state_machine_regs.op_index);
-                }
+		}
 
-              if (op_code == DW_LNE_end_sequence)
+	      if (op_code == DW_LNE_end_sequence)
 		printf ("\n");
 
-              free (newFileName);
-            }
-        }
+	      free (newFileName);
+	    }
+	}
 
       if (file_table)
 	{
@@ -3578,7 +3720,8 @@ display_debug_pubnames_worker (struct dwarf_section *section,
   while (start < end)
     {
       unsigned char *data;
-      unsigned long offset;
+      unsigned char *adr;
+      dwarf_vma offset;
       unsigned int offset_size, initial_length_size;
 
       data = start;
@@ -3607,7 +3750,26 @@ display_debug_pubnames_worker (struct dwarf_section *section,
 
       SAFE_BYTE_GET_AND_INC (names.pn_size, data, offset_size, end);
 
-      start += names.pn_length + initial_length_size;
+      adr = start + names.pn_length + initial_length_size;
+      /* PR 17531: file: 7615b6b2.  */
+      if ((dwarf_signed_vma) names.pn_length < 0
+	  /* PR 17531: file: a5dbeaa7. */
+	  || adr < start)
+	{
+	  warn (_("Negative length for public name: 0x%lx\n"), (long) names.pn_length);
+	  start = end;
+	}
+      else
+	start = adr;
+
+      printf (_("  Length:                              %ld\n"),
+	      (long) names.pn_length);
+      printf (_("  Version:                             %d\n"),
+	      names.pn_version);
+      printf (_("  Offset into .debug_info section:     0x%lx\n"),
+	      (unsigned long) names.pn_offset);
+      printf (_("  Size of area in .debug_info section: %ld\n"),
+	      (long) names.pn_size);
 
       if (names.pn_version != 2 && names.pn_version != 3)
 	{
@@ -3622,15 +3784,6 @@ display_debug_pubnames_worker (struct dwarf_section *section,
 	  continue;
 	}
 
-      printf (_("  Length:                              %ld\n"),
-	      (long) names.pn_length);
-      printf (_("  Version:                             %d\n"),
-	      names.pn_version);
-      printf (_("  Offset into .debug_info section:     0x%lx\n"),
-	      (unsigned long) names.pn_offset);
-      printf (_("  Size of area in .debug_info section: %ld\n"),
-	      (long) names.pn_size);
-
       if (is_gnu)
 	printf (_("\n    Offset  Kind          Name\n"));
       else
@@ -3648,7 +3801,7 @@ display_debug_pubnames_worker (struct dwarf_section *section,
 	      if (data >= end)
 		break;
 	      maxprint = (end - data) - 1;
-	      
+
 	      if (is_gnu)
 		{
 		  unsigned int kind_data;
@@ -3668,11 +3821,12 @@ display_debug_pubnames_worker (struct dwarf_section *section,
 		  kind_name = get_gdb_index_symbol_kind_name (kind);
 		  is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (kind_data);
 		  printf ("    %-6lx  %s,%-10s  %.*s\n",
-			  offset, is_static ? _("s") : _("g"),
+			  (unsigned long) offset, is_static ? _("s") : _("g"),
 			  kind_name, (int) maxprint, data);
 		}
 	      else
-		printf ("    %-6lx\t%.*s\n", offset, (int) maxprint, data);
+		printf ("    %-6lx\t%.*s\n",
+			(unsigned long) offset, (int) maxprint, data);
 
 	      data += strnlen ((char *) data, maxprint) + 1;
 	      if (data >= end)
@@ -4112,7 +4266,7 @@ display_debug_macro (struct dwarf_section *section,
 	}
 
       printf ("\n");
-    }	
+    }
 
   return 1;
 }
@@ -4167,24 +4321,36 @@ display_debug_abbrev (struct dwarf_section *section,
 
 static void
 display_loc_list (struct dwarf_section *section,
-                  unsigned char **start_ptr,
-                  int debug_info_entry,
-                  unsigned long offset,
-                  unsigned long base_address,
-                  int has_frame_base)
+		  unsigned char **start_ptr,
+		  unsigned int debug_info_entry,
+		  unsigned long offset,
+		  unsigned long base_address,
+		  int has_frame_base)
 {
   unsigned char *start = *start_ptr;
   unsigned char *section_end = section->start + section->size;
-  unsigned long cu_offset = debug_information [debug_info_entry].cu_offset;
-  unsigned int pointer_size = debug_information [debug_info_entry].pointer_size;
-  unsigned int offset_size = debug_information [debug_info_entry].offset_size;
-  int dwarf_version = debug_information [debug_info_entry].dwarf_version;
+  unsigned long cu_offset;
+  unsigned int pointer_size;
+  unsigned int offset_size;
+  int dwarf_version;
 
   dwarf_vma begin;
   dwarf_vma end;
   unsigned short length;
   int need_frame_base;
 
+  if (debug_info_entry >= num_debug_info_entries)
+    {
+      warn (_("No debug information available for loc lists of entry: %u\n"),
+	    debug_info_entry);
+      return;
+    }
+
+  cu_offset = debug_information [debug_info_entry].cu_offset;
+  pointer_size = debug_information [debug_info_entry].pointer_size;
+  offset_size = debug_information [debug_info_entry].offset_size;
+  dwarf_version = debug_information [debug_info_entry].dwarf_version;
+
   if (pointer_size < 2 || pointer_size > 8)
     {
       warn (_("Invalid pointer size (%d) in debug info for entry %d\n"),
@@ -4195,72 +4361,72 @@ display_loc_list (struct dwarf_section *section,
   while (1)
     {
       if (start + 2 * pointer_size > section_end)
-        {
-          warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
-                offset);
-          break;
-        }
+	{
+	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+		offset);
+	  break;
+	}
 
       printf ("    %8.8lx ", offset + (start - *start_ptr));
 
       /* 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.  */
+	 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);
 
       if (begin == 0 && end == 0)
-        {
-          printf (_("<End of list>\n"));
-          break;
-        }
+	{
+	  printf (_("<End of list>\n"));
+	  break;
+	}
 
       /* Check base address specifiers.  */
       if (begin == (dwarf_vma) -1 && end != (dwarf_vma) -1)
-        {
-          base_address = end;
-          print_dwarf_vma (begin, pointer_size);
-          print_dwarf_vma (end, pointer_size);
-          printf (_("(base address)\n"));
-          continue;
-        }
+	{
+	  base_address = end;
+	  print_dwarf_vma (begin, pointer_size);
+	  print_dwarf_vma (end, pointer_size);
+	  printf (_("(base address)\n"));
+	  continue;
+	}
 
       if (start + 2 > section_end)
-        {
-          warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
-                offset);
-          break;
-        }
+	{
+	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+		offset);
+	  break;
+	}
 
       SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);
 
       if (start + length > section_end)
-        {
-          warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
-                offset);
-          break;
-        }
+	{
+	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+		offset);
+	  break;
+	}
 
       print_dwarf_vma (begin + base_address, pointer_size);
       print_dwarf_vma (end + base_address, pointer_size);
 
       putchar ('(');
       need_frame_base = decode_location_expression (start,
-                                                    pointer_size,
-                                                    offset_size,
-                                                    dwarf_version,
-                                                    length,
-                                                    cu_offset, section);
+						    pointer_size,
+						    offset_size,
+						    dwarf_version,
+						    length,
+						    cu_offset, section);
       putchar (')');
 
       if (need_frame_base && !has_frame_base)
-        printf (_(" [without DW_AT_frame_base]"));
+	printf (_(" [without DW_AT_frame_base]"));
 
       if (begin == end)
-        fputs (_(" (start == end)"), stdout);
+	fputs (_(" (start == end)"), stdout);
       else if (begin > end)
-        fputs (_(" (start > end)"), stdout);
+	fputs (_(" (start > end)"), stdout);
 
       putchar ('\n');
 
@@ -4287,23 +4453,35 @@ print_addr_index (unsigned int idx, unsigned int len)
 
 static void
 display_loc_list_dwo (struct dwarf_section *section,
-                      unsigned char **start_ptr,
-                      int debug_info_entry,
-                      unsigned long offset,
-                      int has_frame_base)
+		      unsigned char **start_ptr,
+		      unsigned int debug_info_entry,
+		      unsigned long offset,
+		      int has_frame_base)
 {
   unsigned char *start = *start_ptr;
   unsigned char *section_end = section->start + section->size;
-  unsigned long cu_offset = debug_information [debug_info_entry].cu_offset;
-  unsigned int pointer_size = debug_information [debug_info_entry].pointer_size;
-  unsigned int offset_size = debug_information [debug_info_entry].offset_size;
-  int dwarf_version = debug_information [debug_info_entry].dwarf_version;
+  unsigned long cu_offset;
+  unsigned int pointer_size;
+  unsigned int offset_size;
+  int dwarf_version;
   int entry_type;
   unsigned short length;
   int need_frame_base;
   unsigned int idx;
   unsigned int bytes_read;
 
+  if (debug_info_entry >= num_debug_info_entries)
+    {
+      warn (_("No debug information for loc lists of entry: %u\n"),
+	    debug_info_entry);
+      return;
+    }
+
+  cu_offset = debug_information [debug_info_entry].cu_offset;
+  pointer_size = debug_information [debug_info_entry].pointer_size;
+  offset_size = debug_information [debug_info_entry].offset_size;
+  dwarf_version = debug_information [debug_info_entry].dwarf_version;
+
   if (pointer_size < 2 || pointer_size > 8)
     {
       warn (_("Invalid pointer size (%d) in debug info for entry %d\n"),
@@ -4316,79 +4494,79 @@ display_loc_list_dwo (struct dwarf_section *section,
       printf ("    %8.8lx ", offset + (start - *start_ptr));
 
       if (start >= section_end)
-        {
-          warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
-                offset);
-          break;
-        }
+	{
+	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+		offset);
+	  break;
+	}
 
       SAFE_BYTE_GET_AND_INC (entry_type, start, 1, section_end);
       switch (entry_type)
-        {
-          case 0: /* A terminating entry.  */
-            *start_ptr = start;
-	    printf (_("<End of list>\n"));
-            return;
-          case 1: /* A base-address entry.  */
-            idx = read_uleb128 (start, &bytes_read, section_end);
-            start += bytes_read;
-            print_addr_index (idx, 8);
-            printf ("         ");
-            printf (_("(base address selection entry)\n"));
-            continue;
-          case 2: /* A start/end entry.  */
-            idx = read_uleb128 (start, &bytes_read, section_end);
-            start += bytes_read;
-            print_addr_index (idx, 8);
-            idx = read_uleb128 (start, &bytes_read, section_end);
-            start += bytes_read;
-            print_addr_index (idx, 8);
-            break;
-          case 3: /* A start/length entry.  */
-            idx = read_uleb128 (start, &bytes_read, section_end);
-            start += bytes_read;
-            print_addr_index (idx, 8);
-	    SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
-            printf ("%08x ", idx);
-            break;
-          case 4: /* An offset pair entry.  */
-	    SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
-            printf ("%08x ", idx);
-	    SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
-            printf ("%08x ", idx);
-            break;
-          default:
-            warn (_("Unknown location list entry type 0x%x.\n"), entry_type);
-            *start_ptr = start;
-            return;
-        }
+	{
+	case 0: /* A terminating entry.  */
+	  *start_ptr = start;
+	  printf (_("<End of list>\n"));
+	  return;
+	case 1: /* A base-address entry.  */
+	  idx = read_uleb128 (start, &bytes_read, section_end);
+	  start += bytes_read;
+	  print_addr_index (idx, 8);
+	  printf ("         ");
+	  printf (_("(base address selection entry)\n"));
+	  continue;
+	case 2: /* A start/end entry.  */
+	  idx = read_uleb128 (start, &bytes_read, section_end);
+	  start += bytes_read;
+	  print_addr_index (idx, 8);
+	  idx = read_uleb128 (start, &bytes_read, section_end);
+	  start += bytes_read;
+	  print_addr_index (idx, 8);
+	  break;
+	case 3: /* A start/length entry.  */
+	  idx = read_uleb128 (start, &bytes_read, section_end);
+	  start += bytes_read;
+	  print_addr_index (idx, 8);
+	  SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
+	  printf ("%08x ", idx);
+	  break;
+	case 4: /* An offset pair entry.  */
+	  SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
+	  printf ("%08x ", idx);
+	  SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
+	  printf ("%08x ", idx);
+	  break;
+	default:
+	  warn (_("Unknown location list entry type 0x%x.\n"), entry_type);
+	  *start_ptr = start;
+	  return;
+	}
 
       if (start + 2 > section_end)
-        {
-          warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
-                offset);
-          break;
-        }
+	{
+	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+		offset);
+	  break;
+	}
 
       SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);
       if (start + length > section_end)
-        {
-          warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
-                offset);
-          break;
-        }
+	{
+	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+		offset);
+	  break;
+	}
 
       putchar ('(');
       need_frame_base = decode_location_expression (start,
-                                                    pointer_size,
-                                                    offset_size,
-                                                    dwarf_version,
-                                                    length,
-                                                    cu_offset, section);
+						    pointer_size,
+						    offset_size,
+						    dwarf_version,
+						    length,
+						    cu_offset, section);
       putchar (')');
 
       if (need_frame_base && !has_frame_base)
-        printf (_(" [without DW_AT_frame_base]"));
+	printf (_(" [without DW_AT_frame_base]"));
 
       putchar ('\n');
 
@@ -4536,11 +4714,11 @@ display_debug_loc (struct dwarf_section *section, void *file)
 	      if (start < next)
 		warn (_("There is a hole [0x%lx - 0x%lx] in .debug_loc section.\n"),
 		      (unsigned long) (start - section_begin),
-		      (unsigned long) (next - section_begin));
+		      (unsigned long) offset);
 	      else if (start > next)
 		warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_loc section.\n"),
 		      (unsigned long) (start - section_begin),
-		      (unsigned long) (next - section_begin));
+		      (unsigned long) offset);
 	    }
 	  start = next;
 
@@ -4551,11 +4729,11 @@ display_debug_loc (struct dwarf_section *section, void *file)
 	      continue;
 	    }
 
-          if (is_dwo)
-            display_loc_list_dwo (section, &start, i, offset, has_frame_base);
-          else
-            display_loc_list (section, &start, i, offset, base_address,
-                              has_frame_base);
+	  if (is_dwo)
+	    display_loc_list_dwo (section, &start, i, offset, has_frame_base);
+	  else
+	    display_loc_list (section, &start, i, offset, base_address,
+			      has_frame_base);
 	}
     }
 
@@ -4740,7 +4918,13 @@ display_debug_aranges (struct dwarf_section *section,
       if (excess)
 	addr_ranges += (2 * address_size) - excess;
 
-      start += arange.ar_length + initial_length_size;
+      hdrptr = start + arange.ar_length + initial_length_size;
+      if (hdrptr < start || hdrptr > end)
+	{
+	  error (_("Excessive header length: %lx\n"), (long) arange.ar_length);
+	  break;
+	}
+      start = hdrptr;
 
       while (addr_ranges + 2 * address_size <= start)
 	{
@@ -4771,7 +4955,7 @@ comp_addr_base (const void * v0, const void * v1)
 /* Display the debug_addr section.  */
 static int
 display_debug_addr (struct dwarf_section *section,
-                    void *file)
+		    void *file)
 {
   debug_info **debug_addr_info;
   unsigned char *entry;
@@ -4794,42 +4978,51 @@ display_debug_addr (struct dwarf_section *section,
 
   printf (_("Contents of the %s section:\n\n"), section->name);
 
-  debug_addr_info = (debug_info **) xmalloc ((num_debug_info_entries + 1)
-                                             * sizeof (debug_info *));
+  /* PR  17531: file: cf38d01b.
+     We use xcalloc because a corrupt file may not have initialised all of the
+     fields in the debug_info structure, which means that the sort below might
+     try to move uninitialised data.  */
+  debug_addr_info = (debug_info **) xcalloc ((num_debug_info_entries + 1),
+					     sizeof (debug_info *));
 
   count = 0;
   for (i = 0; i < num_debug_info_entries; i++)
-    {
-      if (debug_information [i].addr_base != DEBUG_INFO_UNAVAILABLE)
-        debug_addr_info [count++] = &debug_information [i];
-    }
+    if (debug_information [i].addr_base != DEBUG_INFO_UNAVAILABLE)
+      {
+	/* PR 17531: file: cf38d01b.  */
+	if (debug_information[i].addr_base >= section->size)
+	  warn (_("Corrupt address base (%lx) found in debug section %u\n"),
+		(unsigned long) debug_information[i].addr_base, i);
+	else
+	  debug_addr_info [count++] = debug_information + i;
+      }
 
   /* Add a sentinel to make iteration convenient.  */
   debug_addr_info [count] = (debug_info *) xmalloc (sizeof (debug_info));
   debug_addr_info [count]->addr_base = section->size;
-
   qsort (debug_addr_info, count, sizeof (debug_info *), comp_addr_base);
+
   for (i = 0; i < count; i++)
     {
       unsigned int idx;
       unsigned int address_size = debug_addr_info [i]->pointer_size;
 
       printf (_("  For compilation unit at offset 0x%s:\n"),
-              dwarf_vmatoa ("x", debug_addr_info [i]->cu_offset));
+	      dwarf_vmatoa ("x", debug_addr_info [i]->cu_offset));
 
       printf (_("\tIndex\tAddress\n"));
       entry = section->start + debug_addr_info [i]->addr_base;
       end = section->start + debug_addr_info [i + 1]->addr_base;
       idx = 0;
       while (entry < end)
-        {
-          dwarf_vma base = byte_get (entry, address_size);
-          printf (_("\t%d:\t"), idx);
-          print_dwarf_vma (base, address_size);
-          printf ("\n");
-          entry += address_size;
-          idx++;
-        }
+	{
+	  dwarf_vma base = byte_get (entry, address_size);
+	  printf (_("\t%d:\t"), idx);
+	  print_dwarf_vma (base, address_size);
+	  printf ("\n");
+	  entry += address_size;
+	  idx++;
+	}
     }
   printf ("\n");
 
@@ -4840,7 +5033,7 @@ display_debug_addr (struct dwarf_section *section,
 /* Display the .debug_str_offsets and .debug_str_offsets.dwo sections.  */
 static int
 display_debug_str_offsets (struct dwarf_section *section,
-                           void *file ATTRIBUTE_UNUSED)
+			   void *file ATTRIBUTE_UNUSED)
 {
   if (section->size == 0)
     {
@@ -4909,7 +5102,7 @@ display_debug_ranges (struct dwarf_section *section,
   if (num_range_list == 0)
     {
       /* This can happen when the file was compiled with -gsplit-debug
-         which removes references to range lists from the primary .o file.  */
+	 which removes references to range lists from the primary .o file.  */
       printf (_("No range lists in .debug_info section.\n"));
       return 1;
     }
@@ -4962,7 +5155,7 @@ display_debug_ranges (struct dwarf_section *section,
 		pointer_size, offset);
 	  continue;
 	}
-      
+
       if (dwarf_check != 0 && i > 0)
 	{
 	  if (start < next)
@@ -5036,7 +5229,7 @@ typedef struct Frame_Chunk
 {
   struct Frame_Chunk *next;
   unsigned char *chunk_start;
-  int ncols;
+  unsigned int ncols;
   /* DW_CFA_{undefined,same_value,offset,register,unreferenced}  */
   short int *col_type;
   int *col_offset;
@@ -5046,8 +5239,8 @@ typedef struct Frame_Chunk
   dwarf_vma pc_begin;
   dwarf_vma pc_range;
   int cfa_reg;
-  int cfa_offset;
-  int ra;
+  dwarf_vma cfa_offset;
+  unsigned int ra;
   unsigned char fde_encoding;
   unsigned char cfa_exp;
   unsigned char ptr_size;
@@ -5062,13 +5255,13 @@ static unsigned int dwarf_regnames_count;
    in the frame info.  */
 #define DW_CFA_unreferenced (-1)
 
-/* Return 0 if not more space is needed, 1 if more space is needed,
+/* Return 0 if no more space is needed, 1 if more space is needed,
    -1 for invalid reg.  */
 
 static int
 frame_need_space (Frame_Chunk *fc, unsigned int reg)
 {
-  int prev = fc->ncols;
+  unsigned int prev = fc->ncols;
 
   if (reg < (unsigned int) fc->ncols)
     return 0;
@@ -5078,10 +5271,25 @@ frame_need_space (Frame_Chunk *fc, unsigned int reg)
     return -1;
 
   fc->ncols = reg + 1;
+  /* PR 17512: file: 10450-2643-0.004.
+     If reg == -1 then this can happen...  */
+  if (fc->ncols == 0)
+    return -1;
+
+  /* PR 17512: file: 2844a11d.  */
+  if (fc->ncols > 1024)
+    {
+      error (_("Unfeasibly large register number: %u\n"), reg);
+      fc->ncols = 0;
+      /* FIXME: 1024 is an arbitrary limit.  Increase it if
+	 we ever encounter a valid binary that exceeds it.  */
+      return -1;
+    }
+
   fc->col_type = (short int *) xcrealloc (fc->col_type, fc->ncols,
-                                          sizeof (short int));
+					  sizeof (short int));
   fc->col_offset = (int *) xcrealloc (fc->col_offset, fc->ncols, sizeof (int));
-  /* PR 17512: file:002-10025-0.005.  */ 
+  /* PR 17512: file:002-10025-0.005.  */
   if (fc->col_type == NULL || fc->col_offset == NULL)
     {
       error (_("Out of memory allocating %u columns in dwarf frame arrays\n"),
@@ -5171,16 +5379,16 @@ init_dwarf_regnames_x86_64 (void)
 
 static const char *const dwarf_regnames_aarch64[] =
 {
-   "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7", 
-   "x8",  "x9", "x10", "x11", "x12", "x13", "x14", "x15", 
+   "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7",
+   "x8",  "x9", "x10", "x11", "x12", "x13", "x14", "x15",
   "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
   "x24", "x25", "x26", "x27", "x28", "x29", "x30", "sp",
    NULL, "elr",  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
    NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
    NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
    NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
-   "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7", 
-   "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15", 
+   "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",
+   "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",
   "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
   "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
 };
@@ -5236,9 +5444,9 @@ regname (unsigned int regno, int row)
 }
 
 static void
-frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
+frame_display_row (Frame_Chunk *fc, int *need_col_headers, unsigned int *max_regs)
 {
-  int r;
+  unsigned int r;
   char tmp[100];
 
   if (*max_regs < fc->ncols)
@@ -5268,7 +5476,7 @@ frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
   if (fc->cfa_exp)
     strcpy (tmp, "exp");
   else
-    sprintf (tmp, "%s%+d", regname (fc->cfa_reg, 1), fc->cfa_offset);
+    sprintf (tmp, "%s%+d", regname (fc->cfa_reg, 1), (int) fc->cfa_offset);
   printf ("%-8s ", tmp);
 
   for (r = 0; r < fc->ncols; r++)
@@ -5354,7 +5562,20 @@ read_cie (unsigned char *start, unsigned char *end,
   if (version >= 4)
     {
       GET (fc->ptr_size, 1);
+      if (fc->ptr_size < 1 || fc->ptr_size > 8)
+	{
+	  warn (_("Invalid pointer size (%d) in CIE data\n"), fc->ptr_size);
+	  return end;
+	}
+
       GET (fc->segment_size, 1);
+      /* PR 17512: file: e99d2804.  */
+      if (fc->segment_size > 8 || fc->segment_size + fc->ptr_size > 8)
+	{
+	  warn (_("Invalid segment size (%d) in CIE data\n"), fc->segment_size);
+	  return end;
+	}
+
       eh_addr_size = fc->ptr_size;
     }
   else
@@ -5378,15 +5599,32 @@ read_cie (unsigned char *start, unsigned char *end,
       augmentation_data_len = LEB ();
       augmentation_data = start;
       start += augmentation_data_len;
+      /* PR 17512: file: 11042-2589-0.004.  */
+      if (start > end)
+	{
+	  warn (_("Augmentation data too long: 0x%lx\n"), augmentation_data_len);
+	  return end;
+	}
     }
 
   if (augmentation_data_len)
     {
-      unsigned char *p, *q;
+      unsigned char *p;
+      unsigned char *q;
+      unsigned char *qend;
+
       p = (unsigned char *) fc->augmentation + 1;
       q = augmentation_data;
+      qend = q + augmentation_data_len;
 
-      while (1)
+      /* PR 17531: file: 015adfaa.  */
+      if (qend < q)
+	{
+	  warn (_("Negative augmentation data length: 0x%lx"), augmentation_data_len);
+	  augmentation_data_len = 0;
+	}
+
+      while (p < end && q < augmentation_data + augmentation_data_len)
 	{
 	  if (*p == 'L')
 	    q++;
@@ -5400,6 +5638,8 @@ read_cie (unsigned char *start, unsigned char *end,
 	    break;
 	  p++;
 	}
+      /* Note - it is OK if this loop terminates with q < qend.
+	 Padding may have been inserted to align the end of the CIE.  */
     }
 
   *p_cie = fc;
@@ -5425,9 +5665,9 @@ display_debug_frames (struct dwarf_section *section,
   Frame_Chunk *rs;
   int is_eh = strcmp (section->name, ".eh_frame") == 0;
   unsigned int length_return;
-  int max_regs = 0;
+  unsigned int max_regs = 0;
   const char *bad_reg = _("bad register: ");
-  int saved_eh_addr_size = eh_addr_size;
+  unsigned int saved_eh_addr_size = eh_addr_size;
 
   printf (_("Contents of the %s section:\n"), section->name);
 
@@ -5454,6 +5694,12 @@ display_debug_frames (struct dwarf_section *section,
 	{
 	  printf ("\n%08lx ZERO terminator\n\n",
 		    (unsigned long)(saved_start - section_start));
+	  /* Skip any zero terminators that directly follow.
+	     A corrupt section size could have loaded a whole
+	     slew of zero filled memory bytes.  eg
+	     PR 17512: file: 070-19381-0.004.  */
+	  while (start < end && * start == 0)
+	    ++ start;
 	  continue;
 	}
 
@@ -5484,21 +5730,23 @@ display_debug_frames (struct dwarf_section *section,
 				   || (offset_size == 8 && cie_id == DW64_CIE_ID)))
 	{
 	  int version;
-	  int mreg;
+	  unsigned int mreg;
 
 	  start = read_cie (start, end, &cie, &version,
 			    &augmentation_data_len, &augmentation_data);
 	  /* PR 17512: file: 027-135133-0.005.  */
 	  if (cie == NULL)
 	    break;
+
 	  fc = cie;
 	  fc->next = chunks;
 	  chunks = fc;
 	  fc->chunk_start = saved_start;
-	  mreg = max_regs - 1;
+	  mreg = max_regs > 0 ? max_regs - 1 : 0;
 	  if (mreg < fc->ra)
 	    mreg = fc->ra;
-	  frame_need_space (fc, mreg);
+	  if (frame_need_space (fc, mreg) < 0)
+	    break;
 	  if (fc->fde_encoding)
 	    encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
 
@@ -5528,8 +5776,11 @@ display_debug_frames (struct dwarf_section *section,
 	      if (augmentation_data_len)
 		{
 		  unsigned long i;
+
 		  printf ("  Augmentation data:    ");
 		  for (i = 0; i < augmentation_data_len; ++i)
+		    /* FIXME: If do_wide is FALSE, then we should
+		       add carriage returns at 80 columns...  */
 		    printf (" %02x", augmentation_data[i]);
 		  putchar ('\n');
 		}
@@ -5585,17 +5836,27 @@ display_debug_frames (struct dwarf_section *section,
 			     || (off_size == 8 && c_id == DW64_CIE_ID)))
 			{
 			  int version;
-			  int mreg;
+			  unsigned int mreg;
 
 			  read_cie (cie_scan, end, &cie, &version,
 				    &augmentation_data_len, &augmentation_data);
+			  /* PR 17512: file: 3450-2098-0.004.  */
+			  if (cie == NULL)
+			    {
+			      warn (_("Failed to read CIE information\n"));
+			      break;
+			    }
 			  cie->next = forward_refs;
 			  forward_refs = cie;
 			  cie->chunk_start = look_for;
-			  mreg = max_regs - 1;
+			  mreg = max_regs > 0 ? max_regs - 1 : 0;
 			  if (mreg < cie->ra)
 			    mreg = cie->ra;
-			  frame_need_space (cie, mreg);
+			  if (frame_need_space (cie, mreg) < 0)
+			    {
+			      warn (_("Invalid max register\n"));
+			      break;
+			    }
 			  if (cie->fde_encoding)
 			    encoded_ptr_size
 			      = size_of_encoded_value (cie->fde_encoding);
@@ -5615,7 +5876,11 @@ display_debug_frames (struct dwarf_section *section,
 	      fc->ncols = 0;
 	      fc->col_type = (short int *) xmalloc (sizeof (short int));
 	      fc->col_offset = (int *) xmalloc (sizeof (int));
-	      frame_need_space (fc, max_regs - 1);
+	      if (frame_need_space (fc, max_regs > 0 ? max_regs - 1 : 0) < 0)
+		{
+		  warn (_("Invalid max register\n"));
+		  break;
+		}
 	      cie = fc;
 	      fc->augmentation = "";
 	      fc->fde_encoding = 0;
@@ -5638,7 +5903,11 @@ display_debug_frames (struct dwarf_section *section,
 	      fc->cfa_reg = cie->cfa_reg;
 	      fc->cfa_offset = cie->cfa_offset;
 	      fc->ra = cie->ra;
-	      frame_need_space (fc, max_regs - 1);
+	      if (frame_need_space (fc, max_regs > 0 ? max_regs - 1: 0) < 0)
+		{
+		  warn (_("Invalid max register\n"));
+		  break;
+		}
 	      fc->fde_encoding = cie->fde_encoding;
 	    }
 
@@ -5647,7 +5916,15 @@ display_debug_frames (struct dwarf_section *section,
 
 	  segment_selector = 0;
 	  if (fc->segment_size)
-	    SAFE_BYTE_GET_AND_INC (segment_selector, start, fc->segment_size, end);
+	    {
+	      if (fc->segment_size > sizeof (segment_selector))
+		{
+		  /* PR 17512: file: 9e196b3e.  */
+		  warn (_("Probably corrupt segment size: %d - using 4 instead\n"), fc->segment_size);
+		  fc->segment_size = 4;
+		}
+	      SAFE_BYTE_GET_AND_INC (segment_selector, start, fc->segment_size, end);
+	    }
 
 	  fc->pc_begin = get_encoded_value (&start, fc->fde_encoding, section, end);
 
@@ -5662,6 +5939,15 @@ display_debug_frames (struct dwarf_section *section,
 	      augmentation_data_len = LEB ();
 	      augmentation_data = start;
 	      start += augmentation_data_len;
+	      /* PR 17512: file: 722-8446-0.004.  */
+	      if (start >= end || ((signed long) augmentation_data_len) < 0)
+		{
+		  warn (_("Corrupt augmentation data length: %lx\n"),
+			augmentation_data_len);
+		  start = end;
+		  augmentation_data = NULL;
+		  augmentation_data_len = 0;
+		}
 	    }
 
 	  printf ("\n%08lx %s %s FDE cie=%08lx pc=",
@@ -5706,6 +5992,7 @@ display_debug_frames (struct dwarf_section *section,
 	    {
 	      unsigned int reg, op, opa;
 	      unsigned long temp;
+	      unsigned char * new_start;
 
 	      op = *start++;
 	      opa = op & 0x3f;
@@ -5747,7 +6034,6 @@ display_debug_frames (struct dwarf_section *section,
 		  break;
 		case DW_CFA_restore_extended:
 		  reg = LEB ();
-		  frame_need_space (fc, reg);
 		  if (frame_need_space (fc, reg) >= 0)
 		    fc->col_type[reg] = DW_CFA_undefined;
 		  break;
@@ -5777,26 +6063,28 @@ display_debug_frames (struct dwarf_section *section,
 		  break;
 		case DW_CFA_def_cfa_expression:
 		  temp = LEB ();
-		  if (start + temp < start)
+		  new_start = start + temp;
+		  if (new_start < start)
 		    {
 		      warn (_("Corrupt CFA_def expression value: %lu\n"), temp);
 		      start = block_end;
 		    }
 		  else
-		    start += temp;
+		    start = new_start;
 		  break;
 		case DW_CFA_expression:
 		case DW_CFA_val_expression:
 		  reg = LEB ();
 		  temp = LEB ();
-		  if (start + temp < start)
+		  new_start = start + temp;
+		  if (new_start < start)
 		    {
-		      /* PR 17512: file:306-192417-0.005.  */ 
+		      /* PR 17512: file:306-192417-0.005.  */
 		      warn (_("Corrupt CFA expression value: %lu\n"), temp);
 		      start = block_end;
 		    }
 		  else
-		    start += temp;
+		    start = new_start;
 		  if (frame_need_space (fc, reg) >= 0)
 		    fc->col_type[reg] = DW_CFA_undefined;
 		  break;
@@ -5835,9 +6123,10 @@ display_debug_frames (struct dwarf_section *section,
 
       while (start < block_end)
 	{
+	  unsigned char * tmp;
 	  unsigned op, opa;
 	  unsigned long ul, reg, roffs;
-	  long l;
+	  dwarf_vma l;
 	  dwarf_vma ofs;
 	  dwarf_vma vma;
 	  const char *reg_prefix = "";
@@ -5857,7 +6146,7 @@ display_debug_frames (struct dwarf_section *section,
 	      else
 		printf ("  DW_CFA_advance_loc: %d to %s\n",
 			opa * fc->code_factor,
-			dwarf_vmatoa_1 (NULL, 
+			dwarf_vmatoa_1 (NULL,
 					fc->pc_begin + opa * fc->code_factor,
 					fc->ptr_size));
 	      fc->pc_begin += opa * fc->code_factor;
@@ -5896,7 +6185,7 @@ display_debug_frames (struct dwarf_section *section,
 	      break;
 
 	    case DW_CFA_set_loc:
-	      vma = get_encoded_value (&start, fc->fde_encoding, section, end);
+	      vma = get_encoded_value (&start, fc->fde_encoding, section, block_end);
 	      if (do_debug_frames_interp)
 		frame_display_row (fc, &need_col_headers, &max_regs);
 	      else
@@ -5919,7 +6208,7 @@ display_debug_frames (struct dwarf_section *section,
 	      break;
 
 	    case DW_CFA_advance_loc2:
-	      SAFE_BYTE_GET_AND_INC (ofs, start, 2, end);
+	      SAFE_BYTE_GET_AND_INC (ofs, start, 2, block_end);
 	      if (do_debug_frames_interp)
 		frame_display_row (fc, &need_col_headers, &max_regs);
 	      else
@@ -5932,7 +6221,7 @@ display_debug_frames (struct dwarf_section *section,
 	      break;
 
 	    case DW_CFA_advance_loc4:
-	      SAFE_BYTE_GET_AND_INC (ofs, start, 4, end);
+	      SAFE_BYTE_GET_AND_INC (ofs, start, 4, block_end);
 	      if (do_debug_frames_interp)
 		frame_display_row (fc, &need_col_headers, &max_regs);
 	      else
@@ -6041,13 +6330,13 @@ display_debug_frames (struct dwarf_section *section,
 	      if (! do_debug_frames_interp)
 		printf ("  DW_CFA_remember_state\n");
 	      rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
-              rs->cfa_offset = fc->cfa_offset;
+	      rs->cfa_offset = fc->cfa_offset;
 	      rs->cfa_reg = fc->cfa_reg;
 	      rs->ra = fc->ra;
 	      rs->cfa_exp = fc->cfa_exp;
 	      rs->ncols = fc->ncols;
 	      rs->col_type = (short int *) xcmalloc (rs->ncols,
-                                                     sizeof (* rs->col_type));
+						     sizeof (* rs->col_type));
 	      rs->col_offset = (int *) xcmalloc (rs->ncols, sizeof (* rs->col_offset));
 	      memcpy (rs->col_type, fc->col_type, rs->ncols * sizeof (* fc->col_type));
 	      memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (* fc->col_offset));
@@ -6064,9 +6353,14 @@ display_debug_frames (struct dwarf_section *section,
 		  remembered_state = rs->next;
 		  fc->cfa_offset = rs->cfa_offset;
 		  fc->cfa_reg = rs->cfa_reg;
-	          fc->ra = rs->ra;
-	          fc->cfa_exp = rs->cfa_exp;
-		  frame_need_space (fc, rs->ncols - 1);
+		  fc->ra = rs->ra;
+		  fc->cfa_exp = rs->cfa_exp;
+		  if (frame_need_space (fc, rs->ncols - 1) < 0)
+		    {
+		      warn (_("Invalid column number in saved frame state\n"));
+		      fc->ncols = 0;
+		      break;
+		    }
 		  memcpy (fc->col_type, rs->col_type, rs->ncols * sizeof (* rs->col_type));
 		  memcpy (fc->col_offset, rs->col_offset,
 			  rs->ncols * sizeof (* rs->col_offset));
@@ -6084,7 +6378,7 @@ display_debug_frames (struct dwarf_section *section,
 	      fc->cfa_exp = 0;
 	      if (! do_debug_frames_interp)
 		printf ("  DW_CFA_def_cfa: %s ofs %d\n",
-			regname (fc->cfa_reg, 0), fc->cfa_offset);
+			regname (fc->cfa_reg, 0), (int) fc->cfa_offset);
 	      break;
 
 	    case DW_CFA_def_cfa_register:
@@ -6098,7 +6392,7 @@ display_debug_frames (struct dwarf_section *section,
 	    case DW_CFA_def_cfa_offset:
 	      fc->cfa_offset = LEB ();
 	      if (! do_debug_frames_interp)
-		printf ("  DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
+		printf ("  DW_CFA_def_cfa_offset: %d\n", (int) fc->cfa_offset);
 	      break;
 
 	    case DW_CFA_nop:
@@ -6108,6 +6402,11 @@ display_debug_frames (struct dwarf_section *section,
 
 	    case DW_CFA_def_cfa_expression:
 	      ul = LEB ();
+	      if (start >= block_end || start + ul > block_end || start + ul < start)
+		{
+		  printf (_("  DW_CFA_def_cfa_expression: <corrupt len %lu>\n"), ul);
+		  break;
+		}
 	      if (! do_debug_frames_interp)
 		{
 		  printf ("  DW_CFA_def_cfa_expression (");
@@ -6124,6 +6423,14 @@ display_debug_frames (struct dwarf_section *section,
 	      ul = LEB ();
 	      if (reg >= (unsigned int) fc->ncols)
 		reg_prefix = bad_reg;
+	      /* PR 17512: file: 069-133014-0.006.  */
+	      /* PR 17512: file: 98c02eb4.  */
+	      tmp = start + ul;
+	      if (start >= block_end || tmp > block_end || tmp < start)
+		{
+		  printf (_("  DW_CFA_expression: <corrupt len %lu>\n"), ul);
+		  break;
+		}
 	      if (! do_debug_frames_interp || *reg_prefix != '\0')
 		{
 		  printf ("  DW_CFA_expression: %s%s (",
@@ -6134,7 +6441,7 @@ display_debug_frames (struct dwarf_section *section,
 		}
 	      if (*reg_prefix == '\0')
 		fc->col_type[reg] = DW_CFA_expression;
-	      start += ul;
+	      start = tmp;
 	      break;
 
 	    case DW_CFA_val_expression:
@@ -6142,6 +6449,12 @@ display_debug_frames (struct dwarf_section *section,
 	      ul = LEB ();
 	      if (reg >= (unsigned int) fc->ncols)
 		reg_prefix = bad_reg;
+	      tmp = start + ul;
+	      if (start >= block_end || tmp > block_end || tmp < start)
+		{
+		  printf ("  DW_CFA_val_expression: <corrupt len %lu>\n", ul);
+		  break;
+		}
 	      if (! do_debug_frames_interp || *reg_prefix != '\0')
 		{
 		  printf ("  DW_CFA_val_expression: %s%s (",
@@ -6152,7 +6465,7 @@ display_debug_frames (struct dwarf_section *section,
 		}
 	      if (*reg_prefix == '\0')
 		fc->col_type[reg] = DW_CFA_val_expression;
-	      start += ul;
+	      start = tmp;
 	      break;
 
 	    case DW_CFA_offset_extended_sf:
@@ -6163,7 +6476,7 @@ display_debug_frames (struct dwarf_section *section,
 	      if (! do_debug_frames_interp || *reg_prefix != '\0')
 		printf ("  DW_CFA_offset_extended_sf: %s%s at cfa%+ld\n",
 			reg_prefix, regname (reg, 0),
-			l * fc->data_factor);
+			(long)(l * fc->data_factor));
 	      if (*reg_prefix == '\0')
 		{
 		  fc->col_type[reg] = DW_CFA_offset;
@@ -6179,7 +6492,7 @@ display_debug_frames (struct dwarf_section *section,
 	      if (! do_debug_frames_interp || *reg_prefix != '\0')
 		printf ("  DW_CFA_val_offset_sf: %s%s at cfa%+ld\n",
 			reg_prefix, regname (reg, 0),
-			l * fc->data_factor);
+			(long)(l * fc->data_factor));
 	      if (*reg_prefix == '\0')
 		{
 		  fc->col_type[reg] = DW_CFA_val_offset;
@@ -6194,18 +6507,18 @@ display_debug_frames (struct dwarf_section *section,
 	      fc->cfa_exp = 0;
 	      if (! do_debug_frames_interp)
 		printf ("  DW_CFA_def_cfa_sf: %s ofs %d\n",
-			regname (fc->cfa_reg, 0), fc->cfa_offset);
+			regname (fc->cfa_reg, 0), (int) fc->cfa_offset);
 	      break;
 
 	    case DW_CFA_def_cfa_offset_sf:
 	      fc->cfa_offset = SLEB ();
-	      fc->cfa_offset = fc->cfa_offset * fc->data_factor;
+	      fc->cfa_offset *= fc->data_factor;
 	      if (! do_debug_frames_interp)
-		printf ("  DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
+		printf ("  DW_CFA_def_cfa_offset_sf: %d\n", (int) fc->cfa_offset);
 	      break;
 
 	    case DW_CFA_MIPS_advance_loc8:
-	      SAFE_BYTE_GET_AND_INC (ofs, start, 8, end);
+	      SAFE_BYTE_GET_AND_INC (ofs, start, 8, block_end);
 	      if (do_debug_frames_interp)
 		frame_display_row (fc, &need_col_headers, &max_regs);
 	      else
@@ -6236,7 +6549,7 @@ display_debug_frames (struct dwarf_section *section,
 	      if (! do_debug_frames_interp || *reg_prefix != '\0')
 		printf ("  DW_CFA_GNU_negative_offset_extended: %s%s at cfa%+ld\n",
 			reg_prefix, regname (reg, 0),
-			l * fc->data_factor);
+			(long)(l * fc->data_factor));
 	      if (*reg_prefix == '\0')
 		{
 		  fc->col_type[reg] = DW_CFA_offset;
@@ -6332,9 +6645,42 @@ display_gdb_index (struct dwarf_section *section,
       return 0;
     }
 
+  /* PR 17531: file: 418d0a8a.  */
+  if (tu_list_offset < cu_list_offset)
+    {
+      warn (_("TU offset (%x) is less than CU offset (%x)\n"),
+	    tu_list_offset, cu_list_offset);
+      return 0;
+    }
+
   cu_list_elements = (tu_list_offset - cu_list_offset) / 8;
+
+  if (address_table_offset < tu_list_offset)
+    {
+      warn (_("Address table offset (%x) is less than TU offset (%x)\n"),
+	    address_table_offset, tu_list_offset);
+      return 0;
+    }
+
   tu_list_elements = (address_table_offset - tu_list_offset) / 8;
+
+  /* PR 17531: file: 18a47d3d.  */
+  if (symbol_table_offset < address_table_offset)
+    {
+      warn (_("Symbol table offset (%xl) is less then Address table offset (%x)\n"),
+	    symbol_table_offset, address_table_offset);
+      return 0;
+    }
+
   address_table_size = symbol_table_offset - address_table_offset;
+
+  if (constant_pool_offset < symbol_table_offset)
+    {
+      warn (_("Constant pool offset (%x) is less than symbol table offset (%x)\n"),
+	    constant_pool_offset, symbol_table_offset);
+      return 0;
+    }
+
   symbol_table_slots = (constant_pool_offset - symbol_table_offset) / 8;
 
   cu_list = start + cu_list_offset;
@@ -6343,6 +6689,12 @@ display_gdb_index (struct dwarf_section *section,
   symbol_table = start + symbol_table_offset;
   constant_pool = start + constant_pool_offset;
 
+  if (address_table + address_table_size * (2 + 8 + 4) > section->start + section->size)
+    {
+      warn (_("Address table extends beyond end of section.\n"));
+      return 0;
+    }
+
   printf (_("\nCU table:\n"));
   for (i = 0; i < cu_list_elements; i += 2)
     {
@@ -6369,7 +6721,8 @@ display_gdb_index (struct dwarf_section *section,
     }
 
   printf (_("\nAddress table:\n"));
-  for (i = 0; i < address_table_size; i += 2 * 8 + 4)
+  for (i = 0; i < address_table_size && i <= address_table_size - (2 * 8 + 4);
+       i += 2 * 8 + 4)
     {
       uint64_t low = byte_get_little_endian (address_table + i, 8);
       uint64_t high = byte_get_little_endian (address_table + i + 8, 8);
@@ -6391,11 +6744,46 @@ display_gdb_index (struct dwarf_section *section,
 	  || cu_vector_offset != 0)
 	{
 	  unsigned int j;
+	  unsigned char * adr;
+
+	  adr = constant_pool + name_offset;
+	  /* PR 17531: file: 5b7b07ad.  */
+	  if (adr < constant_pool || adr >= section->start + section->size)
+	    {
+	      printf (_("[%3u] <corrupt offset: %x>"), i, name_offset);
+	      warn (_("Corrupt name offset of 0x%x found for symbol table slot %d\n"),
+		    name_offset, i);
+	    }
+	  else
+	    printf ("[%3u] %.*s:", i,
+		    (int) (section->size - (constant_pool_offset + name_offset)),
+		    constant_pool + name_offset);
+
+	  adr = constant_pool + cu_vector_offset;
+	  if (adr < constant_pool || adr >= section->start + section->size - 3)
+	    {
+	      printf (_("<invalid CU vector offset: %x>\n"), cu_vector_offset);
+	      warn (_("Corrupt CU vector offset of 0x%x found for symbol table slot %d\n"),
+		    cu_vector_offset, i);
+	      continue;
+	    }
+
+	  num_cus = byte_get_little_endian (adr, 4);
+
+	  adr = constant_pool + cu_vector_offset + 4 + num_cus * 4;
+	  if (num_cus * 4 < num_cus
+	      || adr >= section->start + section->size
+	      || adr < constant_pool)
+	    {
+	      printf ("<invalid number of CUs: %d>\n", num_cus);
+	      warn (_("Invalid number of CUs (0x%x) for symbol table slot %d\n"),
+		    num_cus, i);
+	      continue;
+	    }
 
-	  printf ("[%3u] %s:", i, constant_pool + name_offset);
-	  num_cus = byte_get_little_endian (constant_pool + cu_vector_offset, 4);
 	  if (num_cus > 1)
 	    printf ("\n");
+
 	  for (j = 0; j < num_cus; ++j)
 	    {
 	      int is_static;
@@ -6494,7 +6882,7 @@ get_DW_SECT_short_name (unsigned int dw_sect)
       case DW_SECT_MACRO:
 	return "macro";
       default:
-        break;
+	break;
     }
 
   snprintf (buf, sizeof (buf), "%d", dw_sect);
@@ -6523,15 +6911,38 @@ process_cu_tu_index (struct dwarf_section *section, int do_display)
   dwarf_vma signature_low;
   char buf[64];
 
-  version = byte_get (phdr, 4);
+  /* PR 17512: file: 002-168123-0.004.  */
+  if (phdr == NULL)
+    {
+      warn (_("Section %s is empty\n"), section->name);
+      return 0;
+    }
+  /* PR 17512: file: 002-376-0.004.  */
+  if (section->size < 24)
+    {
+      warn (_("Section %s is too small to contain a CU/TU header\n"),
+	    section->name);
+      return 0;
+    }
+
+  SAFE_BYTE_GET (version, phdr, 4, limit);
   if (version >= 2)
-    ncols = byte_get (phdr + 4, 4);
-  nused = byte_get (phdr + 8, 4);
-  nslots = byte_get (phdr + 12, 4);
+    SAFE_BYTE_GET (ncols, phdr + 4, 4, limit);
+  SAFE_BYTE_GET (nused, phdr + 8, 4, limit);
+  SAFE_BYTE_GET (nslots, phdr + 12, 4, limit);
+
   phash = phdr + 16;
   pindex = phash + nslots * 8;
   ppool = pindex + nslots * 4;
 
+  /* PR 17531: file: 45d69832.  */
+  if (pindex < phash || ppool < phdr || (pindex == phash && nslots != 0))
+    {
+      warn (_("Section %s is too small for %d slots\n"),
+	    section->name, nslots);
+      return 0;
+    }
+
   if (do_display)
     {
       printf (_("Contents of the %s section:\n\n"), section->name);
@@ -6542,7 +6953,7 @@ process_cu_tu_index (struct dwarf_section *section, int do_display)
       printf (_("  Number of slots:         %d\n\n"), nslots);
     }
 
-  if (ppool > limit)
+  if (ppool > limit || ppool < phdr)
     {
       warn (_("Section %s too small for %d hash table entries\n"),
 	    section->name, nslots);
@@ -6558,11 +6969,18 @@ process_cu_tu_index (struct dwarf_section *section, int do_display)
 	  unsigned char *shndx_list;
 	  unsigned int shndx;
 
-	  byte_get_64 (phash, &signature_high, &signature_low);
+	  SAFE_BYTE_GET64 (phash, &signature_high, &signature_low, limit);
 	  if (signature_high != 0 || signature_low != 0)
 	    {
-	      j = byte_get (pindex, 4);
+	      SAFE_BYTE_GET (j, pindex, 4, limit);
 	      shndx_list = ppool + j * 4;
+	      /* PR 17531: file: 705e010d.  */
+	      if (shndx_list < ppool)
+		{
+		  warn (_("Section index pool located before start of section\n"));
+		  return 0;
+		}
+
 	      if (do_display)
 		printf (_("  [%3d] Signature:  0x%s  Sections: "),
 			i, dwarf_vmatoa64 (signature_high, signature_low,
@@ -6575,7 +6993,7 @@ process_cu_tu_index (struct dwarf_section *section, int do_display)
 			    section->name);
 		      return 0;
 		    }
-		  shndx = byte_get (shndx_list, 4);
+		  SAFE_BYTE_GET (shndx, shndx_list, 4, limit);
 		  if (shndx == 0)
 		    break;
 		  if (do_display)
@@ -6609,6 +7027,14 @@ process_cu_tu_index (struct dwarf_section *section, int do_display)
 
       is_tu_index = strcmp (section->name, ".debug_tu_index") == 0;
 
+      /* PR 17531: file: 0dd159bf.
+	 Check for wraparound with an overlarge ncols value.  */
+      if (poffsets < ppool || (unsigned int) ((poffsets - ppool) / 4) != ncols)
+	{
+	  warn (_("Overlarge number of columns: %x\n"), ncols);
+	  return 0;
+	}
+
       if (pend > limit)
 	{
 	  warn (_("Section %s too small for offset and size tables\n"),
@@ -6627,49 +7053,75 @@ process_cu_tu_index (struct dwarf_section *section, int do_display)
 	  if (is_tu_index)
 	    {
 	      tu_count = nused;
-	      tu_sets = xcmalloc (nused, sizeof (struct cu_tu_set));
+	      tu_sets = xcalloc2 (nused, sizeof (struct cu_tu_set));
 	      this_set = tu_sets;
 	    }
 	  else
 	    {
 	      cu_count = nused;
-	      cu_sets = xcmalloc (nused, sizeof (struct cu_tu_set));
+	      cu_sets = xcalloc2 (nused, sizeof (struct cu_tu_set));
 	      this_set = cu_sets;
 	    }
 	}
+
       if (do_display)
 	{
 	  for (j = 0; j < ncols; j++)
 	    {
-	      dw_sect = byte_get (ppool + j * 4, 4);
+	      SAFE_BYTE_GET (dw_sect, ppool + j * 4, 4, limit);
 	      printf (" %8s", get_DW_SECT_short_name (dw_sect));
 	    }
 	  printf ("\n");
 	}
+
       for (i = 0; i < nslots; i++)
 	{
-	  byte_get_64 (ph, &signature_high, &signature_low);
-	  row = byte_get (pi, 4);
+	  SAFE_BYTE_GET64 (ph, &signature_high, &signature_low, limit);
+
+	  SAFE_BYTE_GET (row, pi, 4, limit);
 	  if (row != 0)
 	    {
+	      /* PR 17531: file: a05f6ab3.  */
+	      if (row > nused)
+		{
+		  warn (_("Row index (%u) is larger than number of used entries (%u)\n"),
+			row, nused);
+		  return 0;
+		}
+
 	      if (!do_display)
 		memcpy (&this_set[row - 1].signature, ph, sizeof (uint64_t));
+
 	      prow = poffsets + (row - 1) * ncols * 4;
+	      /* PR 17531: file: b8ce60a8.  */
+	      if (prow < poffsets || prow > limit)
+		{
+		  warn (_("Row index (%u) * num columns (%u) > space remaining in section\n"),
+			row, ncols);
+		  return 0;
+		}
+ 
 	      if (do_display)
 		printf (_("  [%3d] 0x%s"),
 			i, dwarf_vmatoa64 (signature_high, signature_low,
 					   buf, sizeof (buf)));
 	      for (j = 0; j < ncols; j++)
 		{
-		  val = byte_get (prow + j * 4, 4);
+		  SAFE_BYTE_GET (val, prow + j * 4, 4, limit);
 		  if (do_display)
 		    printf (" %8d", val);
 		  else
 		    {
-		      dw_sect = byte_get (ppool + j * 4, 4);
-		      this_set [row - 1].section_offsets [dw_sect] = val;
+		      SAFE_BYTE_GET (dw_sect, ppool + j * 4, 4, limit);
+
+		      /* PR 17531: file: 10796eb3.  */
+		      if (dw_sect >= DW_SECT_MAX)
+			warn (_("Overlarge Dwarf section index detected: %u\n"), dw_sect);
+		      else
+			this_set [row - 1].section_offsets [dw_sect] = val;
 		    }
 		}
+
 	      if (do_display)
 		printf ("\n");
 	    }
@@ -6680,51 +7132,62 @@ process_cu_tu_index (struct dwarf_section *section, int do_display)
       ph = phash;
       pi = pindex;
       if (do_display)
-        {
+	{
 	  printf ("\n");
 	  printf (_("  Size table\n"));
 	  printf ("  slot  %-16s  ",
 		 is_tu_index ? _("signature") : _("dwo_id"));
-        }
+	}
+
       for (j = 0; j < ncols; j++)
 	{
-	  val = byte_get (ppool + j * 4, 4);
+	  SAFE_BYTE_GET (val, ppool + j * 4, 4, limit);
 	  if (do_display)
 	    printf (" %8s", get_DW_SECT_short_name (val));
 	}
+
       if (do_display)
 	printf ("\n");
+
       for (i = 0; i < nslots; i++)
 	{
-	  byte_get_64 (ph, &signature_high, &signature_low);
-	  row = byte_get (pi, 4);
+	  SAFE_BYTE_GET64 (ph, &signature_high, &signature_low, limit);
+
+	  SAFE_BYTE_GET (row, pi, 4, limit);
 	  if (row != 0)
 	    {
 	      prow = psizes + (row - 1) * ncols * 4;
+
 	      if (do_display)
 		printf (_("  [%3d] 0x%s"),
 			i, dwarf_vmatoa64 (signature_high, signature_low,
 					   buf, sizeof (buf)));
+
 	      for (j = 0; j < ncols; j++)
 		{
-		  val = byte_get (prow + j * 4, 4);
+		  SAFE_BYTE_GET (val, prow + j * 4, 4, limit);
 		  if (do_display)
 		    printf (" %8d", val);
 		  else
 		    {
-		      dw_sect = byte_get (ppool + j * 4, 4);
+		      SAFE_BYTE_GET (dw_sect, ppool + j * 4, 4, limit);
+		      if (dw_sect >= DW_SECT_MAX)
+			warn (_("Overlarge Dwarf section index detected: %u\n"), dw_sect);
+		      else
 		      this_set [row - 1].section_sizes [dw_sect] = val;
 		    }
 		}
+
 	      if (do_display)
 		printf ("\n");
 	    }
+
 	  ph += 8;
 	  pi += 4;
 	}
     }
   else if (do_display)
-    printf (_("  Unsupported version\n"));
+    printf (_("  Unsupported version (%d)\n"), version);
 
   if (do_display)
       printf ("\n");
@@ -6795,34 +7258,69 @@ display_debug_not_supported (struct dwarf_section *section,
   return 1;
 }
 
+/* Like malloc, but takes two parameters like calloc.
+   Verifies that the first parameter is not too large.
+   Note: does *not* initialise the allocated memory to zero.  */
 void *
 cmalloc (size_t nmemb, size_t size)
 {
   /* Check for overflow.  */
   if (nmemb >= ~(size_t) 0 / size)
     return NULL;
-  else
-    return malloc (nmemb * size);
+
+  return xmalloc (nmemb * size);
 }
 
+/* Like xmalloc, but takes two parameters like calloc.
+   Verifies that the first parameter is not too large.
+   Note: does *not* initialise the allocated memory to zero.  */
 void *
 xcmalloc (size_t nmemb, size_t size)
 {
   /* Check for overflow.  */
   if (nmemb >= ~(size_t) 0 / size)
-    return NULL;
-  else
-    return xmalloc (nmemb * size);
+    {
+      fprintf (stderr,
+	       _("Attempt to allocate an array with an excessive number of elements: 0x%lx\n"),
+	       (long) nmemb);
+      xexit (1);
+    }
+
+  return xmalloc (nmemb * size);
 }
 
+/* Like xrealloc, but takes three parameters.
+   Verifies that the second parameter is not too large.
+   Note: does *not* initialise any new memory to zero.  */
 void *
 xcrealloc (void *ptr, size_t nmemb, size_t size)
 {
   /* Check for overflow.  */
   if (nmemb >= ~(size_t) 0 / size)
-    return NULL;
-  else
-    return xrealloc (ptr, nmemb * size);
+    {
+      fprintf (stderr,
+	       _("Attempt to re-allocate an array with an excessive number of elements: 0x%lx\n"),
+	       (long) nmemb);
+      xexit (1);
+    }
+
+  return xrealloc (ptr, nmemb * size);
+}
+
+/* Like xcalloc, but verifies that the first parameter is not too large.  */
+void *
+xcalloc2 (size_t nmemb, size_t size)
+{
+  /* Check for overflow.  */
+  if (nmemb >= ~(size_t) 0 / size)
+    {
+      fprintf (stderr,
+	       _("Attempt to allocate a zero'ed array with an excessive number of elements: 0x%lx\n"),
+	       (long) nmemb);
+      xexit (1);
+    }
+
+  return xcalloc (nmemb, size);
 }
 
 void
@@ -6850,10 +7348,9 @@ free_debug_memory (void)
 		free (debug_information [i].range_lists);
 	    }
 	}
-
       free (debug_information);
       debug_information = NULL;
-      num_debug_info_entries = 0;
+      alloc_num_debug_info_entries = num_debug_info_entries = 0;
     }
 }
 
@@ -6997,7 +7494,7 @@ dwarf_select_sections_by_letters (const char *letters)
 	break;
 
       default:
-	warn (_("Unrecognized debug option '%s'\n"), optarg);
+	warn (_("Unrecognized debug option '%s'\n"), letters);
 	break;
       }
 }
@@ -7026,76 +7523,76 @@ dwarf_select_sections_all (void)
 
 struct dwarf_section_display debug_displays[] =
 {
-  { { ".debug_abbrev",	    ".zdebug_abbrev",	NULL, NULL, 0, 0, 0 },
+  { { ".debug_abbrev",	    ".zdebug_abbrev",	NULL, NULL, 0, 0, 0, NULL },
     display_debug_abbrev,   &do_debug_abbrevs,	0 },
-  { { ".debug_aranges",	    ".zdebug_aranges",	NULL, NULL, 0, 0, 0 },
+  { { ".debug_aranges",	    ".zdebug_aranges",	NULL, NULL, 0, 0, 0, NULL },
     display_debug_aranges,  &do_debug_aranges,	1 },
-  { { ".debug_frame",       ".zdebug_frame",	NULL, NULL, 0, 0, 0 },
+  { { ".debug_frame",       ".zdebug_frame",	NULL, NULL, 0, 0, 0, NULL },
     display_debug_frames,   &do_debug_frames,	1 },
-  { { ".debug_info",	    ".zdebug_info",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_info",	    ".zdebug_info",	NULL, NULL, 0, 0, abbrev, NULL },
     display_debug_info,	    &do_debug_info,	1 },
-  { { ".debug_line",	    ".zdebug_line",	NULL, NULL, 0, 0, 0 },
+  { { ".debug_line",	    ".zdebug_line",	NULL, NULL, 0, 0, 0, NULL },
     display_debug_lines,    &do_debug_lines,	1 },
-  { { ".debug_pubnames",    ".zdebug_pubnames",	NULL, NULL, 0, 0, 0 },
+  { { ".debug_pubnames",    ".zdebug_pubnames",	NULL, NULL, 0, 0, 0, NULL },
     display_debug_pubnames, &do_debug_pubnames,	0 },
-  { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NULL, NULL, 0, 0, 0 },
+  { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NULL, NULL, 0, 0, 0, NULL },
     display_debug_gnu_pubnames, &do_debug_pubnames, 0 },
-  { { ".eh_frame",	    "",			NULL, NULL, 0, 0, 0 },
+  { { ".eh_frame",	    "",			NULL, NULL, 0, 0, 0, NULL },
     display_debug_frames,   &do_debug_frames,	1 },
-  { { ".debug_macinfo",	    ".zdebug_macinfo",	NULL, NULL, 0, 0, 0 },
+  { { ".debug_macinfo",	    ".zdebug_macinfo",	NULL, NULL, 0, 0, 0, NULL },
     display_debug_macinfo,  &do_debug_macinfo,	0 },
-  { { ".debug_macro",	    ".zdebug_macro",	NULL, NULL, 0, 0, 0 },
+  { { ".debug_macro",	    ".zdebug_macro",	NULL, NULL, 0, 0, 0, NULL },
     display_debug_macro,    &do_debug_macinfo,	1 },
-  { { ".debug_str",	    ".zdebug_str",	NULL, NULL, 0, 0, 0 },
+  { { ".debug_str",	    ".zdebug_str",	NULL, NULL, 0, 0, 0, NULL },
     display_debug_str,	    &do_debug_str,	0 },
-  { { ".debug_loc",	    ".zdebug_loc",	NULL, NULL, 0, 0, 0 },
+  { { ".debug_loc",	    ".zdebug_loc",	NULL, NULL, 0, 0, 0, NULL },
     display_debug_loc,	    &do_debug_loc,	1 },
-  { { ".debug_pubtypes",    ".zdebug_pubtypes",	NULL, NULL, 0, 0, 0 },
+  { { ".debug_pubtypes",    ".zdebug_pubtypes",	NULL, NULL, 0, 0, 0, NULL },
     display_debug_pubnames, &do_debug_pubtypes,	0 },
-  { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NULL, NULL, 0, 0, 0 },
+  { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NULL, NULL, 0, 0, 0, NULL },
     display_debug_gnu_pubnames, &do_debug_pubtypes, 0 },
-  { { ".debug_ranges",	    ".zdebug_ranges",	NULL, NULL, 0, 0, 0 },
+  { { ".debug_ranges",	    ".zdebug_ranges",	NULL, NULL, 0, 0, 0, NULL },
     display_debug_ranges,   &do_debug_ranges,	1 },
-  { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, 0 },
+  { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, 0, NULL },
     display_debug_not_supported, NULL,		0 },
-  { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0, 0 },
+  { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0, 0, NULL },
     display_debug_not_supported, NULL,		0 },
-  { { ".debug_types",	    ".zdebug_types",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_types",	    ".zdebug_types",	NULL, NULL, 0, 0, abbrev, NULL },
     display_debug_types,    &do_debug_info,	1 },
-  { { ".debug_weaknames",   ".zdebug_weaknames", NULL, NULL, 0, 0, 0 },
+  { { ".debug_weaknames",   ".zdebug_weaknames", NULL, NULL, 0, 0, 0, NULL },
     display_debug_not_supported, NULL,		0 },
-  { { ".gdb_index",	    "",	                NULL, NULL, 0, 0, 0 },
+  { { ".gdb_index",	    "",			NULL, NULL, 0, 0, 0, NULL },
     display_gdb_index,      &do_gdb_index,	0 },
-  { { ".trace_info",	    "",			NULL, NULL, 0, 0, trace_abbrev },
+  { { ".trace_info",	    "",			NULL, NULL, 0, 0, trace_abbrev, NULL },
     display_trace_info,	    &do_trace_info,	1 },
-  { { ".trace_abbrev",	    "",			NULL, NULL, 0, 0, 0 },
+  { { ".trace_abbrev",	    "",			NULL, NULL, 0, 0, 0, NULL },
     display_debug_abbrev,   &do_trace_abbrevs,	0 },
-  { { ".trace_aranges",	    "",			NULL, NULL, 0, 0, 0 },
+  { { ".trace_aranges",	    "",			NULL, NULL, 0, 0, 0, NULL },
     display_debug_aranges,  &do_trace_aranges,	0 },
-  { { ".debug_info.dwo",    ".zdebug_info.dwo",	NULL, NULL, 0, 0, abbrev_dwo },
+  { { ".debug_info.dwo",    ".zdebug_info.dwo",	NULL, NULL, 0, 0, abbrev_dwo, NULL },
     display_debug_info,	    &do_debug_info,	1 },
-  { { ".debug_abbrev.dwo",  ".zdebug_abbrev.dwo", NULL, NULL, 0, 0, 0 },
+  { { ".debug_abbrev.dwo",  ".zdebug_abbrev.dwo", NULL, NULL, 0, 0, 0, NULL },
     display_debug_abbrev,   &do_debug_abbrevs,	0 },
-  { { ".debug_types.dwo",   ".zdebug_types.dwo", NULL, NULL, 0, 0, abbrev_dwo },
+  { { ".debug_types.dwo",   ".zdebug_types.dwo", NULL, NULL, 0, 0, abbrev_dwo, NULL },
     display_debug_types,    &do_debug_info,	1 },
-  { { ".debug_line.dwo",    ".zdebug_line.dwo", NULL, NULL, 0, 0, 0 },
+  { { ".debug_line.dwo",    ".zdebug_line.dwo", NULL, NULL, 0, 0, 0, NULL },
     display_debug_lines,    &do_debug_lines,	1 },
-  { { ".debug_loc.dwo",	    ".zdebug_loc.dwo",	NULL, NULL, 0, 0, 0 },
+  { { ".debug_loc.dwo",	    ".zdebug_loc.dwo",	NULL, NULL, 0, 0, 0, NULL },
     display_debug_loc,	    &do_debug_loc,	1 },
-  { { ".debug_macro.dwo",   ".zdebug_macro.dwo", NULL, NULL, 0, 0, 0 },
+  { { ".debug_macro.dwo",   ".zdebug_macro.dwo", NULL, NULL, 0, 0, 0, NULL },
     display_debug_macro,    &do_debug_macinfo,	1 },
-  { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NULL, NULL, 0, 0, 0 },
+  { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NULL, NULL, 0, 0, 0, NULL },
     display_debug_macinfo,  &do_debug_macinfo,	0 },
-  { { ".debug_str.dwo",     ".zdebug_str.dwo",  NULL, NULL, 0, 0, 0 },
+  { { ".debug_str.dwo",     ".zdebug_str.dwo",  NULL, NULL, 0, 0, 0, NULL },
     display_debug_str,      &do_debug_str,	1 },
-  { { ".debug_str_offsets", ".zdebug_str_offsets", NULL, NULL, 0, 0, 0 },
+  { { ".debug_str_offsets", ".zdebug_str_offsets", NULL, NULL, 0, 0, 0, NULL },
     display_debug_str_offsets, NULL,		0 },
-  { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NULL, NULL, 0, 0, 0 },
+  { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NULL, NULL, 0, 0, 0, NULL },
     display_debug_str_offsets, NULL,		0 },
-  { { ".debug_addr",	    ".zdebug_addr",     NULL, NULL, 0, 0, 0 },
+  { { ".debug_addr",	    ".zdebug_addr",     NULL, NULL, 0, 0, 0, NULL },
     display_debug_addr,     &do_debug_addr,	1 },
-  { { ".debug_cu_index",    "",			NULL, NULL, 0, 0, 0 },
+  { { ".debug_cu_index",    "",			NULL, NULL, 0, 0, 0, NULL },
     display_cu_index,       &do_debug_cu_index,	0 },
-  { { ".debug_tu_index",    "",			NULL, NULL, 0, 0, 0 },
+  { { ".debug_tu_index",    "",			NULL, NULL, 0, 0, 0, NULL },
     display_cu_index,       &do_debug_cu_index,	0 },
 };
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 124d9d6..2084a22 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -25,22 +25,9 @@ typedef unsigned HOST_WIDEST_INT  dwarf_size_type;
 /* Structure found in the .debug_line section.  */
 typedef struct
 {
-  unsigned char li_length          [4];
-  unsigned char li_version         [2];
-  unsigned char li_prologue_length [4];
-  unsigned char li_min_insn_length [1];
-  unsigned char li_default_is_stmt [1];
-  unsigned char li_line_base       [1];
-  unsigned char li_line_range      [1];
-  unsigned char li_opcode_base     [1];
-}
-DWARF2_External_LineInfo;
-
-typedef struct
-{
   dwarf_vma	 li_length;
   unsigned short li_version;
-  unsigned int   li_prologue_length;
+  dwarf_vma      li_prologue_length;
   unsigned char  li_min_insn_length;
   unsigned char  li_max_ops_per_insn;
   unsigned char  li_default_is_stmt;
@@ -53,15 +40,6 @@ DWARF2_Internal_LineInfo;
 /* Structure found in .debug_pubnames section.  */
 typedef struct
 {
-  unsigned char pn_length  [4];
-  unsigned char pn_version [2];
-  unsigned char pn_offset  [4];
-  unsigned char pn_size    [4];
-}
-DWARF2_External_PubNames;
-
-typedef struct
-{
   dwarf_vma	 pn_length;
   unsigned short pn_version;
   dwarf_vma	 pn_offset;
@@ -72,15 +50,6 @@ DWARF2_Internal_PubNames;
 /* Structure found in .debug_info section.  */
 typedef struct
 {
-  unsigned char  cu_length        [4];
-  unsigned char  cu_version       [2];
-  unsigned char  cu_abbrev_offset [4];
-  unsigned char  cu_pointer_size  [1];
-}
-DWARF2_External_CompUnit;
-
-typedef struct
-{
   dwarf_vma	 cu_length;
   unsigned short cu_version;
   dwarf_vma	 cu_abbrev_offset;
@@ -88,16 +57,7 @@ typedef struct
 }
 DWARF2_Internal_CompUnit;
 
-typedef struct
-{
-  unsigned char  ar_length       [4];
-  unsigned char  ar_version      [2];
-  unsigned char  ar_info_offset  [4];
-  unsigned char  ar_pointer_size [1];
-  unsigned char  ar_segment_size [1];
-}
-DWARF2_External_ARange;
-
+/* Structure found in .debug_aranges section.  */
 typedef struct
 {
   dwarf_vma	 ar_length;
@@ -164,6 +124,8 @@ struct dwarf_section
   dwarf_vma address;
   dwarf_size_type size;
   enum dwarf_section_display_enum abbrev_sec;
+  /* A spare field for random use.  */
+  void *user_data;
 };
 
 /* A structure containing the name of a debug section
@@ -205,7 +167,7 @@ typedef struct
 }
 debug_info;
 
-extern int eh_addr_size;
+extern unsigned int eh_addr_size;
 
 extern int do_debug_info;
 extern int do_debug_abbrevs;
@@ -246,10 +208,11 @@ extern void dwarf_select_sections_by_names (const char *);
 extern void dwarf_select_sections_by_letters (const char *);
 extern void dwarf_select_sections_all (void);
 
-unsigned int * find_cu_tu_set (void *, unsigned int);
+extern unsigned int * find_cu_tu_set (void *, unsigned int);
 
-void * cmalloc (size_t, size_t);
-void * xcmalloc (size_t, size_t);
-void * xcrealloc (void *, size_t, size_t);
+extern void * cmalloc (size_t, size_t);
+extern void * xcalloc2 (size_t, size_t);
+extern void * xcmalloc (size_t, size_t);
+extern void * xcrealloc (void *, size_t, size_t);
 
 extern dwarf_vma read_leb128 (unsigned char *, unsigned int *, bfd_boolean, const unsigned char * const);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]