CFLAGS+= -fPIC per default?
Joseph Fenton
jlfenton at citlink.net
Sun Feb 22 13:27:50 PST 2004
>>Adding CFLAGS= -fPIC to /etc/make.conf may be a local solution but
>>are there any drawbacks by adding something like
>>.if ${ARCH} == "amd64"
>>CFLAGS+= -fPIC
>>.endif
>>
>>to ports/Mk/bsd.port.mk?
>>
>>
>
>No.. please don't. Although the AMD64 platform supports PIC addressing
>modes directly, it is still a penalty. (Although thankfully, its
>nowhere near as expensive as it is on i386!)
>
>For example, in libc when built in PIC mode:
>#ifdef PIC
> movq PIC_GOT(HIDENAME(curbrk)),%rdx
> movq (%rdx),%rax
>#else
> movq HIDENAME(curbrk)(%rip),%rax
>#endif
>
>The problem is that we can't be sure that everything will be in +/- 31
>bit offsets of each other. This means that PIC objects have to do
>indirect memory references that aren't required in no-pic mode.
>
>I386 also loses a general purpose register (%ebx) which is why -fpic is
>more expensive there. But even though we don't lose a register, its
>still a cost because of the extra global-offset-table memory
>references.
>
>Footnote: you just made me wonder about some of these ifdefs.. We
>shouldn't need them for intra-object references like this. I'll have
>to go and look again.
>
>
Sorry to be anal, but PC-relative addressing is by definition
position-independent code. Who was the bright individual
who decided that when compiling PIC code to NOT use
PC-relative and to NOT use PC-relative for non-PIC code?
This is counter-intuitive. For PIC code, you use PC-relative
addressing in two cases: 1 - the code is guaranteed to be
a constant distance apart, like code in the same section; 2 -
when the loader guarantees the relative position of different
sections, like code and data contained in a ROM.
Case 1 could be violated by the code being too far apart
for PC-relative addressing. This is virtually impossible for
the AMD64 as I doubt we'll see code exceeding 2G in
size in the next several decades. Code is only now exceeding
a few megabytes. Case 2 is usually your problem, which leads
to tables used to hold addresses or offsets.
Both sides of the #ifdef PIC are doing valid PIC code.
PC-relative addressing should be used wherever possible
unless it incurs a speed penalty.
Non-PIC code generally does PC-relative code if it
is faster and is legal, for example, when referring to
code within the same section. When the address must
be set by the loader for non-PIC code, it seems to me
that the fastest code would be like this:
mov <imm32>,%rdx
movq (%rdx),%rax
or if the address is > 4G
movq <imm64>,%rdx
movq (%rdx),%rax
The loader would then set the immediate vector upon
loading the sections. This avoids a memory hit for accessing
a table of addresses while only adding at most 5 bytes to the
size of the code. I would probably use this unless the user
is compiling with flags set to compile with minimized code
size.
Sorry to nit-pick like this, but having worked on both Mac
and Amiga ROMs, PIC mode under BSD really seems
backwards to me.
More information about the freebsd-amd64
mailing list