Subject: Can modules be stripped?

From: Scott A McConnell <[email-masked]>
Date: Fri, 12 Apr 2002 12:41:28 -0500

For my vr5432 based board (2.4.5) I can strip and run executables.

If I strip a module, insmod dies in obj_load() with Floating point
exception.

Has anyone else seen this?

-- 
Scott A. McConnell

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Fri, 12 Apr 2002 18:57:09 +0200 (MET DST)

> If I strip a module, insmod dies in obj_load() with Floating point

 You can't strip modules as they are relocatables -- global symbols and
relocations have to stay intact.  You may try `strip -d' if you want to
remove debugging symbols.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: [email-masked], PGP key available        +

---

From: Stuart Hughes <[email-masked]>
Date: Fri, 12 Apr 2002 17:56:45 +0100

> Has anyone else seen this?

Yep,

Be careful what you strip.  I found the safest thing was to use 'strip
-g'
-- 
Regards, Stuart Hughes

---

From: "Bradley D. LaRonde" <[email-masked]>
Date: Fri, 12 Apr 2002 13:48:48 -0400

----- Original Message -----
From: "Maciej W. Rozycki" <[email-masked]>
To: "Scott A McConnell" <[email-masked]>
Cc: "MIPS/Linux List (SGI)" <[email-masked]>
Sent: Friday, April 12, 2002 12:57 PM
Subject: Re: Can modules be stripped?

> relocations have to stay intact.

OK, you can't strip kernel modules (news to me, then again how often do I
use modules?), but it can't be because they "are relocatables".  I routinely
strip libraries without problem, and those are relocatables too.

So what's the real reason?

Regards,
Brad

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Fri, 12 Apr 2002 20:05:43 +0200 (MET DST)

> strip libraries without problem, and those are relocatables too.

 What kind of libraries?  Shared libraries are shared objects and not
relocatables.  Static libraries ("ar" archives), OTOH, are sets of
relocatables as is e.g. /usr/lib/crt1.o and any assembler output.  The
rule is a relocatable is any object that has unresolved static
relocations, i.e. has not undergone final linking.  If unsure check with
file(1).

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Fri, 12 Apr 2002 20:44:18 +0200 (MET DST)

On Fri, 12 Apr 2002, Bradley D. LaRonde wrote:

> Which brings up an interesting question - why doesn't the kernel use .so
> files for modules?

 There is no need to bring all the dynamic stuff into the kernel.

---

From: "Bradley D. LaRonde" <[email-masked]>
Date: Fri, 12 Apr 2002 14:35:13 -0400

----- Original Message -----
From: "Maciej W. Rozycki" <[email-masked]>
To: "Bradley D. LaRonde" <[email-masked]>
Cc: "MIPS/Linux List (SGI)" <[email-masked]>
Sent: Friday, April 12, 2002 2:05 PM
Subject: Re: Can modules be stripped?

> relocatables.

Oh, oops. :-P  Now I see what you mean.  I confused shared object
w/relocatable.  My bad.

Did I know that kernel modules were "object files" i.e. relocatables.  Yes.
But I've always referred to them as object files (.o), not relocatables,
hence the confusion.

Regards,
Brad

---

From: Daniel Jacobowitz <[email-masked]>
Date: Fri, 12 Apr 2002 20:27:46 -0400

> Which brings up an interesting question - why doesn't the kernel use .so

If you're really curious, compare the gunk in insmod (quite a bit) with
the gunk in ld.so (unspeakable).  Shared libraries are a great deal
more complicated than modules need to be.

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

---

From: Ian Chilton <[email-masked]>
Date: Sat, 13 Apr 2002 01:40:09 +0100

Hello,

> Be careful what you strip.  I found the safest thing was to use 'strip

I always use strip --strip-debug

Bye for Now,

Ian

-----------------------------
 Ian Chilton
 E-Mail: [email-masked]
-----------------------------

---

From: Keith Owens <[email-masked]>
Date: Sat, 13 Apr 2002 11:14:31 +1000

On Fri, 12 Apr 2002 12:41:28 -0500, 
>If I strip a module, insmod dies in obj_load() with Floating point

The rules for stripping a module are "unusual".  Some symbols have to
be kept even if they are static, because even static symbols can be
exported.  The combination of strip -g to remove all debugging data
plus the script below is safe.  Run as 'strip_module $(modprobe -l)'.

Also note that insmod supports compressed modules if you configure
modutils with --enable-zlib.  I do not know if busybox supports this
feature of insmod.

strip_module.

#!/bin/sh
#
#	Given a list of objects, strip all static symbols except those
#	required by insmod.
#
#	Copyright Keith Owens <[email-masked]>.  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).
#

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;
	while ((getline < nmout) > 0) {
		$0 = substr($0, 10);
		# b static variable, uninitialised
		# d static variable, initialised
		# r static array, initialised
		# t static label/procedures
		if ($1 ~ /[bdrt]/)
			to_strip[$2] = "";
		else if ($1 != "?")
			keep_symbol[$2] = "";
		else if ($0 ~ /\? __ksymtab_/)
			keep_symbol[substr($2, 11)] = "";
		else if ($0 ~ /\? __module_parm_/)
			keep_symbol[substr($2, 15)] = "";
		if ($0 ~ /\? __module/)
			new_module_format = 1;
	}
	close(nmout);
	command = "";
	changed = 0;
	if (new_module_format) {
		for (symbol in to_strip) {
			if (!(symbol in keep_symbol)) {
				changed = 1;
				if (length(command) > command_size) {
					do_command(strip command " " tmpcopy);
					command = "";
				}
				command = command " --strip-symbol=" symbol;
			}
		}
	}
	if (command != "") {
		changed = 1;
		do_command(strip command " " tmpcopy);
	}
	if (changed)
		do_command(mv " " tmpcopy " " object);
}

function do_command(command) {
	if ((ret = system(command)) != 0)
		giveup("command \"" command "\" failed " ret, ret);
}

function giveup(message, ret) {
	print "strip_module: " message > "/dev/stderr";
	exit(ret);
}
EOF

awk -f /tmp/$$.awk "$@"
ret=$?
rm -f /tmp/$$.awk
exit $ret

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Mon, 15 Apr 2002 16:21:10 +0200 (MET DST)

> exported.  The combination of strip -g to remove all debugging data

 Hmm, that looks weird to me.  If exporting static symbols is permitted,
shouldn't the symbols be marked global by EXPORT_SYMBOL() then? 

 The following code seems to mark a static symbol global just fine:

static int test = 0; asm(".global test");

so there should be no problem with doing the same in EXPORT_SYMBOL().

---

From: Keith Owens <[email-masked]>
Date: Tue, 16 Apr 2002 00:50:00 +1000

On Mon, 15 Apr 2002 16:21:10 +0200 (MET DST), 
>shouldn't the symbols be marked global by EXPORT_SYMBOL() then? 

Exporting static symbols has always been allowed.  Exported symbols are
the module equivalent of lazy binding, which is logically no different
from passing the address of a static symbol via a structure to a
registration function.  In either case the static symbol can be
accessed from outside the object, without being marked as global.

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Mon, 15 Apr 2002 17:32:54 +0200 (MET DST)

> accessed from outside the object, without being marked as global.

 Well, if you make a symbol available to other modules it becomes global
implicitly as they may refer to it by its name (by means of relocations)
and not an address known from elsewhere.  So keeping the symbol marked
local in the module's symbol table is against a run-time linker's usual
behaviour.  One may expect to perform `ld -rx' on a module and have it
still work as it's what happens for every other relocatable.