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