aboutsummaryrefslogtreecommitdiff
path: root/src/common/mac/macho_walker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/mac/macho_walker.cc')
-rw-r--r--src/common/mac/macho_walker.cc37
1 files changed, 20 insertions, 17 deletions
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;
}