Morgan Herrington wrote:

> Questions
> ---------
> 
> 1) Ignoring issues of performance or actually
>    even sharing the library pages, are there
>    technical reasons that non-PIC code can not be
>    used to build a ".so" library?  [This is for
>    32-bit SPARC, Solaris 9, Sun Studio 8.]

No.

> 2) Does the answer to this question change for
>    64-bit SPARC or for either 32-bit or 64-bit
>    x86?

Sometimes.  There are no technical reasons why non-PIC
code can't be used in dynamic objects, however the
compiler folks often choose defaults for non-PIC code
that restrict the range of addresses the code can
accommodate.

Effectively, if your code is built using abs32 or abs44
then the creation of large objects, or the relocation of
objects separated by large distances at runtime, can result
in "does not fit" relocation errors.

I wish the compiler defaults allowed for complete 64-bit
addressing, as the "does not fit" errors keep cropping
up, and mystifying users.

Perhaps the compiler folks on this alias could add a
more definitive description of their options, and perhaps
a pointer to documentation that would direct users on
how to create the most flexible objects.

> 3) Does the use of "ld -r" to create some of the
>    input objects change the answer [see note,
>    below].

No.

> 4) Could building non-PIC libraries or using
>    "ld -r" on the inputs cause "silent failures"?
>    By that, I mean incorrectly-executing code which
>    doesn't cause either "ld" or "ld.so" to generate
>    a warning/error message.

It shouldn't.

> The bottom-line question is whether they are
> "safe" in only insisting on PIC code when the
> linker complains (and slowly migrating all
> libraries to PIC over time).  

You can mix PIC and non-PIC code, the link-editors
don't care.

> Thanks very much.
> 
> Morgan Herrington, MDE
> 
> 
> Note about use of "ld -r"
> -------------------------
> The manual page for "ld", when describing the "-r"
> option, says, "This option cannot be used in
> dynamic mode or with -a."  The ISV claims that
> they've used it for years in building the *inputs*
> to some of their ".so" libraries without previously
> observing any problems.

The words mean you can't mix -r and -dy in the same ld(1)
operation.   You can use ld -r to generate intermediate
objects, and then later collect these objects into a
final executable or shared object.

> Their use is that some groups aggregate a set
> of objects into a single ".o" file using "ld -r".
> Then these aggregated objects are later combined
> into a much bigger ".so" file.

That's ok.

> Does this violate the "not in dynamic mode" rule?

No.

> If this is *does* cause problems, does it fail
> quietly (for example, with replicated static
> data) or would the failures be obvious (for
> example, an error from "ld.so")?

There are no "quiet" errors from the link-editors
(excepting bugs of course).

Note, there's nothing stopping you from creating
PIC .o's and then combining them into intermediate
objects with ld -r.   There's nothing preventing you
from putting PIC code in archives (.a's) either.


> Explanation/history for anyone who is interested
> ------------------------------------------------
> This is part of a family of dozens of products
> (from multiple corporate divisions) which share
> a few dozen libraries.
> 
> Previously, they tended to use ".a" archives, but
> that model had some problems -- symbol collisions
> between libraries and long link times.  They're
> migrating to using map files to reduce the scope of
> most symbols (to avoid collisions) and are
> switching many of the libraries to be ".so"
> libraries.

Good idea.  Note that, over the years quiet a bit
of work has gone into speeding up archive processing.
It's obviously easier for ld(1) to take an external
deliverable as one .o, but archives do provide for
selecting just the archive members you need.

Shared objects are even better.  But shared objects
also have a cost.  Each has to be located, loaded
and relocated at runtime.  If you have many shared objects
but the same family of objects are always used together,
you're paying a runtime price for them being provided
in separate objects, rather than all built into the same object.

Don't isolate code into a unique shared object unless that
object can be used in different instances, or you want to
make a choice (dlopen) of what object to load.

> When they build the 64-bit version of their
> program, they *sometimes* get link-time errors
> like the following (reformatted for email):
> 
>   ld: fatal:
>       relocation error: R_SPARC_WDISP30:
>       file libvcsnew.o:
>       symbol VeRa__LiSt_InSeRt_AfTeR_tYpElEsS:
>       value 0x3b30629c does not fit
> 
> This looks like the failure signature in some bug
> reports (for example, 4129745 and 4141890) except
> that this comes from "ld" rather than "ld.so".

Investigate your compiler flags, the default code you are
creating isn't sufficient to provide for your address
ranges.

> When they rebuilt the library (reported above)
> using "-KPIC", the problem appeared to go away.
> Unfortunately, because some of the libraries come
> from other divisions and even other companies,
> it's a non-trivial task to rebuild them all.

PIC code can handle any address range.

-- 

Rod.

Reply via email to