fix(header): fix read section headers
This commit is contained in:
parent
4d8fc76ff7
commit
340a321cbe
|
|
@ -14,6 +14,7 @@ public:
|
|||
ElfHeader ReadHeader() const override;
|
||||
std::vector<ProgramHeader> ReadProgramHeaders() const override;
|
||||
std::vector<SectionHeader> ReadSectionHeaders() const override;
|
||||
std::vector<DynamicTag> ReadDynamicTags(const ProgramHeader& dynamicHeader) const override;
|
||||
std::vector<std::uint8_t> ReadSection(const SectionHeader& header) const override;
|
||||
std::vector<std::uint8_t> ReadSegment(const ProgramHeader& header) const override;
|
||||
std::uint64_t GetFileSize() const override;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ public:
|
|||
[[nodiscard]] virtual ElfHeader ReadHeader() const = 0;
|
||||
[[nodiscard]] virtual std::vector<ProgramHeader> ReadProgramHeaders() const = 0;
|
||||
[[nodiscard]] virtual std::vector<SectionHeader> ReadSectionHeaders() const = 0;
|
||||
[[nodiscard]] virtual std::vector<DynamicTag> ReadDynamicTags(const ProgramHeader& dynamicHeader) const = 0;
|
||||
[[nodiscard]] virtual std::vector<std::uint8_t> ReadSection(const SectionHeader& header) const = 0;
|
||||
[[nodiscard]] virtual std::vector<std::uint8_t> ReadSegment(const ProgramHeader& header) const = 0;
|
||||
[[nodiscard]] virtual std::uint64_t GetFileSize() const = 0;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,11 @@ struct SymbolExport {
|
|||
CallSiteInfo CallSites;
|
||||
};
|
||||
|
||||
struct DynamicTag {
|
||||
std::int64_t Tag;
|
||||
std::uint64_t Value;
|
||||
};
|
||||
|
||||
struct RelinkerException : std::runtime_error {
|
||||
FileByteOffset FailureOffset;
|
||||
|
||||
|
|
|
|||
|
|
@ -168,6 +168,29 @@ std::string ElfReader::_resolveShdrName(std::uint32_t nameOffset, const ElfHeade
|
|||
return name;
|
||||
}
|
||||
|
||||
std::vector<DynamicTag> ElfReader::ReadDynamicTags(const ProgramHeader& dynamicHeader) const {
|
||||
_loadFileIntoBuffer();
|
||||
|
||||
std::vector<DynamicTag> tags;
|
||||
FileByteOffset offset = dynamicHeader.Offset;
|
||||
const FileByteOffset end = dynamicHeader.Offset + dynamicHeader.FileSize;
|
||||
|
||||
while (offset + 16 <= end && offset + 16 <= _fileBuffer.size()) {
|
||||
DynamicTag tag;
|
||||
tag.Tag = static_cast<std::int64_t>(_readU64At(offset));
|
||||
tag.Value = _readU64At(offset + 0x08);
|
||||
|
||||
if (tag.Tag == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
tags.push_back(tag);
|
||||
offset += 16;
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t> ElfReader::ReadSection(const SectionHeader& header) const {
|
||||
_loadFileIntoBuffer();
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,12 @@ std::shared_ptr<ICallRegistryWriter> MakeCallRegistryWriter();
|
|||
static constexpr std::uint32_t PT_LOAD = 1;
|
||||
static constexpr std::uint32_t PT_DYNAMIC = 2;
|
||||
static constexpr std::uint32_t PT_SCE_DYNLIBDATA = 0x61000000;
|
||||
static constexpr std::uint32_t SHT_NULL = 0;
|
||||
static constexpr std::uint32_t PF_X = 0x1;
|
||||
|
||||
static constexpr std::int64_t DT_PLTGOT = 0x00000003;
|
||||
static constexpr std::int64_t DT_OS_PLTGOT = 0x61000027;
|
||||
static constexpr std::int64_t DT_PLTRELSZ = 0x00000002;
|
||||
static constexpr std::int64_t DT_OS_PLTRELSZ = 0x6100002d;
|
||||
|
||||
static std::string _relocationTypeName(const std::uint32_t type) {
|
||||
switch (type) {
|
||||
|
|
@ -62,7 +67,6 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
auto header = elfReader->ReadHeader();
|
||||
auto programHeaders = elfReader->ReadProgramHeaders();
|
||||
auto sectionHeaders = elfReader->ReadSectionHeaders();
|
||||
|
||||
std::vector<std::uint8_t> sceDynlibData;
|
||||
std::vector<std::uint8_t> textSection;
|
||||
|
|
@ -75,16 +79,30 @@ int main(int argc, char* argv[]) {
|
|||
sceDynlibData = elfReader->ReadSegment(ph);
|
||||
}
|
||||
|
||||
for (const auto& sh : sectionHeaders) {
|
||||
if (sh.Name == ".text") {
|
||||
textSection = elfReader->ReadSection(sh);
|
||||
textVAddr = sh.MappedAddress;
|
||||
} else if (sh.Name == ".got" || sh.Name == ".got.plt") {
|
||||
gotVAddr = sh.MappedAddress;
|
||||
gotSize = sh.SectionSize;
|
||||
for (const auto& ph : programHeaders) {
|
||||
if (ph.Type == PT_LOAD && (ph.Flags & PF_X) != 0) {
|
||||
textSection = elfReader->ReadSegment(ph);
|
||||
textVAddr = ph.MappedAddress;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& ph : programHeaders) {
|
||||
if (ph.Type != PT_DYNAMIC)
|
||||
continue;
|
||||
|
||||
auto dynTags = elfReader->ReadDynamicTags(ph);
|
||||
|
||||
for (const auto& tag : dynTags) {
|
||||
if (tag.Tag == DT_PLTGOT || tag.Tag == DT_OS_PLTGOT)
|
||||
gotVAddr = tag.Value;
|
||||
else if (tag.Tag == DT_PLTRELSZ || tag.Tag == DT_OS_PLTRELSZ)
|
||||
gotSize = tag.Value;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (sceDynlibData.empty())
|
||||
throw Relinker::RelinkerException("SCE_DYNLIBDATA segment not found");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue