RISC-V: Fix symbol size bug when relaxation deletes bytes.
authorJim Wilson <jimw@sifive.com>
Thu, 1 Mar 2018 22:17:57 +0000 (14:17 -0800)
committerJim Wilson <jimw@sifive.com>
Thu, 1 Mar 2018 22:17:57 +0000 (14:17 -0800)
bfd/
PR 22756
* elfnn-riscv.c (riscv_relax_delete_bytes): When adjust st_size, use
else if instead of if.

bfd/ChangeLog
bfd/elfnn-riscv.c

index e2c5789bdb48731b7f775797aabddf7fc77c970d..517061bc50cf7287a5963891fef0bf2b160d2ab3 100644 (file)
@@ -1,3 +1,9 @@
+2018-03-01  Jim Wilson  <jimw@sifive.com>
+
+       PR 22756
+       * elfnn-riscv.c (riscv_relax_delete_bytes): When adjust st_size, use
+       else if instead of if.
+
 2018-03-01  Alan Modra  <amodra@gmail.com>
 
        * elf32-ft32.c (ft32_info_to_howto_rela): Correct range test.
index 6b2d80c379879a3fc55712c4f8531a81bf7f2d6e..582c8d174836a9a6591b9628c0a82e35d57bd1eb 100644 (file)
@@ -2665,10 +2665,16 @@ riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count,
 
          /* If the symbol *spans* the bytes we just deleted (i.e. its
             *end* is in the moved bytes but its *start* isn't), then we
-            must adjust its size.  */
-         if (sym->st_value <= addr
-             && sym->st_value + sym->st_size > addr
-             && sym->st_value + sym->st_size <= toaddr)
+            must adjust its size.
+
+            This test needs to use the original value of st_value, otherwise
+            we might accidentally decrease size when deleting bytes right
+            before the symbol.  But since deleted relocs can't span across
+            symbols, we can't have both a st_value and a st_size decrease,
+            so it is simpler to just use an else.  */
+         else if (sym->st_value <= addr
+                  && sym->st_value + sym->st_size > addr
+                  && sym->st_value + sym->st_size <= toaddr)
            sym->st_size -= count;
        }
     }
@@ -2716,9 +2722,9 @@ riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count,
            sym_hash->root.u.def.value -= count;
 
          /* As above, adjust the size if needed.  */
-         if (sym_hash->root.u.def.value <= addr
-             && sym_hash->root.u.def.value + sym_hash->size > addr
-             && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
+         else if (sym_hash->root.u.def.value <= addr
+                  && sym_hash->root.u.def.value + sym_hash->size > addr
+                  && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
            sym_hash->size -= count;
        }
     }