diff options
Diffstat (limited to 'src/common/mac')
-rw-r--r-- | src/common/mac/macho_id.cc | 41 | ||||
-rw-r--r-- | src/common/mac/macho_id.h | 15 | ||||
-rw-r--r-- | src/common/mac/macho_walker.cc | 28 | ||||
-rw-r--r-- | src/common/mac/macho_walker.h | 17 |
4 files changed, 77 insertions, 24 deletions
diff --git a/src/common/mac/macho_id.cc b/src/common/mac/macho_id.cc index 44e78205..ce0ecff3 100644 --- a/src/common/mac/macho_id.cc +++ b/src/common/mac/macho_id.cc @@ -52,17 +52,24 @@ extern "C" { // necessary for Leopard namespace MacFileUtilities { MachoID::MachoID(const char *path) - : file_(0), + : memory_(0), + memory_size_(0), + crc_(0), + md5_context_(), + update_function_(NULL) { + strlcpy(path_, path, sizeof(path_)); +} + +MachoID::MachoID(const char *path, void *memory, size_t size) + : memory_(memory), + memory_size_(size), crc_(0), md5_context_(), update_function_(NULL) { strlcpy(path_, path, sizeof(path_)); - file_ = open(path, O_RDONLY); } MachoID::~MachoID() { - if (file_ != -1) - close(file_); } // The CRC info is from http://en.wikipedia.org/wiki/Adler-32 @@ -144,10 +151,8 @@ void MachoID::Update(MachoWalker *walker, off_t offset, size_t size) { bool MachoID::UUIDCommand(int cpu_type, unsigned char bytes[16]) { struct breakpad_uuid_command uuid_cmd; - MachoWalker walker(path_, UUIDWalkerCB, &uuid_cmd); - uuid_cmd.cmd = 0; - if (!walker.WalkHeader(cpu_type)) + if (!WalkHeader(cpu_type, UUIDWalkerCB, &uuid_cmd)) return false; // If we found the command, we'll have initialized the uuid_command @@ -162,10 +167,8 @@ bool MachoID::UUIDCommand(int cpu_type, unsigned char bytes[16]) { bool MachoID::IDCommand(int cpu_type, unsigned char identifier[16]) { struct dylib_command dylib_cmd; - MachoWalker walker(path_, IDWalkerCB, &dylib_cmd); - dylib_cmd.cmd = 0; - if (!walker.WalkHeader(cpu_type)) + if (!WalkHeader(cpu_type, IDWalkerCB, &dylib_cmd)) return false; // If we found the command, we'll have initialized the dylib_command @@ -204,29 +207,39 @@ bool MachoID::IDCommand(int cpu_type, unsigned char identifier[16]) { } uint32_t MachoID::Adler32(int cpu_type) { - MachoWalker walker(path_, WalkerCB, this); update_function_ = &MachoID::UpdateCRC; crc_ = 0; - if (!walker.WalkHeader(cpu_type)) + if (!WalkHeader(cpu_type, WalkerCB, this)) return 0; return crc_; } bool MachoID::MD5(int cpu_type, unsigned char identifier[16]) { - MachoWalker walker(path_, WalkerCB, this); update_function_ = &MachoID::UpdateMD5; MD5Init(&md5_context_); - if (!walker.WalkHeader(cpu_type)) + if (!WalkHeader(cpu_type, WalkerCB, this)) return false; MD5Final(identifier, &md5_context_); return true; } +bool MachoID::WalkHeader(int cpu_type, + MachoWalker::LoadCommandCallback callback, + void *context) { + if (memory_) { + MachoWalker walker(memory_, memory_size_, callback, context); + return walker.WalkHeader(cpu_type); + } else { + MachoWalker walker(path_, callback, context); + return walker.WalkHeader(cpu_type); + } +} + // static bool MachoID::WalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, bool swap, void *context) { diff --git a/src/common/mac/macho_id.h b/src/common/mac/macho_id.h index 9bcefc56..a5338120 100644 --- a/src/common/mac/macho_id.h +++ b/src/common/mac/macho_id.h @@ -37,15 +37,15 @@ #include <limits.h> #include <mach-o/loader.h> +#include "common/mac/macho_walker.h" #include "common/md5.h" namespace MacFileUtilities { -class MachoWalker; - class MachoID { public: MachoID(const char *path); + MachoID(const char *path, void *memory, size_t size); ~MachoID(); // For the given |cpu_type|, return a UUID from the LC_UUID command. @@ -80,6 +80,10 @@ class MachoID { // Bottleneck for update routines void Update(MachoWalker *walker, off_t offset, size_t size); + // Factory for the MachoWalker + bool WalkHeader(int cpu_type, 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, bool swap, void *context); @@ -95,8 +99,11 @@ class MachoID { // File path char path_[PATH_MAX]; - // File descriptor - int file_; + // Memory region to read from + void *memory_; + + // Size of the memory region + size_t memory_size_; // The current crc value uint32_t crc_; diff --git a/src/common/mac/macho_walker.cc b/src/common/mac/macho_walker.cc index 3e8fe211..00fde03e 100644 --- a/src/common/mac/macho_walker.cc +++ b/src/common/mac/macho_walker.cc @@ -52,6 +52,8 @@ namespace MacFileUtilities { MachoWalker::MachoWalker(const char *path, LoadCommandCallback callback, void *context) : file_(0), + memory_(NULL), + memory_size_(0), callback_(callback), callback_context_(context), current_header_(NULL), @@ -60,6 +62,18 @@ MachoWalker::MachoWalker(const char *path, LoadCommandCallback callback, file_ = open(path, O_RDONLY); } +MachoWalker::MachoWalker(void *memory, size_t size, + LoadCommandCallback callback, void *context) + : file_(0), + memory_(memory), + memory_size_(size), + callback_(callback), + callback_context_(context), + current_header_(NULL), + current_header_size_(0), + current_header_offset_(0) { +} + MachoWalker::~MachoWalker() { if (file_ != -1) close(file_); @@ -90,7 +104,19 @@ bool MachoWalker::WalkHeader(int cpu_type) { } bool MachoWalker::ReadBytes(void *buffer, size_t size, off_t offset) { - return pread(file_, buffer, size, offset) == (ssize_t)size; + if (memory_) { + bool result = true; + if (offset + size > memory_size_) { + size = memory_size_ - offset; + result = false; + } + if (size < 0) + return false; + memcpy(buffer, static_cast<char *>(memory_) + offset, size); + return result; + } else { + return pread(file_, buffer, size, offset) == (ssize_t)size; + } } bool MachoWalker::CurrentHeader(struct mach_header_64 *header, off_t *offset) { diff --git a/src/common/mac/macho_walker.h b/src/common/mac/macho_walker.h index 0d30b5c0..cee3eb8d 100644 --- a/src/common/mac/macho_walker.h +++ b/src/common/mac/macho_walker.h @@ -52,7 +52,8 @@ class MachoWalker { off_t offset, bool swap, void *context); MachoWalker(const char *path, LoadCommandCallback callback, void *context); - MachoWalker(int file_descriptor, LoadCommandCallback callback, void *context); + MachoWalker(void *memory, size_t size, LoadCommandCallback callback, + void *context); ~MachoWalker(); // Begin walking the header for |cpu_type|. If |cpu_type| is 0, then the @@ -68,7 +69,7 @@ class MachoWalker { // Read |size| bytes from the opened file at |offset| into |buffer| bool ReadBytes(void *buffer, size_t size, off_t offset); - + // Return the current header and header offset bool CurrentHeader(struct mach_header_64 *header, off_t *offset); @@ -87,19 +88,25 @@ class MachoWalker { // File descriptor to the opened file int file_; + // Memory location to read from. + void *memory_; + + // Size of the memory segment we can read from. + size_t memory_size_; + // User specified callback & context LoadCommandCallback callback_; void *callback_context_; - + // Current header, size, and offset. The mach_header_64 is used for both // 32-bit and 64-bit headers because they only differ in their last field - // (reserved). By adding the |current_header_size_| and the + // (reserved). By adding the |current_header_size_| and the // |current_header_offset_|, you can determine the offset in the file just // after the header. struct mach_header_64 *current_header_; unsigned long current_header_size_; off_t current_header_offset_; - + private: MachoWalker(const MachoWalker &); MachoWalker &operator=(const MachoWalker &); |