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