This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [I don't think it's off-topic at all] Linking speed for C++


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]