1bbeaf6c0SSean Eric Fagan /* 209d64da3SSean Eric Fagan * Copryight 1997 Sean Eric Fagan 309d64da3SSean Eric Fagan * 409d64da3SSean Eric Fagan * Redistribution and use in source and binary forms, with or without 509d64da3SSean Eric Fagan * modification, are permitted provided that the following conditions 609d64da3SSean Eric Fagan * are met: 709d64da3SSean Eric Fagan * 1. Redistributions of source code must retain the above copyright 809d64da3SSean Eric Fagan * notice, this list of conditions and the following disclaimer. 909d64da3SSean Eric Fagan * 2. Redistributions in binary form must reproduce the above copyright 1009d64da3SSean Eric Fagan * notice, this list of conditions and the following disclaimer in the 1109d64da3SSean Eric Fagan * documentation and/or other materials provided with the distribution. 1209d64da3SSean Eric Fagan * 3. All advertising materials mentioning features or use of this software 1309d64da3SSean Eric Fagan * must display the following acknowledgement: 1409d64da3SSean Eric Fagan * This product includes software developed by Sean Eric Fagan 1509d64da3SSean Eric Fagan * 4. Neither the name of the author may be used to endorse or promote 1609d64da3SSean Eric Fagan * products derived from this software without specific prior written 1709d64da3SSean Eric Fagan * permission. 1809d64da3SSean Eric Fagan * 1909d64da3SSean Eric Fagan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2009d64da3SSean Eric Fagan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2109d64da3SSean Eric Fagan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2209d64da3SSean Eric Fagan * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2309d64da3SSean Eric Fagan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2409d64da3SSean Eric Fagan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2509d64da3SSean Eric Fagan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2609d64da3SSean Eric Fagan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2709d64da3SSean Eric Fagan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2809d64da3SSean Eric Fagan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2909d64da3SSean Eric Fagan * SUCH DAMAGE. 3009d64da3SSean Eric Fagan */ 3109d64da3SSean Eric Fagan 323cf51049SPhilippe Charnier #ifndef lint 333cf51049SPhilippe Charnier static const char rcsid[] = 3410714102SDag-Erling Smørgrav "$Id: syscalls.c,v 1.6 1998/10/15 04:31:44 sef Exp $"; 353cf51049SPhilippe Charnier #endif /* not lint */ 363cf51049SPhilippe Charnier 3709d64da3SSean Eric Fagan /* 38bbeaf6c0SSean Eric Fagan * This file has routines used to print out system calls and their 39bbeaf6c0SSean Eric Fagan * arguments. 40bbeaf6c0SSean Eric Fagan */ 41bbeaf6c0SSean Eric Fagan 423cf51049SPhilippe Charnier #include <err.h> 43bbeaf6c0SSean Eric Fagan #include <stdio.h> 44bbeaf6c0SSean Eric Fagan #include <stdlib.h> 45bbeaf6c0SSean Eric Fagan #include <string.h> 46bbeaf6c0SSean Eric Fagan #include <unistd.h> 47bbeaf6c0SSean Eric Fagan #include <sys/types.h> 48bbeaf6c0SSean Eric Fagan #include "syscall.h" 49bbeaf6c0SSean Eric Fagan 50bbeaf6c0SSean Eric Fagan /* 51bbeaf6c0SSean Eric Fagan * This should probably be in its own file. 52bbeaf6c0SSean Eric Fagan */ 53bbeaf6c0SSean Eric Fagan 54bbeaf6c0SSean Eric Fagan struct syscall syscalls[] = { 55bbeaf6c0SSean Eric Fagan { "readlink", 1, 3, 56bbeaf6c0SSean Eric Fagan { { String, 0 } , { String | OUT, 1 }, { Int, 2 }}}, 57bbeaf6c0SSean Eric Fagan { "lseek", 2, 3, 58bbeaf6c0SSean Eric Fagan { { Int, 0 }, {Quad, 2 }, { Int, 4 }}}, 59bbeaf6c0SSean Eric Fagan { "mmap", 2, 6, 60bbeaf6c0SSean Eric Fagan { { Hex, 0 }, {Int, 1}, {Hex, 2}, {Hex, 3}, {Int, 4}, {Quad, 6}}}, 61bbeaf6c0SSean Eric Fagan { "open", 1, 3, 62bbeaf6c0SSean Eric Fagan { { String | IN, 0} , { Int, 1}, {Octal, 2}}}, 63bbeaf6c0SSean Eric Fagan { "linux_open", 1, 3, 64bbeaf6c0SSean Eric Fagan { { String, 0 }, { Int, 1}, { Octal, 2 }}}, 65bbeaf6c0SSean Eric Fagan { "close", 1, 1, { { Int, 0 } } }, 66bbeaf6c0SSean Eric Fagan { "fstat", 1, 2, 67bbeaf6c0SSean Eric Fagan { { Int, 0}, {Ptr | OUT , 1 }}}, 68bbeaf6c0SSean Eric Fagan { "stat", 1, 2, 69bbeaf6c0SSean Eric Fagan { { String | IN, 0 }, { Ptr | OUT, 1 }}}, 70a8f37218SSean Eric Fagan { "lstat", 1, 2, 71a8f37218SSean Eric Fagan { { String | IN, 0 }, { Ptr | OUT, 1 }}}, 72bbeaf6c0SSean Eric Fagan { "linux_newstat", 1, 2, 73bbeaf6c0SSean Eric Fagan { { String | IN, 0 }, { Ptr | OUT, 1 }}}, 74bbeaf6c0SSean Eric Fagan { "linux_newfstat", 1, 2, 75bbeaf6c0SSean Eric Fagan { { Int, 0 }, { Ptr | OUT, 1 }}}, 76bbeaf6c0SSean Eric Fagan { "write", 1, 3, 77bbeaf6c0SSean Eric Fagan { { Int, 0}, { Ptr | IN, 1 }, { Int, 2 }}}, 78970649f9SSean Eric Fagan { "ioctl", 1, 3, 79970649f9SSean Eric Fagan { { Int, 0}, { Ioctl, 1 }, { Hex, 2 }}}, 80bbeaf6c0SSean Eric Fagan { "break", 1, 1, { { Hex, 0 }}}, 81bbeaf6c0SSean Eric Fagan { "exit", 0, 1, { { Hex, 0 }}}, 8210714102SDag-Erling Smørgrav { "access", 1, 2, { { String | IN, 0 }, { Int, 1 }}}, 833cf51049SPhilippe Charnier { 0, 0, 0, { { 0, 0 }}}, 84bbeaf6c0SSean Eric Fagan }; 85bbeaf6c0SSean Eric Fagan 863cf51049SPhilippe Charnier char * ioctlname __P((int)); 873cf51049SPhilippe Charnier 88bbeaf6c0SSean Eric Fagan /* 89bbeaf6c0SSean Eric Fagan * If/when the list gets big, it might be desirable to do it 90bbeaf6c0SSean Eric Fagan * as a hash table or binary search. 91bbeaf6c0SSean Eric Fagan */ 92bbeaf6c0SSean Eric Fagan 93bbeaf6c0SSean Eric Fagan struct syscall * 94bbeaf6c0SSean Eric Fagan get_syscall(const char *name) { 95bbeaf6c0SSean Eric Fagan struct syscall *sc = syscalls; 96bbeaf6c0SSean Eric Fagan 97bbeaf6c0SSean Eric Fagan while (sc->name) { 98bbeaf6c0SSean Eric Fagan if (!strcmp(name, sc->name)) 99bbeaf6c0SSean Eric Fagan return sc; 100bbeaf6c0SSean Eric Fagan sc++; 101bbeaf6c0SSean Eric Fagan } 102bbeaf6c0SSean Eric Fagan return NULL; 103bbeaf6c0SSean Eric Fagan } 104bbeaf6c0SSean Eric Fagan 105bbeaf6c0SSean Eric Fagan /* 106bbeaf6c0SSean Eric Fagan * get_string 107bbeaf6c0SSean Eric Fagan * Copy a string from the process. Note that it is 108bbeaf6c0SSean Eric Fagan * expected to be a C string, but if max is set, it will 109bbeaf6c0SSean Eric Fagan * only get that much. 110bbeaf6c0SSean Eric Fagan */ 111bbeaf6c0SSean Eric Fagan 112bbeaf6c0SSean Eric Fagan char * 113bbeaf6c0SSean Eric Fagan get_string(int procfd, void *offset, int max) { 1143cf51049SPhilippe Charnier char *buf; 115bbeaf6c0SSean Eric Fagan int size, len, c; 116bbeaf6c0SSean Eric Fagan FILE *p; 117bbeaf6c0SSean Eric Fagan 1183cf51049SPhilippe Charnier if ((p = fdopen(procfd, "r")) == NULL) 1193cf51049SPhilippe Charnier err(1, "fdopen"); 120bbeaf6c0SSean Eric Fagan buf = malloc( size = (max ? max : 64 ) ); 121bbeaf6c0SSean Eric Fagan len = 0; 122bbeaf6c0SSean Eric Fagan fseek(p, (long)offset, SEEK_SET); 123bbeaf6c0SSean Eric Fagan while ((c = fgetc(p)) != EOF) { 124bbeaf6c0SSean Eric Fagan buf[len++] = c; 125bbeaf6c0SSean Eric Fagan if (c == 0 || len == max) { 126bbeaf6c0SSean Eric Fagan buf[len] = 0; 127bbeaf6c0SSean Eric Fagan break; 128bbeaf6c0SSean Eric Fagan } 129bbeaf6c0SSean Eric Fagan if (len == size) { 130bbeaf6c0SSean Eric Fagan char *tmp = buf; 131bbeaf6c0SSean Eric Fagan tmp = realloc(buf, size+64); 132bbeaf6c0SSean Eric Fagan if (tmp == NULL) { 133bbeaf6c0SSean Eric Fagan buf[len] = 0; 134bbeaf6c0SSean Eric Fagan return buf; 135bbeaf6c0SSean Eric Fagan } 136bbeaf6c0SSean Eric Fagan size += 64; 137bbeaf6c0SSean Eric Fagan } 138bbeaf6c0SSean Eric Fagan } 139bbeaf6c0SSean Eric Fagan return buf; 140bbeaf6c0SSean Eric Fagan } 141bbeaf6c0SSean Eric Fagan 142bbeaf6c0SSean Eric Fagan 143bbeaf6c0SSean Eric Fagan /* 144bbeaf6c0SSean Eric Fagan * Gag. This is really unportable. Multiplication is more portable. 145bbeaf6c0SSean Eric Fagan * But slower, from the code I saw. 146bbeaf6c0SSean Eric Fagan */ 147bbeaf6c0SSean Eric Fagan 148bbeaf6c0SSean Eric Fagan static long long 149bbeaf6c0SSean Eric Fagan make_quad(unsigned long p1, unsigned long p2) { 150bbeaf6c0SSean Eric Fagan union { 151bbeaf6c0SSean Eric Fagan long long ll; 152bbeaf6c0SSean Eric Fagan unsigned long l[2]; 153bbeaf6c0SSean Eric Fagan } t; 154bbeaf6c0SSean Eric Fagan t.l[0] = p1; 155bbeaf6c0SSean Eric Fagan t.l[1] = p2; 156bbeaf6c0SSean Eric Fagan return t.ll; 157bbeaf6c0SSean Eric Fagan } 158bbeaf6c0SSean Eric Fagan 159bbeaf6c0SSean Eric Fagan 160bbeaf6c0SSean Eric Fagan /* 161bbeaf6c0SSean Eric Fagan * print_arg 162bbeaf6c0SSean Eric Fagan * Converts a syscall argument into a string. Said string is 163bbeaf6c0SSean Eric Fagan * allocated via malloc(), so needs to be free()'d. The file 164bbeaf6c0SSean Eric Fagan * descriptor is for the process' memory (via /proc), and is used 165bbeaf6c0SSean Eric Fagan * to get any data (where the argument is a pointer). sc is 166bbeaf6c0SSean Eric Fagan * a pointer to the syscall description (see above); args is 167bbeaf6c0SSean Eric Fagan * an array of all of the system call arguments. 168bbeaf6c0SSean Eric Fagan */ 169bbeaf6c0SSean Eric Fagan 170bbeaf6c0SSean Eric Fagan char * 171bbeaf6c0SSean Eric Fagan print_arg(int fd, struct syscall_args *sc, unsigned long *args) { 1723cf51049SPhilippe Charnier char *tmp = NULL; 173bbeaf6c0SSean Eric Fagan switch (sc->type & ARG_MASK) { 174bbeaf6c0SSean Eric Fagan case Hex: 175bbeaf6c0SSean Eric Fagan tmp = malloc(12); 17622694ebaSBruce Evans sprintf(tmp, "0x%lx", args[sc->offset]); 177bbeaf6c0SSean Eric Fagan break; 178bbeaf6c0SSean Eric Fagan case Octal: 179bbeaf6c0SSean Eric Fagan tmp = malloc(13); 18022694ebaSBruce Evans sprintf(tmp, "0%lo", args[sc->offset]); 181bbeaf6c0SSean Eric Fagan break; 182bbeaf6c0SSean Eric Fagan case Int: 183bbeaf6c0SSean Eric Fagan tmp = malloc(12); 18422694ebaSBruce Evans sprintf(tmp, "%ld", args[sc->offset]); 185bbeaf6c0SSean Eric Fagan break; 186bbeaf6c0SSean Eric Fagan case String: 187bbeaf6c0SSean Eric Fagan { 188bbeaf6c0SSean Eric Fagan char *tmp2; 189bbeaf6c0SSean Eric Fagan tmp2 = get_string(fd, (void*)args[sc->offset], 0); 190bbeaf6c0SSean Eric Fagan tmp = malloc(strlen(tmp2) + 3); 191bbeaf6c0SSean Eric Fagan sprintf(tmp, "\"%s\"", tmp2); 192bbeaf6c0SSean Eric Fagan free(tmp2); 193bbeaf6c0SSean Eric Fagan } 194bbeaf6c0SSean Eric Fagan break; 195bbeaf6c0SSean Eric Fagan case Quad: 196bbeaf6c0SSean Eric Fagan { 197bbeaf6c0SSean Eric Fagan unsigned long long t; 198bbeaf6c0SSean Eric Fagan unsigned long l1, l2; 199bbeaf6c0SSean Eric Fagan l1 = args[sc->offset]; 200bbeaf6c0SSean Eric Fagan l2 = args[sc->offset+1]; 201bbeaf6c0SSean Eric Fagan t = make_quad(l1, l2); 202bbeaf6c0SSean Eric Fagan tmp = malloc(24); 203bbeaf6c0SSean Eric Fagan sprintf(tmp, "0x%qx", t); 204bbeaf6c0SSean Eric Fagan break; 205bbeaf6c0SSean Eric Fagan } 206bbeaf6c0SSean Eric Fagan case Ptr: 207bbeaf6c0SSean Eric Fagan tmp = malloc(12); 20822694ebaSBruce Evans sprintf(tmp, "0x%lx", args[sc->offset]); 209bbeaf6c0SSean Eric Fagan break; 210970649f9SSean Eric Fagan case Ioctl: 211970649f9SSean Eric Fagan { 212970649f9SSean Eric Fagan char *temp = ioctlname(args[sc->offset]); 213970649f9SSean Eric Fagan if (temp) 214970649f9SSean Eric Fagan tmp = strdup(temp); 215970649f9SSean Eric Fagan else { 216970649f9SSean Eric Fagan tmp = malloc(12); 21722694ebaSBruce Evans sprintf(tmp, "0x%lx", args[sc->offset]); 218970649f9SSean Eric Fagan } 219970649f9SSean Eric Fagan } 220bbeaf6c0SSean Eric Fagan } 221bbeaf6c0SSean Eric Fagan return tmp; 222bbeaf6c0SSean Eric Fagan } 223bbeaf6c0SSean Eric Fagan 224bbeaf6c0SSean Eric Fagan /* 225bbeaf6c0SSean Eric Fagan * print_syscall 226bbeaf6c0SSean Eric Fagan * Print (to outfile) the system call and its arguments. Note that 227bbeaf6c0SSean Eric Fagan * nargs is the number of arguments (not the number of words; this is 228bbeaf6c0SSean Eric Fagan * potentially confusing, I know). 229bbeaf6c0SSean Eric Fagan */ 230bbeaf6c0SSean Eric Fagan 231bbeaf6c0SSean Eric Fagan void 232bbeaf6c0SSean Eric Fagan print_syscall(FILE *outfile, const char *name, int nargs, char **s_args) { 233bbeaf6c0SSean Eric Fagan int i; 234bbeaf6c0SSean Eric Fagan fprintf(outfile, "syscall %s(", name); 235bbeaf6c0SSean Eric Fagan for (i = 0; i < nargs; i++) { 236bbeaf6c0SSean Eric Fagan if (s_args[i]) 237bbeaf6c0SSean Eric Fagan fprintf(outfile, "%s", s_args[i]); 238bbeaf6c0SSean Eric Fagan else 239bbeaf6c0SSean Eric Fagan fprintf(outfile, "<missing argument>"); 240bbeaf6c0SSean Eric Fagan fprintf(outfile, "%s", i < (nargs - 1) ? "," : ""); 241bbeaf6c0SSean Eric Fagan } 242bbeaf6c0SSean Eric Fagan fprintf(outfile, ")\n\t"); 243bbeaf6c0SSean Eric Fagan } 244