mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-04 21:31:03 +00:00
[Object, MachO] Don't crash on parsing invalid MachO header.
Summary: Instead, properly report this error from MachOObjectFile constructor. Test Plan: regression test suite Reviewers: rafael Subscribers: llvm-commits git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239078 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
00faba70cc
commit
1d4ec71798
@ -38,6 +38,7 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
// FIXME: Replace all uses of this function with getStructOrErr.
|
||||
template <typename T>
|
||||
static T getStruct(const MachOObjectFile *O, const char *P) {
|
||||
// Don't read before the beginning or past the end of the file
|
||||
@ -51,6 +52,19 @@ static T getStruct(const MachOObjectFile *O, const char *P) {
|
||||
return Cmd;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static ErrorOr<T> getStructOrErr(const MachOObjectFile *O, const char *P) {
|
||||
// Don't read before the beginning or past the end of the file
|
||||
if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
|
||||
return object_error::parse_failed;
|
||||
|
||||
T Cmd;
|
||||
memcpy(&Cmd, P, sizeof(T));
|
||||
if (O->isLittleEndian() != sys::IsLittleEndianHost)
|
||||
MachO::swapStruct(Cmd);
|
||||
return Cmd;
|
||||
}
|
||||
|
||||
template <typename SegmentCmd>
|
||||
static uint32_t getSegmentLoadCommandNumSections(const SegmentCmd &S,
|
||||
uint32_t Cmdsize) {
|
||||
@ -203,6 +217,16 @@ getNextLoadCommandInfo(const MachOObjectFile *Obj,
|
||||
return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void parseHeader(const MachOObjectFile *Obj, T &Header,
|
||||
std::error_code &EC) {
|
||||
auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0));
|
||||
if (HeaderOrErr)
|
||||
Header = HeaderOrErr.get();
|
||||
else
|
||||
EC = HeaderOrErr.getError();
|
||||
}
|
||||
|
||||
MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
|
||||
bool Is64bits, std::error_code &EC)
|
||||
: ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
|
||||
@ -210,14 +234,15 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
|
||||
DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
|
||||
DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
|
||||
HasPageZeroSegment(false) {
|
||||
// Parse header.
|
||||
if (is64Bit())
|
||||
Header64 = getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
|
||||
parseHeader(this, Header64, EC);
|
||||
else
|
||||
// First fields of MachO::mach_header_64 are the same as
|
||||
// in MachO::mach_header.
|
||||
*reinterpret_cast<MachO::mach_header *>(&this->Header64) =
|
||||
getStruct<MachO::mach_header>(this, getPtr(this, 0));
|
||||
parseHeader(this, *reinterpret_cast<MachO::mach_header *>(&this->Header64),
|
||||
EC);
|
||||
if (EC)
|
||||
return;
|
||||
|
||||
uint32_t LoadCommandCount = getHeader().ncmds;
|
||||
if (LoadCommandCount == 0)
|
||||
|
BIN
test/Object/Inputs/macho-invalid-header
Normal file
BIN
test/Object/Inputs/macho-invalid-header
Normal file
Binary file not shown.
@ -34,3 +34,6 @@ NAME-PAST-EOF: Symbol name entry points before beginning or past end of file
|
||||
RUN: not llvm-nm %p/Inputs/macho-invalid-section-index-getSectionRawName 2>&1 \
|
||||
RUN: | FileCheck -check-prefix INVALID-SECTION-IDX-SYMBOL-SEC %s
|
||||
INVALID-SECTION-IDX-SYMBOL-SEC: getSymbolSection: Invalid section index
|
||||
|
||||
RUN: not llvm-objdump -private-headers %p/Inputs/macho-invalid-header 2>&1 | FileCheck -check-prefix INVALID-HEADER %s
|
||||
INVALID-HEADER: Invalid data was encountered while parsing the file
|
||||
|
Loading…
x
Reference in New Issue
Block a user