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 §_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