00001 #include <RelocationTable.h> 00002 #include <LineInfoTable.h> 00003 #include <SectHeader.h> 00004 #include <BinaryFile.h> 00005 00006 #define LINE_RELOC_OVERFLOW 0xffff 00007 00008 void SectHeader::initFilePointers(BinaryInputFile* binaryInputFile){ 00009 if((GET(s_size) != 0) && !IS_SECT_TYPE(OVRFLO) && !IS_SECT_TYPE(BSS)){ 00010 rawDataPtr = binaryInputFile->fileOffsetToPointer(GET(s_scnptr)); 00011 } 00012 if((GET(s_nreloc) != 0) && !IS_SECT_TYPE(OVRFLO)){ 00013 numOfRelocations = (uint32_t)GET(s_nreloc); 00014 if(numOfRelocations){ 00015 relocationPtr = binaryInputFile->fileOffsetToPointer(GET(s_relptr)); 00016 ASSERT((IS_SECT_TYPE(DATA) || IS_SECT_TYPE(TEXT)) && 00017 "FATAL : Only text and Data can have reloc"); 00018 } 00019 } 00020 if((GET(s_nlnno) != 0) && !IS_SECT_TYPE(OVRFLO)){ 00021 numOfLineInfo = (uint32_t)GET(s_nlnno); 00022 if(numOfLineInfo){ 00023 ASSERT(IS_SECT_TYPE(TEXT) && 00024 "FATAL : Only text and Data can have reloc"); 00025 lineInfoPointer = binaryInputFile->fileOffsetToPointer(GET(s_lnnoptr)); 00026 } 00027 } 00028 } 00029 00030 bool SectHeader::inRange(uint64_t address){ 00031 if(!GET(s_vaddr) || IS_SECT_TYPE(OVRFLO)) 00032 return false; 00033 return (((GET(s_vaddr)) <= address) && (address < (GET(s_vaddr) + GET(s_size)))); 00034 } 00035 00036 RelocationTable* SectHeader::readRelocTable(BinaryInputFile* binaryInputFile,XCoffFile* xcoff){ 00037 relocationTable = NULL; 00038 if(!numOfRelocations || !relocationPtr) 00039 return NULL; 00040 00041 relocationTable = new RelocationTable(relocationPtr,numOfRelocations,xcoff); 00042 relocationTable->read(binaryInputFile); 00043 return relocationTable; 00044 } 00045 00046 LineInfoTable* SectHeader::readLineInfoTable(BinaryInputFile* binaryInputFile,XCoffFile* xcoff){ 00047 lineInfoTable = NULL; 00048 if(!numOfLineInfo || !lineInfoPointer) 00049 return NULL; 00050 00051 lineInfoTable = new LineInfoTable(lineInfoPointer,numOfLineInfo,xcoff); 00052 lineInfoTable->read(binaryInputFile); 00053 return lineInfoTable; 00054 } 00055 00056 bool SectHeader::verify() { 00057 if(IS_SECT_TYPE(BSS)){ 00058 ASSERT((GET(s_scnptr) == 0) && "FATAL : BSS section does not have any raw data\n"); 00059 } 00060 if(!IS_SECT_TYPE(DATA) && !IS_SECT_TYPE(TEXT) && !IS_SECT_TYPE(OVRFLO)){ 00061 ASSERT(!GET(s_relptr) && "FATAL : Only TEXT, DATA, OVERFLO sections can have relocation data\n"); 00062 } 00063 if(!IS_SECT_TYPE(TEXT) && !IS_SECT_TYPE(OVRFLO)){ 00064 ASSERT(!GET(s_lnnoptr) && "FATAL : Only TEXT section can have line info\n"); 00065 } 00066 if(GET(s_nreloc) == LINE_RELOC_OVERFLOW){ 00067 ASSERT((GET(s_nreloc) == GET(s_nlnno)) && 00068 "FATAL : If overflow the #reloc and #lineno should match\n"); 00069 ASSERT((IS_SECT_TYPE(DATA) || IS_SECT_TYPE(TEXT)) && 00070 "FATAL :Only DAT and TEXT can have overflow\n"); 00071 } 00072 if(IS_SECT_TYPE(OVRFLO)){ 00073 ASSERT((GET(s_nreloc) == GET(s_nlnno)) && 00074 "FATAL : The section number in overflow should match\n"); 00075 ASSERT(!GET(s_size) && !GET(s_scnptr) && 00076 "FATAL : other field in overflow should be 0\n"); 00077 } 00078 00079 return true; 00080 } 00081 00082 void SectHeader::setOverFlowSection(SectHeader* sh) { 00083 ASSERT((IS_SECT_TYPE(DATA) || IS_SECT_TYPE(TEXT)) && 00084 "FATAL : Only text and Data can have reloc"); 00085 00086 overFlowSection = sh; 00087 numOfRelocations = (uint32_t)(sh->GET(s_paddr)); 00088 numOfLineInfo = (uint32_t)(sh->GET(s_vaddr)); 00089 } 00090 00091 void SectHeader::print() { 00092 char sname[__MAX_STRING_SIZE]; 00093 00094 memcpy(sname,GET(s_name),8); 00095 sname[8] = '\0'; 00096 00097 PRINT_INFOR("SECTHEADER %s",getTypeName()); 00098 PRINT_INFOR("\tName : %s",sname); 00099 PRINT_INFOR("\tType : %#x [OVRFLO TYPCHK DEBUG LOADER] [R R INFO EXCEPT] [BSS DATA TEXT R] [PAD R R R]",GET(s_flags)); 00100 PRINT_INFOR("\tPVads : %#llx %#llx",GET(s_paddr),GET(s_vaddr)); 00101 PRINT_INFOR("\tRaw : %#llx %lld bytes",GET(s_scnptr),GET(s_size)); 00102 PRINT_INFOR("\tReloc : %#llx %d",GET(s_relptr),GET(s_nreloc)); 00103 PRINT_INFOR("\tLines : %#llx %d",GET(s_lnnoptr),GET(s_nlnno)); 00104 } 00105 00106 uint32_t SectHeader32::read(BinaryInputFile* binaryInputFile){ 00107 setFileOffset(binaryInputFile->currentOffset()); 00108 00109 if(!binaryInputFile->copyBytesIterate(&entry,Size__32_bit_Section_Header)){ 00110 PRINT_ERROR("Section header (32) can not be read"); 00111 } 00112 verify(); 00113 initFilePointers(binaryInputFile); 00114 00115 return Size__32_bit_Section_Header; 00116 } 00117 00118 uint32_t SectHeader64::read(BinaryInputFile* binaryInputFile){ 00119 setFileOffset(binaryInputFile->currentOffset()); 00120 00121 if(!binaryInputFile->copyBytesIterate(&entry,Size__64_bit_Section_Header)){ 00122 PRINT_ERROR("Section header (64) can not be read"); 00123 } 00124 verify(); 00125 initFilePointers(binaryInputFile); 00126 00127 return Size__64_bit_Section_Header; 00128 } 00129 00130 #define CASE_SECTION_TYPE(__str) case STYP_ ## __str: return #__str 00131 const char* SectHeader::getTypeName(){ 00132 switch(GET(s_flags)){ 00133 CASE_SECTION_TYPE(TEXT); 00134 CASE_SECTION_TYPE(DATA); 00135 CASE_SECTION_TYPE(BSS); 00136 CASE_SECTION_TYPE(PAD); 00137 CASE_SECTION_TYPE(LOADER); 00138 CASE_SECTION_TYPE(DEBUG); 00139 CASE_SECTION_TYPE(TYPCHK); 00140 CASE_SECTION_TYPE(EXCEPT); 00141 CASE_SECTION_TYPE(OVRFLO); 00142 CASE_SECTION_TYPE(INFO); 00143 default: { 00144 ASSERT(NULL && "FATAL : Ths symbol type is incorrect"); 00145 return NULL; 00146 00147 } 00148 } 00149 } 00150