public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* why does -fno-pic coge generation on x64 require the large model?
@ 2011-11-07 11:39 Eli Bendersky
  2011-11-07 15:37 ` Ian Lance Taylor
  0 siblings, 1 reply; 8+ messages in thread
From: Eli Bendersky @ 2011-11-07 11:39 UTC (permalink / raw)
  To: gcc-help

Hello,

I'm experimenting with generating PIC and non-PIC code on x64 Ubuntu.
It's possible to generate non PIC code as follows:

  gcc -fno-PIC -mcmodel=large -shared -c file.c

However, I noticed that for other models (i.e. -mcmodel=small, or by
default, without the -mcmodel argument), the code being generated is
not really suitable for PIC as it has problematic load-time
relocations.

My question is - why is the large model required to generate true PIC code?

Thanks in advance,
Eli

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: why does -fno-pic coge generation on x64 require the large model?
  2011-11-07 11:39 why does -fno-pic coge generation on x64 require the large model? Eli Bendersky
@ 2011-11-07 15:37 ` Ian Lance Taylor
  2011-11-07 15:57   ` Eli Bendersky
  0 siblings, 1 reply; 8+ messages in thread
From: Ian Lance Taylor @ 2011-11-07 15:37 UTC (permalink / raw)
  To: Eli Bendersky; +Cc: gcc-help

Eli Bendersky <eliben@gmail.com> writes:

> I'm experimenting with generating PIC and non-PIC code on x64 Ubuntu.
> It's possible to generate non PIC code as follows:
>
>   gcc -fno-PIC -mcmodel=large -shared -c file.c
>
> However, I noticed that for other models (i.e. -mcmodel=small, or by
> default, without the -mcmodel argument), the code being generated is
> not really suitable for PIC as it has problematic load-time
> relocations.
>
> My question is - why is the large model required to generate true PIC code?

It's odd to try to create PIC while using -fno-PIC.  I think you must
have some goal in mind for what you want your generated code to look
like, but I don't know what that is.  It most likely does not correspond
to gcc's goal when using -fno-PIC, which is to not generate PIC.

Ian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: why does -fno-pic coge generation on x64 require the large model?
  2011-11-07 15:37 ` Ian Lance Taylor
@ 2011-11-07 15:57   ` Eli Bendersky
  2011-11-07 17:17     ` Andrew Haley
  2011-11-07 18:12     ` Ian Lance Taylor
  0 siblings, 2 replies; 8+ messages in thread
From: Eli Bendersky @ 2011-11-07 15:57 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-help

On Mon, Nov 7, 2011 at 17:37, Ian Lance Taylor <iant@google.com> wrote:
> Eli Bendersky <eliben@gmail.com> writes:
>
>> I'm experimenting with generating PIC and non-PIC code on x64 Ubuntu.
>> It's possible to generate non PIC code as follows:
>>
>>   gcc -fno-PIC -mcmodel=large -shared -c file.c
>>
>> However, I noticed that for other models (i.e. -mcmodel=small, or by
>> default, without the -mcmodel argument), the code being generated is
>> not really suitable for PIC as it has problematic load-time
>> relocations.
>>
>> My question is - why is the large model required to generate true PIC code?
>
> It's odd to try to create PIC while using -fno-PIC.  I think you must
> have some goal in mind for what you want your generated code to look
> like, but I don't know what that is.  It most likely does not correspond
> to gcc's goal when using -fno-PIC, which is to not generate PIC.
>

As I read my question, I realize my intention has not been clear
enough. When I wrote "not really suitable for PIC", I actually meant
"not really suitable for a shared library". I will try to clarify:

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.

I should also add that my intention here is just curiosity. I was
trying to understand how PIC code works on x64, and got intrigued by
the fact that GCC seemingly forces me to use PIC code for shared
libraries on this architecture, unlike x86 where non-PIC code in
shared libraries is fine.

Eli

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: why does -fno-pic coge generation on x64 require the large model?
  2011-11-07 15:57   ` Eli Bendersky
@ 2011-11-07 17:17     ` Andrew Haley
  2011-11-07 18:12     ` Ian Lance Taylor
  1 sibling, 0 replies; 8+ messages in thread
From: Andrew Haley @ 2011-11-07 17:17 UTC (permalink / raw)
  To: gcc-help

On 11/07/2011 03:56 PM, Eli Bendersky wrote:
> I should also add that my intention here is just curiosity. I was
> trying to understand how PIC code works on x64, and got intrigued by
> the fact that GCC seemingly forces me to use PIC code for shared
> libraries on this architecture, unlike x86 where non-PIC code in
> shared libraries is fine.

The x86 shared library loader has a kludge where pages that contain
non-PIC code are remapped and relocated, so every process ends up with
its own copy of each relocated page.  This is provided for
compatibility with older libraries.  x86_64 is a new architecture, so
it wasn't necessary to provide backwards compatibility for non-PIC
libraries.

Andrew.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: why does -fno-pic coge generation on x64 require the large model?
  2011-11-07 15:57   ` Eli Bendersky
  2011-11-07 17:17     ` Andrew Haley
@ 2011-11-07 18:12     ` Ian Lance Taylor
  2011-11-08  3:19       ` Eli Bendersky
  1 sibling, 1 reply; 8+ messages in thread
From: Ian Lance Taylor @ 2011-11-07 18:12 UTC (permalink / raw)
  To: Eli Bendersky; +Cc: gcc-help

Eli Bendersky <eliben@gmail.com> 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.

Ian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: why does -fno-pic coge generation on x64 require the large model?
  2011-11-07 18:12     ` Ian Lance Taylor
@ 2011-11-08  3:19       ` Eli Bendersky
  2011-11-08  5:49         ` Ian Lance Taylor
  0 siblings, 1 reply; 8+ messages in thread
From: Eli Bendersky @ 2011-11-08  3:19 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-help

>> 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?

> The x86 shared library loader has a kludge where pages that contain
> non-PIC code are remapped and relocated, so every process ends up with
> its own copy of each relocated page.  This is provided for
> compatibility with older libraries.  x86_64 is a new architecture, so
> it wasn't necessary to provide backwards compatibility for non-PIC
> libraries.

So non-PIC code on x86_64 is actually different from non-PIC code on
x86? It *doesn't* need page relocation? What's non-PIC about it then,
and again, why only the large memory model allows it?


Eli

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: why does -fno-pic coge generation on x64 require the large model?
  2011-11-08  3:19       ` Eli Bendersky
@ 2011-11-08  5:49         ` Ian Lance Taylor
  2011-11-08  6:09           ` Eli Bendersky
  0 siblings, 1 reply; 8+ messages in thread
From: Ian Lance Taylor @ 2011-11-08  5:49 UTC (permalink / raw)
  To: Eli Bendersky; +Cc: gcc-help

Eli Bendersky <eliben@gmail.com> 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.


>> The x86 shared library loader has a kludge where pages that contain
>> non-PIC code are remapped and relocated, so every process ends up with
>> its own copy of each relocated page.  This is provided for
>> compatibility with older libraries.  x86_64 is a new architecture, so
>> it wasn't necessary to provide backwards compatibility for non-PIC
>> libraries.
>
> So non-PIC code on x86_64 is actually different from non-PIC code on
> x86? It *doesn't* need page relocation? What's non-PIC about it then,
> and again, why only the large memory model allows it?

Code on x86 is different from code on x86_64 because it uses a different
instruction set.  There is no limitation on x86 non-PIC code in a shared
library because non-PIC x86 code uses a 32-bit absolute address to refer
to a global variable, and that is enough to refer to a shared library
loaded anywhere in the address space.

Ian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: why does -fno-pic coge generation on x64 require the large model?
  2011-11-08  5:49         ` Ian Lance Taylor
@ 2011-11-08  6:09           ` Eli Bendersky
  0 siblings, 0 replies; 8+ messages in thread
From: Eli Bendersky @ 2011-11-08  6:09 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-help

On Tue, Nov 8, 2011 at 07:48, Ian Lance Taylor <iant@google.com> wrote:
> Eli Bendersky <eliben@gmail.com> 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

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-11-08  6:09 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-07 11:39 why does -fno-pic coge generation on x64 require the large model? Eli Bendersky
2011-11-07 15:37 ` Ian Lance Taylor
2011-11-07 15:57   ` Eli Bendersky
2011-11-07 17:17     ` Andrew Haley
2011-11-07 18:12     ` Ian Lance Taylor
2011-11-08  3:19       ` Eli Bendersky
2011-11-08  5:49         ` Ian Lance Taylor
2011-11-08  6:09           ` Eli Bendersky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).