995 iMapFileInfo.iSymbolPCEntrySet.push_back(tmpSymbolEntry); |
983 iMapFileInfo.iSymbolPCEntrySet.push_back(tmpSymbolEntry); |
996 } |
984 } |
997 } |
985 } |
998 } |
986 } |
999 } |
987 } |
|
988 |
|
989 // BsymRomSymbolProcessUnit start |
|
990 |
|
991 void BsymRomSymbolProcessUnit::ProcessEntry(const TPlacedEntry& aEntry) |
|
992 { |
|
993 iPlacedEntry = aEntry; |
|
994 SymbolProcessUnit::ProcessEntry(aEntry); |
|
995 iMapFileInfo.iDbgUnitPCEntry.iPCName = aEntry.iFileName; |
|
996 iMapFileInfo.iDbgUnitPCEntry.iDevName = aEntry.iDevFileName; |
|
997 } |
|
998 |
|
999 void BsymRomSymbolProcessUnit::ProcessExecutableFile(const string& aFile) |
|
1000 { |
|
1001 ResetContentLog(); |
|
1002 char str[MAX_LINE]; |
|
1003 string mapFile2 = aFile+".map"; |
|
1004 size_t dot = aFile.rfind('.'); |
|
1005 string mapFile = aFile.substr(0,dot)+".map"; |
|
1006 ifstream fMap; |
|
1007 fMap.open(mapFile2.c_str()); |
|
1008 if(!fMap.is_open()) { |
|
1009 fMap.open(mapFile.c_str()); |
|
1010 } |
|
1011 if(!fMap.is_open()) { |
|
1012 sprintf(str, "\nWarning: Can't open \"%s\" or \"%s\"\n",mapFile2.c_str(),mapFile.c_str()); |
|
1013 iStdoutLog.push_back(str); |
|
1014 TSymbolPCEntry tmpEntry; |
|
1015 tmpEntry.iSymbolEntry.iAddress = iPlacedEntry.iCodeAddress; |
|
1016 tmpEntry.iSymbolEntry.iLength = iPlacedEntry.iTotalSize; |
|
1017 tmpEntry.iName = aFile.substr(aFile.rfind(PATH_SEPARATOR)+1); |
|
1018 iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry); |
|
1019 iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iDataSymbolCount++; |
|
1020 } |
|
1021 else { |
|
1022 if(!fMap.good()) fMap.clear(); |
|
1023 char buffer[100]; |
|
1024 fMap.getline(buffer, 100); |
|
1025 boost::regex regARMV5("ARM Linker", boost::regex::icase); |
|
1026 boost::regex regGCCEoARMV4("Archive member included", boost::regex::icase); |
|
1027 boost::cmatch what; |
|
1028 if(regex_search(buffer, what, regARMV5)) { |
|
1029 ProcessArmv5File(aFile, fMap); |
|
1030 } |
|
1031 else if(regex_search(buffer, what, regGCCEoARMV4)) { |
|
1032 ProcessGcceOrArm4File(aFile, fMap); |
|
1033 } |
|
1034 else { |
|
1035 fMap.seekg(0, ios_base::beg); |
|
1036 ProcessX86File(aFile, fMap); |
|
1037 } |
|
1038 } |
|
1039 } |
|
1040 |
|
1041 void BsymRomSymbolProcessUnit::ProcessArmv5File(const string& fileName, ifstream& aMap) |
|
1042 { |
|
1043 string symName ; |
|
1044 ArmSymMap symbols ; |
|
1045 vector<char*> words ; |
|
1046 ArmSymbolInfo info; |
|
1047 char* lineStart ; |
|
1048 char buffer[MAX_LINE]; |
|
1049 while(aMap.good() && (!aMap.eof())){ |
|
1050 *buffer = 0; |
|
1051 aMap.getline(buffer,MAX_LINE); |
|
1052 lineStart = buffer ; |
|
1053 SKIP_WS(lineStart); |
|
1054 if(strstr(lineStart,"Global Symbols")) |
|
1055 break ; |
|
1056 char* armstamp = strstr(lineStart,"ARM Code"); |
|
1057 if(0 == armstamp) |
|
1058 armstamp = strstr(lineStart,"Thumb Code") ; |
|
1059 if(0 == armstamp) continue ; |
|
1060 *(armstamp - 1) = 0 ; |
|
1061 |
|
1062 char* hexStr = lineStart ; |
|
1063 char* nameEnd; |
|
1064 while(1) { |
|
1065 hexStr = strstr(hexStr,"0x"); |
|
1066 if(0 == hexStr) break ; |
|
1067 nameEnd = hexStr - 1; |
|
1068 if(*nameEnd == ' ' || *nameEnd == '\t') break ; |
|
1069 hexStr += 2 ; |
|
1070 } |
|
1071 if(0 == hexStr) continue ; |
|
1072 while(nameEnd > lineStart && (*nameEnd == ' ' || *nameEnd == '\t')) |
|
1073 nameEnd -- ; |
|
1074 |
|
1075 nameEnd[1] = 0; |
|
1076 info.name = lineStart; |
|
1077 char* temp ; |
|
1078 TUint32 addr = strtoul(hexStr + 2,&temp,16); |
|
1079 char* decStr ; |
|
1080 if(*armstamp == 'A') |
|
1081 decStr = armstamp + 9 ; |
|
1082 else |
|
1083 decStr = armstamp + 11 ; |
|
1084 SKIP_WS(decStr); |
|
1085 info.size = strtoul(decStr,&temp,10); |
|
1086 SKIP_WS(temp); |
|
1087 info.section = temp; |
|
1088 if(info.section.find("(StubCode)") != string::npos ) |
|
1089 info.size = 8 ; |
|
1090 if(addr > 0){ |
|
1091 symbols.insert(pair<TUint32,ArmSymbolInfo>(addr,info)); |
|
1092 } |
|
1093 } |
|
1094 size_t lenOfFileName = iPlacedEntry.iFileName.length(); |
|
1095 while(aMap.good() && (!aMap.eof())){ |
|
1096 *buffer = 0; |
|
1097 aMap.getline(buffer,MAX_LINE); |
|
1098 lineStart = buffer ; |
|
1099 SKIP_WS(lineStart); |
|
1100 char* hexStr = lineStart ; |
|
1101 char* nameEnd; |
|
1102 while(1) { |
|
1103 hexStr = strstr(hexStr,"0x"); |
|
1104 if(0 == hexStr) break ; |
|
1105 nameEnd = hexStr - 1; |
|
1106 if(*nameEnd == ' ' || *nameEnd == '\t') |
|
1107 break ; |
|
1108 hexStr += 2 ; |
|
1109 } |
|
1110 if(0 == hexStr) continue ; |
|
1111 while(nameEnd > lineStart && (*nameEnd == ' ' || *nameEnd == '\t')){ |
|
1112 nameEnd -- ; |
|
1113 } |
|
1114 nameEnd[1] = 0; |
|
1115 info.name = lineStart; |
|
1116 char *temp ; |
|
1117 TUint32 addr = strtoul(hexStr + 2,&temp,16); |
|
1118 while(*temp < '0' || *temp > '9' )//[^\d]* |
|
1119 temp++ ; |
|
1120 char* decStr = temp ; |
|
1121 info.size = strtoul(decStr,&temp,10); |
|
1122 SKIP_WS(temp); |
|
1123 info.section = temp; |
|
1124 if(info.section.find("(StubCode)") != string::npos ) |
|
1125 info.size = 8 ; |
|
1126 if(addr > 0){ |
|
1127 symbols.insert(pair<TUint32,ArmSymbolInfo>(addr,info)); |
|
1128 } |
|
1129 } |
|
1130 |
|
1131 TUint32 textSectAddr = 0x00008000; // .text gets linked at 0x00008000 |
|
1132 TUint32 dataSectAddr = 0x00400000 ; // .data gets linked at 0x00400000 |
|
1133 size_t allocBytes; |
|
1134 boost::regex regScope("^\\s*(\\w+)\\s*::\\s*(.*)$"); |
|
1135 boost::cmatch what; |
|
1136 for( ArmSymMap::iterator it = symbols.begin(); it != symbols.end() ; it++){ |
|
1137 TSymbolPCEntry tmpEntry; |
|
1138 TUint32 thisAddr = it->first ; |
|
1139 TUint32 romAddr ; |
|
1140 ArmSymbolInfo& info = it->second; |
|
1141 if (thisAddr >= textSectAddr && thisAddr <= (textSectAddr + iPlacedEntry.iTextSize)) { |
|
1142 romAddr = thisAddr - textSectAddr + iPlacedEntry.iCodeAddress ; |
|
1143 tmpEntry.iSymbolEntry.iAddress = romAddr; |
|
1144 iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iCodeSymbolCount++; |
|
1145 } |
|
1146 else if ( iPlacedEntry.iDataAddress && |
|
1147 ( thisAddr >= dataSectAddr && thisAddr <= (dataSectAddr + iPlacedEntry.iTextSize))) { |
|
1148 romAddr = thisAddr-dataSectAddr + iPlacedEntry.iDataBssLinearBase; |
|
1149 tmpEntry.iSymbolEntry.iAddress = romAddr; |
|
1150 iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iDataSymbolCount++; |
|
1151 } |
|
1152 else if ( iPlacedEntry.iDataBssLinearBase && |
|
1153 ( thisAddr >= dataSectAddr && thisAddr <= (dataSectAddr+ iPlacedEntry.iTotalDataSize))) { |
|
1154 romAddr = thisAddr - dataSectAddr + iPlacedEntry.iDataBssLinearBase; |
|
1155 tmpEntry.iSymbolEntry.iAddress = romAddr; |
|
1156 iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iBssSymbolCount++; |
|
1157 } |
|
1158 else { |
|
1159 allocBytes = info.name.length() + 60; |
|
1160 char* msg = new char[allocBytes] ; |
|
1161 snprintf(msg,allocBytes,"\r\nWarning: Symbol %s @ 0x%08x not in text or data segments\r\n", \ |
|
1162 info.name.c_str() ,(unsigned int)thisAddr) ; |
|
1163 iStdoutLog.push_back(msg); |
|
1164 allocBytes = lenOfFileName + 80; |
|
1165 msg = new char[allocBytes]; |
|
1166 snprintf(msg,allocBytes,"Warning: The map file for binary %s is out-of-sync with the binary itself\r\n\r\n",iPlacedEntry.iFileName.c_str()); |
|
1167 iStdoutLog.push_back(msg); |
|
1168 continue ; |
|
1169 } |
|
1170 tmpEntry.iSymbolEntry.iLength = info.size; |
|
1171 if(regex_search(info.name.c_str(), what, regScope)) |
|
1172 { |
|
1173 tmpEntry.iScopeName.assign(what[1].first, what[1].second-what[1].first); |
|
1174 tmpEntry.iName.assign(what[2].first, what[2].second-what[2].first); |
|
1175 } |
|
1176 else |
|
1177 { |
|
1178 tmpEntry.iScopeName = ""; |
|
1179 tmpEntry.iName = info.name; |
|
1180 } |
|
1181 tmpEntry.iSecName = info.section; |
|
1182 iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry); |
|
1183 } |
|
1184 } |
|
1185 |
|
1186 void BsymRomSymbolProcessUnit::ProcessGcceOrArm4File(const string& fileName, ifstream& aMap) |
|
1187 { |
|
1188 char* lineStart; |
|
1189 vector<char*> words ; |
|
1190 char buffer[MAX_LINE]; |
|
1191 while(aMap.good() && (!aMap.eof())){ |
|
1192 aMap.getline(buffer,MAX_LINE); |
|
1193 lineStart = buffer ; |
|
1194 SKIP_WS(lineStart); |
|
1195 if( 0 == strncmp(lineStart,".text",5)) { |
|
1196 lineStart += 5; |
|
1197 break ; |
|
1198 } |
|
1199 } |
|
1200 split(lineStart,words); |
|
1201 TUint32 codeAddr , codeSize; |
|
1202 size_t allocBytes ; |
|
1203 if(words.size() != 2 || |
|
1204 KErrNone != Val(codeAddr,words.at(0)) || |
|
1205 KErrNone != Val(codeSize,words.at(1))) { |
|
1206 allocBytes = iPlacedEntry.iFileName.length() + 60; |
|
1207 char* msg = new char[allocBytes]; |
|
1208 snprintf(msg,allocBytes,"\nError: Can't get .text section info for \"%s\"\r\n",iPlacedEntry.iFileName.c_str()); |
|
1209 iStdoutLog.push_back(msg); |
|
1210 return; |
|
1211 } |
|
1212 map<TUint32,string> symbols ; |
|
1213 TUint32 stubHex = 0; |
|
1214 //Slurp symbols 'til the end of the text section |
|
1215 while(aMap.good() && (!aMap.eof())){ |
|
1216 aMap.getline(buffer,MAX_LINE); |
|
1217 lineStart = buffer ; |
|
1218 SKIP_WS(lineStart); |
|
1219 if(0 == *lineStart) break ; //blank line marks the end of the text section |
|
1220 |
|
1221 // .text <addr> <len> <library(member)> |
|
1222 // .text$something |
|
1223 // <addr> <len> <library(member)> |
|
1224 // <addr> <len> LONG 0x0 |
|
1225 // (/^\s(\.text)?\s+(0x\w+)\s+(0x\w+)\s+(.*)$/io) |
|
1226 if(strncmp(lineStart,".text",5) == 0){ |
|
1227 lineStart += 5 ; |
|
1228 SKIP_WS(lineStart); |
|
1229 } |
|
1230 char* hex1 = NULL ; |
|
1231 char* hex2 = NULL ; |
|
1232 char* strAfterhex1 = NULL ; |
|
1233 TUint32 addr,size ; |
|
1234 if(strncmp(lineStart,"0x",2) == 0){ |
|
1235 hex1 = lineStart + 2; |
|
1236 char* temp ; |
|
1237 addr = strtoul(hex1,&temp,16); |
|
1238 SKIP_WS(temp); |
|
1239 strAfterhex1 = temp ; |
|
1240 if(strncmp(temp,"0x",2) == 0){ |
|
1241 hex2 = temp + 2 ; |
|
1242 } |
|
1243 } |
|
1244 if(NULL != hex2){ |
|
1245 char* libraryfile ; |
|
1246 size = strtoul(hex2,&libraryfile,16); |
|
1247 SKIP_WS(libraryfile); |
|
1248 TUint32 key = addr + size ; |
|
1249 put_to_map(symbols,key,string(""));//impossible symbol as end marker |
|
1250 make_lower(libraryfile); |
|
1251 size_t len = strlen(libraryfile); |
|
1252 char* p1 = strstr(libraryfile,".lib("); |
|
1253 if(NULL == p1) |
|
1254 continue ; |
|
1255 p1 += 5; |
|
1256 if(strcmp(libraryfile + len - 3,".o)")!= 0) |
|
1257 continue ; |
|
1258 len -= 3 ; |
|
1259 libraryfile[len] = 0; |
|
1260 if(EFalse == IsValidNumber(libraryfile + len - 5)) |
|
1261 continue ; |
|
1262 len -= 7 ; |
|
1263 if('_' == libraryfile[len]) |
|
1264 len -- ; |
|
1265 if('s' != libraryfile[len]) |
|
1266 continue ; |
|
1267 char* p2 = libraryfile + len - 1; |
|
1268 while(p2 > p1 ) { |
|
1269 if(*p2 < '0' || *p2 > '9') |
|
1270 break ; |
|
1271 p2 -- ; |
|
1272 } |
|
1273 if(*p2 != 'd') |
|
1274 continue ; |
|
1275 stubHex = addr ; |
|
1276 } |
|
1277 else if(NULL != hex1 && NULL != strAfterhex1){ |
|
1278 //# <addr> <symbol name possibly including spaces> |
|
1279 //(/^\s+(\w+)\s\s+([a-zA-Z_].+)/o) |
|
1280 char* symName = strAfterhex1; |
|
1281 if((*symName >= 'A' && *symName <= 'Z') || |
|
1282 (*symName >= 'a' && *symName <= 'z') || *symName == '_') { |
|
1283 string symbol(symName); |
|
1284 if(addr == stubHex) |
|
1285 symbol.insert(0,"stub "); |
|
1286 |
|
1287 put_to_map(symbols,addr,symbol); |
|
1288 } |
|
1289 } |
|
1290 } |
|
1291 map<TUint32,string>::iterator it = symbols.begin(); |
|
1292 TUint32 lastAddr = it->first; |
|
1293 string lastSymName = it->second; |
|
1294 vector<pair<int,char*> >lines ; |
|
1295 it ++ ; |
|
1296 while(it != symbols.end()) { |
|
1297 TSymbolPCEntry tmpEntry; |
|
1298 TUint32 addr = it->first ; |
|
1299 unsigned int fixedupAddr = lastAddr - codeAddr + iPlacedEntry.iCodeAddress; |
|
1300 TUint size = addr - lastAddr ; |
|
1301 if(!lastSymName.empty()) { |
|
1302 tmpEntry.iSymbolEntry.iAddress = fixedupAddr; |
|
1303 tmpEntry.iSymbolEntry.iLength = size; |
|
1304 tmpEntry.iScopeName = ""; |
|
1305 tmpEntry.iName = lastSymName; |
|
1306 tmpEntry.iSecName = ""; |
|
1307 iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iCodeSymbolCount++; |
|
1308 } |
|
1309 lastAddr = addr ; |
|
1310 lastSymName = it->second; |
|
1311 it ++ ; |
|
1312 } |
|
1313 } |
|
1314 |
|
1315 void BsymRomSymbolProcessUnit::ProcessX86File(const string& fileName, ifstream& aMap) |
|
1316 { |
|
1317 char buffer[MAX_LINE]; |
|
1318 char* lineStart; |
|
1319 while(aMap.good() && (!aMap.eof())){ |
|
1320 aMap.getline(buffer,MAX_LINE); |
|
1321 lineStart = buffer ; |
|
1322 SKIP_WS(lineStart); |
|
1323 if( 0 == strncmp(lineStart,"Address",7)) { |
|
1324 break ; |
|
1325 } |
|
1326 } |
|
1327 aMap.getline(buffer,MAX_LINE); |
|
1328 string lastName ; |
|
1329 TUint32 lastAddr = 0; |
|
1330 vector<pair<int, char*> >lines ; |
|
1331 while(aMap.good() && (!aMap.eof())){ |
|
1332 TSymbolPCEntry tmpEntry; |
|
1333 aMap.getline(buffer,MAX_LINE); |
|
1334 lineStart = buffer ; |
|
1335 SKIP_WS(lineStart); |
|
1336 if(0 != strncmp(lineStart,"0001:",5)) |
|
1337 break ; |
|
1338 char* end ; |
|
1339 TUint32 addr = strtoul(lineStart + 5,&end,16); |
|
1340 char* name = end + 1; |
|
1341 SKIP_WS(name); |
|
1342 end = name + 1; |
|
1343 FIND_WS(end); |
|
1344 *end = 0 ; |
|
1345 if(!lastName.empty()){ |
|
1346 unsigned int size = addr - lastAddr ; |
|
1347 unsigned int romAddr = lastAddr + iPlacedEntry.iCodeAddress; |
|
1348 tmpEntry.iSymbolEntry.iAddress = romAddr; |
|
1349 tmpEntry.iSymbolEntry.iLength = size; |
|
1350 tmpEntry.iName = lastName; |
|
1351 iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry); |
|
1352 iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iCodeSymbolCount++; |
|
1353 } |
|
1354 lastName = name; |
|
1355 lastAddr = addr; |
|
1356 } |
|
1357 if(!lastName.empty()){ |
|
1358 TSymbolPCEntry tmpEntry; |
|
1359 unsigned int romAddr = lastAddr + iPlacedEntry.iCodeAddress; |
|
1360 tmpEntry.iSymbolEntry.iAddress = romAddr; |
|
1361 tmpEntry.iSymbolEntry.iLength = 0; |
|
1362 tmpEntry.iName = lastName; |
|
1363 iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry); |
|
1364 iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iCodeSymbolCount++; |
|
1365 } |
|
1366 } |
|
1367 |
|
1368 void BsymRomSymbolProcessUnit::FlushSymbolContent(ostream &aOut) |
|
1369 { |
|
1370 iSymbolGeneratorPtr->AppendMapFileInfo(iMapFileInfo); |
|
1371 } |
|
1372 |
|
1373 void BsymRomSymbolProcessUnit::ResetContentLog() |
|
1374 { |
|
1375 iStdoutLog.clear(); |
|
1376 iMapFileInfo.iDbgUnitPCEntry.iPCName = ""; |
|
1377 iMapFileInfo.iDbgUnitPCEntry.iDevName = ""; |
|
1378 iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.Reset(); |
|
1379 iMapFileInfo.iSymbolPCEntrySet.clear(); |
|
1380 } |
|
1381 |
|
1382 void BsymRomSymbolProcessUnit::ProcessDataFile(const string& aFile) |
|
1383 { |
|
1384 ResetContentLog(); |
|
1385 string basename = aFile.substr(aFile.rfind(PATH_SEPARATOR)+1); |
|
1386 TSymbolPCEntry tmpEntry; |
|
1387 tmpEntry.iSymbolEntry.iAddress = iPlacedEntry.iDataAddress; |
|
1388 tmpEntry.iSymbolEntry.iLength = 0; |
|
1389 tmpEntry.iName = basename; |
|
1390 iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry); |
|
1391 iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iDataSymbolCount++; |
|
1392 } |