diff -r 000000000000 -r 044383f39525 bintools/checklib/object/elf/elf_file_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bintools/checklib/object/elf/elf_file_header.cpp Tue Oct 27 16:36:35 2009 +0000 @@ -0,0 +1,182 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "elf_file_header.h" +#include +#include + + +namespace elf +{ + File_header::File_header(const char* p1, const char* p2, bool a_pedantic) + : m_data( reinterpret_cast(p1) ) + { + if ( p1 + sizeof(Elf32_Ehdr) > p2 ) + { + throw std::runtime_error("not an ELF object; file too small"); + } + + uint8_t m0 = m_data->e_ident[0]; + uint8_t m1 = m_data->e_ident[1]; + uint8_t m2 = m_data->e_ident[2]; + uint8_t m3 = m_data->e_ident[3]; + + if (m0 != 0x7f || m1 != 'E' || m2 != 'L' || m3 != 'F') + { + throw std::runtime_error("not an ELF object; bad magic"); + } + + if (a_pedantic) // Do some extra checks for correctness. + { + //if (m_data->e_ident[4] != 1) + //{ + // throw std::runtime_error("invalid class; this program can only handle 32-bit objects"); + //} + + //if (m_data->e_ident[5] != 1) + //{ + // throw std::runtime_error("invalid encoding; this program can only handle little-endian objects"); + //} + + //for (unsigned i = EI_PAD; i < sizeof(m_data->e_ident); ++i) + //{ + // if (m_data->e_ident[i] != 0) + // { + // throw std::runtime_error("non-zero pading"); + // } + //} + + //if (m_data->e_type == ET_NONE) + //{ + // throw std::runtime_error("invalid type"); + //} + + //if (m_data->e_phoff == 0 && m_data->e_shoff == 0) + //{ + // throw std::runtime_error("no program headers and no section headers"); + //} + + //if ( m_data->e_phoff + m_data->e_phentsize * m_data->e_phnum > p2 - p1 + 1 ) + //{ + // throw std::runtime_error("file too small for header table"); + //} + + //if (m_data->e_shoff + m_data->e_shentsize * m_data->e_shnum > a_mem.get_size() ) + //{ + // throw std::runtime_error("file too small for header table"); + //} + + //if ( m_data->e_shentsize != sizeof(Elf32_Shdr) ) + //{ + // throw std::runtime_error("e_shentsize doesn't match the actual size of the type"); + //} + + //if (m_data->e_shoff > 0 && m_data->e_shnum == 0) + //{ + // throw std::runtime_error("this program can't handle the combination e_shoff > 0 and e_shnum == 0"); + //} + + //if (m_data->e_shstrndx >= 0xff00) + //{ + // throw std::runtime_error("this program can only handle e_shstrndx < 0xff00"); + //} + + } // if (a_pedantic) + } + + // The following functions are obvious candidates for inlining ... + + // e_type + + bool File_header::is_type_rel() const + { + return (m_data->e_type == ET_REL); + } + bool File_header::is_type_exec() const + { + return (m_data->e_type == ET_EXEC); + } + bool File_header::is_type_dyn() const + { + return (m_data->e_type == ET_DYN); + } + + // e_machine + + bool File_header::is_machine_none() const + { + return (m_data->e_machine == EM_NONE); + } + bool File_header::is_machine_arm() const + { + return (m_data->e_machine == EM_ARM); + } + bool File_header::is_machine_386() const + { + return (m_data->e_machine == EM_386); + } + + uint32_t File_header::get_entry() const + { + return m_data->e_entry; + } + + uint32_t File_header::get_phoff() const + { + return m_data->e_phoff; + } + + uint32_t File_header::get_shoff() const + { + return m_data->e_shoff; + } + + uint32_t File_header::get_flags() const + { + return m_data->e_flags; + } + + uint16_t File_header::get_ehsize() const + { + return m_data->e_ehsize; + } + + uint16_t File_header::get_phentsize() const + { + return m_data->e_phentsize; + } + + uint16_t File_header::get_phnum() const + { + return m_data->e_phnum; + } + + uint16_t File_header::get_shentsize() const + { + return m_data->e_shentsize; + } + + uint16_t File_header::get_shnum() const + { + return m_data->e_shnum; + } + + uint16_t File_header::get_shstrndx() const + { + return m_data->e_shstrndx; + } + +} // namespace elf +