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