124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- ObjectContainerUniversalMachO.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 "ObjectContainerUniversalMachO.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/ArchSpec.h"
12cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton#include "lldb/Core/DataBuffer.h"
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Module.h"
1436b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton#include "lldb/Core/ModuleSpec.h"
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/PluginManager.h"
16cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton#include "lldb/Core/Stream.h"
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Symbol/ObjectFile.h"
185bc8c97d62b2e399bd90fb7e00c903d7887412abCaroline Tice#include "lldb/Target/Target.h"
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
221674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Claytonusing namespace llvm::MachO;
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::Initialize()
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    PluginManager::RegisterPlugin (GetPluginNameStatic(),
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   GetPluginDescriptionStatic(),
2936b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton                                   CreateInstance,
3036b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton                                   GetModuleSpecifications);
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::Terminate()
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    PluginManager::UnregisterPlugin (CreateInstance);
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
400e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Claytonlldb_private::ConstString
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::GetPluginNameStatic()
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
430e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    static ConstString g_name("mach-o");
440e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    return g_name;
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst char *
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::GetPluginDescriptionStatic()
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return "Universal mach-o object container reader.";
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainer *
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::CreateInstance
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
573508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton    const lldb::ModuleSP &module_sp,
58db2dc2b824b61ef7578dc8cdad7b338aa82b1f17Greg Clayton    DataBufferSP& data_sp,
59cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    lldb::offset_t data_offset,
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const FileSpec *file,
61cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    lldb::offset_t file_offset,
62cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    lldb::offset_t length
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
65cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    // We get data when we aren't trying to look for cached container information,
66cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    // so only try and look for an architecture slice if we get data
67cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    if (data_sp)
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
69cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        DataExtractor data;
70cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        data.SetData (data_sp, data_offset, length);
71cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        if (ObjectContainerUniversalMachO::MagicBytesMatch(data))
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
73102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton            std::unique_ptr<ObjectContainerUniversalMachO> container_ap(new ObjectContainerUniversalMachO (module_sp, data_sp, data_offset, file, file_offset, length));
74cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton            if (container_ap->ParseHeader())
75cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton            {
76cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                return container_ap.release();
77cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton            }
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
84db2dc2b824b61ef7578dc8cdad7b338aa82b1f17Greg ClaytonObjectContainerUniversalMachO::MagicBytesMatch (const DataExtractor &data)
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
8636da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton    lldb::offset_t offset = 0;
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t magic = data.GetU32(&offset);
881674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton    return magic == UniversalMagic || magic == UniversalMagicSwapped;
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::ObjectContainerUniversalMachO
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
933508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton    const lldb::ModuleSP &module_sp,
94cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    DataBufferSP& data_sp,
95cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    lldb::offset_t data_offset,
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const FileSpec *file,
97cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    lldb::offset_t file_offset,
98cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    lldb::offset_t length
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) :
100cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    ObjectContainer (module_sp, file, file_offset, length, data_sp, data_offset),
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_header(),
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_fat_archs()
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    memset(&m_header, 0, sizeof(m_header));
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::~ObjectContainerUniversalMachO()
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::ParseHeader ()
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
11536b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    bool success = ParseHeader (m_data, m_header, m_fat_archs);
11636b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    // We no longer need any data, we parsed all we needed to parse
11736b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    // and cached it in m_header and m_fat_archs
11836b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    m_data.Clear();
11936b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    return success;
12036b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton}
12136b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton
12236b877d2d27f7d1890f2d13807a3addb216648e2Greg Claytonbool
12336b877d2d27f7d1890f2d13807a3addb216648e2Greg ClaytonObjectContainerUniversalMachO::ParseHeader (lldb_private::DataExtractor &data,
12436b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton                                            llvm::MachO::fat_header &header,
12536b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton                                            std::vector<llvm::MachO::fat_arch> &fat_archs)
12636b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton{
127cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    bool success = false;
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Store the file offset for this universal file as we could have a universal .o file
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // in a BSD archive, or be contained in another kind of object.
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Universal mach-o files always have their headers in big endian.
13136b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    lldb::offset_t offset = 0;
13236b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    data.SetByteOrder (eByteOrderBig);
13336b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    header.magic = data.GetU32(&offset);
13436b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    fat_archs.clear();
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13636b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    if (header.magic == UniversalMagic)
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13936b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton        data.SetAddressByteSize(4);
14036b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton
14136b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton        header.nfat_arch = data.GetU32(&offset);
14236b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Now we should have enough data for all of the fat headers, so lets index
1445d187e5495ee17f6763337a6ae28c2a7b07e4945Greg Clayton        // them so we know how many architectures that this universal binary contains.
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t arch_idx = 0;
14636b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton        for (arch_idx = 0; arch_idx < header.nfat_arch; ++arch_idx)
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
14836b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton            if (data.ValidOffsetForDataOfSize(offset, sizeof(fat_arch)))
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
1501674b12bbc3dae7b9543b8c5f958e90ddc767fa4Greg Clayton                fat_arch arch;
15136b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton                if (data.GetU32(&offset, &arch, sizeof(fat_arch)/sizeof(uint32_t)))
15236b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton                    fat_archs.push_back(arch);
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
155cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        success = true;
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
15936b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton        memset(&header, 0, sizeof(header));
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
161cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton    return success;
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::Dump (Stream *s) const
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
1677e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20Jason Molenda    s->Printf("%p: ", this);
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->Indent();
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const size_t num_archs = GetNumArchitectures();
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const size_t num_objects = GetNumObjects();
1717e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20Jason Molenda    s->Printf("ObjectContainerUniversalMachO, num_archs = %lu, num_objects = %lu", num_archs, num_objects);
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t i;
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ArchSpec arch;
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->IndentMore();
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (i=0; i<num_archs; i++)
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        s->Indent();
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        GetArchitectureAtIndex(i, arch);
1797e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20Jason Molenda        s->Printf("arch[%u] = %s\n", i, arch.GetArchitectureName());
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (i=0; i<num_objects; i++)
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        s->Indent();
1847e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20Jason Molenda        s->Printf("object[%u] = %s\n", i, GetObjectNameAtIndex (i));
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->IndentLess();
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->EOL();
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::GetNumArchitectures () const
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_header.nfat_arch;
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::GetArchitectureAtIndex (uint32_t idx, ArchSpec& arch) const
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (idx < m_header.nfat_arch)
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
201b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton        arch.SetArchitecture (eArchTypeMachO, m_fat_archs[idx].cputype, m_fat_archs[idx].cpusubtype);
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return true;
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
207e40b6424d9e49306392bec4b44060da36414c382Greg ClaytonObjectFileSP
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::GetObjectFile (const FileSpec *file)
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t arch_idx = 0;
2117508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham    ArchSpec arch;
2127508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham    // If the module hasn't specified an architecture yet, set it to the default
2137508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham    // architecture:
2143508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton    ModuleSP module_sp (GetModule());
2153508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton    if (module_sp)
2167508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham    {
2173508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton        if (!module_sp->GetArchitecture().IsValid())
2183508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton        {
2193508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton            arch = Target::GetDefaultArchitecture ();
2203508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton            if (!arch.IsValid())
221b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton                arch.SetTriple (LLDB_ARCH_DEFAULT);
2223508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton        }
2233508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton        else
2243508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton            arch = module_sp->GetArchitecture();
2253508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton
2263508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton        ArchSpec curr_arch;
2276e3f97b4bbb9ed2918215d2247067fff949d1aa4Jason Molenda        // First, try to find an exact match for the Arch of the Target.
2283508c387c3f0c9ecc439d98048fd7694d41bab1bGreg Clayton        for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
230cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton            if (GetArchitectureAtIndex (arch_idx, curr_arch) && arch.IsExactMatch(curr_arch))
231cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                break;
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
2336e3f97b4bbb9ed2918215d2247067fff949d1aa4Jason Molenda
2346e3f97b4bbb9ed2918215d2247067fff949d1aa4Jason Molenda        // Failing an exact match, try to find a compatible Arch of the Target.
235cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        if (arch_idx >= m_header.nfat_arch)
2366e3f97b4bbb9ed2918215d2247067fff949d1aa4Jason Molenda        {
237cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton            for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
2386e3f97b4bbb9ed2918215d2247067fff949d1aa4Jason Molenda            {
239cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                if (GetArchitectureAtIndex (arch_idx, curr_arch) && arch.IsCompatibleMatch(curr_arch))
240cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                    break;
2416e3f97b4bbb9ed2918215d2247067fff949d1aa4Jason Molenda            }
2426e3f97b4bbb9ed2918215d2247067fff949d1aa4Jason Molenda        }
2436e3f97b4bbb9ed2918215d2247067fff949d1aa4Jason Molenda
244cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        if (arch_idx < m_header.nfat_arch)
245cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        {
246cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton            DataBufferSP data_sp;
247cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton            lldb::offset_t data_offset = 0;
248cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton            return ObjectFile::FindPlugin (module_sp,
249cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                                           file,
250cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                                           m_offset + m_fat_archs[arch_idx].offset,
251cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                                           m_fat_archs[arch_idx].size,
252cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                                           data_sp,
253cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                                           data_offset);
254cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        }
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
256e40b6424d9e49306392bec4b44060da36414c382Greg Clayton    return ObjectFileSP();
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// PluginInterface protocol
26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
2630e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Claytonlldb_private::ConstString
26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::GetPluginName()
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return GetPluginNameStatic();
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectContainerUniversalMachO::GetPluginVersion()
27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 1;
27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27636b877d2d27f7d1890f2d13807a3addb216648e2Greg Claytonsize_t
27736b877d2d27f7d1890f2d13807a3addb216648e2Greg ClaytonObjectContainerUniversalMachO::GetModuleSpecifications (const lldb_private::FileSpec& file,
27836b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton                                                        lldb::DataBufferSP& data_sp,
27936b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton                                                        lldb::offset_t data_offset,
28036b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton                                                        lldb::offset_t file_offset,
2817980d35608225dc71b3dd946d4c3aea85bc24e85Greg Clayton                                                        lldb::offset_t file_size,
28236b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton                                                        lldb_private::ModuleSpecList &specs)
28336b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton{
28436b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    const size_t initial_count = specs.GetSize();
28536b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton
28636b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    DataExtractor data;
2877980d35608225dc71b3dd946d4c3aea85bc24e85Greg Clayton    data.SetData (data_sp, data_offset, data_sp->GetByteSize());
28836b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton
28936b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    if (ObjectContainerUniversalMachO::MagicBytesMatch(data))
29036b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    {
29136b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton        llvm::MachO::fat_header header;
29236b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton        std::vector<llvm::MachO::fat_arch> fat_archs;
29336b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton        if (ParseHeader (data, header, fat_archs))
29436b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton        {
29536b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton            for (const llvm::MachO::fat_arch &fat_arch : fat_archs)
29636b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton            {
2977980d35608225dc71b3dd946d4c3aea85bc24e85Greg Clayton                const lldb::offset_t slice_file_offset = fat_arch.offset + file_offset;
2987980d35608225dc71b3dd946d4c3aea85bc24e85Greg Clayton                if (fat_arch.offset < file_size && file_size > slice_file_offset)
2997980d35608225dc71b3dd946d4c3aea85bc24e85Greg Clayton                {
3007980d35608225dc71b3dd946d4c3aea85bc24e85Greg Clayton                    ObjectFile::GetModuleSpecifications (file,
3017980d35608225dc71b3dd946d4c3aea85bc24e85Greg Clayton                                                         slice_file_offset,
3027980d35608225dc71b3dd946d4c3aea85bc24e85Greg Clayton                                                         file_size - slice_file_offset,
3037980d35608225dc71b3dd946d4c3aea85bc24e85Greg Clayton                                                         specs);
3047980d35608225dc71b3dd946d4c3aea85bc24e85Greg Clayton                }
30536b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton            }
30636b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton        }
30736b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    }
30836b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton    return specs.GetSize() - initial_count;
30936b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton}
31036b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton
311