00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028 using namespace std;
00029
00030 typedef unsigned char * BITS;
00031
00032 typedef enum {
00033 RTA_SCN_DATA = 0,
00034 RTA_SCN_INDEX = 1,
00035 RTA_SCN_UNKNOWN = 2,
00036 WHIRL_SCN_PU = 3,
00037 WHIRL_SCN_LOW_BOUND = WHIRL_SCN_PU-1,
00038 WHIRL_SCN_GBL = 4,
00039 WHIRL_SCN_DST = 5,
00040 WHIRL_SCN_STRTAB = 6,
00041 WHIRL_SCN_SUMMARY = 7,
00042 WHIRL_SCN_FLAGS = 8,
00043 WHIRL_SCN_HI_BOUND = WHIRL_SCN_FLAGS+1
00044 } ANNOT_SCN_TYPE;
00045
00046
00047
00048 #define WHIRL_SCN_NAME_PREFIX ".WHIRL"
00049 #define WHIRL_SCN_NAME_PREFIX_LEN 6
00050 #define WHIRL_PUSECT_SCN_NAME ".WHIRL.pu_section"
00051 #define WHIRL_SUMMARY_SCN_NAME ".WHIRL.summary"
00052 #define WHIRL_FLAGS_SCN_NAME ".WHIRL.flags"
00053
00054
00055 typedef class {
00056 private:
00057 UINT64 pc;
00058 UINT sz;
00059 BITS bits;
00060 public:
00061 void Size(UINT s) { sz = s; }
00062 void Bits(BITS b) { bits = b; }
00063 void Pc(UINT64 p) { pc = p; }
00064 UINT64 Pc(void) { return pc; }
00065 UINT Size(void) { return sz; }
00066 BITS Bits(void) { return bits; }
00067 } RTABuf;
00068
00069 class PU_SectBin {
00070 private:
00071 SecHdr* sect;
00072 SecHdr64* sect64;
00073 BOOL is32bit;
00074 INT num_sect;
00075 STRING name;
00076 vector<RTABuf> pu_sects;
00077 UINT64 start_pc;
00078 UINT sz;
00079
00080 public:
00081 void Name(const STRING s) { name = s; }
00082 void NumSect(const INT n) { num_sect = n; }
00083 void Sect(SecHdr* s) { sect = s; }
00084 void Sect(SecHdr64* s) { sect64 = s; }
00085 void PuSects(vector<RTABuf> p){ pu_sects = p; }
00086 void Is32bit(BOOL b) { is32bit = b; }
00087 void StartPc(UINT64 p) { start_pc = p; }
00088 void SzPus(UINT s) { sz = s; }
00089 STRING Name(void) { return name; }
00090 INT Numsect(void) { return num_sect; }
00091 SecHdr* Sect(void) { return sect; }
00092 SecHdr64* Sect64(void) { return sect64; }
00093 vector<RTABuf> PuSects(void) { return pu_sects; }
00094 BOOL NumsectNone(void) { return (Numsect() == 0); }
00095 BOOL Is32bit(void) { return is32bit; }
00096 UINT64 StartPc(void) { return start_pc; }
00097 UINT SzPus(void) { return sz; }
00098 void PrintBits(FILE* fp, INT i);
00099 void PrintBits(FILE* fp);
00100 BOOL QuickChk(FILE* fp, INT i);
00101 BOOL QuickChk(FILE* fp = stdout);
00102 BOOL VerifyHdr(const Rta_Hdr *prta);
00103 PU_SectBin(INT n = 0) { Name('\0'), NumSect(n), Sect((SecHdr*)0); Sect((SecHdr64*)0); }
00104 ~PU_SectBin() {}
00105 };
00106
00107
00108
00109 class SecHdrTable;
00110
00111 #define FILTER_SECT_NAME_PREFIX ".rta."
00112 #define FILTER_SECT_NAME_LEN 5
00113
00114 typedef class {
00115 ELF_object* _obj;
00116 BOOL _is32bit;
00117 ELF_object64* _obj64;
00118 public:
00119 ELF_object* Obj(void) { return _is32bit ? _obj :(ELF_object*)0;}
00120 SecHdr* Sects(void) { return Obj()->SecHdrTab()->SecTab(); }
00121 ELF_object64* Obj64(void) { return _obj64; }
00122 SecHdr64* Sects64(void) { return Obj64()->SecHdrTab()->SecTab(); }
00123 BOOL Is32bit(void) { return _is32bit; }
00124 INT Sectnum(void) { return _is32bit ? Obj()->SecHdrTab()->SecNum() : Obj64()->SecHdrTab()->SecNum(); }
00125 public:
00126 ANNOT_SCN_TYPE FilterByName(STRING);
00127 void createELFObj(char* elfFile);
00128 STRING Sectname(INT i);
00129 void dumpBin(FILE *fp = stdout);
00130 } ELFBin;
00131
00132
00133 ANNOT_SCN_TYPE ELFBin::FilterByName(STRING s)
00134 {
00135 if (strncmp(RTA_SCN_NAME_PREFIX, s, RTA_SCN_NAME_PREFIX_LEN) == 0) {
00136 if (strcmp(RTA_DATA_SCN_NAME, s) == 0)
00137 return RTA_SCN_DATA;
00138 if (strcmp(RTA_INDEX_SCN_NAME, s) == 0)
00139 return RTA_SCN_INDEX;
00140 return RTA_SCN_UNKNOWN;
00141 }
00142
00143 if (strncmp(WHIRL_SCN_NAME_PREFIX, s, WHIRL_SCN_NAME_PREFIX_LEN) == 0) {
00144 if (strcmp(WHIRL_PUSECT_SCN_NAME, s) == 0)
00145 return WHIRL_SCN_PU;
00146
00147 if (strcmp(WHIRL_SUMMARY_SCN_NAME, s) == 0)
00148 return WHIRL_SCN_SUMMARY;
00149
00150 if (strcmp(WHIRL_FLAGS_SCN_NAME, s) == 0)
00151 return WHIRL_SCN_FLAGS;
00152 }
00153
00154 return RTA_SCN_UNKNOWN;
00155 }
00156
00157 void ELFBin::createELFObj(char* elfFile)
00158 {
00159 try {
00160 _obj = new ELF_object(elfFile);
00161 _is32bit = _obj->Is32Bit();
00162
00163 if (_obj == NULL)
00164 throw(STRING("Cannot create obj"));
00165
00166 if (_is32bit) {
00167 SecHdrTable* _secHdrTab = Obj()->SecHdrTab();
00168 if (_secHdrTab == 0)
00169 throw(STRING("Empty section header"));
00170
00171 if (_obj->_elfHeader->e_shnum() == 0)
00172 throw(STRING("number of sections is zero"));
00173 }
00174 else {
00175 _obj64 = new ELF_object64(elfFile);
00176 SecHdrTable64* _secHdrTab = Obj64()->SecHdrTab();
00177 if (_secHdrTab == 0)
00178 throw(STRING("Empty section header"));
00179
00180 if (Obj64()->_elfHeader->e_shnum() == 0)
00181 throw(STRING("number of sections is zero"));
00182 }
00183 return ;
00184 }
00185 catch (STRING s) {
00186 throw s;
00187 }
00188 }
00189
00190
00191 STRING ELFBin::Sectname(INT i)
00192 {
00193 if (Sectnum() == 0 )
00194 throw(STRING("sectHdr num null"));
00195
00196 if (Is32bit()) {
00197 if (Sects() == 0)
00198 throw(STRING("sectHdr Table null"));
00199
00200 return (STRING)Obj()->SecHdrTab()->getSHdrByIndex(i)->secName();
00201 }
00202 else {
00203 if (Sects64() == 0)
00204 throw(STRING("sectHdr Table null"));
00205 return (STRING)Obj64()->SecHdrTab()->getSHdrByIndex(i)->secName();
00206 }
00207 }
00208
00209 void ELFBin::dumpBin(FILE *fp)
00210 {
00211 INT sect_num = 0;
00212 PU_SectBin pusbin_rta = PU_SectBin(0);
00213 INT p_ofs;
00214 unsigned char* p_tmp;
00215 UINT p_shsz;
00216 BITS p_annot_scn;
00217 vector<RTABuf> rta_buf;
00218 ANNOT_SCN_TYPE scntype, stype;
00219
00220 for (INT k = 0; k < Sectnum(); k++) {
00221 if ((stype = FilterByName(Sectname(k))) != RTA_SCN_UNKNOWN) {
00222
00223 if (Is32bit()) {
00224 p_tmp = (unsigned char *)Obj()->_elfHeader->_startAddr;
00225 SecHdr* SecHdr = Sects();
00226 p_ofs = SecHdr[k].sh_offset();
00227 p_shsz = SecHdr[k].sh_size();
00228 }
00229 else {
00230 p_tmp = (unsigned char *)Obj64()->_elfHeader->_startAddr;
00231 SecHdr64* SecHdr64 = Sects64();
00232 p_ofs = SecHdr64[k].sh_offset();
00233 p_shsz = SecHdr64[k].sh_size();
00234 }
00235
00236 switch (stype) {
00237 case RTA_SCN_INDEX:
00238
00239 if (Is32bit()) {
00240 pusbin_rta.Sect(Sects());
00241 }
00242 else {
00243 pusbin_rta.Sect(Sects64());
00244 }
00245 scntype = stype;
00246 sect_num = p_shsz/sizeof(Rta_Idx_Ent);
00247 FmtAssert((p_shsz%sizeof(Rta_Idx_Ent) == 0), ("index sect not multplier of index class size"));
00248 break;
00249
00250 case RTA_SCN_DATA:
00251 scntype = stype;
00252 p_annot_scn = (BITS)malloc(p_shsz);
00253 memcpy(p_annot_scn, p_tmp+p_ofs, p_shsz);
00254 break;
00255
00256 case WHIRL_SCN_PU:
00257 p_annot_scn = (BITS)malloc(p_shsz);
00258 memcpy(p_annot_scn, p_tmp+p_ofs, p_shsz);
00259 Print_whirl_pu_from_bits(fp, p_annot_scn, p_shsz);
00260 break;
00261
00262 case WHIRL_SCN_GBL:
00263 p_annot_scn = (BITS)malloc(p_shsz);
00264 memcpy(p_annot_scn, p_tmp+p_ofs, p_shsz);
00265 Print_whirl_global_from_bits(fp, p_annot_scn, p_shsz);
00266 break;
00267
00268 case WHIRL_SCN_SUMMARY:
00269 p_annot_scn = (BITS)malloc(p_shsz);
00270 memcpy(p_annot_scn, p_tmp+p_ofs, p_shsz);
00271 Print_whirl_summary_from_bits(fp, p_annot_scn, p_shsz);
00272 break;
00273
00274 case WHIRL_SCN_FLAGS:
00275 p_annot_scn = (BITS)malloc(p_shsz);
00276 memcpy(p_annot_scn, p_tmp+p_ofs, p_shsz);
00277 Print_whirl_flags_from_bits(fp, p_annot_scn, p_shsz);
00278 break;
00279
00280 case WHIRL_SCN_STRTAB:
00281 default:
00282 FmtAssert(0, ("RTA/WHIRL scn type %d not handled", stype));
00283 break;
00284 }
00285 }
00286 }
00287
00288 if (scntype == RTA_SCN_DATA || scntype == RTA_SCN_INDEX) {
00289
00290
00291 Rta_Idx_Ent* rta_idx_array;
00292 rta_idx_array = (Rta_Idx_Ent*)((unsigned char *)p_tmp+p_ofs);
00293 for (INT j=0; j<sect_num; j++, rta_idx_array++) {
00294 RTABuf rta_tmp;
00295
00296 rta_tmp.Pc(Rta_idx_ent_start(rta_idx_array));
00297 rta_tmp.Size(p_shsz);
00298 rta_tmp.Bits(p_annot_scn+Rta_idx_ent_data_off(rta_idx_array));
00299 rta_buf.push_back(rta_tmp);
00300 }
00301
00302 pusbin_rta.NumSect(sect_num);
00303 pusbin_rta.PuSects(rta_buf);
00304 #ifdef DEBUG
00305 pusbin_rta.PrintBits(fp);
00306 pusbin_rta.QuickChk(fp);
00307 #endif // DEBUG
00308 }
00309
00310 if (scntype > WHIRL_SCN_LOW_BOUND && scntype < WHIRL_SCN_HI_BOUND) {
00311 }
00312 }
00313
00314
00315
00316