forked from KolibriOS/kolibrios
Added objconv port.
git-svn-id: svn://kolibrios.org@9683 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
784
programs/develop/objconv/main.cpp
Normal file
784
programs/develop/objconv/main.cpp
Normal file
@@ -0,0 +1,784 @@
|
||||
/**************************** 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
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user