blob: a607d169c9cd61502b6e39275311ca77cadce8cc [file] [log] [blame]
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00001/*
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.
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +000029 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000030
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010031#include "defs.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000032#include <fcntl.h>
33#include <sys/stat.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000034#include <sys/wait.h>
35#include <sys/resource.h>
36#include <sys/utsname.h>
Wichert Akkerman7b3346b2001-10-09 23:47:38 +000037
38/* Bits of module.flags. */
39
40#define MOD_UNINITIALIZED 0
41#define MOD_RUNNING 1
42#define MOD_DELETED 2
43#define MOD_AUTOCLEAN 4
Denys Vlasenkob63256e2011-06-07 12:13:24 +020044#define MOD_VISITED 8
Wichert Akkerman7b3346b2001-10-09 23:47:38 +000045#define MOD_USED_ONCE 16
46#define MOD_JUST_FREED 32
47#define MOD_INITIALIZING 64
48
49/* Values for query_module's which. */
50
51#define QM_MODULES 1
52#define QM_DEPS 2
53#define QM_REFS 3
54#define QM_SYMBOLS 4
55#define QM_INFO 5
56
57struct module_symbol
58{
59 unsigned long value;
60 const char *name;
61};
62
63struct module_info
64{
65 unsigned long addr;
66 unsigned long size;
67 unsigned long flags;
68 long usecount;
69};
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000070
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000071#include "xlat/qm_which.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000072#include "xlat/modflags.h"
Dmitry V. Levind04bb2b2014-06-04 15:51:55 +000073#include "xlat/delete_module_flags.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000074
Dmitry V. Levina0bd3742015-04-07 01:36:50 +000075SYS_FUNC(query_module)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000076{
Dmitry V. Levin62e05962009-11-03 14:38:44 +000077 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000078 printstr(tcp, tcp->u_arg[0], -1);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +020079 tprints(", ");
Dmitry V. Levin297b5942014-04-25 23:39:20 +000080 printxval(qm_which, tcp->u_arg[1], "QM_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +020081 tprints(", ");
Dmitry V. Levin62e05962009-11-03 14:38:44 +000082 } else {
83 size_t ret;
84
85 if (!verbose(tcp) || syserror(tcp) ||
86 umove(tcp, tcp->u_arg[4], &ret) < 0) {
87 tprintf("%#lx, %lu, %#lx", tcp->u_arg[2],
88 tcp->u_arg[3], tcp->u_arg[4]);
Wichert Akkerman9123ac81999-11-27 21:58:20 +000089 } else if (tcp->u_arg[1]==QM_INFO) {
90 struct module_info mi;
Dmitry V. Levin62e05962009-11-03 14:38:44 +000091 if (umove(tcp, tcp->u_arg[2], &mi) < 0) {
92 tprintf("%#lx, ", tcp->u_arg[2]);
93 } else {
94 tprintf("{address=%#lx, size=%lu, flags=",
95 mi.addr, mi.size);
96 printflags(modflags, mi.flags, "MOD_???");
97 tprintf(", usecount=%lu}, ", mi.usecount);
98 }
Denys Vlasenko048cc422012-05-16 12:20:17 +020099 tprintf("%lu", (unsigned long)ret);
Wichert Akkerman9123ac81999-11-27 21:58:20 +0000100 } else if ((tcp->u_arg[1]==QM_MODULES) ||
Dmitry V. Levin414fe7d2009-07-08 11:21:17 +0000101 (tcp->u_arg[1]==QM_DEPS) ||
102 (tcp->u_arg[1]==QM_REFS)) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200103 tprints("{");
Wichert Akkermanaec62381999-11-28 01:56:12 +0000104 if (!abbrev(tcp)) {
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000105 char* data = malloc(tcp->u_arg[3]);
Wichert Akkermanaec62381999-11-28 01:56:12 +0000106 char* mod = data;
107 size_t idx;
108
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000109 if (!data) {
Dmitry V. Levindf389912015-05-25 23:33:31 +0300110 error_msg("Out of memory");
Denys Vlasenko048cc422012-05-16 12:20:17 +0200111 tprintf(" /* %lu entries */ ", (unsigned long)ret);
Wichert Akkermanc7926982000-04-10 22:22:31 +0000112 } else {
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000113 if (umoven(tcp, tcp->u_arg[2],
114 tcp->u_arg[3], data) < 0) {
Denys Vlasenko048cc422012-05-16 12:20:17 +0200115 tprintf(" /* %lu entries */ ", (unsigned long)ret);
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000116 } else {
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200117 for (idx = 0; idx < ret; idx++) {
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000118 tprintf("%s%s",
119 (idx ? ", " : ""),
120 mod);
121 mod += strlen(mod)+1;
122 }
Wichert Akkermanc7926982000-04-10 22:22:31 +0000123 }
124 free(data);
Wichert Akkermanaec62381999-11-28 01:56:12 +0000125 }
Roland McGrathd9f816f2004-09-04 03:39:20 +0000126 } else
Denys Vlasenko048cc422012-05-16 12:20:17 +0200127 tprintf(" /* %lu entries */ ", (unsigned long)ret);
128 tprintf("}, %lu", (unsigned long)ret);
Wichert Akkerman9123ac81999-11-27 21:58:20 +0000129 } else if (tcp->u_arg[1]==QM_SYMBOLS) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200130 tprints("{");
Wichert Akkermanaec62381999-11-28 01:56:12 +0000131 if (!abbrev(tcp)) {
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000132 char* data = malloc(tcp->u_arg[3]);
Wichert Akkermanaec62381999-11-28 01:56:12 +0000133 struct module_symbol* sym = (struct module_symbol*)data;
134 size_t idx;
135
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000136 if (!data) {
Dmitry V. Levindf389912015-05-25 23:33:31 +0300137 error_msg("Out of memory");
Denys Vlasenko048cc422012-05-16 12:20:17 +0200138 tprintf(" /* %lu entries */ ", (unsigned long)ret);
Wichert Akkermanc7926982000-04-10 22:22:31 +0000139 } else {
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000140 if (umoven(tcp, tcp->u_arg[2],
141 tcp->u_arg[3], data) < 0) {
Denys Vlasenko048cc422012-05-16 12:20:17 +0200142 tprintf(" /* %lu entries */ ", (unsigned long)ret);
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000143 } else {
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200144 for (idx = 0; idx < ret; idx++) {
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000145 tprintf("%s{name=%s, value=%lu}",
146 (idx ? " " : ""),
147 data+(long)sym->name,
148 sym->value);
149 sym++;
150 }
Wichert Akkermanc7926982000-04-10 22:22:31 +0000151 }
152 free(data);
Wichert Akkermanaec62381999-11-28 01:56:12 +0000153 }
Wichert Akkermanaec62381999-11-28 01:56:12 +0000154 } else
Denys Vlasenko048cc422012-05-16 12:20:17 +0200155 tprintf(" /* %lu entries */ ", (unsigned long)ret);
156 tprintf("}, %ld", (unsigned long)ret);
Wichert Akkerman9123ac81999-11-27 21:58:20 +0000157 } else {
158 printstr(tcp, tcp->u_arg[2], tcp->u_arg[3]);
159 tprintf(", %#lx", tcp->u_arg[4]);
160 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000161 }
162 return 0;
163}
164
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000165SYS_FUNC(create_module)
Wichert Akkerman50524821999-10-10 22:40:07 +0000166{
Dmitry V. Levind9e87922015-07-20 19:35:42 +0000167 printpath(tcp, tcp->u_arg[0]);
168 tprintf(", %lu", tcp->u_arg[1]);
169
170 return RVAL_DECODED | RVAL_HEX;
Wichert Akkerman50524821999-10-10 22:40:07 +0000171}
172
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000173SYS_FUNC(delete_module)
Dmitry V. Levind04bb2b2014-06-04 15:51:55 +0000174{
Dmitry V. Levind9e87922015-07-20 19:35:42 +0000175 printstr(tcp, tcp->u_arg[0], -1);
176 tprints(", ");
177 printflags(delete_module_flags, tcp->u_arg[1], "O_???");
178
179 return RVAL_DECODED;
Dmitry V. Levind04bb2b2014-06-04 15:51:55 +0000180}
181
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000182SYS_FUNC(init_module)
Wichert Akkerman2f473da1999-11-01 19:53:31 +0000183{
Dmitry V. Levind9e87922015-07-20 19:35:42 +0000184 tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
185 printstr(tcp, tcp->u_arg[2], -1);
186
187 return RVAL_DECODED;
Wichert Akkerman2f473da1999-11-01 19:53:31 +0000188}
Dmitry V. Levinf67502e2014-02-05 16:17:02 +0000189
190#define MODULE_INIT_IGNORE_MODVERSIONS 1
191#define MODULE_INIT_IGNORE_VERMAGIC 2
192
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000193#include "xlat/module_init_flags.h"
Dmitry V. Levinf67502e2014-02-05 16:17:02 +0000194
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000195SYS_FUNC(finit_module)
Dmitry V. Levinf67502e2014-02-05 16:17:02 +0000196{
Dmitry V. Levinf67502e2014-02-05 16:17:02 +0000197 /* file descriptor */
198 printfd(tcp, tcp->u_arg[0]);
199 tprints(", ");
200 /* param_values */
201 printstr(tcp, tcp->u_arg[1], -1);
202 tprints(", ");
203 /* flags */
204 printflags(module_init_flags, tcp->u_arg[2], "MODULE_INIT_???");
205
Dmitry V. Levind9e87922015-07-20 19:35:42 +0000206 return RVAL_DECODED;
Dmitry V. Levinf67502e2014-02-05 16:17:02 +0000207}