Symbols.cpp revision 54e7afa84d945f9137f9372ecde432f9e1a702fc
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Symbols.cpp ---------------------------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Host/Symbols.h" 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <dirent.h> 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <mach-o/loader.h> 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <mach-o/fat.h> 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes 1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <CoreFoundation/CoreFoundation.h> 2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/ArchSpec.h" 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/DataBuffer.h" 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/DataExtractor.h" 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Timer.h" 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/UUID.h" 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton#include "Host/macosx/cfcpp/CFCReleaser.h" 2954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb; 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private; 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerextern "C" { 3454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCFURLRef DBGCopyFullDSYMURLForUUID (CFUUIDRef uuid, CFURLRef exec_url); 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCFDictionaryRef DBGCopyDSYMPropertyLists (CFURLRef dsym_url); 3754e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton 3854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton} 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSkinnyMachOFileContainsArchAndUUID 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const FileSpec &file_spec, 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const ArchSpec *arch, 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const UUID *uuid, // the UUID we are looking for 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner off_t file_offset, 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataExtractor& data, 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t data_offset, 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t magic 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert(magic == MH_CIGAM || magic == MH_MAGIC || magic == MH_CIGAM_64 || magic == MH_MAGIC_64); 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (magic == MH_MAGIC || magic == MH_MAGIC_64) 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetByteOrder (eByteOrderHost); 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (eByteOrderHost == eByteOrderBig) 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetByteOrder (eByteOrderLittle); 5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetByteOrder (eByteOrderBig); 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t i; 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t cputype = data.GetU32(&data_offset); // cpu specifier 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t cpusubtype = data.GetU32(&data_offset); // machine specifier 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data_offset+=4; // Skip mach file type 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t ncmds = data.GetU32(&data_offset); // number of load commands 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t sizeofcmds = data.GetU32(&data_offset); // the size of all the load commands 6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data_offset+=4; // Skip flags 6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Check the architecture if we have a valid arch pointer 6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (arch) 7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 71cf0150574a0a97049efe2dce2cc0aa433705feb3Greg Clayton ArchSpec file_arch(eArchTypeMachO, cputype, cpusubtype); 7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (file_arch != *arch) 7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The file exists, and if a valid arch pointer was passed in we know 7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // if already matches, so we can return if we aren't looking for a specific 7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // UUID 8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (uuid == NULL) 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64) 8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data_offset += 4; // Skip reserved field for in mach_header_64 8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Make sure we have enough data for all the load commands 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64) 8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (data.GetByteSize() < sizeof(struct mach_header_64) + sizeofcmds) 9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header_64) + sizeofcmds)); 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetData (data_buffer_sp); 9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (data.GetByteSize() < sizeof(struct mach_header) + sizeofcmds) 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header) + sizeofcmds)); 10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetData (data_buffer_sp); 10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i=0; i<ncmds; i++) 10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t cmd_offset = data_offset; // Save this data_offset in case parsing of the segment goes awry! 10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t cmd = data.GetU32(&data_offset); 10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t cmd_size = data.GetU32(&data_offset); 10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (cmd == LC_UUID) 11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner UUID file_uuid (data.GetData(&data_offset, 16), 16); 11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return file_uuid == *uuid; 11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data_offset = cmd_offset + cmd_size; 11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerUniversalMachOFileContainsArchAndUUID 12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const FileSpec &file_spec, 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const ArchSpec *arch, 12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const UUID *uuid, 12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner off_t file_offset, 12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataExtractor& data, 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t data_offset, 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t magic 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert(magic == FAT_CIGAM || magic == FAT_MAGIC); 13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Universal mach-o files always have their headers encoded as BIG endian 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetByteOrder(eByteOrderBig); 13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t i; 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t nfat_arch = data.GetU32(&data_offset); // number of structs that follow 13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t fat_header_and_arch_size = sizeof(struct fat_header) + nfat_arch * sizeof(struct fat_arch); 13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (data.GetByteSize() < fat_header_and_arch_size) 14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, fat_header_and_arch_size)); 14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetData (data_buffer_sp); 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i=0; i<nfat_arch; i++) 14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner cpu_type_t arch_cputype = data.GetU32(&data_offset); // cpu specifier (int) 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner cpu_subtype_t arch_cpusubtype = data.GetU32(&data_offset); // machine specifier (int) 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t arch_offset = data.GetU32(&data_offset); // file offset to this object file 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // uint32_t arch_size = data.GetU32(&data_offset); // size of this object file 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // uint32_t arch_align = data.GetU32(&data_offset); // alignment as a power of 2 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data_offset += 8; // Skip size and align as we don't need those 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Only process this slice if the cpu type/subtype matches 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (arch) 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 156cf0150574a0a97049efe2dce2cc0aa433705feb3Greg Clayton ArchSpec fat_arch(eArchTypeMachO, arch_cputype, arch_cpusubtype); 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (fat_arch != *arch) 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Create a buffer with only the arch slice date in it 16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataExtractor arch_data; 16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset + arch_offset, 0x1000)); 16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner arch_data.SetData(data_buffer_sp); 16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t arch_data_offset = 0; 16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t arch_magic = arch_data.GetU32(&arch_data_offset); 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (arch_magic) 16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case MH_CIGAM: // 32 bit mach-o file 17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case MH_MAGIC: // 32 bit mach-o file 17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case MH_CIGAM_64: // 64 bit mach-o file 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case MH_MAGIC_64: // 64 bit mach-o file 17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset + arch_offset, arch_data, arch_data_offset, arch_magic)) 17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool 18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileAtPathContainsArchAndUUID 18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const FileSpec &file_spec, 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const ArchSpec *arch, 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const UUID *uuid 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataExtractor data; 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner off_t file_offset = 0; 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, 0x1000)); 19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0) 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetData(data_buffer_sp); 19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t data_offset = 0; 19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t magic = data.GetU32(&data_offset); 20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (magic) 20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // 32 bit mach-o file 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case MH_CIGAM: 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case MH_MAGIC: 20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case MH_CIGAM_64: 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case MH_MAGIC_64: 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic); 20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // fat mach-o file 21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case FAT_CIGAM: 21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case FAT_MAGIC: 21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return UniversalMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic); 21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner default: 21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic FileSpec 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerLocateDSYMMachFileInDSYMBundle 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const FileSpec& dsym_bundle_fspec, 22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const UUID *uuid, 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const ArchSpec *arch) 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char path[PATH_MAX]; 23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec dsym_fspec; 23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dsym_bundle_fspec.GetPath(path, sizeof(path))) 23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1); 23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DIR* dirp = ::opendir(path); 23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dirp != NULL) 23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const size_t path_len = strlen(path); 24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const int bytes_left = sizeof(path) - path_len - 1; 24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner struct dirent* dp; 24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while ((dp = readdir(dirp)) != NULL) 24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Only search directories 24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) 24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dp->d_namlen == 1 && dp->d_name[0] == '.') 24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.') 25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) 25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::strncpy (&path[path_len], dp->d_name, bytes_left); 25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dsym_fspec.SetFile(path); 26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (FileAtPathContainsArchAndUUID (dsym_fspec, arch, uuid)) 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return dsym_fspec; 26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dsym_fspec.Clear(); 26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return dsym_fspec; 26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic int 27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerLocateMacOSXFilesUsingDebugSymbols 27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const FileSpec *exec_fspec, // An executable path that may or may not be correct if UUID is specified 27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const ArchSpec* arch, // Limit the search to files with this architecture if non-NULL 27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const UUID *uuid, // Match the UUID value if non-NULL, 27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec *out_exec_fspec, // If non-NULL, try and find the executable 27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec *out_dsym_fspec // If non-NULL try and find the debug symbol file 27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int items_found = 0; 28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_exec_fspec) 28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner out_exec_fspec->Clear(); 28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_dsym_fspec) 28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner out_dsym_fspec->Clear(); 28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (uuid && uuid->IsValid()) 28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Try and locate the dSYM file using DebugSymbols first 29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes(); 29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (module_uuid != NULL) 29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes ( NULL, 29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[0], 29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[1], 29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[2], 29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[3], 29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[4], 30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[5], 30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[6], 30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[7], 30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[8], 30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[9], 30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[10], 30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[11], 30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[12], 30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[13], 30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[14], 31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[15])); 31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (module_uuid_ref.get()) 31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CFCReleaser<CFURLRef> exec_url; 31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec) 31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char exec_cf_path[PATH_MAX]; 31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path))) 32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exec_url.reset(::CFURLCreateFromFileSystemRepresentation (NULL, 32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner (const UInt8 *)exec_cf_path, 32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner strlen(exec_cf_path), 32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FALSE)); 32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CFCReleaser<CFURLRef> dsym_url (::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get())); 32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char path[PATH_MAX]; 32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dsym_url.get()) 33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_dsym_fspec) 33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1)) 33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner out_dsym_fspec->SetFile(path); 33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_dsym_fspec->GetFileType () == FileSpec::eFileTypeDirectory) 33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *out_dsym_fspec = LocateDSYMMachFileInDSYMBundle (*out_dsym_fspec, uuid, arch); 34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (*out_dsym_fspec) 34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++items_found; 34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++items_found; 34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_exec_fspec) 35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get()));; 35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dict.get()) 35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CFStringRef exec_cf_path = static_cast<CFStringRef>(::CFDictionaryGetValue (dict.get(), CFSTR("DBGSymbolRichExecutable"))); 35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_cf_path && ::CFStringGetFileSystemRepresentation (exec_cf_path, path, sizeof(path))) 35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++items_found; 35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner out_dsym_fspec->SetFile(path); 36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return items_found; 36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool 37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerLocateDSYMInVincinityOfExecutable (const FileSpec *exec_fspec, const ArchSpec* arch, const UUID *uuid, FileSpec &dsym_fspec) 37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec) 37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char path[PATH_MAX]; 37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec->GetPath(path, sizeof(path))) 37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Make sure the module isn't already just a dSYM file... 37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL) 38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner size_t obj_file_path_length = strlen(path); 38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner strncat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path)); 38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner strncat(path, exec_fspec->GetFilename().AsCString(), sizeof(path)); 38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dsym_fspec.SetFile(path); 38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (FileAtPathContainsArchAndUUID (dsym_fspec, arch, uuid)) 38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner path[obj_file_path_length] = '\0'; 39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char *last_dot = strrchr(path, '.'); 39624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (last_dot != NULL && last_dot[0]) 39724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char *next_slash = strchr(last_dot, '/'); 39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (next_slash != NULL) 40024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *next_slash = '\0'; 40224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner strncat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path)); 40324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner strncat(path, exec_fspec->GetFilename().AsCString(), sizeof(path)); 40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dsym_fspec.SetFile(path); 40524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dsym_fspec.Exists()) 40624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 40724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 40824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *last_dot = '\0'; 41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char *prev_slash = strrchr(path, '/'); 41124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (prev_slash != NULL) 41224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *prev_slash = '\0'; 41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 41424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 41524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 41624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 41724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 41824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 41924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 42024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 42124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 42224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 42324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 42424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 42524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 42624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dsym_fspec.Clear(); 42724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 42824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 42924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 43024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec 43124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymbols::LocateExecutableObjectFile (const FileSpec *exec_fspec, const ArchSpec* arch, const UUID *uuid) 43224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 43324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 43424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)", 43524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>", 43624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner arch ? arch->AsCString() : "<NULL>", 43724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uuid); 43824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 43924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec objfile_fspec; 44024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec && FileAtPathContainsArchAndUUID (*exec_fspec, arch, uuid)) 44124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner objfile_fspec = *exec_fspec; 44224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 44324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner LocateMacOSXFilesUsingDebugSymbols (exec_fspec, arch, uuid, &objfile_fspec, NULL); 44424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return objfile_fspec; 44524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 44624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 44724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec 44824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymbols::LocateExecutableSymbolFile (const FileSpec *exec_fspec, const ArchSpec* arch, const UUID *uuid) 44924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 45024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 45124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "LocateExecutableSymbolFile (file = %s, arch = %s, uuid = %p)", 45224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>", 45324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner arch ? arch->AsCString() : "<NULL>", 45424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uuid); 45524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 45624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec symbol_fspec; 45724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // First try and find the dSYM in the same directory as the executable or in 45824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // an appropriate parent directory 45924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (LocateDSYMInVincinityOfExecutable (exec_fspec, arch, uuid, symbol_fspec) == false) 46024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 46124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We failed to easily find the dSYM above, so use DebugSymbols 46224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner LocateMacOSXFilesUsingDebugSymbols (exec_fspec, arch, uuid, NULL, &symbol_fspec); 46324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 46424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return symbol_fspec; 46524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 466