fix(types): update type names to fix bug with gcc
This commit is contained in:
parent
8a7c7c4e0d
commit
2654c8eb4b
|
|
@ -4,5 +4,4 @@ project(Relinker CXX)
|
|||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
|
||||
add_subdirectory(core/relinker)
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ private:
|
|||
mutable std::vector<std::uint8_t> _fileBuffer;
|
||||
|
||||
void _loadFileIntoBuffer() const;
|
||||
std::uint64_t _readU64At(Offset Offset) const;
|
||||
std::uint32_t _readU32At(Offset Offset) const;
|
||||
std::uint16_t _readU16At(Offset Offset) const;
|
||||
std::uint8_t _readU8At(Offset Offset) const;
|
||||
std::uint64_t _readU64At(FileByteOffset FileByteOffset) const;
|
||||
std::uint32_t _readU32At(FileByteOffset FileByteOffset) const;
|
||||
std::uint16_t _readU16At(FileByteOffset FileByteOffset) const;
|
||||
std::uint8_t _readU8At(FileByteOffset FileByteOffset) const;
|
||||
std::string _resolveShdrName(std::uint32_t NameOffset, const ElfHeader& Header) const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ struct CallRegistryEntry {
|
|||
std::string Nid;
|
||||
std::string Library;
|
||||
std::string RelocationTypeString;
|
||||
Offset RelocationOffset;
|
||||
FileByteOffset RelocationOffset;
|
||||
std::string TargetSection;
|
||||
Offset TargetOffset;
|
||||
std::vector<Offset> CallSites;
|
||||
FileByteOffset TargetOffset;
|
||||
std::vector<FileByteOffset> CallSites;
|
||||
bool CallSitesResolved;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ class ICallSiteResolver {
|
|||
public:
|
||||
virtual ~ICallSiteResolver() = default;
|
||||
|
||||
virtual std::vector<Offset> ResolveCallSites(
|
||||
virtual std::vector<FileByteOffset> ResolveCallSites(
|
||||
const std::vector<std::uint8_t>& TextSection,
|
||||
Offset TextSectionVAddr,
|
||||
Address TargetGotOrPltAddress,
|
||||
Size TargetGotOrPltSize
|
||||
FileByteOffset TextSectionVAddr,
|
||||
VirtualAddress TargetGotOrPltAddress,
|
||||
ByteCount TargetGotOrPltSize
|
||||
) = 0;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ struct LibraryImport {
|
|||
};
|
||||
|
||||
struct RelocationEntry {
|
||||
Offset Offset;
|
||||
FileByteOffset EntryOffset;
|
||||
std::uint64_t Info;
|
||||
std::int64_t Addend;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ public:
|
|||
|
||||
virtual void ScanCodeSectionForSyscalls(
|
||||
const std::vector<std::uint8_t>& CodeSection,
|
||||
Offset CodeSectionOffset,
|
||||
Offset CodeSectionSize
|
||||
FileByteOffset CodeSectionOffset,
|
||||
FileByteOffset CodeSectionSize
|
||||
) = 0;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ public:
|
|||
virtual ~IValidationPolicy() = default;
|
||||
|
||||
virtual void ValidateSyscallAbsence() = 0;
|
||||
virtual void ValidateRelocationTypeSupported(std::uint32_t RelocationTypeValue, Offset Offset) = 0;
|
||||
virtual void ValidateRelocationTypeSupported(std::uint32_t RelocationTypeValue, FileByteOffset FileByteOffset) = 0;
|
||||
virtual void ValidateNidBelongsToLibrary(const std::string& Nid, const std::string& Library) = 0;
|
||||
virtual void ValidateSceStructureSize(Size ExpectedSize, Size ActualSize, Offset Offset) = 0;
|
||||
virtual void ValidateDynamicFieldInterpretable(const std::string& FieldName, Offset Offset) = 0;
|
||||
virtual void ValidateNoSyscallInstructions(const std::vector<std::uint8_t>& CodeSection, Offset CodeOffset) = 0;
|
||||
virtual void ValidateSceStructureSize(ByteCount ExpectedSize, ByteCount ActualSize, FileByteOffset FileByteOffset) = 0;
|
||||
virtual void ValidateDynamicFieldInterpretable(const std::string& FieldName, FileByteOffset FileByteOffset) = 0;
|
||||
virtual void ValidateNoSyscallInstructions(const std::vector<std::uint8_t>& CodeSection, FileByteOffset CodeOffset) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ public:
|
|||
private:
|
||||
std::shared_ptr<ISdkRevisionProfile> _sdkProfile;
|
||||
|
||||
std::uint32_t _readU32At(const std::vector<std::uint8_t>& Data, Offset Offset) const;
|
||||
std::uint16_t _readU16At(const std::vector<std::uint8_t>& Data, Offset Offset) const;
|
||||
std::uint8_t _readU8At(const std::vector<std::uint8_t>& Data, Offset Offset) const;
|
||||
std::uint64_t _readU64At(const std::vector<std::uint8_t>& Data, Offset Offset) const;
|
||||
std::uint32_t _readU32At(const std::vector<std::uint8_t>& Data, FileByteOffset FileByteOffset) const;
|
||||
std::uint16_t _readU16At(const std::vector<std::uint8_t>& Data, FileByteOffset FileByteOffset) const;
|
||||
std::uint8_t _readU8At(const std::vector<std::uint8_t>& Data, FileByteOffset FileByteOffset) const;
|
||||
std::uint64_t _readU64At(const std::vector<std::uint8_t>& Data, FileByteOffset FileByteOffset) const;
|
||||
std::string _extractNidFromRelocationInfo(std::uint64_t Info) const;
|
||||
std::string _getLibraryNameForRelocation(const std::vector<LibraryImport>& Imports, std::uint64_t Info) const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ private:
|
|||
std::uint32_t _sdkRevision;
|
||||
|
||||
void _detectSdkRevision(const std::vector<std::uint8_t>& Data);
|
||||
std::uint32_t _readU32LittleEndian(const std::vector<std::uint8_t>& Data, Offset Offset) const;
|
||||
std::uint16_t _readU16LittleEndian(const std::vector<std::uint8_t>& Data, Offset Offset) const;
|
||||
std::uint32_t _readU32LittleEndian(const std::vector<std::uint8_t>& Data, FileByteOffset FileByteOffset) const;
|
||||
std::uint16_t _readU16LittleEndian(const std::vector<std::uint8_t>& Data, FileByteOffset FileByteOffset) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
namespace Relinker {
|
||||
|
||||
using Offset = std::uint64_t;
|
||||
using Address = std::uint64_t;
|
||||
using Size = std::uint64_t;
|
||||
using FileByteOffset = std::uint64_t;
|
||||
using VirtualAddress = std::uint64_t;
|
||||
using ByteCount = std::uint64_t;
|
||||
|
||||
struct ElfHeader {
|
||||
std::uint16_t Machine;
|
||||
|
|
@ -32,11 +32,11 @@ struct ElfHeader {
|
|||
struct ProgramHeader {
|
||||
std::uint32_t Type;
|
||||
std::uint32_t Flags;
|
||||
Offset Offset;
|
||||
Address VirtualAddress;
|
||||
Address PhysicalAddress;
|
||||
Size FileSize;
|
||||
Size MemorySize;
|
||||
FileByteOffset Offset;
|
||||
VirtualAddress MappedAddress;
|
||||
VirtualAddress PhysicalAddress;
|
||||
ByteCount FileSize;
|
||||
ByteCount MemorySize;
|
||||
std::uint64_t Alignment;
|
||||
};
|
||||
|
||||
|
|
@ -44,9 +44,9 @@ struct SectionHeader {
|
|||
std::string Name;
|
||||
std::uint32_t Type;
|
||||
std::uint64_t Flags;
|
||||
Address VirtualAddress;
|
||||
Offset Offset;
|
||||
Size Size;
|
||||
VirtualAddress MappedAddress;
|
||||
FileByteOffset Offset;
|
||||
ByteCount SectionSize;
|
||||
std::uint32_t Link;
|
||||
std::uint32_t Info;
|
||||
std::uint64_t EntrySize;
|
||||
|
|
@ -56,28 +56,28 @@ struct NidReference {
|
|||
std::string Nid;
|
||||
std::string Library;
|
||||
std::uint32_t RelocationTypeValue;
|
||||
Offset RelocationTableOffset;
|
||||
Address RelocationAddress;
|
||||
FileByteOffset RelocationTableOffset;
|
||||
VirtualAddress RelocationAddress;
|
||||
};
|
||||
|
||||
struct CallSiteInfo {
|
||||
std::vector<Offset> Sites;
|
||||
std::vector<FileByteOffset> Sites;
|
||||
bool Resolved;
|
||||
};
|
||||
|
||||
struct SymbolExport {
|
||||
std::string Nid;
|
||||
std::string Library;
|
||||
Offset GotOffset;
|
||||
Offset PltOffset;
|
||||
FileByteOffset GotOffset;
|
||||
FileByteOffset PltOffset;
|
||||
CallSiteInfo CallSites;
|
||||
};
|
||||
|
||||
struct RelinkerException : std::runtime_error {
|
||||
Offset FailureOffset;
|
||||
|
||||
explicit RelinkerException(const std::string& Message, Offset Offset = 0)
|
||||
: std::runtime_error(Message), FailureOffset(Offset) {}
|
||||
FileByteOffset FailureOffset;
|
||||
|
||||
explicit RelinkerException(const std::string& Message, FileByteOffset FailureOffset = 0)
|
||||
: std::runtime_error(Message), FailureOffset(FailureOffset) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ static std::string _jsonString(const std::string& s) {
|
|||
return out;
|
||||
}
|
||||
|
||||
static std::string _hexOffset(Offset v) {
|
||||
static std::string _hexOffset(FileByteOffset v) {
|
||||
std::ostringstream oss;
|
||||
oss << "\"0x" << std::hex << std::uppercase << v << "\"";
|
||||
return oss.str();
|
||||
|
|
|
|||
|
|
@ -5,20 +5,20 @@ namespace Relinker {
|
|||
|
||||
class CallSiteResolver : public ICallSiteResolver {
|
||||
public:
|
||||
std::vector<Offset> ResolveCallSites(
|
||||
std::vector<FileByteOffset> ResolveCallSites(
|
||||
const std::vector<std::uint8_t>& TextSection,
|
||||
Offset TextSectionVAddr,
|
||||
Address TargetGotOrPltAddress,
|
||||
Size TargetGotOrPltSize) override;
|
||||
FileByteOffset TextSectionVAddr,
|
||||
VirtualAddress TargetGotOrPltAddress,
|
||||
ByteCount TargetGotOrPltSize) override;
|
||||
};
|
||||
|
||||
std::vector<Offset> CallSiteResolver::ResolveCallSites(
|
||||
std::vector<FileByteOffset> CallSiteResolver::ResolveCallSites(
|
||||
const std::vector<std::uint8_t>& TextSection,
|
||||
Offset TextSectionVAddr,
|
||||
Address TargetGotOrPltAddress,
|
||||
Size TargetGotOrPltSize)
|
||||
FileByteOffset TextSectionVAddr,
|
||||
VirtualAddress TargetGotOrPltAddress,
|
||||
ByteCount TargetGotOrPltSize)
|
||||
{
|
||||
std::vector<Offset> sites;
|
||||
std::vector<FileByteOffset> sites;
|
||||
|
||||
if (TextSection.size() < 6)
|
||||
return sites;
|
||||
|
|
@ -59,8 +59,8 @@ std::vector<Offset> CallSiteResolver::ResolveCallSites(
|
|||
(static_cast<std::uint32_t>(TextSection[dispOffset + 2]) << 16) |
|
||||
(static_cast<std::uint32_t>(TextSection[dispOffset + 3]) << 24));
|
||||
|
||||
Address nextInstrVAddr = TextSectionVAddr + i + instrSize;
|
||||
Address resolvedAddr = static_cast<Address>(static_cast<std::int64_t>(nextInstrVAddr) + disp);
|
||||
VirtualAddress nextInstrVAddr = TextSectionVAddr + i + instrSize;
|
||||
VirtualAddress resolvedAddr = static_cast<VirtualAddress>(static_cast<std::int64_t>(nextInstrVAddr) + disp);
|
||||
|
||||
if (resolvedAddr >= TargetGotOrPltAddress &&
|
||||
resolvedAddr < TargetGotOrPltAddress + TargetGotOrPltSize)
|
||||
|
|
|
|||
|
|
@ -27,41 +27,41 @@ void ElfReader::_loadFileIntoBuffer() const {
|
|||
}
|
||||
}
|
||||
|
||||
std::uint8_t ElfReader::_readU8At(Offset Offset) const {
|
||||
std::uint8_t ElfReader::_readU8At(FileByteOffset FileByteOffset) const {
|
||||
_loadFileIntoBuffer();
|
||||
if (Offset >= _fileBuffer.size()) {
|
||||
throw RelinkerException("Offset out of bounds", Offset);
|
||||
if (FileByteOffset >= _fileBuffer.size()) {
|
||||
throw RelinkerException("FileByteOffset out of bounds", FileByteOffset);
|
||||
}
|
||||
return _fileBuffer[Offset];
|
||||
return _fileBuffer[FileByteOffset];
|
||||
}
|
||||
|
||||
std::uint16_t ElfReader::_readU16At(Offset Offset) const {
|
||||
std::uint16_t ElfReader::_readU16At(FileByteOffset FileByteOffset) const {
|
||||
_loadFileIntoBuffer();
|
||||
if (Offset + 2 > _fileBuffer.size()) {
|
||||
throw RelinkerException("Offset out of bounds", Offset);
|
||||
if (FileByteOffset + 2 > _fileBuffer.size()) {
|
||||
throw RelinkerException("FileByteOffset out of bounds", FileByteOffset);
|
||||
}
|
||||
std::uint16_t value;
|
||||
std::memcpy(&value, _fileBuffer.data() + Offset, 2);
|
||||
std::memcpy(&value, _fileBuffer.data() + FileByteOffset, 2);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::uint32_t ElfReader::_readU32At(Offset Offset) const {
|
||||
std::uint32_t ElfReader::_readU32At(FileByteOffset FileByteOffset) const {
|
||||
_loadFileIntoBuffer();
|
||||
if (Offset + 4 > _fileBuffer.size()) {
|
||||
throw RelinkerException("Offset out of bounds", Offset);
|
||||
if (FileByteOffset + 4 > _fileBuffer.size()) {
|
||||
throw RelinkerException("FileByteOffset out of bounds", FileByteOffset);
|
||||
}
|
||||
std::uint32_t value;
|
||||
std::memcpy(&value, _fileBuffer.data() + Offset, 4);
|
||||
std::memcpy(&value, _fileBuffer.data() + FileByteOffset, 4);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::uint64_t ElfReader::_readU64At(Offset Offset) const {
|
||||
std::uint64_t ElfReader::_readU64At(FileByteOffset FileByteOffset) const {
|
||||
_loadFileIntoBuffer();
|
||||
if (Offset + 8 > _fileBuffer.size()) {
|
||||
throw RelinkerException("Offset out of bounds", Offset);
|
||||
if (FileByteOffset + 8 > _fileBuffer.size()) {
|
||||
throw RelinkerException("FileByteOffset out of bounds", FileByteOffset);
|
||||
}
|
||||
std::uint64_t value;
|
||||
std::memcpy(&value, _fileBuffer.data() + Offset, 8);
|
||||
std::memcpy(&value, _fileBuffer.data() + FileByteOffset, 8);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
@ -99,14 +99,14 @@ std::vector<ProgramHeader> ElfReader::ReadProgramHeaders() const {
|
|||
ElfHeader header = ReadHeader();
|
||||
|
||||
std::vector<ProgramHeader> headers;
|
||||
Offset offset = header.ProgramHeaderOffset;
|
||||
FileByteOffset offset = header.ProgramHeaderOffset;
|
||||
|
||||
for (std::uint16_t i = 0; i < header.ProgramHeaderCount; ++i) {
|
||||
ProgramHeader ph;
|
||||
ph.Type = _readU32At(offset);
|
||||
ph.Flags = _readU32At(offset + 0x04);
|
||||
ph.Offset = _readU64At(offset + 0x08);
|
||||
ph.VirtualAddress = _readU64At(offset + 0x10);
|
||||
ph.MappedAddress = _readU64At(offset + 0x10);
|
||||
ph.PhysicalAddress = _readU64At(offset + 0x18);
|
||||
ph.FileSize = _readU64At(offset + 0x20);
|
||||
ph.MemorySize = _readU64At(offset + 0x28);
|
||||
|
|
@ -124,16 +124,16 @@ std::vector<SectionHeader> ElfReader::ReadSectionHeaders() const {
|
|||
ElfHeader header = ReadHeader();
|
||||
|
||||
std::vector<SectionHeader> headers;
|
||||
Offset offset = header.SectionHeaderOffset;
|
||||
FileByteOffset offset = header.SectionHeaderOffset;
|
||||
|
||||
for (std::uint16_t i = 0; i < header.SectionHeaderCount; ++i) {
|
||||
SectionHeader sh;
|
||||
std::uint32_t nameOffset = _readU32At(offset);
|
||||
sh.Type = _readU32At(offset + 0x04);
|
||||
sh.Flags = _readU64At(offset + 0x08);
|
||||
sh.VirtualAddress = _readU64At(offset + 0x10);
|
||||
sh.MappedAddress = _readU64At(offset + 0x10);
|
||||
sh.Offset = _readU64At(offset + 0x18);
|
||||
sh.Size = _readU64At(offset + 0x20);
|
||||
sh.SectionSize = _readU64At(offset + 0x20);
|
||||
sh.Link = _readU32At(offset + 0x28);
|
||||
sh.Info = _readU32At(offset + 0x2c);
|
||||
sh.EntrySize = _readU64At(offset + 0x30);
|
||||
|
|
@ -152,13 +152,13 @@ std::string ElfReader::_resolveShdrName(std::uint32_t NameOffset, const ElfHeade
|
|||
return "";
|
||||
}
|
||||
|
||||
Offset shstrOffset = Header.SectionHeaderOffset +
|
||||
FileByteOffset shstrOffset = Header.SectionHeaderOffset +
|
||||
(Header.SectionHeaderStringIndex * Header.SectionHeaderEntrySize);
|
||||
|
||||
Offset strTableOffset = _readU64At(shstrOffset + 0x18);
|
||||
FileByteOffset strTableOffset = _readU64At(shstrOffset + 0x18);
|
||||
|
||||
std::string name;
|
||||
Offset currentPos = strTableOffset + NameOffset;
|
||||
FileByteOffset currentPos = strTableOffset + NameOffset;
|
||||
|
||||
while (currentPos < _fileBuffer.size() && _fileBuffer[currentPos] != '\0') {
|
||||
name += static_cast<char>(_fileBuffer[currentPos]);
|
||||
|
|
@ -171,11 +171,11 @@ std::string ElfReader::_resolveShdrName(std::uint32_t NameOffset, const ElfHeade
|
|||
std::vector<std::uint8_t> ElfReader::ReadSection(const SectionHeader& Header) const {
|
||||
_loadFileIntoBuffer();
|
||||
|
||||
if (Header.Offset + Header.Size > _fileBuffer.size()) {
|
||||
if (Header.Offset + Header.SectionSize > _fileBuffer.size()) {
|
||||
throw RelinkerException("Section offset out of bounds", Header.Offset);
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t> data(_fileBuffer.begin() + Header.Offset, _fileBuffer.begin() + Header.Offset + Header.Size);
|
||||
std::vector<std::uint8_t> data(_fileBuffer.begin() + Header.Offset, _fileBuffer.begin() + Header.Offset + Header.SectionSize);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,40 +15,40 @@ SceDynlibParser::SceDynlibParser(std::shared_ptr<ISdkRevisionProfile> SdkProfile
|
|||
}
|
||||
|
||||
std::uint8_t SceDynlibParser::_readU8At(
|
||||
const std::vector<std::uint8_t>& Data, Offset Offset) const {
|
||||
if (Offset >= Data.size()) {
|
||||
throw RelinkerException("SCE dynlib data offset out of bounds", Offset);
|
||||
const std::vector<std::uint8_t>& Data, FileByteOffset FileByteOffset) const {
|
||||
if (FileByteOffset >= Data.size()) {
|
||||
throw RelinkerException("SCE dynlib data offset out of bounds", FileByteOffset);
|
||||
}
|
||||
return Data[Offset];
|
||||
return Data[FileByteOffset];
|
||||
}
|
||||
|
||||
std::uint16_t SceDynlibParser::_readU16At(
|
||||
const std::vector<std::uint8_t>& Data, Offset Offset) const {
|
||||
if (Offset + 2 > Data.size()) {
|
||||
throw RelinkerException("SCE dynlib data offset out of bounds", Offset);
|
||||
const std::vector<std::uint8_t>& Data, FileByteOffset FileByteOffset) const {
|
||||
if (FileByteOffset + 2 > Data.size()) {
|
||||
throw RelinkerException("SCE dynlib data offset out of bounds", FileByteOffset);
|
||||
}
|
||||
std::uint16_t value;
|
||||
std::memcpy(&value, Data.data() + Offset, 2);
|
||||
std::memcpy(&value, Data.data() + FileByteOffset, 2);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::uint32_t SceDynlibParser::_readU32At(
|
||||
const std::vector<std::uint8_t>& Data, Offset Offset) const {
|
||||
if (Offset + 4 > Data.size()) {
|
||||
throw RelinkerException("SCE dynlib data offset out of bounds", Offset);
|
||||
const std::vector<std::uint8_t>& Data, FileByteOffset FileByteOffset) const {
|
||||
if (FileByteOffset + 4 > Data.size()) {
|
||||
throw RelinkerException("SCE dynlib data offset out of bounds", FileByteOffset);
|
||||
}
|
||||
std::uint32_t value;
|
||||
std::memcpy(&value, Data.data() + Offset, 4);
|
||||
std::memcpy(&value, Data.data() + FileByteOffset, 4);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::uint64_t SceDynlibParser::_readU64At(
|
||||
const std::vector<std::uint8_t>& Data, Offset Offset) const {
|
||||
if (Offset + 8 > Data.size()) {
|
||||
throw RelinkerException("SCE dynlib data offset out of bounds", Offset);
|
||||
const std::vector<std::uint8_t>& Data, FileByteOffset FileByteOffset) const {
|
||||
if (FileByteOffset + 8 > Data.size()) {
|
||||
throw RelinkerException("SCE dynlib data offset out of bounds", FileByteOffset);
|
||||
}
|
||||
std::uint64_t value;
|
||||
std::memcpy(&value, Data.data() + Offset, 8);
|
||||
std::memcpy(&value, Data.data() + FileByteOffset, 8);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ std::vector<LibraryImport> SceDynlibParser::ParseLibraryImports(
|
|||
std::vector<LibraryImport> imports;
|
||||
imports.reserve(count);
|
||||
|
||||
Offset cursor = baseOff;
|
||||
FileByteOffset cursor = baseOff;
|
||||
for (std::uint32_t i = 0; i < count; ++i) {
|
||||
if (cursor + entrySize > SceDynlibData.size()) {
|
||||
throw RelinkerException("Library import entry out of bounds", cursor);
|
||||
|
|
@ -72,7 +72,7 @@ std::vector<LibraryImport> SceDynlibParser::ParseLibraryImports(
|
|||
std::uint32_t version = _readU16At(SceDynlibData, cursor + 0x06);
|
||||
|
||||
std::string name;
|
||||
Offset namePos = nameOffset;
|
||||
FileByteOffset namePos = nameOffset;
|
||||
while (namePos < SceDynlibData.size() && SceDynlibData[namePos] != '\0') {
|
||||
name += static_cast<char>(SceDynlibData[namePos]);
|
||||
++namePos;
|
||||
|
|
@ -100,11 +100,11 @@ std::vector<RelocationEntry> SceDynlibParser::ParseRelocationTable(
|
|||
}
|
||||
|
||||
std::vector<RelocationEntry> entries;
|
||||
Offset cursor = tableOffset;
|
||||
FileByteOffset cursor = tableOffset;
|
||||
|
||||
while (cursor + entrySize <= SceDynlibData.size()) {
|
||||
RelocationEntry entry;
|
||||
entry.Offset = _readU64At(SceDynlibData, cursor);
|
||||
entry.EntryOffset = _readU64At(SceDynlibData, cursor);
|
||||
entry.Info = _readU64At(SceDynlibData, cursor + 0x08);
|
||||
entry.Addend = static_cast<std::int64_t>(_readU64At(SceDynlibData, cursor + 0x10));
|
||||
entries.push_back(entry);
|
||||
|
|
@ -147,8 +147,8 @@ std::vector<NidReference> SceDynlibParser::ExtractNidReferences(
|
|||
ref.Nid = std::move(nid);
|
||||
ref.Library = std::move(library);
|
||||
ref.RelocationTypeValue = relocType;
|
||||
ref.RelocationTableOffset = static_cast<Offset>(i * _sdkProfile->GetRelocationEntrySize());
|
||||
ref.RelocationAddress = reloc.Offset;
|
||||
ref.RelocationTableOffset = static_cast<FileByteOffset>(i * _sdkProfile->GetRelocationEntrySize());
|
||||
ref.RelocationAddress = reloc.EntryOffset;
|
||||
refs.push_back(std::move(ref));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,22 +25,22 @@ void SdkRevisionProfile::_detectSdkRevision(const std::vector<std::uint8_t>& Dat
|
|||
}
|
||||
|
||||
std::uint32_t SdkRevisionProfile::_readU32LittleEndian(
|
||||
const std::vector<std::uint8_t>& Data, Offset Offset) const {
|
||||
if (Offset + 4 > Data.size()) {
|
||||
throw RelinkerException("Offset out of bounds", Offset);
|
||||
const std::vector<std::uint8_t>& Data, FileByteOffset FileByteOffset) const {
|
||||
if (FileByteOffset + 4 > Data.size()) {
|
||||
throw RelinkerException("FileByteOffset out of bounds", FileByteOffset);
|
||||
}
|
||||
std::uint32_t value;
|
||||
std::memcpy(&value, Data.data() + Offset, 4);
|
||||
std::memcpy(&value, Data.data() + FileByteOffset, 4);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::uint16_t SdkRevisionProfile::_readU16LittleEndian(
|
||||
const std::vector<std::uint8_t>& Data, Offset Offset) const {
|
||||
if (Offset + 2 > Data.size()) {
|
||||
throw RelinkerException("Offset out of bounds", Offset);
|
||||
const std::vector<std::uint8_t>& Data, FileByteOffset FileByteOffset) const {
|
||||
if (FileByteOffset + 2 > Data.size()) {
|
||||
throw RelinkerException("FileByteOffset out of bounds", FileByteOffset);
|
||||
}
|
||||
std::uint16_t value;
|
||||
std::memcpy(&value, Data.data() + Offset, 2);
|
||||
std::memcpy(&value, Data.data() + FileByteOffset, 2);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@ class SyscallScanner : public ISyscallScanner {
|
|||
public:
|
||||
void ScanCodeSectionForSyscalls(
|
||||
const std::vector<std::uint8_t>& CodeSection,
|
||||
Offset CodeSectionOffset,
|
||||
Offset CodeSectionSize) override;
|
||||
FileByteOffset CodeSectionOffset,
|
||||
FileByteOffset CodeSectionSize) override;
|
||||
};
|
||||
|
||||
void SyscallScanner::ScanCodeSectionForSyscalls(
|
||||
const std::vector<std::uint8_t>& CodeSection,
|
||||
Offset CodeSectionOffset,
|
||||
Offset CodeSectionSize) {
|
||||
FileByteOffset CodeSectionOffset,
|
||||
FileByteOffset CodeSectionSize) {
|
||||
std::size_t limit = std::min(CodeSection.size(), static_cast<std::size_t>(CodeSectionSize));
|
||||
|
||||
for (std::size_t i = 0; i + 1 < limit; ++i) {
|
||||
|
|
@ -37,7 +37,7 @@ void SyscallScanner::ScanCodeSectionForSyscalls(
|
|||
bool isSysret = (b0 == SYSRET_BYTE0 && b1 == SYSRET_BYTE1);
|
||||
|
||||
if (isSyscall || isInt80 || isSysenter || isSysret) {
|
||||
Offset instrOffset = CodeSectionOffset + i;
|
||||
FileByteOffset instrOffset = CodeSectionOffset + i;
|
||||
std::ostringstream msg;
|
||||
msg << "Forbidden syscall instruction at code offset 0x" << std::hex << instrOffset;
|
||||
throw RelinkerException(msg.str(), instrOffset);
|
||||
|
|
|
|||
|
|
@ -56,15 +56,15 @@ void ValidationPolicy::RegisterLibraryImport(const std::string& Library) {
|
|||
void ValidationPolicy::ValidateSyscallAbsence() {
|
||||
}
|
||||
|
||||
void ValidationPolicy::ValidateRelocationTypeSupported(std::uint32_t RelocationTypeValue, Offset Offset) {
|
||||
void ValidationPolicy::ValidateRelocationTypeSupported(std::uint32_t RelocationTypeValue, FileByteOffset FileByteOffset) {
|
||||
if (_supportedRelocationTypes.empty()) {
|
||||
_initializeSupportedRelocationTypes();
|
||||
}
|
||||
if (_supportedRelocationTypes.find(RelocationTypeValue) == _supportedRelocationTypes.end()) {
|
||||
std::ostringstream msg;
|
||||
msg << "Unsupported relocation type 0x" << std::hex << RelocationTypeValue
|
||||
<< " at offset 0x" << Offset;
|
||||
throw RelinkerException(msg.str(), Offset);
|
||||
<< " at offset 0x" << FileByteOffset;
|
||||
throw RelinkerException(msg.str(), FileByteOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -77,24 +77,24 @@ void ValidationPolicy::ValidateNidBelongsToLibrary(const std::string& Nid, const
|
|||
}
|
||||
}
|
||||
|
||||
void ValidationPolicy::ValidateSceStructureSize(Size ExpectedSize, Size ActualSize, Offset Offset) {
|
||||
void ValidationPolicy::ValidateSceStructureSize(ByteCount ExpectedSize, ByteCount ActualSize, FileByteOffset FileByteOffset) {
|
||||
if (ActualSize != ExpectedSize) {
|
||||
std::ostringstream msg;
|
||||
msg << "SCE structure size mismatch at offset 0x" << std::hex << Offset
|
||||
msg << "SCE structure size mismatch at offset 0x" << std::hex << FileByteOffset
|
||||
<< ": expected " << std::dec << ExpectedSize << ", got " << ActualSize;
|
||||
throw RelinkerException(msg.str(), Offset);
|
||||
throw RelinkerException(msg.str(), FileByteOffset);
|
||||
}
|
||||
}
|
||||
|
||||
void ValidationPolicy::ValidateDynamicFieldInterpretable(const std::string& FieldName, Offset Offset) {
|
||||
void ValidationPolicy::ValidateDynamicFieldInterpretable(const std::string& FieldName, FileByteOffset FileByteOffset) {
|
||||
std::ostringstream msg;
|
||||
msg << "Dynamic field \"" << FieldName
|
||||
<< "\" cannot be interpreted at offset 0x" << std::hex << Offset;
|
||||
throw RelinkerException(msg.str(), Offset);
|
||||
<< "\" cannot be interpreted at offset 0x" << std::hex << FileByteOffset;
|
||||
throw RelinkerException(msg.str(), FileByteOffset);
|
||||
}
|
||||
|
||||
void ValidationPolicy::ValidateNoSyscallInstructions(
|
||||
const std::vector<std::uint8_t>& CodeSection, Offset CodeOffset) {
|
||||
const std::vector<std::uint8_t>& CodeSection, FileByteOffset CodeOffset) {
|
||||
for (std::size_t i = 0; i + 1 < CodeSection.size(); ++i) {
|
||||
std::uint8_t b0 = CodeSection[i];
|
||||
std::uint8_t b1 = CodeSection[i + 1];
|
||||
|
|
@ -105,7 +105,7 @@ void ValidationPolicy::ValidateNoSyscallInstructions(
|
|||
bool isSysret = (b0 == SYSRET_BYTE0 && b1 == SYSRET_BYTE1);
|
||||
|
||||
if (isSyscall || isInt80 || isSysenter || isSysret) {
|
||||
Offset instrOffset = CodeOffset + i;
|
||||
FileByteOffset instrOffset = CodeOffset + i;
|
||||
std::ostringstream msg;
|
||||
msg << "Forbidden syscall instruction at offset 0x" << std::hex << instrOffset;
|
||||
throw RelinkerException(msg.str(), instrOffset);
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ public:
|
|||
ValidationPolicy() = default;
|
||||
|
||||
void ValidateSyscallAbsence() override;
|
||||
void ValidateRelocationTypeSupported(std::uint32_t RelocationTypeValue, Offset Offset) override;
|
||||
void ValidateRelocationTypeSupported(std::uint32_t RelocationTypeValue, FileByteOffset FileByteOffset) override;
|
||||
void ValidateNidBelongsToLibrary(const std::string& Nid, const std::string& Library) override;
|
||||
void ValidateSceStructureSize(Size ExpectedSize, Size ActualSize, Offset Offset) override;
|
||||
void ValidateDynamicFieldInterpretable(const std::string& FieldName, Offset Offset) override;
|
||||
void ValidateNoSyscallInstructions(const std::vector<std::uint8_t>& CodeSection, Offset CodeOffset) override;
|
||||
void ValidateSceStructureSize(ByteCount ExpectedSize, ByteCount ActualSize, FileByteOffset FileByteOffset) override;
|
||||
void ValidateDynamicFieldInterpretable(const std::string& FieldName, FileByteOffset FileByteOffset) override;
|
||||
void ValidateNoSyscallInstructions(const std::vector<std::uint8_t>& CodeSection, FileByteOffset CodeOffset) override;
|
||||
|
||||
void RegisterLibraryImport(const std::string& Library);
|
||||
|
||||
|
|
|
|||
|
|
@ -66,9 +66,9 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
std::vector<std::uint8_t> sceDynlibData;
|
||||
std::vector<std::uint8_t> textSection;
|
||||
Relinker::Address textVAddr = 0;
|
||||
Relinker::Address gotVAddr = 0;
|
||||
Relinker::Size gotSize = 0;
|
||||
Relinker::VirtualAddress textVAddr = 0;
|
||||
Relinker::VirtualAddress gotVAddr = 0;
|
||||
Relinker::ByteCount gotSize = 0;
|
||||
|
||||
for (const auto& ph : programHeaders) {
|
||||
if (ph.Type == PT_SCE_DYNLIBDATA)
|
||||
|
|
@ -78,10 +78,10 @@ int main(int argc, char* argv[]) {
|
|||
for (const auto& sh : sectionHeaders) {
|
||||
if (sh.Name == ".text") {
|
||||
textSection = elfReader->ReadSection(sh);
|
||||
textVAddr = sh.VirtualAddress;
|
||||
textVAddr = sh.MappedAddress;
|
||||
} else if (sh.Name == ".got" || sh.Name == ".got.plt") {
|
||||
gotVAddr = sh.VirtualAddress;
|
||||
gotSize = sh.Size;
|
||||
gotVAddr = sh.MappedAddress;
|
||||
gotSize = sh.SectionSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ int main(int argc, char* argv[]) {
|
|||
entries.reserve(nidRefs.size());
|
||||
|
||||
for (const auto& ref : nidRefs) {
|
||||
std::vector<Relinker::Offset> callSites;
|
||||
std::vector<Relinker::FileByteOffset> callSites;
|
||||
bool resolved = false;
|
||||
|
||||
if (!textSection.empty() && gotSize > 0) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue