|
From: <sv...@va...> - 2006-10-17 01:37:15
|
Author: sewardj
Date: 2006-10-17 02:37:10 +0100 (Tue, 17 Oct 2006)
New Revision: 6266
Log:
Merge r6129:
Changes to support XCOFF:
- allow modules to have 'member names' as well as file names. A member
name is a "foo.o" name inside a "bar.a"; necessary as AIX
keeps all its dynamic libraries in .a files.
- rename the type RiLoc to DiLoc (this holds a line number indication).
No idea why it was called RiLoc in the first place.
- trace changes in type SysRes
- implement VG_(di_aix5_notify_segchange)
Modified:
trunk/coregrind/m_debuginfo/debuginfo.c
trunk/coregrind/m_debuginfo/priv_storage.h
trunk/coregrind/m_debuginfo/readelf.c
trunk/coregrind/m_debuginfo/storage.c
Modified: trunk/coregrind/m_debuginfo/debuginfo.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_debuginfo/debuginfo.c 2006-10-17 01:36:37 UTC (rev =
6265)
+++ trunk/coregrind/m_debuginfo/debuginfo.c 2006-10-17 01:37:10 UTC (rev =
6266)
@@ -46,12 +46,19 @@
#include "pub_core_options.h"
#include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegIn=
fo)
#include "pub_core_aspacemgr.h"
+#include "pub_core_machine.h" // VG_PLAT_USES_PPCTOC
#include "priv_storage.h"
#include "priv_readdwarf.h"
#include "priv_readstabs.h"
-#include "priv_readelf.h"
+#if defined(VGO_linux)
+# include "priv_readelf.h"
+#elif defined(VGO_aix5)
+# include "pub_core_debuglog.h"
+# include "pub_core_libcproc.h"
+# include "pub_core_libcfile.h"
+# include "priv_readxcoff.h"
+#endif
=20
-
/*------------------------------------------------------------*/
/*--- Root structure ---*/
/*------------------------------------------------------------*/
@@ -72,7 +79,8 @@
/* Allocate and zero out a new SegInfo record. */
static=20
SegInfo* alloc_SegInfo(Addr start, SizeT size, OffT foffset,=20
- const HChar* filename)
+ const UChar* filename,
+ const UChar* memname)
{
SegInfo* si =3D VG_(arena_calloc)(VG_AR_SYMTAB, 1, sizeof(SegInfo));
=20
@@ -80,6 +88,8 @@
si->size =3D size;
si->foffset =3D foffset;
si->filename =3D VG_(arena_strdup)(VG_AR_SYMTAB, filename);
+ si->memname =3D memname ? VG_(arena_strdup)(VG_AR_SYMTAB, memname)
+ : NULL;
=20
// Everything else -- pointers, sizes, arrays -- is zeroed by calloc.
return si;
@@ -110,6 +120,14 @@
*/
static void discard_SegInfo ( SegInfo* si )
{
+# if defined(VGP_ppc32_aix5)
+ HChar* reason =3D "__unload";
+# elif defined(VGP_ppc64_aix5)
+ HChar* reason =3D "kunload64";
+# else
+ HChar* reason =3D "munmap";
+# endif
+
SegInfo** prev_next_ptr =3D &segInfo_list;
SegInfo* curr =3D segInfo_list;
=20
@@ -118,9 +136,10 @@
// Found it; remove from list and free it.
if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
VG_(message)(Vg_DebugMsg,=20
- "Discarding syms at %p-%p in %s due to munmap()=
",=20
+ "Discarding syms at %p-%p in %s due to %s()",=20
si->start, si->start + si->size,
- curr->filename ? curr->filename : (UChar*)"???"=
);
+ curr->filename ? curr->filename : (UChar*)"???"=
,
+ reason);
vg_assert(*prev_next_ptr =3D=3D curr);
*prev_next_ptr =3D curr->next;
VG_(redir_notify_delete_SegInfo)( curr );
@@ -170,12 +189,29 @@
/* Create a new SegInfo with the specific address/length/vma offset,
then snarf whatever info we can from the given filename into it. */
static
-SegInfo* acquire_syms_for_range( Addr seg_addr, SizeT seg_len,
- OffT seg_offset, const Char* seg_filena=
me)
+SegInfo* acquire_syms_for_range(=20
+ /* ALL */ Addr seg_addr,=20
+ /* ALL */ SizeT seg_len,
+ /* ELF only */ OffT seg_offset,=20
+ /* ALL */ const UChar* seg_filename,
+ /* XCOFF only */ const UChar* seg_memname,
+ /* XCOFF only */ Addr data_addr,
+ /* XCOFF only */ SizeT data_len,
+ /* XCOFF only */ Bool is_mainexe
+ )
{
- SegInfo* si =3D alloc_SegInfo(seg_addr, seg_len, seg_offset, seg_file=
name);
+ Bool ok;
+ SegInfo* si =3D alloc_SegInfo(seg_addr, seg_len, seg_offset,=20
+ seg_filename, seg_memname);
+# if defined(VGO_linux)
+ ok =3D ML_(read_elf_debug_info) ( si );
+# elif defined(VGO_aix5)
+ ok =3D ML_(read_xcoff_debug_info) ( si, data_addr, data_len, is_maine=
xe );
+# else
+# error Unknown OS
+# endif
=20
- if (! ML_(read_elf_debug_info) ( si )) {
+ if (!ok) {
// Something went wrong (eg. bad ELF file).
free_SegInfo( si );
si =3D NULL;
@@ -195,12 +231,14 @@
}
=20
=20
-/*------------------------------------------------------------*/
-/*--- ---*/
-/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) ---*/
-/*--- ---*/
-/*------------------------------------------------------------*/
+/*--------------------------------------------------------------*/
+/*--- ---*/
+/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/
+/*--- ---*/
+/*--------------------------------------------------------------*/
=20
+#if defined(VGO_linux)
+
/* The debug info system is driven by notifications that a text
segment has been mapped in, or unmapped. When that happens it
tries to acquire/discard whatever info is available for the
@@ -216,7 +254,7 @@
=20
void VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV )
{
- NSegment* seg;
+ NSegment const * seg;
HChar* filename;
Bool ok;
=20
@@ -260,7 +298,7 @@
seg =3D VG_(am_find_nsegment)(a);
vg_assert(seg);
=20
- filename =3D VG_(am_get_filename)( seg );
+ filename =3D VG_(am_get_filename)( (NSegment*)seg );
if (!filename)
return;
=20
@@ -284,7 +322,8 @@
=20
/* .. and acquire new info. */
acquire_syms_for_range( seg->start, seg->end + 1 - seg->start,=20
- seg->offset, filename );
+ seg->offset, filename,
+ /* XCOFF only */ NULL, 0, 0, False );
=20
/* acquire_syms_for_range makes its own copy of filename, so is
safe to free it. */
@@ -314,7 +353,71 @@
discard_syms_in_range(a, len);
}
=20
+#endif /* defined(VGO_linux) */
=20
+
+/*-------------------------------------------------------------*/
+/*--- ---*/
+/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (AIX5) ---*/
+/*--- ---*/
+/*-------------------------------------------------------------*/
+
+#if defined(VGO_aix5)
+
+/* The supplied parameters describe a code segment and its associated
+ data segment, that have recently been mapped in -- so we need to
+ read debug info for it -- or conversely, have recently been dumped,
+ in which case the relevant debug info has to be unloaded. */
+
+void VG_(di_aix5_notify_segchange)(=20
+ Addr code_start,
+ Word code_len,
+ Addr data_start,
+ Word data_len,
+ UChar* file_name,
+ UChar* mem_name,
+ Bool is_mainexe,
+ Bool acquire )
+{
+ SegInfo* si;
+
+ if (acquire) {
+
+ acquire_syms_for_range(
+ /* ALL */ code_start,=20
+ /* ALL */ code_len,
+ /* ELF only */ 0,
+ /* ALL */ file_name,
+ /* XCOFF only */ mem_name,
+ /* XCOFF only */ data_start,
+ /* XCOFF only */ data_len,
+ /* XCOFF only */ is_mainexe=20
+ );
+
+ } else {
+
+ /* Dump all the segInfos which intersect code_start/code_len. */
+ while (True) {
+ for (si =3D segInfo_list; si; si =3D si->next) {
+ if (code_start + code_len <=3D si->start
+ || si->start + si->size <=3D code_start)
+ continue; /* no overlap */
+ else=20
+ break;
+ }
+ if (si =3D=3D NULL)
+ break;
+ /* Need to delete 'si' */
+ discard_SegInfo(si);
+ }
+
+ }
+}
+ =20
+
+#endif /* defined(VGO_aix5) */
+
+
/*------------------------------------------------------------*/
/*--- ---*/
/*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/
@@ -499,11 +602,25 @@
Caller supplies buf and nbuf. */
Bool VG_(get_objname) ( Addr a, Char* buf, Int nbuf )
{
+ Int used;
SegInfo* si;
=20
+ vg_assert(nbuf > 0);
for (si =3D segInfo_list; si !=3D NULL; si =3D si->next) {
if (si->start <=3D a && a < si->start+si->size) {
VG_(strncpy_safely)(buf, si->filename, nbuf);
+ if (si->memname) {
+ used =3D VG_(strlen)(buf);
+ if (used < nbuf)=20
+ VG_(strncpy_safely)(&buf[used], "(", nbuf-used);
+ used =3D VG_(strlen)(buf);
+ if (used < nbuf)=20
+ VG_(strncpy_safely)(&buf[used], si->memname, nbuf-used);
+ used =3D VG_(strlen)(buf);
+ if (used < nbuf)=20
+ VG_(strncpy_safely)(&buf[used], ")", nbuf-used);
+ }
+ buf[nbuf-1] =3D 0;
return True;
}
}
@@ -590,6 +707,43 @@
}
=20
=20
+/* Map a function name to its entry point and toc pointer. Is done by
+ sequential search of all symbol tables, so is very slow. To
+ mitigate the worst performance effects, you may specify a soname
+ pattern, and only objects matching that pattern are searched.
+ Therefore specify "*" to search all the objects. On TOC-afflicted
+ platforms, a symbol is deemed to be found only if it has a nonzero
+ TOC pointer. */
+Bool VG_(lookup_symbol_SLOW)(UChar* sopatt, UChar* name, Addr* pEnt, Add=
r* pToc)
+{
+ Bool require_pToc =3D False;
+ Int i;
+ SegInfo* si;
+ Bool debug =3D False;
+# if defined(VG_PLAT_USES_PPCTOC)
+ require_pToc =3D True;
+# endif
+ for (si =3D segInfo_list; si; si =3D si->next) {
+ if (debug)
+ VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname)=
;
+ if (!VG_(string_match)(sopatt, si->soname)) {
+ if (debug)
+ VG_(printf)(" ... skip\n");
+ continue;
+ }
+ for (i =3D 0; i < si->symtab_used; i++) {
+ if (0=3D=3DVG_(strcmp)(name, si->symtab[i].name)
+ && (require_pToc ? si->symtab[i].tocptr : True)) {
+ *pEnt =3D si->symtab[i].addr;
+ *pToc =3D si->symtab[i].tocptr;
+ return True;
+ }
+ }
+ }
+ return False;
+}
+
+
/* Print into buf info on code address, function name and filename */
=20
static Int putStr ( Int n, Int n_buf, Char* buf, Char* str )=20
@@ -632,7 +786,9 @@
static UChar buf_srcloc[BUF_LEN];
static UChar buf_dirname[BUF_LEN];
Bool know_dirinfo =3D False;
- Bool know_fnname =3D VG_(get_fnname) (eip, buf_fn, BUF_LEN);
+ Bool know_fnname =3D VG_(clo_sym_offsets)
+ ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN=
)
+ : VG_(get_fnname) (eip, buf_fn, BUF_LEN);
Bool know_objname =3D VG_(get_objname)(eip, buf_obj, BUF_LEN);
Bool know_srcloc =3D VG_(get_filename_linenum)(
eip,=20
@@ -921,13 +1077,15 @@
void VG_(seginfo_syms_getidx) ( const SegInfo *si,=20
Int idx,
/*OUT*/Addr* addr,
+ /*OUT*/Addr* tocptr,
/*OUT*/UInt* size,
/*OUT*/HChar** name )
{
vg_assert(idx >=3D 0 && idx < si->symtab_used);
- if (addr) *addr =3D si->symtab[idx].addr;
- if (size) *size =3D si->symtab[idx].size;
- if (name) *name =3D (HChar*)si->symtab[idx].name;
+ if (addr) *addr =3D si->symtab[idx].addr;
+ if (tocptr) *tocptr =3D si->symtab[idx].tocptr;
+ if (size) *size =3D si->symtab[idx].size;
+ if (name) *name =3D (HChar*)si->symtab[idx].name;
}
=20
=20
Modified: trunk/coregrind/m_debuginfo/priv_storage.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_debuginfo/priv_storage.h 2006-10-17 01:36:37 UTC (r=
ev 6265)
+++ trunk/coregrind/m_debuginfo/priv_storage.h 2006-10-17 01:37:10 UTC (r=
ev 6266)
@@ -142,6 +142,7 @@
Addr start;
UInt size;
UChar* filename; /* in mallocville */
+ UChar* memname; /* malloc'd. AIX5 only: .a member name */
OffT foffset;
UChar* soname;
=20
Modified: trunk/coregrind/m_debuginfo/readelf.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_debuginfo/readelf.c 2006-10-17 01:36:37 UTC (rev 62=
65)
+++ trunk/coregrind/m_debuginfo/readelf.c 2006-10-17 01:37:10 UTC (rev 62=
66)
@@ -738,8 +738,8 @@
if (fd.isError)
return 0;
=20
- if (VG_(fstat)(fd.val, &stat_buf) !=3D 0) {
- VG_(close)(fd.val);
+ if (VG_(fstat)(fd.res, &stat_buf) !=3D 0) {
+ VG_(close)(fd.res);
return 0;
}
=20
@@ -749,23 +749,23 @@
*size =3D stat_buf.st_size;
=20
sres =3D VG_(am_mmap_file_float_valgrind)
- ( *size, VKI_PROT_READ, fd.val, 0 );
+ ( *size, VKI_PROT_READ, fd.res, 0 );
=20
- VG_(close)(fd.val);
+ VG_(close)(fd.res);
=20
if (sres.isError)
return 0;
=20
- calccrc =3D calc_gnu_debuglink_crc32(0, (UChar*)sres.val, *size);
+ calccrc =3D calc_gnu_debuglink_crc32(0, (UChar*)sres.res, *size);
if (calccrc !=3D crc) {
- SysRes res =3D VG_(am_munmap_valgrind)(sres.val, *size);
+ SysRes res =3D VG_(am_munmap_valgrind)(sres.res, *size);
vg_assert(!res.isError);
if (VG_(clo_verbosity) > 1)
VG_(message)(Vg_DebugMsg, "... CRC mismatch (computed %08x wanted %08x=
)", calccrc, crc);
return 0;
}
=20
- return sres.val;
+ return sres.res;
}
=20
/*
@@ -838,17 +838,17 @@
return False;
}
=20
- n_oimage =3D VG_(fsize)(fd.val);
+ n_oimage =3D VG_(fsize)(fd.res);
if (n_oimage < 0) {
ML_(symerr)("Can't stat .so/.exe (to determine its size)?!");
- VG_(close)(fd.val);
+ VG_(close)(fd.res);
return False;
}
=20
sres =3D VG_(am_mmap_file_float_valgrind)
- ( n_oimage, VKI_PROT_READ, fd.val, 0 );
+ ( n_oimage, VKI_PROT_READ, fd.res, 0 );
=20
- VG_(close)(fd.val);
+ VG_(close)(fd.res);
=20
if (sres.isError) {
VG_(message)(Vg_UserMsg, "warning: mmap failed on %s", si->filenam=
e );
@@ -856,7 +856,7 @@
return False;
}
=20
- oimage =3D sres.val;
+ oimage =3D sres.res;
=20
/* Ok, the object image is safely in oimage[0 .. n_oimage-1].=20
Now verify that it is a valid ELF .so or executable image.
Modified: trunk/coregrind/m_debuginfo/storage.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_debuginfo/storage.c 2006-10-17 01:36:37 UTC (rev 62=
65)
+++ trunk/coregrind/m_debuginfo/storage.c 2006-10-17 01:37:10 UTC (rev 62=
66)
@@ -562,7 +562,7 @@
ranges do not overlap. This facilitates using binary search to map
addresses to locations when we come to query the table.
*/
-static Int compare_RiLoc ( void* va, void* vb )=20
+static Int compare_DiLoc ( void* va, void* vb )=20
{
DiLoc* a =3D (DiLoc*)va;
DiLoc* b =3D (DiLoc*)vb;
@@ -583,7 +583,7 @@
=20
/* Sort by start address. */
VG_(ssort)(si->loctab, si->loctab_used,=20
- sizeof(*si->loctab), compare_RiLoc);
+ sizeof(*si->loctab), compare_DiLoc);
=20
/* If two adjacent entries overlap, truncate the first. */
for (i =3D 0; i < ((Int)si->loctab_used)-1; i++) {
|