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