Hi all,

Attached is an initial implementation of a 64-bit ELF object file
reader.  It is based on the existing 32-bit reader.  

This patch allows disassemble to work on x86_64 linux.  Support for
dependent modules is included, though LLDB still needs to be taught how
to resolve shared objects on linux (currently works only when the .so is
in the working directory).

Planed work includes renaming the existing 32 bit reader from
ObjectFileELF to ObjectFileELF32, extend with features from the 64 bit
version, and create a base class containing common functionality.

Any feedback greatly appreciated!

Take care,
Steve


diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index ab4c993..fd0d0c4 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -72,14 +72,18 @@ ObjectFileELF::CreateInstance (Module* module, DataBufferSP& dataSP, const FileS
 bool
 ObjectFileELF::MagicBytesMatch (DataBufferSP& dataSP)
 {
-    DataExtractor data(dataSP, eByteOrderHost, 4);
-    const uint8_t* magic = data.PeekData(0, 4);
+    DataExtractor data(dataSP, eByteOrderHost, EI_CLASS + 1);
+    const uint8_t* magic = data.PeekData(0, EI_CLASS + 1);
     if (magic != NULL)
     {
-        return magic[EI_MAG0] == 0x7f
-            && magic[EI_MAG1] == 'E'
-            && magic[EI_MAG2] == 'L'
-            && magic[EI_MAG3] == 'F';
+        bool have_magic = (magic[EI_MAG0] == 0x7f &&
+                           magic[EI_MAG1] == 'E'  &&
+                           magic[EI_MAG2] == 'L'  &&
+                           magic[EI_MAG3] == 'F');
+    
+        bool have_32bit = magic[EI_CLASS] == 1;
+    
+        return have_magic && have_32bit;
     }
     return false;
 }
@@ -376,7 +380,7 @@ ParseSymbols (Symtab *symtab, SectionList *section_list, const Elf32_Shdr &symta
             break;
         }
 
-        switch (ELF32_ST_BIND (symbol.st_info))
+        switch (ELF_ST_BIND (symbol.st_info))
         {
         default:
         case STT_NOTYPE:
@@ -442,7 +446,7 @@ ParseSymbols (Symtab *symtab, SectionList *section_list, const Elf32_Shdr &symta
                         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?
+                        ELF_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?
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF64.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF64.cpp
new file mode 100644
index 0000000..00c8980
--- /dev/null
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF64.cpp
@@ -0,0 +1,1016 @@
+//===-- ObjectFileELF64.cpp ----------------------------------- -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ObjectFileELF64.h"
+
+#include <cassert>
+#include <algorithm>
+
+#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/FileSpecList.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/Stream.h"
+
+#define CASE_AND_STREAM(s, def, width)                  \
+    case def: s->Printf("%-*s", width, #def); break;
+
+using namespace lldb;
+using namespace lldb_private;
+
+void 
+ObjectFileELF64::Initialize()
+{
+    PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                  GetPluginDescriptionStatic(),
+                                  CreateInstance);
+}
+
+void
+ObjectFileELF64::Terminate()
+{
+    PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+const char *
+ObjectFileELF64::GetPluginNameStatic()
+{
+    return "object-file.elf64";
+}
+
+const char *
+ObjectFileELF64::GetPluginDescriptionStatic()
+{
+    return "ELF object file reader (64-bit).";
+}
+
+ObjectFile *
+ObjectFileELF64::CreateInstance(Module *module,
+                                DataBufferSP &dataSP,
+                                const FileSpec *file, addr_t offset,
+                                addr_t length)
+{
+    if (ObjectFileELF64::MagicBytesMatch(dataSP)) 
+    {
+        std::auto_ptr<ObjectFile> objfile_ap(
+            new ObjectFileELF64(module, dataSP, file, offset, length));
+        if (objfile_ap->ParseHeader()) 
+            return objfile_ap.release();
+    }
+    return 0;
+}
+
+bool
+ObjectFileELF64::MagicBytesMatch(DataBufferSP& dataSP)
+{
+    DataExtractor data(dataSP, eByteOrderHost, EI_CLASS + 1);
+    const uint8_t* magic = data.PeekData(0, EI_CLASS + 1);
+
+    if (magic) 
+    {
+        bool have_magic = (magic[EI_MAG0] == 0x7f &&
+                           magic[EI_MAG1] == 'E'  &&
+                           magic[EI_MAG2] == 'L'  &&
+                           magic[EI_MAG3] == 'F');
+    
+        bool have_64bit = magic[EI_CLASS] == 2;
+    
+        return have_magic && have_64bit;
+    }
+    return false;
+}
+
+ObjectFileELF64::ObjectFileELF64(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;
+    ::memset(&m_header, 0, sizeof(m_header));
+}
+
+ObjectFileELF64::~ObjectFileELF64() { }
+
+ByteOrder
+ObjectFileELF64::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 
+ObjectFileELF64::GetAddressByteSize() const
+{
+    return m_data.GetAddressByteSize();
+}
+
+unsigned
+ObjectFileELF64::SectionIndex(const SectionHeaderCollIter &I)
+{
+    return std::distance(m_section_headers.begin(), I) + 1;
+}
+
+unsigned 
+ObjectFileELF64::SectionIndex(const SectionHeaderCollConstIter &I) const
+{
+    return std::distance(m_section_headers.begin(), I) + 1;
+}
+
+bool
+ObjectFileELF64::ParseHeader()
+{
+    uint32_t offset = GetOffset();
+
+    m_data.SetAddressByteSize(8);
+
+    if (!m_data.GetU8(&offset, m_header.e_ident, EI_NIDENT))
+        return false;
+
+    m_data.SetByteOrder(GetByteOrder());
+
+    // Read e_type and e_machine.
+    if (!m_data.GetU16(&offset, &m_header.e_type, 2))
+        return false;
+
+    // Read e_version.
+    if (!m_data.GetU32(&offset, &m_header.e_version, 1))
+        return false;
+
+    // Read e_entry, e_phoff and e_shoff.
+    if (!m_data.GetU64(&offset, &m_header.e_entry, 3))
+        return false;
+
+    // Read e_flags.
+    if (!m_data.GetU32(&offset, &m_header.e_flags, 1))
+        return false;
+
+    // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and e_shstrndx.
+    if (!m_data.GetU16(&offset, &m_header.e_ehsize, 6))
+        return false;
+
+    return true;
+}
+
+bool
+ObjectFileELF64::GetUUID(UUID* uuid)
+{
+    // FIXME: Return MD5 sum here.  See comment in ObjectFile.h.
+    return false;
+}
+
+uint32_t
+ObjectFileELF64::GetDependentModules(FileSpecList &files)
+{
+    size_t num_modules = ParseDependentModules();
+    uint32_t num_specs = 0;
+
+    for (unsigned i = 0; i < num_modules; ++i) {
+        if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
+            num_specs++;
+    }
+
+    return num_specs;
+}
+
+//----------------------------------------------------------------------
+// ParseDependentModules
+//----------------------------------------------------------------------
+size_t
+ObjectFileELF64::ParseDependentModules()
+{
+    if (m_filespec_ap.get())
+        return m_filespec_ap->GetSize();
+
+    m_filespec_ap.reset(new FileSpecList());
+
+    if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
+        return 0;
+
+    // Locate the dynamic table.
+    user_id_t dynsym_id = 0;
+    user_id_t dynstr_id = 0;
+    for (SectionHeaderCollIter I = m_section_headers.begin();
+         I != m_section_headers.end(); ++I) 
+    {
+        if (I->sh_type == SHT_DYNAMIC) 
+        {
+            dynsym_id = SectionIndex(I);
+            dynstr_id = I->sh_link + 1; // Section ID's are 1 based.
+            break;
+        }
+    }
+
+    if (!(dynsym_id && dynstr_id))
+        return 0;
+
+    SectionList *section_list = GetSectionList();
+    if (!section_list)
+        return 0;
+    
+    // Resolve and load the dynamic table entries and corresponding string
+    // table.
+    Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
+    Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
+    if (!(dynsym && dynstr))
+        return 0;
+
+    DataExtractor dynsym_data;
+    DataExtractor dynstr_data;
+    if (dynsym->ReadSectionDataFromObjectFile(this, dynsym_data) &&
+        dynstr->ReadSectionDataFromObjectFile(this, dynstr_data))
+    {
+        Elf64_Dyn symbol;
+        const unsigned numSymbols = dynsym_data.GetByteSize() / sizeof(Elf64_Dyn);
+        unsigned offset = 0;
+        
+        // The only type of entries we are concerned with are tagged DT_NEEDED,
+        // yielding the name of a required library.
+        for (unsigned i = 0; i < numSymbols; ++i) 
+        {
+            if (!dynsym_data.ValidOffsetForDataOfSize(offset, sizeof(Elf64_Dyn)))
+                break;
+            
+            symbol.d_tag = dynsym_data.GetU64(&offset);
+            symbol.d_un.d_val = dynsym_data.GetU64(&offset);
+            
+            if (symbol.d_tag != DT_NEEDED)
+                continue;
+            
+            const char *lib_name = dynstr_data.PeekCStr(symbol.d_un.d_val);
+            m_filespec_ap->Append(FileSpec(lib_name));
+        }
+    }
+    
+    return m_filespec_ap->GetSize();
+}
+
+//----------------------------------------------------------------------
+// ParseProgramHeaders
+//----------------------------------------------------------------------
+size_t
+ObjectFileELF64::ParseProgramHeaders()
+{
+    // We have already parsed the program headers
+    if (!m_program_headers.empty())
+        return m_program_headers.size();
+
+    // If there are no program headers to read we are done.
+    if (m_header.e_phnum == 0)
+        return 0;
+
+    m_program_headers.resize(m_header.e_phnum);
+    if (m_program_headers.size() != m_header.e_phnum)
+        return 0;
+
+    const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
+    const Elf64_Off ph_offset = m_offset + m_header.e_phoff;
+    DataBufferSP ph_buffer(m_file.ReadFileContents(ph_offset, ph_size));
+
+    if (!ph_buffer.get() || ph_buffer->GetByteSize() != ph_size)
+        return 0;
+    
+    DataExtractor data(ph_buffer, m_data.GetByteOrder(), 
+                       m_data.GetAddressByteSize());
+    
+    uint32_t idx;
+    uint32_t offset;
+    for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx) 
+    {
+        if (!data.GetU32(&offset, &m_program_headers[idx], 8))
+            return 0;
+    }
+
+    if (idx < m_program_headers.size())
+        m_program_headers.resize(idx);
+
+    return m_program_headers.size();
+}
+
+//----------------------------------------------------------------------
+// ParseSectionHeaders
+//----------------------------------------------------------------------
+size_t
+ObjectFileELF64::ParseSectionHeaders()
+{
+    // We have already parsed the section headers
+    if (!m_section_headers.empty())
+        return m_section_headers.size();
+
+    // If there are no section headers we are done.
+    if (m_header.e_shnum == 0)
+        return 0;
+
+    m_section_headers.resize(m_header.e_shnum);
+    if (m_section_headers.size() != m_header.e_shnum)
+        return 0;
+    
+    const size_t sh_size = m_header.e_shnum * m_header.e_shentsize;
+    const Elf64_Off sh_offset = m_offset + m_header.e_shoff;
+    DataBufferSP sh_buffer(m_file.ReadFileContents(sh_offset, sh_size));
+    
+    if (!sh_buffer.get() || sh_buffer->GetByteSize() != sh_size)
+        return 0;
+    
+    DataExtractor data(sh_buffer,
+                       m_data.GetByteOrder(), 
+                       m_data.GetAddressByteSize());
+    
+    uint32_t idx;
+    uint32_t offset;
+    for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx) 
+    {
+        // Read sh_name and sh_type.
+        if (!data.GetU32(&offset, &m_section_headers[idx].sh_name, 2))
+            break;
+
+        // Read sh_flags, sh_addr, sh_offset and sh_size.
+        if (!data.GetU64(&offset, &m_section_headers[idx].sh_flags, 4))
+            break;
+
+        // Read sh_link and sh_info.
+        if (!data.GetU32(&offset, &m_section_headers[idx].sh_link, 2))
+            break;
+
+        // Read sh_addralign and sh_entsize.
+        if (!data.GetU64(&offset, &m_section_headers[idx].sh_addralign, 2))
+            break;
+    }
+    if (idx < m_section_headers.size())
+        m_section_headers.resize(idx);
+    
+    return m_section_headers.size();
+}
+
+size_t
+ObjectFileELF64::GetSectionHeaderStringTable() 
+{
+    if (m_shstr_data.GetByteSize() == 0) 
+    {
+        if (m_header.e_shstrndx && 
+            m_header.e_shstrndx < m_section_headers.size()) 
+        {
+            const Elf64_Shdr &sheader = m_section_headers[m_header.e_shstrndx];
+            const size_t byte_size = sheader.sh_size;
+            const Elf64_Off offset = m_offset + sheader.sh_offset;
+
+            DataBufferSP buffer_sp(m_file.ReadFileContents(offset, byte_size));
+            
+            if (!buffer_sp.get() || buffer_sp->GetByteSize() != byte_size)
+                return 0;
+
+            m_shstr_data.SetData(buffer_sp);
+        }
+    }
+    return m_shstr_data.GetByteSize();
+}
+
+uint32_t
+ObjectFileELF64::GetSectionIndexByName(const char *name)
+{
+    if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
+        return UINT32_MAX;
+
+    // Search the collection of section headers for one with a matching name.
+    for (SectionHeaderCollIter I = m_section_headers.begin();
+         I != m_section_headers.end(); ++I) 
+    {
+        const char *sectionName = m_shstr_data.PeekCStr(I->sh_name);
+
+        if (!sectionName)
+            return UINT32_MAX;
+
+        if (strcmp(name, sectionName) != 0)
+            continue;
+
+        return SectionIndex(I);
+    }
+
+    return UINT32_MAX;
+}
+
+SectionList *ObjectFileELF64::GetSectionList()
+{
+    if (m_sections_ap.get())
+        return m_sections_ap.get();
+
+    if (ParseSectionHeaders() && GetSectionHeaderStringTable()) 
+    {
+        m_sections_ap.reset(new SectionList());
+
+        for (SectionHeaderCollIter I = m_section_headers.begin(); 
+             I != m_section_headers.end(); ++I) 
+        {
+            const Elf64_Shdr &header = *I;
+
+            ConstString name(m_shstr_data.PeekCStr(header.sh_name));
+            uint64_t size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
+
+            SectionSP section(new Section(
+                0,                 // Parent section.
+                GetModule(),       // Module to which this section belongs.
+                SectionIndex(I),   // Section ID.
+                name,              // Section name.
+                eSectionTypeOther, // FIXME: Fill in as appropriate.
+                header.sh_addr,    // VM address.
+                header.sh_size,    // VM size in bytes of this section.
+                header.sh_offset,  // Offset of this section in the file.
+                size,              // Size of the section as found in the file.
+                header.sh_flags)); // Flags for this section.
+
+            m_sections_ap->AddSection(section);
+        }
+    }
+
+    return m_sections_ap.get();
+}
+
+static void
+ParseSymbols(Symtab *symtab, SectionList *section_list, 
+             const Elf64_Shdr &symtab_shdr,
+             const DataExtractor &symtab_data, 
+             const DataExtractor &strtab_data)
+{
+    assert (sizeof(Elf64_Sym) == symtab_shdr.sh_entsize);
+
+    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");
+
+    Elf64_Sym symbol;
+    const unsigned numSymbols = symtab_data.GetByteSize() / sizeof(Elf64_Sym);
+    unsigned offset = 0;
+
+    for (unsigned i = 0; i < numSymbols; ++i) 
+    {
+        if (!symtab_data.ValidOffsetForDataOfSize(offset, sizeof(Elf64_Sym)))
+            break;
+
+        symbol.st_name  = 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);
+        symbol.st_value = symtab_data.GetU64(&offset);
+        symbol.st_size  = symtab_data.GetU64(&offset);
+
+        Section *symbol_section = 0;
+        SymbolType symbol_type = eSymbolTypeInvalid;
+        Elf64_Half symbol_index = symbol.st_shndx;
+
+        switch (symbol_index) 
+        {
+        default:
+            symbol_section = section_list->GetSectionAtIndex(symbol_index).get();
+            break;
+
+        case SHN_ABS:
+            symbol_type = eSymbolTypeAbsolute;
+            break;
+
+        case SHN_UNDEF:
+            symbol_type = eSymbolTypeUndefined;
+            break;
+        }
+
+        switch (ELF_ST_TYPE(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)
+            symbol_value -= symbol_section->GetFileAddress();
+
+        const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
+        bool is_global = ELF_ST_BIND(symbol.st_info) == STB_GLOBAL;
+        uint32_t flags = symbol.st_other << 8 | symbol.st_info;
+
+        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
+            is_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 in which this symbol is defined or null.
+            symbol_value,    // Offset in section or symbol value.
+            symbol.st_size,  // size in bytes of this symbol.
+            flags);          // Symbol flags.
+
+        symtab->AddSymbol(dc_symbol);
+    }
+}
+
+void
+ObjectFileELF64::ParseSymbolTable(Symtab *symbol_table, 
+                                  const Elf64_Shdr &symtab_hdr, 
+                                  user_id_t symtab_id) 
+{
+    assert(symtab_hdr.sh_type == SHT_SYMTAB || symtab_hdr.sh_type == SHT_DYNSYM);
+
+    // Parse in the section list if needed.
+    SectionList *section_list = GetSectionList();
+    if (!section_list)
+        return;
+
+    // Section ID's are ones based.
+    user_id_t strtab_id = symtab_hdr.sh_link + 1;
+
+    Section *symtab = section_list->FindSectionByID(symtab_id).get();
+    Section *strtab = section_list->FindSectionByID(strtab_id).get();
+    if (symtab && strtab) 
+    {
+        DataExtractor symtab_data;
+        DataExtractor strtab_data;
+        if (symtab->ReadSectionDataFromObjectFile(this, symtab_data) &&
+            strtab->ReadSectionDataFromObjectFile(this, strtab_data)) 
+        {
+            ParseSymbols(symbol_table, section_list, symtab_hdr, 
+                         symtab_data, strtab_data);
+        }
+    }
+}
+
+Symtab *
+ObjectFileELF64::GetSymtab()
+{
+    if (m_symtab_ap.get())
+        return m_symtab_ap.get();
+
+    Symtab *symbol_table = new Symtab(this);
+    m_symtab_ap.reset(symbol_table);
+    
+    if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
+        return symbol_table;
+    
+    // Locate and parse all linker symbol tables.
+    for (SectionHeaderCollIter I = m_section_headers.begin();
+         I != m_section_headers.end(); ++I) 
+    {
+        if (I->sh_type == SHT_SYMTAB || I->sh_type == SHT_DYNSYM)
+        {
+            const Elf64_Shdr &symtab_section = *I;
+            user_id_t section_id = SectionIndex(I);
+            ParseSymbolTable(symbol_table, symtab_section, section_id);
+        }
+    }
+
+    return symbol_table;
+}
+
+//===----------------------------------------------------------------------===//
+// Dump
+//
+// Dump the specifics of the runtime file container (such as any headers
+// segments, sections, etc).
+// ----------------------------------------------------------------------
+void 
+ObjectFileELF64::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();
+    DumpDependentModules(s);
+    s->EOL();
+}
+
+//----------------------------------------------------------------------
+// DumpELFHeader
+//
+// Dump the ELF header to the specified output stream
+//----------------------------------------------------------------------
+void
+ObjectFileELF64::DumpELFHeader(Stream *s, const Elf64_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
+ObjectFileELF64::DumpELFHeader_e_type(Stream *s, Elf64_Half 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 
+ObjectFileELF64::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char 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
+ObjectFileELF64::DumpELFProgramHeader(Stream *s, const Elf64_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
+ObjectFileELF64::DumpELFProgramHeader_p_type(Stream *s, Elf64_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 
+ObjectFileELF64::DumpELFProgramHeader_p_flags(Stream *s, Elf64_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
+ObjectFileELF64::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;
+        for (ProgramHeaderCollConstIter I = m_program_headers.begin();
+             I != m_program_headers.end(); ++I, ++idx) 
+        {
+            s->Printf("[%2u] ", idx);
+            ObjectFileELF64::DumpELFProgramHeader(s, *I);
+            s->EOL();
+        }
+    }
+}
+
+//----------------------------------------------------------------------
+// DumpELFSectionHeader
+//
+// Dump a single ELF section header to the specified output stream
+//----------------------------------------------------------------------
+void
+ObjectFileELF64::DumpELFSectionHeader(Stream *s, const Elf64_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
+ObjectFileELF64::DumpELFSectionHeader_sh_type(Stream *s, Elf64_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
+ObjectFileELF64::DumpELFSectionHeader_sh_flags(Stream *s, Elf64_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
+ObjectFileELF64::DumpELFSectionHeaders(Stream *s)
+{
+    if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
+        return;
+
+    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;
+    for (SectionHeaderCollConstIter I = m_section_headers.begin(); 
+         I != m_section_headers.end(); ++I, ++idx) 
+    {
+        s->Printf("[%2u] ", idx);
+        ObjectFileELF64::DumpELFSectionHeader(s, *I);
+        const char* section_name = m_shstr_data.PeekCStr(I->sh_name);
+        if (section_name)
+            *s << ' ' << section_name << "\n";
+    }
+}
+
+void
+ObjectFileELF64::DumpDependentModules(lldb_private::Stream *s)
+{
+    FileSpecList files;
+    if (!GetDependentModules(files))
+        return;
+
+    s->PutCString("Dependent Modules:\n");
+    for (unsigned i = 0; i < files.GetSize(); ++i) {
+        const FileSpec &spec = files.GetFileSpecAtIndex(i);
+        s->Printf("   %s\n", spec.GetFilename().GetCString());
+    }
+}
+
+
+bool 
+ObjectFileELF64::GetTargetTriple(ConstString &target_triple) 
+{
+    static ConstString g_target_triple;
+
+    if (g_target_triple) 
+    {
+        target_triple = g_target_triple;
+        return true;
+    }
+
+    std::string triple;
+    switch (m_header.e_machine) 
+    {
+    default:
+        assert(false && "Unexpected machine type.");
+        break;
+    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;
+    case EM_X86_64: triple.assign("x86_64-"); break;
+    }
+    
+    // TODO: determine if there is a vendor in the ELF? Default to "linux" for now
+    triple += "linux-";
+
+    // TODO: determine if there is an OS in the ELF? Default to "gnu" for now
+    triple += "gnu";
+    g_target_triple.SetCString(triple.c_str());
+    target_triple = g_target_triple;
+
+    return true;
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+const char *
+ObjectFileELF64::GetPluginName()
+{
+    return "ObjectFileELF64";
+}
+
+const char *
+ObjectFileELF64::GetShortPluginName()
+{
+    return GetPluginNameStatic();
+}
+
+uint32_t
+ObjectFileELF64::GetPluginVersion()
+{
+    return 1;
+}
+
+void 
+ObjectFileELF64::GetPluginCommandHelp (const char *command, Stream *strm)
+{
+}
+
+Error 
+ObjectFileELF64::ExecutePluginCommand (Args &command, Stream *strm)
+{
+    Error error;
+    error.SetErrorString("No plug-in commands are currently supported.");
+    return error;
+}
+
+Log *
+ObjectFileELF64::EnablePluginLogging (Stream *strm, Args &command)
+{
+    return 0;
+}
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF64.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF64.h
new file mode 100644
index 0000000..808e214
--- /dev/null
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF64.h
@@ -0,0 +1,201 @@
+//===-- ObjectFileELF64.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_ObjectFileELF64_h_
+#define liblldb_ObjectFileELF64_h_
+
+#include <stdint.h>
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/FileSpec.h"
+#include "lldb/Symbol/ObjectFile.h"
+
+#include "elf.h"
+
+class ObjectFileELF64 : 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
+    //------------------------------------------------------------------
+    ObjectFileELF64(lldb_private::Module* module,
+                    lldb::DataBufferSP& dataSP,
+                    const lldb_private::FileSpec* file,
+                    lldb::addr_t offset,
+                    lldb::addr_t length);
+
+    ~ObjectFileELF64();
+
+    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<Elf64_Phdr>             ProgramHeaderColl;
+    typedef ProgramHeaderColl::iterator         ProgramHeaderCollIter;
+    typedef ProgramHeaderColl::const_iterator   ProgramHeaderCollConstIter;
+
+    typedef std::vector<Elf64_Shdr>             SectionHeaderColl;
+    typedef SectionHeaderColl::iterator         SectionHeaderCollIter;
+    typedef SectionHeaderColl::const_iterator   SectionHeaderCollConstIter;
+
+    Elf64_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;
+    mutable std::auto_ptr<lldb_private::FileSpecList> m_filespec_ap;
+    lldb_private::DataExtractor m_shstr_data;
+
+    size_t ParseSections();
+
+    size_t ParseSymtab(bool minimize);
+
+private:
+    // Returns the 1 based index of a section header.
+    unsigned
+    SectionIndex(const SectionHeaderCollIter &I);
+
+    unsigned
+    SectionIndex(const SectionHeaderCollConstIter &I) const;
+
+    // ELF header dump routines
+    static void
+    DumpELFHeader(lldb_private::Stream *s, const Elf64_Ehdr& header);
+
+    static void
+    DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s, 
+                                  unsigned char ei_data);
+
+    static void
+    DumpELFHeader_e_type(lldb_private::Stream *s, Elf64_Half e_type);
+
+    // ELF program header dump routines
+    void
+    DumpELFProgramHeaders(lldb_private::Stream *s);
+
+    static void
+    DumpELFProgramHeader(lldb_private::Stream *s, const Elf64_Phdr &ph);
+
+    static void
+    DumpELFProgramHeader_p_type(lldb_private::Stream *s, Elf64_Word p_type);
+
+    static void
+    DumpELFProgramHeader_p_flags(lldb_private::Stream *s, Elf64_Word p_flags);
+
+    // ELF section header dump routines
+    void
+    DumpELFSectionHeaders(lldb_private::Stream *s);
+
+    static void
+    DumpELFSectionHeader(lldb_private::Stream *s, const Elf64_Shdr& sh);
+
+    static void
+    DumpELFSectionHeader_sh_type(lldb_private::Stream *s, Elf64_Word sh_type);
+
+    static void
+    DumpELFSectionHeader_sh_flags(lldb_private::Stream *s, Elf64_Word sh_flags);
+
+    void
+    DumpDependentModules(lldb_private::Stream *s);
+
+    size_t
+    ParseProgramHeaders();
+
+    size_t
+    ParseSectionHeaders();
+
+    size_t
+    ParseDependentModules();
+
+    void
+    ParseSymbolTable(lldb_private::Symtab *symbol_table, 
+                     const Elf64_Shdr &symtab_section,
+                     lldb::user_id_t symtab_id);
+
+    size_t
+    GetSectionHeaderStringTable();
+
+    uint32_t
+    GetSectionIndexByName(const char *name);
+};
+
+#endif
diff --git a/source/Plugins/ObjectFile/ELF/elf.h b/source/Plugins/ObjectFile/ELF/elf.h
index 9d08119..047632c 100644
--- a/source/Plugins/ObjectFile/ELF/elf.h
+++ b/source/Plugins/ObjectFile/ELF/elf.h
@@ -10,17 +10,28 @@
 #ifndef __elf_h__
 #define __elf_h__
 
+//----------------------------------------------------------------------
+// Typedefs for ELF32.
 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;
 
+//----------------------------------------------------------------------
+// Typedefs for ELF64.
+typedef uint16_t    Elf64_Half;
+typedef uint32_t    Elf64_Word;
+typedef int32_t     Elf64_Sword;
+typedef uint64_t    Elf64_Xword;
+typedef int64_t     Elf64_Sxword;
+typedef uint64_t    Elf64_Addr;
+typedef uint64_t    Elf64_Off;
 
 #define EI_NIDENT 16
 
 //----------------------------------------------------------------------
-// ELF Header
+// ELF Headers
 //----------------------------------------------------------------------
 typedef struct Elf32_Ehdr_Tag
 {
@@ -40,6 +51,25 @@ typedef struct Elf32_Ehdr_Tag
     Elf32_Half  e_shstrndx;
 } Elf32_Ehdr;
 
+typedef struct Elf64_Ehdr_Tag
+{
+    unsigned char e_ident[EI_NIDENT];
+    Elf64_Half  e_type;
+    Elf64_Half  e_machine;
+    Elf64_Word  e_version;
+    Elf64_Addr  e_entry;
+    Elf64_Off   e_phoff;
+    Elf64_Off   e_shoff;
+    Elf64_Word  e_flags;
+    Elf64_Half  e_ehsize;
+    Elf64_Half  e_phentsize;
+    Elf64_Half  e_phnum;
+    Elf64_Half  e_shentsize;
+    Elf64_Half  e_shnum;
+    Elf64_Half  e_shstrndx;
+} Elf64_Ehdr;
+
+
 //----------------------------------------------------------------------
 // e_type
 //
@@ -69,6 +99,7 @@ typedef struct Elf32_Ehdr_Tag
 #define EM_PPC      20  // PowerPC
 #define EM_PPC64    21  // PowerPC64
 #define EM_ARM      40  // ARM
+#define EM_X86_64   62  // AMD x86-64
 
 
 //----------------------------------------------------------------------
@@ -92,7 +123,7 @@ typedef struct Elf32_Ehdr_Tag
 #define ELFDATA2MSB 2   // Big Endian
 
 //----------------------------------------------------------------------
-// Section Header
+// Section Headers
 //----------------------------------------------------------------------
 typedef struct Elf32_Shdr_Tag
 {
@@ -108,6 +139,20 @@ typedef struct Elf32_Shdr_Tag
     Elf32_Word  sh_entsize;
 } Elf32_Shdr;
 
+typedef struct Elf64_Shdr_Tag
+{
+    Elf64_Word  sh_name;
+    Elf64_Word  sh_type;
+    Elf64_Xword sh_flags;
+    Elf64_Addr  sh_addr;
+    Elf64_Off   sh_offset;
+    Elf64_Xword sh_size;
+    Elf64_Word  sh_link;
+    Elf64_Word  sh_info;
+    Elf64_Xword sh_addralign;
+    Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+
 //----------------------------------------------------------------------
 // Section Types (sh_type)
 //----------------------------------------------------------------------
@@ -149,7 +194,7 @@ typedef struct Elf32_Shdr_Tag
 
 
 //----------------------------------------------------------------------
-// Symbol Table Entry Header
+// Symbol Table Entry Headers
 //----------------------------------------------------------------------
 typedef struct Elf32_Sym_Tag
 {
@@ -161,10 +206,22 @@ typedef struct Elf32_Sym_Tag
     Elf32_Half      st_shndx;
 } Elf32_Sym;
 
+typedef struct Elf64_Sym_Tag
+{
+    Elf64_Word      st_name;
+    unsigned char   st_info;
+    unsigned char   st_other;
+    Elf64_Half      st_shndx;
+    Elf64_Addr      st_value;
+    Elf64_Xword     st_size;
+} Elf64_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))
+// Accessors to the binding and type bits in the st_info field of a symbol table
+// entry.  Valid for both 32 and 64 bit variations.
+#define ELF_ST_BIND(i)    ((i)>>4)
+#define ELF_ST_TYPE(i)    ((i)&0xf)
+#define ELF_ST_INFO(b,t)  (((b)<<4)+((t)&0xf))
 
 // ST_BIND
 #define STB_LOCAL   0
@@ -199,10 +256,70 @@ typedef struct Elf32_Rela_Tag
     Elf32_Sword r_addend;
 } Elf32_Rela;
 
+typedef struct Elf64_Rel_Tag
+{
+    Elf64_Addr  r_offset;
+    Elf64_Word  r_info;
+} Elf64_Rel;
+
+typedef struct Elf64_Rela_Tag
+{
+    Elf64_Addr  r_offset;
+    Elf64_Word  r_info;
+    Elf64_Sword r_addend;
+} Elf64_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))
 
+//----------------------------------------------------------------------
+// Dynamic Table Entry Headers
+//----------------------------------------------------------------------
+typedef struct Elf64_Dyn_Tag
+{
+    Elf64_Sxword d_tag;
+    union
+    {
+        Elf64_Xword d_val;
+        Elf64_Addr  d_ptr;
+    } d_un;
+} Elf64_Dyn;
+
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_BIND_NOW 24
+#define DT_INIT_ARRAY 25
+#define DT_FINI_ARRAY 26
+#define DT_INIT_ARRAYSZ 27
+#define DT_FINI_ARRAYSZ 28
+#define DT_LOOS   0x60000000
+#define DT_HIOS   0x6FFFFFFF
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7FFFFFFF
+
 
 //----------------------------------------------------------------------
 // Program Headers
@@ -219,6 +336,18 @@ typedef struct Elf32_Phdr_Tag
     Elf32_Word  p_align;
 } Elf32_Phdr;
 
+typedef struct Elf64_Phdr_Tag
+{
+    Elf64_Word  p_type;
+    Elf64_Off   p_offset;
+    Elf64_Addr  p_vaddr;
+    Elf64_Addr  p_paddr;
+    Elf64_Word  p_filesz;
+    Elf64_Word  p_memsz;
+    Elf64_Word  p_flags;
+    Elf64_Word  p_align;
+} Elf64_Phdr;
+
 //----------------------------------------------------------------------
 // Program Header Type (p_type)
 //----------------------------------------------------------------------
diff --git a/source/lldb.cpp b/source/lldb.cpp
index 0a0ef93..5847a00 100644
--- a/source/lldb.cpp
+++ b/source/lldb.cpp
@@ -19,6 +19,7 @@
 #include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
 #include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+#include "Plugins/ObjectFile/ELF/ObjectFileELF64.h"
 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h"
 #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
@@ -55,6 +56,7 @@ lldb_private::Initialize ()
         DisassemblerLLVM::Initialize();
         ObjectContainerBSDArchive::Initialize();
         ObjectFileELF::Initialize();
+        ObjectFileELF64::Initialize();
         SymbolVendorMacOSX::Initialize();
         SymbolFileDWARF::Initialize();
         SymbolFileDWARFDebugMap::Initialize();
@@ -84,6 +86,7 @@ lldb_private::Terminate ()
     DisassemblerLLVM::Terminate();
     ObjectContainerBSDArchive::Terminate();
     ObjectFileELF::Terminate();
+    ObjectFileELF64::Terminate();
     SymbolVendorMacOSX::Terminate();
     SymbolFileDWARF::Terminate();
     SymbolFileDWARFDebugMap::Terminate();
_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to