00001 #ifndef _Base_h_
00002 #define _Base_h_
00003
00004 #include <iostream>
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <assert.h>
00008 #include <strings.h>
00009 #include <string.h>
00010 #include <CStructures.h>
00011
00012 #define __MAX_STRING_SIZE 1024
00013 #define __SHOULD_NOT_ARRIVE assert(0 && "Should not be called")
00014
00015 #define GET_FIELD_BASIS(__type,__field) virtual __type get_ ## __field() \
00016 { __SHOULD_NOT_ARRIVE; return ( __type )0; }
00017 #define GET_FIELD_CLASS(__type,__field) inline __type get_ ## __field() \
00018 { return entry.__field ; }
00019 #define GET_FIELD_BASIS_U(__type,__field,__union) virtual __type get_ ## __field() \
00020 { __SHOULD_NOT_ARRIVE; return ( __type )0; }
00021 #define GET_FIELD_CLASS_U(__type,__field,__union) inline __type get_ ## __field() \
00022 { return entry.__union.__field ; }
00023 #define GET_FIELD_BASIS_A(__type,__field,__union) virtual __type get_ ## __union ## _ ## __field() \
00024 { __SHOULD_NOT_ARRIVE; return ( __type )0; }
00025
00026 #define GET_FIELD_CLASS_A(__type,__field,__union) inline __type get_ ## __union ## _ ## __field()
00027
00028 #define GET(__field) get_ ## __field()
00029 #define GET_A(__field,__union) get_ ## __union ## _ ## __field()
00030
00031 #define PRINT_ERROR(...) fprintf(stderr,"*********** ERROR : "); \
00032 fprintf(stderr,## __VA_ARGS__); \
00033 fprintf(stderr,"\n"); \
00034 exit(-1);
00035
00036 #define PRINT_INFOR(...) fprintf(stdout,"Information : "); \
00037 fprintf(stdout,## __VA_ARGS__); \
00038 fprintf(stdout,"\n"); \
00039 fflush(stdout);
00040
00041
00042 #ifdef DEVELOPMENT
00043
00044
00045 #define PRINT_DEBUG(...) fprintf(stdout,"----------- DEBUG : "); \
00046 fprintf(stdout,## __VA_ARGS__); \
00047 fprintf(stdout,"\n");
00048
00049 #define ASSERT(__str) assert(__str);
00050 #define DEBUG(...) __VA_ARGS__
00051 #define DEBUG_MORE(...)
00052 #define TIMER(...) __VA_ARGS__
00053 #define INNER_TIMER(...) __VA_ARGS__
00054
00055 #else
00056
00057 #define PRINT_DEBUG(...)
00058 #define DEBUG(...)
00059 #define DEBUG_MORE(...)
00060 #define ASSERT(__str) assert(__str);
00061 #define TIMER(...) __VA_ARGS__
00062 #define INNER_TIMER(...)
00063
00064 #endif
00065
00066 #define Invalid_UInteger_ID (uint32_t)-1
00067 #define Size__32_bit_File_Header FILHSZ
00068 #define Size__64_bit_File_Header FILHSZ_64
00069 #define Size__32_bit_Auxilary_Header _AOUTHSZ_EXEC
00070 #define Size__64_bit_Auxilary_Header _AOUTHSZ_EXEC_64
00071 #define Size__32_bit_Section_Header SCNHSZ
00072 #define Size__64_bit_Section_Header SCNHSZ_64
00073 #define Size__NN_bit_SymbolTable_Entry SYMESZ
00074 #define Size__32_bit_ExceptionTable_Entry EXCEPTSZ
00075 #define Size__64_bit_ExceptionTable_Entry EXCEPTSZ_64
00076 #define Size__32_bit_LineInfoTable_Entry LINESZ
00077 #define Size__64_bit_LineInfoTable_Entry LINESZ_64
00078 #define Size__32_bit_RelocationTable_Entry RELSZ
00079 #define Size__64_bit_RelocationTable_Entry RELSZ_64
00080
00081 #define Size__32_bit_Loader_Section_Header LDHDRSZ
00082 #define Size__64_bit_Loader_Section_Header LDHDRSZ_64
00083 #define Size__32_bit_Loader_Section_Symbol LDSYMSZ
00084 #define Size__64_bit_Loader_Section_Symbol LDSYMSZ_64
00085 #define Size__32_bit_Loader_Section_Relocation LDRELSZ
00086 #define Size__64_bit_Loader_Section_Relocation LDRELSZ_64
00087
00088 #define Type__Auxilary_Symbol_No_Type 0
00089 #define Type__Auxilary_Symbol_Section 1
00090 #define Type__Auxilary_Symbol_Exception _AUX_EXCEPT
00091 #define Type__Auxilary_Symbol_Function _AUX_FCN
00092 #define Type__Auxilary_Symbol_Block _AUX_SYM
00093 #define Type__Auxilary_Symbol_File _AUX_FILE
00094 #define Type__Auxilary_Symbol_CSect _AUX_CSECT
00095
00096 class VersionTag {
00097 protected:
00098 static char* tag;
00099
00100 public:
00101 static char* getLibraryVersionTag() { return tag; }
00102 };
00103
00104 typedef enum {
00105 XCoffClassTypes_no_type = 0,
00106 XCoffClassTypes_file_header,
00107 XCoffClassTypes_aout_header,
00108 XCoffClassTypes_sect_header,
00109 XCoffClassTypes_sect_rawdata,
00110 XCoffClassTypes_relocation,
00111 XCoffClassTypes_line_info,
00112 XCoffClassTypes_symbol_table,
00113 XCoffClassTypes_string_table,
00114 XCoffClassTypes_Total_Types
00115 } XCoffClassTypes;
00116
00117 class BinaryInputFile;
00118 class BinaryOutputFile;
00119 class XCoffFileGen;
00120 class BaseGen;
00121 class Instruction;
00122
00123 class Base {
00124 protected:
00125 const static uint32_t invalidOffset = 0xffffffff;
00126
00127 uint8_t type;
00128 uint32_t sizeInBytes;
00129 uint32_t fileOffset;
00130
00131 Base() : type(XCoffClassTypes_no_type),sizeInBytes(0),fileOffset(invalidOffset) {}
00132 Base(uint8_t t) : type(t),sizeInBytes(0),fileOffset(invalidOffset) {}
00133 virtual ~Base() {}
00134
00135 public:
00136 uint8_t getType() { return type; }
00137 uint32_t getSizeInBytes() { return sizeInBytes; }
00138
00139 virtual void print() { __SHOULD_NOT_ARRIVE; }
00140 virtual uint32_t read(BinaryInputFile* b) { return 0; }
00141
00142 virtual uint32_t getInstrumentationSize(XCoffFileGen* xCoffGen) { return getSizeInBytes(); }
00143 virtual uint32_t instrument(char* buffer,XCoffFileGen* xCoffGen,BaseGen* gen) { __SHOULD_NOT_ARRIVE; return 0; }
00144
00145 uint32_t getFileOffset() { return fileOffset; }
00146 uint32_t setFileOffset(uint32_t offset) { fileOffset = offset; return (fileOffset+sizeInBytes);}
00147 bool hasInvalidFileOffset() { return (invalidOffset == fileOffset); }
00148
00149 virtual const char* briefName() { __SHOULD_NOT_ARRIVE; return NULL; }
00150
00151 bool includesFileOffset(uint32_t offset);
00152 };
00153
00154 class BaseGen {
00155 protected:
00156 const static uint32_t invalidOffset = 0xffffffff;
00157
00158 uint8_t type;
00159 uint32_t sizeInBytes;
00160 uint32_t fileOffset;
00161 char* instBuffer;
00162
00163 BaseGen() : type(XCoffClassTypes_no_type),sizeInBytes(0),fileOffset(invalidOffset),instBuffer(NULL) {}
00164 BaseGen(uint8_t t) : type(t),sizeInBytes(0),fileOffset(invalidOffset),instBuffer(NULL) {}
00165 virtual ~BaseGen() {}
00166
00167 public:
00168
00169 virtual Base* getParsedBase() { __SHOULD_NOT_ARRIVE; return NULL; }
00170
00171 uint8_t getType() { return type; }
00172 uint32_t getSizeInBytes() { return sizeInBytes; }
00173
00174 uint32_t getFileOffset() { return fileOffset; }
00175 virtual uint32_t setFileOffset(uint32_t offset);
00176 bool hasInvalidFileOffset() { return (invalidOffset == fileOffset); }
00177
00178 virtual void print() { __SHOULD_NOT_ARRIVE; }
00179
00180 void initInstrumentationBuffer(XCoffFileGen* xCoffGen);
00181 virtual void instrument(XCoffFileGen* xCoffGen);
00182 virtual void dump(BinaryOutputFile* bf);
00183
00184 void verifyIdentical(char* origFile,char* instFile);
00185 void printOffsetMapping();
00186
00187 bool includesFileOffset(uint32_t offset);
00188 uint32_t convertFileOffset(uint32_t oldOffset);
00189
00190 void writeWord(uint32_t offset,uint32_t value);
00191 void writeHalfWord(uint32_t offset,uint16_t value);
00192 void writeDouble(uint32_t offset,uint64_t value);
00193 void writeInstructions(uint32_t offset,uint32_t insnCount,Instruction* insnBuffer);
00194 void writeString(uint32_t offset,char* buff,uint32_t len);
00195
00196 };
00197
00198 class HashCode {
00199 private:
00200 typedef union {
00201 struct {
00202 uint32_t res : 8;
00203 uint32_t section : 8;
00204 uint32_t function: 16;
00205 uint32_t block : 16;
00206 uint32_t memop : 16;
00207 } fields;
00208 uint64_t bits;
00209 } HashCodeEntry;
00210
00211 const static uint64_t INVALID_FIELD = 0;
00212
00213 HashCodeEntry entry;
00214
00215 inline bool hasSection() { return (entry.fields.section != INVALID_FIELD); }
00216 inline bool hasFunction() { return (entry.fields.function != INVALID_FIELD); }
00217 inline bool hasBlock() { return (entry.fields.block != INVALID_FIELD); }
00218 inline bool hasMemop() { return (entry.fields.memop != INVALID_FIELD); }
00219
00220 inline static bool validSection(uint32_t s) { return ((0 <= s) && (s < (0x1 << 8))); }
00221 inline static bool validFunction(uint32_t f){ return ((0 <= f) && (f < ((0x1 << 16) - 1))); }
00222 inline static bool validBlock(uint32_t b) { return ((0 <= b) && (b < ((0x1 << 16) - 1))); }
00223 inline static bool validMemop(uint32_t m) { return ((0 <= m) && (m < ((0x1 << 16) - 1))); }
00224 public:
00225
00226 inline uint64_t getValue(){ return entry.bits; }
00227
00228 inline HashCode() { entry.bits = INVALID_FIELD; }
00229 inline HashCode(uint64_t a) { entry.bits = a; }
00230
00231 HashCode(uint32_t s);
00232 HashCode(uint32_t s,uint32_t f);
00233 HashCode(uint32_t s,uint32_t f,uint32_t b);
00234 HashCode(uint32_t s,uint32_t f,uint32_t b,uint32_t m);
00235
00236 inline bool isSection() { return (hasSection() && !hasFunction() && !hasBlock() && !hasMemop()); }
00237 inline bool isFunction() { return (hasSection() && hasFunction() && !hasBlock() && !hasMemop()); }
00238 inline bool isBlock() { return (hasSection() && hasFunction() && hasBlock() && !hasMemop()); }
00239 inline bool isMemop() { return (hasSection() && hasFunction() && hasBlock() && hasMemop()); }
00240 inline bool isValid() { return (isSection() || isFunction() || isBlock() || isMemop()); }
00241
00242 inline uint32_t getSection() { return entry.fields.section; }
00243 inline uint32_t getFunction() { return (hasFunction() ? (entry.fields.function - 1) : INVALID_FIELD); }
00244 inline uint32_t getBlock() { return (hasBlock() ? (entry.fields.block - 1) : INVALID_FIELD); }
00245 inline uint32_t getMemop() { return (hasMemop() ? (entry.fields.memop - 1) : INVALID_FIELD); }
00246 };
00247
00248
00249 extern uint64_t nextAlignAddressHalfWord(uint64_t addr);
00250 extern uint64_t nextAlignAddressWord(uint64_t addr);
00251 extern uint64_t nextAlignAddressDouble(uint64_t addr);
00252
00253 #define FIRST_HALFWORD(__n) ((__n) & 0xffff)
00254 #define SECOND_HALFWORD(__n) (((__n) >> 16) & 0xffff)
00255
00256 extern double timer();
00257 #endif