diff options
author | Alan Modra <amodra@gmail.com> | 2022-01-28 09:46:13 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2022-02-05 17:41:08 +1030 |
commit | d3ec1c514429b8c695974e785e47af8f71c388a2 (patch) | |
tree | 1f0626931250f5666d7971a07130122a0cf2f8fc /ld | |
parent | 9097ec6cc41330b510cf1fdbafad19c4a21a914c (diff) |
PR28827, assertion building LLVM 9 on powerpc64le-linux-gnu
The assertion is this one in ppc_build_one_stub
BFD_ASSERT (stub_entry->stub_offset >= stub_entry->group->stub_sec->size);
It is checking that a stub doesn't overwrite the tail of a previous
stub, so not something trivial.
Normally, stub sizing iterates until no stubs are added, detected by
no change in stub section size. Iteration also continues if no stubs
are added but one or more stubs increases in size, which also can be
detected by a change in stub section size. But there is a
pathological case where stub section sizing decreases one iteration
then increases the next. To handle that situation, stub sizing also
stops at more than STUB_SHRINK_ITER (20) iterations when calculated
stub section size is smaller. The previous larger size is kept for
the actual layout (so that building the stubs, which behaves like
another iteration of stub sizing, will see the stub section sizes
shrink). The problem with that stopping condition is that it assumes
that stub sizing is only affected by addresses external to the stub
sections, which isn't always true.
This patch fixes that by also keeping larger individual stub_offset
addresses past STUB_SHRINK_ITER. It also catches a further
pathological case where one stub shrinks and another expands in such a
way that no stub section size change is seen.
PR 28827
* elf64-ppc.c (struct ppc_link_hash_table): Add stub_changed.
(STUB_SHRINK_ITER): Move earlier in file.
(ppc_size_one_stub): Detect any change in stub_offset. Keep
larger one if past STUB_SHRINK_ITER.
(ppc64_elf_size_stubs): Iterate on stub_changed too.
(cherry picked from commit 0441f94fba61998b4bd18487aacf70a672df099c)
Re: PR28827, assertion building LLVM 9 on powerpc64le-linux-gnu
The previous patch wasn't quite correct. The size and padding depends
on offset used in the current iteration, and if we're fudging the
offset past STUB_SHRINK_ITER then we'd better use that offset. We
can't have plt_stub_pad using stub_sec->size as the offset.
PR 28827
* elf64-ppc.c (plt_stub_pad): Add stub_off param.
(ppc_size_one_stub): Set up stub_offset to value used in this
iteration before sizing the stub. Adjust plt_stub_pad calls.
(cherry picked from commit 2405fc4016feadea33cb747d5654514f62b74ff4)
Re: PR28827, assertion building LLVM 9 on powerpc64le-linux-gnu
In trying to find a testcase for PR28827, I managed to hit a linker
error in bfd_set_section_contents with a .branch_lt input section
being too large for the output .branch_lt.
bfd/
PR 28827
* elf64-ppc.c (ppc64_elf_size_stubs): Set section size to
maxsize past STUB_SHRINK_ITER before laying out. Remove now
unnecessary conditional setting of maxsize at start of loop.
ld/
* testsuite/ld-powerpc/pr28827-2.d,
* testsuite/ld-powerpc/pr28827-2.lnk,
* testsuite/ld-powerpc/pr28827-2.s: New test.
* testsuite/ld-powerpc/powerpc.exp: Run it.
(cherry picked from commit 9ff8aa7d418bc508dbd429576b93e30ed9dc5891)
Diffstat (limited to 'ld')
-rw-r--r-- | ld/testsuite/ld-powerpc/powerpc.exp | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/pr28827-2.d | 48 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/pr28827-2.lnk | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/pr28827-2.s | 15 |
4 files changed, 73 insertions, 0 deletions
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp index 3eb707f42e..3d738f5f93 100644 --- a/ld/testsuite/ld-powerpc/powerpc.exp +++ b/ld/testsuite/ld-powerpc/powerpc.exp @@ -445,6 +445,7 @@ if [ supports_ppc64 ] then { run_dump_test "tlsie" run_dump_test "non-contiguous-powerpc64" run_dump_test "tprel" + run_dump_test "pr28827-2" } run_dump_test "localgot" diff --git a/ld/testsuite/ld-powerpc/pr28827-2.d b/ld/testsuite/ld-powerpc/pr28827-2.d new file mode 100644 index 0000000000..8da819d822 --- /dev/null +++ b/ld/testsuite/ld-powerpc/pr28827-2.d @@ -0,0 +1,48 @@ +#as: -a64 +#ld: -melf64ppc --plt-align=0 -T pr28827-2.lnk +#objdump: -dr + +.*: file format .* + +Disassembly of section \.text: + +.*: +.*: (49 ff ff f0|f0 ff ff 49) b .* <far1> + \.\.\. + +.* <.*\.plt_branch\..*>: +.*: (e9 82 80 28|28 80 82 e9) ld r12,-32728\(r2\) +.*: (7d 89 03 a6|a6 03 89 7d) mtctr r12 +.*: (4e 80 04 20|20 04 80 4e) bctr + +.* <_start>: +.*: (49 ff ff d8|d8 ff ff 49) b .* <far1> +.*: (4b ff ff f0|f0 ff ff 4b) b .* + +Disassembly of section \.far1: + +.*: +.*: (4a 00 00 38|38 00 00 4a) b .* <_start> + +.* <.*\.long_branch\..*>: +.*: (49 ff ff f4|f4 ff ff 49) b .* <far2> + \.\.\. + +.* <far1>: +.*: (41 82 ff f4|f4 ff 82 41) beq .* +.*: (4a 00 00 24|24 00 00 4a) b .* <_start> + +Disassembly of section \.far2: + +.*: +.*: (e9 82 80 20|20 80 82 e9) ld r12,-32736\(r2\) +.*: (7d 89 03 a6|a6 03 89 7d) mtctr r12 +.*: (4e 80 04 20|20 04 80 4e) bctr + +.*: +.*: (4a 00 00 24|24 00 00 4a) b .* <far1> + \.\.\. + +.* <far2>: +.*: (40 82 ff f4|f4 ff 82 40) bne .* +.*: (4b ff ff e4|e4 ff ff 4b) b .* diff --git a/ld/testsuite/ld-powerpc/pr28827-2.lnk b/ld/testsuite/ld-powerpc/pr28827-2.lnk new file mode 100644 index 0000000000..61a8ca269f --- /dev/null +++ b/ld/testsuite/ld-powerpc/pr28827-2.lnk @@ -0,0 +1,9 @@ +SECTIONS +{ + . = SIZEOF_HEADERS; + .text : { *(.text) } + . = . + 0x2000000 + 32 - 4 * SIZEOF (.text); + .far1 : { *(.far1) } + . = . + 0x2000000 + 32 - 4 * SIZEOF (.far1); + .far2 : { *(.far2) } +} diff --git a/ld/testsuite/ld-powerpc/pr28827-2.s b/ld/testsuite/ld-powerpc/pr28827-2.s new file mode 100644 index 0000000000..a628d6d09f --- /dev/null +++ b/ld/testsuite/ld-powerpc/pr28827-2.s @@ -0,0 +1,15 @@ + .globl _start + .text +_start: + b far1 + b far2 + + .section .far1,"ax",@progbits +far1: + beq far2 + b _start + + .section .far2,"ax",@progbits +far2: + bne far1 + b _start |