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 #ifdef _MSC_VER
24 #define _SCL_SECURE_NO_WARNINGS
25 #define ELFIO_NO_INTTYPES
26 #endif
27
28 #include <gtest/gtest.h>
29 #include <elfio/elfio.hpp>
30
31 using namespace ELFIO;
32
33 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,modinfo_read)34 TEST( ELFIOTest, modinfo_read )
35 {
36 elfio reader;
37 ASSERT_EQ( reader.load( "elf_examples/zavl.ko" ), true );
38
39 section* modinfo_sec = reader.sections[".modinfo"];
40 ASSERT_NE( modinfo_sec, nullptr );
41
42 const_modinfo_section_accessor modinfo( modinfo_sec );
43 ASSERT_EQ( modinfo.get_attribute_num(), (Elf_Word)9 );
44
45 struct
46 {
47 std::string field;
48 std::string value;
49 } attributes[] = { { "version", "0.8.3-1ubuntu12.1" },
50 { "license", "CDDL" },
51 { "author", "OpenZFS on Linux" },
52 { "description", "Generic AVL tree implementation" },
53 { "srcversion", "98E85778E754CF75DEF9E8E" },
54 { "depends", "spl" },
55 { "retpoline", "Y" },
56 { "name", "zavl" },
57 { "vermagic", "5.4.0-42-generic SMP mod_unload " } };
58
59 for ( uint32_t i = 0; i < sizeof( attributes ) / sizeof( attributes[0] );
60 i++ ) {
61 std::string field;
62 std::string value;
63 modinfo.get_attribute( i, field, value );
64
65 EXPECT_EQ( field, attributes[i].field );
66 EXPECT_EQ( value, attributes[i].value );
67 }
68
69 for ( uint32_t i = 0; i < sizeof( attributes ) / sizeof( attributes[0] );
70 i++ ) {
71 std::string field = attributes[i].field;
72 std::string value;
73 modinfo.get_attribute( field, value );
74
75 EXPECT_EQ( value, attributes[i].value );
76 }
77 }
78
79 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,modinfo_write)80 TEST( ELFIOTest, modinfo_write )
81 {
82 elfio writer;
83 ASSERT_EQ( writer.load( "elf_examples/zavl.ko" ), true );
84
85 section* modinfo_sec = writer.sections[".modinfo"];
86 ASSERT_NE( modinfo_sec, nullptr );
87
88 modinfo_section_accessor modinfo( modinfo_sec );
89 ASSERT_EQ( modinfo.get_attribute_num(), (Elf_Word)9 );
90
91 modinfo.add_attribute( "test1", "value1" );
92 modinfo.add_attribute( "test2", "value2" );
93
94 ASSERT_EQ( modinfo.get_attribute_num(), (Elf_Word)11 );
95
96 ASSERT_EQ( writer.save( "elf_examples/zavl_gen.ko" ), true );
97
98 elfio reader;
99 ASSERT_EQ( reader.load( "elf_examples/zavl_gen.ko" ), true );
100
101 modinfo_sec = reader.sections[".modinfo"];
102 ASSERT_NE( modinfo_sec, nullptr );
103
104 const_modinfo_section_accessor modinfo1( modinfo_sec );
105 ASSERT_EQ( modinfo1.get_attribute_num(), (Elf_Word)11 );
106
107 struct
108 {
109 std::string field;
110 std::string value;
111 } attributes[] = { { "version", "0.8.3-1ubuntu12.1" },
112 { "license", "CDDL" },
113 { "author", "OpenZFS on Linux" },
114 { "description", "Generic AVL tree implementation" },
115 { "srcversion", "98E85778E754CF75DEF9E8E" },
116 { "depends", "spl" },
117 { "retpoline", "Y" },
118 { "name", "zavl" },
119 { "vermagic", "5.4.0-42-generic SMP mod_unload " },
120 { "test1", "value1" },
121 { "test2", "value2" } };
122
123 for ( uint32_t i = 0; i < sizeof( attributes ) / sizeof( attributes[0] );
124 i++ ) {
125 std::string field;
126 std::string value;
127 modinfo.get_attribute( i, field, value );
128
129 EXPECT_EQ( field, attributes[i].field );
130 EXPECT_EQ( value, attributes[i].value );
131 }
132
133 for ( uint32_t i = 0; i < sizeof( attributes ) / sizeof( attributes[0] );
134 i++ ) {
135 std::string field = attributes[i].field;
136 std::string value;
137 modinfo.get_attribute( field, value );
138
139 EXPECT_EQ( value, attributes[i].value );
140 }
141 }
142
143 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,array_read_32)144 TEST( ELFIOTest, array_read_32 )
145 {
146 elfio reader;
147 ASSERT_EQ( reader.load( "elf_examples/hello_32" ), true );
148
149 section* array_sec = reader.sections[".ctors"];
150 ASSERT_NE( array_sec, nullptr );
151
152 const_array_section_accessor<> array( reader, array_sec );
153 ASSERT_EQ( array.get_entries_num(), (Elf_Xword)2 );
154 Elf64_Addr addr;
155 EXPECT_EQ( array.get_entry( 0, addr ), true );
156 EXPECT_EQ( addr, 0xFFFFFFFF );
157 EXPECT_EQ( array.get_entry( 1, addr ), true );
158 EXPECT_EQ( addr, 0x00000000 );
159 }
160
161 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,array_read_64)162 TEST( ELFIOTest, array_read_64 )
163 {
164 elfio reader;
165 ASSERT_EQ( reader.load( "elf_examples/hello_64" ), true );
166
167 section* array_sec = reader.sections[".ctors"];
168 ASSERT_NE( array_sec, nullptr );
169
170 const_array_section_accessor<Elf64_Addr> array( reader, array_sec );
171 ASSERT_EQ( array.get_entries_num(), (Elf_Xword)2 );
172 Elf64_Addr addr;
173 EXPECT_EQ( array.get_entry( 0, addr ), true );
174 EXPECT_EQ( addr, 0xFFFFFFFFFFFFFFFF );
175 EXPECT_EQ( array.get_entry( 1, addr ), true );
176 EXPECT_EQ( addr, 0x0000000000000000 );
177 }
178
179 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,init_array_read_64)180 TEST( ELFIOTest, init_array_read_64 )
181 {
182 elfio reader;
183 Elf64_Addr addr;
184 ASSERT_EQ( reader.load( "elf_examples/ctors" ), true );
185
186 section* array_sec = reader.sections[".init_array"];
187 ASSERT_NE( array_sec, nullptr );
188
189 const_array_section_accessor<Elf64_Addr> array( reader, array_sec );
190 ASSERT_EQ( array.get_entries_num(), (Elf_Xword)2 );
191 EXPECT_EQ( array.get_entry( 0, addr ), true );
192 EXPECT_EQ( addr, 0x12C0 );
193 EXPECT_EQ( array.get_entry( 1, addr ), true );
194 EXPECT_EQ( addr, 0x149F );
195
196 array_sec = reader.sections[".fini_array"];
197 ASSERT_NE( array_sec, nullptr );
198
199 array_section_accessor<Elf64_Addr> arrayf( reader, array_sec );
200 ASSERT_EQ( arrayf.get_entries_num(), (Elf_Xword)1 );
201 EXPECT_EQ( arrayf.get_entry( 0, addr ), true );
202 EXPECT_EQ( addr, 0x1280 );
203 }
204
205 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,init_array_write_64)206 TEST( ELFIOTest, init_array_write_64 )
207 {
208 elfio reader;
209 Elf64_Addr addr;
210 ASSERT_EQ( reader.load( "elf_examples/ctors" ), true );
211
212 section* array_sec = reader.sections[".init_array"];
213 ASSERT_NE( array_sec, nullptr );
214
215 array_section_accessor<Elf64_Addr> array( reader, array_sec );
216 ASSERT_EQ( array.get_entries_num(), (Elf_Xword)2 );
217 EXPECT_EQ( array.get_entry( 0, addr ), true );
218 EXPECT_EQ( addr, 0x12C0 );
219 EXPECT_EQ( array.get_entry( 1, addr ), true );
220 EXPECT_EQ( addr, 0x149F );
221
222 array.add_entry( 0x12345678 );
223
224 ASSERT_EQ( array.get_entries_num(), (Elf_Xword)3 );
225 EXPECT_EQ( array.get_entry( 0, addr ), true );
226 EXPECT_EQ( addr, 0x12C0 );
227 EXPECT_EQ( array.get_entry( 1, addr ), true );
228 EXPECT_EQ( addr, 0x149F );
229 EXPECT_EQ( array.get_entry( 2, addr ), true );
230 EXPECT_EQ( addr, 0x12345678 );
231 }
232
233 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,test_hex)234 TEST( ELFIOTest, test_hex )
235 {
236 EXPECT_EQ( to_hex_string( 1 ), "0x1" );
237 EXPECT_EQ( to_hex_string( 10 ), "0xA" );
238 EXPECT_EQ( to_hex_string( 0x12345678 ), "0x12345678" );
239 EXPECT_EQ( to_hex_string( 0xFFFFFFFF ), "0xFFFFFFFF" );
240 EXPECT_EQ( to_hex_string( 0xFFFFFFFFFFFFFFFF ), "0xFFFFFFFFFFFFFFFF" );
241 }
242
243 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,hash32_le)244 TEST( ELFIOTest, hash32_le )
245 {
246 elfio reader;
247 // Load ELF data
248
249 ASSERT_EQ( reader.load( "elf_examples/ARMSCII-8.so" ), true );
250
251 std::string name;
252 Elf64_Addr value;
253 Elf_Xword size;
254 unsigned char bind;
255 unsigned char type;
256 Elf_Half section_index;
257 unsigned char other;
258 section* symsec = reader.sections[".dynsym"];
259 symbol_section_accessor syms( reader, symsec );
260
261 for ( Elf_Xword i = 0; i < syms.get_symbols_num(); i++ ) {
262 ASSERT_EQ( syms.get_symbol( i, name, value, size, bind, type,
263 section_index, other ),
264 true );
265 EXPECT_EQ( syms.get_symbol( name, value, size, bind, type,
266 section_index, other ),
267 true );
268 }
269 }
270
271 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,hash32_be)272 TEST( ELFIOTest, hash32_be )
273 {
274 elfio reader;
275 // Load ELF data
276
277 ASSERT_EQ( reader.load( "elf_examples/test_ppc" ), true );
278
279 std::string name;
280 Elf64_Addr value;
281 Elf_Xword size;
282 unsigned char bind;
283 unsigned char type;
284 Elf_Half section_index;
285 unsigned char other;
286 section* symsec = reader.sections[".dynsym"];
287 symbol_section_accessor syms( reader, symsec );
288
289 for ( Elf_Xword i = 0; i < syms.get_symbols_num(); i++ ) {
290 ASSERT_EQ( syms.get_symbol( i, name, value, size, bind, type,
291 section_index, other ),
292 true );
293 EXPECT_EQ( syms.get_symbol( name, value, size, bind, type,
294 section_index, other ),
295 true );
296 }
297 }
298
299 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,gnu_hash32_le)300 TEST( ELFIOTest, gnu_hash32_le )
301 {
302 elfio reader;
303 // Load ELF data
304
305 ASSERT_EQ( reader.load( "elf_examples/hello_32" ), true );
306
307 std::string name;
308 Elf64_Addr value;
309 Elf_Xword size;
310 unsigned char bind;
311 unsigned char type;
312 Elf_Half section_index;
313 unsigned char other;
314 section* symsec = reader.sections[".dynsym"];
315 symbol_section_accessor syms( reader, symsec );
316
317 for ( Elf_Xword i = 0; i < syms.get_symbols_num(); i++ ) {
318 ASSERT_EQ( syms.get_symbol( i, name, value, size, bind, type,
319 section_index, other ),
320 true );
321 EXPECT_EQ( syms.get_symbol( name, value, size, bind, type,
322 section_index, other ),
323 true );
324 }
325 }
326
327 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,gnu_hash64_le)328 TEST( ELFIOTest, gnu_hash64_le )
329 {
330 elfio reader;
331 // Load ELF data
332
333 ASSERT_EQ( reader.load( "elf_examples/main" ), true );
334
335 std::string name;
336 Elf64_Addr value;
337 Elf_Xword size;
338 unsigned char bind;
339 unsigned char type;
340 Elf_Half section_index;
341 unsigned char other;
342 section* symsec = reader.sections[".dynsym"];
343 symbol_section_accessor syms( reader, symsec );
344
345 for ( Elf_Xword i = 0; i < syms.get_symbols_num(); i++ ) {
346 ASSERT_EQ( syms.get_symbol( i, name, value, size, bind, type,
347 section_index, other ),
348 true );
349 EXPECT_EQ( syms.get_symbol( name, value, size, bind, type,
350 section_index, other ),
351 true );
352 }
353 }
354
355 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,gnu_version_64_le)356 TEST( ELFIOTest, gnu_version_64_le )
357 {
358 elfio reader;
359 // Load ELF data
360
361 ASSERT_EQ( reader.load( "elf_examples/hello_64" ), true );
362
363 std::string name;
364 Elf64_Addr value;
365 Elf_Xword size;
366 unsigned char bind;
367 unsigned char type;
368 Elf_Half section_index;
369 unsigned char other;
370
371 section* dynsym = reader.sections[".dynsym"];
372 const_symbol_section_accessor dynsym_acc( reader, dynsym );
373
374 section* gnu_version = reader.sections[".gnu.version"];
375 const_versym_section_accessor gnu_version_arr( gnu_version );
376
377 const section* gnu_version_r = reader.sections[".gnu.version_r"];
378 const_versym_r_section_accessor gnu_version_r_arr( reader, gnu_version_r );
379
380 section* dynstr = reader.sections[".dynstr"];
381
382 EXPECT_EQ( gnu_version->get_link(), dynsym->get_index() );
383 EXPECT_EQ( gnu_version_r->get_link(), dynstr->get_index() );
384
385 EXPECT_EQ( dynsym_acc.get_symbols_num(),
386 gnu_version_arr.get_entries_num() );
387
388 for ( Elf64_Word i = 0; i < dynsym_acc.get_symbols_num(); i++ ) {
389 ASSERT_EQ( dynsym_acc.get_symbol( i, name, value, size, bind, type,
390 section_index, other ),
391 true );
392
393 Elf64_Half verindex = 0;
394 gnu_version_arr.get_entry( i, verindex );
395 if ( i < 2 )
396 EXPECT_EQ( 0, verindex );
397 else
398 EXPECT_EQ( 2, verindex );
399 }
400
401 EXPECT_EQ( gnu_version_r_arr.get_entries_num(), 1 );
402
403 Elf_Half version;
404 std::string file_name;
405 Elf_Word hash;
406 Elf_Half flags;
407 Elf_Half vna_other;
408 std::string dep_name;
409 gnu_version_r_arr.get_entry( 0, version, file_name, hash, flags, vna_other,
410 dep_name );
411 EXPECT_EQ( version, 1 );
412 EXPECT_EQ( file_name, "libc.so.6" );
413 EXPECT_EQ( hash, 0x09691a75 );
414 EXPECT_EQ( flags, 0 );
415 EXPECT_EQ( vna_other, 2 );
416 EXPECT_EQ( dep_name, "GLIBC_2.2.5" );
417 }
418
419 ////////////////////////////////////////////////////////////////////////////////
420 // TEST( ELFIOTest, gnu_version_64_le_modify )
421 // {
422 // elfio reader;
423 // // Load ELF data
424
425 // ASSERT_EQ( reader.load( "elf_examples/hello_64" ), true );
426
427 // std::string name;
428 // Elf64_Addr value;
429 // Elf_Xword size;
430 // unsigned char bind;
431 // unsigned char type;
432 // Elf_Half section_index;
433 // unsigned char other;
434
435 // section* gnu_version = reader.sections[".gnu.version"];
436 // versym_section_accessor gnu_version_arr( gnu_version );
437
438 // section* gnu_version_r = reader.sections[".gnu.version_r"];
439 // versym_r_section_accessor gnu_version_r_arr( reader, gnu_version_r );
440
441 // auto orig_entries_num = gnu_version_arr.get_entries_num();
442 // Elf64_Word i = 0;
443 // for ( i = 0; i < orig_entries_num; i++ ) {
444 // gnu_version_arr.modify_entry( i, i + 10 );
445 // }
446 // gnu_version_arr.add_entry( i + 10 );
447 // gnu_version_arr.add_entry( i + 11 );
448 // EXPECT_EQ( orig_entries_num + 2,
449 // gnu_version_arr.get_entries_num() );
450
451 // for ( i = 0; i < gnu_version_arr.get_entries_num(); i++ ) {
452 // Elf_Half value;
453 // gnu_version_arr.get_entry( i, value );
454 // EXPECT_EQ( i + 10, value );
455 // }
456 // }
457
458 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,move_constructor_and_assignment)459 TEST( ELFIOTest, move_constructor_and_assignment )
460 {
461 elfio r1;
462
463 // Load ELF data
464 ASSERT_EQ( r1.load( "elf_examples/hello_64" ), true );
465 Elf64_Addr entry = r1.get_entry();
466 std::string sec_name = r1.sections[".text"]->get_name();
467 Elf_Xword seg_size = r1.segments[1]->get_memory_size();
468
469 // Move to a vector element
470 std::vector<elfio> v;
471 v.emplace_back( std::move( r1 ) );
472 EXPECT_EQ( v[0].get_entry(), entry );
473 EXPECT_EQ( v[0].sections[".text"]->get_name(), sec_name );
474 EXPECT_EQ( v[0].segments[1]->get_memory_size(), seg_size );
475
476 elfio r2;
477 r2 = std::move( v[0] );
478 EXPECT_EQ( r2.get_entry(), entry );
479 EXPECT_EQ( r2.sections[".text"]->get_name(), sec_name );
480 EXPECT_EQ( r2.segments[1]->get_memory_size(), seg_size );
481 }
482
TEST(ELFIOTest,address_translation_test)483 TEST( ELFIOTest, address_translation_test )
484 {
485 std::vector<address_translation> ranges;
486
487 ranges.emplace_back( 0, 100, 500 );
488 ranges.emplace_back( 500, 1000, 1000 );
489 ranges.emplace_back( 2000, 1000, 3000 );
490
491 address_translator tr;
492 tr.set_address_translation( ranges );
493
494 EXPECT_EQ( tr[0], 500 );
495 EXPECT_EQ( tr[510], 1010 );
496 EXPECT_EQ( tr[1710], 1710 );
497 EXPECT_EQ( tr[2710], 3710 );
498 EXPECT_EQ( tr[3710], 3710 );
499
500 ranges.clear();
501 tr.set_address_translation( ranges );
502
503 EXPECT_EQ( tr[0], 0 );
504 EXPECT_EQ( tr[510], 510 );
505 EXPECT_EQ( tr[1710], 1710 );
506 EXPECT_EQ( tr[2710], 2710 );
507 EXPECT_EQ( tr[3710], 3710 );
508 }
509