Objcopy interleave fails if section address not multiple of interleave.
authorJim Wilson <jimw@sifive.com>
Wed, 6 Dec 2017 18:34:36 +0000 (10:34 -0800)
committerJim Wilson <jimw@sifive.com>
Wed, 6 Dec 2017 18:34:36 +0000 (10:34 -0800)
PR 22465
binutils/
* objcopy.c (copy_section): New local extra.  If isection->lma not
exactly divisible by interleave, then bias from.  Also adjust
osection->lma if necessary.

ld/
* testsuite/ld-elf/interleave-0.d, testsuite/ld-elf/interleave-4.d,
* testsuite/ld-elf/interleave.ld, testsuite/ld-elf/interleave.s: New.

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

index cf0df39..058ebf3 100644 (file)
@@ -1,3 +1,10 @@
+2017-12-06  Jim Wilson  <jimw@sifive.com>
+
+       PR 22465
+       * objcopy.c (copy_section): New local extra.  If isection->lma not
+       exactly divisible by interleave, then bias from.  Also adjust
+       osection->lma if necessary.
+
 2017-12-06  Alan Modra  <amodra@gmail.com>
 
        PR 22552
index c45133b..f40b355 100644 (file)
@@ -3898,6 +3898,15 @@ copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
          char *end = (char *) memhunk + size;
          int i;
 
+         /* If the section address is not exactly divisible by the interleave,
+            then we must bias the from address.  If the copy_byte is less than
+            the bias, then we must skip forward one interleave, and increment
+            the final lma.  */
+         int extra = isection->lma % interleave;
+         from -= extra;
+         if (copy_byte < extra)
+           from += interleave;
+
          for (; from < end; from += interleave)
            for (i = 0; i < copy_width; i++)
              {
@@ -3908,6 +3917,8 @@ copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
 
          size = (size + interleave - 1 - copy_byte) / interleave * copy_width;
          osection->lma /= interleave;
+         if (copy_byte < extra)
+           osection->lma++;
        }
 
       if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
index 9713d96..d4758d4 100644 (file)
@@ -1,3 +1,8 @@
+2017-12-06  Jim Wilson  <jimw@sifive.com>
+
+       * testsuite/ld-elf/interleave-0.d, testsuite/ld-elf/interleave-4.d,
+       * testsuite/ld-elf/interleave.ld, testsuite/ld-elf/interleave.s: New.
+
 2017-12-06  Nick Clifton  <nickc@redhat.com>
 
        * testsuite/lib/ld-lib.exp (check_shared_lib_support): Return
diff --git a/ld/testsuite/ld-elf/interleave-0.d b/ld/testsuite/ld-elf/interleave-0.d
new file mode 100644 (file)
index 0000000..837223c
--- /dev/null
@@ -0,0 +1,9 @@
+#name: --interleave test byte 0
+#source: interleave.s
+#ld: -Tinterleave.ld
+#objcopy: --interleave=8 --interleave-width=1 --byte=0 -O verilog
+
+@0+0
+00 
+@0+2
+14 
diff --git a/ld/testsuite/ld-elf/interleave-4.d b/ld/testsuite/ld-elf/interleave-4.d
new file mode 100644 (file)
index 0000000..a4bb808
--- /dev/null
@@ -0,0 +1,9 @@
+#name: --interleave test byte 4
+#source: interleave.s
+#ld: -Tinterleave.ld
+#objcopy: --interleave=8 --interleave-width=1 --byte=4 -O verilog
+
+@0+0
+04 
+@0+1
+10 
diff --git a/ld/testsuite/ld-elf/interleave.ld b/ld/testsuite/ld-elf/interleave.ld
new file mode 100644 (file)
index 0000000..6406166
--- /dev/null
@@ -0,0 +1,10 @@
+MEMORY
+{
+  x0(xrw): ORIGIN = 0x0, LENGTH = 8
+  x1(xrw): ORIGIN = 0xC, LENGTH = 8
+}
+SECTIONS
+{
+  .a0 : { *(.text.a0) } > x0
+  .a1 : { *(.text.a1) } > x1
+}
diff --git a/ld/testsuite/ld-elf/interleave.s b/ld/testsuite/ld-elf/interleave.s
new file mode 100644 (file)
index 0000000..490aa59
--- /dev/null
@@ -0,0 +1,18 @@
+       .section ".text.a0"
+       .byte 0x00
+       .byte 0x01
+       .byte 0x02
+       .byte 0x03
+       .byte 0x04
+       .byte 0x05
+       .byte 0x06
+       .byte 0x07
+       .section ".text.a1"
+       .byte 0x10
+       .byte 0x11
+       .byte 0x12
+       .byte 0x13
+       .byte 0x14
+       .byte 0x15
+       .byte 0x16
+       .byte 0x17