Symbols.cpp revision 36da2aa6dc5ad9994b638ed09eb81c44cc05540b
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 128cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen // Emit some warning messages since the UUIDs do not match! 129cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen char path_buf[PATH_MAX]; 130cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen path_buf[0] = '\0'; 131cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen const char *path = file_spec.GetPath(path_buf, PATH_MAX) ? path_buf 132cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen : file_spec.GetFilename().AsCString(); 1339262cd52e254fb261334254a80a1b316d59b555cJohnny Chen StreamString ss_m_uuid, ss_o_uuid; 1349262cd52e254fb261334254a80a1b316d59b555cJohnny Chen uuid->Dump(&ss_m_uuid); 1359262cd52e254fb261334254a80a1b316d59b555cJohnny Chen file_uuid.Dump(&ss_o_uuid); 136cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen Host::SystemLog (Host::eSystemLogWarning, 1379262cd52e254fb261334254a80a1b316d59b555cJohnny Chen "warning: UUID mismatch detected between binary (%s) and:\n\t'%s' (%s)\n", 1389262cd52e254fb261334254a80a1b316d59b555cJohnny Chen ss_m_uuid.GetData(), path, ss_o_uuid.GetData()); 139cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen return false; 14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data_offset = cmd_offset + cmd_size; 14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerUniversalMachOFileContainsArchAndUUID 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const FileSpec &file_spec, 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const ArchSpec *arch, 1510467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton const lldb_private::UUID *uuid, 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner off_t file_offset, 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataExtractor& data, 15436da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::offset_t data_offset, 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t magic 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 1581674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton assert(magic == UniversalMagic || magic == UniversalMagicSwapped); 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Universal mach-o files always have their headers encoded as BIG endian 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetByteOrder(eByteOrderBig); 16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t i; 16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t nfat_arch = data.GetU32(&data_offset); // number of structs that follow 16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t fat_header_and_arch_size = sizeof(struct fat_header) + nfat_arch * sizeof(struct fat_arch); 16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (data.GetByteSize() < fat_header_and_arch_size) 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, fat_header_and_arch_size)); 16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetData (data_buffer_sp); 17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i=0; i<nfat_arch; i++) 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner cpu_type_t arch_cputype = data.GetU32(&data_offset); // cpu specifier (int) 17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner cpu_subtype_t arch_cpusubtype = data.GetU32(&data_offset); // machine specifier (int) 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t arch_offset = data.GetU32(&data_offset); // file offset to this object file 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // uint32_t arch_size = data.GetU32(&data_offset); // size of this object file 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // uint32_t arch_align = data.GetU32(&data_offset); // alignment as a power of 2 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data_offset += 8; // Skip size and align as we don't need those 18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Only process this slice if the cpu type/subtype matches 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (arch) 18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 183cf0150574a0a97049efe2dce2cc0aa433705feb3Greg Clayton ArchSpec fat_arch(eArchTypeMachO, arch_cputype, arch_cpusubtype); 18464246cda58b64208f5c415fc52909c45c3dc3e2bSean Callanan if (!fat_arch.IsExactMatch(*arch)) 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Create a buffer with only the arch slice date in it 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataExtractor arch_data; 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset + arch_offset, 0x1000)); 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner arch_data.SetData(data_buffer_sp); 19236da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::offset_t arch_data_offset = 0; 19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t arch_magic = arch_data.GetU32(&arch_data_offset); 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (arch_magic) 19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 1971674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic32: 1981674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic32Swapped: 1991674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic64: 2001674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic64Swapped: 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset + arch_offset, arch_data, arch_data_offset, arch_magic)) 20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool 21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileAtPathContainsArchAndUUID 21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const FileSpec &file_spec, 21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const ArchSpec *arch, 2140467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton const lldb_private::UUID *uuid 21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataExtractor data; 21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner off_t file_offset = 0; 21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, 0x1000)); 22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0) 22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner data.SetData(data_buffer_sp); 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::offset_t data_offset = 0; 22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t magic = data.GetU32(&data_offset); 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (magic) 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // 32 bit mach-o file 2311674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic32: 2321674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic32Swapped: 2331674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic64: 2341674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case HeaderMagic64Swapped: 23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic); 23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // fat mach-o file 2381674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case UniversalMagic: 2391674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton case UniversalMagicSwapped: 24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return UniversalMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic); 24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner default: 24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 24995b765e8000b44644d021e95bc58eac95028573bGreg ClaytonFileSpec 25095b765e8000b44644d021e95bc58eac95028573bGreg ClaytonSymbols::FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec, 25195b765e8000b44644d021e95bc58eac95028573bGreg Clayton const lldb_private::UUID *uuid, 25295b765e8000b44644d021e95bc58eac95028573bGreg Clayton const ArchSpec *arch) 25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char path[PATH_MAX]; 25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec dsym_fspec; 25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dsym_bundle_fspec.GetPath(path, sizeof(path))) 25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1); 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26252fd984f7e67c3a0ab18d5565f40356bcfa84822Greg Clayton lldb_utility::CleanUp <DIR *, int> dirp (opendir(path), NULL, closedir); 263ad400274d4e3ed01a4c730e1d6f95e6cb2ac73dcGreg Clayton if (dirp.is_valid()) 26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 265537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton dsym_fspec.GetDirectory().SetCString(path); 26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner struct dirent* dp; 267ad400274d4e3ed01a4c730e1d6f95e6cb2ac73dcGreg Clayton while ((dp = readdir(dirp.get())) != NULL) 26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Only search directories 27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) 27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dp->d_namlen == 1 && dp->d_name[0] == '.') 27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.') 27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) 28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 281537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton dsym_fspec.GetFilename().SetCString(dp->d_name); 28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (FileAtPathContainsArchAndUUID (dsym_fspec, arch, uuid)) 28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return dsym_fspec; 28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dsym_fspec.Clear(); 28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return dsym_fspec; 29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic int 29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerLocateMacOSXFilesUsingDebugSymbols 29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 295444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const ModuleSpec &module_spec, 29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec *out_exec_fspec, // If non-NULL, try and find the executable 29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec *out_dsym_fspec // If non-NULL try and find the debug symbol file 29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int items_found = 0; 30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_exec_fspec) 30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner out_exec_fspec->Clear(); 30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_dsym_fspec) 30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner out_dsym_fspec->Clear(); 30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3083e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#if !defined (__arm__) // No DebugSymbols on the iOS devices 3093e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton 310444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const UUID *uuid = module_spec.GetUUIDPtr(); 311444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const ArchSpec *arch = module_spec.GetArchitecturePtr(); 312444fe998bf707bd076a70c3a779db8575533695eGreg Clayton 31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (uuid && uuid->IsValid()) 31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Try and locate the dSYM file using DebugSymbols first 31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes(); 31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (module_uuid != NULL) 31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 3190fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes (NULL, 32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[0], 32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[1], 32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[2], 32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[3], 32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[4], 32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[5], 32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[6], 32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[7], 32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[8], 32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[9], 33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[10], 33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[11], 33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[12], 33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[13], 33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[14], 33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner module_uuid[15])); 33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (module_uuid_ref.get()) 33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CFCReleaser<CFURLRef> exec_url; 340444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); 34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec) 34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char exec_cf_path[PATH_MAX]; 34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path))) 34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exec_url.reset(::CFURLCreateFromFileSystemRepresentation (NULL, 34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner (const UInt8 *)exec_cf_path, 34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner strlen(exec_cf_path), 34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FALSE)); 34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CFCReleaser<CFURLRef> dsym_url (::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get())); 35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char path[PATH_MAX]; 35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dsym_url.get()) 35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_dsym_fspec) 35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1)) 35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 3601b09dfef975addaa4aa330edb1dc7e28b8436028Jason Molenda out_dsym_fspec->SetFile(path, path[0] == '~'); 36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_dsym_fspec->GetFileType () == FileSpec::eFileTypeDirectory) 36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 36495b765e8000b44644d021e95bc58eac95028573bGreg Clayton *out_dsym_fspec = Symbols::FindSymbolFileInBundle (*out_dsym_fspec, uuid, arch); 36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (*out_dsym_fspec) 36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++items_found; 36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++items_found; 37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 375964deba8853eb794e59263322b59b09b43669618Greg Clayton CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get())); 376964deba8853eb794e59263322b59b09b43669618Greg Clayton CFDictionaryRef uuid_dict = NULL; 377964deba8853eb794e59263322b59b09b43669618Greg Clayton if (dict.get()) 37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 379964deba8853eb794e59263322b59b09b43669618Greg Clayton char uuid_cstr_buf[64]; 380964deba8853eb794e59263322b59b09b43669618Greg Clayton const char *uuid_cstr = uuid->GetAsCString (uuid_cstr_buf, sizeof(uuid_cstr_buf)); 381964deba8853eb794e59263322b59b09b43669618Greg Clayton CFCString uuid_cfstr (uuid_cstr); 38263e5cf65c43615da20b272fde2a21ffd4fa6eb29Jason Molenda uuid_dict = static_cast<CFDictionaryRef>(::CFDictionaryGetValue (dict.get(), uuid_cfstr.get())); 383964deba8853eb794e59263322b59b09b43669618Greg Clayton if (uuid_dict) 38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 385964deba8853eb794e59263322b59b09b43669618Greg Clayton 386964deba8853eb794e59263322b59b09b43669618Greg Clayton CFStringRef actual_src_cfpath = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSourcePath"))); 387964deba8853eb794e59263322b59b09b43669618Greg Clayton if (actual_src_cfpath) 38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 389964deba8853eb794e59263322b59b09b43669618Greg Clayton CFStringRef build_src_cfpath = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGBuildSourcePath"))); 390964deba8853eb794e59263322b59b09b43669618Greg Clayton if (build_src_cfpath) 391b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton { 392964deba8853eb794e59263322b59b09b43669618Greg Clayton char actual_src_path[PATH_MAX]; 393964deba8853eb794e59263322b59b09b43669618Greg Clayton char build_src_path[PATH_MAX]; 394964deba8853eb794e59263322b59b09b43669618Greg Clayton ::CFStringGetFileSystemRepresentation (actual_src_cfpath, actual_src_path, sizeof(actual_src_path)); 395964deba8853eb794e59263322b59b09b43669618Greg Clayton ::CFStringGetFileSystemRepresentation (build_src_cfpath, build_src_path, sizeof(build_src_path)); 3964d8c5434779393d5502b45f42a9371477604aab7Greg Clayton if (actual_src_path[0] == '~') 3974d8c5434779393d5502b45f42a9371477604aab7Greg Clayton { 3984d8c5434779393d5502b45f42a9371477604aab7Greg Clayton FileSpec resolved_source_path(actual_src_path, true); 3994d8c5434779393d5502b45f42a9371477604aab7Greg Clayton resolved_source_path.GetPath(actual_src_path, sizeof(actual_src_path)); 4004d8c5434779393d5502b45f42a9371477604aab7Greg Clayton } 401964deba8853eb794e59263322b59b09b43669618Greg Clayton module_spec.GetSourceMappingList().Append (ConstString(build_src_path), ConstString(actual_src_path), true); 402b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton } 4030fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4040fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 405964deba8853eb794e59263322b59b09b43669618Greg Clayton } 406964deba8853eb794e59263322b59b09b43669618Greg Clayton 407964deba8853eb794e59263322b59b09b43669618Greg Clayton if (out_exec_fspec) 408964deba8853eb794e59263322b59b09b43669618Greg Clayton { 409964deba8853eb794e59263322b59b09b43669618Greg Clayton bool success = false; 410964deba8853eb794e59263322b59b09b43669618Greg Clayton if (uuid_dict) 411964deba8853eb794e59263322b59b09b43669618Greg Clayton { 412964deba8853eb794e59263322b59b09b43669618Greg Clayton CFStringRef exec_cf_path = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSymbolRichExecutable"))); 413964deba8853eb794e59263322b59b09b43669618Greg Clayton if (exec_cf_path && ::CFStringGetFileSystemRepresentation (exec_cf_path, path, sizeof(path))) 414964deba8853eb794e59263322b59b09b43669618Greg Clayton { 415964deba8853eb794e59263322b59b09b43669618Greg Clayton ++items_found; 416964deba8853eb794e59263322b59b09b43669618Greg Clayton out_exec_fspec->SetFile(path, path[0] == '~'); 417964deba8853eb794e59263322b59b09b43669618Greg Clayton if (out_exec_fspec->Exists()) 418964deba8853eb794e59263322b59b09b43669618Greg Clayton success = true; 419964deba8853eb794e59263322b59b09b43669618Greg Clayton } 420964deba8853eb794e59263322b59b09b43669618Greg Clayton } 4219ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton 4229ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton if (!success) 4230fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4240fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton // No dictionary, check near the dSYM bundle for an executable that matches... 4250fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1)) 4260fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4270fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton char *dsym_extension_pos = ::strstr (path, ".dSYM"); 4280fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (dsym_extension_pos) 4290fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4300fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton *dsym_extension_pos = '\0'; 4310fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton FileSpec file_spec (path, true); 4320fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton switch (file_spec.GetFileType()) 4330fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4340fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeDirectory: // Bundle directory? 4350fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4360fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton CFCBundle bundle (path); 4370fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton CFCReleaser<CFURLRef> bundle_exe_url (bundle.CopyExecutableURL ()); 4380fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (bundle_exe_url.get()) 4390fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4400fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (::CFURLGetFileSystemRepresentation (bundle_exe_url.get(), true, (UInt8*)path, sizeof(path)-1)) 4410fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4420fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton FileSpec bundle_exe_file_spec (path, true); 4430fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton 4440fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (FileAtPathContainsArchAndUUID (bundle_exe_file_spec, arch, uuid)) 4450fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4460fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton ++items_found; 4470fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton *out_exec_fspec = bundle_exe_file_spec; 4480fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4490fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4500fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4510fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4520fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton break; 4530fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton 4540fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypePipe: // Forget pipes 4550fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeSocket: // We can't process socket files 4560fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeInvalid: // File doesn't exist... 4570fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton break; 4580fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton 4590fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeUnknown: 4600fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeRegular: 4610fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeSymbolicLink: 4620fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton case FileSpec::eFileTypeOther: 4630fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (FileAtPathContainsArchAndUUID (file_spec, arch, uuid)) 4640fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton { 4650fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton ++items_found; 4660fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton *out_exec_fspec = file_spec; 4670fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4680fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton break; 4690fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 4700fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton } 47124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 47224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 4783e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#endif // #if !defined (__arm__) 4793e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton 48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return items_found; 48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 48224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 48324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool 484444fe998bf707bd076a70c3a779db8575533695eGreg ClaytonLocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec, FileSpec &dsym_fspec) 48524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 486444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); 48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec) 48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char path[PATH_MAX]; 49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (exec_fspec->GetPath(path, sizeof(path))) 49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Make sure the module isn't already just a dSYM file... 49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL) 49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner size_t obj_file_path_length = strlen(path); 49678c180ab423d3a802566d49a41363b132f20c907Filipe Cabecinhas strlcat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path)); 49778c180ab423d3a802566d49a41363b132f20c907Filipe Cabecinhas strlcat(path, exec_fspec->GetFilename().AsCString(), sizeof(path)); 49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 499537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton dsym_fspec.SetFile(path, false); 50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 501444fe998bf707bd076a70c3a779db8575533695eGreg Clayton if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr())) 50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 50524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner path[obj_file_path_length] = '\0'; 50824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char *last_dot = strrchr(path, '.'); 51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (last_dot != NULL && last_dot[0]) 51124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char *next_slash = strchr(last_dot, '/'); 51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (next_slash != NULL) 51424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *next_slash = '\0'; 51678c180ab423d3a802566d49a41363b132f20c907Filipe Cabecinhas strlcat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path)); 51778c180ab423d3a802566d49a41363b132f20c907Filipe Cabecinhas strlcat(path, exec_fspec->GetFilename().AsCString(), sizeof(path)); 518537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton dsym_fspec.SetFile(path, false); 519444fe998bf707bd076a70c3a779db8575533695eGreg Clayton if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr())) 52024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 52124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 52324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *last_dot = '\0'; 52424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char *prev_slash = strrchr(path, '/'); 52524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (prev_slash != NULL) 52624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *prev_slash = '\0'; 52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 52924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 53224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 53324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 53424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 54024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dsym_fspec.Clear(); 54124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 54224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 54324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 54424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec 545444fe998bf707bd076a70c3a779db8575533695eGreg ClaytonSymbols::LocateExecutableObjectFile (const ModuleSpec &module_spec) 54624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 547444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); 548444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const ArchSpec *arch = module_spec.GetArchitecturePtr(); 549444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const UUID *uuid = module_spec.GetUUIDPtr(); 55024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 55124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)", 55224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>", 553940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton arch ? arch->GetArchitectureName() : "<NULL>", 55424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uuid); 55524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 55624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec objfile_fspec; 557444fe998bf707bd076a70c3a779db8575533695eGreg Clayton if (exec_fspec && FileAtPathContainsArchAndUUID (exec_fspec, arch, uuid)) 558444fe998bf707bd076a70c3a779db8575533695eGreg Clayton objfile_fspec = exec_fspec; 55924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 560444fe998bf707bd076a70c3a779db8575533695eGreg Clayton LocateMacOSXFilesUsingDebugSymbols (module_spec, &objfile_fspec, NULL); 56124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return objfile_fspec; 56224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 56324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 56424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec 565444fe998bf707bd076a70c3a779db8575533695eGreg ClaytonSymbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec) 56624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 567444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); 568444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const ArchSpec *arch = module_spec.GetArchitecturePtr(); 569444fe998bf707bd076a70c3a779db8575533695eGreg Clayton const UUID *uuid = module_spec.GetUUIDPtr(); 570444fe998bf707bd076a70c3a779db8575533695eGreg Clayton 57124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 57224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "LocateExecutableSymbolFile (file = %s, arch = %s, uuid = %p)", 57324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>", 574940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton arch ? arch->GetArchitectureName() : "<NULL>", 57524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uuid); 57624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 57724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileSpec symbol_fspec; 57824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // First try and find the dSYM in the same directory as the executable or in 57924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // an appropriate parent directory 580444fe998bf707bd076a70c3a779db8575533695eGreg Clayton if (LocateDSYMInVincinityOfExecutable (module_spec, symbol_fspec) == false) 58124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 58224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We failed to easily find the dSYM above, so use DebugSymbols 583444fe998bf707bd076a70c3a779db8575533695eGreg Clayton LocateMacOSXFilesUsingDebugSymbols (module_spec, NULL, &symbol_fspec); 58424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 58524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return symbol_fspec; 58624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 587b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton 588b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton 589437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Claytonstatic bool 590437b5bccea45a5981edbbbeb4e23424aec4ce774Greg ClaytonGetModuleSpecInfoFromUUIDDictionary (CFDictionaryRef uuid_dict, ModuleSpec &module_spec) 591437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton{ 592437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton bool success = false; 593437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (uuid_dict != NULL && CFGetTypeID (uuid_dict) == CFDictionaryGetTypeID ()) 594437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 595437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton std::string str; 596437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFStringRef cf_str; 597437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 598437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSymbolRichExecutable")); 599437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) 600437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 601437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (CFCString::FileSystemRepresentation(cf_str, str)) 602437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton module_spec.GetFileSpec().SetFile (str.c_str(), true); 603437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 604437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 605437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGDSYMPath")); 606437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) 607437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 608437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (CFCString::FileSystemRepresentation(cf_str, str)) 609437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 610437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton module_spec.GetSymbolFileSpec().SetFile (str.c_str(), true); 611437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton success = true; 612437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 613437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 614437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 615437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGArchitecture")); 616437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) 617437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 618437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (CFCString::FileSystemRepresentation(cf_str, str)) 619437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton module_spec.GetArchitecture().SetTriple(str.c_str()); 620437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 621437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 622437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton std::string DBGBuildSourcePath; 623437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton std::string DBGSourcePath; 624437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 625437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGBuildSourcePath")); 626437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) 627437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 628437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath); 629437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 630437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 631437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSourcePath")); 632437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) 633437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 634437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFCString::FileSystemRepresentation(cf_str, DBGSourcePath); 635437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 636437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 637437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) 638437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 639437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton module_spec.GetSourceMappingList().Append (ConstString(DBGBuildSourcePath.c_str()), ConstString(DBGSourcePath.c_str()), true); 640437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 641437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 642437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton return success; 643437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton} 644b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton 645b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton 646b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Claytonbool 647d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason MolendaSymbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec, bool force_lookup) 648b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton{ 649b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton bool success = false; 650b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton const UUID *uuid_ptr = module_spec.GetUUIDPtr(); 651437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr(); 652d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda 653d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda // It's expensive to check for the DBGShellCommands defaults setting, only do it once per 654d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda // lldb run and cache the result. 655d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda static bool g_have_checked_for_dbgshell_command = false; 656d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda static const char *g_dbgshell_command = NULL; 657d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda if (g_have_checked_for_dbgshell_command == false) 658d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda { 659d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda g_have_checked_for_dbgshell_command = true; 660d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda CFTypeRef defaults_setting = CFPreferencesCopyAppValue (CFSTR ("DBGShellCommands"), CFSTR ("com.apple.DebugSymbols")); 661d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda if (defaults_setting && CFGetTypeID (defaults_setting) == CFStringGetTypeID()) 662d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda { 663d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda char cstr_buf[PATH_MAX]; 664d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda if (CFStringGetCString ((CFStringRef) defaults_setting, cstr_buf, sizeof (cstr_buf), kCFStringEncodingUTF8)) 665d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda { 666d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda g_dbgshell_command = strdup (cstr_buf); // this malloc'ed memory will never be freed 667d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda } 668d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda } 669d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda if (defaults_setting) 670d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda { 671d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda CFRelease (defaults_setting); 672d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda } 673d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda } 674d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda 675d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda // When g_dbgshell_command is NULL, the user has not enabled the use of an external program 676d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda // to find the symbols, don't run it for them. 677d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda if (force_lookup == false && g_dbgshell_command == NULL) 678d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda { 679d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda return false; 680d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda } 681d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda 682437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (uuid_ptr || (file_spec_ptr && file_spec_ptr->Exists())) 683b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 684b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton static bool g_located_dsym_for_uuid_exe = false; 685b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton static bool g_dsym_for_uuid_exe_exists = false; 686b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton static char g_dsym_for_uuid_exe_path[PATH_MAX]; 687b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton if (!g_located_dsym_for_uuid_exe) 688b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 689b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton g_located_dsym_for_uuid_exe = true; 690b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton const char *dsym_for_uuid_exe_path_cstr = getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE"); 691b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton FileSpec dsym_for_uuid_exe_spec; 692b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton if (dsym_for_uuid_exe_path_cstr) 693b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 694b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true); 695b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); 696b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 697b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton 698b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton if (!g_dsym_for_uuid_exe_exists) 699b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 700f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false); 701b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); 702b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton if (!g_dsym_for_uuid_exe_exists) 703b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 70436da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton long bufsize; 705f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1) 706f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda { 707f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda char buffer[bufsize]; 708f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda struct passwd pwd; 709f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda struct passwd *tilde_rc = NULL; 710f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda // we are a library so we need to use the reentrant version of getpwnam() 711f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda if (getpwnam_r ("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 712f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda && tilde_rc 713f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda && tilde_rc->pw_dir) 714f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda { 715f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda std::string dsymforuuid_path(tilde_rc->pw_dir); 716f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda dsymforuuid_path += "/bin/dsymForUUID"; 717f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false); 718f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); 719f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda } 720f25697550690a7cda6a013c596fb8e6159b58256Jason Molenda } 721b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 722b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 723d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) 724d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda { 725d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true); 726d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); 727d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda } 728d6d45ceeae51b6dbb9221a3cf82441afa212a7dcJason Molenda 729b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton if (g_dsym_for_uuid_exe_exists) 730b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton dsym_for_uuid_exe_spec.GetPath (g_dsym_for_uuid_exe_path, sizeof(g_dsym_for_uuid_exe_path)); 731b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 732b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton if (g_dsym_for_uuid_exe_exists) 733b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 734b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton char uuid_cstr_buffer[64]; 735437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton char file_path[PATH_MAX]; 736437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton uuid_cstr_buffer[0] = '\0'; 737437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton file_path[0] = '\0'; 738437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton const char *uuid_cstr = NULL; 739437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 740437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (uuid_ptr) 741437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton uuid_cstr = uuid_ptr->GetAsCString(uuid_cstr_buffer, sizeof(uuid_cstr_buffer)); 742437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 743437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (file_spec_ptr) 744437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton file_spec_ptr->GetPath(file_path, sizeof(file_path)); 745437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 746437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton StreamString command; 747437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (uuid_cstr) 74863e5cf65c43615da20b272fde2a21ffd4fa6eb29Jason Molenda command.Printf("%s --ignoreNegativeCache --copyExecutable %s", g_dsym_for_uuid_exe_path, uuid_cstr); 749437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton else if (file_path && file_path[0]) 75063e5cf65c43615da20b272fde2a21ffd4fa6eb29Jason Molenda command.Printf("%s --ignoreNegativeCache --copyExecutable %s", g_dsym_for_uuid_exe_path, file_path); 751437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 752437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (!command.GetString().empty()) 753b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 754437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton int exit_status = -1; 755437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton int signo = -1; 756437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton std::string command_output; 757437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton Error error = Host::RunShellCommand (command.GetData(), 758437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton NULL, // current working directory 759437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton &exit_status, // Exit status 760437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton &signo, // Signal int * 761437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton &command_output, // Command output 762437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 30, // Large timeout to allow for long dsym download times 763437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton NULL); // Don't run in a shell (we don't need shell expansion) 764437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (error.Success() && exit_status == 0 && !command_output.empty()) 765b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 766437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFCData data (CFDataCreateWithBytesNoCopy (NULL, 767437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton (const UInt8 *)command_output.data(), 768437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton command_output.size(), 769437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton kCFAllocatorNull)); 770437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 771437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFCReleaser<CFDictionaryRef> plist((CFDictionaryRef)::CFPropertyListCreateFromXMLData (NULL, data.get(), kCFPropertyListImmutable, NULL)); 772437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton 773437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ()) 774b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 775437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (uuid_cstr) 776b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 777437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFCString uuid_cfstr(uuid_cstr); 778437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue (plist.get(), uuid_cfstr.get()); 779437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton success = GetModuleSpecInfoFromUUIDDictionary (uuid_dict, module_spec); 780b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 781437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton else 782b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 783437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton const CFIndex num_values = ::CFDictionaryGetCount(plist.get()); 784437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (num_values > 0) 785b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton { 786437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton std::vector<CFStringRef> keys (num_values, NULL); 787437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton std::vector<CFDictionaryRef> values (num_values, NULL); 788437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton ::CFDictionaryGetKeysAndValues(plist.get(), NULL, (const void **)&values[0]); 789437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (num_values == 1) 790437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 791437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton return GetModuleSpecInfoFromUUIDDictionary (values[0], module_spec); 792437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 793437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton else 794437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 795437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton for (CFIndex i=0; i<num_values; ++i) 796437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 797437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton ModuleSpec curr_module_spec; 798437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton if (GetModuleSpecInfoFromUUIDDictionary (values[i], curr_module_spec)) 799437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 80040e278caddf5442776f9408f20d757cc85fe630aSean Callanan if (module_spec.GetArchitecture().IsCompatibleMatch(curr_module_spec.GetArchitecture())) 801437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton { 802437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton module_spec = curr_module_spec; 803437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton return true; 804437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 805437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 806437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 807437b5bccea45a5981edbbbeb4e23424aec4ce774Greg Clayton } 808b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 809b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 810b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 811b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 812b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 813b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 814b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton } 815b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton return success; 816b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton} 817b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton 818