2018-03-01 Jim Wilson PR 22756 * elfnn-riscv.c (riscv_relax_delete_bytes): When adjust st_size, use else if instead of if. Index: binutils-2.30/bfd/elfnn-riscv.c =================================================================== --- binutils-2.30.orig/bfd/elfnn-riscv.c +++ binutils-2.30/bfd/elfnn-riscv.c @@ -2639,10 +2639,16 @@ riscv_relax_delete_bytes (bfd *abfd, ase /* 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; } } @@ -2690,9 +2696,9 @@ riscv_relax_delete_bytes (bfd *abfd, ase 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; } }