From: Kevin Enderby Date: Thu, 8 Oct 2015 22:50:55 +0000 (+0000) Subject: Fix a bug in llvm-objdump’s printing of Objective-C meta data X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=1ef3c282a257230e4168799dd3c676ee92e1b250;p=oota-llvm.git Fix a bug in llvm-objdump’s printing of Objective-C meta data from malformed Mach-O files that caused a crash because of a section header had a size that extended past the end of the file. rdar://22983603 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249768 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index f89e8e48594..4f9ccedd0c6 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/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/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0040.macho b/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0040.macho new file mode 100644 index 00000000000..f0765a4ce51 Binary files /dev/null and b/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0040.macho differ diff --git a/test/tools/llvm-objdump/malformed-machos.test b/test/tools/llvm-objdump/malformed-machos.test index e836239a250..2167c706550 100644 --- a/test/tools/llvm-objdump/malformed-machos.test +++ b/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/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index b6b910f55dc..993e9e6817b 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/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);