annotate lib/vma-iter.c @ 17480:f40b3156a43e

selinux-at: omit unnecessary include * lib/selinux-at.c: Don't include dosname.h; not needed, since this source file doesn't use its macros, and subsidiary files that use the macros already include it.
author Paul Eggert <eggert@cs.ucla.edu>
date Fri, 23 Aug 2013 13:53:46 -0700
parents e542fd46ad6f
children 344018b6e5d7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
14220
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Iteration over virtual memory areas.
17249
e542fd46ad6f maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents: 16935
diff changeset
2 Copyright (C) 2011-2013 Free Software Foundation, Inc.
14220
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3 Written by Bruno Haible <bruno@clisp.org>, 2011.
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 This program is free software: you can redistribute it and/or modify
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 the Free Software Foundation; either version 3 of the License, or
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 (at your option) any later version.
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 GNU General Public License for more details.
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18 #include <config.h>
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 /* Specification. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 #include "vma-iter.h"
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 #include <errno.h> /* errno */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 #include <stdlib.h> /* size_t */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #include <fcntl.h> /* open, O_RDONLY */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26 #include <unistd.h> /* getpagesize, read, close */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 #if defined __sgi || defined __osf__ /* IRIX, OSF/1 */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 # include <string.h> /* memcpy */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30 # include <sys/types.h>
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 # include <sys/mman.h> /* mmap, munmap */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 # include <sys/procfs.h> /* PIOC*, prmap_t */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 #endif
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34
16935
498a2211d839 Write "Mac OS X" instead of "MacOS X".
Bruno Haible <bruno@clisp.org>
parents: 16201
diff changeset
35 #if defined __APPLE__ && defined __MACH__ /* Mac OS X */
14220
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36 # include <mach/mach.h>
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37 #endif
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39 #if (defined _WIN32 || defined __WIN32__) || defined __CYGWIN__ /* Windows */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 # include <windows.h>
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41 #endif
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42
14226
7e521272b3c6 vma-iter: Treat Haiku like BeOS.
Bruno Haible <bruno@clisp.org>
parents: 14223
diff changeset
43 #if defined __BEOS__ || defined __HAIKU__ /* BeOS, Haiku */
14220
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44 # include <OS.h>
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45 #endif
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46
14235
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
47 #if HAVE_MQUERY /* OpenBSD */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
48 # include <sys/types.h>
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
49 # include <sys/mman.h> /* mquery */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
50 #endif
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
51
14220
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
52
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
53 /* Support for reading text files in the /proc file system. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
54
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
55 #if defined __linux__ || defined __FreeBSD__ || defined __NetBSD__ /* || defined __CYGWIN__ */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57 /* Buffered read-only streams.
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 We cannot use <stdio.h> here, because fopen() calls malloc(), and a malloc()
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 call may call mmap() and thus pre-allocate available memory. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
61 struct rofile
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63 int fd;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64 size_t position;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65 size_t filled;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66 int eof_seen;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67 char buffer[1024];
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 };
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70 /* Open a read-only file stream. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71 static int
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 rof_open (struct rofile *rof, const char *filename)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 int fd = open (filename, O_RDONLY);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75 if (fd < 0)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76 return -1;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77 rof->fd = fd;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
78 rof->position = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
79 rof->filled = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
80 rof->eof_seen = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
81 return 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
82 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
84 /* Return the next byte from a read-only file stream without consuming it,
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
85 or -1 at EOF. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
86 static int
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87 rof_peekchar (struct rofile *rof)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
88 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
89 if (rof->position == rof->filled)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
90 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
91 if (rof->eof_seen)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
92 return -1;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
93 else
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
94 for (;;)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
95 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
96 int n = read (rof->fd, rof->buffer, sizeof (rof->buffer));
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97 # ifdef EINTR
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
98 if (n < 0 && errno == EINTR)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
99 continue;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 # endif
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 if (n <= 0)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103 rof->eof_seen = 1;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104 return -1;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
105 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106 rof->filled = n;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
107 rof->position = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
109 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
110 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
111 return (unsigned char) rof->buffer[rof->position];
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
112 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
113
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
114 /* Return the next byte from a read-only file stream, or -1 at EOF. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
115 static int
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
116 rof_getchar (struct rofile *rof)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
117 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
118 int c = rof_peekchar (rof);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
119 if (c >= 0)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
120 rof->position++;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
121 return c;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
122 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
123
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
124 /* Parse an unsigned hexadecimal number from a read-only file stream. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
125 static int
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
126 rof_scanf_lx (struct rofile *rof, unsigned long *valuep)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
127 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
128 unsigned long value = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
129 unsigned int numdigits = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
130 for (;;)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
131 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
132 int c = rof_peekchar (rof);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
133 if (c >= '0' && c <= '9')
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
134 value = (value << 4) + (c - '0');
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
135 else if (c >= 'A' && c <= 'F')
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
136 value = (value << 4) + (c - 'A' + 10);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
137 else if (c >= 'a' && c <= 'f')
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
138 value = (value << 4) + (c - 'a' + 10);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
139 else
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
140 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
141 rof_getchar (rof);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
142 numdigits++;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
143 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
144 if (numdigits == 0)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
145 return -1;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
146 *valuep = value;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
147 return 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
148 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
149
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
150 /* Close a read-only file stream. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
151 static void
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
152 rof_close (struct rofile *rof)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
153 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
154 close (rof->fd);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
155 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
156
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
157 #endif
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
158
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
159
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
160 void
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
161 vma_iterate (vma_iterate_callback_fn callback, void *data)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
162 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
163 #if defined __linux__ /* || defined __CYGWIN__ */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
164
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
165 struct rofile rof;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
166 int c;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
167
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
168 /* Open the current process' maps file. It describes one VMA per line. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
169 if (rof_open (&rof, "/proc/self/maps") < 0)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
170 return;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
171
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
172 for (;;)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
173 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
174 unsigned long start, end;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
175 unsigned int flags;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
176
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
177 /* Parse one line. First start and end. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
178 if (!(rof_scanf_lx (&rof, &start) >= 0
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
179 && rof_getchar (&rof) == '-'
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
180 && rof_scanf_lx (&rof, &end) >= 0))
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
181 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
182 /* Then the flags. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
183 do
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
184 c = rof_getchar (&rof);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
185 while (c == ' ');
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
186 flags = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
187 if (c == 'r')
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
188 flags |= VMA_PROT_READ;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
189 c = rof_getchar (&rof);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
190 if (c == 'w')
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
191 flags |= VMA_PROT_WRITE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
192 c = rof_getchar (&rof);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
193 if (c == 'x')
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
194 flags |= VMA_PROT_EXECUTE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
195 while (c = rof_getchar (&rof), c != -1 && c != '\n')
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
196 ;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
197
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
198 if (callback (data, start, end, flags))
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
199 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
200 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
201 rof_close (&rof);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
202
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
203 #elif defined __FreeBSD__ || defined __NetBSD__
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
204
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
205 struct rofile rof;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
206 int c;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
207
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
208 /* Open the current process' maps file. It describes one VMA per line. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
209 if (rof_open (&rof, "/proc/curproc/map") < 0)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
210 return;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
211
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
212 for (;;)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
213 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
214 unsigned long start, end;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
215 unsigned int flags;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
216
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
217 /* Parse one line. First start. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
218 if (!(rof_getchar (&rof) == '0'
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
219 && rof_getchar (&rof) == 'x'
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
220 && rof_scanf_lx (&rof, &start) >= 0))
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
221 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
222 while (c = rof_peekchar (&rof), c == ' ' || c == '\t')
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
223 rof_getchar (&rof);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
224 /* Then end. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
225 if (!(rof_getchar (&rof) == '0'
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
226 && rof_getchar (&rof) == 'x'
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
227 && rof_scanf_lx (&rof, &end) >= 0))
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
228 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
229 /* Then the flags. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
230 do
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
231 c = rof_getchar (&rof);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
232 while (c == ' ');
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
233 flags = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
234 if (c == 'r')
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
235 flags |= VMA_PROT_READ;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
236 c = rof_getchar (&rof);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
237 if (c == 'w')
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
238 flags |= VMA_PROT_WRITE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
239 c = rof_getchar (&rof);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
240 if (c == 'x')
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
241 flags |= VMA_PROT_EXECUTE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
242 while (c = rof_getchar (&rof), c != -1 && c != '\n')
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
243 ;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
244
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
245 if (callback (data, start, end, flags))
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
246 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
247 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
248 rof_close (&rof);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
249
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
250 #elif defined __sgi || defined __osf__ /* IRIX, OSF/1 */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
251
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
252 size_t pagesize;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
253 char fnamebuf[6+10+1];
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
254 char *fname;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
255 int fd;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
256 int nmaps;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
257 size_t memneed;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
258 # if HAVE_MAP_ANONYMOUS
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
259 # define zero_fd -1
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
260 # define map_flags MAP_ANONYMOUS
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
261 # else
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
262 int zero_fd;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
263 # define map_flags 0
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
264 # endif
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
265 void *auxmap;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
266 unsigned long auxmap_start;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
267 unsigned long auxmap_end;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
268 prmap_t* maps;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
269 prmap_t* mp;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
270
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
271 pagesize = getpagesize ();
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
272
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
273 /* Construct fname = sprintf (fnamebuf+i, "/proc/%u", getpid ()). */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
274 fname = fnamebuf + sizeof (fnamebuf) - 1;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
275 *fname = '\0';
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
276 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
277 unsigned int value = getpid ();
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
278 do
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
279 *--fname = (value % 10) + '0';
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
280 while ((value = value / 10) > 0);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
281 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
282 fname -= 6;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
283 memcpy (fname, "/proc/", 6);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
284
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
285 fd = open (fname, O_RDONLY);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
286 if (fd < 0)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
287 return;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
288
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
289 if (ioctl (fd, PIOCNMAP, &nmaps) < 0)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
290 goto fail2;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
291
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
292 memneed = (nmaps + 10) * sizeof (prmap_t);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
293 /* Allocate memneed bytes of memory.
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
294 We cannot use alloca here, because not much stack space is guaranteed.
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
295 We also cannot use malloc here, because a malloc() call may call mmap()
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
296 and thus pre-allocate available memory.
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
297 So use mmap(), and ignore the resulting VMA. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
298 memneed = ((memneed - 1) / pagesize + 1) * pagesize;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
299 # if !HAVE_MAP_ANONYMOUS
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
300 zero_fd = open ("/dev/zero", O_RDONLY, 0644);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
301 if (zero_fd < 0)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
302 goto fail2;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
303 # endif
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
304 auxmap = (void *) mmap ((void *) 0, memneed, PROT_READ | PROT_WRITE,
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
305 map_flags | MAP_PRIVATE, zero_fd, 0);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
306 # if !HAVE_MAP_ANONYMOUS
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
307 close (zero_fd);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
308 # endif
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
309 if (auxmap == (void *) -1)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
310 goto fail2;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
311 auxmap_start = (unsigned long) auxmap;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
312 auxmap_end = auxmap_start + memneed;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
313 maps = (prmap_t *) auxmap;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
314
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
315 if (ioctl (fd, PIOCMAP, maps) < 0)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
316 goto fail1;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
317
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
318 for (mp = maps;;)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
319 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
320 unsigned long start, end;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
321 unsigned int flags;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
322
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
323 start = (unsigned long) mp->pr_vaddr;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
324 end = start + mp->pr_size;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
325 if (start == 0 && end == 0)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
326 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
327 flags = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
328 if (mp->pr_mflags & MA_READ)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
329 flags |= VMA_PROT_READ;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
330 if (mp->pr_mflags & MA_WRITE)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
331 flags |= VMA_PROT_WRITE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
332 if (mp->pr_mflags & MA_EXEC)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
333 flags |= VMA_PROT_EXECUTE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
334 mp++;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
335 if (start <= auxmap_start && auxmap_end - 1 <= end - 1)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
336 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
337 /* Consider [start,end-1] \ [auxmap_start,auxmap_end-1]
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
338 = [start,auxmap_start-1] u [auxmap_end,end-1]. */
14223
af4da95a33d1 vma-iter: Avoid empty intervals.
Bruno Haible <bruno@clisp.org>
parents: 14220
diff changeset
339 if (start < auxmap_start)
af4da95a33d1 vma-iter: Avoid empty intervals.
Bruno Haible <bruno@clisp.org>
parents: 14220
diff changeset
340 if (callback (data, start, auxmap_start, flags))
af4da95a33d1 vma-iter: Avoid empty intervals.
Bruno Haible <bruno@clisp.org>
parents: 14220
diff changeset
341 break;
af4da95a33d1 vma-iter: Avoid empty intervals.
Bruno Haible <bruno@clisp.org>
parents: 14220
diff changeset
342 if (auxmap_end - 1 < end - 1)
af4da95a33d1 vma-iter: Avoid empty intervals.
Bruno Haible <bruno@clisp.org>
parents: 14220
diff changeset
343 if (callback (data, auxmap_end, end, flags))
af4da95a33d1 vma-iter: Avoid empty intervals.
Bruno Haible <bruno@clisp.org>
parents: 14220
diff changeset
344 break;
14220
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
345 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
346 else
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
347 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
348 if (callback (data, start, end, flags))
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
349 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
350 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
351 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
352 munmap (auxmap, memneed);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
353 close (fd);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
354 return;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
355
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
356 fail1:
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
357 munmap (auxmap, memneed);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
358 fail2:
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
359 close (fd);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
360 return;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
361
16935
498a2211d839 Write "Mac OS X" instead of "MacOS X".
Bruno Haible <bruno@clisp.org>
parents: 16201
diff changeset
362 #elif defined __APPLE__ && defined __MACH__ /* Mac OS X */
14220
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
363
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
364 task_t task = mach_task_self ();
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
365 vm_address_t address;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
366 vm_size_t size;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
367
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
368 for (address = VM_MIN_ADDRESS;; address += size)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
369 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
370 int more;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
371 mach_port_t object_name;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
372 unsigned int flags;
16935
498a2211d839 Write "Mac OS X" instead of "MacOS X".
Bruno Haible <bruno@clisp.org>
parents: 16201
diff changeset
373 /* In Mac OS X 10.5, the types vm_address_t, vm_offset_t, vm_size_t have
14220
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
374 32 bits in 32-bit processes and 64 bits in 64-bit processes. Whereas
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
375 mach_vm_address_t and mach_vm_size_t are always 64 bits large.
16935
498a2211d839 Write "Mac OS X" instead of "MacOS X".
Bruno Haible <bruno@clisp.org>
parents: 16201
diff changeset
376 Mac OS X 10.5 has three vm_region like methods:
14220
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
377 - vm_region. It has arguments that depend on whether the current
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
378 process is 32-bit or 64-bit. When linking dynamically, this
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
379 function exists only in 32-bit processes. Therefore we use it only
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
380 in 32-bit processes.
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
381 - vm_region_64. It has arguments that depend on whether the current
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
382 process is 32-bit or 64-bit. It interprets a flavor
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
383 VM_REGION_BASIC_INFO as VM_REGION_BASIC_INFO_64, which is
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
384 dangerous since 'struct vm_region_basic_info_64' is larger than
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
385 'struct vm_region_basic_info'; therefore let's write
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
386 VM_REGION_BASIC_INFO_64 explicitly.
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
387 - mach_vm_region. It has arguments that are 64-bit always. This
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
388 function is useful when you want to access the VM of a process
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
389 other than the current process.
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
390 In 64-bit processes, we could use vm_region_64 or mach_vm_region.
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
391 I choose vm_region_64 because it uses the same types as vm_region,
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
392 resulting in less conditional code. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
393 # if defined __ppc64__ || defined __x86_64__
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
394 struct vm_region_basic_info_64 info;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
395 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
396
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
397 more = (vm_region_64 (task, &address, &size, VM_REGION_BASIC_INFO_64,
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
398 (vm_region_info_t)&info, &info_count, &object_name)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
399 == KERN_SUCCESS);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
400 # else
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
401 struct vm_region_basic_info info;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
402 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
403
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
404 more = (vm_region (task, &address, &size, VM_REGION_BASIC_INFO,
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
405 (vm_region_info_t)&info, &info_count, &object_name)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
406 == KERN_SUCCESS);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
407 # endif
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
408 if (object_name != MACH_PORT_NULL)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
409 mach_port_deallocate (mach_task_self (), object_name);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
410 if (!more)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
411 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
412 flags = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
413 if (info.protection & VM_PROT_READ)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
414 flags |= VMA_PROT_READ;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
415 if (info.protection & VM_PROT_WRITE)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
416 flags |= VMA_PROT_WRITE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
417 if (info.protection & VM_PROT_EXECUTE)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
418 flags |= VMA_PROT_EXECUTE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
419 if (callback (data, address, address + size, flags))
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
420 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
421 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
422
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
423 #elif (defined _WIN32 || defined __WIN32__) || defined __CYGWIN__
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
424 /* Windows platform. Use the native Windows API. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
425
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
426 MEMORY_BASIC_INFORMATION info;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
427 unsigned long address = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
428
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
429 while (VirtualQuery ((void*)address, &info, sizeof(info)) == sizeof(info))
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
430 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
431 if (info.State != MEM_FREE)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
432 /* Ignore areas where info.State has the value MEM_RESERVE or,
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
433 equivalently, info.Protect has the undocumented value 0.
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
434 This is needed, so that on Cygwin, areas used by malloc() are
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
435 distinguished from areas reserved for future malloc(). */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
436 if (info.State != MEM_RESERVE)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
437 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
438 unsigned long start, end;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
439 unsigned int flags;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
440
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
441 start = (unsigned long)info.BaseAddress;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
442 end = start + info.RegionSize;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
443 switch (info.Protect & ~(PAGE_GUARD|PAGE_NOCACHE))
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
444 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
445 case PAGE_READONLY:
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
446 flags = VMA_PROT_READ;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
447 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
448 case PAGE_READWRITE:
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
449 case PAGE_WRITECOPY:
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
450 flags = VMA_PROT_READ | VMA_PROT_WRITE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
451 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
452 case PAGE_EXECUTE:
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
453 flags = VMA_PROT_EXECUTE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
454 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
455 case PAGE_EXECUTE_READ:
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
456 flags = VMA_PROT_READ | VMA_PROT_EXECUTE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
457 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
458 case PAGE_EXECUTE_READWRITE:
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
459 case PAGE_EXECUTE_WRITECOPY:
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
460 flags = VMA_PROT_READ | VMA_PROT_WRITE | VMA_PROT_EXECUTE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
461 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
462 case PAGE_NOACCESS:
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
463 default:
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
464 flags = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
465 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
466 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
467
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
468 if (callback (data, start, end, flags))
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
469 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
470 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
471 address = (unsigned long)info.BaseAddress + info.RegionSize;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
472 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
473
14226
7e521272b3c6 vma-iter: Treat Haiku like BeOS.
Bruno Haible <bruno@clisp.org>
parents: 14223
diff changeset
474 #elif defined __BEOS__ || defined __HAIKU__
14220
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
475 /* Use the BeOS specific API. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
476
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
477 area_info info;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
478 int32 cookie;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
479
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
480 cookie = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
481 while (get_next_area_info (0, &cookie, &info) == B_OK)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
482 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
483 unsigned long start, end;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
484 unsigned int flags;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
485
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
486 start = (unsigned long) info.address;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
487 end = start + info.size;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
488 flags = 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
489 if (info.protection & B_READ_AREA)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
490 flags |= VMA_PROT_READ | VMA_PROT_EXECUTE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
491 if (info.protection & B_WRITE_AREA)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
492 flags |= VMA_PROT_WRITE;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
493
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
494 if (callback (data, start, end, flags))
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
495 break;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
496 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
497
14235
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
498 #elif HAVE_MQUERY /* OpenBSD */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
499
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
500 uintptr_t pagesize;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
501 uintptr_t address;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
502 int /*bool*/ address_known_mapped;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
503
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
504 pagesize = getpagesize ();
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
505 /* Avoid calling mquery with a NULL first argument, because this argument
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
506 value has a specific meaning. We know the NULL page is unmapped. */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
507 address = pagesize;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
508 address_known_mapped = 0;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
509 for (;;)
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
510 {
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
511 /* Test whether the page at address is mapped. */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
512 if (address_known_mapped
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
513 || mquery ((void *) address, pagesize, 0, MAP_FIXED, -1, 0)
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
514 == (void *) -1)
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
515 {
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
516 /* The page at address is mapped.
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
517 This is the start of an interval. */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
518 uintptr_t start = address;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
519 uintptr_t end;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
520
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
521 /* Find the end of the interval. */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
522 end = (uintptr_t) mquery ((void *) address, pagesize, 0, 0, -1, 0);
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
523 if (end == (uintptr_t) (void *) -1)
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
524 end = 0; /* wrap around */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
525 address = end;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
526
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
527 /* It's too complicated to find out about the flags. Just pass 0. */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
528 if (callback (data, start, end, 0))
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
529 break;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
530
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
531 if (address < pagesize) /* wrap around? */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
532 break;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
533 }
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
534 /* Here we know that the page at address is unmapped. */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
535 {
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
536 uintptr_t query_size = pagesize;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
537
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
538 address += pagesize;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
539
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
540 /* Query larger and larger blocks, to get through the unmapped address
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
541 range with few mquery() calls. */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
542 for (;;)
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
543 {
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
544 if (2 * query_size > query_size)
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
545 query_size = 2 * query_size;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
546 if (address + query_size - 1 < query_size) /* wrap around? */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
547 {
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
548 address_known_mapped = 0;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
549 break;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
550 }
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
551 if (mquery ((void *) address, query_size, 0, MAP_FIXED, -1, 0)
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
552 == (void *) -1)
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
553 {
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
554 /* Not all the interval [address .. address + query_size - 1]
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
555 is unmapped. */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
556 address_known_mapped = (query_size == pagesize);
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
557 break;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
558 }
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
559 /* The interval [address .. address + query_size - 1] is
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
560 unmapped. */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
561 address += query_size;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
562 }
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
563 /* Reduce the query size again, to determine the precise size of the
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
564 unmapped interval that starts at address. */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
565 while (query_size > pagesize)
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
566 {
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
567 query_size = query_size / 2;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
568 if (address + query_size - 1 >= query_size)
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
569 {
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
570 if (mquery ((void *) address, query_size, 0, MAP_FIXED, -1, 0)
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
571 != (void *) -1)
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
572 {
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
573 /* The interval [address .. address + query_size - 1] is
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
574 unmapped. */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
575 address += query_size;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
576 address_known_mapped = 0;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
577 }
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
578 else
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
579 address_known_mapped = (query_size == pagesize);
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
580 }
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
581 }
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
582 /* Here again query_size = pagesize, and
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
583 either address + pagesize - 1 < pagesize, or
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
584 mquery ((void *) address, pagesize, 0, MAP_FIXED, -1, 0) fails.
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
585 So, the unmapped area ends at address. */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
586 }
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
587 if (address + pagesize - 1 < pagesize) /* wrap around? */
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
588 break;
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
589 }
6b8b94f919ce vma-iter, get-rusage-as: Add OpenBSD support.
Bruno Haible <bruno@clisp.org>
parents: 14226
diff changeset
590
14220
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
591 #endif
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
592 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
593
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
594
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
595 #ifdef TEST
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
596
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
597 #include <stdio.h>
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
598
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
599 /* Output the VMAs of the current process in a format similar to the Linux
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
600 /proc/$pid/maps file. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
601
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
602 static int
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
603 vma_iterate_callback (void *data, uintptr_t start, uintptr_t end,
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
604 unsigned int flags)
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
605 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
606 printf ("%08lx-%08lx %c%c%c\n",
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
607 (unsigned long) start, (unsigned long) end,
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
608 flags & VMA_PROT_READ ? 'r' : '-',
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
609 flags & VMA_PROT_WRITE ? 'w' : '-',
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
610 flags & VMA_PROT_EXECUTE ? 'x' : '-');
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
611 return 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
612 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
613
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
614 int
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
615 main ()
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
616 {
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
617 vma_iterate (vma_iterate_callback, NULL);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
618
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
619 /* Let the user interactively look at the /proc file system. */
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
620 sleep (10);
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
621
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
622 return 0;
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
623 }
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
624
996391c07734 New module 'vma-iter'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
625 #endif /* TEST */