summaryrefslogtreecommitdiffstats
path: root/share/examples/lkm/misc/module/miscmod.c
blob: bfb5589e817b8a60ff9384e7d77dded9e98869e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/* 25 May 93*/
/*
 * miscmod.c
 *
 * 05 Jun 93	Terry Lambert		Split mycall.c out
 * 25 May 93	Terry Lambert		Original
 *
 * Copyright (c) 1993 Terrence R. Lambert.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Terrence R. Lambert.
 * 4. The name Terrence R. Lambert may not be used to endorse or promote
 *    products derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
#include <sys/exec.h>
#include <sys/sysent.h>
#include <sys/lkm.h>

/* XXX this should be in a header. */
extern int	misccall __P((struct proc *p, void *uap));

/*
 * These two entries define our system call and module information.  We
 * have 0 arguments to our system call.
 */
static struct sysent newent = {
	0,	misccall		/* # of args, function pointer*/
};

/*
 * Miscellaneous modules must have their own save areas...
 */
static struct sysent	oldent;		/* save are for old callslot entry*/

/*
 * Number of syscall entries for a.out executables
 */
#define nsysent (aout_sysvec.sv_size)

MOD_MISC( misc);


/*
 * This function is called each time the module is loaded or unloaded.
 * Since we are a miscellaneous module, we have to provide whatever
 * code is necessary to patch ourselves into the area we are being
 * loaded to change.
 *
 * For the system call table, we duplicate the code in the kern_lkm.c
 * file for patching into the system call table.  We can tell what
 * has been allocated, etc. by virtue of the fact that we know the
 * criteria used by the system call loader interface.  We still
 * kick out the copyright to the console here (to give an example).
 *
 * The stat information is basically common to all modules, so there
 * is no real issue involved with stat; we will leave it lkm_nullcmd(),
 * cince we don't have to do anything about it.
 */
static int
misc_load( lkmtp, cmd)
struct lkm_table	*lkmtp;
int			cmd;
{
	int			i;
	struct lkm_misc		*args = lkmtp->private.lkm_misc;
	int			err = 0;	/* default = success*/

	switch( cmd) {
	case LKM_E_LOAD:

		/*
		 * Don't load twice! (lkmexists() is exported by kern_lkm.c)
		 */
		if( lkmexists( lkmtp))
			return( EEXIST);

		/*
		 * This is where we would express a slot preference if
		 * we had one; since we don't, we will simply duplicate
		 * the "auto" code and forget the other.
		 */

		/*
		 * Search the table looking for a slot...
		 */
		for( i = 0; i < nsysent; i++)
			if( sysent[ i].sy_call == (sy_call_t *)lkmnosys)
				break;		/* found it!*/
		/* out of allocable slots?*/
		if( i == nsysent) {
			err = ENFILE;
			break;
		}

		/* save old -- we must provide our own data area*/
		bcopy( &sysent[ i], &oldent, sizeof( struct sysent));

		/* replace with new*/
		bcopy( &newent, &sysent[ i], sizeof( struct sysent));

		/* done!*/
		args->lkm_offset = i;	/* slot in sysent[]*/


		/* if we make it to here, print copyright on console*/
		printf( "\nSample Loaded miscellaneous module (system call)\n");
		printf( "Copyright (c) 1993\n");
		printf( "Terrence R. Lambert\n");
		printf( "All rights reserved\n");

		break;		/* Success*/

	case LKM_E_UNLOAD:
		/* current slot...*/
		i = args->lkm_offset;

		/* replace current slot contents with old contents*/
		bcopy( &oldent, &sysent[ i], sizeof( struct sysent));

		break;		/* Success*/

	default:	/* we only understand load/unload*/
		err = EINVAL;
		break;
	}

	return( err);
}

/*
 * External entry point; should generally match name of .o file.  The
 * arguments are always the same for all loaded modules.  The "load",
 * "unload", and "stat" functions in "DISPATCH" will be called under
 * their respective circumstances unless their value is "lkm_nullcmd".  If
 * called, they are called with the same arguments (cmd is included to
 * allow the use of a single function, ver is included for version
 * matching between modules and the kernel loader for the modules).
 *
 * Since we expect to link in the kernel and add external symbols to
 * the kernel symbol name space in a future version, generally all
 * functions used in the implementation of a particular module should
 * be static unless they are expected to be seen in other modules or
 * to resolve unresolved symbols alread existing in the kernel (the
 * second case is not likely to ever occur).
 *
 * The entry point should return 0 unless it is refusing load (in which
 * case it should return an errno from errno.h).
 */
int
misc_mod( lkmtp, cmd, ver)
struct lkm_table	*lkmtp;
int			cmd;
int			ver;
{
	MOD_DISPATCH(misc, lkmtp, cmd, ver,
		misc_load, misc_load, lkm_nullcmd);
}
OpenPOWER on IntegriCloud