Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Shared libraries and executables can be built with PIC code enabled and disabled. I.e. if you build them without PIC they can still be used by other apps. However, non-PIC libraries are not supported everywhere - but on Linux there are, with some limitations.</p> <p>=== This is a brief explanation that you don't need ;-) ===</p> <p>What PIC does, is that it makes code position independent. Each shared library is loaded at some position in memory - for security reasons this place is often randomized - and thus "absolute" memory references in the code can't really be "absolute" - in fact they are relative to the library's memory segment start address. After the library is loaded, they have to be adjusted.</p> <p>This can be done by walking all of them (their addresses will be stored in the file header) and corrected. But this is slow, and "corrected" image can't be shared between processes if the base address is different.</p> <p>Thus a different method is usually used. Each reference to a memory is done via a special register (usually ebx). When a function is called, at the start it jumps to a special code block that adjusts ebx value to the library's memory segment address. Then the function access its data using [ebx + know offset].</p> <p>So for each program only this code block have to be adjusted, not every function and memory reference. </p> <p>Notice that if function is know to be called from the same shared library's other function, the compiler/linker can omit PIC register (ebx) adjustment, because it is known to already have the correct value. In some architectures (most notably x86_64) programs can access data relative to the IP (current instruction pointer), which is already absolute-adjusted and thus it elimitates the need for a special register like ebx and its adjustment.</p> <p>=== Here is the end of the section that can be skipped without reading ===</p> <p>So why would you want to build something without PIC?</p> <p>Well, first of all it slows down you program by few percents, because at the start of each function an additional code is run to adjust register, and a precious register is not available for the optimizer (x86 only). Often function can't know if it's called from same library or from another, and thus even internal calls suffer from the penalty. So if you want to optimized for speed - try to compile without PIC.</p> <p>Then, the code size is a bit bigger, as you noticed, because each function will contain a few more instructions to setup PIC register.</p> <p>This can be avoid to some degree if we use Link-time optimization (--lto switch) and protected functions visibility so that compiler knows which functions are not called externally at all and thus they do not need PIC code. But I haven't tried that (yet).</p> <p>And why would you want to use PIC? Because it's more secure (this is required for address space randomization); because not all systems support non-PIC libs; because startup load time may be slower for non-PIC libs (the whole code segment have to be adjusted to absolute addresses instead of just table stubs); and loaded library segments can't be shared if they are loaded into different space (i.e. it may cause more memory used). Then, not all compiler/linker flags are compatible with non-PIC libraries (from what I remember there's something about thread-local support) so sometimes you won't be able to build non-PIC code at all.</p> <p>So non-PIC code is a bit riskier (less secure) and you can't get it always, but if you need it (e.g. for speed) - why not.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload