From 788af978df01c3667be99a1607b774f5fa844113 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Thu, 1 Mar 2018 14:17:57 -0800 Subject: [PATCH] RISC-V: Fix symbol size bug when relaxation deletes bytes. bfd/ PR 22756 * elfnn-riscv.c (riscv_relax_delete_bytes): When adjust st_size, use else if instead of if. --- bfd/ChangeLog | 6 ++++++ bfd/elfnn-riscv.c | 20 +++++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index e2c5789..517061b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2018-03-01 Jim Wilson + + PR 22756 + * elfnn-riscv.c (riscv_relax_delete_bytes): When adjust st_size, use + else if instead of if. + 2018-03-01 Alan Modra * elf32-ft32.c (ft32_info_to_howto_rela): Correct range test. diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 6b2d80c..582c8d1 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -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; } } -- 2.7.4