mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2025-04-01 23:07:04 +00:00
Changes to support patch #108:
- Calculate unique file id for mach-o files - Add file id support to dump_syms and symupload tools - Fix return values of tools to indicate success or failure - Change dump_syms class to be Objective-C++ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@109 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
50e299b00e
commit
d31c8b0292
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "client/mac/handler/minidump_generator.h"
|
||||
#include "client/minidump_file_writer-inl.h"
|
||||
#include "common/mac/file_id.h"
|
||||
#include "common/mac/string_utilities.h"
|
||||
|
||||
using MacStringUtils::ConvertToString;
|
||||
|
@ -492,6 +493,7 @@ bool MinidumpGenerator::WriteModuleStream(unsigned int index,
|
|||
if (!header)
|
||||
return false;
|
||||
|
||||
int cpu_type = header->cputype;
|
||||
unsigned long slide = _dyld_get_image_vmaddr_slide(index);
|
||||
const char* name = _dyld_get_image_name(index);
|
||||
const struct load_command *cmd =
|
||||
|
@ -513,7 +515,7 @@ bool MinidumpGenerator::WriteModuleStream(unsigned int index,
|
|||
module->size_of_image = seg->vmsize;
|
||||
module->module_name_rva = string_location.rva;
|
||||
|
||||
if (!WriteCVRecord(module, name))
|
||||
if (!WriteCVRecord(module, cpu_type, name))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -540,7 +542,7 @@ static int FindExecutableModule() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool MinidumpGenerator::WriteCVRecord(MDRawModule *module,
|
||||
bool MinidumpGenerator::WriteCVRecord(MDRawModule *module, int cpu_type,
|
||||
const char *module_path) {
|
||||
TypedMDRVA<MDCVInfoPDB70> cv(&writer_);
|
||||
|
||||
|
@ -566,14 +568,25 @@ bool MinidumpGenerator::WriteCVRecord(MDRawModule *module,
|
|||
cv_ptr->cv_signature = MD_CVINFOPDB70_SIGNATURE;
|
||||
cv_ptr->age = 0;
|
||||
|
||||
// Convert the string to MDGUID
|
||||
// TODO(waylonis):
|
||||
// MacOS doesn't currently have a uuid string, so we'll just write a
|
||||
// placeholder here.
|
||||
cv_ptr->signature.data1 = 0;
|
||||
cv_ptr->signature.data2 = 0;
|
||||
cv_ptr->signature.data3 = 0;
|
||||
memset(cv_ptr->signature.data4, 0, sizeof(cv_ptr->signature.data4));
|
||||
// Get the module identifier
|
||||
FileID file_id(module_path);
|
||||
unsigned char identifier[16];
|
||||
|
||||
if (file_id.MachoIdentifier(cpu_type, identifier)) {
|
||||
cv_ptr->signature.data1 = (uint32_t)identifier[0] << 24 |
|
||||
(uint32_t)identifier[1] << 16 | (uint32_t)identifier[2] << 8 |
|
||||
(uint32_t)identifier[3];
|
||||
cv_ptr->signature.data2 = (uint32_t)identifier[4] << 8 | identifier[5];
|
||||
cv_ptr->signature.data3 = (uint32_t)identifier[6] << 8 | identifier[7];
|
||||
cv_ptr->signature.data4[0] = identifier[8];
|
||||
cv_ptr->signature.data4[1] = identifier[9];
|
||||
cv_ptr->signature.data4[2] = identifier[10];
|
||||
cv_ptr->signature.data4[3] = identifier[11];
|
||||
cv_ptr->signature.data4[4] = identifier[12];
|
||||
cv_ptr->signature.data4[5] = identifier[13];
|
||||
cv_ptr->signature.data4[6] = identifier[14];
|
||||
cv_ptr->signature.data4[7] = identifier[15];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,8 @@ class MinidumpGenerator {
|
|||
bool WriteContext(thread_state_data_t state,
|
||||
MDLocationDescriptor *register_location);
|
||||
bool WriteThreadStream(mach_port_t thread_id, MDRawThread *thread);
|
||||
bool WriteCVRecord(MDRawModule *module, const char *module_path);
|
||||
bool WriteCVRecord(MDRawModule *module, int cpu_type,
|
||||
const char *module_path);
|
||||
bool WriteModuleStream(unsigned int index, MDRawModule *module);
|
||||
|
||||
// disallow copy ctor and operator=
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
@protected
|
||||
NSString *sourcePath_; // Source of symbols (STRONG)
|
||||
NSString *architecture_; // Architecture to extract (STRONG)
|
||||
NSString *uuidStr_; // Module UUID (STRONG)
|
||||
NSMutableDictionary *addresses_; // Addresses and symbols (STRONG)
|
||||
NSMutableDictionary *sources_; // Address and Source file paths (STRONG)
|
||||
NSMutableArray *cppAddresses_; // Addresses of C++ symbols (STRONG)
|
||||
|
@ -56,11 +55,6 @@
|
|||
- (BOOL)setArchitecture:(NSString *)architecture;
|
||||
- (NSString *)architecture;
|
||||
|
||||
// Specify a UUID to output with the symbol file.
|
||||
// If none specified, a new one will be created
|
||||
- (void)setUUID:(NSString *)uuidStr;
|
||||
- (NSString *)uuid;
|
||||
|
||||
// Write the symbols to |symbolFilePath|. Return YES if successful.
|
||||
- (BOOL)writeSymbolFile:(NSString *)symbolFilePath;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
// (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.m: Create a symbol file for use with minidumps
|
||||
// dump_syms.mm: Create a symbol file for use with minidumps
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
@ -43,6 +43,9 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "dump_syms.h"
|
||||
#import "common/mac/file_id.h"
|
||||
|
||||
using google_airbag::FileID;
|
||||
|
||||
static NSString *kAddressSymbolKey = @"symbol";
|
||||
static NSString *kAddressConvertedSymbolKey = @"converted_symbol";
|
||||
|
@ -52,6 +55,7 @@ static NSString *kHeaderBaseAddressKey = @"baseAddr";
|
|||
static NSString *kHeaderSizeKey = @"size";
|
||||
static NSString *kHeaderOffsetKey = @"offset"; // Offset to the header
|
||||
static NSString *kHeaderIs64BitKey = @"is64";
|
||||
static NSString *kHeaderCPUTypeKey = @"cpuType";
|
||||
static NSString *kUnknownSymbol = @"???";
|
||||
|
||||
@interface DumpSymbols(PrivateMethods)
|
||||
|
@ -70,6 +74,26 @@ static NSString *kUnknownSymbol = @"???";
|
|||
- (NSMutableString *)generateSymbolFileString;
|
||||
@end
|
||||
|
||||
static BOOL StringHeadMatches(NSString *str, NSString *head) {
|
||||
int headLen = [head length];
|
||||
int strLen = [str length];
|
||||
|
||||
if (headLen > strLen)
|
||||
return NO;
|
||||
|
||||
return [[str substringToIndex:headLen] isEqualToString:head];
|
||||
}
|
||||
|
||||
static BOOL StringTailMatches(NSString *str, NSString *tail) {
|
||||
int tailLen = [tail length];
|
||||
int strLen = [str length];
|
||||
|
||||
if (tailLen > strLen)
|
||||
return NO;
|
||||
|
||||
return [[str substringFromIndex:strLen - tailLen] isEqualToString:tail];
|
||||
}
|
||||
|
||||
@implementation DumpSymbols
|
||||
//=============================================================================
|
||||
- (NSString *)stringFromTask:(NSString *)action args:(NSArray *)args
|
||||
|
@ -131,7 +155,7 @@ static NSString *kUnknownSymbol = @"???";
|
|||
//=============================================================================
|
||||
- (NSArray *)convertCPlusPlusSymbols:(NSArray *)symbols {
|
||||
NSString *action = @"/usr/bin/c++filt";
|
||||
int count = [symbols count];
|
||||
unsigned int count = [symbols count];
|
||||
|
||||
// It's possible that we have too many symbols on the command line.
|
||||
// Unfortunately, c++filt doesn't take a file containing names, so we'll
|
||||
|
@ -168,7 +192,7 @@ static NSString *kUnknownSymbol = @"???";
|
|||
NSArray *addresses = [cppAddresses_ sortedArrayUsingSelector:
|
||||
@selector(compare:)];
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
for (unsigned int i = 0; i < count; ++i) {
|
||||
NSMutableDictionary *dict = [addresses_ objectForKey:
|
||||
[addresses objectAtIndex:i]];
|
||||
NSString *symbol = [dict objectForKey:kAddressSymbolKey];
|
||||
|
@ -183,7 +207,7 @@ static NSString *kUnknownSymbol = @"???";
|
|||
NSArray *converted = [self convertCPlusPlusSymbols:symbols];
|
||||
[symbols release];
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
for (unsigned int i = 0; i < count; ++i) {
|
||||
NSMutableDictionary *dict = [addresses_ objectForKey:
|
||||
[addresses objectAtIndex:i]];
|
||||
NSString *symbol = [converted objectAtIndex:i];
|
||||
|
@ -204,27 +228,26 @@ static NSString *kUnknownSymbol = @"???";
|
|||
// If the function starts with "_Z" or "__Z" then add it to the list of
|
||||
// addresses to run through the c++filt
|
||||
BOOL isCPP = NO;
|
||||
if ([name length] > 3) {
|
||||
unichar buffer[3];
|
||||
[name getCharacters:buffer range:NSMakeRange(0, 3)];
|
||||
if (buffer[0] == '_') {
|
||||
if (buffer[1] == '_' && buffer[2] == 'Z') {
|
||||
// Remove the leading underscore
|
||||
name = [name substringFromIndex:1];
|
||||
isCPP = YES;
|
||||
} else if (buffer[1] == 'Z') {
|
||||
isCPP = YES;
|
||||
}
|
||||
}
|
||||
|
||||
if (StringHeadMatches(name, @"__Z")) {
|
||||
// Remove the leading underscore
|
||||
name = [name substringFromIndex:1];
|
||||
isCPP = YES;
|
||||
} else if (StringHeadMatches(name, @"_Z")) {
|
||||
isCPP = YES;
|
||||
}
|
||||
|
||||
if (isCPP) {
|
||||
// Check if this is some debug symbol that ends in ".eh" I appears as
|
||||
// though it's got to do with exception handling, but it's not the
|
||||
// actual address of the function. So we'll ignore them
|
||||
if ([[name substringFromIndex:[name length] - 3] isEqualToString:@".eh"])
|
||||
return;
|
||||
// Filter out non-functions
|
||||
if (StringTailMatches(name, @".eh"))
|
||||
return;
|
||||
|
||||
if (StringTailMatches(name, @"__func__"))
|
||||
return;
|
||||
|
||||
if (StringTailMatches(name, @"GCC_except_table"))
|
||||
return;
|
||||
|
||||
if (isCPP) {
|
||||
if (!cppAddresses_)
|
||||
cppAddresses_ = [[NSMutableArray alloc] init];
|
||||
[cppAddresses_ addObject:addressNum];
|
||||
|
@ -320,10 +343,11 @@ static NSString *kUnknownSymbol = @"???";
|
|||
#define SwapShortIfNeeded(a) (swap ? NXSwapShort(a) : (a))
|
||||
//=============================================================================
|
||||
- (BOOL)loadSymbolInfo:(void *)base offset:(uint32_t)offset {
|
||||
struct mach_header *header = (struct mach_header *)(base + offset);
|
||||
struct mach_header *header = (struct mach_header *)((uint32_t)base + offset);
|
||||
BOOL swap = (header->magic == MH_CIGAM);
|
||||
uint32_t count = SwapLongIfNeeded(header->ncmds);
|
||||
struct load_command *cmd = (void *)header + sizeof(struct mach_header);
|
||||
struct load_command *cmd =
|
||||
(struct load_command *)((uint32_t)header + sizeof(struct mach_header));
|
||||
uint32_t symbolTableCommand = SwapLongIfNeeded(LC_SYMTAB);
|
||||
BOOL result = NO;
|
||||
|
||||
|
@ -336,19 +360,18 @@ static NSString *kUnknownSymbol = @"???";
|
|||
uint32_t ncmds = SwapLongIfNeeded(symtab->nsyms);
|
||||
uint32_t symoff = SwapLongIfNeeded(symtab->symoff);
|
||||
uint32_t stroff = SwapLongIfNeeded(symtab->stroff);
|
||||
struct nlist *list = (struct nlist *)(base + symoff + offset);
|
||||
struct nlist *list = (struct nlist *)((uint32_t)base + symoff + offset);
|
||||
char *strtab = ((char *)header + stroff);
|
||||
|
||||
// Process each command, looking for debugging stuff
|
||||
for (uint32_t j = 0; j < ncmds; ++j, ++list) {
|
||||
// Fill in an nlist_64 structure and process with that
|
||||
struct nlist_64 nlist64 = {
|
||||
.n_un.n_strx = SwapLongIfNeeded(list->n_un.n_strx),
|
||||
.n_type = list->n_type,
|
||||
.n_sect = list->n_sect,
|
||||
.n_desc = SwapIntIfNeeded(list->n_desc),
|
||||
.n_value = (uint64_t)SwapLongIfNeeded(list->n_value)
|
||||
};
|
||||
struct nlist_64 nlist64;
|
||||
nlist64.n_un.n_strx = SwapLongIfNeeded(list->n_un.n_strx);
|
||||
nlist64.n_type = list->n_type;
|
||||
nlist64.n_sect = list->n_sect;
|
||||
nlist64.n_desc = SwapIntIfNeeded(list->n_desc);
|
||||
nlist64.n_value = (uint64_t)SwapLongIfNeeded(list->n_value);
|
||||
|
||||
if ([self processSymbolItem:&nlist64 stringTable:strtab])
|
||||
result = YES;
|
||||
|
@ -356,7 +379,7 @@ static NSString *kUnknownSymbol = @"???";
|
|||
}
|
||||
|
||||
uint32_t cmdSize = SwapLongIfNeeded(cmd->cmdsize);
|
||||
cmd = (struct load_command *)((char *)cmd + cmdSize);
|
||||
cmd = (struct load_command *)((uint32_t)cmd + cmdSize);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -364,10 +387,12 @@ static NSString *kUnknownSymbol = @"???";
|
|||
|
||||
//=============================================================================
|
||||
- (BOOL)loadSymbolInfo64:(void *)base offset:(uint32_t)offset {
|
||||
struct mach_header_64 *header = (struct mach_header_64 *)(base + offset);
|
||||
struct mach_header_64 *header = (struct mach_header_64 *)
|
||||
((uint32_t)base + offset);
|
||||
BOOL swap = (header->magic == MH_CIGAM_64);
|
||||
uint32_t count = SwapLongIfNeeded(header->ncmds);
|
||||
struct load_command *cmd = (void *)header + sizeof(struct mach_header);
|
||||
struct load_command *cmd =
|
||||
(struct load_command *)((uint32_t)header + sizeof(struct mach_header));
|
||||
uint32_t symbolTableCommand = SwapLongIfNeeded(LC_SYMTAB);
|
||||
BOOL result = NO;
|
||||
|
||||
|
@ -377,7 +402,7 @@ static NSString *kUnknownSymbol = @"???";
|
|||
uint32_t ncmds = SwapLongIfNeeded(symtab->nsyms);
|
||||
uint32_t symoff = SwapLongIfNeeded(symtab->symoff);
|
||||
uint32_t stroff = SwapLongIfNeeded(symtab->stroff);
|
||||
struct nlist_64 *list = (struct nlist_64 *)(base + symoff);
|
||||
struct nlist_64 *list = (struct nlist_64 *)((uint32_t)base + symoff);
|
||||
char *strtab = ((char *)header + stroff);
|
||||
|
||||
// Process each command, looking for debugging stuff
|
||||
|
@ -386,13 +411,12 @@ static NSString *kUnknownSymbol = @"???";
|
|||
continue;
|
||||
|
||||
// Fill in an nlist_64 structure and process with that
|
||||
struct nlist_64 nlist64 = {
|
||||
.n_un.n_strx = SwapLongIfNeeded(list->n_un.n_strx),
|
||||
.n_type = list->n_type,
|
||||
.n_sect = list->n_sect,
|
||||
.n_desc = SwapIntIfNeeded(list->n_desc),
|
||||
.n_value = SwapLongLongIfNeeded(list->n_value)
|
||||
};
|
||||
struct nlist_64 nlist64;
|
||||
nlist64.n_un.n_strx = SwapLongIfNeeded(list->n_un.n_strx);
|
||||
nlist64.n_type = list->n_type;
|
||||
nlist64.n_sect = list->n_sect;
|
||||
nlist64.n_desc = SwapIntIfNeeded(list->n_desc);
|
||||
nlist64.n_value = SwapLongLongIfNeeded(list->n_value);
|
||||
|
||||
if ([self processSymbolItem:&nlist64 stringTable:strtab])
|
||||
result = YES;
|
||||
|
@ -400,7 +424,7 @@ static NSString *kUnknownSymbol = @"???";
|
|||
}
|
||||
|
||||
uint32_t cmdSize = SwapLongIfNeeded(cmd->cmdsize);
|
||||
cmd = (struct load_command *)((char *)cmd + cmdSize);
|
||||
cmd = (struct load_command *)((uint32_t)cmd + cmdSize);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -411,7 +435,7 @@ static NSString *kUnknownSymbol = @"???";
|
|||
NSMutableData *data = [[NSMutableData alloc]
|
||||
initWithContentsOfMappedFile:sourcePath_];
|
||||
NSDictionary *headerInfo = [headers_ objectForKey:architecture_];
|
||||
char *base = [data mutableBytes];
|
||||
void *base = [data mutableBytes];
|
||||
uint32_t offset =
|
||||
[[headerInfo objectForKey:kHeaderOffsetKey] unsignedLongValue];
|
||||
BOOL is64 = [[headerInfo objectForKey:kHeaderIs64BitKey] boolValue];
|
||||
|
@ -424,10 +448,11 @@ static NSString *kUnknownSymbol = @"???";
|
|||
|
||||
//=============================================================================
|
||||
- (BOOL)loadHeader:(void *)base offset:(uint32_t)offset {
|
||||
struct mach_header *header = (struct mach_header *)(base + offset);
|
||||
struct mach_header *header = (struct mach_header *)((uint32_t)base + offset);
|
||||
BOOL swap = (header->magic == MH_CIGAM);
|
||||
uint32_t count = SwapLongIfNeeded(header->ncmds);
|
||||
struct load_command *cmd = (void *)header + sizeof(struct mach_header);
|
||||
struct load_command *cmd =
|
||||
(struct load_command *)((uint32_t)header + sizeof(struct mach_header));
|
||||
|
||||
for (uint32_t i = 0; cmd && (i < count); i++) {
|
||||
uint32_t segmentCommand = SwapLongIfNeeded(LC_SEGMENT);
|
||||
|
@ -445,6 +470,7 @@ static NSString *kUnknownSymbol = @"???";
|
|||
[NSNumber numberWithUnsignedLongLong:(uint64_t)size], kHeaderSizeKey,
|
||||
[NSNumber numberWithUnsignedLong:offset], kHeaderOffsetKey,
|
||||
[NSNumber numberWithBool:NO], kHeaderIs64BitKey,
|
||||
[NSNumber numberWithUnsignedLong:cpu], kHeaderCPUTypeKey,
|
||||
nil] forKey:cpuStr];
|
||||
|
||||
return YES;
|
||||
|
@ -452,7 +478,7 @@ static NSString *kUnknownSymbol = @"???";
|
|||
}
|
||||
|
||||
uint32_t cmdSize = SwapLongIfNeeded(cmd->cmdsize);
|
||||
cmd = (struct load_command *)((char *)cmd + cmdSize);
|
||||
cmd = (struct load_command *)((uint32_t)cmd + cmdSize);
|
||||
}
|
||||
|
||||
return NO;
|
||||
|
@ -460,10 +486,12 @@ static NSString *kUnknownSymbol = @"???";
|
|||
|
||||
//=============================================================================
|
||||
- (BOOL)loadHeader64:(void *)base offset:(uint32_t)offset {
|
||||
struct mach_header_64 *header = (struct mach_header_64 *)(base + offset);
|
||||
struct mach_header_64 *header =
|
||||
(struct mach_header_64 *)((uint32_t)base + offset);
|
||||
BOOL swap = (header->magic == MH_CIGAM_64);
|
||||
uint32_t count = SwapLongIfNeeded(header->ncmds);
|
||||
struct load_command *cmd = (void *)header + sizeof(struct mach_header_64);
|
||||
struct load_command *cmd =
|
||||
(struct load_command *)((uint32_t)header + sizeof(struct mach_header_64));
|
||||
|
||||
for (uint32_t i = 0; cmd && (i < count); i++) {
|
||||
uint32_t segmentCommand = SwapLongIfNeeded(LC_SEGMENT_64);
|
||||
|
@ -487,7 +515,7 @@ static NSString *kUnknownSymbol = @"???";
|
|||
}
|
||||
|
||||
uint32_t cmdSize = SwapLongIfNeeded(cmd->cmdsize);
|
||||
cmd = (struct load_command *)((char *)cmd + cmdSize);
|
||||
cmd = (struct load_command *)((uint32_t)cmd + cmdSize);
|
||||
}
|
||||
|
||||
return NO;
|
||||
|
@ -498,7 +526,7 @@ static NSString *kUnknownSymbol = @"???";
|
|||
uint64_t result = 0;
|
||||
NSMutableData *data = [[NSMutableData alloc]
|
||||
initWithContentsOfMappedFile:sourcePath_];
|
||||
char *bytes = [data mutableBytes];
|
||||
void *bytes = [data mutableBytes];
|
||||
struct fat_header *fat = (struct fat_header *)bytes;
|
||||
|
||||
if (!fat) {
|
||||
|
@ -523,7 +551,7 @@ static NSString *kUnknownSymbol = @"???";
|
|||
|
||||
if (isFat) {
|
||||
struct fat_arch *archs =
|
||||
(struct fat_arch *)((void *)fat + sizeof(struct fat_header));
|
||||
(struct fat_arch *)((uint32_t)fat + sizeof(struct fat_header));
|
||||
uint32_t count = SwapLongIfNeeded(fat->nfat_arch);
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
|
@ -583,17 +611,36 @@ static BOOL WriteFormat(int fd, const char *fmt, ...) {
|
|||
NSArray *sortedAddresses = [[addresses_ allKeys]
|
||||
sortedArrayUsingSelector:@selector(compare:)];
|
||||
|
||||
// Module
|
||||
if (!WriteFormat(fd, "MODULE mac %s %s 1 %s\n", [architecture_ UTF8String],
|
||||
[uuidStr_ UTF8String],
|
||||
[[sourcePath_ lastPathComponent] UTF8String]))
|
||||
// UUID
|
||||
FileID file_id([sourcePath_ fileSystemRepresentation]);
|
||||
unsigned char identifier[16];
|
||||
char identifierStr[40];
|
||||
const char *moduleName = [[sourcePath_ lastPathComponent] UTF8String];
|
||||
int cpu_type = [[archDict objectForKey:kHeaderCPUTypeKey] unsignedLongValue];
|
||||
if (file_id.MachoIdentifier(cpu_type, identifier)) {
|
||||
FileID::ConvertIdentifierToString(identifier, identifierStr,
|
||||
sizeof(identifierStr));
|
||||
}
|
||||
else {
|
||||
strlcpy(identifierStr, moduleName, sizeof(identifierStr));
|
||||
}
|
||||
|
||||
// Remove the dashes from the string
|
||||
NSMutableString *compactedStr =
|
||||
[NSMutableString stringWithCString:identifierStr encoding:NSASCIIStringEncoding];
|
||||
[compactedStr replaceOccurrencesOfString:@"-" withString:@"" options:0
|
||||
range:NSMakeRange(0, [compactedStr length])];
|
||||
|
||||
if (!WriteFormat(fd, "MODULE mac %s %s0 %s\n", [architecture_ UTF8String],
|
||||
[compactedStr UTF8String], moduleName)) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Sources ordered by address
|
||||
NSArray *sources = [[sources_ allKeys]
|
||||
NSArray *sources = [[sources_ allKeys]
|
||||
sortedArrayUsingSelector:@selector(compare:)];
|
||||
int sourceCount = [sources count];
|
||||
for (int i = 0; i < sourceCount; ++i) {
|
||||
unsigned int sourceCount = [sources count];
|
||||
for (unsigned int i = 0; i < sourceCount; ++i) {
|
||||
NSString *file = [sources_ objectForKey:[sources objectAtIndex:i]];
|
||||
if (!WriteFormat(fd, "FILE %d %s\n", i + 1, [file UTF8String]))
|
||||
return NO;
|
||||
|
@ -605,9 +652,9 @@ static BOOL WriteFormat(int fd, const char *fmt, ...) {
|
|||
uint64_t nextSourceFileAddress = 0;
|
||||
NSNumber *nextAddress;
|
||||
uint64_t nextAddressVal;
|
||||
int addressCount = [sortedAddresses count];
|
||||
unsigned int addressCount = [sortedAddresses count];
|
||||
|
||||
for (int i = 0; i < addressCount; ++i) {
|
||||
for (unsigned int i = 0; i < addressCount; ++i) {
|
||||
NSNumber *address = [sortedAddresses objectAtIndex:i];
|
||||
uint64_t addressVal = [address unsignedLongLongValue] - baseAddress;
|
||||
|
||||
|
@ -625,6 +672,22 @@ static BOOL WriteFormat(int fd, const char *fmt, ...) {
|
|||
NSNumber *line = [dict objectForKey:kAddressSourceLineKey];
|
||||
NSString *symbol = [dict objectForKey:kAddressConvertedSymbolKey];
|
||||
|
||||
if (!symbol)
|
||||
symbol = [dict objectForKey:kAddressSymbolKey];
|
||||
|
||||
// Skip some symbols
|
||||
if (StringHeadMatches(symbol, @"__gnu"))
|
||||
continue;
|
||||
|
||||
if (StringHeadMatches(symbol, @"typeinfo "))
|
||||
continue;
|
||||
|
||||
if (StringHeadMatches(symbol, @"EH_frame"))
|
||||
continue;
|
||||
|
||||
if (StringHeadMatches(symbol, @"GCC_except_table"))
|
||||
continue;
|
||||
|
||||
// Find the source file (if any) that contains this address
|
||||
while (sourceCount && (addressVal >= nextSourceFileAddress)) {
|
||||
fileIdx = nextFileIdx;
|
||||
|
@ -635,33 +698,30 @@ static BOOL WriteFormat(int fd, const char *fmt, ...) {
|
|||
nextSourceFileAddress = [addr unsignedLongLongValue] - baseAddress;
|
||||
} else {
|
||||
nextSourceFileAddress = baseAddress + moduleSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!symbol)
|
||||
symbol = [dict objectForKey:kAddressSymbolKey];
|
||||
|
||||
if (line) {
|
||||
if (symbol) {
|
||||
NSNumber *functionLength = [dict objectForKey:kFunctionSizeKey];
|
||||
uint64_t functionLengthVal = [functionLength unsignedLongLongValue];
|
||||
|
||||
// Function
|
||||
if (!WriteFormat(fd, "FUNC %llx %llx 0 %s%c", addressVal,
|
||||
functionLengthVal, [symbol UTF8String],
|
||||
terminatingChar))
|
||||
if (!WriteFormat(fd, "FUNC %llx %llx 0 %s\n", addressVal,
|
||||
functionLengthVal, [symbol UTF8String]))
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Source line
|
||||
uint64_t length = nextAddressVal - addressVal;
|
||||
if (!WriteFormat(fd, "%llx %llx %d %d%c", addressVal, length,
|
||||
[line unsignedIntValue], fileIdx, terminatingChar))
|
||||
if (!WriteFormat(fd, "%llx %llx %d %d\n", addressVal, length,
|
||||
[line unsignedIntValue], fileIdx))
|
||||
return NO;
|
||||
} else {
|
||||
// PUBLIC <address> <stack-size> <name>
|
||||
if (!WriteFormat(fd, "PUBLIC %llx 0 %s%c", addressVal,
|
||||
[symbol UTF8String], terminatingChar))
|
||||
if (!WriteFormat(fd, "PUBLIC %llx 0 %s\n", addressVal,
|
||||
[symbol UTF8String]))
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
@ -671,10 +731,9 @@ static BOOL WriteFormat(int fd, const char *fmt, ...) {
|
|||
|
||||
//=============================================================================
|
||||
- (id)initWithContentsOfFile:(NSString *)path {
|
||||
if (self = [super init]) {
|
||||
if ((self = [super init])) {
|
||||
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
|
||||
NSLog(@"Missing source file: %@", path);
|
||||
[self autorelease];
|
||||
return nil;
|
||||
}
|
||||
|
@ -682,7 +741,6 @@ static BOOL WriteFormat(int fd, const char *fmt, ...) {
|
|||
sourcePath_ = [path copy];
|
||||
|
||||
if (![self loadModuleInfo]) {
|
||||
NSLog(@"Not a valid Mach-o file: %@", path);
|
||||
[self autorelease];
|
||||
return nil;
|
||||
}
|
||||
|
@ -707,8 +765,6 @@ static BOOL WriteFormat(int fd, const char *fmt, ...) {
|
|||
// Specify the default architecture
|
||||
[self setArchitecture:[[headers_ allKeys] objectAtIndex:0]];
|
||||
}
|
||||
|
||||
[self setUUID:nil];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -723,7 +779,6 @@ static BOOL WriteFormat(int fd, const char *fmt, ...) {
|
|||
- (void)dealloc {
|
||||
[sourcePath_ release];
|
||||
[architecture_ release];
|
||||
[uuidStr_ release];
|
||||
[addresses_ release];
|
||||
[sources_ release];
|
||||
[headers_ release];
|
||||
|
@ -769,22 +824,6 @@ static BOOL WriteFormat(int fd, const char *fmt, ...) {
|
|||
return architecture_;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (void)setUUID:(NSString *)uuidStr {
|
||||
if (!uuidStr) {
|
||||
CFUUIDRef uuid = CFUUIDCreate(NULL);
|
||||
uuidStr = [(NSString *)CFUUIDCreateString(NULL, uuid) autorelease];
|
||||
}
|
||||
|
||||
[uuidStr_ autorelease];
|
||||
uuidStr_ = [uuidStr copy];
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (NSString *)uuid {
|
||||
return uuidStr_;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (BOOL)writeSymbolFile:(NSString *)destinationPath {
|
||||
const char *dest = [destinationPath fileSystemRepresentation];
|
|
@ -103,7 +103,7 @@ bool MachoWalker::FindHeader(int cpu_type, off_t &offset) {
|
|||
offset = sizeof(magic);
|
||||
|
||||
// Figure out what type of file we've got
|
||||
bool is_fat;
|
||||
bool is_fat = false;
|
||||
if (magic == FAT_MAGIC || magic == FAT_CIGAM) {
|
||||
is_fat = true;
|
||||
}
|
||||
|
@ -119,9 +119,6 @@ bool MachoWalker::FindHeader(int cpu_type, off_t &offset) {
|
|||
if (!ReadBytes(&header_cpu_type, sizeof(header_cpu_type), offset))
|
||||
return false;
|
||||
|
||||
if (NXHostByteOrder() != NX_BigEndian)
|
||||
header_cpu_type = NXSwapLong(header_cpu_type);
|
||||
|
||||
if (valid_cpu_type != header_cpu_type)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -309,6 +309,7 @@ static void SetupOptions(int argc, const char *argv[], Options *options) {
|
|||
if ((argc - optind) != 1) {
|
||||
fprintf(stderr, "%s: Missing minidump file\n", argv[0]);
|
||||
Usage(argc, argv);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
options->minidumpPath = [[NSFileManager defaultManager]
|
||||
|
|
|
@ -32,7 +32,13 @@
|
|||
9BDF1AFC0B1BEB6300F8391B /* address_map-inl.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BDF1AFA0B1BEB6300F8391B /* address_map-inl.h */; };
|
||||
9BDF1AFD0B1BEB6300F8391B /* address_map.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BDF1AFB0B1BEB6300F8391B /* address_map.h */; };
|
||||
9BDF21A60B1E825400F8391B /* dump_syms.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BDF192D0B1BC15D00F8391B /* dump_syms.h */; };
|
||||
9BDF21A70B1E825400F8391B /* dump_syms.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF192E0B1BC15D00F8391B /* dump_syms.m */; };
|
||||
9BDF21A70B1E825400F8391B /* dump_syms.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF192E0B1BC15D00F8391B /* dump_syms.mm */; };
|
||||
9BE650B20B52FE3000611104 /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650AC0B52FE3000611104 /* file_id.cc */; };
|
||||
9BE650B30B52FE3000611104 /* file_id.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BE650AD0B52FE3000611104 /* file_id.h */; };
|
||||
9BE650B40B52FE3000611104 /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650AE0B52FE3000611104 /* macho_id.cc */; };
|
||||
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 */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
|
@ -54,6 +60,9 @@
|
|||
9B35FEEB0B26761C008DE8C7 /* basic_code_modules.h in CopyFiles */,
|
||||
9B3904960B2E52D90059FABE /* basic_source_line_resolver.h in CopyFiles */,
|
||||
9B3904970B2E52D90059FABE /* source_line_resolver_interface.h in CopyFiles */,
|
||||
9BE650B30B52FE3000611104 /* file_id.h in CopyFiles */,
|
||||
9BE650B50B52FE3000611104 /* macho_id.h in CopyFiles */,
|
||||
9BE650B70B52FE3000611104 /* macho_walker.h in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
|
@ -92,12 +101,18 @@
|
|||
9BDF176B0B1B8CB100F8391B /* on_demand_symbol_supplier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = on_demand_symbol_supplier.h; sourceTree = "<group>"; };
|
||||
9BDF176C0B1B8CB100F8391B /* on_demand_symbol_supplier.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = on_demand_symbol_supplier.mm; sourceTree = "<group>"; };
|
||||
9BDF192D0B1BC15D00F8391B /* dump_syms.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dump_syms.h; path = ../../../common/mac/dump_syms.h; sourceTree = SOURCE_ROOT; };
|
||||
9BDF192E0B1BC15D00F8391B /* dump_syms.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = dump_syms.m; path = ../../../common/mac/dump_syms.m; sourceTree = SOURCE_ROOT; };
|
||||
9BDF192E0B1BC15D00F8391B /* dump_syms.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = dump_syms.mm; path = ../../../common/mac/dump_syms.mm; sourceTree = SOURCE_ROOT; };
|
||||
9BDF1A270B1BD58200F8391B /* pathname_stripper.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = pathname_stripper.cc; path = ../../../processor/pathname_stripper.cc; sourceTree = SOURCE_ROOT; };
|
||||
9BDF1A7A0B1BE30100F8391B /* range_map-inl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "range_map-inl.h"; path = "../../../processor/range_map-inl.h"; sourceTree = SOURCE_ROOT; };
|
||||
9BDF1A7B0B1BE30100F8391B /* range_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = range_map.h; path = ../../../processor/range_map.h; sourceTree = SOURCE_ROOT; };
|
||||
9BDF1AFA0B1BEB6300F8391B /* address_map-inl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "address_map-inl.h"; path = "../../../processor/address_map-inl.h"; sourceTree = SOURCE_ROOT; };
|
||||
9BDF1AFB0B1BEB6300F8391B /* address_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = address_map.h; path = ../../../processor/address_map.h; sourceTree = SOURCE_ROOT; };
|
||||
9BE650AC0B52FE3000611104 /* file_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = file_id.cc; path = ../../../common/mac/file_id.cc; sourceTree = SOURCE_ROOT; };
|
||||
9BE650AD0B52FE3000611104 /* file_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = file_id.h; path = ../../../common/mac/file_id.h; sourceTree = SOURCE_ROOT; };
|
||||
9BE650AE0B52FE3000611104 /* macho_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_id.cc; path = ../../../common/mac/macho_id.cc; sourceTree = SOURCE_ROOT; };
|
||||
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; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -116,7 +131,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
9BDF192D0B1BC15D00F8391B /* dump_syms.h */,
|
||||
9BDF192E0B1BC15D00F8391B /* dump_syms.m */,
|
||||
9BDF192E0B1BC15D00F8391B /* dump_syms.mm */,
|
||||
08FB7796FE84155DC02AAC07 /* crash_report.mm */,
|
||||
9BDF176B0B1B8CB100F8391B /* on_demand_symbol_supplier.h */,
|
||||
9BDF176C0B1B8CB100F8391B /* on_demand_symbol_supplier.mm */,
|
||||
|
@ -130,6 +145,7 @@
|
|||
08FB7795FE84155DC02AAC07 /* airbag */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9BE650AB0B52FE1A00611104 /* common */,
|
||||
9BDF17280B1B8B0200F8391B /* processor */,
|
||||
9BDF16F70B1B8ACD00F8391B /* google_airbag */,
|
||||
);
|
||||
|
@ -214,6 +230,19 @@
|
|||
name = processor;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9BE650AB0B52FE1A00611104 /* common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9BE650AC0B52FE3000611104 /* file_id.cc */,
|
||||
9BE650AD0B52FE3000611104 /* file_id.h */,
|
||||
9BE650AE0B52FE3000611104 /* macho_id.cc */,
|
||||
9BE650AF0B52FE3000611104 /* macho_id.h */,
|
||||
9BE650B00B52FE3000611104 /* macho_walker.cc */,
|
||||
9BE650B10B52FE3000611104 /* macho_walker.h */,
|
||||
);
|
||||
name = common;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
|
@ -265,9 +294,12 @@
|
|||
9BDF175D0B1B8C1B00F8391B /* process_state.cc in Sources */,
|
||||
9BDF176E0B1B8CB100F8391B /* on_demand_symbol_supplier.mm in Sources */,
|
||||
9BDF1A280B1BD58200F8391B /* pathname_stripper.cc in Sources */,
|
||||
9BDF21A70B1E825400F8391B /* dump_syms.m in Sources */,
|
||||
9BDF21A70B1E825400F8391B /* dump_syms.mm in Sources */,
|
||||
9B35FEEA0B26761C008DE8C7 /* basic_code_modules.cc in Sources */,
|
||||
9B3904990B2E52FD0059FABE /* basic_source_line_resolver.cc in Sources */,
|
||||
9BE650B20B52FE3000611104 /* file_id.cc in Sources */,
|
||||
9BE650B40B52FE3000611104 /* macho_id.cc in Sources */,
|
||||
9BE650B60B52FE3000611104 /* macho_walker.cc in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -286,6 +318,7 @@
|
|||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = NO;
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
OTHER_LDFLAGS = "-lcrypto";
|
||||
PRODUCT_NAME = crash_report;
|
||||
USER_HEADER_SEARCH_PATHS = "../../../../** $(inherited)";
|
||||
ZERO_LINK = NO;
|
||||
|
@ -305,6 +338,7 @@
|
|||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = NO;
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
OTHER_LDFLAGS = "-lcrypto";
|
||||
PRODUCT_NAME = crash_report;
|
||||
USER_HEADER_SEARCH_PATHS = "../../../../** $(inherited)";
|
||||
ZERO_LINK = NO;
|
||||
|
|
|
@ -7,10 +7,16 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
8DD76F9A0486AA7600D96B5E /* dump_syms.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* dump_syms.m */; settings = {ATTRIBUTES = (); }; };
|
||||
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 */; };
|
||||
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 */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
|
@ -21,17 +27,26 @@
|
|||
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 */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
08FB7796FE84155DC02AAC07 /* dump_syms.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = dump_syms.m; path = ../../../common/mac/dump_syms.m; sourceTree = "<group>"; };
|
||||
08FB7796FE84155DC02AAC07 /* dump_syms.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = dump_syms.mm; path = ../../../common/mac/dump_syms.mm; sourceTree = "<group>"; };
|
||||
08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||
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 = "<group>"; };
|
||||
9BDF186E0B1BB43700F8391B /* dump_syms_tool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = dump_syms_tool.m; sourceTree = "<group>"; };
|
||||
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; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -49,8 +64,14 @@
|
|||
08FB7794FE84155DC02AAC07 /* dump_syms */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9BE650410B52F6D800611104 /* file_id.cc */,
|
||||
9BE650420B52F6D800611104 /* file_id.h */,
|
||||
9BE650430B52F6D800611104 /* macho_id.cc */,
|
||||
9BE650440B52F6D800611104 /* macho_id.h */,
|
||||
9BE650450B52F6D800611104 /* macho_walker.cc */,
|
||||
9BE650460B52F6D800611104 /* macho_walker.h */,
|
||||
9BDF186D0B1BB43700F8391B /* dump_syms.h */,
|
||||
08FB7796FE84155DC02AAC07 /* dump_syms.m */,
|
||||
08FB7796FE84155DC02AAC07 /* dump_syms.mm */,
|
||||
9BDF186E0B1BB43700F8391B /* dump_syms_tool.m */,
|
||||
08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */,
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */,
|
||||
|
@ -115,8 +136,11 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8DD76F9A0486AA7600D96B5E /* dump_syms.m in Sources */,
|
||||
8DD76F9A0486AA7600D96B5E /* dump_syms.mm in Sources */,
|
||||
9BDF18700B1BB43700F8391B /* dump_syms_tool.m in Sources */,
|
||||
9BE650470B52F6D800611104 /* file_id.cc in Sources */,
|
||||
9BE650490B52F6D800611104 /* macho_id.cc in Sources */,
|
||||
9BE6504B0B52F6D800611104 /* macho_walker.cc in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -127,7 +151,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_C_LANGUAGE_STANDARD = "compiler-default";
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
|
@ -140,7 +164,9 @@
|
|||
"$(inherited)",
|
||||
);
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
OTHER_LDFLAGS = "-lcrypto";
|
||||
PRODUCT_NAME = dump_syms;
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Debug;
|
||||
|
@ -152,7 +178,7 @@
|
|||
ppc,
|
||||
i386,
|
||||
);
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_C_LANGUAGE_STANDARD = "compiler-default";
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
|
@ -163,7 +189,9 @@
|
|||
"$(inherited)",
|
||||
);
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
OTHER_LDFLAGS = "-lcrypto";
|
||||
PRODUCT_NAME = dump_syms;
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Release;
|
||||
|
|
|
@ -46,21 +46,31 @@ typedef struct {
|
|||
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;
|
||||
}
|
||||
|
||||
[dump setArchitecture:options->arch];
|
||||
[dump setUUID:options->uuidStr];
|
||||
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 airbag symbol file. If a UUID is not specified,\n"
|
||||
"the program will try to locate one in the mach-o-file. If one is\n"
|
||||
"not found, one will be created.\n");
|
||||
fprintf(stderr, "Usage: %s [-a ppc|i386|x86][-u uuid] <mach-o-file>\n",
|
||||
fprintf(stderr, "Output an Airbag symbol file from a Mach-o file.\n");
|
||||
fprintf(stderr, "Usage: %s [-a ppc|i386|x86] <Mach-o file>\n",
|
||||
argv[0]);
|
||||
fprintf(stderr, "\t-a: Architecture type [default: native]\n");
|
||||
fprintf(stderr, "\t-u: Specify a UUID\n");
|
||||
fprintf(stderr, "\t-h: Usage\n");
|
||||
fprintf(stderr, "\t-?: Usage\n");
|
||||
}
|
||||
|
@ -97,9 +107,6 @@ static void SetupOptions(int argc, const char *argv[], Options *options) {
|
|||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
options->uuidStr = [NSString stringWithUTF8String:optarg];
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
Usage(argc, argv);
|
||||
|
@ -107,14 +114,9 @@ static void SetupOptions(int argc, const char *argv[], Options *options) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!options->uuidStr) {
|
||||
CFUUIDRef uuid = CFUUIDCreate(NULL);
|
||||
options->uuidStr = (NSString *)CFUUIDCreateString(NULL, uuid);
|
||||
}
|
||||
|
||||
|
||||
if ((argc - optind) != 1) {
|
||||
fprintf(stderr, "%s: Missing executable\n", argv[0]);
|
||||
fprintf(stderr, "Must specify Mach-o file\n");
|
||||
Usage(argc, argv);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -135,5 +137,5 @@ int main (int argc, const char * argv[]) {
|
|||
|
||||
[pool release];
|
||||
|
||||
return options.result;
|
||||
return !options.result;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
// debug_identifier: the debug file's identifier, usually consisting of
|
||||
// the guid and age embedded in the pdb, e.g.
|
||||
// "11111111BBBB3333DDDD555555555555F"
|
||||
// version: the file version of the module, e.g. "1.2.3.4"
|
||||
// os: the operating system that the module was built for
|
||||
// cpu: the CPU that the module was built for (x86 or ppc)
|
||||
// symbol_file: the contents of the airbag-format symbol file
|
||||
|
@ -47,7 +46,6 @@
|
|||
typedef struct {
|
||||
NSString *symbolsPath;
|
||||
NSString *uploadURLStr;
|
||||
NSString *version;
|
||||
BOOL success;
|
||||
} Options;
|
||||
|
||||
|
@ -69,11 +67,11 @@ static NSArray *ModuleDataForSymbolFile(NSString *file) {
|
|||
}
|
||||
|
||||
//=============================================================================
|
||||
static NSString *CompactIdentifier(NSString *uuid, NSString *age) {
|
||||
static NSString *CompactIdentifier(NSString *uuid) {
|
||||
NSMutableString *str = [NSMutableString stringWithString:uuid];
|
||||
[str replaceOccurrencesOfString:@"-" withString:@"" options:0
|
||||
range:NSMakeRange(0, [str length])];
|
||||
[str appendString:age];
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -83,22 +81,30 @@ static void Start(Options *options) {
|
|||
HTTPMultipartUpload *ul = [[HTTPMultipartUpload alloc] initWithURL:url];
|
||||
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
|
||||
NSArray *moduleParts = ModuleDataForSymbolFile(options->symbolsPath);
|
||||
NSString *compactedID = CompactIdentifier([moduleParts objectAtIndex:3],
|
||||
[moduleParts objectAtIndex:4]);
|
||||
NSMutableString *compactedID =
|
||||
[NSMutableString stringWithString:[moduleParts objectAtIndex:3]];
|
||||
[compactedID replaceOccurrencesOfString:@"-" withString:@"" options:0
|
||||
range:NSMakeRange(0, [compactedID length])];
|
||||
|
||||
// Add parameters
|
||||
if (options->version)
|
||||
[parameters setObject:options->version forKey:@"version"];
|
||||
[parameters setObject:compactedID forKey:@"debug_identifier"];
|
||||
|
||||
// MODULE <os> <cpu> <uuid> <age> <module-name>
|
||||
// 0 1 2 3 4 5
|
||||
[parameters setObject:@"1" forKey:@"age"];
|
||||
// MODULE <os> <cpu> <uuid> <module-name>
|
||||
// 0 1 2 3 4
|
||||
[parameters setObject:[moduleParts objectAtIndex:1] forKey:@"os"];
|
||||
[parameters setObject:[moduleParts objectAtIndex:2] forKey:@"cpu"];
|
||||
[parameters setObject:[moduleParts objectAtIndex:5] forKey:@"debug_file"];
|
||||
[parameters setObject:[moduleParts objectAtIndex:5] forKey:@"code_file"];
|
||||
[parameters setObject:compactedID forKey:@"debug_identifier"];
|
||||
[parameters setObject:[moduleParts objectAtIndex:4] forKey:@"debug_file"];
|
||||
[parameters setObject:[moduleParts objectAtIndex:4] forKey:@"code_file"];
|
||||
[ul setParameters:parameters];
|
||||
|
||||
NSArray *keys = [parameters allKeys];
|
||||
int count = [keys count];
|
||||
for (int i = 0; i < count; ++i) {
|
||||
NSString *key = [keys objectAtIndex:i];
|
||||
NSString *value = [parameters objectForKey:key];
|
||||
fprintf(stdout, "'%s' = '%s'\n", [key UTF8String],
|
||||
[value UTF8String]);
|
||||
}
|
||||
|
||||
// Add file
|
||||
[ul addFileAtPath:options->symbolsPath name:@"symbol_file"];
|
||||
|
@ -123,10 +129,9 @@ static void Start(Options *options) {
|
|||
static void
|
||||
Usage(int argc, const char *argv[]) {
|
||||
fprintf(stderr, "Submit symbol information.\n");
|
||||
fprintf(stderr, "Usage: %s [-v version] <symbols> <upload-URL>\n", argv[0]);
|
||||
fprintf(stderr, "Usage: %s <symbols> <upload-URL>\n", argv[0]);
|
||||
fprintf(stderr, "<symbols> should be created by using the dump_syms tool.\n");
|
||||
fprintf(stderr, "<upload-URL> is the destination for the upload\n");
|
||||
fprintf(stderr, "\t-v: Version information (e.g., 1.2.3.4)\n");
|
||||
fprintf(stderr, "\t-h: Usage\n");
|
||||
fprintf(stderr, "\t-?: Usage\n");
|
||||
}
|
||||
|
@ -137,11 +142,8 @@ SetupOptions(int argc, const char *argv[], Options *options) {
|
|||
extern int optind;
|
||||
char ch;
|
||||
|
||||
while ((ch = getopt(argc, (char * const *)argv, "v:h?")) != -1) {
|
||||
while ((ch = getopt(argc, (char * const *)argv, "h?")) != -1) {
|
||||
switch (ch) {
|
||||
case 'v':
|
||||
options->version = [NSString stringWithCString:optarg];
|
||||
break;
|
||||
default:
|
||||
Usage(argc, argv);
|
||||
exit(0);
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
/* Begin PBXFileReference section */
|
||||
08FB7796FE84155DC02AAC07 /* symupload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = symupload.m; sourceTree = "<group>"; };
|
||||
08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||
8DD76FA10486AA7600D96B5E /* symupload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = symupload; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8DD76FA10486AA7600D96B5E /* symupload */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = symupload; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9BD833680B03E4080055103E /* HTTPMultipartUpload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPMultipartUpload.h; path = ../../../common/mac/HTTPMultipartUpload.h; sourceTree = "<group>"; };
|
||||
9BD833690B03E4080055103E /* HTTPMultipartUpload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTTPMultipartUpload.m; path = ../../../common/mac/HTTPMultipartUpload.m; sourceTree = "<group>"; };
|
||||
9BD835FB0B0544950055103E /* minidump_upload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = minidump_upload; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
|
Loading…
Reference in a new issue