diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 0da08bb0d6..0222d32310 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2014-11-03 Andrew Burgess + + * elf32-avr.c (elf32_avr_relax_delete_bytes): During linker + relaxation, reduce the size of symbols that span the deleted + bytes. + 2014-11-03 Andrew Burgess * elf32-avr.c (elf32_avr_relax_delete_bytes): Modify symbols diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index 8498d29493..5aa3cf6e13 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -1881,10 +1881,22 @@ elf32_avr_relax_delete_bytes (bfd *abfd, isymend = isym + symtab_hdr->sh_info; for (; isym < isymend; isym++) { - if (isym->st_shndx == sec_shndx - && isym->st_value > addr - && isym->st_value <= toaddr) - isym->st_value -= count; + if (isym->st_shndx == sec_shndx) + { + if (isym->st_value > addr + && isym->st_value <= toaddr) + isym->st_value -= count; + + if (isym->st_value <= addr + && isym->st_value + isym->st_size > addr) + { + /* If this assert fires then we have a symbol that ends + part way through an instruction. Does that make + sense? */ + BFD_ASSERT (isym->st_value + isym->st_size >= addr + count); + isym->st_size -= count; + } + } } } @@ -1898,11 +1910,22 @@ elf32_avr_relax_delete_bytes (bfd *abfd, struct elf_link_hash_entry *sym_hash = *sym_hashes; if ((sym_hash->root.type == bfd_link_hash_defined || sym_hash->root.type == bfd_link_hash_defweak) - && sym_hash->root.u.def.section == sec - && sym_hash->root.u.def.value > addr - && sym_hash->root.u.def.value <= toaddr) + && sym_hash->root.u.def.section == sec) { - sym_hash->root.u.def.value -= count; + if (sym_hash->root.u.def.value > addr + && sym_hash->root.u.def.value <= toaddr) + sym_hash->root.u.def.value -= count; + + if (sym_hash->root.u.def.value <= addr + && (sym_hash->root.u.def.value + sym_hash->size > addr)) + { + /* If this assert fires then we have a symbol that ends + part way through an instruction. Does that make + sense? */ + BFD_ASSERT (sym_hash->root.u.def.value + sym_hash->size + >= addr + count); + sym_hash->size -= count; + } } } diff --git a/ld/ChangeLog b/ld/ChangeLog index 86258cb316..56b9bd8aed 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2014-11-03 Andrew Burgess + + * testsuite/ld-avr/relax-02.d: Update to check size of symbols has + changed. + * testsuite/ld-avr/relax-03.d: Likewise. + 2014-11-03 Andrew Burgess * testsuite/ld-avr/relax-02.d: New file. diff --git a/ld/testsuite/ld-avr/relax-02.d b/ld/testsuite/ld-avr/relax-02.d index 64457098b0..c8d9b1037c 100644 --- a/ld/testsuite/ld-avr/relax-02.d +++ b/ld/testsuite/ld-avr/relax-02.d @@ -9,20 +9,20 @@ SYMBOL TABLE: #... -00000000 l F \.text [0-9a-f]+ local_start -0000000a l F \.text [0-9a-f]+ local_func_1 -00000014 l F \.text [0-9a-f]+ local_func_2 -0000001e l F \.text [0-9a-f]+ local_func_3 +00000000 l F \.text 0000000a local_start +0000000a l F \.text 0000000a local_func_1 +00000014 l F \.text 0000000a local_func_2 +0000001e l F \.text 0000000a local_func_3 00000032 l \.text 00000000 local_end_label 00000028 g \.text 00000000 dest #... -00000014 g F \.text [0-9a-f]+ func_2 +00000014 g F \.text 0000000a func_2 #... -00000000 g F \.text [0-9a-f]+ _start +00000000 g F \.text 0000000a _start 00000032 g \.text 00000000 end_label -0000000a g F \.text [0-9a-f]+ func_1 +0000000a g F \.text 0000000a func_1 #... -0000001e g F \.text [0-9a-f]+ func_3 +0000001e g F \.text 0000000a func_3 diff --git a/ld/testsuite/ld-avr/relax-03.d b/ld/testsuite/ld-avr/relax-03.d index a538c0459a..3adc279306 100644 --- a/ld/testsuite/ld-avr/relax-03.d +++ b/ld/testsuite/ld-avr/relax-03.d @@ -9,10 +9,10 @@ SYMBOL TABLE: #... -00000000 l F .text [0-9a-f]+ local_start +00000000 l F .text 0000000a local_start 0000000a l .text 00000000 local_end_label #... -00000000 g F \.text [0-9a-f]+ _start +00000000 g F \.text 0000000a _start 0000000a g \.text 00000000 end_label #...