00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef _WIN32
00010 #include <dlfcn.h>
00011 #else
00012 #include <windows.h>
00013 #endif
00014
00015 #include "BinaryFile.h"
00016 #include "ElfBinaryFile.h"
00017 #include "Win32BinaryFile.h"
00018 #include "PalmBinaryFile.h"
00019 #include "HpSomBinaryFile.h"
00020 #include "ExeBinaryFile.h"
00021 #include "config.h"
00022
00023 #include <iostream>
00024
00025 BinaryFile *BinaryFileFactory::Load( const char *sName )
00026 {
00027 BinaryFile *pBF = getInstanceFor( sName );
00028 if( pBF == NULL ) {
00029 std::cerr << "unrecognised binary file format.\n";
00030 return NULL;
00031 }
00032 if( pBF->RealLoad( sName ) == 0 ) {
00033 fprintf( stderr, "Loading '%s' failed\n", sName );
00034 delete pBF;
00035 return NULL;
00036 }
00037 pBF->getTextLimits();
00038 return pBF;
00039 }
00040
00041 #define TESTMAGIC2(buf,off,a,b) (buf[off] == a && buf[off+1] == b)
00042 #define TESTMAGIC4(buf,off,a,b,c,d) (buf[off] == a && buf[off+1] == b && \
00043 buf[off+2] == c && buf[off+3] == d)
00044
00045
00046 typedef BinaryFile* (*constructFcn)();
00047
00048 BinaryFile* BinaryFileFactory::getInstanceFor( const char *sName ) {
00049 FILE *f;
00050 unsigned char buf[64];
00051 std::string libName;
00052 BinaryFile *res = NULL;
00053
00054 f = fopen (sName, "rb");
00055 if( f == NULL ) {
00056 fprintf(stderr, "Unable to open binary file: %s\n", sName );
00057 return NULL;
00058 }
00059 fread (buf, sizeof(buf), 1, f);
00060 if( TESTMAGIC4(buf,0, '\177','E','L','F') ) {
00061
00062 libName = "ElfBinaryFile";
00063 } else if( TESTMAGIC2( buf,0, 'M','Z' ) ) {
00064 int peoff = LMMH(buf[0x3C]);
00065 if( peoff != 0 && fseek(f, peoff, SEEK_SET) != -1 ) {
00066 fread( buf, 4, 1, f );
00067 if( TESTMAGIC4( buf,0, 'P','E',0,0 ) ) {
00068
00069 libName = "Win32BinaryFile";
00070 } else if( TESTMAGIC2( buf,0, 'N','E' ) ) {
00071
00072 } else if( TESTMAGIC2( buf,0, 'L','E' ) ) {
00073
00074 libName = "DOS4GWBinaryFile";
00075 } else if( TESTMAGIC2( buf,0, 'L','X' ) ) {
00076
00077 }
00078 }
00079
00080 if( libName.size() == 0 )
00081 libName = "ExeBinaryFile";
00082 } else if( TESTMAGIC4( buf,0x3C, 'a','p','p','l' ) ||
00083 TESTMAGIC4( buf,0x3C, 'p','a','n','l' ) ) {
00084
00085 libName = "PalmBinaryFile";
00086 } else if( buf[0] == 0xfe && buf[1] == 0xed && buf[2] == 0xfa && buf[3] == 0xce ) {
00087
00088 libName = "MachOBinaryFile";
00089 #ifdef __CYGWIN__
00090 fprintf(stderr, "Sorry, Cygwin-hosted Boomerang cannot compile the MachOBinaryFile module at present"
00091 "\n");
00092 fclose(f);
00093 return NULL;
00094 #endif
00095 } else if( buf[0] == 0x02 && buf[2] == 0x01 &&
00096 (buf[1] == 0x10 || buf[1] == 0x0B) &&
00097 (buf[3] == 0x07 || buf[3] == 0x08 || buf[4] == 0x0B) ) {
00098
00099 libName = "HpSomBinaryFile";
00100 } else {
00101 fprintf( stderr, "Unrecognised binary file\n" );
00102 fclose(f);
00103 return NULL;
00104 }
00105
00106
00107 #ifndef _WIN32 // Cygwin, Unix/Linux
00108 libName = std::string("lib/lib") + libName;
00109 #ifdef __CYGWIN__
00110 libName += ".dll";
00111 #else
00112 #if HOST_OSX
00113 libName += ".dylib";
00114 #else
00115 libName += ".so";
00116 #endif
00117 #endif
00118 dlHandle = dlopen(libName.c_str(), RTLD_LAZY);
00119 if (dlHandle == NULL) {
00120 fprintf( stderr, "Could not open dynamic loader library %s\n", libName.c_str());
00121 fprintf( stderr, "%s\n", dlerror());
00122 fclose(f);
00123 return NULL;
00124 }
00125
00126 #if 0 // HOST_OSX_10_2 // Not sure when the underscore is really needed
00127 #define UNDERSCORE "_" // Only OSX 10.2 seems to need this underscore
00128 #else
00129 #define UNDERSCORE
00130 #endif
00131 constructFcn pFcn = (constructFcn) dlsym(dlHandle, UNDERSCORE "construct");
00132 #else // Else MSVC, MinGW
00133 libName += ".dll";
00134 #ifdef __MINGW32__
00135 libName = "lib/lib" + libName;
00136 #endif
00137 hModule = LoadLibraryA(libName.c_str());
00138 if(hModule == NULL) {
00139 int err = GetLastError();
00140 fprintf( stderr, "Could not open dynamic loader library %s (error #%d)\n", libName.c_str(), err);
00141 fclose(f);
00142 return NULL;
00143 }
00144
00145 constructFcn pFcn = (constructFcn) GetProcAddress((HINSTANCE)hModule, "construct");
00146 #endif
00147
00148 if (pFcn == NULL) {
00149 fprintf( stderr, "Loader library %s does not have a construct function\n", libName.c_str());
00150 #ifndef _WIN32
00151 fprintf( stderr, "dlerror returns %s\n", dlerror());
00152 #endif
00153 fclose(f);
00154 return NULL;
00155 }
00156
00157 res = (*pFcn)();
00158 fclose(f);
00159 return res;
00160 }
00161
00162 void BinaryFileFactory::UnLoad() {
00163 #ifdef _WIN32
00164 FreeLibrary((HINSTANCE)hModule);
00165 #else
00166 dlclose(dlHandle);
00167 #endif
00168 }