aboutsummaryrefslogtreecommitdiff
path: root/src/common/mac
diff options
context:
space:
mode:
authorqsr@chromium.org <qsr@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2011-10-20 15:22:48 +0000
committerqsr@chromium.org <qsr@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2011-10-20 15:22:48 +0000
commit446616ee2276a4b9a30adf796c3a7bc692eb8239 (patch)
tree7addca2038878761508fc6c3597b32be796ae842 /src/common/mac
parentFix svn:executable and svn:eol-style properties in src/client/windows. (diff)
downloadbreakpad-446616ee2276a4b9a30adf796c3a7bc692eb8239.tar.xz
Allow to retrieve id of a module from memory instead of going to disk for iOS.
Allow macho_id and macho_walker to read data from memory. Wire up this when reading module on iOS. Review URL: http://breakpad.appspot.com/319001 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@873 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/mac')
-rw-r--r--src/common/mac/macho_id.cc41
-rw-r--r--src/common/mac/macho_id.h15
-rw-r--r--src/common/mac/macho_walker.cc28
-rw-r--r--src/common/mac/macho_walker.h17
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 &);