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> 14f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda#include <pwd.h> 151674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton#include "llvm/Support/MachO.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" 25444fe998bf707bd076a70c3a779db8575533695eGreg Clayton#include "lldb/Core/Module.h" 2649ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Core/ModuleSpec.h" 279262cd52e254fb261334254a80a1b316d59b555cJohnny Chen#include "lldb/Core/StreamString.h" 2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Timer.h" 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/UUID.h" 30cd548034fa23113e995b8463d14f910ba2f7298cGreg Clayton#include "lldb/Host/Endian.h" 31cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen#include "lldb/Host/Host.h" 32ad400274d4e3ed01a4c730e1d6f95e6cb2ac73dcGreg Clayton#include "lldb/Utility/CleanUp.h" 33a1ebbd2410cafb890ab8519ae4e6b24cc618bd6aDaniel Dunbar#include "Host/macosx/cfcpp/CFCBundle.h" 34b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton#include "Host/macosx/cfcpp/CFCData.h" 3554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton#include "Host/macosx/cfcpp/CFCReleaser.h" 36b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton#include "Host/macosx/cfcpp/CFCString.h" 375bc7b67ccc8bb4a977d129e51313067dcbc7bb94Chris Lattner#include "mach/machine.h" 3854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton 390fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb; 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private; 421674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Claytonusing namespace llvm::MachO; 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 443e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#if !defined (__arm__) // No DebugSymbols on the iOS devices 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerextern "C" { 4654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCFURLRef DBGCopyFullDSYMURLForUUID (CFUUIDRef uuid, CFURLRef exec_url); 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCFDictionaryRef DBGCopyDSYMPropertyLists (CFURLRef dsym_url); 4954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton 5054e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton} 513e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#endif 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSkinnyMachOFileContainsArchAndUUID 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const FileSpec &file_spec, 5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const ArchSpec *arch, 580467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton const lldb_private::UUID *uuid, // the UUID we are looking for 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner off_t file_offset, 6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataExtractor& data, 6136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::offset_t data_offset, 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t magic 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 651674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton assert(magic == HeaderMagic32 || magic == HeaderMagic32Swapped || magic == HeaderMagic64 || magic == HeaderMagic64Swapped); 661674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton if (magic == HeaderMagic32 || magic == HeaderMagic64) 67cd548034fa23113e995b8463d14f910ba2f7298cGreg Clayton data.SetByteOrder (lldb::endian::InlHostByteOrder()); 68cd548034fa23113e995b8463d14f910ba2f7298cGreg Clayton else if (lldb::endian::InlHostByteOrder() == eByteOrderBig) 6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetByteOrder (eByteOrderLittle); 7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetByteOrder (eByteOrderBig); 7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t i; 7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t cputype = data.GetU32(&data_offset); // cpu specifier 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t cpusubtype = data.GetU32(&data_offset); // machine specifier 7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data_offset+=4; // Skip mach file type 7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t ncmds = data.GetU32(&data_offset); // number of load commands 7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t sizeofcmds = data.GetU32(&data_offset); // the size of all the load commands 7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data_offset+=4; // Skip flags 8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Check the architecture if we have a valid arch pointer 8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (arch) 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 84cf0150574a0a97049efe2dce2cc0aa433705feb3Greg Clayton ArchSpec file_arch(eArchTypeMachO, cputype, cpusubtype); 8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 86878f13c99c0dcbe2a5ac22f233522233d8dc52d4Sean Callanan if (!file_arch.IsCompatibleMatch(*arch)) 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The file exists, and if a valid arch pointer was passed in we know 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // if already matches, so we can return if we aren't looking for a specific 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // UUID 9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (uuid == NULL) 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 961674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton if (magic == HeaderMagic64Swapped || magic == HeaderMagic64) 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data_offset += 4; // Skip reserved field for in mach_header_64 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Make sure we have enough data for all the load commands 1001674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton if (magic == HeaderMagic64Swapped || magic == HeaderMagic64) 10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (data.GetByteSize() < sizeof(struct mach_header_64) + sizeofcmds) 10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header_64) + sizeofcmds)); 10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetData (data_buffer_sp); 10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (data.GetByteSize() < sizeof(struct mach_header) + sizeofcmds) 11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header) + sizeofcmds)); 11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetData (data_buffer_sp); 11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i=0; i<ncmds; i++) 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 11936da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton const lldb::offset_t cmd_offset = data_offset; // Save this data_offset in case parsing of the segment goes awry! 12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t cmd = data.GetU32(&data_offset); 12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t cmd_size = data.GetU32(&data_offset); 1221674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton if (cmd == LoadCommandUUID) 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 1240467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton lldb_private::UUID file_uuid (data.GetData(&data_offset, 16), 16); 125cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen if (file_uuid == *uuid) 126cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen return true; 127cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen return false; 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data_offset = cmd_offset + cmd_size; 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerUniversalMachOFileContainsArchAndUUID 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const FileSpec &file_spec, 13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const ArchSpec *arch, 1390467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton const lldb_private::UUID *uuid, 14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner off_t file_offset, 14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataExtractor& data, 14236da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::offset_t data_offset, 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t magic 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 1461674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton assert(magic == UniversalMagic || magic == UniversalMagicSwapped); 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Universal mach-o files always have their headers encoded as BIG endian 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetByteOrder(eByteOrderBig); 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t i; 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t nfat_arch = data.GetU32(&data_offset); // number of structs that follow 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t fat_header_and_arch_size = sizeof(struct fat_header) + nfat_arch * sizeof(struct fat_arch); 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (data.GetByteSize() < fat_header_and_arch_size) 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, fat_header_and_arch_size)); 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetData (data_buffer_sp); 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i=0; i<nfat_arch; i++) 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner cpu_type_t arch_cputype = data.GetU32(&data_offset); // cpu specifier (int) 16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner cpu_subtype_t arch_cpusubtype = data.GetU32(&data_offset); // machine specifier (int) 16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t arch_offset = data.GetU32(&data_offset); // file offset to this object file 16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // uint32_t arch_size = data.GetU32(&data_offset); // size of this object file 16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // uint32_t arch_align = data.GetU32(&data_offset); // alignment as a power of 2 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data_offset += 8; // Skip size and align as we don't need those 16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Only process this slice if the cpu type/subtype matches 16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (arch) 17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 171cf0150574a0a97049efe2dce2cc0aa433705feb3Greg Clayton ArchSpec fat_arch(eArchTypeMachO, arch_cputype, arch_cpusubtype); 17264246cda58b64208f5c415fc52909c45c3dc3e2bSean Callanan if (!fat_arch.IsExactMatch(*arch)) 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Create a buffer with only the arch slice date in it 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataExtractor arch_data; 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset + arch_offset, 0x1000)); 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner arch_data.SetData(data_buffer_sp); 18036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::offset_t arch_data_offset = 0; 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t arch_magic = arch_data.GetU32(&arch_data_offset); 18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (arch_magic) 18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 1851674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic32: 1861674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic32Swapped: 1871674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic64: 1881674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic64Swapped: 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset + arch_offset, arch_data, arch_data_offset, arch_magic)) 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool 19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileAtPathContainsArchAndUUID 19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const FileSpec &file_spec, 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const ArchSpec *arch, 2020467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton const lldb_private::UUID *uuid 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataExtractor data; 20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner off_t file_offset = 0; 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, 0x1000)); 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0) 21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetData(data_buffer_sp); 21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 21336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::offset_t data_offset = 0; 21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t magic = data.GetU32(&data_offset); 21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (magic) 21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // 32 bit mach-o file 2191674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic32: 2201674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic32Swapped: 2211674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic64: 2221674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic64Swapped: 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic); 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // fat mach-o file 2261674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case UniversalMagic: 2271674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case UniversalMagicSwapped: 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return UniversalMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic); 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner default: 23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23795b765e8000b44644d021e95bc58eac95028573bGreg ClaytonFileSpec 23895b765e8000b44644d021e95bc58eac95028573bGreg ClaytonSymbols::FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec, 23995b765e8000b44644d021e95bc58eac95028573bGreg Clayton const lldb_private::UUID *uuid, 24095b765e8000b44644d021e95bc58eac95028573bGreg Clayton const ArchSpec *arch) 24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char path[PATH_MAX]; 24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec dsym_fspec; 24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dsym_bundle_fspec.GetPath(path, sizeof(path))) 24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1); 24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25052fd984f7e67c3a0ab18d5565f40356bcfa84822Greg Clayton lldb_utility::CleanUp <DIR *, int> dirp (opendir(path), NULL, closedir); 251ad400274d4e3ed01a4c730e1d6f95e6cb2ac73dcGreg Clayton if (dirp.is_valid()) 25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 253537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton dsym_fspec.GetDirectory().SetCString(path); 25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner struct dirent* dp; 255ad400274d4e3ed01a4c730e1d6f95e6cb2ac73dcGreg Clayton while ((dp = readdir(dirp.get())) != NULL) 25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Only search directories 25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) 25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dp->d_namlen == 1 && dp->d_name[0] == '.') 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.') 26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) 26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 269537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton dsym_fspec.GetFilename().SetCString(dp->d_name); 27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (FileAtPathContainsArchAndUUID (dsym_fspec, arch, uuid)) 27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return dsym_fspec; 27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dsym_fspec.Clear(); 27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return dsym_fspec; 27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic int 28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerLocateMacOSXFilesUsingDebugSymbols 28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 283444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const ModuleSpec &module_spec, 28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec *out_exec_fspec, // If non-NULL, try and find the executable 28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec *out_dsym_fspec // If non-NULL try and find the debug symbol file 28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int items_found = 0; 28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_exec_fspec) 29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner out_exec_fspec->Clear(); 29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_dsym_fspec) 29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner out_dsym_fspec->Clear(); 29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2963e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#if !defined (__arm__) // No DebugSymbols on the iOS devices 2973e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton 298444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const UUID *uuid = module_spec.GetUUIDPtr(); 299444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const ArchSpec *arch = module_spec.GetArchitecturePtr(); 300444fe998bf707bd076a70c3a779db8575533695eGreg Clayton 30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (uuid && uuid->IsValid()) 30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Try and locate the dSYM file using DebugSymbols first 30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes(); 30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (module_uuid != NULL) 30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 3070fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes (NULL, 30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[0], 30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[1], 31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[2], 31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[3], 31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[4], 31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[5], 31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[6], 31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[7], 31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[8], 31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[9], 31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[10], 31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[11], 32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[12], 32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[13], 32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[14], 32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[15])); 32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (module_uuid_ref.get()) 32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CFCReleaser<CFURLRef> exec_url; 328444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); 32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec) 33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char exec_cf_path[PATH_MAX]; 33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path))) 33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exec_url.reset(::CFURLCreateFromFileSystemRepresentation (NULL, 33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner (const UInt8 *)exec_cf_path, 33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner strlen(exec_cf_path), 33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FALSE)); 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CFCReleaser<CFURLRef> dsym_url (::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get())); 34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char path[PATH_MAX]; 34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dsym_url.get()) 34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_dsym_fspec) 34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1)) 34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 3481b09dfef975addaa4aa330edb1dc7e28b8436028Jason Molenda out_dsym_fspec->SetFile(path, path[0] == '~'); 34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_dsym_fspec->GetFileType () == FileSpec::eFileTypeDirectory) 35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35295b765e8000b44644d021e95bc58eac95028573bGreg Clayton *out_dsym_fspec = Symbols::FindSymbolFileInBundle (*out_dsym_fspec, uuid, arch); 35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (*out_dsym_fspec) 35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++items_found; 35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++items_found; 35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 363964deba8853eb794e59263322b59b09b43669618Greg Clayton CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get())); 364964deba8853eb794e59263322b59b09b43669618Greg Clayton CFDictionaryRef uuid_dict = NULL; 365964deba8853eb794e59263322b59b09b43669618Greg Clayton if (dict.get()) 36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 36742b336cd509cad89be08f78775d3b1c8c7656a1bJason Molenda CFCString uuid_cfstr (uuid->GetAsString().c_str()); 36863e5cf65c43615da20b272fde2a21ffd4fa6eb29Jason Molenda uuid_dict = static_cast<CFDictionaryRef>(::CFDictionaryGetValue (dict.get(), uuid_cfstr.get())); 369964deba8853eb794e59263322b59b09b43669618Greg Clayton if (uuid_dict) 37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 371964deba8853eb794e59263322b59b09b43669618Greg Clayton 372964deba8853eb794e59263322b59b09b43669618Greg Clayton CFStringRef actual_src_cfpath = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSourcePath"))); 373964deba8853eb794e59263322b59b09b43669618Greg Clayton if (actual_src_cfpath) 37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 375964deba8853eb794e59263322b59b09b43669618Greg Clayton CFStringRef build_src_cfpath = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGBuildSourcePath"))); 376964deba8853eb794e59263322b59b09b43669618Greg Clayton if (build_src_cfpath) 377b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton { 378964deba8853eb794e59263322b59b09b43669618Greg Clayton char actual_src_path[PATH_MAX]; 379964deba8853eb794e59263322b59b09b43669618Greg Clayton char build_src_path[PATH_MAX]; 380964deba8853eb794e59263322b59b09b43669618Greg Clayton ::CFStringGetFileSystemRepresentation (actual_src_cfpath, actual_src_path, sizeof(actual_src_path)); 381964deba8853eb794e59263322b59b09b43669618Greg Clayton ::CFStringGetFileSystemRepresentation (build_src_cfpath, build_src_path, sizeof(build_src_path)); 3824d8c5434779393d5502b45f42a9371477604aab7Greg Clayton if (actual_src_path[0] == '~') 3834d8c5434779393d5502b45f42a9371477604aab7Greg Clayton { 3844d8c5434779393d5502b45f42a9371477604aab7Greg Clayton FileSpec resolved_source_path(actual_src_path, true); 3854d8c5434779393d5502b45f42a9371477604aab7Greg Clayton resolved_source_path.GetPath(actual_src_path, sizeof(actual_src_path)); 3864d8c5434779393d5502b45f42a9371477604aab7Greg Clayton } 387964deba8853eb794e59263322b59b09b43669618Greg Clayton module_spec.GetSourceMappingList().Append (ConstString(build_src_path), ConstString(actual_src_path), true); 388b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton } 3890fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 3900fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 391964deba8853eb794e59263322b59b09b43669618Greg Clayton } 392964deba8853eb794e59263322b59b09b43669618Greg Clayton 393964deba8853eb794e59263322b59b09b43669618Greg Clayton if (out_exec_fspec) 394964deba8853eb794e59263322b59b09b43669618Greg Clayton { 395964deba8853eb794e59263322b59b09b43669618Greg Clayton bool success = false; 396964deba8853eb794e59263322b59b09b43669618Greg Clayton if (uuid_dict) 397964deba8853eb794e59263322b59b09b43669618Greg Clayton { 398964deba8853eb794e59263322b59b09b43669618Greg Clayton CFStringRef exec_cf_path = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSymbolRichExecutable"))); 399964deba8853eb794e59263322b59b09b43669618Greg Clayton if (exec_cf_path && ::CFStringGetFileSystemRepresentation (exec_cf_path, path, sizeof(path))) 400964deba8853eb794e59263322b59b09b43669618Greg Clayton { 401964deba8853eb794e59263322b59b09b43669618Greg Clayton ++items_found; 402964deba8853eb794e59263322b59b09b43669618Greg Clayton out_exec_fspec->SetFile(path, path[0] == '~'); 403964deba8853eb794e59263322b59b09b43669618Greg Clayton if (out_exec_fspec->Exists()) 404964deba8853eb794e59263322b59b09b43669618Greg Clayton success = true; 405964deba8853eb794e59263322b59b09b43669618Greg Clayton } 406964deba8853eb794e59263322b59b09b43669618Greg Clayton } 4079ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton 4089ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton if (!success) 4090fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4100fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton // No dictionary, check near the dSYM bundle for an executable that matches... 4110fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1)) 4120fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4130fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton char *dsym_extension_pos = ::strstr (path, ".dSYM"); 4140fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (dsym_extension_pos) 4150fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4160fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton *dsym_extension_pos = '\0'; 4170fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton FileSpec file_spec (path, true); 4180fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton switch (file_spec.GetFileType()) 4190fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4200fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeDirectory: // Bundle directory? 4210fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4220fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton CFCBundle bundle (path); 4230fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton CFCReleaser<CFURLRef> bundle_exe_url (bundle.CopyExecutableURL ()); 4240fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (bundle_exe_url.get()) 4250fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4260fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (::CFURLGetFileSystemRepresentation (bundle_exe_url.get(), true, (UInt8*)path, sizeof(path)-1)) 4270fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4280fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton FileSpec bundle_exe_file_spec (path, true); 4290fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton 4300fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (FileAtPathContainsArchAndUUID (bundle_exe_file_spec, arch, uuid)) 4310fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4320fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton ++items_found; 4330fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton *out_exec_fspec = bundle_exe_file_spec; 4340fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4350fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4360fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4370fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4380fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton break; 4390fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton 4400fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypePipe: // Forget pipes 4410fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeSocket: // We can't process socket files 4420fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeInvalid: // File doesn't exist... 4430fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton break; 4440fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton 4450fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeUnknown: 4460fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeRegular: 4470fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeSymbolicLink: 4480fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeOther: 4490fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (FileAtPathContainsArchAndUUID (file_spec, arch, uuid)) 4500fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4510fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton ++items_found; 4520fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton *out_exec_fspec = file_spec; 4530fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4540fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton break; 4550fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4560fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 45724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 45824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 45924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 46024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 46124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 46224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 46324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 4643e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#endif // #if !defined (__arm__) 4653e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton 46624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return items_found; 46724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 46824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 46924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool 470444fe998bf707bd076a70c3a779db8575533695eGreg ClaytonLocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec, FileSpec &dsym_fspec) 47124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 472444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); 47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec) 47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char path[PATH_MAX]; 47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec->GetPath(path, sizeof(path))) 47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 47824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Make sure the module isn't already just a dSYM file... 47924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL) 48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner size_t obj_file_path_length = strlen(path); 48278c180ab423d3a802566d49a41363b132f20c907Filipe Cabecinhas strlcat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path)); 48378c180ab423d3a802566d49a41363b132f20c907Filipe Cabecinhas strlcat(path, exec_fspec->GetFilename().AsCString(), sizeof(path)); 48424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 485537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton dsym_fspec.SetFile(path, false); 48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 487444fe998bf707bd076a70c3a779db8575533695eGreg Clayton if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr())) 48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner path[obj_file_path_length] = '\0'; 49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char *last_dot = strrchr(path, '.'); 49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (last_dot != NULL && last_dot[0]) 49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char *next_slash = strchr(last_dot, '/'); 49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (next_slash != NULL) 50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *next_slash = '\0'; 50278c180ab423d3a802566d49a41363b132f20c907Filipe Cabecinhas strlcat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path)); 50378c180ab423d3a802566d49a41363b132f20c907Filipe Cabecinhas strlcat(path, exec_fspec->GetFilename().AsCString(), sizeof(path)); 504537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton dsym_fspec.SetFile(path, false); 505444fe998bf707bd076a70c3a779db8575533695eGreg Clayton if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr())) 50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 50824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *last_dot = '\0'; 51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char *prev_slash = strrchr(path, '/'); 51124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (prev_slash != NULL) 51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *prev_slash = '\0'; 51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 51424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 51624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 51724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 51824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 51924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 52024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 52124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 52324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 52424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 52524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 52624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dsym_fspec.Clear(); 52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 52924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 53024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec 531444fe998bf707bd076a70c3a779db8575533695eGreg ClaytonSymbols::LocateExecutableObjectFile (const ModuleSpec &module_spec) 53224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 533444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); 534444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const ArchSpec *arch = module_spec.GetArchitecturePtr(); 535444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const UUID *uuid = module_spec.GetUUIDPtr(); 53624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)", 53824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>", 539940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton arch ? arch->GetArchitectureName() : "<NULL>", 54024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uuid); 54124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 54224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec objfile_fspec; 543444fe998bf707bd076a70c3a779db8575533695eGreg Clayton if (exec_fspec && FileAtPathContainsArchAndUUID (exec_fspec, arch, uuid)) 544444fe998bf707bd076a70c3a779db8575533695eGreg Clayton objfile_fspec = exec_fspec; 54524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 546444fe998bf707bd076a70c3a779db8575533695eGreg Clayton LocateMacOSXFilesUsingDebugSymbols (module_spec, &objfile_fspec, NULL); 54724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return objfile_fspec; 54824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 54924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 55024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec 551444fe998bf707bd076a70c3a779db8575533695eGreg ClaytonSymbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec) 55224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 553444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); 554444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const ArchSpec *arch = module_spec.GetArchitecturePtr(); 555444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const UUID *uuid = module_spec.GetUUIDPtr(); 556444fe998bf707bd076a70c3a779db8575533695eGreg Clayton 55724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 55824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "LocateExecutableSymbolFile (file = %s, arch = %s, uuid = %p)", 55924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>", 560940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton arch ? arch->GetArchitectureName() : "<NULL>", 56124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uuid); 56224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 56324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec symbol_fspec; 56424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // First try and find the dSYM in the same directory as the executable or in 56524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // an appropriate parent directory 566444fe998bf707bd076a70c3a779db8575533695eGreg Clayton if (LocateDSYMInVincinityOfExecutable (module_spec, symbol_fspec) == false) 56724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 56824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We failed to easily find the dSYM above, so use DebugSymbols 569444fe998bf707bd076a70c3a779db8575533695eGreg Clayton LocateMacOSXFilesUsingDebugSymbols (module_spec, NULL, &symbol_fspec); 57024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 57124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return symbol_fspec; 57224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 573b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton 574b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton 575437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Claytonstatic bool 576437b5bccea45a5981edbbbeb4e23424aec4ce774Greg ClaytonGetModuleSpecInfoFromUUIDDictionary (CFDictionaryRef uuid_dict, ModuleSpec &module_spec) 577437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton{ 578437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton bool success = false; 579437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (uuid_dict != NULL && CFGetTypeID (uuid_dict) == CFDictionaryGetTypeID ()) 580437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 581437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton std::string str; 582437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFStringRef cf_str; 583437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 584437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSymbolRichExecutable")); 585437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) 586437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 587437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (CFCString::FileSystemRepresentation(cf_str, str)) 588437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton module_spec.GetFileSpec().SetFile (str.c_str(), true); 589437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 590437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 591437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGDSYMPath")); 592437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) 593437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 594437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (CFCString::FileSystemRepresentation(cf_str, str)) 595437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 596437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton module_spec.GetSymbolFileSpec().SetFile (str.c_str(), true); 597437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton success = true; 598437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 599437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 600437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 601437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGArchitecture")); 602437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) 603437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 604437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (CFCString::FileSystemRepresentation(cf_str, str)) 605437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton module_spec.GetArchitecture().SetTriple(str.c_str()); 606437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 607437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 608437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton std::string DBGBuildSourcePath; 609437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton std::string DBGSourcePath; 610437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 611437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGBuildSourcePath")); 612437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) 613437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 614437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath); 615437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 616437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 617437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSourcePath")); 618437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) 619437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 620437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFCString::FileSystemRepresentation(cf_str, DBGSourcePath); 621437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 622437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 623437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) 624437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 625437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton module_spec.GetSourceMappingList().Append (ConstString(DBGBuildSourcePath.c_str()), ConstString(DBGSourcePath.c_str()), true); 626437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 627437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 628437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton return success; 629437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton} 630b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton 631b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton 632b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Claytonbool 633d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason MolendaSymbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec, bool force_lookup) 634b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton{ 635b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton bool success = false; 636b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton const UUID *uuid_ptr = module_spec.GetUUIDPtr(); 637437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr(); 638d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda 639d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda // It's expensive to check for the DBGShellCommands defaults setting, only do it once per 640d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda // lldb run and cache the result. 641d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda static bool g_have_checked_for_dbgshell_command = false; 642d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda static const char *g_dbgshell_command = NULL; 643d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda if (g_have_checked_for_dbgshell_command == false) 644d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda { 645d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda g_have_checked_for_dbgshell_command = true; 646d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda CFTypeRef defaults_setting = CFPreferencesCopyAppValue (CFSTR ("DBGShellCommands"), CFSTR ("com.apple.DebugSymbols")); 647d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda if (defaults_setting && CFGetTypeID (defaults_setting) == CFStringGetTypeID()) 648d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda { 649d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda char cstr_buf[PATH_MAX]; 650d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda if (CFStringGetCString ((CFStringRef) defaults_setting, cstr_buf, sizeof (cstr_buf), kCFStringEncodingUTF8)) 651d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda { 652d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda g_dbgshell_command = strdup (cstr_buf); // this malloc'ed memory will never be freed 653d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda } 654d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda } 655d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda if (defaults_setting) 656d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda { 657d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda CFRelease (defaults_setting); 658d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda } 659d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda } 660d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda 661d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda // When g_dbgshell_command is NULL, the user has not enabled the use of an external program 662d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda // to find the symbols, don't run it for them. 663d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda if (force_lookup == false && g_dbgshell_command == NULL) 664d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda { 665d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda return false; 666d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda } 667d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda 668437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (uuid_ptr || (file_spec_ptr && file_spec_ptr->Exists())) 669b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 670b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton static bool g_located_dsym_for_uuid_exe = false; 671b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton static bool g_dsym_for_uuid_exe_exists = false; 672b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton static char g_dsym_for_uuid_exe_path[PATH_MAX]; 673b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton if (!g_located_dsym_for_uuid_exe) 674b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 675b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton g_located_dsym_for_uuid_exe = true; 676b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton const char *dsym_for_uuid_exe_path_cstr = getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE"); 677b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton FileSpec dsym_for_uuid_exe_spec; 678b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton if (dsym_for_uuid_exe_path_cstr) 679b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 680b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true); 681b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); 682b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 683b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton 684b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton if (!g_dsym_for_uuid_exe_exists) 685b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 686f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false); 687b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); 688b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton if (!g_dsym_for_uuid_exe_exists) 689b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 69036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton long bufsize; 691f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1) 692f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda { 693f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda char buffer[bufsize]; 694f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda struct passwd pwd; 695f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda struct passwd *tilde_rc = NULL; 696f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda // we are a library so we need to use the reentrant version of getpwnam() 697f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda if (getpwnam_r ("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 698f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda && tilde_rc 699f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda && tilde_rc->pw_dir) 700f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda { 701f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda std::string dsymforuuid_path(tilde_rc->pw_dir); 702f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda dsymforuuid_path += "/bin/dsymForUUID"; 703f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false); 704f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); 705f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda } 706f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda } 707b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 708b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 709d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) 710d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda { 711d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true); 712d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); 713d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda } 714d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda 715b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton if (g_dsym_for_uuid_exe_exists) 716b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton dsym_for_uuid_exe_spec.GetPath (g_dsym_for_uuid_exe_path, sizeof(g_dsym_for_uuid_exe_path)); 717b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 718b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton if (g_dsym_for_uuid_exe_exists) 719b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 72042b336cd509cad89be08f78775d3b1c8c7656a1bJason Molenda std::string uuid_str; 721437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton char file_path[PATH_MAX]; 722437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton file_path[0] = '\0'; 723437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 724437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (uuid_ptr) 72542b336cd509cad89be08f78775d3b1c8c7656a1bJason Molenda uuid_str = uuid_ptr->GetAsString(); 726437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 727437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (file_spec_ptr) 728437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton file_spec_ptr->GetPath(file_path, sizeof(file_path)); 729437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 730437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton StreamString command; 73142b336cd509cad89be08f78775d3b1c8c7656a1bJason Molenda if (!uuid_str.empty()) 73242b336cd509cad89be08f78775d3b1c8c7656a1bJason Molenda command.Printf("%s --ignoreNegativeCache --copyExecutable %s", g_dsym_for_uuid_exe_path, uuid_str.c_str()); 733437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton else if (file_path && file_path[0]) 73463e5cf65c43615da20b272fde2a21ffd4fa6eb29Jason Molenda command.Printf("%s --ignoreNegativeCache --copyExecutable %s", g_dsym_for_uuid_exe_path, file_path); 735437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 736437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (!command.GetString().empty()) 737b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 738437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton int exit_status = -1; 739437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton int signo = -1; 740437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton std::string command_output; 741437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton Error error = Host::RunShellCommand (command.GetData(), 742437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton NULL, // current working directory 743437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton &exit_status, // Exit status 744437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton &signo, // Signal int * 745437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton &command_output, // Command output 746437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 30, // Large timeout to allow for long dsym download times 747437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton NULL); // Don't run in a shell (we don't need shell expansion) 748437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (error.Success() && exit_status == 0 && !command_output.empty()) 749b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 750437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFCData data (CFDataCreateWithBytesNoCopy (NULL, 751437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton (const UInt8 *)command_output.data(), 752437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton command_output.size(), 753437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton kCFAllocatorNull)); 754437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 755437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFCReleaser<CFDictionaryRef> plist((CFDictionaryRef)::CFPropertyListCreateFromXMLData (NULL, data.get(), kCFPropertyListImmutable, NULL)); 756437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 75750972aead4df9c8524d5f8b522e9d92895c72e48Sean Callanan if (plist.get() && CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ()) 758b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 75942b336cd509cad89be08f78775d3b1c8c7656a1bJason Molenda if (!uuid_str.empty()) 760b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 76142b336cd509cad89be08f78775d3b1c8c7656a1bJason Molenda CFCString uuid_cfstr(uuid_str.c_str()); 762437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue (plist.get(), uuid_cfstr.get()); 763437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton success = GetModuleSpecInfoFromUUIDDictionary (uuid_dict, module_spec); 764b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 765437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton else 766b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 767437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton const CFIndex num_values = ::CFDictionaryGetCount(plist.get()); 768437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (num_values > 0) 769b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 770437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton std::vector<CFStringRef> keys (num_values, NULL); 771437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton std::vector<CFDictionaryRef> values (num_values, NULL); 772437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton ::CFDictionaryGetKeysAndValues(plist.get(), NULL, (const void **)&values[0]); 773437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (num_values == 1) 774437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 775437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton return GetModuleSpecInfoFromUUIDDictionary (values[0], module_spec); 776437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 777437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton else 778437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 779437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton for (CFIndex i=0; i<num_values; ++i) 780437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 781437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton ModuleSpec curr_module_spec; 782437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (GetModuleSpecInfoFromUUIDDictionary (values[i], curr_module_spec)) 783437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 78440e278caddf5442776f9408f20d757cc85fe630aSean Callanan if (module_spec.GetArchitecture().IsCompatibleMatch(curr_module_spec.GetArchitecture())) 785437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 786437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton module_spec = curr_module_spec; 787437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton return true; 788437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 789437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 790437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 791437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 792b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 793b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 794b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 795b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 796b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 797b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 798b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 799b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton return success; 800b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton} 801b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton 802