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