From bde680c855263f27d7c93152961b0de0bab13142 Mon Sep 17 00:00:00 2001 From: Ondra97 <47064087+Ondra97@users.noreply.github.com> Date: Mon, 12 Oct 2026 21:40:28 +0200 Subject: [PATCH] fix(relinker): map standalone RELRO in unused import filtering --- .../UnusedNidFilter/EntryPointCollector.cpp | 9 +++--- .../RelativeRelocationIndex.cpp | 11 +++---- .../relinker/tests/StrictNidFilterTests.cpp | 2 ++ .../relinker/relinker/tests/test_sce_relro.py | 32 +++++++++++++++++++ docs/dev/debt/relinker.md | 2 +- 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/core/relinker/relinker/src/analysis/UnusedNidFilter/EntryPointCollector.cpp b/core/relinker/relinker/src/analysis/UnusedNidFilter/EntryPointCollector.cpp index 8e87a10d8..e95afa383 100644 --- a/core/relinker/relinker/src/analysis/UnusedNidFilter/EntryPointCollector.cpp +++ b/core/relinker/relinker/src/analysis/UnusedNidFilter/EntryPointCollector.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -75,11 +76,9 @@ public: if (phEntSize < 56) throw RelinkerException("ELF program header entry too small"); std::vector loads; - for (std::uint16_t i = 0; i < phCount; ++i) { - std::size_t phPos = static_cast(phOff) + i * phEntSize; - if (phPos + 56 > elfBytes.size()) throw RelinkerException("Program header out of bounds"); - if (read32(elfBytes, phPos) != PT_LOAD) continue; - loads.push_back({read64(elfBytes, phPos + 16), read64(elfBytes, phPos + 8), read64(elfBytes, phPos + 32)}); + for (const auto& header : ElfReader(elfBytes).ReadProgramHeaders()) { + if (header.Type != PT_LOAD) continue; + loads.push_back({header.MappedAddress, header.Offset, header.FileSize}); } for (std::uint16_t i = 0; i < phCount; ++i) { diff --git a/core/relinker/relinker/src/analysis/UnusedNidFilter/RelativeRelocationIndex.cpp b/core/relinker/relinker/src/analysis/UnusedNidFilter/RelativeRelocationIndex.cpp index 39de6fdf6..1d0be749b 100644 --- a/core/relinker/relinker/src/analysis/UnusedNidFilter/RelativeRelocationIndex.cpp +++ b/core/relinker/relinker/src/analysis/UnusedNidFilter/RelativeRelocationIndex.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -147,12 +148,10 @@ std::unique_ptr BuildRelativeRelocationIndex( hasSceDynlibData = true; sceTableBase = read64(elfBytes, phPos + 8); } - if (type != PT_LOAD) continue; - LoadSegment seg; - seg.fileOffset = read64(elfBytes, phPos + 8); - seg.vaddr = read64(elfBytes, phPos + 16); - seg.fileSize = read64(elfBytes, phPos + 32); - loads.push_back(seg); + } + for (const auto& header : ElfReader(elfBytes).ReadProgramHeaders()) { + if (header.Type != PT_LOAD) continue; + loads.push_back({header.MappedAddress, header.Offset, header.FileSize}); } std::unordered_map targets; diff --git a/core/relinker/relinker/tests/StrictNidFilterTests.cpp b/core/relinker/relinker/tests/StrictNidFilterTests.cpp index 487839560..b39ffb6c9 100644 --- a/core/relinker/relinker/tests/StrictNidFilterTests.cpp +++ b/core/relinker/relinker/tests/StrictNidFilterTests.cpp @@ -397,7 +397,9 @@ void relativeRelocationTableBounds() { bytes[6] = 1; write(bytes, 16, 3); write(bytes, 18, 62); + write(bytes, 20, 1); write(bytes, 32, 64); + write(bytes, 52, 64); write(bytes, 54, 56); write(bytes, 56, 2); diff --git a/core/relinker/relinker/tests/test_sce_relro.py b/core/relinker/relinker/tests/test_sce_relro.py index bcb878337..51de2a095 100644 --- a/core/relinker/relinker/tests/test_sce_relro.py +++ b/core/relinker/relinker/tests/test_sce_relro.py @@ -1,3 +1,4 @@ +import json import os from pathlib import Path import struct @@ -41,6 +42,29 @@ def relink(relinker, work, name, image, options): return result, output +def filtered_fixture(extra, lifecycle): + image = fixture(extra) + if not lifecycle: + image[0x1100:0x1118] = image[0x700:0x718] + struct.pack_into("