
On Sat, 26 Jul 2008 14:29:35 -0700 "J. William Campbell" jwilliamcampbell@comcast.net wrote:
Haavard Skinnemoen wrote:
On Fri, 25 Jul 2008 22:51:09 +0200 kenneth johansson kenneth@southpole.se wrote:
Can't see any reason for using this flag over -fPIC for a program like u-boot.
You need both. One is a compiler flag, the other is a linker flag. The linker will probably barf if you try to create a PIC executable from modules that were not compiled with -fPIC.
No, it won't.
On some platforms it will. Text relocations are nasty, so some platforms (e.g. avr32) just refuse to deal with them. But that's not really relevant -- each architecture should decide whether to compile with -fPIC or not.
You just get a module with a lot more relocations to do. I have verified that all four possible combinations of the compiler -fPIC and linker -pie work and make sense. FWIW, -fPIC code on IA32 is about 16% larger than non-PIC code, while on the Blackfin, -fPIC code is about 2% larger than non-PIC code. This is an average over several large C++ applications.
Right...that's counting the whole loadable image or just the .text section? Not suprising that a modern architecture like Blackfin likes -fPIC a lot better than an old beast like i386 though.
I agree with this suggestion. This is the only way to ensure a "sane" environment, because it emulates what the compiler expects to happen. Looping over all the relocation entries and doing the "right thing" is architecture specific, but the process is general. The GOT entries can also be processed this way. Effort spent on this approach will tend to be more generic than the current PPC specific approach.
Right...I think the GOT entries already are processed this way, sort of.
Ah, of course. The strings are probably read directly from flash.
Maybe not. I have been looking at assembly dumps of short examples on the IA32 built with -fPIC. It is clear that the method of addressing static variables and static constants is DIFFERENT from the method used for global variables. The relationship of the location of the text segment (executable code), the GOT data, and the static variables/constants must remain fixed. The location of the entire program can move, but it must move in one piece. If it does move as one piece, the lea (load effective address) instructions relative to the GOT pointer will be relocated to the new address correctly. These references are based totally on the offset from the point of reference. If the code is similar on your platform (which I bet it is), then the reference will not be to the flash but rather the "new" place where the data was moved..
Yes, address calculations in the code should be correct, as the whole thing was compiled with -fPIC. Data references, however, are usually not. The code being discussed here is an array of pointers to strings. I'm pretty sure the pointers are still pointing to flash after relocation.
Global variables, however are referenced indirectly via 32 bit address pointers in the GOT, and these addresses must be relocated by the "loader".
The global variables themselves are accessed through the GOT, yes. But the _value_ of a global variable is currently not relocated automatically.
The "loader" also must relocate any initialized pointers, because the program itself does not. It would be interesting to know how this is accomplished, via what relocation codes, but it does happen.
This is what's currently being done manually by adding a fixed offset to all the pointers we "know" need to be relocated. When linking with -pie, these initialized pointers will get a dynamic relocation entry each so that we can replace all these manual fixups by simply iterating over the relocations.
To summarize: Address calculations in executable code do not need to change since we already compile with -fPIC. Initialized pointers, however, are currently handled in a very suboptimal way, and linking with -pie might be one piece of the solution to this.
Haavard