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