]> granicus.if.org Git - strace/blob - mem.c
Initial revision
[strace] / mem.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  *      $Id$
30  */
31
32 #include "defs.h"
33
34 #ifdef LINUXSPARC
35 #include <linux/mman.h>
36 #else
37 #include <sys/mman.h>
38 #endif
39 #if defined(LINUX) && defined(__i386__)
40 #include <asm/ldt.h>
41 #endif
42
43 int
44 sys_brk(tcp)
45 struct tcb *tcp;
46 {
47         if (entering(tcp)) {
48                 tprintf("%#lx", tcp->u_arg[0]);
49         }
50 #ifdef linux
51         return RVAL_HEX;
52 #else
53         return 0;
54 #endif
55 }
56
57 int
58 sys_sbrk(tcp)
59 struct tcb *tcp;
60 {
61         if (entering(tcp)) {
62                 tprintf("%lu", tcp->u_arg[0]);
63         }
64         return RVAL_HEX;
65 }
66
67 static struct xlat mmap_prot[] = {
68         { PROT_NONE,    "PROT_NONE",    },
69         { PROT_READ,    "PROT_READ"     },
70         { PROT_WRITE,   "PROT_WRITE"    },
71         { PROT_EXEC,    "PROT_EXEC"     },
72         { 0,            NULL            },
73 };
74
75 static struct xlat mmap_flags[] = {
76         { MAP_SHARED,   "MAP_SHARED"    },
77         { MAP_PRIVATE,  "MAP_PRIVATE"   },
78         { MAP_FIXED,    "MAP_FIXED"     },
79 #ifdef MAP_ANONYMOUS
80         { MAP_ANONYMOUS,"MAP_ANONYMOUS" },
81 #endif
82 #ifdef MAP_RENAME
83         { MAP_RENAME,   "MAP_RENAME"    },
84 #endif
85 #ifdef MAP_NORESERVE
86         { MAP_NORESERVE,"MAP_NORESERVE" },
87 #endif
88 #ifdef _MAP_NEW
89         { _MAP_NEW,     "_MAP_NEW"      },
90 #endif
91 #ifdef MAP_GROWSDOWN
92         { MAP_GROWSDOWN,"MAP_GROWSDOWN" },
93 #endif
94 #ifdef MAP_DENYWRITE
95         { MAP_DENYWRITE,"MAP_DENYWRITE" },
96 #endif
97 #ifdef MAP_EXECUTABLE
98         { MAP_EXECUTABLE,"MAP_EXECUTABLE"},
99 #endif
100 #ifdef MAP_FILE
101         { MAP_FILE,"MAP_FILE"},
102 #endif
103 #ifdef MAP_LOCKED
104         { MAP_LOCKED,"MAP_LOCKED"},
105 #endif
106         { 0,            NULL            },
107 };
108
109 int
110 sys_mmap(tcp)
111 struct tcb *tcp;
112 {
113 #ifdef LINUX
114 #if defined(ALPHA) || defined(sparc)
115         long *u_arg = tcp->u_arg;
116 #else /* !ALPHA */
117         long u_arg[6];
118 #endif /* !ALPHA */
119 #else /* !LINUX */
120         long *u_arg = tcp->u_arg;
121 #endif /* !LINUX */
122
123         if (entering(tcp)) {
124 #ifdef LINUX
125 #if !defined(ALPHA) && !defined(__sparc__)
126                 if (umoven(tcp, tcp->u_arg[0], sizeof u_arg,
127                                 (char *) u_arg) == -1)
128                         return 0;
129 #endif /* ALPHA/sparc */
130 #endif /* LINUX */
131
132                 /* addr */
133                 tprintf("%#lx, ", u_arg[0]);
134                 /* len */
135                 tprintf("%lu, ", u_arg[1]);
136                 /* prot */
137                 printflags(mmap_prot, u_arg[2]);
138                 tprintf(", ");
139                 /* flags */
140                 printxval(mmap_flags, u_arg[3] & MAP_TYPE, "MAP_???");
141                 addflags(mmap_flags, u_arg[3] & ~MAP_TYPE);
142                 /* fd */
143                 tprintf(", %ld, ", u_arg[4]);
144                 /* offset */
145                 tprintf("%#lx", u_arg[5]);
146         }
147         return RVAL_HEX;
148 }
149
150 int
151 sys_munmap(tcp)
152 struct tcb *tcp;
153 {
154         if (entering(tcp)) {
155                 tprintf("%#lx, %lu",
156                         tcp->u_arg[0], tcp->u_arg[1]);
157         }
158         return 0;
159 }
160
161 int
162 sys_mprotect(tcp)
163 struct tcb *tcp;
164 {
165         if (entering(tcp)) {
166                 tprintf("%#lx, %lu, ",
167                         tcp->u_arg[0], tcp->u_arg[1]);
168                 if (!printflags(mmap_prot, tcp->u_arg[2]))
169                         tprintf("PROT_???");
170         }
171         return 0;
172 }
173
174 #ifdef MS_ASYNC
175
176 static struct xlat mctl_sync[] = {
177         { MS_ASYNC,     "MS_ASYNC"      },
178         { MS_INVALIDATE,"MS_INVALIDATE" },
179 #ifdef MS_SYNC
180         { MS_SYNC,      "MS_SYNC"       },
181 #endif
182         { 0,            NULL            },
183 };
184
185 int
186 sys_msync(tcp)
187 struct tcb *tcp;
188 {
189         if (entering(tcp)) {
190                 /* addr */
191                 tprintf("%#lx", tcp->u_arg[0]);
192                 /* len */
193                 tprintf(", %lu, ", tcp->u_arg[1]);
194                 /* flags */
195                 if (!printflags(mctl_sync, tcp->u_arg[2]))
196                         tprintf("MS_???");
197         }
198         return 0;
199 }
200
201 #endif /* MS_ASYNC */
202
203 #ifdef MC_SYNC
204
205 static struct xlat mctl_funcs[] = {
206         { MC_LOCK,      "MC_LOCK"       },
207         { MC_LOCKAS,    "MC_LOCKAS"     },
208         { MC_SYNC,      "MC_SYNC"       },
209         { MC_UNLOCK,    "MC_UNLOCK"     },
210         { MC_UNLOCKAS,  "MC_UNLOCKAS"   },
211         { 0,            NULL            },
212 };
213
214 static struct xlat mctl_lockas[] = {
215         { MCL_CURRENT,  "MCL_CURRENT"   },
216         { MCL_FUTURE,   "MCL_FUTURE"    },
217         { 0,            NULL            },
218 };
219
220 int
221 sys_mctl(tcp)
222 struct tcb *tcp;
223 {
224         int arg, function;
225
226         if (entering(tcp)) {
227                 /* addr */
228                 tprintf("%#lx", tcp->u_arg[0]);
229                 /* len */
230                 tprintf(", %lu, ", tcp->u_arg[1]);
231                 /* function */
232                 function = tcp->u_arg[2];
233                 if (!printflags(mctl_funcs, function))
234                         tprintf("MC_???");
235                 /* arg */
236                 arg = tcp->u_arg[3];
237                 tprintf(", ");
238                 switch (function) {
239                 case MC_SYNC:
240                         if (!printflags(mctl_sync, arg))
241                                 tprintf("MS_???");
242                         break;
243                 case MC_LOCKAS:
244                         if (!printflags(mctl_lockas, arg))
245                                 tprintf("MCL_???");
246                         break;
247                 default:
248                         tprintf("%#x", arg);
249                         break;
250                 }
251         }
252         return 0;
253 }
254
255 #endif /* MC_SYNC */
256
257 int
258 sys_mincore(tcp)
259 struct tcb *tcp;
260 {
261         int i, len;
262         char *vec = NULL;
263
264         if (entering(tcp)) {
265                 tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
266         } else {
267                 len = tcp->u_arg[1];
268                 if (syserror(tcp) || tcp->u_arg[2] == 0 ||
269                         (vec = malloc((u_int)len)) == NULL ||
270                         umoven(tcp, tcp->u_arg[2], len, vec) < 0)
271                         tprintf("%#lx", tcp->u_arg[2]);
272                 else {
273                         tprintf("[");
274                         for (i = 0; i < len; i++) {
275                                 if (abbrev(tcp) && i >= max_strlen) {
276                                         tprintf("...");
277                                         break;
278                                 }
279                                 tprintf((vec[i] & 1) ? "1" : "0");
280                         }
281                         tprintf("]");
282                 }
283                 if (vec)
284                         free(vec);
285         }
286         return 0;
287 }
288
289 int
290 sys_getpagesize(tcp)
291 struct tcb *tcp;
292 {
293         if (exiting(tcp))
294                 return RVAL_HEX;
295         return 0;
296 }
297
298 #if defined(LINUX) && defined(__i386__)
299 int
300 sys_modify_ldt(tcp)
301 struct tcb *tcp;
302 {
303         if (entering(tcp)) {
304                 struct modify_ldt_ldt_s copy;
305                 tprintf("%ld", tcp->u_arg[0]);
306                 if (tcp->u_arg[1] == 0
307                                 || tcp->u_arg[2] != sizeof (struct modify_ldt_ldt_s)
308                                 || umove(tcp, tcp->u_arg[1], &copy) == -1)
309                         tprintf(", %lx", tcp->u_arg[1]);
310                 else {
311                         tprintf(", {entry_number:%d, ", copy.entry_number);
312                         if (!verbose(tcp))
313                                 tprintf("...}");
314                         else {
315                                 tprintf("base_addr:%#08lx, "
316                                                 "limit:%d, "
317                                                 "seg_32bit:%d, "
318                                                 "contents:%d, "
319                                                 "read_exec_only:%d, "
320                                                 "limit_in_pages:%d, "
321                                                 "seg_not_present:%d, "
322                                                 "useable:%d}",
323                                                 copy.base_addr,
324                                                 copy.limit,
325                                                 copy.seg_32bit,
326                                                 copy.contents,
327                                                 copy.read_exec_only,
328                                                 copy.limit_in_pages,
329                                                 copy.seg_not_present,
330                                                 copy.useable);
331                         }
332                 }
333                 tprintf(", %lu", tcp->u_arg[2]);
334         }
335         return 0;
336 }
337 #endif /* LINUX && __i386__ */
338