mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-12-02 00:56:27 +00:00
* coffcode.h (coff_sort_func_alent): New function.
(coff_slurp_line_table): Sort line table if not already sorted.
This commit is contained in:
parent
0fdaa00544
commit
e708816d5a
@ -1,3 +1,8 @@
|
||||
2007-08-01 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
* coffcode.h (coff_sort_func_alent): New function.
|
||||
(coff_slurp_line_table): Sort line table if not already sorted.
|
||||
|
||||
2007-08-01 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* elf.c (_bfd_elf_map_sections_to_segments): Work around buggy
|
||||
|
167
bfd/coffcode.h
167
bfd/coffcode.h
@ -4253,12 +4253,34 @@ SUBSUBSECTION
|
||||
How does this work ?
|
||||
*/
|
||||
|
||||
static int
|
||||
coff_sort_func_alent (const void * arg1, const void * arg2)
|
||||
{
|
||||
const alent *al1 = *(const alent **) arg1;
|
||||
const alent *al2 = *(const alent **) arg2;
|
||||
const coff_symbol_type *s1 = (const coff_symbol_type *) (al1->u.sym);
|
||||
const coff_symbol_type *s2 = (const coff_symbol_type *) (al2->u.sym);
|
||||
|
||||
if (s1->symbol.value < s2->symbol.value)
|
||||
return -1;
|
||||
else if (s1->symbol.value > s2->symbol.value)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
coff_slurp_line_table (bfd *abfd, asection *asect)
|
||||
{
|
||||
LINENO *native_lineno;
|
||||
alent *lineno_cache;
|
||||
bfd_size_type amt;
|
||||
unsigned int counter;
|
||||
alent *cache_ptr;
|
||||
bfd_vma prev_offset = 0;
|
||||
int ordered = 1;
|
||||
unsigned int nbr_func;
|
||||
LINENO *src;
|
||||
|
||||
BFD_ASSERT (asect->lineno == NULL);
|
||||
|
||||
@ -4270,67 +4292,120 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
|
||||
(_("%B: warning: line number table read failed"), abfd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent);
|
||||
lineno_cache = bfd_alloc (abfd, amt);
|
||||
if (lineno_cache == NULL)
|
||||
return FALSE;
|
||||
else
|
||||
|
||||
cache_ptr = lineno_cache;
|
||||
src = native_lineno;
|
||||
nbr_func = 0;
|
||||
|
||||
for (counter = 0; counter < asect->lineno_count; counter++)
|
||||
{
|
||||
unsigned int counter = 0;
|
||||
alent *cache_ptr = lineno_cache;
|
||||
LINENO *src = native_lineno;
|
||||
struct internal_lineno dst;
|
||||
|
||||
while (counter < asect->lineno_count)
|
||||
bfd_coff_swap_lineno_in (abfd, src, &dst);
|
||||
cache_ptr->line_number = dst.l_lnno;
|
||||
|
||||
if (cache_ptr->line_number == 0)
|
||||
{
|
||||
struct internal_lineno dst;
|
||||
bfd_boolean warned;
|
||||
bfd_signed_vma symndx;
|
||||
coff_symbol_type *sym;
|
||||
|
||||
bfd_coff_swap_lineno_in (abfd, src, &dst);
|
||||
cache_ptr->line_number = dst.l_lnno;
|
||||
|
||||
if (cache_ptr->line_number == 0)
|
||||
nbr_func++;
|
||||
warned = FALSE;
|
||||
symndx = dst.l_addr.l_symndx;
|
||||
if (symndx < 0
|
||||
|| (bfd_vma) symndx >= obj_raw_syment_count (abfd))
|
||||
{
|
||||
bfd_boolean warned;
|
||||
bfd_signed_vma symndx;
|
||||
coff_symbol_type *sym;
|
||||
|
||||
warned = FALSE;
|
||||
symndx = dst.l_addr.l_symndx;
|
||||
if (symndx < 0
|
||||
|| (bfd_vma) symndx >= obj_raw_syment_count (abfd))
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%B: warning: illegal symbol index %ld in line numbers"),
|
||||
abfd, dst.l_addr.l_symndx);
|
||||
symndx = 0;
|
||||
warned = TRUE;
|
||||
}
|
||||
/* FIXME: We should not be casting between ints and
|
||||
pointers like this. */
|
||||
sym = ((coff_symbol_type *)
|
||||
((symndx + obj_raw_syments (abfd))
|
||||
->u.syment._n._n_n._n_zeroes));
|
||||
cache_ptr->u.sym = (asymbol *) sym;
|
||||
if (sym->lineno != NULL && ! warned)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%B: warning: duplicate line number information for `%s'"),
|
||||
abfd, bfd_asymbol_name (&sym->symbol));
|
||||
}
|
||||
sym->lineno = cache_ptr;
|
||||
(*_bfd_error_handler)
|
||||
(_("%B: warning: illegal symbol index %ld in line numbers"),
|
||||
abfd, dst.l_addr.l_symndx);
|
||||
symndx = 0;
|
||||
warned = TRUE;
|
||||
}
|
||||
else
|
||||
cache_ptr->u.offset = dst.l_addr.l_paddr
|
||||
- bfd_section_vma (abfd, asect);
|
||||
|
||||
cache_ptr++;
|
||||
src++;
|
||||
counter++;
|
||||
/* FIXME: We should not be casting between ints and
|
||||
pointers like this. */
|
||||
sym = ((coff_symbol_type *)
|
||||
((symndx + obj_raw_syments (abfd))
|
||||
->u.syment._n._n_n._n_zeroes));
|
||||
cache_ptr->u.sym = (asymbol *) sym;
|
||||
if (sym->lineno != NULL && ! warned)
|
||||
(*_bfd_error_handler)
|
||||
(_("%B: warning: duplicate line number information for `%s'"),
|
||||
abfd, bfd_asymbol_name (&sym->symbol));
|
||||
|
||||
sym->lineno = cache_ptr;
|
||||
if (sym->symbol.value < prev_offset)
|
||||
ordered = 0;
|
||||
prev_offset = sym->symbol.value;
|
||||
}
|
||||
cache_ptr->line_number = 0;
|
||||
else
|
||||
cache_ptr->u.offset = dst.l_addr.l_paddr
|
||||
- bfd_section_vma (abfd, asect);
|
||||
|
||||
cache_ptr++;
|
||||
src++;
|
||||
}
|
||||
cache_ptr->line_number = 0;
|
||||
|
||||
/* On some systems (eg AIX5.3) the lineno table may not be sorted. */
|
||||
if (!ordered)
|
||||
{
|
||||
/* Sort the table. */
|
||||
alent **func_table;
|
||||
alent *n_lineno_cache;
|
||||
|
||||
/* Create a table of functions. */
|
||||
func_table = bfd_malloc (nbr_func * sizeof (alent *));
|
||||
if (func_table != NULL)
|
||||
{
|
||||
alent **p = func_table;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < counter; i++)
|
||||
if (lineno_cache[i].line_number == 0)
|
||||
*p++ = &lineno_cache[i];
|
||||
|
||||
/* Sort by functions. */
|
||||
qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent);
|
||||
|
||||
/* Create the new sorted table. */
|
||||
n_lineno_cache = bfd_alloc (abfd, amt);
|
||||
if (n_lineno_cache != NULL)
|
||||
{
|
||||
alent *n_cache_ptr = n_lineno_cache;
|
||||
|
||||
for (i = 0; i < nbr_func; i++)
|
||||
{
|
||||
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;
|
||||
sym->lineno = n_cache_ptr;
|
||||
n_cache_ptr++;
|
||||
old_ptr++;
|
||||
|
||||
/* Copy the line number entries. */
|
||||
while (old_ptr->line_number != 0)
|
||||
*n_cache_ptr++ = *old_ptr++;
|
||||
}
|
||||
n_cache_ptr->line_number = 0;
|
||||
bfd_release (abfd, lineno_cache);
|
||||
lineno_cache = n_lineno_cache;
|
||||
}
|
||||
free (func_table);
|
||||
}
|
||||
}
|
||||
|
||||
asect->lineno = lineno_cache;
|
||||
/* FIXME, free native_lineno here, or use alloca or something. */
|
||||
bfd_release (abfd, native_lineno);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user