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 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * $Id$ 31 */ 32#include "defs.h" 33 34#if defined(LINUX) 35 36#include <fcntl.h> 37#include <sys/stat.h> 38#include <sys/time.h> 39#include <sys/wait.h> 40#include <sys/resource.h> 41#include <sys/utsname.h> 42#ifndef HAVE_ANDROID_OS 43#include <sys/user.h> 44#endif 45#include <sys/syscall.h> 46#include <signal.h> 47 48/* Bits of module.flags. */ 49 50#define MOD_UNINITIALIZED 0 51#define MOD_RUNNING 1 52#define MOD_DELETED 2 53#define MOD_AUTOCLEAN 4 54#define MOD_VISITED 8 55#define MOD_USED_ONCE 16 56#define MOD_JUST_FREED 32 57#define MOD_INITIALIZING 64 58 59/* Values for query_module's which. */ 60 61#define QM_MODULES 1 62#define QM_DEPS 2 63#define QM_REFS 3 64#define QM_SYMBOLS 4 65#define QM_INFO 5 66 67struct module_symbol 68{ 69 unsigned long value; 70 const char *name; 71}; 72 73struct module_info 74{ 75 unsigned long addr; 76 unsigned long size; 77 unsigned long flags; 78 long usecount; 79}; 80 81static const struct xlat which[] = { 82 { 0, "0" }, 83 { QM_MODULES, "QM_MODULES" }, 84 { QM_DEPS, "QM_DEPS" }, 85 { QM_REFS, "QM_REFS" }, 86 { QM_SYMBOLS, "QM_SYMBOLS" }, 87 { QM_INFO, "QM_INFO" }, 88 { 0, NULL }, 89}; 90 91static const struct xlat modflags[] = { 92 { MOD_UNINITIALIZED, "MOD_UNINITIALIZED" }, 93 { MOD_RUNNING, "MOD_RUNNING" }, 94 { MOD_DELETED, "MOD_DELETED" }, 95 { MOD_AUTOCLEAN, "MOD_AUTOCLEAN" }, 96 { MOD_VISITED, "MOD_VISITED" }, 97 { MOD_USED_ONCE, "MOD_USED_ONCE" }, 98 { MOD_JUST_FREED, "MOD_JUST_FREED" }, 99 { 0, NULL }, 100}; 101 102int 103sys_query_module(struct tcb *tcp) 104{ 105 if (entering(tcp)) { 106 printstr(tcp, tcp->u_arg[0], -1); 107 tprintf(", "); 108 printxval(which, tcp->u_arg[1], "QM_???"); 109 tprintf(", "); 110 } else { 111 size_t ret; 112 113 if (!verbose(tcp) || syserror(tcp) || 114 umove(tcp, tcp->u_arg[4], &ret) < 0) { 115 tprintf("%#lx, %lu, %#lx", tcp->u_arg[2], 116 tcp->u_arg[3], tcp->u_arg[4]); 117 } else if (tcp->u_arg[1]==QM_INFO) { 118 struct module_info mi; 119 if (umove(tcp, tcp->u_arg[2], &mi) < 0) { 120 tprintf("%#lx, ", tcp->u_arg[2]); 121 } else { 122 tprintf("{address=%#lx, size=%lu, flags=", 123 mi.addr, mi.size); 124 printflags(modflags, mi.flags, "MOD_???"); 125 tprintf(", usecount=%lu}, ", mi.usecount); 126 } 127 tprintf("%Zu", ret); 128 } else if ((tcp->u_arg[1]==QM_MODULES) || 129 (tcp->u_arg[1]==QM_DEPS) || 130 (tcp->u_arg[1]==QM_REFS)) { 131 tprintf("{"); 132 if (!abbrev(tcp)) { 133 char* data = malloc(tcp->u_arg[3]); 134 char* mod = data; 135 size_t idx; 136 137 if (!data) { 138 fprintf(stderr, "out of memory\n"); 139 tprintf(" /* %Zu entries */ ", ret); 140 } else { 141 if (umoven(tcp, tcp->u_arg[2], 142 tcp->u_arg[3], data) < 0) { 143 tprintf(" /* %Zu entries */ ", ret); 144 } else { 145 for (idx=0; idx<ret; idx++) { 146 tprintf("%s%s", 147 (idx ? ", " : ""), 148 mod); 149 mod += strlen(mod)+1; 150 } 151 } 152 free(data); 153 } 154 } else 155 tprintf(" /* %Zu entries */ ", ret); 156 tprintf("}, %Zu", ret); 157 } else if (tcp->u_arg[1]==QM_SYMBOLS) { 158 tprintf("{"); 159 if (!abbrev(tcp)) { 160 char* data = malloc(tcp->u_arg[3]); 161 struct module_symbol* sym = (struct module_symbol*)data; 162 size_t idx; 163 164 if (!data) { 165 fprintf(stderr, "out of memory\n"); 166 tprintf(" /* %Zu entries */ ", ret); 167 } else { 168 if (umoven(tcp, tcp->u_arg[2], 169 tcp->u_arg[3], data) < 0) { 170 tprintf(" /* %Zu entries */ ", ret); 171 } else { 172 for (idx=0; idx<ret; idx++) { 173 tprintf("%s{name=%s, value=%lu}", 174 (idx ? " " : ""), 175 data+(long)sym->name, 176 sym->value); 177 sym++; 178 } 179 } 180 free(data); 181 } 182 } else 183 tprintf(" /* %Zu entries */ ", ret); 184 tprintf("}, %Zd", ret); 185 } else { 186 printstr(tcp, tcp->u_arg[2], tcp->u_arg[3]); 187 tprintf(", %#lx", tcp->u_arg[4]); 188 } 189 } 190 return 0; 191} 192 193int 194sys_create_module(tcp) 195struct tcb *tcp; 196{ 197 if (entering(tcp)) { 198 printpath(tcp, tcp->u_arg[0]); 199 tprintf(", %lu", tcp->u_arg[1]); 200 } 201 return RVAL_HEX; 202} 203 204int 205sys_init_module(tcp) 206struct tcb *tcp; 207{ 208 if (entering(tcp)) { 209 tprintf("%#lx, ", tcp->u_arg[0]); 210 tprintf("%lu, ", tcp->u_arg[1]); 211 printstr(tcp, tcp->u_arg[2], -1); 212 } 213 return 0; 214} 215#endif /* LINUX */ 216