mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
Privatise parse_procselfmaps() and move it into aspacemgr.c in order
to benefit from the module-cycle-breaking functions in aspacemgr.c. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4805
This commit is contained in:
parent
c3d915e97b
commit
a03a1fa3bd
@ -124,10 +124,17 @@ static Addr aspacem_vStart = 0;
|
||||
|
||||
/* ------ end of STATE for the address-space manager ------ */
|
||||
|
||||
// Forwards decls
|
||||
static void aspacem_exit ( Int );
|
||||
/* ------ Forwards decls ------ */
|
||||
static void aspacem_exit ( Int );
|
||||
static Int find_nsegment_idx ( Addr a );
|
||||
|
||||
static void parse_procselfmaps (
|
||||
void (*record_mapping)( Addr addr, SizeT len, UInt prot,
|
||||
UInt dev, UInt ino, ULong offset,
|
||||
const UChar* filename ),
|
||||
void (*record_gap)( Addr addr, SizeT len )
|
||||
);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
/*--- ---*/
|
||||
@ -308,6 +315,23 @@ static void aspacem_exit( Int status )
|
||||
aspacem_assert(2+2 == 5);
|
||||
}
|
||||
|
||||
static SysRes aspacem_open ( const Char* pathname, Int flags, Int mode )
|
||||
{
|
||||
SysRes res = VG_(do_syscall3)(__NR_open, (UWord)pathname, flags, mode);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aspacem_close ( Int fd )
|
||||
{
|
||||
(void)VG_(do_syscall1)(__NR_close, fd);
|
||||
}
|
||||
|
||||
static Int aspacem_read ( Int fd, void* buf, Int count)
|
||||
{
|
||||
SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
|
||||
return res.isError ? -1 : res.val;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Functions for extracting information about file descriptors.
|
||||
@ -982,8 +1006,8 @@ Bool VG_(am_do_sync_check) ( const HChar* fn,
|
||||
sync_check_ok = True;
|
||||
if (0)
|
||||
VG_(debugLog)(0,"aspacem", "do_sync_check %s:%d\n", file,line);
|
||||
VG_(parse_procselfmaps)( sync_check_mapping_callback,
|
||||
sync_check_gap_callback );
|
||||
parse_procselfmaps( sync_check_mapping_callback,
|
||||
sync_check_gap_callback );
|
||||
if (!sync_check_ok) {
|
||||
VG_(debugLog)(0,"aspacem",
|
||||
"sync check at %s:%d (%s): FAILED\n",
|
||||
@ -1503,7 +1527,7 @@ Addr VG_(am_startup) ( Addr sp_at_startup )
|
||||
VG_(am_show_nsegments)(2, "Initial layout");
|
||||
|
||||
VG_(debugLog)(2, "aspacem", "Reading /proc/self/maps\n");
|
||||
VG_(parse_procselfmaps) ( read_maps_callback, NULL );
|
||||
parse_procselfmaps( read_maps_callback, NULL );
|
||||
|
||||
VG_(am_show_nsegments)(2, "With contents of /proc/self/maps");
|
||||
|
||||
@ -2710,6 +2734,264 @@ Int VG_(am_get_VgStack_unused_szB)( VgStack* stack )
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
/*--- ---*/
|
||||
/*--- A simple parser for /proc/self/maps on Linux 2.4.X/2.6.X. ---*/
|
||||
/*--- Almost completely independent of the stuff above. The ---*/
|
||||
/*--- only function it 'exports' to the code above this comment ---*/
|
||||
/*--- is parse_procselfmaps. ---*/
|
||||
/*--- ---*/
|
||||
/*-----------------------------------------------------------------*/
|
||||
|
||||
/* Size of a smallish table used to read /proc/self/map entries. */
|
||||
#define M_PROCMAP_BUF 100000
|
||||
|
||||
/* static ... to keep it out of the stack frame. */
|
||||
static Char procmap_buf[M_PROCMAP_BUF];
|
||||
|
||||
/* Records length of /proc/self/maps read into procmap_buf. */
|
||||
static Int buf_n_tot;
|
||||
|
||||
/* Helper fns. */
|
||||
|
||||
static Int hexdigit ( Char c )
|
||||
{
|
||||
if (c >= '0' && c <= '9') return (Int)(c - '0');
|
||||
if (c >= 'a' && c <= 'f') return 10 + (Int)(c - 'a');
|
||||
if (c >= 'A' && c <= 'F') return 10 + (Int)(c - 'A');
|
||||
return -1;
|
||||
}
|
||||
|
||||
static Int decdigit ( Char c )
|
||||
{
|
||||
if (c >= '0' && c <= '9') return (Int)(c - '0');
|
||||
return -1;
|
||||
}
|
||||
|
||||
static Int readchar ( const Char* buf, Char* ch )
|
||||
{
|
||||
if (*buf == 0) return 0;
|
||||
*ch = *buf;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Int readhex ( const Char* buf, UWord* val )
|
||||
{
|
||||
Int n = 0;
|
||||
*val = 0;
|
||||
while (hexdigit(*buf) >= 0) {
|
||||
*val = (*val << 4) + hexdigit(*buf);
|
||||
n++; buf++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static Int readdec ( const Char* buf, UInt* val )
|
||||
{
|
||||
Int n = 0;
|
||||
*val = 0;
|
||||
while (hexdigit(*buf) >= 0) {
|
||||
*val = (*val * 10) + decdigit(*buf);
|
||||
n++; buf++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/* Get the contents of /proc/self/maps into a static buffer. If
|
||||
there's a syntax error, it won't fit, or other failure, just
|
||||
abort. */
|
||||
|
||||
static void read_procselfmaps_into_buf ( void )
|
||||
{
|
||||
Int n_chunk;
|
||||
SysRes fd;
|
||||
|
||||
/* Read the initial memory mapping from the /proc filesystem. */
|
||||
fd = aspacem_open( "/proc/self/maps", VKI_O_RDONLY, 0 );
|
||||
if (fd.isError)
|
||||
aspacem_barf("can't open /proc/self/maps");
|
||||
|
||||
buf_n_tot = 0;
|
||||
do {
|
||||
n_chunk = aspacem_read( fd.val, &procmap_buf[buf_n_tot],
|
||||
M_PROCMAP_BUF - buf_n_tot );
|
||||
buf_n_tot += n_chunk;
|
||||
} while ( n_chunk > 0 && buf_n_tot < M_PROCMAP_BUF );
|
||||
|
||||
aspacem_close(fd.val);
|
||||
|
||||
if (buf_n_tot >= M_PROCMAP_BUF-5)
|
||||
aspacem_barf_toolow("M_PROCMAP_BUF");
|
||||
if (buf_n_tot == 0)
|
||||
aspacem_barf("I/O error on /proc/self/maps");
|
||||
|
||||
procmap_buf[buf_n_tot] = 0;
|
||||
}
|
||||
|
||||
/* Parse /proc/self/maps. For each map entry, call
|
||||
record_mapping, passing it, in this order:
|
||||
|
||||
start address in memory
|
||||
length
|
||||
page protections (using the VKI_PROT_* flags)
|
||||
mapped file device and inode
|
||||
offset in file, or zero if no file
|
||||
filename, zero terminated, or NULL if no file
|
||||
|
||||
So the sig of the called fn might be
|
||||
|
||||
void (*record_mapping)( Addr start, SizeT size, UInt prot,
|
||||
UInt dev, UInt info,
|
||||
ULong foffset, UChar* filename )
|
||||
|
||||
Note that the supplied filename is transiently stored; record_mapping
|
||||
should make a copy if it wants to keep it.
|
||||
|
||||
Nb: it is important that this function does not alter the contents of
|
||||
procmap_buf!
|
||||
*/
|
||||
static void parse_procselfmaps (
|
||||
void (*record_mapping)( Addr addr, SizeT len, UInt prot,
|
||||
UInt dev, UInt ino, ULong offset,
|
||||
const UChar* filename ),
|
||||
void (*record_gap)( Addr addr, SizeT len )
|
||||
)
|
||||
{
|
||||
Int i, j, i_eol;
|
||||
Addr start, endPlusOne, gapStart;
|
||||
UChar* filename;
|
||||
UChar rr, ww, xx, pp, ch, tmp;
|
||||
UInt ino, prot;
|
||||
UWord foffset, maj, min;
|
||||
|
||||
read_procselfmaps_into_buf();
|
||||
|
||||
aspacem_assert('\0' != procmap_buf[0] && 0 != buf_n_tot);
|
||||
|
||||
if (0)
|
||||
VG_(debugLog)(0, "procselfmaps", "raw:\n%s\n", procmap_buf);
|
||||
|
||||
/* Ok, it's safely aboard. Parse the entries. */
|
||||
i = 0;
|
||||
gapStart = Addr_MIN;
|
||||
while (True) {
|
||||
if (i >= buf_n_tot) break;
|
||||
|
||||
/* Read (without fscanf :) the pattern %16x-%16x %c%c%c%c %16x %2x:%2x %d */
|
||||
j = readhex(&procmap_buf[i], &start);
|
||||
if (j > 0) i += j; else goto syntaxerror;
|
||||
j = readchar(&procmap_buf[i], &ch);
|
||||
if (j == 1 && ch == '-') i += j; else goto syntaxerror;
|
||||
j = readhex(&procmap_buf[i], &endPlusOne);
|
||||
if (j > 0) i += j; else goto syntaxerror;
|
||||
|
||||
j = readchar(&procmap_buf[i], &ch);
|
||||
if (j == 1 && ch == ' ') i += j; else goto syntaxerror;
|
||||
|
||||
j = readchar(&procmap_buf[i], &rr);
|
||||
if (j == 1 && (rr == 'r' || rr == '-')) i += j; else goto syntaxerror;
|
||||
j = readchar(&procmap_buf[i], &ww);
|
||||
if (j == 1 && (ww == 'w' || ww == '-')) i += j; else goto syntaxerror;
|
||||
j = readchar(&procmap_buf[i], &xx);
|
||||
if (j == 1 && (xx == 'x' || xx == '-')) i += j; else goto syntaxerror;
|
||||
/* This field is the shared/private flag */
|
||||
j = readchar(&procmap_buf[i], &pp);
|
||||
if (j == 1 && (pp == 'p' || pp == '-' || pp == 's'))
|
||||
i += j; else goto syntaxerror;
|
||||
|
||||
j = readchar(&procmap_buf[i], &ch);
|
||||
if (j == 1 && ch == ' ') i += j; else goto syntaxerror;
|
||||
|
||||
j = readhex(&procmap_buf[i], &foffset);
|
||||
if (j > 0) i += j; else goto syntaxerror;
|
||||
|
||||
j = readchar(&procmap_buf[i], &ch);
|
||||
if (j == 1 && ch == ' ') i += j; else goto syntaxerror;
|
||||
|
||||
j = readhex(&procmap_buf[i], &maj);
|
||||
if (j > 0) i += j; else goto syntaxerror;
|
||||
j = readchar(&procmap_buf[i], &ch);
|
||||
if (j == 1 && ch == ':') i += j; else goto syntaxerror;
|
||||
j = readhex(&procmap_buf[i], &min);
|
||||
if (j > 0) i += j; else goto syntaxerror;
|
||||
|
||||
j = readchar(&procmap_buf[i], &ch);
|
||||
if (j == 1 && ch == ' ') i += j; else goto syntaxerror;
|
||||
|
||||
j = readdec(&procmap_buf[i], &ino);
|
||||
if (j > 0) i += j; else goto syntaxerror;
|
||||
|
||||
goto read_line_ok;
|
||||
|
||||
syntaxerror:
|
||||
VG_(debugLog)(0, "Valgrind:",
|
||||
"FATAL: syntax error reading /proc/self/maps\n");
|
||||
{ Int k, m;
|
||||
HChar buf50[51];
|
||||
m = 0;
|
||||
buf50[m] = 0;
|
||||
k = i - 50;
|
||||
if (k < 0) k = 0;
|
||||
for (; k <= i; k++) {
|
||||
buf50[m] = procmap_buf[k];
|
||||
buf50[m+1] = 0;
|
||||
if (m < 50-1) m++;
|
||||
}
|
||||
VG_(debugLog)(0, "procselfmaps", "Last 50 chars: '%s'\n", buf50);
|
||||
}
|
||||
aspacem_exit(1);
|
||||
|
||||
read_line_ok:
|
||||
|
||||
/* Try and find the name of the file mapped to this segment, if
|
||||
it exists. Note that files can contains spaces. */
|
||||
|
||||
// Move i to the next non-space char, which should be either a '/' or
|
||||
// a newline.
|
||||
while (procmap_buf[i] == ' ' && i < buf_n_tot-1) i++;
|
||||
|
||||
// Move i_eol to the end of the line.
|
||||
i_eol = i;
|
||||
while (procmap_buf[i_eol] != '\n' && i_eol < buf_n_tot-1) i_eol++;
|
||||
|
||||
// If there's a filename...
|
||||
if (i < i_eol-1 && procmap_buf[i] == '/') {
|
||||
/* Minor hack: put a '\0' at the filename end for the call to
|
||||
'record_mapping', then restore the old char with 'tmp'. */
|
||||
filename = &procmap_buf[i];
|
||||
tmp = filename[i_eol - i];
|
||||
filename[i_eol - i] = '\0';
|
||||
} else {
|
||||
tmp = 0;
|
||||
filename = NULL;
|
||||
foffset = 0;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
if (rr == 'r') prot |= VKI_PROT_READ;
|
||||
if (ww == 'w') prot |= VKI_PROT_WRITE;
|
||||
if (xx == 'x') prot |= VKI_PROT_EXEC;
|
||||
|
||||
if (record_gap && gapStart < start)
|
||||
(*record_gap) ( gapStart, start-gapStart );
|
||||
|
||||
(*record_mapping) ( start, endPlusOne-start,
|
||||
prot, maj * 256 + min, ino,
|
||||
foffset, filename );
|
||||
|
||||
if ('\0' != tmp) {
|
||||
filename[i_eol - i] = tmp;
|
||||
}
|
||||
|
||||
i = i_eol + 1;
|
||||
gapStart = endPlusOne;
|
||||
}
|
||||
|
||||
if (record_gap && gapStart < Addr_MAX)
|
||||
(*record_gap) ( gapStart, Addr_MAX - gapStart + 1 );
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/*--- end ---*/
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
||||
@ -29,265 +29,8 @@
|
||||
The GNU General Public License is contained in the file COPYING.
|
||||
*/
|
||||
|
||||
#include "pub_core_basics.h"
|
||||
#include "pub_core_debuglog.h"
|
||||
#include "pub_core_aspacemgr.h"
|
||||
#include "pub_core_libcassert.h"
|
||||
#include "pub_core_libcfile.h"
|
||||
|
||||
/* Size of a smallish table used to read /proc/self/map entries. */
|
||||
#define M_PROCMAP_BUF 50000
|
||||
|
||||
/* static ... to keep it out of the stack frame. */
|
||||
static Char procmap_buf[M_PROCMAP_BUF];
|
||||
|
||||
/* Records length of /proc/self/maps read into procmap_buf. */
|
||||
static Int buf_n_tot;
|
||||
|
||||
/* Minimum and maximum addresses */
|
||||
#define Addr_MIN ((Addr)0)
|
||||
#define Addr_MAX ((Addr)(-1ULL))
|
||||
|
||||
/* Helper fns. */
|
||||
|
||||
static Int hexdigit ( Char c )
|
||||
{
|
||||
if (c >= '0' && c <= '9') return (Int)(c - '0');
|
||||
if (c >= 'a' && c <= 'f') return 10 + (Int)(c - 'a');
|
||||
if (c >= 'A' && c <= 'F') return 10 + (Int)(c - 'A');
|
||||
return -1;
|
||||
}
|
||||
|
||||
static Int decdigit ( Char c )
|
||||
{
|
||||
if (c >= '0' && c <= '9') return (Int)(c - '0');
|
||||
return -1;
|
||||
}
|
||||
|
||||
static Int readchar ( const Char* buf, Char* ch )
|
||||
{
|
||||
if (*buf == 0) return 0;
|
||||
*ch = *buf;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Int readhex ( const Char* buf, UWord* val )
|
||||
{
|
||||
Int n = 0;
|
||||
*val = 0;
|
||||
while (hexdigit(*buf) >= 0) {
|
||||
*val = (*val << 4) + hexdigit(*buf);
|
||||
n++; buf++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static Int readdec ( const Char* buf, UInt* val )
|
||||
{
|
||||
Int n = 0;
|
||||
*val = 0;
|
||||
while (hexdigit(*buf) >= 0) {
|
||||
*val = (*val * 10) + decdigit(*buf);
|
||||
n++; buf++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/* Read /proc/self/maps, store the contents into a static buffer. If
|
||||
there's a syntax error or other failure, just abort. */
|
||||
|
||||
static void read_procselfmaps ( void )
|
||||
{
|
||||
Int n_chunk;
|
||||
SysRes fd;
|
||||
|
||||
/* Read the initial memory mapping from the /proc filesystem. */
|
||||
fd = VG_(open) ( "/proc/self/maps", VKI_O_RDONLY, 0 );
|
||||
if (fd.isError) {
|
||||
VG_(debugLog)(0, "Valgrind:", "FATAL: can't open /proc/self/maps\n");
|
||||
VG_(exit)(1);
|
||||
}
|
||||
buf_n_tot = 0;
|
||||
do {
|
||||
n_chunk = VG_(read) ( fd.val, &procmap_buf[buf_n_tot],
|
||||
M_PROCMAP_BUF - buf_n_tot );
|
||||
buf_n_tot += n_chunk;
|
||||
} while ( n_chunk > 0 && buf_n_tot < M_PROCMAP_BUF );
|
||||
VG_(close)(fd.val);
|
||||
if (buf_n_tot >= M_PROCMAP_BUF-5) {
|
||||
VG_(debugLog)(0, "Valgrind:", "FATAL: M_PROCMAP_BUF is too small;\n");
|
||||
VG_(debugLog)(0, "Valgrind:", " increase it and recompile.\n");
|
||||
VG_(exit)(1);
|
||||
}
|
||||
if (buf_n_tot == 0) {
|
||||
VG_(debugLog)(0, "Valgrind:", "FATAL: I/O error on /proc/self/maps\n");
|
||||
VG_(exit)(1);
|
||||
}
|
||||
procmap_buf[buf_n_tot] = 0;
|
||||
}
|
||||
|
||||
/* Parse /proc/self/maps. For each map entry, call
|
||||
record_mapping, passing it, in this order:
|
||||
|
||||
start address in memory
|
||||
length
|
||||
page protections (using the VKI_PROT_* flags)
|
||||
mapped file device and inode
|
||||
offset in file, or zero if no file
|
||||
filename, zero terminated, or NULL if no file
|
||||
|
||||
So the sig of the called fn might be
|
||||
|
||||
void (*record_mapping)( Addr start, SizeT size, UInt prot,
|
||||
UInt dev, UInt info,
|
||||
ULong foffset, UChar* filename )
|
||||
|
||||
Note that the supplied filename is transiently stored; record_mapping
|
||||
should make a copy if it wants to keep it.
|
||||
|
||||
Nb: it is important that this function does not alter the contents of
|
||||
procmap_buf!
|
||||
*/
|
||||
void VG_(parse_procselfmaps) (
|
||||
void (*record_mapping)( Addr addr, SizeT len, UInt prot,
|
||||
UInt dev, UInt ino, ULong foff, const UChar* filename ),
|
||||
void (*record_gap)( Addr addr, SizeT len )
|
||||
)
|
||||
{
|
||||
Int i, j, i_eol;
|
||||
Addr start, endPlusOne, gapStart;
|
||||
UChar* filename;
|
||||
UChar rr, ww, xx, pp, ch, tmp;
|
||||
UInt ino, prot;
|
||||
UWord foffset, maj, min;
|
||||
|
||||
read_procselfmaps();
|
||||
|
||||
tl_assert( '\0' != procmap_buf[0] && 0 != buf_n_tot);
|
||||
|
||||
if (0)
|
||||
VG_(debugLog)(0, "procselfmaps", "raw:\n%s\n", procmap_buf);
|
||||
|
||||
/* Ok, it's safely aboard. Parse the entries. */
|
||||
i = 0;
|
||||
gapStart = Addr_MIN;
|
||||
while (True) {
|
||||
if (i >= buf_n_tot) break;
|
||||
|
||||
/* Read (without fscanf :) the pattern %16x-%16x %c%c%c%c %16x %2x:%2x %d */
|
||||
j = readhex(&procmap_buf[i], &start);
|
||||
if (j > 0) i += j; else goto syntaxerror;
|
||||
j = readchar(&procmap_buf[i], &ch);
|
||||
if (j == 1 && ch == '-') i += j; else goto syntaxerror;
|
||||
j = readhex(&procmap_buf[i], &endPlusOne);
|
||||
if (j > 0) i += j; else goto syntaxerror;
|
||||
|
||||
j = readchar(&procmap_buf[i], &ch);
|
||||
if (j == 1 && ch == ' ') i += j; else goto syntaxerror;
|
||||
|
||||
j = readchar(&procmap_buf[i], &rr);
|
||||
if (j == 1 && (rr == 'r' || rr == '-')) i += j; else goto syntaxerror;
|
||||
j = readchar(&procmap_buf[i], &ww);
|
||||
if (j == 1 && (ww == 'w' || ww == '-')) i += j; else goto syntaxerror;
|
||||
j = readchar(&procmap_buf[i], &xx);
|
||||
if (j == 1 && (xx == 'x' || xx == '-')) i += j; else goto syntaxerror;
|
||||
/* This field is the shared/private flag */
|
||||
j = readchar(&procmap_buf[i], &pp);
|
||||
if (j == 1 && (pp == 'p' || pp == '-' || pp == 's'))
|
||||
i += j; else goto syntaxerror;
|
||||
|
||||
j = readchar(&procmap_buf[i], &ch);
|
||||
if (j == 1 && ch == ' ') i += j; else goto syntaxerror;
|
||||
|
||||
j = readhex(&procmap_buf[i], &foffset);
|
||||
if (j > 0) i += j; else goto syntaxerror;
|
||||
|
||||
j = readchar(&procmap_buf[i], &ch);
|
||||
if (j == 1 && ch == ' ') i += j; else goto syntaxerror;
|
||||
|
||||
j = readhex(&procmap_buf[i], &maj);
|
||||
if (j > 0) i += j; else goto syntaxerror;
|
||||
j = readchar(&procmap_buf[i], &ch);
|
||||
if (j == 1 && ch == ':') i += j; else goto syntaxerror;
|
||||
j = readhex(&procmap_buf[i], &min);
|
||||
if (j > 0) i += j; else goto syntaxerror;
|
||||
|
||||
j = readchar(&procmap_buf[i], &ch);
|
||||
if (j == 1 && ch == ' ') i += j; else goto syntaxerror;
|
||||
|
||||
j = readdec(&procmap_buf[i], &ino);
|
||||
if (j > 0) i += j; else goto syntaxerror;
|
||||
|
||||
goto read_line_ok;
|
||||
|
||||
syntaxerror:
|
||||
VG_(debugLog)(0, "Valgrind:",
|
||||
"FATAL: syntax error reading /proc/self/maps\n");
|
||||
{ Int k, m;
|
||||
HChar buf50[51];
|
||||
m = 0;
|
||||
buf50[m] = 0;
|
||||
k = i - 50;
|
||||
if (k < 0) k = 0;
|
||||
for (; k <= i; k++) {
|
||||
buf50[m] = procmap_buf[k];
|
||||
buf50[m+1] = 0;
|
||||
if (m < 50-1) m++;
|
||||
}
|
||||
VG_(debugLog)(0, "procselfmaps", "Last 50 chars: '%s'\n", buf50);
|
||||
}
|
||||
VG_(exit)(1);
|
||||
|
||||
read_line_ok:
|
||||
|
||||
/* Try and find the name of the file mapped to this segment, if
|
||||
it exists. Note that files can contains spaces. */
|
||||
|
||||
// Move i to the next non-space char, which should be either a '/' or
|
||||
// a newline.
|
||||
while (procmap_buf[i] == ' ' && i < buf_n_tot-1) i++;
|
||||
|
||||
// Move i_eol to the end of the line.
|
||||
i_eol = i;
|
||||
while (procmap_buf[i_eol] != '\n' && i_eol < buf_n_tot-1) i_eol++;
|
||||
|
||||
// If there's a filename...
|
||||
if (i < i_eol-1 && procmap_buf[i] == '/') {
|
||||
/* Minor hack: put a '\0' at the filename end for the call to
|
||||
'record_mapping', then restore the old char with 'tmp'. */
|
||||
filename = &procmap_buf[i];
|
||||
tmp = filename[i_eol - i];
|
||||
filename[i_eol - i] = '\0';
|
||||
} else {
|
||||
tmp = 0;
|
||||
filename = NULL;
|
||||
foffset = 0;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
if (rr == 'r') prot |= VKI_PROT_READ;
|
||||
if (ww == 'w') prot |= VKI_PROT_WRITE;
|
||||
if (xx == 'x') prot |= VKI_PROT_EXEC;
|
||||
|
||||
if (record_gap && gapStart < start)
|
||||
(*record_gap) ( gapStart, start-gapStart );
|
||||
|
||||
(*record_mapping) ( start, endPlusOne-start,
|
||||
prot, maj * 256 + min, ino,
|
||||
foffset, filename );
|
||||
|
||||
if ('\0' != tmp) {
|
||||
filename[i_eol - i] = tmp;
|
||||
}
|
||||
|
||||
i = i_eol + 1;
|
||||
gapStart = endPlusOne;
|
||||
}
|
||||
|
||||
if (record_gap && gapStart < Addr_MAX)
|
||||
(*record_gap) ( gapStart, Addr_MAX - gapStart + 1 );
|
||||
}
|
||||
/* Contents of this file were folded into aspacemgr.c on 28 Sept
|
||||
05. */
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/*--- end read_procselfmaps.c ---*/
|
||||
|
||||
@ -41,14 +41,6 @@
|
||||
|
||||
#include "pub_tool_aspacemgr.h"
|
||||
|
||||
/* Parses /proc/self/maps, calling `record_mapping' for each entry. */
|
||||
extern
|
||||
void VG_(parse_procselfmaps) (
|
||||
void (*record_mapping)( Addr addr, SizeT len, UInt prot,
|
||||
UInt dev, UInt ino, ULong foff,
|
||||
const UChar *filename ),
|
||||
void (*record_gap)( Addr addr, SizeT len ) );
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Definition of address-space segments
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user