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