kolibrios/programs/develop/objconv/main.cpp
turbocat 60a4b1c9ef Added objconv port.
git-svn-id: svn://kolibrios.org@9683 a494cfbc-eb01-0410-851d-a64ba20cac60
2022-02-06 11:09:00 +00:00

785 lines
32 KiB
C++

/**************************** main.cpp **********************************
* Author: Agner Fog
* Date created: 2006-07-26
* Last modified: 2011-10-28
* Project: objconv
* Module: main.cpp
* Description:
* Objconv is a portable C++ program for converting object file formats.
* Compile for console mode on any platform.
*
* Module main contains the program entry
*
* Copyright 2006-2011 GNU General Public License http://www.gnu.org/licenses
*****************************************************************************/
#include "stdafx.h"
// Texts of option feedback. Adding or removing leading underscores on symbols
SIntTxt UnderscoreOptionNames[] = {
{CMDL_UNDERSCORE_NOCHANGE, "Not adding or removing underscores for this filetype"},
{CMDL_UNDERSCORE_REMOVE, "Removing leading underscores from symbol names"},
{CMDL_UNDERSCORE_ADD, "Adding leading underscores to symbol names"},
{CMDL_UNDERSCORE_REMOVE|CMDL_KEEP_ALIAS, "Removing leading underscores from symbol names. Keeping old name as alias"},
{CMDL_UNDERSCORE_ADD|CMDL_KEEP_ALIAS, "Adding leading underscores to symbol names. Keeping old name as alias"}
};
// Texts of option feedback. Changing leading dot or underscore on section names
SIntTxt SectionDotOptionNames[] = {
{CMDL_SECTIONDOT_NOCHANGE, "Not changing leading character on section names for this filetype"},
{CMDL_SECTIONDOT_U2DOT, "Changing leading underscores on section names to dot"},
{CMDL_SECTIONDOT_DOT2U, "Changing leading dot on nonstandard section names to underscore"}
};
// Check that integer type definitions are correct.
// Will generate an error message if the compiler makes the integer types
// with wrong size.
static void CheckIntegerTypes() {
if (
sizeof(uint8) != 1 ||
sizeof(int16) != 2 ||
sizeof(int32) != 4 ||
sizeof(int64) != 8) {
err.submit(9001); // Make error message if type definitions are wrong
}
}
// Check that we are running on a machine with little-endian memory organization
static void CheckEndianness() {
static uint8 bytes[4] = {1, 2, 3, 4};
if (*(uint32*)bytes != 0x04030201) {
// Big endian
err.submit(9002);
}
}
// Function to convert powers of 2 to index
int FloorLog2(uint32 x) {
int i = -1;
do {
x >>= 1;
i++;
} while (x);
return i;
}
const char * timestring(uint32 t) {
// Convert 32 bit time stamp to string
// Fix the problem that time_t may be 32 bit or 64 bit
union {
time_t t;
uint32 t32;
} utime;
utime.t = 0;
utime.t32 = t;
const char * string = ctime(&utime.t);
if (string == 0) string = "?";
return string;
}
// Main. Program starts here
int main(int argc, char * argv[]) {
CheckIntegerTypes(); // Check that compiler has the right integer sizes
CheckEndianness(); // Check that machine is little-endian
#ifdef _DEBUG
// For debugging only. Remove this
if (argc == 1) {
char * dummyarg[] = {"", "@resp.txt"}; // Read command line from file resp.txt
argc = 2; argv = dummyarg;}
#endif
cmd.ReadCommandLine(argc, argv); // Read command line parameters
if (cmd.ShowHelp) return 0; // Help screen has been printed. Do nothing else
CMain maincvt; // This object takes care of all conversions etc.
maincvt.Go();
// Do everything the command line says
if (cmd.Verbose) printf("\n"); // End with newline
return err.GetWorstError(); // Return with error code
}
// Class CMainConverter is used for control of the conversion process
CMain::CMain() : CFileBuffer() {
}
void CMain::Go() {
// Do whatever the command line parameters say
FileName = cmd.InputFile; // Get input file name from command line
// Ignore nonexisting filename when building library
int IgnoreError = (cmd.FileOptions & CMDL_FILE_IN_IF_EXISTS) && !cmd.OutputFile;
Read(IgnoreError); // Read input file
GetFileType(); // Determine file type
cmd.InputType = FileType; // Save input file type in cmd for access from other modules
if (cmd.OutputType == 0) {
// desired type not specified
cmd.OutputType = FileType;
}
if (err.Number()) return; // Return if error
CheckOutputFileName(); // Construct output file name with default extension
if (err.Number()) return;
if ((FileType & (FILETYPE_LIBRARY | FILETYPE_OMFLIBRARY))
|| (cmd.LibraryOptions & CMDL_LIBRARY_ADDMEMBER)) {
// Input file is a library or we are building a library
CLibrary lib; // Library handler object
*this >> lib; // Transfer my file buffer to lib
lib.Go(); // Do conversion or dump
*this << lib; // Get file buffer back
}
else {
// Input file is an object file
CConverter conv; // Make converter object
*this >> conv; // Transfer my file buffer to conv
conv.Go(); // Do conversion or dump
*this << conv; // Get file buffer back
}
if ((cmd.FileOptions & CMDL_FILE_OUTPUT) && OutputFileName) {
// There is an output file to write
cmd.CheckSymbolModifySuccess(); // Check if symbols to modify were found
if (err.Number()) return; // Return if error
FileName = OutputFileName; // Output file name
Write(); // Write output file
if (cmd.Verbose) cmd.ReportStatistics(); // Report statistics
}
}
CConverter::CConverter() {
// Constructor
}
void CConverter::DumpCOF() {
// Dump COFF file
CCOFF cof; // Make object for interpreting COFF file
*this >> cof; // Give it my buffer
cof.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
cof.Dump(cmd.DumpOptions); // Dump file
*this << cof; // Take back my buffer
}
void CConverter::DumpELF() {
// Dump ELF file
if (WordSize == 32) {
// Make object for interpreting 32 bit ELF file
CELF<ELF32STRUCTURES> elf;
*this >> elf; // Give it my buffer
elf.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
elf.Dump(cmd.DumpOptions); // Dump file
*this << elf; // Take back my buffer
}
else {
// Make object for interpreting 32 bit ELF file
CELF<ELF64STRUCTURES> elf;
*this >> elf; // Give it my buffer
elf.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
elf.Dump(cmd.DumpOptions); // Dump file
*this << elf; // Take back my buffer
}
}
void CConverter::DumpMACHO() {
// Dump Mach-O file
if (WordSize == 32) {
// Make object for interpreting 32 bit Mach-O file
CMACHO<MAC32STRUCTURES> macho;
*this >> macho; // Give it my buffer
macho.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
macho.Dump(cmd.DumpOptions); // Dump file
*this << macho; // Take back my buffer
}
else {
// Make object for interpreting 64 bit Mach-O file
CMACHO<MAC64STRUCTURES> macho;
*this >> macho; // Give it my buffer
macho.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
macho.Dump(cmd.DumpOptions); // Dump file
*this << macho; // Take back my buffer
}
}
void CConverter::ParseMACUnivBin() {
// Dump Mac universal binary
CMACUNIV macuniv; // Make object for interpreting Mac universal binary file
*this >> macuniv; // Give it my buffer
macuniv.Go(cmd.DumpOptions); // Dump file components
*this << macuniv; // Take back my buffer
}
void CConverter::DumpOMF() {
// Dump OMF file
COMF omf; // Make object for interpreting OMF file
*this >> omf; // Give it my buffer
omf.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
omf.Dump(cmd.DumpOptions); // Dump file
*this << omf; // Take back my buffer
}
void CConverter::COF2ELF() {
// Convert COFF to ELF file
if (WordSize == 32) {
// Make instance of converter, 32 bit template
CCOF2ELF<ELF32STRUCTURES> conv; // Make object for conversion
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
else {
// Make instance of converter, 64 bit template
CCOF2ELF<ELF64STRUCTURES> conv; // Make object for conversion
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
}
void CConverter::COF2OMF() {
// Convert COFF to OMF file
CCOF2OMF conv; // Make object for conversion
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
void CConverter::OMF2COF() {
// Convert OMF to COFF file
COMF2COF conv; // Make object for conversion
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
void CConverter::ELF2COF() {
// Convert ELF to COFF file
if (WordSize == 32) {
// Make instance of converter, 32 bit template
CELF2COF<ELF32STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
else {
// Make instance of converter, 64 bit template
CELF2COF<ELF64STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
}
void CConverter::ELF2MAC() {
// Convert ELF to Mach-O file
if (WordSize == 32) {
// Make instance of converter, 32 bit template
CELF2MAC<ELF32STRUCTURES,MAC32STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
else {
// Make instance of converter, 64 bit template
CELF2MAC<ELF64STRUCTURES,MAC64STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
}
void CConverter::MAC2ELF() {
// Convert Mach-O file to ELF file
if (WordSize == 32) {
// Make instance of converter, 32 bit template
CMAC2ELF<MAC32STRUCTURES,ELF32STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
else {
// Make instance of converter, 64 bit template
CMAC2ELF<MAC64STRUCTURES,ELF64STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
}
void CConverter::COF2ASM() {
// Disassemble COFF file
CCOF2ASM conv; // Make object for conversion
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
void CConverter::ELF2ASM() {
// Disassemble ELF file
if (WordSize == 32) {
// Make instance of converter, 32 bit template
CELF2ASM<ELF32STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
else {
// Make instance of converter, 64 bit template
CELF2ASM<ELF64STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
}
void CConverter::MAC2ASM() {
// Disassemble Mach-O file
if (WordSize == 32) {
// Make instance of converter, 32 bit template
CMAC2ASM<MAC32STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
else {
// Make instance of converter, 64 bit template
CMAC2ASM<MAC64STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
}
void CConverter::OMF2ASM() {
// Disassemble OMF file
COMF2ASM conv; // Make object for conversion
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
void CConverter::COF2COF() {
// Make changes in COFF file
CCOF2COF conv; // Make instance of converter
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
void CConverter::ELF2ELF() {
// Make changes in ELF file
if (WordSize == 32) {
// Make instance of converter, 32 bit template
CELF2ELF<ELF32STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
else {
// Make instance of converter, 64 bit template
CELF2ELF<ELF64STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
}
void CConverter::MAC2MAC() {
// Make changes in Mach-O file
if (WordSize == 32) {
// Make instance of converter, 32 bit template
CMAC2MAC<MAC32STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
else {
// Make instance of converter, 64 bit template
CMAC2MAC<MAC64STRUCTURES> conv;
*this >> conv; // Give it my buffer
conv.ParseFile(); // Parse file buffer
if (err.Number()) return; // Return if error
conv.Convert(); // Convert
*this << conv; // Take back converted buffer
}
}
void CConverter::Go() {
// Convert or dump file, depending on command line parameters
GetFileType(); // Determine file type
cmd.InputType = FileType; // Save input file type in cmd for access from other modules
if (err.Number()) return; // Return if error
if (cmd.OutputType == CMDL_OUTPUT_DUMP) {
// File dump requested
if (cmd.Verbose > 0) {
// Tell what we are doing:
printf("\nDump of file: %s, type: %s%i", FileName, GetFileFormatName(FileType), WordSize);
}
switch(FileType) {
case FILETYPE_ELF:
DumpELF(); break;
case FILETYPE_COFF:
DumpCOF(); break;
case FILETYPE_MACHO_LE:
DumpMACHO(); break;
case FILETYPE_OMF:
DumpOMF(); break;
case FILETYPE_MAC_UNIVBIN:
ParseMACUnivBin(); break;
default:
err.submit(2010, GetFileFormatName(FileType)); // Dump of this file type not supported
}
printf("\n"); // New line
}
else {
// File conversion requested
if (cmd.DesiredWordSize == 0) cmd.DesiredWordSize = WordSize;
if (WordSize && WordSize != cmd.DesiredWordSize) {
err.submit(2012, WordSize, cmd.DesiredWordSize); // Cannot convert word size
return;
}
if (Executable && cmd.OutputType != CMDL_OUTPUT_MASM) {
// Attempt to convert executable file
err.submit(2022);
}
if (err.Number()) return; // Return if error
if (cmd.Verbose > (uint32)(cmd.LibraryOptions != 0)) {
// Tell what we are doing:
printf("\nInput file: %s, output file: %s", FileName, OutputFileName);
if (FileType != cmd.OutputType) {
printf("\nConverting from %s%2i to %s%2i",
GetFileFormatName(FileType), WordSize,
GetFileFormatName(cmd.OutputType), WordSize);
}
else {
printf("\nModifying %s%2i file", GetFileFormatName(FileType), WordSize);
}
}
// Check underscore options
if (cmd.Underscore && cmd.OutputType != 0) {
if (cmd.Underscore == CMDL_UNDERSCORE_CHANGE) {
// Find underscore option for desired conversion
if (WordSize == 32) {
// In 32-bit, all formats except ELF have underscores
if (FileType == FILETYPE_ELF && cmd.OutputType != FILETYPE_ELF) {
// Converting from ELF32. Add underscores
cmd.Underscore = CMDL_UNDERSCORE_ADD;
}
else if (FileType != FILETYPE_ELF && cmd.OutputType == FILETYPE_ELF) {
// Converting to ELF32. Remove underscores
cmd.Underscore = CMDL_UNDERSCORE_REMOVE;
}
else {
// Anything else 32-bit. No change
cmd.Underscore = CMDL_UNDERSCORE_NOCHANGE;
}
}
else {
// In 64-bit, only Mach-O has underscores
if (FileType == FILETYPE_MACHO_LE && cmd.OutputType != FILETYPE_MACHO_LE) {
// Converting from MachO-64. Remove underscores
cmd.Underscore = CMDL_UNDERSCORE_REMOVE;
}
else if (FileType != FILETYPE_MACHO_LE && cmd.OutputType == FILETYPE_MACHO_LE) {
// Converting to MachO-64. Add underscores
cmd.Underscore = CMDL_UNDERSCORE_ADD;
}
else {
// Anything else 64-bit. No change
cmd.Underscore = CMDL_UNDERSCORE_NOCHANGE;
}
}
}
if (cmd.Verbose > (uint32)(cmd.LibraryOptions != 0)) { // Tell which option is chosen
printf("\n%s", Lookup(UnderscoreOptionNames, cmd.Underscore));
}
}
// Check sectionname options
if (cmd.SegmentDot && cmd.OutputType != 0) {
if (cmd.SegmentDot == CMDL_SECTIONDOT_CHANGE) {
if (cmd.OutputType == FILETYPE_COFF || cmd.OutputType == FILETYPE_MACHO_LE || cmd.OutputType == FILETYPE_OMF) {
// Change leading '.' to '_' in nonstandard section names
cmd.SegmentDot = CMDL_SECTIONDOT_DOT2U;
}
else if (cmd.OutputType == FILETYPE_ELF) {
// Change leading '_' to '.' in nonstandard section names
cmd.SegmentDot = CMDL_SECTIONDOT_U2DOT;
}
else {
cmd.SegmentDot = CMDL_SECTIONDOT_NOCHANGE;
}
}
if (cmd.Verbose > (uint32)(cmd.LibraryOptions != 0)) { // Tell which option is chosen
printf("\n%s", Lookup(SectionDotOptionNames, cmd.SegmentDot));
}
}
// Check debug info options
if (cmd.DebugInfo == CMDL_DEBUG_DEFAULT) {
cmd.DebugInfo = (FileType != cmd.OutputType) ? CMDL_DEBUG_STRIP : CMDL_DEBUG_PRESERVE;
}
// Check exception handler info options
if (cmd.ExeptionInfo == CMDL_EXCEPTION_DEFAULT) {
cmd.ExeptionInfo = (FileType != cmd.OutputType) ? CMDL_EXCEPTION_STRIP : CMDL_EXCEPTION_PRESERVE;
}
// Choose conversion
switch (FileType) {
// Conversion from ELF
case FILETYPE_ELF:
switch (cmd.OutputType) {
case FILETYPE_COFF:
// Conversion from ELF to COFF
ELF2ELF(); // Make symbol changes in ELF file
if (err.Number()) return; // Return if error
ELF2COF(); // Convert to COFF
break;
case FILETYPE_MACHO_LE:
// Conversion from ELF to Mach-O
ELF2MAC(); // Convert to Mach-O
if (err.Number()) return; // Return if error
MAC2MAC(); // Make symbol changes in Mach-O file, sort symbol tables alphabetically
break;
case FILETYPE_OMF:
// Conversion from ELF to OMF
ELF2ELF(); // Make symbol changes in ELF file
if (err.Number()) return; // Return if error
ELF2COF(); // Convert to COFF first
if (err.Number()) return; // Return if error
COF2OMF(); // Then convert to OMF
break;
case FILETYPE_ELF:
// Make changes in ELF file
if (cmd.SymbolChangesRequested()) {
ELF2ELF(); // Make symbol changes in ELF file
}
else if (!cmd.LibraryOptions) {
err.submit(1006); // Warning: nothing to do
}
break;
case CMDL_OUTPUT_MASM:
// Disassemble ELF file
ELF2ASM(); // Disassemble
break;
default:
// Conversion not supported
err.submit(2013, GetFileFormatName(FileType), GetFileFormatName(cmd.OutputType));
}
break;
// Conversion from COFF
case FILETYPE_COFF:
switch (cmd.OutputType) {
case FILETYPE_COFF:
// No conversion. Modify file
if (cmd.DebugInfo == CMDL_DEBUG_STRIP || cmd.ExeptionInfo == CMDL_EXCEPTION_STRIP) {
COF2ELF(); // Convert to ELF and back again to strip debug and exception info
if (err.Number()) return; // Return if error
ELF2COF();
err.submit(1008); // Warning: Converting to ELF and back again
}
if (cmd.SymbolChangesRequested()) {
COF2COF(); // Make symbol name changes in COFF file
}
else if (cmd.DebugInfo != CMDL_DEBUG_STRIP && cmd.ExeptionInfo != CMDL_EXCEPTION_STRIP && !cmd.LibraryOptions) {
err.submit(1006); // Warning: nothing to do
}
break;
case FILETYPE_ELF:
COF2COF(); // Make symbol changes in COFF file
if (err.Number()) return; // Return if error
COF2ELF(); // Convert to ELF
break;
case FILETYPE_OMF:
COF2COF(); // Make symbol changes in COFF file
if (err.Number()) return; // Return if error
COF2OMF(); // Convert to OMF
break;
case FILETYPE_MACHO_LE:
COF2ELF(); // Convert from COFF to ELF
if (err.Number()) return; // Return if error
ELF2MAC(); // Then convert from ELF to Mach-O
if (err.Number()) return; // Return if error
MAC2MAC(); // Make symbol changes in Mach-O file and sort symbol table
break;
case CMDL_OUTPUT_MASM:
// Disassemble COFF file
COF2ASM(); // Disassemble
break;
default:
// Conversion not supported
err.submit(2013, GetFileFormatName(FileType), GetFileFormatName(cmd.OutputType));
}
break;
// Conversion from OMF
case FILETYPE_OMF:
switch (cmd.OutputType) {
case FILETYPE_OMF:
// No conversion. Modify file
if (cmd.SymbolChangesRequested() || cmd.DebugInfo == CMDL_DEBUG_STRIP || cmd.ExeptionInfo == CMDL_EXCEPTION_STRIP) {
OMF2COF(); // Convert to COFF and back again to do requested changes
if (err.Number()) return; // Return if error
COF2COF(); // Make symbol changes in COFF file
if (err.Number()) return; // Return if error
COF2OMF();
err.submit(1009); // Warning: Converting to COFF and back again
}
break;
case FILETYPE_COFF:
OMF2COF(); // Convert to COFF
if (err.Number()) return; // Return if error
COF2COF(); // Make symbol changes in COFF file
break;
case FILETYPE_ELF:
OMF2COF(); // Convert to COFF
if (err.Number()) return; // Return if error
COF2COF(); // Make symbol changes in COFF file
if (err.Number()) return; // Return if error
COF2ELF(); // Convert to ELF
break;
case FILETYPE_MACHO_LE:
OMF2COF(); // Convert to COFF
if (err.Number()) return; // Return if error
COF2ELF(); // Convert from COFF to ELF
if (err.Number()) return; // Return if error
ELF2MAC(); // Then convert from ELF to Mach-O
if (err.Number()) return; // Return if error
MAC2MAC(); // Make symbol changes in Mach-O file and sort symbol table
break;
case CMDL_OUTPUT_MASM:
// Disassemble OMF file
OMF2ASM(); // Disassemble
break;
default:
// Conversion not supported
err.submit(2013, GetFileFormatName(FileType), GetFileFormatName(cmd.OutputType));
}
break;
// Conversions from Mach-O
case FILETYPE_MACHO_LE:
switch (cmd.OutputType) {
case FILETYPE_ELF:
MAC2ELF(); // Convert to ELF
if (err.Number()) return; // Return if error
ELF2ELF(); // Make symbol changes in ELF file
break;
case FILETYPE_COFF:
MAC2ELF(); // Convert to ELF
if (err.Number()) return; // Return if error
ELF2ELF(); // Make symbol changes in ELF file
if (err.Number()) return; // Return if error
ELF2COF(); // Convert to COFF
break;
case FILETYPE_OMF:
MAC2ELF(); // Convert to ELF
if (err.Number()) return; // Return if error
ELF2ELF(); // Make symbol changes in ELF file
if (err.Number()) return; // Return if error
ELF2COF(); // Convert to COFF
if (err.Number()) return; // Return if error
COF2OMF(); // Convert to OMF
break;
case FILETYPE_MACHO_LE:
MAC2MAC(); // Make symbol changes in mACH-o file
break;
case CMDL_OUTPUT_MASM:
// Disassemble Mach-O file
MAC2ASM(); // Disassemble
break;
default:
// Conversion not supported
err.submit(2013, GetFileFormatName(FileType), GetFileFormatName(cmd.OutputType));
}
break;
case FILETYPE_MAC_UNIVBIN:
ParseMACUnivBin(); break;
// Conversion from other types
default:
err.submit(2006, FileName, GetFileFormatName(FileType)); // Conversion of this file type not supported
}
}
}