1 /* 2 Copyright (C) 2001-present by Serge Lamikhov-Center 3 4 Permission is hereby granted, free of charge, to any person obtaining a copy 5 of this software and associated documentation files (the "Software"), to deal 6 in the Software without restriction, including without limitation the rights 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 copies of the Software, and to permit persons to whom the Software is 9 furnished to do so, subject to the following conditions: 10 11 The above copyright notice and this permission notice shall be included in 12 all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 THE SOFTWARE. 21 */ 22 23 #ifndef ELF_HEADER_HPP 24 #define ELF_HEADER_HPP 25 26 #include <iostream> 27 28 namespace ELFIO { 29 30 class elf_header 31 { 32 public: ~elf_header()33 virtual ~elf_header(){}; 34 virtual bool load( std::istream& stream ) = 0; 35 virtual bool save( std::ostream& stream ) const = 0; 36 37 // ELF header functions 38 ELFIO_GET_ACCESS_DECL( unsigned char, class ); 39 ELFIO_GET_ACCESS_DECL( unsigned char, elf_version ); 40 ELFIO_GET_ACCESS_DECL( unsigned char, encoding ); 41 ELFIO_GET_ACCESS_DECL( Elf_Half, header_size ); 42 ELFIO_GET_ACCESS_DECL( Elf_Half, section_entry_size ); 43 ELFIO_GET_ACCESS_DECL( Elf_Half, segment_entry_size ); 44 45 ELFIO_GET_SET_ACCESS_DECL( Elf_Word, version ); 46 ELFIO_GET_SET_ACCESS_DECL( unsigned char, os_abi ); 47 ELFIO_GET_SET_ACCESS_DECL( unsigned char, abi_version ); 48 ELFIO_GET_SET_ACCESS_DECL( Elf_Half, type ); 49 ELFIO_GET_SET_ACCESS_DECL( Elf_Half, machine ); 50 ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); 51 ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, entry ); 52 ELFIO_GET_SET_ACCESS_DECL( Elf_Half, sections_num ); 53 ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, sections_offset ); 54 ELFIO_GET_SET_ACCESS_DECL( Elf_Half, segments_num ); 55 ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, segments_offset ); 56 ELFIO_GET_SET_ACCESS_DECL( Elf_Half, section_name_str_index ); 57 }; 58 59 template <class T> struct elf_header_impl_types; 60 template <> struct elf_header_impl_types<Elf32_Ehdr> 61 { 62 typedef Elf32_Phdr Phdr_type; 63 typedef Elf32_Shdr Shdr_type; 64 static const unsigned char file_class = ELFCLASS32; 65 }; 66 template <> struct elf_header_impl_types<Elf64_Ehdr> 67 { 68 typedef Elf64_Phdr Phdr_type; 69 typedef Elf64_Shdr Shdr_type; 70 static const unsigned char file_class = ELFCLASS64; 71 }; 72 73 template <class T> class elf_header_impl : public elf_header 74 { 75 public: 76 //------------------------------------------------------------------------------ elf_header_impl(endianess_convertor * convertor,unsigned char encoding)77 elf_header_impl( endianess_convertor* convertor, unsigned char encoding ) 78 { 79 this->convertor = convertor; 80 81 std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), 82 '\0' ); 83 84 header.e_ident[EI_MAG0] = ELFMAG0; 85 header.e_ident[EI_MAG1] = ELFMAG1; 86 header.e_ident[EI_MAG2] = ELFMAG2; 87 header.e_ident[EI_MAG3] = ELFMAG3; 88 header.e_ident[EI_CLASS] = elf_header_impl_types<T>::file_class; 89 header.e_ident[EI_DATA] = encoding; 90 header.e_ident[EI_VERSION] = EV_CURRENT; 91 header.e_version = ( *convertor )( (Elf_Word)EV_CURRENT ); 92 header.e_ehsize = ( sizeof( header ) ); 93 header.e_ehsize = ( *convertor )( header.e_ehsize ); 94 header.e_shstrndx = ( *convertor )( (Elf_Half)1 ); 95 header.e_phentsize = 96 sizeof( typename elf_header_impl_types<T>::Phdr_type ); 97 header.e_shentsize = 98 sizeof( typename elf_header_impl_types<T>::Shdr_type ); 99 header.e_phentsize = ( *convertor )( header.e_phentsize ); 100 header.e_shentsize = ( *convertor )( header.e_shentsize ); 101 } 102 103 //------------------------------------------------------------------------------ load(std::istream & stream)104 bool load( std::istream& stream ) 105 { 106 stream.seekg( 0 ); 107 stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) ); 108 109 return ( stream.gcount() == sizeof( header ) ); 110 } 111 112 //------------------------------------------------------------------------------ save(std::ostream & stream) const113 bool save( std::ostream& stream ) const 114 { 115 stream.seekp( 0 ); 116 stream.write( reinterpret_cast<const char*>( &header ), 117 sizeof( header ) ); 118 119 return stream.good(); 120 } 121 122 //------------------------------------------------------------------------------ 123 // ELF header functions 124 ELFIO_GET_ACCESS( unsigned char, class, header.e_ident[EI_CLASS] ); 125 ELFIO_GET_ACCESS( unsigned char, elf_version, header.e_ident[EI_VERSION] ); 126 ELFIO_GET_ACCESS( unsigned char, encoding, header.e_ident[EI_DATA] ); 127 ELFIO_GET_ACCESS( Elf_Half, header_size, header.e_ehsize ); 128 ELFIO_GET_ACCESS( Elf_Half, section_entry_size, header.e_shentsize ); 129 ELFIO_GET_ACCESS( Elf_Half, segment_entry_size, header.e_phentsize ); 130 131 ELFIO_GET_SET_ACCESS( Elf_Word, version, header.e_version ); 132 ELFIO_GET_SET_ACCESS( unsigned char, os_abi, header.e_ident[EI_OSABI] ); 133 ELFIO_GET_SET_ACCESS( unsigned char, 134 abi_version, 135 header.e_ident[EI_ABIVERSION] ); 136 ELFIO_GET_SET_ACCESS( Elf_Half, type, header.e_type ); 137 ELFIO_GET_SET_ACCESS( Elf_Half, machine, header.e_machine ); 138 ELFIO_GET_SET_ACCESS( Elf_Word, flags, header.e_flags ); 139 ELFIO_GET_SET_ACCESS( Elf_Half, section_name_str_index, header.e_shstrndx ); 140 ELFIO_GET_SET_ACCESS( Elf64_Addr, entry, header.e_entry ); 141 ELFIO_GET_SET_ACCESS( Elf_Half, sections_num, header.e_shnum ); 142 ELFIO_GET_SET_ACCESS( Elf64_Off, sections_offset, header.e_shoff ); 143 ELFIO_GET_SET_ACCESS( Elf_Half, segments_num, header.e_phnum ); 144 ELFIO_GET_SET_ACCESS( Elf64_Off, segments_offset, header.e_phoff ); 145 146 private: 147 T header; 148 endianess_convertor* convertor; 149 }; 150 151 } // namespace ELFIO 152 153 #endif // ELF_HEADER_HPP 154