tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kernel libraries and dead code in MODULAR kernels
On 3 Sep, 2015, at 18:08 , Masao Uebayashi <uebayasi%gmail.com@localhost> wrote:
> (Coming back to the original post.)
>
> On Mon, Aug 31, 2015 at 10:55 AM, Dennis Ferguson
> <dennis.c.ferguson%gmail.com@localhost> wrote:
>> I've been compiling the same kernel configuration with and without
>> options MODULAR and noticed that the MODULAR kernels have a not
>> inconsiderable amount of code that is called neither by the kernel
>> nor any of the modules. I've appended a list of the global symbols
>> from libkern.[ao] that end up being included in amd64 mostly-GENERIC
>> modular kernels that have no callers and are omitted from non-modular
>> kernel builds.
>>
>> The reason for this is that while non-modular kernels build a libkern.a
>> from which only code that is actually called by something is loaded into
>> the kernel, modular kernels instead build a libkern.o from which everything
>> is unconditionally included. While I understand why this is done (everything
>> is included in case the separately-compiled modules need it) it causes
>> a difficult problem if you would like to have a modular kernel without
>> the dead code. A few of those functions are in fact no longer used and
>> could just be eliminated from the build, but the rest seem to end up
>> there either because their use depends on configuration options which may
>> or may not be defined, or they are members of a library that is also used
>> in user space that has a richer API there than the kernel makes use of, or
>> the use of particular functions (e.g. in the runtime library) is dependent
>> on the architecture being built.
>
> Yes, finding unused functions is hard. Not only in libkern, but also
> libc, or variables in abandaned `Makefile.kern.inc'. Removing one
> needs so much mental energy (especially when those picky wandering).
I'm not so interested in ridding the kernel of all unused code (though
I suspect someone clever might be able to use the -ffunction-sections and
-fdata-sections compiler flags plus the ld --gc-sections option to
find some of it). I'd be happy if modular and non-modular kernels
had the same unused stuff, and that libkern.a could be used when
building either.
It seems to me that both non-modular and modular kernels are both just
single programs at this point. There is no guarantee that any module
will be useful with a kernel except those that are compiled with it,
as far as I can tell, so a modular kernel is pretty much the same program
as a non-modular kernel but built so that some of the program text doesn't
have to occupy memory if it isn't being used. I don't really buy that building
a modular kernel turns /netbsd into a shared library. The fact that the
modules are built before the "library" suggests something else.
>> I do notice that for modular kernels the modules are built before the kernel
>> is. Is there no way to harvest the undefined global symbols from the modules
>> and include these to force the kernel link to resolve them?
>
> I don't think there is one, even in userland. Dependency is per-library/module.
What I would like just doesn't seem all that hard to me, it is just that build
tools are way outside my skill set so anything I did myself is guaranteed to
be an unseemly hack.
For a unseemly hack version, however, I've appended a shell script which, when
pointed at a full set of modules that might be used with a /netbsd being built,
may produce a .o file to link with the /netbsd that should guarantee the kernel
includes all globals from libkern.a required by the modules and cause a complaint
if the kernel is missing something. It seems like someone who actually knows what
they're doing should be able to figure out a good way to enable loading against
libkern.a for modular kernels.
Dennis Ferguson
#! /bin/sh
#
# kmod_harvest.sh
MODDIR=/stand/amd64 # where modules are
UNDEF_DOT_O=needed_by_modules.o # .o with symbols kernel link must resolve
UNDEF_RAW=/tmp/undef$$.syms
DEF_RAW=/tmp/def$$.syms
C_TMP=/tmp/crap$$.c
OBJ_TMP=/tmp/crap$$.o
(cd ${MODDIR}; find . -name \*.kmod -exec nm -gu '{}' \;) | \
sed -e 's/^ * U //' | sort | uniq > ${UNDEF_RAW}
(cd ${MODDIR}; find . -name \*.kmod -exec nm -g --defined-only '{}' \;) | \
sed -e 's/^[^ ]* [ADRTW] //' | sort | uniq > ${DEF_RAW}
SYMS=""
for i in `comm -23 ${UNDEF_RAW} ${DEF_RAW}`; do
SYMS="${SYMS} -u $i"
done
cp /dev/null ${C_TMP}
gcc -c -o ${OBJ_TMP} ${C_TMP}
eval ld -o ${UNDEF_DOT_O} -r ${SYMS} ${OBJ_TMP}
rm -f ${UNDEF_RAW} ${DEF_RAW} ${C_TMP} ${OBJ_TMP}
Home |
Main Index |
Thread Index |
Old Index