gas-ld-diff.xtensa 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. From 6a17eba5358549d0d6d195bb22b34cdbc068def2 Mon Sep 17 00:00:00 2001
  2. From: Volodymyr Arbatov <arbatov@cadence.com>
  3. Date: Mon, 6 May 2013 09:43:21 -0800
  4. Subject: [PATCH] Use signed data type for R_XTENSA_DIFF* relocation offsets.
  5. R_XTENSA_DIFF relocation offsets are in fact signed. Treat them as such.
  6. Add testcase that examines ld behaviour on R_XTENSA_DIFF relocation
  7. changing sign during relaxation.
  8. 2014-05-02 Volodymyr Arbatov <arbatov@cadence.com>
  9. David Weatherford <weath@cadence.com>
  10. Max Filippov <jcmvbkbc@gmail.com>
  11. bfd/
  12. * elf32-xtensa.c (relax_section): treat R_XTENSA_DIFF* relocations as
  13. signed.
  14. gas/
  15. * config/tc-xtensa.c (md_apply_fix): mark BFD_RELOC_XTENSA_DIFF*
  16. fixups as signed.
  17. ---
  18. Backported from: 1058c7532d0b012ac329219264ddad59049fb6e6
  19. Changes to Changelog files and tests are dropped.
  20. bfd/elf32-xtensa.c | 32 ++++++++++++-----------
  21. gas/config/tc-xtensa.c | 3 +++
  22. 2 files changed, 20 insertions(+), 15 deletions(-)
  23. diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
  24. index edb04b4..8818d67 100644
  25. --- a/bfd/elf32-xtensa.c
  26. +++ b/bfd/elf32-xtensa.c
  27. @@ -222,11 +222,11 @@ static reloc_howto_type elf_howto_table[] =
  28. FALSE, 0, 0, FALSE),
  29. /* Relocations for supporting difference of symbols. */
  30. - HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
  31. + HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_signed,
  32. bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8", FALSE, 0, 0xff, FALSE),
  33. - HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
  34. + HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_signed,
  35. bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16", FALSE, 0, 0xffff, FALSE),
  36. - HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
  37. + HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
  38. bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32", FALSE, 0, 0xffffffff, FALSE),
  39. /* General immediate operand relocations. */
  40. @@ -9013,7 +9013,8 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
  41. || r_type == R_XTENSA_DIFF16
  42. || r_type == R_XTENSA_DIFF32)
  43. {
  44. - bfd_vma diff_value = 0, new_end_offset, diff_mask = 0;
  45. + bfd_signed_vma diff_value = 0;
  46. + bfd_vma new_end_offset, diff_mask = 0;
  47. if (bfd_get_section_limit (abfd, sec) < old_source_offset)
  48. {
  49. @@ -9027,15 +9028,15 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
  50. {
  51. case R_XTENSA_DIFF8:
  52. diff_value =
  53. - bfd_get_8 (abfd, &contents[old_source_offset]);
  54. + bfd_get_signed_8 (abfd, &contents[old_source_offset]);
  55. break;
  56. case R_XTENSA_DIFF16:
  57. diff_value =
  58. - bfd_get_16 (abfd, &contents[old_source_offset]);
  59. + bfd_get_signed_16 (abfd, &contents[old_source_offset]);
  60. break;
  61. case R_XTENSA_DIFF32:
  62. diff_value =
  63. - bfd_get_32 (abfd, &contents[old_source_offset]);
  64. + bfd_get_signed_32 (abfd, &contents[old_source_offset]);
  65. break;
  66. }
  67. @@ -9047,24 +9048,25 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
  68. switch (r_type)
  69. {
  70. case R_XTENSA_DIFF8:
  71. - diff_mask = 0xff;
  72. - bfd_put_8 (abfd, diff_value,
  73. + diff_mask = 0x7f;
  74. + bfd_put_signed_8 (abfd, diff_value,
  75. &contents[old_source_offset]);
  76. break;
  77. case R_XTENSA_DIFF16:
  78. - diff_mask = 0xffff;
  79. - bfd_put_16 (abfd, diff_value,
  80. + diff_mask = 0x7fff;
  81. + bfd_put_signed_16 (abfd, diff_value,
  82. &contents[old_source_offset]);
  83. break;
  84. case R_XTENSA_DIFF32:
  85. - diff_mask = 0xffffffff;
  86. - bfd_put_32 (abfd, diff_value,
  87. + diff_mask = 0x7fffffff;
  88. + bfd_put_signed_32 (abfd, diff_value,
  89. &contents[old_source_offset]);
  90. break;
  91. }
  92. - /* Check for overflow. */
  93. - if ((diff_value & ~diff_mask) != 0)
  94. + /* Check for overflow. Sign bits must be all zeroes or all ones */
  95. + if ((diff_value & ~diff_mask) != 0 &&
  96. + (diff_value & ~diff_mask) != (-1 & ~diff_mask))
  97. {
  98. (*link_info->callbacks->reloc_dangerous)
  99. (link_info, _("overflow after relaxation"),
  100. diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
  101. index 58ace38..7547c0a0 100644
  102. --- a/gas/config/tc-xtensa.c
  103. +++ b/gas/config/tc-xtensa.c
  104. @@ -5867,12 +5867,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
  105. {
  106. case BFD_RELOC_8:
  107. fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8;
  108. + fixP->fx_signed = 1;
  109. break;
  110. case BFD_RELOC_16:
  111. fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16;
  112. + fixP->fx_signed = 1;
  113. break;
  114. case BFD_RELOC_32:
  115. fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32;
  116. + fixP->fx_signed = 1;
  117. break;
  118. default:
  119. break;
  120. --
  121. 1.8.1.4