diff --git a/core/elfpatcher/include/elfpatcher/general/IProgramHeaderLayoutBuilder.hpp b/core/elfpatcher/include/elfpatcher/general/IProgramHeaderLayoutBuilder.hpp index 27972ef47..75b2ae1e1 100644 --- a/core/elfpatcher/include/elfpatcher/general/IProgramHeaderLayoutBuilder.hpp +++ b/core/elfpatcher/include/elfpatcher/general/IProgramHeaderLayoutBuilder.hpp @@ -11,7 +11,7 @@ namespace Elfpatcher { public: virtual ~IProgramHeaderLayoutBuilder() = default; - virtual std::uint64_t ComputeExtraBlockVaddr(const std::vector& originalHeaders) const = 0; + virtual std::uint64_t ComputeExtraBlockVaddr(const std::vector& originalHeaders, std::uint64_t extraBlockOffset) const = 0; virtual std::uint16_t WriteLayout(std::vector& buf, const ProgramHeaderLayoutRequest& request) const = 0; }; diff --git a/core/elfpatcher/include/elfpatcher/general/ProgramHeaderLayoutBuilder.hpp b/core/elfpatcher/include/elfpatcher/general/ProgramHeaderLayoutBuilder.hpp index 8a5c72cd4..fcff63757 100644 --- a/core/elfpatcher/include/elfpatcher/general/ProgramHeaderLayoutBuilder.hpp +++ b/core/elfpatcher/include/elfpatcher/general/ProgramHeaderLayoutBuilder.hpp @@ -15,7 +15,7 @@ namespace Elfpatcher { std::shared_ptr byteWriter ); - std::uint64_t ComputeExtraBlockVaddr(const std::vector& originalHeaders) const override; + std::uint64_t ComputeExtraBlockVaddr(const std::vector& originalHeaders, std::uint64_t extraBlockOffset) const override; std::uint16_t WriteLayout( std::vector& buf, diff --git a/core/elfpatcher/src/general/ProgramHeaderLayoutBuilder.cpp b/core/elfpatcher/src/general/ProgramHeaderLayoutBuilder.cpp index 76ca7c672..2be7bc93c 100644 --- a/core/elfpatcher/src/general/ProgramHeaderLayoutBuilder.cpp +++ b/core/elfpatcher/src/general/ProgramHeaderLayoutBuilder.cpp @@ -96,7 +96,8 @@ std::uint32_t ProgramHeaderLayoutBuilder::_fixLoadFlags(std::uint32_t originalFl } std::uint64_t ProgramHeaderLayoutBuilder::ComputeExtraBlockVaddr( - const std::vector& originalHeaders + const std::vector& 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; diff --git a/core/elfpatcher/src/linux/LinuxElfPatcher.cpp b/core/elfpatcher/src/linux/LinuxElfPatcher.cpp index 7762d5872..1ee380a03 100644 --- a/core/elfpatcher/src/linux/LinuxElfPatcher.cpp +++ b/core/elfpatcher/src/linux/LinuxElfPatcher.cpp @@ -73,7 +73,7 @@ std::vector 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)