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