public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
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;
>   }
>

  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).