Skip to contentSkip to conversation

ELF/Modutils problem

DISCUSSION Brady Brown 4 participants 9 messages Sep 20, 2000 – Sep 27, 2000 MIPS

lore
Share & tools
lore
#0 lore raw

I'm having trouble getting modutils 2.3.10 to work on a little endian MIPS box running a 2.4.0-test3 kernel. I am cross compiling the kernel and modules on an i386 using egcs1.0.3a-2 and binutils2.8.1-1. It appears that the symbol table format in the ELF file created by mipsel-linux-gcc during a module build is incorrect.

As I read the ELF 1.1 spec - all symbols with STB_LOCAL bindings should precede all other symbols (weak and global) in the symbol table. Then the symbol table section's sh_info section header member holds the symbol table index for the first non-local symbol (and thus can then be used to determine the number of local symbols). Using the readelf utility on a generated module shows that the local symbols are not grouped together before all other symbols but are intermixed though out the symbol table, and the sh_info field in the header is not set to the first non-local symbol index.

When insmod runs it malloc's memory equal to the sh_info field and then begins to populate the local symbols into it. Because of the bad symbol ordering and incorrect value in sh_info, the malloc'd memory is far to small to hold all of the local symbols so memory gets blasted and the module fails to load correctly.

As a side test I tried to incrementally link the module.o file using mipsel-linux-ld -r module.o -o module. Viewing the ELF output from this stage showed a correct symbol ordering and sh_info field so it appears that the linker is generating the correct format for the symbol table (problem with gcc only?). Has this problem been addressed/resolved? Any suggestions?

#1 lore raw
Quoted 8 lines · Brady Brown

I'm having trouble getting modutils 2.3.10 to work on a little endian MIPS box running a 2.4.0-test3 kernel. I am cross compiling the kernel and modules on an i386 using egcs1.0.3a-2 and binutils2.8.1-1. It appears that the symbol table format in the ELF file created by mipsel-linux-gcc during a module build is incorrect.

As I read the ELF 1.1 spec - all symbols with STB_LOCAL bindings should precede all other symbols (weak and global) in the symbol table.

modutils 2.3.11 includes a sanity check on the number of local symbols precisely because of this MIPS problem. I agree with you that mips gcc is violating the ELF standard, 2.3.11 just detects this and issues an error message instead of overwriting memory but gcc needs to be fixed. BTW, you might want to upgrade to modutils >= 2.3.15, there are some MIPS patches in modutils 2.3.15.

#2 lore raw
Quoted 8 lines · Keith Owens
Quoted 6 lines · Brady Brown

I'm having trouble getting modutils 2.3.10 to work on a little endian MIPS box running a 2.4.0-test3 kernel. I am cross compiling the kernel and modules on an i386 using egcs1.0.3a-2 and binutils2.8.1-1. It appears that the symbol table format in the ELF file created by mipsel-linux-gcc during a module build is incorrect.

Quoted 7 lines
Quoted 2 lines

As I read the ELF 1.1 spec - all symbols with STB_LOCAL bindings should precede all other symbols (weak and global) in the symbol table.

modutils 2.3.11 includes a sanity check on the number of local symbols precisely because of this MIPS problem. I agree with you that mips gcc is violating the ELF standard, 2.3.11 just detects this and issues an error message instead of overwriting memory but gcc needs to be fixed.

And gcc has nothing to with it so it won't need to be fixed ...

Ralf

#3 lore raw
Quoted 7 lines · Ralf Baechle
Quoted 4 lines · Keith Owens

modutils 2.3.11 includes a sanity check on the number of local symbols precisely because of this MIPS problem. I agree with you that mips gcc is violating the ELF standard, 2.3.11 just detects this and issues an error message instead of overwriting memory but gcc needs to be fixed.

And gcc has nothing to with it so it won't need to be fixed ...

Point taken, I should have said the MIPS toolchain instead of gcc. Something in the toolchain is generating an ELF object that does not follow the rules. Can we catch someone's attention to get it fixed?

#4 lore raw
Quoted 11 lines · Keith Owens
Quoted 7 lines · Keith Owens
Quoted 4 lines

modutils 2.3.11 includes a sanity check on the number of local symbols precisely because of this MIPS problem. I agree with you that mips gcc is violating the ELF standard, 2.3.11 just detects this and issues an error message instead of overwriting memory but gcc needs to be fixed.

And gcc has nothing to with it so it won't need to be fixed ...

Point taken, I should have said the MIPS toolchain instead of gcc. Something in the toolchain is generating an ELF object that does not follow the rules. Can we catch someone's attention to get it fixed?

Ulf Carlsson <[email protected]> is currently maintaining binutils. Ulf, you got the bandwidth to take a look at this? After a look over the gas code it's not obvious to my why this doesn't work on MIPS but on all the other architectures, you probably know the internals of this beast better than I do.

Ralf

#5 lore raw
Quoted 14 lines · Ralf Baechle
Quoted 11 lines · Keith Owens
Quoted 7 lines · Keith Owens
Quoted 4 lines

modutils 2.3.11 includes a sanity check on the number of local symbols precisely because of this MIPS problem. I agree with you that mips gcc is violating the ELF standard, 2.3.11 just detects this and issues an error message instead of overwriting memory but gcc needs to be fixed.

And gcc has nothing to with it so it won't need to be fixed ...

Point taken, I should have said the MIPS toolchain instead of gcc. Something in the toolchain is generating an ELF object that does not follow the rules. Can we catch someone's attention to get it fixed?

Quoted 7 lines

Ulf Carlsson <[email protected]> is currently maintaining binutils. Ulf, you got the bandwidth to take a look at this? After a look over the gas code it's not obvious to my why this doesn't work on MIPS but on all the other architectures, you probably know the internals of this beast better than I do.

Ralf

I'm not sure what exact piece of the tool chain forms the un-linked elf file, but as I stated originally the symbol table in the .o file is incorrect after compiling and then if I do an incremental link (-r) the symbol table and length pointer have been corrected. Based upon this it looks like the output from the linker is correct, but the output from the earlier stage is wrong.

#6 lore raw
Quoted 11 lines · Brady Brown
Quoted 5 lines

Ulf Carlsson <[email protected]> is currently maintaining binutils. Ulf, you got the bandwidth to take a look at this? After a look over the gas code it's not obvious to my why this doesn't work on MIPS but on all the other architectures, you probably know the internals of this beast better than I do.

I'm not sure what exact piece of the tool chain forms the un-linked elf file, but as I stated originally the symbol table in the .o file is incorrect after compiling and then if I do an incremental link (-r) the symbol table and length pointer have been corrected. Based upon this it looks like the output from the linker is correct, but the output from the earlier stage is wrong.

It's the assembler as below text case demonstrates.

Ralf

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2.1). # To extract the files from this archive, save it to some FILE, remove

# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 2000-09-23 23:03 MEST by <[email protected]>.
# Source directory was `/home/ralf/src/binutils'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#     37 -rw-rw-r-- nuke-as-01/s.s
#    161 -rw-r--r-- nuke-as-01/Makefile
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 -a -f $$.touch; then
  shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 -a ! -f 123123592001.5 -a -f $$.touch; then
  shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 -a -f $$.touch; then
  shar_touch='touch -am $3$4$5$6$2 "$8"'
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch
#
if mkdir _sh01696; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= nuke-as-01/s.s ==============
if test ! -d 'nuke-as-01'; then
  $echo 'x -' 'creating directory' 'nuke-as-01'
  mkdir 'nuke-as-01'
fi
if test -f 'nuke-as-01/s.s' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'nuke-as-01/s.s' '(file already exists)'
else
  $echo 'x -' extracting 'nuke-as-01/s.s' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'nuke-as-01/s.s' &&
X	.globl	x1
x1:	.word	x1
x2:	.word	x2
SHAR_EOF
  (set 20 00 09 22 02 42 43 'nuke-as-01/s.s'; eval "$shar_touch") &&
  chmod 0664 'nuke-as-01/s.s' ||
  $echo 'restore of' 'nuke-as-01/s.s' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'nuke-as-01/s.s:' 'MD5 check failed'
509bca5a5362c487c805dbc79d9d32a8  nuke-as-01/s.s
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'nuke-as-01/s.s'`"
    test 37 -eq "$shar_count" ||
    $echo 'nuke-as-01/s.s:' 'original size' '37,' 'current size' "$shar_count!"
  fi
fi
# ============= nuke-as-01/Makefile ==============
if test -f 'nuke-as-01/Makefile' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'nuke-as-01/Makefile' '(file already exists)'
else
  $echo 'x -' extracting 'nuke-as-01/Makefile' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'nuke-as-01/Makefile' &&
target = mips64-linux-
AS = $(target)as
OBJDUMP = $(target)objdump
READELF = $(target)readelf
X
CFLAGS =
X
all:	s.o
X	$(READELF) -s $^
X
clean distclean:
X	rm -f s.o
SHAR_EOF
  (set 20 00 09 21 15 47 28 'nuke-as-01/Makefile'; eval "$shar_touch") &&
  chmod 0644 'nuke-as-01/Makefile' ||
  $echo 'restore of' 'nuke-as-01/Makefile' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'nuke-as-01/Makefile:' 'MD5 check failed'
4d263e9d27b40dbb44f9fadc00160fa5  nuke-as-01/Makefile
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'nuke-as-01/Makefile'`"
    test 161 -eq "$shar_count" ||
    $echo 'nuke-as-01/Makefile:' 'original size' '161,' 'current size' "$shar_count!"
  fi
fi
rm -fr _sh01696
exit 0
#7 lore raw
Quoted 1 line

It's the assembler as below text case demonstrates.

Thanks. I'll take a look at it. I remember that I've looked at this problem once before.

Ulf

#8 lore raw
Quoted 4 lines · Ulf Carlsson
Quoted 1 line

It's the assembler as below text case demonstrates.

Thanks. I'll take a look at it. I remember that I've looked at this problem once before.

This piece of gold in bfd/elf32-mips.c seems to be the problem:

/* Determine whether a symbol is global for the purposes of splitting
the symbol table into global symbols and local symbols. At least on Irix 5, this split must be between section symbols and all other symbols. On most ELF targets the split is between static symbols and externally visible symbols. */

/*ARGSUSED*/
static boolean
mips_elf_sym_is_global (abfd, sym)

     bfd *abfd ATTRIBUTE_UNUSED;
     asymbol *sym;

{
return (sym->flags & BSF_SECTION_SYM) == 0 ? true : false;
}

So our objects are correct, just IRIX flavoured at this point ... Now for a proper fix I think I need somebody who knows IRIX ELF like his pocket ...

Ralf