void JavaJncReader::_fillLineNumSrcMap( JNCInlineMap& ilmap, int numFrames, void* vbcisArray, void* vmethodArray, gtUInt64 thisPc, gtUInt64 nextPc ) { jint* bcisArray = (jint*) vbcisArray; jmethodID* methodArray = (jmethodID*) vmethodArray; int xx; numFrames -= 2; for (xx = numFrames; xx >= 0; xx--) { LineNumSrc lns; addrRanges addrRange; bool ret = _getSrcInfoFromBcAndMethodID(bcisArray[xx], methodArray[xx], lns.lineNum, lns.sourceFile); if (false == ret) { continue; } addrRange.startAddr = thisPc; addrRange.stopAddr = nextPc; // lns.startAddr = thisPc; // lns.stopAddr = nextPc; lns.methodId = methodArray[xx]; lns.symName = GetMethodName(methodArray[xx]); if ((gtUInt64) - 1 == nextPc) { for (unsigned int j = 1; j < m_addressRangeTable.size(); j++) { if ((m_addressRangeTable[j].id == methodArray[xx]) && (thisPc >= (gtUInt64) m_addressRangeTable[j].pc_start) && (thisPc <= (gtUInt64) m_addressRangeTable[j].pc_end)) { addrRange.startAddr = (gtUInt64) m_addressRangeTable[j].pc_start; addrRange.stopAddr = (gtUInt64) m_addressRangeTable[j].pc_end; break; } } } lns.addrs.push_back(addrRange); ilmap.insert(JNCInlineMap::value_type(thisPc, lns)); } }
// GetOffsetLines() // OffsetLinenumMap JavaJncReader::GetOffsetLines() { int line = -1; string file; if (! m_lineMap.isEmpty()) { return m_lineMap; } // fprintf (stderr, "CJNCReader::GetOffsetLines (size:%u) n", // m_jncPcStackInfoMap.size()); for (JncPcStackInfoMap::iterator it = m_jncPcStackInfoMap.begin(), itEnd = m_jncPcStackInfoMap.end(); it != itEnd; ++it) { gtUInt64 pc = it->first; if (gJncReaderVerbose) { OS_OUTPUT_FORMAT_DEBUG_LOG(OS_DEBUG_LOG_DEBUG, L"loadaddr: 0x%llx, size:%ld, pc = 0x%llx, stack size = %u", m_loadAddr, m_textSize, it->first, it->second->numstackframes); } int i = 0; for (i = 0 ; i < it->second->numstackframes; i++) { _getSrcInfoFromBcAndMethodID(it->second->bcis[i], it->second->methods[i], line, file); // Add it to offset line table unsigned int codeOffset = pc - m_loadAddr; m_lineMap[codeOffset] = line; // printf (" Frame:%2u, bcis:%4d, method:(%d) %s (%d,%s)\n", // i, it->second->bcis[i], // it->second->methods[i], // m_jncMethodMap[it->second->methods[i]].name.c_str(), // line, file.c_str()); } } // printf ("CJNcReader::GetOffsetLines: END \n"); return m_lineMap; } // GetOffsetLines
void JavaJncReader::DumpJncPcStackInfoMap(FILE* f) { if (nullptr == f) { return; } int line = -1; std::string file; fprintf(f, "DumpJncPcStackInfoMap - (size:%u)\n", m_jncPcStackInfoMap.size()); JncPcStackInfoMap::iterator it, itEnd; for (it = m_jncPcStackInfoMap.begin(), itEnd = m_jncPcStackInfoMap.end(); it != itEnd; ++it) { fprintf(f, "pc = 0x%llx, stack size = %u\n", it->first, it->second->numstackframes); for (int i = 0 ; i < it->second->numstackframes; i++) { bool ret = _getSrcInfoFromBcAndMethodID(it->second->bcis[i], it->second->methods[i], line, file); if (false == ret) { continue; } fprintf(f, " FRAME:%2u, bcis:%4d, method:(%lld) %s (%d,%s)\n", i, it->second->bcis[i], it->second->methods[i], m_jncMethodMap[it->second->methods[i]].name.c_str(), line, file.c_str()); } } fprintf(f, "DumpJncPcStackInfoMap - END\n"); return; }
void JavaJncReader::DumpJncPcStackInfoMap(FILE* f) { (void)(f); // unused #if 0 int line = -1; string file; fprintf(f, "DumpJncPcStackInfoMap - (size:%u) n", m_jncPcStackInfoMap.size()); for (JncPcStackInfoMap::iterator it = m_jncPcStackInfoMap.begin(), itEnd = m_jncPcStackInfoMap.end(); it != itEnd; ++it) { fprintf(f, "pc = 0x%llx, stack size = %u\n", it->first, it->second->numstackframes); for (int i = 0 ; i < it->second->numstackframes; i++) { _getSrcInfoFromBcAndMethodID(it->second->bcis[i], it->second->methods[i], line, file); fprintf(f, " Frame:%2u, bcis:%4d, method:(%d) %s (%d,%s)\n", i, it->second->bcis[i], it->second->methods[i], m_jncMethodMap[it->second->methods[i]].name.c_str(), line, file.c_str()); } } fprintf(f, "DumpJncPcStackInfoMap - END\n"); #endif // 0 return; }
bool JavaJncReader::_process_inline_map() { std::string file; JncPcStackInfoMap::iterator it = m_jncPcStackInfoMap.begin(), itEnd = m_jncPcStackInfoMap.end(); bool ret = true; for (; it != itEnd; ++it) { int numFrames = it->second->numstackframes; if (1 == numFrames) { continue; } gtUInt64 thisPc = (gtUInt64) it->second->pc; jint* bcisArray = it->second->bcis; jmethodID* methodArray = it->second->methods; JNCInlineMap ilmap; gtUInt64 nextPc = static_cast<gtUInt64>(-1); JncPcStackInfoMap::iterator nextit = it; ++nextit; if (nextit != itEnd) { nextPc = (gtUInt64) nextit->second->pc; } _fillLineNumSrcMap(ilmap, numFrames, bcisArray, methodArray, thisPc, nextPc); int parentLine; std::string parentSource; int xx = numFrames - 1; _getSrcInfoFromBcAndMethodID(bcisArray[xx], methodArray[xx], parentLine, parentSource); JavaInlineMap::iterator jilmit = m_javaInlineMap.find(parentLine); std::pair<JavaInlineMap::iterator, JavaInlineMap::iterator> pairMapIt = m_javaInlineMap.equal_range(parentLine); JavaInlineMap::iterator itr = pairMapIt.first; while (itr != pairMapIt.second) { jilmit = itr; itr++; } if (jilmit == m_javaInlineMap.end()) { // Parent line does not exist - add it m_javaInlineMap.insert(JavaInlineMap::value_type(parentLine, ilmap)); } else { // Parent line exists - see if this stack already exists if (ilmap.size() == jilmit->second.size()) { bool bMerged = false; while (!bMerged) { JNCInlineMap::iterator newilmapit = ilmap.begin(); JNCInlineMap::iterator newmainit = jilmit->second.begin(); bool bIsEqual = true; for (; (newilmapit != ilmap.end()) && (newmainit != jilmit->second.end()); ++newilmapit, ++newmainit) { if (!(newilmapit->second == newmainit->second)) { bIsEqual = false; break; } } if (bIsEqual) { // Merge the address range of this stack with the existing stack newilmapit = ilmap.begin(); newmainit = jilmit->second.begin(); for (; (newilmapit != ilmap.end()) && (newmainit != jilmit->second.end()); ++newilmapit, ++newmainit) { addrRanges ilAR = *(newilmapit->second.addrs.begin()); // will only be one of these // multiple of these bool bDidMerge = false; AddressRangeList::iterator arIt = newmainit->second.addrs.begin(), arEnd = newmainit->second.addrs.end(); for (; arIt != arEnd; ++arIt) { if ((ilAR.startAddr >= (*arIt).startAddr) && (ilAR.startAddr <= (*arIt).stopAddr)) { (*arIt).startAddr = std::min((*arIt).startAddr, ilAR.startAddr); (*arIt).stopAddr = std::max((*arIt).stopAddr, ilAR.stopAddr); bDidMerge = true; // TODO: Need to check if adding this range should merge other ranges break; } } if (!bDidMerge) { newmainit->second.addrs.push_back(ilAR); } } bMerged = true; } if (bMerged) { break; } ++jilmit; if ((jilmit == m_javaInlineMap.end()) || (jilmit->first != parentLine)) { break; } } if (!bMerged) { // TODO: What about this case? // printf("After while - no merge done!!\n"); fflush(stdout); } } else { m_javaInlineMap.insert(JavaInlineMap::value_type(parentLine, ilmap)); } // if (ilmap.size() == jilmit->second.size()) } // if (jilmit == m_javaInlineMap.end()) } // for return ret; }
OffsetLinenumMap JavaJncReader::GetOffsetLines(std::wstring funcName) { int line = -1; std::string file; if (! m_lineMap.isEmpty()) { return m_lineMap; } //fprintf(debugFP, "============================\n"); //DumpJncPcStackInfoMap(debugFP); //if (gJncReaderVerbose) //{ //fprintf (stderr, "CJNCReader::GetOffsetLines (size:%lu) n", // m_jncPcStackInfoMap.size()); //} JncPcStackInfoMap::iterator it, itEnd; for (it = m_jncPcStackInfoMap.begin(), itEnd = m_jncPcStackInfoMap.end(); it != itEnd; ++it) { gtUInt64 pc = it->first; if (nullptr != debugFP) { fprintf(debugFP, "loadaddr: 0x%llx, pc = 0x%llx, stack size = %u\n", m_LoadAddr, pc, it->second->numstackframes); } int i = 0; for (i = 0 ; i < it->second->numstackframes; i++) { if (m_jncMethodMap[it->second->methods[i]].name.empty()) { if (debugFP != nullptr) { fprintf(debugFP, "Empty methods name..\n"); } continue; } std::wstring tmpStr(m_jncMethodMap[it->second->methods[i]].name.begin(), m_jncMethodMap[it->second->methods[i]].name.end()); // parse method signature char parsedMethodSig[OS_MAX_PATH] = { 0 }; parseMethodSignature(nullptr, m_jncMethodMap[it->second->methods[i]].signature.data(), parsedMethodSig); // append parsed signature to tmpStr tmpStr.append(parsedMethodSig, parsedMethodSig + strlen(parsedMethodSig)); if ((!funcName.empty()) && wcscmp(funcName.c_str(), tmpStr.c_str())) { continue; } bool rv = _getSrcInfoFromBcAndMethodID(it->second->bcis[i], it->second->methods[i], line, file); if (false == rv) { continue; } // Add it to offset line table unsigned int codeOffset = (unsigned int)(pc - m_LoadAddr); m_lineMap[codeOffset] = line; // if (gJncReaderVerbose) if (nullptr != debugFP) { fprintf(debugFP, " Frame:%2u, bcis:%4d, method:(%lld) %s (%d,%s)\n", i, it->second->bcis[i], it->second->methods[i], m_jncMethodMap[it->second->methods[i]].name.c_str(), line, file.c_str()); } } } return m_lineMap; } // GetOffsetLines(wstring funcName)
bool JavaJncReader::GetSrcInfoFromAddressWithFile( gtUInt64 addr, int& srcLine, string& srcFile ) { // Check if this address belongs to the code section of this module if ((addr < m_loadAddr) || (addr >= (m_loadAddr + m_textSize))) { return false; } if (m_jncMethodMap.size() == 0) { return false; } // If the address is the beginning of the function, just return the info // NOTE: This is often the case, so this block helps speed things up. if (addr == m_loadAddr) { // Get last item in the MethodMap srcFile = m_srcFile; srcLine = m_startLine; return true; } // Search the PCStackInfoMap for the appropriate data bool bFound = false; JncPcStackInfoMap::reverse_iterator rit = m_jncPcStackInfoMap.rbegin(), rend = m_jncPcStackInfoMap.rend(); for (; rit != rend; ++rit) { if (addr >= rit->first) { bFound = true; break; } } // If not found, we assume that this address belongs // to the first line of the function if (!bFound) { srcFile = m_srcFile; srcLine = m_startLine; } else { int level = rit->second->numstackframes - 1; bool foundit = false; for (level = 0; level < rit->second->numstackframes; level++) { string file; _getSrcInfoFromBcAndMethodID(rit->second->bcis[level], rit->second->methods[level], srcLine, file); if (srcFile == file) { foundit = true; break; } } if (!foundit) { return false; } } return true; }
// GetOffsetLines(wstring funcName) // OffsetLinenumMap JavaJncReader::GetOffsetLines(wstring funcName) { int line = -1; string file; if (! m_lineMap.isEmpty()) { return m_lineMap; } if (gJncReaderVerbose) { fprintf(stderr, "CJNCReader::GetOffsetLines (size:%lu) n", m_jncPcStackInfoMap.size()); } JncPcStackInfoMap::iterator it = m_jncPcStackInfoMap.begin(); JncPcStackInfoMap::iterator itEnd = m_jncPcStackInfoMap.end(); for (; it != itEnd; it++) { uint64_t pc = it->first; if (gJncReaderVerbose) { fprintf(stderr, "loadaddr: 0x%lx, size:%ld, pc = 0x%lx, stack size = %u\n", m_loadAddr, m_textSize, it->first, it->second->numstackframes); } int i = 0; for (i = 0 ; i < it->second->numstackframes; i++) { wstring tmpStr(m_jncMethodMap[it->second->methods[i]].name.begin(), m_jncMethodMap[it->second->methods[i]].name.end()); // parse method signature char parsedMethodSig[OS_MAX_PATH] = { 0 }; parseMethodSignature(nullptr, m_jncMethodMap[it->second->methods[i]].signature.data(), parsedMethodSig); // append parsed signature to tmpStr tmpStr.append(parsedMethodSig, parsedMethodSig + strlen(parsedMethodSig)); if ((!funcName.empty()) && wcscmp(funcName.c_str(), tmpStr.c_str())) { continue; } _getSrcInfoFromBcAndMethodID(it->second->bcis[i], it->second->methods[i], line, file); // Add it to offset line table unsigned int codeOffset = pc - m_loadAddr; m_lineMap[codeOffset] = line; if (gJncReaderVerbose) { fprintf(stderr, " Frame:%2u, bcis:%4d, method:(%lx) %s (%d,%s)\n", i, it->second->bcis[i], (uint64_t)it->second->methods[i], m_jncMethodMap[it->second->methods[i]].name.c_str(), line, file.c_str()); } } } return m_lineMap; } // GetOffsetLines(wstring funcName)