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