summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Object/MachOObjectFile.cpp29
-rw-r--r--llvm/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0040.machobin0 -> 9248 bytes
-rw-r--r--llvm/test/tools/llvm-objdump/malformed-machos.test6
-rw-r--r--llvm/tools/llvm-objdump/MachODump.cpp2
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
new file mode 100644
index 00000000000..f0765a4ce51
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/Inputs/malformed-machos/mem-crup-0040.macho
Binary files differ
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);
OpenPOWER on IntegriCloud