1bbeaf6c0SSean Eric Fagan /* 2bbeaf6c0SSean Eric Fagan * This file has routines used to print out system calls and their 3bbeaf6c0SSean Eric Fagan * arguments. 4bbeaf6c0SSean Eric Fagan */ 5bbeaf6c0SSean Eric Fagan /* 6970649f9SSean Eric Fagan * $Id: syscalls.c,v 1.1 1997/12/06 05:23:10 sef Exp $ 7bbeaf6c0SSean Eric Fagan */ 8bbeaf6c0SSean Eric Fagan 9bbeaf6c0SSean Eric Fagan #include <stdio.h> 10bbeaf6c0SSean Eric Fagan #include <stdlib.h> 11bbeaf6c0SSean Eric Fagan #include <string.h> 12bbeaf6c0SSean Eric Fagan #include <unistd.h> 13bbeaf6c0SSean Eric Fagan #include <sys/types.h> 14bbeaf6c0SSean Eric Fagan #include "syscall.h" 15bbeaf6c0SSean Eric Fagan 16bbeaf6c0SSean Eric Fagan /* 17bbeaf6c0SSean Eric Fagan * This should probably be in its own file. 18bbeaf6c0SSean Eric Fagan */ 19bbeaf6c0SSean Eric Fagan 20bbeaf6c0SSean Eric Fagan struct syscall syscalls[] = { 21bbeaf6c0SSean Eric Fagan { "readlink", 1, 3, 22bbeaf6c0SSean Eric Fagan { { String, 0 } , { String | OUT, 1 }, { Int, 2 }}}, 23bbeaf6c0SSean Eric Fagan { "lseek", 2, 3, 24bbeaf6c0SSean Eric Fagan { { Int, 0 }, {Quad, 2 }, { Int, 4 }}}, 25bbeaf6c0SSean Eric Fagan { "mmap", 2, 6, 26bbeaf6c0SSean Eric Fagan { { Hex, 0 }, {Int, 1}, {Hex, 2}, {Hex, 3}, {Int, 4}, {Quad, 6}}}, 27bbeaf6c0SSean Eric Fagan { "open", 1, 3, 28bbeaf6c0SSean Eric Fagan { { String | IN, 0} , { Int, 1}, {Octal, 2}}}, 29bbeaf6c0SSean Eric Fagan { "linux_open", 1, 3, 30bbeaf6c0SSean Eric Fagan { { String, 0 }, { Int, 1}, { Octal, 2 }}}, 31bbeaf6c0SSean Eric Fagan { "close", 1, 1, { { Int, 0 } } }, 32bbeaf6c0SSean Eric Fagan { "fstat", 1, 2, 33bbeaf6c0SSean Eric Fagan { { Int, 0}, {Ptr | OUT , 1 }}}, 34bbeaf6c0SSean Eric Fagan { "stat", 1, 2, 35bbeaf6c0SSean Eric Fagan { { String | IN, 0 }, { Ptr | OUT, 1 }}}, 36bbeaf6c0SSean Eric Fagan { "linux_newstat", 1, 2, 37bbeaf6c0SSean Eric Fagan { { String | IN, 0 }, { Ptr | OUT, 1 }}}, 38bbeaf6c0SSean Eric Fagan { "linux_newfstat", 1, 2, 39bbeaf6c0SSean Eric Fagan { { Int, 0 }, { Ptr | OUT, 1 }}}, 40bbeaf6c0SSean Eric Fagan { "write", 1, 3, 41bbeaf6c0SSean Eric Fagan { { Int, 0}, { Ptr | IN, 1 }, { Int, 2 }}}, 42970649f9SSean Eric Fagan { "ioctl", 1, 3, 43970649f9SSean Eric Fagan { { Int, 0}, { Ioctl, 1 }, { Hex, 2 }}}, 44bbeaf6c0SSean Eric Fagan { "break", 1, 1, { { Hex, 0 }}}, 45bbeaf6c0SSean Eric Fagan { "exit", 0, 1, { { Hex, 0 }}}, 46bbeaf6c0SSean Eric Fagan { 0, 0, 0, { 0, 0 } }, 47bbeaf6c0SSean Eric Fagan }; 48bbeaf6c0SSean Eric Fagan 49bbeaf6c0SSean Eric Fagan /* 50bbeaf6c0SSean Eric Fagan * If/when the list gets big, it might be desirable to do it 51bbeaf6c0SSean Eric Fagan * as a hash table or binary search. 52bbeaf6c0SSean Eric Fagan */ 53bbeaf6c0SSean Eric Fagan 54bbeaf6c0SSean Eric Fagan struct syscall * 55bbeaf6c0SSean Eric Fagan get_syscall(const char *name) { 56bbeaf6c0SSean Eric Fagan struct syscall *sc = syscalls; 57bbeaf6c0SSean Eric Fagan 58bbeaf6c0SSean Eric Fagan while (sc->name) { 59bbeaf6c0SSean Eric Fagan if (!strcmp(name, sc->name)) 60bbeaf6c0SSean Eric Fagan return sc; 61bbeaf6c0SSean Eric Fagan sc++; 62bbeaf6c0SSean Eric Fagan } 63bbeaf6c0SSean Eric Fagan return NULL; 64bbeaf6c0SSean Eric Fagan } 65bbeaf6c0SSean Eric Fagan 66bbeaf6c0SSean Eric Fagan /* 67bbeaf6c0SSean Eric Fagan * get_string 68bbeaf6c0SSean Eric Fagan * Copy a string from the process. Note that it is 69bbeaf6c0SSean Eric Fagan * expected to be a C string, but if max is set, it will 70bbeaf6c0SSean Eric Fagan * only get that much. 71bbeaf6c0SSean Eric Fagan */ 72bbeaf6c0SSean Eric Fagan 73bbeaf6c0SSean Eric Fagan char * 74bbeaf6c0SSean Eric Fagan get_string(int procfd, void *offset, int max) { 75bbeaf6c0SSean Eric Fagan char *buf, *tmp; 76bbeaf6c0SSean Eric Fagan int size, len, c; 77bbeaf6c0SSean Eric Fagan FILE *p; 78bbeaf6c0SSean Eric Fagan 79bbeaf6c0SSean Eric Fagan if ((p = fdopen(procfd, "r")) == NULL) { 80bbeaf6c0SSean Eric Fagan perror("fdopen"); 81bbeaf6c0SSean Eric Fagan exit(1); 82bbeaf6c0SSean Eric Fagan } 83bbeaf6c0SSean Eric Fagan buf = malloc( size = (max ? max : 64 ) ); 84bbeaf6c0SSean Eric Fagan len = 0; 85bbeaf6c0SSean Eric Fagan fseek(p, (long)offset, SEEK_SET); 86bbeaf6c0SSean Eric Fagan while ((c = fgetc(p)) != EOF) { 87bbeaf6c0SSean Eric Fagan buf[len++] = c; 88bbeaf6c0SSean Eric Fagan if (c == 0 || len == max) { 89bbeaf6c0SSean Eric Fagan buf[len] = 0; 90bbeaf6c0SSean Eric Fagan break; 91bbeaf6c0SSean Eric Fagan } 92bbeaf6c0SSean Eric Fagan if (len == size) { 93bbeaf6c0SSean Eric Fagan char *tmp = buf; 94bbeaf6c0SSean Eric Fagan tmp = realloc(buf, size+64); 95bbeaf6c0SSean Eric Fagan if (tmp == NULL) { 96bbeaf6c0SSean Eric Fagan buf[len] = 0; 97bbeaf6c0SSean Eric Fagan return buf; 98bbeaf6c0SSean Eric Fagan } 99bbeaf6c0SSean Eric Fagan size += 64; 100bbeaf6c0SSean Eric Fagan } 101bbeaf6c0SSean Eric Fagan } 102bbeaf6c0SSean Eric Fagan return buf; 103bbeaf6c0SSean Eric Fagan } 104bbeaf6c0SSean Eric Fagan 105bbeaf6c0SSean Eric Fagan 106bbeaf6c0SSean Eric Fagan /* 107bbeaf6c0SSean Eric Fagan * Gag. This is really unportable. Multiplication is more portable. 108bbeaf6c0SSean Eric Fagan * But slower, from the code I saw. 109bbeaf6c0SSean Eric Fagan */ 110bbeaf6c0SSean Eric Fagan 111bbeaf6c0SSean Eric Fagan static long long 112bbeaf6c0SSean Eric Fagan make_quad(unsigned long p1, unsigned long p2) { 113bbeaf6c0SSean Eric Fagan union { 114bbeaf6c0SSean Eric Fagan long long ll; 115bbeaf6c0SSean Eric Fagan unsigned long l[2]; 116bbeaf6c0SSean Eric Fagan } t; 117bbeaf6c0SSean Eric Fagan t.l[0] = p1; 118bbeaf6c0SSean Eric Fagan t.l[1] = p2; 119bbeaf6c0SSean Eric Fagan return t.ll; 120bbeaf6c0SSean Eric Fagan } 121bbeaf6c0SSean Eric Fagan 122bbeaf6c0SSean Eric Fagan 123bbeaf6c0SSean Eric Fagan /* 124bbeaf6c0SSean Eric Fagan * print_arg 125bbeaf6c0SSean Eric Fagan * Converts a syscall argument into a string. Said string is 126bbeaf6c0SSean Eric Fagan * allocated via malloc(), so needs to be free()'d. The file 127bbeaf6c0SSean Eric Fagan * descriptor is for the process' memory (via /proc), and is used 128bbeaf6c0SSean Eric Fagan * to get any data (where the argument is a pointer). sc is 129bbeaf6c0SSean Eric Fagan * a pointer to the syscall description (see above); args is 130bbeaf6c0SSean Eric Fagan * an array of all of the system call arguments. 131bbeaf6c0SSean Eric Fagan */ 132bbeaf6c0SSean Eric Fagan 133bbeaf6c0SSean Eric Fagan char * 134bbeaf6c0SSean Eric Fagan print_arg(int fd, struct syscall_args *sc, unsigned long *args) { 135bbeaf6c0SSean Eric Fagan char *tmp; 136bbeaf6c0SSean Eric Fagan switch (sc->type & ARG_MASK) { 137bbeaf6c0SSean Eric Fagan case Hex: 138bbeaf6c0SSean Eric Fagan tmp = malloc(12); 139bbeaf6c0SSean Eric Fagan sprintf(tmp, "0x%x", args[sc->offset]); 140bbeaf6c0SSean Eric Fagan break; 141bbeaf6c0SSean Eric Fagan case Octal: 142bbeaf6c0SSean Eric Fagan tmp = malloc(13); 143bbeaf6c0SSean Eric Fagan sprintf(tmp, "0%o", args[sc->offset]); 144bbeaf6c0SSean Eric Fagan break; 145bbeaf6c0SSean Eric Fagan case Int: 146bbeaf6c0SSean Eric Fagan tmp = malloc(12); 147bbeaf6c0SSean Eric Fagan sprintf(tmp, "%d", args[sc->offset]); 148bbeaf6c0SSean Eric Fagan break; 149bbeaf6c0SSean Eric Fagan case String: 150bbeaf6c0SSean Eric Fagan { 151bbeaf6c0SSean Eric Fagan char *tmp2; 152bbeaf6c0SSean Eric Fagan tmp2 = get_string(fd, (void*)args[sc->offset], 0); 153bbeaf6c0SSean Eric Fagan tmp = malloc(strlen(tmp2) + 3); 154bbeaf6c0SSean Eric Fagan sprintf(tmp, "\"%s\"", tmp2); 155bbeaf6c0SSean Eric Fagan free(tmp2); 156bbeaf6c0SSean Eric Fagan } 157bbeaf6c0SSean Eric Fagan break; 158bbeaf6c0SSean Eric Fagan case Quad: 159bbeaf6c0SSean Eric Fagan { 160bbeaf6c0SSean Eric Fagan unsigned long long t; 161bbeaf6c0SSean Eric Fagan unsigned long l1, l2; 162bbeaf6c0SSean Eric Fagan l1 = args[sc->offset]; 163bbeaf6c0SSean Eric Fagan l2 = args[sc->offset+1]; 164bbeaf6c0SSean Eric Fagan t = make_quad(l1, l2); 165bbeaf6c0SSean Eric Fagan tmp = malloc(24); 166bbeaf6c0SSean Eric Fagan sprintf(tmp, "0x%qx", t); 167bbeaf6c0SSean Eric Fagan break; 168bbeaf6c0SSean Eric Fagan } 169bbeaf6c0SSean Eric Fagan case Ptr: 170bbeaf6c0SSean Eric Fagan tmp = malloc(12); 171bbeaf6c0SSean Eric Fagan sprintf(tmp, "0x%x", args[sc->offset]); 172bbeaf6c0SSean Eric Fagan break; 173970649f9SSean Eric Fagan case Ioctl: 174970649f9SSean Eric Fagan { 175970649f9SSean Eric Fagan char *temp = ioctlname(args[sc->offset]); 176970649f9SSean Eric Fagan if (temp) 177970649f9SSean Eric Fagan tmp = strdup(temp); 178970649f9SSean Eric Fagan else { 179970649f9SSean Eric Fagan tmp = malloc(12); 180970649f9SSean Eric Fagan sprintf(tmp, "0x%x", args[sc->offset]); 181970649f9SSean Eric Fagan } 182970649f9SSean Eric Fagan } 183bbeaf6c0SSean Eric Fagan } 184bbeaf6c0SSean Eric Fagan return tmp; 185bbeaf6c0SSean Eric Fagan } 186bbeaf6c0SSean Eric Fagan 187bbeaf6c0SSean Eric Fagan /* 188bbeaf6c0SSean Eric Fagan * print_syscall 189bbeaf6c0SSean Eric Fagan * Print (to outfile) the system call and its arguments. Note that 190bbeaf6c0SSean Eric Fagan * nargs is the number of arguments (not the number of words; this is 191bbeaf6c0SSean Eric Fagan * potentially confusing, I know). 192bbeaf6c0SSean Eric Fagan */ 193bbeaf6c0SSean Eric Fagan 194bbeaf6c0SSean Eric Fagan void 195bbeaf6c0SSean Eric Fagan print_syscall(FILE *outfile, const char *name, int nargs, char **s_args) { 196bbeaf6c0SSean Eric Fagan int i; 197bbeaf6c0SSean Eric Fagan fprintf(outfile, "syscall %s(", name); 198bbeaf6c0SSean Eric Fagan for (i = 0; i < nargs; i++) { 199bbeaf6c0SSean Eric Fagan if (s_args[i]) 200bbeaf6c0SSean Eric Fagan fprintf(outfile, "%s", s_args[i]); 201bbeaf6c0SSean Eric Fagan else 202bbeaf6c0SSean Eric Fagan fprintf(outfile, "<missing argument>"); 203bbeaf6c0SSean Eric Fagan fprintf(outfile, "%s", i < (nargs - 1) ? "," : ""); 204bbeaf6c0SSean Eric Fagan } 205bbeaf6c0SSean Eric Fagan fprintf(outfile, ")\n\t"); 206bbeaf6c0SSean Eric Fagan } 207