Position of independent code: what's the difference at compile time?

Reading through libtool docs I wondered why we need to tell the compiler to generate position-independent code. After all, the generated object file doesn't yet know where in the address space it will be linked, so one object file should always remain position-independent, right? And besides, for creating shared libs, it doesn't mean that it just means baking all the object files that make up that library, and possibly setting all the relative references that became "trainees" into the baked-together library, leaving everything else links (absolute and relative) to be populated later by the linker-loader? Why is this a concern for the compiler too?

+3


source to share


1 answer


I wondered why we need to tell the compiler to generate position-independent code. After all, the generated object file does not yet know where in the address space it will be linked, so one object file must be position independent at all times, right?

When you tell your compiler to create position independent code (PIC), it is completely different from a compiler that produces non-PIC, mainly in terms of function and data access. The reason for using PIC is to avoid buffer overflow or code rewriting that occurs when someone enters multiple lines of code into the address space of your application, mostly written in low-level languages ​​like C / C ++, because by default C / C ++ does not check boundaries.

It uses an indirect method to access data and functions using the Global Offset Table (GOT). This GOT is usually found in a special machine registry. The main advantage of using this table is that code generation is independent of the actual load address. At runtime, it will update the offsets in the table based on the current load address of the required libraries.

When the compiler creates an object file (.lo in PIC), it loads the object at an arbitrary address unchanged, and even if the object's load address is fixed for some ABI, it will load each required library in random order. The generated object file does not know where in the address space it will be linked to, namely that the PIC wants to make sure that the fixed address is not fixed, which could compromise the security of the application if an attacker finds this address.



And besides, for creating shared libs, it doesn't mean that it just means baking all the object files that highlight that library and possibly set all the relative links that become "trainees" for the baked-together lib, all the rest do links (absolute and relative) have to be filled in later by the linker-loader? Why is this a concern for the compiler too?

In the case of a shared library libtool, when it sees the PIC flag set in the preprocessor, it automatically creates an object file for the shared libraries. They did not become "trainees" because shared libraries can be located anywhere in the memory layout of a process, and are accessed indirectly through some flags set at creation.

Wiki: http://en.wikipedia.org/wiki/Position-independent_code

Gentoo: http://wiki.gentoo.org/wiki/Project:Hardened

+2


source







All Articles