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.
