From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7027 invoked by alias); 1 Aug 2007 08:28:07 -0000 Received: (qmail 7018 invoked by uid 22791); 1 Aug 2007 08:28:06 -0000 X-Spam-Check-By: sourceware.org Received: from province.act-europe.fr (HELO province.act-europe.fr) (212.157.227.214) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 01 Aug 2007 08:28:02 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-province.act-europe.fr (Postfix) with ESMTP id 5B7EF1658D0 for ; Wed, 1 Aug 2007 10:27:59 +0200 (CEST) Received: from province.act-europe.fr ([127.0.0.1]) by localhost (province.act-europe.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id flObB0HlSIjT for ; Wed, 1 Aug 2007 10:27:59 +0200 (CEST) Received: from [10.10.127.242] (dhcp-guest-242.act-europe.fr [10.10.127.242]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by province.act-europe.fr (Postfix) with ESMTP id E716B16583E for ; Wed, 1 Aug 2007 10:27:58 +0200 (CEST) Mime-Version: 1.0 (Apple Message framework v752.3) In-Reply-To: <1E2B7EE8-FACB-490E-8357-665B10D74AE3@adacore.com> References: <1E2B7EE8-FACB-490E-8357-665B10D74AE3@adacore.com> Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed Message-Id: <1F02F57B-4B2A-4FCF-8ABC-2DEE40C276A6@adacore.com> Content-Transfer-Encoding: 7bit From: Tristan Gingold Subject: Ping: [Patch]: fix addr2line on AIX5.3 Date: Wed, 01 Aug 2007 08:28:00 -0000 To: binutils@sourceware.org X-Mailer: Apple Mail (2.752.3) X-IsSubscribed: yes Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2007-08/txt/msg00011.txt.bz2 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 > > * 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; > } >