Repository navigation
feat(relinker): load Linux executables at a fixed base - #4593
Conversation
|
The overlap check on #4140 lists this PR. The two only touch the same lines: both add an option to |
5e6b74b to
03dd25f
Compare
|
Rebased onto More from Ruffle (PPSA68091) with
|
|
Tested on Linux with PPSA15304 (engine: Unreal Engine 5), a second case besides #4013 that needs the console's load address. Its bundled
|
|
Thanks @ee6aba54, that's a good second case. It also exercises a base above 4 GiB ( |
|
Rebased onto |
66b3c81 to
c25a578
Compare
|
XPSemu (PPSA97358), the third title in #4013, on Linux (headless): on |
|
Rebased onto current Checked: relinker + libkernel build and 263/263 ctest ( |
c25a578 to
3d101e8
Compare
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
|
What
Linux side of #4013, the counterpart of #4140's
--windows-fixed-base. Ruffle (PPSA68091), VLC (PPSA85300) and XPSemu (PPSA97358) read GOT slots atoffset + 0x400000, where each offset comes fromapp0/imports.txt, so they assume the console's load address. The relinked Linux executable is a PIE loaded at0x555555554000, and the first read faults.The relinker option.
relinker --linux-fixed-base <address>writes the executable asET_EXECand adds the address to every virtual address it holds, so virtual address 0 lands at the address, as on the console:PT_NULLandPT_GNU_STACK;DT_STRTAB,DT_SYMTAB,DT_HASH,DT_RELA,DT_JMPREL,DT_PLTGOT);R_X86_64_RELATIVEandR_X86_64_IRELATIVE, whichld.sono longer adds a load bias to;SHN_ABSandSTT_TLSsymbols stay unchanged.It throws instead of writing an image that would not load:
RELATIVEtarget below the image;DT_NEEDEDin the executable's dependency table;PT_LOADalignment;The CLI takes a 64 KiB-aligned address from
0x10000through0x7fffffff0000, in decimal or hexadecimal, and rejects the option with--windows,--macosor--lazy-binding. Lazy binding would need the PLT slots' initial contents rebased, and it is deprecated. Bundled guest modules keep their normal placement. Without the option the output is unchanged: the DOOM catalog executable relinks byte for byte the same as withmain's relinker.The libkernel fix.
dlsymin the default scope recognized the main program by comparingdladdr'sdli_fbasewithdl_iterate_phdr'sdlpi_addr. For anET_EXECimage these differ:dlpi_addris 0 anddli_fbaseis the image's first page, so symbols of a non-PIE executable were not found. It now compares link maps, taken fromdladdr1(RTLD_DL_LINKMAP)anddlinfo(dlopen(NULL), RTLD_DI_LINKMAP).Tested
Linux (Ubuntu, GCC, Release, NVIDIA RTX 2080 SUPER) on
maind592d54:sce_module/libc.prxunwrapped:main:SIGSEGVatcmpq $0x0,0x400000(%rax),rax= 0x24d5370, as in Ruffle, VLC and XPSemu read their GOT at a fixed 0x400000 base from app0/imports.txt and fault once all imports load #4013.--registry --linux-fixed-base 0x400000: the output isET_EXECwith entry 0x2d8ecd0 (0x298ecd0 + 0x400000). The import check passes, and the title opens VideoOut, builds its shaders and renders, then stops at an unrelated AGC limit:only normal color rendering with copy ROP is supported (CB_COLOR_CONTROL 0x00cc0050, mode FMASK decompress).linux_fixed_basetest:0x400000 + entryand that itsRELATIVEslot holds that address (SIGTRAPon success);RELATIVEtarget.linux_executable_exportsnow also runs at a fixed base, wheredlsym(RTLD_DEFAULT)from a needed library resolves an executable export. Without the symbol rebasing it fails withSIGSEGV.guest_dynamic_loader_fixed_base:GuestDynamicLoader.cppbuilt with-no-pie. Before the libkernel fix it aborts (sceKernelDlsym(0, GuestDefaultScopeOnly)misses the executable symbol); after the fix it passes.cli_argscovers parsing, the range, alignment, malformed values, repetition and the conflicts.check_conventions.pyandcheck_test_registration.pypass.linux_fixed_base,guest_dynamic_loader_fixed_base,linux_executable_exportsandcli_argspass on Linux. The branch merges cleanly onto currentmain2a5eca1.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)