This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [I don't think it's off-topic at all] Linking speed for C++
- To: Joe Buck <jbuck at synopsys dot COM>
- Subject: Re: [I don't think it's off-topic at all] Linking speed for C++
- From: Michael Matz <matz at kde dot org>
- Date: Tue, 29 May 2001 22:57:39 +0200 (MET DST)
- cc: Richard Henderson <rth at redhat dot com>, <gcc at gcc dot gnu dot org>
Hi,
On Tue, 22 May 2001, Joe Buck wrote:
> Richard Henderson wrote:
> > While it's true that it does not completely eliminate the
> > dynamic relocation, it does (or should) eliminate a symbol
> > lookup -- eg an R_386_32 relocation should be replaced by
> > an R_386_RELATIVE relocation which is considerably simpler
> > to process.
>
> Well, in that case some interested KDE developer might want to try using
> -Bsymbolic and see if it improves startup times ...
Well, if it only worked ;) After building some of our bigger libraries by
hand for a test (with -Bsymbolic) the reduction in symbol-based
relocations is really looking good:
libkio.so.3.0.0 : 2346 - 1177
libksycoca.so.3.0.0 : 2090 - 1014
libkdecore.so.3.0.0 : 3902 - 1920
libkdeui.so.3.0.0 : 20059 - 14226
libkhtml.so.3.0.0 : 16583 - 2368
First number normal build, second number with -Bsymbolic. The number
itself are the output of "objdump -R .so | grep -v '\*ASB\*' | wc -l".
But programs linked against those libs fail sometimes. After quite some
time I've reduced it to this:
----- lib.h -----
class A {
public:
A();
static A* get_the_A() { return TheA; }
private:
void init();
static A* TheA;
};
----- lib1.cpp -----
#include <lib.h>
A* A::TheA = 0;
A::A() { init (); };
void A::init ()
{ TheA = this; }
----- prog.cpp -----
#include <lib.h>
int main()
{ A a;
if (!a.get_the_A())
abort();
return 0;
}
--------------------
prog.cpp needs to be build with optimization (so the get_the_A() call is
inlined). The lib1 can be built in any way. If prog is dynamically
linked to lib1 and the found lib1 was compiled with -Bsymbolic prog
abort()'s. This is due to lib1's version of init() setting another TheA
than the one read from in main(). I don't know why exactly this is
happening. The relevant objdump -R output (shortened) for the normal lib1:
OFFSET TYPE VALUE
000007cf R_386_PC32 init__1A
000007d8 R_386_PC32 init__1A
000007f7 R_386_32 _1A.TheA
0000188c R_386_RELATIVE *ABS*
000018c4 R_386_GLOB_DAT ___brk_addr
and for -Bsymbolic lib1:
OFFSET TYPE VALUE
000007e7 R_386_RELATIVE *ABS*
0000187c R_386_RELATIVE *ABS*
000018b4 R_386_GLOB_DAT ___brk_addr
objdump -d for normal lib (only init(), the call is correctly done):
000007f0 <init__1A>:
7f0: 55 push %ebp
7f1: 89 e5 mov %esp,%ebp
7f3: 8b 45 08 mov 0x8(%ebp),%eax # eax <--- this
7f6: a3 00 00 00 00 mov %eax,0x0 # TheA <--- eax
7fb: 89 ec mov %ebp,%esp
7fd: 5d pop %ebp
7fe: c3 ret
objdump -d for -Bsymbolic (again only init() ):
000007e0 <init__1A>:
7e0: 55 push %ebp
7e1: 89 e5 mov %esp,%ebp
7e3: 8b 45 08 mov 0x8(%ebp),%eax # eax <--- this
7e6: a3 84 18 00 00 mov %eax,0x1884 # TheA <--- eax
7eb: 89 ec mov %ebp,%esp
7ed: 5d pop %ebp
7ee: c3 ret
The program itself has for TheA the following relocation:
0804970c R_386_COPY _1A.TheA
And the testing insn in main() which abort is this:
8048595: 83 3d 0c 97 04 08 00 cmpl $0x0,0x804970c
If I all load this into gdb I then indeed see references to two different
locations (with -Bsymbolic libs): init()
Dump of assembler code for function init__1A:
0x400187e0 <init__1A>: push %ebp
0x400187e1 <init__1A+1>: mov %esp,%ebp
0x400187e3 <init__1A+3>: mov 0x8(%ebp),%eax
0x400187e6 <init__1A+6>: mov %eax,0x40019884 # TheA <--- this
...
and main():
(gdb) disassemble
Dump of assembler code for function main:
0x8048580 <main>: push %ebp
0x8048581 <main+1>: mov %esp,%ebp
0x8048583 <main+3>: sub $0x18,%esp
0x8048586 <main+6>: add $0xfffffff4,%esp
0x8048589 <main+9>: lea 0xffffffff(%ebp),%eax
0x804858c <main+12>: push %eax
0x804858d <main+13>: call 0x8048454 <__1A>
0x8048592 <main+18>: add $0x10,%esp
0x8048595 <main+21>: cmpl $0x0,0x804970c # TheA == 0
And here I'm finally at loss. Is ld.so wrong, or ld, or as, or gcc?
Anyone?
system: g++ 2.95.2, ld 2.10.91 (with BFD 2.10.0.33), ld.so-2.2,
i386-linux (stock SuSE 7.1)
Ciao,
Michael.