mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-23 09:03:22 -05:00
Merge pull request #7782 from parl0v/fix/unwrap-self-unstored-version-segment
fix(tools): unwrap SELF dumps that leave out the version segment
This commit is contained in:
2 files changed
+32
-2
No files matched your search
@@ -168,6 +168,31 @@ class UnwrapTest(unittest.TestCase):
|
||||
self.assertEqual(data[version[2]:version[2] + version[5]], pattern(13, 0x10))
|
||||
self.assertEqual(note[5], 0)
|
||||
|
||||
def test_a_version_segment_the_container_does_not_store_is_emitted_without_file_bytes(self):
|
||||
segments = default_segments() + [(SCE_COMMENT, 4, 0x15A0, 0x0, 0x20, 0x10), (PT_NOTE, 4, 0x15C0, 0x0, 0x18, 4),
|
||||
(SCE_VERSION, 4, 0x15D8, 0x0, 0x10, 0x10)]
|
||||
records = default_records() + [(0x410004, 0xA80, 0x20), (0x302804, 0xAA0, 0x20)]
|
||||
for stored in (0, 8):
|
||||
with self.subTest(stored=stored):
|
||||
payloads = dict(default_payloads())
|
||||
payloads[0xAA0] = pattern(11, 0x20)
|
||||
if stored:
|
||||
payloads[0xAC0] = pattern(13, stored)
|
||||
container = build_container(segments, records, payloads)
|
||||
self.assertEqual(len(container), 0xAC0 + stored)
|
||||
result, output = self.convert(container)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
data, headers = read_program_headers(output)
|
||||
loads = [header for header in headers if header[0] == PT_LOAD]
|
||||
self.assertEqual(data[loads[0][2]:loads[0][2] + loads[0][5]], pattern(1, 0x100))
|
||||
self.assertEqual(data[loads[1][2]:loads[1][2] + loads[1][5]], pattern(9, 0x80))
|
||||
comment = [header for header in headers if header[0] == SCE_COMMENT][0]
|
||||
self.assertEqual(data[comment[2]:comment[2] + comment[5]], pattern(11, 0x20))
|
||||
version = [header for header in headers if header[0] == SCE_VERSION][0]
|
||||
self.assertEqual((version[2], version[5]), (0, 0))
|
||||
for header in headers:
|
||||
self.assertLessEqual(header[2] + header[5], len(data))
|
||||
|
||||
def test_declared_offsets_are_used_when_the_container_has_no_records(self):
|
||||
segments = [(PT_LOAD, 1, 0x800, 0x0, 0x40, 0x1000), (PT_LOAD, 4, 0x900, 0x1000, 0x40, 0x1000)]
|
||||
payloads = {0x800: pattern(3, 0x40), 0x900: pattern(5, 0x40)}
|
||||
|
||||
@@ -14,8 +14,10 @@ differ inside a container:
|
||||
mapping of the PT_LOAD that contains them. Segments without a vaddr that
|
||||
follow the last recorded one in the ELF are stored right after it, back to
|
||||
back in ELF order, except a PT_NOTE, which the container leaves out and which
|
||||
is emitted without file bytes. Other segments without a vaddr carry the shift
|
||||
of the last placed one.
|
||||
is emitted without file bytes. Some dumps end right after the recorded ones
|
||||
and leave out the version segment as well, so one that would run past the
|
||||
end of the file is emitted without file bytes too. Other segments without a
|
||||
vaddr carry the shift of the last placed one.
|
||||
- The segments are packed without honouring p_align, while ELF requires
|
||||
p_offset % p_align == p_vaddr % p_align. Every region is copied to an offset
|
||||
that satisfies it, which the relinker enforces on guest modules.
|
||||
@@ -156,6 +158,9 @@ def place_segments(data, headers, records):
|
||||
continue
|
||||
header["source"] = cursor
|
||||
cursor += header["size"]
|
||||
if cursor > len(data):
|
||||
header["source"] = 0
|
||||
header["size"] = 0
|
||||
for header in loads:
|
||||
if header["size"] == 0 or header["index"] in placed:
|
||||
continue
|
||||
|
||||
Reference in new issue
Block a user