]> granicus.if.org Git - strace/blob - mem.c
Added support for old*stat syscalls for Linux
[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
40 #if defined(LINUX) && defined(__i386__)
41 #include <linux/ldt.h>
42 #endif
43
44 int
45 sys_brk(tcp)
46 struct tcb *tcp;
47 {
48         if (entering(tcp)) {
49                 tprintf("%#lx", tcp->u_arg[0]);
50         }
51 #ifdef LINUX
52         return RVAL_HEX;
53 #else
54         return 0;
55 #endif
56 }
57
58 int
59 sys_sbrk(tcp)
60 struct tcb *tcp;
61 {
62         if (entering(tcp)) {
63                 tprintf("%lu", tcp->u_arg[0]);
64         }
65         return RVAL_HEX;
66 }
67
68 static struct xlat mmap_prot[] = {
69         { PROT_NONE,    "PROT_NONE",    },
70         { PROT_READ,    "PROT_READ"     },
71         { PROT_WRITE,   "PROT_WRITE"    },
72         { PROT_EXEC,    "PROT_EXEC"     },
73         { 0,            NULL            },
74 };
75
76 static struct xlat mmap_flags[] = {
77         { MAP_SHARED,   "MAP_SHARED"    },
78         { MAP_PRIVATE,  "MAP_PRIVATE"   },
79         { MAP_FIXED,    "MAP_FIXED"     },
80 #ifdef MAP_ANONYMOUS
81         { MAP_ANONYMOUS,"MAP_ANONYMOUS" },
82 #endif
83 #ifdef MAP_RENAME
84         { MAP_RENAME,   "MAP_RENAME"    },
85 #endif
86 #ifdef MAP_NORESERVE
87         { MAP_NORESERVE,"MAP_NORESERVE" },
88 #endif
89 #ifdef _MAP_NEW
90         { _MAP_NEW,     "_MAP_NEW"      },
91 #endif
92 #ifdef MAP_GROWSDOWN
93         { MAP_GROWSDOWN,"MAP_GROWSDOWN" },
94 #endif
95 #ifdef MAP_DENYWRITE
96         { MAP_DENYWRITE,"MAP_DENYWRITE" },
97 #endif
98 #ifdef MAP_EXECUTABLE
99         { MAP_EXECUTABLE,"MAP_EXECUTABLE"},
100 #endif
101 #ifdef MAP_FILE
102         { MAP_FILE,"MAP_FILE"},
103 #endif
104 #ifdef MAP_LOCKED
105         { MAP_LOCKED,"MAP_LOCKED"},
106 #endif
107         { 0,            NULL            },
108 };
109
110 int
111 sys_mmap(tcp)
112 struct tcb *tcp;
113 {
114 #ifdef LINUX
115 #  if defined(ALPHA) || defined(sparc)
116         long *u_arg = tcp->u_arg;
117 #  else /* !ALPHA */
118         long u_arg[6];
119 #  endif /* !ALPHA */
120 #else /* !LINUX */
121         long *u_arg = tcp->u_arg;
122 #endif /* !LINUX */
123
124         if (entering(tcp)) {
125 #if defined(LINUX) && !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 /* LINUX && !ALPHA && !sparc */
130
131                 /* addr */
132                 tprintf("%#lx, ", u_arg[0]);
133                 /* len */
134                 tprintf("%lu, ", u_arg[1]);
135                 /* prot */
136                 printflags(mmap_prot, u_arg[2]);
137                 tprintf(", ");
138                 /* flags */
139                 printxval(mmap_flags, u_arg[3] & MAP_TYPE, "MAP_???");
140                 addflags(mmap_flags, u_arg[3] & ~MAP_TYPE);
141                 /* fd */
142                 tprintf(", %ld, ", u_arg[4]);
143                 /* offset */
144                 tprintf("%#lx", u_arg[5]);
145         }
146         return RVAL_HEX;
147 }
148
149 int
150 sys_munmap(tcp)
151 struct tcb *tcp;
152 {
153         if (entering(tcp)) {
154                 tprintf("%#lx, %lu",
155                         tcp->u_arg[0], tcp->u_arg[1]);
156         }
157         return 0;
158 }
159
160 int
161 sys_mprotect(tcp)
162 struct tcb *tcp;
163 {
164         if (entering(tcp)) {
165                 tprintf("%#lx, %lu, ",
166                         tcp->u_arg[0], tcp->u_arg[1]);
167                 if (!printflags(mmap_prot, tcp->u_arg[2]))
168                         tprintf("PROT_???");
169         }
170         return 0;
171 }
172
173 #ifdef MS_ASYNC
174
175 static struct xlat mctl_sync[] = {
176         { MS_ASYNC,     "MS_ASYNC"      },
177         { MS_INVALIDATE,"MS_INVALIDATE" },
178 #ifdef MS_SYNC
179         { MS_SYNC,      "MS_SYNC"       },
180 #endif
181         { 0,            NULL            },
182 };
183
184 int
185 sys_msync(tcp)
186 struct tcb *tcp;
187 {
188         if (entering(tcp)) {
189                 /* addr */
190                 tprintf("%#lx", tcp->u_arg[0]);
191                 /* len */
192                 tprintf(", %lu, ", tcp->u_arg[1]);
193                 /* flags */
194                 if (!printflags(mctl_sync, tcp->u_arg[2]))
195                         tprintf("MS_???");
196         }
197         return 0;
198 }
199
200 #endif /* MS_ASYNC */
201
202 #ifdef MC_SYNC
203
204 static struct xlat mctl_funcs[] = {
205         { MC_LOCK,      "MC_LOCK"       },
206         { MC_LOCKAS,    "MC_LOCKAS"     },
207         { MC_SYNC,      "MC_SYNC"       },
208         { MC_UNLOCK,    "MC_UNLOCK"     },
209         { MC_UNLOCKAS,  "MC_UNLOCKAS"   },
210         { 0,            NULL            },
211 };
212
213 static struct xlat mctl_lockas[] = {
214         { MCL_CURRENT,  "MCL_CURRENT"   },
215         { MCL_FUTURE,   "MCL_FUTURE"    },
216         { 0,            NULL            },
217 };
218
219 int
220 sys_mctl(tcp)
221 struct tcb *tcp;
222 {
223         int arg, function;
224
225         if (entering(tcp)) {
226                 /* addr */
227                 tprintf("%#lx", tcp->u_arg[0]);
228                 /* len */
229                 tprintf(", %lu, ", tcp->u_arg[1]);
230                 /* function */
231                 function = tcp->u_arg[2];
232                 if (!printflags(mctl_funcs, function))
233                         tprintf("MC_???");
234                 /* arg */
235                 arg = tcp->u_arg[3];
236                 tprintf(", ");
237                 switch (function) {
238                 case MC_SYNC:
239                         if (!printflags(mctl_sync, arg))
240                                 tprintf("MS_???");
241                         break;
242                 case MC_LOCKAS:
243                         if (!printflags(mctl_lockas, arg))
244                                 tprintf("MCL_???");
245                         break;
246                 default:
247                         tprintf("%#x", arg);
248                         break;
249                 }
250         }
251         return 0;
252 }
253
254 #endif /* MC_SYNC */
255
256 int
257 sys_mincore(tcp)
258 struct tcb *tcp;
259 {
260         int i, len;
261         char *vec = NULL;
262
263         if (entering(tcp)) {
264                 tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
265         } else {
266                 len = tcp->u_arg[1];
267                 if (syserror(tcp) || tcp->u_arg[2] == 0 ||
268                         (vec = malloc((u_int)len)) == NULL ||
269                         umoven(tcp, tcp->u_arg[2], len, vec) < 0)
270                         tprintf("%#lx", tcp->u_arg[2]);
271                 else {
272                         tprintf("[");
273                         for (i = 0; i < len; i++) {
274                                 if (abbrev(tcp) && i >= max_strlen) {
275                                         tprintf("...");
276                                         break;
277                                 }
278                                 tprintf((vec[i] & 1) ? "1" : "0");
279                         }
280                         tprintf("]");
281                 }
282                 if (vec)
283                         free(vec);
284         }
285         return 0;
286 }
287
288 int
289 sys_getpagesize(tcp)
290 struct tcb *tcp;
291 {
292         if (exiting(tcp))
293                 return RVAL_HEX;
294         return 0;
295 }
296
297 #if defined(LINUX) && defined(__i386__)
298 int
299 sys_modify_ldt(tcp)
300 struct tcb *tcp;
301 {
302         if (entering(tcp)) {
303                 struct modify_ldt_ldt_s copy;
304                 tprintf("%ld", tcp->u_arg[0]);
305                 if (tcp->u_arg[1] == 0
306                                 || tcp->u_arg[2] != sizeof (struct modify_ldt_ldt_s)
307                                 || umove(tcp, tcp->u_arg[1], &copy) == -1)
308                         tprintf(", %lx", tcp->u_arg[1]);
309                 else {
310                         tprintf(", {entry_number:%d, ", copy.entry_number);
311                         if (!verbose(tcp))
312                                 tprintf("...}");
313                         else {
314                                 tprintf("base_addr:%#08lx, "
315                                                 "limit:%d, "
316                                                 "seg_32bit:%d, "
317                                                 "contents:%d, "
318                                                 "read_exec_only:%d, "
319                                                 "limit_in_pages:%d, "
320                                                 "seg_not_present:%d, "
321                                                 "useable:%d}",
322                                                 copy.base_addr,
323                                                 copy.limit,
324                                                 copy.seg_32bit,
325                                                 copy.contents,
326                                                 copy.read_exec_only,
327                                                 copy.limit_in_pages,
328                                                 copy.seg_not_present,
329                                                 copy.useable);
330                         }
331                 }
332                 tprintf(", %lu", tcp->u_arg[2]);
333         }
334         return 0;
335 }
336 #endif /* LINUX && __i386__ */
337