5

I'm adding a thread local variable to a couple of object files that are always linked directly to executables. These objects will never be included inside a shared library (and it's safe to assume this will hold true for the foreseeable future). This means the -fPIC flag is not required for these objects, correct?

Our codebase has the -fPIC flag for all objects by default. Many of these are included in shared libraries so the use of -fPIC makes sense. However, this flag presents an issue debugging the new thread local variable because GDB crashes while stepping over thread local variable with -fPIC. If I remove -fPIC from those few object files with the new thread local variable, I can debug properly.

I can't find any authoritative statements that mixing non-PIC objects with PIC objects in an executable is okay. My testing thus far shows it's okay, but it does not feel kosher, and online discussion is generally "do not mix PIC and non PIC" due to the shared library case.

Is it safe to link non PIC objects into an executable built with PIC objects and libraries in this case? Maybe there is an authoritative statement from GCC docs on this being safe, but I cannot find it.

EDIT: Binary patching gcc to avoid this bug is not a solution in the short-term. Switching compiler on Linux is not a possible solution.

Community
  • 1
  • 1
Kizaru
  • 2,443
  • 3
  • 24
  • 39
  • I think this should be fine. Mixing `-fPIC` code with non-PIC code in an executable has the downsides of PIC (extra indirection for globals / functions), but the executable is not PIC. So you'd get a more efficient executable by building PIC objects for your shared libraries, then re-compiling the same source without PIC for the version that's going to go in a non-PIC binary. Note that position-independent executables are a thing, and OS X requires it for x86-64, but Linux/Windows don't. It would allow address-space layout randomization even for executables, not just libs. – Peter Cordes Apr 06 '16 at 20:15
  • Not posting this as an answer, because it's not something I've tried. I understand how PIC works in terms of the asm output, but I may be overlooking something. – Peter Cordes Apr 06 '16 at 20:17

2 Answers2

4

Except for Bugs like the above it should be fine. I cant deliver you references to definitive documents describing this, but only speak from experience. gcc (or the assembler) will produce different code when you specify -fPIC, but the resulting code still uses standardized relocation symbols. For linking pieces together, this doesnt matter at first, a linker will just stubbornly string everything together and doesnt know whether the code denotes PIC on non-PIC code. I know this because I work with systems which dont support shared libraries, and I had to wrap my own loaders.

The final point tough, is that you can tell the linker if the resulting object should be a shared library or not. Only then will the linker generate some (OS-specific) Structures and symbols to denote im-/exports. Otherwise the linker will just finish its work, the primary difference is that missing symbols will result in an error.

The clean separation between Compiler + Linker should guarantee that the flags should not matter (outside of performance differences). I would be careful with LTO tough, this had several problems with different compiler-settings in the past.

As said, I spent some time investigating this and red several docs about ELF and dynamic loaders. You will find an explicit mention of linking PIC/non-PIC nowhere, but the linking process really doesn`t care about the compiler-settings for the inputs, valid code will stay valid code.

If you want to link non-PIC code to a shared library (PIC), the linker will quit if absolute relocation`s are encountered (which is very likely). If you want to link any code to a program, you are only limited to what the final program can deal with. On a OS supporting PIC you can use anything, otherwise the linker might complain about missing symbols or unsupported sections/relocation types.

Norbert Lange
  • 1,162
  • 1
  • 10
  • 15
0

It is possible almost always, but sometimes it requires some tricks

vitaly.v.ch
  • 2,485
  • 4
  • 26
  • 36