From 45a0eaf77022963d639d6d19871dbab7b79703fc Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Tue, 23 Oct 2018 19:02:06 +1030
Subject: [PATCH] PR23806, NULL pointer dereference in merge_strings

        PR 23806
        * merge.c (_bfd_add_merge_section): Don't attempt to merge
        sections with ridiculously large alignments.
---
 bfd/ChangeLog |  6 ++++++
 bfd/merge.c   | 15 +++++++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index cc04287..f13882a 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,11 @@
 2018-10-23  Alan Modra  <amodra@gmail.com>
 
+	PR 23806
+	* merge.c (_bfd_add_merge_section): Don't attempt to merge
+	sections with ridiculously large alignments.
+
+2018-10-23  Alan Modra  <amodra@gmail.com>
+
 	PR 23805
 	* elflink.c (elf_link_input_bfd): Don't segfault on finding
 	STT_TLS symbols without any TLS sections.  Instead, change the
diff --git a/bfd/merge.c b/bfd/merge.c
index 5e3bba0..7de0c88 100644
--- a/bfd/merge.c
+++ b/bfd/merge.c
@@ -24,6 +24,7 @@
    as used in ELF SHF_MERGE.  */
 
 #include "sysdep.h"
+#include <limits.h>
 #include "bfd.h"
 #include "elf-bfd.h"
 #include "libbfd.h"
@@ -385,12 +386,18 @@ _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
       return TRUE;
     }
 
-  align = sec->alignment_power;
-  if ((sec->entsize < (unsigned) 1 << align
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+  if (sec->alignment_power >= sizeof (align) * CHAR_BIT)
+    return TRUE;
+
+  align = 1u << sec->alignment_power;
+  if ((sec->entsize < align
        && ((sec->entsize & (sec->entsize - 1))
 	   || !(sec->flags & SEC_STRINGS)))
-      || (sec->entsize > (unsigned) 1 << align
-	  && (sec->entsize & (((unsigned) 1 << align) - 1))))
+      || (sec->entsize > align
+	  && (sec->entsize & (align - 1))))
     {
       /* Sanity check.  If string character size is smaller than
 	 alignment, then we require character size to be a power