Kernel (elf.c):
- Skip R_386_JMP_SLOT relocations when PT_INTERP present (let ld.so resolve lazily)
- Load DT_NEEDED shared libraries at SHLIB_BASE (0x11000000)
- Support ET_EXEC and ET_DYN interpreters with correct base offset
- Fix AT_PHDR auxv computation for PIE binaries
- Store auxv in static buffer for execve to push in correct stack position
- Use pmm_alloc_page() instead of restrictive low-16MB allocator
Execve (syscall.c):
- Push auxv entries right after envp[] (Linux stack layout convention)
so ld.so can find them by walking argc → argv[] → envp[] → auxv
ld.so (ldso.c):
- Complete rewrite for lazy PLT/GOT binding
- Parse auxv (AT_ENTRY, AT_PHDR, AT_PHNUM, AT_PHENT)
- Find PT_DYNAMIC, extract DT_PLTGOT/DT_JMPREL/DT_PLTRELSZ/DT_SYMTAB/DT_STRTAB
- Set GOT[1]=link_map, GOT[2]=_dl_runtime_resolve trampoline
- Implement _dl_runtime_resolve asm trampoline + dl_fixup C resolver
- Symbol lookup in shared library via DT_HASH at SHLIB_BASE
- Compiled as non-PIC ET_EXEC at INTERP_BASE (0x12000000)
VMM (vmm.c):
- Use pmm_alloc_page() for page table allocation (PAE PTs can be anywhere)
Test infrastructure:
- PIE test binary (pie_main.c) calls test_add() from libpietest.so via PLT
- Shared library (pie_func.c) provides test_add()
- Smoke test patterns for lazy PLT OK + PLT cached OK
- 80/83 smoke tests pass, cppcheck clean