From: Tristan Gingold <gingold@adacore.com>
To: binutils@sourceware.org
Subject: Ping: [Patch]: fix addr2line on AIX5.3
Date: Wed, 01 Aug 2007 08:28:00 -0000 [thread overview]
Message-ID: <1F02F57B-4B2A-4FCF-8ABC-2DEE40C276A6@adacore.com> (raw)
In-Reply-To: <1E2B7EE8-FACB-490E-8357-665B10D74AE3@adacore.com>
No comment received so far for this patch.
Tristan.
On Jul 13, 2007, at 3:19 PM, Tristan Gingold wrote:
> Hi,
>
> on AIX (tested only with version 5.3), addr2line is not reliable
> because native linker doesn't sort
> line tables. This patch fixes the issue by sorting the line table
> when they are read only if they aren't
> already. This approach should be pretty safe and almost
> transparent to other coff backend.
>
> I am not sure this is the right approach so comments are very welcome.
>
> Tristan.
>
> bfd:
> 2007-07-13 Tristan Gingold <gingold@adacore.com>
>
> * coffcode.h (coff_sort_func_alent): New function.
> (coff_slurp_line_table): Sort line table if not already sorted.
>
> diff -c -p -r1.140 coffcode.h
> *** coffcode.h 12 Jul 2007 07:16:40 -0000 1.140
> --- coffcode.h 13 Jul 2007 13:11:09 -0000
> *************** SUBSUBSECTION
> *** 4253,4264 ****
> --- 4253,4286 ----
> 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;
> + else
> + 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);
>
> *************** coff_slurp_line_table (bfd *abfd, asecti
> *** 4274,4336 ****
> lineno_cache = bfd_alloc (abfd, amt);
> if (lineno_cache == NULL)
> return FALSE;
> ! else
> {
> ! unsigned int counter = 0;
> ! alent *cache_ptr = lineno_cache;
> ! LINENO *src = native_lineno;
>
> ! while (counter < asect->lineno_count)
> {
> ! struct internal_lineno dst;
>
> ! bfd_coff_swap_lineno_in (abfd, src, &dst);
> ! cache_ptr->line_number = dst.l_lnno;
>
> ! if (cache_ptr->line_number == 0)
> {
> ! 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;
> }
> ! else
> ! cache_ptr->u.offset = dst.l_addr.l_paddr
> ! - bfd_section_vma (abfd, asect);
> !
> ! cache_ptr++;
> ! src++;
> ! counter++;
> }
> - cache_ptr->line_number = 0;
> -
> }
> asect->lineno = lineno_cache;
> ! /* FIXME, free native_lineno here, or use alloca or something. */
> return TRUE;
> }
>
> --- 4296,4407 ----
> lineno_cache = bfd_alloc (abfd, amt);
> if (lineno_cache == NULL)
> return FALSE;
> !
> ! cache_ptr = lineno_cache;
> ! src = native_lineno;
> ! nbr_func = 0;
> !
> ! for (counter = 0; counter < asect->lineno_count; counter++)
> {
> ! struct internal_lineno dst;
> !
> ! bfd_coff_swap_lineno_in (abfd, src, &dst);
> ! cache_ptr->line_number = dst.l_lnno;
>
> ! if (cache_ptr->line_number == 0)
> {
> ! bfd_boolean warned;
> ! bfd_signed_vma symndx;
> ! coff_symbol_type *sym;
> !
> ! nbr_func++;
> ! 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;
> ! if (sym->symbol.value < prev_offset)
> ! ordered = 0;
> ! prev_offset = sym->symbol.value;
> ! }
> ! 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;
> ! bfd_release (abfd, native_lineno);
> return TRUE;
> }
>
next prev parent reply other threads:[~2007-08-01 8:28 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-13 23:01 Tristan Gingold
2007-08-01 8:28 ` Tristan Gingold [this message]
2007-08-01 16:57 ` Nick Clifton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1F02F57B-4B2A-4FCF-8ABC-2DEE40C276A6@adacore.com \
--to=gingold@adacore.com \
--cc=binutils@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).