On Wed, 31 Oct 2001 17:47:49 -0500,
Daniel Jacobowitz <email@example.com> wrote:
>Now, there's two things wrong here. One of them is the bad value. I
>think that I've already seen this problem, and that it has something to
>do with the way stabs are and used to be emitted. packet_exit is
>presumably in the .text.exit section, which is presumably the problem.
>Before linking, the stab looked like:
>2971 FUN 0 1870 0000000000000000 159366 packet_exit:f(0,20)
>and had a relocation:
>0000000000008b58 R_MIPS_32 .text.exit
>unless I miss my guess.
>So it looks like binutils did not relocate the stabs for .text.exit properly.
>Why? It's pretty simple; there was nothing to relocate it to. From the
>kernel's linker script:
> /* Sections to be discarded */
> /DISCARD/ :
>So instead of the subtle error we get in objfiles containing multiple
>sections, which we'll still need to deal with for the kernel for
>.text.init, we have a completely bogus result.
>We need to discard the stabs records for discarded symbols.
The problem is worse than stabs. If a function is marked __exit _and_
some code in another section refers to that function then :-
* ld resolves the reference as offset xxx from the start of section
.text.exit which is expected to get a decent start address.
* Section .text.exit is discarded, giving it a zero start address.
* The function call ends up as a branch to _address_ xxx.
This is a silent bug on many architectures, it only bites when the
__exit function is called, usually on a rarely tested error path. On
architectures that use PC relative branches (such as IA64), the linker
may not be able to fit a PC relative branch from the high kernel
address to the low (and incorrect) xxx address into an instruction so
it gets an error during link. Section .data.exit is even worse, most
references to data are via full word pointers and the bug is silent
ld should probably discard sections and all symbols in those sections
before resolving external references.