|
1 // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32tools/e32image/tr_main.cpp |
|
15 // Translate X->E32Image top level |
|
16 // |
|
17 // |
|
18 |
|
19 #ifndef __LINUX__ |
|
20 #include <io.h> |
|
21 #endif |
|
22 #include <string.h> |
|
23 |
|
24 #ifdef __VC32__ |
|
25 #ifdef __MSVCDOTNET__ |
|
26 #include <strstream> |
|
27 #include <iomanip> |
|
28 #else //!__MSVCDOTNET__ |
|
29 #include <strstrea.h> |
|
30 #include <iomanip.h> |
|
31 #endif //__MSVCDOTNET__ |
|
32 #else // !__VC32__*/ |
|
33 #ifdef __TOOLS2__ |
|
34 #include <sstream> |
|
35 #include <iomanip> |
|
36 #else |
|
37 #include <strstream.h> |
|
38 #include <iomanip.h> |
|
39 #endif // __VC32__ |
|
40 #endif |
|
41 |
|
42 #include <e32std.h> |
|
43 |
|
44 #ifdef __SUPPORT_PE_FILES__ |
|
45 #include "pe_file.h" |
|
46 #endif |
|
47 #ifdef __SUPPORT_ELF_FILES__ |
|
48 #include "elftran.h" |
|
49 #endif |
|
50 |
|
51 #include <h_utl.h> |
|
52 #include <h_ver.h> |
|
53 #include <stdio.h> |
|
54 |
|
55 extern int gAlignConstSection; |
|
56 extern TUint gConstSectionAddressMask; |
|
57 |
|
58 int gVerbose=0; |
|
59 char *gFile1=NULL; |
|
60 char *gFile2=NULL; |
|
61 unsigned int gStack=0; |
|
62 unsigned int gHeapMin=0; |
|
63 unsigned int gHeapMax=0; |
|
64 TUid gUid1=KNullUid; |
|
65 TUid gUid2=KNullUid; |
|
66 TUid gUid3=KNullUid; |
|
67 unsigned int gSecureId=0; |
|
68 unsigned int gVendorId=0; |
|
69 unsigned int gVersionWord=0x00010000u; |
|
70 int gCallEntryPoints=TRUE; |
|
71 int gFixedAddress=FALSE; |
|
72 int gPriority=EPriorityForeground; |
|
73 SCapabilitySet gCapability={0}; |
|
74 int gAllowDllData=FALSE; |
|
75 // fix warning for Linux warning: 0 instead of NULL |
|
76 TUint gDataBase=0; |
|
77 int gCompress=TRUE; |
|
78 unsigned int gFPU=0; |
|
79 |
|
80 int gCodePaged=FALSE; |
|
81 int gCodeUnpaged=FALSE; |
|
82 int gCodeDefaultPaged=FALSE; |
|
83 |
|
84 int gDataPaged=FALSE; |
|
85 int gDataUnpaged=FALSE; |
|
86 int gDataDefaultPaged=FALSE; |
|
87 |
|
88 int gDebuggable=FALSE; |
|
89 int gSmpSafe=FALSE; |
|
90 |
|
91 int gSetStack=FALSE; |
|
92 int gSetHeap=FALSE; |
|
93 int gSetUid1=FALSE; |
|
94 int gSetUid2=FALSE; |
|
95 int gSetUid3=FALSE; |
|
96 int gSetCallEntryPoints=FALSE; |
|
97 int gSetFixedAddress=FALSE; |
|
98 int gSetPriority=FALSE; |
|
99 int gSetCapability=FALSE; |
|
100 int gSetCompress=FALSE; |
|
101 int gSetVersion=FALSE; |
|
102 int gSetSecureId=FALSE; |
|
103 int gSetVendorId=FALSE; |
|
104 int gSetFPU=FALSE; |
|
105 |
|
106 int gSetCodePaged=FALSE; |
|
107 int gSetDataPaged=FALSE; |
|
108 |
|
109 int gSetSymLkup=FALSE; |
|
110 int gSetDebuggable=FALSE; |
|
111 int gSetSmpSafe=FALSE; |
|
112 |
|
113 enum CompressionMethods |
|
114 { |
|
115 ENoCompression = 0, |
|
116 EDeflate = 1, |
|
117 EBytePair = 2, |
|
118 }; |
|
119 |
|
120 int gCompressionMethod = EDeflate; |
|
121 int gSuppressComprMethod = FALSE; |
|
122 |
|
123 #ifdef __SUPPORT_PE_FILES__ |
|
124 char* gX86imp=NULL; |
|
125 int gX86num_imp_dlls=0; |
|
126 int gX86imp_size=0; |
|
127 int gX86num_imports=0; |
|
128 #endif |
|
129 |
|
130 TBool gLittleEndian=ETrue; |
|
131 |
|
132 class E32ImageFileRef |
|
133 { |
|
134 public: |
|
135 E32ImageFileRef() {iPtr = E32ImageFile::New();} |
|
136 ~E32ImageFileRef() {delete iPtr;} |
|
137 class E32ImageFile& Ref() {return *iPtr;} |
|
138 private: |
|
139 E32ImageFileRef(const E32ImageFileRef&); |
|
140 E32ImageFileRef& operator=(const E32ImageFileRef&); |
|
141 private: |
|
142 E32ImageFile* iPtr; |
|
143 }; |
|
144 |
|
145 int setPagedFlags(E32ImageFile& f) |
|
146 { |
|
147 unsigned check1 = gCodePaged + gCodeUnpaged + gCodeDefaultPaged; |
|
148 unsigned check2 = gDataPaged + gDataUnpaged + gDataDefaultPaged; |
|
149 |
|
150 if (check1 > 1 || check2 > 1) |
|
151 { |
|
152 Print(EError, "Conflicting paging options.\n"); |
|
153 return KErrArgument; |
|
154 } |
|
155 |
|
156 if (gCodePaged) |
|
157 { |
|
158 f.iHdr->iFlags |= KImageCodePaged; |
|
159 f.iHdr->iFlags &= ~KImageCodeUnpaged; |
|
160 } |
|
161 else if (gCodeUnpaged) |
|
162 { |
|
163 f.iHdr->iFlags |= KImageCodeUnpaged; |
|
164 f.iHdr->iFlags &= ~KImageCodePaged; |
|
165 } |
|
166 else if (gCodeDefaultPaged) |
|
167 { |
|
168 f.iHdr->iFlags &= ~KImageCodePaged; |
|
169 f.iHdr->iFlags &= ~KImageCodeUnpaged; |
|
170 } |
|
171 |
|
172 if (gDataPaged) |
|
173 { |
|
174 f.iHdr->iFlags |= KImageDataPaged; |
|
175 f.iHdr->iFlags &= ~KImageDataUnpaged; |
|
176 } |
|
177 else if (gDataUnpaged) |
|
178 { |
|
179 f.iHdr->iFlags |= KImageDataUnpaged; |
|
180 f.iHdr->iFlags &= ~KImageDataPaged; |
|
181 } |
|
182 else if (gDataDefaultPaged) |
|
183 { |
|
184 f.iHdr->iFlags &= ~KImageDataPaged; |
|
185 f.iHdr->iFlags &= ~KImageDataUnpaged; |
|
186 } |
|
187 |
|
188 return KErrNone; |
|
189 } |
|
190 |
|
191 void setDebuggableFlags(E32ImageFile& f) |
|
192 { |
|
193 if (gDebuggable) |
|
194 { |
|
195 f.iHdr->iFlags |= KImageDebuggable; |
|
196 } |
|
197 else |
|
198 { |
|
199 f.iHdr->iFlags &= ~KImageDebuggable; |
|
200 } |
|
201 } |
|
202 |
|
203 void setSmpSafeFlags(E32ImageFile& f) |
|
204 { |
|
205 if (gSmpSafe) |
|
206 { |
|
207 f.iHdr->iFlags |= KImageSMPSafe; |
|
208 } |
|
209 else |
|
210 { |
|
211 f.iHdr->iFlags &= ~KImageSMPSafe; |
|
212 } |
|
213 } |
|
214 |
|
215 int dotran(const char* ifilename, const char* ofilename) |
|
216 { |
|
217 E32ImageFileRef fRef; |
|
218 E32ImageFile& f = fRef.Ref(); |
|
219 int r=f.Translate(ifilename, gDataBase, gAllowDllData, gSetSymLkup); |
|
220 if (r!=KErrNone) |
|
221 return r; |
|
222 if (gSetStack) |
|
223 f.SetStackSize(gStack); |
|
224 if (gSetHeap) |
|
225 { |
|
226 f.SetHeapSizeMin(gHeapMin); |
|
227 f.SetHeapSizeMax(gHeapMax); |
|
228 } |
|
229 if (!gSetUid1) |
|
230 gUid1=TUid::Uid(f.iHdr->iUid1); |
|
231 if (!gSetUid2) |
|
232 gUid2=TUid::Uid(f.iHdr->iUid2); |
|
233 if (!gSetUid3) |
|
234 gUid3=TUid::Uid(f.iHdr->iUid3); |
|
235 if (!gSetSecureId) |
|
236 gSecureId = f.iHdr->iUid3; |
|
237 if (!gSetVendorId) |
|
238 gVendorId = 0; |
|
239 f.SetUids(gUid1, gUid2, gUid3); |
|
240 f.SetSecureId(gSecureId); |
|
241 f.SetVendorId(gVendorId); |
|
242 if (gSetCallEntryPoints) |
|
243 f.SetCallEntryPoints(gCallEntryPoints); |
|
244 if (gSetCapability) |
|
245 f.SetCapability(gCapability); |
|
246 if (gSetPriority) |
|
247 { |
|
248 if (f.iHdr->iFlags&KImageDll) |
|
249 Print(EWarning,"Cannot set priority of a DLL.\n"); |
|
250 else |
|
251 f.SetPriority((TProcessPriority)gPriority); |
|
252 } |
|
253 if (gSetFixedAddress) |
|
254 { |
|
255 if (f.iHdr->iFlags&KImageDll) |
|
256 Print(EWarning,"Cannot set fixed address for DLL.\n"); |
|
257 else |
|
258 f.SetFixedAddress(gFixedAddress); |
|
259 } |
|
260 if (gSetVersion) |
|
261 f.iHdr->iModuleVersion = gVersionWord; |
|
262 |
|
263 if(gCompress) |
|
264 { |
|
265 switch(gCompressionMethod) |
|
266 { |
|
267 case ENoCompression: |
|
268 f.iHdr->iCompressionType = KFormatNotCompressed; |
|
269 break; |
|
270 |
|
271 case EDeflate: |
|
272 f.iHdr->iCompressionType = KUidCompressionDeflate; |
|
273 |
|
274 break; |
|
275 |
|
276 case EBytePair: |
|
277 f.iHdr->iCompressionType = KUidCompressionBytePair; |
|
278 |
|
279 break; |
|
280 |
|
281 default: |
|
282 Print(EError, "Unknown compression method:%d", gCompressionMethod); |
|
283 return 1; |
|
284 |
|
285 } // End of switch() |
|
286 |
|
287 } |
|
288 else |
|
289 { |
|
290 f.iHdr->iCompressionType = KFormatNotCompressed; |
|
291 } |
|
292 |
|
293 |
|
294 if (gSetFPU) |
|
295 f.SetFPU(gFPU); |
|
296 |
|
297 r = setPagedFlags(f); |
|
298 if (r != KErrNone) |
|
299 { |
|
300 return r; |
|
301 } |
|
302 |
|
303 setDebuggableFlags(f); |
|
304 |
|
305 setSmpSafeFlags(f); |
|
306 |
|
307 f.CreateExportBitMap(); |
|
308 f.AddExportDescription(); |
|
309 f.UpdateHeaderCrc(); |
|
310 r = f.Validate(); |
|
311 if (r!=KErrNone) |
|
312 return r; |
|
313 |
|
314 ofstream ofile(ofilename, ios::binary); |
|
315 if (!ofile) |
|
316 { |
|
317 Print(EError,"Cannot open %s for output.\n",ofilename); |
|
318 return 1; |
|
319 } |
|
320 ofile << f; |
|
321 ofile.close(); |
|
322 if (gVerbose) |
|
323 f.Dump((TText*)ofilename,gVerbose); |
|
324 return KErrNone; |
|
325 } |
|
326 |
|
327 |
|
328 int dodump(const char* ifilename) |
|
329 { |
|
330 E32ImageFile f; |
|
331 TInt r = f.Open(ifilename); |
|
332 if (r>0) |
|
333 return 1; |
|
334 else if (r==KErrCorrupt || r==KErrNotSupported) |
|
335 { |
|
336 Print(EError,"%s is not a valid E32Image file.\n",ifilename); |
|
337 return 1; |
|
338 } |
|
339 else if (r!=0) |
|
340 { |
|
341 Print(EError,"Error %d reading %s.\n",r,ifilename); |
|
342 return 1; |
|
343 } |
|
344 f.Dump((TText*)ifilename, gVerbose ? gVerbose : E32ImageFile::EDumpDefaults); |
|
345 return KErrNone; |
|
346 } |
|
347 |
|
348 int doalter(const char* ifilename) |
|
349 { |
|
350 E32ImageFile f; |
|
351 TInt r = f.Open(ifilename); |
|
352 if (r>0) |
|
353 return 1; |
|
354 else if (r==KErrCorrupt || r==KErrNotSupported) |
|
355 { |
|
356 Print(EError,"%s is not a valid E32Image file.\n",ifilename); |
|
357 return 1; |
|
358 } |
|
359 else if (r!=0) |
|
360 { |
|
361 Print(EError,"Error %d reading %s.\n",r,ifilename); |
|
362 return 1; |
|
363 } |
|
364 |
|
365 TUint hdrfmt = f.iHdr->HeaderFormat(); |
|
366 if (hdrfmt != KImageHdrFmt_V) |
|
367 { |
|
368 Print(EError,"Can't modify old format binaries\n"); |
|
369 return 1; |
|
370 } |
|
371 |
|
372 if (gDataBase) |
|
373 { |
|
374 Print(EWarning, "Ignoring -datalinkaddress Switch"); |
|
375 } |
|
376 if (gSetStack) |
|
377 f.SetStackSize(gStack); |
|
378 if (gSetHeap) |
|
379 { |
|
380 f.SetHeapSizeMin(gHeapMin); |
|
381 f.SetHeapSizeMax(gHeapMax); |
|
382 } |
|
383 if (!gSetUid1) |
|
384 gUid1=TUid::Uid(f.iHdr->iUid1); |
|
385 if (!gSetUid2) |
|
386 gUid2=TUid::Uid(f.iHdr->iUid2); |
|
387 if (!gSetUid3) |
|
388 gUid3=TUid::Uid(f.iHdr->iUid3); |
|
389 f.SetUids(gUid1, gUid2, gUid3); |
|
390 if (gSetSecureId) |
|
391 f.SetSecureId(gSecureId); |
|
392 if (gSetVendorId) |
|
393 f.SetVendorId(gVendorId); |
|
394 if (gSetCallEntryPoints) |
|
395 f.SetCallEntryPoints(gCallEntryPoints); |
|
396 if (gSetCapability) |
|
397 f.SetCapability(gCapability); |
|
398 if (gSetPriority) |
|
399 { |
|
400 if (f.iHdr->iFlags&KImageDll) |
|
401 Print(EWarning,"Cannot set priority of a DLL.\n"); |
|
402 else |
|
403 f.SetPriority((TProcessPriority)gPriority); |
|
404 } |
|
405 if (gSetFixedAddress) |
|
406 { |
|
407 if (f.iHdr->iFlags&KImageDll) |
|
408 Print(EWarning,"Cannot set fixed address for DLL.\n"); |
|
409 else |
|
410 f.SetFixedAddress(gFixedAddress); |
|
411 } |
|
412 if (gSetVersion) |
|
413 f.iHdr->iModuleVersion = gVersionWord; |
|
414 |
|
415 if(gCompress) |
|
416 { |
|
417 switch(gCompressionMethod) |
|
418 { |
|
419 case ENoCompression: |
|
420 f.iHdr->iCompressionType = KFormatNotCompressed; |
|
421 break; |
|
422 |
|
423 case EDeflate: |
|
424 f.iHdr->iCompressionType = KUidCompressionDeflate; |
|
425 |
|
426 break; |
|
427 |
|
428 case EBytePair: |
|
429 f.iHdr->iCompressionType = KUidCompressionBytePair; |
|
430 |
|
431 break; |
|
432 |
|
433 default: |
|
434 Print(EError, "Unknown compression method:%d", gCompressionMethod); |
|
435 return 1; |
|
436 |
|
437 } // End of switch() |
|
438 } |
|
439 else |
|
440 f.iHdr->iCompressionType = KFormatNotCompressed; |
|
441 |
|
442 if (gSetFPU) |
|
443 f.SetFPU(gFPU); |
|
444 |
|
445 r = setPagedFlags(f); |
|
446 if (r != KErrNone) |
|
447 { |
|
448 return r; |
|
449 } |
|
450 |
|
451 setDebuggableFlags(f); |
|
452 |
|
453 setSmpSafeFlags(f); |
|
454 |
|
455 f.UpdateHeaderCrc(); |
|
456 r = f.Validate(); |
|
457 if (r!=KErrNone) |
|
458 return r; |
|
459 |
|
460 ofstream ofile(ifilename, ios::binary); |
|
461 if (!ofile) |
|
462 { |
|
463 Print(EError,"Cannot open %s for output.\n",ifilename); |
|
464 return 1; |
|
465 } |
|
466 ofile << f; |
|
467 ofile.close(); |
|
468 if (gVerbose) |
|
469 f.Dump((TText *)ifilename,gVerbose); |
|
470 return KErrNone; |
|
471 } |
|
472 |
|
473 int helpme(char *aStr) |
|
474 { |
|
475 Print(EAlways,"Syntax: %s [options] inputfile outputfile\n",aStr); |
|
476 Print(EAlways," %s [options] e32imagefile\n",aStr); |
|
477 Print(EAlways,"option: [-v] [[-no]call[entrypoint]] [-priority <priority>]\n"); |
|
478 Print(EAlways," [-stack <size>] [-heap <min> <max>] [-uid<n> <uid>]\n"); |
|
479 Print(EAlways," [-allowdlldata] [-datalinkaddress <base>] [-fixed] [-moving]\n"); |
|
480 Print(EAlways," [-align-const-section] [-const-section-address-mask <mask>]\n"); |
|
481 Print(EAlways," [-[no]compress] [-compressionmethod none|deflate|bytepair]\n"); |
|
482 Print(EAlways," [-capability \"<list>\"] [-version M.m] [-vid <id>]\n"); |
|
483 Print(EAlways," [-fpu <softvfp|vfpv2>]\n"); |
|
484 Print(EAlways," [-codepaging <paged|unpaged|default>]\n"); |
|
485 Print(EAlways," [-datapaging <paged|unpaged|default>]\n"); |
|
486 Print(EAlways," [-debuggable]\n"); |
|
487 Print(EAlways," [-smpsafe]\n"); |
|
488 Print(EAlways," [-sym_name_lkup]\n"); |
|
489 Print(EAlways," [-dump [h][s][c][d][e][i]]\n"); |
|
490 Print(EAlways,"flags for dump: h Header\n"); |
|
491 Print(EAlways," s Security info\n"); |
|
492 Print(EAlways," c Code section\n"); |
|
493 Print(EAlways," d Data section\n"); |
|
494 Print(EAlways," e Export info\n"); |
|
495 Print(EAlways," i Import table\n"); |
|
496 return KErrArgument; |
|
497 } |
|
498 |
|
499 int isNumber(char *aStr) |
|
500 { |
|
501 return (aStr[0]>='0') && (aStr[0]<='9'); |
|
502 } |
|
503 |
|
504 int getUIntArg(unsigned int &aVal, int argc, char *argv[], int i) |
|
505 { |
|
506 if (i>=argc) |
|
507 return KErrArgument; |
|
508 if (!isNumber(argv[i])) |
|
509 return KErrArgument; |
|
510 #ifdef __LINUX__ |
|
511 int n; |
|
512 sscanf(argv[i], "%i", &n); |
|
513 aVal = n; |
|
514 #else |
|
515 #ifdef __TOOLS2__ |
|
516 istringstream s(argv[i]/*, strlen(argv[i])*/); |
|
517 #else |
|
518 istrstream s(argv[i], strlen(argv[i])); |
|
519 #endif |
|
520 |
|
521 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) |
|
522 s >> setbase(0); |
|
523 #endif //__MSVCDOTNET__ |
|
524 |
|
525 s >> aVal; |
|
526 #endif // __LINUX__ |
|
527 return KErrNone; |
|
528 } |
|
529 |
|
530 int getCapabilitiesArg(SCapabilitySet& aVal, int argc, char *argv[], int i) |
|
531 { |
|
532 memset(&aVal,0,sizeof(aVal)); |
|
533 if (i>=argc) |
|
534 return KErrArgument; |
|
535 if (isNumber(argv[i])) |
|
536 return getUIntArg(*(TUint*)&aVal[0], argc, argv, i); |
|
537 return ParseCapabilitiesArg(aVal,argv[i]); |
|
538 } |
|
539 |
|
540 int getPriorityArg(int &aVal, int argc, char *argv[], int i) |
|
541 { |
|
542 |
|
543 if (i>=argc) |
|
544 return KErrArgument; |
|
545 if (isNumber(argv[i])) |
|
546 { |
|
547 #ifdef __LINUX__ |
|
548 int n; |
|
549 sscanf(argv[i], "%i", &n); |
|
550 aVal = n; |
|
551 #else |
|
552 #ifdef __TOOLS2__ |
|
553 istringstream s(argv[i]); |
|
554 #else |
|
555 istrstream s(argv[i], strlen(argv[i])); |
|
556 #endif |
|
557 |
|
558 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) |
|
559 s >> setbase(0); |
|
560 #endif //__MSVCDOTNET__ |
|
561 |
|
562 s>>aVal; |
|
563 #endif // __LINUX__ |
|
564 } |
|
565 else |
|
566 { |
|
567 if (stricmp(argv[i], "low")==0) |
|
568 aVal=EPriorityLow; |
|
569 else if (strnicmp(argv[i], "background",4)==0) |
|
570 aVal=EPriorityBackground; |
|
571 else if (strnicmp(argv[i], "foreground",4)==0) |
|
572 aVal=EPriorityForeground; |
|
573 else if (stricmp(argv[i], "high")==0) |
|
574 aVal=EPriorityHigh; |
|
575 else if (strnicmp(argv[i], "windowserver",3)==0) |
|
576 aVal=EPriorityWindowServer; |
|
577 else if (strnicmp(argv[i], "fileserver",4)==0) |
|
578 aVal=EPriorityFileServer; |
|
579 else if (strnicmp(argv[i], "realtime",4)==0) |
|
580 aVal=EPriorityRealTimeServer; |
|
581 else if (strnicmp(argv[i], "supervisor",3)==0) |
|
582 aVal=EPrioritySupervisor; |
|
583 else |
|
584 { |
|
585 Print(EError, "Unrecognised priority\n"); |
|
586 return KErrArgument; |
|
587 } |
|
588 } |
|
589 if (aVal<EPriorityLow || aVal>EPrioritySupervisor) |
|
590 { |
|
591 Print(EError, "Priority out of range\n"); |
|
592 return KErrArgument; |
|
593 } |
|
594 return KErrNone; |
|
595 } |
|
596 |
|
597 int getVersionArg(unsigned int& aVal, const char* aArg) |
|
598 { |
|
599 const char* s = aArg; |
|
600 unsigned int major = 0; |
|
601 unsigned int minor = 0; |
|
602 for (; major<=6553 && *s>='0' && *s<='9'; ++s) |
|
603 major = major*10 + (*s - '0'); |
|
604 if (*s == '.') |
|
605 { |
|
606 for (++s; minor<=6553 && *s>='0' && *s<='9'; ++s) |
|
607 minor = minor*10 + (*s - '0'); |
|
608 if (*s==0 && major<32768 && minor<32768) |
|
609 { |
|
610 aVal = (major << 16) | minor; |
|
611 return KErrNone; |
|
612 } |
|
613 } |
|
614 Print(EError, "Bad argument to -version\n"); |
|
615 return KErrArgument; |
|
616 } |
|
617 |
|
618 int getFPUArg(unsigned int &aVal, int argc, char *argv[], int i) |
|
619 { |
|
620 if (i>=argc) |
|
621 return KErrArgument; |
|
622 else if (strnicmp(argv[i], "softvfp", 7)==0) |
|
623 aVal = 0; |
|
624 else if (strnicmp(argv[i], "vfpv2", 5)==0) |
|
625 aVal = 1; |
|
626 else |
|
627 { |
|
628 Print(EError, "Bad argument to -fpu\n"); |
|
629 return KErrArgument; |
|
630 } |
|
631 |
|
632 return KErrNone; |
|
633 } |
|
634 |
|
635 int getCompressionMethod(int &aVal, int argc, char *argv[], int i) |
|
636 { |
|
637 if( i >= argc || argv[i] == NULL) |
|
638 { |
|
639 Print(EError, "Missing argument to -compressionmethod\n"); |
|
640 return KErrArgument; |
|
641 } |
|
642 else if (strnicmp(argv[i], "none", 2) == 0) |
|
643 { |
|
644 aVal = ENoCompression; |
|
645 } |
|
646 else if (strnicmp(argv[i], "deflate", 7) == 0) |
|
647 { |
|
648 aVal = EDeflate; |
|
649 } |
|
650 else if (strnicmp(argv[i], "bytepair", 8) == 0) |
|
651 { |
|
652 aVal = EBytePair; |
|
653 } |
|
654 else |
|
655 { |
|
656 Print(EError, "Bad argument '%s' to -compressionmethod\n", argv[i]); |
|
657 return KErrArgument; |
|
658 } |
|
659 |
|
660 return KErrNone; |
|
661 |
|
662 } |
|
663 |
|
664 |
|
665 int processCL(int argc, char *argv[]) |
|
666 { |
|
667 |
|
668 int r=KErrNone; |
|
669 int i=1; |
|
670 while (i<argc) |
|
671 { |
|
672 if (stricmp("-v", argv[i])==0) |
|
673 gVerbose |= E32ImageFile::EDumpDefaults; |
|
674 else if (stricmp("-dump", argv[i])==0) |
|
675 { |
|
676 i++; |
|
677 if (i>=argc) |
|
678 return KErrArgument; |
|
679 char* s=argv[i]; |
|
680 while(char c = *(s++)) |
|
681 { |
|
682 if(c<'a') |
|
683 c += 'a'-'A'; |
|
684 switch(c) |
|
685 { |
|
686 case 'h': gVerbose |= E32ImageFile::EDumpHeader; break; |
|
687 case 's': gVerbose |= E32ImageFile::EDumpSecurityInfo; break; |
|
688 case 'c': gVerbose |= E32ImageFile::EDumpCode; break; |
|
689 case 'd': gVerbose |= E32ImageFile::EDumpData; break; |
|
690 case 'e': gVerbose |= E32ImageFile::EDumpExports; break; |
|
691 case 'i': gVerbose |= E32ImageFile::EDumpImports; break; |
|
692 default: return KErrArgument; |
|
693 } |
|
694 } |
|
695 } |
|
696 else if (stricmp("-stack", argv[i])==0) |
|
697 { |
|
698 i++; |
|
699 gSetStack=TRUE; |
|
700 r=getUIntArg(gStack, argc, argv, i); |
|
701 } |
|
702 else if (stricmp("-uid1", argv[i])==0) |
|
703 { |
|
704 i++; |
|
705 gSetUid1=TRUE; |
|
706 unsigned int id; |
|
707 r=getUIntArg(id, argc, argv, i); |
|
708 gUid1=TUid::Uid(id); |
|
709 } |
|
710 else if (stricmp("-uid2", argv[i])==0) |
|
711 { |
|
712 i++; |
|
713 gSetUid2=TRUE; |
|
714 unsigned int id; |
|
715 r=getUIntArg(id, argc, argv, i); |
|
716 gUid2=TUid::Uid(id); |
|
717 } |
|
718 else if (stricmp("-uid3", argv[i])==0) |
|
719 { |
|
720 i++; |
|
721 gSetUid3=TRUE; |
|
722 unsigned int id; |
|
723 r=getUIntArg(id, argc, argv, i); |
|
724 gUid3=TUid::Uid(id); |
|
725 } |
|
726 else if (stricmp("-version", argv[i])==0) |
|
727 { |
|
728 i++; |
|
729 r=getVersionArg(gVersionWord, argv[i]); |
|
730 gSetVersion=TRUE; |
|
731 } |
|
732 else if (stricmp("-sid", argv[i])==0) |
|
733 { |
|
734 i++; |
|
735 r=getUIntArg(gSecureId, argc, argv, i); |
|
736 gSetSecureId=TRUE; |
|
737 } |
|
738 else if (stricmp("-vid", argv[i])==0) |
|
739 { |
|
740 i++; |
|
741 r=getUIntArg(gVendorId, argc, argv, i); |
|
742 gSetVendorId=TRUE; |
|
743 } |
|
744 else if (strnicmp("-nocall", argv[i], 7)==0) |
|
745 { |
|
746 gSetCallEntryPoints=TRUE; |
|
747 gCallEntryPoints=FALSE; |
|
748 } |
|
749 else if (strnicmp("-call", argv[i], 5)==0) |
|
750 { |
|
751 gSetCallEntryPoints=TRUE; |
|
752 gCallEntryPoints=TRUE; |
|
753 } |
|
754 else if (strnicmp("-fixed", argv[i], 3)==0) |
|
755 { |
|
756 gSetFixedAddress=TRUE; |
|
757 gFixedAddress=TRUE; |
|
758 } |
|
759 else if (strnicmp("-moving", argv[i], 3)==0) |
|
760 { |
|
761 gSetFixedAddress=TRUE; |
|
762 gFixedAddress=FALSE; |
|
763 } |
|
764 else if (strnicmp("-priority", argv[i], 4)==0) |
|
765 { |
|
766 i++; |
|
767 gSetPriority=TRUE; |
|
768 r=getPriorityArg(gPriority,argc,argv,i); |
|
769 } |
|
770 else if (strnicmp("-capability", argv[i], 10)==0) |
|
771 { |
|
772 i++; |
|
773 gSetCapability=TRUE; |
|
774 r=getCapabilitiesArg(gCapability, argc, argv, i); |
|
775 } |
|
776 else if (strnicmp("-heap", argv[i], 4)==0) |
|
777 { |
|
778 i++; |
|
779 gSetHeap=TRUE; |
|
780 r=getUIntArg(gHeapMin, argc, argv, i); |
|
781 if (r==KErrNone) |
|
782 r=getUIntArg(gHeapMax, argc, argv, ++i); |
|
783 } |
|
784 else if (strnicmp("-allow", argv[i], 6)==0) // Note, toolchain passes 'allow' for 'allowdlldata' |
|
785 { |
|
786 gAllowDllData=TRUE; |
|
787 } |
|
788 else if( strnicmp("-compressionmethod", argv[i], 18) == 0) |
|
789 { |
|
790 if(!gSuppressComprMethod) |
|
791 { |
|
792 gCompress = TRUE; |
|
793 gSetCompress = TRUE; |
|
794 r = getCompressionMethod(gCompressionMethod, argc, argv, ++i); |
|
795 } |
|
796 else |
|
797 { |
|
798 ++i; // Skip the compression method because compessionmethod suppressed. |
|
799 } |
|
800 } |
|
801 else if (strnicmp("-compress", argv[i], 9)==0) |
|
802 { |
|
803 gCompress=TRUE; |
|
804 gSetCompress=TRUE; |
|
805 gSuppressComprMethod=FALSE; |
|
806 } |
|
807 else if (strnicmp("-nocompress", argv[i], 11)==0) |
|
808 { |
|
809 gCompress=FALSE; |
|
810 gSetCompress=TRUE; |
|
811 gSuppressComprMethod = TRUE; |
|
812 gCompressionMethod = ENoCompression; |
|
813 } |
|
814 else if (strnicmp("-datalinkaddress", argv[i], 16)==0) |
|
815 { |
|
816 i++; |
|
817 r=getUIntArg(gDataBase, argc, argv, i); |
|
818 } |
|
819 else if (strnicmp("-align-const-section", argv[i], 20)==0) |
|
820 { |
|
821 gAlignConstSection=TRUE; |
|
822 } |
|
823 else if (strnicmp("-const-section-address-mask", argv[i], 27)==0) |
|
824 { |
|
825 i++; |
|
826 r=getUIntArg(gConstSectionAddressMask, argc, argv, i); |
|
827 } |
|
828 else if (strnicmp("-fpu", argv[i], 4)==0) |
|
829 { |
|
830 i++; |
|
831 r=getFPUArg(gFPU, argc, argv, i); |
|
832 gSetFPU=TRUE; |
|
833 } |
|
834 else if (strnicmp("-paged", argv[i], 6) == 0) |
|
835 { |
|
836 gCodePaged=TRUE; |
|
837 gSetCodePaged=TRUE; |
|
838 } |
|
839 else if (strnicmp("-unpaged", argv[i], 8) == 0) |
|
840 { |
|
841 gCodeUnpaged=TRUE; |
|
842 gSetCodePaged=TRUE; |
|
843 } |
|
844 else if (strnicmp("-defaultpaged", argv[i], 13) == 0) |
|
845 { |
|
846 gCodeDefaultPaged=TRUE; |
|
847 gSetCodePaged=TRUE; |
|
848 } |
|
849 else if (strnicmp("-codepaging", argv[i], 11)==0) |
|
850 { |
|
851 i++; |
|
852 |
|
853 if (i>=argc) |
|
854 { |
|
855 r = KErrArgument; |
|
856 } |
|
857 else if ( strnicmp(argv[i], "paged", 5) == 0 ) |
|
858 { |
|
859 gCodePaged=TRUE; |
|
860 } |
|
861 else if ( strnicmp(argv[i], "unpaged", 7) == 0 ) |
|
862 { |
|
863 gCodeUnpaged=TRUE; |
|
864 } |
|
865 else if ( strnicmp(argv[i], "default", 7) == 0 ) |
|
866 { |
|
867 gCodeDefaultPaged=TRUE; |
|
868 } |
|
869 else |
|
870 { |
|
871 Print(EError, "Bad argument to -codepaging\n"); |
|
872 r = KErrArgument; |
|
873 } |
|
874 |
|
875 gSetCodePaged=TRUE; |
|
876 } |
|
877 else if (strnicmp("-datapaging", argv[i], 11)==0) |
|
878 { |
|
879 i++; |
|
880 |
|
881 if (i>=argc) |
|
882 { |
|
883 r = KErrArgument; |
|
884 } |
|
885 else if ( strnicmp(argv[i], "paged", 5) == 0 ) |
|
886 { |
|
887 gDataPaged=TRUE; |
|
888 } |
|
889 else if ( strnicmp(argv[i], "unpaged", 7) == 0 ) |
|
890 { |
|
891 gDataUnpaged=TRUE; |
|
892 } |
|
893 else if ( strnicmp(argv[i], "default", 7) == 0 ) |
|
894 { |
|
895 gDataDefaultPaged=TRUE; |
|
896 } |
|
897 else |
|
898 { |
|
899 Print(EError, "Bad argument to -datapaging\n"); |
|
900 r = KErrArgument; |
|
901 } |
|
902 |
|
903 gSetDataPaged=TRUE; |
|
904 } |
|
905 else if (strnicmp("-sym_name_lkup", argv[i], 14) == 0) |
|
906 { |
|
907 gSetSymLkup=TRUE; |
|
908 } |
|
909 else if (strnicmp("-debuggable", argv[i], 11) == 0) |
|
910 { |
|
911 gDebuggable=TRUE; |
|
912 gSetDebuggable=TRUE; |
|
913 } |
|
914 else if (strnicmp("-smpsafe", argv[i], 8) == 0) |
|
915 { |
|
916 gSmpSafe=TRUE; |
|
917 gSetSmpSafe=TRUE; |
|
918 } |
|
919 #ifdef __SUPPORT_PE_FILES__ |
|
920 else if (strnicmp("-x86imp=", argv[i], 8)==0) |
|
921 { |
|
922 const char* x86impfile=argv[i]+8; |
|
923 // printf("%s\n",x86impfile); |
|
924 FILE* f=fopen(x86impfile,"rb"); |
|
925 if (!f) |
|
926 r=KErrArgument; |
|
927 else |
|
928 { |
|
929 fseek(f,0,SEEK_END); |
|
930 long size=ftell(f); |
|
931 fseek(f,0,SEEK_SET); |
|
932 if (size>4) |
|
933 { |
|
934 gX86imp=new char[size]; |
|
935 fread(gX86imp,1,size,f); |
|
936 } |
|
937 fclose(f); |
|
938 r=KErrNone; |
|
939 if (gX86imp) |
|
940 { |
|
941 gX86imp_size=ALIGN4(size); |
|
942 // printf("size %d\n",size); |
|
943 int i; |
|
944 int* p=(int*)gX86imp; |
|
945 gX86num_imp_dlls=*p++; |
|
946 for (i=0; i<gX86num_imp_dlls; ++i) |
|
947 { |
|
948 ++p; |
|
949 int n=*p++; |
|
950 gX86num_imports+=n; |
|
951 p+=n; |
|
952 } |
|
953 // fprintf(stderr,"#imports=%d\n",gX86num_imports); |
|
954 } |
|
955 } |
|
956 } |
|
957 #endif |
|
958 else if (gFile1==NULL) |
|
959 { |
|
960 gFile1 = NormaliseFileName(argv[i]); |
|
961 } |
|
962 else if (gFile2==NULL) |
|
963 { |
|
964 gFile2 = NormaliseFileName(argv[i]); |
|
965 } |
|
966 else |
|
967 r=KErrArgument; |
|
968 if (r!=KErrNone) |
|
969 return r; |
|
970 i++; |
|
971 } |
|
972 return KErrNone; |
|
973 } |
|
974 |
|
975 int main(int argc, char *argv[]) |
|
976 { |
|
977 #ifdef __SUPPORT_PE_FILES__ |
|
978 Print(EAlways,"\nPETRAN - PE file preprocessor"); |
|
979 #endif |
|
980 #ifdef __SUPPORT_ELF_FILES__ |
|
981 Print(EAlways,"\nELFTRAN - ELF file preprocessor"); |
|
982 #endif |
|
983 Print(EAlways," V%02d.%02d (Build %03d)\n",MajorVersion,MinorVersion,Build); |
|
984 int r=processCL(argc, argv); |
|
985 if (r!=KErrNone) |
|
986 return helpme(argv[0]); |
|
987 if (gFile2) |
|
988 return dotran(gFile1, gFile2); |
|
989 if ((gSetStack || gSetUid1 || gSetUid2 || gSetUid3 || gSetCallEntryPoints || gSetPriority |
|
990 || gSetCapability || gSetCompress || gSetHeap || gSetVersion || gSetSecureId |
|
991 || gSetVendorId || gSetFixedAddress || gSetFPU || gSetCodePaged || gSetDataPaged || gSetDebuggable || gSetSmpSafe) && gFile1) |
|
992 return doalter(gFile1); |
|
993 if (gFile1) |
|
994 return dodump(gFile1); |
|
995 helpme(argv[0]); |
|
996 return KErrArgument; |
|
997 } |