Adjust the output section size to skip gap fills
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 29 Sep 2015 13:33:03 +0000 (06:33 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 29 Sep 2015 13:33:24 +0000 (06:33 -0700)
In objcopy, copy_object calls copy_section to copy contents of input
section to output section.  When --gap-fill= is used, objcopy extends
the size of output sectios to fill gaps between output sections with
gap fills.  In this case, we adjust the output section size to skip
gap files to avoid reading beypond the input section buffer before
calling copy_section and restore the output section size after input
sections have been copied.

binutils/

PR binutils/19005
* objcopy.c (copy_object): Adjust the output section size to
skip gap fills between sections when copying from input sections
to output sections.

ld/testsuite/

PR binutils/19005
* ld-elf/pr19005.d: New file.
* ld-elf/pr19005.s: Likewise.
* ld-elf/pr19005.t: Likewise.

binutils/ChangeLog
binutils/objcopy.c
ld/testsuite/ChangeLog
ld/testsuite/ld-elf/pr19005.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr19005.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr19005.t [new file with mode: 0644]

index 128cce5637e1ff8005c18924c85080ab001d1ca4..8d2f984868e143ed71eea69834b4f91ee5dafce6 100644 (file)
@@ -1,3 +1,10 @@
+2015-09-29  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR binutils/19005
+       * objcopy.c (copy_object): Adjust the output section size to
+       skip gap fills between sections when copying from input sections
+       to output sections.
+
 2015-09-28  Nick Clifton  <nickc@redhat.com>
 
        * po/fr.po: Updated French translation.
index e4cb3e2d3fb6db4d3ef747fc3b4a89d0e92dca6e..c94d515a389c1975e8946859acf1811814be4597 100644 (file)
@@ -1640,6 +1640,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
   void *dhandle;
   enum bfd_architecture iarch;
   unsigned int imach;
+  unsigned int c, i;
 
   if (ibfd->xvec->byteorder != obfd->xvec->byteorder
       && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
@@ -2071,11 +2072,11 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
        }
     }
 
-  if (bfd_count_sections (obfd) != 0
+  c = bfd_count_sections (obfd);
+  if (c != 0
       && (gap_fill_set || pad_to_set))
     {
       asection **set;
-      unsigned int c, i;
 
       /* We must fill in gaps between the sections and/or we must pad
         the last section to a specified address.  We do this by
@@ -2083,7 +2084,6 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
         increasing the section sizes as required to fill the gaps.
         We write out the gap contents below.  */
 
-      c = bfd_count_sections (obfd);
       osections = (asection **) xmalloc (c * sizeof (asection *));
       set = osections;
       bfd_map_over_sections (obfd, get_sections, &set);
@@ -2212,7 +2212,24 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
   bfd_map_over_sections (ibfd, copy_relocations_in_section, obfd);
 
   /* This has to happen after the symbol table has been set.  */
+  if (gap_fill_set)
+    {
+      /* Adjust the output section size to skip gap fills between
+        sections.  */
+      c = bfd_count_sections (obfd);
+      for (i = 0; i < c; i++)
+       if (gaps[i] != 0)
+         osections[i]->size -= gaps[i];
+    }
   bfd_map_over_sections (ibfd, copy_section, obfd);
+  if (gap_fill_set)
+    {
+      /* Restore the output section size for gap fills between
+        sections.  */
+      for (i = 0; i < c; i++)
+       if (gaps[i] != 0)
+         osections[i]->size += gaps[i];
+    }
 
   if (add_sections != NULL)
     {
@@ -2264,7 +2281,6 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
   if (gap_fill_set || pad_to_set)
     {
       bfd_byte *buf;
-      int c, i;
 
       /* Fill in the gaps.  */
       if (max_gap > 8192)
index 3a6a5094b85e3cb4db393a0c18d4801f079521f5..40eb3589c6f8cbee0bc942f5094568dc301b5bc6 100644 (file)
@@ -1,3 +1,10 @@
+2015-09-29  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR binutils/19005
+       * ld-elf/pr19005.d: New file.
+       * ld-elf/pr19005.s: Likewise.
+       * ld-elf/pr19005.t: Likewise.
+
 2015-08-11  Peter Zotov  <whitequark@whitequark.org>
 
        PR ld/18759
diff --git a/ld/testsuite/ld-elf/pr19005.d b/ld/testsuite/ld-elf/pr19005.d
new file mode 100644 (file)
index 0000000..a4df0d3
--- /dev/null
@@ -0,0 +1,10 @@
+#ld: -Tpr19005.t
+#objcopy_linked_file: -O binary -j .foo -j .bar --gap-fill=0xff
+#objdump: -b binary -s
+
+#...
+Contents of section .data:
+ 0000 10ffffff ffffffff ffffffff ffffffff  ................
+ 0010 ffffffff ffffffff ffffffff ffffffff  ................
+ 0020 20.*
+#pass
diff --git a/ld/testsuite/ld-elf/pr19005.s b/ld/testsuite/ld-elf/pr19005.s
new file mode 100644 (file)
index 0000000..8bd860f
--- /dev/null
@@ -0,0 +1,11 @@
+       .section .foo,"ax",%progbits
+       .globl  _start
+       .type   _start, %function
+_start:
+       .byte 0x10
+       .section .bar,"ax",%progbits
+       .globl  aligned
+       .type   aligned, %function
+       .p2align 5
+aligned:
+       .byte 0x20
diff --git a/ld/testsuite/ld-elf/pr19005.t b/ld/testsuite/ld-elf/pr19005.t
new file mode 100644 (file)
index 0000000..0e89e0b
--- /dev/null
@@ -0,0 +1,6 @@
+SECTIONS
+{
+  .foo : { *(.foo) }
+  .bar : { *(.bar) }
+  /DISCARD/ : { *(.*) }
+}