##// END OF EJS Templates
Added ".dynsym" section for symbol lookup.
Jeandet Alexis -
r13:5e16a30c7e05 default
parent child
Show More
@@ -1,1095 +1,1098
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the SocExplorer Software
3 3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 2 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author :
20 20 Alexis Jeandet
21 21 -- Mail :
22 22 alexis.jeandet@member.fsf.org
23 23 ----------------------------------------------------------------------------*/
24 24 #include "elffile.h"
25 25 #include "srecfile.h"
26 26 #include "binaryfile.h"
27 27 #include <stdint.h>
28 28
29 29 ElfFile::ElfFile()
30 30 :abstractBinFile()
31 31 {
32 32 this->opened = false;
33 33 this->type_elf = false;
34 34 this->elfFile = (int)NULL;
35 35 this->e = NULL;
36 36 this->data = NULL;
37 this->SymbolCount = 0;
37 38 }
38 39
39 40 ElfFile::ElfFile(const QString &File)
40 41 :abstractBinFile()
41 42 {
42 43 this->opened = false;
43 44 this->type_elf = false;
44 45 this->elfFile = (int)NULL;
45 46 this->e = NULL;
46 47 this->p_fileName = File;
47 48 this->data = NULL;
49 this->SymbolCount = 0;
48 50 openFile(File);
49 51 }
50 52
51 53 ElfFile::~ElfFile()
52 54 {
53 55 closeFile();
54 56 if(scn)free(scn);
55 57 if(data)free(data);
56 58 for(int i=0;i<this->sections.count();i++)
57 59 {
58 60 delete this->sections.at(i);
59 61 }
60 62 this->sections.clear();
61 63 for(int i=0;i<this->Segments.count();i++)
62 64 {
63 65 free(this->Segments.at(i));
64 66 }
65 67 this->Segments.clear();
66 68 for(int i=0;i<symbols.count();i++)
67 69 {
68 70 delete this->symbols.at(i);
69 71 }
70 72 this->symbols.clear();
71 73 }
72 74
73 75 bool ElfFile::openFile(const QString &File)
74 76 {
75 77 this->p_fileName = File;
76 78 this->closeFile();
77 79 if(elf_version(EV_CURRENT)==EV_NONE)return 0;
78 80 #ifdef _ELF_WINDOWS_
79 81 this->elfFile = open(File.toStdString().c_str(),O_RDONLY|O_BINARY ,0);
80 82 #else
81 83 this->elfFile = open(File.toStdString().c_str(),O_RDONLY ,0);
82 84 #endif
83 85 if(this->elfFile==(int)NULL)return 0;
84 86 this->e = elf_begin(this->elfFile,ELF_C_READ,NULL);
85 87 if(this->e==NULL)return 0;
86 88 this->ek = elf_kind(this->e);
87 89 gelf_getehdr (this->e, &this->ehdr );
88 90 elf_getshdrstrndx (this->e, &this->shstrndx);
89 91 this->updateSegments();
90 92 this->updateSections();
91 93 this->updateSymbols();
92 94 this->opened = true;
93 95 return 1;
94 96 }
95 97
96 98 bool ElfFile::isopened()
97 99 {
98 100 return this->opened;
99 101 }
100 102
101 103 int ElfFile::closeFile()
102 104 {
103 105 if(this->elfFile!=(int)NULL)
104 106 {
105 107 if(this->e!=NULL)
106 108 {
107 109 elf_end(this->e);
108 110 this->e = NULL;
109 111 }
110 112 close(this->elfFile);
111 113 this->elfFile = (int)NULL;
112 114 }
113 115 this->opened = false;
114 116 return 0;
115 117 }
116 118
117 119
118 120 QList<codeFragment*> ElfFile::getFragments(QStringList fragmentList)
119 121 {
120 122 QList<codeFragment*> fragments;
121 123 if (isopened())
122 124 {
123 125 for(int i =0;i<fragmentList.count();i++)
124 126 {
125 127 fragments.append(getFragment(fragmentList.at(i)));
126 128 }
127 129 }
128 130 return fragments;
129 131 }
130 132
131 133 QList<codeFragment*> ElfFile::getFragments()
132 134 {
133 135 return getFragments(QStringList()<<".data"<<".text");
134 136 }
135 137
136 138 codeFragment *ElfFile::getFragment(const QString &name)
137 139 {
138 140 codeFragment* fragment= new codeFragment();
139 141 for(int i=0;i<getSectionCount();i++)
140 142 {
141 143 if(getSectionName(i) == name)
142 144 {
143 145 fragment->data =NULL;
144 146 fragment->size = getSectionDatasz(i);
145 147 fragment->address = getSectionPaddr(i);
146 148 getSectionData(i,&fragment->data);
147 149 }
148 150 }
149 151 return fragment;
150 152 }
151 153
152 154
153 155
154 156
155 157
156 158
157 159
158 160 QString elfresolveMachine(Elf64_Half e_machine)
159 161 {
160 162 QString machineName;
161 163 //Update from with bash script don't write it by yourself!
162 164 switch(e_machine)
163 165 {
164 166 case EM_NONE:
165 167 machineName = " No machine ";
166 168 break;
167 169 case EM_M32:
168 170 machineName = " AT&T WE 32100 ";
169 171 break;
170 172 case EM_SPARC:
171 173 machineName = " SUN SPARC ";
172 174 break;
173 175 case EM_386:
174 176 machineName = " Intel 80386 ";
175 177 break;
176 178 case EM_68K:
177 179 machineName = " Motorola m68k family ";
178 180 break;
179 181 case EM_88K:
180 182 machineName = " Motorola m88k family ";
181 183 break;
182 184 case EM_860:
183 185 machineName = " Intel 80860 ";
184 186 break;
185 187 case EM_MIPS:
186 188 machineName = " MIPS R3000 big-endian ";
187 189 break;
188 190 case EM_S370:
189 191 machineName = " IBM System/370 ";
190 192 break;
191 193 case EM_MIPS_RS3_LE:
192 194 machineName = " MIPS R3000 little-endian ";
193 195 break;
194 196 case EM_PARISC:
195 197 machineName = " HPPA ";
196 198 break;
197 199 case EM_VPP500:
198 200 machineName = " Fujitsu VPP500 ";
199 201 break;
200 202 case EM_SPARC32PLUS:
201 203 machineName = " Sun's \"v8plus\" ";
202 204 break;
203 205 case EM_960:
204 206 machineName = " Intel 80960 ";
205 207 break;
206 208 case EM_PPC:
207 209 machineName = " PowerPC ";
208 210 break;
209 211 case EM_PPC64:
210 212 machineName = " PowerPC 64-bit ";
211 213 break;
212 214 case EM_S390:
213 215 machineName = " IBM S390 ";
214 216 break;
215 217 case EM_V800:
216 218 machineName = " NEC V800 series ";
217 219 break;
218 220 case EM_FR20:
219 221 machineName = " Fujitsu FR20 ";
220 222 break;
221 223 case EM_RH32:
222 224 machineName = " TRW RH-32 ";
223 225 break;
224 226 case EM_RCE:
225 227 machineName = " Motorola RCE ";
226 228 break;
227 229 case EM_ARM:
228 230 machineName = " ARM ";
229 231 break;
230 232 case EM_FAKE_ALPHA:
231 233 machineName = " Digital Alpha ";
232 234 break;
233 235 case EM_SH:
234 236 machineName = " Hitachi SH ";
235 237 break;
236 238 case EM_SPARCV9:
237 239 machineName = " SPARC v9 64-bit ";
238 240 break;
239 241 case EM_TRICORE:
240 242 machineName = " Siemens Tricore ";
241 243 break;
242 244 case EM_ARC:
243 245 machineName = " Argonaut RISC Core ";
244 246 break;
245 247 case EM_H8_300:
246 248 machineName = " Hitachi H8/300 ";
247 249 break;
248 250 case EM_H8_300H:
249 251 machineName = " Hitachi H8/300H ";
250 252 break;
251 253 case EM_H8S:
252 254 machineName = " Hitachi H8S ";
253 255 break;
254 256 case EM_H8_500:
255 257 machineName = " Hitachi H8/500 ";
256 258 break;
257 259 case EM_IA_64:
258 260 machineName = " Intel Merced ";
259 261 break;
260 262 case EM_MIPS_X:
261 263 machineName = " Stanford MIPS-X ";
262 264 break;
263 265 case EM_COLDFIRE:
264 266 machineName = " Motorola Coldfire ";
265 267 break;
266 268 case EM_68HC12:
267 269 machineName = " Motorola M68HC12 ";
268 270 break;
269 271 case EM_MMA:
270 272 machineName = " Fujitsu MMA Multimedia Accelerator";
271 273 break;
272 274 case EM_PCP:
273 275 machineName = " Siemens PCP ";
274 276 break;
275 277 case EM_NCPU:
276 278 machineName = " Sony nCPU embeeded RISC ";
277 279 break;
278 280 case EM_NDR1:
279 281 machineName = " Denso NDR1 microprocessor ";
280 282 break;
281 283 case EM_STARCORE:
282 284 machineName = " Motorola Start*Core processor ";
283 285 break;
284 286 case EM_ME16:
285 287 machineName = " Toyota ME16 processor ";
286 288 break;
287 289 case EM_ST100:
288 290 machineName = " STMicroelectronic ST100 processor ";
289 291 break;
290 292 case EM_TINYJ:
291 293 machineName = " Advanced Logic Corp. Tinyj emb.fam";
292 294 break;
293 295 case EM_X86_64:
294 296 machineName = " AMD x86-64 architecture ";
295 297 break;
296 298 case EM_PDSP:
297 299 machineName = " Sony DSP Processor ";
298 300 break;
299 301 case EM_FX66:
300 302 machineName = " Siemens FX66 microcontroller ";
301 303 break;
302 304 case EM_ST9PLUS:
303 305 machineName = " STMicroelectronics ST9+ 8/16 mc ";
304 306 break;
305 307 case EM_ST7:
306 308 machineName = " STmicroelectronics ST7 8 bit mc ";
307 309 break;
308 310 case EM_68HC16:
309 311 machineName = " Motorola MC68HC16 microcontroller ";
310 312 break;
311 313 case EM_68HC11:
312 314 machineName = " Motorola MC68HC11 microcontroller ";
313 315 break;
314 316 case EM_68HC08:
315 317 machineName = " Motorola MC68HC08 microcontroller ";
316 318 break;
317 319 case EM_68HC05:
318 320 machineName = " Motorola MC68HC05 microcontroller ";
319 321 break;
320 322 case EM_SVX:
321 323 machineName = " Silicon Graphics SVx ";
322 324 break;
323 325 case EM_ST19:
324 326 machineName = " STMicroelectronics ST19 8 bit mc ";
325 327 break;
326 328 case EM_VAX:
327 329 machineName = " Digital VAX ";
328 330 break;
329 331 case EM_CRIS:
330 332 machineName = " Axis Communications 32-bit embedded processor ";
331 333 break;
332 334 case EM_JAVELIN:
333 335 machineName = " Infineon Technologies 32-bit embedded processor ";
334 336 break;
335 337 case EM_FIREPATH:
336 338 machineName = " Element 14 64-bit DSP Processor ";
337 339 break;
338 340 case EM_ZSP:
339 341 machineName = " LSI Logic 16-bit DSP Processor ";
340 342 break;
341 343 case EM_MMIX:
342 344 machineName = " Donald Knuth's educational 64-bit processor ";
343 345 break;
344 346 case EM_HUANY:
345 347 machineName = " Harvard University machine-independent object files ";
346 348 break;
347 349 case EM_PRISM:
348 350 machineName = " SiTera Prism ";
349 351 break;
350 352 case EM_AVR:
351 353 machineName = " Atmel AVR 8-bit microcontroller ";
352 354 break;
353 355 case EM_FR30:
354 356 machineName = " Fujitsu FR30 ";
355 357 break;
356 358 case EM_D10V:
357 359 machineName = " Mitsubishi D10V ";
358 360 break;
359 361 case EM_D30V:
360 362 machineName = " Mitsubishi D30V ";
361 363 break;
362 364 case EM_V850:
363 365 machineName = " NEC v850 ";
364 366 break;
365 367 case EM_M32R:
366 368 machineName = " Mitsubishi M32R ";
367 369 break;
368 370 case EM_MN10300:
369 371 machineName = " Matsushita MN10300 ";
370 372 break;
371 373 case EM_MN10200:
372 374 machineName = " Matsushita MN10200 ";
373 375 break;
374 376 case EM_PJ:
375 377 machineName = " picoJava ";
376 378 break;
377 379 case EM_OPENRISC:
378 380 machineName = " OpenRISC 32-bit embedded processor ";
379 381 break;
380 382 case EM_ARC_A5:
381 383 machineName = " ARC Cores Tangent-A5 ";
382 384 break;
383 385 case EM_XTENSA:
384 386 machineName = " Tensilica Xtensa Architecture ";
385 387 break;
386 388 #ifndef EM_AARCH64
387 389 #define EM_AARCH64 183
388 390 #endif
389 391 case EM_AARCH64:
390 392 machineName = " ARM AARCH64 ";
391 393 break;
392 394 #ifndef EM_TILEPRO
393 395 #define EM_TILEPRO 188
394 396 #endif
395 397 case EM_TILEPRO:
396 398 machineName = " Tilera TILEPro ";
397 399 break;
398 400 #ifndef EM_MICROBLAZE
399 401 #define EM_MICROBLAZE 189
400 402 #endif
401 403 case EM_MICROBLAZE:
402 404 machineName = " Xilinx MicroBlaze ";
403 405 break;
404 406 #ifndef EM_TILEGX
405 407 #define EM_TILEGX 191
406 408 #endif
407 409 case EM_TILEGX:
408 410 machineName = " Tilera TILE-Gx ";
409 411 break;
410 412 case EM_NUM:
411 413 machineName = "";
412 414 break;
413 415 default:
414 416 machineName ="Unknow Machine";
415 417 break;
416 418 }
417 419 return machineName;
418 420 }
419 421
420 422
421 423
422 424
423 425 QString ElfFile::getClass()
424 426 {
425 427 if(this->e!=NULL)
426 428 {
427 429 int eclass = gelf_getclass(this->e);
428 430 if(eclass==ELFCLASS32)return "ELF32";
429 431 if(eclass==ELFCLASS64)return "ELF64";
430 432 }
431 433 return "none";
432 434 }
433 435
434 436
435 437 bool ElfFile::iself()
436 438 {
437 439 return (this->getType()!="Unknow");
438 440 }
439 441
440 442 QString ElfFile::getArchitecture()
441 443 {
442 444 if(this->e!=NULL)
443 445 {
444 446 return elfresolveMachine(this->ehdr.e_machine);
445 447 }
446 448 return "";
447 449 }
448 450
449 451
450 452 QString ElfFile::getType()
451 453 {
452 454 QString kind("");
453 455 if(this->e!=NULL)
454 456 {
455 457 switch(this->ek)
456 458 {
457 459 case ELF_K_AR:
458 460 kind = "Archive";
459 461 break;
460 462 case ELF_K_ELF:
461 463 kind = "Elf";
462 464 break;
463 465 case ELF_K_COFF:
464 466 kind = "COFF";
465 467 break;
466 468 case ELF_K_NUM:
467 469 kind = "NUM";
468 470 break;
469 471 case ELF_K_NONE:
470 472 kind = "Data";
471 473 break;
472 474 default:
473 475 kind = "Unknow";
474 476 break;
475 477 }
476 478 }
477 479 return kind;
478 480 }
479 481
480 482 QString ElfFile::getEndianness()
481 483 {
482 484 if(this->e!=NULL)
483 485 {
484 486 if(this->ehdr.e_ident[EI_DATA]==ELFDATA2LSB)return "2's complement, little endian";
485 487 if(this->ehdr.e_ident[EI_DATA]==ELFDATA2MSB)return "2's complement, big endian";
486 488 }
487 489 return "none";
488 490 }
489 491
490 492 QString ElfFile::getABI()
491 493 {
492 494 if(this->e!=NULL)
493 495 {
494 496 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_NONE)return "UNIX System V ABI";
495 497 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_SYSV)return "Alias";
496 498 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_HPUX)return "HP-UX";
497 499 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_NETBSD)return "NetBSD";
498 500 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_LINUX)return "Object uses GNU ELF extensions";
499 501 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_SOLARIS)return "Sun Solaris";
500 502 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_AIX)return "IBM AIX";
501 503 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_IRIX)return "SGI Irix";
502 504 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_FREEBSD)return "FreeBSD";
503 505 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_TRU64)return "Compaq TRU64 UNIX";
504 506 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_MODESTO)return " Novell Modesto";
505 507 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_OPENBSD)return "OpenBSD";
506 508 #ifndef ELFOSABI_ARM_AEABI
507 509 #define ELFOSABI_ARM_AEABI 64
508 510 #endif
509 511 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_ARM_AEABI)return "ARM EABI";
510 512 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_ARM)return "ARM";
511 513 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_STANDALONE)return "Standalone (embedded) application";
512 514 }
513 515 return "none";
514 516 }
515 517
516 518
517 519 qint64 ElfFile::getVersion()
518 520 {
519 521 if(this->e!=NULL)
520 522 {
521 523 return this->ehdr.e_version;
522 524 }
523 525 return -1;
524 526 }
525 527
526 528 qint64 ElfFile::getEntryPointAddress()
527 529 {
528 530 if(this->e!=NULL)
529 531 {
530 532 return this->ehdr.e_entry;
531 533 }
532 534 return -1;
533 535 }
534 536
535 537
536 538 int ElfFile::getSectionCount()
537 539 {
538 540 return (int)this->SectionCount;
539 541 }
540 542
541 543 int ElfFile::getSymbolCount()
542 544 {
543 545 return (int)this->SymbolCount;
544 546 }
545 547
546 548
547 549 int ElfFile::getSegmentCount()
548 550 {
549 551 return (int)this->SegmentCount;
550 552 }
551 553
552 554
553 555 QString ElfFile::getSegmentType(int index)
554 556 {
555 557 QString type("");
556 558 if(this->e!=NULL)
557 559 {
558 560 if(index < this->Segments.count())
559 561 {
560 562 switch(this->Segments.at(index)->p_type)
561 563 {
562 564 case PT_NULL:
563 565 type = "Program header table entry unused";
564 566 break;
565 567 case PT_LOAD:
566 568 type = "Loadable program segment";
567 569 break;
568 570 case PT_DYNAMIC :
569 571 type = "Dynamic linking information";
570 572 break;
571 573 case PT_INTERP:
572 574 type ="Program interpreter";
573 575 break;
574 576 case PT_NOTE:
575 577 type = "Auxiliary information";
576 578 break;
577 579 case PT_SHLIB:
578 580 type = "Reserved";
579 581 break;
580 582 case PT_PHDR:
581 583 type = "Entry for header table itself";
582 584 break;
583 585 case PT_TLS:
584 586 type = "Thread-local storage segment";
585 587 break;
586 588 case PT_NUM:
587 589 type = "Number of defined types";
588 590 break;
589 591 case PT_LOOS:
590 592 type = "Start of OS-specific";
591 593 break;
592 594 case PT_SUNWSTACK:
593 595 type = "Stack segment";
594 596 break;
595 597 case PT_LOPROC:
596 598 type = "Start of processor-specific";
597 599 break;
598 600 case PT_HIPROC:
599 601 type = "End of processor-specific";
600 602 break;
601 603 default:
602 604 type = "Unknow Section Type";
603 605 break;
604 606 }
605 607 }
606 608 }
607 609
608 610 return type;
609 611 }
610 612
611 613
612 614 qint64 ElfFile::getSegmentOffset(int index)
613 615 {
614 616 qint64 Offset = -1;
615 617 if(this->e!=NULL)
616 618 {
617 619 if(index < this->Segments.count())
618 620 {
619 621 Offset = (qint64)this->Segments.at(index)->p_offset;
620 622 }
621 623 }
622 624 return Offset;
623 625 }
624 626
625 627
626 628 qint64 ElfFile::getSegmentVaddr(int index)
627 629 {
628 630 int64_t Vaddr = 0;
629 631 if(this->e!=NULL)
630 632 {
631 633 if(index < this->Segments.count())
632 634 {
633 635 Vaddr = (int64_t)this->Segments.at(index)->p_vaddr;
634 636 }
635 637 }
636 638 return Vaddr;
637 639 }
638 640
639 641
640 642 qint64 ElfFile::getSegmentPaddr(int index)
641 643 {
642 644 int64_t Paddr=0;
643 645 if(this->e!=NULL)
644 646 {
645 647 if(index < this->Segments.count())
646 648 {
647 649 Paddr = (int64_t)this->Segments.at(index)->p_paddr;
648 650 }
649 651 }
650 652 return Paddr;
651 653 }
652 654
653 655 qint64 ElfFile::getSectionPaddr(int index)
654 656 {
655 657 int64_t Paddr=0;
656 658 if(this->e!=NULL)
657 659 {
658 660 if(index < this->sections.count())
659 661 {
660 662 Paddr = (int64_t)this->sections.at(index)->section_header->sh_addr;
661 663 }
662 664 }
663 665 return Paddr;
664 666 }
665 667
666 668
667 669 qint64 ElfFile::getSegmentFilesz(int index)
668 670 {
669 671 int64_t FileSz=0;
670 672 if(this->e!=NULL)
671 673 {
672 674 if(index < this->Segments.count())
673 675 {
674 676 FileSz = (int64_t)this->Segments.at(index)->p_filesz;
675 677 }
676 678 }
677 679 return FileSz;
678 680 }
679 681
680 682 qint64 ElfFile::getSectionDatasz(int index)
681 683 {
682 684 int64_t DataSz=0;
683 685 if(this->e!=NULL)
684 686 {
685 687 if(index < this->sections.count())
686 688 {
687 689 if(this->sections.at(index)->section_header->sh_type==SHT_NOBITS)
688 690 {
689 691 DataSz=0;
690 692 }
691 693 else
692 694 {
693 695 DataSz = (int64_t)this->sections.at(index)->data->d_size;
694 696 }
695 697 }
696 698 }
697 699 return DataSz;
698 700 }
699 701
700 702 bool ElfFile::getSectionData(int index, char **buffer)
701 703 {
702 704 if(this->e!=NULL)
703 705 {
704 706 if(index < this->sections.count())
705 707 {
706 708 *buffer = (char *)malloc(this->sections.at(index)->data->d_size);
707 709 memcpy(*buffer,this->sections.at(index)->data->d_buf,this->sections.at(index)->data->d_size);
708 710 return true;
709 711 }
710 712 }
711 713 return false;
712 714 }
713 715
714 716
715 717 qint64 ElfFile::getSegmentMemsz(int index)
716 718 {
717 719 int64_t MemSz=0;
718 720 if(this->e!=NULL)
719 721 {
720 722 if(index < this->Segments.count())
721 723 {
722 724 MemSz = (int64_t)this->Segments.at(index)->p_memsz;
723 725 }
724 726 }
725 727 return MemSz;
726 728 }
727 729
728 730 qint64 ElfFile::getSectionMemsz(int index)
729 731 {
730 732 int64_t MemSz=0;
731 733 if(this->e!=NULL)
732 734 {
733 735 if(index < this->sections.count())
734 736 {
735 737 MemSz = (int64_t)this->sections.at(index)->section_header->sh_size;
736 738 }
737 739 }
738 740 return MemSz;
739 741 }
740 742
741 743
742 744 QString ElfFile::getSegmentFlags(int index)
743 745 {
744 746 QString flags("");
745 747 if(this->e!=NULL)
746 748 {
747 749 if(index < this->Segments.count())
748 750 {
749 751 if((this->Segments.at(index)->p_flags&PF_X) == PF_X)flags+="x";
750 752 if((this->Segments.at(index)->p_flags&PF_W) == PF_W)flags+="w";
751 753 if((this->Segments.at(index)->p_flags&PF_R) == PF_R)flags+="r";
752 754 if((this->Segments.at(index)->p_flags&PF_MASKOS) == PF_MASKOS)flags+=" OS-specific";
753 755 if((this->Segments.at(index)->p_flags&PF_MASKPROC) == PF_MASKPROC)flags+=" Processor-specific";
754 756 }
755 757 }
756 758 return flags;
757 759 }
758 760
759 761
760 762 QString ElfFile::getSectionName(int index)
761 763 {
762 764 if((index<sections.count()) && (index>=0))
763 765 {
764 766 char* nameChr = elf_strptr(this->e , this->shstrndx , this->sections.at(index)->section_header->sh_name);
765 767 return QString(nameChr);
766 768 }
767 769 return "";
768 770 }
769 771
770 772
771 773 void ElfFile::updateSections()
772 774 {
773 775 for(int i=0;i<this->sections.count();i++)
774 776 {
775 777 delete this->sections.at(i);
776 778 }
777 779 this->sections.clear();
778 780 this->scn = elf_nextscn (this->e , NULL );
779 781 this->SectionCount = 0;
780 782 while( this->scn != NULL )
781 783 {
782 784 GElf_Shdr* shdr = (GElf_Shdr*)malloc(sizeof(GElf_Shdr));
783 785 gelf_getshdr ( this->scn , shdr );
784 786 Elf_Data* data = elf_getdata(this->scn, NULL);
785 787 this->sections.append(new Elf_Section(data,shdr));
786 788 this->SectionCount+=1;
787 789 this->scn = elf_nextscn(e , scn);
788 790 }
789 791 }
790 792
791 793
792 794 void ElfFile::updateSegments()
793 795 {
794 796 for(int i=0;i<this->Segments.count();i++)
795 797 {
796 798 free(this->Segments.at(i));
797 799 }
798 800 this->Segments.clear();
799 801 this->SegmentCount = 0;
800 802 GElf_Phdr* header=(GElf_Phdr*)malloc(sizeof(GElf_Phdr));
801 803 while ( header == gelf_getphdr(this->e ,this->SegmentCount, header ))
802 804 {
803 805 this->Segments.append(header);
804 806 this->SegmentCount++;
805 807 header=(GElf_Phdr*)malloc(sizeof(GElf_Phdr));
806 808 }
807 809 this->SegmentCount = this->Segments.count();
808 810 free(header);
809 811 }
810 812
811 813 void ElfFile::updateSymbols()
812 814 {
813 815 for(int i=0;i<symbols.count();i++)
814 816 {
815 817 delete this->symbols.at(i);
816 818 }
817 819 this->symbols.clear();
818 820 updateSections(); //Useless in most case but safer to do it
819 821 for(int i=0;i<(int)SectionCount;i++)
820 822 {
821 823 //First find Symbol table
822 if(this->getSectionName(i)==".symtab")
824 QString sectionName = this->getSectionName(i);
825 if(sectionName==".symtab" || sectionName == ".dynsym")
823 826 {
824 827 Elf_Section* sec = sections.at(i);
825 828 this->SymbolCount = sec->section_header->sh_size / sec->section_header->sh_entsize;
826 829 //Then list all symbols
827 830 for(int j=0;j<(int)this->SymbolCount;j++)
828 831 {
829 832 GElf_Sym* esym = (GElf_Sym*)malloc(sizeof(GElf_Sym));
830 833 gelf_getsym(sec->data, j, esym);
831 834 QString name = elf_strptr(this->e,sec->section_header->sh_link,esym->st_name);
832 835 Elf_Symbol* sym = new Elf_Symbol(name,esym);
833 836 symbols.append(sym);
834 837 }
835 838 }
836 839 }
837 840
838 841 }
839 842
840 843
841 844
842 845 QString ElfFile::getSectionType(int index)
843 846 {
844 847 QString type("");
845 848 if(this->e!=NULL)
846 849 {
847 850 if(index < this->sections.count())
848 851 {
849 852 switch(this->sections.at(index)->section_header->sh_type)
850 853 {
851 854 case SHT_NULL : type = "Section header table entry unused"; break;
852 855 case SHT_PROGBITS : type = "Program data"; break;
853 856 case SHT_SYMTAB : type = "Symbol table"; break;
854 857 case SHT_STRTAB : type = "String table"; break;
855 858 case SHT_RELA : type = "Relocation entries with addends"; break;
856 859 case SHT_HASH : type = "Symbol hash table"; break;
857 860 case SHT_DYNAMIC : type = "Dynamic linking information"; break;
858 861 case SHT_NOTE : type = "Notes"; break;
859 862 case SHT_NOBITS :type = "Program space with no data (bss)"; break;
860 863 case SHT_REL :type = "Relocation entries, no addends"; break;
861 864 case SHT_SHLIB : type = "Reserved"; break;
862 865 case SHT_DYNSYM : type = "Dynamic linker symbol table"; break;
863 866 case SHT_INIT_ARRAY : type = "Array of constructors"; break;
864 867 case SHT_FINI_ARRAY : type = "Array of destructors"; break;
865 868 case SHT_PREINIT_ARRAY : type = "Array of pre-constructors"; break;
866 869 case SHT_GROUP : type = "Section group"; break;
867 870 case SHT_SYMTAB_SHNDX : type = "Extended section indeces"; break;
868 871 case SHT_NUM : type = "Number of defined types. "; break;
869 872 case SHT_LOOS : type = "Start OS-specific. "; break;
870 873 case SHT_LOSUNW : type = "Sun-specific low bound. "; break;
871 874 case SHT_SUNW_COMDAT : type = " "; break;
872 875 case SHT_SUNW_syminfo : type = " "; break;
873 876 case SHT_GNU_verdef : type = "Version definition section. "; break;
874 877 case SHT_GNU_verneed : type = "Version needs section. "; break;
875 878 case SHT_GNU_versym : type = "Version symbol table. "; break;
876 879 case SHT_LOPROC : type = "Start of processor-specific"; break;
877 880 case SHT_HIPROC : type = "End of processor-specific"; break;
878 881 case SHT_HIUSER : type = "End of application-specific"; break;
879 882 }
880 883 }
881 884 }
882 885 return type;
883 886 }
884 887
885 888 int ElfFile::getSectionIndex(QString name)
886 889 {
887 890 if(this->e!=NULL)
888 891 {
889 892 for(int i=0;i<sections.count();i++)
890 893 {
891 894 if(getSectionName(i)==name)
892 895 return i;
893 896 }
894 897 }
895 898 return -1;
896 899 }
897 900
898 901 bool ElfFile::sectionIsNobits(int index)
899 902 {
900 903 if(this->e!=NULL)
901 904 {
902 905 if(index < this->sections.count())
903 906 {
904 907 return this->sections.at(index)->section_header->sh_type== SHT_NOBITS;
905 908 }
906 909 }
907 910 return false;
908 911 }
909 912
910 913 QString ElfFile::getSymbolName(int index)
911 914 {
912 915 if(this->e!=NULL)
913 916 {
914 917 if(index < this->symbols.count())
915 918 {
916 919 return symbols.at(index)->name;
917 920 }
918 921 }
919 922 return "";
920 923 }
921 924
922 925 QString ElfFile::getSymbolType(int index)
923 926 {
924 927 if(this->e!=NULL)
925 928 {
926 929 if(index < this->symbols.count())
927 930 {
928 931 int type = GELF_ST_TYPE(symbols.at(index)->sym->st_info);
929 932 switch(type)
930 933 {
931 934 case STT_NOTYPE:
932 935 return "No Type";
933 936 break;
934 937 case STT_OBJECT:
935 938 return "Object";
936 939 break;
937 940 case STT_FUNC:
938 941 return "Function";
939 942 break;
940 943 case STT_SECTION:
941 944 return "Section";
942 945 break;
943 946 case STT_FILE:
944 947 return "File";
945 948 break;
946 949 case STT_COMMON:
947 950 return "Common data object";
948 951 break;
949 952 case STT_TLS:
950 953 return "Thread-local data object";
951 954 break;
952 955 case STT_NUM:
953 956 return "Number of defined types";
954 957 break;
955 958 case STT_LOOS:
956 959 return "Start of OS-specific";
957 960 break;
958 961 case STT_HIOS:
959 962 return "End of OS-specific";
960 963 break;
961 964 case STT_LOPROC:
962 965 return "Start of processor-specific";
963 966 break;
964 967 case STT_HIPROC:
965 968 return "End of processor-specific";
966 969 break;
967 970 default:
968 971 return "none";
969 972 break;
970 973 }
971 974 }
972 975 }
973 976 return "none";
974 977 }
975 978
976 979 quint64 ElfFile::getSymbolSize(int index)
977 980 {
978 981 if(this->e!=NULL)
979 982 {
980 983 if((index < this->symbols.count()) && (index>=0))
981 984 {
982 985 return symbols.at(index)->sym->st_size;
983 986 }
984 987 }
985 988 return 0;
986 989 }
987 990
988 991 QString ElfFile::getSymbolSectionName(int index)
989 992 {
990 993 if(this->e!=NULL)
991 994 {
992 995 if((index < this->symbols.count()) && (index>=0))
993 996 {
994 997 return getSectionName(symbols.at(index)->sym->st_shndx-1);
995 998 }
996 999 }
997 1000 return "none";
998 1001 }
999 1002
1000 1003 int ElfFile::getSymbolSectionIndex(int index)
1001 1004 {
1002 1005 if(this->e!=NULL)
1003 1006 {
1004 1007 if((index < this->symbols.count()) && (index>=0))
1005 1008 {
1006 1009 return symbols.at(index)->sym->st_shndx;
1007 1010 }
1008 1011 }
1009 1012 return 0;
1010 1013 }
1011 1014
1012 1015 quint64 ElfFile::getSymbolAddress(int index)
1013 1016 {
1014 1017 if(this->e!=NULL)
1015 1018 {
1016 1019 if((index < this->symbols.count()) && (index>=0))
1017 1020 {
1018 1021 return symbols.at(index)->sym->st_value;
1019 1022 }
1020 1023 }
1021 1024 return 0;
1022 1025 }
1023 1026
1024 1027 QString ElfFile::getSymbolLinkType(int index)
1025 1028 {
1026 1029 if(this->e!=NULL)
1027 1030 {
1028 1031 if(index < this->symbols.count())
1029 1032 {
1030 1033 int btype = GELF_ST_BIND(symbols.at(index)->sym->st_info);
1031 1034 switch(btype)
1032 1035 {
1033 1036 case STB_LOCAL:
1034 1037 return "Local";
1035 1038 break;
1036 1039 case STB_GLOBAL:
1037 1040 return "Global";
1038 1041 break;
1039 1042 case STB_WEAK:
1040 1043 return "Weak";
1041 1044 break;
1042 1045 case STB_NUM:
1043 1046 return "Number of defined types";
1044 1047 break;
1045 1048 case STB_LOOS:
1046 1049 return "Start of OS-specific";
1047 1050 break;
1048 1051 case STB_HIOS:
1049 1052 return "End of OS-specific";
1050 1053 break;
1051 1054 case STB_LOPROC:
1052 1055 return "Start of processor-specific";
1053 1056 break;
1054 1057 case STB_HIPROC:
1055 1058 return "End of processor-specific";
1056 1059 break;
1057 1060 default:
1058 1061 return "none";
1059 1062 break;
1060 1063 }
1061 1064 }
1062 1065 }
1063 1066 return "none";
1064 1067 }
1065 1068
1066 1069 bool ElfFile::isElf(const QString &File)
1067 1070 {
1068 1071 int file =0;
1069 1072 #ifdef _ELF_WINDOWS_
1070 1073 file = open(File.toStdString().c_str(),O_RDONLY|O_BINARY ,0);
1071 1074 #else
1072 1075 file = open(File.toStdString().c_str(),O_RDONLY ,0);
1073 1076 #endif
1074 1077 char Magic[4];
1075 1078 if(file!=-1)
1076 1079 {
1077 1080 size_t res = read(file,Magic,4);
1078 1081 close(file);
1079 1082 if((res==4) && (Magic[0]==0x7f) && (Magic[1]==0x45) && (Magic[2]==0x4c) && (Magic[3]==0x46))
1080 1083 {
1081 1084 return true;
1082 1085 }
1083 1086 }
1084 1087 return false;
1085 1088 }
1086 1089
1087 1090 bool ElfFile::toSrec(const QString &File)
1088 1091 {
1089 1092 return srecFile::toSrec(this->getFragments(),File);
1090 1093 }
1091 1094
1092 1095 bool ElfFile::toBinary(const QString &File)
1093 1096 {
1094 1097 return binaryFile::toBinary(getFragments(),File);
1095 1098 }
General Comments 0
You need to be logged in to leave comments. Login now