File: aix.c

package info (click to toggle)
mlton 20130715-3
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 60,900 kB
  • ctags: 69,386
  • sloc: xml: 34,418; ansic: 17,399; lisp: 2,879; makefile: 1,605; sh: 1,254; pascal: 256; python: 143; asm: 97
file content (142 lines) | stat: -rw-r--r-- 4,450 bytes parent folder | download
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);
        }
}