aboutsummaryrefslogtreecommitdiff
path: root/src/client/mac/handler/dynamic_images.cc
diff options
context:
space:
mode:
authornealsid <nealsid@4c0a9323-5329-0410-9bdc-e9ce6186880e>2008-10-22 05:08:50 +0000
committernealsid <nealsid@4c0a9323-5329-0410-9bdc-e9ce6186880e>2008-10-22 05:08:50 +0000
commit32441cc0608ddaf81885d23acf63f4b53cb73744 (patch)
tree531187cc989b4008635f5f398679742e7ee94e64 /src/client/mac/handler/dynamic_images.cc
parentIssue 276 - generate GUIDs ahead of time in Linux handler. r=Liu Li (diff)
downloadbreakpad-32441cc0608ddaf81885d23acf63f4b53cb73744.tar.xz
Issue 181: Add version info for Mac OS X modules. Found by iterating over load commands until I found LC_ID_DYLIB. Also modified crash_report to generate version number. Also added suspend/resume capability to exception handler, necessary because exception handling can behave strangely across fork() calls. Also added fix for filtering out functions with no line number information, and for filtering out some multiple inheritance glue the compiler generates.
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@291 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client/mac/handler/dynamic_images.cc')
-rw-r--r--src/client/mac/handler/dynamic_images.cc54
1 files changed, 38 insertions, 16 deletions
diff --git a/src/client/mac/handler/dynamic_images.cc b/src/client/mac/handler/dynamic_images.cc
index 7bbcd566..ac1cca40 100644
--- a/src/client/mac/handler/dynamic_images.cc
+++ b/src/client/mac/handler/dynamic_images.cc
@@ -187,7 +187,7 @@ void* ReadTaskMemory(task_port_t target_task,
//==============================================================================
// Initializes vmaddr_, vmsize_, and slide_
-void DynamicImage::CalculateMemoryInfo() {
+void DynamicImage::CalculateMemoryAndVersionInfo() {
breakpad_mach_header *header = GetMachHeader();
// unless we can process the header, ensure that calls to
@@ -195,7 +195,11 @@ void DynamicImage::CalculateMemoryInfo() {
vmaddr_ = 0;
vmsize_ = 0;
slide_ = 0;
+ version_ = 0;
+ bool foundTextSection = false;
+ bool foundDylibIDCommand = false;
+
#if __LP64__
if(header->magic != MH_MAGIC_64) {
return;
@@ -206,30 +210,48 @@ void DynamicImage::CalculateMemoryInfo() {
}
#endif
- const struct load_command *cmd =
- reinterpret_cast<const struct load_command *>(header + 1);
-
- for (unsigned int i = 0; cmd && (i < header->ncmds); ++i) {
#ifdef __LP64__
- if (cmd->cmd == LC_SEGMENT_64) {
+ const uint32_t segmentLoadCommand = LC_SEGMENT_64;
#else
- if (cmd->cmd == LC_SEGMENT) {
+ const uint32_t segmentLoadCommand = LC_SEGMENT;
#endif
- const breakpad_mach_segment_command *seg =
- reinterpret_cast<const breakpad_mach_segment_command *>(cmd);
- if (!strcmp(seg->segname, "__TEXT")) {
- vmaddr_ = seg->vmaddr;
- vmsize_ = seg->vmsize;
- slide_ = 0;
+ const struct load_command *cmd =
+ reinterpret_cast<const struct load_command *>(header + 1);
- if (seg->fileoff == 0 && seg->filesize != 0) {
- slide_ = (uintptr_t)GetLoadAddress() - (uintptr_t)seg->vmaddr;
+ for (unsigned int i = 0; cmd && (i < header->ncmds); ++i) {
+ if (!foundTextSection) {
+ if (cmd->cmd == segmentLoadCommand) {
+ const breakpad_mach_segment_command *seg =
+ reinterpret_cast<const breakpad_mach_segment_command *>(cmd);
+
+ if (!strcmp(seg->segname, "__TEXT")) {
+ vmaddr_ = seg->vmaddr;
+ vmsize_ = seg->vmsize;
+ slide_ = 0;
+
+ if (seg->fileoff == 0 && seg->filesize != 0) {
+ slide_ = (uintptr_t)GetLoadAddress() - (uintptr_t)seg->vmaddr;
+ }
+ foundTextSection = true;
}
- return;
}
}
+ if (!foundDylibIDCommand) {
+ if (cmd->cmd == LC_ID_DYLIB) {
+ const struct dylib_command *dc =
+ reinterpret_cast<const struct dylib_command *>(cmd);
+
+ version_ = dc->dylib.current_version;
+ foundDylibIDCommand = true;
+ }
+ }
+
+ if (foundDylibIDCommand && foundTextSection) {
+ return;
+ }
+
cmd = reinterpret_cast<const struct load_command *>
(reinterpret_cast<const char *>(cmd) + cmd->cmdsize);
}