Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

shared library creation and -KPIC/pic clarification

70 views
Skip to first unread message

rice....@gmail.com

unread,
Dec 16, 2005, 9:35:13 AM12/16/05
to
I have search the solaris newsgroups on the topic of shared library
creation and the use of the -KPIC/-kpic flag to compile the objects
comprising the library. I think I have a basic understanding of the
main issues. The Sun docs state that -KPIC/pic *must* be used to when
compiling objects for shared libraries. Yet I have noticed that shared
libraries created without this flag load just fine at runtime.

Please correct me if I am wrong...

(1) shared libraries compiled without PIC objects are runtime linkable,
but cannot be shared across processes

(2) point (1) is not really a problem if the shared library will not be
used by a multitude of concurrent processes

(3) only libraries built from -KPIC objects can be really shared by
concurrent processes


A related issue: can a shared library be composed of PIC objects and
non-PIC objects (from static archives lib*.a) ? If so, how does this
composition affect runtime linking?

Also how does a linker deal with objects from a static library that
were built with the -KPIC flag? (Eg. ld -o foo foo.o libwithpicobj.a )

Much thanks!

--Eric

Dave

unread,
Dec 16, 2005, 10:18:52 AM12/16/05
to
rice....@gmail.com wrote:

> (3) only libraries built from -KPIC objects can be really shared by
> concurrent processes

I'm trying to find out more about the libraries at the minute. so are no
expert. But the Sun Studio 11 says -kPIC is deprecated. It is still
excepted, but you should use -xcode=pic32 instead. There are other
arguments that can be used to replace the pic32 (abs21, abs44, abs64,
pci13 or pci32). Take a read of the docs.


--
Dave K

http://www.southminster-branch-line.org.uk/

Please note my email address changes periodically to avoid spam.
It is always of the form: month-year@domain. Hitting reply will work
for a couple of months only. Later set it manually. The month is
always written in 3 letters (e.g. Jan, not January etc)

Iain Bason

unread,
Dec 16, 2005, 10:44:32 AM12/16/05
to
In article <1134743713.2...@g47g2000cwa.googlegroups.com>,
rice....@gmail.com wrote:

> I have search the solaris newsgroups on the topic of shared library
> creation and the use of the -KPIC/-kpic flag to compile the objects
> comprising the library. I think I have a basic understanding of the
> main issues. The Sun docs state that -KPIC/pic *must* be used to when
> compiling objects for shared libraries. Yet I have noticed that shared
> libraries created without this flag load just fine at runtime.
>
> Please correct me if I am wrong...
>
> (1) shared libraries compiled without PIC objects are runtime linkable,
> but cannot be shared across processes

That's correct, although for 64 bit code you would have to compile with
-xcode=abs64 rather than the default -xcode=abs44.

> (2) point (1) is not really a problem if the shared library will not be
> used by a multitude of concurrent processes

Non-pic code may take longer to link at runtime, because it can have
more relocations. For instance, if the code calls "write" ten times,
then the pic version will need only one relocation at runtime while the
non-pic version will need ten.

> (3) only libraries built from -KPIC objects can be really shared by
> concurrent processes

That is mostly true. It is possible for some pages of a non-pic .so to
have no relocations in them, in which case those pages will be shared.
I imagine that would be pretty rare, though.

> A related issue: can a shared library be composed of PIC objects and
> non-PIC objects (from static archives lib*.a) ? If so, how does this
> composition affect runtime linking?

Yes, one can mix and match. If pic code and non-pic code wind up in the
same page, then that page will not be shared amongst processes. Aside
from that, the only factor is that the more pic code there is the fewer
relocations will need to be done.

> Also how does a linker deal with objects from a static library that
> were built with the -KPIC flag? (Eg. ld -o foo foo.o libwithpicobj.a )

Pic code just uses different instructions to call functions and to
access variables. Sometimes those instructions require different
relocation entries. The linker knows how to interpret each relocation
entry, so there is no problem mixing objects this way.

However, pic code can be slower than non-pic code. Pic code adds an
extra jump to function calls (the call is to a table, which contains
jumps to the actual functions). Pic code adds an extra load to access a
global variable (it loads the address from the Global Offset Table, then
loads the actual variable). Usually this overhead is not significant
compared to everything else your program is spending time on, but of
course there are pathological cases.

Iain

Casper H.S. Dik

unread,
Dec 16, 2005, 11:22:24 AM12/16/05
to
rice....@gmail.com writes:

>I have search the solaris newsgroups on the topic of shared library
>creation and the use of the -KPIC/-kpic flag to compile the objects
>comprising the library. I think I have a basic understanding of the
>main issues. The Sun docs state that -KPIC/pic *must* be used to when
>compiling objects for shared libraries. Yet I have noticed that shared
>libraries created without this flag load just fine at runtime.

>Please correct me if I am wrong...

>(1) shared libraries compiled without PIC objects are runtime linkable,
>but cannot be shared across processes

Not completely true:
- they're never shared (true)
- they may be mapped at a point in the address space which
make relocation calls to other libraries impossible and
the runtime linker will bail out (more likely in 64 bit
mode)
- startup time is longer but code may be more efficient

>(2) point (1) is not really a problem if the shared library will not be
>used by a multitude of concurrent processes

- yes, except when it fails to start.

>(3) only libraries built from -KPIC objects can be really shared by
>concurrent processes

- correct

>A related issue: can a shared library be composed of PIC objects and
>non-PIC objects (from static archives lib*.a) ? If so, how does this
>composition affect runtime linking?

Depends on the nature of the symbols defined in the non PIC bits.

>Also how does a linker deal with objects from a static library that
>were built with the -KPIC flag? (Eg. ld -o foo foo.o libwithpicobj.a )

Just fine.

Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.

rice....@gmail.com

unread,
Dec 16, 2005, 6:49:15 PM12/16/05
to
Ok. So if I am understanding the responses:

(1) building shared libs *without* -KPIC/pic compiled objects is
relatively risky.

(2) building a shared lib with -KPIC compiled objects and linking with
a static archive (no pic objects) is also relatively risky

Is there an option/directive to cause the linker to merge two shared
libs into one self contained shared library? If I create libfoo.so and
libbar.so is it possible to link these to produce libfoobar.so such
that the runtime linker will not be loading libfoo and libbar when
loading libfoobar?

--Eric

rice....@gmail.com

unread,
Dec 16, 2005, 7:07:02 PM12/16/05
to
...a follow-on question:

If I were to take the lazy approach and just build all objects with the
-KPIC/pic option, how might this affect linking to static archives?
Will the linker remove the extra code introduced for position
independence?

I can see that
cc -c -Kpic foo.c -o foo.o
ar -rv libfoo.a foo.o
...
ld -o libbar.so -z allextract -lfoo

will do the right thing. But what about

cc -o myapplication main.o -dn -lfoo

How will the relocatable cruft be handled in this case?

TIA
--Eric

Richard L. Hamilton

unread,
Dec 17, 2005, 5:30:48 AM12/17/05
to
In article <1134778022.8...@g47g2000cwa.googlegroups.com>,

AFAIK, position-independent code might be more than just a bit of
initialization, it might be relative rather than absolute jumps or
something like that. So it might not be feasible to remove the
position-independent-ness of it after the fact. Nor should it be
necessary; aside from a slight efficiency penalty, I'd guess that it
should work just as well for just about any userland purpose.


--
mailto:rlh...@smart.net http://www.smart.net/~rlhamil

Lasik/PRK theme music:
"In the Hall of the Mountain King", from "Peer Gynt"

Dave

unread,
Dec 18, 2005, 7:56:38 AM12/18/05
to
Iain Bason wrote:

> That's correct, although for 64 bit code you would have to compile with
> -xcode=abs64 rather than the default -xcode=abs44.

I'm puzzled by this. Looking at the man page for cc it says the default
for 64-bit compiles is abs44, But it also says (see below from the man
page)

"When building shared dynamic libraries, the default -xcode value of
abs44 (not abs32) will not work with -xarch=v9, v9a, or v9b. Specify
-xcode=pic13 or -xcode=pic32 instead."

So there it says use -xcode=pic13 or -xcode=pic3 for 64-bit compiles.
I'm confused by this issue, and need to know soon, so if you can clarify
it, I'd like to know. Although abs64 is mentioned as an argument for
xcode, there is no information about when to use it.

***Part of man page from cc in Sun Studio 11. ***

-xcode=v
(SPARC) Specify code address space

Note: It is highly recommended that you build shared
objects by specifying -xcode=pic13 or -xcode=pic32. It
is possible to build workable shared objects with
-xarch=v9 -xcode=abs64 and with -xarch=v8 -xcode=abs32,
but these will be inefficient. Shared objects built
with -xarch=v9 -xcode=abs32 or -xarch=v9 -xcode=abs44
will not work.

The values for -xcode are:

abs32 This is the default for 32-bit systems. Gen-
erates 32-bit absolute addresses.
Code + data + bss size is limited to 2**32
bytes.
-xarch=(generic|v8|v8a|8plus|v8plusa|v8plusb)

abs44 This is the default for 64-bit systems. Gen-
erates 44-bit absolute addresses.
Code + data + bss size is limited to 2**44
bytes. Available only on 64-bit architectures:
-xarch=(v9|v9a|v9b)

abs64 Generates 64-bit absolute addresses.
Available only on 64-bit architectures:
-xarch=(v9|v9a|v9b)

Last change: 2005/09/26 45

User Commands cc(1)

pic13 Generates position-independent code for use in
shared libraries (small model).
Equivalent to -Kpic. Permits references to at
most 2**11 unique external symbols on 32-bit
architectures, 2**10 on 64-bit.

pic32 Generates position-independent code for use in
shared libraries (large model).
Equivalent to -KPIC. Permits references to at
most 2**30 unique external symbols on 32-bit
architectures, 2**29 on 64-bit.

The default on V8 is -xcode=abs32. The default for
SPARC and UltraSPARC V9 is -xcode=abs44.

When building shared dynamic libraries, the default
-xcode value of abs44 (not abs32) will not work with
-xarch=v9, v9a, or v9b. Specify -xcode=pic13 or
-xcode=pic32 instead.

To determine whether to use -xcode=pic13 or
-xcode=pic32, check the size of the Global Offset Table
(GOT) by using elfdump -c (see the elfdump(1) man page
for more information) and to look for the section
header, sh_name: .got. The sh_size value is the size of
the GOT. If the GOT is less than 8,192 bytes, specify
-xcode=pic13, otherwise specify -xcode=pic32.

In general, use the following guidelines to determine
how you should use -xcode:

o If you are building an executable you should not use
-xcode=pic13 or -xcode=pic32.

o If you are building an archive library only for
linking into executables you should not use
-xcode=pic13 or -xcode=pic32.

o If you are building a shared library, start with
-xcode=pic13 and once the GOT size exceeds 8,192 bytes,
use -xcode=pic32.

o If you are building an archive library for linking
into shared libraries you should just use -xcode=pic32.

Casper H.S. Dik

unread,
Dec 18, 2005, 8:49:35 AM12/18/05
to
>I'm puzzled by this. Looking at the man page for cc it says the default
>for 64-bit compiles is abs44, But it also says (see below from the man
>page)

>"When building shared dynamic libraries, the default -xcode value of
>abs44 (not abs32) will not work with -xarch=v9, v9a, or v9b. Specify
>-xcode=pic13 or -xcode=pic32 instead."

Yep, if building a shared library, you'll need to use pic.

>So there it says use -xcode=pic13 or -xcode=pic3 for 64-bit compiles.
>I'm confused by this issue, and need to know soon, so if you can clarify
>it, I'd like to know. Although abs64 is mentioned as an argument for
>xcode, there is no information about when to use it.

-xcode=abs64 is needed when the code is too big for abs44
(code + statically allocated data > 2^44 bytes)

Dave

unread,
Dec 18, 2005, 10:20:16 AM12/18/05
to
Casper H.S. Dik wrote:

>>So there it says use -xcode=pic13 or -xcode=pic3 for 64-bit compiles.
>>I'm confused by this issue, and need to know soon, so if you can clarify
>>it, I'd like to know. Although abs64 is mentioned as an argument for
>>xcode, there is no information about when to use it.
>
>
> -xcode=abs64 is needed when the code is too big for abs44
> (code + statically allocated data > 2^44 bytes)
>
> Casper

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.

There is no need for code + statically allocated data to get anywhere
near 2^44 bytes for my application, so suggestions for what compiler
switches are needed for a 64-bit binary would be welcome. My only reason
for wishing to compile in 64-bit mode is to make use of the 64-bit
variables.

Casper H.S. Dik

unread,
Dec 18, 2005, 10:49:07 AM12/18/05
to
Dave <INVALID-see-signature...@southminster-branch-line.org.uk> 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.

>There is no need for code + statically allocated data to get anywhere
>near 2^44 bytes for my application, so suggestions for what compiler
>switches are needed for a 64-bit binary would be welcome. My only reason
>for wishing to compile in 64-bit mode is to make use of the 64-bit
>variables.

The default is fine and -xcode=abs32 should work also.

Casper

Dave

unread,
Dec 18, 2005, 11:30:00 AM12/18/05
to
Casper H.S. Dik wrote:
> Dave <INVALID-see-signature...@southminster-branch-line.org.uk> 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.

Seongbae Park

unread,
Dec 19, 2005, 1:26:34 PM12/19/05
to
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, http://blogs.sun.com/seongbae/"

Henry Townsend

unread,
Dec 19, 2005, 2:26:49 PM12/19/05
to
Seongbae Park wrote:
> 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.

Seongbae,

Now that you're here, let me ask a follow-on question. It would seem to
follow from the above that if I'm writing a library which might be
loaded via LD_PRELOAD, then I really ought to use -xcode=pic32 because
there's no way to predict what other shared libraries and how many
symbols might be involved at runtime link time. Is that right?

Thanks,
HT

rice....@gmail.com

unread,
Dec 19, 2005, 2:47:46 PM12/19/05
to
On the topic of that "older branch", my question about using KPIC for
archives and static linking...

Besides a potential performance issue, is there any problem of linking
statically to an archive that contains -KPIC compiled objects? Or will
the linker complain about some incompatabilities and quit?

Seongbae Park

unread,
Dec 19, 2005, 4:47:15 PM12/19/05
to

No. This -xcode=pic32/pic13 is per shared library issue -
it doesn't matter how many other libraries are loaded.

Each shared library built with -xcode=pic32/pic13
has a table of pointers to the named objects it accesses.
e.g. if a shared library compiled with pic{13,32} has a function:

extern int global_var;
int func(void) {
return global_var;
}

Regardless of whether global_var is within the shared library or outside,
the shared library needs a table (Global Offset Table)
that contains a pointer to the global_var (and all the other
symbols accessed by the shared library).
pic13/32 determines the maximum size of that table
due to the assembly code the compiler generates.
e.g. the above will turn into following assembly with -xcode=pic13
(I've omitted GOT address forming part):

.global test
test:
...
! %o2 contains GOT.
/* 0x001c 3 */ ld [%o2+%got13(global)],%o5
/* 0x0020 */ retl ! Result = %o0
/* 0x0024 */ ld [%o5],%o0


This contrasts to -xcode=pic32:

.global test


test:
/* 0x0004 3 */ sethi %got22(global),%o2
...
/* 0x0014 3 */ add %o2,%got10(global),%o5
...
! %o1 contains GOT.
/* 0x0024 3 */ ld [%o1+%o5],%o0
/* 0x0028 */ retl ! Result = %o0
/* 0x002c */ ld [%o0],%o0

As you can see, pic13/32 determines the maximum possible offset from GOT,
hence limit the number of symbols used in the shared library.

Or, in a pseudo-C code, GOT table is something like:

void *GOT[] =
{
...
&global_var, /* GOT[m] */
...
};

and the compiler essentially turns func() into:

int func(void) {
return *(int *)GOT[m];
}

And pic13/32 determines how big "m" can be (13-bit or 32-bit).
Each shared library has its own GOT table,
and hence other libraries don't matter.

Seongbae Park

unread,
Dec 19, 2005, 4:49:31 PM12/19/05
to
rice....@gmail.com <rice....@gmail.com> wrote:
> On the topic of that "older branch", my question about using KPIC for
> archives and static linking...
>
> Besides a potential performance issue, is there any problem of linking
> statically to an archive that contains -KPIC compiled objects?

No.

> Or will the linker complain about some incompatabilities and quit?

No. It will link and run just fine.

0 new messages