From ee3b52e917c3a19850232a6a20f5698090619fc6 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 30 Dec 2014 19:09:11 -0800
Subject: Assign file position for .strtab only if needed

bfd/

	PR ld/17773
	* elflink.c (bfd_elf_final_link): Assign the file position for
	the symbol string table only there are symbols to be emitted.

ld/testsuite/

	PR ld/17773
	* ld-elf/binutils.exp (binutils_test): Add an optional
	readelf_options.  Replace -l with $readelf_options.  Add a
	gap test.
	* ld/testsuite/ld-elf/gap.s: New file.
---
 bfd/ChangeLog                    |  6 ++++++
 bfd/elflink.c                    | 38 ++++++++++++++++++++------------------
 ld/testsuite/ChangeLog           |  8 ++++++++
 ld/testsuite/ld-elf/binutils.exp | 15 +++++++++------
 ld/testsuite/ld-elf/gap.s        |  4 ++++
 5 files changed, 47 insertions(+), 24 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/gap.s

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b883d3c..02b1ef7 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2014-12-30  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/17773
+	* elflink.c (bfd_elf_final_link): Assign the file position for
+	the symbol string table only there are symbols to be emitted.
+
 2014-12-28  Alan Modra  <amodra@gmail.com>
 
 	PR 17766
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 16421cf..1ceb9e5 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -10614,7 +10614,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   unsigned int i;
   Elf_Internal_Shdr *symtab_hdr;
   Elf_Internal_Shdr *symtab_shndx_hdr;
-  Elf_Internal_Shdr *symstrtab_hdr;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   struct elf_outext_info eoinfo;
   bfd_boolean merged;
@@ -11315,25 +11314,28 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
     }
 
 
-  /* Finish up and write out the symbol string table (.strtab)
-     section.  */
-  symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
-  /* sh_name was set in prep_headers.  */
-  symstrtab_hdr->sh_type = SHT_STRTAB;
-  symstrtab_hdr->sh_flags = 0;
-  symstrtab_hdr->sh_addr = 0;
-  symstrtab_hdr->sh_size = _bfd_stringtab_size (flinfo.symstrtab);
-  symstrtab_hdr->sh_entsize = 0;
-  symstrtab_hdr->sh_link = 0;
-  symstrtab_hdr->sh_info = 0;
-  /* sh_offset is set just below.  */
-  symstrtab_hdr->sh_addralign = 1;
-
-  off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, TRUE);
-  elf_next_file_pos (abfd) = off;
-
   if (bfd_get_symcount (abfd) > 0)
     {
+      /* Finish up and write out the symbol string table (.strtab)
+	 section.  */
+      Elf_Internal_Shdr *symstrtab_hdr;
+
+      symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
+      /* sh_name was set in prep_headers.  */
+      symstrtab_hdr->sh_type = SHT_STRTAB;
+      symstrtab_hdr->sh_flags = 0;
+      symstrtab_hdr->sh_addr = 0;
+      symstrtab_hdr->sh_size = _bfd_stringtab_size (flinfo.symstrtab);
+      symstrtab_hdr->sh_entsize = 0;
+      symstrtab_hdr->sh_link = 0;
+      symstrtab_hdr->sh_info = 0;
+      /* sh_offset is set just below.  */
+      symstrtab_hdr->sh_addralign = 1;
+
+      off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr,
+						       off, TRUE);
+      elf_next_file_pos (abfd) = off;
+
       if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0
 	  || ! _bfd_stringtab_emit (abfd, flinfo.symstrtab))
 	return FALSE;
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 6fc0318..49ab015 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2014-12-30  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/17773
+	* ld-elf/binutils.exp (binutils_test): Add an optional
+	readelf_options.  Replace -l with $readelf_options.  Add a
+	gap test.
+	* ld/testsuite/ld-elf/gap.s: New file.
+
 2014-12-26  Alan Modra  <amodra@gmail.com>
 
 	* ld-sh/sh64/crangerel1.rd: Update.
diff --git a/ld/testsuite/ld-elf/binutils.exp b/ld/testsuite/ld-elf/binutils.exp
index 4ade8cb..37ab6b3 100644
--- a/ld/testsuite/ld-elf/binutils.exp
+++ b/ld/testsuite/ld-elf/binutils.exp
@@ -38,8 +38,9 @@ if { [istarget *-*-linux*aout*]
 # to hardwire the test name. This is important if ld_options contains
 # absolute path names because the default test name is constructed
 # from the prog_name and ld_options and we do not want absolute paths
-# to appear in the test_name.
-proc binutils_test { prog_name ld_options test {test_name ""}} {
+# to appear in the test_name.  The optional readelf_options can be
+# used to specify different options for readelf.
+proc binutils_test { prog_name ld_options test {test_name ""} {readelf_options "-l"}} {
     global as
     global ld
     global READELF
@@ -71,8 +72,8 @@ proc binutils_test { prog_name ld_options test {test_name ""}} {
 	return
     }
 
-    send_log "$READELF -l --wide tmpdir/$test > tmpdir/$test.exp\n"
-    set got [remote_exec host "$READELF -l --wide tmpdir/$test" "" "/dev/null" "tmpdir/$test.exp"]
+    send_log "$READELF $readelf_options --wide tmpdir/$test > tmpdir/$test.exp\n"
+    set got [remote_exec host "$READELF $readelf_options --wide tmpdir/$test" "" "/dev/null" "tmpdir/$test.exp"]
     if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
 	send_log "$got\n"
 	unresolved "$test_name"
@@ -111,8 +112,8 @@ proc binutils_test { prog_name ld_options test {test_name ""}} {
 	return
     }
 
-    send_log "$READELF -l --wide tmpdir/$test > tmpdir/$test.out\n"
-    set got [remote_exec host "$READELF -l --wide tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+    send_log "$READELF $readelf_options --wide tmpdir/$test > tmpdir/$test.out\n"
+    set got [remote_exec host "$READELF $readelf_options --wide tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
     if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
 	send_log "$got\n"
 	unresolved "$test_name"
@@ -176,3 +177,5 @@ foreach testitem $tls_tests {
 	binutils_test objcopy $testopt $testitem
     }
 }
+
+binutils_test strip "-s" gap "" "-lS"
diff --git a/ld/testsuite/ld-elf/gap.s b/ld/testsuite/ld-elf/gap.s
new file mode 100644
index 0000000..039d26b
--- /dev/null
+++ b/ld/testsuite/ld-elf/gap.s
@@ -0,0 +1,4 @@
+ .text
+ .global _start
+_start:
+ .long 0
-- 
cgit v1.1