This is the mail archive of the gcc-prs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: libgcj/5773: integrate addr2line and c++filt into libjava instead of external process


The following reply was made to PR libgcj/5773; it has been noted by GNATS.

From: Todd Stock <toddastock@yahoo.com>
To: toddastock@yahoo.com
Cc: gcc-gnats@gcc.gnu.org
Subject: Re: libgcj/5773: integrate addr2line and c++filt into libjava instead of external process
Date: Mon, 25 Feb 2002 11:30:28 -0800

 This is a multi-part message in MIME format.
 --------------050005020800040500010404
 Content-Type: text/plain; charset=us-ascii; format=flowed
 Content-Transfer-Encoding: 7bit
 
 I forgot to add the code when checking for dynamic loaded objects.
 
 -Todd
 
 --------------050005020800040500010404
 Content-Type: text/plain;
  name="addr2line.cc"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="addr2line.cc"
 
 // addr2line.cc - Convert addresses to names
 
 /* Copyright (C) 2000  Free Software Foundation, Inc
 
    This file is part of libgcj.
 
 This software is copyrighted work licensed under the terms of the
 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 details.  */
 
 /**
  * @author Todd Stock <toddastock@yahoo.com>
  * @date Feb 24  2002
  */
 
 #include <config.h>
 
 #ifdef HAVE_LIBBFD
 
 #include <jvm.h>
 #include <gcj/cni.h>
 
 #include <addr2line.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 
 extern "C" {
 #include "demangle.h"
 }
 
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
 #endif
 
 void free(void *);
 
 static void
 addr2LineErrorHandler (const char *s, ...)
   {
   }
 
 Addr2Line::Addr2Line (char *executable)
   {
     char **matching;
 
     abfd = NULL;
 
     bfd_init ();
 
     bfd_set_error_handler( addr2LineErrorHandler );
 
     const char *target = TARGET;
     if (! bfd_set_default_target (target))
       {
         fprintf( stderr, "can't set BFD default target to `%s': %s", target, bfd_errmsg (bfd_get_error ()));
         return;
       }
 
     abfd = bfd_openr (executable, NULL);
     if (abfd == NULL)
       {
         printErr( executable );
         return;
       }
 
     if (bfd_check_format (abfd, bfd_archive))
       {
         fprintf( stderr, "%s: can not get addresses from archive", executable );
         bfd_close (abfd);
         abfd = NULL;
         return;
       }
 
     if (! bfd_check_format_matches (abfd, bfd_object, &matching))
       {
         printErr ( bfd_get_filename (abfd) );
         if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
           {
 //	    list_matching_formats (matching);
 	    free(matching);
 	  }
         bfd_close (abfd);
         abfd = NULL;
         return;
       }
 
     long storage;
     long symcount;
 
     if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0)
       {
         bfd_close (abfd);
         abfd = NULL;
         return;
       }
 
     storage = bfd_get_symtab_upper_bound (abfd);
     if (storage < 0)
       {
         printErr ( bfd_get_filename (abfd) );
         bfd_close (abfd);
         abfd = NULL;
         return;
       }
 
     syms = (asymbol **) _Jv_Malloc(storage);
 
     symcount = bfd_canonicalize_symtab (abfd, syms);
     if (symcount < 0)
       {
         printErr ( bfd_get_filename (abfd) );
         bfd_close (abfd);
         abfd = NULL;
         _Jv_Free (syms);
         syms = NULL;
         return;
       }
 
     needFree = found = false;
     methodName = "??";
     fileName = NULL;
     line = 0;
   }
 
 Addr2Line::~Addr2Line ()
   {
     if (syms != NULL)
       { 
         _Jv_Free (syms);
         syms = NULL;
       }
 
     if (abfd != NULL)
       {
         bfd_close (abfd);
       }
   }
 
 void
 find_address_in_section ( bfd *abfd, asection *section, void *data)
   {
     bfd_vma vma;
     bfd_size_type size;
     Addr2Line *x = (Addr2Line *)data;
 
     if (x->found)
       return;
 
     if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
       return;
 
     vma = bfd_get_section_vma (abfd, section);
     if (x->pc < vma)
       return;
 
     size = bfd_get_section_size_before_reloc (section);
     if (x->pc >= vma + size)
       return;
 
     x->found = bfd_find_nearest_line (abfd, section, x->syms, x->pc - vma, &x->fileName, &x->_methodName, (unsigned int *)&x->line);
   }
 
 bool
 Addr2Line::lookup (void *p)
 {
   extern char **_Jv_argv;
   typedef unsigned word_t __attribute ((mode (word)));
   word_t n = (word_t) p;
   int digits = sizeof (void *) * 2;
 
   strcpy (hex, "0x");
   for (int i = digits - 1; i >= 0; i--)
     {
       int digit = n % 16;
 
       n /= 16;
       hex[i+2] = digit > 9 ? 'a' + digit - 10 : '0' + digit;
     }
   hex [digits+2] = 0;
 
 #if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR)
   { 
     Dl_info dl_info;
     
     if (dladdr (p, &dl_info))
       {
         if (dl_info.dli_fname)
           {
           strncpy (file_name, dl_info.dli_fname, sizeof file_name);
           fileName = &file_name[0];
           }
         if (dl_info.dli_sname)
           {
           strncpy (method_name, dl_info.dli_sname, sizeof method_name);
 	  methodName = &method_name[0];
           }
 
        /* Don't trust dladdr() if the address is from the main program. */
        if (dl_info.dli_fname != NULL
            && dl_info.dli_sname != NULL
            && (_Jv_argv == NULL || strcmp (file_name, _Jv_argv[0]) != 0))
          return true;
       }
   }
 #endif
 
   return _lookup( hex );
 }
 
 bool
 Addr2Line::_lookup( char *addr_hex )
   {
     if( needFree ) {
       free( methodName );
     }
     needFree = false;
 
     if (addr_hex == NULL)
       return false;
 
     pc = bfd_scan_vma( addr_hex, NULL, 16 );
 
     found = false;
     methodName = "??";
     fileName = NULL;
     line = 0;
 
     if (abfd == NULL)
       return false;
 
     bfd_map_over_sections( abfd, find_address_in_section, this );
     if( found )
       {
         if( _methodName == NULL )
           {
             methodName = "??";
           }
         else
           {
             needFree = true;
             char *res = cplus_demangle( _methodName,  DMGL_ANSI | DMGL_PARAMS );
             if (res == NULL)
             {
               methodName = strdup(_methodName);
             }
           else
             {
               methodName = res;
             }
         }
         return true;
       }
     return false;
   }
 
 void
 Addr2Line::printErr( char *string )
   {
     const char *errmsg = bfd_errmsg (bfd_get_error ());
     if (string)
       fprintf (stderr, "Addr2Line: %s: %s\n", string, errmsg);
     else
       fprintf (stderr, "Addr2Line: %s\n", errmsg);
   }
 
 #endif
 
 --------------050005020800040500010404
 Content-Type: text/plain;
  name="addr2line.h"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="addr2line.h"
 
 // addr2line.h - Convert addresses to names (header)
 
 /* Copyright (C) 2000  Free Software Foundation, Inc
 
    This file is part of libgcj.
 
 This software is copyrighted work licensed under the terms of the
 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 details.  */
 
 /**
  * @author Todd Stock <toddastock@yahoo.com>
  * @date Feb 24  2002
  */
 
 #ifndef ADDR2LINE
 #define ADDR2LINE
 
 #include <bfd.h>
 
 class Addr2Line
   {
 
 public:
 
     Addr2Line (char *);
     ~Addr2Line ();
 
     void *operator new (size_t bytes)
       {
         return _Jv_Malloc (bytes);
       }
 
     void operator delete (void *mem)
       {
         _Jv_Free (mem);
       }
 
     bool lookup (void *);
 
     char *methodName;
     const char *fileName;
     jlong line;
     char hex[sizeof (void *) * 2 + 5];
 
 private:
 
     friend void find_address_in_section (bfd *, asection *, void *);
     bool _lookup (char *);
     void printErr (char *);
 
     const char *_methodName;
     bfd *abfd;
     asymbol **syms;
     bfd_vma pc;
     bool found;
     bool needFree;
 
     char file_name[1024];
     char method_name[1024];
   };
 #endif
 
 --------------050005020800040500010404--
 
 
 _________________________________________________________
 Do You Yahoo!?
 Get your free @yahoo.com address at http://mail.yahoo.com
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]