[3/4] MIPS/BFD: Fix the size of `.reginfo' and `.MIPS.abiflags' sections

Message ID alpine.DEB.2.00.1801310045390.4074@tp.orcam.me.uk
State New
Headers show
Series
  • LD: Support fixed-size sections some psABIs may require
Related show

Commit Message

Maciej W. Rozycki Jan. 31, 2018, 10:58 p.m.
Use the SEC_FIXED_SIZE flag to actually fix the size of `.reginfo' and 
`.MIPS.abiflags' sections in `_bfd_mips_elf_always_size_sections', as 
originally intended, removing link failures such as:

ld: final link failed: Section has no contents

or:

ld: final link failed: Bad value

or:

ld: foo: .reginfo section size should be 24 bytes, actual size is 32

and assertion failures like:

ld: BFD (GNU Binutils) 2.30.51.20180131 assertion fail .../bfd/elfxx-mips.c:14322

in link scenarios involving a linker script that either creates an 
output `.reginfo' or `.MIPS.abiflags' section from scratch or produces 
either section from different sections.  If such an output section's 
size turns out to be incorrect according to the psABI, then the section 
is either truncated or padded out to the correct size, as relevant.

This allows people to handle these sections in a link in an unusual way, 
while still addressing the issue covered by commit 58807c48a5a3 
("_bfd_mips_elf_final_link: Notify user about wrong .reginfo size").

The original arrangement, coming from an unindentified change made to 
what was called `mips_elf_always_size_sections' back then, between 
commit 02650bd0a97e ("This adds ABI flags to MIPS/ELF object files.") 
and commit 252b5132c753 ("19990502 sourceware import"), also missing 
from BFD ChangeLog files, assumed that the output section size is not 
going to change after return from `bfd_elf_size_dynamic_sections', the 
caller of that function, called in turn from `ldemul_before_allocation' 
via `gld${EMULATION_NAME}_before_allocation' in ld/emultempl/elf32.em, 
and ultimately from `lang_process'.  This is because later on in 
`lang_process' processing `lang_size_sections' is called , happily 
recalculating the section size, and it has actually already been the 
case at the time of commit 252b5132c753 ("19990502 sourceware import"), 
so the assumption was clearly incorrect right from the beginning.

	bfd/
	* elfxx-mips.c (_bfd_mips_elf_always_size_sections): Set 
	SEC_FIXED_SIZE and SEC_HAS_CONTENTS flags for `.reginfo' and 
	`.MIPS.abiflags' sections.
	(_bfd_mips_elf_final_link): Avoid reading beyond `.reginfo' 
	section's end.

	ld/
	* ldlang.c ():
	* testsuite/ld-mips-elf/reginfo-0.d: New test.
	* testsuite/ld-mips-elf/reginfo-0r.d: New test.
	* testsuite/ld-mips-elf/reginfo-1.d: New test.
	* testsuite/ld-mips-elf/reginfo-1r.d: New test.
	* testsuite/ld-mips-elf/reginfo-2.d: New test.
	* testsuite/ld-mips-elf/reginfo-2r.d: New test.
	* testsuite/ld-mips-elf/mips-abiflags-0.d: New test.
	* testsuite/ld-mips-elf/mips-abiflags-0r.d: New test.
	* testsuite/ld-mips-elf/mips-abiflags-1.d: New test.
	* testsuite/ld-mips-elf/mips-abiflags-1r.d: New test.
	* testsuite/ld-mips-elf/mips-abiflags-2.d: New test.
	* testsuite/ld-mips-elf/mips-abiflags-2r.d: New test.
	* testsuite/ld-mips-elf/reginfo-0.ld: New test linker script.
	* testsuite/ld-mips-elf/reginfo-1.ld: New test linker script.
	* testsuite/ld-mips-elf/mips-abiflags-0.ld: New test linker
	script.
	* testsuite/ld-mips-elf/mips-abiflags-1.ld: New test linker
	script.
	* testsuite/ld-mips-elf/reginfo-1.s: New test source.
	* testsuite/ld-mips-elf/reginfo-2.s: New test source.
	* testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
---
Hi,

 I will commit this change once 1/4 and 2/4 have been approved.

  Maciej
---
 bfd/elfxx-mips.c                            |   17 ++++++++++++++---
 ld/testsuite/ld-mips-elf/mips-abiflags-0.d  |    9 +++++++++
 ld/testsuite/ld-mips-elf/mips-abiflags-0.ld |    5 +++++
 ld/testsuite/ld-mips-elf/mips-abiflags-0r.d |    6 ++++++
 ld/testsuite/ld-mips-elf/mips-abiflags-1.d  |    6 ++++++
 ld/testsuite/ld-mips-elf/mips-abiflags-1.ld |    5 +++++
 ld/testsuite/ld-mips-elf/mips-abiflags-1r.d |    6 ++++++
 ld/testsuite/ld-mips-elf/mips-abiflags-2.d  |    6 ++++++
 ld/testsuite/ld-mips-elf/mips-abiflags-2r.d |    6 ++++++
 ld/testsuite/ld-mips-elf/mips-elf.exp       |   17 +++++++++++++++++
 ld/testsuite/ld-mips-elf/reginfo-0.d        |    9 +++++++++
 ld/testsuite/ld-mips-elf/reginfo-0.ld       |    5 +++++
 ld/testsuite/ld-mips-elf/reginfo-0r.d       |    9 +++++++++
 ld/testsuite/ld-mips-elf/reginfo-1.d        |    9 +++++++++
 ld/testsuite/ld-mips-elf/reginfo-1.ld       |    5 +++++
 ld/testsuite/ld-mips-elf/reginfo-1.s        |   10 ++++++++++
 ld/testsuite/ld-mips-elf/reginfo-1r.d       |    9 +++++++++
 ld/testsuite/ld-mips-elf/reginfo-2.d        |    9 +++++++++
 ld/testsuite/ld-mips-elf/reginfo-2.s        |   10 ++++++++++
 ld/testsuite/ld-mips-elf/reginfo-2r.d       |    9 +++++++++
 20 files changed, 164 insertions(+), 3 deletions(-)

binutils-mips-section-fixed-size.diff

Patch

Index: binutils/bfd/elfxx-mips.c
===================================================================
--- binutils.orig/bfd/elfxx-mips.c	2018-01-31 20:39:18.347471249 +0000
+++ binutils/bfd/elfxx-mips.c	2018-01-31 20:39:36.453010820 +0000
@@ -9284,12 +9284,19 @@  _bfd_mips_elf_always_size_sections (bfd 
   /* The .reginfo section has a fixed size.  */
   sect = bfd_get_section_by_name (output_bfd, ".reginfo");
   if (sect != NULL)
-    bfd_set_section_size (output_bfd, sect, sizeof (Elf32_External_RegInfo));
+    {
+      bfd_set_section_size (output_bfd, sect, sizeof (Elf32_External_RegInfo));
+      sect->flags |= SEC_FIXED_SIZE | SEC_HAS_CONTENTS;
+    }
 
   /* The .MIPS.abiflags section has a fixed size.  */
   sect = bfd_get_section_by_name (output_bfd, ".MIPS.abiflags");
   if (sect != NULL)
-    bfd_set_section_size (output_bfd, sect, sizeof (Elf_External_ABIFlags_v0));
+    {
+      bfd_set_section_size (output_bfd, sect,
+			    sizeof (Elf_External_ABIFlags_v0));
+      sect->flags |= SEC_FIXED_SIZE | SEC_HAS_CONTENTS;
+    }
 
   hti.info = info;
   hti.output_bfd = output_bfd;
@@ -14341,6 +14348,7 @@  _bfd_mips_elf_final_link (bfd *abfd, str
 	      bfd *input_bfd;
 	      Elf32_External_RegInfo ext;
 	      Elf32_RegInfo sub;
+	      bfd_size_type sz;
 
 	      if (p->type != bfd_indirect_link_order)
 		{
@@ -14352,8 +14360,11 @@  _bfd_mips_elf_final_link (bfd *abfd, str
 	      input_section = p->u.indirect.section;
 	      input_bfd = input_section->owner;
 
+	      sz = (input_section->size < sizeof (ext)
+		    ? input_section->size : sizeof (ext));
+	      memset (&ext, 0, sizeof (ext));
 	      if (! bfd_get_section_contents (input_bfd, input_section,
-					      &ext, 0, sizeof ext))
+					      &ext, 0, sz))
 		return FALSE;
 
 	      bfd_mips_elf32_swap_reginfo_in (input_bfd, &ext, &sub);
Index: binutils/ld/testsuite/ld-mips-elf/mips-abiflags-0.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/mips-abiflags-0.d	2018-01-31 20:39:50.014216809 +0000
@@ -0,0 +1,9 @@ 
+#readelf: -x .MIPS.abiflags
+#name: MIPS .MIPS.abiflags section size 0
+#source: empty.s RUN_OBJCOPY
+#objcopy_objects: -R .MIPS.abiflags
+#ld: -T mips-abiflags-0.ld
+
+Hex dump of section '\.MIPS\.abiflags':
+  0x00000000 ........ ........ ........ ........ .*
+  0x00000010 ........ ........                   .*
Index: binutils/ld/testsuite/ld-mips-elf/mips-abiflags-0.ld
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/mips-abiflags-0.ld	2018-01-31 20:39:50.038804641 +0000
@@ -0,0 +1,5 @@ 
+SECTIONS
+{
+  .MIPS.abiflags : { foo = .; }
+  /DISCARD/ : { *(*) }
+}
Index: binutils/ld/testsuite/ld-mips-elf/mips-abiflags-0r.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/mips-abiflags-0r.d	2018-01-31 20:39:50.063419800 +0000
@@ -0,0 +1,6 @@ 
+#readelf: -x .MIPS.abiflags
+#name: MIPS .MIPS.abiflags section size 0 (relocatable)
+#source: empty.s RUN_OBJCOPY
+#objcopy_objects: -R .MIPS.abiflags
+#ld: -r -T mips-abiflags-0.ld
+#dump: mips-abiflags-0.d
Index: binutils/ld/testsuite/ld-mips-elf/mips-abiflags-1.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/mips-abiflags-1.d	2018-01-31 20:39:50.079950763 +0000
@@ -0,0 +1,6 @@ 
+#readelf: -x .MIPS.abiflags
+#name: MIPS .MIPS.abiflags section size 1
+#source: reginfo-1.s RUN_OBJCOPY
+#objcopy_objects: -R .MIPS.abiflags
+#ld: -T mips-abiflags-1.ld
+#dump: mips-abiflags-0.d
Index: binutils/ld/testsuite/ld-mips-elf/mips-abiflags-1.ld
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/mips-abiflags-1.ld	2018-01-31 20:39:50.093283056 +0000
@@ -0,0 +1,5 @@ 
+SECTIONS
+{
+  .MIPS.abiflags : { *(.foo) }
+  /DISCARD/ : { *(*) }
+}
Index: binutils/ld/testsuite/ld-mips-elf/mips-abiflags-1r.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/mips-abiflags-1r.d	2018-01-31 20:39:50.107557304 +0000
@@ -0,0 +1,6 @@ 
+#readelf: -x .MIPS.abiflags
+#name: MIPS .MIPS.abiflags section size 1 (relocatable)
+#source: reginfo-1.s RUN_OBJCOPY
+#objcopy_objects: -R .MIPS.abiflags
+#ld: -r -T mips-abiflags-1.ld
+#dump: mips-abiflags-0.d
Index: binutils/ld/testsuite/ld-mips-elf/mips-abiflags-2.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/mips-abiflags-2.d	2018-01-31 20:39:50.154683870 +0000
@@ -0,0 +1,6 @@ 
+#readelf: -x .MIPS.abiflags
+#name: MIPS .MIPS.abiflags section size 2
+#source: reginfo-2.s RUN_OBJCOPY
+#objcopy_objects: -R .MIPS.abiflags
+#ld: -T mips-abiflags-1.ld
+#dump: mips-abiflags-0.d
Index: binutils/ld/testsuite/ld-mips-elf/mips-abiflags-2r.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/mips-abiflags-2r.d	2018-01-31 20:39:50.185666564 +0000
@@ -0,0 +1,6 @@ 
+#readelf: -x .MIPS.abiflags
+#name: MIPS .MIPS.abiflags section size 2 (relocatable)
+#source: reginfo-2.s RUN_OBJCOPY
+#objcopy_objects: -R .MIPS.abiflags
+#ld: -r -T mips-abiflags-1.ld
+#dump: mips-abiflags-0.d
Index: binutils/ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
--- binutils.orig/ld/testsuite/ld-mips-elf/mips-elf.exp	2018-01-31 20:39:18.466421960 +0000
+++ binutils/ld/testsuite/ld-mips-elf/mips-elf.exp	2018-01-31 20:39:50.204273465 +0000
@@ -57,6 +57,7 @@  set has_newabi [expr [istarget *-*-irix6
 		     || [istarget mips*-sde-elf*] \
 		     || [istarget mips*-mti-elf*] \
 		     || [istarget mips*-img-elf*]]
+set has_elf32 [expr ![istarget *-*-openbsd*]]
 set linux_gnu [expr [istarget mips*-*-linux*]]
 set embedded_elf [expr [istarget mips*-*-elf]]
 
@@ -1237,3 +1238,19 @@  rename mips_old_prune_warnings prune_war
 
 # Verify that we can link ELF input into the `binary' output format.
 run_dump_test "binary"
+
+# Verify special section processing.
+if $has_elf32 {
+    run_dump_test "reginfo-0"
+    run_dump_test "reginfo-0r"
+    run_dump_test "reginfo-1"
+    run_dump_test "reginfo-1r"
+    run_dump_test "reginfo-2"
+    run_dump_test "reginfo-2r"
+}
+run_dump_test "mips-abiflags-0"
+run_dump_test "mips-abiflags-0r"
+run_dump_test "mips-abiflags-1"
+run_dump_test "mips-abiflags-1r"
+run_dump_test "mips-abiflags-2"
+run_dump_test "mips-abiflags-2r"
Index: binutils/ld/testsuite/ld-mips-elf/reginfo-0.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/reginfo-0.d	2018-01-31 20:39:50.225553681 +0000
@@ -0,0 +1,9 @@ 
+#readelf: -x .reginfo
+#name: MIPS .reginfo section size 0
+#source: empty.s RUN_OBJCOPY
+#objcopy_objects: -R .reginfo
+#ld: -T reginfo-0.ld
+
+Hex dump of section '\.reginfo':
+  0x00000000 00000000 00000000 00000000 00000000 .*
+  0x00000010 00000000 00000000                   .*
Index: binutils/ld/testsuite/ld-mips-elf/reginfo-0.ld
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/reginfo-0.ld	2018-01-31 20:39:50.249346367 +0000
@@ -0,0 +1,5 @@ 
+SECTIONS
+{
+  .reginfo : { foo = .; }
+  /DISCARD/ : { *(*) }
+}
Index: binutils/ld/testsuite/ld-mips-elf/reginfo-0r.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/reginfo-0r.d	2018-01-31 20:39:50.263453533 +0000
@@ -0,0 +1,9 @@ 
+#readelf: -x .reginfo
+#name: MIPS .reginfo section size 0 (relocatable)
+#source: empty.s RUN_OBJCOPY
+#objcopy_objects: -R .reginfo
+#ld: -r -T reginfo-0.ld
+
+Hex dump of section '\.reginfo':
+  0x00000000 00000000 00000000 00000000 00000000 .*
+  0x00000010 00000000 ........                   .*
Index: binutils/ld/testsuite/ld-mips-elf/reginfo-1.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/reginfo-1.d	2018-01-31 20:39:50.281883423 +0000
@@ -0,0 +1,9 @@ 
+#readelf: -x .reginfo
+#name: MIPS .reginfo section size 1
+#source: reginfo-1.s RUN_OBJCOPY
+#objcopy_objects: -R .reginfo
+#ld: -T reginfo-1.ld
+
+Hex dump of section '\.reginfo':
+  0x00000000 01020304 05060708 090a0b0c 0d0e0f10 .*
+  0x00000010 00000000 00000000                   .*
Index: binutils/ld/testsuite/ld-mips-elf/reginfo-1.ld
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/reginfo-1.ld	2018-01-31 20:39:50.290060371 +0000
@@ -0,0 +1,5 @@ 
+SECTIONS
+{
+  .reginfo : { *(.foo) }
+  /DISCARD/ : { *(*) }
+}
Index: binutils/ld/testsuite/ld-mips-elf/reginfo-1.s
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/reginfo-1.s	2018-01-31 20:39:50.330495816 +0000
@@ -0,0 +1,10 @@ 
+	.section .foo, "aw", @progbits
+	.globl	foo
+	.type	foo, @object
+foo:
+	.set	.Li, 0
+	.rept	16
+	.set	.Li, .Li + 1
+	.byte	.Li
+	.endr
+	.size	foo, . - foo
Index: binutils/ld/testsuite/ld-mips-elf/reginfo-1r.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/reginfo-1r.d	2018-01-31 20:39:50.343675523 +0000
@@ -0,0 +1,9 @@ 
+#readelf: -x .reginfo
+#name: MIPS .reginfo section size 1 (relocatable)
+#source: reginfo-1.s RUN_OBJCOPY
+#objcopy_objects: -R .reginfo
+#ld: -r -T reginfo-1.ld
+
+Hex dump of section '\.reginfo':
+  0x00000000 01020304 05060708 090a0b0c 0d0e0f10 .*
+  0x00000010 00000000 ........                   .*
Index: binutils/ld/testsuite/ld-mips-elf/reginfo-2.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/reginfo-2.d	2018-01-31 20:39:50.355018478 +0000
@@ -0,0 +1,9 @@ 
+#readelf: -x .reginfo
+#name: MIPS .reginfo section size 2
+#source: reginfo-2.s RUN_OBJCOPY
+#objcopy_objects: -R .reginfo
+#ld: -T reginfo-1.ld
+
+Hex dump of section '\.reginfo':
+  0x00000000 01020304 05060708 090a0b0c 0d0e0f10 .*
+  0x00000010 11121314 00000000                   .*
Index: binutils/ld/testsuite/ld-mips-elf/reginfo-2.s
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/reginfo-2.s	2018-01-31 20:39:50.369233613 +0000
@@ -0,0 +1,10 @@ 
+	.section .foo, "aw", @progbits
+	.globl	foo
+	.type	foo, @object
+foo:
+	.set	.Li, 0
+	.rept	32
+	.set	.Li, .Li + 1
+	.byte	.Li
+	.endr
+	.size	foo, . - foo
Index: binutils/ld/testsuite/ld-mips-elf/reginfo-2r.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/reginfo-2r.d	2018-01-31 20:39:50.386346255 +0000
@@ -0,0 +1,9 @@ 
+#readelf: -x .reginfo
+#name: MIPS .reginfo section size 2 (relocatable)
+#source: reginfo-2.s RUN_OBJCOPY
+#objcopy_objects: -R .reginfo
+#ld: -r -T reginfo-1.ld
+
+Hex dump of section '\.reginfo':
+  0x00000000 01020304 05060708 090a0b0c 0d0e0f10 .*
+  0x00000010 11121314 ........                   .*