1 /**************************** main.cpp **********************************
2 * Author: Agner Fog
3 * Date created: 2006-07-26
4 * Last modified: 2011-10-28
5 * Project: objconv
6 * Module: main.cpp
7 * Description:
8 * Objconv is a portable C++ program for converting object file formats.
9 * Compile for console mode on any platform.
10 *
11 * Module main contains the program entry
12 *
13 * Copyright 2006-2011 GNU General Public License http://www.gnu.org/licenses
14 *****************************************************************************/
15
16 #include "stdafx.h"
17
18 // Texts of option feedback. Adding or removing leading underscores on symbols
19 SIntTxt UnderscoreOptionNames[] = {
20 {CMDL_UNDERSCORE_NOCHANGE, "Not adding or removing underscores for this filetype"},
21 {CMDL_UNDERSCORE_REMOVE, "Removing leading underscores from symbol names"},
22 {CMDL_UNDERSCORE_ADD, "Adding leading underscores to symbol names"},
23 {CMDL_UNDERSCORE_REMOVE|CMDL_KEEP_ALIAS, "Removing leading underscores from symbol names. Keeping old name as alias"},
24 {CMDL_UNDERSCORE_ADD|CMDL_KEEP_ALIAS, "Adding leading underscores to symbol names. Keeping old name as alias"}
25 };
26
27 // Texts of option feedback. Changing leading dot or underscore on section names
28 SIntTxt SectionDotOptionNames[] = {
29 {CMDL_SECTIONDOT_NOCHANGE, "Not changing leading character on section names for this filetype"},
30 {CMDL_SECTIONDOT_U2DOT, "Changing leading underscores on section names to dot"},
31 {CMDL_SECTIONDOT_DOT2U, "Changing leading dot on nonstandard section names to underscore"}
32 };
33
34 // Check that integer type definitions are correct.
35 // Will generate an error message if the compiler makes the integer types
36 // with wrong size.
CheckIntegerTypes()37 static void CheckIntegerTypes() {
38 if (
39 sizeof(uint8_t) != 1 ||
40 sizeof(int16_t) != 2 ||
41 sizeof(int32_t) != 4 ||
42 sizeof(int64_t) != 8) {
43 err.submit(9001); // Make error message if type definitions are wrong
44 }
45 }
46
47 // Check that we are running on a machine with little-endian memory organization
CheckEndianness()48 static void CheckEndianness() {
49 static uint8_t bytes[4] = {1, 2, 3, 4};
50 if (*(uint32_t*)bytes != 0x04030201) {
51 // Big endian
52 err.submit(9002);
53 }
54 }
55
56 // Function to convert powers of 2 to index
FloorLog2(uint32_t x)57 int FloorLog2(uint32_t x) {
58 int i = -1;
59 do {
60 x >>= 1;
61 i++;
62 } while (x);
63 return i;
64 }
65
timestring(uint32_t t)66 const char * timestring(uint32_t t) {
67 // Convert 32 bit time stamp to string
68 // Fix the problem that time_t may be 32 bit or 64 bit
69 union {
70 time_t t;
71 uint32_t t32;
72 } utime;
73 utime.t = 0;
74 utime.t32 = t;
75 const char * string = ctime(&utime.t);
76 if (string == 0) string = "?";
77 return string;
78 }
79
80 // Main. Program starts here
main(int argc,char * argv[])81 int main(int argc, char * argv[]) {
82 CheckIntegerTypes(); // Check that compiler has the right integer sizes
83 CheckEndianness(); // Check that machine is little-endian
84
85 #ifdef _DEBUG
86 // For debugging only. You may remove this
87 if (argc == 1) {
88 const char * dummyarg[] = {"", "@resp.txt"}; // Read command line from file resp.txt
89 argc = 2; argv = (char**)dummyarg;}
90 #endif
91
92 cmd.ReadCommandLine(argc, argv); // Read command line parameters
93 if (cmd.ShowHelp) return 0; // Help screen has been printed. Do nothing else
94
95 CMain maincvt; // This object takes care of all conversions etc.
96 maincvt.Go();
97 // Do everything the command line says
98
99 if (cmd.Verbose) printf("\n"); // End with newline
100 return err.GetWorstError(); // Return with error code
101 }
102
103
104 // Class CMainConverter is used for control of the conversion process
CMain()105 CMain::CMain() : CFileBuffer() {
106 }
107
Go()108 void CMain::Go() {
109 // Do whatever the command line parameters say
110 FileName = cmd.InputFile; // Get input file name from command line
111 // Ignore nonexisting filename when building library
112 int IgnoreError = (cmd.FileOptions & CMDL_FILE_IN_IF_EXISTS) && !cmd.OutputFile;
113 Read(IgnoreError); // Read input file
114 GetFileType(); // Determine file type
115 cmd.InputType = FileType; // Save input file type in cmd for access from other modules
116 if (cmd.OutputType == 0) {
117 // desired type not specified
118 cmd.OutputType = FileType;
119 }
120 if (err.Number()) return; // Return if error
121 CheckOutputFileName(); // Construct output file name with default extension
122 if (err.Number()) return;
123
124 if ((FileType & (FILETYPE_LIBRARY | FILETYPE_OMFLIBRARY))
125 || (cmd.LibraryOptions & CMDL_LIBRARY_ADDMEMBER)) {
126 // Input file is a library or we are building a library
127 CLibrary lib; // Library handler object
128 *this >> lib; // Transfer my file buffer to lib
129 lib.Go(); // Do conversion or dump
130 *this << lib; // Get file buffer back
131 }
132 else {
133 // Input file is an object file
134 CConverter conv; // Make converter object
135 *this >> conv; // Transfer my file buffer to conv
136 conv.Go(); // Do conversion or dump
137 *this << conv; // Get file buffer back
138 }
139 if ((cmd.FileOptions & CMDL_FILE_OUTPUT) && OutputFileName) {
140 // There is an output file to write
141 cmd.CheckSymbolModifySuccess(); // Check if symbols to modify were found
142 if (err.Number()) return; // Return if error
143 FileName = OutputFileName; // Output file name
144 Write(); // Write output file
145 if (cmd.Verbose) cmd.ReportStatistics(); // Report statistics
146 }
147 }
148
CConverter()149 CConverter::CConverter() {
150 // Constructor
151 }
152
DumpCOF()153 void CConverter::DumpCOF() {
154 // Dump COFF file
155 CCOFF cof; // Make object for interpreting COFF file
156 *this >> cof; // Give it my buffer
157 cof.ParseFile(); // Parse file buffer
158 if (err.Number()) return; // Return if error
159 cof.Dump(cmd.DumpOptions); // Dump file
160 *this << cof; // Take back my buffer
161 }
162
DumpELF()163 void CConverter::DumpELF() {
164 // Dump ELF file
165 if (WordSize == 32) {
166 // Make object for interpreting 32 bit ELF file
167 CELF<ELF32STRUCTURES> elf;
168 *this >> elf; // Give it my buffer
169 elf.ParseFile(); // Parse file buffer
170 if (err.Number()) return; // Return if error
171 elf.Dump(cmd.DumpOptions); // Dump file
172 *this << elf; // Take back my buffer
173 }
174 else {
175 // Make object for interpreting 32 bit ELF file
176 CELF<ELF64STRUCTURES> elf;
177 *this >> elf; // Give it my buffer
178 elf.ParseFile(); // Parse file buffer
179 if (err.Number()) return; // Return if error
180 elf.Dump(cmd.DumpOptions); // Dump file
181 *this << elf; // Take back my buffer
182 }
183 }
184
DumpMACHO()185 void CConverter::DumpMACHO() {
186 // Dump Mach-O file
187 if (WordSize == 32) {
188 // Make object for interpreting 32 bit Mach-O file
189 CMACHO<MAC32STRUCTURES> macho;
190 *this >> macho; // Give it my buffer
191 macho.ParseFile(); // Parse file buffer
192 if (err.Number()) return; // Return if error
193 macho.Dump(cmd.DumpOptions); // Dump file
194 *this << macho; // Take back my buffer
195 }
196 else {
197 // Make object for interpreting 64 bit Mach-O file
198 CMACHO<MAC64STRUCTURES> macho;
199 *this >> macho; // Give it my buffer
200 macho.ParseFile(); // Parse file buffer
201 if (err.Number()) return; // Return if error
202 macho.Dump(cmd.DumpOptions); // Dump file
203 *this << macho; // Take back my buffer
204 }
205 }
206
ParseMACUnivBin()207 void CConverter::ParseMACUnivBin() {
208 // Dump Mac universal binary
209 CMACUNIV macuniv; // Make object for interpreting Mac universal binary file
210 *this >> macuniv; // Give it my buffer
211 macuniv.Go(cmd.DumpOptions); // Dump file components
212 *this << macuniv; // Take back my buffer
213 }
214
DumpOMF()215 void CConverter::DumpOMF() {
216 // Dump OMF file
217 COMF omf; // Make object for interpreting OMF file
218 *this >> omf; // Give it my buffer
219 omf.ParseFile(); // Parse file buffer
220 if (err.Number()) return; // Return if error
221 omf.Dump(cmd.DumpOptions); // Dump file
222 *this << omf; // Take back my buffer
223 }
224
COF2ELF()225 void CConverter::COF2ELF() {
226 // Convert COFF to ELF file
227 if (WordSize == 32) {
228 // Make instance of converter, 32 bit template
229 CCOF2ELF<ELF32STRUCTURES> conv; // Make object for conversion
230 *this >> conv; // Give it my buffer
231 conv.ParseFile(); // Parse file buffer
232 if (err.Number()) return; // Return if error
233 conv.Convert(); // Convert
234 *this << conv; // Take back converted buffer
235 }
236 else {
237 // Make instance of converter, 64 bit template
238 CCOF2ELF<ELF64STRUCTURES> conv; // Make object for conversion
239 *this >> conv; // Give it my buffer
240 conv.ParseFile(); // Parse file buffer
241 if (err.Number()) return; // Return if error
242 conv.Convert(); // Convert
243 *this << conv; // Take back converted buffer
244 }
245 }
246
COF2OMF()247 void CConverter::COF2OMF() {
248 // Convert COFF to OMF file
249 CCOF2OMF conv; // Make object for conversion
250 *this >> conv; // Give it my buffer
251 conv.ParseFile(); // Parse file buffer
252 if (err.Number()) return; // Return if error
253 conv.Convert(); // Convert
254 *this << conv; // Take back converted buffer
255 }
256
OMF2COF()257 void CConverter::OMF2COF() {
258 // Convert OMF to COFF file
259 COMF2COF conv; // Make object for conversion
260 *this >> conv; // Give it my buffer
261 conv.ParseFile(); // Parse file buffer
262 if (err.Number()) return; // Return if error
263 conv.Convert(); // Convert
264 *this << conv; // Take back converted buffer
265 }
266
ELF2COF()267 void CConverter::ELF2COF() {
268 // Convert ELF to COFF file
269 if (WordSize == 32) {
270 // Make instance of converter, 32 bit template
271 CELF2COF<ELF32STRUCTURES> conv;
272 *this >> conv; // Give it my buffer
273 conv.ParseFile(); // Parse file buffer
274 if (err.Number()) return; // Return if error
275 conv.Convert(); // Convert
276 *this << conv; // Take back converted buffer
277 }
278 else {
279 // Make instance of converter, 64 bit template
280 CELF2COF<ELF64STRUCTURES> conv;
281 *this >> conv; // Give it my buffer
282 conv.ParseFile(); // Parse file buffer
283 if (err.Number()) return; // Return if error
284 conv.Convert(); // Convert
285 *this << conv; // Take back converted buffer
286 }
287 }
288
ELF2MAC()289 void CConverter::ELF2MAC() {
290 // Convert ELF to Mach-O file
291 if (WordSize == 32) {
292 // Make instance of converter, 32 bit template
293 CELF2MAC<ELF32STRUCTURES,MAC32STRUCTURES> conv;
294 *this >> conv; // Give it my buffer
295 conv.ParseFile(); // Parse file buffer
296 if (err.Number()) return; // Return if error
297 conv.Convert(); // Convert
298 *this << conv; // Take back converted buffer
299 }
300 else {
301 // Make instance of converter, 64 bit template
302 CELF2MAC<ELF64STRUCTURES,MAC64STRUCTURES> conv;
303 *this >> conv; // Give it my buffer
304 conv.ParseFile(); // Parse file buffer
305 if (err.Number()) return; // Return if error
306 conv.Convert(); // Convert
307 *this << conv; // Take back converted buffer
308 }
309 }
310
MAC2ELF()311 void CConverter::MAC2ELF() {
312 // Convert Mach-O file to ELF file
313 if (WordSize == 32) {
314 // Make instance of converter, 32 bit template
315 CMAC2ELF<MAC32STRUCTURES,ELF32STRUCTURES> conv;
316 *this >> conv; // Give it my buffer
317 conv.ParseFile(); // Parse file buffer
318 if (err.Number()) return; // Return if error
319 conv.Convert(); // Convert
320 *this << conv; // Take back converted buffer
321 }
322 else {
323 // Make instance of converter, 64 bit template
324 CMAC2ELF<MAC64STRUCTURES,ELF64STRUCTURES> conv;
325 *this >> conv; // Give it my buffer
326 conv.ParseFile(); // Parse file buffer
327 if (err.Number()) return; // Return if error
328 conv.Convert(); // Convert
329 *this << conv; // Take back converted buffer
330 }
331 }
332
COF2ASM()333 void CConverter::COF2ASM() {
334 // Disassemble COFF file
335 CCOF2ASM conv; // Make object for conversion
336 *this >> conv; // Give it my buffer
337 conv.ParseFile(); // Parse file buffer
338 if (err.Number()) return; // Return if error
339 conv.Convert(); // Convert
340 *this << conv; // Take back converted buffer
341 }
342
ELF2ASM()343 void CConverter::ELF2ASM() {
344 // Disassemble ELF file
345 if (WordSize == 32) {
346 // Make instance of converter, 32 bit template
347 CELF2ASM<ELF32STRUCTURES> conv;
348 *this >> conv; // Give it my buffer
349 conv.ParseFile(); // Parse file buffer
350 if (err.Number()) return; // Return if error
351 conv.Convert(); // Convert
352 *this << conv; // Take back converted buffer
353 }
354 else {
355 // Make instance of converter, 64 bit template
356 CELF2ASM<ELF64STRUCTURES> conv;
357 *this >> conv; // Give it my buffer
358 conv.ParseFile(); // Parse file buffer
359 if (err.Number()) return; // Return if error
360 conv.Convert(); // Convert
361 *this << conv; // Take back converted buffer
362 }
363 }
364
MAC2ASM()365 void CConverter::MAC2ASM() {
366 // Disassemble Mach-O file
367 if (WordSize == 32) {
368 // Make instance of converter, 32 bit template
369 CMAC2ASM<MAC32STRUCTURES> conv;
370 *this >> conv; // Give it my buffer
371 conv.ParseFile(); // Parse file buffer
372 if (err.Number()) return; // Return if error
373 conv.Convert(); // Convert
374 *this << conv; // Take back converted buffer
375 }
376 else {
377 // Make instance of converter, 64 bit template
378 CMAC2ASM<MAC64STRUCTURES> conv;
379 *this >> conv; // Give it my buffer
380 conv.ParseFile(); // Parse file buffer
381 if (err.Number()) return; // Return if error
382 conv.Convert(); // Convert
383 *this << conv; // Take back converted buffer
384 }
385 }
386
OMF2ASM()387 void CConverter::OMF2ASM() {
388 // Disassemble OMF file
389 COMF2ASM conv; // Make object for conversion
390 *this >> conv; // Give it my buffer
391 conv.ParseFile(); // Parse file buffer
392 if (err.Number()) return; // Return if error
393 conv.Convert(); // Convert
394 *this << conv; // Take back converted buffer
395 }
396
COF2COF()397 void CConverter::COF2COF() {
398 // Make changes in COFF file
399 CCOF2COF conv; // Make instance of converter
400 *this >> conv; // Give it my buffer
401 conv.ParseFile(); // Parse file buffer
402 if (err.Number()) return; // Return if error
403 conv.Convert(); // Convert
404 *this << conv; // Take back converted buffer
405 }
406
ELF2ELF()407 void CConverter::ELF2ELF() {
408 // Make changes in ELF file
409 if (WordSize == 32) {
410 // Make instance of converter, 32 bit template
411 CELF2ELF<ELF32STRUCTURES> conv;
412 *this >> conv; // Give it my buffer
413 conv.ParseFile(); // Parse file buffer
414 if (err.Number()) return; // Return if error
415 conv.Convert(); // Convert
416 *this << conv; // Take back converted buffer
417 }
418 else {
419 // Make instance of converter, 64 bit template
420 CELF2ELF<ELF64STRUCTURES> conv;
421 *this >> conv; // Give it my buffer
422 conv.ParseFile(); // Parse file buffer
423 if (err.Number()) return; // Return if error
424 conv.Convert(); // Convert
425 *this << conv; // Take back converted buffer
426 }
427 }
428
MAC2MAC()429 void CConverter::MAC2MAC() {
430 // Make changes in Mach-O file
431 if (WordSize == 32) {
432 // Make instance of converter, 32 bit template
433 CMAC2MAC<MAC32STRUCTURES> conv;
434 *this >> conv; // Give it my buffer
435 conv.ParseFile(); // Parse file buffer
436 if (err.Number()) return; // Return if error
437 conv.Convert(); // Convert
438 *this << conv; // Take back converted buffer
439 }
440 else {
441 // Make instance of converter, 64 bit template
442 CMAC2MAC<MAC64STRUCTURES> conv;
443 *this >> conv; // Give it my buffer
444 conv.ParseFile(); // Parse file buffer
445 if (err.Number()) return; // Return if error
446 conv.Convert(); // Convert
447 *this << conv; // Take back converted buffer
448 }
449 }
450
Go()451 void CConverter::Go() {
452 // Convert or dump file, depending on command line parameters
453 GetFileType(); // Determine file type
454 cmd.InputType = FileType; // Save input file type in cmd for access from other modules
455 if (err.Number()) return; // Return if error
456
457 if (cmd.OutputType == CMDL_OUTPUT_DUMP) {
458 // File dump requested
459 if (cmd.Verbose > 0) {
460 // Tell what we are doing:
461 printf("\nDump of file: %s, type: %s%i", FileName, GetFileFormatName(FileType), WordSize);
462 }
463
464 switch(FileType) {
465 case FILETYPE_ELF:
466 DumpELF(); break;
467
468 case FILETYPE_COFF:
469 DumpCOF(); break;
470
471 case FILETYPE_MACHO_LE:
472 DumpMACHO(); break;
473
474 case FILETYPE_OMF:
475 DumpOMF(); break;
476
477 case FILETYPE_MAC_UNIVBIN:
478 ParseMACUnivBin(); break;
479
480 default:
481 err.submit(2010, GetFileFormatName(FileType)); // Dump of this file type not supported
482 }
483 printf("\n"); // New line
484 }
485 else {
486 // File conversion requested
487 if (cmd.DesiredWordSize == 0) cmd.DesiredWordSize = WordSize;
488 if (WordSize && WordSize != cmd.DesiredWordSize) {
489 err.submit(2012, WordSize, cmd.DesiredWordSize); // Cannot convert word size
490 return;
491 }
492 if (Executable && cmd.OutputType != CMDL_OUTPUT_MASM) {
493 // Attempt to convert executable file
494 err.submit(2022);
495 }
496 if (err.Number()) return; // Return if error
497
498 if (cmd.Verbose > (uint32_t)(cmd.LibraryOptions != 0)) {
499 // Tell what we are doing:
500 printf("\nInput file: %s, output file: %s", FileName, OutputFileName);
501 if (FileType != cmd.OutputType) {
502 printf("\nConverting from %s%2i to %s%2i",
503 GetFileFormatName(FileType), WordSize,
504 GetFileFormatName(cmd.OutputType), WordSize);
505 }
506 else {
507 printf("\nModifying %s%2i file", GetFileFormatName(FileType), WordSize);
508 }
509 }
510
511 // Check underscore options
512 if (cmd.Underscore && cmd.OutputType != 0) {
513 if (cmd.Underscore == CMDL_UNDERSCORE_CHANGE) {
514 // Find underscore option for desired conversion
515 if (WordSize == 32) {
516 // In 32-bit, all formats except ELF have underscores
517 if (FileType == FILETYPE_ELF && cmd.OutputType != FILETYPE_ELF) {
518 // Converting from ELF32. Add underscores
519 cmd.Underscore = CMDL_UNDERSCORE_ADD;
520 }
521 else if (FileType != FILETYPE_ELF && cmd.OutputType == FILETYPE_ELF) {
522 // Converting to ELF32. Remove underscores
523 cmd.Underscore = CMDL_UNDERSCORE_REMOVE;
524 }
525 else {
526 // Anything else 32-bit. No change
527 cmd.Underscore = CMDL_UNDERSCORE_NOCHANGE;
528 }
529 }
530 else {
531 // In 64-bit, only Mach-O has underscores
532 if (FileType == FILETYPE_MACHO_LE && cmd.OutputType != FILETYPE_MACHO_LE) {
533 // Converting from MachO-64. Remove underscores
534 cmd.Underscore = CMDL_UNDERSCORE_REMOVE;
535 }
536 else if (FileType != FILETYPE_MACHO_LE && cmd.OutputType == FILETYPE_MACHO_LE) {
537 // Converting to MachO-64. Add underscores
538 cmd.Underscore = CMDL_UNDERSCORE_ADD;
539 }
540 else {
541 // Anything else 64-bit. No change
542 cmd.Underscore = CMDL_UNDERSCORE_NOCHANGE;
543 }
544 }
545 }
546 if (cmd.Verbose > (uint32_t)(cmd.LibraryOptions != 0)) { // Tell which option is chosen
547 printf("\n%s", Lookup(UnderscoreOptionNames, cmd.Underscore));
548 }
549 }
550
551 // Check sectionname options
552 if (cmd.SegmentDot && cmd.OutputType != 0) {
553 if (cmd.SegmentDot == CMDL_SECTIONDOT_CHANGE) {
554 if (cmd.OutputType == FILETYPE_COFF || cmd.OutputType == FILETYPE_MACHO_LE || cmd.OutputType == FILETYPE_OMF) {
555 // Change leading '.' to '_' in nonstandard section names
556 cmd.SegmentDot = CMDL_SECTIONDOT_DOT2U;
557 }
558 else if (cmd.OutputType == FILETYPE_ELF) {
559 // Change leading '_' to '.' in nonstandard section names
560 cmd.SegmentDot = CMDL_SECTIONDOT_U2DOT;
561 }
562 else {
563 cmd.SegmentDot = CMDL_SECTIONDOT_NOCHANGE;
564 }
565 }
566 if (cmd.Verbose > (uint32_t)(cmd.LibraryOptions != 0)) { // Tell which option is chosen
567 printf("\n%s", Lookup(SectionDotOptionNames, cmd.SegmentDot));
568 }
569 }
570
571 // Check debug info options
572 if (cmd.DebugInfo == CMDL_DEBUG_DEFAULT) {
573 cmd.DebugInfo = (FileType != cmd.OutputType) ? CMDL_DEBUG_STRIP : CMDL_DEBUG_PRESERVE;
574 }
575
576 // Check exception handler info options
577 if (cmd.ExeptionInfo == CMDL_EXCEPTION_DEFAULT) {
578 cmd.ExeptionInfo = (FileType != cmd.OutputType) ? CMDL_EXCEPTION_STRIP : CMDL_EXCEPTION_PRESERVE;
579 }
580
581 // Choose conversion
582 switch (FileType) {
583
584 // Conversion from ELF
585 case FILETYPE_ELF:
586 switch (cmd.OutputType) {
587 case FILETYPE_COFF:
588 // Conversion from ELF to COFF
589 ELF2ELF(); // Make symbol changes in ELF file
590 if (err.Number()) return; // Return if error
591 ELF2COF(); // Convert to COFF
592 break;
593
594 case FILETYPE_MACHO_LE:
595 // Conversion from ELF to Mach-O
596 ELF2MAC(); // Convert to Mach-O
597 if (err.Number()) return; // Return if error
598 MAC2MAC(); // Make symbol changes in Mach-O file, sort symbol tables alphabetically
599 break;
600
601 case FILETYPE_OMF:
602 // Conversion from ELF to OMF
603 ELF2ELF(); // Make symbol changes in ELF file
604 if (err.Number()) return; // Return if error
605 ELF2COF(); // Convert to COFF first
606 if (err.Number()) return; // Return if error
607 COF2OMF(); // Then convert to OMF
608 break;
609
610 case FILETYPE_ELF:
611 // Make changes in ELF file
612 if (cmd.SymbolChangesRequested()) {
613 ELF2ELF(); // Make symbol changes in ELF file
614 }
615 else if (!cmd.LibraryOptions) {
616 err.submit(1006); // Warning: nothing to do
617 }
618 break;
619
620 case CMDL_OUTPUT_MASM:
621 // Disassemble ELF file
622 ELF2ASM(); // Disassemble
623 break;
624
625 default:
626 // Conversion not supported
627 err.submit(2013, GetFileFormatName(FileType), GetFileFormatName(cmd.OutputType));
628 }
629 break;
630
631
632 // Conversion from COFF
633 case FILETYPE_COFF:
634 switch (cmd.OutputType) {
635 case FILETYPE_COFF:
636 // No conversion. Modify file
637 if (cmd.DebugInfo == CMDL_DEBUG_STRIP || cmd.ExeptionInfo == CMDL_EXCEPTION_STRIP) {
638 COF2ELF(); // Convert to ELF and back again to strip debug and exception info
639 if (err.Number()) return; // Return if error
640 ELF2COF();
641 err.submit(1008); // Warning: Converting to ELF and back again
642 }
643 if (cmd.SymbolChangesRequested()) {
644 COF2COF(); // Make symbol name changes in COFF file
645 }
646 else if (cmd.DebugInfo != CMDL_DEBUG_STRIP && cmd.ExeptionInfo != CMDL_EXCEPTION_STRIP && !cmd.LibraryOptions) {
647 err.submit(1006); // Warning: nothing to do
648 }
649 break;
650
651 case FILETYPE_ELF:
652 COF2COF(); // Make symbol changes in COFF file
653 if (err.Number()) return; // Return if error
654 COF2ELF(); // Convert to ELF
655 break;
656
657 case FILETYPE_OMF:
658 COF2COF(); // Make symbol changes in COFF file
659 if (err.Number()) return; // Return if error
660 COF2OMF(); // Convert to OMF
661 break;
662
663 case FILETYPE_MACHO_LE:
664 COF2ELF(); // Convert from COFF to ELF
665 if (err.Number()) return; // Return if error
666 ELF2MAC(); // Then convert from ELF to Mach-O
667 if (err.Number()) return; // Return if error
668 MAC2MAC(); // Make symbol changes in Mach-O file and sort symbol table
669 break;
670
671 case CMDL_OUTPUT_MASM:
672 // Disassemble COFF file
673 COF2ASM(); // Disassemble
674 break;
675
676 default:
677 // Conversion not supported
678 err.submit(2013, GetFileFormatName(FileType), GetFileFormatName(cmd.OutputType));
679 }
680 break;
681
682
683 // Conversion from OMF
684 case FILETYPE_OMF:
685 switch (cmd.OutputType) {
686 case FILETYPE_OMF:
687 // No conversion. Modify file
688 if (cmd.SymbolChangesRequested() || cmd.DebugInfo == CMDL_DEBUG_STRIP || cmd.ExeptionInfo == CMDL_EXCEPTION_STRIP) {
689 OMF2COF(); // Convert to COFF and back again to do requested changes
690 if (err.Number()) return; // Return if error
691 COF2COF(); // Make symbol changes in COFF file
692 if (err.Number()) return; // Return if error
693 COF2OMF();
694 err.submit(1009); // Warning: Converting to COFF and back again
695 }
696 break;
697
698 case FILETYPE_COFF:
699 OMF2COF(); // Convert to COFF
700 if (err.Number()) return; // Return if error
701 COF2COF(); // Make symbol changes in COFF file
702 break;
703
704 case FILETYPE_ELF:
705 OMF2COF(); // Convert to COFF
706 if (err.Number()) return; // Return if error
707 COF2COF(); // Make symbol changes in COFF file
708 if (err.Number()) return; // Return if error
709 COF2ELF(); // Convert to ELF
710 break;
711
712 case FILETYPE_MACHO_LE:
713 OMF2COF(); // Convert to COFF
714 if (err.Number()) return; // Return if error
715 COF2ELF(); // Convert from COFF to ELF
716 if (err.Number()) return; // Return if error
717 ELF2MAC(); // Then convert from ELF to Mach-O
718 if (err.Number()) return; // Return if error
719 MAC2MAC(); // Make symbol changes in Mach-O file and sort symbol table
720 break;
721
722 case CMDL_OUTPUT_MASM:
723 // Disassemble OMF file
724 OMF2ASM(); // Disassemble
725 break;
726
727 default:
728 // Conversion not supported
729 err.submit(2013, GetFileFormatName(FileType), GetFileFormatName(cmd.OutputType));
730 }
731 break;
732
733 // Conversions from Mach-O
734 case FILETYPE_MACHO_LE:
735
736 switch (cmd.OutputType) {
737 case FILETYPE_ELF:
738 MAC2ELF(); // Convert to ELF
739 if (err.Number()) return; // Return if error
740 ELF2ELF(); // Make symbol changes in ELF file
741 break;
742
743 case FILETYPE_COFF:
744 MAC2ELF(); // Convert to ELF
745 if (err.Number()) return; // Return if error
746 ELF2ELF(); // Make symbol changes in ELF file
747 if (err.Number()) return; // Return if error
748 ELF2COF(); // Convert to COFF
749 break;
750
751 case FILETYPE_OMF:
752 MAC2ELF(); // Convert to ELF
753 if (err.Number()) return; // Return if error
754 ELF2ELF(); // Make symbol changes in ELF file
755 if (err.Number()) return; // Return if error
756 ELF2COF(); // Convert to COFF
757 if (err.Number()) return; // Return if error
758 COF2OMF(); // Convert to OMF
759 break;
760
761 case FILETYPE_MACHO_LE:
762 MAC2MAC(); // Make symbol changes in mACH-o file
763 break;
764
765 case CMDL_OUTPUT_MASM:
766 // Disassemble Mach-O file
767 MAC2ASM(); // Disassemble
768 break;
769
770 default:
771 // Conversion not supported
772 err.submit(2013, GetFileFormatName(FileType), GetFileFormatName(cmd.OutputType));
773 }
774 break;
775
776 case FILETYPE_MAC_UNIVBIN:
777 ParseMACUnivBin(); break;
778
779 // Conversion from other types
780 default:
781 err.submit(2006, FileName, GetFileFormatName(FileType)); // Conversion of this file type not supported
782 }
783 }
784 }
785