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 #endif
26
27 #include <gtest/gtest.h>
28
29 #include <elfio/elfio.hpp>
30 #include <elfio/elfio_utils.hpp>
31
32 using namespace ELFIO;
33
34 ////////////////////////////////////////////////////////////////////////////////
checkHeader(const elfio & reader,unsigned char nClass,unsigned char encoding,unsigned char elfVersion,Elf_Half type,Elf_Half machine,Elf_Word version,Elf64_Addr entry,Elf_Word flags,Elf_Half secNum,Elf_Half segNum,unsigned char OSABI,unsigned char ABIVersion)35 void checkHeader( const elfio& reader,
36 unsigned char nClass,
37 unsigned char encoding,
38 unsigned char elfVersion,
39 Elf_Half type,
40 Elf_Half machine,
41 Elf_Word version,
42 Elf64_Addr entry,
43 Elf_Word flags,
44 Elf_Half secNum,
45 Elf_Half segNum,
46 unsigned char OSABI,
47 unsigned char ABIVersion )
48 {
49 EXPECT_EQ( reader.get_class(), nClass );
50 EXPECT_EQ( reader.get_encoding(), encoding );
51 EXPECT_EQ( reader.get_elf_version(), elfVersion );
52 EXPECT_EQ( reader.get_os_abi(), OSABI );
53 EXPECT_EQ( reader.get_abi_version(), ABIVersion );
54 EXPECT_EQ( reader.get_type(), type );
55 EXPECT_EQ( reader.get_machine(), machine );
56 EXPECT_EQ( reader.get_version(), version );
57 EXPECT_EQ( reader.get_entry(), entry );
58 EXPECT_EQ( reader.get_flags(), flags );
59 EXPECT_EQ( reader.sections.size(), secNum );
60 EXPECT_EQ( reader.segments.size(), segNum );
61 }
62
63 ////////////////////////////////////////////////////////////////////////////////
checkSection(const section * sec,Elf_Half index,const std::string & name,Elf_Word type,Elf_Xword flags,Elf64_Addr address,Elf_Xword size,Elf_Word link,Elf_Word info,Elf_Xword addrAlign,Elf_Xword entrySize)64 void checkSection( const section* sec,
65 Elf_Half index,
66 const std::string& name,
67 Elf_Word type,
68 Elf_Xword flags,
69 Elf64_Addr address,
70 Elf_Xword size,
71 Elf_Word link,
72 Elf_Word info,
73 Elf_Xword addrAlign,
74 Elf_Xword entrySize )
75 {
76 EXPECT_EQ( sec->get_index(), index );
77 EXPECT_EQ( sec->get_name(), name );
78 EXPECT_EQ( sec->get_type(), type );
79 EXPECT_EQ( sec->get_flags(), flags );
80 EXPECT_EQ( sec->get_address(), address );
81 EXPECT_EQ( sec->get_size(), size );
82 EXPECT_EQ( sec->get_link(), link );
83 EXPECT_EQ( sec->get_info(), info );
84 EXPECT_EQ( sec->get_addr_align(), addrAlign );
85 EXPECT_EQ( sec->get_entry_size(), entrySize );
86 }
87
88 ////////////////////////////////////////////////////////////////////////////////
checkSection(const section * sec,const std::string & name,Elf_Word type,Elf_Xword flags,Elf64_Addr address,Elf_Xword size,Elf_Word link,Elf_Word info,Elf_Xword addrAlign,Elf_Xword entrySize)89 void checkSection( const section* sec,
90 const std::string& name,
91 Elf_Word type,
92 Elf_Xword flags,
93 Elf64_Addr address,
94 Elf_Xword size,
95 Elf_Word link,
96 Elf_Word info,
97 Elf_Xword addrAlign,
98 Elf_Xword entrySize )
99 {
100 checkSection( sec, sec->get_index(), name, type, flags, address, size, link,
101 info, addrAlign, entrySize );
102 }
103
104 ////////////////////////////////////////////////////////////////////////////////
checkSegment(const segment * seg,Elf_Word type,Elf64_Addr vaddr,Elf64_Addr paddr,Elf_Xword fsize,Elf_Xword msize,Elf_Word flags,Elf_Xword align)105 void checkSegment( const segment* seg,
106 Elf_Word type,
107 Elf64_Addr vaddr,
108 Elf64_Addr paddr,
109 Elf_Xword fsize,
110 Elf_Xword msize,
111 Elf_Word flags,
112 Elf_Xword align )
113 {
114 EXPECT_EQ( seg->get_type(), type );
115 EXPECT_EQ( seg->get_virtual_address(), vaddr );
116 EXPECT_EQ( seg->get_physical_address(), paddr );
117 EXPECT_EQ( seg->get_file_size(), fsize );
118 EXPECT_EQ( seg->get_memory_size(), msize );
119 EXPECT_EQ( seg->get_flags(), flags );
120 EXPECT_EQ( seg->get_align(), align );
121 }
122
123 ////////////////////////////////////////////////////////////////////////////////
checkSymbol(const const_symbol_section_accessor & sr,Elf_Xword index,const std::string & name_,Elf64_Addr value_,Elf_Xword size_,unsigned char bind_,unsigned char type_,Elf_Half section_,unsigned char other_)124 void checkSymbol( const const_symbol_section_accessor& sr,
125 Elf_Xword index,
126 const std::string& name_,
127 Elf64_Addr value_,
128 Elf_Xword size_,
129 unsigned char bind_,
130 unsigned char type_,
131 Elf_Half section_,
132 unsigned char other_ )
133 {
134 std::string name;
135 Elf64_Addr value;
136 Elf_Xword size;
137 unsigned char bind;
138 unsigned char type;
139 Elf_Half section;
140 unsigned char other;
141
142 ASSERT_EQ(
143 sr.get_symbol( index, name, value, size, bind, type, section, other ),
144 true );
145 EXPECT_EQ( name, name_ );
146 EXPECT_EQ( value, value_ );
147 EXPECT_EQ( size, size_ );
148 EXPECT_EQ( bind, bind_ );
149 EXPECT_EQ( type, type_ );
150 EXPECT_EQ( section, section_ );
151 EXPECT_EQ( other, other_ );
152 }
153
154 ////////////////////////////////////////////////////////////////////////////////
checkRelocation(const const_relocation_section_accessor * pRT,Elf_Xword index,Elf64_Addr offset_,Elf64_Addr symbolValue_,const std::string & symbolName_,unsigned char type_,Elf_Sxword addend_,Elf_Sxword calcValue_)155 void checkRelocation( const const_relocation_section_accessor* pRT,
156 Elf_Xword index,
157 Elf64_Addr offset_,
158 Elf64_Addr symbolValue_,
159 const std::string& symbolName_,
160 unsigned char type_,
161 Elf_Sxword addend_,
162 Elf_Sxword calcValue_ )
163 {
164 Elf64_Addr offset;
165 Elf64_Addr symbolValue;
166 std::string symbolName;
167 unsigned type;
168 Elf_Sxword addend;
169 Elf_Sxword calcValue;
170
171 ASSERT_EQ( pRT->get_entry( index, offset, symbolValue, symbolName, type,
172 addend, calcValue ),
173 true );
174 EXPECT_EQ( offset, offset_ );
175 EXPECT_EQ( symbolValue, symbolValue_ );
176 EXPECT_EQ( symbolName, symbolName_ );
177 EXPECT_EQ( type, type_ );
178 EXPECT_EQ( addend, addend_ );
179 EXPECT_EQ( calcValue, calcValue_ );
180 }
181
182 ////////////////////////////////////////////////////////////////////////////////
checkNote(const const_note_section_accessor & notes,Elf_Word index,Elf_Word type_,const std::string & name_,Elf_Word descSize_)183 void checkNote( const const_note_section_accessor& notes,
184 Elf_Word index,
185 Elf_Word type_,
186 const std::string& name_,
187 Elf_Word descSize_ )
188 {
189 Elf_Word type;
190 std::string name;
191 char* desc;
192 Elf_Word descSize;
193
194 ASSERT_EQ( notes.get_note( index, type, name, desc, descSize ), true );
195 EXPECT_EQ( type, type_ );
196 EXPECT_EQ( name, name_ );
197 EXPECT_EQ( descSize, descSize_ );
198 }
199
200 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,load32)201 TEST( ELFIOTest, load32 )
202 {
203 bool is_lazy = false;
204 do {
205 is_lazy = !is_lazy;
206 elfio reader;
207 ASSERT_EQ( reader.load( "elf_examples/hello_32", is_lazy ), true );
208 checkHeader( reader, ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ET_EXEC,
209 EM_386, 1, 0x80482b0, 0, 28, 7, 0, 0 );
210
211 ////////////////////////////////////////////////////////////////////////////
212 // Check sections
213 const section* sec = reader.sections[0];
214 checkSection( sec, 0, "", SHT_NULL, 0, 0, 0, 0, 0, 0, 0 );
215
216 sec = reader.sections[1];
217 checkSection( sec, 1, ".interp", SHT_PROGBITS, SHF_ALLOC, 0x08048114,
218 0x13, 0, 0, 1, 0 );
219
220 sec = reader.sections[9];
221 checkSection( sec, 9, ".rel.plt", SHT_REL, SHF_ALLOC, 0x08048234, 0x18,
222 4, 11, 4, 8 );
223
224 sec = reader.sections[19];
225 checkSection( sec, 19, ".dynamic", SHT_DYNAMIC, SHF_WRITE | SHF_ALLOC,
226 0x080494a0, 0xc8, 5, 0, 4, 8 );
227
228 sec = reader.sections[27];
229 checkSection( sec, 27, ".strtab", SHT_STRTAB, 0, 0x0, 0x259, 0, 0, 1,
230 0 );
231
232 for ( Elf_Half i = 0; i < reader.sections.size(); ++i ) {
233 sec = reader.sections[i];
234 EXPECT_EQ( sec->get_index(), i );
235 }
236
237 const section* sec1 = reader.sections[".strtab"];
238 EXPECT_EQ( sec->get_index(), sec1->get_index() );
239
240 ////////////////////////////////////////////////////////////////////////////
241 // Check segments
242 const segment* seg = reader.segments[0];
243 checkSegment( seg, PT_PHDR, 0x08048034, 0x08048034, 0x000e0, 0x000e0,
244 PF_R + PF_X, 4 );
245
246 seg = reader.segments[4];
247 checkSegment( seg, PT_DYNAMIC, 0x080494a0, 0x080494a0, 0x000c8, 0x000c8,
248 PF_R + PF_W, 4 );
249
250 seg = reader.segments[6];
251 checkSegment( seg, 0x6474E551, 0x0, 0x0, 0x0, 0x0, PF_R + PF_W, 4 );
252
253 ////////////////////////////////////////////////////////////////////////////
254 // Check symbol table
255 sec = reader.sections[".symtab"];
256
257 const_symbol_section_accessor sr( reader, sec );
258
259 EXPECT_EQ( sr.get_symbols_num(), 68 );
260 checkSymbol( sr, 0, "", 0x00000000, 0, STB_LOCAL, STT_NOTYPE, STN_UNDEF,
261 ELF_ST_VISIBILITY( STV_DEFAULT ) );
262 checkSymbol( sr, 1, "", 0x08048114, 0, STB_LOCAL, STT_SECTION, 1,
263 ELF_ST_VISIBILITY( STV_DEFAULT ) );
264 checkSymbol( sr, 39, "hello.c", 0x00000000, 0, STB_LOCAL, STT_FILE,
265 SHN_ABS, ELF_ST_VISIBILITY( STV_DEFAULT ) );
266 checkSymbol( sr, 65, "__i686.get_pc_thunk.bx", 0x08048429, 0,
267 STB_GLOBAL, STT_FUNC, 12,
268 ELF_ST_VISIBILITY( STV_HIDDEN ) );
269 checkSymbol( sr, 66, "main", 0x08048384, 43, STB_GLOBAL, STT_FUNC, 12,
270 ELF_ST_VISIBILITY( STV_DEFAULT ) );
271 checkSymbol( sr, 67, "_init", 0x0804824c, 0, STB_GLOBAL, STT_FUNC, 10,
272 ELF_ST_VISIBILITY( STV_DEFAULT ) );
273
274 ////////////////////////////////////////////////////////////////////////////
275 // Check relocation table
276 sec = reader.sections[".rel.dyn"];
277
278 const_relocation_section_accessor reloc( reader, sec );
279 EXPECT_EQ( reloc.get_entries_num(), 1 );
280
281 checkRelocation( &reloc, 0, 0x08049568, 0x0, "__gmon_start__",
282 R_386_GLOB_DAT, 0, 0 );
283
284 sec = reader.sections[".rel.plt"];
285
286 const_relocation_section_accessor reloc1( reader, sec );
287 EXPECT_EQ( reloc1.get_entries_num(), 3 );
288
289 checkRelocation( &reloc1, 0, 0x08049578, 0x0, "__gmon_start__",
290 R_X86_64_JUMP_SLOT, 0, 0 );
291 checkRelocation( &reloc1, 1, 0x0804957c, 0x0, "__libc_start_main",
292 R_X86_64_JUMP_SLOT, 0, 0 );
293 checkRelocation( &reloc1, 2, 0x08049580, 0x0, "puts",
294 R_X86_64_JUMP_SLOT, 0, 0 );
295
296 ////////////////////////////////////////////////////////////////////////////
297 // Check note reader
298 sec = reader.sections[".note.ABI-tag"];
299
300 const_note_section_accessor notes( reader, sec );
301 EXPECT_EQ( notes.get_notes_num(), 1u );
302
303 checkNote( notes, 0, 1, std::string( "GNU" ), 16 );
304 } while ( is_lazy );
305 }
306
307 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,load64)308 TEST( ELFIOTest, load64 )
309 {
310 bool is_lazy = false;
311 do {
312 is_lazy = !is_lazy;
313 elfio reader;
314
315 ASSERT_EQ( reader.load( "elf_examples/hello_64", is_lazy ), true );
316
317 ////////////////////////////////////////////////////////////////////////////
318 // Check ELF header
319 checkHeader( reader, ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ET_EXEC,
320 EM_X86_64, 1, 0x4003c0, 0, 29, 8, 0, 0 );
321
322 ////////////////////////////////////////////////////////////////////////////
323 // Check sections
324 const section* sec = reader.sections[0];
325
326 checkSection( sec, 0, "", SHT_NULL, 0, 0, 0, 0, 0, 0, 0 );
327
328 sec = reader.sections[1];
329
330 checkSection( sec, 1, ".interp", SHT_PROGBITS, SHF_ALLOC,
331 0x0000000000400200, 0x1c, 0, 0, 1, 0 );
332
333 sec = reader.sections[9];
334
335 checkSection( sec, 9, ".rela.plt", SHT_RELA, SHF_ALLOC,
336 0x0000000000400340, 0x30, 4, 11, 8, 0x18 );
337
338 sec = reader.sections[20];
339
340 checkSection( sec, 20, ".dynamic", SHT_DYNAMIC, SHF_WRITE | SHF_ALLOC,
341 0x0000000000600698, 0x190, 5, 0, 8, 0x10 );
342
343 sec = reader.sections[28];
344
345 checkSection( sec, 28, ".strtab", SHT_STRTAB, 0, 0x0, 0x23f, 0, 0, 1,
346 0 );
347
348 const section* sec1 = reader.sections[".strtab"];
349 EXPECT_EQ( sec->get_index(), sec1->get_index() );
350
351 ////////////////////////////////////////////////////////////////////////////
352 // Check segments
353 const segment* seg = reader.segments[0];
354 checkSegment( seg, PT_PHDR, 0x0000000000400040, 0x0000000000400040,
355 0x00000000000001c0, 0x00000000000001c0, PF_R + PF_X, 8 );
356
357 seg = reader.segments[2];
358 checkSegment( seg, PT_LOAD, 0x0000000000400000, 0x0000000000400000,
359 0x000000000000066c, 0x000000000000066c, PF_R + PF_X,
360 0x200000 );
361
362 seg = reader.segments[7];
363 checkSegment( seg, 0x6474E551, 0x0, 0x0, 0x0, 0x0, PF_R + PF_W, 8 );
364
365 ////////////////////////////////////////////////////////////////////////////
366 // Check symbol table
367 sec = reader.sections[".symtab"];
368
369 const_symbol_section_accessor sr( reader, sec );
370
371 EXPECT_EQ( sr.get_symbols_num(), 67 );
372 checkSymbol( sr, 0, "", 0x00000000, 0, STB_LOCAL, STT_NOTYPE, STN_UNDEF,
373 ELF_ST_VISIBILITY( STV_DEFAULT ) );
374 checkSymbol( sr, 1, "", 0x00400200, 0, STB_LOCAL, STT_SECTION, 1,
375 ELF_ST_VISIBILITY( STV_DEFAULT ) );
376 checkSymbol( sr, 40, "hello.c", 0x00000000, 0, STB_LOCAL, STT_FILE,
377 SHN_ABS, ELF_ST_VISIBILITY( STV_DEFAULT ) );
378 checkSymbol( sr, 52, "__gmon_start__", 0x00000000, 0, STB_WEAK,
379 STT_NOTYPE, STN_UNDEF, ELF_ST_VISIBILITY( STV_DEFAULT ) );
380 checkSymbol( sr, 64, "_edata", 0x0060085c, 0, STB_GLOBAL, STT_NOTYPE,
381 SHN_ABS, ELF_ST_VISIBILITY( STV_DEFAULT ) );
382 checkSymbol( sr, 65, "main", 0x00400498, 21, STB_GLOBAL, STT_FUNC, 12,
383 ELF_ST_VISIBILITY( STV_DEFAULT ) );
384 checkSymbol( sr, 66, "_init", 0x00400370, 0, STB_GLOBAL, STT_FUNC, 10,
385 ELF_ST_VISIBILITY( STV_DEFAULT ) );
386
387 ////////////////////////////////////////////////////////////////////////////
388 // Check relocation table
389 sec = reader.sections[".rela.dyn"];
390
391 const_relocation_section_accessor reloc( reader, sec );
392 EXPECT_EQ( reloc.get_entries_num(), 1 );
393
394 checkRelocation( &reloc, 0, 0x00600828, 0x0, "__gmon_start__",
395 R_X86_64_GLOB_DAT, 0, 0 );
396
397 sec = reader.sections[".rela.plt"];
398
399 const_relocation_section_accessor reloc1( reader, sec );
400 EXPECT_EQ( reloc1.get_entries_num(), 2 );
401
402 checkRelocation( &reloc1, 0, 0x00600848, 0x0, "puts",
403 R_X86_64_JUMP_SLOT, 0, 0 );
404 checkRelocation( &reloc1, 1, 0x00600850, 0x0, "__libc_start_main",
405 R_X86_64_JUMP_SLOT, 0, 0 );
406
407 ////////////////////////////////////////////////////////////////////////////
408 // Check note reader
409 sec = reader.sections[".note.ABI-tag"];
410
411 const_note_section_accessor notes( reader, sec );
412 EXPECT_EQ( notes.get_notes_num(), 1u );
413
414 checkNote( notes, 0, 1, std::string( "GNU" ), 16 );
415 } while ( is_lazy );
416 }
417
418 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,hello_64_o)419 TEST( ELFIOTest, hello_64_o )
420 {
421 elfio reader;
422
423 ASSERT_EQ( reader.load( "elf_examples/hello_64.o" ), true );
424
425 ////////////////////////////////////////////////////////////////////////////
426 // Check ELF header
427 checkHeader( reader, ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ET_REL, EM_X86_64,
428 1, 0, 0, 13, 0, 0, 0 );
429
430 ////////////////////////////////////////////////////////////////////////////
431 // Check sections
432 const section* sec = reader.sections[0];
433
434 checkSection( sec, 0, "", SHT_NULL, 0, 0, 0, 0, 0, 0, 0 );
435
436 sec = reader.sections[1];
437
438 checkSection( sec, 1, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0,
439 0x15, 0, 0, 4, 0 );
440
441 const section* sec1 = reader.sections[".text"];
442 EXPECT_EQ( sec->get_index(), sec1->get_index() );
443
444 sec = reader.sections[12];
445 checkSection( sec, 12, ".strtab", SHT_STRTAB, 0, 0x0, 0x13, 0, 0, 1, 0 );
446
447 sec1 = reader.sections[".strtab"];
448 EXPECT_EQ( sec->get_index(), sec1->get_index() );
449
450 ////////////////////////////////////////////////////////////////////////////
451 // Check symbol table
452 sec = reader.sections[".symtab"];
453
454 const_symbol_section_accessor sr( reader, sec );
455
456 EXPECT_EQ( sr.get_symbols_num(), 11 );
457 checkSymbol( sr, 9, "main", 0x00000000, 21, STB_GLOBAL, STT_FUNC, 1,
458 ELF_ST_VISIBILITY( STV_DEFAULT ) );
459
460 ////////////////////////////////////////////////////////////////////////////
461 // Check relocation table
462 sec = reader.sections[".rela.text"];
463
464 const_relocation_section_accessor reloc( reader, sec );
465 EXPECT_EQ( reloc.get_entries_num(), 2 );
466
467 checkRelocation( &reloc, 0, 0x00000005, 0x0, "", R_X86_64_32, 0, 0 );
468 checkRelocation( &reloc, 1, 0x0000000A, 0x0, "puts", R_X86_64_PC32,
469 0xfffffffffffffffcULL, -14 );
470
471 sec = reader.sections[".rela.eh_frame"];
472
473 const_relocation_section_accessor reloc1( reader, sec );
474 EXPECT_EQ( reloc1.get_entries_num(), 1 );
475
476 checkRelocation( &reloc1, 0, 0x00000020, 0x0, "", R_X86_64_32, 0, 0 );
477 }
478
479 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,hello_32_o)480 TEST( ELFIOTest, hello_32_o )
481 {
482 elfio reader;
483
484 ASSERT_EQ( reader.load( "elf_examples/hello_32.o" ), true );
485
486 ////////////////////////////////////////////////////////////////////////////
487 // Check ELF header
488 checkHeader( reader, ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ET_REL, EM_386, 1,
489 0, 0, 11, 0, 0, 0 );
490
491 ////////////////////////////////////////////////////////////////////////////
492 // Check sections
493 const section* sec = reader.sections[0];
494
495 checkSection( sec, 0, "", SHT_NULL, 0, 0, 0, 0, 0, 0, 0 );
496
497 sec = reader.sections[1];
498
499 checkSection( sec, 1, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0,
500 0x2b, 0, 0, 4, 0 );
501
502 const section* sec1 = reader.sections[".text"];
503 EXPECT_EQ( sec->get_index(), sec1->get_index() );
504
505 sec = reader.sections[10];
506
507 checkSection( sec, 10, ".strtab", SHT_STRTAB, 0, 0x0, 0x13, 0, 0, 1, 0 );
508
509 sec1 = reader.sections[".strtab"];
510 EXPECT_EQ( sec->get_index(), sec1->get_index() );
511
512 ////////////////////////////////////////////////////////////////////////////
513 // Check symbol table
514 sec = reader.sections[".symtab"];
515
516 const_symbol_section_accessor sr( reader, sec );
517
518 EXPECT_EQ( sr.get_symbols_num(), 10 );
519 checkSymbol( sr, 8, "main", 0x00000000, 43, STB_GLOBAL, STT_FUNC, 1,
520 ELF_ST_VISIBILITY( STV_DEFAULT ) );
521
522 ////////////////////////////////////////////////////////////////////////////
523 // Check relocation table
524 sec = reader.sections[".rel.text"];
525
526 const_relocation_section_accessor reloc( reader, sec );
527 EXPECT_EQ( reloc.get_entries_num(), 2 );
528
529 checkRelocation( &reloc, 0, 0x00000014, 0x0, "", R_386_32, 0, 0 );
530 checkRelocation( &reloc, 1, 0x00000019, 0x0, "puts", R_386_PC32, 0x0, -25 );
531 }
532
533 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,test_ppc_o)534 TEST( ELFIOTest, test_ppc_o )
535 {
536 elfio reader;
537
538 ASSERT_EQ( reader.load( "elf_examples/test_ppc.o" ), true );
539
540 ////////////////////////////////////////////////////////////////////////////
541 // Check ELF header
542 checkHeader( reader, ELFCLASS32, ELFDATA2MSB, EV_CURRENT, ET_REL, EM_PPC, 1,
543 0, 0, 16, 0, 0, 0 );
544
545 ////////////////////////////////////////////////////////////////////////////
546 // Check sections
547 const section* sec = reader.sections[0];
548
549 checkSection( sec, 0, "", SHT_NULL, 0, 0, 0, 0, 0, 0, 0 );
550
551 sec = reader.sections[1];
552
553 checkSection( sec, 1, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0,
554 0x118, 0, 0, 4, 0 );
555
556 const section* sec1 = reader.sections[".text"];
557 EXPECT_EQ( sec->get_index(), sec1->get_index() );
558
559 sec = reader.sections[15];
560
561 checkSection( sec, 15, ".strtab", SHT_STRTAB, 0, 0x0, 0x14f, 0, 0, 1, 0 );
562
563 sec1 = reader.sections[".strtab"];
564 EXPECT_EQ( sec->get_index(), sec1->get_index() );
565
566 ////////////////////////////////////////////////////////////////////////////
567 // Check symbol table
568 sec = reader.sections[".symtab"];
569
570 const_symbol_section_accessor sr( reader, sec );
571
572 EXPECT_EQ( sr.get_symbols_num(), 24 );
573 checkSymbol( sr, 14, "main", 0x00000000, 92, STB_GLOBAL, STT_FUNC, 1,
574 ELF_ST_VISIBILITY( STV_DEFAULT ) );
575 checkSymbol( sr, 8, "_GLOBAL__I_main", 0x000000DC, 60, STB_LOCAL, STT_FUNC,
576 1, ELF_ST_VISIBILITY( STV_DEFAULT ) );
577
578 ////////////////////////////////////////////////////////////////////////////
579 // Check relocation table
580 sec = reader.sections[".rela.text"];
581
582 const_relocation_section_accessor reloc( reader, sec );
583 EXPECT_EQ( reloc.get_entries_num(), 18 );
584
585 checkRelocation( &reloc, 0, 0x00000016, 0x0, "_ZSt4cout", 6, 0, 0 );
586 checkRelocation( &reloc, 1, 0x0000001a, 0x0, "_ZSt4cout", 4, 0x0, 0 );
587 checkRelocation( &reloc, 17, 0x000000c0, 0x0, "__cxa_atexit", 10, 0x0, 0 );
588
589 sec = reader.sections[".rela.ctors"];
590
591 const_relocation_section_accessor reloc1( reader, sec );
592 EXPECT_EQ( reloc1.get_entries_num(), 1 );
593
594 checkRelocation( &reloc1, 0, 0x00000000, 0x0, "", 1, 0xDC, 0xDC );
595
596 sec = reader.sections[".rela.eh_frame"];
597
598 const_relocation_section_accessor reloc2( reader, sec );
599 EXPECT_EQ( reloc2.get_entries_num(), 3 );
600
601 checkRelocation( &reloc2, 1, 0x00000020, 0x0, "", 1, 0x0, 0x0 );
602 }
603
604 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,test_ppc)605 TEST( ELFIOTest, test_ppc )
606 {
607 elfio reader;
608
609 ASSERT_EQ( reader.load( "elf_examples/test_ppc" ), true );
610
611 ////////////////////////////////////////////////////////////////////////////
612 // Check ELF header
613 checkHeader( reader, ELFCLASS32, ELFDATA2MSB, EV_CURRENT, ET_EXEC, EM_PPC,
614 1, 0x10000550, 0, 31, 8, 0, 0 );
615
616 ////////////////////////////////////////////////////////////////////////////
617 // Check sections
618 const section* sec = reader.sections[0];
619
620 checkSection( sec, 0, "", SHT_NULL, 0, 0, 0, 0, 0, 0, 0 );
621
622 sec = reader.sections[1];
623
624 checkSection( sec, 1, ".interp", SHT_PROGBITS, SHF_ALLOC,
625 0x0000000010000134, 0xd, 0, 0, 1, 0 );
626
627 sec = reader.sections[9];
628
629 checkSection( sec, 9, ".rela.plt", SHT_RELA, SHF_ALLOC, 0x00000000010000494,
630 0x6c, 4, 22, 4, 0xc );
631
632 sec = reader.sections[20];
633
634 checkSection( sec, 20, ".dynamic", SHT_DYNAMIC, SHF_WRITE | SHF_ALLOC,
635 0x0000000010010aec, 0xe8, 5, 0, 4, 0x8 );
636
637 sec = reader.sections[28];
638
639 checkSection( sec, 28, ".shstrtab", SHT_STRTAB, 0, 0x0, 0x101, 0, 0, 1, 0 );
640
641 const section* sec1 = reader.sections[".shstrtab"];
642 EXPECT_EQ( sec->get_index(), sec1->get_index() );
643
644 ////////////////////////////////////////////////////////////////////////////
645 // Check segments
646 const segment* seg = reader.segments[0];
647 checkSegment( seg, PT_PHDR, 0x10000034, 0x10000034, 0x00100, 0x00100,
648 PF_R + PF_X, 4 );
649
650 seg = reader.segments[2];
651 checkSegment( seg, PT_LOAD, 0x10000000, 0x10000000, 0x00acc, 0x00acc,
652 PF_R + PF_X, 0x10000 );
653
654 seg = reader.segments[7];
655 checkSegment( seg, 0x6474E551, 0x0, 0x0, 0x0, 0x0, PF_R + PF_W, 0x4 );
656
657 ////////////////////////////////////////////////////////////////////////////
658 // Check symbol table
659 sec = reader.sections[".symtab"];
660
661 const_symbol_section_accessor sr( reader, sec );
662
663 EXPECT_EQ( sr.get_symbols_num(), 80 );
664 checkSymbol( sr, 0, "", 0x00000000, 0, STB_LOCAL, STT_NOTYPE, STN_UNDEF,
665 ELF_ST_VISIBILITY( STV_DEFAULT ) );
666 checkSymbol( sr, 1, "", 0x10000134, 0, STB_LOCAL, STT_SECTION, 1,
667 ELF_ST_VISIBILITY( STV_DEFAULT ) );
668 checkSymbol( sr, 40, "__CTOR_END__", 0x10010AD4, 0, STB_LOCAL, STT_OBJECT,
669 16, ELF_ST_VISIBILITY( STV_DEFAULT ) );
670 checkSymbol( sr, 52, "__init_array_start", 0x10010acc, 0, STB_LOCAL,
671 STT_NOTYPE, 16, ELF_ST_VISIBILITY( STV_HIDDEN ) );
672 checkSymbol( sr, 64, "_ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4", 0x10000920,
673 204, STB_GLOBAL, STT_FUNC, SHN_UNDEF,
674 ELF_ST_VISIBILITY( STV_DEFAULT ) );
675 checkSymbol( sr, 78, "main", 0x1000069c, 92, STB_GLOBAL, STT_FUNC, 11,
676 ELF_ST_VISIBILITY( STV_DEFAULT ) );
677 checkSymbol( sr, 79, "_init", 0x10000500, 0, STB_GLOBAL, STT_FUNC, 10,
678 ELF_ST_VISIBILITY( STV_DEFAULT ) );
679
680 ////////////////////////////////////////////////////////////////////////////
681 // Check relocation table
682 sec = reader.sections[".rela.dyn"];
683
684 const_relocation_section_accessor reloc( reader, sec );
685 EXPECT_EQ( reloc.get_entries_num(), 2 );
686
687 checkRelocation( &reloc, 1, 0x10010c0c, 0x10010c0c, "_ZSt4cout", 19, 0, 0 );
688
689 sec = reader.sections[".rela.plt"];
690
691 const_relocation_section_accessor reloc1( reader, sec );
692 EXPECT_EQ( reloc1.get_entries_num(), 9 );
693
694 checkRelocation( &reloc1, 0, 0x10010be4, 0x100008e0, "__cxa_atexit", 21, 0,
695 0 );
696 checkRelocation( &reloc1, 1, 0x10010be8, 0x0, "__gmon_start__", 21, 0, 0 );
697
698 ////////////////////////////////////////////////////////////////////////////
699 // Check note reader
700 sec = reader.sections[".note.ABI-tag"];
701
702 const_note_section_accessor notes( reader, sec );
703 EXPECT_EQ( notes.get_notes_num(), 1u );
704
705 checkNote( notes, 0, 1, std::string( "GNU" ), 16 );
706 }
707
708 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,test_dummy_out_i386_32)709 TEST( ELFIOTest, test_dummy_out_i386_32 )
710 {
711 elfio writer;
712
713 writer.create( ELFCLASS32, ELFDATA2LSB );
714
715 writer.set_os_abi( 0 );
716 writer.set_abi_version( 0 );
717 writer.set_type( ET_REL );
718 writer.set_machine( EM_386 );
719 writer.set_flags( 0 );
720
721 // Set program entry point
722 writer.set_entry( 0x80482b0 );
723
724 // Add Note section
725 section* note_sec = writer.sections.add( ".note" );
726 note_sec->set_type( SHT_NOTE );
727 note_sec->set_flags( SHF_ALLOC );
728 note_sec->set_addr_align( 4 );
729 note_section_accessor note_writer( writer, note_sec );
730 char descr[6] = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
731 note_writer.add_note( 0x77, "Hello", descr, 6 );
732 EXPECT_EQ( note_sec->get_index(), 2 );
733
734 // Create ELF file
735 writer.save( "elf_examples/elf_dummy_header_i386_32.elf" );
736
737 elfio reader;
738 ASSERT_EQ( reader.load( "elf_examples/elf_dummy_header_i386_32.elf" ),
739 true );
740
741 ////////////////////////////////////////////////////////////////////////////
742 // Check ELF header
743 checkHeader( reader, ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ET_REL, EM_386,
744 EV_CURRENT, 0x80482b0, 0, 3, 0, 0, 0 );
745 ////////////////////////////////////////////////////////////////////////////
746 // Check sections
747 const section* sec = reader.sections[""];
748
749 checkSection( sec, 0, "", SHT_NULL, 0, 0, 0, 0, 0, 0, 0 );
750
751 sec = reader.sections[".shstrtab"];
752
753 checkSection( sec, 1, ".shstrtab", SHT_STRTAB, 0, 0, 17, 0, 0, 1, 0 );
754
755 sec = reader.sections[".note"];
756
757 EXPECT_EQ( sec->get_index(), 2 );
758 checkSection( sec, 2, ".note", SHT_NOTE, SHF_ALLOC, 0, 28, 0, 0, 4, 0 );
759 }
760
761 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,test_dummy_out_ppc_32)762 TEST( ELFIOTest, test_dummy_out_ppc_32 )
763 {
764 elfio writer;
765
766 writer.create( ELFCLASS32, ELFDATA2MSB );
767
768 writer.set_os_abi( 0 );
769 writer.set_abi_version( 0 );
770 writer.set_type( ET_REL );
771 writer.set_machine( EM_PPC );
772 writer.set_flags( 0 );
773
774 // Set program entry point
775 writer.set_entry( 0x80482b0 );
776
777 // Add Note section
778 section* note_sec = writer.sections.add( ".note" );
779 note_sec->set_type( SHT_NOTE );
780 note_sec->set_flags( SHF_ALLOC );
781 note_sec->set_addr_align( 4 );
782 note_section_accessor note_writer( writer, note_sec );
783 char descr[6] = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
784 note_writer.add_note( 0x77, "Hello", descr, 6 );
785 EXPECT_EQ( note_sec->get_index(), 2 );
786
787 // Create ELF file
788 writer.save( "elf_examples/elf_dummy_header_ppc_32.elf" );
789
790 elfio reader;
791 ASSERT_EQ( reader.load( "elf_examples/elf_dummy_header_ppc_32.elf" ),
792 true );
793
794 ////////////////////////////////////////////////////////////////////////////
795 // Check ELF header
796 checkHeader( reader, ELFCLASS32, ELFDATA2MSB, EV_CURRENT, ET_REL, EM_PPC,
797 EV_CURRENT, 0x80482b0, 0, 3, 0, 0, 0 );
798 ////////////////////////////////////////////////////////////////////////////
799 // Check sections
800 const section* sec = reader.sections[""];
801
802 checkSection( sec, 0, "", SHT_NULL, 0, 0, 0, 0, 0, 0, 0 );
803
804 sec = reader.sections[".note"];
805
806 EXPECT_EQ( sec->get_index(), 2 );
807 checkSection( sec, 2, ".note", SHT_NOTE, SHF_ALLOC, 0, 28, 0, 0, 4, 0 );
808
809 sec = reader.sections[".shstrtab"];
810
811 checkSection( sec, 1, ".shstrtab", SHT_STRTAB, 0, 0, 17, 0, 0, 1, 0 );
812 }
813
814 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,test_dummy_out_i386_64)815 TEST( ELFIOTest, test_dummy_out_i386_64 )
816 {
817 elfio writer;
818
819 writer.create( ELFCLASS64, ELFDATA2LSB );
820
821 writer.set_os_abi( 0 );
822 writer.set_abi_version( 0 );
823 writer.set_type( ET_REL );
824 writer.set_machine( EM_X86_64 );
825 writer.set_flags( 0 );
826
827 // Set program entry point
828 writer.set_entry( 0x120380482b0ULL );
829
830 // Add Note section
831 section* note_sec = writer.sections.add( ".note" );
832 note_sec->set_type( SHT_NOTE );
833 note_sec->set_flags( SHF_ALLOC );
834 note_sec->set_addr_align( 4 );
835 note_section_accessor note_writer( writer, note_sec );
836 char descr[6] = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
837 note_writer.add_note( 0x77, "Hello", descr, 6 );
838 EXPECT_EQ( note_sec->get_index(), 2 );
839
840 // Create ELF file
841 writer.save( "elf_examples/elf_dummy_header_i386_64.elf" );
842
843 elfio reader;
844 ASSERT_EQ( reader.load( "elf_examples/elf_dummy_header_i386_64.elf" ),
845 true );
846
847 ////////////////////////////////////////////////////////////////////////////
848 // Check ELF header
849 checkHeader( reader, ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ET_REL, EM_X86_64,
850 EV_CURRENT, 0x120380482b0ULL, 0, 3, 0, 0, 0 );
851 ////////////////////////////////////////////////////////////////////////////
852 // Check sections
853 const section* sec = reader.sections[""];
854
855 checkSection( sec, 0, "", SHT_NULL, 0, 0, 0, 0, 0, 0, 0 );
856
857 sec = reader.sections[".note"];
858
859 EXPECT_EQ( sec->get_index(), 2 );
860 checkSection( sec, 2, ".note", SHT_NOTE, SHF_ALLOC, 0, 28, 0, 0, 4, 0 );
861
862 sec = reader.sections[".shstrtab"];
863
864 checkSection( sec, 1, ".shstrtab", SHT_STRTAB, 0, 0, 17, 0, 0, 1, 0 );
865 }
866
867 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,test_dummy_out_ppc_64)868 TEST( ELFIOTest, test_dummy_out_ppc_64 )
869 {
870 elfio writer;
871
872 writer.create( ELFCLASS64, ELFDATA2MSB );
873
874 writer.set_os_abi( 0 );
875 writer.set_abi_version( 0 );
876 writer.set_type( ET_REL );
877 writer.set_machine( EM_PPC64 );
878 writer.set_flags( 0 );
879
880 // Set program entry point
881 writer.set_entry( 0x120380482b0ULL );
882
883 // Add Note section
884 section* note_sec = writer.sections.add( ".note" );
885 note_sec->set_type( SHT_NOTE );
886 note_sec->set_flags( SHF_ALLOC );
887 note_sec->set_addr_align( 4 );
888 note_section_accessor note_writer( writer, note_sec );
889 char descr[6] = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
890 note_writer.add_note( 0x77, "Hello", descr, 6 );
891 EXPECT_EQ( note_sec->get_index(), 2 );
892
893 // Create ELF file
894 writer.save( "elf_examples/elf_dummy_header_ppc_64.elf" );
895
896 elfio reader;
897 ASSERT_EQ( reader.load( "elf_examples/elf_dummy_header_ppc_64.elf" ),
898 true );
899
900 ////////////////////////////////////////////////////////////////////////////
901 // Check ELF header
902 checkHeader( reader, ELFCLASS64, ELFDATA2MSB, EV_CURRENT, ET_REL, EM_PPC64,
903 EV_CURRENT, 0x120380482b0ULL, 0, 3, 0, 0, 0 );
904 ////////////////////////////////////////////////////////////////////////////
905 // Check sections
906 const section* sec = reader.sections[""];
907
908 checkSection( sec, 0, "", SHT_NULL, 0, 0, 0, 0, 0, 0, 0 );
909
910 sec = reader.sections[".shstrtab"];
911
912 checkSection( sec, 1, ".shstrtab", SHT_STRTAB, 0, 0, 17, 0, 0, 1, 0 );
913
914 sec = reader.sections[".note"];
915
916 EXPECT_EQ( sec->get_index(), 2 );
917 checkSection( sec, 2, ".note", SHT_NOTE, SHF_ALLOC, 0, 28, 0, 0, 4, 0 );
918 }
919
920 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,test_dynamic_64_1)921 TEST( ELFIOTest, test_dynamic_64_1 )
922 {
923 elfio reader;
924
925 ASSERT_EQ( reader.load( "elf_examples/main" ), true );
926
927 section* dynsec = reader.sections[".dynamic"];
928 ASSERT_TRUE( dynsec != nullptr );
929
930 dynamic_section_accessor da( reader, dynsec );
931
932 EXPECT_EQ( da.get_entries_num(), 21 );
933
934 Elf_Xword tag;
935 Elf_Xword value;
936 std::string str;
937 da.get_entry( 0, tag, value, str );
938 EXPECT_EQ( tag, DT_NEEDED );
939 EXPECT_EQ( str, "libfunc.so" );
940 da.get_entry( 1, tag, value, str );
941 EXPECT_EQ( tag, DT_NEEDED );
942 EXPECT_EQ( str, "libc.so.6" );
943 da.get_entry( 2, tag, value, str );
944 EXPECT_EQ( tag, DT_INIT );
945 EXPECT_EQ( value, 0x400530 );
946 da.get_entry( 19, tag, value, str );
947 EXPECT_EQ( tag, 0x6ffffff0 );
948 EXPECT_EQ( value, 0x40047e );
949 da.get_entry( 20, tag, value, str );
950 EXPECT_EQ( tag, DT_NULL );
951 EXPECT_EQ( value, 0 );
952 }
953
954 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,test_dynamic_64_2)955 TEST( ELFIOTest, test_dynamic_64_2 )
956 {
957 elfio reader;
958
959 ASSERT_EQ( reader.load( "elf_examples/libfunc.so" ), true );
960
961 section* dynsec = reader.sections[".dynamic"];
962 ASSERT_TRUE( dynsec != nullptr );
963
964 dynamic_section_accessor da( reader, dynsec );
965
966 EXPECT_EQ( da.get_entries_num(), 20 );
967
968 Elf_Xword tag;
969 Elf_Xword value;
970 std::string str;
971 da.get_entry( 0, tag, value, str );
972 EXPECT_EQ( tag, DT_NEEDED );
973 EXPECT_EQ( str, "libc.so.6" );
974 da.get_entry( 1, tag, value, str );
975 EXPECT_EQ( tag, DT_INIT );
976 EXPECT_EQ( value, 0x480 );
977 da.get_entry( 18, tag, value, str );
978 EXPECT_EQ( tag, 0x6ffffff9 );
979 EXPECT_EQ( value, 1 );
980 da.get_entry( 19, tag, value, str );
981 EXPECT_EQ( tag, DT_NULL );
982 EXPECT_EQ( value, 0 );
983 }
984
985 class mock_wiiu_compression : public compression_interface
986 {
987 public:
988 std::unique_ptr<char[]>
inflate(const char * data,const endianess_convertor * convertor,Elf_Xword compressed_size,Elf_Xword & uncompressed_size) const989 inflate( const char* data,
990 const endianess_convertor* convertor,
991 Elf_Xword compressed_size,
992 Elf_Xword& uncompressed_size ) const override
993 {
994 uncompressed_size = 2 * compressed_size;
995 return std::unique_ptr<char[]>(
996 new ( std::nothrow ) char[uncompressed_size + 1] );
997 }
998
deflate(const char * data,const endianess_convertor * convertor,Elf_Xword decompressed_size,Elf_Xword & compressed_size) const999 std::unique_ptr<char[]> deflate( const char* data,
1000 const endianess_convertor* convertor,
1001 Elf_Xword decompressed_size,
1002 Elf_Xword& compressed_size ) const override
1003 {
1004 compressed_size = decompressed_size / 2;
1005 return std::unique_ptr<char[]>(
1006 new ( std::nothrow ) char[compressed_size + 1] );
1007 }
1008 };
1009
1010 ////////////////////////////////////////////////////////////////////////////////
1011 // Given: a valid RPX file
1012 // When: we load it with no compression implementation
1013 // Then: the size returns the raw section size (compressed size)
1014 // When: we load it with a mock compression implementation
1015 // Then: the size changes to reflect the mock compression implementation is being called
1016 //
1017 // This test does not do any further validation because doing so would require providing
1018 // a real compression implementation
TEST(ELFIOTest,test_rpx)1019 TEST( ELFIOTest, test_rpx )
1020 {
1021 elfio reader( new ( std::nothrow ) mock_wiiu_compression() );
1022 elfio reader_no_compression;
1023
1024 ASSERT_EQ( reader_no_compression.load( "elf_examples/helloworld.rpx" ),
1025 true );
1026 const section* text1 = reader_no_compression.sections[1];
1027 EXPECT_EQ( text1->get_size(), 36744 );
1028
1029 ASSERT_EQ( reader.load( "elf_examples/helloworld.rpx" ), true );
1030 const section* text2 = reader.sections[1];
1031 EXPECT_EQ( text2->get_size(), text1->get_size() * 2 );
1032 }
1033
1034 ////////////////////////////////////////////////////////////////////////////////
TEST(ELFIOTest,test_dynamic_64_3)1035 TEST( ELFIOTest, test_dynamic_64_3 )
1036 {
1037 elfio reader;
1038
1039 ASSERT_EQ( reader.load( "elf_examples/main" ), true );
1040
1041 section* dynsec = reader.sections[".dynamic"];
1042 ASSERT_TRUE( dynsec != nullptr );
1043
1044 dynamic_section_accessor da( reader, dynsec );
1045 EXPECT_EQ( da.get_entries_num(), 21 );
1046
1047 section* strsec1 = reader.sections.add( ".dynstr" );
1048 strsec1->set_type( SHT_STRTAB );
1049 strsec1->set_entry_size( reader.get_default_entry_size( SHT_STRTAB ) );
1050
1051 section* dynsec1 = reader.sections.add( ".dynamic1" );
1052 dynsec1->set_type( SHT_DYNAMIC );
1053 dynsec1->set_entry_size( reader.get_default_entry_size( SHT_DYNAMIC ) );
1054 dynsec1->set_link( strsec1->get_index() );
1055 dynamic_section_accessor da1( reader, dynsec1 );
1056
1057 Elf_Xword tag;
1058 Elf_Xword tag1;
1059 Elf_Xword value;
1060 Elf_Xword value1;
1061 std::string str;
1062 std::string str1;
1063
1064 for ( unsigned int i = 0; i < da.get_entries_num(); ++i ) {
1065 da.get_entry( i, tag, value, str );
1066 if ( tag == DT_NEEDED || tag == DT_SONAME || tag == DT_RPATH ||
1067 tag == DT_RUNPATH ) {
1068 da1.add_entry( tag, str );
1069 }
1070 else {
1071 da1.add_entry( tag, value );
1072 }
1073 }
1074
1075 for ( unsigned int i = 0; i < da.get_entries_num(); ++i ) {
1076 da.get_entry( i, tag, value, str );
1077 da1.get_entry( i, tag1, value1, str1 );
1078
1079 EXPECT_EQ( tag, tag1 );
1080 if ( tag == DT_NEEDED || tag == DT_SONAME || tag == DT_RPATH ||
1081 tag == DT_RUNPATH ) {
1082 EXPECT_EQ( str, str1 );
1083 }
1084 else {
1085 EXPECT_EQ( value, value1 );
1086 }
1087 }
1088 }
1089