diff options
author | Kevin Enderby <enderby@apple.com> | 2016-10-27 20:59:10 +0000 |
---|---|---|
committer | Kevin Enderby <enderby@apple.com> | 2016-10-27 20:59:10 +0000 |
commit | bc5c29a65f5326484b12384a519945df341aa557 (patch) | |
tree | 6cd051b43e595fa7c67011d9bd556411a0f5d55f /llvm/lib/Object/MachOObjectFile.cpp | |
parent | 58e14743cae66da3a19bed8e95f2c6a118263933 (diff) | |
download | bcm5719-llvm-bc5c29a65f5326484b12384a519945df341aa557.tar.gz bcm5719-llvm-bc5c29a65f5326484b12384a519945df341aa557.zip |
Another additional error check for invalid Mach-O files for the
obsolete load commands.
Again the philosophy of the error checking in libObject for
Mach-O files, the idea behind the checking is that we never
will return a Mach-O file out of libObject that contains unknown
things the library code can’t operate on. So known obsolete
load commands will cause a hard error.
Also to make things clear I have added comments to the
values and structures in Support/Mach-O.h and
Support/MachO.def as to what is obsolete.
As noted in a TODO in the code, there may need to be a
non-default mode to allow some unknown values for well
structured Mach-O files with things like unknown load
load commands. So things like using an old lldb on a newer
Mach-O file could still provide some limited functionality.
llvm-svn: 285342
Diffstat (limited to 'llvm/lib/Object/MachOObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/MachOObjectFile.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp index 5bfc51ecf62..8bb55175efa 100644 --- a/llvm/lib/Object/MachOObjectFile.cpp +++ b/llvm/lib/Object/MachOObjectFile.cpp @@ -912,6 +912,23 @@ static Error checkTwoLevelHintsCommand(const MachOObjectFile *Obj, return Error::success(); } +// Returns true if the libObject code does not support the load command and its +// contents. The cmd value it is treated as an unknown load command but with +// an error message that says the cmd value is obsolete. +static bool isLoadCommandObsolete(uint32_t cmd) { + if (cmd == MachO::LC_SYMSEG || + cmd == MachO::LC_LOADFVMLIB || + cmd == MachO::LC_IDFVMLIB || + cmd == MachO::LC_IDENT || + cmd == MachO::LC_FVMFILE || + cmd == MachO::LC_PREPAGE || + cmd == MachO::LC_PREBOUND_DYLIB || + cmd == MachO::LC_TWOLEVEL_HINTS || + cmd == MachO::LC_PREBIND_CKSUM) + return true; + return false; +} + Expected<std::unique_ptr<MachOObjectFile>> MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, uint32_t UniversalCputype, @@ -1250,11 +1267,20 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, } else if (Load.C.cmd == MachO::LC_THREAD) { if ((Err = checkThreadCommand(this, Load, I, "LC_THREAD"))) return; + // Note: LC_TWOLEVEL_HINTS is really obsolete and is not supported. } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) { if ((Err = checkTwoLevelHintsCommand(this, Load, I, &TwoLevelHintsLoadCmd))) return; + } else if (isLoadCommandObsolete(Load.C.cmd)) { + Err = malformedError("load command " + Twine(I) + " for cmd value of: " + + Twine(Load.C.cmd) + " is obsolete and not " + "supported"); + return; } + // TODO: generate a error for unknown load commands by default. But still + // need work out an approach to allow or not allow unknown values like this + // as an option for some uses like lldb. if (I < LoadCommandCount - 1) { if (auto LoadOrErr = getNextLoadCommandInfo(this, I, Load)) Load = *LoadOrErr; |