Symbols.cpp revision 444fe998bf707bd076a70c3a779db8575533695e
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"
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Timer.h"
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/UUID.h"
27cd548034fa23113e995b8463d14f910ba2f7298cGreg Clayton#include "lldb/Host/Endian.h"
28cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen#include "lldb/Host/Host.h"
29ad400274d4e3ed01a4c730e1d6f95e6cb2ac73dcGreg Clayton#include "lldb/Utility/CleanUp.h"
30a1ebbd2410cafb890ab8519ae4e6b24cc618bd6aDaniel Dunbar#include "Host/macosx/cfcpp/CFCBundle.h"
3154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton#include "Host/macosx/cfcpp/CFCReleaser.h"
32b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton#include "Host/macosx/cfcpp/CFCString.h"
335bc7b67ccc8bb4a977d129e51313067dcbc7bb94Chris Lattner#include "mach/machine.h"
3454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton
350fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
381674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Claytonusing namespace llvm::MachO;
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
403e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#if !defined (__arm__) // No DebugSymbols on the iOS devices
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerextern "C" {
4254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCFURLRef DBGCopyFullDSYMURLForUUID (CFUUIDRef uuid, CFURLRef exec_url);
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCFDictionaryRef DBGCopyDSYMPropertyLists (CFURLRef dsym_url);
4554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton
4654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton}
473e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#endif
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSkinnyMachOFileContainsArchAndUUID
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const FileSpec &file_spec,
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const ArchSpec *arch,
540467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton    const lldb_private::UUID *uuid,   // the UUID we are looking for
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    off_t file_offset,
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DataExtractor& data,
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t data_offset,
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t magic
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
611674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton    assert(magic == HeaderMagic32 || magic == HeaderMagic32Swapped || magic == HeaderMagic64 || magic == HeaderMagic64Swapped);
621674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton    if (magic == HeaderMagic32 || magic == HeaderMagic64)
63cd548034fa23113e995b8463d14f910ba2f7298cGreg Clayton        data.SetByteOrder (lldb::endian::InlHostByteOrder());
64cd548034fa23113e995b8463d14f910ba2f7298cGreg Clayton    else if (lldb::endian::InlHostByteOrder() == eByteOrderBig)
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data.SetByteOrder (eByteOrderLittle);
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data.SetByteOrder (eByteOrderBig);
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t i;
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t cputype      = data.GetU32(&data_offset);    // cpu specifier
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t cpusubtype   = data.GetU32(&data_offset);    // machine specifier
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    data_offset+=4; // Skip mach file type
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t ncmds        = data.GetU32(&data_offset);    // number of load commands
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t sizeofcmds   = data.GetU32(&data_offset);    // the size of all the load commands
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    data_offset+=4; // Skip flags
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Check the architecture if we have a valid arch pointer
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (arch)
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
80cf0150574a0a97049efe2dce2cc0aa433705feb3Greg Clayton        ArchSpec file_arch(eArchTypeMachO, cputype, cpusubtype);
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (file_arch != *arch)
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // The file exists, and if a valid arch pointer was passed in we know
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // if already matches, so we can return if we aren't looking for a specific
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // UUID
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (uuid == NULL)
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return true;
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
921674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton    if (magic == HeaderMagic64Swapped || magic == HeaderMagic64)
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data_offset += 4;   // Skip reserved field for in mach_header_64
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Make sure we have enough data for all the load commands
961674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton    if (magic == HeaderMagic64Swapped || magic == HeaderMagic64)
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (data.GetByteSize() < sizeof(struct mach_header_64) + sizeofcmds)
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header_64) + sizeofcmds));
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            data.SetData (data_buffer_sp);
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (data.GetByteSize() < sizeof(struct mach_header) + sizeofcmds)
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header) + sizeofcmds));
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            data.SetData (data_buffer_sp);
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (i=0; i<ncmds; i++)
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint32_t cmd_offset = data_offset;    // Save this data_offset in case parsing of the segment goes awry!
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t cmd        = data.GetU32(&data_offset);
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t cmd_size   = data.GetU32(&data_offset);
1181674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        if (cmd == LoadCommandUUID)
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
1200467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton            lldb_private::UUID file_uuid (data.GetData(&data_offset, 16), 16);
121cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            if (file_uuid == *uuid)
122cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen                return true;
123cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen
124cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            // Emit some warning messages since the UUIDs do not match!
125cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            char path_buf[PATH_MAX];
126cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            path_buf[0] = '\0';
127cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            const char *path = file_spec.GetPath(path_buf, PATH_MAX) ? path_buf
128cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen                                                                     : file_spec.GetFilename().AsCString();
129cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            Host::SystemLog (Host::eSystemLogWarning,
130cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen                             "warning: UUID mismatch detected between binary and:\n\t'%s'\n",
131cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen                             path);
132cbf1591dd5b3d9d364d401bd857241bde198b645Johnny Chen            return false;
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data_offset = cmd_offset + cmd_size;
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerUniversalMachOFileContainsArchAndUUID
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const FileSpec &file_spec,
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const ArchSpec *arch,
1440467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton    const lldb_private::UUID *uuid,
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    off_t file_offset,
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DataExtractor& data,
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t data_offset,
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t magic
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
1511674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton    assert(magic == UniversalMagic || magic == UniversalMagicSwapped);
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Universal mach-o files always have their headers encoded as BIG endian
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    data.SetByteOrder(eByteOrderBig);
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t i;
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t nfat_arch = data.GetU32(&data_offset);   // number of structs that follow
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t fat_header_and_arch_size = sizeof(struct fat_header) + nfat_arch * sizeof(struct fat_arch);
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (data.GetByteSize() < fat_header_and_arch_size)
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, fat_header_and_arch_size));
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data.SetData (data_buffer_sp);
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (i=0; i<nfat_arch; i++)
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        cpu_type_t      arch_cputype        = data.GetU32(&data_offset);    // cpu specifier (int)
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        cpu_subtype_t   arch_cpusubtype     = data.GetU32(&data_offset);    // machine specifier (int)
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t        arch_offset         = data.GetU32(&data_offset);    // file offset to this object file
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //  uint32_t        arch_size           = data.GetU32(&data_offset);    // size of this object file
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //  uint32_t        arch_align          = data.GetU32(&data_offset);    // alignment as a power of 2
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data_offset += 8;   // Skip size and align as we don't need those
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Only process this slice if the cpu type/subtype matches
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (arch)
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
176cf0150574a0a97049efe2dce2cc0aa433705feb3Greg Clayton            ArchSpec fat_arch(eArchTypeMachO, arch_cputype, arch_cpusubtype);
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (fat_arch != *arch)
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                continue;
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Create a buffer with only the arch slice date in it
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DataExtractor arch_data;
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset + arch_offset, 0x1000));
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        arch_data.SetData(data_buffer_sp);
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t arch_data_offset = 0;
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t arch_magic = arch_data.GetU32(&arch_data_offset);
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (arch_magic)
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
1901674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic32:
1911674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic32Swapped:
1921674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic64:
1931674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic64Swapped:
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset + arch_offset, arch_data, arch_data_offset, arch_magic))
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return true;
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileAtPathContainsArchAndUUID
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const FileSpec &file_spec,
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const ArchSpec *arch,
2070467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton    const lldb_private::UUID *uuid
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DataExtractor data;
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    off_t file_offset = 0;
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, 0x1000));
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0)
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        data.SetData(data_buffer_sp);
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t data_offset = 0;
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t magic = data.GetU32(&data_offset);
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (magic)
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // 32 bit mach-o file
2241674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic32:
2251674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic32Swapped:
2261674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic64:
2271674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case HeaderMagic64Swapped:
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic);
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // fat mach-o file
2311674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case UniversalMagic:
2321674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton        case UniversalMagicSwapped:
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return UniversalMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic);
23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic FileSpec
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerLocateDSYMMachFileInDSYMBundle
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const FileSpec& dsym_bundle_fspec,
2460467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Clayton    const lldb_private::UUID *uuid,
24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const ArchSpec *arch)
24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char path[PATH_MAX];
25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FileSpec dsym_fspec;
25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (dsym_bundle_fspec.GetPath(path, sizeof(path)))
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25752fd984f7e67c3a0ab18d5565f40356bcfa84822Greg Clayton        lldb_utility::CleanUp <DIR *, int> dirp (opendir(path), NULL, closedir);
258ad400274d4e3ed01a4c730e1d6f95e6cb2ac73dcGreg Clayton        if (dirp.is_valid())
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
260537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton            dsym_fspec.GetDirectory().SetCString(path);
26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            struct dirent* dp;
262ad400274d4e3ed01a4c730e1d6f95e6cb2ac73dcGreg Clayton            while ((dp = readdir(dirp.get())) != NULL)
26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // Only search directories
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN)
26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (dp->d_namlen == 1 && dp->d_name[0] == '.')
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        continue;
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        continue;
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN)
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
276537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton                    dsym_fspec.GetFilename().SetCString(dp->d_name);
27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (FileAtPathContainsArchAndUUID (dsym_fspec, arch, uuid))
27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        return dsym_fspec;
27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dsym_fspec.Clear();
28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return dsym_fspec;
28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic int
28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerLocateMacOSXFilesUsingDebugSymbols
28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
290444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const ModuleSpec &module_spec,
29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FileSpec *out_exec_fspec,   // If non-NULL, try and find the executable
29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FileSpec *out_dsym_fspec    // If non-NULL try and find the debug symbol file
29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int items_found = 0;
29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (out_exec_fspec)
29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        out_exec_fspec->Clear();
29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (out_dsym_fspec)
30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        out_dsym_fspec->Clear();
30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3033e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#if !defined (__arm__) // No DebugSymbols on the iOS devices
3043e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton
305444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const UUID *uuid = module_spec.GetUUIDPtr();
306444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const ArchSpec *arch = module_spec.GetArchitecturePtr();
307444fe998bf707bd076a70c3a779db8575533695eGreg Clayton
30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (uuid && uuid->IsValid())
30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Try and locate the dSYM file using DebugSymbols first
31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes();
31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (module_uuid != NULL)
31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
3140fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes (NULL,
31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[0],
31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[1],
31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[2],
31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[3],
31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[4],
32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[5],
32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[6],
32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[7],
32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[8],
32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[9],
32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[10],
32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[11],
32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[12],
32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[13],
32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[14],
33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                            module_uuid[15]));
33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (module_uuid_ref.get())
33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                CFCReleaser<CFURLRef> exec_url;
335444fe998bf707bd076a70c3a779db8575533695eGreg Clayton                const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (exec_fspec)
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    char exec_cf_path[PATH_MAX];
33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path)))
34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        exec_url.reset(::CFURLCreateFromFileSystemRepresentation (NULL,
34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                                  (const UInt8 *)exec_cf_path,
34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                                  strlen(exec_cf_path),
34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                                  FALSE));
34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                CFCReleaser<CFURLRef> dsym_url (::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get()));
34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                char path[PATH_MAX];
34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (dsym_url.get())
35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (out_dsym_fspec)
35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
355537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton                            out_dsym_fspec->SetFile(path, false);
35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            if (out_dsym_fspec->GetFileType () == FileSpec::eFileTypeDirectory)
35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            {
35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                *out_dsym_fspec = LocateDSYMMachFileInDSYMBundle (*out_dsym_fspec, uuid, arch);
36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                if (*out_dsym_fspec)
36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    ++items_found;
36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            }
36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            else
36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            {
36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                ++items_found;
36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            }
36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (out_exec_fspec)
37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
3729ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton                        CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get()));
3739ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton                        bool success = false;
37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        if (dict.get())
37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
376b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                            char uuid_cstr_buf[64];
377b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                            const char *uuid_cstr = uuid->GetAsCString (uuid_cstr_buf, sizeof(uuid_cstr_buf));
378b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                            CFCString uuid_cfstr (uuid_cstr);
379b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                            CFDictionaryRef uuid_dict = static_cast<CFDictionaryRef>(::CFDictionaryGetValue (dict.get(), uuid_cfstr.get()));
380b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                            if (uuid_dict)
38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            {
382b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                                CFStringRef exec_cf_path = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSymbolRichExecutable")));
383b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                                if (exec_cf_path && ::CFStringGetFileSystemRepresentation (exec_cf_path, path, sizeof(path)))
384b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                                {
385b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                                    ++items_found;
386b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                                    out_exec_fspec->SetFile(path, path[0] == '~');
3879ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton                                    if (out_exec_fspec->Exists())
3889ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton                                        success = true;
389b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton                                }
3900fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            }
3910fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        }
3929ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton
3939ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton                        if (!success)
3940fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        {
3950fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            // No dictionary, check near the dSYM bundle for an executable that matches...
3960fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
3970fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            {
3980fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                char *dsym_extension_pos = ::strstr (path, ".dSYM");
3990fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                if (dsym_extension_pos)
4000fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                {
4010fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                    *dsym_extension_pos = '\0';
4020fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                    FileSpec file_spec (path, true);
4030fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                    switch (file_spec.GetFileType())
4040fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                    {
4050fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeDirectory:  // Bundle directory?
4060fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            {
4070fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                CFCBundle bundle (path);
4080fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                CFCReleaser<CFURLRef> bundle_exe_url (bundle.CopyExecutableURL ());
4090fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                if (bundle_exe_url.get())
4100fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                {
4110fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                    if (::CFURLGetFileSystemRepresentation (bundle_exe_url.get(), true, (UInt8*)path, sizeof(path)-1))
4120fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                    {
4130fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                        FileSpec bundle_exe_file_spec (path, true);
4140fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
4150fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                        if (FileAtPathContainsArchAndUUID (bundle_exe_file_spec, arch, uuid))
4160fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                        {
4170fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                            ++items_found;
4180fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                            *out_exec_fspec = bundle_exe_file_spec;
4190fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                        }
4200fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                    }
4210fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                }
4220fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            }
4230fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            break;
4240fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
4250fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypePipe:       // Forget pipes
4260fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeSocket:     // We can't process socket files
4270fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeInvalid:    // File doesn't exist...
4280fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            break;
4290fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
4300fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeUnknown:
4310fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeRegular:
4320fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeSymbolicLink:
4330fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                        case FileSpec::eFileTypeOther:
4340fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            if (FileAtPathContainsArchAndUUID (file_spec, arch, uuid))
4350fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            {
4360fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                ++items_found;
4370fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                                *out_exec_fspec = file_spec;
4380fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            }
4390fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            break;
4400fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                    }
4410fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                }
44224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            }
44324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
44424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
44524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
44624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
44724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
44824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
4493e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton#endif // #if !defined (__arm__)
4503e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton
45124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return items_found;
45224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
45324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
45424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool
455444fe998bf707bd076a70c3a779db8575533695eGreg ClaytonLocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec, FileSpec &dsym_fspec)
45624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
457444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
45824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (exec_fspec)
45924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
46024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        char path[PATH_MAX];
46124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (exec_fspec->GetPath(path, sizeof(path)))
46224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
46324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Make sure the module isn't already just a dSYM file...
46424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL)
46524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
46624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                size_t obj_file_path_length = strlen(path);
46724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                strncat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path));
46824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                strncat(path, exec_fspec->GetFilename().AsCString(), sizeof(path));
46924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
470537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton                dsym_fspec.SetFile(path, false);
47124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
472444fe998bf707bd076a70c3a779db8575533695eGreg Clayton                if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    return true;
47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                else
47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
47824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    path[obj_file_path_length] = '\0';
47924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    char *last_dot = strrchr(path, '.');
48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    while (last_dot != NULL && last_dot[0])
48224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
48324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        char *next_slash = strchr(last_dot, '/');
48424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        if (next_slash != NULL)
48524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            *next_slash = '\0';
48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            strncat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path));
48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            strncat(path, exec_fspec->GetFilename().AsCString(), sizeof(path));
489537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton                            dsym_fspec.SetFile(path, false);
490444fe998bf707bd076a70c3a779db8575533695eGreg Clayton                            if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                return true;
49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            else
49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            {
49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                *last_dot = '\0';
49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                char *prev_slash = strrchr(path, '/');
49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                if (prev_slash != NULL)
49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    *prev_slash = '\0';
49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                else
49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    break;
50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            }
50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        else
50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            break;
50524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
50824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
51124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dsym_fspec.Clear();
51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
51424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec
516444fe998bf707bd076a70c3a779db8575533695eGreg ClaytonSymbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)
51724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
518444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
519444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const ArchSpec *arch = module_spec.GetArchitecturePtr();
520444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const UUID *uuid = module_spec.GetUUIDPtr();
52124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Timer scoped_timer (__PRETTY_FUNCTION__,
52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",
52324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
524940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton                        arch ? arch->GetArchitectureName() : "<NULL>",
52524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        uuid);
52624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FileSpec objfile_fspec;
528444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    if (exec_fspec && FileAtPathContainsArchAndUUID (exec_fspec, arch, uuid))
529444fe998bf707bd076a70c3a779db8575533695eGreg Clayton        objfile_fspec = exec_fspec;
53024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
531444fe998bf707bd076a70c3a779db8575533695eGreg Clayton        LocateMacOSXFilesUsingDebugSymbols (module_spec, &objfile_fspec, NULL);
53224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return objfile_fspec;
53324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
53424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
53524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec
536444fe998bf707bd076a70c3a779db8575533695eGreg ClaytonSymbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)
53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
538444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
539444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const ArchSpec *arch = module_spec.GetArchitecturePtr();
540444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    const UUID *uuid = module_spec.GetUUIDPtr();
541444fe998bf707bd076a70c3a779db8575533695eGreg Clayton
54224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Timer scoped_timer (__PRETTY_FUNCTION__,
54324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        "LocateExecutableSymbolFile (file = %s, arch = %s, uuid = %p)",
54424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
545940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton                        arch ? arch->GetArchitectureName() : "<NULL>",
54624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        uuid);
54724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
54824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FileSpec symbol_fspec;
54924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // First try and find the dSYM in the same directory as the executable or in
55024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // an appropriate parent directory
551444fe998bf707bd076a70c3a779db8575533695eGreg Clayton    if (LocateDSYMInVincinityOfExecutable (module_spec, symbol_fspec) == false)
55224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
55324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // We failed to easily find the dSYM above, so use DebugSymbols
554444fe998bf707bd076a70c3a779db8575533695eGreg Clayton        LocateMacOSXFilesUsingDebugSymbols (module_spec, NULL, &symbol_fspec);
55524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
55624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return symbol_fspec;
55724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
558