Update dump_syms to correctly filter on cpu subtype.
Right now, if an archive contain multiple executable for the same CPU but with different subtype, there is no way to dump any but the first one. Review URL: https://breakpad.appspot.com/476002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1061 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
a1da3a504b
commit
872d464500
9 changed files with 95 additions and 65 deletions
|
@ -31,6 +31,7 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#include <mach/host_info.h>
|
#include <mach/host_info.h>
|
||||||
|
#include <mach/machine.h>
|
||||||
#include <mach/vm_statistics.h>
|
#include <mach/vm_statistics.h>
|
||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h>
|
||||||
#include <mach-o/loader.h>
|
#include <mach-o/loader.h>
|
||||||
|
@ -1304,14 +1305,15 @@ bool MinidumpGenerator::WriteCVRecord(MDRawModule *module, int cpu_type,
|
||||||
MacFileUtilities::MachoID macho(module_path,
|
MacFileUtilities::MachoID macho(module_path,
|
||||||
reinterpret_cast<void *>(module->base_of_image),
|
reinterpret_cast<void *>(module->base_of_image),
|
||||||
static_cast<size_t>(module->size_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)
|
if (!result)
|
||||||
result = macho.MD5(cpu_type, identifier);
|
result = macho.MD5(cpu_type, CPU_SUBTYPE_MULTIPLE, identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
FileID file_id(module_path);
|
FileID file_id(module_path);
|
||||||
result = file_id.MachoIdentifier(cpu_type, identifier);
|
result = file_id.MachoIdentifier(cpu_type, CPU_SUBTYPE_MULTIPLE,
|
||||||
|
identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
|
|
|
@ -53,6 +53,7 @@ const NXArchInfo* ArchInfo_armv7s() {
|
||||||
CPU_SUBTYPE_ARM_V7);
|
CPU_SUBTYPE_ARM_V7);
|
||||||
armv7s->name = "armv7s";
|
armv7s->name = "armv7s";
|
||||||
armv7s->cpusubtype = CPU_SUBTYPE_ARM_V7S;
|
armv7s->cpusubtype = CPU_SUBTYPE_ARM_V7S;
|
||||||
|
armv7s->description = "arm v7s";
|
||||||
return armv7s;
|
return armv7s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -204,7 +204,8 @@ string DumpSymbols::Identifier() {
|
||||||
FileID file_id([object_filename_ fileSystemRepresentation]);
|
FileID file_id([object_filename_ fileSystemRepresentation]);
|
||||||
unsigned char identifier_bytes[16];
|
unsigned char identifier_bytes[16];
|
||||||
cpu_type_t cpu_type = selected_object_file_->cputype;
|
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",
|
fprintf(stderr, "Unable to calculate UUID of mach-o binary %s!\n",
|
||||||
[object_filename_ fileSystemRepresentation]);
|
[object_filename_ fileSystemRepresentation]);
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -70,13 +70,15 @@ bool FileID::FileIdentifier(unsigned char identifier[16]) {
|
||||||
return true;
|
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_);
|
MachoID macho(path_);
|
||||||
|
|
||||||
if (macho.UUIDCommand(cpu_type, identifier))
|
if (macho.UUIDCommand(cpu_type, cpu_subtype, identifier))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return macho.MD5(cpu_type, identifier);
|
return macho.MD5(cpu_type, cpu_subtype, identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#define COMMON_MAC_FILE_ID_H__
|
#define COMMON_MAC_FILE_ID_H__
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <mach/machine.h>
|
||||||
|
|
||||||
namespace google_breakpad {
|
namespace google_breakpad {
|
||||||
|
|
||||||
|
@ -50,15 +51,18 @@ class FileID {
|
||||||
bool FileIdentifier(unsigned char identifier[16]);
|
bool FileIdentifier(unsigned char identifier[16]);
|
||||||
|
|
||||||
// Treat the file as a mach-o file that will contain one or more archicture.
|
// 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)
|
// Accepted values for |cpu_type| and |cpu_subtype| (e.g., CPU_TYPE_X86 or
|
||||||
// are listed in /usr/include/mach/machine.h.
|
// 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_type| is 0, then the native cpu type is used. If |cpu_subtype| is
|
||||||
// Returns false if opening the file failed or if the |cpu_type| is not
|
// CPU_SUBTYPE_MULTIPLE, the match is only done on |cpu_type|.
|
||||||
// present in the file.
|
// 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|.
|
// Return the unique identifier in |identifier|.
|
||||||
// The current implementation will look for the (in order of priority):
|
// The current implementation will look for the (in order of priority):
|
||||||
// LC_UUID, LC_ID_DYLIB, or MD5 hash of the given |cpu_type|.
|
// 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
|
// Convert the |identifier| data to a NULL terminated string. The string will
|
||||||
// be formatted as a UUID (e.g., 22F065BB-FC9C-49F7-80FE-26A7CEBD7BCE).
|
// be formatted as a UUID (e.g., 22F065BB-FC9C-49F7-80FE-26A7CEBD7BCE).
|
||||||
|
@ -75,4 +79,3 @@ class FileID {
|
||||||
} // namespace google_breakpad
|
} // namespace google_breakpad
|
||||||
|
|
||||||
#endif // COMMON_MAC_FILE_ID_H__
|
#endif // COMMON_MAC_FILE_ID_H__
|
||||||
|
|
||||||
|
|
|
@ -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;
|
struct breakpad_uuid_command uuid_cmd;
|
||||||
uuid_cmd.cmd = 0;
|
uuid_cmd.cmd = 0;
|
||||||
if (!WalkHeader(cpu_type, UUIDWalkerCB, &uuid_cmd))
|
if (!WalkHeader(cpu_type, cpu_subtype, UUIDWalkerCB, &uuid_cmd))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If we found the command, we'll have initialized the uuid_command
|
// 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;
|
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;
|
struct dylib_command dylib_cmd;
|
||||||
dylib_cmd.cmd = 0;
|
dylib_cmd.cmd = 0;
|
||||||
if (!WalkHeader(cpu_type, IDWalkerCB, &dylib_cmd))
|
if (!WalkHeader(cpu_type, cpu_subtype, IDWalkerCB, &dylib_cmd))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If we found the command, we'll have initialized the dylib_command
|
// 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;
|
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;
|
update_function_ = &MachoID::UpdateCRC;
|
||||||
crc_ = 0;
|
crc_ = 0;
|
||||||
|
|
||||||
if (!WalkHeader(cpu_type, WalkerCB, this))
|
if (!WalkHeader(cpu_type, cpu_subtype, WalkerCB, this))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return crc_;
|
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;
|
update_function_ = &MachoID::UpdateMD5;
|
||||||
|
|
||||||
MD5Init(&md5_context_);
|
MD5Init(&md5_context_);
|
||||||
|
|
||||||
if (!WalkHeader(cpu_type, WalkerCB, this))
|
if (!WalkHeader(cpu_type, cpu_subtype, WalkerCB, this))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MD5Final(identifier, &md5_context_);
|
MD5Final(identifier, &md5_context_);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MachoID::WalkHeader(int cpu_type,
|
bool MachoID::WalkHeader(cpu_type_t cpu_type,
|
||||||
|
cpu_subtype_t cpu_subtype,
|
||||||
MachoWalker::LoadCommandCallback callback,
|
MachoWalker::LoadCommandCallback callback,
|
||||||
void *context) {
|
void *context) {
|
||||||
if (memory_) {
|
if (memory_) {
|
||||||
MachoWalker walker(memory_, memory_size_, callback, context);
|
MachoWalker walker(memory_, memory_size_, callback, context);
|
||||||
return walker.WalkHeader(cpu_type);
|
return walker.WalkHeader(cpu_type, cpu_subtype);
|
||||||
} else {
|
} else {
|
||||||
MachoWalker walker(path_, callback, context);
|
MachoWalker walker(path_, callback, context);
|
||||||
return walker.WalkHeader(cpu_type);
|
return walker.WalkHeader(cpu_type, cpu_subtype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#define COMMON_MAC_MACHO_ID_H__
|
#define COMMON_MAC_MACHO_ID_H__
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <mach/machine.h>
|
||||||
#include <mach-o/loader.h>
|
#include <mach-o/loader.h>
|
||||||
|
|
||||||
#include "common/mac/macho_walker.h"
|
#include "common/mac/macho_walker.h"
|
||||||
|
@ -48,22 +49,32 @@ class MachoID {
|
||||||
MachoID(const char *path, void *memory, size_t size);
|
MachoID(const char *path, void *memory, size_t size);
|
||||||
~MachoID();
|
~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.
|
// 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.
|
// 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
|
// For the given |cpu_type| and |cpu_subtype|, return the Adler32 CRC for the
|
||||||
// segment(s).
|
// mach-o data segment(s).
|
||||||
// Return 0 on error (e.g., if the file is not a mach-o file)
|
// 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
|
// 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:
|
private:
|
||||||
// Signature of class member function to be called with data read from file
|
// 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);
|
void Update(MachoWalker *walker, off_t offset, size_t size);
|
||||||
|
|
||||||
// Factory for the MachoWalker
|
// Factory for the MachoWalker
|
||||||
bool WalkHeader(int cpu_type, MachoWalker::LoadCommandCallback callback,
|
bool WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype,
|
||||||
void *context);
|
MachoWalker::LoadCommandCallback callback, void *context);
|
||||||
|
|
||||||
// The callback from the MachoWalker for CRC and MD5
|
// The callback from the MachoWalker for CRC and MD5
|
||||||
static bool WalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
|
static bool WalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
|
||||||
|
|
|
@ -79,21 +79,18 @@ MachoWalker::~MachoWalker() {
|
||||||
close(file_);
|
close(file_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MachoWalker::ValidateCPUType(int cpu_type) {
|
bool MachoWalker::WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) {
|
||||||
// If the user didn't specify, use the local architecture.
|
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) {
|
if (cpu_type == 0) {
|
||||||
const NXArchInfo *arch = NXGetLocalArchInfo();
|
const NXArchInfo *arch = NXGetLocalArchInfo();
|
||||||
assert(arch);
|
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;
|
off_t offset;
|
||||||
if (FindHeader(valid_cpu_type, offset)) {
|
if (FindHeader(valid_cpu_type, valid_cpu_subtype, offset)) {
|
||||||
if (cpu_type & CPU_ARCH_ABI64)
|
if (cpu_type & CPU_ARCH_ABI64)
|
||||||
return WalkHeader64AtOffset(offset);
|
return WalkHeader64AtOffset(offset);
|
||||||
|
|
||||||
|
@ -131,8 +128,9 @@ bool MachoWalker::CurrentHeader(struct mach_header_64 *header, off_t *offset) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MachoWalker::FindHeader(int cpu_type, off_t &offset) {
|
bool MachoWalker::FindHeader(cpu_type_t cpu_type,
|
||||||
int valid_cpu_type = ValidateCPUType(cpu_type);
|
cpu_subtype_t cpu_subtype,
|
||||||
|
off_t &offset) {
|
||||||
// Read the magic bytes that's common amongst all mach-o files
|
// Read the magic bytes that's common amongst all mach-o files
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
if (!ReadBytes(&magic, sizeof(magic), 0))
|
if (!ReadBytes(&magic, sizeof(magic), 0))
|
||||||
|
@ -153,15 +151,18 @@ bool MachoWalker::FindHeader(int cpu_type, off_t &offset) {
|
||||||
if (!is_fat) {
|
if (!is_fat) {
|
||||||
// If we don't have a fat header, check if the cpu type matches the single
|
// If we don't have a fat header, check if the cpu type matches the single
|
||||||
// header
|
// header
|
||||||
cpu_type_t header_cpu_type;
|
struct mach_header header;
|
||||||
if (!ReadBytes(&header_cpu_type, sizeof(header_cpu_type), offset))
|
if (!ReadBytes(&header, sizeof(header), 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (magic == MH_CIGAM || magic == MH_CIGAM_64)
|
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;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
return true;
|
return true;
|
||||||
|
@ -186,7 +187,9 @@ bool MachoWalker::FindHeader(int cpu_type, off_t &offset) {
|
||||||
if (NXHostByteOrder() != NX_BigEndian)
|
if (NXHostByteOrder() != NX_BigEndian)
|
||||||
swap_fat_arch(&arch, 1, NXHostByteOrder());
|
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;
|
offset = arch.offset;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#ifndef COMMON_MAC_MACHO_WALKER_H__
|
#ifndef COMMON_MAC_MACHO_WALKER_H__
|
||||||
#define COMMON_MAC_MACHO_WALKER_H__
|
#define COMMON_MAC_MACHO_WALKER_H__
|
||||||
|
|
||||||
|
#include <mach/machine.h>
|
||||||
#include <mach-o/loader.h>
|
#include <mach-o/loader.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -56,16 +57,14 @@ class MachoWalker {
|
||||||
void *context);
|
void *context);
|
||||||
~MachoWalker();
|
~MachoWalker();
|
||||||
|
|
||||||
// Begin walking the header for |cpu_type|. If |cpu_type| is 0, then the
|
// Begin walking the header for |cpu_type| and |cpu_subtype|. If |cpu_type|
|
||||||
// native cpu type is used. Otherwise, accepted values are listed in
|
// is 0, then the native cpu type is used. Otherwise, accepted values are
|
||||||
// /usr/include/mach/machine.h (e.g., CPU_TYPE_X86 or CPU_TYPE_POWERPC).
|
// listed in /usr/include/mach/machine.h (e.g., CPU_TYPE_X86 or
|
||||||
// Returns false if opening the file failed or if the |cpu_type| is not
|
// CPU_TYPE_POWERPC). If |cpu_subtype| is CPU_SUBTYPE_MULTIPLE, the match is
|
||||||
// present in the file.
|
// only done on |cpu_type|.
|
||||||
bool WalkHeader(int cpu_type);
|
// Returns false if opening the file failed or if the |cpu_type|/|cpu_subtype|
|
||||||
|
// is not present in the file.
|
||||||
// Locate (if any) the header offset for |cpu_type| and return in |offset|.
|
bool WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype);
|
||||||
// Return true if found, false otherwise.
|
|
||||||
bool FindHeader(int cpu_type, off_t &offset);
|
|
||||||
|
|
||||||
// Read |size| bytes from the opened file at |offset| into |buffer|
|
// Read |size| bytes from the opened file at |offset| into |buffer|
|
||||||
bool ReadBytes(void *buffer, size_t size, off_t offset);
|
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);
|
bool CurrentHeader(struct mach_header_64 *header, off_t *offset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Validate the |cpu_type|
|
// Locate (if any) the header offset for |cpu_type| and return in |offset|.
|
||||||
int ValidateCPUType(int cpu_type);
|
// 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
|
// Process an individual header starting at |offset| from the start of the
|
||||||
// file. Return true if successful, false otherwise.
|
// file. Return true if successful, false otherwise.
|
||||||
|
|
Loading…
Reference in a new issue