diff options
-rw-r--r-- | bfd/ChangeLog | 12 | ||||
-rw-r--r-- | bfd/coffcode.h | 61 | ||||
-rw-r--r-- | bfd/pe-mips.c | 2 |
3 files changed, 44 insertions, 31 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 72b6ceb..afbbc26 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,17 @@ 2014-11-11 Alan Modra <amodra@gmail.com> + PR binutils/17512 + * coffcode.h (coff_slurp_line_table): Don't bfd_zalloc, just + memset the particular bits we need. Update src after hitting loop + "continue". Don't count lineno omitted due to invalid symbols in + nbr_func, and update lineno_count. Init entire terminating + lineno. Don't both allocating terminator in n_lineno_cache. + Redirect sym->lineno pointer to where n_lineno_cache will be + copied, and free n_lineno_cache. + * pe-mips.c (NUM_HOWTOS): Typo fix. + +2014-11-11 Alan Modra <amodra@gmail.com> + * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Adjust section size check to account for possible zero terminator. diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 8c6b1dd..6bc8014 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -4517,7 +4517,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect) BFD_ASSERT (asect->lineno == NULL); amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent); - lineno_cache = (alent *) bfd_zalloc (abfd, amt); + lineno_cache = (alent *) bfd_alloc (abfd, amt); if (lineno_cache == NULL) return FALSE; @@ -4536,22 +4536,24 @@ coff_slurp_line_table (bfd *abfd, asection *asect) src = native_lineno; nbr_func = 0; - for (counter = 0; counter < asect->lineno_count; counter++) + for (counter = 0; counter < asect->lineno_count; counter++, src++) { struct internal_lineno dst; bfd_coff_swap_lineno_in (abfd, src, &dst); cache_ptr->line_number = dst.l_lnno; + /* Appease memory checkers that get all excited about + uninitialised memory when copying alents if u.offset is + larger than u.sym. (64-bit BFD on 32-bit host.) */ + memset (&cache_ptr->u, 0, sizeof (cache_ptr->u)); if (cache_ptr->line_number == 0) { - bfd_signed_vma symndx; + bfd_vma symndx; coff_symbol_type *sym; - nbr_func++; symndx = dst.l_addr.l_symndx; - if (symndx < 0 - || (bfd_vma) symndx >= obj_raw_syment_count (abfd)) + if (symndx >= obj_raw_syment_count (abfd)) { (*_bfd_error_handler) (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"), @@ -4567,13 +4569,16 @@ coff_slurp_line_table (bfd *abfd, asection *asect) /* PR 17512 file: 078-10659-0.004 */ if (sym < obj_symbols (abfd) - || sym > obj_symbols (abfd) + obj_raw_syment_count (abfd)) - sym = NULL; - - cache_ptr->u.sym = (asymbol *) sym; - if (sym == NULL) + || sym >= obj_symbols (abfd) + obj_raw_syment_count (abfd)) + { + (*_bfd_error_handler) + (_("%B: warning: illegal symbol in line number entry %d"), + abfd, counter); continue; + } + nbr_func++; + cache_ptr->u.sym = (asymbol *) sym; if (sym->lineno != NULL) (*_bfd_error_handler) (_("%B: warning: duplicate line number information for `%s'"), @@ -4585,14 +4590,13 @@ coff_slurp_line_table (bfd *abfd, asection *asect) prev_offset = sym->symbol.value; } else - cache_ptr->u.offset = dst.l_addr.l_paddr - - bfd_section_vma (abfd, asect); - + cache_ptr->u.offset = (dst.l_addr.l_paddr + - bfd_section_vma (abfd, asect)); cache_ptr++; - src++; } - cache_ptr->line_number = 0; + asect->lineno_count = cache_ptr - lineno_cache; + memset (cache_ptr, 0, sizeof (*cache_ptr)); bfd_release (abfd, native_lineno); /* On some systems (eg AIX5.3) the lineno table may not be sorted. */ @@ -4617,8 +4621,8 @@ coff_slurp_line_table (bfd *abfd, asection *asect) qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent); /* Create the new sorted table. */ - amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent); - n_lineno_cache = (alent *) bfd_zalloc (abfd, amt); + amt = (bfd_size_type) asect->lineno_count * sizeof (alent); + n_lineno_cache = (alent *) bfd_alloc (abfd, amt); if (n_lineno_cache != NULL) { alent *n_cache_ptr = n_lineno_cache; @@ -4628,23 +4632,20 @@ coff_slurp_line_table (bfd *abfd, asection *asect) coff_symbol_type *sym; alent *old_ptr = func_table[i]; - /* Copy the function entry and update it. */ - *n_cache_ptr = *old_ptr; - sym = (coff_symbol_type *) n_cache_ptr->u.sym; - if (sym != NULL) - sym->lineno = n_cache_ptr; - n_cache_ptr++; - old_ptr++; + /* Update the function entry. */ + sym = (coff_symbol_type *) old_ptr->u.sym; + /* PR binutils/17512: Point the lineno to where + this entry will be after the memcpy below. */ + sym->lineno = lineno_cache + (n_cache_ptr - n_lineno_cache); - /* Copy the line number entries. */ - while (old_ptr->line_number != 0) + /* Copy the function and line number entries. */ + do *n_cache_ptr++ = *old_ptr++; + while (old_ptr->line_number != 0); } - n_cache_ptr->line_number = 0; memcpy (lineno_cache, n_lineno_cache, amt); } - /* PR binutils/17512: Do *not* free the func table - and new lineno cache - they are now being used. */ + bfd_release (abfd, func_table); } } diff --git a/bfd/pe-mips.c b/bfd/pe-mips.c index 940c069..57ec51f 100644 --- a/bfd/pe-mips.c +++ b/bfd/pe-mips.c @@ -339,7 +339,7 @@ static reloc_howto_type howto_table[] = FALSE), /* Pcrel_offset. */ }; -#define NUM_HOWTOS ((sizeof (howto_table) / sizeof (howto_table[0])) +#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0])) /* Turn a howto into a reloc nunmber. */ |