• 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:
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