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,

The COFF/PE related changes in BFD have now gone in.

Cheers
  Nick

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

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

	PR binutils/17512
	* coffcode.h (coff_compute_section_file_positions): Report
	negative page sizes.

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

	PR binutils/17512
	* coffcode.h (styp_to_sec_flags): Use an unsigned long type to
	hold the flag bits.

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

	PR binutils/17512
	* peXXigen.c (rsrc_print_resource_entries): Add range check for
	addresses that wrap around the address space.
	(rsrc_parse_entry): Likewise.

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

	PR binutils/17512
	* ecoff.c: Use bfd_alloc2 to allocate space for structure arrays.
	(_bfd_ecoff_slurp_symbol_table): Check for a negative symbol
	index or an out of range fdr index.
	* peXXigen.c (pe_print_edata):  Check for numeric overflow in edt
	fields.

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

	PR binutils/17512
	* coffcode.h (handle_COMDAT): When searching for the section
	symbol, make sure that there is space left in the symbol table.

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

	PR binutils/17512
	* coffcode.h (coff_set_arch_mach_hook): Check return value from
	bfd_malloc.
	(coff_slurp_line_table): Return FALSE if the line number
	information was corrupt.
	(coff_slurp_symbol_table): Return FALSE if the symbol information
	was corrupt.
	* peXXigen.c (_bfd_XXi_swap_aouthdr_in): Set bfd_error if the
	read fails.
	(slurp_symtab): Check the return from bfd_malloc.
	(_bfd_XX_bfd_copy_private_bfd_data_common): Fail if the copy
	encountered an error.
	(_bfd_XXi_final_link_postscript): Fail if a section could not be
	copied.
	* peicode.h (pe_bfd_object_p): Fail if the header could not be
	swapped in.

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

	PR binutils/17512
	* coffcode.h (coff_slurp_symbol_table): Return false if we failed
	to load the line table.

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

	PR binutils/17512
	* coff-i860.c (CALC_ADDEND): Always set an addend value.

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

	PR binutils/17512
	* ecoff.c (_bfd_ecoff_slurp_symbol_table): Warn about and correct
	a discrepancy between the isymMax and ifdMax values in the
	symbolic header.

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

	PR binutils/17512
	* coff-h8300.c (rtype2howto): Replace abort with returning a NULL
	value.
	* coff-h8500.c (rtype2howto): Likewise.
	* coff-tic30.c (rtype2howto): Likewise.
	* coff-z80.c (rtype2howto): Likewise.
	* coff-z8k.c (rtype2howto): Likewise.
	* coff-ia64.c (RTYPE2HOWTO): Always return a valid howto.
	* coff-m68k.c (m68k_rtype2howto): Return a NULL howto if none
	could be found.
	* coff-mcore.c (RTYPE2HOWTO): Add range checking.
	* coff-w65.c (rtype2howto): Likewise.
	* coff-we32k.c (RTYPE2HOWTO): Likewise.
	* pe-mips.c (RTYPE2HOWTO): Likewise.
	* coff-x86_64.c (coff_amd64_reloc): Likewise.  Replace abort with
	an error return.
	* coffcode.h (coff_slurp_reloc_table): Allow the rel parameter to
	be unused.
	* coffgen.c (make_a_section_from_file): Check the length of a
	section name before testing to see if it is a debug section name.
	(coff_object_p): Zero out any uninitialised bytes in the opt
	header.
	* ecoff.c (_bfd_ecoff_slurp_symbolic_info): Test for the raw
	source being empty when there are values to be processed.
	(_bfd_ecoff_slurp_symbol_table): Add range check.

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

	PR binutils/17512
	* coffgen.c (coff_get_normalized_symtab): Check for an excessive
	number of auxillary entries.

	2014-11-21  Alexander Cherepanov  <cherepan@mccme.ru>

	PR binutils/17512
	* coffgen.c (_bfd_coff_read_string_table): Test allocation of
	string table before clearing the first few bytes.

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b1dcab2..906c975 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,126 @@
+2015-03-24  Nick Clifton  <nickc@redhat.com>
+
+	Apply from master:
+	2015-02-26  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* coffcode.h (coff_compute_section_file_positions): Report
+	negative page sizes.
+
+	2015-02-10  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* coffcode.h (styp_to_sec_flags): Use an unsigned long type to
+	hold the flag bits.
+
+	2015-02-06  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* peXXigen.c (rsrc_print_resource_entries): Add range check for
+	addresses that wrap around the address space.
+	(rsrc_parse_entry): Likewise.
+
+	2015-02-03  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* ecoff.c: Use bfd_alloc2 to allocate space for structure arrays.
+	(_bfd_ecoff_slurp_symbol_table): Check for a negative symbol
+	index or an out of range fdr index.
+	* peXXigen.c (pe_print_edata):  Check for numeric overflow in edt
+	fields.
+
+	2015-01-22  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* coffcode.h (handle_COMDAT): When searching for the section
+	symbol, make sure that there is space left in the symbol table.
+
+	2015-01-21  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* coffcode.h (coff_set_arch_mach_hook): Check return value from
+	bfd_malloc.
+	(coff_slurp_line_table): Return FALSE if the line number
+	information was corrupt.
+	(coff_slurp_symbol_table): Return FALSE if the symbol information
+	was corrupt.
+	* peXXigen.c (_bfd_XXi_swap_aouthdr_in): Set bfd_error if the
+	read fails.
+	(slurp_symtab): Check the return from bfd_malloc.
+	(_bfd_XX_bfd_copy_private_bfd_data_common): Fail if the copy
+	encountered an error.
+	(_bfd_XXi_final_link_postscript): Fail if a section could not be
+	copied.
+	* peicode.h (pe_bfd_object_p): Fail if the header could not be
+	swapped in.
+
+	2015-01-08  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* coffcode.h (coff_slurp_symbol_table): Return false if we failed
+	to load the line table.
+
+	2015-01-06  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* coff-i860.c (CALC_ADDEND): Always set an addend value.
+
+	2014-11-27  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* ecoff.c (_bfd_ecoff_slurp_symbol_table): Warn about and correct
+	a discrepancy between the isymMax and ifdMax values in the
+	symbolic header.
+
+	2014-11-26  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* coff-h8300.c (rtype2howto): Replace abort with returning a NULL
+	value.
+	* coff-h8500.c (rtype2howto): Likewise.
+	* coff-tic30.c (rtype2howto): Likewise.
+	* coff-z80.c (rtype2howto): Likewise.
+	* coff-z8k.c (rtype2howto): Likewise.
+	* coff-ia64.c (RTYPE2HOWTO): Always return a valid howto.
+	* coff-m68k.c (m68k_rtype2howto): Return a NULL howto if none
+	could be found.
+	* coff-mcore.c (RTYPE2HOWTO): Add range checking.
+	* coff-w65.c (rtype2howto): Likewise.
+	* coff-we32k.c (RTYPE2HOWTO): Likewise.
+	* pe-mips.c (RTYPE2HOWTO): Likewise.
+	* coff-x86_64.c (coff_amd64_reloc): Likewise.  Replace abort with
+	an error return.
+	* coffcode.h (coff_slurp_reloc_table): Allow the rel parameter to
+	be unused.
+	* coffgen.c (make_a_section_from_file): Check the length of a
+	section name before testing to see if it is a debug section name.
+	(coff_object_p): Zero out any uninitialised bytes in the opt
+	header.
+	* ecoff.c (_bfd_ecoff_slurp_symbolic_info): Test for the raw
+	source being empty when there are values to be processed.
+	(_bfd_ecoff_slurp_symbol_table): Add range check.
+
+	2014-11-21  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* coffgen.c (coff_get_normalized_symtab): Check for an excessive
+	number of auxillary entries.
+
+	2014-11-21  Alexander Cherepanov  <cherepan@mccme.ru>
+
+	PR binutils/17512
+	* coffgen.c (_bfd_coff_read_string_table): Test allocation of
+	string table before clearing the first few bytes.
+
+2014-11-18  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* peXXigen.c (pe_print_pdata): Fail if the section's virtual size
+	is larger than its real size.
+	(rsrc_print_section): Fix off-by-one error checking for overflow.
+	* pei-x86_64.c (pex64_bfd_print_pdata): Handle empty unwind
+	sections.
+
 2015-03-18  Alan Modra  <amodra@gmail.com>
 
 	Apply from master
diff --git a/bfd/coff-h8300.c b/bfd/coff-h8300.c
index 5ec48c9..10123d3 100644
--- a/bfd/coff-h8300.c
+++ b/bfd/coff-h8300.c
@@ -337,7 +337,7 @@ rtype2howto (arelent *internal, struct internal_reloc *dst)
       internal->howto = howto_table + 19;
       break;
     default:
-      abort ();
+      internal->howto = NULL;
       break;
     }
 }
diff --git a/bfd/coff-h8500.c b/bfd/coff-h8500.c
index 574f956..b6a996e 100644
--- a/bfd/coff-h8500.c
+++ b/bfd/coff-h8500.c
@@ -95,7 +95,7 @@ rtype2howto (arelent * internal, struct internal_reloc *dst)
   switch (dst->r_type)
     {
     default:
-      abort ();
+      internal->howto = NULL;
       break;
     case R_H8500_IMM8:
       internal->howto = &r_imm8;
diff --git a/bfd/coff-i860.c b/bfd/coff-i860.c
index 341183f..338ec75 100644
--- a/bfd/coff-i860.c
+++ b/bfd/coff-i860.c
@@ -467,7 +467,10 @@ static reloc_howto_type howto_table[] =
    FIXME: This macro refers to symbols and asect; these are from the
    calling function, not the macro arguments.  */
 
-#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)
+/* PR 17512: file: 0a38fb7c
+   Set an addend value, even if it is not going to be used.  A tool
+   like coffdump might be used to print out the contents of the reloc.  */
+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) (cache_ptr)->addend = 0
 
 /* We use the special COFF backend linker.  */
 #define coff_relocate_section _bfd_coff_generic_relocate_section
diff --git a/bfd/coff-m68k.c b/bfd/coff-m68k.c
index f7089a6..5ebf52c 100644
--- a/bfd/coff-m68k.c
+++ b/bfd/coff-m68k.c
@@ -143,6 +143,7 @@ m68k_rtype2howto (arelent *internal, int relocentry)
     case R_PCRWORD:	internal->howto = m68kcoff_howto_table + 4; break;
     case R_PCRLONG:	internal->howto = m68kcoff_howto_table + 5; break;
     case R_RELLONG_NEG:	internal->howto = m68kcoff_howto_table + 6; break;
+    default:            internal->howto = NULL; break;
     }
 }
 
diff --git a/bfd/coff-mcore.c b/bfd/coff-mcore.c
index 7dad44f..9f30cfc 100644
--- a/bfd/coff-mcore.c
+++ b/bfd/coff-mcore.c
@@ -273,16 +273,15 @@ mcore_coff_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
 }
 #undef HOW2MAP
 
+#define NUM_HOWTOS NUM_ELEM (mcore_coff_howto_table)
+
 static reloc_howto_type *
 mcore_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 			      const char *r_name)
 {
   unsigned int i;
 
-  for (i = 0;
-       i < (sizeof (mcore_coff_howto_table)
-	    / sizeof (mcore_coff_howto_table[0]));
-       i++)
+  for (i = 0; i < NUM_HOWTOS; i++)
     if (mcore_coff_howto_table[i].name != NULL
 	&& strcasecmp (mcore_coff_howto_table[i].name, r_name) == 0)
       return &mcore_coff_howto_table[i];
@@ -290,8 +289,11 @@ mcore_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
   return NULL;
 }
 
-#define RTYPE2HOWTO(cache_ptr, dst) \
-  (cache_ptr)->howto = mcore_coff_howto_table + (dst)->r_type;
+#define RTYPE2HOWTO(cache_ptr, dst)				\
+  ((cache_ptr)->howto =						\
+   ((dst)->r_type < NUM_HOWTOS					\
+    ? mcore_coff_howto_table + (dst)->r_type			\
+    : NULL))
 
 static reloc_howto_type *
 coff_mcore_rtype_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
@@ -303,7 +305,7 @@ coff_mcore_rtype_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
 {
   reloc_howto_type * howto;
 
-  if (rel->r_type >= NUM_ELEM (mcore_coff_howto_table))
+  if (rel->r_type >= NUM_HOWTOS)
     return NULL;
 
   howto = mcore_coff_howto_table + rel->r_type;
diff --git a/bfd/coff-tic30.c b/bfd/coff-tic30.c
index 740c82c..ab95308 100644
--- a/bfd/coff-tic30.c
+++ b/bfd/coff-tic30.c
@@ -136,7 +136,7 @@ rtype2howto (arelent *internal, struct internal_reloc *dst)
       internal->howto = &tic30_coff_howto_table[4];
       break;
     default:
-      abort ();
+      internal->howto = NULL;
       break;
     }
 }
diff --git a/bfd/coff-w65.c b/bfd/coff-w65.c
index f208730..d575f58 100644
--- a/bfd/coff-w65.c
+++ b/bfd/coff-w65.c
@@ -42,6 +42,8 @@ static reloc_howto_type howto_table[] =
     HOWTO (R_W65_DP,      0,  0, 8,  FALSE, 0, complain_overflow_bitfield, 0, "dp", TRUE, 0x000000ff, 0x000000ff, FALSE),
   };
 
+#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0]))
+
 /* Turn a howto into a reloc number.  */
 
 #define SELECT_RELOC(x,howto) \
@@ -61,7 +63,7 @@ static reloc_howto_type howto_table[] =
 static int
 select_reloc (reloc_howto_type *howto)
 {
-  return howto->type ;
+  return howto->type;
 }
 
 /* Code to turn a r_type into a howto ptr, uses the above howto table.  */
@@ -70,7 +72,10 @@ static void
 rtype2howto (arelent *internal,
 	     struct internal_reloc *dst)
 {
-  internal->howto = howto_table + dst->r_type - 1;
+  if (dst->r_type > 0 && dst->r_type <= NUM_HOWTOS)
+    internal->howto = howto_table + dst->r_type - 1;
+  else
+    internal->howto = NULL;
 }
 
 #define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
diff --git a/bfd/coff-we32k.c b/bfd/coff-we32k.c
index d5481b8..b754815 100644
--- a/bfd/coff-we32k.c
+++ b/bfd/coff-we32k.c
@@ -53,14 +53,19 @@ static reloc_howto_type howto_table[] =
   HOWTO(R_PCRLONG,	       0,  2, 	32, TRUE,  0, complain_overflow_signed, 0, "DISP32",   TRUE, 0xffffffff,0xffffffff, FALSE),
 };
 
+#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0]))
+
 /* Turn a howto into a reloc  nunmber */
 
 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
 #define BADMAG(x) WE32KBADMAG(x)
 #define WE32K	1
 
-#define RTYPE2HOWTO(cache_ptr, dst) \
-	    (cache_ptr)->howto = howto_table + (dst)->r_type;
+#define RTYPE2HOWTO(cache_ptr, dst)				\
+  ((cache_ptr)->howto =						\
+   ((dst)->r_type < NUM_HOWTOS					\
+    ? howto_table + (dst)->r_type				\
+    : NULL))
 
 #ifndef bfd_pe_print_pdata
 #define bfd_pe_print_pdata	NULL
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index 2a21bb8..742adc2 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -143,6 +143,16 @@ coff_amd64_reloc (bfd *abfd,
 	reloc_howto_type *howto = reloc_entry->howto;
 	unsigned char *addr = (unsigned char *) data + reloc_entry->address;
 
+	/* FIXME: We do not have an end address for data, so we cannot
+	   accurately range check any addresses computed against it.
+	   cf: PR binutils/17512: file: 1085-1761-0.004.
+	   For now we do the best that we can.  */
+	if (addr < (unsigned char *) data || addr > ((unsigned char *) data) + input_section->size)
+	  {
+	    bfd_set_error (bfd_error_bad_value);
+	    return bfd_reloc_notsupported;
+	  }
+
 	switch (howto->size)
 	  {
 	  case 0:
@@ -177,7 +187,8 @@ coff_amd64_reloc (bfd *abfd,
 	    break;
 
 	  default:
-	    abort ();
+	    bfd_set_error (bfd_error_bad_value);
+	    return bfd_reloc_notsupported;
 	  }
       }
 
diff --git a/bfd/coff-z80.c b/bfd/coff-z80.c
index 7b62cdf..fd68b12 100644
--- a/bfd/coff-z80.c
+++ b/bfd/coff-z80.c
@@ -81,7 +81,7 @@ rtype2howto (arelent *internal, struct internal_reloc *dst)
   switch (dst->r_type)
     {
     default:
-      abort ();
+      internal->howto = NULL;
       break;
     case R_IMM8:
       internal->howto = &r_imm8;
diff --git a/bfd/coff-z8k.c b/bfd/coff-z8k.c
index c85713f..7f67ee8 100644
--- a/bfd/coff-z8k.c
+++ b/bfd/coff-z8k.c
@@ -85,7 +85,7 @@ rtype2howto (arelent *internal, struct internal_reloc *dst)
   switch (dst->r_type)
     {
     default:
-      abort ();
+      internal->howto = NULL;
       break;
     case R_IMM8:
       internal->howto = &r_imm8;
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 9990b16..2b1c3d0 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -1009,6 +1009,13 @@ handle_COMDAT (bfd * abfd,
 
 		seen_state = 1;
 
+		/* PR 17512: file: e2cfe54f.  */
+		if (esym + bfd_coff_symesz (abfd) >= esymend)
+		  {
+		    _bfd_error_handler (_("%B: warning: No symbol for section '%s' found"),
+					abfd, symname);
+		    break;
+		  }
 		/* This is the section symbol.  */
 		bfd_coff_swap_aux_in (abfd, (esym + bfd_coff_symesz (abfd)),
 				      isym.n_type, isym.n_sclass,
@@ -1162,7 +1169,7 @@ styp_to_sec_flags (bfd *abfd,
 		   flagword *flags_ptr)
 {
   struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
-  long styp_flags = internal_s->s_flags;
+  unsigned long styp_flags = internal_s->s_flags;
   flagword sec_flags;
   bfd_boolean result = TRUE;
   bfd_boolean is_dbg = FALSE;
@@ -1185,7 +1192,7 @@ styp_to_sec_flags (bfd *abfd,
   /* Process each flag bit in styp_flags in turn.  */
   while (styp_flags)
     {
-      long flag = styp_flags & - styp_flags;
+      unsigned long flag = styp_flags & - styp_flags;
       char * unhandled = NULL;
 
       styp_flags &= ~ flag;
@@ -2073,7 +2080,11 @@ coff_mkobject_hook (bfd * abfd,
 #endif
 
   if ((internal_f->f_flags & F_GO32STUB) != 0)
-    coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE);
+    {
+      coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE);
+      if (coff->go32stub == NULL)
+	return NULL;
+    }
   if (coff->go32stub != NULL)
     memcpy (coff->go32stub, internal_f->go32stub, GO32_STUBSIZE);
 
@@ -2278,6 +2289,8 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr)
 		bfd_size_type amt = bfd_coff_symesz (abfd);
 
 		buf = bfd_malloc (amt);
+		if (buf == NULL)
+		  return FALSE;
 		if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
 		    || bfd_bread (buf, amt, abfd) != amt)
 		  {
@@ -2666,10 +2679,16 @@ coff_write_relocs (bfd * abfd, int first_undef)
 	amt = s->reloc_count;
 	amt *= sizeof (arelent *);
 	p = bfd_malloc (amt);
-	if (p == NULL && s->reloc_count > 0)
-	  return FALSE;
-	memcpy (p, s->orelocation, (size_t) amt);
-	qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr);
+	if (p == NULL)
+	  {
+	    if (s->reloc_count > 0)
+	      return FALSE;
+	  }
+	else
+	  {
+	    memcpy (p, s->orelocation, (size_t) amt);
+	    qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr);
+	  }
       }
 #endif
 
@@ -3151,6 +3170,15 @@ coff_compute_section_file_positions (bfd * abfd)
 	 This repairs 'ld -r' for arm-wince-pe target.  */
       if (page_size == 0)
 	page_size = 1;
+
+      /* PR 17512: file: 0ac816d3.  */
+      if (page_size < 0)
+	{
+	  bfd_set_error (bfd_error_file_too_big);
+	  (*_bfd_error_handler)
+	    (_("%B: page size is too large (0x%x)"), abfd, page_size);
+	  return FALSE;
+	}
     }
   else
     page_size = PE_DEF_FILE_ALIGNMENT;
@@ -4526,6 +4554,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
   unsigned int nbr_func;
   LINENO *src;
   bfd_boolean have_func;
+  bfd_boolean ret = TRUE;
 
   BFD_ASSERT (asect->lineno == NULL);
 
@@ -4575,6 +4604,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
 		(_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
 		 abfd, (long) symndx, counter);
 	      cache_ptr->line_number = -1;
+	      ret = FALSE;
 	      continue;
 	    }
 
@@ -4587,6 +4617,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
 		(_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
 		 abfd, (long) symndx, counter);
 	      cache_ptr->line_number = -1;
+	      ret = FALSE;
 	      continue;
 	    }
 	  sym = (coff_symbol_type *) (ent->u.syment._n._n_n._n_zeroes);
@@ -4599,6 +4630,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
 		(_("%B: warning: illegal symbol in line number entry %d"),
 		 abfd, counter);
 	      cache_ptr->line_number = -1;
+	      ret = FALSE;
 	      continue;
 	    }
 
@@ -4678,11 +4710,15 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
 
 	      memcpy (lineno_cache, n_lineno_cache, amt);
 	    }
+	  else
+	    ret = FALSE;
 	  bfd_release (abfd, func_table);
 	}
+      else
+	ret = FALSE;
     }
 
-  return TRUE;
+  return ret;
 }
 
 /* Slurp in the symbol table, converting it to generic form.  Note
@@ -4697,6 +4733,7 @@ coff_slurp_symbol_table (bfd * abfd)
   unsigned int *table_ptr;
   bfd_size_type amt;
   unsigned int number_of_symbols = 0;
+  bfd_boolean ret = TRUE;
 
   if (obj_symbols (abfd))
     return TRUE;
@@ -5012,13 +5049,14 @@ coff_slurp_symbol_table (bfd * abfd)
 #if defined(TIC80COFF) || defined(TICOFF)
 	    case C_UEXT:	/* Tentative external definition.  */
 #endif
-	    case C_EXTLAB:	/* External load time label.  */
-	    case C_HIDDEN:	/* Ext symbol in dmert public lib.  */
 	    default:
 	      (*_bfd_error_handler)
 		(_("%B: Unrecognized storage class %d for %s symbol `%s'"),
 		 abfd, src->u.syment.n_sclass,
 		 dst->symbol.section->name, dst->symbol.name);
+	      ret = FALSE;
+	    case C_EXTLAB:	/* External load time label.  */
+	    case C_HIDDEN:	/* Ext symbol in dmert public lib.  */
 	      dst->symbol.flags = BSF_DEBUGGING;
 	      dst->symbol.value = (src->u.syment.n_value);
 	      break;
@@ -5046,12 +5084,13 @@ coff_slurp_symbol_table (bfd * abfd)
     p = abfd->sections;
     while (p)
       {
-	coff_slurp_line_table (abfd, p);
+	if (! coff_slurp_line_table (abfd, p))
+	  return FALSE;
 	p = p->next;
       }
   }
 
-  return TRUE;
+  return ret;
 }
 
 /* Classify a COFF symbol.  A couple of targets have globally visible
@@ -5310,7 +5349,7 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
 static reloc_howto_type *
 coff_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
 		     asection *sec ATTRIBUTE_UNUSED,
-		     struct internal_reloc *rel,
+		     struct internal_reloc *rel ATTRIBUTE_UNUSED,
 		     struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
 		     struct internal_syment *sym ATTRIBUTE_UNUSED,
 		     bfd_vma *addendp ATTRIBUTE_UNUSED)
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index a22f67a..d071d8a 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -146,8 +146,9 @@ make_a_section_from_file (bfd *abfd,
   /* Compress/decompress DWARF debug sections with names: .debug_* and
      .zdebug_*, after the section flags is set.  */
   if ((flags & SEC_DEBUGGING)
+      && strlen (name) > 7
       && ((name[1] == 'd' && name[6] == '_')
-	  || (name[1] == 'z' && name[7] == '_')))
+	  || (strlen (name) > 8 && name[1] == 'z' && name[7] == '_')))
     {
       enum { nothing, compress, decompress } action = nothing;
       char *new_name = NULL;
@@ -365,6 +366,10 @@ coff_object_p (bfd *abfd)
 	  bfd_release (abfd, opthdr);
 	  return NULL;
 	}
+      /* PR 17512: file: 11056-1136-0.004.  */
+      if (internal_f.f_opthdr < aoutsz)
+	memset (((char *) opthdr) + internal_f.f_opthdr, 0, aoutsz - internal_f.f_opthdr);
+
       bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a);
       bfd_release (abfd, opthdr);
     }
@@ -463,7 +468,10 @@ _bfd_coff_internal_syment_name (bfd *abfd,
 	  if (strings == NULL)
 	    return NULL;
 	}
-      if (sym->_n._n_n._n_offset >= obj_coff_strings_len (abfd))
+      /* PR 17910: Only check for string overflow if the length has been set.
+	 Some DLLs, eg those produced by Visual Studio, may not set the length field.  */
+      if (obj_coff_strings_len (abfd) > 0
+	  && sym->_n._n_n._n_offset >= obj_coff_strings_len (abfd))
 	return NULL;
       return strings + sym->_n._n_n._n_offset;
     }
@@ -760,8 +768,9 @@ coff_renumber_symbols (bfd *bfd_ptr, int *first_undef)
 
   for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
     {
-      coff_symbol_type *coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]);
+      coff_symbol_type *coff_symbol_ptr;
 
+      coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]);
       symbol_ptr_ptr[symbol_index]->udata.i = symbol_index;
       if (coff_symbol_ptr && coff_symbol_ptr->native)
 	{
@@ -805,9 +814,9 @@ coff_mangle_symbols (bfd *bfd_ptr)
 
   for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
     {
-      coff_symbol_type *coff_symbol_ptr =
-      coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]);
+      coff_symbol_type *coff_symbol_ptr;
 
+      coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]);
       if (coff_symbol_ptr && coff_symbol_ptr->native)
 	{
 	  int i;
@@ -1711,15 +1720,15 @@ _bfd_coff_read_string_table (bfd *abfd)
     }
 
   strings = (char *) bfd_malloc (strsize + 1);
+  if (strings == NULL)
+    return NULL;
+
   /* PR 17521 file: 079-54929-0.004.
      A corrupt file could contain an index that points into the first
      STRING_SIZE_SIZE bytes of the string table, so make sure that
      they are zero.  */
   memset (strings, 0, STRING_SIZE_SIZE);
 
-  if (strings == NULL)
-    return NULL;
-
   if (bfd_bread (strings + STRING_SIZE_SIZE, strsize - STRING_SIZE_SIZE, abfd)
       != strsize - STRING_SIZE_SIZE)
     {
@@ -1808,6 +1817,16 @@ coff_get_normalized_symtab (bfd *abfd)
       symbol_ptr = internal_ptr;
       internal_ptr->is_sym = TRUE;
 
+      /* PR 17512: file: 1353-1166-0.004.  */
+      if (symbol_ptr->u.syment.n_sclass == C_FILE
+	  && symbol_ptr->u.syment.n_numaux > 0
+	  && raw_src + symesz + symbol_ptr->u.syment.n_numaux
+	  * symesz > raw_end)
+	{
+	  bfd_release (abfd, internal);
+	  return NULL;
+	}
+
       for (i = 0;
 	   i < symbol_ptr->u.syment.n_numaux;
 	   i++)
@@ -1815,7 +1834,10 @@ coff_get_normalized_symtab (bfd *abfd)
 	  internal_ptr++;
 	  /* PR 17512: Prevent buffer overrun.  */
 	  if (internal_ptr >= internal_end)
-	    return NULL;
+	    {
+	      bfd_release (abfd, internal);
+	      return NULL;
+	    }
 
 	  raw_src += symesz;
 	  bfd_coff_swap_aux_in (abfd, (void *) raw_src,
@@ -1823,6 +1845,7 @@ coff_get_normalized_symtab (bfd *abfd)
 				symbol_ptr->u.syment.n_sclass,
 				(int) i, symbol_ptr->u.syment.n_numaux,
 				&(internal_ptr->u.auxent));
+
 	  internal_ptr->is_sym = FALSE;
 	  coff_pointerize_aux (abfd, internal, symbol_ptr, i,
 			       internal_ptr);
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index 2782795..ef9e362 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -2789,7 +2789,7 @@ _bfd_coff_reloc_link_order (bfd *output_bfd,
 
       size = bfd_get_reloc_size (howto);
       buf = (bfd_byte *) bfd_zmalloc (size);
-      if (buf == NULL)
+      if (buf == NULL && size != 0)
 	return FALSE;
 
       rstat = _bfd_relocate_contents (howto, output_bfd,
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
index 01f51e6..f65249b 100644
--- a/bfd/ecoff.c
+++ b/bfd/ecoff.c
@@ -504,7 +504,6 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd,
   struct fdr *fdr_ptr;
   bfd_size_type raw_end;
   bfd_size_type cb_end;
-  bfd_size_type amt;
   file_ptr pos;
 
   BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info);
@@ -607,14 +606,16 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd,
 
      We need to look at the fdr to deal with a lot of information in
      the symbols, so we swap them here.  */
-  amt = internal_symhdr->ifdMax;
-  amt *= sizeof (struct fdr);
-  debug->fdr = (FDR *) bfd_alloc (abfd, amt);
+  debug->fdr = (FDR *) bfd_alloc2 (abfd, internal_symhdr->ifdMax,
+				   sizeof (struct fdr));
   if (debug->fdr == NULL)
     return FALSE;
   external_fdr_size = backend->debug_swap.external_fdr_size;
   fdr_ptr = debug->fdr;
   fraw_src = (char *) debug->external_fdr;
+  /* PR 17512: file: 3372-1243-0.004.  */
+  if (fraw_src == NULL && internal_symhdr->ifdMax > 0)
+    return FALSE;
   fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size;
   for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
     (*backend->debug_swap.swap_fdr_in) (abfd, (void *) fraw_src, fdr_ptr);
@@ -856,7 +857,6 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd)
     = backend->debug_swap.swap_ext_in;
   void (* const swap_sym_in) (bfd *, void *, SYMR *)
     = backend->debug_swap.swap_sym_in;
-  bfd_size_type internal_size;
   ecoff_symbol_type *internal;
   ecoff_symbol_type *internal_ptr;
   char *eraw_src;
@@ -875,9 +875,8 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd)
   if (bfd_get_symcount (abfd) == 0)
     return TRUE;
 
-  internal_size = bfd_get_symcount (abfd);
-  internal_size *= sizeof (ecoff_symbol_type);
-  internal = (ecoff_symbol_type *) bfd_alloc (abfd, internal_size);
+  internal = (ecoff_symbol_type *) bfd_alloc2 (abfd, bfd_get_symcount (abfd),
+					       sizeof (ecoff_symbol_type)); 
   if (internal == NULL)
     return FALSE;
 
@@ -891,16 +890,30 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd)
       EXTR internal_esym;
 
       (*swap_ext_in) (abfd, (void *) eraw_src, &internal_esym);
+
+      /* PR 17512: file: 3372-1000-0.004.  */
+      if (internal_esym.asym.iss >= ecoff_data (abfd)->debug_info.symbolic_header.issExtMax
+	  || internal_esym.asym.iss < 0)
+	return FALSE;
+
       internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ssext
 				   + internal_esym.asym.iss);
+
       if (!ecoff_set_symbol_info (abfd, &internal_esym.asym,
 				  &internal_ptr->symbol, 1,
 				  internal_esym.weakext))
 	return FALSE;
+
       /* The alpha uses a negative ifd field for section symbols.  */
       if (internal_esym.ifd >= 0)
-	internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr
-			     + internal_esym.ifd);
+	{
+	  /* PR 17512: file: 3372-1983-0.004.  */
+	  if (internal_esym.ifd >= ecoff_data (abfd)->debug_info.symbolic_header.ifdMax)
+	    internal_ptr->fdr = NULL;
+	  else
+	    internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr
+				 + internal_esym.ifd);
+	}
       else
 	internal_ptr->fdr = NULL;
       internal_ptr->local = FALSE;
@@ -938,6 +951,20 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd)
 	}
     }
 
+  /* PR 17512: file: 3372-3080-0.004.
+     A discrepancy between ecoff_data (abfd)->debug_info.symbolic_header.isymMax
+     and ecoff_data (abfd)->debug_info.symbolic_header.ifdMax can mean that
+     we have fewer symbols than we were expecting.  Allow for this by updating
+     the symbol count and warning the user.  */
+  if (internal_ptr - internal < (ptrdiff_t) bfd_get_symcount (abfd))
+    {
+      bfd_get_symcount (abfd) = internal_ptr - internal;
+      (*_bfd_error_handler)
+	(_("%B: warning: isymMax (%ld) is greater than ifdMax (%d)\n"),
+	 abfd, ecoff_data (abfd)->debug_info.symbolic_header.isymMax,
+	 ecoff_data (abfd)->debug_info.symbolic_header.ifdMax);
+    }
+
   ecoff_data (abfd)->canonical_symbols = internal;
 
   return TRUE;
@@ -3976,7 +4003,7 @@ ecoff_reloc_link_order (bfd *output_bfd,
 
       size = bfd_get_reloc_size (rel.howto);
       buf = (bfd_byte *) bfd_zmalloc (size);
-      if (buf == NULL)
+      if (buf == NULL && size != 0)
 	return FALSE;
       rstat = _bfd_relocate_contents (rel.howto, output_bfd,
 				      (bfd_vma) addend, buf);
diff --git a/bfd/opncls.c b/bfd/opncls.c
index 75af627..404b944 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -940,15 +940,19 @@ bfd_alloc (bfd *abfd, bfd_size_type size)
   unsigned long ul_size = (unsigned long) size;
 
   if (size != ul_size
-      /* A small negative size can result in objalloc_alloc allocating just
-	 1 byte of memory, but the caller will be expecting more.  So catch
-	 this case here.  */
-      || (size != 0 && (((ul_size + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1)) == 0)))
+      /* Note - although objalloc_alloc takes an unsigned long as its
+	 argument, internally the size is treated as a signed long.  This can
+	 lead to problems where, for example, a request to allocate -1 bytes
+	 can result in just 1 byte being allocated, rather than
+	 ((unsigned long) -1) bytes.  Also memory checkers will often
+	 complain about attempts to allocate a negative amount of memory.
+	 So to stop these problems we fail if the size is negative.  */
+      || ((signed long) ul_size) < 0)
     {
       bfd_set_error (bfd_error_no_memory);
       return NULL;
     }
-							
+
   ret = objalloc_alloc ((struct objalloc *) abfd->memory, ul_size);
   if (ret == NULL)
     bfd_set_error (bfd_error_no_memory);
diff --git a/bfd/pe-mips.c b/bfd/pe-mips.c
index 57ec51f..d7edc2b 100644
--- a/bfd/pe-mips.c
+++ b/bfd/pe-mips.c
@@ -349,8 +349,11 @@ static reloc_howto_type howto_table[] =
 /* Customize coffcode.h.  */
 #define MIPS 1
 
-#define RTYPE2HOWTO(cache_ptr, dst) \
-	    (cache_ptr)->howto = howto_table + (dst)->r_type;
+#define RTYPE2HOWTO(cache_ptr, dst)				\
+  ((cache_ptr)->howto =						\
+   ((dst)->r_type < NUM_HOWTOS					\
+    ? howto_table + (dst)->r_type				\
+    : NULL))
 
 /* Compute the addend of a reloc.  If the reloc is to a common symbol,
    the object file contains the value of the common symbol.  By the
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 13e39e4..c09779a 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -526,6 +526,8 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
 	(*_bfd_error_handler)
 	  (_("%B: aout header specifies an invalid number of data-directory entries: %d"),
 	   abfd, a->NumberOfRvaAndSizes);
+	bfd_set_error (bfd_error_bad_value);
+
 	/* Paranoia: If the number is corrupt, then assume that the
 	   actual entries themselves might be corrupt as well.  */
 	a->NumberOfRvaAndSizes = 0;
@@ -1149,7 +1151,7 @@ _bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length
   /* Ensure null termination of filename.  */
   buffer[256] = '\0';
 
-  cvinfo->CVSignature = H_GET_32(abfd, buffer);
+  cvinfo->CVSignature = H_GET_32 (abfd, buffer);
   cvinfo->Age = 0;
 
   if ((cvinfo->CVSignature == CVINFO_PDB70_CVSIGNATURE)
@@ -1755,6 +1757,8 @@ pe_print_edata (bfd * abfd, void * vfile)
 
   /* PR 17512: Handle corrupt PE binaries.  */
   if (edt.eat_addr + (edt.num_functions * 4) - adj >= datasize
+      /* PR 17512: file: 092b1829 */
+      || (edt.num_functions * 4) < edt.num_functions
       /* PR 17512 file: 140-165018-0.004.  */
       || data + edt.eat_addr - adj < data)
     fprintf (file, _("\tInvalid Export Address Table rva (0x%lx) or entry count (0x%lx)\n"),
@@ -1799,6 +1803,8 @@ pe_print_edata (bfd * abfd, void * vfile)
 
   /* PR 17512: Handle corrupt PE binaries.  */
   if (edt.npt_addr + (edt.num_names * 4) - adj >= datasize
+      /* PR 17512: file: bb68816e.  */
+      || edt.num_names * 4 < edt.num_names
       || (data + edt.npt_addr - adj) < data)
     fprintf (file, _("\tInvalid Name Pointer Table rva (0x%lx) or entry count (0x%lx)\n"),
 	     (long) edt.npt_addr,
@@ -1890,6 +1896,14 @@ pe_print_pdata (bfd * abfd, void * vfile)
   if (datasize == 0)
     return TRUE;
 
+  /* PR 17512: file: 002-193900-0.004.  */
+  if (datasize < stop)
+    {
+      fprintf (file, _("Virtual size of .pdata section (%ld) larger than real size (%ld)\n"),
+	       (long) stop, (long) datasize);
+      return FALSE;
+    }
+
   if (! bfd_malloc_and_get_section (abfd, section, &data))
     {
       if (data != NULL)
@@ -1999,7 +2013,11 @@ slurp_symtab (bfd *abfd, sym_cache *psc)
   if (storage < 0)
     return NULL;
   if (storage)
-    sy = (asymbol **) bfd_malloc (storage);
+    {
+      sy = (asymbol **) bfd_malloc (storage);
+      if (sy == NULL)
+	return NULL;
+    }
 
   psc->symcount = bfd_canonicalize_symtab (abfd, sy);
   if (psc->symcount < 0)
@@ -2198,7 +2216,7 @@ pe_print_reloc (bfd * abfd, void * vfile)
     {
       int j;
       bfd_vma virtual_address;
-      long number, size;
+      unsigned long number, size;
       bfd_byte *chunk_end;
 
       /* The .reloc section is a sequence of blocks, with a header consisting
@@ -2213,7 +2231,7 @@ pe_print_reloc (bfd * abfd, void * vfile)
 
       fprintf (file,
 	       _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
-	       (unsigned long) virtual_address, size, (unsigned long) size, number);
+	       (unsigned long) virtual_address, size, size, number);
 
       chunk_end = p + size;
       if (chunk_end > end)
@@ -2284,6 +2302,7 @@ rsrc_print_resource_entries (FILE *         file,
 			     bfd_vma        rva_bias)
 {
   unsigned long entry, addr, size;
+  bfd_byte * leaf;
 
   if (data + 8 >= regions->section_end)
     return regions->section_end + 1;
@@ -2364,18 +2383,21 @@ rsrc_print_resource_entries (FILE *         file,
 					    regions, rva_bias);
     }
 
-  if (regions->section_start + entry + 16 >= regions->section_end)
+  leaf = regions->section_start + entry;
+
+  if (leaf + 16 >= regions->section_end
+      /* PR 17512: file: 055dff7e.  */
+      || leaf < regions->section_start)
     return regions->section_end + 1;
 
   fprintf (file, _("%03x %*.s  Leaf: Addr: %#08lx, Size: %#08lx, Codepage: %d\n"),
-	   (int) (entry),
-	   indent, " ",
-	   addr = (long) bfd_get_32 (abfd, regions->section_start + entry),
-	   size = (long) bfd_get_32 (abfd, regions->section_start + entry + 4),
-	   (int) bfd_get_32 (abfd, regions->section_start + entry + 8));
+	   (int) (entry), indent, " ",
+	   addr = (long) bfd_get_32 (abfd, leaf),
+	   size = (long) bfd_get_32 (abfd, leaf + 4),
+	   (int) bfd_get_32 (abfd, leaf + 8));
 
   /* Check that the reserved entry is 0.  */
-  if (bfd_get_32 (abfd, regions->section_start + entry + 12) != 0
+  if (bfd_get_32 (abfd, leaf + 12) != 0
       /* And that the data address/size is valid too.  */
       || (regions->section_start + (addr - rva_bias) + size > regions->section_end))
     return regions->section_end + 1;
@@ -2526,7 +2548,7 @@ rsrc_print_section (bfd * abfd, void * vfile)
 	      /* If the extra data is all zeros then do not complain.
 		 This is just padding so that the section meets the
 		 page size requirements.  */
-	      while (data ++ < regions.section_end)
+	      while (++ data < regions.section_end)
 		if (*data != 0)
 		  break;
 	      if (data < regions.section_end)
@@ -2652,7 +2674,10 @@ pe_print_debugdata (bfd * abfd, void * vfile)
       if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW)
         {
           char signature[CV_INFO_SIGNATURE_LENGTH * 2 + 1];
-          char buffer[256 + 1];
+	  /* PR 17512: file: 065-29434-0.001:0.1
+	     We need to use a 32-bit aligned buffer
+	     to safely read in a codeview record.  */
+          char buffer[256 + 1] ATTRIBUTE_ALIGNED_ALIGNOF (CODEVIEW_INFO);
           CODEVIEW_INFO *cvinfo = (CODEVIEW_INFO *) buffer;
 
           /* The debug entry doesn't have to have to be in a section,
@@ -2922,6 +2947,16 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
           struct external_IMAGE_DEBUG_DIRECTORY *dd =
 	    (struct external_IMAGE_DEBUG_DIRECTORY *)(data + (addr - section->vma));
 
+	  /* PR 17512: file: 0f15796a.  */
+	  if (ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size + (addr - section->vma)
+	      > bfd_get_section_size (section))
+	    {
+	      _bfd_error_handler (_("%B: Data Directory size (%lx) exceeds space left in section (%lx)"),
+				  obfd, ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size,
+				  bfd_get_section_size (section) - (addr - section->vma));
+	      return FALSE;
+	    }
+
           for (i = 0; i < ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
 		 / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
             {
@@ -2945,8 +2980,16 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
             }
 
           if (!bfd_set_section_contents (obfd, section, data, 0, section->size))
-            _bfd_error_handler (_("Failed to update file offsets in debug directory"));
+	    {
+	      _bfd_error_handler (_("Failed to update file offsets in debug directory"));
+	      return FALSE;
+	    }
         }
+      else if (section)
+	{
+	  _bfd_error_handler (_("%B: Failed to read debug data section"), obfd);
+	  return FALSE;
+	}
     }
 
   return TRUE;
@@ -3228,9 +3271,14 @@ rsrc_parse_entry (bfd *            abfd,
   if (entry->value.leaf == NULL)
     return dataend;
 
-  addr = bfd_get_32 (abfd, datastart + val);
-  size = entry->value.leaf->size = bfd_get_32 (abfd, datastart + val + 4);
-  entry->value.leaf->codepage = bfd_get_32 (abfd, datastart + val + 8);
+  data = datastart + val;
+  if (data < datastart || data >= dataend)
+    return dataend;
+
+  addr = bfd_get_32 (abfd, data);
+  size = entry->value.leaf->size = bfd_get_32 (abfd, data + 4);
+  entry->value.leaf->codepage = bfd_get_32 (abfd, data + 8);
+  /* FIXME: We assume that the reserved field (data + 12) is OK.  */
 
   entry->value.leaf->data = bfd_malloc (size);
   if (entry->value.leaf->data == NULL)
@@ -3560,6 +3608,7 @@ rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b)
 #elif defined HAVE_WCHAR_H
   {
     unsigned int  i;
+
     res = 0;
     for (i = min (alen, blen); i--; astring += 2, bstring += 2)
       {
@@ -4457,6 +4506,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
 	      }
 	    free (tmp_data);
 	  }
+	else
+	  result = FALSE;
       }
   }
 #endif
diff --git a/bfd/pei-x86_64.c b/bfd/pei-x86_64.c
index 48554d3..e53a353 100644
--- a/bfd/pei-x86_64.c
+++ b/bfd/pei-x86_64.c
@@ -276,8 +276,9 @@ pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
 	    fprintf (file, ", unknown(%u))", info);
 	  break;
 	default:
-	  /* Already caught by the previous scan.  */
-	  abort ();
+	  /* PR 17512: file: 2245-7442-0.004.  */
+	  fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1]));
+	  break;
       }
       if (unexpected)
 	fprintf (file, " [Unexpected!]");
@@ -317,17 +318,31 @@ pex64_dump_xdata (FILE *file, bfd *abfd,
   bfd_vma vaddr;
   bfd_vma end_addr;
   bfd_vma addr = rf->rva_UnwindData;
+  bfd_size_type sec_size = xdata_section->rawsize > 0 ? xdata_section->rawsize : xdata_section->size;
   struct pex64_unwind_info ui;
 
   vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
   addr -= vaddr;
 
+  /* PR 17512: file: 2245-7442-0.004.  */
+  if (addr >= sec_size)
+    {
+      fprintf (file, _("warning: xdata section corrupt\n"));
+      return;
+    }
+
   if (endx)
-    end_addr = endx[0] - vaddr;
+    {
+      end_addr = endx[0] - vaddr;
+      /* PR 17512: file: 2245-7442-0.004.  */
+      if (end_addr > sec_size)
+	{
+	  fprintf (file, _("warning: xdata section corrupt"));
+	  end_addr = sec_size;
+	}
+    }
   else
-    end_addr = (xdata_section->rawsize != 0 ?
-		xdata_section->rawsize : xdata_section->size);
-
+    end_addr = sec_size;
 
   pex64_get_unwind_info (abfd, &ui, &xdata[addr]);
 
@@ -380,7 +395,11 @@ pex64_dump_xdata (FILE *file, bfd *abfd,
 	   ui.FrameRegister == 0 ? "none"
 	   : pex_regs[(unsigned int) ui.FrameRegister]);
 
-  pex64_xdata_print_uwd_codes (file, abfd, &ui, rf);
+  /* PR 17512: file: 2245-7442-0.004.  */
+  if (ui.CountOfCodes * 2 + ui.rawUnwindCodes > xdata + xdata_section->size)
+    fprintf (file, _("Too many unwind codes (%ld)\n"), (long) ui.CountOfCodes);
+  else
+    pex64_xdata_print_uwd_codes (file, abfd, &ui, rf);
 
   switch (ui.Flags)
     {
@@ -439,23 +458,24 @@ sort_xdata_arr (const void *l, const void *r)
 /* Display unwind tables for x86-64.  */
 
 static bfd_boolean
-pex64_bfd_print_pdata (bfd *abfd, void *vfile)
+pex64_bfd_print_pdata_section (bfd *abfd, void *vfile, asection *pdata_section)
 {
   FILE *file = (FILE *) vfile;
   bfd_byte *pdata = NULL;
   bfd_byte *xdata = NULL;
-  asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata");
-  asection *xdata_section;
+  asection *xdata_section = NULL;
   bfd_vma xdata_base;
   bfd_size_type i;
+  bfd_size_type datasize;
   bfd_size_type stop;
-  bfd_vma prev_beginaddress = 0;
-  bfd_vma prev_unwinddata_rva = 0;
+  bfd_vma prev_beginaddress = (bfd_vma) -1;
+  bfd_vma prev_unwinddata_rva = (bfd_vma) -1;
   bfd_vma imagebase;
   int onaline = PDATA_ROW_SIZE;
   int seen_error = 0;
   bfd_vma *xdata_arr = NULL;
   int xdata_arr_cnt;
+  bfd_boolean virt_size_is_zero = FALSE;
 
   /* Sanity checks.  */
   if (pdata_section == NULL
@@ -466,12 +486,38 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
   stop = pei_section_data (abfd, pdata_section)->virt_size;
   if ((stop % onaline) != 0)
     fprintf (file,
-	     _("warning: .pdata section size (%ld) is not a multiple of %d\n"),
-	     (long) stop, onaline);
+	     _("Warning: %s section size (%ld) is not a multiple of %d\n"),
+	     pdata_section->name, (long) stop, onaline);
+
+  datasize = pdata_section->size;
+  if (datasize == 0)
+    {
+      if (stop)
+	fprintf (file, _("Warning: %s section size is zero\n"),
+		 pdata_section->name);
+      return TRUE;
+    }
+
+  /* virt_size might be zero for objects.  */
+  if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0)
+    {
+      stop = (datasize / onaline) * onaline;
+      virt_size_is_zero = TRUE;
+    }
+  else if (datasize < stop)
+      {
+	fprintf (file,
+		 _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"),
+		 pdata_section->name, (unsigned long) datasize,
+		 (unsigned long) stop);
+	/* Be sure not to read passed datasize.  */
+	stop = datasize / onaline;
+      }
 
   /* Display functions table.  */
   fprintf (file,
-	   _("\nThe Function Table (interpreted .pdata section contents)\n"));
+	   _("\nThe Function Table (interpreted %s section contents)\n"),
+	   pdata_section->name);
 
   fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t  UnwindData\n"));
 
@@ -482,7 +528,10 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
   xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
   xdata_arr_cnt = 0;
 
-  imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
+  if (strcmp (abfd->xvec->name, "pei-x86-64") == 0)
+    imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
+  else
+    imagebase = 0;
 
   for (i = 0; i < stop; i += onaline)
     {
@@ -490,6 +539,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
 
       if (i + PDATA_ROW_SIZE > stop)
 	break;
+
       pex64_get_runtime_function (abfd, &rf, &pdata[i]);
 
       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
@@ -528,8 +578,9 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
 	  seen_error = 1;
 	  fprintf (file, "  has negative unwind address\n");
 	}
-      if (rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
-        xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
+      else if ((rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
+		|| virt_size_is_zero)
+	xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
     }
 
   if (seen_error)
@@ -545,20 +596,42 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
 
   /* Find the section containing the unwind data (.xdata).  */
   xdata_base = xdata_arr[0];
-  xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata");
-
-  if (!xdata_section)
-    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data");
+  /* For sections with long names, first look for the same
+     section name, replacing .pdata by .xdata prefix.  */
+  if (strcmp (pdata_section->name, ".pdata") != 0)
+    {
+      size_t len = strlen (pdata_section->name);
+      char *xdata_name = alloca (len + 1);
+
+      xdata_name = memcpy (xdata_name, pdata_section->name, len + 1);
+      /* Transform .pdata prefix into .xdata prefix.  */
+      if (len > 1)
+	xdata_name [1] = 'x';
+      xdata_section = pex64_get_section_by_rva (abfd, xdata_base,
+						xdata_name);
+    }
+  /* Second, try the .xdata section itself.  */
   if (!xdata_section)
     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata");
-  if (!xdata_section)
+  /* Otherwise, if xdata_base is non zero, search also inside
+     other standard sections.  */
+  if (!xdata_section && xdata_base)
+    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata");
+  if (!xdata_section && xdata_base)
+    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data");
+  if (!xdata_section && xdata_base)
     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata");
-  if (!xdata_section)
+  if (!xdata_section && xdata_base)
     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text");
+  /* Transfer xdata section into xdata array.  */
   if (!xdata_section
       || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata))
     goto done;
 
+  /* Avoid "also used "... ouput for single unwind info
+     in object file.  */
+  prev_unwinddata_rva = (bfd_vma) -1;
+
   /* Do dump of pdata related xdata.  */
   for (i = 0; i < stop; i += onaline)
     {
@@ -566,6 +639,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
 
       if (i + PDATA_ROW_SIZE > stop)
 	break;
+
       pex64_get_runtime_function (abfd, &rf, &pdata[i]);
 
       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
@@ -573,7 +647,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
 	/* We are probably into the padding of the section now.  */
 	break;
       if (i == 0)
-        fprintf (file, "\nDump of .xdata\n");
+        fprintf (file, _("\nDump of %s\n"), xdata_section->name);
 
       fputc (' ', file);
       fprintf_vma (file, rf.rva_UnwindData + imagebase);
@@ -596,7 +670,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
       fprintf_vma (file, rf.rva_EndAddress + imagebase);
       fputc ('\n', file);
 
-      if (rf.rva_UnwindData != 0)
+      if (rf.rva_UnwindData != 0 || virt_size_is_zero)
 	{
 	  if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
 	    {
@@ -635,6 +709,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
 		 identical pointers in the array; advance past all of them.  */
 	      while (p[0] <= rf.rva_UnwindData)
 		++p;
+
 	      if (p[0] == ~((bfd_vma) 0))
 		p = NULL;
 
@@ -651,6 +726,37 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
   return TRUE;
 }
 
+/* Static counter of number of found pdata sections.  */
+static bfd_boolean pdata_count;
+
+/* Functionn prototype.  */
+bfd_boolean pex64_bfd_print_pdata (bfd *, void *);
+
+/* Helper function for bfd_map_over_section.  */
+static void
+pex64_print_all_pdata_sections (bfd *abfd, asection *pdata, void *obj)
+{
+  if (CONST_STRNEQ (pdata->name, ".pdata"))
+    {
+      if (pex64_bfd_print_pdata_section (abfd, obj, pdata))
+	pdata_count++;
+    }
+}
+
+bfd_boolean
+pex64_bfd_print_pdata (bfd *abfd, void *vfile)
+{
+  asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata");
+
+  if (pdata_section)
+    return pex64_bfd_print_pdata_section (abfd, vfile, pdata_section);
+
+  pdata_count = 0;
+  bfd_map_over_sections (abfd, pex64_print_all_pdata_sections, vfile);
+  return (pdata_count > 0);
+}
+
 #define bfd_pe_print_pdata   pex64_bfd_print_pdata
+#define bfd_coff_std_swap_table bfd_coff_pei_swap_table
 
 #include "coff-x86_64.c"
diff --git a/bfd/peicode.h b/bfd/peicode.h
index 8365353..ab39cd6 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -1343,7 +1343,10 @@ pe_bfd_object_p (bfd * abfd)
 	  != (bfd_size_type) opt_hdr_size)
 	return NULL;
 
+      bfd_set_error (bfd_error_no_error);
       bfd_coff_swap_aouthdr_in (abfd, opthdr, & internal_a);
+      if (bfd_get_error () != bfd_error_no_error)
+	return NULL;
     }
 
   return coff_real_object_p (abfd, internal_f.f_nscns, &internal_f,
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index 9522974..7f321ee 100644
--- a/bfd/xcofflink.c
+++ b/bfd/xcofflink.c
@@ -5738,7 +5738,7 @@ xcoff_reloc_link_order (bfd *output_bfd,
 
       size = bfd_get_reloc_size (howto);
       buf = bfd_zmalloc (size);
-      if (buf == NULL)
+      if (buf == NULL && size != 0)
 	return FALSE;
 
       rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);

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