diff options
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf32-xtensa.c | 55 | ||||
-rw-r--r-- | ld/ChangeLog | 8 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/call_overflow.d | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/call_overflow1.s | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/call_overflow2.s | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/call_overflow3.s | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/xtensa.exp | 1 |
8 files changed, 105 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c10f1a4..ce088c9 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2019-02-20 Eric Tsai <erictsai@cadence.com> + + * elf32-xtensa.c (is_resolvable_asm_expansion): Scan output + sections between the call site and call destination and adjust + call distance by the largest alignment. + 2019-02-20 Alan Hayward <alan.hayward@arm.com> * elf-bfd.h (elfcore_write_aarch_pauth): Add declaration. diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index edd9a0d..c3df3d6 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -7195,6 +7195,11 @@ is_resolvable_asm_expansion (bfd *abfd, bfd_boolean *is_reachable_p) { asection *target_sec; + asection *s; + bfd_vma first_vma; + bfd_vma last_vma; + unsigned int first_align; + unsigned int adjust; bfd_vma target_offset; r_reloc r_rel; xtensa_opcode opcode, direct_call_opcode; @@ -7283,6 +7288,56 @@ is_resolvable_asm_expansion (bfd *abfd, + target_sec->output_offset + target_offset); } + /* Adjust addresses with alignments for the worst case to see if call insn + can fit. Don't relax l32r + callx to call if the target can be out of + range due to alignment. + Caller and target addresses are highest and lowest address. + Search all sections between caller and target, looking for max alignment. + The adjustment is max alignment bytes. If the alignment at the lowest + address is less than the adjustment, apply the adjustment to highest + address. */ + + /* Start from lowest address. + Lowest address aligmnet is from input section. + Initial alignment (adjust) is from input section. */ + if (dest_address > self_address) + { + s = sec->output_section; + last_vma = dest_address; + first_align = sec->alignment_power; + adjust = target_sec->alignment_power; + } + else + { + s = target_sec->output_section; + last_vma = self_address; + first_align = target_sec->alignment_power; + adjust = sec->alignment_power; + } + + first_vma = s->vma; + + /* Find the largest alignment in output section list. */ + for (; s && s->vma >= first_vma && s->vma <= last_vma ; s = s->next) + { + if (s->alignment_power > adjust) + adjust = s->alignment_power; + } + + if (adjust > first_align) + { + /* Alignment may enlarge the range, adjust highest address. */ + adjust = 1 << adjust; + if (dest_address > self_address) + { + dest_address += adjust; + } + else + { + self_address += adjust; + } + } + *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0, self_address, dest_address); diff --git a/ld/ChangeLog b/ld/ChangeLog index 508858f..0e00e41 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2019-02-20 Eric Tsai <erictsai@cadence.com> + + * testsuite/ld-xtensa/call_overflow.d: New test definition. + * testsuite/ld-xtensa/call_overflow1.s: New test source. + * testsuite/ld-xtensa/call_overflow2.s: New test source. + * testsuite/ld-xtensa/call_overflow3.s: New test source. + * testsuite/ld-xtensa/xtensa.exp: Add call_overflow test. + 2019-02-14 Thomas Schwinge <thomas@codesourcery.com> * testsuite/ld-elf/elf.exp: Remove Hurd XFAILs. diff --git a/ld/testsuite/ld-xtensa/call_overflow.d b/ld/testsuite/ld-xtensa/call_overflow.d new file mode 100644 index 0000000..9572848 --- /dev/null +++ b/ld/testsuite/ld-xtensa/call_overflow.d @@ -0,0 +1,7 @@ +#source: call_overflow1.s +#source: call_overflow2.s +#source: call_overflow3.s +#as: --longcalls +#ld: +#objdump: -d +#... diff --git a/ld/testsuite/ld-xtensa/call_overflow1.s b/ld/testsuite/ld-xtensa/call_overflow1.s new file mode 100644 index 0000000..8b03289 --- /dev/null +++ b/ld/testsuite/ld-xtensa/call_overflow1.s @@ -0,0 +1,9 @@ + .text + .global _start + .align 4 +_start: + call8 a + .rep 2051 + nop.n + nop.n + .endr diff --git a/ld/testsuite/ld-xtensa/call_overflow2.s b/ld/testsuite/ld-xtensa/call_overflow2.s new file mode 100644 index 0000000..c3f36fa --- /dev/null +++ b/ld/testsuite/ld-xtensa/call_overflow2.s @@ -0,0 +1,14 @@ + .text + .global a + .align 4 +a: + j a + + .align 4 +x: + call8 b +#29 + .rep 131070 + nop.n + nop.n + .endr diff --git a/ld/testsuite/ld-xtensa/call_overflow3.s b/ld/testsuite/ld-xtensa/call_overflow3.s new file mode 100644 index 0000000..33f59d8 --- /dev/null +++ b/ld/testsuite/ld-xtensa/call_overflow3.s @@ -0,0 +1,5 @@ + .text + .align 32 + .global b +b: + j b diff --git a/ld/testsuite/ld-xtensa/xtensa.exp b/ld/testsuite/ld-xtensa/xtensa.exp index e8befa9..91b2314 100644 --- a/ld/testsuite/ld-xtensa/xtensa.exp +++ b/ld/testsuite/ld-xtensa/xtensa.exp @@ -23,6 +23,7 @@ if { !([istarget "xtensa*-*-*"]) } { return } +run_dump_test "call_overflow" run_dump_test "coalesce" run_dump_test "diff_overflow" run_dump_test "lcall" |