From cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001 Mon Sep 17 00:00:00 2001 From: nealsid Date: Wed, 8 Oct 2008 23:56:02 +0000 Subject: Added DWARF support to Breakpad client. Thanks to Google for open sourcing their DWARF code! Modified dump_syms to detect dSYM bundles or a binary with DWARF data appropriately, and convert data from DWARF reader to dump_syms native structures R=danny.berlin (original writer of DWARF code) git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@286 4c0a9323-5329-0410-9bdc-e9ce6186880e --- .../crash_report.xcodeproj/project.pbxproj | 20 +++ .../dump_syms/dump_syms.xcodeproj/project.pbxproj | 61 ++++++--- src/tools/mac/dump_syms/dump_syms_tool.mm | 142 +++++++++++++++++++++ 3 files changed, 207 insertions(+), 16 deletions(-) create mode 100644 src/tools/mac/dump_syms/dump_syms_tool.mm (limited to 'src/tools/mac') diff --git a/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj b/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj index f3e04d61..4b31f5ff 100644 --- a/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj +++ b/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj @@ -43,6 +43,9 @@ 9BE650B50B52FE3000611104 /* macho_id.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BE650AF0B52FE3000611104 /* macho_id.h */; }; 9BE650B60B52FE3000611104 /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650B00B52FE3000611104 /* macho_walker.cc */; }; 9BE650B70B52FE3000611104 /* macho_walker.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BE650B10B52FE3000611104 /* macho_walker.h */; }; + F9C7ECE50E8ABCA600E953AD /* bytereader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9C7ECE20E8ABCA600E953AD /* bytereader.cc */; }; + F9C7ECE60E8ABCA600E953AD /* dwarf2reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9C7ECE30E8ABCA600E953AD /* dwarf2reader.cc */; }; + F9C7ECE70E8ABCA600E953AD /* functioninfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9C7ECE40E8ABCA600E953AD /* functioninfo.cc */; }; FD6625CD0CF4D45C004AC844 /* stackwalker_amd64.cc in Sources */ = {isa = PBXBuildFile; fileRef = FD6625C40CF4D438004AC844 /* stackwalker_amd64.cc */; }; FD8EDEAE0CADDAD400A5EDF1 /* stackwalker_sparc.cc in Sources */ = {isa = PBXBuildFile; fileRef = FD8EDEAC0CADDAD400A5EDF1 /* stackwalker_sparc.cc */; }; FD8EDEAF0CADDAD400A5EDF1 /* stackwalker_sparc.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FD8EDEAD0CADDAD400A5EDF1 /* stackwalker_sparc.h */; }; @@ -127,6 +130,9 @@ 9BE650AF0B52FE3000611104 /* macho_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_id.h; path = ../../../common/mac/macho_id.h; sourceTree = SOURCE_ROOT; }; 9BE650B00B52FE3000611104 /* macho_walker.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_walker.cc; path = ../../../common/mac/macho_walker.cc; sourceTree = SOURCE_ROOT; }; 9BE650B10B52FE3000611104 /* macho_walker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_walker.h; path = ../../../common/mac/macho_walker.h; sourceTree = SOURCE_ROOT; }; + F9C7ECE20E8ABCA600E953AD /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/mac/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; }; + F9C7ECE30E8ABCA600E953AD /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/mac/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; }; + F9C7ECE40E8ABCA600E953AD /* functioninfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = functioninfo.cc; path = ../../../common/mac/dwarf/functioninfo.cc; sourceTree = SOURCE_ROOT; }; FD6625C40CF4D438004AC844 /* stackwalker_amd64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_amd64.cc; path = ../../../processor/stackwalker_amd64.cc; sourceTree = SOURCE_ROOT; }; FD6625C50CF4D438004AC844 /* stackwalker_amd64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stackwalker_amd64.h; path = ../../../processor/stackwalker_amd64.h; sourceTree = SOURCE_ROOT; }; FD8EDEAC0CADDAD400A5EDF1 /* stackwalker_sparc.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_sparc.cc; path = ../../../processor/stackwalker_sparc.cc; sourceTree = SOURCE_ROOT; }; @@ -148,6 +154,7 @@ 08FB7794FE84155DC02AAC07 /* crash_report */ = { isa = PBXGroup; children = ( + F9C7ECE10E8ABC7F00E953AD /* DWARF */, 5578003E0BE1F28500EC23E0 /* macho_utilities.cc */, 5578003F0BE1F28500EC23E0 /* macho_utilities.h */, 9BDF192D0B1BC15D00F8391B /* dump_syms.h */, @@ -269,6 +276,16 @@ name = common; sourceTree = ""; }; + F9C7ECE10E8ABC7F00E953AD /* DWARF */ = { + isa = PBXGroup; + children = ( + F9C7ECE20E8ABCA600E953AD /* bytereader.cc */, + F9C7ECE30E8ABCA600E953AD /* dwarf2reader.cc */, + F9C7ECE40E8ABCA600E953AD /* functioninfo.cc */, + ); + name = DWARF; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -332,6 +349,9 @@ 8B40BDC00C0638E4009535AF /* logging.cc in Sources */, FD8EDEAE0CADDAD400A5EDF1 /* stackwalker_sparc.cc in Sources */, FD6625CD0CF4D45C004AC844 /* stackwalker_amd64.cc in Sources */, + F9C7ECE50E8ABCA600E953AD /* bytereader.cc in Sources */, + F9C7ECE60E8ABCA600E953AD /* dwarf2reader.cc in Sources */, + F9C7ECE70E8ABCA600E953AD /* functioninfo.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj b/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj index 3a19cb96..6f22c0d0 100644 --- a/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj +++ b/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj @@ -8,17 +8,15 @@ /* Begin PBXBuildFile section */ 5578008B0BE1F3AB00EC23E0 /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 557800890BE1F3AB00EC23E0 /* macho_utilities.cc */; }; - 5578008C0BE1F3AB00EC23E0 /* macho_utilities.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5578008A0BE1F3AB00EC23E0 /* macho_utilities.h */; }; 8DD76F9A0486AA7600D96B5E /* dump_syms.mm in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* dump_syms.mm */; settings = {ATTRIBUTES = (); }; }; 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; }; - 9BDF186F0B1BB43700F8391B /* dump_syms.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BDF186D0B1BB43700F8391B /* dump_syms.h */; }; - 9BDF18700B1BB43700F8391B /* dump_syms_tool.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF186E0B1BB43700F8391B /* dump_syms_tool.m */; }; + 9BDF18700B1BB43700F8391B /* dump_syms_tool.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF186E0B1BB43700F8391B /* dump_syms_tool.mm */; }; 9BE650470B52F6D800611104 /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650410B52F6D800611104 /* file_id.cc */; }; - 9BE650480B52F6D800611104 /* file_id.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BE650420B52F6D800611104 /* file_id.h */; }; 9BE650490B52F6D800611104 /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650430B52F6D800611104 /* macho_id.cc */; }; - 9BE6504A0B52F6D800611104 /* macho_id.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BE650440B52F6D800611104 /* macho_id.h */; }; 9BE6504B0B52F6D800611104 /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650450B52F6D800611104 /* macho_walker.cc */; }; - 9BE6504C0B52F6D800611104 /* macho_walker.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BE650460B52F6D800611104 /* macho_walker.h */; }; + F95B42320E0E22D100DBDE83 /* bytereader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F95B422C0E0E22D100DBDE83 /* bytereader.cc */; }; + F95B42330E0E22D100DBDE83 /* dwarf2reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */; }; + F9C7ED430E8AD93000E953AD /* functioninfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9C7ED420E8AD93000E953AD /* functioninfo.cc */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -28,11 +26,6 @@ dstPath = /usr/share/man/man1/; dstSubfolderSpec = 0; files = ( - 9BDF186F0B1BB43700F8391B /* dump_syms.h in CopyFiles */, - 9BE650480B52F6D800611104 /* file_id.h in CopyFiles */, - 9BE6504A0B52F6D800611104 /* macho_id.h in CopyFiles */, - 9BE6504C0B52F6D800611104 /* macho_walker.h in CopyFiles */, - 5578008C0BE1F3AB00EC23E0 /* macho_utilities.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; @@ -45,13 +38,22 @@ 5578008A0BE1F3AB00EC23E0 /* macho_utilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_utilities.h; path = ../../../common/mac/macho_utilities.h; sourceTree = SOURCE_ROOT; }; 8DD76FA10486AA7600D96B5E /* dump_syms */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dump_syms; sourceTree = BUILT_PRODUCTS_DIR; }; 9BDF186D0B1BB43700F8391B /* dump_syms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dump_syms.h; path = ../../../common/mac/dump_syms.h; sourceTree = ""; }; - 9BDF186E0B1BB43700F8391B /* dump_syms_tool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = dump_syms_tool.m; sourceTree = ""; }; + 9BDF186E0B1BB43700F8391B /* dump_syms_tool.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = dump_syms_tool.mm; sourceTree = ""; }; 9BE650410B52F6D800611104 /* file_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = file_id.cc; path = ../../../common/mac/file_id.cc; sourceTree = SOURCE_ROOT; }; 9BE650420B52F6D800611104 /* file_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = file_id.h; path = ../../../common/mac/file_id.h; sourceTree = SOURCE_ROOT; }; 9BE650430B52F6D800611104 /* macho_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_id.cc; path = ../../../common/mac/macho_id.cc; sourceTree = SOURCE_ROOT; }; 9BE650440B52F6D800611104 /* macho_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_id.h; path = ../../../common/mac/macho_id.h; sourceTree = SOURCE_ROOT; }; 9BE650450B52F6D800611104 /* macho_walker.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_walker.cc; path = ../../../common/mac/macho_walker.cc; sourceTree = SOURCE_ROOT; }; 9BE650460B52F6D800611104 /* macho_walker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_walker.h; path = ../../../common/mac/macho_walker.h; sourceTree = SOURCE_ROOT; }; + F95B422B0E0E22D100DBDE83 /* bytereader-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "bytereader-inl.h"; path = "../../../common/mac/dwarf/bytereader-inl.h"; sourceTree = SOURCE_ROOT; }; + F95B422C0E0E22D100DBDE83 /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/mac/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; }; + F95B422D0E0E22D100DBDE83 /* bytereader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bytereader.h; path = ../../../common/mac/dwarf/bytereader.h; sourceTree = SOURCE_ROOT; }; + F95B422E0E0E22D100DBDE83 /* dwarf2enums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2enums.h; path = ../../../common/mac/dwarf/dwarf2enums.h; sourceTree = SOURCE_ROOT; }; + F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/mac/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; }; + F95B42300E0E22D100DBDE83 /* dwarf2reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2reader.h; path = ../../../common/mac/dwarf/dwarf2reader.h; sourceTree = SOURCE_ROOT; }; + F95B42310E0E22D100DBDE83 /* line_state_machine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = line_state_machine.h; path = ../../../common/mac/dwarf/line_state_machine.h; sourceTree = SOURCE_ROOT; }; + F9C7ED420E8AD93000E953AD /* functioninfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = functioninfo.cc; path = ../../../common/mac/dwarf/functioninfo.cc; sourceTree = SOURCE_ROOT; }; + F9F5344D0E7C902C0012363F /* functioninfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = functioninfo.h; path = ../../../common/mac/dwarf/functioninfo.h; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -69,6 +71,7 @@ 08FB7794FE84155DC02AAC07 /* dump_syms */ = { isa = PBXGroup; children = ( + F9F5344B0E7C8FFC0012363F /* DWARF */, 557800890BE1F3AB00EC23E0 /* macho_utilities.cc */, 5578008A0BE1F3AB00EC23E0 /* macho_utilities.h */, 9BE650410B52F6D800611104 /* file_id.cc */, @@ -79,7 +82,7 @@ 9BE650460B52F6D800611104 /* macho_walker.h */, 9BDF186D0B1BB43700F8391B /* dump_syms.h */, 08FB7796FE84155DC02AAC07 /* dump_syms.mm */, - 9BDF186E0B1BB43700F8391B /* dump_syms_tool.m */, + 9BDF186E0B1BB43700F8391B /* dump_syms_tool.mm */, 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */, 1AB674ADFE9D54B511CA2CBB /* Products */, ); @@ -102,6 +105,22 @@ name = Products; sourceTree = ""; }; + F9F5344B0E7C8FFC0012363F /* DWARF */ = { + isa = PBXGroup; + children = ( + F9C7ED420E8AD93000E953AD /* functioninfo.cc */, + F9F5344D0E7C902C0012363F /* functioninfo.h */, + F95B422E0E0E22D100DBDE83 /* dwarf2enums.h */, + F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */, + F95B42300E0E22D100DBDE83 /* dwarf2reader.h */, + F95B422D0E0E22D100DBDE83 /* bytereader.h */, + F95B422B0E0E22D100DBDE83 /* bytereader-inl.h */, + F95B422C0E0E22D100DBDE83 /* bytereader.cc */, + F95B42310E0E22D100DBDE83 /* line_state_machine.h */, + ); + name = DWARF; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -129,9 +148,11 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "dump_syms" */; + compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 08FB7794FE84155DC02AAC07 /* dump_syms */; projectDirPath = ""; + projectRoot = ""; targets = ( 8DD76F960486AA7600D96B5E /* dump_syms */, ); @@ -144,11 +165,14 @@ buildActionMask = 2147483647; files = ( 8DD76F9A0486AA7600D96B5E /* dump_syms.mm in Sources */, - 9BDF18700B1BB43700F8391B /* dump_syms_tool.m in Sources */, + F9C7ED430E8AD93000E953AD /* functioninfo.cc in Sources */, + 9BDF18700B1BB43700F8391B /* dump_syms_tool.mm in Sources */, 9BE650470B52F6D800611104 /* file_id.cc in Sources */, 9BE650490B52F6D800611104 /* macho_id.cc in Sources */, 9BE6504B0B52F6D800611104 /* macho_walker.cc in Sources */, 5578008B0BE1F3AB00EC23E0 /* macho_utilities.cc in Sources */, + F95B42320E0E22D100DBDE83 /* bytereader.cc in Sources */, + F95B42330E0E22D100DBDE83 /* dwarf2reader.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -158,7 +182,9 @@ 1DEB927508733DD40010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEPLOYMENT_POSTPROCESSING = YES; + GCC_CHAR_IS_UNSIGNED_CHAR = YES; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -186,10 +212,12 @@ ppc, i386, ); + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_CHAR_IS_UNSIGNED_CHAR = YES; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = ""; HEADER_SEARCH_PATHS = ( @@ -199,6 +227,7 @@ INSTALL_PATH = "$(HOME)/bin"; OTHER_LDFLAGS = "-lcrypto"; PRODUCT_NAME = dump_syms; + STRIP_STYLE = "non-global"; WARNING_CFLAGS = "-Wall"; ZERO_LINK = NO; }; diff --git a/src/tools/mac/dump_syms/dump_syms_tool.mm b/src/tools/mac/dump_syms/dump_syms_tool.mm new file mode 100644 index 00000000..827cea41 --- /dev/null +++ b/src/tools/mac/dump_syms/dump_syms_tool.mm @@ -0,0 +1,142 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// dump_syms_tool.m: Command line tool that uses the DumpSymbols class. +// TODO(waylonis): accept stdin + +#include +#include + +#include "dump_syms.h" +#include "common/mac/macho_utilities.h" + +typedef struct { + NSString *srcPath; + NSString *arch; + NSString *uuidStr; + BOOL result; +} Options; + +//============================================================================= +static void Start(Options *options) { + DumpSymbols *dump = [[DumpSymbols alloc] + initWithContentsOfFile:options->srcPath]; + + if (!dump) { + fprintf(stderr, "%s is not a valid Mach-o file\n", + [options->srcPath fileSystemRepresentation]); + options->result = NO; + return; + } + + if (![dump setArchitecture:options->arch]) { + fprintf(stderr, "Architecture: %s not available in %s\n", + [options->arch UTF8String], + [options->srcPath fileSystemRepresentation]); + options->result = NO; + return; + } + + options->result = [dump writeSymbolFile:@"-"]; +} + +//============================================================================= +static void Usage(int argc, const char *argv[]) { + fprintf(stderr, "Output a Breakpad symbol file from a Mach-o file.\n"); + fprintf(stderr, "Usage: %s [-a ppc|i386|x86] \n", + argv[0]); + fprintf(stderr, "\t-a: Architecture type [default: native]\n"); + fprintf(stderr, "\t-h: Usage\n"); + fprintf(stderr, "\t-?: Usage\n"); +} + +//============================================================================= +static void SetupOptions(int argc, const char *argv[], Options *options) { + extern int optind; + const NXArchInfo *localArchInfo = NXGetLocalArchInfo(); + signed char ch; + + if (localArchInfo) { + if (localArchInfo->cputype & CPU_ARCH_ABI64) + options->arch = (localArchInfo->cputype == CPU_TYPE_POWERPC64) ? @"ppc64": + @"x86_64"; + else + options->arch = (localArchInfo->cputype == CPU_TYPE_POWERPC) ? @"ppc" : + @"x86"; + } + + while ((ch = getopt(argc, (char * const *)argv, "a:h?")) != -1) { + switch (ch) { + case 'a': + if (strcmp("ppc", optarg) == 0) + options->arch = @"ppc"; + else if (strcmp("x86", optarg) == 0 || strcmp("i386", optarg) == 0) + options->arch = @"x86"; + else if (strcmp("ppc64", optarg) == 0) + options->arch = @"ppc64"; + else if (strcmp("x86_64", optarg) == 0) + options->arch = @"x86_64"; + else { + fprintf(stderr, "%s: Invalid architecture: %s\n", argv[0], optarg); + Usage(argc, argv); + exit(1); + } + break; + case '?': + case 'h': + Usage(argc, argv); + exit(0); + break; + } + } + + if ((argc - optind) != 1) { + fprintf(stderr, "Must specify Mach-o file\n"); + Usage(argc, argv); + exit(1); + } + + options->srcPath = [[NSFileManager defaultManager] + stringWithFileSystemRepresentation:argv[optind] + length:strlen(argv[optind])]; +} + +//============================================================================= +int main (int argc, const char * argv[]) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + Options options; + + bzero(&options, sizeof(Options)); + SetupOptions(argc, argv, &options); + Start(&options); + + [pool release]; + + return !options.result; +} -- cgit v1.2.1