904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. From 7fc39194f8fb48914c995f8ec3826d50086f1ec0 Mon Sep 17 00:00:00 2001
  2. From: Sterling Augustine <augustine.sterling@gmail.com>
  3. Date: Tue, 25 Jan 2011 13:59:13 -0800
  4. Subject: [PATCH] Fix 'call8: call target out of range' xtensa ld relaxation
  5. bug
  6. During link-time relaxation distance between cross-section call site and
  7. its target may grow, producing 'call target out of range' error for
  8. relaxed calls. Be more conservative when calculating whether or not a
  9. callx can be converted to a straight call.
  10. 2014-09-23 Sterling Augustine <augustine.sterling@gmail.com>
  11. bfd/
  12. * elf32-xtensa.c (is_resolvable_asm_expansion): for cross-section
  13. call relaxation use furthermost addresses where call source and
  14. destination can be to check whether it's in the range of a direct
  15. call.
  16. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
  17. ---
  18. bfd/elf32-xtensa.c | 41 +++++++++++++++++++++++++++++++++++++----
  19. 1 file changed, 37 insertions(+), 4 deletions(-)
  20. diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
  21. index 09862e3..e32496a 100644
  22. --- a/bfd/elf32-xtensa.c
  23. +++ b/bfd/elf32-xtensa.c
  24. @@ -7124,10 +7124,43 @@ is_resolvable_asm_expansion (bfd *abfd,
  25. || is_reloc_sym_weak (abfd, irel)))
  26. return FALSE;
  27. - self_address = (sec->output_section->vma
  28. - + sec->output_offset + irel->r_offset + 3);
  29. - dest_address = (target_sec->output_section->vma
  30. - + target_sec->output_offset + target_offset);
  31. + if (target_sec->output_section != sec->output_section)
  32. + {
  33. + /* If the two sections are sufficiently far away that relaxation
  34. + might take the call out of range, we can't simplify. For
  35. + example, a positive displacement call into another memory
  36. + could get moved to a lower address due to literal removal,
  37. + but the destination won't move, and so the displacment might
  38. + get larger.
  39. +
  40. + If the displacement is negative, assume the destination could
  41. + move as far back as the start of the output section. The
  42. + self_address will be at least as far into the output section
  43. + as it is prior to relaxation.
  44. +
  45. + If the displacement is postive, assume the destination will be in
  46. + it's pre-relaxed location (because relaxation only makes sections
  47. + smaller). The self_address could go all the way to the beginning
  48. + of the output section. */
  49. +
  50. + dest_address = target_sec->output_section->vma;
  51. + self_address = sec->output_section->vma;
  52. +
  53. + if (sec->output_section->vma > target_sec->output_section->vma)
  54. + self_address += sec->output_offset + irel->r_offset + 3;
  55. + else
  56. + dest_address += bfd_get_section_limit (abfd, target_sec->output_section);
  57. + /* Call targets should be four-byte aligned. */
  58. + dest_address = (dest_address + 3) & ~3;
  59. + }
  60. + else
  61. + {
  62. +
  63. + self_address = (sec->output_section->vma
  64. + + sec->output_offset + irel->r_offset + 3);
  65. + dest_address = (target_sec->output_section->vma
  66. + + target_sec->output_offset + target_offset);
  67. + }
  68. *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0,
  69. self_address, dest_address);
  70. --
  71. 1.8.1.4