diff --git a/binutils/ChangeLog b/binutils/ChangeLog index cf0df39edf..058ebf38be 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,10 @@ +2017-12-06 Jim Wilson + + 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 PR 22552 diff --git a/binutils/objcopy.c b/binutils/objcopy.c index c45133b41b..f40b355c14 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -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)) diff --git a/ld/ChangeLog b/ld/ChangeLog index 9713d9696b..d4758d4eaf 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2017-12-06 Jim Wilson + + * 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 * 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 index 0000000000..837223c83a --- /dev/null +++ b/ld/testsuite/ld-elf/interleave-0.d @@ -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 index 0000000000..a4bb808ab6 --- /dev/null +++ b/ld/testsuite/ld-elf/interleave-4.d @@ -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 index 0000000000..6406166c88 --- /dev/null +++ b/ld/testsuite/ld-elf/interleave.ld @@ -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 index 0000000000..490aa59d5b --- /dev/null +++ b/ld/testsuite/ld-elf/interleave.s @@ -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