Import Upstream version 20180207
[hcoop/debian/mlton.git] / runtime / platform / aix.c
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 }