-fpic or -fPIC?

-fpic or -fPIC?

Post by Michael Meissn » Thu, 25 Jan 1996 04:00:00



In article <4e5inu$...@isis.fiu.edu> habi...@catevr.fiu.edu () writes:

| Hi,
|
| I have been trying to compile some shared library.  My question is
| why some libraries uses -fpic switch to compile a shared library
| while the other libray package uses -fPIC at the compiling stage and
| -fpic at the final stage?  I tried to understand this by looking at
| the gcc manpage.  The manpage says that -fpic is used to generate a
| position-independent code(pic) for shared library whereas -fPIC is
| used to emit a position-independent code for a dynamic linking.

On an x86, it doesn't matter whether you use -fpic or -fPIC.  That's because
all of the memory reference instructions that include an offset on the x86,
have only byte and 32-bit offsets (in 16-bit mode, it is byte and 16-bit
offsets).  Since a 256 byte GOT (Global Offset Table -- it is where the actual
pointers to data are kept) is useless for anything but toy programs, it means
that all instructions that use the GOT use a 32-bit offset.

On other systems, such as the SPARC, MIPS, and PowerPC, the offset used in
instructions is smaller, typically 16 bits.  That means a GOT with a 16 bit
offset is limited to 65K (or 8192 unique addresses for 32-bit programs and 4096
unique address for 64-bit programs).  If your program cannot use a small GOT,
it then has to synthesize the full GOT offset by using two or more
instructions, which can slow it down.  Thus, if you can get by with a small
GOT, you use -fpic, and if you need a large GOT, you use -fPIC.

For example, consider the following function:

        int i;
        void foo(){ i = 0; }

On an x86, this would generate the following without -fpic:

                .file   "foo.c"
                .version        "01.01"
        gcc2_compiled.:
        .text
                .align 16
        .globl foo
                .type    foo,@function
        foo:
                pushl %ebp
                movl %esp,%ebp
                movl $0,i                       # zero i directly
                movl %ebp,%esp
                popl %ebp
                ret
        .Lfe1:
                .size    foo,.Lfe1-foo
                .comm   i,4,4
                .ident  "GCC: (GNU) 2.7.2"

If you use either -fpic or -fPIC, it generates:

                .file   "foo.c"
                .version        "01.01"
        gcc2_compiled.:
        .text
                .align 16
        .globl foo
                .type    foo,@function
        foo:
                pushl %ebp
                movl %esp,%ebp
                pushl %ebx
                call .L2                        # calculate GOT address
        .L2:
                popl %ebx
                addl $_GLOBAL_OFFSET_TABLE_+[.-.L2],%ebx
                movl i@GOT(%ebx),%eax           # put &i into %eax
                movl $0,(%eax)                  # zero i
                movl -4(%ebp),%ebx
                movl %ebp,%esp
                popl %ebp
                ret
        .Lfe1:
                .size    foo,.Lfe1-foo
                .comm   i,4,4
                .ident  "GCC: (GNU) 2.7.2"

On a PowerPC, it would generate:

                .file   "foo.c"
        gcc2_compiled.:
                .section        ".text"
                .align 2
                .globl foo
                .type    foo,@function
        foo:
                addis 9,0,i@ha                  # load upper 16 bits of &i
                li 0,0
                stw 0,i@l(9)                    # zero i
                blr
        .Lfe1:
                .size    foo,.Lfe1-foo
                .comm   i,4,4
                .ident  "GCC: (GNU) cygnus-2.7.2-960106"

With -fpic it might generate:

                .file   "foo.c"
        gcc2_compiled.:
                .section        ".text"
                .align 2
                .globl foo
                .type    foo,@function
        foo:
                mflr 0
                stw 0,4(1)
                stwu 1,-8(1)
                li 0,0
                bl _GLOBAL_OFFSET_TABLE-4       # get GOT address in lr
                mflr 9                          # move GOT address to r9
                lwz 3,i@got(9)                  # move &i to r3
                stw 0,0(3)                      # zero i
                addi 1,1,8
                lwz 0,4(1)
                mtlr 0
                blr
        .Lfe1:
                .size    foo,.Lfe1-foo
                .comm   i,4,4
                .ident  "GCC: (GNU) cygnus-2.7.2-960106"

With -fPIC it might generate:

                .file   "foo.c"
        gcc2_compiled.:
                .section        ".text"
                .align 2
                .globl foo
                .type    foo,@function
        foo:
                mflr 0
                stw 0,4(1)
                stwu 1,-8(1)
                li 0,0
                bl _GLOBAL_OFFSET_TABLE-4       # GOT address to lr
                mflr 9                          # move lr to r9
                addis 10,0,i@got@ha             # upper 32 bits of GOT offset
                addi 10,10,i@got@l              # lower 32 bits of GOT offset
                stwx 0,9,10                     # zero i
                addi 1,1,8
                lwz 0,4(1)
                mtlr 0
                blr
        .Lfe1:
                .size    foo,.Lfe1-foo
                .comm   i,4,4
                .ident  "GCC: (GNU) cygnus-2.7.2-960106"

| Can anyone please tell me if I am doing something wrong with these
| switches to create an ELF shared library?  Please kindly eMail me
| your response.  Thank you.

No, read the bloody group.
--
Michael Meissner, Cygnus Support (East Coast)
Suite 105, 48 Grove Street, Somerville, MA 02144, USA
meiss...@cygnus.com, 617-629-3016 (office),  617-629-3010 (fax)

 
 
 

-fpic or -fPIC?

Post by habi.. » Thu, 25 Jan 1996 04:00:00


Hi,

I have been trying to compile some shared library.  My question is
why some libraries uses -fpic switch to compile a shared library
while the other libray package uses -fPIC at the compiling stage and
-fpic at the final stage?  I tried to understand this by looking at
the gcc manpage.  The manpage says that -fpic is used to generate a
position-independent code(pic) for shared library whereas -fPIC is
used to emit a position-independent code for a dynamic linking.

Can anyone please tell me if I am doing something wrong with these
switches to create an ELF shared library?  Please kindly eMail me
your response.  Thank you.

--


 
 
 

1. to -fPIC or to not -fPIC ... what is the difference?

I modified my library, which I'm currently re-organizing, to build
both an .a and .so files, with the .a files compiled without -fPIC
and the .so files compiled with -fPIC.  There is no difference in
compiled code between them for every source file.

But should there be for the x86 platform?  I've heard that the x86
platform actually suffered most with -fPIC because it had to use a
register for some kind of extra base address.  Anyone have any ideas?

--
-----------------------------------------------------------------
| Phil Howard - KA9WGN |   Dallas   | http://linuxhomepage.com/ |

-----------------------------------------------------------------

2. Need Soundblaster MIDI port help

3. gcc -fpic/-fPIC; -shared; i386

4. ijppp crashing serial connection

5. -fPIC and -fpic?

6. does anyone know?

7. Why using fPIC

8. expect+special character

9. -fPIC and shared libraries

10. Help: C-function `uselib', gcc -fPIC

11. printf in -fPIC lib dumps core

12. GCC -fPIC question

13. gcc -fPIC does not work