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
|
#!/bin/sh
#
# Given a list of objects, strip all static symbols except those
# required by insmod.
#
# Copyright Keith Owens <kaos@ocs.com.au>. GPL.
# Sat Feb 1 12:52:17 EST 1997
#
# Mainly intended for reducing the size of modules to save space
# on emergency and install disks. Be aware that removing the
# static symbols reduces the amount of diagnostic information
# available for oops. Not recommended for normal module usage.
#
# This code requires the modules use MODULE_PARM and EXPORT_.
# Do not strip modules that have not been converted to use
# MODULE_PARM or are using the old method of exporting symbols.
# In particular do not use on modules prior to 2.1.20 (approx).
#
# The objects are stripped in /tmp, only if the strip works is
# the original overwritten. If the command line to strip the
# symbols becomes too long, the strip is done in multiple passes.
# Running strip_module twice on the same object is safe (and a
# waste of time).
#
sizeofptr="/tmp/$$.sizeofptr"
echo 'int main() { return sizeof(void *); }' | gcc -xc - -o $sizeofptr
$sizeofptr
export SIZEOF_POINTER=$?
rm -f $sizeofptr
cat > /tmp/$$.awk <<\EOF
BEGIN {
strip = "/usr/bin/objcopy";
nm = "/usr/bin/nm";
cp = "/bin/cp";
mv = "/bin/mv";
rm = "/bin/rm";
tmp = "/tmp";
command_size = 400; # arbitrary but safe
getline < "/proc/self/stat";
pid = $1;
tmpcopy = tmp "/" pid ".object";
nmout = tmp "/" pid ".nmout";
for (i = 1; i < ARGC; ++i)
strip_module(ARGV[i]);
do_command(rm " -f " tmpcopy " " nmout);
exit(0);
}
function strip_module(object,
keep_symbol, to_strip, symbol, command, changed) {
do_command(cp " -a " object " " tmpcopy);
do_command(nm " " tmpcopy " > " nmout);
# delete array_name sometimes breaks, internal error, play safe
for (symbol in keep_symbol)
delete keep_symbol[symbol];
for (symbol in to_strip)
delete to_strip[symbol];
new_module_format = 0;
ptrskip = 2 + 2 * ENVIRON["SIZEOF_POINTER"];
while ((getline < nmout) > 0) {
$0 = substr($0, ptrskip);
# b static variable, uninitialised
# d static variable, initialised
# r static array, initialised
# t static label/procedures
if ($1 ~ /[bdrt]/)
to_strip[$2] = "";
else if ($2 ~ /R __ksymtab_/)
keep_symbol[substr($2, 11)] = "";
else if ($0 ~ /R __module_parm_/)
keep_symbol[substr($2, 15)] = "";
else if ($0 ~ /D __parm_/)
keep_symbol[substr($2, 8)] = "";
else if ($3 ~ /__ksymtab/) {
keep_symbol[$5] = "";
}
else if ($1 != "?")
keep_symbol[$2] = "";
if ($2 ~ /__module/)
new_module_format = 1;
}
close(nmout);
command = "";
changed = 0;
failure = 0;
if (new_module_format) {
for (symbol in to_strip) {
if (!(symbol in keep_symbol)) {
changed = 1;
if (length(command) > command_size) {
failure = failure || do_command(strip command " " tmpcopy);
command = "";
}
command = command " --strip-symbol=" symbol;
}
}
}
if (command != "") {
changed = 1;
failure = failure || do_command(strip command " " tmpcopy);
}
if (changed && !failure)
do_command(mv " " tmpcopy " " object);
}
function do_command(command) {
if ((ret = system(command)) != 0) {
giveup("command \"" command "\" failed " ret, ret);
return 1;
}
return 0;
}
function giveup(message, ret) {
print "strip_module: " message > "/dev/stderr";
# exit(ret);
}
EOF
awk -f /tmp/$$.awk "$@"
ret=$?
rm -f /tmp/$$.awk
exit $ret
|