Symbols.cpp revision b924eb6c5250a9909dc55ac736d231f7ccae423b
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>
141674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton#include "llvm/Support/MachO.h"
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <CoreFoundation/CoreFoundation.h>
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/ArchSpec.h"
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/DataBuffer.h"
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/DataExtractor.h"
24444fe998bf707bd076a70c3a779db8575533695eGreg Clayton#include "lldb/Core/Module.h"
2549ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Core/ModuleSpec.h"
269262cd52e254fb261334254a80a1b316d59b555cJohnny Chen#include "lldb/Core/StreamString.h"
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Timer.h"
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/UUID.h"
29cd548034fa23113e995b8463d14f910ba2f7298cGreg Clayton#include "lldb/Host/Endian.h"
30cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen#include "lldb/Host/Host.h"
31ad400274d4e3ed01a4c730e1d6f95e6cb2ac73dcGreg Clayton#include "lldb/Utility/CleanUp.h"
32a1ebbd2410cafb890ab8519ae4e6b24cc618bd6aDaniel Dunbar#include "Host/macosx/cfcpp/CFCBundle.h"
33b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton#include "Host/macosx/cfcpp/CFCData.h"
3454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton#include "Host/macosx/cfcpp/CFCReleaser.h"
35b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton#include "Host/macosx/cfcpp/CFCString.h"
365bc7b67ccc8bb4a977d129e51313067dcbc7bb94Chris Lattner#include "mach/machine.h"
3754e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton
380fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
411674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Claytonusing namespace llvm::MachO;
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
433e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#if !defined (__arm__) // No DebugSymbols on the iOS devices
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerextern "C" {
4554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCFURLRef DBGCopyFullDSYMURLForUUID (CFUUIDRef uuid, CFURLRef exec_url);
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCFDictionaryRef DBGCopyDSYMPropertyLists (CFURLRef dsym_url);
4854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton
4954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton}
503e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#endif
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSkinnyMachOFileContainsArchAndUUID
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const FileSpec &file_spec,
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const ArchSpec *arch,
570467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton    const lldb_private::UUID *uuid,   // the UUID we are looking for
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    off_t file_offset,
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DataExtractor& data,
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t data_offset,
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t magic
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
641674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton    assert(magic == HeaderMagic32 || magic == HeaderMagic32Swapped || magic == HeaderMagic64 || magic == HeaderMagic64Swapped);
651674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton    if (magic == HeaderMagic32 || magic == HeaderMagic64)
66cd548034fa23113e995b8463d14f910ba2f7298cGreg Clayton        data.SetByteOrder (lldb::endian::InlHostByteOrder());
67cd548034fa23113e995b8463d14f910ba2f7298cGreg Clayton    else if (lldb::endian::InlHostByteOrder() == eByteOrderBig)
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data.SetByteOrder (eByteOrderLittle);
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data.SetByteOrder (eByteOrderBig);
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t i;
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t cputype      = data.GetU32(&data_offset);    // cpu specifier
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t cpusubtype   = data.GetU32(&data_offset);    // machine specifier
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    data_offset+=4; // Skip mach file type
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t ncmds        = data.GetU32(&data_offset);    // number of load commands
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t sizeofcmds   = data.GetU32(&data_offset);    // the size of all the load commands
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    data_offset+=4; // Skip flags
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Check the architecture if we have a valid arch pointer
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (arch)
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
83cf0150574a0a97049efe2dce2cc0aa433705feb3Greg Clayton        ArchSpec file_arch(eArchTypeMachO, cputype, cpusubtype);
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (file_arch != *arch)
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // The file exists, and if a valid arch pointer was passed in we know
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // if already matches, so we can return if we aren't looking for a specific
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // UUID
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (uuid == NULL)
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return true;
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
951674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton    if (magic == HeaderMagic64Swapped || magic == HeaderMagic64)
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data_offset += 4;   // Skip reserved field for in mach_header_64
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Make sure we have enough data for all the load commands
991674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton    if (magic == HeaderMagic64Swapped || magic == HeaderMagic64)
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (data.GetByteSize() < sizeof(struct mach_header_64) + sizeofcmds)
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header_64) + sizeofcmds));
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            data.SetData (data_buffer_sp);
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (data.GetByteSize() < sizeof(struct mach_header) + sizeofcmds)
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header) + sizeofcmds));
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            data.SetData (data_buffer_sp);
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (i=0; i<ncmds; i++)
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint32_t cmd_offset = data_offset;    // Save this data_offset in case parsing of the segment goes awry!
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t cmd        = data.GetU32(&data_offset);
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t cmd_size   = data.GetU32(&data_offset);
1211674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        if (cmd == LoadCommandUUID)
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
1230467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton            lldb_private::UUID file_uuid (data.GetData(&data_offset, 16), 16);
124cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            if (file_uuid == *uuid)
125cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen                return true;
126cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen
127cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            // Emit some warning messages since the UUIDs do not match!
128cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            char path_buf[PATH_MAX];
129cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            path_buf[0] = '\0';
130cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            const char *path = file_spec.GetPath(path_buf, PATH_MAX) ? path_buf
131cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen                                                                     : file_spec.GetFilename().AsCString();
1329262cd52e254fb261334254a80a1b316d59b555cJohnny Chen            StreamString ss_m_uuid, ss_o_uuid;
1339262cd52e254fb261334254a80a1b316d59b555cJohnny Chen            uuid->Dump(&ss_m_uuid);
1349262cd52e254fb261334254a80a1b316d59b555cJohnny Chen            file_uuid.Dump(&ss_o_uuid);
135cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            Host::SystemLog (Host::eSystemLogWarning,
1369262cd52e254fb261334254a80a1b316d59b555cJohnny Chen                             "warning: UUID mismatch detected between binary (%s) and:\n\t'%s' (%s)\n",
1379262cd52e254fb261334254a80a1b316d59b555cJohnny Chen                             ss_m_uuid.GetData(), path, ss_o_uuid.GetData());
138cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            return false;
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data_offset = cmd_offset + cmd_size;
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerUniversalMachOFileContainsArchAndUUID
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const FileSpec &file_spec,
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const ArchSpec *arch,
1500467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton    const lldb_private::UUID *uuid,
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    off_t file_offset,
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DataExtractor& data,
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t data_offset,
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t magic
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
1571674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton    assert(magic == UniversalMagic || magic == UniversalMagicSwapped);
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Universal mach-o files always have their headers encoded as BIG endian
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    data.SetByteOrder(eByteOrderBig);
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t i;
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t nfat_arch = data.GetU32(&data_offset);   // number of structs that follow
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t fat_header_and_arch_size = sizeof(struct fat_header) + nfat_arch * sizeof(struct fat_arch);
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (data.GetByteSize() < fat_header_and_arch_size)
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, fat_header_and_arch_size));
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data.SetData (data_buffer_sp);
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (i=0; i<nfat_arch; i++)
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        cpu_type_t      arch_cputype        = data.GetU32(&data_offset);    // cpu specifier (int)
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        cpu_subtype_t   arch_cpusubtype     = data.GetU32(&data_offset);    // machine specifier (int)
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t        arch_offset         = data.GetU32(&data_offset);    // file offset to this object file
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //  uint32_t        arch_size           = data.GetU32(&data_offset);    // size of this object file
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //  uint32_t        arch_align          = data.GetU32(&data_offset);    // alignment as a power of 2
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data_offset += 8;   // Skip size and align as we don't need those
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Only process this slice if the cpu type/subtype matches
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (arch)
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
182cf0150574a0a97049efe2dce2cc0aa433705feb3Greg Clayton            ArchSpec fat_arch(eArchTypeMachO, arch_cputype, arch_cpusubtype);
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (fat_arch != *arch)
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                continue;
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Create a buffer with only the arch slice date in it
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DataExtractor arch_data;
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset + arch_offset, 0x1000));
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        arch_data.SetData(data_buffer_sp);
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t arch_data_offset = 0;
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t arch_magic = arch_data.GetU32(&arch_data_offset);
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (arch_magic)
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
1961674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic32:
1971674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic32Swapped:
1981674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic64:
1991674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic64Swapped:
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset + arch_offset, arch_data, arch_data_offset, arch_magic))
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return true;
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileAtPathContainsArchAndUUID
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const FileSpec &file_spec,
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const ArchSpec *arch,
2130467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton    const lldb_private::UUID *uuid
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DataExtractor data;
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    off_t file_offset = 0;
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, 0x1000));
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0)
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data.SetData(data_buffer_sp);
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t data_offset = 0;
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t magic = data.GetU32(&data_offset);
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (magic)
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // 32 bit mach-o file
2301674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic32:
2311674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic32Swapped:
2321674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic64:
2331674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic64Swapped:
23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic);
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // fat mach-o file
2371674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case UniversalMagic:
2381674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case UniversalMagicSwapped:
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return UniversalMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic);
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
24895b765e8000b44644d021e95bc58eac95028573bGreg ClaytonFileSpec
24995b765e8000b44644d021e95bc58eac95028573bGreg ClaytonSymbols::FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec,
25095b765e8000b44644d021e95bc58eac95028573bGreg Clayton                                 const lldb_private::UUID *uuid,
25195b765e8000b44644d021e95bc58eac95028573bGreg Clayton                                 const ArchSpec *arch)
25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char path[PATH_MAX];
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FileSpec dsym_fspec;
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (dsym_bundle_fspec.GetPath(path, sizeof(path)))
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);
26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26152fd984f7e67c3a0ab18d5565f40356bcfa84822Greg Clayton        lldb_utility::CleanUp <DIR *, int> dirp (opendir(path), NULL, closedir);
262ad400274d4e3ed01a4c730e1d6f95e6cb2ac73dcGreg Clayton        if (dirp.is_valid())
26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
264537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton            dsym_fspec.GetDirectory().SetCString(path);
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            struct dirent* dp;
266ad400274d4e3ed01a4c730e1d6f95e6cb2ac73dcGreg Clayton            while ((dp = readdir(dirp.get())) != NULL)
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // Only search directories
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN)
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (dp->d_namlen == 1 && dp->d_name[0] == '.')
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        continue;
27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        continue;
27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN)
27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
280537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton                    dsym_fspec.GetFilename().SetCString(dp->d_name);
28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (FileAtPathContainsArchAndUUID (dsym_fspec, arch, uuid))
28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        return dsym_fspec;
28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dsym_fspec.Clear();
28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return dsym_fspec;
28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic int
29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerLocateMacOSXFilesUsingDebugSymbols
29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
294444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const ModuleSpec &module_spec,
29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FileSpec *out_exec_fspec,   // If non-NULL, try and find the executable
29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FileSpec *out_dsym_fspec    // If non-NULL try and find the debug symbol file
29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int items_found = 0;
30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (out_exec_fspec)
30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        out_exec_fspec->Clear();
30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (out_dsym_fspec)
30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        out_dsym_fspec->Clear();
30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3073e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#if !defined (__arm__) // No DebugSymbols on the iOS devices
3083e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton
309444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const UUID *uuid = module_spec.GetUUIDPtr();
310444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const ArchSpec *arch = module_spec.GetArchitecturePtr();
311444fe998bf707bd076a70c3a779db8575533695eGreg Clayton
31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (uuid && uuid->IsValid())
31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Try and locate the dSYM file using DebugSymbols first
31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes();
31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (module_uuid != NULL)
31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
3180fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes (NULL,
31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[0],
32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[1],
32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[2],
32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[3],
32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[4],
32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[5],
32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[6],
32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[7],
32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[8],
32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[9],
32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[10],
33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[11],
33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[12],
33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[13],
33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[14],
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[15]));
33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (module_uuid_ref.get())
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                CFCReleaser<CFURLRef> exec_url;
339444fe998bf707bd076a70c3a779db8575533695eGreg Clayton                const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (exec_fspec)
34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    char exec_cf_path[PATH_MAX];
34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path)))
34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        exec_url.reset(::CFURLCreateFromFileSystemRepresentation (NULL,
34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                                  (const UInt8 *)exec_cf_path,
34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                                  strlen(exec_cf_path),
34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                                  FALSE));
34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                CFCReleaser<CFURLRef> dsym_url (::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get()));
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                char path[PATH_MAX];
35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (dsym_url.get())
35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (out_dsym_fspec)
35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
359537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton                            out_dsym_fspec->SetFile(path, false);
36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            if (out_dsym_fspec->GetFileType () == FileSpec::eFileTypeDirectory)
36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            {
36395b765e8000b44644d021e95bc58eac95028573bGreg Clayton                                *out_dsym_fspec = Symbols::FindSymbolFileInBundle (*out_dsym_fspec, uuid, arch);
36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                if (*out_dsym_fspec)
36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    ++items_found;
36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            }
36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            else
36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            {
36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                ++items_found;
37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            }
37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
374964deba8853eb794e59263322b59b09b43669618Greg Clayton                    CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get()));
375964deba8853eb794e59263322b59b09b43669618Greg Clayton                    CFDictionaryRef uuid_dict = NULL;
376964deba8853eb794e59263322b59b09b43669618Greg Clayton                    if (dict.get())
37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
378964deba8853eb794e59263322b59b09b43669618Greg Clayton                        char uuid_cstr_buf[64];
379964deba8853eb794e59263322b59b09b43669618Greg Clayton                        const char *uuid_cstr = uuid->GetAsCString (uuid_cstr_buf, sizeof(uuid_cstr_buf));
380964deba8853eb794e59263322b59b09b43669618Greg Clayton                        CFCString uuid_cfstr (uuid_cstr);
381964deba8853eb794e59263322b59b09b43669618Greg Clayton                        CFDictionaryRef uuid_dict = static_cast<CFDictionaryRef>(::CFDictionaryGetValue (dict.get(), uuid_cfstr.get()));
382964deba8853eb794e59263322b59b09b43669618Greg Clayton                        if (uuid_dict)
38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
384964deba8853eb794e59263322b59b09b43669618Greg Clayton
385964deba8853eb794e59263322b59b09b43669618Greg Clayton                            CFStringRef actual_src_cfpath = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSourcePath")));
386964deba8853eb794e59263322b59b09b43669618Greg Clayton                            if (actual_src_cfpath)
38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            {
388964deba8853eb794e59263322b59b09b43669618Greg Clayton                                CFStringRef build_src_cfpath = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGBuildSourcePath")));
389964deba8853eb794e59263322b59b09b43669618Greg Clayton                                if (build_src_cfpath)
390b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                                {
391964deba8853eb794e59263322b59b09b43669618Greg Clayton                                    char actual_src_path[PATH_MAX];
392964deba8853eb794e59263322b59b09b43669618Greg Clayton                                    char build_src_path[PATH_MAX];
393964deba8853eb794e59263322b59b09b43669618Greg Clayton                                    ::CFStringGetFileSystemRepresentation (actual_src_cfpath, actual_src_path, sizeof(actual_src_path));
394964deba8853eb794e59263322b59b09b43669618Greg Clayton                                    ::CFStringGetFileSystemRepresentation (build_src_cfpath, build_src_path, sizeof(build_src_path));
3954d8c5434779393d5502b45f42a9371477604aab7Greg Clayton                                    if (actual_src_path[0] == '~')
3964d8c5434779393d5502b45f42a9371477604aab7Greg Clayton                                    {
3974d8c5434779393d5502b45f42a9371477604aab7Greg Clayton                                        FileSpec resolved_source_path(actual_src_path, true);
3984d8c5434779393d5502b45f42a9371477604aab7Greg Clayton                                        resolved_source_path.GetPath(actual_src_path, sizeof(actual_src_path));
3994d8c5434779393d5502b45f42a9371477604aab7Greg Clayton                                    }
400964deba8853eb794e59263322b59b09b43669618Greg Clayton                                    module_spec.GetSourceMappingList().Append (ConstString(build_src_path), ConstString(actual_src_path), true);
401b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                                }
4020fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            }
4030fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        }
404964deba8853eb794e59263322b59b09b43669618Greg Clayton                    }
405964deba8853eb794e59263322b59b09b43669618Greg Clayton
406964deba8853eb794e59263322b59b09b43669618Greg Clayton                    if (out_exec_fspec)
407964deba8853eb794e59263322b59b09b43669618Greg Clayton                    {
408964deba8853eb794e59263322b59b09b43669618Greg Clayton                        bool success = false;
409964deba8853eb794e59263322b59b09b43669618Greg Clayton                        if (uuid_dict)
410964deba8853eb794e59263322b59b09b43669618Greg Clayton                        {
411964deba8853eb794e59263322b59b09b43669618Greg Clayton                            CFStringRef exec_cf_path = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSymbolRichExecutable")));
412964deba8853eb794e59263322b59b09b43669618Greg Clayton                            if (exec_cf_path && ::CFStringGetFileSystemRepresentation (exec_cf_path, path, sizeof(path)))
413964deba8853eb794e59263322b59b09b43669618Greg Clayton                            {
414964deba8853eb794e59263322b59b09b43669618Greg Clayton                                ++items_found;
415964deba8853eb794e59263322b59b09b43669618Greg Clayton                                out_exec_fspec->SetFile(path, path[0] == '~');
416964deba8853eb794e59263322b59b09b43669618Greg Clayton                                if (out_exec_fspec->Exists())
417964deba8853eb794e59263322b59b09b43669618Greg Clayton                                    success = true;
418964deba8853eb794e59263322b59b09b43669618Greg Clayton                            }
419964deba8853eb794e59263322b59b09b43669618Greg Clayton                        }
4209ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton
4219ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton                        if (!success)
4220fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        {
4230fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            // No dictionary, check near the dSYM bundle for an executable that matches...
4240fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
4250fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            {
4260fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                char *dsym_extension_pos = ::strstr (path, ".dSYM");
4270fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                if (dsym_extension_pos)
4280fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                {
4290fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                    *dsym_extension_pos = '\0';
4300fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                    FileSpec file_spec (path, true);
4310fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                    switch (file_spec.GetFileType())
4320fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                    {
4330fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeDirectory:  // Bundle directory?
4340fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            {
4350fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                CFCBundle bundle (path);
4360fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                CFCReleaser<CFURLRef> bundle_exe_url (bundle.CopyExecutableURL ());
4370fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                if (bundle_exe_url.get())
4380fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                {
4390fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                    if (::CFURLGetFileSystemRepresentation (bundle_exe_url.get(), true, (UInt8*)path, sizeof(path)-1))
4400fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                    {
4410fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                        FileSpec bundle_exe_file_spec (path, true);
4420fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
4430fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                        if (FileAtPathContainsArchAndUUID (bundle_exe_file_spec, arch, uuid))
4440fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                        {
4450fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                            ++items_found;
4460fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                            *out_exec_fspec = bundle_exe_file_spec;
4470fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                        }
4480fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                    }
4490fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                }
4500fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            }
4510fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            break;
4520fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
4530fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypePipe:       // Forget pipes
4540fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeSocket:     // We can't process socket files
4550fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeInvalid:    // File doesn't exist...
4560fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            break;
4570fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
4580fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeUnknown:
4590fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeRegular:
4600fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeSymbolicLink:
4610fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeOther:
4620fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            if (FileAtPathContainsArchAndUUID (file_spec, arch, uuid))
4630fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            {
4640fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                ++items_found;
4650fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                *out_exec_fspec = file_spec;
4660fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            }
4670fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            break;
4680fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                    }
4690fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                }
47024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            }
47124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
47224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
4773e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#endif // #if !defined (__arm__)
4783e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton
47924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return items_found;
48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
48224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool
483444fe998bf707bd076a70c3a779db8575533695eGreg ClaytonLocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec, FileSpec &dsym_fspec)
48424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
485444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (exec_fspec)
48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        char path[PATH_MAX];
48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (exec_fspec->GetPath(path, sizeof(path)))
49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Make sure the module isn't already just a dSYM file...
49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL)
49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                size_t obj_file_path_length = strlen(path);
49578c180ab423d3a802566d49a41363b132f20c907Filipe Cabecinhas                strlcat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path));
49678c180ab423d3a802566d49a41363b132f20c907Filipe Cabecinhas                strlcat(path, exec_fspec->GetFilename().AsCString(), sizeof(path));
49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
498537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton                dsym_fspec.SetFile(path, false);
49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
500444fe998bf707bd076a70c3a779db8575533695eGreg Clayton                if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    return true;
50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                else
50524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    path[obj_file_path_length] = '\0';
50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
50824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    char *last_dot = strrchr(path, '.');
50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    while (last_dot != NULL && last_dot[0])
51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
51124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        char *next_slash = strchr(last_dot, '/');
51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        if (next_slash != NULL)
51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
51424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            *next_slash = '\0';
51578c180ab423d3a802566d49a41363b132f20c907Filipe Cabecinhas                            strlcat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path));
51678c180ab423d3a802566d49a41363b132f20c907Filipe Cabecinhas                            strlcat(path, exec_fspec->GetFilename().AsCString(), sizeof(path));
517537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton                            dsym_fspec.SetFile(path, false);
518444fe998bf707bd076a70c3a779db8575533695eGreg Clayton                            if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
51924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                return true;
52024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            else
52124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            {
52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                *last_dot = '\0';
52324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                char *prev_slash = strrchr(path, '/');
52424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                if (prev_slash != NULL)
52524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    *prev_slash = '\0';
52624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                else
52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    break;
52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            }
52924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
53024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        else
53124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
53224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            break;
53324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
53424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
53524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
53624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
53824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
53924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dsym_fspec.Clear();
54024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
54124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
54224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
54324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec
544444fe998bf707bd076a70c3a779db8575533695eGreg ClaytonSymbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)
54524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
546444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
547444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const ArchSpec *arch = module_spec.GetArchitecturePtr();
548444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const UUID *uuid = module_spec.GetUUIDPtr();
54924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Timer scoped_timer (__PRETTY_FUNCTION__,
55024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",
55124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
552940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton                        arch ? arch->GetArchitectureName() : "<NULL>",
55324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        uuid);
55424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
55524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FileSpec objfile_fspec;
556444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    if (exec_fspec && FileAtPathContainsArchAndUUID (exec_fspec, arch, uuid))
557444fe998bf707bd076a70c3a779db8575533695eGreg Clayton        objfile_fspec = exec_fspec;
55824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
559444fe998bf707bd076a70c3a779db8575533695eGreg Clayton        LocateMacOSXFilesUsingDebugSymbols (module_spec, &objfile_fspec, NULL);
56024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return objfile_fspec;
56124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
56224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
56324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec
564444fe998bf707bd076a70c3a779db8575533695eGreg ClaytonSymbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)
56524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
566444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
567444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const ArchSpec *arch = module_spec.GetArchitecturePtr();
568444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const UUID *uuid = module_spec.GetUUIDPtr();
569444fe998bf707bd076a70c3a779db8575533695eGreg Clayton
57024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Timer scoped_timer (__PRETTY_FUNCTION__,
57124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        "LocateExecutableSymbolFile (file = %s, arch = %s, uuid = %p)",
57224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
573940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton                        arch ? arch->GetArchitectureName() : "<NULL>",
57424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        uuid);
57524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
57624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FileSpec symbol_fspec;
57724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // First try and find the dSYM in the same directory as the executable or in
57824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // an appropriate parent directory
579444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    if (LocateDSYMInVincinityOfExecutable (module_spec, symbol_fspec) == false)
58024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
58124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // We failed to easily find the dSYM above, so use DebugSymbols
582444fe998bf707bd076a70c3a779db8575533695eGreg Clayton        LocateMacOSXFilesUsingDebugSymbols (module_spec, NULL, &symbol_fspec);
58324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
58424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return symbol_fspec;
58524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
586b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton
587b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton
588b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton
589b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton
590b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Claytonbool
591b924eb6c5250a9909dc55ac736d231f7ccae423bGreg ClaytonSymbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec)
592b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton{
593b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton    bool success = false;
594b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton    const UUID *uuid_ptr = module_spec.GetUUIDPtr();
595b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton    if (uuid_ptr)
596b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton    {
597b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton        static bool g_located_dsym_for_uuid_exe = false;
598b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton        static bool g_dsym_for_uuid_exe_exists = false;
599b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton        static char g_dsym_for_uuid_exe_path[PATH_MAX];
600b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton        if (!g_located_dsym_for_uuid_exe)
601b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton        {
602b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            g_located_dsym_for_uuid_exe = true;
603b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            const char *dsym_for_uuid_exe_path_cstr = getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE");
604b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            FileSpec dsym_for_uuid_exe_spec;
605b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            if (dsym_for_uuid_exe_path_cstr)
606b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            {
607b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true);
608b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
609b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            }
610b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton
611b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            if (!g_dsym_for_uuid_exe_exists)
612b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            {
613b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                dsym_for_uuid_exe_spec.SetFile("~rc/bin/dsymForUUID", true);
614b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
615b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                if (!g_dsym_for_uuid_exe_exists)
616b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                {
617b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                    dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false);
618b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                }
619b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            }
620b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton
621b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            if (g_dsym_for_uuid_exe_exists)
622b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                dsym_for_uuid_exe_spec.GetPath (g_dsym_for_uuid_exe_path, sizeof(g_dsym_for_uuid_exe_path));
623b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton        }
624b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton        if (g_dsym_for_uuid_exe_exists)
625b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton        {
626b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            StreamString command;
627b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            char uuid_cstr_buffer[64];
628b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            const char *uuid_cstr = uuid_ptr->GetAsCString(uuid_cstr_buffer, sizeof(uuid_cstr_buffer));
629b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            command.Printf("%s --copyExecutable %s", g_dsym_for_uuid_exe_path, uuid_cstr);
630b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            int exit_status = -1;
631b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            int signo = -1;
632b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            std::string command_output;
633b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            Error error = Host::RunShellCommand (command.GetData(),
634b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                                 NULL,              // current working directory
635b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                                 &exit_status,      // Exit status
636b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                                 &signo,            // Signal int *
637b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                                 &command_output,   // Command output
638b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                                 30,                // Large timeout to allow for long dsym download times
639b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                                 NULL);             // Don't run in a shell (we don't need shell expansion)
640b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            if (error.Success() && exit_status == 0 && !command_output.empty())
641b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            {
642b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                CFCData data (CFDataCreateWithBytesNoCopy (NULL,
643b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                                           (const UInt8 *)command_output.data(),
644b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                                           command_output.size(),
645b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                                           kCFAllocatorNull));
646b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton
647b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                CFCReleaser<CFPropertyListRef> plist(::CFPropertyListCreateFromXMLData (NULL, data.get(), kCFPropertyListImmutable, NULL));
648b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton
649b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                if (CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ())
650b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                {
651b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                    std::string str;
652b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                    CFCString uuid_cfstr(uuid_cstr);
653b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                    CFTypeRef uuid_dict = CFDictionaryGetValue ((CFDictionaryRef) plist.get(), uuid_cfstr.get());
654b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                    if (uuid_dict != NULL && CFGetTypeID (uuid_dict) == CFDictionaryGetTypeID ())
655b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                    {
656b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                        CFStringRef cf_str;
657b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton
658b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSymbolRichExecutable"));
659b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
660b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                        {
661b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                            if (CFCString::FileSystemRepresentation(cf_str, str))
662b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                            {
663b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                success = true;
664b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                module_spec.GetFileSpec().SetFile (str.c_str(), true);
665b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                            }
666b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                        }
667b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton
668b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGDSYMPath"));
669b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
670b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                        {
671b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                            if (CFCString::FileSystemRepresentation(cf_str, str))
672b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                            {
673b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                success = true;
674b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                                module_spec.GetSymbolFileSpec().SetFile (str.c_str(), true);
675b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                            }
676b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                        }
677b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                    }
678b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton                }
679b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton            }
680b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton        }
681b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton    }
682b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton    return success;
683b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton}
684b924eb6c5250a9909dc55ac736d231f7ccae423bGreg Clayton
685