@@ -1307,6 +1307,310 @@ std::vector<DebugModule> EsrevenAdapter::GetModuleList()
13071307}
13081308
13091309
1310+ std::vector<TTDMemoryEvent> EsrevenAdapter::GetTTDMemoryAccessForAddress (uint64_t startAddress, uint64_t endAddress, TTDMemoryAccessType accessType)
1311+ {
1312+ if (m_isTargetRunning)
1313+ return {};
1314+
1315+ if (!m_rspConnector)
1316+ return {};
1317+
1318+ // Convert TTDMemoryAccessType flags to comma-separated string
1319+ std::vector<std::string> types;
1320+ if (accessType & TTDMemoryRead)
1321+ types.push_back (" read" );
1322+ if (accessType & TTDMemoryWrite)
1323+ types.push_back (" write" );
1324+ if (accessType & TTDMemoryExecute)
1325+ types.push_back (" execute" );
1326+
1327+ if (types.empty ())
1328+ return {};
1329+
1330+ std::string typesStr;
1331+ for (size_t i = 0 ; i < types.size (); i++)
1332+ {
1333+ if (i > 0 )
1334+ typesStr += " ," ;
1335+ typesStr += types[i];
1336+ }
1337+
1338+ // Send the custom REVEN packet: rvn:get-memory-accesses:<start>:<end>:<types>
1339+ auto response = m_rspConnector->TransmitAndReceive (
1340+ RspData (" rvn:get-memory-accesses:{:x}:{:x}:{}" , startAddress, endAddress, typesStr));
1341+ std::string jsonStr = response.AsString ();
1342+
1343+ // Check if we got a valid JSON array response
1344+ if (jsonStr.empty () || jsonStr[0 ] != ' [' )
1345+ return {};
1346+
1347+ std::vector<TTDMemoryEvent> result;
1348+
1349+ // Simple JSON parser for array of memory access objects
1350+ size_t pos = 0 ;
1351+ while (pos < jsonStr.length ())
1352+ {
1353+ // Find the start of an object
1354+ size_t objStart = jsonStr.find (' {' , pos);
1355+ if (objStart == std::string::npos)
1356+ break ;
1357+
1358+ // Find the end of the object
1359+ size_t objEnd = jsonStr.find (' }' , objStart);
1360+ if (objEnd == std::string::npos)
1361+ break ;
1362+
1363+ std::string objStr = jsonStr.substr (objStart, objEnd - objStart + 1 );
1364+
1365+ TTDMemoryEvent event;
1366+ event.eventType = " MemoryAccess" ;
1367+
1368+ // Helper lambda to extract uint64_t value from JSON
1369+ auto extractUInt64 = [](const std::string& json, const std::string& key) -> uint64_t {
1370+ size_t keyPos = json.find (" \" " + key + " \" " );
1371+ if (keyPos == std::string::npos)
1372+ return 0 ;
1373+
1374+ size_t colonPos = json.find (' :' , keyPos);
1375+ if (colonPos == std::string::npos)
1376+ return 0 ;
1377+
1378+ // Skip whitespace after colon
1379+ size_t valueStart = colonPos + 1 ;
1380+ while (valueStart < json.length () && std::isspace (json[valueStart]))
1381+ valueStart++;
1382+
1383+ // Check if value is null
1384+ if (json.substr (valueStart, 4 ) == " null" )
1385+ return 0 ;
1386+
1387+ // Find end of number (comma, closing brace, or whitespace)
1388+ size_t valueEnd = valueStart;
1389+ while (valueEnd < json.length () &&
1390+ std::isdigit (json[valueEnd]))
1391+ valueEnd++;
1392+
1393+ if (valueEnd > valueStart)
1394+ {
1395+ std::string valueStr = json.substr (valueStart, valueEnd - valueStart);
1396+ return std::stoull (valueStr);
1397+ }
1398+ return 0 ;
1399+ };
1400+
1401+ // Helper lambda to extract string value from JSON
1402+ auto extractString = [](const std::string& json, const std::string& key) -> std::string {
1403+ size_t keyPos = json.find (" \" " + key + " \" " );
1404+ if (keyPos == std::string::npos)
1405+ return " " ;
1406+
1407+ size_t colonPos = json.find (' :' , keyPos);
1408+ if (colonPos == std::string::npos)
1409+ return " " ;
1410+
1411+ size_t valueStart = json.find (' "' , colonPos);
1412+ if (valueStart == std::string::npos)
1413+ return " " ;
1414+
1415+ size_t valueEnd = json.find (' "' , valueStart + 1 );
1416+ if (valueEnd == std::string::npos)
1417+ return " " ;
1418+
1419+ return json.substr (valueStart + 1 , valueEnd - valueStart - 1 );
1420+ };
1421+
1422+ // Extract fields from JSON
1423+ uint64_t transitionId = extractUInt64 (objStr, " transition_id" );
1424+ event.address = extractUInt64 (objStr, " address" );
1425+ event.memoryAddress = event.address ; // Same as address
1426+ event.size = extractUInt64 (objStr, " size" );
1427+ event.instructionAddress = extractUInt64 (objStr, " instruction_address" );
1428+ event.value = extractUInt64 (objStr, " value" );
1429+
1430+ // Extract thread_id (may be null)
1431+ event.threadId = static_cast <uint32_t >(extractUInt64 (objStr, " thread_id" ));
1432+ event.uniqueThreadId = event.threadId ;
1433+
1434+ // Convert transition_id to TTDPosition (use as sequence, step=0)
1435+ event.timeStart = TTDPosition (transitionId, 0 );
1436+ event.timeEnd = event.timeStart ;
1437+
1438+ // Extract and convert access_type string to enum
1439+ std::string accessTypeStr = extractString (objStr, " access_type" );
1440+ if (accessTypeStr == " read" )
1441+ event.accessType = TTDMemoryRead;
1442+ else if (accessTypeStr == " write" )
1443+ event.accessType = TTDMemoryWrite;
1444+ else if (accessTypeStr == " execute" )
1445+ event.accessType = TTDMemoryExecute;
1446+ else
1447+ event.accessType = TTDMemoryRead; // Default
1448+
1449+ result.push_back (event);
1450+
1451+ pos = objEnd + 1 ;
1452+ }
1453+
1454+ return result;
1455+ }
1456+
1457+
1458+ std::vector<TTDPositionRangeIndexedMemoryEvent> EsrevenAdapter::GetTTDMemoryAccessForPositionRange (
1459+ uint64_t startAddress, uint64_t endAddress, TTDMemoryAccessType accessType,
1460+ const TTDPosition startTime, const TTDPosition endTime)
1461+ {
1462+ if (m_isTargetRunning)
1463+ return {};
1464+
1465+ if (!m_rspConnector)
1466+ return {};
1467+
1468+ // Convert TTDMemoryAccessType flags to comma-separated string
1469+ std::vector<std::string> types;
1470+ if (accessType & TTDMemoryRead)
1471+ types.push_back (" read" );
1472+ if (accessType & TTDMemoryWrite)
1473+ types.push_back (" write" );
1474+ if (accessType & TTDMemoryExecute)
1475+ types.push_back (" execute" );
1476+
1477+ if (types.empty ())
1478+ return {};
1479+
1480+ std::string typesStr;
1481+ for (size_t i = 0 ; i < types.size (); i++)
1482+ {
1483+ if (i > 0 )
1484+ typesStr += " ," ;
1485+ typesStr += types[i];
1486+ }
1487+
1488+ // TTDPosition.sequence maps to REVEN transition_id (step is always 0 in REVEN)
1489+ uint64_t startTransition = startTime.sequence ;
1490+ uint64_t endTransition = endTime.sequence ;
1491+
1492+ // Send the custom REVEN packet with time range: rvn:get-memory-accesses:<start>:<end>:<types>:<start_trans>:<end_trans>
1493+ auto response = m_rspConnector->TransmitAndReceive (
1494+ RspData (" rvn:get-memory-accesses:{:x}:{:x}:{}:{}:{}" ,
1495+ startAddress, endAddress, typesStr, startTransition, endTransition));
1496+ std::string jsonStr = response.AsString ();
1497+
1498+ // Check if we got a valid JSON array response
1499+ if (jsonStr.empty () || jsonStr[0 ] != ' [' )
1500+ return {};
1501+
1502+ std::vector<TTDPositionRangeIndexedMemoryEvent> result;
1503+
1504+ // Simple JSON parser for array of memory access objects
1505+ size_t pos = 0 ;
1506+ while (pos < jsonStr.length ())
1507+ {
1508+ // Find the start of an object
1509+ size_t objStart = jsonStr.find (' {' , pos);
1510+ if (objStart == std::string::npos)
1511+ break ;
1512+
1513+ // Find the end of the object
1514+ size_t objEnd = jsonStr.find (' }' , objStart);
1515+ if (objEnd == std::string::npos)
1516+ break ;
1517+
1518+ std::string objStr = jsonStr.substr (objStart, objEnd - objStart + 1 );
1519+
1520+ TTDPositionRangeIndexedMemoryEvent event;
1521+
1522+ // Helper lambda to extract uint64_t value from JSON
1523+ auto extractUInt64 = [](const std::string& json, const std::string& key) -> uint64_t {
1524+ size_t keyPos = json.find (" \" " + key + " \" " );
1525+ if (keyPos == std::string::npos)
1526+ return 0 ;
1527+
1528+ size_t colonPos = json.find (' :' , keyPos);
1529+ if (colonPos == std::string::npos)
1530+ return 0 ;
1531+
1532+ // Skip whitespace after colon
1533+ size_t valueStart = colonPos + 1 ;
1534+ while (valueStart < json.length () && std::isspace (json[valueStart]))
1535+ valueStart++;
1536+
1537+ // Check if value is null
1538+ if (json.substr (valueStart, 4 ) == " null" )
1539+ return 0 ;
1540+
1541+ // Find end of number
1542+ size_t valueEnd = valueStart;
1543+ while (valueEnd < json.length () && std::isdigit (json[valueEnd]))
1544+ valueEnd++;
1545+
1546+ if (valueEnd > valueStart)
1547+ {
1548+ std::string valueStr = json.substr (valueStart, valueEnd - valueStart);
1549+ return std::stoull (valueStr);
1550+ }
1551+ return 0 ;
1552+ };
1553+
1554+ // Helper lambda to extract string value from JSON
1555+ auto extractString = [](const std::string& json, const std::string& key) -> std::string {
1556+ size_t keyPos = json.find (" \" " + key + " \" " );
1557+ if (keyPos == std::string::npos)
1558+ return " " ;
1559+
1560+ size_t colonPos = json.find (' :' , keyPos);
1561+ if (colonPos == std::string::npos)
1562+ return " " ;
1563+
1564+ size_t valueStart = json.find (' "' , colonPos);
1565+ if (valueStart == std::string::npos)
1566+ return " " ;
1567+
1568+ size_t valueEnd = json.find (' "' , valueStart + 1 );
1569+ if (valueEnd == std::string::npos)
1570+ return " " ;
1571+
1572+ return json.substr (valueStart + 1 , valueEnd - valueStart - 1 );
1573+ };
1574+
1575+ // Extract fields from JSON
1576+ uint64_t transitionId = extractUInt64 (objStr, " transition_id" );
1577+ event.address = extractUInt64 (objStr, " address" );
1578+ event.size = extractUInt64 (objStr, " size" );
1579+ event.instructionAddress = extractUInt64 (objStr, " instruction_address" );
1580+ event.value = extractUInt64 (objStr, " value" );
1581+
1582+ // Extract thread_id (may be null)
1583+ event.threadId = static_cast <uint32_t >(extractUInt64 (objStr, " thread_id" ));
1584+ event.uniqueThreadId = event.threadId ;
1585+
1586+ // Convert transition_id to TTDPosition (use as sequence, step=0)
1587+ event.position = TTDPosition (transitionId, 0 );
1588+
1589+ // Extract and convert access_type string to enum
1590+ std::string accessTypeStr = extractString (objStr, " access_type" );
1591+ if (accessTypeStr == " read" )
1592+ event.accessType = TTDMemoryRead;
1593+ else if (accessTypeStr == " write" )
1594+ event.accessType = TTDMemoryWrite;
1595+ else if (accessTypeStr == " execute" )
1596+ event.accessType = TTDMemoryExecute;
1597+ else
1598+ event.accessType = TTDMemoryRead; // Default
1599+
1600+ // Initialize data array (first 8 bytes at memory address)
1601+ // REVEN doesn't provide this currently, so zero it out
1602+ for (int i = 0 ; i < 8 ; i++)
1603+ event.data [i] = 0 ;
1604+
1605+ result.push_back (event);
1606+
1607+ pos = objEnd + 1 ;
1608+ }
1609+
1610+ return result;
1611+ }
1612+
1613+
13101614std::string EsrevenAdapter::GetTargetArchitecture ()
13111615{
13121616 return m_remoteArch;
0 commit comments