diff options
author | Jim Wilson <jimw@sifive.com> | 2017-12-06 10:34:36 -0800 |
---|---|---|
committer | Jim Wilson <jimw@sifive.com> | 2017-12-06 10:34:36 -0800 |
commit | 1c9c7ce078427891a94dc7604ce9e62175ebfda5 (patch) | |
tree | 43462daac8331919898ef39d5eba799b1f27217f /binutils | |
parent | 7cc244debb587d0f6179d80b5ca9b0ee86e9ab72 (diff) | |
download | gdb-1c9c7ce078427891a94dc7604ce9e62175ebfda5.zip gdb-1c9c7ce078427891a94dc7604ce9e62175ebfda5.tar.gz gdb-1c9c7ce078427891a94dc7604ce9e62175ebfda5.tar.bz2 |
Objcopy interleave fails if section address not multiple of interleave.
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.
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 7 | ||||
-rw-r--r-- | binutils/objcopy.c | 11 |
2 files changed, 18 insertions, 0 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index cf0df39..058ebf3 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -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 diff --git a/binutils/objcopy.c b/binutils/objcopy.c index c45133b..f40b355 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)) |