This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
Re: libgcj/5773: integrate addr2line and c++filt into libjava instead of external process
- From: Todd Stock <toddastock at yahoo dot com>
- To: nobody at gcc dot gnu dot org
- Cc: gcc-prs at gcc dot gnu dot org,
- Date: 25 Feb 2002 19:36:01 -0000
- Subject: Re: libgcj/5773: integrate addr2line and c++filt into libjava instead of external process
- Reply-to: Todd Stock <toddastock at yahoo dot com>
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