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