Re: shared library creation and -KPIC/pic clarification

Dave wrote:
> Casper H.S. Dik wrote:
>> Dave writes:
>>>So is this statement in the Sun Studio 11 man page for cc:
>>>"Shared objects built with -xarch=v9 -xcode=abs32 or -xarch=v9
>>>-xcode=abs44 will not work."
>>>wrong or am I just interpreting it incorrectly? That indicates to me
>>>that xarch=v9 -xcode=abs44 will not work under any circumstances, which
>>>seems a bit odd given it is the default on 64-bit systems.
>> Not, it says *shared objects*. So programs will work fine with
>> -xcode=abs44 but shared libraries will not.
> Sorry, it was a shared library I wanted to create. So I assume
> -xcode=pic13 is what I need?
> Will -xcode=pic32 work if the GOT table is *under* 8k? If one is going
> to distribute a program for others to compile, one is unlikely to be in
> a position to know this.
> I've got no feeling for when -xcode=pic13 might need to be replaced by
> -xcode=pic32.

There's so much confusion here that I doubt I'll be able to address
all of them in a single post. I'll try to post a blog on this later
but let me give a quick shot at explaning what -xcode is and how it affects
your code. This is only for SPARC. Intel side has slightly different issues.

What -xcode determines is what code sequence the compiler will generate
to form the address of any symbol (a symbol could be a function or an object).
So, for example, -xcode=abs44 tells the compiler that
only lower 44-bits of the address of any symbol the code accesses are important
hence the compiler generates the code sequence that takes only lower 44-bit
and necessary relocations for them.
This address forming code sequence does not apply to function calls
because SPARC function calls are PC-relative AND because
calls to shared libraries go through PLT which can reach the entire 64-bit
address space. This issue only comes up when there's a global variable access
or when the pointer to a function is used.

-xcode=abs64, as its name implies, tells the compiler to assume
full 64bit is necessary to form any address.
Hence this flag is always safe.

So why does the compiler use -xcode=abs44 by default ?
It does so because it gives the better performace than -xcode=abs64
and works fine for most applications.
On the SPARC,
it takes 6 instructions to form 64-bit constant
whereas it takes 4 instructions to form 44-bit constant.
This different doesn't sound much but if your program size is large
and has many of address forming code, it could be non-trivial.

So when does -xcode=abs44 cause the runtime linker to fail ?
when the runtime linker resolves such 44-bit related relocations
and finds out that the actual address of the symbol needs more than 44-bit,
it fails to load the object and kills the program.
This can happen in following scenarios:
1. (More common than 2) All object files used in linking the executable
are compiled with at least -xcode=abs44,
and one of the shared libraries the executable links with
have been loaded into the high address range above 2^44
(regardless of how the shared library itself is built),
and the executable has an access to a global object within the shared library
or has formed a function pointer to any functions within the library.
This is the case the Studio documentation warns about.

2. (Very rare) Regardless of how the executable is compiled,
the executable loads at least two shared libraries
and one of them is compiled with -xcode=abs44
and the other is more than 2^44 away from the shared library
built with -xcode=abs44. In this case,
the runtime linker will fail to resolve relocations
used within the -xcode=abs44 built shared library.
This doesn't happen often, because most shared libraries are
built with -xcode=pic13/pic32.

In the different branch of this thread,
I've seen someone mentioning using an archive library to build
a shared library. Please remember that an archive library
is simply a collection of objects, hence, for most practical purposes,
an archive library should be treated as just bunch of objects.
>From that point of view, an archive library needs to be compiled
with whatever flag is necessary for its final use.

In another branch, there was a question about -xcode=pic13/pic32.
To determine which one (pic13 or pic32) to use,
one need to know the number of access to global symbols
in the final shared library that the object will be part of.
Since there's no easy way to know that,
usually one needs to do a trial-and-error approach:
try building a shared library with -xcode=pic13
and if the linking succeeds, then it's fine.

Now, that is a hassle (although it's usually a hassle
that has to be taken care of only once)
but the benefit of -xcode=pic13 is again the performance (what else?).
The reason is similar as abs44 vs abs64.
With -xcode=pic13, the compiler will generate
different (and shorter) code sequence to form the address
than -xcode=pic32.

Oh well, this isn't that quick nor short.
But I hope this addresses most questions.
Again, as a reminder, this is only for SPARC.
Intel has different -xcode values and different associated issues...
#pragma ident "Seongbae Park, compiler,";