help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Don't use -fpic if library is too specialized?


From: Paul Pluzhnikov
Subject: Re: Don't use -fpic if library is too specialized?
Date: Thu, 28 Sep 2006 08:38:07 -0700
User-agent: Gnus/5.1006 (Gnus v5.10.6) XEmacs/21.4 (Jumbo Shrimp, linux)

"Boris" <boris@gtemail.net> writes:

> Paul Pluzhnikov wrote:

>> If shared, note that on some platforms (e.g. Linux/x86_64) you simply
>> can't build a DSO from non-PIC code (i.e. you'll have no choice).
>
> Does this mean that g++ automatically compiles PIC code or that it aborts 
> with an error unless you pass the option -fpic?

g++ compiles PIC only if you tell it to.
The linker refuses to link non-PIC code into a DSO:

$ cat foo.c
int x;
int foo() { return x; }

$ gcc -c foo.c
$ ld -shared -o foo.so foo.o
ld: foo.o: relocation R_X86_64_32 against `a local symbol' can not be used when 
making a shared object; recompile with -fPIC
foo.o: could not read symbols: Bad value

> If I'm building a shared library and there is only one program running my 
> library is linked in I don't gain anything either

You do loose some performance and some swap memory by having non-PIC
code (but only if the system needs to swap): when the non-PIC DSO
is loaded, its text pages must be modified, so the "system" makes
private copies of them. If these pages need to be swapped, then
they must be written to swap. Non-modified pages could simply be
discarded, and paged back in from the original on-disk file.

> but have a better 
> performance with non-PIC code - is this correct?

Yes: you need one additional indirection on calls and global
data references in PIC code. If you perform *a lot* of calls and/or
use a lot of globals, then you might see slight performance decrease
in PIC code.

Note that if the majority of your calls and global data references
are "intra-DSO", you can avoid PIC overhead by making "internal"
calls.

I forgot exactly how glibc achieves that, but I know that in newer
versions of glibc, fopen() calls mmap() directly (instead of
calling through PLT):

$ gdb -q /lib/libc.so.6
(gdb) disass mmap_remap_check
0x0005c2a0 <mmap_remap_check+0>:        push   %ebp
0x0005c2a1 <mmap_remap_check+1>:        mov    %esp,%ebp
...
0x0005c2f6 <mmap_remap_check+86>:       call   0xb9e30 <munmap>        ## 
non-PIC call
...
0x0005c391 <mmap_remap_check+241>:      call   0xb62c0 <getpagesize>   ## 
another one
...

Cheers,
-- 
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]