关于启用虚拟内存时仍需使用PIC可执行文件的技术疑问
Great question—this is a super common point of confusion because virtual memory makes it seem like each process has free rein over the entire address space. Let’s break down why position-independent code (PIC) still matters, even with paging doing its thing:
1. Shared Libraries: The Biggest Reason
Virtual memory gives each process its own isolated address space, but shared libraries are built to be reused across multiple processes. If a shared library wasn’t PIC, every process that loaded it would need its own modified copy in memory—because the loader would have to rewrite all hardcoded absolute addresses in the library to match the process’s specific virtual address space.
PIC avoids this waste by using relative offsets for code references and structures like the Global Offset Table (GOT) for data access. That means a single copy of the PIC library lives in physical memory, and all processes sharing it just map that same physical page into their own virtual address spaces. It’s a massive win for memory efficiency.
2. Faster Program Startup
Non-PIC executables (or libraries) require the loader to do relocation work at launch: scanning through the code and adjusting every fixed absolute address to point to the correct spot in the process’s virtual memory. For large programs or those using dozens of shared libraries, this adds noticeable overhead.
PIC skips most of this busywork. The code itself doesn’t rely on fixed addresses, so the loader only needs to set up a few global data structures (like the GOT) instead of rewriting chunks of code. This makes program launch faster, especially on systems running lots of processes.
3. ASLR Compatibility (Security)
Address Space Layout Randomization (ASLR) is a critical security feature that randomly shuffles where code, data, and libraries live in a process’s virtual address space. This makes it way harder for attackers to exploit vulnerabilities like buffer overflows, since they can’t predict where critical code or data is located.
Non-PIC code breaks ASLR because it depends on fixed absolute addresses. If the loader randomizes the base address of a non-PIC executable, the code will try to access the wrong memory locations and crash. PIC, by contrast, doesn’t care where it’s loaded—so ASLR can do its security job without breaking the program.
4. Edge Cases Without Full Virtual Memory
While your question focuses on systems with virtual memory, it’s worth mentioning that PIC is essential for environments without paging (like small embedded systems or real-time operating systems). In these cases, there’s no MMU to handle address translation, so code needs to run correctly no matter where it’s loaded in physical memory.
To circle back to your original thought: You’re totally right that virtual memory handles per-process address isolation and page-level relocation. But PIC solves problems that virtual memory doesn’t touch—like efficient shared library reuse, faster loading, security via ASLR, and compatibility with memory-constrained systems.
内容的提问来源于stack exchange,提问作者Trey

