1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
#include "platform.h"
#include <sys/mman.h>
#include <sys/procfs.h>
#include <sys/vminfo.h>
#include "diskBack.unix.c"
#include "mmap-protect.c"
#include "nonwin.c"
#include "recv.nonblock.c"
#include "use-mmap.c"
size_t GC_pageSize (void) {
long pageSize;
pageSize = sysconf (_SC_PAGESIZE);
if (pageSize < 0)
diee ("GC_pageSize error: sysconf (_SC_PAGESIZE) failed");
return (size_t)pageSize;
}
/* We cannot use _SC_PHYS_PAGES from sysconf.c. It fails on some
versions of AIX. */
uintmax_t GC_physMem (void) {
struct vminfo vminfo;
uintmax_t physMem;
if (vmgetinfo (&vminfo, VMINFO, sizeof (vminfo)) < 0)
diee ("GC_physMem error: vmgetinfo failed");
physMem = (uintmax_t)vminfo.memsizepgs * (uintmax_t)4096;
return physMem;
}
struct map_type {
int flag;
const char *type;
};
static struct map_type map_types[] =
{{MA_MAINEXEC, "main"},
{MA_KERNTEXT, "kern"},
{MA_SHARED, "shared"},
{MA_STACK, "stack"},
{0, NULL}};
struct map_segment {
prptr64_t start;
prptr64_t end;
const char *name;
};
static struct map_segment map_segments[] =
{{(prptr64_t)0x00000000, (prptr64_t)0x0fffffff, "kernel"},
/* Application program text. */
{(prptr64_t)0x10000000, (prptr64_t)0x1fffffff, "text"},
/* Application program data and the application stack. */
{(prptr64_t)0x20000000, (prptr64_t)0x2fffffff, "data"},
/* Available for use by shared memory or mmap services. */
{(prptr64_t)0x30000000, (prptr64_t)0xafffffff, "mmap"},
/* Shared library text. */
{(prptr64_t)0xd0000000, (prptr64_t)0xdfffffff, "shtext"},
/* Miscellaneous kernel data. */
{(prptr64_t)0xe0000000, (prptr64_t)0xefffffff, "kdata"},
/* Application shared library data. */
{(prptr64_t)0xf0000000, (prptr64_t)0xffffffff, "shdata"},
{0, 0, NULL}};
static const char *
get_map_type (int flags, prptr64_t addr)
{
struct map_type *m;
for (m = map_types; m->flag; m++)
if (m->flag & flags)
return m->type;
if ((addr >= (prptr64_t)0xd0000000 && addr <= (prptr64_t)0xdfffffff)
|| (addr >= (prptr64_t)0xf0000000 && addr <= (prptr64_t)0xffffffff))
return "shlib";
return "";
}
static const char *
get_map_segment (prptr64_t addr)
{
struct map_segment *m;
for (m = map_segments; m->name; m++)
if (m->start <= addr && m->end >= addr)
return m->name;
return "";
}
#define BUFLEN 65536
void GC_displayMem (void)
{
pid_t pid = getpid ();
char fname[128];
int fd = 0;
char *buf;
struct prmap *map;
printf ("va_start va_end perm type segment file (member) [object]\n");
printf ("--------+--------+---+------+------+----------------------\n");
snprintf (fname, sizeof (fname), "/proc/%d/map", pid);
fd = open (fname, O_RDONLY);
if (fd == -1)
diee ("showMem error: opening %s failed", fname);
/* I couldn't figure out a way to get the size of the map file
beforehand (only open, read, write, and close work on files under
/proc), so let's just hope that 64k will be enough. */
buf = malloc (BUFLEN);
if (buf == NULL)
die ("showMem error: out of memory.");
read (fd, buf, BUFLEN);
map = (struct prmap*)buf;
for (map = (struct prmap*)buf; map->pr_size; map++) {
char *m = buf + map->pr_pathoff;
m += strlen (m) + 1;
if (!m[0])
m = NULL;
printf ("%08llx %08llx %s%s%s %-6s %-6s %s %s%s%s[%s]\n",
map->pr_vaddr, map->pr_vaddr + map->pr_size,
map->pr_mflags & MA_READ ? "r" : "-",
map->pr_mflags & MA_WRITE ? "w" : "-",
map->pr_mflags & MA_EXEC ? "x" : "-",
get_map_type (map->pr_mflags, map->pr_vaddr),
get_map_segment (map->pr_vaddr),
buf + map->pr_pathoff,
m ? "(" : "", m ? m : "", m ? ") " : "",
map->pr_mapname);
}
}
|