Initial checkin of lldb code from internal Apple repo.

llvm-svn: 105619
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
new file mode 100644
index 0000000..b34dd3d
--- /dev/null
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -0,0 +1,929 @@
+//===-- ObjectFileELF.cpp ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ObjectFileELF.h"
+
+#include <mach/machine.h>
+#include <assert.h>
+
+#include <algorithm>
+
+#include <stdint.h>
+#include "elf.h"
+#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Symbol/ObjectFile.h"
+
+#define CASE_AND_STREAM(s, def, width)  case def: s->Printf("%-*s", width, #def); break;
+
+static uint32_t ELFMachineToMachCPU(Elf32_Half machine);
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace std;
+
+
+#include <mach-o/nlist.h>
+#include <mach-o/stab.h>
+
+
+void
+ObjectFileELF::Initialize()
+{
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   GetPluginDescriptionStatic(),
+                                   CreateInstance);
+}
+
+void
+ObjectFileELF::Terminate()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+
+const char *
+ObjectFileELF::GetPluginNameStatic()
+{
+    return "object-file.elf32";
+}
+
+const char *
+ObjectFileELF::GetPluginDescriptionStatic()
+{
+    return "ELF object file reader (32-bit).";
+}
+
+
+ObjectFile *
+ObjectFileELF::CreateInstance (Module* module, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length)
+{
+    if (ObjectFileELF::MagicBytesMatch(dataSP))
+    {
+        std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileELF (module, dataSP, file, offset, length));
+        if (objfile_ap.get() && objfile_ap->ParseHeader())
+            return objfile_ap.release();
+    }
+    return NULL;
+}
+
+bool
+ObjectFileELF::MagicBytesMatch (DataBufferSP& dataSP)
+{
+    DataExtractor data(dataSP, eByteOrderHost, 4);
+    const uint8_t* magic = data.PeekData(0, 4);
+    if (magic != NULL)
+    {
+        return magic[EI_MAG0] == 0x7f
+            && magic[EI_MAG1] == 'E'
+            && magic[EI_MAG2] == 'L'
+            && magic[EI_MAG3] == 'F';
+    }
+    return false;
+}
+
+
+ObjectFileELF::ObjectFileELF(Module* module, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length) :
+    ObjectFile (module, file, offset, length, dataSP),
+    m_header(),
+    m_program_headers(),
+    m_section_headers(),
+    m_sections_ap(),
+    m_symtab_ap(),
+    m_shstr_data()
+{
+    if (file)
+        m_file = *file;
+    ::bzero (&m_header, sizeof(m_header));
+}
+
+
+ObjectFileELF::~ObjectFileELF()
+{
+}
+
+ByteOrder
+ObjectFileELF::GetByteOrder () const
+{
+    if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
+        return eByteOrderBig;
+    if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
+        return eByteOrderLittle;
+    return eByteOrderInvalid;
+}
+
+size_t
+ObjectFileELF::GetAddressByteSize () const
+{
+    return m_data.GetAddressByteSize();
+}
+
+bool
+ObjectFileELF::ParseHeader ()
+{
+    m_data.SetAddressByteSize(4);
+    uint32_t offset = GetOffset();
+    if (m_data.GetU8(&offset, m_header.e_ident, EI_NIDENT) == NULL)
+        return false;
+
+    m_data.SetByteOrder(GetByteOrder());
+
+    // Read e_type and e_machine
+    if (m_data.GetU16(&offset, &m_header.e_type, 2) == NULL)
+        return false;
+
+    // read e_version, e_entry, e_phoff, e_shoff, e_flags
+    if (m_data.GetU32(&offset, &m_header.e_version, 5) == NULL)
+        return false;
+
+    // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum, e_shstrndx
+    if (m_data.GetU16(&offset, &m_header.e_ehsize, 6) == NULL)
+        return false;
+
+    return true;
+}
+
+bool
+ObjectFileELF::GetUUID (UUID* uuid)
+{
+    return false;
+}
+
+uint32_t
+ObjectFileELF::GetDependentModules(FileSpecList& files)
+{
+    return 0;
+}
+
+//----------------------------------------------------------------------
+// ParseProgramHeaders
+//----------------------------------------------------------------------
+size_t
+ObjectFileELF::ParseProgramHeaders()
+{
+    // We have already parsed the program headers
+    if (!m_program_headers.empty())
+        return m_program_headers.size();
+
+    uint32_t offset = 0;
+    if (m_header.e_phnum > 0)
+    {
+        m_program_headers.resize(m_header.e_phnum);
+
+        if (m_program_headers.size() != m_header.e_phnum)
+            return 0;
+
+        const size_t byte_size = m_header.e_phnum * m_header.e_phentsize;
+        DataBufferSP buffer_sp(m_file.ReadFileContents(m_offset + m_header.e_phoff, byte_size));
+
+        if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != byte_size)
+            return 0;
+
+        DataExtractor data(buffer_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+
+        uint32_t idx;
+        for (idx = 0; idx < m_header.e_phnum; ++idx)
+        {
+            if (data.GetU32(&offset, &m_program_headers[idx].p_type, 8) == NULL)
+                return 0;
+        }
+        if (idx < m_program_headers.size())
+            m_program_headers.resize(idx);
+    }
+
+    return m_program_headers.size();
+}
+
+
+//----------------------------------------------------------------------
+// ParseSectionHeaders
+//----------------------------------------------------------------------
+size_t
+ObjectFileELF::ParseSectionHeaders()
+{
+    // We have already parsed the section headers
+    if (!m_section_headers.empty())
+        return m_section_headers.size();
+
+    if (m_header.e_shnum > 0)
+    {
+        uint32_t offset = 0;
+
+        m_section_headers.resize(m_header.e_shnum);
+
+        if (m_section_headers.size() != m_header.e_shnum)
+            return 0;
+
+        const size_t byte_size = m_header.e_shnum * m_header.e_shentsize;
+        DataBufferSP buffer_sp(m_file.ReadFileContents(m_offset + m_header.e_shoff, byte_size));
+
+        if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != byte_size)
+            return 0;
+
+        DataExtractor data(buffer_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+
+        uint32_t idx;
+        for (idx = 0; idx < m_header.e_shnum; ++idx)
+        {
+            if (data.GetU32(&offset, &m_section_headers[idx].sh_name, 10) == NULL)
+                break;
+        }
+        if (idx < m_section_headers.size())
+            m_section_headers.resize(idx);
+    }
+
+    return m_section_headers.size();
+}
+
+size_t
+ObjectFileELF::GetSectionHeaderStringTable()
+{
+    if (m_shstr_data.GetByteSize() == 0)
+    {
+        if (m_header.e_shstrndx && m_header.e_shstrndx < m_section_headers.size())
+        {
+            const size_t byte_size = m_section_headers[m_header.e_shstrndx].sh_size;
+            DataBufferSP buffer_sp(m_file.ReadFileContents(m_offset + m_section_headers[m_header.e_shstrndx].sh_offset, byte_size));
+
+            if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != byte_size)
+                return 0;
+
+            m_shstr_data.SetData(buffer_sp);
+        }
+    }
+    return m_shstr_data.GetByteSize();
+}
+
+uint32_t
+ObjectFileELF::GetSectionIndexByName(const char *name)
+{
+    if (ParseSectionHeaders() && GetSectionHeaderStringTable())
+    {
+        uint32_t offset = 1;    // Skip leading NULL string at offset 0;
+        while (m_shstr_data.ValidOffset(offset))
+        {
+            uint32_t sh_name = offset;  // Save offset in case we find a match
+            const char* sectionHeaderName = m_shstr_data.GetCStr(&offset);
+            if (sectionHeaderName)
+            {
+                if (strcmp(name, sectionHeaderName) == 0)
+                {
+                    SectionHeaderCollIter pos;
+                    for (pos = m_section_headers.begin(); pos != m_section_headers.end(); ++pos)
+                    {
+                        if ( (*pos).sh_name == sh_name )
+                        {
+                            // section indexes are 1 based
+                            return std::distance(m_section_headers.begin(), pos) + 1;
+                        }
+                    }
+                    return UINT32_MAX;
+                }
+            }
+            else
+            {
+                return UINT32_MAX;
+            }
+        }
+    }
+
+    return UINT32_MAX;
+}
+
+SectionList *
+ObjectFileELF::GetSectionList()
+{
+    if (m_sections_ap.get() == NULL)
+    {
+        m_sections_ap.reset(new SectionList());
+        if (ParseSectionHeaders() && GetSectionHeaderStringTable())
+        {
+            uint32_t sh_idx = 0;
+            const size_t num_sections = m_section_headers.size();
+            for (sh_idx = 0; sh_idx < num_sections; ++sh_idx)
+            {
+                ConstString section_name(m_shstr_data.PeekCStr(m_section_headers[sh_idx].sh_name));
+                uint64_t section_file_size = m_section_headers[sh_idx].sh_type == SHT_NOBITS ? 0 : m_section_headers[sh_idx].sh_size;
+                SectionSP section_sp(new Section(NULL,                                  // Parent section
+                                                 GetModule(),                           // Module to which this section belongs
+                                                 sh_idx + 1,                            // Section ID is the 1 based
+                                                 section_name,                          // Name of this section
+                                                 eSectionTypeOther,  // TODO: fill this in appropriately for ELF...
+                                                 m_section_headers[sh_idx].sh_addr,     // File VM address
+                                                 m_section_headers[sh_idx].sh_size,     // VM size in bytes of this section
+                                                 m_section_headers[sh_idx].sh_offset,   // Offset to the data for this section in the file
+                                                 section_file_size,                     // Size in bytes of this section as found in the the file
+                                                 m_section_headers[sh_idx].sh_flags));  // Flags for this section
+                if (section_sp.get())
+                    m_sections_ap->AddSection(section_sp);
+
+            }
+        }
+    }
+    return m_sections_ap.get();
+}
+
+static void
+ParseSymbols (Symtab *symtab, SectionList *section_list, const Elf32_Shdr &symtab_shdr, const DataExtractor& symtab_data, const DataExtractor& strtab_data)
+{
+    assert (sizeof(Elf32_Sym) == symtab_shdr.sh_entsize);
+    const uint32_t num_symbols = symtab_data.GetByteSize() / sizeof(Elf32_Sym);
+    uint32_t offset = 0;
+    Elf32_Sym symbol;
+    uint32_t i;
+    static ConstString text_section_name(".text");
+    static ConstString init_section_name(".init");
+    static ConstString fini_section_name(".fini");
+    static ConstString ctors_section_name(".ctors");
+    static ConstString dtors_section_name(".dtors");
+
+    static ConstString data_section_name(".data");
+    static ConstString rodata_section_name(".rodata");
+    static ConstString rodata1_section_name(".rodata1");
+    static ConstString data2_section_name(".data1");
+    static ConstString bss_section_name(".bss");
+
+    for (i=0; i<num_symbols; ++i)
+    {
+    //  if (symtab_data.GetU32(&offset, &symbol.st_name, 3) == 0)
+    //      break;
+
+        if (!symtab_data.ValidOffsetForDataOfSize(offset, sizeof(Elf32_Sym)))
+            break;
+
+        symbol.st_name  = symtab_data.GetU32 (&offset);
+        symbol.st_value = symtab_data.GetU32 (&offset);
+        symbol.st_size  = symtab_data.GetU32 (&offset);
+        symbol.st_info  = symtab_data.GetU8  (&offset);
+        symbol.st_other = symtab_data.GetU8  (&offset);
+        symbol.st_shndx = symtab_data.GetU16 (&offset);
+
+        Section * symbol_section = NULL;
+        SymbolType symbol_type = eSymbolTypeInvalid;
+
+        switch (symbol.st_shndx)
+        {
+        case SHN_ABS:
+            symbol_type = eSymbolTypeAbsolute;
+            break;
+        case SHN_UNDEF:
+            symbol_type = eSymbolTypeUndefined;
+            break;
+        default:
+            symbol_section = section_list->GetSectionAtIndex (symbol.st_shndx).get();
+            break;
+        }
+
+        switch (ELF32_ST_BIND (symbol.st_info))
+        {
+        default:
+        case STT_NOTYPE:
+            // The symbol's type is not specified.
+            break;
+
+        case STT_OBJECT:
+            // The symbol is associated with a data object, such as a variable, an array, etc.
+            symbol_type == eSymbolTypeData;
+            break;
+
+        case STT_FUNC:
+            // The symbol is associated with a function or other executable code.
+            symbol_type == eSymbolTypeCode;
+            break;
+
+        case STT_SECTION:
+            // The symbol is associated with a section. Symbol table entries of
+            // this type exist primarily for relocation and normally have
+            // STB_LOCAL binding.
+            break;
+
+        case STT_FILE:
+            // Conventionally, the symbol's name gives the name of the source
+            // file associated with the object file. A file symbol has STB_LOCAL
+            // binding, its section index is SHN_ABS, and it precedes the other
+            // STB_LOCAL symbols for the file, if it is present.
+            symbol_type == eSymbolTypeObjectFile;
+            break;
+        }
+
+        if (symbol_type == eSymbolTypeInvalid)
+        {
+            if (symbol_section)
+            {
+                const ConstString &sect_name = symbol_section->GetName();
+                if (sect_name == text_section_name ||
+                    sect_name == init_section_name ||
+                    sect_name == fini_section_name ||
+                    sect_name == ctors_section_name ||
+                    sect_name == dtors_section_name)
+                {
+                    symbol_type = eSymbolTypeCode;
+                }
+                else
+                if (sect_name == data_section_name ||
+                    sect_name == data2_section_name ||
+                    sect_name == rodata_section_name ||
+                    sect_name == rodata1_section_name ||
+                    sect_name == bss_section_name)
+                {
+                    symbol_type = eSymbolTypeData;
+                }
+            }
+        }
+
+        uint64_t symbol_value = symbol.st_value;
+        if (symbol_section != NULL)
+            symbol_value -= symbol_section->GetFileAddress();
+        const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
+
+        Symbol dc_symbol(i,             // ID is the original symbol table index
+                        symbol_name,    // symbol name
+                        false,          // Is the symbol name mangled?
+                        symbol_type,    // type of this symbol
+                        ELF32_ST_BIND (symbol.st_info) == STB_GLOBAL,   // Is this globally visible?
+                        false,          // Is this symbol debug info?
+                        false,          // Is this symbol a trampoline?
+                        false,          // Is this symbol artificial?
+                        symbol_section, // section pointer if symbol_value is an offset within a section, else NULL
+                        symbol_value,   // offset from section if section is non-NULL, else the value for this symbol
+                        symbol.st_size, // size in bytes of this symbol
+                        symbol.st_other << 8 | symbol.st_info); // symbol flags
+        symtab->AddSymbol(dc_symbol);
+    }
+}
+
+
+Symtab *
+ObjectFileELF::GetSymtab()
+{
+    if (m_symtab_ap.get() == NULL)
+    {
+        m_symtab_ap.reset(new Symtab(this));
+
+        if (ParseSectionHeaders() && GetSectionHeaderStringTable())
+        {
+            uint32_t symtab_idx = UINT32_MAX;
+            uint32_t dynsym_idx = UINT32_MAX;
+            uint32_t sh_idx = 0;
+            const size_t num_sections = m_section_headers.size();
+            for (sh_idx = 0; sh_idx < num_sections; ++sh_idx)
+            {
+                if (m_section_headers[sh_idx].sh_type == SHT_SYMTAB)
+                {
+                    symtab_idx = sh_idx;
+                    break;
+                }
+                if (m_section_headers[sh_idx].sh_type == SHT_DYNSYM)
+                {
+                    dynsym_idx = sh_idx;
+                }
+            }
+
+            SectionList *section_list = NULL;
+            static ConstString g_symtab(".symtab");
+            static ConstString g_strtab(".strtab");
+            static ConstString g_dynsym(".dynsym");
+            static ConstString g_dynstr(".dynstr");
+            // Check if we found a full symbol table?
+            if (symtab_idx < num_sections)
+            {
+                section_list = GetSectionList();
+                if (section_list)
+                {
+                    Section *symtab_section = section_list->FindSectionByName(g_symtab).get();
+                    Section *strtab_section = section_list->FindSectionByName(g_strtab).get();
+                    if (symtab_section && strtab_section)
+                    {
+                        DataExtractor symtab_data;
+                        DataExtractor strtab_data;
+                        if (symtab_section->ReadSectionDataFromObjectFile (this, symtab_data) > 0 &&
+                            strtab_section->ReadSectionDataFromObjectFile (this, strtab_data) > 0)
+                        {
+                            ParseSymbols (m_symtab_ap.get(), section_list, m_section_headers[symtab_idx], symtab_data, strtab_data);
+                        }
+                    }
+                }
+            }
+            // Check if we found a reduced symbol table that gets used for dynamic linking?
+            else if (dynsym_idx < num_sections)
+            {
+                section_list = GetSectionList();
+                if (section_list)
+                {
+                    Section *dynsym_section = section_list->FindSectionByName(g_dynsym).get();
+                    Section *dynstr_section = section_list->FindSectionByName(g_dynstr).get();
+                    if (dynsym_section && dynstr_section)
+                    {
+                        DataExtractor dynsym_data;
+                        DataExtractor dynstr_data;
+                        if (dynsym_section->ReadSectionDataFromObjectFile (this, dynsym_data) > 0 &&
+                            dynstr_section->ReadSectionDataFromObjectFile (this, dynstr_data) > 0)
+                        {
+                            ParseSymbols (m_symtab_ap.get(), section_list, m_section_headers[dynsym_idx], dynsym_data, dynstr_data);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return m_symtab_ap.get();
+}
+
+//
+////----------------------------------------------------------------------
+//// GetNListSymtab
+////----------------------------------------------------------------------
+//bool
+//ELF32RuntimeFileParser::GetNListSymtab(BinaryDataRef& stabs_data, BinaryDataRef& stabstr_data, bool locals_only, uint32_t& value_size)
+//{
+//  value_size = 4; // Size in bytes of the nlist n_value member
+//  return  GetSectionInfo(GetSectionIndexByName(".stab"), NULL, NULL, NULL, NULL, NULL, NULL, &stabs_data, NULL) &&
+//          GetSectionInfo(GetSectionIndexByName(".stabstr"), NULL, NULL, NULL, NULL, NULL, NULL, &stabstr_data, NULL);
+//}
+//
+//===----------------------------------------------------------------------===//
+// Dump
+//
+// Dump the specifics of the runtime file container (such as any headers
+// segments, sections, etc).
+//----------------------------------------------------------------------
+void
+ObjectFileELF::Dump(Stream *s)
+{
+    DumpELFHeader(s, m_header);
+    s->EOL();
+    DumpELFProgramHeaders(s);
+    s->EOL();
+    DumpELFSectionHeaders(s);
+    s->EOL();
+    SectionList *section_list = GetSectionList();
+    if (section_list)
+        section_list->Dump(s, NULL, true);
+    Symtab *symtab = GetSymtab();
+    if (symtab)
+        symtab->Dump(s, NULL);
+    s->EOL();
+}
+
+//----------------------------------------------------------------------
+// DumpELFHeader
+//
+// Dump the ELF header to the specified output stream
+//----------------------------------------------------------------------
+void
+ObjectFileELF::DumpELFHeader(Stream *s, const Elf32_Ehdr& header)
+{
+
+    s->PutCString ("ELF Header\n");
+    s->Printf ("e_ident[EI_MAG0   ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
+    s->Printf ("e_ident[EI_MAG1   ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
+    s->Printf ("e_ident[EI_MAG2   ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
+    s->Printf ("e_ident[EI_MAG3   ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
+    s->Printf ("e_ident[EI_CLASS  ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
+    s->Printf ("e_ident[EI_DATA   ] = 0x%2.2x ", header.e_ident[EI_DATA]);
+    DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
+    s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
+    s->Printf ("e_ident[EI_PAD    ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
+
+    s->Printf("e_type      = 0x%4.4x ", header.e_type);
+    DumpELFHeader_e_type(s, header.e_type);
+    s->Printf("\ne_machine   = 0x%4.4x\n", header.e_machine);
+    s->Printf("e_version   = 0x%8.8x\n", header.e_version);
+    s->Printf("e_entry     = 0x%8.8x\n", header.e_entry);
+    s->Printf("e_phoff     = 0x%8.8x\n", header.e_phoff);
+    s->Printf("e_shoff     = 0x%8.8x\n", header.e_shoff);
+    s->Printf("e_flags     = 0x%8.8x\n", header.e_flags);
+    s->Printf("e_ehsize    = 0x%4.4x\n", header.e_ehsize);
+    s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
+    s->Printf("e_phnum     = 0x%4.4x\n", header.e_phnum);
+    s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
+    s->Printf("e_shnum     = 0x%4.4x\n", header.e_shnum);
+    s->Printf("e_shstrndx  = 0x%4.4x\n", header.e_shstrndx);
+}
+
+//----------------------------------------------------------------------
+// DumpELFHeader_e_type
+//
+// Dump an token value for the ELF header member e_type
+//----------------------------------------------------------------------
+void
+ObjectFileELF::DumpELFHeader_e_type(Stream *s, uint16_t e_type)
+{
+    switch (e_type)
+    {
+    case ET_NONE:   *s << "ET_NONE"; break;
+    case ET_REL:    *s << "ET_REL"; break;
+    case ET_EXEC:   *s << "ET_EXEC"; break;
+    case ET_DYN:    *s << "ET_DYN"; break;
+    case ET_CORE:   *s << "ET_CORE"; break;
+    default:
+        break;
+    }
+}
+
+//----------------------------------------------------------------------
+// DumpELFHeader_e_ident_EI_DATA
+//
+// Dump an token value for the ELF header member e_ident[EI_DATA]
+//----------------------------------------------------------------------
+void
+ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, uint16_t ei_data)
+{
+    switch (ei_data)
+    {
+    case ELFDATANONE:   *s << "ELFDATANONE"; break;
+    case ELFDATA2LSB:   *s << "ELFDATA2LSB - Little Endian"; break;
+    case ELFDATA2MSB:   *s << "ELFDATA2MSB - Big Endian"; break;
+    default:
+        break;
+    }
+}
+
+
+//----------------------------------------------------------------------
+// DumpELFProgramHeader
+//
+// Dump a single ELF program header to the specified output stream
+//----------------------------------------------------------------------
+void
+ObjectFileELF::DumpELFProgramHeader(Stream *s, const Elf32_Phdr& ph)
+{
+    DumpELFProgramHeader_p_type(s, ph.p_type);
+    s->Printf(" %8.8x %8.8x %8.8x %8.8x %8.8x %8.8x (", ph.p_offset, ph.p_vaddr, ph.p_paddr, ph.p_filesz, ph.p_memsz, ph.p_flags);
+    DumpELFProgramHeader_p_flags(s, ph.p_flags);
+    s->Printf(") %8.8x", ph.p_align);
+}
+
+//----------------------------------------------------------------------
+// DumpELFProgramHeader_p_type
+//
+// Dump an token value for the ELF program header member p_type which
+// describes the type of the program header
+//----------------------------------------------------------------------
+void
+ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, Elf32_Word p_type)
+{
+    const int kStrWidth = 10;
+    switch (p_type)
+    {
+    CASE_AND_STREAM(s, PT_NULL      , kStrWidth);
+    CASE_AND_STREAM(s, PT_LOAD      , kStrWidth);
+    CASE_AND_STREAM(s, PT_DYNAMIC   , kStrWidth);
+    CASE_AND_STREAM(s, PT_INTERP    , kStrWidth);
+    CASE_AND_STREAM(s, PT_NOTE      , kStrWidth);
+    CASE_AND_STREAM(s, PT_SHLIB     , kStrWidth);
+    CASE_AND_STREAM(s, PT_PHDR      , kStrWidth);
+    default:
+        s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
+        break;
+    }
+}
+
+
+//----------------------------------------------------------------------
+// DumpELFProgramHeader_p_flags
+//
+// Dump an token value for the ELF program header member p_flags
+//----------------------------------------------------------------------
+void
+ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, Elf32_Word p_flags)
+{
+    *s  << ((p_flags & PF_X) ? "PF_X" : "    ")
+        << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
+        << ((p_flags & PF_W) ? "PF_W" : "    ")
+        << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
+        << ((p_flags & PF_R) ? "PF_R" : "    ");
+}
+
+//----------------------------------------------------------------------
+// DumpELFProgramHeaders
+//
+// Dump all of the ELF program header to the specified output stream
+//----------------------------------------------------------------------
+void
+ObjectFileELF::DumpELFProgramHeaders(Stream *s)
+{
+    if (ParseProgramHeaders())
+    {
+        s->PutCString("Program Headers\n");
+        s->PutCString("IDX  p_type     p_offset p_vaddr  p_paddr  p_filesz p_memsz  p_flags                   p_align\n");
+        s->PutCString("==== ---------- -------- -------- -------- -------- -------- ------------------------- --------\n");
+
+        uint32_t idx = 0;
+        ProgramHeaderCollConstIter pos;
+
+        for (pos = m_program_headers.begin(); pos != m_program_headers.end(); ++pos, ++idx)
+        {
+            s->Printf ("[%2u] ", idx);
+            ObjectFileELF::DumpELFProgramHeader(s, *pos);
+            s->EOL();
+        }
+    }
+}
+
+
+//----------------------------------------------------------------------
+// DumpELFSectionHeader
+//
+// Dump a single ELF section header to the specified output stream
+//----------------------------------------------------------------------
+void
+ObjectFileELF::DumpELFSectionHeader(Stream *s, const Elf32_Shdr& sh)
+{
+    s->Printf ("%8.8x ", sh.sh_name);
+    DumpELFSectionHeader_sh_type(s, sh.sh_type);
+    s->Printf (" %8.8x (", sh.sh_flags);
+    DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
+    s->Printf (") %8.8x %8.8x %8.8x %8.8x %8.8x %8.8x %8.8x",
+                sh.sh_addr, sh.sh_offset, sh.sh_size, sh.sh_link, sh.sh_info, sh.sh_addralign, sh.sh_entsize);
+}
+
+//----------------------------------------------------------------------
+// DumpELFSectionHeader_sh_type
+//
+// Dump an token value for the ELF section header member sh_type which
+// describes the type of the section
+//----------------------------------------------------------------------
+void
+ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, Elf32_Word sh_type)
+{
+    const int kStrWidth = 12;
+    switch (sh_type)
+    {
+    CASE_AND_STREAM(s, SHT_NULL     , kStrWidth);
+    CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
+    CASE_AND_STREAM(s, SHT_SYMTAB   , kStrWidth);
+    CASE_AND_STREAM(s, SHT_STRTAB   , kStrWidth);
+    CASE_AND_STREAM(s, SHT_RELA     , kStrWidth);
+    CASE_AND_STREAM(s, SHT_HASH     , kStrWidth);
+    CASE_AND_STREAM(s, SHT_DYNAMIC  , kStrWidth);
+    CASE_AND_STREAM(s, SHT_NOTE     , kStrWidth);
+    CASE_AND_STREAM(s, SHT_NOBITS   , kStrWidth);
+    CASE_AND_STREAM(s, SHT_REL      , kStrWidth);
+    CASE_AND_STREAM(s, SHT_SHLIB    , kStrWidth);
+    CASE_AND_STREAM(s, SHT_DYNSYM   , kStrWidth);
+    CASE_AND_STREAM(s, SHT_LOPROC   , kStrWidth);
+    CASE_AND_STREAM(s, SHT_HIPROC   , kStrWidth);
+    CASE_AND_STREAM(s, SHT_LOUSER   , kStrWidth);
+    CASE_AND_STREAM(s, SHT_HIUSER   , kStrWidth);
+    default:
+        s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
+        break;
+    }
+}
+
+
+//----------------------------------------------------------------------
+// DumpELFSectionHeader_sh_flags
+//
+// Dump an token value for the ELF section header member sh_flags
+//----------------------------------------------------------------------
+void
+ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, Elf32_Word sh_flags)
+{
+    *s  << ((sh_flags & SHF_WRITE) ? "WRITE" : "     ")
+        << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
+        << ((sh_flags & SHF_ALLOC) ? "ALLOC" : "     ")
+        << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
+        << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : "         ");
+}
+//----------------------------------------------------------------------
+// DumpELFSectionHeaders
+//
+// Dump all of the ELF section header to the specified output stream
+//----------------------------------------------------------------------
+void
+ObjectFileELF::DumpELFSectionHeaders(Stream *s)
+{
+    if (ParseSectionHeaders() && GetSectionHeaderStringTable())
+    {
+        s->PutCString("Section Headers\n");
+        s->PutCString("IDX  name     type         flags                            addr     offset   size     link     info     addralgn entsize  Name\n");
+        s->PutCString("==== -------- ------------ -------------------------------- -------- -------- -------- -------- -------- -------- -------- ====================\n");
+
+        uint32_t idx = 0;
+        SectionHeaderCollConstIter pos;
+
+        for (pos = m_section_headers.begin(); pos != m_section_headers.end(); ++pos, ++idx)
+        {
+            s->Printf ("[%2u] ", idx);
+            ObjectFileELF::DumpELFSectionHeader(s, *pos);
+            const char* section_name = m_shstr_data.PeekCStr(pos->sh_name);
+            if (section_name)
+                *s << ' ' << section_name << "\n";
+        }
+    }
+}
+
+static uint32_t
+ELFMachineToMachCPU(Elf32_Half machine)
+{
+    switch (machine)
+    {
+    case EM_SPARC:  return CPU_TYPE_SPARC;
+    case EM_386:    return CPU_TYPE_I386;
+    case EM_68K:    return CPU_TYPE_MC680x0;
+    case EM_88K:    return CPU_TYPE_MC88000;
+    case EM_860:    return CPU_TYPE_I860;
+    case EM_MIPS:   return 8;   // commented out in mach/machine.h
+    case EM_PPC:    return CPU_TYPE_POWERPC;
+    case EM_PPC64:  return CPU_TYPE_POWERPC64;
+    case EM_ARM:    return 12;  // commented out in mach/machine.h
+    }
+    return 0;
+}
+
+bool
+ObjectFileELF::GetTargetTriple (ConstString &target_triple)
+{
+    static ConstString g_target_triple;
+
+    if (g_target_triple)
+    {
+        target_triple = g_target_triple;
+    }
+    else
+    {
+        std::string triple;
+        switch (m_header.e_machine)
+        {
+        case EM_SPARC:  triple.assign("sparc-"); break;
+        case EM_386:    triple.assign("i386-"); break;
+        case EM_68K:    triple.assign("68k-"); break;
+        case EM_88K:    triple.assign("88k-"); break;
+        case EM_860:    triple.assign("i860-"); break;
+        case EM_MIPS:   triple.assign("mips-"); break;
+        case EM_PPC:    triple.assign("powerpc-"); break;
+        case EM_PPC64:  triple.assign("powerpc64-"); break;
+        case EM_ARM:    triple.assign("arm-"); break;
+        }
+        // TODO: determine if there is a vendor in the ELF? Default to "apple" for now
+        triple += "apple-";
+        // TODO: determine if there is an OS in the ELF? Default to "darwin" for now
+        triple += "darwin10";
+        g_target_triple.SetCString(triple.c_str());
+        target_triple = g_target_triple;
+    }
+    return !target_triple.IsEmpty();
+}
+
+
+//bool
+//ELF32RuntimeFileParser::GetArch(ArchSpec &arch) const
+//{
+//  arch.SetCPUType(ELFMachineToMachCPU(m_header.e_machine));
+//  arch.SetCPUSubtype(ArchSpec::eAny);
+//  return true;
+//}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+const char *
+ObjectFileELF::GetPluginName()
+{
+    return "ObjectFileELF";
+}
+
+const char *
+ObjectFileELF::GetShortPluginName()
+{
+    return GetPluginNameStatic();
+}
+
+uint32_t
+ObjectFileELF::GetPluginVersion()
+{
+    return 1;
+}
+
+void
+ObjectFileELF::GetPluginCommandHelp (const char *command, Stream *strm)
+{
+}
+
+Error
+ObjectFileELF::ExecutePluginCommand (Args &command, Stream *strm)
+{
+    Error error;
+    error.SetErrorString("No plug-in command are currently supported.");
+    return error;
+}
+
+Log *
+ObjectFileELF::EnablePluginLogging (Stream *strm, Args &command)
+{
+    return NULL;
+}
+
+
+
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
new file mode 100644
index 0000000..5d5778c
--- /dev/null
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -0,0 +1,197 @@
+//===-- ObjectFileELF.h -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ObjectFileELF_h_
+#define liblldb_ObjectFileELF_h_
+
+#include <stdint.h>
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/FileSpec.h"
+#include "lldb/Symbol/ObjectFile.h"
+
+#include "elf.h"
+
+//----------------------------------------------------------------------
+// This class needs to be hidden as eventually belongs in a plugin that
+// will export the ObjectFile protocol
+//----------------------------------------------------------------------
+class ObjectFileELF :
+    public lldb_private::ObjectFile
+{
+public:
+    //------------------------------------------------------------------
+    // Static Functions
+    //------------------------------------------------------------------
+    static void
+    Initialize();
+
+    static void
+    Terminate();
+
+    static const char *
+    GetPluginNameStatic();
+
+    static const char *
+    GetPluginDescriptionStatic();
+
+    static lldb_private::ObjectFile *
+    CreateInstance (lldb_private::Module* module,
+                    lldb::DataBufferSP& dataSP,
+                    const lldb_private::FileSpec* file,
+                    lldb::addr_t offset,
+                    lldb::addr_t length);
+    static bool
+    MagicBytesMatch (lldb::DataBufferSP& dataSP);
+
+    //------------------------------------------------------------------
+    // Member Functions
+    //------------------------------------------------------------------
+    ObjectFileELF (lldb_private::Module* module,
+                   lldb::DataBufferSP& dataSP,
+                   const lldb_private::FileSpec* file,
+                   lldb::addr_t offset,
+                   lldb::addr_t length);
+
+    virtual
+    ~ObjectFileELF();
+
+    virtual bool
+    ParseHeader ();
+
+    virtual lldb::ByteOrder
+    GetByteOrder () const;
+
+    virtual size_t
+    GetAddressByteSize ()  const;
+
+    virtual lldb_private::Symtab *
+    GetSymtab();
+
+    virtual lldb_private::SectionList *
+    GetSectionList();
+
+    virtual void
+    Dump (lldb_private::Stream *s);
+
+    virtual bool
+    GetTargetTriple (lldb_private::ConstString &target_triple);
+
+    virtual bool
+    GetUUID (lldb_private::UUID* uuid);
+
+    virtual uint32_t
+    GetDependentModules(lldb_private::FileSpecList& files);
+
+    //------------------------------------------------------------------
+    // PluginInterface protocol
+    //------------------------------------------------------------------
+    virtual const char *
+    GetPluginName();
+
+    virtual const char *
+    GetShortPluginName();
+
+    virtual uint32_t
+    GetPluginVersion();
+
+    virtual void
+    GetPluginCommandHelp (const char *command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Error
+    ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Log *
+    EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command);
+
+
+
+protected:
+    typedef std::vector<Elf32_Phdr>             ProgramHeaderColl;
+    typedef ProgramHeaderColl::iterator         ProgramHeaderCollIter;
+    typedef ProgramHeaderColl::const_iterator   ProgramHeaderCollConstIter;
+
+    typedef std::vector<Elf32_Shdr>             SectionHeaderColl;
+    typedef SectionHeaderColl::iterator         SectionHeaderCollIter;
+    typedef SectionHeaderColl::const_iterator   SectionHeaderCollConstIter;
+
+    Elf32_Ehdr m_header;
+    ProgramHeaderColl m_program_headers;
+    SectionHeaderColl m_section_headers;
+    mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
+    mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
+    lldb_private::DataExtractor m_shstr_data;
+
+    size_t
+    ParseSections ();
+
+    size_t
+    ParseSymtab (bool minimize);
+
+private:
+
+    // ELF header dump routines
+    static void
+    DumpELFHeader (lldb_private::Stream *s,
+                   const Elf32_Ehdr& header);
+
+    static void
+    DumpELFHeader_e_ident_EI_DATA (lldb_private::Stream *s,
+                                   uint16_t ei_data);
+    static void
+    DumpELFHeader_e_type (lldb_private::Stream *s,
+                          uint16_t e_type);
+
+    // ELF program header dump routines
+    void
+    DumpELFProgramHeaders (lldb_private::Stream *s);
+
+    static void
+    DumpELFProgramHeader (lldb_private::Stream *s,
+                          const Elf32_Phdr& ph);
+
+    static void
+    DumpELFProgramHeader_p_type (lldb_private::Stream *s,
+                                 Elf32_Word p_type);
+
+    static void
+    DumpELFProgramHeader_p_flags (lldb_private::Stream *s,
+                                  Elf32_Word p_flags);
+
+    // ELF section header dump routines
+    void
+    DumpELFSectionHeaders (lldb_private::Stream *s);
+
+    static void
+    DumpELFSectionHeader (lldb_private::Stream *s,
+                          const Elf32_Shdr& sh);
+
+    static void
+    DumpELFSectionHeader_sh_type (lldb_private::Stream *s,
+                                  Elf32_Word sh_type);
+
+    static void
+    DumpELFSectionHeader_sh_flags (lldb_private::Stream *s,
+                                   Elf32_Word sh_flags);
+
+    size_t
+    ParseProgramHeaders ();
+
+    size_t
+    ParseSectionHeaders ();
+
+    size_t
+    GetSectionHeaderStringTable ();
+
+    uint32_t
+    GetSectionIndexByName (const char *name);
+};
+
+#endif // #ifndef liblldb_ObjectFileELF_h_
diff --git a/lldb/source/Plugins/ObjectFile/ELF/elf.h b/lldb/source/Plugins/ObjectFile/ELF/elf.h
new file mode 100644
index 0000000..9d08119
--- /dev/null
+++ b/lldb/source/Plugins/ObjectFile/ELF/elf.h
@@ -0,0 +1,240 @@
+//===-- elf.h ---------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __elf_h__
+#define __elf_h__
+
+typedef uint16_t    Elf32_Half;
+typedef uint32_t    Elf32_Word;
+typedef int32_t     Elf32_Sword;
+typedef uint32_t    Elf32_Addr;
+typedef uint32_t    Elf32_Off;
+
+
+#define EI_NIDENT 16
+
+//----------------------------------------------------------------------
+// ELF Header
+//----------------------------------------------------------------------
+typedef struct Elf32_Ehdr_Tag
+{
+    unsigned char e_ident[EI_NIDENT];
+    Elf32_Half  e_type;
+    Elf32_Half  e_machine;
+    Elf32_Word  e_version;
+    Elf32_Addr  e_entry;
+    Elf32_Off   e_phoff;
+    Elf32_Off   e_shoff;
+    Elf32_Word  e_flags;
+    Elf32_Half  e_ehsize;
+    Elf32_Half  e_phentsize;
+    Elf32_Half  e_phnum;
+    Elf32_Half  e_shentsize;
+    Elf32_Half  e_shnum;
+    Elf32_Half  e_shstrndx;
+} Elf32_Ehdr;
+
+//----------------------------------------------------------------------
+// e_type
+//
+// This member identifies the object file type.
+//----------------------------------------------------------------------
+#define ET_NONE     0       // No file type
+#define ET_REL      1       // Relocatable file
+#define ET_EXEC     2       // Executable file
+#define ET_DYN      3       // Shared object file
+#define ET_CORE     4       // Core file
+#define ET_LOPROC   0xff00  // Processor-specific
+#define ET_HIPROC   0xffff  // Processor-specific
+
+//----------------------------------------------------------------------
+// e_machine
+//
+// Machine Type
+//----------------------------------------------------------------------
+#define EM_NONE     0   // No machine
+#define EM_M32      1   // AT&T WE 32100
+#define EM_SPARC    2   // SPARC
+#define EM_386      3   // Intel 80386
+#define EM_68K      4   // Motorola 68000
+#define EM_88K      5   // Motorola 88000
+#define EM_860      7   // Intel 80860
+#define EM_MIPS     8   // MIPS RS3000
+#define EM_PPC      20  // PowerPC
+#define EM_PPC64    21  // PowerPC64
+#define EM_ARM      40  // ARM
+
+
+//----------------------------------------------------------------------
+// e_ident indexes
+//----------------------------------------------------------------------
+#define EI_MAG0     0   // File identification
+#define EI_MAG1     1   // File identification
+#define EI_MAG2     2   // File identification
+#define EI_MAG3     3   // File identification
+#define EI_CLASS    4   // File class
+#define EI_DATA     5   // Data encoding
+#define EI_VERSION  6   // File version
+#define EI_PAD      7   // Start of padding bytes
+
+
+//----------------------------------------------------------------------
+// EI_DATA definitions
+//----------------------------------------------------------------------
+#define ELFDATANONE 0   // Invalid data encoding
+#define ELFDATA2LSB 1   // Little Endian
+#define ELFDATA2MSB 2   // Big Endian
+
+//----------------------------------------------------------------------
+// Section Header
+//----------------------------------------------------------------------
+typedef struct Elf32_Shdr_Tag
+{
+    Elf32_Word  sh_name;
+    Elf32_Word  sh_type;
+    Elf32_Word  sh_flags;
+    Elf32_Addr  sh_addr;
+    Elf32_Off   sh_offset;
+    Elf32_Word  sh_size;
+    Elf32_Word  sh_link;
+    Elf32_Word  sh_info;
+    Elf32_Word  sh_addralign;
+    Elf32_Word  sh_entsize;
+} Elf32_Shdr;
+
+//----------------------------------------------------------------------
+// Section Types (sh_type)
+//----------------------------------------------------------------------
+#define SHT_NULL        0
+#define SHT_PROGBITS    1
+#define SHT_SYMTAB      2
+#define SHT_STRTAB      3
+#define SHT_RELA        4
+#define SHT_HASH        5
+#define SHT_DYNAMIC     6
+#define SHT_NOTE        7
+#define SHT_NOBITS      8
+#define SHT_REL         9
+#define SHT_SHLIB       10
+#define SHT_DYNSYM      11
+#define SHT_LOPROC      0x70000000
+#define SHT_HIPROC      0x7fffffff
+#define SHT_LOUSER      0x80000000
+#define SHT_HIUSER      0xffffffff
+
+//----------------------------------------------------------------------
+// Special Section Indexes
+//----------------------------------------------------------------------
+#define SHN_UNDEF       0
+#define SHN_LORESERVE   0xff00
+#define SHN_LOPROC      0xff00
+#define SHN_HIPROC      0xff1f
+#define SHN_ABS         0xfff1
+#define SHN_COMMON      0xfff2
+#define SHN_HIRESERVE   0xffff
+
+//----------------------------------------------------------------------
+// Section Attribute Flags (sh_flags)
+//----------------------------------------------------------------------
+#define SHF_WRITE       0x1
+#define SHF_ALLOC       0x2
+#define SHF_EXECINSTR   0x4
+#define SHF_MASKPROC    0xf0000000
+
+
+//----------------------------------------------------------------------
+// Symbol Table Entry Header
+//----------------------------------------------------------------------
+typedef struct Elf32_Sym_Tag
+{
+    Elf32_Word      st_name;
+    Elf32_Addr      st_value;
+    Elf32_Word      st_size;
+    unsigned char   st_info;
+    unsigned char   st_other;
+    Elf32_Half      st_shndx;
+} Elf32_Sym;
+
+
+#define ELF32_ST_BIND(i)    ((i)>>4)
+#define ELF32_ST_TYPE(i)    ((i)&0xf)
+#define ELF32_ST_INFO(b,t)  (((b)<<4)+((t)&0xf))
+
+// ST_BIND
+#define STB_LOCAL   0
+#define STB_GLOBAL  1
+#define STB_WEAK    2
+#define STB_LOPROC  13
+#define STB_HIPROC  15
+
+// ST_TYPE
+#define STT_NOTYPE  0
+#define STT_OBJECT  1
+#define STT_FUNC    2
+#define STT_SECTION 3
+#define STT_FILE    4
+#define STT_LOPROC  13
+#define STT_HIPROC  15
+
+
+//----------------------------------------------------------------------
+// Relocation Entries
+//----------------------------------------------------------------------
+typedef struct Elf32_Rel_Tag
+{
+    Elf32_Addr  r_offset;
+    Elf32_Word  r_info;
+} Elf32_Rel;
+
+typedef struct Elf32_Rela_Tag
+{
+    Elf32_Addr  r_offset;
+    Elf32_Word  r_info;
+    Elf32_Sword r_addend;
+} Elf32_Rela;
+
+#define ELF32_R_SYM(i)      ((i)>>8)
+#define ELF32_R_TYPE(i)     ((unsignedchar)(i))
+#define ELF32_R_INFO(s,t)   (((s)<<8)+(unsignedchar)(t))
+
+
+//----------------------------------------------------------------------
+// Program Headers
+//----------------------------------------------------------------------
+typedef struct Elf32_Phdr_Tag
+{
+    Elf32_Word  p_type;
+    Elf32_Off   p_offset;
+    Elf32_Addr  p_vaddr;
+    Elf32_Addr  p_paddr;
+    Elf32_Word  p_filesz;
+    Elf32_Word  p_memsz;
+    Elf32_Word  p_flags;
+    Elf32_Word  p_align;
+} Elf32_Phdr;
+
+//----------------------------------------------------------------------
+// Program Header Type (p_type)
+//----------------------------------------------------------------------
+#define PT_NULL     0
+#define PT_LOAD     1
+#define PT_DYNAMIC  2
+#define PT_INTERP   3
+#define PT_NOTE     4
+#define PT_SHLIB    5
+#define PT_PHDR     6
+#define PT_LOPROC   0x70000000
+#define PT_HIPROC   0x7fffffff
+
+#define PF_X        (1 << 0)    // executable
+#define PF_W        (1 << 1)    // writable
+#define PF_R        (1 << 2)    // readable
+
+
+#endif // __elf_h__
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
new file mode 100644
index 0000000..682a116
--- /dev/null
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -0,0 +1,1311 @@
+//===-- ObjectFileMachO.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ObjectFileMachO.h"
+
+#include <mach-o/nlist.h>
+#include <mach-o/stab.h>
+
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/FileSpec.h"
+#include "lldb/Core/FileSpecList.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/Core/UUID.h"
+#include "lldb/Symbol/ObjectFile.h"
+
+#ifndef S_DTRACE_DOF
+// section contains DTrace Object Format
+#define S_DTRACE_DOF 0xf
+#endif
+
+#ifndef S_LAZY_DYLIB_SYMBOL_POINTERS
+// section with only lazy symbol pointers to lazy loaded dylibs
+#define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+void
+ObjectFileMachO::Initialize()
+{
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   GetPluginDescriptionStatic(),
+                                   CreateInstance);
+}
+
+void
+ObjectFileMachO::Terminate()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+
+const char *
+ObjectFileMachO::GetPluginNameStatic()
+{
+    return "object-file.mach-o";
+}
+
+const char *
+ObjectFileMachO::GetPluginDescriptionStatic()
+{
+    return "Mach-o object file reader (32 and 64 bit)";
+}
+
+
+ObjectFile *
+ObjectFileMachO::CreateInstance (Module* module, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length)
+{
+    if (ObjectFileMachO::MagicBytesMatch(dataSP))
+    {
+        std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module, dataSP, file, offset, length));
+        if (objfile_ap.get() && objfile_ap->ParseHeader())
+            return objfile_ap.release();
+    }
+    return NULL;
+}
+
+
+static uint32_t
+MachHeaderSizeFromMagic(uint32_t magic)
+{
+    switch (magic)
+    {
+    case MH_MAGIC:
+    case MH_CIGAM:
+        return sizeof(struct mach_header);
+
+    case MH_MAGIC_64:
+    case MH_CIGAM_64:
+        return sizeof(struct mach_header_64);
+        break;
+
+    default:
+        break;
+    }
+    return 0;
+}
+
+
+bool
+ObjectFileMachO::MagicBytesMatch (DataBufferSP& dataSP)
+{
+    DataExtractor data(dataSP, eByteOrderHost, 4);
+    uint32_t offset = 0;
+    uint32_t magic = data.GetU32(&offset);
+    return MachHeaderSizeFromMagic(magic) != 0;
+}
+
+
+ObjectFileMachO::ObjectFileMachO(Module* module, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length) :
+    ObjectFile(module, file, offset, length, dataSP),
+    m_mutex (Mutex::eMutexTypeRecursive),
+    m_header(),
+    m_sections_ap(),
+    m_symtab_ap()
+{
+    ::bzero (&m_header, sizeof(m_header));
+    ::bzero (&m_dysymtab, sizeof(m_dysymtab));
+}
+
+
+ObjectFileMachO::~ObjectFileMachO()
+{
+}
+
+
+bool
+ObjectFileMachO::ParseHeader ()
+{
+    lldb_private::Mutex::Locker locker(m_mutex);
+    bool can_parse = false;
+    uint32_t offset = 0;
+    m_data.SetByteOrder (eByteOrderHost);
+    // Leave magic in the original byte order
+    m_header.magic = m_data.GetU32(&offset);
+    switch (m_header.magic)
+    {
+    case MH_MAGIC:
+        m_data.SetByteOrder (eByteOrderHost);
+        m_data.SetAddressByteSize(4);
+        can_parse = true;
+        break;
+
+    case MH_MAGIC_64:
+        m_data.SetByteOrder (eByteOrderHost);
+        m_data.SetAddressByteSize(8);
+        can_parse = true;
+        break;
+
+    case MH_CIGAM:
+        m_data.SetByteOrder(eByteOrderHost == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
+        m_data.SetAddressByteSize(4);
+        can_parse = true;
+        break;
+
+    case MH_CIGAM_64:
+        m_data.SetByteOrder(eByteOrderHost == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
+        m_data.SetAddressByteSize(8);
+        can_parse = true;
+        break;
+
+    default:
+        break;
+    }
+
+    if (can_parse)
+    {
+        m_data.GetU32(&offset, &m_header.cputype, 6);
+
+        ArchSpec mach_arch(m_header.cputype, m_header.cpusubtype);
+        if (mach_arch == m_module->GetArchitecture())
+        {
+            // Read in all only the load command data
+            DataBufferSP data_sp(m_file.ReadFileContents(m_offset, m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic)));
+            m_data.SetData (data_sp);
+            return true;
+        }
+    }
+    else
+    {
+        memset(&m_header, 0, sizeof(struct mach_header));
+    }
+    return false;
+}
+
+
+ByteOrder
+ObjectFileMachO::GetByteOrder () const
+{
+    lldb_private::Mutex::Locker locker(m_mutex);
+    return m_data.GetByteOrder ();
+}
+
+
+size_t
+ObjectFileMachO::GetAddressByteSize () const
+{
+    lldb_private::Mutex::Locker locker(m_mutex);
+    return m_data.GetAddressByteSize ();
+}
+
+
+Symtab *
+ObjectFileMachO::GetSymtab()
+{
+    lldb_private::Mutex::Locker locker(m_mutex);
+    if (m_symtab_ap.get() == NULL)
+    {
+        m_symtab_ap.reset(new Symtab(this));
+        ParseSymtab(false);
+    }
+    return m_symtab_ap.get();
+}
+
+
+SectionList *
+ObjectFileMachO::GetSectionList()
+{
+    lldb_private::Mutex::Locker locker(m_mutex);
+    if (m_sections_ap.get() == NULL)
+    {
+        m_sections_ap.reset(new SectionList());
+        ParseSections();
+    }
+    return m_sections_ap.get();
+}
+
+
+size_t
+ObjectFileMachO::ParseSections ()
+{
+    lldb::user_id_t segID = 0;
+    lldb::user_id_t sectID = 0;
+    struct segment_command_64 load_cmd;
+    uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+    uint32_t i;
+    //bool dump_sections = false;
+    for (i=0; i<m_header.ncmds; ++i)
+    {
+        const uint32_t load_cmd_offset = offset;
+        if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
+            break;
+
+        if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
+        {
+            if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
+            {
+                load_cmd.vmaddr = m_data.GetAddress(&offset);
+                load_cmd.vmsize = m_data.GetAddress(&offset);
+                load_cmd.fileoff = m_data.GetAddress(&offset);
+                load_cmd.filesize = m_data.GetAddress(&offset);
+                if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
+                {
+                    // Keep a list of mach segments around in case we need to
+                    // get at data that isn't stored in the abstracted Sections.
+                    m_mach_segments.push_back (load_cmd);
+
+                    ConstString segment_name (load_cmd.segname, std::min<int>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
+                    // Use a segment ID of the segment index shifted left by 8 so they
+                    // never conflict with any of the sections.
+                    SectionSP segment_sp;
+                    if (segment_name)
+                    {
+                        segment_sp.reset(new Section (NULL,
+                                                      GetModule(),            // Module to which this section belongs
+                                                      ++segID << 8,           // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
+                                                      segment_name,           // Name of this section
+                                                      eSectionTypeContainer,  // This section is a container of other sections.
+                                                      load_cmd.vmaddr,        // File VM address == addresses as they are found in the object file
+                                                      load_cmd.vmsize,        // VM size in bytes of this section
+                                                      load_cmd.fileoff,       // Offset to the data for this section in the file
+                                                      load_cmd.filesize,      // Size in bytes of this section as found in the the file
+                                                      load_cmd.flags));       // Flags for this section
+
+                        m_sections_ap->AddSection(segment_sp);
+                    }
+
+                    struct section_64 sect64;
+                    ::bzero (&sect64, sizeof(sect64));
+                    // Push a section into our mach sections for the section at
+                    // index zero (NO_SECT)
+                    m_mach_sections.push_back(sect64);
+                    uint32_t segment_sect_idx;
+                    const lldb::user_id_t first_segment_sectID = sectID + 1;
+
+
+                    const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
+                    for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
+                    {
+                        if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
+                            break;
+                        if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
+                            break;
+                        sect64.addr = m_data.GetAddress(&offset);
+                        sect64.size = m_data.GetAddress(&offset);
+
+                        if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
+                            break;
+
+                        // Keep a list of mach sections around in case we need to
+                        // get at data that isn't stored in the abstracted Sections.
+                        m_mach_sections.push_back (sect64);
+
+                        ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
+                        if (!segment_name)
+                        {
+                            // We have a segment with no name so we need to conjure up
+                            // segments that correspond to the section's segname if there
+                            // isn't already such a section. If there is such a section,
+                            // we resize the section so that it spans all sections.
+                            // We also mark these sections as fake so address matches don't
+                            // hit if they land in the gaps between the child sections.
+                            segment_name.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
+                            segment_sp = m_sections_ap->FindSectionByName (segment_name);
+                            if (segment_sp.get())
+                            {
+                                Section *segment = segment_sp.get();
+                                // Grow the section size as needed.
+                                const lldb::addr_t sect64_min_addr = sect64.addr;
+                                const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
+                                const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
+                                const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
+                                const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
+                                if (sect64_min_addr >= curr_seg_min_addr)
+                                {
+                                    const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
+                                    // Only grow the section size if needed
+                                    if (new_seg_byte_size > curr_seg_byte_size)
+                                        segment->SetByteSize (new_seg_byte_size);
+                                }
+                                else
+                                {
+                                    // We need to change the base address of the segment and
+                                    // adjust the child section offsets for all existing children.
+                                    const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
+                                    segment->Slide(slide_amount, false);
+                                    segment->GetChildren().Slide (-slide_amount, false);
+                                    segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
+                                }
+                            }
+                            else
+                            {
+                                // Create a fake section for the section's named segment
+                                segment_sp.reset(new Section(segment_sp.get(),       // Parent section
+                                                             GetModule(),            // Module to which this section belongs
+                                                             ++segID << 8,           // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
+                                                             segment_name,           // Name of this section
+                                                             eSectionTypeContainer,  // This section is a container of other sections.
+                                                             sect64.addr,            // File VM address == addresses as they are found in the object file
+                                                             sect64.size,            // VM size in bytes of this section
+                                                             sect64.offset,          // Offset to the data for this section in the file
+                                                             sect64.offset ? sect64.size : 0,        // Size in bytes of this section as found in the the file
+                                                             load_cmd.flags));       // Flags for this section
+                                segment_sp->SetIsFake(true);
+                                m_sections_ap->AddSection(segment_sp);
+                            }
+                        }
+                        assert (segment_sp.get());
+
+                        uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
+                        static ConstString g_sect_name_objc_data ("__objc_data");
+                        static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
+                        static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
+                        static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
+                        static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
+                        static ConstString g_sect_name_objc_const ("__objc_const");
+                        static ConstString g_sect_name_objc_classlist ("__objc_classlist");
+                        static ConstString g_sect_name_cfstring ("__cfstring");
+                        SectionType sect_type = eSectionTypeOther;
+
+                        if (section_name == g_sect_name_objc_selrefs)
+                        {
+                            sect_type = eSectionTypeDataCStringPointers;
+                        }
+                        else if (section_name == g_sect_name_objc_msgrefs)
+                        {
+                            sect_type = eSectionTypeDataObjCMessageRefs;
+                        }
+                        else if (section_name == g_sect_name_objc_data ||
+                                 section_name == g_sect_name_objc_classrefs ||
+                                 section_name == g_sect_name_objc_superrefs ||
+                                 section_name == g_sect_name_objc_const ||
+                                 section_name == g_sect_name_objc_classlist)
+                        {
+                            sect_type = eSectionTypeDataPointers;
+                        }
+                        else if (section_name == g_sect_name_cfstring)
+                        {
+                            sect_type = eSectionTypeDataObjCCFStrings;
+                        }
+
+                        if (sect_type == eSectionTypeOther)
+                        {
+                            switch (mach_sect_type)
+                            {
+                            // TODO: categorize sections by other flags for regular sections
+                            case S_REGULAR:
+
+                                sect_type = eSectionTypeOther;
+                                break;
+                            case S_ZEROFILL:                    sect_type = eSectionTypeZeroFill; break;
+                            case S_CSTRING_LITERALS:            sect_type = eSectionTypeDataCString;    break; // section with only literal C strings
+                            case S_4BYTE_LITERALS:              sect_type = eSectionTypeData4;    break; // section with only 4 byte literals
+                            case S_8BYTE_LITERALS:              sect_type = eSectionTypeData8;    break; // section with only 8 byte literals
+                            case S_LITERAL_POINTERS:            sect_type = eSectionTypeDataPointers;  break; // section with only pointers to literals
+                            case S_NON_LAZY_SYMBOL_POINTERS:    sect_type = eSectionTypeDataPointers;  break; // section with only non-lazy symbol pointers
+                            case S_LAZY_SYMBOL_POINTERS:        sect_type = eSectionTypeDataPointers;  break; // section with only lazy symbol pointers
+                            case S_SYMBOL_STUBS:                sect_type = eSectionTypeCode;  break; // section with only symbol stubs, byte size of stub in the reserved2 field
+                            case S_MOD_INIT_FUNC_POINTERS:      sect_type = eSectionTypeDataPointers;    break; // section with only function pointers for initialization
+                            case S_MOD_TERM_FUNC_POINTERS:      sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
+                            case S_COALESCED:                   sect_type = eSectionTypeOther; break;
+                            case S_GB_ZEROFILL:                 sect_type = eSectionTypeZeroFill; break;
+                            case S_INTERPOSING:                 sect_type = eSectionTypeCode;  break; // section with only pairs of function pointers for interposing
+                            case S_16BYTE_LITERALS:             sect_type = eSectionTypeData16; break; // section with only 16 byte literals
+                            case S_DTRACE_DOF:                  sect_type = eSectionTypeDebug; break;
+                            case S_LAZY_DYLIB_SYMBOL_POINTERS:  sect_type = eSectionTypeDataPointers;  break;
+                            default: break;
+                            }
+                        }
+
+                        SectionSP section_sp(new Section(segment_sp.get(),
+                                                         GetModule(),
+                                                         ++sectID,
+                                                         section_name,
+                                                         sect_type,
+                                                         sect64.addr - segment_sp->GetFileAddress(),
+                                                         sect64.size,
+                                                         sect64.offset,
+                                                         sect64.offset == 0 ? 0 : sect64.size,
+                                                         sect64.flags));
+                        segment_sp->GetChildren().AddSection(section_sp);
+
+                        if (segment_sp->IsFake())
+                        {
+                            segment_sp.reset();
+                            segment_name.Clear();
+                        }
+                    }
+                    if (m_header.filetype == MH_DSYM)
+                    {
+                        if (first_segment_sectID <= sectID)
+                        {
+                            lldb::user_id_t sect_uid;
+                            for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
+                            {
+                                SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
+                                SectionSP next_section_sp;
+                                if (sect_uid + 1 <= sectID)
+                                    next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
+
+                                if (curr_section_sp.get())
+                                {
+                                    if (curr_section_sp->GetByteSize() == 0)
+                                    {
+                                        if (next_section_sp.get() != NULL)
+                                            curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
+                                        else
+                                            curr_section_sp->SetByteSize ( load_cmd.vmsize );
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        else if (load_cmd.cmd == LC_DYSYMTAB)
+        {
+            m_dysymtab.cmd = load_cmd.cmd;
+            m_dysymtab.cmdsize = load_cmd.cmdsize;
+            m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
+        }
+
+        offset = load_cmd_offset + load_cmd.cmdsize;
+    }
+//    if (dump_sections)
+//    {
+//        StreamFile s(stdout);
+//        m_sections_ap->Dump(&s, true);
+//    }
+    return sectID;  // Return the number of sections we registered with the module
+}
+
+class MachSymtabSectionInfo
+{
+public:
+
+    MachSymtabSectionInfo (SectionList *section_list) :
+        m_section_list (section_list),
+        m_section_infos()
+    {
+        // Get the number of sections down to a depth of 1 to include
+        // all segments and their sections, but no other sections that
+        // may be added for debug map or
+        m_section_infos.resize(section_list->GetNumSections(1));
+    }
+
+
+    Section *
+    GetSection (uint8_t n_sect, addr_t file_addr)
+    {
+        if (n_sect == 0)
+            return NULL;
+        if (n_sect < m_section_infos.size())
+        {
+            if (m_section_infos[n_sect].section == NULL)
+            {
+                Section *section = m_section_list->FindSectionByID (n_sect).get();
+                m_section_infos[n_sect].section = section;
+                assert (section != NULL);
+                m_section_infos[n_sect].vm_range.SetBaseAddress (section->GetFileAddress());
+                m_section_infos[n_sect].vm_range.SetByteSize (section->GetByteSize());
+            }
+            if (m_section_infos[n_sect].vm_range.Contains(file_addr))
+                return m_section_infos[n_sect].section;
+        }
+        return m_section_list->FindSectionContainingFileAddress(file_addr).get();
+    }
+
+protected:
+    struct SectionInfo
+    {
+        SectionInfo () :
+            vm_range(),
+            section (NULL)
+        {
+        }
+
+        VMRange vm_range;
+        Section *section;
+    };
+    SectionList *m_section_list;
+    std::vector<SectionInfo> m_section_infos;
+};
+
+
+
+size_t
+ObjectFileMachO::ParseSymtab (bool minimize)
+{
+    Timer scoped_timer(__PRETTY_FUNCTION__,
+                       "ObjectFileMachO::ParseSymtab () module = %s",
+                       m_file.GetFilename().AsCString(""));
+    struct symtab_command symtab_load_command;
+    uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+    uint32_t i;
+    for (i=0; i<m_header.ncmds; ++i)
+    {
+        const uint32_t cmd_offset = offset;
+        // Read in the load command and load command size
+        if (m_data.GetU32(&offset, &symtab_load_command, 2) == NULL)
+            break;
+        // Watch for the symbol table load command
+        if (symtab_load_command.cmd == LC_SYMTAB)
+        {
+            // Read in the rest of the symtab load command
+            if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4))
+            {
+                Symtab *symtab = m_symtab_ap.get();
+                SectionList *section_list = GetSectionList();
+                assert(section_list);
+                const size_t addr_size = m_data.GetAddressByteSize();
+                const ByteOrder endian = m_data.GetByteOrder();
+                bool bit_width_32 = addr_size == 4;
+                const size_t nlist_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
+
+                DataBufferSP symtab_data_sp(m_file.ReadFileContents(m_offset + symtab_load_command.symoff, symtab_load_command.nsyms * nlist_size));
+                DataBufferSP strtab_data_sp(m_file.ReadFileContents(m_offset + symtab_load_command.stroff, symtab_load_command.strsize));
+
+                const char *strtab_data = (const char *)strtab_data_sp->GetBytes();
+//                DataExtractor symtab_data(symtab_data_sp, endian, addr_size);
+//                DataExtractor strtab_data(strtab_data_sp, endian, addr_size);
+
+                static ConstString g_segment_name_TEXT ("__TEXT");
+                static ConstString g_segment_name_DATA ("__DATA");
+                static ConstString g_segment_name_OBJC ("__OBJC");
+                static ConstString g_section_name_eh_frame ("__eh_frame");
+                SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
+                SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
+                SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
+                SectionSP eh_frame_section_sp;
+                if (text_section_sp.get())
+                    eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
+                else
+                    eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
+
+                uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NO_SECT;
+                //uint32_t symtab_offset = 0;
+                const uint8_t* nlist_data = symtab_data_sp->GetBytes();
+                assert (symtab_data_sp->GetByteSize()/nlist_size >= symtab_load_command.nsyms);
+
+
+                if (endian != eByteOrderHost)
+                {
+                    // ...
+                    assert (!"UNIMPLEMENTED: Swap all nlist entries");
+                }
+                uint32_t N_SO_index = UINT_MAX;
+
+                MachSymtabSectionInfo section_info (section_list);
+                std::vector<uint32_t> N_FUN_indexes;
+                std::vector<uint32_t> N_NSYM_indexes;
+                std::vector<uint32_t> N_INCL_indexes;
+                std::vector<uint32_t> N_BRAC_indexes;
+                std::vector<uint32_t> N_COMM_indexes;
+                uint32_t nlist_idx = 0;
+                Symbol *symbol_ptr = NULL;
+
+                uint32_t sym_idx = 0;
+                Symbol *sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
+                uint32_t num_syms = symtab->GetNumSymbols();
+
+                //symtab->Reserve (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
+                for (nlist_idx = 0; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
+                {
+                    struct nlist_64 nlist;
+                    if (bit_width_32)
+                    {
+                        struct nlist* nlist32_ptr = (struct nlist*)(nlist_data + (nlist_idx * nlist_size));
+                        nlist.n_un.n_strx = nlist32_ptr->n_un.n_strx;
+                        nlist.n_type = nlist32_ptr->n_type;
+                        nlist.n_sect = nlist32_ptr->n_sect;
+                        nlist.n_desc = nlist32_ptr->n_desc;
+                        nlist.n_value = nlist32_ptr->n_value;
+                    }
+                    else
+                    {
+                        nlist = *((struct nlist_64*)(nlist_data + (nlist_idx * nlist_size)));
+                    }
+
+                    SymbolType type = eSymbolTypeInvalid;
+                    const char* symbol_name = &strtab_data[nlist.n_un.n_strx];
+                    if (symbol_name[0] == '\0')
+                        symbol_name = NULL;
+                    Section* symbol_section = NULL;
+                    bool add_nlist = true;
+                    bool is_debug = ((nlist.n_type & N_STAB) != 0);
+
+                    assert (sym_idx < num_syms);
+
+                    sym[sym_idx].SetDebug (is_debug);
+
+                    if (is_debug)
+                    {
+                        switch (nlist.n_type)
+                        {
+                        case N_GSYM:    // global symbol: name,,NO_SECT,type,0
+                            // Sometimes the N_GSYM value contains the address.
+                            if (nlist.n_value != 0)
+                                symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+                            type = eSymbolTypeGlobal;
+                            break;
+
+                        case N_FNAME:   // procedure name (f77 kludge): name,,NO_SECT,0,0
+                            type = eSymbolTypeFunction;
+                            break;
+
+                        case N_FUN:                                         // procedure: name,,n_sect,linenumber,address
+                            if (symbol_name)
+                            {
+                                type = eSymbolTypeFunction;
+                                symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+                                // We use the current number of symbols in the symbol table in lieu of
+                                // using nlist_idx in case we ever start trimming entries out
+                                N_FUN_indexes.push_back(sym_idx);
+                            }
+                            else
+                            {
+                                type = eSymbolTypeFunctionEnd;
+
+                                if ( !N_FUN_indexes.empty() )
+                                {
+                                    // Copy the size of the function into the original STAB entry so we don't have
+                                    // to hunt for it later
+                                    symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
+                                    N_FUN_indexes.pop_back();
+                                    // We dont' really need the end function STAB as it contains the size which
+                                    // we already placed with the original symbol, so don't add it if we want a
+                                    // minimal symbol table
+                                    if (minimize)
+                                        add_nlist = false;
+                                }
+                            }
+                            break;
+
+                        case N_STSYM:   // static symbol: name,,n_sect,type,address
+                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+                            type = eSymbolTypeStatic;
+                            break;
+
+                        case N_LCSYM:   // .lcomm symbol: name,,n_sect,type,address
+                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+                            type = eSymbolTypeCommonBlock;
+                            break;
+
+                        case N_BNSYM:
+                            // We use the current number of symbols in the symbol table in lieu of
+                            // using nlist_idx in case we ever start trimming entries out
+                            if (minimize)
+                            {
+                                // Skip these if we want minimal symbol tables
+                                add_nlist = false;
+                            }
+                            else
+                            {
+                                symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+                                N_NSYM_indexes.push_back(sym_idx);
+                                type = eSymbolTypeScopeBegin;
+                            }
+                            break;
+
+                        case N_ENSYM:
+                            // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
+                            // so that we can always skip the entire symbol if we need to navigate
+                            // more quickly at the source level when parsing STABS
+                            if (minimize)
+                            {
+                                // Skip these if we want minimal symbol tables
+                                add_nlist = false;
+                            }
+                            else
+                            {
+                                if ( !N_NSYM_indexes.empty() )
+                                {
+                                    symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
+                                    symbol_ptr->SetByteSize(sym_idx + 1);
+                                    symbol_ptr->SetSizeIsSibling(true);
+                                    N_NSYM_indexes.pop_back();
+                                }
+                                type = eSymbolTypeScopeEnd;
+                            }
+                            break;
+
+
+                        case N_OPT:     // emitted with gcc2_compiled and in gcc source
+                            type = eSymbolTypeCompiler;
+                            break;
+
+                        case N_RSYM:    // register sym: name,,NO_SECT,type,register
+                            type = eSymbolTypeVariable;
+                            break;
+
+                        case N_SLINE:   // src line: 0,,n_sect,linenumber,address
+                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+                            type = eSymbolTypeLineEntry;
+                            break;
+
+                        case N_SSYM:    // structure elt: name,,NO_SECT,type,struct_offset
+                            type = eSymbolTypeVariableType;
+                            break;
+
+                        case N_SO:
+                            type = eSymbolTypeSourceFile;
+                            if (symbol_name == NULL)
+                            {
+                                if (N_SO_index == UINT_MAX)
+                                {
+                                    // Skip the extra blank N_SO entries that happen when the entire
+                                    // path is contained in the second consecutive N_SO STAB.
+                                    if (minimize)
+                                        add_nlist = false;
+                                }
+                                else
+                                {
+                                    // Set the size of the N_SO to the terminating index of this N_SO
+                                    // so that we can always skip the entire N_SO if we need to navigate
+                                    // more quickly at the source level when parsing STABS
+                                    symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
+                                    symbol_ptr->SetByteSize(sym_idx + 1);
+                                    symbol_ptr->SetSizeIsSibling(true);
+                                }
+                                N_NSYM_indexes.clear();
+                                N_INCL_indexes.clear();
+                                N_BRAC_indexes.clear();
+                                N_COMM_indexes.clear();
+                                N_FUN_indexes.clear();
+                                N_SO_index = UINT_MAX;
+                            }
+                            else if (symbol_name[0] == '/')
+                            {
+                                // We use the current number of symbols in the symbol table in lieu of
+                                // using nlist_idx in case we ever start trimming entries out
+                                N_SO_index = sym_idx;
+                            }
+                            break;
+
+                        case N_OSO:     // object file name: name,,0,0,st_mtime
+                            type = eSymbolTypeObjectFile;
+                            break;
+
+                        case N_LSYM:    // local sym: name,,NO_SECT,type,offset
+                            type = eSymbolTypeLocal;
+                            break;
+
+                        //----------------------------------------------------------------------
+                        // INCL scopes
+                        //----------------------------------------------------------------------
+                        case N_BINCL:   // include file beginning: name,,NO_SECT,0,sum
+                            // We use the current number of symbols in the symbol table in lieu of
+                            // using nlist_idx in case we ever start trimming entries out
+                            N_INCL_indexes.push_back(sym_idx);
+                            type = eSymbolTypeScopeBegin;
+                            break;
+                        case N_EINCL:   // include file end: name,,NO_SECT,0,0
+
+                            // Set the size of the N_BINCL to the terminating index of this N_EINCL
+                            // so that we can always skip the entire symbol if we need to navigate
+                            // more quickly at the source level when parsing STABS
+                            if ( !N_INCL_indexes.empty() )
+                            {
+                                symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
+                                symbol_ptr->SetByteSize(sym_idx + 1);
+                                symbol_ptr->SetSizeIsSibling(true);
+                                N_INCL_indexes.pop_back();
+                            }
+                            type = eSymbolTypeScopeEnd;
+                            break;
+
+                        case N_SOL:     // #included file name: name,,n_sect,0,address
+                            type = eSymbolTypeHeaderFile;
+                            break;
+
+                        case N_PARAMS:  // compiler parameters: name,,NO_SECT,0,0
+                            type = eSymbolTypeCompiler;
+                            break;
+
+                        case N_VERSION: // compiler version: name,,NO_SECT,0,0
+                            type = eSymbolTypeCompiler;
+                            break;
+
+                        case N_OLEVEL:  // compiler -O level: name,,NO_SECT,0,0
+                            type = eSymbolTypeCompiler;
+                            break;
+
+                        case N_PSYM:    // parameter: name,,NO_SECT,type,offset
+                            type = eSymbolTypeVariable;
+                            break;
+
+                        case N_ENTRY:   // alternate entry: name,,n_sect,linenumber,address
+                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+                            type = eSymbolTypeLineEntry;
+                            break;
+
+                        //----------------------------------------------------------------------
+                        // Left and Right Braces
+                        //----------------------------------------------------------------------
+                        case N_LBRAC:   // left bracket: 0,,NO_SECT,nesting level,address
+                            // We use the current number of symbols in the symbol table in lieu of
+                            // using nlist_idx in case we ever start trimming entries out
+                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+                            N_BRAC_indexes.push_back(sym_idx);
+                            type = eSymbolTypeScopeBegin;
+                            break;
+
+                        case N_RBRAC:   // right bracket: 0,,NO_SECT,nesting level,address
+                            // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
+                            // so that we can always skip the entire symbol if we need to navigate
+                            // more quickly at the source level when parsing STABS
+                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+                            if ( !N_BRAC_indexes.empty() )
+                            {
+                                symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
+                                symbol_ptr->SetByteSize(sym_idx + 1);
+                                symbol_ptr->SetSizeIsSibling(true);
+                                N_BRAC_indexes.pop_back();
+                            }
+                            type = eSymbolTypeScopeEnd;
+                            break;
+
+                        case N_EXCL:    // deleted include file: name,,NO_SECT,0,sum
+                            type = eSymbolTypeHeaderFile;
+                            break;
+
+                        //----------------------------------------------------------------------
+                        // COMM scopes
+                        //----------------------------------------------------------------------
+                        case N_BCOMM:   // begin common: name,,NO_SECT,0,0
+                            // We use the current number of symbols in the symbol table in lieu of
+                            // using nlist_idx in case we ever start trimming entries out
+                            type = eSymbolTypeScopeBegin;
+                            N_COMM_indexes.push_back(sym_idx);
+                            break;
+
+                        case N_ECOML:   // end common (local name): 0,,n_sect,0,address
+                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+                            // Fall through
+
+                        case N_ECOMM:   // end common: name,,n_sect,0,0
+                            // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
+                            // so that we can always skip the entire symbol if we need to navigate
+                            // more quickly at the source level when parsing STABS
+                            if ( !N_COMM_indexes.empty() )
+                            {
+                                symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
+                                symbol_ptr->SetByteSize(sym_idx + 1);
+                                symbol_ptr->SetSizeIsSibling(true);
+                                N_COMM_indexes.pop_back();
+                            }
+                            type = eSymbolTypeScopeEnd;
+                            break;
+
+                        case N_LENG:    // second stab entry with length information
+                            type = eSymbolTypeAdditional;
+                            break;
+
+                        default: break;
+                        }
+                    }
+                    else
+                    {
+                        //uint8_t n_pext    = N_PEXT & nlist.n_type;
+                        uint8_t n_type  = N_TYPE & nlist.n_type;
+                        sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
+
+                        if (symbol_name && ::strstr (symbol_name, ".objc") == symbol_name)
+                        {
+                            type = eSymbolTypeRuntime;
+                        }
+                        else
+                        {
+                            switch (n_type)
+                            {
+                            case N_INDR:    // Fall through
+                            case N_PBUD:    // Fall through
+                            case N_UNDF:
+                                type = eSymbolTypeExtern;
+                                break;
+
+                            case N_ABS:
+                                type = eSymbolTypeAbsolute;
+                                break;
+
+                            case N_SECT:
+                                symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+
+                                assert(symbol_section != NULL);
+                                if (TEXT_eh_frame_sectID == nlist.n_sect)
+                                {
+                                    type = eSymbolTypeException;
+                                }
+                                else
+                                {
+                                    uint32_t section_type = symbol_section->GetAllFlagBits() & SECTION_TYPE;
+
+                                    switch (section_type)
+                                    {
+                                    case S_REGULAR:                     break; // regular section
+                                    //case S_ZEROFILL:                  type = eSymbolTypeData;    break; // zero fill on demand section
+                                    case S_CSTRING_LITERALS:            type = eSymbolTypeData;    break; // section with only literal C strings
+                                    case S_4BYTE_LITERALS:              type = eSymbolTypeData;    break; // section with only 4 byte literals
+                                    case S_8BYTE_LITERALS:              type = eSymbolTypeData;    break; // section with only 8 byte literals
+                                    case S_LITERAL_POINTERS:            type = eSymbolTypeTrampoline; break; // section with only pointers to literals
+                                    case S_NON_LAZY_SYMBOL_POINTERS:    type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
+                                    case S_LAZY_SYMBOL_POINTERS:        type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
+                                    case S_SYMBOL_STUBS:                type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
+                                    case S_MOD_INIT_FUNC_POINTERS:      type = eSymbolTypeCode;    break; // section with only function pointers for initialization
+                                    case S_MOD_TERM_FUNC_POINTERS:      type = eSymbolTypeCode;    break; // section with only function pointers for termination
+                                    //case S_COALESCED:                 type = eSymbolType;    break; // section contains symbols that are to be coalesced
+                                    //case S_GB_ZEROFILL:               type = eSymbolTypeData;    break; // zero fill on demand section (that can be larger than 4 gigabytes)
+                                    case S_INTERPOSING:                 type = eSymbolTypeTrampoline;  break; // section with only pairs of function pointers for interposing
+                                    case S_16BYTE_LITERALS:             type = eSymbolTypeData;    break; // section with only 16 byte literals
+                                    case S_DTRACE_DOF:                  type = eSymbolTypeInstrumentation; break;
+                                    case S_LAZY_DYLIB_SYMBOL_POINTERS:  type = eSymbolTypeTrampoline; break;
+                                    default: break;
+                                    }
+
+                                    if (type == eSymbolTypeInvalid)
+                                    {
+                                        const char *symbol_sect_name = symbol_section->GetName().AsCString();
+                                        if (symbol_section->IsDescendant (text_section_sp.get()))
+                                        {
+                                            if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SELF_MODIFYING_CODE | S_ATTR_SOME_INSTRUCTIONS))
+                                                type = eSymbolTypeData;
+                                            else
+                                                type = eSymbolTypeCode;
+                                        }
+                                        else
+                                        if (symbol_section->IsDescendant(data_section_sp.get()))
+                                        {
+                                            if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
+                                            {
+                                                type = eSymbolTypeRuntime;
+                                            }
+                                            else
+                                            if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
+                                            {
+                                                type = eSymbolTypeException;
+                                            }
+                                            else
+                                            {
+                                                type = eSymbolTypeData;
+                                            }
+                                        }
+                                        else
+                                        if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
+                                        {
+                                            type = eSymbolTypeTrampoline;
+                                        }
+                                        else
+                                        if (symbol_section->IsDescendant(objc_section_sp.get()))
+                                        {
+                                            type = eSymbolTypeRuntime;
+                                        }
+                                    }
+                                }
+                                break;
+                            }
+                        }
+                    }
+
+                    if (add_nlist)
+                    {
+                        bool symbol_name_is_mangled = false;
+                        if (symbol_name && symbol_name[0] == '_')
+                        {
+                            symbol_name_is_mangled = symbol_name[1] == '_';
+                            symbol_name++;  // Skip the leading underscore
+                        }
+                        uint64_t symbol_value = nlist.n_value;
+                        if (symbol_section != NULL)
+                            symbol_value -= symbol_section->GetFileAddress();
+
+                        sym[sym_idx].SetID (nlist_idx);
+                        sym[sym_idx].SetType (type);
+                        if (symbol_name)
+                            sym[sym_idx].GetMangled().SetValue(symbol_name, symbol_name_is_mangled);
+                        sym[sym_idx].GetAddressRangeRef().GetBaseAddress().SetSection (symbol_section);
+                        sym[sym_idx].GetAddressRangeRef().GetBaseAddress().SetOffset (symbol_value);
+                        sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
+
+                        ++sym_idx;
+                    }
+                    else
+                    {
+                        sym[sym_idx].Clear();
+                    }
+
+                }
+
+
+                // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value
+                // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all
+                // such entries by figuring out what the address for the global is by looking up this non-STAB
+                // entry and copying the value into the debug symbol's value to save us the hassle in the
+                // debug symbol parser.
+
+                Symbol *global_symbol = NULL;
+                for (nlist_idx = 0;
+                     nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType(eSymbolTypeGlobal, nlist_idx)) != NULL;
+                     nlist_idx++)
+                {
+                    if (global_symbol->GetValue().GetFileAddress() == 0)
+                    {
+                        std::vector<uint32_t> indexes;
+                        if (symtab->AppendSymbolIndexesWithName(global_symbol->GetMangled().GetName(), indexes) > 0)
+                        {
+                            std::vector<uint32_t>::const_iterator pos;
+                            std::vector<uint32_t>::const_iterator end = indexes.end();
+                            for (pos = indexes.begin(); pos != end; ++pos)
+                            {
+                                symbol_ptr = symtab->SymbolAtIndex(*pos);
+                                if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
+                                {
+                                    global_symbol->SetValue(symbol_ptr->GetValue());
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+                // Now synthesize indirect symbols
+                if (m_dysymtab.nindirectsyms != 0)
+                {
+                    DataBufferSP indirect_symbol_indexes_sp(m_file.ReadFileContents(m_offset + m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4));
+
+                    if (indirect_symbol_indexes_sp && indirect_symbol_indexes_sp->GetByteSize())
+                    {
+                        DataExtractor indirect_symbol_index_data (indirect_symbol_indexes_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+
+                        for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
+                        {
+                            if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == S_SYMBOL_STUBS)
+                            {
+                                uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
+                                if (symbol_stub_byte_size == 0)
+                                    continue;
+
+                                const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
+
+                                if (num_symbol_stubs == 0)
+                                    continue;
+
+                                const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
+                                uint32_t stub_sym_id = symtab_load_command.nsyms;
+                                for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
+                                {
+                                    const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
+                                    const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
+                                    uint32_t symbol_stub_offset = symbol_stub_index * 4;
+                                    if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
+                                    {
+                                        const uint32_t symbol_index = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
+
+                                        Symbol *stub_symbol = symtab->SymbolAtIndex(symbol_index);
+                                        if (stub_symbol)
+                                        {
+                                            Address so_addr(symbol_stub_addr, section_list);
+
+                                            if (stub_symbol->GetType() == eSymbolTypeExtern)
+                                            {
+                                                // Change the external symbol into a trampoline that makes sense
+                                                // These symbols were N_UNDF N_EXT, and are useless to us, so we
+                                                // can re-use them so we don't have to make up a synthetic symbol
+                                                // for no good reason.
+                                                stub_symbol->SetType (eSymbolTypeTrampoline);
+                                                stub_symbol->SetExternal (false);
+                                                stub_symbol->GetAddressRangeRef().GetBaseAddress() = so_addr;
+                                                stub_symbol->GetAddressRangeRef().SetByteSize (symbol_stub_byte_size);
+                                            }
+                                            else
+                                            {
+                                                // Make a synthetic symbol to describe the trampoline stub
+                                                if (sym_idx >= num_syms)
+                                                {
+                                                    sym = symtab->Resize (num_syms + 16);
+                                                    num_syms = symtab->GetNumSymbols();
+                                                }
+                                                sym[sym_idx].SetID (stub_sym_id++);
+                                                sym[sym_idx].GetMangled() = stub_symbol->GetMangled();
+                                                sym[sym_idx].SetType (eSymbolTypeTrampoline);
+                                                sym[sym_idx].SetIsSynthetic (true);
+                                                sym[sym_idx].GetAddressRangeRef().GetBaseAddress() = so_addr;
+                                                sym[sym_idx].GetAddressRangeRef().SetByteSize (symbol_stub_byte_size);
+                                                ++sym_idx;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                if (sym_idx != symtab->GetNumSymbols())
+                    symtab->Resize (sym_idx);
+
+                return symtab->GetNumSymbols();
+            }
+        }
+        offset = cmd_offset + symtab_load_command.cmdsize;
+    }
+    return 0;
+}
+
+
+void
+ObjectFileMachO::Dump (Stream *s)
+{
+    lldb_private::Mutex::Locker locker(m_mutex);
+    s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
+    s->Indent();
+    if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
+        s->PutCString("ObjectFileMachO64");
+    else
+        s->PutCString("ObjectFileMachO32");
+
+    ArchSpec header_arch(m_header.cputype, m_header.cpusubtype);
+
+    *s << ", file = '" << m_file << "', arch = " << header_arch.AsCString() << "\n";
+
+    if (m_sections_ap.get())
+        m_sections_ap->Dump(s, NULL, true);
+
+    if (m_symtab_ap.get())
+        m_symtab_ap->Dump(s, NULL);
+}
+
+
+bool
+ObjectFileMachO::GetUUID (UUID* uuid)
+{
+    lldb_private::Mutex::Locker locker(m_mutex);
+    struct uuid_command load_cmd;
+    uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+    uint32_t i;
+    for (i=0; i<m_header.ncmds; ++i)
+    {
+        const uint32_t cmd_offset = offset;
+        if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
+            break;
+
+        if (load_cmd.cmd == LC_UUID)
+        {
+            const uint8_t *uuid_bytes = m_data.PeekData(offset, 16);
+            if (uuid_bytes)
+            {
+                uuid->SetBytes (uuid_bytes);
+                return true;
+            }
+            return false;
+        }
+        offset = cmd_offset + load_cmd.cmdsize;
+    }
+    return false;
+}
+
+
+uint32_t
+ObjectFileMachO::GetDependentModules (FileSpecList& files)
+{
+    lldb_private::Mutex::Locker locker(m_mutex);
+    struct load_command load_cmd;
+    uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+    uint32_t count = 0;
+    uint32_t i;
+    for (i=0; i<m_header.ncmds; ++i)
+    {
+        const uint32_t cmd_offset = offset;
+        if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
+            break;
+
+        switch (load_cmd.cmd)
+        {
+        case LC_LOAD_DYLIB:
+        case LC_LOAD_WEAK_DYLIB:
+        case LC_REEXPORT_DYLIB:
+        case LC_LOAD_DYLINKER:
+        case LC_LOADFVMLIB:
+            {
+                uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
+                const char *path = m_data.PeekCStr(name_offset);
+                // Skip any path that starts with '@' since these are usually:
+                // @executable_path/.../file
+                // @rpath/.../file
+                if (path && path[0] != '@')
+                {
+                    FileSpec file_spec(path);
+                    if (files.AppendIfUnique(file_spec))
+                        count++;
+                }
+            }
+            break;
+
+        default:
+            break;
+        }
+        offset = cmd_offset + load_cmd.cmdsize;
+    }
+    return count;
+}
+
+bool
+ObjectFileMachO::GetTargetTriple (ConstString &target_triple)
+{
+    lldb_private::Mutex::Locker locker(m_mutex);
+    std::string triple(GetModule()->GetArchitecture().AsCString());
+    triple += "-apple-darwin";
+    target_triple.SetCString(triple.c_str());
+    if (target_triple)
+        return true;
+    return false;
+}
+
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+const char *
+ObjectFileMachO::GetPluginName()
+{
+    return "ObjectFileMachO";
+}
+
+const char *
+ObjectFileMachO::GetShortPluginName()
+{
+    return GetPluginNameStatic();
+}
+
+uint32_t
+ObjectFileMachO::GetPluginVersion()
+{
+    return 1;
+}
+
+void
+ObjectFileMachO::GetPluginCommandHelp (const char *command, Stream *strm)
+{
+}
+
+Error
+ObjectFileMachO::ExecutePluginCommand (Args &command, Stream *strm)
+{
+    Error error;
+    error.SetErrorString("No plug-in command are currently supported.");
+    return error;
+}
+
+Log *
+ObjectFileMachO::EnablePluginLogging (Stream *strm, Args &command)
+{
+    return NULL;
+}
+
+
+
+
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
new file mode 100644
index 0000000..3ffeb24
--- /dev/null
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -0,0 +1,131 @@
+//===-- ObjectFileMachO.h ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ObjectFileMachO_h_
+#define liblldb_ObjectFileMachO_h_
+
+#include <mach-o/loader.h>
+#include "lldb/Core/FileSpec.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/ObjectFile.h"
+
+//----------------------------------------------------------------------
+// This class needs to be hidden as eventually belongs in a plugin that
+// will export the ObjectFile protocol
+//----------------------------------------------------------------------
+class ObjectFileMachO :
+    public lldb_private::ObjectFile
+{
+public:
+    //------------------------------------------------------------------
+    // Static Functions
+    //------------------------------------------------------------------
+    static void
+    Initialize();
+
+    static void
+    Terminate();
+
+    static const char *
+    GetPluginNameStatic();
+
+    static const char *
+    GetPluginDescriptionStatic();
+
+    static ObjectFile *
+    CreateInstance (lldb_private::Module* module,
+                    lldb::DataBufferSP& dataSP,
+                    const lldb_private::FileSpec* file,
+                    lldb::addr_t offset,
+                    lldb::addr_t length);
+
+    static bool
+    MagicBytesMatch (lldb::DataBufferSP& dataSP);
+
+    //------------------------------------------------------------------
+    // Member Functions
+    //------------------------------------------------------------------
+    ObjectFileMachO (lldb_private::Module* module,
+                     lldb::DataBufferSP& dataSP,
+                     const lldb_private::FileSpec* file,
+                     lldb::addr_t offset,
+                     lldb::addr_t length);
+
+    virtual
+    ~ObjectFileMachO();
+
+    virtual bool
+    ParseHeader ();
+
+    virtual lldb::ByteOrder
+    GetByteOrder () const;
+
+    virtual size_t
+    GetAddressByteSize ()  const;
+
+    virtual lldb_private::Symtab *
+    GetSymtab();
+
+    virtual lldb_private::SectionList *
+    GetSectionList();
+
+    virtual void
+    Dump (lldb_private::Stream *s);
+
+    virtual bool
+    GetTargetTriple (lldb_private::ConstString &target_triple);
+
+    virtual bool
+    GetUUID (lldb_private::UUID* uuid);
+
+    virtual uint32_t
+    GetDependentModules (lldb_private::FileSpecList& files);
+
+    //------------------------------------------------------------------
+    // PluginInterface protocol
+    //------------------------------------------------------------------
+    virtual const char *
+    GetPluginName();
+
+    virtual const char *
+    GetShortPluginName();
+
+    virtual uint32_t
+    GetPluginVersion();
+
+    virtual void
+    GetPluginCommandHelp (const char *command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Error
+    ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Log *
+    EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command);
+
+
+
+protected:
+    mutable lldb_private::Mutex m_mutex;
+    struct  mach_header m_header;
+    mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
+    mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
+
+    struct dysymtab_command m_dysymtab;
+    std::vector<struct segment_command_64> m_mach_segments;
+    std::vector<struct section_64> m_mach_sections;
+
+    size_t
+    ParseSections ();
+
+    size_t
+    ParseSymtab (bool minimize);
+
+};
+
+#endif  // liblldb_ObjectFileMachO_h_