views:

371

answers:

3

If I do --strip-debug or --strip-unneeded, I have the .ko that lists all function names with nm, if I do just strip foo.ko I have a kernel module that refuses to load.

Does anyone know a quick shortcut how to remove all symbols that are not needed for module loading so that people cannot reverse engineer the API:s as easily?

PS: For all you open source bigots missionaries; this is something that general public will never be using in any case so no need to turn the question into a GPL flame war.

+2  A: 

I'm not sure I understand what the problem really is: When developing a .ko, if I don't explicitly add something like

ccflags-y += -ggdb -O0 -Wall

into my Makefile, I don't get any symbol but for those that I publish or external ref myself. I'm sure I don't get any other symbols for several good reasons:

  • the resulting .ko file is considerably smaller,
  • dumping the file and analyzing the ELF shows the tables are not there,
  • I can't see nor access the symbols in kgdb.

So I'm a little puzzled at your question, actually?... What are those symbols you do see in your .ko (and don't want to)? How are they declared in your source file? In which ELF sections do they end up? And (sorry, dumb question ahead): Did you define static all things that didn't need to be seen outside of their own module?

filofel
Nope, they end up there with `-Os` and no `-g` -flags.
Kimvais
+2  A: 

With no answer to my previous questions, here are some guesses that could also be some clues, and a step to an answer:

From what I recall, a .ko is nothing but an .o file resulting from the merge of all the .o files generated by your source module, and the addition of a .modinfo section. At the end of any .ko building Makefile, there is an LD call: from what I recall, ld is called with the -r option, and this is what create that .o file that the Makefile calls a .ko. This resulting file is not to be confused with an archive or object library (.a file), that is just a format archiving / packaging multiple .o files as one: A merged object is the result of a link that produces yet another .o module: But in the resulting module, all sections that could be merged have been, and all public / external pairs that could be resolved have been inside those sections. So I assume that you end up with your .ko file containing all your "local" extern definitions:

  • Those that are extern because they are used to call across the .o modules in your .ko (but are not needed anymore since they are not supposed to be called from outside the .ko), and

  • those that the .ko module DO need to properly communicate with the loader and kernel.

The former have most likely already been resolved by ld during the merge, but ld has no way to know whether you intend to have them also callable from outside the .ko.

So the extraneous symbols you see are those that are extern for each of your .o files, but are not needed as extern for the resulting .ko. And what you are looking for is a way to strip only those.

Does this last paragraph properly describe the symbols you want to get rid of?

filofel
I think this is exactly what we are talking about here. Sorry for not updating earlier. In any case, what you say here makes perfect sense and I will have to investigate further.
Kimvais
+2  A: 

I think this is exactly what we are talking about here.

OK, then it looks like one solution is to "manually" remove the extraneous symbols. The "strip" utility seems to allow individually stripping (or keeping) of symbols, so you would have to use one --strip-all and a small bunch of --keep-symbol= . Note that --wildcard might help a bit, too. You can do the opposite, of course, keep all and individually strip, depending on what's the most convenient.

A good start could be to remove all the symbols that you explicitly defined in your module for cross-module linking and don't want to appear - just leaving the obvious useful ones, things like init and exit. And to not touch those that have been generated by / belong to the kernel dev software infrastructure. Then trial and error until you find the right recipe... In fact, I would think that about all your own symbols might be removable, apart from those you explicitly defined yourself as EXPORT_SYMBOL (and init / exit, of course).

Good luck! :)

PS:

In fact, it seems that the required source information exists in all .ko projects to perform the required stripping automatically: Unless I'm missing something, it seems that anything that's not EXPORT_SYMBOL or explicitly inserted by the build software could theoretically be stripped by default at the end of "ld -r" time that ends a .ko build. It's just that I don't think the toolchain (compiler / linker) have provision / directives / options to individually designate "strip or keep" syms for the relocatable link / merge. Otherwise, some modifications in the EXPORT_SYMBOL macro and in a few other places could probably achieve the result you're after, and shave some bytes from most .ko files in any Linux system.

filofel
Ok, this sort of transforms the question to - what else is needed than `*_init()`, `*_exit()` and the ones that I explicitly `EXPORT_SYMBOL()`? - or is it really all?
Kimvais
That's why I mentioned this would be trial and error: I'm not quite sure, I've not had to play that game ever before. I would start by leaving alone in any symbol I didn't put myself, and removing anything that's calling across my own source modules and that has presumably been resolved by the .ko ld. If that works, I would start from this one and try to do some more cleanup, piecemeal, testing, and iterating like this. Very empirical, but heck... if it solves your problem, it might be good enough.
filofel