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.cc39
1 files changed, 36 insertions, 3 deletions
diff --git a/src/common/mac/macho_walker.cc b/src/common/mac/macho_walker.cc
index 5e9de5f4..81ba3bb5 100644
--- a/src/common/mac/macho_walker.cc
+++ b/src/common/mac/macho_walker.cc
@@ -38,6 +38,7 @@
#include <mach-o/arch.h>
#include <mach-o/loader.h>
#include <mach-o/swap.h>
+#include <string.h>
#include <unistd.h>
#include "common/mac/macho_walker.h"
@@ -93,6 +94,16 @@ bool MachoWalker::ReadBytes(void *buffer, size_t size, off_t offset) {
return pread(file_, buffer, size, offset) == (ssize_t)size;
}
+bool MachoWalker::CurrentHeader(struct mach_header_64 *header, off_t *offset) {
+ if (current_header_) {
+ memcpy(header, current_header_, sizeof(mach_header_64));
+ *offset = current_header_offset_;
+ return true;
+ }
+
+ return false;
+}
+
bool MachoWalker::FindHeader(int cpu_type, off_t &offset) {
int valid_cpu_type = ValidateCPUType(cpu_type);
// Read the magic bytes that's common amongst all mach-o files
@@ -165,8 +176,22 @@ bool MachoWalker::WalkHeaderAtOffset(off_t offset) {
bool swap = (header.magic == MH_CIGAM);
if (swap)
swap_mach_header(&header, NXHostByteOrder());
-
- return WalkHeaderCore(offset + sizeof(header), header.ncmds, swap);
+
+ // Copy the data into the mach_header_64 structure. Since the 32-bit and
+ // 64-bit only differ in the last field (reserved), this is safe to do.
+ struct mach_header_64 header64;
+ memcpy((void *)&header64, (const void *)&header, sizeof(header));
+ header64.reserved = 0;
+
+ current_header_ = &header64;
+ current_header_size_ = sizeof(header); // 32-bit, not 64-bit
+ current_header_offset_ = offset;
+ offset += current_header_size_;
+ bool result = WalkHeaderCore(offset, header.ncmds, swap);
+ current_header_ = NULL;
+ current_header_size_ = 0;
+ current_header_offset_ = 0;
+ return result;
}
bool MachoWalker::WalkHeader64AtOffset(off_t offset) {
@@ -178,7 +203,15 @@ bool MachoWalker::WalkHeader64AtOffset(off_t offset) {
if (swap)
swap_mach_header_64(&header, NXHostByteOrder());
- return WalkHeaderCore(offset + sizeof(header), header.ncmds, swap);
+ current_header_ = &header;
+ current_header_size_ = sizeof(header);
+ current_header_offset_ = offset;
+ offset += current_header_size_;
+ bool result = WalkHeaderCore(offset, header.ncmds, swap);
+ current_header_ = NULL;
+ current_header_size_ = 0;
+ current_header_offset_ = 0;
+ return result;
}
bool MachoWalker::WalkHeaderCore(off_t offset, uint32_t number_of_commands,