Re: Modules

Alan Modra (alan@spri.levels.unisa.edu.au)
Fri, 12 Apr 1996 09:26:48 +0930 (CST)


> From: Craig Hutchison <craig@ns1.dac.net>
> Hi,
>
> I recently downloaded the 1.3.85 kernel and compiled it. In the
> configuration of the kernel I chose to make the slip and ppp modules to
> be added when I needed them. The kernel compiles fine, and the modules
> compile and install as well. However, when I go to install the modules
> I get and error like this:
>
> gcc2_compiled. undefined
> failed to load module! The symbols from kernel 1.3.85 don't match 1.3.85

> [deleted]
> I think that I am doing everything correctly because it worked for the
> other kernels I compiled. The only changes I made to the system since I
> made the 1.3.69 kernel was that I went and installed the following
> packages:
>
> 1. binutils-2.6.0.12.bin.tar.gz
> [deleted]

The new binutils is the cause of your problem. It turns up a bug in
insmod.

> From: Ian Lance Taylor <ian@cygnus.com>
> Date: Tue, 9 Apr 96 23:55:24 EDT
>
> From: alan@spri.levels.unisa.edu.au (Alan Modra)
> Date: Wed, 10 Apr 1996 09:59:36 +0930 (CST)
>
> Somewhere since gas-960129, the handling of symbols defined outside
> of a segment such as "gcc2_compiled.", has changed. On elf32_i386, I
> find that st_info is now zero (STT_NOTYPE), rather than one
> (STT_OBJECT). This breaks insmod on linux, because it wrongly used
> (sp->st_info & 0xf) == 0 to test for undefined symbols. I've fixed
> insmod, but why the change? Is STT_NOTYPE correct for symbols such as
> gcc2_compiled. ?
>
> The change was made for compatibility with other ELF assemblers. They
> do not set the type of a symbol to STT_OBJECT unless the assembler
> source specifically directs them to using the .type directive.
>
> Also, gcc2_compiled does not represent an object, so STT_OBJECT seems
> conceptually wrong.

Here's my fix. (or you can find modules-1.3.69f somewhere on the net,
fixed by Bjorn Eckwall before I even found a problem)

diff -ur dosemu-0.63.1/src/arch/linux/syscallmgr/load_elf.c ./dosemu/src/arch/linux/syscallmgr/load_elf.c
--- dosemu-0.63.1/src/arch/linux/syscallmgr/load_elf.c Sun Nov 5 04:16:53 1995
+++ ./dosemu/src/arch/linux/syscallmgr/load_elf.c Wed Apr 10 14:49:29 1996
@@ -105,7 +105,7 @@
if(symtab_index) {
sp = &symtab[symtab_index];
#ifdef DEBUG
- insmod_debug ("%s %x %x %d %d %x (%x) ",
+ insmod_debug ("%s %x %x %x %x %x (%x) ",
sp->u.e.st_name,
(int)sp->u.e.st_value,
(int)sp->u.e.st_size,
@@ -395,6 +395,30 @@
for (n = nsymbols, sp = symtab ; --n >= 0 ; sp++) {
/* look up name and add sp to binary tree */
findsym(stringtab + sp->u.e.st_name, sp, strncmp);
+#ifdef DEBUG
+ insmod_debug ("%s %x %x %x %x %x ",
+ sp->u.e.st_name,
+ (int)sp->u.e.st_value,
+ (int)sp->u.e.st_size,
+ (int)sp->u.e.st_info,
+ (int)sp->u.e.st_other,
+ (int)sp->u.e.st_shndx);
+#endif
+ /* insmod.c uses ELF32_ST_TYPE(sp->u.e.st_info) == STT_NOTYPE
+ * as a test for undefined symbols. This is actually wrong,
+ * but allows the elf and aout code to be similar. Here we
+ * make sure st_info is set according to the proper test for
+ * undefined symbols
+ */
+ if (sp->u.e.st_shndx == SHN_UNDEF) {
+ if (ELF32_ST_TYPE(sp->u.e.st_info) != STT_NOTYPE)
+ sp->u.e.st_info &= ~0x0f;
+ }
+ else {
+ if (ELF32_ST_TYPE(sp->u.e.st_info) == STT_NOTYPE)
+ sp->u.e.st_info |= STT_OBJECT;
+ }
+
if ((ELF32_ST_BIND(sp->u.e.st_info) == STB_GLOBAL) &&
(ELF32_ST_TYPE(sp->u.e.st_info) != STT_NOTYPE))
symother(sp) = DEF_BY_MODULE; /* abuse: mark extdef */