public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [Patch]: fix addr2line on AIX5.3
@ 2007-07-13 23:01 Tristan Gingold
  2007-08-01  8:28 ` Ping: " Tristan Gingold
  2007-08-01 16:57 ` Nick Clifton
  0 siblings, 2 replies; 3+ messages in thread
From: Tristan Gingold @ 2007-07-13 23:01 UTC (permalink / raw)
  To: binutils

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;
   }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Ping: [Patch]: fix addr2line on AIX5.3
  2007-07-13 23:01 [Patch]: fix addr2line on AIX5.3 Tristan Gingold
@ 2007-08-01  8:28 ` Tristan Gingold
  2007-08-01 16:57 ` Nick Clifton
  1 sibling, 0 replies; 3+ messages in thread
From: Tristan Gingold @ 2007-08-01  8:28 UTC (permalink / raw)
  To: binutils

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;
>   }
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Patch]: fix addr2line on AIX5.3
  2007-07-13 23:01 [Patch]: fix addr2line on AIX5.3 Tristan Gingold
  2007-08-01  8:28 ` Ping: " Tristan Gingold
@ 2007-08-01 16:57 ` Nick Clifton
  1 sibling, 0 replies; 3+ messages in thread
From: Nick Clifton @ 2007-08-01 16:57 UTC (permalink / raw)
  To: Tristan Gingold; +Cc: binutils

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

My apologies for taking so long to review this patch.

It is fine, so I have checked it into the repository.

Cheers
   Nick


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-08-01 16:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-07-13 23:01 [Patch]: fix addr2line on AIX5.3 Tristan Gingold
2007-08-01  8:28 ` Ping: " Tristan Gingold
2007-08-01 16:57 ` Nick Clifton

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