aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/mac/handler/minidump_generator.cc8
-rw-r--r--src/common/mac/arch_utilities.cc1
-rw-r--r--src/common/mac/dump_syms.mm3
-rw-r--r--src/common/mac/file_id.cc8
-rw-r--r--src/common/mac/file_id.h17
-rw-r--r--src/common/mac/macho_id.cc27
-rw-r--r--src/common/mac/macho_id.h33
-rw-r--r--src/common/mac/macho_walker.cc37
-rw-r--r--src/common/mac/macho_walker.h26
9 files changed, 95 insertions, 65 deletions
diff --git a/src/client/mac/handler/minidump_generator.cc b/src/client/mac/handler/minidump_generator.cc
index d5bce994..fac1a60b 100644
--- a/src/client/mac/handler/minidump_generator.cc
+++ b/src/client/mac/handler/minidump_generator.cc
@@ -31,6 +31,7 @@
#include <cstdio>
#include <mach/host_info.h>
+#include <mach/machine.h>
#include <mach/vm_statistics.h>
#include <mach-o/dyld.h>
#include <mach-o/loader.h>
@@ -1304,14 +1305,15 @@ bool MinidumpGenerator::WriteCVRecord(MDRawModule *module, int cpu_type,
MacFileUtilities::MachoID macho(module_path,
reinterpret_cast<void *>(module->base_of_image),
static_cast<size_t>(module->size_of_image));
- result = macho.UUIDCommand(cpu_type, identifier);
+ result = macho.UUIDCommand(cpu_type, CPU_SUBTYPE_MULTIPLE, identifier);
if (!result)
- result = macho.MD5(cpu_type, identifier);
+ result = macho.MD5(cpu_type, CPU_SUBTYPE_MULTIPLE, identifier);
}
if (!result) {
FileID file_id(module_path);
- result = file_id.MachoIdentifier(cpu_type, identifier);
+ result = file_id.MachoIdentifier(cpu_type, CPU_SUBTYPE_MULTIPLE,
+ identifier);
}
if (result) {
diff --git a/src/common/mac/arch_utilities.cc b/src/common/mac/arch_utilities.cc
index 6f7c494c..972a3dae 100644
--- a/src/common/mac/arch_utilities.cc
+++ b/src/common/mac/arch_utilities.cc
@@ -53,6 +53,7 @@ const NXArchInfo* ArchInfo_armv7s() {
CPU_SUBTYPE_ARM_V7);
armv7s->name = "armv7s";
armv7s->cpusubtype = CPU_SUBTYPE_ARM_V7S;
+ armv7s->description = "arm v7s";
return armv7s;
}
diff --git a/src/common/mac/dump_syms.mm b/src/common/mac/dump_syms.mm
index ad2afd01..d79afe26 100644
--- a/src/common/mac/dump_syms.mm
+++ b/src/common/mac/dump_syms.mm
@@ -204,7 +204,8 @@ string DumpSymbols::Identifier() {
FileID file_id([object_filename_ fileSystemRepresentation]);
unsigned char identifier_bytes[16];
cpu_type_t cpu_type = selected_object_file_->cputype;
- if (!file_id.MachoIdentifier(cpu_type, identifier_bytes)) {
+ cpu_subtype_t cpu_subtype = selected_object_file_->cpusubtype;
+ if (!file_id.MachoIdentifier(cpu_type, cpu_subtype, identifier_bytes)) {
fprintf(stderr, "Unable to calculate UUID of mach-o binary %s!\n",
[object_filename_ fileSystemRepresentation]);
return "";
diff --git a/src/common/mac/file_id.cc b/src/common/mac/file_id.cc
index b81cf834..a2ee320b 100644
--- a/src/common/mac/file_id.cc
+++ b/src/common/mac/file_id.cc
@@ -70,13 +70,15 @@ bool FileID::FileIdentifier(unsigned char identifier[16]) {
return true;
}
-bool FileID::MachoIdentifier(int cpu_type, unsigned char identifier[16]) {
+bool FileID::MachoIdentifier(cpu_type_t cpu_type,
+ cpu_subtype_t cpu_subtype,
+ unsigned char identifier[16]) {
MachoID macho(path_);
- if (macho.UUIDCommand(cpu_type, identifier))
+ if (macho.UUIDCommand(cpu_type, cpu_subtype, identifier))
return true;
- return macho.MD5(cpu_type, identifier);
+ return macho.MD5(cpu_type, cpu_subtype, identifier);
}
// static
diff --git a/src/common/mac/file_id.h b/src/common/mac/file_id.h
index eb06b0d6..1d6dfde1 100644
--- a/src/common/mac/file_id.h
+++ b/src/common/mac/file_id.h
@@ -35,6 +35,7 @@
#define COMMON_MAC_FILE_ID_H__
#include <limits.h>
+#include <mach/machine.h>
namespace google_breakpad {
@@ -50,15 +51,18 @@ class FileID {
bool FileIdentifier(unsigned char identifier[16]);
// Treat the file as a mach-o file that will contain one or more archicture.
- // Accepted values for |cpu_type| (e.g., CPU_TYPE_X86 or CPU_TYPE_POWERPC)
- // are listed in /usr/include/mach/machine.h.
- // If |cpu_type| is 0, then the native cpu type is used.
- // Returns false if opening the file failed or if the |cpu_type| is not
- // present in the file.
+ // Accepted values for |cpu_type| and |cpu_subtype| (e.g., CPU_TYPE_X86 or
+ // CPU_TYPE_POWERPC) are listed in /usr/include/mach/machine.h.
+ // If |cpu_type| is 0, then the native cpu type is used. If |cpu_subtype| is
+ // CPU_SUBTYPE_MULTIPLE, the match is only done on |cpu_type|.
+ // Returns false if opening the file failed or if the |cpu_type|/|cpu_subtype|
+ // is not present in the file.
// Return the unique identifier in |identifier|.
// The current implementation will look for the (in order of priority):
// LC_UUID, LC_ID_DYLIB, or MD5 hash of the given |cpu_type|.
- bool MachoIdentifier(int cpu_type, unsigned char identifier[16]);
+ bool MachoIdentifier(cpu_type_t cpu_type,
+ cpu_subtype_t cpu_subtype,
+ unsigned char identifier[16]);
// Convert the |identifier| data to a NULL terminated string. The string will
// be formatted as a UUID (e.g., 22F065BB-FC9C-49F7-80FE-26A7CEBD7BCE).
@@ -75,4 +79,3 @@ class FileID {
} // namespace google_breakpad
#endif // COMMON_MAC_FILE_ID_H__
-
diff --git a/src/common/mac/macho_id.cc b/src/common/mac/macho_id.cc
index abe1fabd..aa2cfc83 100644
--- a/src/common/mac/macho_id.cc
+++ b/src/common/mac/macho_id.cc
@@ -153,10 +153,12 @@ void MachoID::Update(MachoWalker *walker, off_t offset, size_t size) {
}
}
-bool MachoID::UUIDCommand(int cpu_type, unsigned char bytes[16]) {
+bool MachoID::UUIDCommand(cpu_type_t cpu_type,
+ cpu_subtype_t cpu_subtype,
+ unsigned char bytes[16]) {
struct breakpad_uuid_command uuid_cmd;
uuid_cmd.cmd = 0;
- if (!WalkHeader(cpu_type, UUIDWalkerCB, &uuid_cmd))
+ if (!WalkHeader(cpu_type, cpu_subtype, UUIDWalkerCB, &uuid_cmd))
return false;
// If we found the command, we'll have initialized the uuid_command
@@ -169,10 +171,12 @@ bool MachoID::UUIDCommand(int cpu_type, unsigned char bytes[16]) {
return false;
}
-bool MachoID::IDCommand(int cpu_type, unsigned char identifier[16]) {
+bool MachoID::IDCommand(cpu_type_t cpu_type,
+ cpu_subtype_t cpu_subtype,
+ unsigned char identifier[16]) {
struct dylib_command dylib_cmd;
dylib_cmd.cmd = 0;
- if (!WalkHeader(cpu_type, IDWalkerCB, &dylib_cmd))
+ if (!WalkHeader(cpu_type, cpu_subtype, IDWalkerCB, &dylib_cmd))
return false;
// If we found the command, we'll have initialized the dylib_command
@@ -210,37 +214,38 @@ bool MachoID::IDCommand(int cpu_type, unsigned char identifier[16]) {
return false;
}
-uint32_t MachoID::Adler32(int cpu_type) {
+uint32_t MachoID::Adler32(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) {
update_function_ = &MachoID::UpdateCRC;
crc_ = 0;
- if (!WalkHeader(cpu_type, WalkerCB, this))
+ if (!WalkHeader(cpu_type, cpu_subtype, WalkerCB, this))
return 0;
return crc_;
}
-bool MachoID::MD5(int cpu_type, unsigned char identifier[16]) {
+bool MachoID::MD5(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype, unsigned char identifier[16]) {
update_function_ = &MachoID::UpdateMD5;
MD5Init(&md5_context_);
- if (!WalkHeader(cpu_type, WalkerCB, this))
+ if (!WalkHeader(cpu_type, cpu_subtype, WalkerCB, this))
return false;
MD5Final(identifier, &md5_context_);
return true;
}
-bool MachoID::WalkHeader(int cpu_type,
+bool MachoID::WalkHeader(cpu_type_t cpu_type,
+ cpu_subtype_t cpu_subtype,
MachoWalker::LoadCommandCallback callback,
void *context) {
if (memory_) {
MachoWalker walker(memory_, memory_size_, callback, context);
- return walker.WalkHeader(cpu_type);
+ return walker.WalkHeader(cpu_type, cpu_subtype);
} else {
MachoWalker walker(path_, callback, context);
- return walker.WalkHeader(cpu_type);
+ return walker.WalkHeader(cpu_type, cpu_subtype);
}
}
diff --git a/src/common/mac/macho_id.h b/src/common/mac/macho_id.h
index ccb126d4..10375491 100644
--- a/src/common/mac/macho_id.h
+++ b/src/common/mac/macho_id.h
@@ -35,6 +35,7 @@
#define COMMON_MAC_MACHO_ID_H__
#include <limits.h>
+#include <mach/machine.h>
#include <mach-o/loader.h>
#include "common/mac/macho_walker.h"
@@ -48,22 +49,32 @@ class MachoID {
MachoID(const char *path, void *memory, size_t size);
~MachoID();
- // For the given |cpu_type|, return a UUID from the LC_UUID command.
+ // For the given |cpu_type| and |cpu_subtype|, return a UUID from the LC_UUID
+ // command.
// Return false if there isn't a LC_UUID command.
- bool UUIDCommand(int cpu_type, unsigned char identifier[16]);
+ bool UUIDCommand(cpu_type_t cpu_type,
+ cpu_subtype_t cpu_subtype,
+ unsigned char identifier[16]);
- // For the given |cpu_type|, return a UUID from the LC_ID_DYLIB command.
+ // For the given |cpu_type| and |cpu_subtype|, return a UUID from the
+ // LC_ID_DYLIB command.
// Return false if there isn't a LC_ID_DYLIB command.
- bool IDCommand(int cpu_type, unsigned char identifier[16]);
+ bool IDCommand(cpu_type_t cpu_type,
+ cpu_subtype_t cpu_subtype,
+ unsigned char identifier[16]);
- // For the given |cpu_type|, return the Adler32 CRC for the mach-o data
- // segment(s).
+ // For the given |cpu_type| and |cpu_subtype|, return the Adler32 CRC for the
+ // mach-o data segment(s).
// Return 0 on error (e.g., if the file is not a mach-o file)
- uint32_t Adler32(int cpu_type);
+ uint32_t Adler32(cpu_type_t cpu_type,
+ cpu_subtype_t cpu_subtype);
- // For the given |cpu_type|, return the MD5 for the mach-o data segment(s).
+ // For the given |cpu_type|, and |cpu_subtype| return the MD5 for the mach-o
+ // data segment(s).
// Return true on success, false otherwise
- bool MD5(int cpu_type, unsigned char identifier[16]);
+ bool MD5(cpu_type_t cpu_type,
+ cpu_subtype_t cpu_subtype,
+ unsigned char identifier[16]);
private:
// Signature of class member function to be called with data read from file
@@ -81,8 +92,8 @@ class MachoID {
void Update(MachoWalker *walker, off_t offset, size_t size);
// Factory for the MachoWalker
- bool WalkHeader(int cpu_type, MachoWalker::LoadCommandCallback callback,
- void *context);
+ bool WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype,
+ MachoWalker::LoadCommandCallback callback, void *context);
// The callback from the MachoWalker for CRC and MD5
static bool WalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
diff --git a/src/common/mac/macho_walker.cc b/src/common/mac/macho_walker.cc
index eb915c39..b2948b71 100644
--- a/src/common/mac/macho_walker.cc
+++ b/src/common/mac/macho_walker.cc
@@ -79,21 +79,18 @@ MachoWalker::~MachoWalker() {
close(file_);
}
-int MachoWalker::ValidateCPUType(int cpu_type) {
- // If the user didn't specify, use the local architecture.
+bool MachoWalker::WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) {
+ cpu_type_t valid_cpu_type = cpu_type;
+ cpu_subtype_t valid_cpu_subtype = cpu_subtype;
+ // if |cpu_type| is 0, use the native cpu type.
if (cpu_type == 0) {
const NXArchInfo *arch = NXGetLocalArchInfo();
assert(arch);
- cpu_type = arch->cputype;
+ valid_cpu_type = arch->cputype;
+ valid_cpu_subtype = CPU_SUBTYPE_MULTIPLE;
}
-
- return cpu_type;
-}
-
-bool MachoWalker::WalkHeader(int cpu_type) {
- int valid_cpu_type = ValidateCPUType(cpu_type);
off_t offset;
- if (FindHeader(valid_cpu_type, offset)) {
+ if (FindHeader(valid_cpu_type, valid_cpu_subtype, offset)) {
if (cpu_type & CPU_ARCH_ABI64)
return WalkHeader64AtOffset(offset);
@@ -131,8 +128,9 @@ bool MachoWalker::CurrentHeader(struct mach_header_64 *header, off_t *offset) {
return false;
}
-bool MachoWalker::FindHeader(int cpu_type, off_t &offset) {
- int valid_cpu_type = ValidateCPUType(cpu_type);
+bool MachoWalker::FindHeader(cpu_type_t cpu_type,
+ cpu_subtype_t cpu_subtype,
+ off_t &offset) {
// Read the magic bytes that's common amongst all mach-o files
uint32_t magic;
if (!ReadBytes(&magic, sizeof(magic), 0))
@@ -153,15 +151,18 @@ bool MachoWalker::FindHeader(int cpu_type, off_t &offset) {
if (!is_fat) {
// If we don't have a fat header, check if the cpu type matches the single
// header
- cpu_type_t header_cpu_type;
- if (!ReadBytes(&header_cpu_type, sizeof(header_cpu_type), offset))
+ struct mach_header header;
+ if (!ReadBytes(&header, sizeof(header), 0))
return false;
if (magic == MH_CIGAM || magic == MH_CIGAM_64)
- header_cpu_type = ByteSwap(header_cpu_type);
+ swap_mach_header(&header, NXHostByteOrder());
- if (valid_cpu_type != header_cpu_type)
+ if (cpu_type != header.cputype ||
+ (cpu_subtype != CPU_SUBTYPE_MULTIPLE &&
+ cpu_subtype != header.cpusubtype)) {
return false;
+ }
offset = 0;
return true;
@@ -186,7 +187,9 @@ bool MachoWalker::FindHeader(int cpu_type, off_t &offset) {
if (NXHostByteOrder() != NX_BigEndian)
swap_fat_arch(&arch, 1, NXHostByteOrder());
- if (arch.cputype == valid_cpu_type) {
+ if (arch.cputype == cpu_type &&
+ (cpu_subtype == CPU_SUBTYPE_MULTIPLE ||
+ arch.cpusubtype == cpu_subtype)) {
offset = arch.offset;
return true;
}
diff --git a/src/common/mac/macho_walker.h b/src/common/mac/macho_walker.h
index cee3eb8d..dd535814 100644
--- a/src/common/mac/macho_walker.h
+++ b/src/common/mac/macho_walker.h
@@ -34,6 +34,7 @@
#ifndef COMMON_MAC_MACHO_WALKER_H__
#define COMMON_MAC_MACHO_WALKER_H__
+#include <mach/machine.h>
#include <mach-o/loader.h>
#include <sys/types.h>
@@ -56,16 +57,14 @@ class MachoWalker {
void *context);
~MachoWalker();
- // Begin walking the header for |cpu_type|. If |cpu_type| is 0, then the
- // native cpu type is used. Otherwise, accepted values are listed in
- // /usr/include/mach/machine.h (e.g., CPU_TYPE_X86 or CPU_TYPE_POWERPC).
- // Returns false if opening the file failed or if the |cpu_type| is not
- // present in the file.
- bool WalkHeader(int cpu_type);
-
- // Locate (if any) the header offset for |cpu_type| and return in |offset|.
- // Return true if found, false otherwise.
- bool FindHeader(int cpu_type, off_t &offset);
+ // Begin walking the header for |cpu_type| and |cpu_subtype|. If |cpu_type|
+ // is 0, then the native cpu type is used. Otherwise, accepted values are
+ // listed in /usr/include/mach/machine.h (e.g., CPU_TYPE_X86 or
+ // CPU_TYPE_POWERPC). If |cpu_subtype| is CPU_SUBTYPE_MULTIPLE, the match is
+ // only done on |cpu_type|.
+ // Returns false if opening the file failed or if the |cpu_type|/|cpu_subtype|
+ // is not present in the file.
+ bool WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype);
// Read |size| bytes from the opened file at |offset| into |buffer|
bool ReadBytes(void *buffer, size_t size, off_t offset);
@@ -74,8 +73,11 @@ class MachoWalker {
bool CurrentHeader(struct mach_header_64 *header, off_t *offset);
private:
- // Validate the |cpu_type|
- int ValidateCPUType(int cpu_type);
+ // Locate (if any) the header offset for |cpu_type| and return in |offset|.
+ // Return true if found, false otherwise.
+ bool FindHeader(cpu_type_t cpu_type,
+ cpu_subtype_t cpu_subtype,
+ off_t &offset);
// Process an individual header starting at |offset| from the start of the
// file. Return true if successful, false otherwise.