##// END OF EJS Templates
Elf Symbol enumeration WIP.
Jeandet Alexis -
r41:da052a0662f0 default
parent child
Show More
@@ -1,823 +1,846
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
26 26 ElfFile::ElfFile()
27 27 :abstractExecFile()
28 28 {
29 29 this->opened = false;
30 30 this->type_elf = false;
31 31 this->elfFile = NULL;
32 32 this->e = NULL;
33 33 }
34 34
35 35 ElfFile::ElfFile(const QString &File)
36 36 :abstractExecFile()
37 37 {
38 38 this->opened = false;
39 39 this->type_elf = false;
40 40 this->elfFile = NULL;
41 41 this->e = NULL;
42 42 this->p_fileName = File;
43 43 openFile(File);
44 44 }
45 45
46 46 bool ElfFile::openFile(const QString &File)
47 47 {
48 48 this->p_fileName = File;
49 49 this->closeFile();
50 50 if(elf_version(EV_CURRENT)==EV_NONE)return 0;
51 51 #ifdef _ELF_WINDOWS_
52 52 this->elfFile = open(File.toStdString().c_str(),O_RDONLY|O_BINARY ,0);
53 53 #else
54 54 this->elfFile = open(File.toStdString().c_str(),O_RDONLY ,0);
55 55 #endif
56 56 if(this->elfFile==NULL)return 0;
57 57 this->e = elf_begin(this->elfFile,ELF_C_READ,NULL);
58 58 if(this->e==NULL)return 0;
59 59 this->ek = elf_kind(this->e);
60 60 gelf_getehdr (this->e, &this->ehdr );
61 61 elf_getshdrstrndx (this->e, &this->shstrndx);
62 62 this->updateSegments();
63 63 this->updateSections();
64 this->updateSymbols();
64 65 this->opened = true;
65 66 return 1;
66 67 }
67 68
68 69 bool ElfFile::isopened()
69 70 {
70 71 return this->opened;
71 72 }
72 73
73 74 int ElfFile::closeFile()
74 75 {
75 76 if(this->elfFile!=NULL)
76 77 {
77 78 if(this->e!=NULL)
78 79 {
79 80 elf_end(this->e);
80 81 this->e = NULL;
81 82 }
82 83 close(this->elfFile);
83 84 this->elfFile = NULL;
84 85 }
85 86 this->opened = false;
86 87 return 0;
87 88 }
88 89
89 90
90 91 QList<codeFragment*> ElfFile::getFragments(QStringList fragmentList)
91 92 {
92 93 QList<codeFragment*> fragments;
93 94 if (isopened())
94 95 {
95 96 for(int i =0;i<fragmentList.count();i++)
96 97 {
97 98 fragments.append(getFragment(fragmentList.at(i)));
98 99 }
99 100 }
100 101 return fragments;
101 102 }
102 103
103 104 QList<codeFragment*> ElfFile::getFragments()
104 105 {
105 106 return getFragments(QStringList()<<".data"<<".text");
106 107 }
107 108
108 109 codeFragment *ElfFile::getFragment(const QString &name)
109 110 {
110 111 codeFragment* fragment= new codeFragment();
111 112 for(int i=0;i<getSectionCount();i++)
112 113 {
113 114 if(getSectionName(i) == name)
114 115 {
115 116 fragment->data =NULL;
116 117 fragment->size = getSectionDatasz(i);
117 118 fragment->address = getSectionPaddr(i);
118 119 getSectionData(i,&fragment->data);
119 120 }
120 121 }
121 122
122 123 }
123 124
124 125
125 126
126 127
127 128
128 129
129 130
130 131 QString elfresolveMachine(Elf64_Half e_machine)
131 132 {
132 133 QString machineName;
133 134 //Update from with bash script don't write it by yourself!
134 135 switch(e_machine)
135 136 {
136 137 case EM_NONE:
137 138 machineName = " No machine ";
138 139 break;
139 140 case EM_M32:
140 141 machineName = " AT&T WE 32100 ";
141 142 break;
142 143 case EM_SPARC:
143 144 machineName = " SUN SPARC ";
144 145 break;
145 146 case EM_386:
146 147 machineName = " Intel 80386 ";
147 148 break;
148 149 case EM_68K:
149 150 machineName = " Motorola m68k family ";
150 151 break;
151 152 case EM_88K:
152 153 machineName = " Motorola m88k family ";
153 154 break;
154 155 case EM_860:
155 156 machineName = " Intel 80860 ";
156 157 break;
157 158 case EM_MIPS:
158 159 machineName = " MIPS R3000 big-endian ";
159 160 break;
160 161 case EM_S370:
161 162 machineName = " IBM System/370 ";
162 163 break;
163 164 case EM_MIPS_RS3_LE:
164 165 machineName = " MIPS R3000 little-endian ";
165 166 break;
166 167 case EM_PARISC:
167 168 machineName = " HPPA ";
168 169 break;
169 170 case EM_VPP500:
170 171 machineName = " Fujitsu VPP500 ";
171 172 break;
172 173 case EM_SPARC32PLUS:
173 174 machineName = " Sun's \"v8plus\" ";
174 175 break;
175 176 case EM_960:
176 177 machineName = " Intel 80960 ";
177 178 break;
178 179 case EM_PPC:
179 180 machineName = " PowerPC ";
180 181 break;
181 182 case EM_PPC64:
182 183 machineName = " PowerPC 64-bit ";
183 184 break;
184 185 case EM_S390:
185 186 machineName = " IBM S390 ";
186 187 break;
187 188 case EM_V800:
188 189 machineName = " NEC V800 series ";
189 190 break;
190 191 case EM_FR20:
191 192 machineName = " Fujitsu FR20 ";
192 193 break;
193 194 case EM_RH32:
194 195 machineName = " TRW RH-32 ";
195 196 break;
196 197 case EM_RCE:
197 198 machineName = " Motorola RCE ";
198 199 break;
199 200 case EM_ARM:
200 201 machineName = " ARM ";
201 202 break;
202 203 case EM_FAKE_ALPHA:
203 204 machineName = " Digital Alpha ";
204 205 break;
205 206 case EM_SH:
206 207 machineName = " Hitachi SH ";
207 208 break;
208 209 case EM_SPARCV9:
209 210 machineName = " SPARC v9 64-bit ";
210 211 break;
211 212 case EM_TRICORE:
212 213 machineName = " Siemens Tricore ";
213 214 break;
214 215 case EM_ARC:
215 216 machineName = " Argonaut RISC Core ";
216 217 break;
217 218 case EM_H8_300:
218 219 machineName = " Hitachi H8/300 ";
219 220 break;
220 221 case EM_H8_300H:
221 222 machineName = " Hitachi H8/300H ";
222 223 break;
223 224 case EM_H8S:
224 225 machineName = " Hitachi H8S ";
225 226 break;
226 227 case EM_H8_500:
227 228 machineName = " Hitachi H8/500 ";
228 229 break;
229 230 case EM_IA_64:
230 231 machineName = " Intel Merced ";
231 232 break;
232 233 case EM_MIPS_X:
233 234 machineName = " Stanford MIPS-X ";
234 235 break;
235 236 case EM_COLDFIRE:
236 237 machineName = " Motorola Coldfire ";
237 238 break;
238 239 case EM_68HC12:
239 240 machineName = " Motorola M68HC12 ";
240 241 break;
241 242 case EM_MMA:
242 243 machineName = " Fujitsu MMA Multimedia Accelerator";
243 244 break;
244 245 case EM_PCP:
245 246 machineName = " Siemens PCP ";
246 247 break;
247 248 case EM_NCPU:
248 249 machineName = " Sony nCPU embeeded RISC ";
249 250 break;
250 251 case EM_NDR1:
251 252 machineName = " Denso NDR1 microprocessor ";
252 253 break;
253 254 case EM_STARCORE:
254 255 machineName = " Motorola Start*Core processor ";
255 256 break;
256 257 case EM_ME16:
257 258 machineName = " Toyota ME16 processor ";
258 259 break;
259 260 case EM_ST100:
260 261 machineName = " STMicroelectronic ST100 processor ";
261 262 break;
262 263 case EM_TINYJ:
263 264 machineName = " Advanced Logic Corp. Tinyj emb.fam";
264 265 break;
265 266 case EM_X86_64:
266 267 machineName = " AMD x86-64 architecture ";
267 268 break;
268 269 case EM_PDSP:
269 270 machineName = " Sony DSP Processor ";
270 271 break;
271 272 case EM_FX66:
272 273 machineName = " Siemens FX66 microcontroller ";
273 274 break;
274 275 case EM_ST9PLUS:
275 276 machineName = " STMicroelectronics ST9+ 8/16 mc ";
276 277 break;
277 278 case EM_ST7:
278 279 machineName = " STmicroelectronics ST7 8 bit mc ";
279 280 break;
280 281 case EM_68HC16:
281 282 machineName = " Motorola MC68HC16 microcontroller ";
282 283 break;
283 284 case EM_68HC11:
284 285 machineName = " Motorola MC68HC11 microcontroller ";
285 286 break;
286 287 case EM_68HC08:
287 288 machineName = " Motorola MC68HC08 microcontroller ";
288 289 break;
289 290 case EM_68HC05:
290 291 machineName = " Motorola MC68HC05 microcontroller ";
291 292 break;
292 293 case EM_SVX:
293 294 machineName = " Silicon Graphics SVx ";
294 295 break;
295 296 case EM_ST19:
296 297 machineName = " STMicroelectronics ST19 8 bit mc ";
297 298 break;
298 299 case EM_VAX:
299 300 machineName = " Digital VAX ";
300 301 break;
301 302 case EM_CRIS:
302 303 machineName = " Axis Communications 32-bit embedded processor ";
303 304 break;
304 305 case EM_JAVELIN:
305 306 machineName = " Infineon Technologies 32-bit embedded processor ";
306 307 break;
307 308 case EM_FIREPATH:
308 309 machineName = " Element 14 64-bit DSP Processor ";
309 310 break;
310 311 case EM_ZSP:
311 312 machineName = " LSI Logic 16-bit DSP Processor ";
312 313 break;
313 314 case EM_MMIX:
314 315 machineName = " Donald Knuth's educational 64-bit processor ";
315 316 break;
316 317 case EM_HUANY:
317 318 machineName = " Harvard University machine-independent object files ";
318 319 break;
319 320 case EM_PRISM:
320 321 machineName = " SiTera Prism ";
321 322 break;
322 323 case EM_AVR:
323 324 machineName = " Atmel AVR 8-bit microcontroller ";
324 325 break;
325 326 case EM_FR30:
326 327 machineName = " Fujitsu FR30 ";
327 328 break;
328 329 case EM_D10V:
329 330 machineName = " Mitsubishi D10V ";
330 331 break;
331 332 case EM_D30V:
332 333 machineName = " Mitsubishi D30V ";
333 334 break;
334 335 case EM_V850:
335 336 machineName = " NEC v850 ";
336 337 break;
337 338 case EM_M32R:
338 339 machineName = " Mitsubishi M32R ";
339 340 break;
340 341 case EM_MN10300:
341 342 machineName = " Matsushita MN10300 ";
342 343 break;
343 344 case EM_MN10200:
344 345 machineName = " Matsushita MN10200 ";
345 346 break;
346 347 case EM_PJ:
347 348 machineName = " picoJava ";
348 349 break;
349 350 case EM_OPENRISC:
350 351 machineName = " OpenRISC 32-bit embedded processor ";
351 352 break;
352 353 case EM_ARC_A5:
353 354 machineName = " ARC Cores Tangent-A5 ";
354 355 break;
355 356 case EM_XTENSA:
356 357 machineName = " Tensilica Xtensa Architecture ";
357 358 break;
358 359 case EM_AARCH64:
359 360 machineName = " ARM AARCH64 ";
360 361 break;
361 362 case EM_TILEPRO:
362 363 machineName = " Tilera TILEPro ";
363 364 break;
364 365 case EM_MICROBLAZE:
365 366 machineName = " Xilinx MicroBlaze ";
366 367 break;
367 368 case EM_TILEGX:
368 369 machineName = " Tilera TILE-Gx ";
369 370 break;
370 371 case EM_NUM:
371 372 machineName = "";
372 373 break;
373 374 default:
374 375 machineName ="Unknow Machine";
375 376 break;
376 377 }
377 378 return machineName;
378 379 }
379 380
380 381
381 382
382 383
383 384 QString ElfFile::getClass()
384 385 {
385 386 if(this->e!=NULL)
386 387 {
387 388 int eclass = gelf_getclass(this->e);
388 389 if(eclass==ELFCLASS32)return "ELF32";
389 390 if(eclass==ELFCLASS64)return "ELF64";
390 391 }
391 392 return "none";
392 393 }
393 394
394 395
395 396 bool ElfFile::iself()
396 397 {
397 398 return (this->getType()!="Unknow");
398 399 }
399 400
400 401 QString ElfFile::getArchitecture()
401 402 {
402 403 if(this->e!=NULL)
403 404 {
404 405 return elfresolveMachine(this->ehdr.e_machine);
405 406 }
406 407 return "";
407 408 }
408 409
409 410
410 411 QString ElfFile::getType()
411 412 {
412 413 QString kind("");
413 414 if(this->e!=NULL)
414 415 {
415 416 switch(this->ek)
416 417 {
417 418 case ELF_K_AR:
418 419 kind = "Archive";
419 420 break;
420 421 case ELF_K_ELF:
421 422 kind = "Elf";
422 423 break;
423 424 case ELF_K_COFF:
424 425 kind = "COFF";
425 426 break;
426 427 case ELF_K_NUM:
427 428 kind = "NUM";
428 429 break;
429 430 case ELF_K_NONE:
430 431 kind = "Data";
431 432 break;
432 433 default:
433 434 kind = "Unknow";
434 435 break;
435 436 }
436 437 }
437 438 return kind;
438 439 }
439 440
440 441 QString ElfFile::getEndianness()
441 442 {
442 443 if(this->e!=NULL)
443 444 {
444 445 if(this->ehdr.e_ident[EI_DATA]==ELFDATA2LSB)return "2's complement, little endian";
445 446 if(this->ehdr.e_ident[EI_DATA]==ELFDATA2MSB)return "2's complement, big endian";
446 447 }
447 448 return "none";
448 449 }
449 450
450 451 QString ElfFile::getABI()
451 452 {
452 453 if(this->e!=NULL)
453 454 {
454 455 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_NONE)return "UNIX System V ABI";
455 456 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_SYSV)return "Alias";
456 457 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_HPUX)return "HP-UX";
457 458 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_NETBSD)return "NetBSD";
458 459 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_GNU)return "Object uses GNU ELF extensions";
459 460 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_LINUX)return "Compatibility alias";
460 461 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_SOLARIS)return "Sun Solaris";
461 462 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_AIX)return "IBM AIX";
462 463 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_IRIX)return "SGI Irix";
463 464 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_FREEBSD)return "FreeBSD";
464 465 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_TRU64)return "Compaq TRU64 UNIX";
465 466 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_MODESTO)return " Novell Modesto";
466 467 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_OPENBSD)return "OpenBSD";
467 468 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_ARM_AEABI)return "ARM EABI";
468 469 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_ARM)return "ARM";
469 470 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_STANDALONE)return "Standalone (embedded) application";
470 471 }
471 472 return "none";
472 473 }
473 474
474 475
475 476 qint64 ElfFile::getVersion()
476 477 {
477 478 if(this->e!=NULL)
478 479 {
479 480 return this->ehdr.e_version;
480 481 }
481 482 }
482 483
483 484 qint64 ElfFile::getEntryPointAddress()
484 485 {
485 486 if(this->e!=NULL)
486 487 {
487 488 return this->ehdr.e_entry;
488 489 }
489 490 }
490 491
491 492
492 493 int ElfFile::getSectionCount()
493 494 {
494 495 return (int)this->SectionCount;
495 496 }
496 497
497 498 int ElfFile::getSymbolCount()
498 499 {
499 500 return (int)this->SymbolCount;
500 501 }
501 502
502 503
503 504 int ElfFile::getSegmentCount()
504 505 {
505 506 return (int)this->SegmentCount;
506 507 }
507 508
508 509
509 510 QString ElfFile::getSegmentType(int index)
510 511 {
511 512 QString type("");
512 513 if(this->e!=NULL)
513 514 {
514 515 if(index < this->Segments.count())
515 516 {
516 517 switch(this->Segments.at(index)->p_type)
517 518 {
518 519 case PT_NULL:
519 520 type = "Program header table entry unused";
520 521 break;
521 522 case PT_LOAD:
522 523 type = "Loadable program segment";
523 524 break;
524 525 case PT_DYNAMIC :
525 526 type = "Dynamic linking information";
526 527 break;
527 528 case PT_INTERP:
528 529 type ="Program interpreter";
529 530 break;
530 531 case PT_NOTE:
531 532 type = "Auxiliary information";
532 533 break;
533 534 case PT_SHLIB:
534 535 type = "Reserved";
535 536 break;
536 537 case PT_PHDR:
537 538 type = "Entry for header table itself";
538 539 break;
539 540 case PT_TLS:
540 541 type = "Thread-local storage segment";
541 542 break;
542 543 case PT_NUM:
543 544 type = "Number of defined types";
544 545 break;
545 546 case PT_LOOS:
546 547 type = "Start of OS-specific";
547 548 break;
548 549 case PT_SUNWSTACK:
549 550 type = "Stack segment";
550 551 break;
551 552 case PT_LOPROC:
552 553 type = "Start of processor-specific";
553 554 break;
554 555 case PT_HIPROC:
555 556 type = "End of processor-specific";
556 557 break;
557 558 default:
558 559 type = "Unknow Section Type";
559 560 break;
560 561 }
561 562 }
562 563 }
563 564
564 565 return type;
565 566 }
566 567
567 568
568 569 qint64 ElfFile::getSegmentOffset(int index)
569 570 {
570 571 int64_t Offset;
571 572 if(this->e!=NULL)
572 573 {
573 574 if(index < this->Segments.count())
574 575 {
575 576 Offset = (int64_t)this->Segments.at(index)->p_offset;
576 577 }
577 578 }
578 579 return Offset;
579 580 }
580 581
581 582
582 583 qint64 ElfFile::getSegmentVaddr(int index)
583 584 {
584 585 int64_t Vaddr = 0;
585 586 if(this->e!=NULL)
586 587 {
587 588 if(index < this->Segments.count())
588 589 {
589 590 Vaddr = (int64_t)this->Segments.at(index)->p_vaddr;
590 591 }
591 592 }
592 593 return Vaddr;
593 594 }
594 595
595 596
596 597 qint64 ElfFile::getSegmentPaddr(int index)
597 598 {
598 599 int64_t Paddr=0;
599 600 if(this->e!=NULL)
600 601 {
601 602 if(index < this->Segments.count())
602 603 {
603 604 Paddr = (int64_t)this->Segments.at(index)->p_paddr;
604 605 }
605 606 }
606 607 return Paddr;
607 608 }
608 609
609 610 qint64 ElfFile::getSectionPaddr(int index)
610 611 {
611 612 int64_t Paddr=0;
612 613 if(this->e!=NULL)
613 614 {
614 615 if(index < this->sections.count())
615 616 {
616 617 Paddr = (int64_t)this->sections.at(index)->section_header->sh_addr;
617 618 }
618 619 }
619 620 return Paddr;
620 621 }
621 622
622 623
623 624 qint64 ElfFile::getSegmentFilesz(int index)
624 625 {
625 626 int64_t FileSz=0;
626 627 if(this->e!=NULL)
627 628 {
628 629 if(index < this->Segments.count())
629 630 {
630 631 FileSz = (int64_t)this->Segments.at(index)->p_filesz;
631 632 }
632 633 }
633 634 return FileSz;
634 635 }
635 636
636 637 qint64 ElfFile::getSectionDatasz(int index)
637 638 {
638 639 int64_t DataSz=0;
639 640 if(this->e!=NULL)
640 641 {
641 642 if(index < this->sections.count())
642 643 {
643 644 DataSz = (int64_t)this->sections.at(index)->data->d_size;
644 645 }
645 646 }
646 647 return DataSz;
647 648 }
648 649
649 650 bool ElfFile::getSectionData(int index, char **buffer)
650 651 {
651 652 if(this->e!=NULL)
652 653 {
653 654 if(index < this->sections.count())
654 655 {
655 656 *buffer = (char *)this->sections.at(index)->data->d_buf;
656 657 return true;
657 658 }
658 659 }
659 660 return false;
660 661 }
661 662
662 663
663 664 qint64 ElfFile::getSegmentMemsz(int index)
664 665 {
665 666 int64_t MemSz=0;
666 667 if(this->e!=NULL)
667 668 {
668 669 if(index < this->Segments.count())
669 670 {
670 671 MemSz = (int64_t)this->Segments.at(index)->p_memsz;
671 672 }
672 673 }
673 674 return MemSz;
674 675 }
675 676
676 677 qint64 ElfFile::getSectionMemsz(int index)
677 678 {
678 679 int64_t MemSz=0;
679 680 if(this->e!=NULL)
680 681 {
681 682 if(index < this->sections.count())
682 683 {
683 684 MemSz = (int64_t)this->sections.at(index)->section_header->sh_size;
684 685 }
685 686 }
686 687 return MemSz;
687 688 }
688 689
689 690
690 691 QString ElfFile::getSegmentFlags(int index)
691 692 {
692 693 QString flags("");
693 694 if(this->e!=NULL)
694 695 {
695 696 if(index < this->Segments.count())
696 697 {
697 698 if((this->Segments.at(index)->p_flags&PF_X) == PF_X)flags+="x";
698 699 if((this->Segments.at(index)->p_flags&PF_W) == PF_W)flags+="w";
699 700 if((this->Segments.at(index)->p_flags&PF_R) == PF_R)flags+="r";
700 701 if((this->Segments.at(index)->p_flags&PF_MASKOS) == PF_MASKOS)flags+=" OS-specific";
701 702 if((this->Segments.at(index)->p_flags&PF_MASKPROC) == PF_MASKPROC)flags+=" Processor-specific";
702 703 }
703 704 }
704 705 return flags;
705 706 }
706 707
707 708
708 709 QString ElfFile::getSectionName(int index)
709 710 {
710 711 char* nameChr = elf_strptr(this->e , this->shstrndx , this->sections.at(index)->section_header->sh_name);
711 712 return QString(nameChr);
712 713 }
713 714
714 715
715 716 void ElfFile::updateSections()
716 717 {
717 718 for(int i=0;i<this->sections.count();i++)
718 719 {
719 720 delete this->sections.at(i);
720 721 }
721 722 this->sections.clear();
722 723 this->scn = elf_nextscn (this->e , NULL );
723 724 this->SectionCount = 0;
724 725 while( this->scn != NULL )
725 726 {
726 727 GElf_Shdr* shdr = (GElf_Shdr*)malloc(sizeof(GElf_Shdr));
727 728 gelf_getshdr ( this->scn , shdr );
728 729 Elf_Data* data = elf_getdata(this->scn, NULL);
729 730 this->sections.append(new Elf_Section(data,shdr));
730 731 this->SectionCount+=1;
731 732 this->scn = elf_nextscn(e , scn);
732 733 }
733 734 }
734 735
735 736
736 737 void ElfFile::updateSegments()
737 738 {
738 739 elf_getphdrnum (this->e , &this->SegmentCount);
739 740 for(int i=0;i<this->Segments.count();i++)
740 741 {
741 742 free(this->Segments.at(i));
742 743 }
743 744 this->Segments.clear();
744 745 for(int i=0;i<this->SegmentCount;i++)
745 746 {
746 747 GElf_Phdr* header=(GElf_Phdr*)malloc(sizeof(GElf_Phdr));
747 748 gelf_getphdr (this->e , i , header );
748 749 this->Segments.append(header);
749 750 }
750 751 }
751 752
752 753 void ElfFile::updateSymbols()
753 754 {
755 for(int i=0;i<symbols.count();i++)
756 {
757 delete this->symbols.at(i);
758 }
759 this->symbols.clear();
760 updateSections(); //Useless in most case but safer to do it
761 for(int i=0;i<SectionCount;i++)
762 {
763 //First find Symbol table
764 if(this->getSectionName(i)==".symtab")
765 {
766 Elf_Section* sec = sections.at(i);
767 this->SymbolCount = sec->section_header->sh_size / sec->section_header->sh_entsize;
768 //Then list all symbols
769 for(int j=0;j<this->SymbolCount;j++)
770 {
771 GElf_Sym* esym = (GElf_Sym*)malloc(sizeof(GElf_Sym));
772 gelf_getsym(sec->data, j, esym);
773 QString name = elf_strptr(this->e,sec->section_header->sh_link,esym->st_name);
774 Elf_Symbol* sym = new Elf_Symbol(name,esym);
775 symbols.append(sym);
776 }
777 }
778 }
754 779
755 780 }
756 781
757 782
758 783
759
760
761 784 QString ElfFile::getSectionType(int index)
762 785 {
763 786 QString type("");
764 787 if(this->e!=NULL)
765 788 {
766 789 if(index < this->Segments.count())
767 790 {
768 791 switch(this->Segments.at(index)->p_type)
769 792 {
770 793 case SHT_NULL : type = "Section header table entry unused"; break;
771 794 case SHT_PROGBITS : type = "Program data"; break;
772 795 case SHT_SYMTAB : type = "Symbol table"; break;
773 796 case SHT_STRTAB : type = "String table"; break;
774 797 case SHT_RELA : type = "Relocation entries with addends"; break;
775 798 case SHT_HASH : type = "Symbol hash table"; break;
776 799 case SHT_DYNAMIC : type = "Dynamic linking information"; break;
777 800 case SHT_NOTE : type = "Notes"; break;
778 801 case SHT_NOBITS :type = "Program space with no data (bss)"; break;
779 802 case SHT_REL :type = "Relocation entries, no addends"; break;
780 803 case SHT_SHLIB : type = "Reserved"; break;
781 804 case SHT_DYNSYM : type = "Dynamic linker symbol table"; break;
782 805 case SHT_INIT_ARRAY : type = "Array of constructors"; break;
783 806 case SHT_FINI_ARRAY : type = "Array of destructors"; break;
784 807 case SHT_PREINIT_ARRAY : type = "Array of pre-constructors"; break;
785 808 case SHT_GROUP : type = "Section group"; break;
786 809 case SHT_SYMTAB_SHNDX : type = "Extended section indeces"; break;
787 810 case SHT_NUM : type = "Number of defined types. "; break;
788 811 case SHT_LOOS : type = "Start OS-specific. "; break;
789 812 case SHT_LOSUNW : type = "Sun-specific low bound. "; break;
790 813 case SHT_SUNW_COMDAT : type = " "; break;
791 814 case SHT_SUNW_syminfo : type = " "; break;
792 815 case SHT_GNU_verdef : type = "Version definition section. "; break;
793 816 case SHT_GNU_verneed : type = "Version needs section. "; break;
794 817 case SHT_GNU_versym : type = "Version symbol table. "; break;
795 818 case SHT_LOPROC : type = "Start of processor-specific"; break;
796 819 case SHT_HIPROC : type = "End of processor-specific"; break;
797 820 case SHT_HIUSER : type = "End of application-specific"; break;
798 821 }
799 822 }
800 823 }
801 824 return type;
802 825 }
803 826
804 827 bool ElfFile::isElf(const QString &File)
805 828 {
806 829 int file =0;
807 830 #ifdef _ELF_WINDOWS_
808 831 file = open(File.toStdString().c_str(),O_RDONLY|O_BINARY ,0);
809 832 #else
810 833 file = open(File.toStdString().c_str(),O_RDONLY ,0);
811 834 #endif
812 835 char Magic[4];
813 836 if(file!=-1)
814 837 {
815 838 read(file,Magic,4);
816 839 close(file);
817 840 if(Magic[0]==0x7f && Magic[1]==0x45 && Magic[2]==0x4c && Magic[3]==0x46)
818 841 {
819 842 return true;
820 843 }
821 844 }
822 845 return false;
823 846 }
@@ -1,104 +1,119
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 : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22 #include <abstractexecfile.h>
23 23 #include <QtCore/QObject>
24 24 #include <QtCore/QStringList>
25 25 #include <libelf.h>
26 26 #include <gelf.h>
27 27 #include <sys/types.h>
28 28 #include <sys/stat.h>
29 29 #include <fcntl.h>
30 30 #include <unistd.h>
31 31 #ifndef ELFFILE_H
32 32 #define ELFFILE_H
33 33
34 34 class Elf_Section
35 35 {
36 36 public:
37 37 Elf_Section(){}
38 38 Elf_Section(Elf_Data* data,GElf_Shdr* section_header)
39 39 {
40 40 this->data = data;
41 41 this->section_header = section_header;
42 42 }
43 ~Elf_Section()
44 {
45 free(section_header);
46 }
43 47 Elf_Data* data;
44 48 GElf_Shdr* section_header;
45 49 };
46 50
51 class Elf_Symbol
52 {
53 public:
54 Elf_Symbol(){}
55 Elf_Symbol(const QString& name,GElf_Sym* sym):name(name),sym(sym){}
56 ~Elf_Symbol(){free(sym);}
57 QString name;
58 GElf_Sym* sym;
59 };
60
47 61 class ElfFile : public abstractExecFile
48 62 {
49 63 Q_OBJECT
50 64 public:
51 65 ElfFile();
52 66 ElfFile(const QString& File);
53 67 bool openFile(const QString& File);
54 68 bool isopened();
55 69 int closeFile();
56 70 QList<codeFragment*> getFragments();
57 71 QList<codeFragment*> getFragments(QStringList fragmentList);
58 72
59 73 QString getClass();
60 74 QString getArchitecture();
61 75 QString getType();
62 76 QString getEndianness();
63 77 QString getABI();
64 78 qint64 getVersion();
65 79 qint64 getEntryPointAddress();
66 80 int getSectionCount();
67 81 int getSymbolCount();
68 82 int getSegmentCount();
69 83 QString getSegmentType(int index);
70 84 qint64 getSegmentOffset(int index);
71 85 qint64 getSegmentVaddr(int index);
72 86 qint64 getSegmentPaddr(int index);
73 87 qint64 getSectionPaddr(int index);
74 88 qint64 getSegmentFilesz(int index);
75 89 qint64 getSectionDatasz(int index);
76 90 bool getSectionData(int index, char **buffer);
77 91 qint64 getSegmentMemsz(int index);
78 92 qint64 getSectionMemsz(int index);
79 93 QString getSegmentFlags(int index);
80 94 QString getSectionName(int index);
81 95 QString getSectionType(int index);
82 96 bool iself();
83 97 static bool isElf(const QString& File);
84 98
85 99 private:
86 100 codeFragment* getFragment(const QString& name);
87 101 void updateSections();
88 102 void updateSegments();
89 103 void updateSymbols();
90 104 int elfFile;
91 105 bool opened;
92 106 bool type_elf;
93 107 Elf* e;
94 108 Elf_Kind ek;
95 109 GElf_Ehdr ehdr;
96 110 Elf_Scn * scn;
97 111 Elf_Data * data;
98 112 size_t SymbolCount,SectionCount,SegmentCount, shstrndx;
99 113 QList<GElf_Phdr*> Segments;
100 114 QList<Elf_Section*> sections;
115 QList<Elf_Symbol*> symbols;
101 116
102 117 };
103 118
104 119 #endif // ELFFILE_H
@@ -1,46 +1,46
1 1 #include "elffilewidget.h"
2 2 #include "ui_elffilewidget.h"
3 3
4 4 elfFileWidget::elfFileWidget(QWidget *parent) :
5 5 QWidget(parent),
6 6 ui(new Ui::elfFileWidget)
7 7 {
8 8 ui->setupUi(this);
9 9 }
10 10
11 11 elfFileWidget::~elfFileWidget()
12 12 {
13 13 delete ui;
14 14 }
15 15
16 16 void elfFileWidget::updateElfFile(ElfFile *file)
17 17 {
18 18 this->p_elf = file;
19 19 if(p_elf->isopened() && p_elf->iself())
20 20 {
21 21 this->ui->classLabel->setText(p_elf->getClass());
22 22 this->ui->VersionLabel->setText(QString::number(p_elf->getVersion()));
23 23 this->ui->machineLabel->setText(p_elf->getArchitecture());
24 24 this->ui->endiannesLabel->setText(p_elf->getEndianness());
25 25 this->ui->abiLabel->setText(p_elf->getABI());
26 26 this->ui->entryPointLabel->setText(QString("0x%1").arg((uint)p_elf->getEntryPointAddress(),8,16));
27 27 this->ui->typeLabel->setText(p_elf->getType());
28 28 this->ui->sectionCountLabel->setText(QString::number(p_elf->getSectionCount()));
29 // this->ui->symbolCountLabel->setText(p_elf->get);
29 this->ui->symbolCountLabel->setText(QString::number(p_elf->getSymbolCount()));
30 30 }
31 31 }
32 32
33 33
34 34
35 35
36 36
37 37
38 38
39 39
40 40
41 41
42 42
43 43
44 44
45 45
46 46
General Comments 0
You need to be logged in to leave comments. Login now