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