Merge pull request #1238 from hashaam1217/fix/windows-overlapping-load-segments
fix(relinker): reject overlapping PT_LOAD segments before sizing the Windows image
This commit is contained in:
commit
296d68a31d
|
|
@ -28,15 +28,16 @@ WindowsLoadImage::WindowsLoadImage(const std::vector<std::uint8_t>& source, cons
|
|||
throw Domain::RelinkerException("No PT_LOAD segments found");
|
||||
std::sort(segments.begin(), segments.end(), [](const auto& left, const auto& right) { return left.MappedAddress < right.MappedAddress; });
|
||||
firstAddress = segments.front().MappedAddress & ~static_cast<std::uint64_t>(SectionAlignment - 1);
|
||||
const auto end = segments.back().MappedAddress + segments.back().MemorySize;
|
||||
std::uint64_t end = firstAddress;
|
||||
for (const auto& segment : segments) {
|
||||
if (segment.MappedAddress < end)
|
||||
throw Domain::RelinkerException("Overlapping PT_LOAD memory ranges", segment.MappedAddress);
|
||||
end = segment.MappedAddress + segment.MemorySize;
|
||||
}
|
||||
data.resize(AlignRva(end - firstAddress));
|
||||
CheckedRva(LoadRva + static_cast<std::uint64_t>(data.size()));
|
||||
pageFlags.resize(data.size() / SectionAlignment);
|
||||
std::uint64_t previousEnd = firstAddress;
|
||||
for (const auto& segment : segments) {
|
||||
if (segment.MappedAddress < previousEnd)
|
||||
throw Domain::RelinkerException("Overlapping PT_LOAD memory ranges", segment.MappedAddress);
|
||||
previousEnd = segment.MappedAddress + segment.MemorySize;
|
||||
const auto offset = static_cast<std::size_t>(segment.MappedAddress - firstAddress);
|
||||
std::copy_n(source.begin() + static_cast<std::ptrdiff_t>(segment.Offset), static_cast<std::size_t>(segment.FileSize), data.begin() + static_cast<std::ptrdiff_t>(offset));
|
||||
std::uint32_t flags = 0;
|
||||
|
|
|
|||
|
|
@ -77,6 +77,16 @@ def main():
|
|||
|
||||
result, output = run_case(relinker, work, "strict", ["unused-filter=2"], b"\x90\xc3")
|
||||
assert result.returncode == 2 and "multiple executable segments" in result.stderr and not output.exists(), result
|
||||
|
||||
for name, memory_size in (("overlap-past-end", 0x10000000000000), ("overlap-next", 0x1300)):
|
||||
image = fixture(b"\x90\xc3")
|
||||
struct.pack_into("<Q", image, 64 + 40, memory_size)
|
||||
source = work / (name + ".elf")
|
||||
output = work / (name + ".exe")
|
||||
source.write_bytes(image)
|
||||
result = subprocess.run([str(relinker), "--skip-sce-module", "--windows", str(source), str(output)],
|
||||
capture_output=True, text=True, timeout=20)
|
||||
assert result.returncode == 2 and "Overlapping PT_LOAD memory ranges" in result.stderr and not output.exists(), (name, result)
|
||||
print("Executable segment tests passed")
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue