|
From: <sv...@va...> - 2005-09-18 22:44:22
|
Author: sewardj
Date: 2005-09-18 23:44:17 +0100 (Sun, 18 Sep 2005)
New Revision: 4677
Log:
Add simplistic support for loading/unloading debug info.
Modified:
branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c
branches/ASPACEM/coregrind/m_debuginfo/symtab.c
branches/ASPACEM/coregrind/m_main.c
branches/ASPACEM/coregrind/m_syswrap/syswrap-generic.c
branches/ASPACEM/coregrind/m_syswrap/syswrap-x86-linux.c
branches/ASPACEM/coregrind/pub_core_aspacemgr.h
branches/ASPACEM/coregrind/pub_core_debuginfo.h
Modified: branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.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
--- branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-18 10:07:5=
1 UTC (rev 4676)
+++ branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-18 22:44:1=
7 UTC (rev 4677)
@@ -1751,6 +1751,63 @@
}
=20
=20
+/* Get the filename corresponding to this segment, if known and if it
+ has one. The returned name's storage cannot be assumed to be
+ persistent, so the caller should immediately copy the name
+ elsewhere. */
+HChar* VG_(am_get_filename)( NSegment* seg )
+{
+ Int i;
+ aspacem_assert(seg);
+ i =3D seg->fnIdx;
+ if (i < 0 || i >=3D segnames_used || !segnames[i].inUse)
+ return NULL;
+ else
+ return &segnames[i].fname[0];
+}
+
+/* Collect up the start addresses of all non-free, non-resvn segments.
+ The interface is a bit strange. You have to call it twice. If
+ 'starts' is NULL, the number of such segments is calculated and
+ written to *nStarts. If 'starts' is non-NULL, it should point to
+ an array of size *nStarts, and the segment start addresses are
+ written at starts[0 .. *nStarts-1]. In the latter case, the number
+ of required slots is recalculated, and the function asserts if this
+ is not equal to *nStarts. */
+
+void VG_(am_get_segment_starts)( Addr* starts, Int* nStarts )
+{
+ Int i, j, nSegs;
+
+ nSegs =3D 0;
+ for (i =3D 0; i < nsegments_used; i++) {
+ if (nsegments[i].kind =3D=3D SkFree || nsegments[i].kind =3D=3D Sk=
Resvn)
+ continue;
+ nSegs++;
+ }
+
+ if (starts =3D=3D NULL) {
+ /* caller just wants to know how many segments there are. */
+ *nStarts =3D nSegs;
+ return;
+ }
+
+ /* otherwise, caller really is after the segments. */
+ /* If this assertion fails, the passed-in *nStarts is incorrect. */
+ aspacem_assert(*nStarts =3D=3D nSegs);
+
+ j =3D 0;
+ for (i =3D 0; i < nsegments_used; i++) {
+ if (nsegments[i].kind =3D=3D SkFree || nsegments[i].kind =3D=3D Sk=
Resvn)
+ continue;
+ starts[j] =3D nsegments[i].start;
+ j++;
+ }
+
+ aspacem_assert(j =3D=3D nSegs); /* this should not fail */
+}
+
+
/*-----------------------------------------------------------------*/
/*--- ---*/
/*--- Sanity checking and preening of the segment array. ---*/
@@ -2150,6 +2207,32 @@
return is_valid_for_client( start, len, prot, True/*free is OK*/ );
}
=20
+
+/* Test if a piece of memory is addressable by valgrind with at least
+ PROT_NONE protection permissions by examining the underlying
+ segments. */
+static Bool is_valid_for_valgrind( Addr start, SizeT len )
+{
+ Int i, iLo, iHi;
+
+ if (len =3D=3D 0)
+ return True; /* somewhat dubious case */
+ if (start + len < start)
+ return False; /* reject wraparounds */
+
+ iLo =3D find_nsegment_idx(start);
+ iHi =3D find_nsegment_idx(start + len - 1);
+ for (i =3D iLo; i <=3D iHi; i++) {
+ if (nsegments[i].kind =3D=3D SkFileV || nsegments[i].kind =3D=3D S=
kAnonV) {
+ /* ok */
+ } else {
+ return False;
+ }
+ }
+ return True;
+}
+
+
/*-----------------------------------------------------------------*/
/*--- ---*/
/*--- Modifying the segment array, and constructing segments. ---*/
@@ -3008,12 +3091,80 @@
}
=20
=20
-/* Unmap the given address range an update the segment array
- accordingly. This fails if the range isn't valid for the
- client. */
+/* Map a file at an unconstrained address for V, and update the
+ segment array accordingly. This is used by V for transiently
+ mapping in object files to read their debug info. */
=20
-SysRes VG_(am_munmap_client)( Addr start, SizeT len )
+SysRes VG_(am_mmap_file_float_valgrind) ( SizeT length, UInt prot,=20
+ Int fd, SizeT offset )
{
+ SysRes sres;
+ NSegment seg;
+ Addr advised;
+ Bool ok;
+ MapRequest req;
+ UInt dev, ino;
+ HChar buf[VKI_PATH_MAX];
+=20
+ /* Not allowable. */
+ if (length =3D=3D 0)
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
+
+ /* Ask for an advisory. If it's negative, fail immediately. */
+ req.rkind =3D MAny;
+ req.start =3D 0;
+ req.len =3D length;
+ advised =3D VG_(am_get_advisory)( &req, True/*client*/, &ok );
+ if (!ok)
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
+
+ /* We have been advised that the mapping is allowable at the
+ specified address. So hand it off to the kernel, and propagate
+ any resulting failure immediately. */
+ sres =3D VG_(am_do_mmap_NO_NOTIFY)(=20
+ advised, length, prot,=20
+ VKI_MAP_FIXED|VKI_MAP_PRIVATE,=20
+ fd, offset=20
+ );
+ if (sres.isError)
+ return sres;
+
+ if (sres.val !=3D advised) {
+ /* I don't think this can happen. It means the kernel made a
+ fixed map succeed but not at the requested location. Try to
+ repair the damage, then return saying the mapping failed. */
+ (void)do_munmap_NO_NOTIFY( sres.val, length );
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
+ }
+
+ /* Ok, the mapping succeeded. Now notify the interval map. */
+ init_nsegment( &seg );
+ seg.kind =3D SkFileV;
+ seg.start =3D sres.val;
+ seg.end =3D seg.start + VG_PGROUNDUP(length) - 1;
+ seg.offset =3D offset;
+ seg.hasR =3D toBool(prot & VKI_PROT_READ);
+ seg.hasW =3D toBool(prot & VKI_PROT_WRITE);
+ seg.hasX =3D toBool(prot & VKI_PROT_EXEC);
+ if (get_inode_for_fd(fd, &dev, &ino)) {
+ seg.dev =3D dev;
+ seg.ino =3D ino;
+ }
+ if (get_name_for_fd(fd, buf, VKI_PATH_MAX)) {
+ seg.fnIdx =3D allocate_segname( buf );
+ }
+ add_segment( &seg );
+
+ AM_SANITY_CHECK;
+ return sres;
+}
+
+
+/* --- --- munmap helper --- --- */
+
+static=20
+SysRes am_munmap_both_wrk ( Addr start, SizeT len, Bool forClient )
+{
SysRes sres;
=20
if (!VG_IS_PAGE_ALIGNED(start))
@@ -3029,9 +3180,14 @@
aspacem_assert(VG_IS_PAGE_ALIGNED(start));
aspacem_assert(VG_IS_PAGE_ALIGNED(len));
=20
- if (!VG_(am_is_valid_for_client_or_free_or_resvn)
- ( start, len, VKI_PROT_NONE ))
- goto eINVAL;
+ if (forClient) {
+ if (!VG_(am_is_valid_for_client_or_free_or_resvn)
+ ( start, len, VKI_PROT_NONE ))
+ goto eINVAL;
+ } else {
+ if (!is_valid_for_valgrind( start, len ))
+ goto eINVAL;
+ }
=20
sres =3D do_munmap_NO_NOTIFY( start, len );
if (sres.isError)
@@ -3045,7 +3201,24 @@
return VG_(mk_SysRes_Error)( VKI_EINVAL );
}
=20
+/* Unmap the given address range and update the segment array
+ accordingly. This fails if the range isn't valid for the
+ client. */
=20
+SysRes VG_(am_munmap_client)( Addr start, SizeT len )
+{
+ return am_munmap_both_wrk( start, len, True/*client*/ );
+}
+
+/* Unmap the given address range and update the segment array
+ accordingly. This fails if the range isn't valid for valgrind. */
+
+SysRes VG_(am_munmap_valgrind)( Addr start, SizeT len )
+{
+ return am_munmap_both_wrk( start, len, False/*valgrind*/ );
+}
+
+
/* --- --- --- reservations --- --- --- */
=20
/* Create a reservation from START .. START+LENGTH-1, with the given
Modified: branches/ASPACEM/coregrind/m_debuginfo/symtab.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
--- branches/ASPACEM/coregrind/m_debuginfo/symtab.c 2005-09-18 10:07:51 U=
TC (rev 4676)
+++ branches/ASPACEM/coregrind/m_debuginfo/symtab.c 2005-09-18 22:44:17 U=
TC (rev 4677)
@@ -45,6 +45,8 @@
#include "pub_core_redir.h"
#include "pub_core_tooliface.h" // For VG_(needs).data_syms
=20
+#include "pub_core_aspacemgr.h"
+
#include "priv_symtypes.h"
#include "priv_symtab.h"
=20
@@ -95,6 +97,124 @@
=20
=20
/*------------------------------------------------------------*/
+/*--- TOP LEVEL ---*/
+/*------------------------------------------------------------*/
+
+/* If this mapping is at the beginning of a file, isn't part of
+ Valgrind, is at least readable and seems to contain an object
+ file, then try reading symbols from it.
+
+ Getting this heuristic right is critical. On x86-linux,
+ objects are typically mapped twice:
+
+ 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so
+ 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so
+
+ whereas ppc32-linux mysteriously does this:
+
+ 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so
+ 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so
+ 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so
+
+ The third mapping should not be considered to have executable code in=
.
+ Therefore a test which works for both is: r and x and NOT w. Reading
+ symbols from the rwx segment -- which overlaps the r-x segment in the
+ file -- causes the redirection mechanism to redirect to addresses in
+ that third segment, which is wrong and causes crashes.
+*/
+
+static Bool is_self ( HChar* filename )
+{=20
+ return VG_(strstr)( filename, "/lib/valgrind/" ) !=3D NULL;
+}
+
+////////////
+
+// fwds
+static void unload_symbols ( Addr start, SizeT length );
+
+static void nuke_syms_in_range ( Addr start, SizeT length )
+{
+ /* Repeatedly scan the segInfo list, looking for segInfos in this
+ range, and call unload_symbols on the segInfo's stated start
+ point. This modifies the list, hence the multiple
+ iterations. */
+ Bool found;
+ SegInfo* curr;
+
+ while (True) {
+ found =3D False;
+
+ curr =3D segInfo_list;
+ while (True) {
+ if (curr =3D=3D NULL) break;
+ if (start+length-1 < curr->start || curr->start+curr->size-1 < =
start) {
+ /* no overlap */
+ } else {
+ found =3D True;
+ break;
+ }
+ curr =3D curr->next;
+ }
+
+ if (!found) break;
+ unload_symbols( curr->start, 1 );
+
+ }
+}
+
+void VG_(di_notify_mmap)( Addr a )
+{
+ NSegment* seg;
+ HChar* filename;
+ Bool ok;
+
+ seg =3D VG_(am_find_nsegment)(a);
+ vg_assert(seg);
+
+ filename =3D VG_(am_get_filename)( seg );
+ if (!filename)
+ return;
+
+ filename =3D VG_(arena_strdup)( VG_AR_SYMTAB, filename );
+
+ ok =3D (seg->kind =3D=3D SkFileC || (seg->kind =3D=3D SkFileV && is_s=
elf(filename)))
+ && seg->offset =3D=3D 0
+ && seg->fnIdx !=3D -1
+ && seg->hasR
+ && seg->hasX
+ && !seg->hasW
+ && VG_(is_object_file)( (const void*)seg->start );
+
+ if (!ok) {
+ VG_(arena_free)(VG_AR_SYMTAB, filename);
+ return;
+ }
+
+ nuke_syms_in_range( seg->start, seg->end + 1 - seg->start );
+ VG_(read_seg_symbols)( seg->start, seg->end + 1 - seg->start,=20
+ seg->offset, filename );
+
+ /* VG_(read_seg_symbols) makes its own copy of filename, so is safe
+ to free it. */
+ VG_(arena_free)(VG_AR_SYMTAB, filename);
+}
+
+void VG_(di_notify_munmap)( Addr a, SizeT len )
+{
+ nuke_syms_in_range(a, len);
+}
+
+void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot )
+{
+ if (!(prot & VKI_PROT_EXEC))
+ nuke_syms_in_range(a, len);
+}
+
+
+
+
+/*------------------------------------------------------------*/
/*--- ---*/
/*------------------------------------------------------------*/
=20
@@ -1261,7 +1381,7 @@
ElfXX_Ehdr* ehdr; /* The ELF header =
*/
ElfXX_Shdr* shdr; /* The section table =
*/
UChar* sh_strtab; /* The section table's string table =
*/
- SysRes fd;
+ SysRes fd, sres;
Int i;
Bool ok;
Addr oimage;
@@ -1272,7 +1392,8 @@
=20
oimage =3D (Addr)NULL;
if (VG_(clo_verbosity) > 1)
- VG_(message)(Vg_DebugMsg, "Reading syms from %s (%p)", si->filenam=
e, si->start );
+ VG_(message)(Vg_DebugMsg, "Reading syms from %s (%p)",=20
+ si->filename, si->start );
=20
/* mmap the object image aboard, so that we can read symbols and
line number info out of it. It will be munmapped immediately
@@ -1291,18 +1412,19 @@
return False;
}
=20
- oimage =3D (Addr)VG_(mmap)( NULL, n_oimage,=20
- VKI_PROT_READ, VKI_MAP_PRIVATE|VKI_MAP_NOSY=
MS,=20
- 0, fd.val, 0 );
+ sres =3D VG_(am_mmap_file_float_valgrind)
+ ( n_oimage, VKI_PROT_READ, fd.val, 0 );
=20
VG_(close)(fd.val);
=20
- if (oimage =3D=3D ((Addr)(-1))) {
+ if (sres.isError) {
VG_(message)(Vg_UserMsg, "warning: mmap failed on %s", si->filenam=
e );
VG_(message)(Vg_UserMsg, " no symbols or debug info loaded=
" );
return False;
}
=20
+ oimage =3D sres.val;
+
/* 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.
*/
@@ -1631,14 +1753,14 @@
res =3D True;
=20
out: {
- Int m_res;
+ SysRes m_res;
/* Last, but not least, heave the image(s) back overboard. */
if (dimage) {
- m_res =3D VG_(munmap) ( (void*)dimage, n_dimage );
- vg_assert(0 =3D=3D m_res);
+ m_res =3D VG_(am_munmap_valgrind) ( dimage, n_dimage );
+ vg_assert(!m_res.isError);
}
- m_res =3D VG_(munmap) ( (void*)oimage, n_oimage );
- vg_assert(0 =3D=3D m_res);
+ m_res =3D VG_(am_munmap_valgrind) ( oimage, n_oimage );
+ vg_assert(!m_res.isError);
return res;
}=20
}
Modified: branches/ASPACEM/coregrind/m_main.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
--- branches/ASPACEM/coregrind/m_main.c 2005-09-18 10:07:51 UTC (rev 4676=
)
+++ branches/ASPACEM/coregrind/m_main.c 2005-09-18 22:44:17 UTC (rev 4677=
)
@@ -2344,11 +2344,26 @@
}
=20
//=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
- // Finished setting up operating environment. Now initialise
- // Valgrind. (This is where the old VG_(main)() started.)
+ //
+ // Finished loading/setting up the client address space.
+ //
//=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
=20
//--------------------------------------------------------------
+ // Initialise translation table and translation cache
+ // p: aspacem
+ //--------------------------------------------------------------
+ VG_(debugLog)(1, "main", "Initialise TT/TC\n");
+ VG_(init_tt_tc)();
+
+ //--------------------------------------------------------------
+ // Initialise the redirect table.
+ // p: init_tt_tc [so it can call VG_(search_transtab) safely]
+ //--------------------------------------------------------------
+ VG_(debugLog)(1, "main", "Initialise redirects\n");
+ VG_(setup_code_redirect_table)();
+
+ //--------------------------------------------------------------
// setup file descriptors
// p: n/a
//--------------------------------------------------------------
@@ -2449,6 +2464,31 @@
}
=20
//--------------------------------------------------------------
+ // Load debug info for the existing segments.
+ // p: setup_code_redirect_table [so that redirs can be recorded]
+ // p: mallocfree
+ // p: probably: setup fds and process CLOs, so that logging works
+ //--------------------------------------------------------------
+ { Addr* seg_starts;
+ Int n_seg_starts;
+ /* find out how many spaces are needed */
+ VG_(am_get_segment_starts)( NULL, &n_seg_starts );
+ /* allocate */
+ seg_starts =3D VG_(malloc)( n_seg_starts * sizeof(Addr) );
+ vg_assert(seg_starts);
+ /* guard against race */
+ VG_(am_get_segment_starts)( NULL, &i );
+ vg_assert(n_seg_starts =3D=3D i);
+ /* acquire */
+ VG_(am_get_segment_starts)( seg_starts, &n_seg_starts );
+ /* show them all to the debug info reader */
+ for (i =3D 0; i < n_seg_starts; i++)
+ VG_(di_notify_mmap)( seg_starts[i] );
+ /* release */
+ VG_(free)( seg_starts );
+ }
+
+ //--------------------------------------------------------------
// Initialise the scheduler
// p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
//--------------------------------------------------------------
@@ -2508,23 +2548,6 @@
}
=20
//--------------------------------------------------------------
- // Initialise translation table and translation cache
- // p: read_procselfmaps [so the anonymous mmaps for the TT/TC
- // aren't identified as part of the client, which would waste
- // > 20M of virtual address space.]
- //--------------------------------------------------------------
- VG_(debugLog)(1, "main", "Initialise TT/TC\n");
- VG_(init_tt_tc)();
-
- //--------------------------------------------------------------
- // Initialise the redirect table.
- // p: parse_procselfmaps? [XXX for debug info?]
- // p: init_tt_tc [so it can call VG_(search_transtab) safely]
- //--------------------------------------------------------------
- VG_(debugLog)(1, "main", "Initialise redirects\n");
- VG_(setup_code_redirect_table)();
-
- //--------------------------------------------------------------
// Tell the tool about permissions in our handwritten assembly
// helpers.
// p: init tool [for 'new_mem_startup']
Modified: branches/ASPACEM/coregrind/m_syswrap/syswrap-generic.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
--- branches/ASPACEM/coregrind/m_syswrap/syswrap-generic.c 2005-09-18 10:=
07:51 UTC (rev 4676)
+++ branches/ASPACEM/coregrind/m_syswrap/syswrap-generic.c 2005-09-18 22:=
44:17 UTC (rev 4677)
@@ -4740,6 +4740,7 @@
page_align_addr_and_len(&a, &len);
VG_(am_notify_mprotect)(a, len, prot);
VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
+ VG_(di_notify_mprotect)( a, len, prot );
}
=20
PRE(sys_munmap)
@@ -4760,6 +4761,7 @@
page_align_addr_and_len(&a, &len);
VG_(am_notify_munmap)(a, len);
VG_TRACK( die_mem_munmap, a, len );
+ VG_(di_notify_munmap)( a, len );
}
=20
PRE(sys_mincore)
Modified: branches/ASPACEM/coregrind/m_syswrap/syswrap-x86-linux.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
--- branches/ASPACEM/coregrind/m_syswrap/syswrap-x86-linux.c 2005-09-18 1=
0:07:51 UTC (rev 4676)
+++ branches/ASPACEM/coregrind/m_syswrap/syswrap-x86-linux.c 2005-09-18 2=
2:44:17 UTC (rev 4677)
@@ -1539,6 +1539,8 @@
args[4-1], /* the original flags value */
a5, a6=20
);
+ /* Load symbols? */
+ VG_(di_notify_mmap)( (Addr)sres.val );
}
=20
/* Stay sane */
Modified: branches/ASPACEM/coregrind/pub_core_aspacemgr.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
--- branches/ASPACEM/coregrind/pub_core_aspacemgr.h 2005-09-18 10:07:51 U=
TC (rev 4676)
+++ branches/ASPACEM/coregrind/pub_core_aspacemgr.h 2005-09-18 22:44:17 U=
TC (rev 4677)
@@ -281,7 +281,23 @@
/* Show the segment array on the debug log, at given loglevel. */
extern void VG_(am_show_nsegments) ( Int logLevel, HChar* who );
=20
+/* Get the filename corresponding to this segment, if known and if it
+ has one. The returned name's storage cannot be assumed to be
+ persistent, so the caller should immediately copy the name
+ elsewhere. */
+extern HChar* VG_(am_get_filename)( NSegment* );
=20
+/* Collect up the start addresses of all non-free, non-resvn segments.
+ The interface is a bit strange. You have to call it twice. If
+ 'starts' is NULL, the number of such segments is calculated and
+ written to *nStarts. If 'starts' is non-NULL, it should point to
+ an array of size *nStarts, and the segment start addresses are
+ written at starts[0 .. *nStarts-1]. In the latter case, the number
+ of required slots is recalculated, and the function asserts if this
+ is not equal to *nStarts. */
+extern void VG_(am_get_segment_starts)( Addr* starts, Int* nStarts );
+
+
//--------------------------------------------------------------
// Functions pertaining to the central query-notify mechanism
// used to handle mmap/munmap/mprotect resulting from client
@@ -370,11 +386,21 @@
itself more address space when needed. */
extern SysRes VG_(am_mmap_anon_float_valgrind)( SizeT cszB );
=20
-/* Unmap the given address range an update the segment array
+/* Map a file at an unconstrained address for V, and update the
+ segment array accordingly. This is used by V for transiently
+ mapping in object files to read their debug info. */
+extern SysRes VG_(am_mmap_file_float_valgrind)
+ ( SizeT length, UInt prot, Int fd, SizeT offset );
+
+/* Unmap the given address range and update the segment array
accordingly. This fails if the range isn't valid for the
client. */
extern SysRes VG_(am_munmap_client)( Addr start, SizeT length );
=20
+/* Unmap the given address range and update the segment array
+ accordingly. This fails if the range isn't valid for valgrind. */
+extern SysRes VG_(am_munmap_valgrind)( Addr start, SizeT length );
+
/* --- --- --- reservations --- --- --- */
=20
/* Create a reservation from START .. START+LENGTH-1, with the given
Modified: branches/ASPACEM/coregrind/pub_core_debuginfo.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
--- branches/ASPACEM/coregrind/pub_core_debuginfo.h 2005-09-18 10:07:51 U=
TC (rev 4676)
+++ branches/ASPACEM/coregrind/pub_core_debuginfo.h 2005-09-18 22:44:17 U=
TC (rev 4677)
@@ -41,6 +41,10 @@
=20
#include "pub_tool_debuginfo.h"
=20
+extern void VG_(di_notify_mmap)( Addr a );
+extern void VG_(di_notify_munmap)( Addr a, SizeT len );
+extern void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot );
+
extern Bool VG_(is_object_file) ( const void *hdr );
extern SegInfo *VG_(read_seg_symbols) ( Addr addr, SizeT len,
OffT offset, const Char* filenam=
e);
|
|
From: Nicholas N. <nj...@cs...> - 2005-09-19 04:52:29
|
On Sun, 18 Sep 2005, sv...@va... wrote:
> + if (sres.val != advised) {
> + /* I don't think this can happen. It means the kernel made a
> + fixed map succeed but not at the requested location. Try to
> + repair the damage, then return saying the mapping failed. */
> + (void)do_munmap_NO_NOTIFY( sres.val, length );
> + return VG_(mk_SysRes_Error)( VKI_EINVAL );
> + }
I think we've seen a buggy kernel do that before.
Nick
|
|
From: Julian S. <js...@ac...> - 2005-09-19 09:22:53
|
On Monday 19 September 2005 05:52, Nicholas Nethercote wrote:
> On Sun, 18 Sep 2005, sv...@va... wrote:
> > + if (sres.val != advised) {
> > + /* I don't think this can happen. It means the kernel made a
> > + fixed map succeed but not at the requested location. Try to
> > + repair the damage, then return saying the mapping failed. */
> > + (void)do_munmap_NO_NOTIFY( sres.val, length );
> > + return VG_(mk_SysRes_Error)( VKI_EINVAL );
> > + }
>
> I think we've seen a buggy kernel do that before.
I was thinking that we should have a standard function to
call, perhaps VG_(kernel_bug)( HChar* what, Bool fatal ) to call
whenever the kernel doesn't behave the way we expect, as a
centralised uniform way of reporting such behaviour.
J
|