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
|
/* Functions for the Linux module syscall interface.
Copyright 1996, 1997 Linux International.
Contributed by Richard Henderson <rth@tamu.edu>
This file is part of the Linux modutils.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ident "$Id$"
#include <stdlib.h>
#include <errno.h>
#include "module.h"
/* Kernel headers before 2.1.mumble need this on the Alpha to get
_syscall* defined. */
#define __LIBRARY__
#include <asm/unistd.h>
/*======================================================================*/
#if defined(__i386__) || defined(__m68k__) || defined(__arm__)
#define __NR__create_module __NR_create_module
static inline _syscall2(long, _create_module, const char *, name, size_t, size)
unsigned long create_module(const char *name, size_t size)
{
/* Why all this fuss?
In linux 2.1, the address returned by create module point in
kernel space which is now mapped at the top of user space (at
0xc0000000 on i386). This looks like a negative number for a
long. The normal syscall macro of linux 2.0 (and all libc compile
with linux 2.0 or below) consider that the return value is a
negative number and consider it is an error number (A kernel
convention, return value are positive or negative, indicating the
error number).
By checking the value of errno, we know if we have been fooled by
the syscall2 macro and we fix it. */
long ret = _create_module(name, size);
if (ret == -1 && errno > 125)
{
ret = -errno;
errno = 0;
}
return ret;
}
#elif defined(__alpha__)
/* Alpha doesn't have the same problem, exactly, but a bug in older
kernels fails to clear the error flag. Clear it here explicitly. */
#define __NR__create_module __NR_create_module
static inline _syscall4(unsigned long, _create_module, const char *, name,
size_t, size, size_t, dummy, size_t, err);
unsigned long create_module(const char *name, size_t size)
{
return _create_module(name, size, 0, 0);
}
#else
/* Sparc, MIPS, (and Alpha, but that's another problem) don't mistake
return values for errors due to the nature of the system call. */
_syscall2(unsigned long, create_module, const char *, name, size_t, size)
#endif
|