Re: why does -fno-pic coge generation on x64 require the large model?

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

 



On Tue, Nov 8, 2011 at 07:48, Ian Lance Taylor <iant@xxxxxxxxxx> wrote:
> Eli Bendersky <eliben@xxxxxxxxx> writes:
>
>>>> What I'm trying to see is how to convince GCC to generate NON-PIC code
>>>> and link it into a shared library for x64. I only managed to do this
>>>> with "-fno-PIC -mcmodel=large", and I wonder why with other memory
>>>> models it doesn't work out. I suspect this has to do with some
>>>> artifact of x64's addressing modes for symbol offsets.
>>>
>>> Yes.  If it were easy to permit non-PIC x86_64 code in a shared library,
>>> gcc would do it.  But the only way to do that is, as you say, to use the
>>> large memory model, which is relatively inefficient.
>>>
>>
>> Yes, I realize this. Hence my original question - *why* is the large
>> memory model the only way to do it? I know it's relatively
>> inefficient, because it's the most general and flexible in terms of
>> addressing. Why aren't the small & medium models flexible enough?
>
> It's straightforward if you think about it and try to write down the
> actual code sequences.
>
> To write position independent code you need to be able to write a
> position independent reference to a global variable which may be defined
> in a different shared library.  When compiling with -fPIC the compiler
> arranges to load the address of the global variable from the GOT.  The
> dynamic linker fills in the GOT at runtime.  The GOT is always in the
> same shared library, so you can reasonably use a 32-bit PC-relative
> reference (this assumes that a single shared library will be 2G or less
> in total address space, which is a reasonable assumption).  Of course,
> you pay the price of a double indirection for each reference to a global
> variable.
>
> When you don't compile with -fPIC, then global variables are referenced
> directly, rather than via a GOT.  When a shared library not loaded in
> the low 32 bits of memory needs to refer to a global variable loaded in
> a different shared library also not loaded in the low 32 bits of memory,
> then the library needs to use a 64-bit address.  The compiler will only
> generate a 64-bit address when using the large model.
><snip>

Ian, thanks - this clarifies the issue.
Eli



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux