Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.
  37. static void CheckIntegerTypes() {
  38.    if (
  39.       sizeof(uint8) != 1 ||
  40.       sizeof(int16) != 2 ||
  41.       sizeof(int32) != 4 ||
  42.       sizeof(int64) != 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
  48. static void CheckEndianness() {
  49.    static uint8 bytes[4] = {1, 2, 3, 4};
  50.    if (*(uint32*)bytes != 0x04030201) {
  51.       // Big endian
  52.       err.submit(9002);
  53.    }
  54. }
  55.  
  56. // Function to convert powers of 2 to index
  57. int FloorLog2(uint32 x) {
  58.    int i = -1;
  59.    do {
  60.       x >>= 1;
  61.       i++;
  62.    } while (x);
  63.    return i;
  64. }
  65.  
  66. const char * timestring(uint32 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 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
  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. Remove this
  87.    if (argc == 1) {
  88.       char * dummyarg[] = {"", "@resp.txt"}; // Read command line from file resp.txt
  89.       argc = 2; argv = 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
  105. CMain::CMain() : CFileBuffer() {
  106. }
  107.  
  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.  
  149. CConverter::CConverter() {
  150.    // Constructor
  151. }
  152.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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)(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)(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)(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.