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: 33 virtual ~elf_header() = default; 34 35 virtual bool load( std::istream& stream ) = 0; 36 virtual bool save( std::ostream& stream ) const = 0; 37 38 // ELF header functions 39 ELFIO_GET_ACCESS_DECL( unsigned char, class ); 40 ELFIO_GET_ACCESS_DECL( unsigned char, elf_version ); 41 ELFIO_GET_ACCESS_DECL( unsigned char, encoding ); 42 ELFIO_GET_ACCESS_DECL( Elf_Half, header_size ); 43 ELFIO_GET_ACCESS_DECL( Elf_Half, section_entry_size ); 44 ELFIO_GET_ACCESS_DECL( Elf_Half, segment_entry_size ); 45 46 ELFIO_GET_SET_ACCESS_DECL( Elf_Word, version ); 47 ELFIO_GET_SET_ACCESS_DECL( unsigned char, os_abi ); 48 ELFIO_GET_SET_ACCESS_DECL( unsigned char, abi_version ); 49 ELFIO_GET_SET_ACCESS_DECL( Elf_Half, type ); 50 ELFIO_GET_SET_ACCESS_DECL( Elf_Half, machine ); 51 ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); 52 ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, entry ); 53 ELFIO_GET_SET_ACCESS_DECL( Elf_Half, sections_num ); 54 ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, sections_offset ); 55 ELFIO_GET_SET_ACCESS_DECL( Elf_Half, segments_num ); 56 ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, segments_offset ); 57 ELFIO_GET_SET_ACCESS_DECL( Elf_Half, section_name_str_index ); 58 }; 59 60 template <class T> struct elf_header_impl_types; 61 template <> struct elf_header_impl_types<Elf32_Ehdr> 62 { 63 using Phdr_type = Elf32_Phdr; 64 using Shdr_type = Elf32_Shdr; 65 static const unsigned char file_class = ELFCLASS32; 66 }; 67 template <> struct elf_header_impl_types<Elf64_Ehdr> 68 { 69 using Phdr_type = Elf64_Phdr; 70 using Shdr_type = Elf64_Shdr; 71 static const unsigned char file_class = ELFCLASS64; 72 }; 73 74 template <class T> class elf_header_impl : public elf_header 75 { 76 public: 77 //------------------------------------------------------------------------------ elf_header_impl(endianess_convertor * convertor,unsigned char encoding,const address_translator * translator)78 elf_header_impl( endianess_convertor* convertor, 79 unsigned char encoding, 80 const address_translator* translator ) 81 : convertor( convertor ), translator( translator ) 82 { 83 header.e_ident[EI_MAG0] = ELFMAG0; 84 header.e_ident[EI_MAG1] = ELFMAG1; 85 header.e_ident[EI_MAG2] = ELFMAG2; 86 header.e_ident[EI_MAG3] = ELFMAG3; 87 header.e_ident[EI_CLASS] = elf_header_impl_types<T>::file_class; 88 header.e_ident[EI_DATA] = encoding; 89 header.e_ident[EI_VERSION] = EV_CURRENT; 90 header.e_version = ( *convertor )( (Elf_Word)EV_CURRENT ); 91 header.e_ehsize = ( sizeof( header ) ); 92 header.e_ehsize = ( *convertor )( header.e_ehsize ); 93 header.e_shstrndx = ( *convertor )( (Elf_Half)1 ); 94 header.e_phentsize = 95 sizeof( typename elf_header_impl_types<T>::Phdr_type ); 96 header.e_shentsize = 97 sizeof( typename elf_header_impl_types<T>::Shdr_type ); 98 header.e_phentsize = ( *convertor )( header.e_phentsize ); 99 header.e_shentsize = ( *convertor )( header.e_shentsize ); 100 } 101 102 //------------------------------------------------------------------------------ load(std::istream & stream)103 bool load( std::istream& stream ) override 104 { 105 stream.seekg( ( *translator )[0] ); 106 stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) ); 107 108 return ( stream.gcount() == sizeof( header ) ); 109 } 110 111 //------------------------------------------------------------------------------ save(std::ostream & stream) const112 bool save( std::ostream& stream ) const override 113 { 114 stream.seekp( ( *translator )[0] ); 115 stream.write( reinterpret_cast<const char*>( &header ), 116 sizeof( header ) ); 117 118 return stream.good(); 119 } 120 121 //------------------------------------------------------------------------------ 122 // ELF header functions 123 ELFIO_GET_ACCESS( unsigned char, class, header.e_ident[EI_CLASS] ); 124 ELFIO_GET_ACCESS( unsigned char, elf_version, header.e_ident[EI_VERSION] ); 125 ELFIO_GET_ACCESS( unsigned char, encoding, header.e_ident[EI_DATA] ); 126 ELFIO_GET_ACCESS( Elf_Half, header_size, header.e_ehsize ); 127 ELFIO_GET_ACCESS( Elf_Half, section_entry_size, header.e_shentsize ); 128 ELFIO_GET_ACCESS( Elf_Half, segment_entry_size, header.e_phentsize ); 129 130 ELFIO_GET_SET_ACCESS( Elf_Word, version, header.e_version ); 131 ELFIO_GET_SET_ACCESS( unsigned char, os_abi, header.e_ident[EI_OSABI] ); 132 ELFIO_GET_SET_ACCESS( unsigned char, 133 abi_version, 134 header.e_ident[EI_ABIVERSION] ); 135 ELFIO_GET_SET_ACCESS( Elf_Half, type, header.e_type ); 136 ELFIO_GET_SET_ACCESS( Elf_Half, machine, header.e_machine ); 137 ELFIO_GET_SET_ACCESS( Elf_Word, flags, header.e_flags ); 138 ELFIO_GET_SET_ACCESS( Elf_Half, section_name_str_index, header.e_shstrndx ); 139 ELFIO_GET_SET_ACCESS( Elf64_Addr, entry, header.e_entry ); 140 ELFIO_GET_SET_ACCESS( Elf_Half, sections_num, header.e_shnum ); 141 ELFIO_GET_SET_ACCESS( Elf64_Off, sections_offset, header.e_shoff ); 142 ELFIO_GET_SET_ACCESS( Elf_Half, segments_num, header.e_phnum ); 143 ELFIO_GET_SET_ACCESS( Elf64_Off, segments_offset, header.e_phoff ); 144 145 private: 146 T header = {}; 147 endianess_convertor* convertor = nullptr; 148 const address_translator* translator = nullptr; 149 }; 150 151 } // namespace ELFIO 152 153 #endif // ELF_HEADER_HPP 154