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