Subject: Re: i386/ELF stabs
To: Frank van der Linden <firstname.lastname@example.org>
From: Todd Whitesel <email@example.com>
Date: 07/07/1999 20:24:36
> * For the i386, the linenumber information lies outside
> the function information, which can't be correct.
I agree this seems very wrong. I've seen quite a few mangled stabs
sections, but never that.
> * The values of the SLINE symbols (which are the matching
> PCs at which this line is located) are supposed to be
> relative to the start of the function. This is correct
> in the sparc binary, but ld(1) has made them absolute
> already on the i386 port, which is wrong.
Beware!! Not all stabs are alike. According to the stabs document
maintained by Cygnus, the default behavior is for the linker to fully
relocate the stabs, but Sun hacked things in their 'acc' compiler to
make the stabs be relative offsets (to speed up linking). See
> Looking at the gdb code, it uses the N_FUN stab to get the
> start of the function, and then adds the offset in the N_SLINE
> stab to get the PC. So for the i386, this goes wrong in 2 ways:
> you have not yet encountered N_FUN when you hit the N_SLINE
> stabs, so the offset is wrong, plus the value of N_SLINE is not
> relative as it's supposed to be. This actually makes things
> go right accidentally for the first function, because the offset
> is 0 at that point, and if you add the absolute value in the
> N_SLINE stab, you end up at the right address.
That offset code is usually inside #ifdef SOFUN_ADDRESS_MAYBE_MISSING,
which, in both GDB 4.17 and 4.18, is only activated for Solaris (on
sparc, x86, and -- hmm! -- powerpc).
Did we clone our ELF configs from Solaris native or something??
> Now, the reason I'm posting about this here, is that I'm not really
> a bfd/binutils expert (and don't really want to be ;-)), and I'm
> hoping that other people can track down what's wrong here. I don't
> seem to see any large differences with regard to stabs between
> sparc and i386 in the ld(1) sources, so I don't understand where
> the problems come from.
The difference probably shows up before ld(1), in the assembly file
passed between the compiler & assembler. Either the .stabs directive
references an absolute label or a difference of two labels; it's the
compiler's call which way this is done, and GDB just has to grok it.
toddpw @ best.com