Fix PR 24564 - link fails for some rcalls/rjmps with wraparound
authorSenthil Kumar Selvaraj <senthilkumar.selvaraj@microchip.com>
Thu, 16 May 2019 11:46:36 +0000 (17:16 +0530)
committerSenthil Kumar Selvaraj <senthilkumar.selvaraj@microchip.com>
Tue, 21 May 2019 07:04:22 +0000 (12:34 +0530)
commit338ba75534fbfeb64d7009f29a89f25826a1f4d2
tree49680dd9ed1d62be18a568a14643e7fffeb4c204
parentda0523c66604dc11b8787d3e0123ea80a2503f14
Fix PR 24564 - link fails for some rcalls/rjmps with wraparound

The current code to compute relative distance in the wrap around case does not
handle the edge case of the target (after adjusting for implicit PC increment)
being exactly half of the wrap around distance. This patch fixes that and adds a
testcase.

The range for a forward relative jump call is 4096 bytes ((2 * 2047) + (2 bytes
for the implicit PC increment)). If the target of the jump is at a distance of
4098 bytes, it is out of range for a forward jump - however, a backward jump can
still reach that address if pmem-wrap-around is 8192.

Assume address 0 has rjmp to address 4098. With a wrap around of 8192 and
*without* adjusting for the implicit PC increment of 2 bytes, rjmp .-4096 will
jump to address 4096 (wrap around at 8192 and decreasing addresses from then
on). Adjusting 2 bytes for the implicit PC increment, the actual target is 4098.

avr_relative_distance_considering_wrap_around though, does the wrap around only
if the passed in distance is less than half of the wrap around distance. In this
case, it is exactly equal to half (original distance 4098, adjusted distance of
4096 and wraparound of 8192), and the bypassed wrap around causes the reloc
overflow error.

Fix by wrapping around even if adjusted distance is equal to half of wrap around
distance.
bfd/ChangeLog
bfd/elf32-avr.c
ld/ChangeLog
ld/testsuite/ld-avr/wraparound-range-boundary.d [new file with mode: 0644]
ld/testsuite/ld-avr/wraparound-range-boundary.s [new file with mode: 0644]