/* * timemachine_api_test.cc * * An example program for the TimeMachine API */ #include #include #include "timemachine_api.h" #if !defined(MIN) #define MIN(x,y) ((x < y) ? x : y) #endif // Example data access function - prints values from the TS_Packet structure void print_packets(TM_CONNECTION conn, TS_Packet *data, int num) { for(int i=0; i= 0) { if(src_line != -1) { tm_mprintf(conn, " %s#%d\n", buf, src_line); } else { tm_mprintf(conn, " %s+0x%x\n", buf, offset); } } else { tm_mprintf(conn, " symbol unknown\n"); } } else if(data[i].type == TSP_ExtendedOpcode) { tm_mprintf(conn, "ExtOpc PC = 0x%08x\n", (uint32)(data[i].address & 0xffffffff)); } else if(data[i].type == TSP_Data) { uint8 access = data[i].u.data.access; char access_string[] = " ", *as = access_string; if (access & TSPA_Read) *as++ = 'R'; if (access & TSPA_Write) *as++ = 'W'; if (access & TSPA_Fetch) *as++ = 'F'; if ((access & TSPA_DataUnavailable) || (access & TSPA_AddressUnavailable)) *as++ = 'U'; tm_mprintf(conn, "Data%s Addr = 0x%08x Value = 0x", access_string, (uint32)(data[i].address & 0xffffffff)); // value is uint64. print the upper 32 bits if they're used int size = data[i].u.data.size; if (size > 4) tm_mprintf(conn, "%08x", (uint32)(data[i].u.data.value >> 32)); // print the lower 32 bits and the size tm_mprintf(conn, "%08x Size = %d\n", (uint32)data[i].u.data.value, size); char buf[80]; if(tm_get_data_symbol(conn, data[i].address, buf, sizeof(buf)) >= 0) tm_mprintf(conn, " %s\n", buf); else tm_mprintf(conn, " symbol unknown\n"); } else if(data[i].type == TSP_Event) { tm_mprintf(conn, "Event Type = %d\n", data[i].u.event); } else if(data[i].type == TSP_RawData) { tm_mprintf(conn, "Raw Data\n"); } else if(data[i].type == TSP_RawData_Start) { tm_mprintf(conn, "Raw Data Start\n"); } else if(data[i].type == TSP_FunctionEvent) { char buf[80]; int src_line, offset; if (tm_get_instruction_symbol(conn, data[i].address, buf, sizeof(buf), &src_line, &offset) < 0) sprintf(buf, ""); tm_mprintf(conn, "Function Event type=%s, timetag=0x%016llx, func=%s\n", (data[i].u.fn_event.type == TSPF_Entry) ? "Entry" : "Exit", data[i].u.fn_event.timetag, buf); } else if (data[i].type == TSP_AddressSync) { tm_mprintf(conn, "Address Sync addr=0x%016llx\n", data[i].address); } else { tm_mprintf(conn, "Undefined type: %d\n", data[i].type); } } } // Example analysis function - counts instructions and memory accesses void print_stats(TM_CONNECTION conn, TS_Packet *data, int num) { int num_instructions = 0; int num_reads = 0; int num_writes = 0; for(int i=0; i