Check corrupt VTENTRY entry in bfd_elf_gc_record_vtentry

Message ID 20190411033208.706-1-hjl.tools@gmail.com
State New
Headers show
Series
  • Check corrupt VTENTRY entry in bfd_elf_gc_record_vtentry
Related show

Commit Message

H.J. Lu April 11, 2019, 3:32 a.m.
Instead of BFD_ASSERT (h != NULL) with

ld: BFD ... assertion fail .../bfd/elf64-x86-64.c:2562
ld: bad.o: invalid string offset 50331648 >= 371 for section `nterp'

check corrupt VTENTRY entry in bfd_elf_gc_record_vtentry with

ld: bad.o: section 'g': corrupt VTENTRY entry

	* elf-m10300.c (mn10300_elf_check_relocs): Remove BFD_ASSERT of
	"h != NULL".  Don't check "h != NULL" before calling.
	bfd_elf_gc_record_vtentry.
	* elf32-arm.c (elf32_arm_check_relocs): Likewise.
	* elf32-bfin.c (bfin_check_relocs): Likewise.
	* elf32-cris.c (cris_elf_check_relocs): Likewise.
	* elf32-csky.c (csky_elf_check_relocs): Likewise.
	* elf32-d10v.c (elf32_d10v_check_relocs): Likewise.
	* elf32-dlx.c (elf32_dlx_check_relocs): Likewise.
	* elf32-fr30.c (fr30_elf_check_relocs): Likewise.
	* elf32-frv.c (elf32_frv_check_relocs): Likewise.
	* elf32-hppa.c (elf32_hppa_check_relocs): Likewise.
	* elf32-i386.c (elf_i386_check_relocs): Likewise.
	* elf32-iq2000.c (iq2000_elf_check_relocs): Likewise.
	* elf32-m32r.c (m32r_elf_check_relocs): Likewise.
	* elf32-m68hc1x.c (elf32_m68hc11_check_relocs): Likewise.
	* elf32-m68k.c (elf_m68k_check_relocs): Likewise.
	* elf32-mcore.c (mcore_elf_check_relocs): Likewise.
	* elf32-metag.c (elf_metag_check_relocs): Likewise.
	* elf32-or1k.c (or1k_elf_check_relocs): Likewise.
	* elf32-ppc.c (ppc_elf_check_relocs): Likewise.
	* elf32-s390.c (elf_s390_check_relocs): Likewise.
	* elf32-sh.c (sh_elf_check_relocs): Likewise.
	* elf32-v850.c (v850_elf_check_relocs): Likewise.
	* elf32-vax.c (elf_vax_check_relocs): Likewise.
	* elf32-xstormy16.c (xstormy16_elf_check_relocs): Likewise.
	* elf32-xtensa.c (elf_xtensa_check_relocs): Likewise.
	* elf64-mmix.c (mmix_elf_check_relocs): Likewise.
	* elf64-ppc.c (ppc64_elf_check_relocs): Likewise.
	* elf64-s390.c (elf_s390_check_relocs): Likewise.
	* elf64-x86-64.c (elf_s390_check_relocs): Likewise.
	* elfxx-mips.c (_bfd_mips_elf_check_relocs): Likewise.
	* elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Likewise.
	* elflink.c (bfd_elf_gc_record_vtinherit): Check for corrupt
	VTENTRY entry.
---
 bfd/elf-m10300.c      |  4 +---
 bfd/elf32-arm.c       |  4 +---
 bfd/elf32-bfin.c      |  4 +---
 bfd/elf32-cris.c      |  4 +---
 bfd/elf32-csky.c      |  4 +---
 bfd/elf32-d10v.c      |  4 +---
 bfd/elf32-dlx.c       |  4 +---
 bfd/elf32-fr30.c      |  4 +---
 bfd/elf32-frv.c       |  4 +---
 bfd/elf32-hppa.c      |  6 +++---
 bfd/elf32-i386.c      |  4 +---
 bfd/elf32-iq2000.c    |  4 +---
 bfd/elf32-m32r.c      |  8 ++------
 bfd/elf32-m68hc1x.c   |  4 +---
 bfd/elf32-m68k.c      |  4 +---
 bfd/elf32-mcore.c     |  4 +---
 bfd/elf32-metag.c     |  4 +---
 bfd/elf32-or1k.c      |  4 +---
 bfd/elf32-ppc.c       |  4 +---
 bfd/elf32-s390.c      |  4 +---
 bfd/elf32-sh.c        |  4 +---
 bfd/elf32-v850.c      |  4 +---
 bfd/elf32-vax.c       |  4 +---
 bfd/elf32-xstormy16.c |  4 +---
 bfd/elf32-xtensa.c    |  4 +---
 bfd/elf64-mmix.c      |  4 +---
 bfd/elf64-ppc.c       |  4 +---
 bfd/elf64-s390.c      |  4 +---
 bfd/elf64-x86-64.c    |  4 +---
 bfd/elflink.c         | 12 ++++++++++--
 bfd/elfxx-mips.c      |  4 +---
 bfd/elfxx-sparc.c     |  4 +---
 32 files changed, 44 insertions(+), 98 deletions(-)

-- 
2.20.1

Comments

Alan Modra April 11, 2019, 6:08 a.m. | #1
On Wed, Apr 10, 2019 at 08:32:08PM -0700, H.J. Lu wrote:
> 	* elf-m10300.c (mn10300_elf_check_relocs): Remove BFD_ASSERT of

> 	"h != NULL".  Don't check "h != NULL" before calling.

> 	bfd_elf_gc_record_vtentry.

> 	* elf32-arm.c (elf32_arm_check_relocs): Likewise.

> 	* elf32-bfin.c (bfin_check_relocs): Likewise.

> 	* elf32-cris.c (cris_elf_check_relocs): Likewise.

> 	* elf32-csky.c (csky_elf_check_relocs): Likewise.

> 	* elf32-d10v.c (elf32_d10v_check_relocs): Likewise.

> 	* elf32-dlx.c (elf32_dlx_check_relocs): Likewise.

> 	* elf32-fr30.c (fr30_elf_check_relocs): Likewise.

> 	* elf32-frv.c (elf32_frv_check_relocs): Likewise.

> 	* elf32-hppa.c (elf32_hppa_check_relocs): Likewise.

> 	* elf32-i386.c (elf_i386_check_relocs): Likewise.

> 	* elf32-iq2000.c (iq2000_elf_check_relocs): Likewise.

> 	* elf32-m32r.c (m32r_elf_check_relocs): Likewise.

> 	* elf32-m68hc1x.c (elf32_m68hc11_check_relocs): Likewise.

> 	* elf32-m68k.c (elf_m68k_check_relocs): Likewise.

> 	* elf32-mcore.c (mcore_elf_check_relocs): Likewise.

> 	* elf32-metag.c (elf_metag_check_relocs): Likewise.

> 	* elf32-or1k.c (or1k_elf_check_relocs): Likewise.

> 	* elf32-ppc.c (ppc_elf_check_relocs): Likewise.

> 	* elf32-s390.c (elf_s390_check_relocs): Likewise.

> 	* elf32-sh.c (sh_elf_check_relocs): Likewise.

> 	* elf32-v850.c (v850_elf_check_relocs): Likewise.

> 	* elf32-vax.c (elf_vax_check_relocs): Likewise.

> 	* elf32-xstormy16.c (xstormy16_elf_check_relocs): Likewise.

> 	* elf32-xtensa.c (elf_xtensa_check_relocs): Likewise.

> 	* elf64-mmix.c (mmix_elf_check_relocs): Likewise.

> 	* elf64-ppc.c (ppc64_elf_check_relocs): Likewise.

> 	* elf64-s390.c (elf_s390_check_relocs): Likewise.

> 	* elf64-x86-64.c (elf_s390_check_relocs): Likewise.

> 	* elfxx-mips.c (_bfd_mips_elf_check_relocs): Likewise.

> 	* elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Likewise.

> 	* elflink.c (bfd_elf_gc_record_vtinherit): Check for corrupt

> 	VTENTRY entry.


OK, thanks, except

> --- a/bfd/elf32-hppa.c

> +++ b/bfd/elf32-hppa.c

> @@ -1273,9 +1273,9 @@ elf32_hppa_check_relocs (bfd *abfd,

>  	  /* This relocation describes which C++ vtable entries are actually

>  	     used.  Record for later use during GC.  */

>  	case R_PARISC_GNU_VTENTRY:

> -	  BFD_ASSERT (hh != NULL);

> -	  if (hh != NULL

> -	      && !bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rela->r_addend))

> +	  if (!bfd_elf_gc_record_vtentry (abfd, sec,

> +					  hh ? &hh->eh : NULL,

> +					  rela->r_addend))

>  	    return FALSE;

>  	  continue;

>  


let's not special case hh being NULL here.  The call as written before
should be fine.  &hh->eh is equivalent to
(struct elf_link_hash_entry *) hh.

Is this a work-around for some nonsense compiler warning?  If so, how
does it fare with the typical offsetof macro?
#define offsetof(type, member) ((size_t) &((type *) 0)->member)

-- 
Alan Modra
Australia Development Lab, IBM
H.J. Lu April 11, 2019, 1:46 p.m. | #2
On Wed, Apr 10, 2019 at 11:08 PM Alan Modra <amodra@gmail.com> wrote:
>

> On Wed, Apr 10, 2019 at 08:32:08PM -0700, H.J. Lu wrote:

> >       * elf-m10300.c (mn10300_elf_check_relocs): Remove BFD_ASSERT of

> >       "h != NULL".  Don't check "h != NULL" before calling.

> >       bfd_elf_gc_record_vtentry.

> >       * elf32-arm.c (elf32_arm_check_relocs): Likewise.

> >       * elf32-bfin.c (bfin_check_relocs): Likewise.

> >       * elf32-cris.c (cris_elf_check_relocs): Likewise.

> >       * elf32-csky.c (csky_elf_check_relocs): Likewise.

> >       * elf32-d10v.c (elf32_d10v_check_relocs): Likewise.

> >       * elf32-dlx.c (elf32_dlx_check_relocs): Likewise.

> >       * elf32-fr30.c (fr30_elf_check_relocs): Likewise.

> >       * elf32-frv.c (elf32_frv_check_relocs): Likewise.

> >       * elf32-hppa.c (elf32_hppa_check_relocs): Likewise.

> >       * elf32-i386.c (elf_i386_check_relocs): Likewise.

> >       * elf32-iq2000.c (iq2000_elf_check_relocs): Likewise.

> >       * elf32-m32r.c (m32r_elf_check_relocs): Likewise.

> >       * elf32-m68hc1x.c (elf32_m68hc11_check_relocs): Likewise.

> >       * elf32-m68k.c (elf_m68k_check_relocs): Likewise.

> >       * elf32-mcore.c (mcore_elf_check_relocs): Likewise.

> >       * elf32-metag.c (elf_metag_check_relocs): Likewise.

> >       * elf32-or1k.c (or1k_elf_check_relocs): Likewise.

> >       * elf32-ppc.c (ppc_elf_check_relocs): Likewise.

> >       * elf32-s390.c (elf_s390_check_relocs): Likewise.

> >       * elf32-sh.c (sh_elf_check_relocs): Likewise.

> >       * elf32-v850.c (v850_elf_check_relocs): Likewise.

> >       * elf32-vax.c (elf_vax_check_relocs): Likewise.

> >       * elf32-xstormy16.c (xstormy16_elf_check_relocs): Likewise.

> >       * elf32-xtensa.c (elf_xtensa_check_relocs): Likewise.

> >       * elf64-mmix.c (mmix_elf_check_relocs): Likewise.

> >       * elf64-ppc.c (ppc64_elf_check_relocs): Likewise.

> >       * elf64-s390.c (elf_s390_check_relocs): Likewise.

> >       * elf64-x86-64.c (elf_s390_check_relocs): Likewise.

> >       * elfxx-mips.c (_bfd_mips_elf_check_relocs): Likewise.

> >       * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Likewise.

> >       * elflink.c (bfd_elf_gc_record_vtinherit): Check for corrupt

> >       VTENTRY entry.

>

> OK, thanks, except

>

> > --- a/bfd/elf32-hppa.c

> > +++ b/bfd/elf32-hppa.c

> > @@ -1273,9 +1273,9 @@ elf32_hppa_check_relocs (bfd *abfd,

> >         /* This relocation describes which C++ vtable entries are actually

> >            used.  Record for later use during GC.  */

> >       case R_PARISC_GNU_VTENTRY:

> > -       BFD_ASSERT (hh != NULL);

> > -       if (hh != NULL

> > -           && !bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rela->r_addend))

> > +       if (!bfd_elf_gc_record_vtentry (abfd, sec,

> > +                                       hh ? &hh->eh : NULL,

> > +                                       rela->r_addend))

> >           return FALSE;

> >         continue;

> >

>

> let's not special case hh being NULL here.  The call as written before

> should be fine.  &hh->eh is equivalent to

> (struct elf_link_hash_entry *) hh.

>

> Is this a work-around for some nonsense compiler warning?  If so, how

> does it fare with the typical offsetof macro?

> #define offsetof(type, member) ((size_t) &((type *) 0)->member)

>


Fixed and pushed.

Thanks.

-- 
H.J.

Patch

diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c
index 398636ae0e..f0ef8eb0be 100644
--- a/bfd/elf-m10300.c
+++ b/bfd/elf-m10300.c
@@ -1136,9 +1136,7 @@  mn10300_elf_check_relocs (bfd *abfd,
 	/* This relocation describes which C++ vtable entries are actually
 	   used.  Record for later use during GC.  */
 	case R_MN10300_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    goto fail;
 	  break;
 
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index b5b2dab357..03f3a59171 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -15380,9 +15380,7 @@  elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	/* This relocation describes which C++ vtable entries are actually
 	   used.  Record for later use during GC.  */
 	case R_ARM_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
 	    return FALSE;
 	  break;
 	}
diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c
index 2e4751f89c..db052a1ff2 100644
--- a/bfd/elf32-bfin.c
+++ b/bfd/elf32-bfin.c
@@ -1210,9 +1210,7 @@  bfin_check_relocs (bfd * abfd,
 	/* This relocation describes which C++ vtable entries
 	   are actually used.  Record for later use during GC.  */
 	case R_BFIN_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c
index 520b61a3f1..595c36be1f 100644
--- a/bfd/elf32-cris.c
+++ b/bfd/elf32-cris.c
@@ -3485,9 +3485,7 @@  cris_elf_check_relocs (bfd *abfd,
 	/* This relocation describes which C++ vtable entries are actually
 	   used.  Record for later use during GC.  */
 	case R_CRIS_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf32-csky.c b/bfd/elf32-csky.c
index fb380b1395..b3451b60b2 100644
--- a/bfd/elf32-csky.c
+++ b/bfd/elf32-csky.c
@@ -2873,9 +2873,7 @@  csky_elf_check_relocs (bfd * abfd,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_CKCORE_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 	}
diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c
index 0c05106835..4cd0aec106 100644
--- a/bfd/elf32-d10v.c
+++ b/bfd/elf32-d10v.c
@@ -308,9 +308,7 @@  elf32_d10v_check_relocs (bfd *abfd,
 	/* This relocation describes which C++ vtable entries are actually
 	   used.  Record for later use during GC.  */
 	case R_D10V_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
 	    return FALSE;
 	  break;
 	}
diff --git a/bfd/elf32-dlx.c b/bfd/elf32-dlx.c
index f66e944170..edddcb1085 100644
--- a/bfd/elf32-dlx.c
+++ b/bfd/elf32-dlx.c
@@ -465,9 +465,7 @@  elf32_dlx_check_relocs (bfd *abfd,
 	/* This relocation describes which C++ vtable entries are actually
 	   used.  Record for later use during GC.  */
 	case R_DLX_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 	}
diff --git a/bfd/elf32-fr30.c b/bfd/elf32-fr30.c
index 3a0c3ae209..6a13767c7a 100644
--- a/bfd/elf32-fr30.c
+++ b/bfd/elf32-fr30.c
@@ -687,9 +687,7 @@  fr30_elf_check_relocs (bfd *abfd,
 	/* This relocation describes which C++ vtable entries are actually
 	   used.  Record for later use during GC.  */
 	case R_FR30_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 	}
diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c
index ebc101ede8..8c6a97dea2 100644
--- a/bfd/elf32-frv.c
+++ b/bfd/elf32-frv.c
@@ -6237,9 +6237,7 @@  elf32_frv_check_relocs (bfd *abfd,
 	/* This relocation describes which C++ vtable entries are actually
 	   used.  Record for later use during GC.  */
 	case R_FRV_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
index 95b729aa75..c05545488c 100644
--- a/bfd/elf32-hppa.c
+++ b/bfd/elf32-hppa.c
@@ -1273,9 +1273,9 @@  elf32_hppa_check_relocs (bfd *abfd,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_PARISC_GNU_VTENTRY:
-	  BFD_ASSERT (hh != NULL);
-	  if (hh != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rela->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec,
+					  hh ? &hh->eh : NULL,
+					  rela->r_addend))
 	    return FALSE;
 	  continue;
 
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 5d3f2eb4b5..d2ea5a729e 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -1908,9 +1908,7 @@  do_size:
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_386_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
 	    goto error_return;
 	  break;
 
diff --git a/bfd/elf32-iq2000.c b/bfd/elf32-iq2000.c
index 096122687d..6e47027292 100644
--- a/bfd/elf32-iq2000.c
+++ b/bfd/elf32-iq2000.c
@@ -501,9 +501,7 @@  iq2000_elf_check_relocs (bfd *abfd,
 	  /* This relocation describes which C++ vtable entries
 	     are actually used.  Record for later use during GC.  */
 	case R_IQ2000_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
index 92ed2d19b0..8f05a5e4d6 100644
--- a/bfd/elf32-m32r.c
+++ b/bfd/elf32-m32r.c
@@ -3807,15 +3807,11 @@  m32r_elf_check_relocs (bfd *abfd,
 	/* This relocation describes which C++ vtable entries are actually
 	   used.  Record for later use during GC.  */
 	case R_M32R_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
 	    return FALSE;
 	  break;
 	case R_M32R_RELA_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 	}
diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c
index 7a01749191..6a996789b5 100644
--- a/bfd/elf32-m68hc1x.c
+++ b/bfd/elf32-m68hc1x.c
@@ -890,9 +890,7 @@  elf32_m68hc11_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	/* This relocation describes which C++ vtable entries are actually
 	   used.  Record for later use during GC.  */
 	case R_M68HC11_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 	}
diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c
index 8d0eab06f2..0fe546661f 100644
--- a/bfd/elf32-m68k.c
+++ b/bfd/elf32-m68k.c
@@ -2801,9 +2801,7 @@  elf_m68k_check_relocs (bfd *abfd,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_68K_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf32-mcore.c b/bfd/elf32-mcore.c
index 764623cce6..7bca458508 100644
--- a/bfd/elf32-mcore.c
+++ b/bfd/elf32-mcore.c
@@ -628,9 +628,7 @@  mcore_elf_check_relocs (bfd * abfd,
 	/* This relocation describes which C++ vtable entries are actually
 	   used.  Record for later use during GC.  */
 	case R_MCORE_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 	}
diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c
index 6d48c8c988..f68f9dca6f 100644
--- a/bfd/elf32-metag.c
+++ b/bfd/elf32-metag.c
@@ -2374,9 +2374,7 @@  elf_metag_check_relocs (bfd *abfd,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_METAG_GNU_VTENTRY:
-	  BFD_ASSERT (hh != NULL);
-	  if (hh != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rel->r_addend))
 	    return FALSE;
 	  break;
 	}
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
index 2f200b197b..c1bbac98fb 100644
--- a/bfd/elf32-or1k.c
+++ b/bfd/elf32-or1k.c
@@ -1927,9 +1927,7 @@  or1k_elf_check_relocs (bfd *abfd,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_OR1K_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 6991e8ddc1..e73539afa2 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -3316,9 +3316,7 @@  ppc_elf_check_relocs (bfd *abfd,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_PPC_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
index 49a301f062..7bdccdbef9 100644
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -1366,9 +1366,7 @@  elf_s390_check_relocs (bfd *abfd,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_390_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index d66ac1269f..91900b8bea 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -5570,9 +5570,7 @@  sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_SH_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c
index 0de095d3aa..90a18d3a8d 100644
--- a/bfd/elf32-v850.c
+++ b/bfd/elf32-v850.c
@@ -101,9 +101,7 @@  v850_elf_check_relocs (bfd *abfd,
 	/* This relocation describes which C++ vtable entries
 	   are actually used.  Record for later use during GC.  */
 	case R_V850_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c
index 10c01a9b9e..2af7050707 100644
--- a/bfd/elf32-vax.c
+++ b/bfd/elf32-vax.c
@@ -783,9 +783,7 @@  elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_VAX_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf32-xstormy16.c b/bfd/elf32-xstormy16.c
index a64513d578..05a9326685 100644
--- a/bfd/elf32-xstormy16.c
+++ b/bfd/elf32-xstormy16.c
@@ -513,9 +513,7 @@  xstormy16_elf_check_relocs (bfd *abfd,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_XSTORMY16_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 	}
diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
index 37ea200eea..09625e6087 100644
--- a/bfd/elf32-xtensa.c
+++ b/bfd/elf32-xtensa.c
@@ -1102,9 +1102,7 @@  elf_xtensa_check_relocs (bfd *abfd,
 	case R_XTENSA_GNU_VTENTRY:
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  continue;
 
diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c
index d332151a36..839bd45b4a 100644
--- a/bfd/elf64-mmix.c
+++ b/bfd/elf64-mmix.c
@@ -2004,9 +2004,7 @@  mmix_elf_check_relocs (bfd *abfd,
 	/* This relocation describes which C++ vtable entries are actually
 	   used.  Record for later use during GC.  */
 	case R_MMIX_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 	}
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 5be3fe00f1..a795ad1578 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -4555,9 +4555,7 @@  ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_PPC64_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
index 3879676ff3..6bc6dfd50e 100644
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -1301,9 +1301,7 @@  elf_s390_check_relocs (bfd *abfd,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_390_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 6790228271..27e23a0793 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2373,9 +2373,7 @@  do_size:
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_X86_64_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    goto error_return;
 	  break;
 
diff --git a/bfd/elflink.c b/bfd/elflink.c
index c796e27a14..85fda6f5d2 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -13727,14 +13727,22 @@  bfd_elf_gc_record_vtinherit (bfd *abfd,
 /* Called from check_relocs to record the existence of a VTENTRY reloc.  */
 
 bfd_boolean
-bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED,
-			   asection *sec ATTRIBUTE_UNUSED,
+bfd_elf_gc_record_vtentry (bfd *abfd, asection *sec,
 			   struct elf_link_hash_entry *h,
 			   bfd_vma addend)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   unsigned int log_file_align = bed->s->log_file_align;
 
+  if (!h)
+    {
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: section '%pA': corrupt VTENTRY entry"),
+			  abfd, sec);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+
   if (!h->u2.vtable)
     {
       h->u2.vtable = ((struct elf_link_virtual_table_entry *)
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 5998bc43a8..74dadf48f7 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -8992,9 +8992,7 @@  _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  /* This relocation describes which C++ vtable entries are actually
 	     used.  Record for later use during GC.  */
 	case R_MIPS_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
 	    return FALSE;
 	  break;
 
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index f09dcbdc18..e479884071 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -1837,9 +1837,7 @@  _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  break;
 
 	case R_SPARC_GNU_VTENTRY:
-	  BFD_ASSERT (h != NULL);
-	  if (h != NULL
-	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 	    return FALSE;
 	  break;