diff options
Diffstat (limited to '3rdParty/Breakpad/src/common/mac/macho_reader.cc')
-rw-r--r-- | 3rdParty/Breakpad/src/common/mac/macho_reader.cc | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/3rdParty/Breakpad/src/common/mac/macho_reader.cc b/3rdParty/Breakpad/src/common/mac/macho_reader.cc index f1f0a17..52f3c41 100644 --- a/3rdParty/Breakpad/src/common/mac/macho_reader.cc +++ b/3rdParty/Breakpad/src/common/mac/macho_reader.cc @@ -43,6 +43,10 @@ #define CPU_TYPE_ARM 12 #endif +#if !defined(CPU_TYPE_ARM_64) +#define CPU_TYPE_ARM_64 16777228 +#endif + namespace google_breakpad { namespace mach_o { @@ -97,22 +101,26 @@ bool FatReader::Read(const uint8_t *buffer, size_t size) { // Read the list of object files. object_files_.resize(object_files_count); for (size_t i = 0; i < object_files_count; i++) { - struct fat_arch *objfile = &object_files_[i]; + struct fat_arch objfile; // Read this object file entry, byte-swapping as appropriate. - cursor >> objfile->cputype - >> objfile->cpusubtype - >> objfile->offset - >> objfile->size - >> objfile->align; + cursor >> objfile.cputype + >> objfile.cpusubtype + >> objfile.offset + >> objfile.size + >> objfile.align; + + SuperFatArch super_fat_arch(objfile); + object_files_[i] = super_fat_arch; + if (!cursor) { reporter_->TooShort(); return false; } // Does the file actually have the bytes this entry refers to? size_t fat_size = buffer_.Size(); - if (objfile->offset > fat_size || - objfile->size > fat_size - objfile->offset) { + if (objfile.offset > fat_size || + objfile.size > fat_size - objfile.offset) { reporter_->MisplacedObjectFile(); return false; } @@ -135,16 +143,14 @@ bool FatReader::Read(const uint8_t *buffer, size_t size) { } object_files_[0].offset = 0; - object_files_[0].size = static_cast<uint32_t>(buffer_.Size()); + object_files_[0].size = static_cast<uint64_t>(buffer_.Size()); // This alignment is correct for 32 and 64-bit x86 and ppc. // See get_align in the lipo source for other architectures: // http://www.opensource.apple.com/source/cctools/cctools-773/misc/lipo.c object_files_[0].align = 12; // 2^12 == 4096 - return true; } } - reporter_->BadHeader(); return false; } @@ -175,15 +181,15 @@ void Reader::Reporter::LoadCommandRegionTruncated() { void Reader::Reporter::LoadCommandsOverrun(size_t claimed, size_t i, LoadCommandType type) { - fprintf(stderr, "%s: file's header claims there are %ld" - " load commands, but load command #%ld", + fprintf(stderr, "%s: file's header claims there are %zu" + " load commands, but load command #%zu", filename_.c_str(), claimed, i); if (type) fprintf(stderr, ", of type %d,", type); fprintf(stderr, " extends beyond the end of the load command region\n"); } void Reader::Reporter::LoadCommandTooShort(size_t i, LoadCommandType type) { - fprintf(stderr, "%s: the contents of load command #%ld, of type %d," + fprintf(stderr, "%s: the contents of load command #%zu, of type %d," " extend beyond the size given in the load command's header\n", filename_.c_str(), i, type); } @@ -242,6 +248,7 @@ bool Reader::Read(const uint8_t *buffer, case CPU_TYPE_POWERPC: expected_magic = MH_MAGIC; break; + case CPU_TYPE_ARM_64: case CPU_TYPE_X86_64: expected_magic = MH_CIGAM_64; break; @@ -310,7 +317,7 @@ bool Reader::WalkLoadCommands(Reader::LoadCommandHandler *handler) const { // remainder of the load command series. ByteBuffer command(list_cursor.here(), list_cursor.Available()); ByteCursor cursor(&command, big_endian_); - + // Read the command type and size --- fields common to all commands. uint32_t type, size; if (!(cursor >> type)) { @@ -395,7 +402,7 @@ bool Reader::WalkLoadCommands(Reader::LoadCommandHandler *handler) const { return false; break; } - + default: { if (!handler->UnknownCommand(type, command)) return false; @@ -414,7 +421,7 @@ class Reader::SegmentFinder : public LoadCommandHandler { public: // Create a load command handler that looks for a segment named NAME, // and sets SEGMENT to describe it if found. - SegmentFinder(const string &name, Segment *segment) + SegmentFinder(const string &name, Segment *segment) : name_(name), segment_(segment), found_() { } // Return true if the traversal found the segment, false otherwise. @@ -474,10 +481,12 @@ bool Reader::WalkSegmentSections(const Segment &segment, reporter_->SectionsMissing(segment.name); return false; } - if ((section.flags & SECTION_TYPE) == S_ZEROFILL) { + const uint32_t section_type = section.flags & SECTION_TYPE; + if (section_type == S_ZEROFILL || section_type == S_THREAD_LOCAL_ZEROFILL || + section_type == S_GB_ZEROFILL) { // Zero-fill sections have a size, but no contents. section.contents.start = section.contents.end = NULL; - } else if (segment.contents.start == NULL && + } else if (segment.contents.start == NULL && segment.contents.end == NULL) { // Mach-O files in .dSYM bundles have the contents of the loaded // segments removed, and their file offsets and file sizes zeroed |