• 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 ELFIO_UTILS_HPP
24 #define ELFIO_UTILS_HPP
25 
26 #include <cstdint>
27 #include <ostream>
28 
29 #define ELFIO_GET_ACCESS( TYPE, NAME, FIELD ) \
30     TYPE get_##NAME() const { return ( *convertor )( FIELD ); }
31 
32 #define ELFIO_SET_ACCESS( TYPE, NAME, FIELD ) \
33     void set_##NAME( TYPE value )             \
34     {                                         \
35         FIELD = value;                        \
36         FIELD = ( *convertor )( FIELD );      \
37     }
38 #define ELFIO_GET_SET_ACCESS( TYPE, NAME, FIELD )               \
39     TYPE get_##NAME() const { return ( *convertor )( FIELD ); } \
40     void set_##NAME( TYPE value )                               \
41     {                                                           \
42         FIELD = value;                                          \
43         FIELD = ( *convertor )( FIELD );                        \
44     }
45 
46 #define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) virtual TYPE get_##NAME() const = 0
47 
48 #define ELFIO_SET_ACCESS_DECL( TYPE, NAME ) \
49     virtual void set_##NAME( TYPE value ) = 0
50 
51 #define ELFIO_GET_SET_ACCESS_DECL( TYPE, NAME ) \
52     virtual TYPE get_##NAME() const       = 0;  \
53     virtual void set_##NAME( TYPE value ) = 0
54 
55 namespace ELFIO {
56 
57 //------------------------------------------------------------------------------
58 class endianess_convertor
59 {
60   public:
61     //------------------------------------------------------------------------------
endianess_convertor()62     endianess_convertor() { need_conversion = false; }
63 
64     //------------------------------------------------------------------------------
setup(unsigned char elf_file_encoding)65     void setup( unsigned char elf_file_encoding )
66     {
67         need_conversion = ( elf_file_encoding != get_host_encoding() );
68     }
69 
70     //------------------------------------------------------------------------------
operator ()(uint64_t value) const71     uint64_t operator()( uint64_t value ) const
72     {
73         if ( !need_conversion ) {
74             return value;
75         }
76         value = ( ( value & 0x00000000000000FFull ) << 56 ) |
77                 ( ( value & 0x000000000000FF00ull ) << 40 ) |
78                 ( ( value & 0x0000000000FF0000ull ) << 24 ) |
79                 ( ( value & 0x00000000FF000000ull ) << 8 ) |
80                 ( ( value & 0x000000FF00000000ull ) >> 8 ) |
81                 ( ( value & 0x0000FF0000000000ull ) >> 24 ) |
82                 ( ( value & 0x00FF000000000000ull ) >> 40 ) |
83                 ( ( value & 0xFF00000000000000ull ) >> 56 );
84 
85         return value;
86     }
87 
88     //------------------------------------------------------------------------------
operator ()(int64_t value) const89     int64_t operator()( int64_t value ) const
90     {
91         if ( !need_conversion ) {
92             return value;
93         }
94         return ( int64_t )( *this )( (uint64_t)value );
95     }
96 
97     //------------------------------------------------------------------------------
operator ()(uint32_t value) const98     uint32_t operator()( uint32_t value ) const
99     {
100         if ( !need_conversion ) {
101             return value;
102         }
103         value =
104             ( ( value & 0x000000FF ) << 24 ) | ( ( value & 0x0000FF00 ) << 8 ) |
105             ( ( value & 0x00FF0000 ) >> 8 ) | ( ( value & 0xFF000000 ) >> 24 );
106 
107         return value;
108     }
109 
110     //------------------------------------------------------------------------------
operator ()(int32_t value) const111     int32_t operator()( int32_t value ) const
112     {
113         if ( !need_conversion ) {
114             return value;
115         }
116         return ( int32_t )( *this )( (uint32_t)value );
117     }
118 
119     //------------------------------------------------------------------------------
operator ()(uint16_t value) const120     uint16_t operator()( uint16_t value ) const
121     {
122         if ( !need_conversion ) {
123             return value;
124         }
125         value = ( ( value & 0x00FF ) << 8 ) | ( ( value & 0xFF00 ) >> 8 );
126 
127         return value;
128     }
129 
130     //------------------------------------------------------------------------------
operator ()(int16_t value) const131     int16_t operator()( int16_t value ) const
132     {
133         if ( !need_conversion ) {
134             return value;
135         }
136         return ( int16_t )( *this )( (uint16_t)value );
137     }
138 
139     //------------------------------------------------------------------------------
operator ()(int8_t value) const140     int8_t operator()( int8_t value ) const { return value; }
141 
142     //------------------------------------------------------------------------------
operator ()(uint8_t value) const143     uint8_t operator()( uint8_t value ) const { return value; }
144 
145     //------------------------------------------------------------------------------
146   private:
147     //------------------------------------------------------------------------------
get_host_encoding() const148     unsigned char get_host_encoding() const
149     {
150         static const int tmp = 1;
151         if ( 1 == *(const char*)&tmp ) {
152             return ELFDATA2LSB;
153         }
154         else {
155             return ELFDATA2MSB;
156         }
157     }
158 
159     //------------------------------------------------------------------------------
160   private:
161     bool need_conversion;
162 };
163 
164 //------------------------------------------------------------------------------
elf_hash(const unsigned char * name)165 inline uint32_t elf_hash( const unsigned char* name )
166 {
167     uint32_t h = 0, g;
168     while ( *name ) {
169         h = ( h << 4 ) + *name++;
170         g = h & 0xf0000000;
171         if ( g != 0 )
172             h ^= g >> 24;
173         h &= ~g;
174     }
175     return h;
176 }
177 
to_hex_string(uint64_t value)178 inline std::string to_hex_string( uint64_t value )
179 {
180     std::string str;
181 
182     while ( value ) {
183         auto digit = value & 0xF;
184         if ( digit < 0xA )
185             str = char( '0' + digit ) + str;
186         else
187             str = char( 'A' + digit - 0xA ) + str;
188         value >>= 4;
189     }
190 
191     return "0x" + str;
192 }
193 
adjust_stream_size(std::ostream & stream,std::streamsize offset)194 inline void adjust_stream_size( std::ostream& stream, std::streamsize offset )
195 {
196     stream.seekp( 0, stream.end );
197     if ( stream.tellp() < offset ) {
198         std::streamsize size = offset - stream.tellp();
199         stream.write( std::string( size, '\0' ).c_str(), size );
200     }
201     stream.seekp( offset );
202 }
203 
204 } // namespace ELFIO
205 
206 #endif // ELFIO_UTILS_HPP
207