• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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