fix(relinker): map executable section addresses through load segments
This commit is contained in:
parent
5edae35361
commit
7ea423f78b
|
|
@ -1,5 +1,7 @@
|
|||
#include <elfpatcher/general/SectionHeaderTableBuilder.hpp>
|
||||
#include <elfpatcher/general/ElfConstants.hpp>
|
||||
#include <io/BufferUtils.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Elfpatcher {
|
||||
|
||||
|
|
@ -38,6 +40,21 @@ void SectionHeaderTableBuilder::WriteTable(
|
|||
std::vector<std::uint8_t>& buf,
|
||||
const SectionHeaderTableRequest& request
|
||||
) const {
|
||||
const auto phOffset = Io::ReadU64(buf, kEhdrPhOffOffset);
|
||||
const auto phCount = Io::ReadU16(buf, kEhdrPhNumOffset);
|
||||
const auto phStride = Io::ReadU16(buf, kEhdrPhEntSizeOffset);
|
||||
const auto mappedAddress = [&](std::uint64_t offset) {
|
||||
for (std::uint16_t index = 0; index < phCount; ++index) {
|
||||
const auto header = phOffset + index * phStride;
|
||||
if (Io::ReadU32(buf, header) != PT_LOAD) continue;
|
||||
const auto start = Io::ReadU64(buf, header + 8);
|
||||
const auto size = Io::ReadU64(buf, header + 32);
|
||||
if (offset >= start && offset - start < size)
|
||||
return Io::ReadU64(buf, header + 16) + offset - start;
|
||||
}
|
||||
throw std::runtime_error("Allocated output section is outside load segments");
|
||||
};
|
||||
|
||||
const auto shStrTabOff = static_cast<std::uint64_t>(buf.size());
|
||||
constexpr std::uint64_t shStrTabSize = sizeof(kShStrTabBlob);
|
||||
for (const char i : kShStrTabBlob)
|
||||
|
|
@ -48,10 +65,10 @@ void SectionHeaderTableBuilder::WriteTable(
|
|||
|
||||
_writeSectionHeader(buf, shOff + kShdrEntrySize * 0, 0, SHT_NULL, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
_writeSectionHeader(buf, shOff + kShdrEntrySize * 1, kShStrTabNameOffset, SHT_STRTAB, 0, shStrTabOff, shStrTabOff, shStrTabSize, 0, 0, kNoSpecialAlignment, 0);
|
||||
_writeSectionHeader(buf, shOff + kShdrEntrySize * 2, kDynStrNameOffset, SHT_STRTAB, SHF_ALLOC, request.DynStrOffset, request.DynStrOffset, request.DynStrSize, 0, 0, kNoSpecialAlignment, 0);
|
||||
_writeSectionHeader(buf, shOff + kShdrEntrySize * 3, kDynSymNameOffset, SHT_DYNSYM, SHF_ALLOC, request.DynSymOffset, request.DynSymOffset, request.DynSymSize, kDynSymLinkToStrTab, kDynSymInfoFirstGlobal, kDynSymAlign, kSymEntrySize);
|
||||
_writeSectionHeader(buf, shOff + kShdrEntrySize * 4, kDynamicNameOffset, SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE, request.DynamicSegmentOffset, request.DynamicSegmentOffset, request.DynamicSegmentSize, kDynamicLinkToStrTab, 0, kDynSymAlign, kDynEntrySize);
|
||||
_writeSectionHeader(buf, shOff + kShdrEntrySize * 5, kTextNameOffset, SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, request.StubOffset, request.StubOffset, request.StubSize, 0, 0, kNoSpecialAlignment, 0);
|
||||
_writeSectionHeader(buf, shOff + kShdrEntrySize * 2, kDynStrNameOffset, SHT_STRTAB, SHF_ALLOC, mappedAddress(request.DynStrOffset), request.DynStrOffset, request.DynStrSize, 0, 0, kNoSpecialAlignment, 0);
|
||||
_writeSectionHeader(buf, shOff + kShdrEntrySize * 3, kDynSymNameOffset, SHT_DYNSYM, SHF_ALLOC, mappedAddress(request.DynSymOffset), request.DynSymOffset, request.DynSymSize, kDynSymLinkToStrTab, kDynSymInfoFirstGlobal, kDynSymAlign, kSymEntrySize);
|
||||
_writeSectionHeader(buf, shOff + kShdrEntrySize * 4, kDynamicNameOffset, SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE, mappedAddress(request.DynamicSegmentOffset), request.DynamicSegmentOffset, request.DynamicSegmentSize, kDynamicLinkToStrTab, 0, kDynSymAlign, kDynEntrySize);
|
||||
_writeSectionHeader(buf, shOff + kShdrEntrySize * 5, kTextNameOffset, SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, mappedAddress(request.StubOffset), request.StubOffset, request.StubSize, 0, 0, kNoSpecialAlignment, 0);
|
||||
|
||||
_byteWriter->WriteU64(buf, kEhdrShOffOffset, shOff);
|
||||
_byteWriter->WriteU16(buf, kEhdrShEntSizeOffset, static_cast<std::uint16_t>(kShdrEntrySize));
|
||||
|
|
|
|||
Loading…
Reference in New Issue