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