diff options
-rw-r--r-- | llvm/lib/Object/MachOObjectFile.cpp | 29 | ||||
-rw-r--r-- | llvm/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0040.macho | bin | 0 -> 9248 bytes | |||
-rw-r--r-- | llvm/test/tools/llvm-objdump/malformed-machos.test | 6 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/MachODump.cpp | 2 |
4 files changed, 34 insertions, 3 deletions
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp index f89e8e48594..4f9ccedd0c6 100644 --- a/llvm/lib/Object/MachOObjectFile.cpp +++ b/llvm/lib/Object/MachOObjectFile.cpp @@ -483,9 +483,32 @@ uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const { } uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const { - if (is64Bit()) - return getSection64(Sec).size; - return getSection(Sec).size; + // In the case if a malformed Mach-O file where the section offset is past + // the end of the file or some part of the section size is past the end of + // the file return a size of zero or a size that covers the rest of the file + // but does not extend past the end of the file. + uint32_t SectOffset, SectType; + uint64_t SectSize; + + if (is64Bit()) { + MachO::section_64 Sect = getSection64(Sec); + SectOffset = Sect.offset; + SectSize = Sect.size; + SectType = Sect.flags & MachO::SECTION_TYPE; + } else { + MachO::section Sect = getSection(Sec); + SectOffset = Sect.offset; + SectSize = Sect.size; + SectType = Sect.flags & MachO::SECTION_TYPE; + } + if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL) + return SectSize; + uint64_t FileSize = getData().size(); + if (SectOffset > FileSize) + return 0; + if (FileSize - SectOffset < SectSize) + return FileSize - SectOffset; + return SectSize; } std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec, diff --git a/llvm/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0040.macho b/llvm/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0040.macho Binary files differnew file mode 100644 index 00000000000..f0765a4ce51 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0040.macho diff --git a/llvm/test/tools/llvm-objdump/malformed-machos.test b/llvm/test/tools/llvm-objdump/malformed-machos.test index e836239a250..2167c706550 100644 --- a/llvm/test/tools/llvm-objdump/malformed-machos.test +++ b/llvm/test/tools/llvm-objdump/malformed-machos.test @@ -18,3 +18,9 @@ # RUN: | FileCheck -check-prefix=m0010 %s # m0010: 00000000000010e0 0x10e8 _OBJC_CLASS_ + +# RUN: llvm-objdump -macho -objc-meta-data \ +# RUN: %p/Inputs/malformed-machos/mem-crup-0040.macho \ +# RUN: | FileCheck -check-prefix=m0040 %s + +# m0040: 00000000000010a0 0xf39 -[tiny_dylib init] diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index b6b910f55dc..993e9e6817b 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -2340,6 +2340,8 @@ static const char *get_pointer_64(uint64_t Address, uint32_t &offset, for (unsigned SectIdx = 0; SectIdx != info->Sections->size(); SectIdx++) { uint64_t SectAddress = ((*(info->Sections))[SectIdx]).getAddress(); uint64_t SectSize = ((*(info->Sections))[SectIdx]).getSize(); + if (SectSize == 0) + continue; if (objc_only) { StringRef SectName; ((*(info->Sections))[SectIdx]).getName(SectName); |