fix(patcher): preserve offset alignment for extra block vaddr

This commit is contained in:
boykopovar 2026-08-18 19:04:48 +03:00
parent 201c4f1d44
commit 4147ca1f4c
4 changed files with 10 additions and 5 deletions

View File

@ -11,7 +11,7 @@ namespace Elfpatcher {
public:
virtual ~IProgramHeaderLayoutBuilder() = default;
virtual std::uint64_t ComputeExtraBlockVaddr(const std::vector<Domain::ProgramHeader>& originalHeaders) const = 0;
virtual std::uint64_t ComputeExtraBlockVaddr(const std::vector<Domain::ProgramHeader>& originalHeaders, std::uint64_t extraBlockOffset) const = 0;
virtual std::uint16_t WriteLayout(std::vector<std::uint8_t>& buf, const ProgramHeaderLayoutRequest& request) const = 0;
};

View File

@ -15,7 +15,7 @@ namespace Elfpatcher {
std::shared_ptr<Io::IByteWriter> byteWriter
);
std::uint64_t ComputeExtraBlockVaddr(const std::vector<Domain::ProgramHeader>& originalHeaders) const override;
std::uint64_t ComputeExtraBlockVaddr(const std::vector<Domain::ProgramHeader>& originalHeaders, std::uint64_t extraBlockOffset) const override;
std::uint16_t WriteLayout(
std::vector<std::uint8_t>& buf,

View File

@ -96,7 +96,8 @@ std::uint32_t ProgramHeaderLayoutBuilder::_fixLoadFlags(std::uint32_t originalFl
}
std::uint64_t ProgramHeaderLayoutBuilder::ComputeExtraBlockVaddr(
const std::vector<Domain::ProgramHeader>& originalHeaders
const std::vector<Domain::ProgramHeader>& originalHeaders,
std::uint64_t extraBlockOffset
) const {
bool foundLoad = false;
std::uint64_t highestVaddrEnd = 0;
@ -114,7 +115,11 @@ std::uint64_t ProgramHeaderLayoutBuilder::ComputeExtraBlockVaddr(
throw Domain::RelinkerException("No kept PT_LOAD segment to anchor the extra block against");
const std::uint64_t align = kDefaultLoadAlignment;
const std::uint64_t vaddr = (highestVaddrEnd + align - 1) & ~(align - 1);
const std::uint64_t offsetRemainder = extraBlockOffset & (align - 1);
const std::uint64_t alignedFloor = highestVaddrEnd & ~(align - 1);
std::uint64_t vaddr = alignedFloor | offsetRemainder;
if (vaddr < highestVaddrEnd)
vaddr += align;
if (vaddr < highestVaddrEnd)
throw Domain::RelinkerException("Extra block vaddr computation overflowed");
return vaddr;

View File

@ -73,7 +73,7 @@ std::vector<std::uint8_t> LinuxElfPatcher::Patch(
_byteWriter->AppendU64(buf, 0);
const std::uint64_t extraBlockOff = dynStrOff;
const std::uint64_t extraBlockVaddr = _programHeaderLayoutBuilder->ComputeExtraBlockVaddr(originalHeaders);
const std::uint64_t extraBlockVaddr = _programHeaderLayoutBuilder->ComputeExtraBlockVaddr(originalHeaders, extraBlockOff);
const auto vaddrOfExtraBlockOffset = [extraBlockOff, extraBlockVaddr](std::uint64_t fileOffset) -> std::uint64_t {
if (fileOffset < extraBlockOff)