I was wondering if there is any way to determine if a given .o file was
compiled as PIC?
Thanks,
Jim
take a look at "Linker and libraries guide" on dos.sun.com
dump -Lv libfoo.so.1 | grep TEXTREL
The value of the TEXTREL entry is irrelevant. Its presence in a shared
object indicates that text relocations exist.
presence of TEXTREL means you compiled without PIC, if i understand what
is said in docs.sun.com
I thought the question was about .o files, not about shared libraries.
Also, I haven't delved into building shared libraries in quite some
time, but intuition tells me that all shared libraries would have to
be relocatable; otherwise, chaos would ensue with memory management.
- Logan
I don't know if this is guaranteed to work, but some compilers (and
versions thereof) seem to leave the actual "command line" of their
invocation in the object file. So the following might work for you:
$ strings -a <objectfile> | grep <your compilers name or PIC or
whatever>
For example with the Sun compiler (I think it works at least back to
version 5.0 or so):
$ cat <<EOT > foo.c
void func() {}
EOT
$ cc -KPIC -DWHATEVER -I/test/me -c foo.c
$ strings -a foo.o | grep cc
/opt/SUNWspro/bin/cc -KPIC -DWHATEVER -I/test/me -c foo.c
Ok here is the simplest solution about shared objects & not shared
library:
A .o file containing position-independent code contains an unresolved
external reference to _GLOBAL_OFFSET_TABLE_,
nm file.o | grep _GLOBAL_OFFSET_TABLE_
U _GLOBAL_OFFSET_TABLE_
Hi,
Yes, per the subject, I am asking about ".o" files, not shared
libraries.
Jim
Hi,
Some background on my original question: The reason for the question is
I am trying to help someone who's trying to make a shared lib, but he
needs to link in a static lib (.a). I found info that we should extract
the .o files from the .a, then link to make the final shared lib (.so).
However, I then found info that this wouldn't work unless the extracted
.o files were compiled as PIC, and thus the question in my original
post.
It turns out that the .o files that I extracted from the .a were NOT
compiled with PIC, using Deepak's suggestion (nm | grep _GLOBAL...).
Now, I've read that even if the .o files were not compiled with PIC,
that it is possible to incorporate them into a shared lib by using ld,
but without the "-z text".
Perhaps this is getting close to time to move this to
compu.unix.programmer, but if not, then can anyone tell me if the above
(ld without "-z text") is the correct way to achieve this?
Thanks,
Jim
Looks good - experiment seems to confirm:
$ PATH=/usr/xpg4/bin:/usr/bin:/usr/ccs/bin:/opt/SUNWspro/bin;export PATH
$ cat silly.c
void
silly(void)
{
return;
}
$ type cc
cc is /opt/SUNWspro/bin/cc
$ cc -Kpic silly.c -c -o silly-pic.o
$ cc silly.c -c -o silly-nonpic.o
$ type file
file is /usr/bin/file
$ file silly*.o
silly-nonpic.o: ELF 32-bit MSB relocatable SPARC32PLUS Version 1, V8+ Required
silly-pic.o: ELF 32-bit MSB relocatable SPARC32PLUS Version 1, V8+ Required
$ nm silly-pic.o
silly-pic.o:
[Index] Value Size Type Bind Other Shndx Name
[7] | 0| 0|NOTY |GLOB |0 |UNDEF |_GLOBAL_OFFSET_TABLE_
[2] | 0| 0|OBJT |LOCL |0 |3 |Bbss.bss
[3] | 0| 0|OBJT |LOCL |0 |4 |Ddata.data
[4] | 0| 0|OBJT |LOCL |0 |6 |Dpicdata.picdata
[5] | 0| 0|OBJT |LOCL |0 |5 |Drodata.rodata
[6] | 16| 20|FUNC |GLOB |0 |2 |silly
[1] | 0| 0|FILE |LOCL |0 |ABS |silly.c
$ nm silly-nonpic.o
silly-nonpic.o:
[Index] Value Size Type Bind Other Shndx Name
[2] | 0| 0|OBJT |LOCL |0 |3 |Bbss.bss
[3] | 0| 0|OBJT |LOCL |0 |4 |Ddata.data
[4] | 0| 0|OBJT |LOCL |0 |5 |Drodata.rodata
[5] | 16| 20|FUNC |GLOB |0 |2 |silly
[1] | 0| 0|FILE |LOCL |0 |ABS |silly.c
How about with gcc?
$ PATH=/opt/sfw/gcc-3.2/bin:/usr/xpg4/bin:/usr/bin:/usr/ccs/bin:/opt/SUNWspro/bin;export PATH
$ gcc -fpic -c silly.c -o silly-gcc-pic.o
$ gcc -c silly.c -o silly-gcc-nonpic.o
$ nm silly-gcc*.o
silly-gcc-nonpic.o:
[Index] Value Size Type Bind Other Shndx Name
[2] | 0| 0|SECT |LOCL |0 |2 |
[3] | 0| 16|FUNC |GLOB |0 |2 |silly
[1] | 0| 0|FILE |LOCL |0 |ABS |silly.c
silly-gcc-pic.o:
[Index] Value Size Type Bind Other Shndx Name
[2] | 0| 0|SECT |LOCL |0 |2 |
[3] | 0| 16|FUNC |GLOB |0 |2 |silly
[1] | 0| 0|FILE |LOCL |0 |ABS |silly.c
Nope.
Hmm, maybe still need to look for a better solution...
$ ls -l silly-gcc*.o
-rw-r--r-- 1 rlhamil owner 524 Jan 10 10:54 silly-gcc-nonpic.o
-rw-r--r-- 1 rlhamil owner 524 Jan 10 10:54 silly-gcc-pic.o
$ cmp -l silly-gcc-*.o
[no differences]
What gives?
--
mailto:rlh...@smart.net http://www.smart.net/~rlhamil
Lasik/PRK theme music:
"In the Hall of the Mountain King", from "Peer Gynt"
> $ cat silly.c
> void
> silly(void)
> {
> return;
> }
> How about with gcc?
> silly-gcc-nonpic.o:
>
> [Index] Value Size Type Bind Other Shndx Name
>
> [2] | 0| 0|SECT |LOCL |0 |2 |
> [3] | 0| 16|FUNC |GLOB |0 |2 |silly
> [1] | 0| 0|FILE |LOCL |0 |ABS |silly.c
>
> silly-gcc-pic.o:
>
> [Index] Value Size Type Bind Other Shndx Name
>
> [2] | 0| 0|SECT |LOCL |0 |2 |
> [3] | 0| 16|FUNC |GLOB |0 |2 |silly
> [1] | 0| 0|FILE |LOCL |0 |ABS |silly.c
> Hmm, maybe still need to look for a better solution...
>
> $ ls -l silly-gcc*.o
> -rw-r--r-- 1 rlhamil owner 524 Jan 10 10:54 silly-gcc-nonpic.o
> -rw-r--r-- 1 rlhamil owner 524 Jan 10 10:54 silly-gcc-pic.o
> $ cmp -l silly-gcc-*.o
> [no differences]
>
> What gives?
It's irrelevant whether that file is compiled with PIC flag or not
because the code doesn't require modification to be address independent.
It already is address independent. And gcc just didn't add bloat to the
object file.
Try with:
extern int foo;
int
silly(void)
{
return foo;
}
--
.-. .-. Yes, I am an agent of Satan, but my duties are largely
(_ \ / _) ceremonial.
|
| da...@fly.srk.fer.hr
In practice, a presence of global offset table
(symbol name _GLOBAL_OFFSET_TABLE_)
means an object is compiled with PIC
(unless the code is extremely trivial, e.g. no function calls
and no global variable access).
To be pedantic, following is the compiler gobbledygook on this issue.
Whether a file is "compiled with PIC"
is not exactly the interesting question.
The question is, whether all code in a particular object file
is position independent (e.g. through inline assembly
you can inject position dependent code into a .c file
that's compiled with -PIC).
The best way to determine whether any object is position independent
is to do elfdump -r and inspect text relocations.
On SPARC, if you ever see any absolute relocations in .rela.text like:
R_SPARC_{HI22/LO10/H44/M44/L44/HH22/LM22/HM10/LO10/...} [1]
then this means the code is NOT position independent.
The lack of any absolute relocation means it *may* be position independent
- you need more close inspection to be sure.
e.g. with linker scoping, the compiler may generate R_SPARC_WDISP30
relocation even in PIC code, if the symbol marked hidden or symbolic,
since the relocation will be resolved at link time
and the final code will still be position independent [2].
[1] There are different absolute relocations on Intel side
but I don't remember them off the top of my head.
And there are other absolute relocations.
Most of the time, the presence of R_SPARC_WDISP30 also means
the code is not position independent.
[2] Our compiler doesn't do this,
and I think it's better to be left to the linker. It's just that
in theory, there are relocations that can be resolved at link time
that sometimes makes the code position dependent, sometimes not.
--
#pragma ident "Seongbae Park, compiler, http://blogs.sun.com/seongbae/"
Ok, good one; that does have _GLOBAL_OFFSET_TABLE_.
And I see that Seongbae Park's follow-up covers some additional cases
involving the relocation techniques employed. Still not absolutely
an answer, but getting closer...
Thanks, this is getting more and more interesting.
So does the linker know for sure whether or not a particular object file
is position-independent? If so, could it be given an option to report
that sort of thing? Otherwise, is there enough info available that a new
utility could always figure it out (without having to actually disassemble
and examine the text segment)? And if even that isn't feasible, would it
be worth adding something to the compilers/assembler to flag
position-independent object files (and to the linker to propagate the flag
only if all input were position-independent and any other relevant
additional conditions were met such that the output also would be)?
It does seem at first glance to be the sort of question that people might
want to ask, and answer, easily.
I'd say, why ?
I'm not sure what's the value of figuring out
whether a .o is position-independent or not.
If you have the source code,
then you set the compilation flag correctly.
If you don't have the source,
you ask whoever provided .o to build it correctly for shared library usage.
I guess in theory, there can be a situation
where you have an object file and you don't know how it's built
but want to use it in a shared library,
but I doubt such a case warrants any extra effort to
add yet another obscure option to the linker
(linker can tell during the linking of the shared library).
In practice, looking for the reference of
_GLOBAL_OFFSET_TABLE_ work most of the time,
and the only time it doesn't work
is when somebody tries really hard to break that
(in which case s/he supposedly already knows).
Seems to me a quite common case might be where you have a static (.a)
library and want to make use of it in a shared library. I've had to do
this many times; though in fact in my situations I've always had access
to the source and could make sure it was compiled correctly, I can
easily imagine the library coming from a close-source vendor.
HT
Does that mean one could simply try to use the linker to create a
shared library from the .o files, and if they weren't suitable,
it could reliably detect that and warn (or fail)? Then that
would arguably be sufficient; one could always just try and
see if it worked. Only if it could be fooled would that really
be insufficient. And one could presumably create a script that
invoked the linker with the appropriate options (and deleted the
output if it succeeded), just to tell if it worked. If that could
be done, what _would_ be the appropriate options?
> In practice, looking for the reference of
> _GLOBAL_OFFSET_TABLE_ work most of the time,
> and the only time it doesn't work
> is when somebody tries really hard to break that
> (in which case s/he supposedly already knows).
--
> Does that mean one could simply try to use the linker to create a
> shared library from the .o files, and if they weren't suitable,
> it could reliably detect that and warn (or fail)?
The linker will reliably fail (given '-z text').
> Then that
> would arguably be sufficient; one could always just try and
> see if it worked.
It is sufficient, provided one understands the error and the reason
for failure.
Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.