diff -Nur modutils-2.3.10/ChangeLog modutils-2.3.11/ChangeLog --- modutils-2.3.10/ChangeLog Thu Mar 16 21:19:15 2000 +++ modutils-2.3.11/ChangeLog Thu Apr 20 14:31:49 2000 @@ -1,3 +1,17 @@ +2000-04-20 Keith Owens + + modutils 2.3.11 + + * Add ieee1394 directory, requested by Andreas Bombe. + * Documentation and options updates. Add long options, clean + up missing or incorrect usage entries. Callum . + * White space cleanup. + * Do meta expansion on "include" and "if" parameters. + * Ignore genksyms suffix when reading map from -F. + * Add support for kallsyms to assist kernel debugging. + * Hint message for -EBUSY. + * Sanity check on number of local symbols. + 2000-03-15 Keith Owens modutils 2.3.10 @@ -1056,7 +1070,7 @@ * obj/obj_sparc.c: Likewise. * insmod/rmmod.c (old_get_modules): Fix error check from read. - + Sat Jan 4 16:46:09 CST 1997 Richard Henderson * insmod/insmod.c (main): Check that we did find the module's diff -Nur modutils-2.3.10/INSTALL modutils-2.3.11/INSTALL --- modutils-2.3.10/INSTALL Tue Dec 7 21:42:01 1999 +++ modutils-2.3.11/INSTALL Thu Apr 13 18:17:59 2000 @@ -50,8 +50,8 @@ configure takes ten modutils specific options, as well as the standard configure options. ---enable-combined Create insmod and rmmod/modprobe/lsmod/ksyms as - one executable. Default is one combined module, +--enable-combined Create insmod and rmmod/modprobe/lsmod/ksyms as + one executable. Default is one combined module, if you --disable-combined you can still combine individual modules into insmod with --enable-combined-X. diff -Nur modutils-2.3.10/Makefile.in modutils-2.3.11/Makefile.in --- modutils-2.3.10/Makefile.in Mon Nov 22 01:08:04 1999 +++ modutils-2.3.11/Makefile.in Thu Apr 20 10:04:45 2000 @@ -1,4 +1,4 @@ -# $Id: Makefile.in 1.2 Mon, 22 Nov 1999 01:08:04 +1100 keith $ +# $Id: Makefile.in 1.4 Thu, 20 Apr 2000 10:04:45 +1000 kaos $ srcdir = @srcdir@ diff -Nur modutils-2.3.10/NEWS modutils-2.3.11/NEWS --- modutils-2.3.10/NEWS Fri Oct 8 20:23:53 1999 +++ modutils-2.3.11/NEWS Thu Apr 13 18:17:59 2000 @@ -8,7 +8,7 @@ - Added option "-q" to insmod and modprobe for silent loading. - Depmod logic restructured, Test an extreme case with /etc/modules.conf: depfile=/lib/modules/modules.dep - path=/lib/modules + path=/lib/modules This is example is just for testing, but it is a good test. You might like the "-q" option to depmod... With "-q" modprobe will now silently seriously probe for a good stack. @@ -19,11 +19,11 @@ Since snap-990308: - Additional keywords for /etc/modules.conf: - if, else, elseif, endif, include, define, above, below + if, else, elseif, endif, include, define, above, below - Also uses wordexp() or glob() if available. - All arguments in config files are expanded w.r.t. meta-characters. - New depmod options (some especially for distribution maintainers): - -C file Use alternate config file + -C file Use alternate config file -F file Read kernel symbols from a file -b base Work with a moved image of /lib/modules -q Keep QUIET about unresolved symbols @@ -58,7 +58,7 @@ runs. Note that the module must have _very_ large initial data for this to have any effect at all. Modules with large firmware blocks to download are good candidates though. - - Aliases are now matched through globbing (for devfs), and + - Aliases are now matched through globbing (for devfs), and aliases of aliases resolve properly. Since 2.1.55: diff -Nur modutils-2.3.10/TODO modutils-2.3.11/TODO --- modutils-2.3.10/TODO Fri Nov 26 01:33:48 1999 +++ modutils-2.3.11/TODO Thu Apr 20 10:04:45 2000 @@ -1,13 +1,5 @@ -From modutils-2.3.7 - - - Fix the confusion when an alias is specified with options and - that alias is also a module name which is loaded in the same run. - From modutils-2.2.2-pre6: - - Test and verify meta_expand, especially the completely - untested support for wordexp() (libc2.1) - - Are there more optimizations to do for handling meta-characters? Example: look for $VAR in the environment instead of "/bin/echo" @@ -19,7 +11,7 @@ insmod: - - Persistant module parameters. + - Persistant module parameters. util: (alias.h) insmod: (modprobe.c) @@ -31,7 +23,7 @@ * Bjorn says: One way is to use the "include" directive... Otherwise, an extension to the modules.dep file format could handle most of this problem: - "/lib/modules/.../isofs.o: [type=fs device=iso9660] dependencies" + "/lib/modules/.../isofs.o: [type=fs device=iso9660] dependencies" config file: @@ -40,4 +32,3 @@ * Bjorn says: This is mostly solved with the "include", "define" and "if" directives for /etc/modules.conf. Note that the kmod environment to modprobe is _very_ sparse... - diff -Nur modutils-2.3.10/config.guess modutils-2.3.11/config.guess --- modutils-2.3.10/config.guess Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/config.guess Thu Apr 13 18:17:59 2000 @@ -247,18 +247,18 @@ echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi - else echo i586-dg-dgux${UNAME_RELEASE} - fi - exit 0 ;; + else echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; @@ -401,25 +401,25 @@ exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd - exit 0 ;; + exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit 0 ;; + exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd - exit 0 ;; + exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd - exit 0 ;; + exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd - exit 0 ;; + exit 0 ;; CRAY*X-MP:*:*:*) echo xmp-cray-unicos - exit 0 ;; + exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} exit 0 ;; @@ -433,12 +433,12 @@ exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos - exit 0 ;; + exit 0 ;; F300:UNIX_System_V:*:*) - FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; + FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; F301:UNIX_System_V:*:*) echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` exit 0 ;; @@ -485,7 +485,7 @@ s/.*supported emulations: *// s/ .*// p'` - case "$ld_supported_emulations" in + case "$ld_supported_emulations" in i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; @@ -513,18 +513,18 @@ case "$?" in 1) UNAME_MACHINE="alphaev5" - ;; - 2) + ;; + 2) UNAME_MACHINE="alphaev56" - ;; - esac + ;; + esac objdump --private-headers dummy | \ grep ld.so.1 > /dev/null if test "$?" = 0 ; then LIBC="libc1" fi - fi + fi rm -f dummy.s dummy echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 elif test "${UNAME_MACHINE}" = "mips" ; then @@ -593,11 +593,11 @@ echo i386-sequent-sysv4 exit 0 ;; i?86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. + # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) @@ -622,10 +622,10 @@ fi exit 0 ;; pc:*:*:*) - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp - exit 0 ;; + exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; @@ -654,8 +654,8 @@ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; @@ -686,9 +686,9 @@ fi exit 0 ;; PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit 0 ;; + # says + echo i586-unisys-sysv4 + exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm @@ -706,11 +706,11 @@ exit 0 ;; R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv${UNAME_RELEASE} else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv${UNAME_RELEASE} fi - exit 0 ;; + exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 @@ -732,11 +732,11 @@ #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else "" #endif - ); exit (0); + ); exit (0); #endif #endif diff -Nur modutils-2.3.10/configure modutils-2.3.11/configure --- modutils-2.3.10/configure Sat Jan 1 23:08:36 2000 +++ modutils-2.3.11/configure Thu Apr 20 10:04:45 2000 @@ -13,10 +13,10 @@ # Any additions from configure.in: ac_default_prefix=/usr ac_help="$ac_help - --enable-combined Create insmod and rmmod/modprobe/lsmod/ksyms as - one executable. Default is one combined module, - if you --disable-combined you can still combine - individual modules into insmod with --enable-combined-X." + --enable-combined Create insmod and rmmod/modprobe/lsmod/ksyms/kallsyms + as one executable. Default is one combined module, + if you --disable-combined you can still combine + individual modules into insmod with --enable-combined-X." ac_help="$ac_help --enable-combined-rmmod Create insmod and rmmod as one executable (default)" ac_help="$ac_help @@ -26,6 +26,8 @@ ac_help="$ac_help --enable-combined-ksyms Create insmod and ksyms as one executable (default)" ac_help="$ac_help + --enable-combined-kallsyms Create insmod and kallsyms as one executable (default)" +ac_help="$ac_help --enable-compat-2-0 Create utilities runnable on a Linux 2.0 system (default)" ac_help="$ac_help --enable-kerneld Create kerneld binary (default)" @@ -33,8 +35,8 @@ --disable-insmod-static Do not create insmod.static binary (default)" ac_help="$ac_help --enable-common-sparc Make all the utilities work on both sparc32 and sparc64 - as one executable (default on sparc is yes, default on - other architectures is no)" + as one executable (default on sparc is yes, default on + other architectures is no)" ac_help="$ac_help --enable-strip Strip binaries during install (default)" @@ -609,7 +611,7 @@ fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:613: checking host system type" >&5 +echo "configure:615: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -630,7 +632,7 @@ echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:634: checking target system type" >&5 +echo "configure:636: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -648,7 +650,7 @@ echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:652: checking build system type" >&5 +echo "configure:654: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -688,14 +690,14 @@ *) ARCH=$target_cpu ;; esac -for i in rmmod modprobe lsmod ksyms +for i in rmmod modprobe lsmod ksyms kallsyms do eval COMBINE_$i=$i done # Check whether --enable-combined or --disable-combined was given. if test "${enable_combined+set}" = set; then enableval="$enable_combined" if test "$enableval" = "no"; then - for i in rmmod modprobe lsmod ksyms + for i in rmmod modprobe lsmod ksyms kallsyms do eval COMBINE_$i="" done fi @@ -750,6 +752,18 @@ +# Check whether --enable-combined-kallsyms or --disable-combined-kallsyms was given. +if test "${enable_combined_kallsyms+set}" = set; then + enableval="$enable_combined_kallsyms" + if test "$enableval" = "yes"; then + COMBINE_kallsyms=kallsyms + else + COMBINE_kallsyms="" +fi +fi + + + # Check whether --enable-compat-2-0 or --disable-compat-2-0 was given. if test "${enable_compat_2_0+set}" = set; then enableval="$enable_compat_2_0" @@ -836,7 +850,7 @@ # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:840: checking for $ac_word" >&5 +echo "configure:854: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -866,7 +880,7 @@ # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:870: checking for $ac_word" >&5 +echo "configure:884: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -917,7 +931,7 @@ # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:921: checking for $ac_word" >&5 +echo "configure:935: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -949,7 +963,7 @@ fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:953: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:967: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -960,12 +974,12 @@ cat > conftest.$ac_ext << EOF -#line 964 "configure" +#line 978 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -991,12 +1005,12 @@ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:995: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1009: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1000: checking whether we are using GNU C" >&5 +echo "configure:1014: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1005,7 +1019,7 @@ yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1009: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1023: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1024,7 +1038,7 @@ ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1028: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1042: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1058,7 +1072,7 @@ # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1062: checking for $ac_word" >&5 +echo "configure:1076: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1086,7 +1100,7 @@ fi echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 -echo "configure:1090: checking whether ln -s works" >&5 +echo "configure:1104: checking whether ln -s works" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1143,12 +1157,12 @@ fi echo $ac_n "checking for wordexp""... $ac_c" 1>&6 -echo "configure:1147: checking for wordexp" >&5 +echo "configure:1161: checking for wordexp" >&5 if eval "test \"`echo '$''{'ac_cv_func_wordexp'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1189: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_wordexp=yes" else @@ -1192,12 +1206,12 @@ fi echo $ac_n "checking for glob""... $ac_c" 1>&6 -echo "configure:1196: checking for glob" >&5 +echo "configure:1210: checking for glob" >&5 if eval "test \"`echo '$''{'ac_cv_func_glob'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1238: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_glob=yes" else @@ -1250,13 +1264,13 @@ if test "$ARCH" = "alpha"; then echo $ac_n "checking for broken alpha assembler""... $ac_c" 1>&6 -echo "configure:1254: checking for broken alpha assembler" >&5 +echo "configure:1268: checking for broken alpha assembler" >&5 cat > conftest.c <&5; (eval $ac_compile) 2>&5; }; then + if { (eval echo configure:1274: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ac_broken_gas=no if objdump -r conftest.o | grep 'LITERAL.*y.*4$' > /dev/null; then cat >> confdefs.h <<\EOF @@ -1445,6 +1459,7 @@ s%@COMBINE_modprobe@%$COMBINE_modprobe%g s%@COMBINE_lsmod@%$COMBINE_lsmod%g s%@COMBINE_ksyms@%$COMBINE_ksyms%g +s%@COMBINE_kallsyms@%$COMBINE_kallsyms%g s%@kerneld_SUBDIR@%$kerneld_SUBDIR%g s%@insmod_static@%$insmod_static%g s%@COMMON_sparc@%$COMMON_sparc%g diff -Nur modutils-2.3.10/configure.in modutils-2.3.11/configure.in --- modutils-2.3.10/configure.in Sat Jan 1 23:08:36 2000 +++ modutils-2.3.11/configure.in Thu Apr 20 10:04:45 2000 @@ -1,4 +1,4 @@ -dnl $Id: configure.in 1.11 Sat, 01 Jan 2000 23:08:36 +1100 keith $ +dnl $Id: configure.in 1.11.1.3 Thu, 20 Apr 2000 10:04:45 +1000 kaos $ AC_INIT(insmod/insmod.c) AC_PREFIX_DEFAULT(/usr) @@ -35,16 +35,16 @@ *) ARCH=$target_cpu ;; esac -for i in rmmod modprobe lsmod ksyms +for i in rmmod modprobe lsmod ksyms kallsyms do eval COMBINE_$i=$i done AC_ARG_ENABLE(combined, -[ --enable-combined Create insmod and rmmod/modprobe/lsmod/ksyms as - one executable. Default is one combined module, - if you --disable-combined you can still combine - individual modules into insmod with --enable-combined-X.], +[ --enable-combined Create insmod and rmmod/modprobe/lsmod/ksyms/kallsyms + as one executable. Default is one combined module, + if you --disable-combined you can still combine + individual modules into insmod with --enable-combined-X.], [if test "$enableval" = "no"; then - for i in rmmod modprobe lsmod ksyms + for i in rmmod modprobe lsmod ksyms kallsyms do eval COMBINE_$i="" done fi]) @@ -85,6 +85,15 @@ fi]) AC_SUBST(COMBINE_ksyms) +AC_ARG_ENABLE(combined-kallsyms, +[ --enable-combined-kallsyms Create insmod and kallsyms as one executable (default)], +[if test "$enableval" = "yes"; then + COMBINE_kallsyms=kallsyms + else + COMBINE_kallsyms="" +fi]) +AC_SUBST(COMBINE_kallsyms) + AC_ARG_ENABLE(compat-2-0, [ --enable-compat-2-0 Create utilities runnable on a Linux 2.0 system (default)], [if test "$enableval" = "yes"; then @@ -111,8 +120,8 @@ COMMON_sparc=yes AC_ARG_ENABLE(common-sparc, [ --enable-common-sparc Make all the utilities work on both sparc32 and sparc64 - as one executable (default on sparc is yes, default on - other architectures is no)], + as one executable (default on sparc is yes, default on + other architectures is no)], [if test "$enableval" = "yes"; then COMMON_sparc=yes else diff -Nur modutils-2.3.10/depmod/Makefile.in modutils-2.3.11/depmod/Makefile.in --- modutils-2.3.10/depmod/Makefile.in Sun Dec 19 20:23:21 1999 +++ modutils-2.3.11/depmod/Makefile.in Tue Apr 18 13:38:59 2000 @@ -1,4 +1,4 @@ -# $Id: Makefile.in 1.9 Sun, 19 Dec 1999 20:23:21 +1100 keith $ +# $Id: Makefile.in 1.10 Tue, 18 Apr 2000 13:38:59 +1000 kaos $ srcdir=@srcdir@ VPATH=@srcdir@ @@ -25,7 +25,7 @@ ifeq (@COMMON_sparc@,yes) DEFSNOARCH += -DCOMMON_3264 DEFS += -DONLY_32 -DEFS64 := -DELF_MACHINE_H='"elf_sparc64.h"' -DARCH_sparc64 -DONLY_64 +DEFS64 := -DONLY_64 -DELF_MACHINE_H='"elf_sparc64.h"' -DARCH_sparc64 OBJS += depmod_64.o endif diff -Nur modutils-2.3.10/depmod/depmod.c modutils-2.3.11/depmod/depmod.c --- modutils-2.3.10/depmod/depmod.c Wed Mar 15 21:14:05 2000 +++ modutils-2.3.11/depmod/depmod.c Thu Apr 20 14:31:49 2000 @@ -27,15 +27,17 @@ Fixes: Add -r flag: Keith Owens October 1999. - + Rationalize common code for 32/64 bit architectures. Fix error message for modules.dep. Keith Owens December 1999 Add arch64(). Keith Owens December 1999. + Ignore any genksyms suffix when using -F. + Keith Owens April 2000. */ -#ident "$Id: depmod.c 1.9 Wed, 15 Mar 2000 21:14:05 +1100 keith $" +#ident "$Id: depmod.c 1.13 Thu, 20 Apr 2000 14:31:49 +1000 kaos $" #include #include @@ -49,6 +51,7 @@ #include #include #include +#include #include #include ELF_MACHINE_H @@ -67,6 +70,8 @@ struct MODULE *module; /* Module declaring this symbol */ const char *name; unsigned short hashval; + unsigned short hashval_nosuffix; + unsigned short length_nosuffix; char status; } SYMBOL; @@ -115,12 +120,15 @@ * Add defined symbol to the head of the list of defined symbols. * Return the new symbol. */ -static SYMBOL *addsym(const char *name, MODULE *module, SYM_STATUS status) +static SYMBOL *addsym(const char *name, MODULE *module, SYM_STATUS status, + int ignore_suffix) { SYMBOL added; SYMBOL *me; unsigned short hashval = 0; - const char *pt = name; + const char *pt = name, *pt_R; + char *p; + int l; for (pt = name; *pt; ++pt) hashval = (hashval << 1) ^ *pt; @@ -132,6 +140,26 @@ added.hashval = hashval; added.status = status; + /* Compute the hash without the trailing genksym suffix if required */ + if (ignore_suffix && (pt_R = strstr(name, "_R"))) { + l = strlen(pt_R); + if (l >= 10) { /* May be _R.*xxxxxxxx */ + (void)strtoul(pt_R+l-8, &p, 16); + if (!*p) { /* It is _R.*xxxxxxxx */ + added.length_nosuffix = pt_R - name; + hashval = 0; + for (pt = name; pt < pt_R; ++pt) + hashval = (hashval << 1) ^ *pt; + hashval %= 2048; + added.hashval_nosuffix = hashval; + } + } + } + else { + added.hashval_nosuffix = 0; + added.length_nosuffix = 0; + } + if (status == SYM_DEFINED) { if (symavail == NULL || symavail == maxsyms) { @@ -146,8 +174,8 @@ } me = symavail++; *me = added; - me->next = symhash[hashval]; - symhash[hashval] = me; + me->next = symhash[added.hashval]; + symhash[added.hashval] = me; } else { me = (SYMBOL *)xmalloc(sizeof(SYMBOL)); *me = added; @@ -190,7 +218,11 @@ definition. Symbol hash linked list has newest first, so we want the last match in the chain. In particular, this prefers - kernel symbols to that of any module. */ + kernel symbols to that of any module. + + If we are ignoring the genksyms suffix in this + comparision then there are two hashes to try. + */ find = symhash[psym->hashval]; while (find) { @@ -200,6 +232,19 @@ } find = find->next; } + if (psym->status == SYM_UNDEF && psym->length_nosuffix) { + /* Try again ignoring the suffix */ + find = symhash[psym->hashval_nosuffix]; + while (find) { + if (strncmp(find->name, psym->name, + psym->length_nosuffix) == 0 && + !find->name[psym->length_nosuffix]) { + psym->status = SYM_RESOLVED; + psym->module = find->module; + } + find = find->next; + } + } if (psym->status == SYM_UNDEF) resolved = 0; } @@ -211,7 +256,7 @@ * Read the symbols in an object and register them in the symbol table. * Return -1 if there is an error. */ -static int loadobj(const char *objname) +static int loadobj(const char *objname, int ignore_suffix) { static char *currdir; static int currdir_len; @@ -236,7 +281,7 @@ if ((fp = fopen(objname, "r")) == NULL) return 1; - if (!(f = obj_load(fp))) { + if (!(f = obj_load(fp, ET_REL))) { fclose(fp); return -1; } @@ -282,7 +327,8 @@ if (ELFW(ST_BIND)(objsym->info) != STB_WEAK) { undefs[n_undefs++] = addsym(objsym->name, mod, - SYM_UNDEF); + SYM_UNDEF, + ignore_suffix); } continue; } @@ -295,7 +341,8 @@ /* Ignore leading "__ksymtab_" */ defsym[n_defsym++] = addsym(objsym->name + 10, mod, - SYM_DEFINED); + SYM_DEFINED, + ignore_suffix); } continue; } @@ -311,7 +358,8 @@ if (ELFW(ST_BIND)(objsym->info) == STB_GLOBAL) { defsym[n_defsym++] = addsym(objsym->name, mod, - SYM_DEFINED); + SYM_DEFINED, + ignore_suffix); } continue; } @@ -328,7 +376,8 @@ ) { defsym[n_defsym++] = addsym(objsym->name, mod, - SYM_DEFINED); + SYM_DEFINED, + ignore_suffix); } } } @@ -385,7 +434,7 @@ int is_mapfile = 0; int n_syms = 0; int size; - char line[100]; + char line[PATH_MAX]; char *p; mod->name = "-"; @@ -396,8 +445,8 @@ /* Fake the _mod_use_count_ symbol provided by insmod */ /* Dummy */ - symtab[n_syms++] = addsym("mod_use_count_", mod, SYM_DEFINED); - symtab[n_syms++] = addsym("__this_module", mod, SYM_DEFINED); + symtab[n_syms++] = addsym("mod_use_count_", mod, SYM_DEFINED, 0); + symtab[n_syms++] = addsym("__this_module", mod, SYM_DEFINED, 0); /* * Specification: depmod / kernel syms only @@ -417,7 +466,7 @@ error("Can't read %s", file_syms); return -1; } - if (!fgets(line, 100, fp)) { + if (!fgets(line, sizeof(line), fp)) { fclose(fp); error("premature EOF on %s", file_syms); return -1; @@ -442,9 +491,9 @@ } if (p) - symtab[n_syms++] = addsym(p, mod, SYM_DEFINED); + symtab[n_syms++] = addsym(p, mod, SYM_DEFINED, 0); - while (fgets(line, 100, fp)) { + while (fgets(line, sizeof(line), fp)) { if (!is_mapfile && strchr(line, '[')) continue; strtok(line, " \t\n"); /* Skip first word */ @@ -455,7 +504,7 @@ p = strtok(NULL, " \t\n"); } assert(n_syms < 10000); - symtab[n_syms++] = addsym(p, mod, SYM_DEFINED); + symtab[n_syms++] = addsym(p, mod, SYM_DEFINED, 0); } fclose(fp); } else { /* Use the exported symbols from currently running kernel */ @@ -464,7 +513,7 @@ for (ksym = ksyms; so_far < nksyms; ++so_far, ksym++) { assert(n_syms < 10000); - symtab[n_syms++] = addsym((char *)ksym->name, mod, SYM_DEFINED); + symtab[n_syms++] = addsym((char *)ksym->name, mod, SYM_DEFINED, 0); } } @@ -561,7 +610,7 @@ "depmod -[aA] [-n -e -v -q -V]\n" " [-C configfile] [-F kernelsyms] [-b basedirectory] [forced_version]\n" "depmod [-n -e -v -q] [-f kernelsyms] module1.o module2.o ...\n" - "If no arguments (expect options) are given, \"depmod -a\" is assumed\n" + "If no arguments (except options) are given, \"depmod -a\" is assumed\n" "\n" "depmod will output a dependancy list suitable for the modprobe utility.\n" "depmod -a will find the list of modules to probe from the file\n" @@ -573,18 +622,28 @@ "\n" "Normally depmod operates silently, reporting only the list of modules that\n" "won't load properly (missing symbols).\n" - "Option -q will make depmod keep quiet about missing symbols\n" - "Option -e output all the unresolved symbol for a given module\n" - "Option -s output all error message to the syslog daemon\n" - "Option -v force a printout of all visited modules.\n" - "Option -n will write the dependency file on stdout only.\n" - "Option -V will show you the release version of depmod\n" - "Option -r will allow root to load modules that are not owned by root\n" "\n" - "The following options are useful for people managing distributions;\n" - "Option '-b basedirectory': use an image of a module tree.\n" - "Option '-C configfile': use the file instead of /etc/modules.conf.\n" - "Option '-F kernelsyms': use the file instead of the current kernel symbols.\n" + "Options:\n" + "\t-a, --all Probe modules listed in " ETC_MODULES_CONF "\n" + "\t-A Like -a, compares timestamps first\n" + "\t-q, --quiet Don't report missing symbols\n" + "\t-e, --errsyms List unresolved symbols for the given module\n" + "\t-s, --syslog Report errors using syslog\n" + "\t-v, --verbose Print all visited modules\n" + "\t-n, --show Write the dependency file on stdout only\n" + "\t-r, --root Allow root to allow modules not owned by root\n" + "\t-V, --version Print the release version\n" + "\t-h, --help Print this usage message\n" + "\n" + "The following options are useful for people managing distributions:\n" + "\t-b basedirectory\n" + "\t --basedir basedirectory Use an image of a module tree.\n" + "\t-C configfile\n" + "\t --config configfile Use the file instead of\n" + "\t " ETC_MODULES_CONF ".\n" + "\t-F kernelsyms\n" + "\t --filesyms kernelsyms Use the file instead of the\n" + "\t current kernel symbols.\n" ); } #endif /* defined(COMMON_3264) && defined(ONLY_32) */ @@ -601,10 +660,10 @@ #if defined(COMMON_3264) && defined(ONLY_64) int depmod_main(int argc, char **argv) { - if (arch64()) - return depmod_main_64(argc, argv); - else - return depmod_main_32(argc, argv); + if (arch64()) + return depmod_main_64(argc, argv); + else + return depmod_main_32(argc, argv); } #endif /* defined(COMMON_3264) && defined(ONLY_64) */ @@ -618,13 +677,14 @@ char *conf_file = NULL; char *file_syms = NULL; char *base_dir = NULL; + int ignore_suffix = 0; /* Ignore genksyms suffix on resolve? */ struct option long_opts[] = { {"all", 0, 0, 'a'}, {"basedir", 1, 0, 'b'}, {"config", 1, 0, 'C'}, {"errsyms", 0, 0, 'e'}, - {"filesysm", 1, 0, 'F'}, + {"filesyms", 1, 0, 'F'}, {"help", 0, 0, 'h'}, {"show", 0, 0, 'n'}, {"quiet", 0, 0, 'q'}, @@ -706,6 +766,8 @@ argc -= optind; argv += optind; + ignore_suffix = file_syms != NULL; + if (stdmode || argc == 0) { /* option -a is the default without arguments */ if (argc > 0) { @@ -721,19 +783,15 @@ int i; GLOB_LIST *g = config_lstmod(NULL, NULL, 0); for (i = 0; g && i < g->pathc; i++) - loadobj(g->pathv[i]); + loadobj(g->pathv[i], ignore_suffix); resolve(); - - if (nflag) - prtdepend(NULL, base_dir); - else - prtdepend(depfile, base_dir); + prtdepend(nflag ? NULL : depfile, base_dir); } } else { /* not stdmode */ if ((ret = addksyms(file_syms)) != -1) { for (; argc > 0 && ret != -1; ++argv, --argc) - loadobj(*argv); + loadobj(*argv, ignore_suffix); resolve(); prtdepend(NULL, base_dir); } diff -Nur modutils-2.3.10/example/kallsyms.c modutils-2.3.11/example/kallsyms.c --- modutils-2.3.10/example/kallsyms.c Thu Jan 1 10:00:00 1970 +++ modutils-2.3.11/example/kallsyms.c Fri Apr 21 19:31:54 2000 @@ -0,0 +1,264 @@ +/* An example of using kallsyms data in a kernel debugger. + + Copyright 2000 Keith Owens April 2000 + + 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: kallsyms.c 1.1 Fri, 21 Apr 2000 19:31:54 +1000 kaos $" + +/* + This code uses the list of all kernel and module symbols to :- + + * Find any non-stack symbol in a kernel or module. Symbols do + not have to be exported for debugging. + + * Convert an address to the module (or kernel) that owns it, the + section it is in and the nearest symbol. This finds all non-stack + symbols, not just exported ones. + + You need modutils >= 2.3.11 and a kernel with the kallsyms patch + which was compiled with CONFIG_KALLSYMS. + */ + +#include +#include +#include +#include +#include + +/* These external symbols are only available on kernels compiled with + * CONFIG_KALLSYMS. + */ + +extern const char __start___kallsyms[]; +extern const char __stop___kallsyms[]; + +static struct module *local_module_list; + +static void get_module_list(void) +{ + const struct kallsyms_header *ka_hdr; + const struct kallsyms_section *ka_sec; + const struct kallsyms_symbol *ka_sym; + const char *ka_str; + int i; + const char *p; + + if (__start___kallsyms >= __stop___kallsyms) + return; + ka_hdr = (struct kallsyms_header *)__start___kallsyms; + ka_sec = (struct kallsyms_section *) + ((char *)(ka_hdr) + ka_hdr->section_off); + ka_sym = (struct kallsyms_symbol *) + ((char *)(ka_hdr) + ka_hdr->symbol_off); + ka_str = + ((char *)(ka_hdr) + ka_hdr->string_off); + + for (i = 0; i < ka_hdr->symbols; kallsyms_next_sym(ka_hdr, ka_sym), ++i) { + p = ka_str + ka_sym->name_off; + if (strcmp(p, "module_list") == 0) { + if (ka_sym->symbol_addr) + local_module_list = *((struct module **)(ka_sym->symbol_addr)); + break; + } + } +} + +static void __inline__ do_first_time(void) +{ + static int first_time = 1; + if (first_time) + get_module_list(); + first_time = 0; +} + +/* A symbol can appear in more than one module. A token is used to + * restart the scan at the next module, set the token to 0 for the + * first scan of each symbol. + */ + +int kallsyms_symbol_to_address( + const char *name, /* Name to lookup */ + unsigned long *token, /* Which module to start at */ + const char **mod_name, /* Set to module name */ + unsigned long *mod_start, /* Set to start address of module */ + unsigned long *mod_end, /* Set to end address of module */ + const char **sec_name, /* Set to section name */ + unsigned long *sec_start, /* Set to start address of section */ + unsigned long *sec_end, /* Set to end address of section */ + const char **sym_name, /* Set to full symbol name */ + unsigned long *sym_start, /* Set to start address of symbol */ + unsigned long *sym_end /* Set to end address of symbol */ + ) +{ + const struct kallsyms_header *ka_hdr = NULL; /* stupid gcc */ + const struct kallsyms_section *ka_sec; + const struct kallsyms_symbol *ka_sym = NULL; + const char *ka_str = NULL; + const struct module *m; + int i = 0, l; + const char *p, *pt_R; + char *p2; + + do_first_time(); + + /* Restart? */ + m = local_module_list; + if (token && *token) { + for (; m; m = m->next) + if ((unsigned long)m == *token) + break; + if (m) + m = m->next; + } + + for (; m; m = m->next) { + if (!mod_member_present(m, kallsyms_start) || + !mod_member_present(m, kallsyms_end) || + m->kallsyms_start >= m->kallsyms_end) + continue; + ka_hdr = (struct kallsyms_header *)m->kallsyms_start; + ka_sym = (struct kallsyms_symbol *) + ((char *)(ka_hdr) + ka_hdr->symbol_off); + ka_str = + ((char *)(ka_hdr) + ka_hdr->string_off); + for (i = 0; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) { + p = ka_str + ka_sym->name_off; + if (strcmp(p, name) == 0) + break; + /* Unversioned requests match versioned names */ + if (!(pt_R = strstr(p, "_R"))) + continue; + l = strlen(pt_R); + if (l < 10) + continue; /* Not _R.*xxxxxxxx */ + (void)simple_strtoul(pt_R+l-8, &p2, 16); + if (*p2) + continue; /* Not _R.*xxxxxxxx */ + if (strncmp(p, name, pt_R-p) == 0) + break; /* Match with version */ + } + if (i < ka_hdr->symbols) + break; + } + + if (token) + *token = (unsigned long)m; + if (!m) + return(0); /* not found */ + + ka_sec = (const struct kallsyms_section *) + ((char *)ka_hdr + ka_hdr->section_off + ka_sym->section_off); + *mod_name = *(m->name) ? m->name : "kernel"; + *mod_start = ka_hdr->start; + *mod_end = ka_hdr->end; + *sec_name = ka_sec->name_off + ka_str; + *sec_start = ka_sec->start; + *sec_end = ka_sec->start + ka_sec->size; + *sym_name = ka_sym->name_off + ka_str; + *sym_start = ka_sym->symbol_addr; + if (i < ka_hdr->symbols-1) { + const struct kallsyms_symbol *ka_symn = ka_sym; + kallsyms_next_sym(ka_hdr, ka_symn); + *sym_end = ka_symn->symbol_addr; + } + else + *sym_end = *sec_end; + return(1); +} + +int kallsyms_address_to_symbol( + unsigned long address, /* Address to lookup */ + const char **mod_name, /* Set to module name */ + unsigned long *mod_start, /* Set to start address of module */ + unsigned long *mod_end, /* Set to end address of module */ + const char **sec_name, /* Set to section name */ + unsigned long *sec_start, /* Set to start address of section */ + unsigned long *sec_end, /* Set to end address of section */ + const char **sym_name, /* Set to full symbol name */ + unsigned long *sym_start, /* Set to start address of symbol */ + unsigned long *sym_end /* Set to end address of symbol */ + ) +{ + const struct kallsyms_header *ka_hdr = NULL; /* stupid gcc */ + const struct kallsyms_section *ka_sec = NULL; + const struct kallsyms_symbol *ka_sym; + const char *ka_str; + const struct module *m; + int i; + unsigned long end; + + do_first_time(); + + for (m = local_module_list; m; m = m->next) { + if (!mod_member_present(m, kallsyms_start) || + !mod_member_present(m, kallsyms_end) || + m->kallsyms_start >= m->kallsyms_end) + continue; + ka_hdr = (struct kallsyms_header *)m->kallsyms_start; + ka_sec = (const struct kallsyms_section *) + ((char *)ka_hdr + ka_hdr->section_off); + /* Is the address in any section in this module? */ + for (i = 0; i < ka_hdr->sections; ++i, kallsyms_next_sec(ka_hdr, ka_sec)) { + if (ka_sec->start <= address && + (ka_sec->start + ka_sec->size) > address) + break; + } + if (i < ka_hdr->sections) + break; /* Found a matching section */ + } + + if (!m) + return(0); /* not found */ + + ka_sym = (struct kallsyms_symbol *) + ((char *)(ka_hdr) + ka_hdr->symbol_off); + ka_str = + ((char *)(ka_hdr) + ka_hdr->string_off); + *mod_name = *(m->name) ? m->name : "kernel"; + *mod_start = ka_hdr->start; + *mod_end = ka_hdr->end; + *sec_name = ka_sec->name_off + ka_str; + *sec_start = ka_sec->start; + *sec_end = ka_sec->start + ka_sec->size; + *sym_name = *sec_name; /* In case we find no matching symbol */ + *sym_start = *sec_start; + *sym_end = *sec_end; + + for (i = 0; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) { + if (ka_sym->symbol_addr > address) + continue; + if (i < ka_hdr->symbols-1) { + const struct kallsyms_symbol *ka_symn = ka_sym; + kallsyms_next_sym(ka_hdr, ka_symn); + end = ka_symn->symbol_addr; + } + else + end = *sec_end; + if (end <= address) + continue; + if ((char *)ka_hdr + ka_hdr->section_off + ka_sym->section_off + != (char *)ka_sec) + continue; /* wrong section */ + *sym_name = ka_str + ka_sym->name_off; + *sym_start = ka_sym->symbol_addr; + *sym_end = end; + break; + } + return(1); +} diff -Nur modutils-2.3.10/genksyms/Makefile.in modutils-2.3.11/genksyms/Makefile.in --- modutils-2.3.10/genksyms/Makefile.in Tue Dec 7 18:15:35 1999 +++ modutils-2.3.11/genksyms/Makefile.in Thu Apr 13 18:17:59 2000 @@ -1,4 +1,4 @@ -# $Id: Makefile.in 1.7 Tue, 07 Dec 1999 18:15:35 +1100 keith $ +# $Id: Makefile.in 1.8 Thu, 13 Apr 2000 18:17:59 +1000 kaos $ srcdir=@srcdir@ VPATH=@srcdir@ @@ -68,7 +68,7 @@ install install-bin: all $(INSTALL) $(STRIP) genksyms $(sbindir) -# auto-generated dependancies are almost redundant once we add all the +# auto-generated dependancies are almost redundant once we add all the # rules to get the generated files built first. dep depend: diff -Nur modutils-2.3.10/genksyms/genksyms.c modutils-2.3.11/genksyms/genksyms.c --- modutils-2.3.10/genksyms/genksyms.c Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/genksyms/genksyms.c Thu Apr 13 18:17:59 2000 @@ -20,7 +20,7 @@ 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: genksyms.c 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $" +#ident "$Id: genksyms.c 1.2 Thu, 13 Apr 2000 18:17:59 +1000 kaos $" #include #include @@ -28,6 +28,7 @@ #include #include #include +#include #include "genksyms.h" #include "util.h" @@ -43,7 +44,7 @@ int cur_line = 1; char *cur_filename, *output_directory; -int flag_debug, flag_dump_defs, flag_export_globals, flag_warnings; +int flag_debug, flag_dump_defs, flag_warnings; int checksum_version = 1, kernel_version = version(2,0,0); static int errors; @@ -459,20 +460,48 @@ } +void genksyms_usage(void) +{ + fputs("Usage:\n" + "genksyms [-dDwqhV] [-k kernel_version] [-p prefix] > .../linux/module/*.ver\n" + "\n" + " -d, --debug Increment the debug level (repeatable)\n" + " -D, --dump Dump expanded symbol defs (for debugging only)\n" + " -w, --warnings Enable warnings\n" + " -q, --quiet Disable warnings (default)\n" + " -h, --help Print this message\n" + " -V, --version Print the release version\n" + " -k ver\n" + " --kernel ver Set the kernel version for which we are compiling\n" + " -p string\n" + " --prefix string Set a mangling prefix for all symbols\n" + , stderr); +} + int main(int argc, char **argv) { int o; - while ((o = getopt(argc, argv, "dgwqVDk:p:")) != EOF) + struct option long_opts[] = { + {"debug", 0, 0, 'd'}, + {"warnings", 0, 0, 'w'}, + {"quiet", 0, 0, 'q'}, + {"dump", 0, 0, 'D'}, + {"kernel", 1, 0, 'k'}, + {"prefix", 1, 0, 'p'}, + {"version", 0, 0, 'V'}, + {"help", 0, 0, 'h'}, + {0, 0, 0, 0} + }; + + while ((o = getopt_long(argc, argv, "dwqVDk:p:", + &long_opts[0], NULL)) != EOF) switch (o) { case 'd': flag_debug++; break; - case 'g': - flag_export_globals = 1; - break; case 'w': flag_warnings = 1; break; @@ -480,7 +509,7 @@ flag_warnings = 0; break; case 'V': - fputs("genksyms version " MODUTILS_VERSION "\n", stderr); + fputs("genksyms version " MODUTILS_VERSION "\n", stderr); break; case 'D': flag_dump_defs = 1; @@ -503,35 +532,24 @@ kernel_version = a << 16 | b << 8 | c; } - break; + break; case 'p': crc_prefix = optarg; break; - + case 'h': + genksyms_usage(); + return 0; default: - usage: - fputs("Usage:\n" - "genksyms [-dDwqV] -k kernel_version > .../linux/module/*.ver\n" - "\n" - " -d Debug level -- repeat to increase\n" - " -D Dump final exported definitions\n" - " -w Enable warnings (aka errors)\n" - " -q Disable warnings (default)\n" - " -V Show version\n" - " -k ver Set the kernel version for which we are compiling\n" - " -p string Set a mangling prefix for all symbols\n" - , stderr); + genksyms_usage(); return 1; } if (kernel_version >= version(2,1,18)) { - if (optind != argc) - goto usage; - - /* Exporting all globals is depreciated. */ - if (flag_export_globals) - goto usage; + if (optind != argc) { + genksyms_usage(); + return 1; + } /* For newer kernels, eliminate some irrelevant constructs. */ checksum_version = 2; @@ -540,8 +558,10 @@ } else { - if (optind+1 != argc) - goto usage; + if (optind+1 != argc) { + genksyms_usage(); + return 1; + } output_directory = argv[optind]; } @@ -557,11 +577,6 @@ } yyparse(); - - if (flag_export_globals) - { - /* FIXME */ - } if (checksum_version == 1) { diff -Nur modutils-2.3.10/genksyms/genksyms.h modutils-2.3.11/genksyms/genksyms.h --- modutils-2.3.10/genksyms/genksyms.h Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/genksyms/genksyms.h Thu Apr 13 18:17:59 2000 @@ -24,7 +24,7 @@ #ifndef MODUTILS_GENKSYMS_H #define MODUTILS_GENKSYMS_H 1 -#ident "$Id: genksyms.h 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $" +#ident "$Id: genksyms.h 1.2 Thu, 13 Apr 2000 18:17:59 +1000 kaos $" #include @@ -57,7 +57,7 @@ extern int cur_line; extern char *cur_filename, *output_directory; -extern int flag_debug, flag_dump_defs, flag_export_globals, flag_warnings; +extern int flag_debug, flag_dump_defs, flag_warnings; extern int checksum_version, kernel_version; extern int want_brace_phrase, want_exp_phrase, discard_phrase_contents; diff -Nur modutils-2.3.10/genksyms/keywords.c modutils-2.3.11/genksyms/keywords.c --- modutils-2.3.10/genksyms/keywords.c Sun Nov 21 19:27:16 1999 +++ modutils-2.3.11/genksyms/keywords.c Thu Apr 13 18:17:59 2000 @@ -2,7 +2,7 @@ /* Command-line: gperf -a -C -g -H is_reserved_hash -k 1,3,$ -N is_reserved_word -p -t keywords.gperf */ -#ident "$Id: keywords.c 1.2 Sun, 21 Nov 1999 19:27:16 +1100 keith $" +#ident "$Id: keywords.c 1.3 Thu, 13 Apr 2000 18:17:59 +1000 kaos $" struct resword { const char *name; int token; }; #define MIN_WORD_LENGTH 3 @@ -48,57 +48,57 @@ static const struct resword wordlist[] = { - {"",}, {"",}, {"",}, + {"",}, {"",}, {"",}, {"asm", ASM_KEYW}, - {"",}, + {"",}, {"__asm", ASM_KEYW}, - {"",}, + {"",}, {"__asm__", ASM_KEYW}, - {"",}, + {"",}, {"attribute", ATTRIBUTE_KEYW}, {"__signed__", SIGNED_KEYW}, {"__attribute", ATTRIBUTE_KEYW}, - {"",}, + {"",}, {"__attribute__", ATTRIBUTE_KEYW}, - {"",}, + {"",}, {"__volatile", VOLATILE_KEYW}, {"struct", STRUCT_KEYW}, {"__volatile__", VOLATILE_KEYW}, {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, - {"",}, {"",}, + {"",}, {"",}, {"extern", EXTERN_KEYW}, {"typedef", TYPEDEF_KEYW}, {"int", INT_KEYW}, {"auto", AUTO_KEYW}, {"short", SHORT_KEYW}, - {"",}, {"",}, + {"",}, {"",}, {"__inline", INLINE_KEYW}, {"enum", ENUM_KEYW}, {"__inline__", INLINE_KEYW}, - {"",}, {"",}, + {"",}, {"",}, {"__signed", SIGNED_KEYW}, - {"",}, + {"",}, {"float", FLOAT_KEYW}, {"static", STATIC_KEYW}, {"__const", CONST_KEYW}, {"volatile", VOLATILE_KEYW}, {"__const__", CONST_KEYW}, - {"",}, {"",}, {"",}, + {"",}, {"",}, {"",}, {"register", REGISTER_KEYW}, {"char", CHAR_KEYW}, - {"",}, + {"",}, {"signed", SIGNED_KEYW}, - {"",}, {"",}, {"",}, + {"",}, {"",}, {"",}, {"const", CONST_KEYW}, {"inline", INLINE_KEYW}, - {"",}, {"",}, + {"",}, {"",}, {"void", VOID_KEYW}, - {"",}, + {"",}, {"double", DOUBLE_KEYW}, - {"",}, + {"",}, {"unsigned", UNSIGNED_KEYW}, {"long", LONG_KEYW}, - {"",}, {"",}, {"",}, {"",}, {"",}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"union", UNION_KEYW}, }; diff -Nur modutils-2.3.10/genksyms/lex.l modutils-2.3.11/genksyms/lex.l --- modutils-2.3.10/genksyms/lex.l Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/genksyms/lex.l Fri Apr 14 11:59:15 2000 @@ -22,7 +22,7 @@ %{ -#ident "$Id: lex.l 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $" +#ident "$Id: lex.l 1.2 Fri, 14 Apr 2000 11:59:15 +1000 kaos $" #include #include @@ -77,7 +77,7 @@ {STRING} return STRING; {CHAR} return CHAR; -{IDENT} return IDENT; +{IDENT} return IDENT; /* The Pedant requires that the other C multi-character tokens be recognized as tokens. We don't actually use them since we don't diff -Nur modutils-2.3.10/genksyms/parse.y modutils-2.3.11/genksyms/parse.y --- modutils-2.3.10/genksyms/parse.y Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/genksyms/parse.y Thu Apr 13 18:17:59 2000 @@ -22,7 +22,7 @@ %{ -#ident "$Id: parse.y 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $" +#ident "$Id: parse.y 1.2 Thu, 13 Apr 2000 18:17:59 +1000 kaos $" #include #include "genksyms.h" @@ -346,8 +346,8 @@ remove_node($1); $$ = $1; } - /* This wasn't really a typedef name but an identifier that - shadows one. */ + /* This wasn't really a typedef name but an identifier that + shadows one. */ | TYPE { if (checksum_version > 1) remove_node($1); diff -Nur modutils-2.3.10/include/kallsyms.h modutils-2.3.11/include/kallsyms.h --- modutils-2.3.10/include/kallsyms.h Thu Jan 1 10:00:00 1970 +++ modutils-2.3.11/include/kallsyms.h Fri Apr 21 20:48:56 2000 @@ -0,0 +1,131 @@ +/* kallsyms headers + Copyright 2000 Keith Owens + + This file is part of the Linux modutils. It is exported to kernel + space so debuggers can access the kallsyms data. + + The kallsyms data contains all the non-stack symbols from a kernel + or a module. The kernel symbols are held between __start___kallsyms + and __stop___kallsyms. The symbols for a module are accessed via + the struct module chain which is based at module_list. + + 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: kallsyms.h 1.7 Fri, 21 Apr 2000 20:48:56 +1000 kaos $" + +#ifndef MODUTILS_KALLSYMS_H +#define MODUTILS_KALLSYMS_H 1 + +/* Have to (re)define these ElfW entries here because external kallsyms + * code does not have access to modutils/include/obj.h. This code is + * included from user spaces tools (modutils) and kernel, they need + * different includes. + */ + +#ifndef ELFCLASS32 +#ifdef __KERNEL__ +#include +#else /* __KERNEL__ */ +#include +#endif /* __KERNEL__ */ +#endif /* ELFCLASS32 */ + +#ifndef ELFCLASSM +#define ELFCLASSM ELF_CLASS +#endif + +#ifndef ElfW +# if ELFCLASSM == ELFCLASS32 +# define ElfW(x) Elf32_ ## x +# define ELFW(x) ELF32_ ## x +# else +# define ElfW(x) Elf64_ ## x +# define ELFW(x) ELF64_ ## x +# endif +#endif + +/* Format of data in the kallsyms section. + * Most of the fields are small numbers but the total size and all + * offsets can be large so use the 32/64 bit types for these fields. + * + * Do not use sizeof() on these structures, modutils may be using extra + * fields. Instead use the size fields in the header to access the + * other bits of data. + */ + +struct kallsyms_header { + int size; /* Size of this header */ + ElfW(Word) total_size; /* Total size of kallsyms data */ + int sections; /* Number of section entries */ + ElfW(Off) section_off; /* Offset to first section entry */ + int section_size; /* Size of one section entry */ + int symbols; /* Number of symbol entries */ + ElfW(Off) symbol_off; /* Offset to first symbol entry */ + int symbol_size; /* Size of one symbol entry */ + ElfW(Off) string_off; /* Offset to first string */ + ElfW(Addr) start; /* Start address of first section */ + ElfW(Addr) end; /* End address of last section */ +}; + +struct kallsyms_section { + ElfW(Addr) start; /* Start address of section */ + ElfW(Word) size; /* Size of this section */ + ElfW(Off) name_off; /* Offset to section name */ + ElfW(Word) flags; /* Flags from section */ +}; + +struct kallsyms_symbol { + ElfW(Off) section_off; /* Offset to section that owns this symbol */ + ElfW(Addr) symbol_addr; /* Address of symbol */ + ElfW(Off) name_off; /* Offset to symbol name */ +}; + +#define KALLSYMS_SEC_NAME "__kallsyms" +#define KALLSYMS_IDX 2 /* obj_kallsyms creates kallsyms as section 2 */ + +#define kallsyms_next_sec(h,s) \ + ((s) = (struct kallsyms_section *)((char *)(s) + (h)->section_size)) +#define kallsyms_next_sym(h,s) \ + ((s) = (struct kallsyms_symbol *)((char *)(s) + (h)->symbol_size)) + +int kallsyms_symbol_to_address( + const char *name, /* Name to lookup */ + unsigned long *token, /* Which module to start with */ + const char **mod_name, /* Set to module name or "kernel" */ + unsigned long *mod_start, /* Set to start address of module */ + unsigned long *mod_end, /* Set to end address of module */ + const char **sec_name, /* Set to section name */ + unsigned long *sec_start, /* Set to start address of section */ + unsigned long *sec_end, /* Set to end address of section */ + const char **sym_name, /* Set to full symbol name */ + unsigned long *sym_start, /* Set to start address of symbol */ + unsigned long *sym_end /* Set to end address of symbol */ + ); + +int kallsyms_address_to_symbol( + unsigned long address, /* Address to lookup */ + const char **mod_name, /* Set to module name */ + unsigned long *mod_start, /* Set to start address of module */ + unsigned long *mod_end, /* Set to end address of module */ + const char **sec_name, /* Set to section name */ + unsigned long *sec_start, /* Set to start address of section */ + unsigned long *sec_end, /* Set to end address of section */ + const char **sym_name, /* Set to full symbol name */ + unsigned long *sym_start, /* Set to start address of symbol */ + unsigned long *sym_end /* Set to end address of symbol */ + ); + +#endif /* kallsyms.h */ diff -Nur modutils-2.3.10/include/kerneld.h modutils-2.3.11/include/kerneld.h --- modutils-2.3.10/include/kerneld.h Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/include/kerneld.h Thu Apr 13 18:17:59 2000 @@ -1,10 +1,10 @@ -/* Definitions for the Linux kerneld SYSV IPC interface. +/* Definitions for the Linux kerneld SYSV IPC interface. This file was part of the Linux kernel, and so is covered by the GPL. */ #ifndef MODUTILS_KERNELD_H #define MODUTILS_KERNELD_H -#ident "$Id: kerneld.h 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $" +#ident "$Id: kerneld.h 1.2 Thu, 13 Apr 2000 18:17:59 +1000 kaos $" #define KERNELD_SYSTEM 1 #define KERNELD_REQUEST_MODULE 2 /* "insmod" */ diff -Nur modutils-2.3.10/include/module.h modutils-2.3.11/include/module.h --- modutils-2.3.10/include/module.h Fri Nov 26 00:00:09 1999 +++ modutils-2.3.11/include/module.h Tue Apr 18 13:38:59 2000 @@ -23,7 +23,7 @@ #ifndef MODUTILS_MODULE_H #define MODUTILS_MODULE_H 1 -#ident "$Id: module.h 1.2 Fri, 26 Nov 1999 00:00:09 +1100 keith $" +#ident "$Id: module.h 1.3 Tue, 18 Apr 2000 13:38:59 +1000 kaos $" /* This file contains the structures used by the 2.0 and 2.1 kernels. We do not use the kernel headers directly because we do not wish @@ -156,6 +156,8 @@ unsigned tgt_long persist_end; unsigned tgt_long can_unload; unsigned tgt_long runsize; + unsigned tgt_long kallsyms_start; + unsigned tgt_long kallsyms_end; }; struct module_info diff -Nur modutils-2.3.10/include/obj.h modutils-2.3.11/include/obj.h --- modutils-2.3.10/include/obj.h Mon Nov 22 01:38:27 1999 +++ modutils-2.3.11/include/obj.h Tue Apr 18 13:38:59 2000 @@ -24,7 +24,7 @@ #ifndef MODUTILS_OBJ_H #define MODUTILS_OBJ_H 1 -#ident "$Id: obj.h 1.2 Mon, 22 Nov 1999 01:38:27 +1100 keith $" +#ident "$Id: obj.h 1.4 Tue, 18 Apr 2000 13:38:59 +1000 kaos $" /* The relocatable object is manipulated using elfin types. */ @@ -148,7 +148,7 @@ #define obj_extend_section ObjW(extend_section) #define obj_string_patch ObjW(string_patch) #define obj_symbol_patch ObjW(symbol_patch) -#define obj_check_undefineds ObjW(check_undefineds) +#define obj_check_undefineds ObjW(check_undefineds) #define obj_allocate_commons ObjW(allocate_commons) #define obj_load_size ObjW(load_size) #define obj_relocate ObjW(relocate) @@ -163,9 +163,9 @@ #define arch_init_module ObjW(arch_init_module) #define arch_load_proc_section ObjW(arch_load_proc_section) -unsigned long obj_elf_hash(const char *); +unsigned long obj_elf_hash (const char *); -unsigned long obj_elf_hash_n(const char *, unsigned long len); +unsigned long obj_elf_hash_n (const char *, unsigned long len); struct obj_symbol *obj_add_symbol (struct obj_file *f, const char *name, unsigned long symidx, int info, int secidx, @@ -174,10 +174,10 @@ struct obj_symbol *obj_find_symbol (struct obj_file *f, const char *name); -ElfW(Addr) obj_symbol_final_value(struct obj_file *f, +ElfW(Addr) obj_symbol_final_value (struct obj_file *f, struct obj_symbol *sym); -void obj_set_symbol_compare(struct obj_file *f, +void obj_set_symbol_compare (struct obj_file *f, int (*cmp)(const char *, const char *), unsigned long (*hash)(const char *)); @@ -199,26 +199,28 @@ void *obj_extend_section (struct obj_section *sec, unsigned long more); -int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, +int obj_string_patch (struct obj_file *f, int secidx, ElfW(Addr) offset, const char *string); -int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, +int obj_symbol_patch (struct obj_file *f, int secidx, ElfW(Addr) offset, struct obj_symbol *sym); -int obj_check_undefineds(struct obj_file *f, int quiet); +int obj_check_undefineds (struct obj_file *f, int quiet); -void obj_allocate_commons(struct obj_file *f); +void obj_allocate_commons (struct obj_file *f); unsigned long obj_load_size (struct obj_file *f); int obj_relocate (struct obj_file *f, ElfW(Addr) base); -struct obj_file *obj_load(FILE *f); +struct obj_file *obj_load (FILE *f, Elf32_Half e_type); -void obj_free(struct obj_file *f); +void obj_free (struct obj_file *f); int obj_create_image (struct obj_file *f, char *image); +int obj_kallsyms (struct obj_file *fin, struct obj_file **fout); + /* Architecture specific manipulation routines. */ struct obj_file *arch_new_file (void); @@ -238,6 +240,6 @@ struct module; int arch_init_module (struct obj_file *f, struct module *); -int arch_load_proc_section(struct obj_section *sec, FILE *fp); +int arch_load_proc_section (struct obj_section *sec, FILE *fp); #endif /* obj.h */ diff -Nur modutils-2.3.10/include/version.h modutils-2.3.11/include/version.h --- modutils-2.3.10/include/version.h Sat Dec 25 18:38:01 1999 +++ modutils-2.3.11/include/version.h Tue Apr 4 12:41:06 2000 @@ -1 +1 @@ -#define MODUTILS_VERSION "2.3.10" +#define MODUTILS_VERSION "2.3.11" diff -Nur modutils-2.3.10/insmod/Makefile.in modutils-2.3.11/insmod/Makefile.in --- modutils-2.3.10/insmod/Makefile.in Sat Dec 25 14:34:16 1999 +++ modutils-2.3.11/insmod/Makefile.in Tue Apr 18 13:38:59 2000 @@ -1,4 +1,4 @@ -# $Id: Makefile.in 1.17 Sat, 25 Dec 1999 14:34:16 +1100 keith $ +# $Id: Makefile.in 1.18 Tue, 18 Apr 2000 13:38:59 +1000 kaos $ srcdir=@srcdir@ VPATH=@srcdir@ @@ -22,10 +22,10 @@ DEFSNOARCH := -I$(srcdir)/../include -D_GNU_SOURCE @DEFS@ $(EXTRA_DEFS) DEFS := -DELF_MACHINE_H='"elf_$(ARCH).h"' -DARCH_$(ARCH) -PROGS := insmod modprobe rmmod lsmod ksyms modinfo +PROGS := insmod modprobe rmmod lsmod ksyms kallsyms modinfo # COMB is the list of utilities to combine with insmod into one executable -COMB := @COMBINE_rmmod@ @COMBINE_modprobe@ @COMBINE_lsmod@ @COMBINE_ksyms@ +COMB := @COMBINE_rmmod@ @COMBINE_modprobe@ @COMBINE_lsmod@ @COMBINE_ksyms@ @COMBINE_kallsyms@ COMBDEFS := $(addprefix -DCOMBINE_, $(COMB)) COMB_STATIC := $(addsuffix .static, $(COMB)) @@ -45,7 +45,7 @@ MODINFOOBJS += modinfo_64.o DEFSNOARCH += -DCOMMON_3264 DEFS += -DONLY_32 -DEFS64 := -DELF_MACHINE_H='"elf_sparc64.h"' -DARCH_sparc64 -DONLY_64 +DEFS64 := -DONLY_64 -DELF_MACHINE_H='"elf_sparc64.h"' -DARCH_sparc64 endif INSMODOBJS += $(addsuffix .o, $(COMB)) @@ -62,7 +62,7 @@ $(CC) $(CFLAGS) $(DEFSNOARCH) $(DEFS64) $(COMBDEFS) -c -o $@ $< # Rule for building "normal" modutils executables (non-combined) -%: %.c ../util/libutil.a +%: %.c ../obj/libobj.a ../util/libutil.a $(CC) $(CFLAGS) $(DEFSNOARCH) $(DEFS) -o $@ $^ $(LDFLAGS) #===================================================================== diff -Nur modutils-2.3.10/insmod/insmod.c modutils-2.3.11/insmod/insmod.c --- modutils-2.3.10/insmod/insmod.c Wed Mar 15 23:50:08 2000 +++ modutils-2.3.11/insmod/insmod.c Fri Apr 21 13:50:20 2000 @@ -4,7 +4,7 @@ New implementation contributed by Richard Henderson Based on original work by Bjorn Ekwall Restructured (and partly rewritten) by: - Björn Ekwall February 1999 + Björn Ekwall February 1999 This file is part of the Linux modutils. @@ -39,14 +39,16 @@ More flexible recognition of the way the utility was called. Suggested by Stepan Kasal, implemented in a different way by Keith Owens December 1999. - + Rationalize common code for 32/64 bit architectures. Keith Owens December 1999. Add arch64(). Keith Owens December 1999. + kallsyms support + Keith Owens April 2000. */ -#ident "$Id: insmod.c 1.12 Wed, 15 Mar 2000 23:50:08 +1100 keith $" +#ident "$Id: insmod.c 1.17 Fri, 21 Apr 2000 13:50:20 +1000 kaos $" #include #include @@ -63,6 +65,7 @@ #include "module.h" #include "obj.h" +#include "kallsyms.h" #include "util.h" #include "version.h" @@ -90,6 +93,7 @@ extern int rmmod_main(int argc, char **argv); extern int ksyms_main(int argc, char **argv); extern int lsmod_main(int argc, char **argv); +extern int kallsyms_main(int argc, char **argv); /*======================================================================*/ @@ -116,7 +120,7 @@ return a << 16 | b << 8 | c; } -/* String comparison for non-co-versioned kernel and module. +/* String comparison for non-co-versioned kernel and module. * prefix should be the same as used by genksyms for this kernel. */ static char *ncv_prefix = NULL; /* Overridden by --prefix option */ @@ -183,7 +187,7 @@ !(ncv_plen && strncmp(b + alen + 2, ncv_prefix, ncv_plen))) { return strncmp(a, b, alen); } else if (alen == blen + 10 + ncv_plen && - a[blen] == '_' && a[blen + 1] == 'R' && + a[blen] == '_' && a[blen + 1] == 'R' && !(ncv_plen && strncmp(a + blen + 2, ncv_prefix, ncv_plen))) { return strncmp(a, b, blen); } else @@ -599,10 +603,12 @@ return obj_find_symbol(f, "Using_Versions") != NULL; } -/* add module source, timestamp, kernel version and a symbol for the start of some sections. - * this info is used by ksymoops to do better debugging. +/* add module source, timestamp, kernel version and a symbol for the + * start of some sections. this info is used by ksymoops to do better + * debugging. */ -static void add_ksymoops_symbols(struct obj_file *f, const char *filename, const char *m_name) +static void add_ksymoops_symbols(struct obj_file *f, const char *filename, + const char *m_name) { struct obj_section *sec; struct obj_symbol *sym; @@ -921,7 +927,63 @@ return 1; } -static int init_module(const char *m_name, struct obj_file *f, unsigned long m_size) + +/* Add a kallsyms section if the kernel supports all symbols. */ +static int add_kallsyms(struct obj_file *f, + struct obj_section **module_kallsyms) +{ + struct module_symbol *s; + struct obj_file *f_kallsyms; + struct obj_section *sec_kallsyms; + size_t i; + int l; + const char *p, *pt_R; + unsigned long start = 0, stop = 0; + + for (i = 0, s = ksyms; i < nksyms; ++i, ++s) { + p = (char *)s->name; + pt_R = strstr(p, "_R"); + if (pt_R) + l = pt_R - p; + else + l = strlen(p); + if (strncmp(p, "__start_" KALLSYMS_SEC_NAME, l) == 0) + start = s->value; + else if (strncmp(p, "__stop_" KALLSYMS_SEC_NAME, l) == 0) + stop = s->value; + } + + if (start >= stop) + return(0); + + /* The kernel contains all symbols, do the same for this module. */ + + /* Add an empty kallsyms section to the module if necessary */ + for (i = 0; i < f->header.e_shnum; ++i) { + if (strcmp(f->sections[i]->name, KALLSYMS_SEC_NAME) == 0) { + *module_kallsyms = f->sections[i]; + break; + } + } + if (!*module_kallsyms) + *module_kallsyms = obj_create_alloced_section(f, KALLSYMS_SEC_NAME, 0, 0); + + /* Size and populate kallsyms */ + if (obj_kallsyms(f, &f_kallsyms)) + return(1); + sec_kallsyms = f_kallsyms->sections[KALLSYMS_IDX]; + (*module_kallsyms)->header.sh_addralign = sec_kallsyms->header.sh_addralign; + (*module_kallsyms)->header.sh_size = sec_kallsyms->header.sh_size; + free((*module_kallsyms)->contents); + (*module_kallsyms)->contents = sec_kallsyms->contents; + sec_kallsyms->contents = NULL; + obj_free(f_kallsyms); + + return 0; +} + +static int init_module(const char *m_name, struct obj_file *f, + unsigned long m_size) { struct module *module; struct obj_section *sec; @@ -948,7 +1010,8 @@ module->ndeps = n_ext_modules_used; } module->init = obj_symbol_final_value(f, obj_find_symbol(f, "init_module")); - module->cleanup = obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module")); + module->cleanup = obj_symbol_final_value(f, + obj_find_symbol(f, "cleanup_module")); sec = obj_find_section(f, "__ex_table"); if (sec) { @@ -965,6 +1028,11 @@ module->runsize > sec->header.sh_addr - m_addr) module->runsize = sec->header.sh_addr - m_addr; } + sec = obj_find_section(f, KALLSYMS_SEC_NAME); + if (sec && sec->header.sh_size) { + module->kallsyms_start = sec->header.sh_addr; + module->kallsyms_end = module->kallsyms_start + sec->header.sh_size; + } if (!arch_init_module(f, module)) return 0; @@ -978,9 +1046,9 @@ ret = sys_init_module(m_name, (struct module *) image); if (ret) { error("init_module: %m"); - if (ret == -EBUSY) + if (errno == EBUSY) lprintf("Hint: this error can be caused by incorrect module parameters, " - "including invalid IO and IRQ parameters\n"); + "including invalid IO or IRQ parameters"); } free(image); @@ -989,7 +1057,8 @@ } #ifdef COMPAT_2_0 -static int old_init_module(const char *m_name, struct obj_file *f, unsigned long m_size) +static int old_init_module(const char *m_name, struct obj_file *f, + unsigned long m_size) { char *image; struct old_mod_routines routines; @@ -1014,7 +1083,7 @@ } total = (sizeof(struct old_symbol_table) + nsyms * sizeof(struct old_module_symbol) + - n_ext_modules_used * sizeof(struct old_module_ref) + + n_ext_modules_used * sizeof(struct old_module_ref) + strsize); symtab = xmalloc(total); symtab->size = total; @@ -1061,7 +1130,8 @@ /* Fill in routines. */ routines.init = obj_symbol_final_value(f, obj_find_symbol(f, "init_module")); - routines.cleanup = obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module")); + routines.cleanup = obj_symbol_final_value(f, + obj_find_symbol(f, "cleanup_module")); /* * Whew! All of the initialization is complete. @@ -1078,7 +1148,7 @@ */ ret = old_sys_init_module(m_name, image + sizeof(long), (m_size - sizeof(long)) | - (flag_autoclean ? OLD_MOD_AUTOCLEAN : 0), + (flag_autoclean ? OLD_MOD_AUTOCLEAN : 0), &routines, symtab); if (ret) @@ -1101,25 +1171,27 @@ void insmod_usage(void) { fputs("Usage:\n" - "insmod [-fkmopsvVxXyY] [-o name] [-P prefix] module [[sym=value]...]\n" + "insmod [-fhkmopqsvVxXyY] [-o name] [-P prefix] module [[sym=value]...]\n" "\n" " module Filename of a loadable kernel module (*.o)\n" " -f, --force Force loading under wrong kernel version\n" + " -h, --help Print this message.\n" " -k, --autoclean Make module autoclean-able\n" " -m, --map Generate load map (so crashes can be traced)\n" " -n, --noload Don't load, just show\n" " -o NAME, --name=NAME Set internal module name to NAME\n" " -p, --poll Poll mode; check if the module matches the kernel\n" + " -q, --quiet Don't print unresolved symbols\n" " -s, --syslog Report errors via syslog\n" " -v, --verbose Verbose output\n" " -L, --lock Prevent simultaneous loads of the same module\n" " -V, --version Show version\n" - " -x Do not export externs\n" - " -X Do export externs (default)\n" - " -y Do not add ksymoops symbols\n" - " -Y Do add ksymoops symbols (default)\n" - " -r Allow root to load modules not owned by root\n" + " -x, --noexport Do not export externs\n" + " -X, --export Do export externs (default)\n" + " -y, --noksymoops Do not add ksymoops symbols\n" + " -Y, --ksymoops Do add ksymoops symbols (default)\n" + " -r, --root Allow root to load modules not owned by root\n" " -P PREFIX\n" " --prefix=PREFIX Prefix for kernel or module symbols\n" ,stderr); @@ -1158,6 +1230,7 @@ {"noksymoops", 0, 0, 'y'}, {"ksymoops", 0, 0, 'Y'}, {"root", 0, 0, 'r'}, + {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; char *m_name = NULL; @@ -1169,6 +1242,7 @@ char *filename; FILE *fp; struct obj_file *f; + struct obj_section *kallsyms = NULL; int o; int noload = 0; int dolock = 1; /*Note: was: 0; */ @@ -1182,7 +1256,7 @@ errors = optind = 0; /* Process the command line. */ - while ((o = getopt_long(argc, argv, "fkmno:pqsvVxXLP:yYr", + while ((o = getopt_long(argc, argv, "fhkmno:pqsvVxXLP:yYr", &long_opts[0], NULL)) != EOF) switch (o) { case 'f': /* force loading */ @@ -1236,6 +1310,7 @@ case 'P': /* use prefix on crc */ set_ncv_prefix(optarg); break; + case 'h': /* Print the usage message. */ default: insmod_usage(); break; @@ -1309,7 +1384,7 @@ } error_file = filename; - if ((f = obj_load(fp)) == NULL) + if ((f = obj_load(fp, ET_REL)) == NULL) goto out; /* Version correspondence? */ @@ -1371,6 +1446,11 @@ if (k_new_syscalls) create_module_ksymtab(f); + /* kallsyms based on relocatable addresses */ + if (add_kallsyms(f, &kallsyms)) + goto out; + /**** No symbols or sections to be changed after kallsyms above ***/ + if (errors) goto out; @@ -1418,6 +1498,11 @@ delete_module(m_name); goto out; } + + /* Do kallsyms again, this time we have the final addresses */ + if (add_kallsyms(f, &kallsyms)) + goto out; + if (!noload) { #ifdef COMPAT_2_0 if (k_new_syscalls) @@ -1485,6 +1570,9 @@ #ifdef COMBINE_lsmod { "lsmod", &lsmod_main }, #endif + #ifdef COMBINE_kallsyms + { "kallsyms", &kallsyms_main }, + #endif }; #define MAINS_NO (sizeof(mains)/sizeof(mains[0])) static int mains_match; @@ -1521,7 +1609,8 @@ if (mains_match == 0 && MAINS_NO == 1) ++mains_match; /* Not combined, any name will do */ if (mains_match == 0) { - error("%s does not have a recognisable name, the name must contain one of %s.", + error("%s does not have a recognisable name, " + "the name must contain one of %s.", error_id1, error_id2); return(1); } diff -Nur modutils-2.3.10/insmod/kallsyms.c modutils-2.3.11/insmod/kallsyms.c --- modutils-2.3.10/insmod/kallsyms.c Thu Jan 1 10:00:00 1970 +++ modutils-2.3.11/insmod/kallsyms.c Thu Apr 20 14:31:49 2000 @@ -0,0 +1,160 @@ +/* Create a section containing all the symbols for an object. + + Copyright 2000 Keith Owens April 2000 + + 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. + */ + + /* + Fixes: + */ + +#ident "$Id: kallsyms.c 1.2 Thu, 20 Apr 2000 14:31:49 +1000 kaos $" + +#include +#include + +#include "module.h" +#include "obj.h" +#include "kallsyms.h" +#include "util.h" +#include "version.h" + +extern int kallsyms_main_32(int argc, char **argv); +extern int kallsyms_main_64(int argc, char **argv); + +/*======================================================================*/ + +/* For common 3264 code, only compile the usage message once, in the 64 bit version */ +#if defined(COMMON_3264) && defined(ONLY_32) +extern void kallsyms_usage(void); /* Use the copy in the 64 bit version */ +#else /* Common 64 bit version or any non common code - compile usage routine */ +void +kallsyms_usage (void) +{ + fputs("Usage:\n" + "kallsyms [-Vh] file\n" + + "\n" + " -V, --version Show version\n" + " -h, --help Print this message.\n" + " file Filename of a kernel (e.g. vmlinux)\n" + ,stderr); +} +#endif /* defined(COMMON_3264) && defined(ONLY_32) */ + +#if defined(COMMON_3264) && defined(ONLY_32) +#define KALLSYMS_MAIN kallsyms_main_32 /* 32 bit version */ +#elif defined(COMMON_3264) && defined(ONLY_64) +#define KALLSYMS_MAIN kallsyms_main_64 /* 64 bit version */ +#else +#define KALLSYMS_MAIN kallsyms_main /* Not common code */ +#endif + +int KALLSYMS_MAIN (int argc, char **argv) +{ + struct option long_opts[] = { + {"version", 0, 0, 'V'}, + {"help", 0, 0, 'h'}, + {0, 0, 0, 0} + }; + char *filename = NULL; + FILE *fp; + struct obj_file *fin, *fout; + int i, c; + + error_file = "kallsyms"; + + /* To handle repeated calls from combined modprobe */ + errors = optind = 0; + + /* Process the command line. */ + while ((c = getopt_long(argc, argv, "Vh", + &long_opts[0], NULL)) != EOF) + switch (c) { + case 'V': + fputs("kallsyms version " MODUTILS_VERSION "\n", stderr); + return(0); + case 'h': /* Print the usage message. */ + kallsyms_usage(); + return(0); + default: + kallsyms_usage(); + return(1); + } + + if (optind != argc-1) { + kallsyms_usage(); + return(1); + } + + filename = argv[optind++]; + error_file = filename; + if ((fp = fopen(filename, "r")) == NULL) { + error("%s: %m", filename); + return 1; + } + + if ((fin = obj_load(fp, ET_EXEC)) == NULL) { + fclose(fp); + return 1; + } + fclose(fp); + + error_file = "kallsyms"; + if (obj_kallsyms(fin, &fout)) + return 1; + + /* Write the extracted data */ + fwrite(&fout->header, sizeof(fout->header), 1, stdout); + for (i = 0; i < fout->header.e_shnum; ++i) + fwrite(&fout->sections[i]->header, fout->header.e_shentsize, 1, stdout); + for (i = 0; i < fout->header.e_shnum; ++i) { + if (fout->sections[i]->header.sh_size) { + fseek(stdout, fout->sections[i]->header.sh_offset, SEEK_SET); + fwrite(fout->sections[i]->contents, + fout->sections[i]->header.sh_size, 1, stdout); + } + } + + return 0; +} + +/* For common 3264 code, add an overall kallsyms_main, in the 64 bit version. */ +#if defined(COMMON_3264) && defined(ONLY_64) +int kallsyms_main (int argc, char **argv) +{ + if (arch64()) + return kallsyms_main_64(argc, argv); + else + return kallsyms_main_32(argc, argv); +} +#endif /* defined(COMMON_3264) && defined(ONLY_64) */ + + +/* For common 3264 code, only compile main in the 64 bit version. */ +#if defined(COMMON_3264) && defined(ONLY_32) +/* Use the main in the 64 bit version */ +#else +/* Not common 3264 code, only need main if not combined with insmod */ +#ifndef COMBINE_kallsyms +int main(int argc, char **argv) +{ + return(kallsyms_main(argc, argv)); +} +#endif /* COMBINE_kallsyms */ +#endif /* defined(COMMON_3264) && defined(ONLY_32) */ diff -Nur modutils-2.3.10/insmod/ksyms.c modutils-2.3.11/insmod/ksyms.c --- modutils-2.3.10/insmod/ksyms.c Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/insmod/ksyms.c Thu Apr 13 18:17:59 2000 @@ -21,9 +21,10 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id: ksyms.c 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $" +#ident "$Id: ksyms.c 1.2 Thu, 13 Apr 2000 18:17:59 +1000 kaos $" #include +#include #include "module.h" #include "version.h" @@ -35,6 +36,19 @@ #define main ksyms_main #endif +void ksyms_usage(void) +{ + fputs("Usage:\n" + "ksyms [-ahm?V]\n" + "\n" + " -a, --all Display all symbols\n" + " -h, --noheader Suppress the column header\n" + " -m, --info Display module information\n" + " -H, --help Print this message\n" + " -V, --version Print the release version\n" + ,stderr); +} + /*FIXME: A non-root ksyms: copy the output from /proc/ksyms */ int main(int argc, char **argv) { @@ -46,9 +60,19 @@ int flag_mod_info = 0; int flag_print_header = 1; + struct option long_opts[] = { + {"all", 0, 0, 'a'}, + {"info", 0, 0, 'm'}, + {"noheader", 0, 0, 'h'}, + {"version", 0, 0, 'V'}, + {"help", 0, 0, 'H'}, + {0, 0, 0, 0} + }; + error_file = "ksyms"; - while ((i = getopt(argc, argv, "amhV")) != EOF) + while ((i = getopt_long(argc, argv, "amhVH", + &long_opts[0], NULL)) != EOF) switch (i) { case 'a': flag_allsyms = 1; @@ -62,6 +86,12 @@ case 'V': fputs("ksyms version " MODUTILS_VERSION "\n", stderr); break; + case 'H': + ksyms_usage(); + return 0; + default: + ksyms_usage(); + return 1; } if (!get_kernel_info(K_SYMBOLS | K_INFO)) diff -Nur modutils-2.3.10/insmod/lsmod.c modutils-2.3.11/insmod/lsmod.c --- modutils-2.3.10/insmod/lsmod.c Fri Nov 26 00:00:09 1999 +++ modutils-2.3.11/insmod/lsmod.c Thu Apr 13 18:17:59 2000 @@ -21,30 +21,62 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id: lsmod.c 1.2 Fri, 26 Nov 1999 00:00:09 +1100 keith $" +#ident "$Id: lsmod.c 1.3 Thu, 13 Apr 2000 18:17:59 +1000 kaos $" #include #include #include #include #include +#include #include "module.h" #include "util.h" #include "obj.h" #include "modstat.h" +#include "version.h" #ifdef COMBINE_lsmod #define main lsmod_main #endif +void lsmod_usage(void) +{ + fputs("Usage:\n" + "lsmod [-Vh]\n" + "\n" + " -V, --version Print the release version\n" + " -h, --help Print this message\n" + ,stderr); +} + int main(int argc, char **argv) { struct module_stat *m; int i; int j; + struct option long_opts[] = { + {"version", 0, 0, 'V'}, + {"help", 0, 0, 'h'}, + {0, 0, 0, 0} + }; + error_file = "lsmod"; + + while ((i = getopt_long(argc, argv, "Vh", + &long_opts[0], NULL)) != EOF) + switch(i) { + case 'V': + fputs("lsmod version " MODUTILS_VERSION "\n",stderr); + return 0; + case 'h': + lsmod_usage(); + return 0; + default: + lsmod_usage(); + return 1; + } /* A header. */ puts("Module Size Used by"); diff -Nur modutils-2.3.10/insmod/modinfo.c modutils-2.3.11/insmod/modinfo.c --- modutils-2.3.10/insmod/modinfo.c Sun Dec 26 20:47:58 1999 +++ modutils-2.3.11/insmod/modinfo.c Thu Apr 20 14:31:49 2000 @@ -31,7 +31,7 @@ * Keith Owens December 1999. */ -#ident "$Id: modinfo.c 1.6 Sun, 26 Dec 1999 20:47:58 +1100 keith $" +#ident "$Id: modinfo.c 1.8 Thu, 20 Apr 2000 14:31:49 +1000 kaos $" #include #include @@ -134,11 +134,13 @@ break; case 'a': - (void) append_modinfo_tag(f, "author", "", &out_str, last_char - out_str); + (void) append_modinfo_tag(f, "author", "", + &out_str, last_char - out_str); break; case 'd': - (void) append_modinfo_tag(f, "description", "", &out_str, last_char - out_str); + (void) append_modinfo_tag(f, "description", "", + &out_str, last_char - out_str); break; case '{':{ @@ -178,7 +180,8 @@ return &buffer[0]; } -static void show_parameter(struct obj_file *f, char *key, char *value, char *desc) +static void show_parameter(struct obj_file *f, char *key, char *value, + char *desc) { struct obj_symbol *sym; int min, max; @@ -303,7 +306,7 @@ if ((fp = fopen(filename, "r")) == NULL) { error("%s: %m", filename); return -1; - } else if ((f = obj_load(fp)) == NULL) + } else if ((f = obj_load(fp, ET_REL)) == NULL) return -1; fclose(fp); diff -Nur modutils-2.3.10/insmod/modprobe.c modutils-2.3.11/insmod/modprobe.c --- modutils-2.3.10/insmod/modprobe.c Thu Mar 16 21:19:15 2000 +++ modutils-2.3.11/insmod/modprobe.c Thu Apr 20 14:31:49 2000 @@ -368,7 +368,8 @@ * aliased off -1 * error -2 */ -static int build_stack(LINK **stack, const char *name, const char *objname, int dir, DESC *rev, int mode, int allow_alias) +static int build_stack(LINK **stack, const char *name, const char *objname, + int dir, DESC *rev, int mode, int allow_alias) { NODE *nod; DESC *desc; @@ -458,7 +459,8 @@ * not allowed. */ for (nod = desc->nod->dep; nod; nod = nod->next) { - if ((r = build_stack(stack, nod->key, nod->str, dir, rev, MODE_NORMAL, 0)) < 0) + if ((r = build_stack(stack, nod->key, nod->str, dir, rev, + MODE_NORMAL, 0)) < 0) return r; } @@ -1236,7 +1238,8 @@ * Install OK: 0 asked_for points to the requested module node * */ -static int probe_stack(const char *name, const char *obj, char **options, DESC **asked_for) +static int probe_stack(const char *name, const char *obj, char **options, + DESC **asked_for) { LINK *stack; LINK *p; @@ -1309,7 +1312,7 @@ * # * An option is a keyword followed by an equal sign and a value. * No spaces are allowed in the sequence, unless quoted. - * + * * The option list ends at the end of the list or at the * first non-option argument (a possible next module). */ @@ -1417,9 +1420,12 @@ "options:\n" "\t-a, --all Load _all_ matching modules\n" "\t-c, --showconfig Show current configuration\n" + "\t-d, --debug Print debugging information\n" + "\t-h, --help Print this message\n" "\t-k, --autoclean Set 'autoclean' on loaded modules\n" "\t-l, --list List matching modules\n" "\t-n, --show Don't actually perform the action\n" + "\t-q, --quiet Quiet operation\n" "\t-r, --remove Remove module (stacks) or do autoclean\n" "\t-s, --syslog Use syslog to report\n" "\t-t, --type moduletype Only look for modules of this type\n" @@ -1452,12 +1458,13 @@ {"syslog", 0, 0, 's'}, {"config", 1, 0, 'C'}, {"quiet", 1, 0, 'q'}, + {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; error_file = "modprobe"; - while ((o = getopt_long(argc, argv, "t:acdlnqrvksC:V", + while ((o = getopt_long(argc, argv, "t:acdhlnqrvksC:V", &long_opts[0], NULL)) != EOF) { switch (o) { case 't': /* type of module */ @@ -1475,7 +1482,10 @@ case 'd': debug = 1; break; - + case 'h': + usage(); + return 0; + break; case 'l': list = 1; break; diff -Nur modutils-2.3.10/insmod/rmmod.c modutils-2.3.11/insmod/rmmod.c --- modutils-2.3.10/insmod/rmmod.c Sat Dec 25 14:34:16 1999 +++ modutils-2.3.11/insmod/rmmod.c Thu Apr 13 18:17:59 2000 @@ -24,11 +24,12 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id: rmmod.c 1.6 Sat, 25 Dec 1999 14:34:16 +1100 keith $" +#ident "$Id: rmmod.c 1.7 Thu, 13 Apr 2000 18:17:59 +1000 kaos $" #include #include #include +#include #include "module.h" #include "version.h" @@ -43,6 +44,19 @@ #define main rmmod_main #endif +void rmmod_usage(void) +{ + fputs("Usage:\n" + "rmmod [-arshV] module ...\n" + "\n" + " -a, --all Remove all unused modules\n" + " -r, --stacks Remove stacks, starting at the named module\n" + " -s, --syslog Use syslog for error messages\n" + " -h, --help Print this message\n" + " -V, --version Print the release version number\n" + ,stderr); +} + int main(int argc, char **argv) { struct module_stat *m; @@ -53,6 +67,15 @@ size_t n_module_names; char *module_names = NULL; + struct option long_opts[] = { + {"all", 0, 0, 'a'}, + {"stacks", 0, 0, 'r'}, + {"syslog", 0, 0, 's'}, + {"version", 0, 0, 'V'}, + {"help", 0, 0, 'h'}, + {0, 0, 0, 0} + }; + error_file = "rmmod"; /* @@ -60,12 +83,13 @@ * gives no indication that any modules were deleted so we have to * do it the hard way. */ - get_kernel_info(0); + get_kernel_info(0); module_names = xmalloc(l_module_name_list); memcpy(module_names, module_name_list, l_module_name_list); n_module_names = n_module_stat; - while ((i = getopt(argc, argv, "arsV")) != EOF) + while ((i = getopt_long(argc, argv, "arsVh", + &long_opts[0], NULL)) != EOF) switch (i) { case 'a': /* Remove all unused modules and stacks. */ @@ -93,9 +117,12 @@ fputs("rmmod version " MODUTILS_VERSION "\n", stderr); break; + case 'h': + rmmod_usage(); + return 0; default: - usage: - fputs("Usage: rmmod [-a] [-r] [-s] module ...\n", stderr); + usage: + rmmod_usage(); return 1; } diff -Nur modutils-2.3.10/insmod/test/test.c modutils-2.3.11/insmod/test/test.c --- modutils-2.3.10/insmod/test/test.c Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/insmod/test/test.c Thu Apr 13 18:17:59 2000 @@ -18,7 +18,7 @@ printk("load=<%s>\n", load); if (load[0]) - request_module(load); + request_module(load); return fail; } diff -Nur modutils-2.3.10/install-sh modutils-2.3.11/install-sh --- modutils-2.3.10/install-sh Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/install-sh Thu Apr 13 18:17:59 2000 @@ -115,7 +115,7 @@ if [ x"$dir_arg" != x ]; then dst=$src src="" - + if [ -d $dst ]; then instcmd=: else @@ -124,7 +124,7 @@ else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad +# might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] @@ -134,7 +134,7 @@ echo "install: $src does not exist" exit 1 fi - + if [ x"$dst" = x ] then echo "install: no destination specified" @@ -162,7 +162,7 @@ # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then -defaultIFS=' +defaultIFS=' ' IFS="${IFS-${defaultIFS}}" @@ -201,17 +201,17 @@ # If we're going to rename the final executable, determine the name now. - if [ x"$transformarg" = x ] + if [ x"$transformarg" = x ] then dstfile=`basename $dst` else - dstfile=`basename $dst $transformbasename | + dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename - if [ x"$dstfile" = x ] + if [ x"$dstfile" = x ] then dstfile=`basename $dst` else @@ -242,7 +242,7 @@ # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile + $doit $mvcmd $dsttmp $dstdir/$dstfile fi && diff -Nur modutils-2.3.10/kerneld/README.kerneld modutils-2.3.11/kerneld/README.kerneld --- modutils-2.3.10/kerneld/README.kerneld Fri Oct 8 20:23:53 1999 +++ modutils-2.3.11/kerneld/README.kerneld Fri Apr 14 11:59:15 2000 @@ -1,8 +1,8 @@ - "Kerneld": An implementation of "kernel deamons" - or + "Kerneld": An implementation of "kernel deamons" + or A truly automatic and invisible support for loadable modules in Linux - Bjorn Ekwall in May 1995 and January + March 1996 + Bjorn Ekwall in May 1995 and January + March 1996 Executive summary: @@ -35,7 +35,7 @@ Example: I have these lines to complement the defaults in modprobe: alias scsi_hostadapter aha1542 - alias eth0 3c509 + alias eth0 3c509 alias eth1 de620 options de620 bnc=1 ("modprobe -c" will show you the current modprobe configuration) diff -Nur modutils-2.3.10/kerneld/README.ppp-slip modutils-2.3.11/kerneld/README.ppp-slip --- modutils-2.3.10/kerneld/README.ppp-slip Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/kerneld/README.ppp-slip Thu Apr 13 18:17:59 2000 @@ -60,18 +60,18 @@ @@ -73,6 +73,10 @@ #include "vt_kern.h" #include "selection.h" - + +#ifdef CONFIG_KERNELD +#include +#endif + #define CONSOLE_DEV MKDEV(TTY_MAJOR,0) #define TTY_DEV MKDEV(TTYAUX_MAJOR,0) - + @@ -211,8 +215,17 @@ - int retval = 0; - struct tty_ldisc o_ldisc; - + int retval = 0; + struct tty_ldisc o_ldisc; + - if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS) || - !(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) + if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS)) @@ -85,6 +85,6 @@ + } +#endif + if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) - return -EINVAL; - - if (tty->ldisc.num == ldisc) + return -EINVAL; + + if (tty->ldisc.num == ldisc) diff -Nur modutils-2.3.10/kerneld/kerneld.c modutils-2.3.11/kerneld/kerneld.c --- modutils-2.3.10/kerneld/kerneld.c Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/kerneld/kerneld.c Fri Apr 14 11:59:15 2000 @@ -28,7 +28,7 @@ * Kerneld warnings: Steve Dodd */ -#ident "$Id: kerneld.c 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $" +#ident "$Id: kerneld.c 1.3 Fri, 14 Apr 2000 11:59:15 +1000 kaos $" #define CONFIG_KERNELD #include @@ -372,7 +372,7 @@ } } break; - + case KERNELD_SYSTEM: if (newjob->msg.id) /* reply wanted */ pipe(pipes); @@ -422,7 +422,7 @@ exit(1); } break; - + case KERNELD_DELAYED_RELEASE_MODULE: case KERNELD_RELEASE_MODULE: if (keep) @@ -471,7 +471,7 @@ exit(1); } break; - + case KERNELD_BLANKER: /* Find any previous running blanker */ for (job = job_head; job; job = job->next) { @@ -619,7 +619,7 @@ break; for (prev = &persist_head, persist = persist_head; persist; - prev = &(persist->next), persist = persist->next) { + prev = &(persist->next), persist = persist->next) { if (strcmp(k->arr, persist->key.dptr) == 0) break; } @@ -729,7 +729,7 @@ if ((select(job->reply_fd + 1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timeout) > 0) && - FD_ISSET(job->reply_fd, &readfds)) { + FD_ISSET(job->reply_fd, &readfds)) { job->reply_size = read(job->reply_fd, job->msg.text, MSIZE); } diff -Nur modutils-2.3.10/man/create_module.2 modutils-2.3.11/man/create_module.2 --- modutils-2.3.10/man/create_module.2 Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/man/create_module.2 Thu Apr 13 18:17:59 2000 @@ -1,7 +1,7 @@ .\" Copyright (C) 1996 Free Software Foundation, Inc. .\" This file is distributed accroding to the GNU General Public License. .\" See the file COPYING in the top level source directory for details. -.\" $Id: create_module.2 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $ +.\" $Id: create_module.2 1.2 Thu, 13 Apr 2000 18:17:59 +1000 kaos $ .\" .TH CREATE_MODULE 2 "26 Dec 1996" Linux "Linux Module Support" .SH NAME @@ -36,7 +36,7 @@ enough for the module. .TP .B EFAULT -.I name +.I name is outside the program's accessible address space. .SH "SEE ALSO .BR init_module "(2), " delete_module "(2), " query_module "(2)." diff -Nur modutils-2.3.10/man/delete_module.2 modutils-2.3.11/man/delete_module.2 --- modutils-2.3.10/man/delete_module.2 Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/man/delete_module.2 Thu Apr 13 18:17:59 2000 @@ -1,7 +1,7 @@ .\" Copyright (C) 1996 Free Software Foundation, Inc. .\" This file is distributed accroding to the GNU General Public License. .\" See the file COPYING in the top level source directory for details. -.\" $Id: delete_module.2 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $ +.\" $Id: delete_module.2 1.2 Thu, 13 Apr 2000 18:17:59 +1000 kaos $ .\" .TH DELETE_MODULE 2 "26 Dec 1996" Linux "Linux Module Support" .SH NAME @@ -35,7 +35,7 @@ The module is in use. .TP .B EFAULT -.I name +.I name is outside the program's accessible address space. .SH "SEE ALSO .BR create_module "(2), " init_module "(2), " query_module "(2). diff -Nur modutils-2.3.10/man/depmod.8 modutils-2.3.11/man/depmod.8 --- modutils-2.3.10/man/depmod.8 Wed Mar 15 21:14:05 2000 +++ modutils-2.3.11/man/depmod.8 Thu Apr 20 14:31:49 2000 @@ -2,7 +2,7 @@ .\" Copyright (c) 1995, 1999 Bjorn Ekwall (bj0rn@blox.se) .\" This program is distributed according to the Gnu General Public License. .\" See the file COPYING in the base distribution directory -.\" $Id: depmod.8 1.5 Wed, 15 Mar 2000 21:14:05 +1100 keith $ +.\" $Id: depmod.8 1.6 Thu, 20 Apr 2000 14:31:49 +1000 kaos $ .\" .TH DEPMOD 8 "October 12, 1999" Linux "Linux Module Support" .SH NAME @@ -95,7 +95,8 @@ The environment variable .B MODULECONF can also be used to select a different -configuration file from the default /etc/modules.conf (or /etc/conf.modules (depreciated)). +configuration file from the default /etc/modules.conf (or +/etc/conf.modules (depreciated)). .TP .I "\-F kernelsyms" When building dependency files for a different kernel than the currently diff -Nur modutils-2.3.10/man/genksyms.8 modutils-2.3.11/man/genksyms.8 --- modutils-2.3.10/man/genksyms.8 Fri Oct 8 20:23:53 1999 +++ modutils-2.3.11/man/genksyms.8 Thu Apr 13 18:17:59 2000 @@ -2,7 +2,7 @@ .\" Copyright (c) 1997 Linux International .\" This program is distributed according to the Gnu General Public License. .\" See the file COPYING in the kernel source directory /linux -.\" $Id: genksyms.8 1.2 Fri, 08 Oct 1999 20:23:53 +1000 keith $ +.\" $Id: genksyms.8 1.3 Thu, 13 Apr 2000 18:17:59 +1000 kaos $ .\" .TH GENKSYMS 8 "Sep 10, 1997" Linux "Linux Module Support" .SH NAME @@ -17,7 +17,7 @@ .B gcc -E source.c and generates a file containing version information. .PP -Depending on the output format indicated by the +Depending on the output format indicated by the .B \-k option, the output will either be written to a .ver file in the named output directory, or to the standard output. @@ -55,14 +55,14 @@ Dump expanded symbol definitions to stderr. For debugging use only. .TP 8 .I \-d -Output debugging information; repeating this option increases the +Output debugging information; repeating this option increases the verbosity. Debug level 1 generates moderate information about the actions being taken; debug level 2 enables parser recognition output; debug level 3 enables lexical analysis output. .TP 8 .I \-k version Select the version of the kernel for which to generate output. Omitting -this option assumes a version below 2.1.0. Versions below 2.1.18 +this option assumes a version below 2.1.0. Versions below 2.1.18 use checksum version 1, and produce their output in the directory given on the command line. Versions 2.1.18 and above use checksum version 2 and produce their output on stdout. diff -Nur modutils-2.3.10/man/get_kernel_syms.2 modutils-2.3.11/man/get_kernel_syms.2 --- modutils-2.3.10/man/get_kernel_syms.2 Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/man/get_kernel_syms.2 Thu Apr 13 18:17:59 2000 @@ -1,7 +1,7 @@ .\" Copyright (C) 1996 Free Software Foundation, Inc. .\" This file is distributed accroding to the GNU General Public License. .\" See the file COPYING in the top level source directory for details. -.\" $Id: get_kernel_syms.2 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $ +.\" $Id: get_kernel_syms.2 1.2 Thu, 13 Apr 2000 18:17:59 +1000 kaos $ .\" .TH GET_KERNEL_SYMS 2 "26 Dec 1996" Linux "Linux Module Support" .SH NAME @@ -13,8 +13,8 @@ .BI "int get_kernel_syms(struct kernel_sym *" table ); .fi .SH DESCRIPTION -If \fItable\fP is \fBNULL\fP, \fBget_kernel_syms\fP returns the -number of symbols available for query. Otherwise it fills in a +If \fItable\fP is \fBNULL\fP, \fBget_kernel_syms\fP returns the +number of symbols available for query. Otherwise it fills in a table of structures: .PP .RS diff -Nur modutils-2.3.10/man/init_module.2 modutils-2.3.11/man/init_module.2 --- modutils-2.3.10/man/init_module.2 Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/man/init_module.2 Thu Apr 13 18:17:59 2000 @@ -1,7 +1,7 @@ .\" Copyright (C) 1996 Free Software Foundation, Inc. .\" This file is distributed accroding to the GNU General Public License. .\" See the file COPYING in the top level source directory for details. -.\" $Id: init_module.2 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $ +.\" $Id: init_module.2 1.2 Thu, 13 Apr 2000 18:17:59 +1000 kaos $ .\" .TH INIT_MODULE 2 "26 Dec 1996" "Linux 2.1.17" "Linux Module Support" .SH NAME @@ -14,7 +14,7 @@ .fi .SH DESCRIPTION .B init_module -loads the relocated module image into kernel space and runs the +loads the relocated module image into kernel space and runs the module's \fIinit\fP function. .PP The module image begins with a module structure and is followed by diff -Nur modutils-2.3.10/man/insmod.8 modutils-2.3.11/man/insmod.8 --- modutils-2.3.10/man/insmod.8 Wed Mar 15 23:50:08 2000 +++ modutils-2.3.11/man/insmod.8 Thu Apr 20 14:31:49 2000 @@ -1,14 +1,15 @@ .\" Copyright (c) 1996 Free Software Foundation, Inc. .\" This program is distributed according to the Gnu General Public License. .\" See the file COPYING in the kernel source directory. -.\" $Id: insmod.8 1.5 Wed, 15 Mar 2000 23:50:08 +1100 keith $ +.\" $Id: insmod.8 1.7 Thu, 20 Apr 2000 14:31:49 +1000 kaos $ .\" .TH INSMOD 8 "October 12 1999" Linux "Linux Module Support" .SH NAME insmod \- install loadable kernel module .SH SYNOPSIS .B insmod -[\-fkmpqrsxXvyY] [\-P\ prefix] [\-o\ module_name] object_file [\ symbol=value\ ...\ ] +[\-fkmpqrsxXvyY] [\-P\ prefix] [\-o\ module_name] +object_file [\ symbol=value\ ...\ ] .SH DESCRIPTION .B Insmod installs a loadable module in the running kernel. @@ -17,15 +18,16 @@ tries to link a module into the running kernel by resolving all symbols from the kernel's exported symbol table. .PP -If the object file name is given without extension, +If the object file name is given without extension, .B insmod will search for the module in some common default directories. The environment variable MODPATH can be used to override this default. If a module configuration file such as /etc/modules.conf exists, it will override the paths defined in MODPATH. .br -The environment variable MODULECONF can also be used to select a different -configuration file from the default /etc/modules.conf (or /etc/conf.modules (depreciated)). +The environment variable MODULECONF can also be used to select a +different configuration file from the default /etc/modules.conf (or +/etc/conf.modules (depreciated)). This environment variable will override all the definitions above. .SS OPTIONS .TP @@ -115,11 +117,11 @@ In modules built for 2.0 series kernels, any integer or character pointer symbol may be treated as a parameter and modified. Beginning in the 2.1 series kernels, symbols are explicitly marked as parameters so that -only specific values may be changed. Furthermore type information is +only specific values may be changed. Furthermore type information is provided for checking the values provided at load time. .PP In the case of integers, all values may be in decimal, octal or -hexadecimal a la C: 17, 021 or 0x11. Array elements are specified +hexadecimal a la C: 17, 021 or 0x11. Array elements are specified sequence separated by commas; elements can be skipped by omitting the value. .PP diff -Nur modutils-2.3.10/man/kallsyms.8 modutils-2.3.11/man/kallsyms.8 --- modutils-2.3.10/man/kallsyms.8 Thu Jan 1 10:00:00 1970 +++ modutils-2.3.11/man/kallsyms.8 Thu Apr 20 11:14:13 2000 @@ -0,0 +1,154 @@ +.\" Copyright (c) 2000 Keith Owens +.\" This program is distributed according to the Gnu General Public License. +.\" See the file COPYING in the kernel source directory. +.\" $Id: kallsyms.8 1.2 Thu, 20 Apr 2000 11:14:13 +1000 kaos $ +.\" +.TH KALLSYMS 8 "April 20 2000" Linux "Linux Module Support" +.SH NAME +kallsyms \- Extract all kernel symbols for debugging +.SH SYNOPSIS +.B kallsyms +[\-Vh] kernel_filename +.SH DESCRIPTION +.hy 0 +.B Kallsyms +extracts all the non-stack symbols from a kernel and builds a data blob +that can be linked into that kernel for use by debuggers. +.PP +A normal kernel only exports symbols that are used by modules. +For debugging you may want a list of all the non-stack symbols, not +just the exported ones. +.B kallsyms +extracts all sections and symbols from a kernel, constructs a list of +the sections, symbols and their addresses and writes a relocatable +object containing just the __kallsyms section. +After the __kallsyms section is linked into the kernel and the kernel +has been booted, any debugger can use the data in the __kallsyms +section to get better symbol resolution. +.PP +For example, a debugger can use the __kallsyms data to resolve a kernel +address to\ :- +.PD 0 +.IP * 3 +The owning kernel or module. +.IP * 3 +The section within the owning code. +.IP * 3 +The nearest symbol. +.PD 1 +.fi +.SS OPTIONS +.TP +.I "\-V" +Print the version of modutils. +.TP +.I "\-h" +Print the help text. +.SH LINKER PASSES +.PP +To create a kernel containing an accurate __kallsyms section, you have +to make four linker passes instead of the normal single link step. +kallsyms and the linker are fast, the three extra steps take a few +seconds on a P200. +.IP 1 3 +The initial build of the kernel, without any __kallsyms data. +Run kallsyms against the output of this link, creating a relocatable +object which contains all the sections and symbols in the raw kernel. +.IP 2 3 +Link the kernel again, this time including the kallsyms output from +step (1). +Adding the __kallsyms section changes the number of sections and many +of the kernel symbol offsets so run kallsyms again against the second +link, again saving the relocatable output. +.IP 3 3 +Link the kernel again, this time including the kallsyms output from +step (2). +Run kallsyms against the latest version of the kernel. +The size and position of the __kallsyms section on this run is now +stable, none of the kernel sections or symbols will change after this +run. +The kallsyms output contains the final values of the kernel symbols. +.IP 4 3 +Link the final kernel, including the kallsyms output from step (3). +.SH DATA FORMAT +.PP +The __kallsyms section is a bit unusual. +It deliberately has no relocatable data, all "pointers" are represented +as byte offsets into the section or as absolute numbers. +This means it can be stored anywhere without relocation problems. +In particular it can be stored within a kernel image, it can be stored +separately from the kernel image, it can be appended to a module just +before loading, it can be stored in a separate area etc. +.PP +/usr/include/sys/kallsyms.h contains the mappings for the __kallsyms +data. +.SS Header +.PD 0 +.IP * 3 +Size of header. +.IP * 3 +Total size of the __kallsyms data, including strings. +.IP * 3 +Number of sections. +This only included sections which are loaded into memory. +.IP * 3 +Offset to the first section entry from start of the __kallsyms header. +.IP * 3 +Size of each section entry, excluding the name string. +.IP * 3 +Number of symbols. +.IP * 3 +Offset to the first symbol entry from the start of the __kallsyms +header. +.IP * 3 +Size of each symbol entry, excluding the name string. +.IP * 3 +Offset to the first string from the start of the __kallsyms header. +.IP * 3 +Start address of the first section[1]. +.IP * 3 +End address of the last section[1]. +.PD 1 +.SS Section entry +.PP +One entry per loaded section. +Since __kallsyms is a loaded section, if the input file contains a +__kallsyms section then it is included in this list. +.PD 0 +.IP * 3 +Start of the section within the kernel[1]. +.IP * 3 +Size of section. +.IP * 3 +Offset to the name of section, from the start of the __kallsyms +strings. +.IP * 3 +Section flags, from the original Elf section. +.PD 1 +.SS Symbol entry +.PP +One per symbol in the input file. +Only symbols that fall within loaded sections are stored. +.PD 0 +.IP * 3 +Offset to the __kallsyms section entry that this symbol falls within. +The offset is from the start of the __kallsyms section entries. +.IP * 3 +Address of the symbol within the kernel[1]. +The symbols are sorted in ascending order on this field. +.IP * 3 +Offset to the name of symbol, from the start of the __kallsyms strings. +.PD 1 +.SS Strings +.PP +A set of NUL terminated strings. +Each name is referenced using an offset from the start of the +__kallsyms string area. +.SS Note [1] +.PP +These fields are exceptions to the "everything is an offset" rule. +They contain absolute addresses within the kernel. +.SH SEE ALSO +\fBinsmod\fP(8). +.SH HISTORY +Initial version by Keith Owens , April 2000 diff -Nur modutils-2.3.10/man/kerneld.8 modutils-2.3.11/man/kerneld.8 --- modutils-2.3.10/man/kerneld.8 Sun Dec 19 20:23:21 1999 +++ modutils-2.3.11/man/kerneld.8 Thu Apr 20 14:31:49 2000 @@ -1,7 +1,7 @@ .\" Copyright (c) 1995 Bjorn Ekwall .\" This program is distributed according to the Gnu General Public License. .\" See the file COPYING in the kernel source directory /linux -.\" $Id: kerneld.8 1.2 Sun, 19 Dec 1999 20:23:21 +1100 keith $ +.\" $Id: kerneld.8 1.3 Thu, 20 Apr 2000 14:31:49 +1000 kaos $ .\" .TH KERNELD 8 "May 14, 1995" Linux "Linux Extensions" .SH NAME @@ -77,4 +77,5 @@ .SH SEE ALSO insmod(8), rmmod(8), modprobe(8), depmod(8), syslogd(8) .SH HISTORY -The kerneld support was inspired by discussions with Jacques Gelinas +The kerneld support was inspired by discussions with Jacques Gelinas + diff -Nur modutils-2.3.10/man/kernelversion.1 modutils-2.3.11/man/kernelversion.1 --- modutils-2.3.10/man/kernelversion.1 Tue Oct 12 21:06:08 1999 +++ modutils-2.3.11/man/kernelversion.1 Thu Apr 13 18:17:59 2000 @@ -1,4 +1,4 @@ -.\" $Id: kernelversion.1 1.2 Tue, 12 Oct 1999 21:06:08 +1000 keith $ +.\" $Id: kernelversion.1 1.3 Thu, 13 Apr 2000 18:17:59 +1000 kaos $ .TH KERNELVERSION 1 "Debian GNU/Linux" "DEBIAN" .SH NAME kernelversion \- program to report major version of kernel @@ -8,7 +8,7 @@ .B kernelversion is a small program for Debian/GNU Linux to report the major version of the kernel. This version is used by the modutils package to calculate -the directories for kernel modules. See +the directories for kernel modules. See .B /etc/modules.conf for a sample usage. .SH OPTIONS diff -Nur modutils-2.3.10/man/modprobe.8 modutils-2.3.11/man/modprobe.8 --- modutils-2.3.10/man/modprobe.8 Tue Oct 12 20:53:21 1999 +++ modutils-2.3.11/man/modprobe.8 Thu Apr 20 14:31:49 2000 @@ -2,7 +2,7 @@ .\" Copyright (c) 1995, 1999 Bjorn Ekwall (bj0rn@blox.se) .\" This program is distributed according to the Gnu General Public License. .\" See the file COPYING in the base distribution directory -.\" $Id: modprobe.8 1.3 Tue, 12 Oct 1999 20:53:21 +1000 keith $ +.\" $Id: modprobe.8 1.4 Thu, 20 Apr 2000 14:31:49 +1000 kaos $ .\" .TH MODPROBE 8 "March 15, 1999" Linux "Linux Module Support" .SH NAME @@ -87,7 +87,8 @@ can also be used to select (and override) a different -configuration file from the default /etc/modules.conf (or /etc/conf.modules (depreciated)). +configuration file from the default /etc/modules.conf (or +/etc/conf.modules (depreciated)). .SH DESCRIPTION The .B modprobe diff -Nur modutils-2.3.10/man/modules.conf.5 modutils-2.3.11/man/modules.conf.5 --- modutils-2.3.10/man/modules.conf.5 Thu Mar 16 21:19:15 2000 +++ modutils-2.3.11/man/modules.conf.5 Thu Apr 13 18:17:59 2000 @@ -1,7 +1,7 @@ .\"/* Copyright 1999 Bjorn Ekwall .\" This program is distributed according to the Gnu General Public License. .\" See the file COPYING in the base distribution directory -.\" +.\" .TH MODULES.CONF 5 "07 December 1999" .UC 4 .SH NAME @@ -491,6 +491,7 @@ path[atm]=/lib/modules/`uname \-r`/atm path[usb]=/lib/modules/`uname \-r`/usb path[ide]=/lib/modules/`uname \-r`/ide + path[ieee1394]=/lib/modules/`uname \-r`/ieee1394 path[fs]=/lib/modules/`kernelversion`/fs path[net]=/lib/modules/`kernelversion`/net @@ -507,6 +508,7 @@ path[atm]=/lib/modules/`kernelversion`/atm path[usb]=/lib/modules/`kernelversion`/usb path[ide]=/lib/modules/`kernelversion`/ide + path[ieee1394]=/lib/modules/`kernelversion`/ieee1394 path[fs]=/lib/modules/default/fs path[net]=/lib/modules/default/net @@ -523,6 +525,7 @@ path[atm]=/lib/modules/default/atm path[usb]=/lib/modules/default/usb path[ide]=/lib/modules/default/ide + path[ieee1394]=/lib/modules/default/ieee1394 path[fs]=/lib/modules/fs path[net]=/lib/modules/net @@ -539,6 +542,7 @@ path[atm]=/lib/modules/atm path[usb]=/lib/modules/usb path[ide]=/lib/modules/ide + path[ieee1394]=/lib/modules/ieee1394 .PP There are also a set of default .I alias diff -Nur modutils-2.3.10/man/query_module.2 modutils-2.3.11/man/query_module.2 --- modutils-2.3.10/man/query_module.2 Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/man/query_module.2 Thu Apr 13 18:17:59 2000 @@ -1,7 +1,7 @@ .\" Copyright (C) 1996 Free Software Foundation, Inc. .\" This file is distributed accroding to the GNU General Public License. .\" See the file COPYING in the top level source directory for details. -.\" $Id: query_module.2 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $ +.\" $Id: query_module.2 1.2 Thu, 13 Apr 2000 18:17:59 +1000 kaos $ .\" .TH QUERY_MODULE 2 "26 Dec 1996" "Linux 2.1.17" "Linux Module Support" .SH NAME @@ -14,10 +14,10 @@ void *\fIbuf\fB, size_t \fIbufsize\fB, size_t *\fIret\fB); .fi .SH DESCRIPTION -.B query_module +.B query_module requests information related to loadable modules from the kernel. The precise nature of the information and its format depends on the \fIwhich\fP -subfunction. Some functions require \fIname\fP to name a currently +subfunction. Some functions require \fIname\fP to name a currently loaded module, some allow \fIname\fP to be \fBNULL\fP indicating the kernel proper. @@ -27,8 +27,8 @@ Always returns success. Used to probe for the system call. .TP .B QM_MODULES -Returns the names of all loaded modules. The output buffer format is -adjacent null-terminated strings; \fIret\fP is set to the number of +Returns the names of all loaded modules. The output buffer format is +adjacent null-terminated strings; \fIret\fP is set to the number of modules. .TP .B QM_DEPS @@ -74,7 +74,7 @@ .fi .PP where \fIaddress\fP is the kernel address at which the module resides, -\fIsize\fP is the size of the module in bytes, and \fIflags\fP is +\fIsize\fP is the size of the module in bytes, and \fIflags\fP is a mask of \fBMOD_RUNNING\fP, \fBMOD_AUTOCLEAN\fP, et al that indicates the current status of the module. \fIret\fP is set to the size of the \fBmodule_info\fP struct. @@ -88,7 +88,7 @@ No module by that \fIname\fP exists. .TP .B EINVAL -Invalid \fIwhich\fP, or \fIname\fP indicates the kernel for an +Invalid \fIwhich\fP, or \fIname\fP indicates the kernel for an inappropriate subfunction. .TP .B ENOSPC diff -Nur modutils-2.3.10/modutils.spec modutils-2.3.11/modutils.spec --- modutils-2.3.10/modutils.spec Sat Dec 25 18:38:01 1999 +++ modutils-2.3.11/modutils.spec Fri Apr 21 19:34:16 2000 @@ -1,6 +1,6 @@ Summary: Module utilities Name: modutils -Version: 2.3.10 +Version: 2.3.11 Release: 1 Copyright: GPL Group: Utilities/System @@ -32,7 +32,7 @@ mkdir -p $RPM_BUILD_ROOT/{usr/man/man{1,2,5,8},sbin} make install prefix=$RPM_BUILD_ROOT/usr exec_prefix=$RPM_BUILD_ROOT # kerneld is not compiled by default, it is obsolete for kernel >= 2.1.91. -# (cd kerneld; +# (cd kerneld; # make install-scripts prefix=$RPM_BUILD_ROOT/usr exec_prefix=$RPM_BUILD_ROOT # ) # security hole, works poorly anyway @@ -53,6 +53,7 @@ %attr(755,root,root)/sbin/modinfo %attr(755,root,root)/sbin/modprobe %attr(755,root,root)/sbin/rmmod +%attr(755,root,root)/sbin/kallsyms %attr(755,root,root)/sbin/insmod_ksymoops_clean %attr(755,root,root)/sbin/kernelversion %attr(644,root,root)/usr/man/man1/kernelversion.1 @@ -71,4 +72,5 @@ %attr(644,root,root)/usr/man/man8/modinfo.8 %attr(644,root,root)/usr/man/man8/modprobe.8 %attr(644,root,root)/usr/man/man8/rmmod.8 -%attr(-,root,root) %doc COPYING README CREDITS TODO ChangeLog NEWS +%attr(644,root,root)/usr/man/man8/kallsyms.8 +%attr(-,root,root) %doc COPYING README CREDITS TODO ChangeLog NEWS example/kallsyms.c include/kallsyms.h diff -Nur modutils-2.3.10/obj/Makefile.in modutils-2.3.11/obj/Makefile.in --- modutils-2.3.10/obj/Makefile.in Sun Dec 19 20:23:21 1999 +++ modutils-2.3.11/obj/Makefile.in Tue Apr 18 13:38:59 2000 @@ -1,4 +1,4 @@ -# $Id: Makefile.in 1.10 Sun, 19 Dec 1999 20:23:21 +1100 keith $ +# $Id: Makefile.in 1.11 Tue, 18 Apr 2000 13:38:59 +1000 kaos $ srcdir=@srcdir@ VPATH=@srcdir@ @@ -21,15 +21,15 @@ DEFSNOARCH := -I$(srcdir)/../include -D_GNU_SOURCE @DEFS@ $(EXTRA_DEFS) DEFS := -DELF_MACHINE_H='"elf_$(ARCH).h"' -DARCH_$(ARCH) -LIBOBJ_OBJS := obj_common.o obj_load.o obj_reloc.o obj_$(ARCH).o +LIBOBJ_OBJS := obj_kallsyms.o obj_common.o obj_load.o obj_reloc.o obj_$(ARCH).o LIBOBJ_SRCS := $(LIBOBJ_OBJS:.o=.c) ifeq (@COMMON_sparc@,yes) -LIBOBJ_OBJS += obj_common_64.o obj_load_64.o obj_reloc_64.o obj_sparc64_64.o +LIBOBJ_OBJS += obj_kallsyms_64.o obj_common_64.o obj_load_64.o obj_reloc_64.o obj_sparc64_64.o LIBOBJ_SRCS += obj_sparc64.c DEFSNOARCH += -DCOMMON_3264 DEFS += -DONLY_32 -DEFS64 := -DELF_MACHINE_H='"elf_sparc64.h"' -DARCH_sparc64 -DONLY_64 +DEFS64 := -DONLY_64 -DELF_MACHINE_H='"elf_sparc64.h"' -DARCH_sparc64 endif %.o: %.c diff -Nur modutils-2.3.10/obj/obj_arm.c modutils-2.3.11/obj/obj_arm.c --- modutils-2.3.10/obj/obj_arm.c Mon Oct 18 11:04:32 1999 +++ modutils-2.3.11/obj/obj_arm.c Fri Apr 14 11:59:15 2000 @@ -21,7 +21,7 @@ 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: obj_arm.c 1.2 Mon, 18 Oct 1999 11:04:32 +1000 keith $" +#ident "$Id: obj_arm.c 1.4 Fri, 14 Apr 2000 11:59:15 +1000 kaos $" #include #include @@ -124,7 +124,7 @@ { case R_ARM_NONE: break; - + case R_ARM_ABS32: *loc += v; break; @@ -132,21 +132,21 @@ case R_ARM_GOT32: /* needs an entry in the .got: set it, once */ if (! asym->gotent.reloc_done) - { + { asym->gotent.reloc_done = 1; *(Elf32_Addr *)(afile->got->contents + asym->gotent.offset) = v; - } + } /* make the reloc with_respect_to_.got */ *loc += asym->gotent.offset; break; - + /* relative reloc, always to _GLOBAL_OFFSET_TABLE_ (which is .got) similar to branch, but is full 32 bits relative */ case R_ARM_GOTPC: assert(got); *loc += got - dot; break; - + case R_ARM_PC24: case R_ARM_PLT32: /* find the plt entry and initialize it if necessary */ @@ -155,11 +155,11 @@ if (! pe->inited) { ip = (unsigned long *) (afile->plt->contents + pe->offset); - ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */ - ip[1] = v; /* sym@ */ + ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */ + ip[1] = v; /* sym@ */ pe->inited = 1; } - + /* relative distance to target */ v -= dot; /* if the target is too far away.... */ @@ -183,7 +183,7 @@ assert(got); *loc += v - got; break; - + default: printf("Warning: unhandled reloc %d\n",ELF32_R_TYPE(rel->r_info)); ret = obj_reloc_unhandled; @@ -214,7 +214,7 @@ continue; syms = f->sections[sec->header.sh_link]; strs = f->sections[syms->header.sh_link]; - + rel = (ElfW(RelM) *) sec->contents; relend = rel + (sec->header.sh_size / sizeof(ElfW(RelM))); symtab = (ElfW(Sym) *) syms->contents; @@ -222,54 +222,54 @@ for (; rel < relend; ++rel) { - extsym = &symtab[ELF32_R_SYM(rel->r_info)]; - - switch(ELF32_R_TYPE(rel->r_info)) { - case R_ARM_PC24: - case R_ARM_PLT32: + extsym = &symtab[ELF32_R_SYM(rel->r_info)]; + + switch(ELF32_R_TYPE(rel->r_info)) { + case R_ARM_PC24: + case R_ARM_PLT32: if (extsym->st_name) name = strtab + extsym->st_name; else name = f->sections[extsym->st_shndx]->name; intsym = (struct arm_symbol *) obj_find_symbol(f, name); - + pe = &intsym->pltent; - + if (! pe->allocated) - { + { pe->allocated = 1; pe->offset = plt_offset; plt_offset += 8; pe->inited = 0; - } + } break; - + /* these two don_t need got entries, but they need - the .got to exist */ - case R_ARM_GOTOFF: - case R_ARM_GOTPC: + the .got to exist */ + case R_ARM_GOTOFF: + case R_ARM_GOTPC: if (got_offset==0) got_offset = 4; break; - - case R_ARM_GOT32: + + case R_ARM_GOT32: if (extsym->st_name) name = strtab + extsym->st_name; else name = f->sections[extsym->st_shndx]->name; intsym = (struct arm_symbol *) obj_find_symbol(f, name); - + ge = (struct arm_got_entry *) &intsym->gotent; if (! ge->allocated) - { + { ge->allocated = 1; ge->offset = got_offset; got_offset += sizeof(void*); - } + } break; - default: + default: continue; - } + } } } @@ -280,10 +280,10 @@ struct obj_section* sec = obj_find_section(f, ".got"); if (sec) obj_extend_section(sec, got_offset); - else + else { sec = obj_create_alloced_section(f, ".got", 8, got_offset); - assert(sec); + assert(sec); } afile->got = sec; } diff -Nur modutils-2.3.10/obj/obj_common.c modutils-2.3.11/obj/obj_common.c --- modutils-2.3.10/obj/obj_common.c Mon Oct 18 16:33:17 1999 +++ modutils-2.3.11/obj/obj_common.c Thu Apr 20 14:31:49 2000 @@ -19,7 +19,7 @@ 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: obj_common.c 1.2 Mon, 18 Oct 1999 16:33:17 +1000 keith $" +#ident "$Id: obj_common.c 1.4 Thu, 20 Apr 2000 14:31:49 +1000 kaos $" #include #include @@ -60,7 +60,7 @@ void obj_set_symbol_compare (struct obj_file *f, - int (*cmp)(const char *, const char *), + int (*cmp)(const char *, const char *), unsigned long (*hash)(const char *)) { if (cmp) @@ -116,11 +116,11 @@ by ld -r. The only reason locals are now seen at this level at all is so that we can do semi-sensible things with parameters. */ - + struct obj_symbol *nsym, **p; nsym = arch_new_symbol(); - nsym->next = sym->next; + nsym->next = sym->next; nsym->ksymidx = -1; /* Excise the old (local) symbol from the hash chain. */ @@ -167,8 +167,13 @@ f->symtab[hash] = sym; sym->ksymidx = -1; - if (ELFW(ST_BIND)(info) == STB_LOCAL && symidx != -1) - f->local_symtab[symidx] = sym; + if (ELFW(ST_BIND)(info) == STB_LOCAL && symidx != -1) { + if (symidx >= f->local_symtab_size) + error("local symbol %s with index %ld exceeds local_symtab_size %ld", + name, (long) symidx, (long) f->local_symtab_size); + else + f->local_symtab[symidx] = sym; + } found: sym->name = name; diff -Nur modutils-2.3.10/obj/obj_kallsyms.c modutils-2.3.11/obj/obj_kallsyms.c --- modutils-2.3.10/obj/obj_kallsyms.c Thu Jan 1 10:00:00 1970 +++ modutils-2.3.11/obj/obj_kallsyms.c Fri Apr 21 10:53:07 2000 @@ -0,0 +1,293 @@ +/* Build a section containing all non-stack symbols. + Copyright 2000 Keith Owens + + 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: obj_kallsyms.c 1.7 Fri, 21 Apr 2000 10:53:07 +1000 kaos $" + +#include +#include +#include + +#include "obj.h" +#include "kallsyms.h" +#include "util.h" + +/*======================================================================*/ + +#define EXPAND_BY 4096 /* Arbitrary */ + +/* Append a string to the big list of strings */ + +static void +append_string (const char *s, char **strings, + ElfW(Word) *strings_size, ElfW(Word) *strings_left) +{ + int l = strlen(s) + 1; + while (l > *strings_left) { + *strings = xrealloc(*strings, *strings_size += EXPAND_BY); + *strings_left += EXPAND_BY; + } + memcpy((char *)*strings+*strings_size-*strings_left, s, l); + *strings_left -= l; +} + + +/* Append a symbol to the big list of symbols */ + +static void +append_symbol (const struct kallsyms_symbol *s, + struct kallsyms_symbol **symbols, + ElfW(Word) *symbols_size, ElfW(Word) *symbols_left) +{ + int l = sizeof(*s); + while (l > *symbols_left) { + *symbols = xrealloc(*symbols, *symbols_size += EXPAND_BY); + *symbols_left += EXPAND_BY; + } + memcpy((char *)*symbols+*symbols_size-*symbols_left, s, l); + *symbols_left -= l; +} + +/* qsort compare routine to sort symbols */ + +static const char *sym_strings; + +static int +symbol_compare (const void *a, const void *b) +{ + struct kallsyms_symbol *c = (struct kallsyms_symbol *) a; + struct kallsyms_symbol *d = (struct kallsyms_symbol *) b; + + if (c->symbol_addr > d->symbol_addr) + return(1); + if (c->symbol_addr < d->symbol_addr) + return(-1); + return(strcmp(sym_strings+c->name_off, sym_strings+d->name_off)); +} + + +/* Extract all symbols from the input obj_file, ignore ones that are + * no use for debugging, build an output obj_file containing only the + * kallsyms section. + * + * The kallsyms section is a bit unusual. It deliberately has no + * relocatable data, all "pointers" are represented as byte offsets + * into the the section. This means it can be stored anywhere without + * relocation problems. In particular it can be stored within a kernel + * image, it can be stored separately from the kernel image, it can be + * appended to a module just before loading, it can be stored in a + * separate area etc. + * + * Format of the kallsyms section. + * + * Header: + * Size of header. + * Total size of kallsyms data, including strings. + * Number of loaded sections. + * Offset to first section entry from start of header. + * Size of each section entry, excluding the name string. + * Number of symbols. + * Offset to first symbol entry from start of header. + * Size of each symbol entry, excluding the name string. + * + * Section entry - one per loaded section. + * Start of section[1]. + * Size of section. + * Offset to name of section, from start of strings. + * Section flags. + * + * Symbol entry - one per symbol in the input file[2]. + * Offset of section that owns this symbol, from start of section data. + * Address of symbol within the real section[1]. + * Offset to name of symbol, from start of strings. + * + * Notes: [1] This is an exception to the "represent pointers as + * offsets" rule, it is a value, not an offset. The start + * address of a section or a symbol is extracted from the + * obj_file data which may contain absolute or relocatable + * addresses. If the addresses are relocatable then the + * caller must adjust the section and/or symbol entries in + * kallsyms after relocation. + * [2] Only symbols that fall within loaded sections are stored. + */ + +int +obj_kallsyms (struct obj_file *fin, struct obj_file **fout_result) +{ + struct obj_file *fout; + int i, loaded = 0, *fin_to_allsym_map; + struct obj_section *isec, *osec; + struct kallsyms_header *a_hdr; + struct kallsyms_section *a_sec; + ElfW(Off) sec_off; + struct kallsyms_symbol *symbols = NULL, a_sym; + ElfW(Word) symbols_size = 0, symbols_left = 0; + char *strings = NULL, *p; + ElfW(Word) strings_size = 0, strings_left = 0; + ElfW(Off) file_offset; + static char strtab[] = "\000" KALLSYMS_SEC_NAME; + + /* Create the kallsyms section. */ + fout = arch_new_file(); + memset(fout, 0, sizeof(*fout)); + fout->symbol_cmp = strcmp; + fout->symbol_hash = obj_elf_hash; + fout->load_order_search_start = &fout->load_order; + + /* Copy file characteristics from input file and modify to suit */ + memcpy(&fout->header, &fin->header, sizeof(fout->header)); + fout->header.e_type = ET_REL; /* Output is relocatable */ + fout->header.e_entry = 0; /* No entry point */ + fout->header.e_phoff = 0; /* No program header */ + file_offset = sizeof(fout->header); /* Step over Elf header */ + fout->header.e_shoff = file_offset; /* Section headers next */ + fout->header.e_flags = 0; /* No flags */ + fout->header.e_phentsize = 0; /* No program header */ + fout->header.e_phnum = 0; /* No program header */ + fout->header.e_shnum = KALLSYMS_IDX+1; /* Initial, strtab, kallsyms */ + fout->header.e_shstrndx = KALLSYMS_IDX-1; /* strtab */ + file_offset += fout->header.e_shentsize * fout->header.e_shnum; + + /* Populate the section data for kallsyms itself */ + fout->sections = xmalloc(sizeof(*(fout->sections))*fout->header.e_shnum); + memset(fout->sections, 0, sizeof(*(fout->sections))*fout->header.e_shnum); + + fout->sections[0] = osec = arch_new_section(); + memset(osec, 0, sizeof(*osec)); + osec->header.sh_type = SHT_NULL; + osec->header.sh_link = SHN_UNDEF; + + fout->sections[KALLSYMS_IDX-1] = osec = arch_new_section(); + memset(osec, 0, sizeof(*osec)); + osec->name = ".strtab"; + osec->header.sh_type = SHT_STRTAB; + osec->header.sh_link = SHN_UNDEF; + osec->header.sh_offset = file_offset; + osec->header.sh_size = sizeof(strtab); + osec->contents = xmalloc(sizeof(strtab)); + memcpy(osec->contents, strtab, sizeof(strtab)); + file_offset += osec->header.sh_size; + + fout->sections[KALLSYMS_IDX] = osec = arch_new_section(); + memset(osec, 0, sizeof(*osec)); + osec->name = KALLSYMS_SEC_NAME; + osec->header.sh_name = 1; /* Offset in strtab */ + osec->header.sh_type = SHT_PROGBITS; /* Load it */ + osec->header.sh_flags = SHF_ALLOC; /* Read only data */ + osec->header.sh_link = SHN_UNDEF; + osec->header.sh_addralign = sizeof(ElfW(Word)); + file_offset = (file_offset + osec->header.sh_addralign - 1) + & -(osec->header.sh_addralign); + osec->header.sh_offset = file_offset; + + /* How many loaded sections are there? */ + for (i = 0; i < fin->header.e_shnum; ++i) { + if (fin->sections[i]->header.sh_flags & SHF_ALLOC) + ++loaded; + } + + /* Initial contents, header + one entry per input section. No strings. */ + osec->header.sh_size = sizeof(*a_hdr) + loaded*sizeof(*a_sec); + a_hdr = (struct kallsyms_header *) osec->contents = + xmalloc(osec->header.sh_size); + memset(osec->contents, 0, osec->header.sh_size); + a_hdr->size = sizeof(*a_hdr); + a_hdr->sections = loaded; + a_hdr->section_off = a_hdr->size; + a_hdr->section_size = sizeof(*a_sec); + a_hdr->symbol_off = osec->header.sh_size; + a_hdr->symbol_size = sizeof(a_sym); + a_hdr->start = (ElfW(Addr))(~0); + + /* Map input section numbers to kallsyms section offsets. */ + sec_off = 0; /* Offset to first kallsyms section entry */ + fin_to_allsym_map = xmalloc(sizeof(*fin_to_allsym_map)*fin->header.e_shnum); + for (i = 0; i < fin->header.e_shnum; ++i) { + isec = fin->sections[i]; + if (isec->header.sh_flags & SHF_ALLOC) { + fin_to_allsym_map[isec->idx] = sec_off; + sec_off += a_hdr->section_size; + } + else + fin_to_allsym_map[isec->idx] = -1; /* Ignore this section */ + } + + /* Copy the loaded section data. */ + a_sec = (struct kallsyms_section *) ((char *) a_hdr + a_hdr->section_off); + for (i = 0; i < fin->header.e_shnum; ++i) { + isec = fin->sections[i]; + if (!(isec->header.sh_flags & SHF_ALLOC)) + continue; + a_sec->start = isec->header.sh_addr; + a_sec->size = isec->header.sh_size; + a_sec->flags = isec->header.sh_flags; + a_sec->name_off = strings_size - strings_left; + append_string(isec->name, &strings, &strings_size, &strings_left); + if (a_sec->start < a_hdr->start) + a_hdr->start = a_sec->start; + if (a_sec->start+a_sec->size > a_hdr->end) + a_hdr->end = a_sec->start+a_sec->size; + ++a_sec; + } + + /* Build the kallsyms symbol table from the symbol hashes. */ + for (i = 0; i < HASH_BUCKETS; ++i) { + struct obj_symbol *sym = fin->symtab[i]; + for (sym = fin->symtab[i]; sym ; sym = sym->next) { + if (!sym || sym->secidx >= fin->header.e_shnum) + continue; + if ((a_sym.section_off = fin_to_allsym_map[sym->secidx]) == -1) + continue; + if (strcmp(sym->name, "gcc2_compiled.") == 0 || + strncmp(sym->name, "__insmod_", 9) == 0) + continue; + a_sym.symbol_addr = sym->value; + if (fin->header.e_type == ET_REL) + a_sym.symbol_addr += fin->sections[sym->secidx]->header.sh_addr; + a_sym.name_off = strings_size - strings_left; + append_symbol(&a_sym, &symbols, &symbols_size, &symbols_left); + append_string(sym->name, &strings, &strings_size, &strings_left); + ++a_hdr->symbols; + } + } + free(fin_to_allsym_map); + + /* Sort the symbols into ascending order by address and name */ + sym_strings = strings; /* For symbol_compare */ + qsort((char *) symbols, (unsigned) a_hdr->symbols, + sizeof(* symbols), symbol_compare); + sym_strings = NULL; + + /* Put the lot together */ + osec->header.sh_size = a_hdr->total_size = + a_hdr->symbol_off + + a_hdr->symbols*a_hdr->symbol_size + + strings_size - strings_left; + a_hdr = (struct kallsyms_header *) osec->contents = + xrealloc(a_hdr, a_hdr->total_size); + p = (char *)a_hdr + a_hdr->symbol_off; + memcpy(p, symbols, a_hdr->symbols*a_hdr->symbol_size); + free(symbols); + p += a_hdr->symbols*a_hdr->symbol_size; + a_hdr->string_off = p - (char *)a_hdr; + memcpy(p, strings, strings_size - strings_left); + free(strings); + + *fout_result = fout; + return 0; +} diff -Nur modutils-2.3.10/obj/obj_load.c modutils-2.3.11/obj/obj_load.c --- modutils-2.3.10/obj/obj_load.c Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/obj/obj_load.c Thu Apr 20 14:31:49 2000 @@ -3,6 +3,7 @@ Contributed by Richard Henderson obj_free() added by Björn Ekwall March 1999 + Support for kallsyms Keith Owens April 2000 This file is part of the Linux modutils. @@ -20,7 +21,7 @@ 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: obj_load.c 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $" +#ident "$Id: obj_load.c 1.4 Thu, 20 Apr 2000 14:31:49 +1000 kaos $" #include #include @@ -32,7 +33,7 @@ /*======================================================================*/ struct obj_file * -obj_load (FILE *fp) +obj_load (FILE *fp, Elf32_Half e_type) { struct obj_file *f; ElfW(Shdr) *section_headers; @@ -70,9 +71,20 @@ error("ELF file not for this architecture"); return NULL; } - if (f->header.e_type != ET_REL) + if (f->header.e_type != e_type && e_type != ET_NONE) { - error("ELF file not a relocatable object"); + switch (e_type) { + case ET_REL: + error("ELF file not a relocatable object"); + break; + case ET_EXEC: + error("ELF file not an executable object"); + break; + default: + error("ELF file has wrong type, expecting %d got %d", + e_type, f->header.e_type); + break; + } return NULL; } @@ -111,7 +123,7 @@ sec->idx = i; switch (sec->header.sh_type) - { + { case SHT_NULL: case SHT_NOTE: case SHT_NOBITS: @@ -127,10 +139,10 @@ sec->contents = xmalloc(sec->header.sh_size); fseek(fp, sec->header.sh_offset, SEEK_SET); if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) - { - error("error reading ELF section data: %m"); - return NULL; - } + { + error("error reading ELF section data: %m"); + return NULL; + } } else sec->contents = NULL; @@ -150,7 +162,7 @@ if (sec->header.sh_type >= SHT_LOPROC) { if (arch_load_proc_section(sec, fp) < 0) - return NULL; + return NULL; break; } diff -Nur modutils-2.3.10/obj/obj_mips.c modutils-2.3.11/obj/obj_mips.c --- modutils-2.3.10/obj/obj_mips.c Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/obj/obj_mips.c Thu Apr 13 18:17:59 2000 @@ -18,7 +18,7 @@ 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: obj_mips.c 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $" +#ident "$Id: obj_mips.c 1.2 Thu, 13 Apr 2000 18:17:59 +1000 kaos $" #include #include @@ -129,7 +129,7 @@ case R_MIPS_26: if (v % 4) - ret = obj_reloc_dangerous; + ret = obj_reloc_dangerous; if ((v & 0xf0000000) != (dot & 0xf0000000)) ret = obj_reloc_overflow; *loc = (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) & 0x03ffffff); @@ -139,15 +139,15 @@ { struct mips_hi16 *n; - /* We cannot relocate this one now because we don't know the value - of the carry we need to add. Save the information, and let LO16 + /* We cannot relocate this one now because we don't know the value + of the carry we need to add. Save the information, and let LO16 do the actual relocation. */ - n = (struct mips_hi16 *) xmalloc (sizeof *n); - n->addr = loc; - n->value = v; - n->next = mf->mips_hi16_list; - mf->mips_hi16_list = n; - break; + n = (struct mips_hi16 *) xmalloc (sizeof *n); + n->addr = loc; + n->value = v; + n->next = mf->mips_hi16_list; + mf->mips_hi16_list = n; + break; } case R_MIPS_LO16: @@ -199,7 +199,7 @@ *loc = insnlo; break; } - + default: ret = obj_reloc_unhandled; break; diff -Nur modutils-2.3.10/obj/obj_reloc.c modutils-2.3.11/obj/obj_reloc.c --- modutils-2.3.10/obj/obj_reloc.c Mon Nov 22 01:38:27 1999 +++ modutils-2.3.11/obj/obj_reloc.c Thu Apr 13 18:17:59 2000 @@ -19,7 +19,7 @@ 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: obj_reloc.c 1.4 Mon, 22 Nov 1999 01:38:27 +1100 keith $" +#ident "$Id: obj_reloc.c 1.5 Thu, 13 Apr 2000 18:17:59 +1000 kaos $" #include #include @@ -309,12 +309,12 @@ else { /* Others we look up in the hash table. */ - const char *name; + const char *name; if (extsym->st_name) name = strtab + extsym->st_name; - else + else name = f->sections[extsym->st_shndx]->name; - intsym = obj_find_symbol(f, name); + intsym = obj_find_symbol(f, name); } value = obj_symbol_final_value(f, intsym); @@ -323,9 +323,9 @@ #if SHT_RELM == SHT_RELA #if defined(__alpha__) && defined(AXP_BROKEN_GAS) - /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */ - if (!extsym || !extsym->st_name || - ELFW(ST_BIND)(extsym->st_info) != STB_LOCAL) + /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */ + if (!extsym || !extsym->st_name || + ELFW(ST_BIND)(extsym->st_info) != STB_LOCAL) #endif value += rel->r_addend; #endif diff -Nur modutils-2.3.10/obj/obj_sparc64.c modutils-2.3.11/obj/obj_sparc64.c --- modutils-2.3.10/obj/obj_sparc64.c Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/obj/obj_sparc64.c Thu Apr 13 18:17:59 2000 @@ -19,7 +19,7 @@ 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: obj_sparc64.c 1.1 Wed, 25 Aug 1999 16:26:49 +1000 keith $" +#ident "$Id: obj_sparc64.c 1.2 Thu, 13 Apr 2000 18:17:59 +1000 kaos $" #include #include @@ -103,7 +103,7 @@ #define R_SPARC_PC_LM22 39 #endif - + #endif int @@ -219,7 +219,7 @@ *loc = (*loc & ~0x7ff) | (v & 0x7ff); break; -#ifdef R_SPARC_64 +#ifdef R_SPARC_64 case R_SPARC_64: loc[0] = (v >> 32); loc[1] = v; @@ -249,7 +249,7 @@ *loc = (*loc & ~0x3fffff) | ((v >> 10) & 0x3fffff); break; #endif - + case R_SPARC_WDISP16: v -= dot; if (v % 4) diff -Nur modutils-2.3.10/util/alias.h modutils-2.3.11/util/alias.h --- modutils-2.3.10/util/alias.h Thu Mar 16 14:27:53 2000 +++ modutils-2.3.11/util/alias.h Thu Apr 13 18:17:59 2000 @@ -32,6 +32,7 @@ "atm", "usb", "ide", + "ieee1394", NULL /* marks the end of the list! */ }; @@ -83,20 +84,20 @@ "char-major-10-1 psaux", /* /dev/psaux PS/2-style mouse port */ "char-major-10-2 msbusmouse", /* /dev/inportbm Microsoft Inport bus mouse */ "char-major-10-3 atixlmouse", /* /dev/atibm ATI XL bus mouse */ - /* /dev/jbm J-mouse */ - /* /dev/amigamouse Amiga mouse (68k/Amiga) */ - /* /dev/atarimouse Atari mouse */ - /* /dev/sunmouse Sun mouse */ - /* /dev/beep Fancy beep device */ - /* /dev/modreq Kernel module load request */ + /* /dev/jbm J-mouse */ + /* /dev/amigamouse Amiga mouse (68k/Amiga) */ + /* /dev/atarimouse Atari mouse */ + /* /dev/sunmouse Sun mouse */ + /* /dev/beep Fancy beep device */ + /* /dev/modreq Kernel module load request */ "char-major-10-130 wdt", /* /dev/watchdog Watchdog timer port */ "char-major-10-131 wdt", /* /dev/temperature Machine internal temperature */ - /* /dev/hwtrap Hardware fault trap */ - /* /dev/exttrp External device trap */ + /* /dev/hwtrap Hardware fault trap */ + /* /dev/exttrp External device trap */ "char-major-10-135 off", /* rtc cannot be compiled as a module */ "char-major-10-139 openprom", /* /dev/openprom Linux/Sparc interface */ "char-major-10-144 nvram", /* from Tigran Aivazian */ - + "char-major-14 soundcore", "char-major-19 cyclades", "char-major-20 cyclades", @@ -128,11 +129,11 @@ "net-pf-3 off", /* PF_AX25 3 Amateur Radio AX.25 */ "net-pf-4 off", /* PF_IPX 4 Novell IPX */ "net-pf-5 off", /* PF_APPLETALK 5 Appletalk DDP */ - "net-pf-6 off", /* PF_NETROM 6 Amateur radio NetROM */ - /* PF_BRIDGE 7 Multiprotocol bridge */ - /* PF_AAL5 8 Reserved for Werner's ATM */ - /* PF_X25 9 Reserved for X.25 project */ - /* PF_INET6 10 IP version 6 */ + "net-pf-6 off", /* PF_NETROM 6 Amateur radio NetROM */ + /* PF_BRIDGE 7 Multiprotocol bridge */ + /* PF_AAL5 8 Reserved for Werner's ATM */ + /* PF_X25 9 Reserved for X.25 project */ + /* PF_INET6 10 IP version 6 */ /* next two from Thanks! */ "net-pf-17 af_packet", diff -Nur modutils-2.3.10/util/config.c modutils-2.3.11/util/config.c --- modutils-2.3.10/util/config.c Wed Mar 15 21:14:05 2000 +++ modutils-2.3.11/util/config.c Thu Apr 20 14:31:49 2000 @@ -269,7 +269,8 @@ return orig; } -static void decode_list(int *n, OPT_LIST **list, char *arg, int adding, char *version) +static void decode_list(int *n, OPT_LIST **list, char *arg, int adding, + char *version) { GLOB_LIST *pg; GLOB_LIST *prevlist = NULL; @@ -641,8 +642,8 @@ if (fin) { struct stat statbuf1, statbuf2; - if (fstat(fileno(fin), &statbuf1) == 0) - config_mtime = statbuf1.st_mtime; + if (fstat(fileno(fin), &statbuf1) == 0) + config_mtime = statbuf1.st_mtime; config_file = xstrdup(conf_file); /* Save name actually used */ if (!conf_file_specified && stat(ETC_MODULES_CONF, &statbuf1) == 0 && @@ -655,7 +656,7 @@ fprintf(stderr, "Warning: You do not need a link from %s to\n" " %s. The use of %s is depreciated,\n" - " please remove %s and rename %s\n" + " please remove %s and rename %s\n" " to %s as soon as possible. Commands.\n" " rm %s\n" " mv %s %s\n", @@ -806,8 +807,8 @@ if (strncmp(arg, "-f", 2) == 0) { char *file = next_word(arg); - - if (access(file, R_OK) == 0) + meta_expand(file, &g, NULL, version); + if (access(g.pathc ? g.pathv[0] : file, R_OK) == 0) state[level] = !not; else state[level] = not; @@ -845,32 +846,32 @@ if (strcmp(cmp, "==") == 0 || strcmp(cmp, "=") == 0) { - if (numeric) + if (numeric) state[level] = (n1 == n2); else state[level] = strcmp(w1, w2) == 0; } else if (strcmp(cmp, "!=") == 0) { - if (numeric) + if (numeric) state[level] = (n1 != n2); else state[level] = strcmp(w1, w2) != 0; } else if (strcmp(cmp, ">=") == 0) { - if (numeric) + if (numeric) state[level] = (n1 >= n2); else state[level] = strcmp(w1, w2) >= 0; } else if (strcmp(cmp, "<=") == 0) { - if (numeric) + if (numeric) state[level] = (n1 <= n2); else state[level] = strcmp(w1, w2) <= 0; } else if (strcmp(cmp, ">") == 0) { - if (numeric) + if (numeric) state[level] = (n1 > n2); else state[level] = strcmp(w1, w2) > 0; } else if (strcmp(cmp, "<") == 0) { - if (numeric) + if (numeric) state[level] = (n1 < n2); else state[level] = strcmp(w1, w2) < 0; @@ -916,14 +917,12 @@ * include */ if (!assgn && strcmp(parm, "include") == 0) { - char incfile[PATH_MAX]; - - sscanf(arg, "%s", incfile); + meta_expand(arg, &g, NULL, version); - if (!do_read(all, version, base_dir, incfile)) + if (!do_read(all, version, base_dir, g.pathc ? g.pathv[0] : arg)) one_err = 0; else - error("include %s failed\n", incfile); + error("include %s failed\n", arg); } /* @@ -1284,7 +1283,7 @@ if ((p = strrchr(file, '/')) == NULL) p = (char *)file; else - p += 1; + p += 1; if (strcmp(p, looking_for) != 0) return 0; diff -Nur modutils-2.3.10/util/meta_expand.c modutils-2.3.11/util/meta_expand.c --- modutils-2.3.10/util/meta_expand.c Wed Aug 25 16:26:49 1999 +++ modutils-2.3.11/util/meta_expand.c Fri Apr 14 11:59:15 2000 @@ -186,6 +186,7 @@ pt, version, s + 1); + *p = '`'; } strcpy(tmpline, wrk); pt = tmpline; @@ -207,6 +208,7 @@ (int)(k - version), version, s + 1); + *p = '`'; strcpy(tmpline, wrk); pt = tmpline; } @@ -214,7 +216,7 @@ break; } while ((p = strchr(pt, '`')) != NULL); } - + /* * Any remaining meta-chars? */