Line 15... |
Line 15... |
// Array of opcode string pointers (we malloc space for actual strings)
|
// Array of opcode string pointers (we malloc space for actual strings)
|
char *opcode_strings[MAX_OR1K_32_OPCODES];
|
char *opcode_strings[MAX_OR1K_32_OPCODES];
|
// Count for occurance of each opcode
|
// Count for occurance of each opcode
|
int opcode_count[MAX_OR1K_32_OPCODES];
|
int opcode_count[MAX_OR1K_32_OPCODES];
|
|
|
// Maximum number of pairs
|
// Maximum number of pairs to keep track of
|
#define MAX_OR1K_32_PAIRS (MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES)
|
#define MAX_OR1K_32_PAIRS (MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES)
|
// 2-dimensional array, long enough to hold all possible pairs, and the 2
|
// 2-dimensional array, long enough to hold all possible pairs, and the 2
|
// indexes corresponding to their opcode in the *opcode_strings[] array
|
// indexes corresponding to their opcode in the *opcode_strings[] array
|
// Ie. Each will be: [previous_opcode][current_opcode][count]
|
// Ie. Each will be: [previous_opcode][current_opcode][count]
|
int opcode_pairs[MAX_OR1K_32_PAIRS][3];
|
int opcode_pairs[MAX_OR1K_32_PAIRS][3];
|
|
|
// Maximum number of pairs
|
// Maximum number of triplets to kep track of
|
#define MAX_OR1K_32_TRIPLETS (MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES)
|
#define MAX_OR1K_32_TRIPLETS (MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES)
|
// 2-dimensional array, long enough to hold all possible pairs, and the 2
|
// 2-dimensional array, long enough to hold all possible pairs, and the 2
|
// indexes corresponding to their opcode in the *opcode_strings[] array
|
// indexes corresponding to their opcode in the *opcode_strings[] array
|
// Ie. Each will be: [second_previous_opcode][first_previous_opcode][current_opcode][count]
|
// Ie. Each will be:
|
|
// [second_prev][first_prev][current_opcode][count]
|
int opcode_triplets[MAX_OR1K_32_TRIPLETS][4];
|
int opcode_triplets[MAX_OR1K_32_TRIPLETS][4];
|
|
|
// Maximum number of pairs
|
// Maximum number of quadruples to keep track of
|
#define MAX_OR1K_32_QUADS (MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES)
|
#define MAX_OR1K_32_QUADS (MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES)
|
// 2-dimensional array, long enough to hold all possible pairs, and the 2
|
// 2-dimensional array, long enough to hold all possible pairs, and the 2
|
// indexes corresponding to their opcode in the *opcode_strings[] array
|
// indexes corresponding to their opcode in the *opcode_strings[] array
|
// Ie. Each will be: [second_previous_opcode][first_previous_opcode][current_opcode][count]
|
// Ie. Each will be:
|
|
// [third_prev][second_prev][first_prev][current_opcode][count]
|
int opcode_quads[MAX_OR1K_32_QUADS][5];
|
int opcode_quads[MAX_OR1K_32_QUADS][5];
|
|
|
// Strings shouldn't be more than 32 bytes long
|
// Strings shouldn't be more than 32 bytes long
|
#define OPCODE_STRING_SIZE 32
|
#define OPCODE_STRING_SIZE 32
|
|
|
// Indicator for an opcode we haven't seen before
|
// Indicator for an opcode we haven't seen before
|
#define IS_UNIQUE -1
|
#define IS_UNIQUE -1
|
|
|
// Result type
|
// Result defines
|
#define SORTED_DESCENDING_DISPLAY
|
#define SORTED_DESCENDING_DISPLAY
|
|
|
|
// Style of output - String or CSV
|
|
// Uncomment only 1!
|
|
#define DISPLAY_STRING
|
|
//#define DISPLAY_CSV
|
|
|
|
// Report only the 10 most common pairs/triples/quadruples, etc
|
|
#define MAX_SETS_TO_REPORT 10
|
|
|
// Little function to strip newlines
|
// Little function to strip newlines
|
inline void strip_newline(char* str)
|
inline void strip_newline(char* str)
|
{
|
{
|
int len = strlen(str);
|
int len = strlen(str);
|
if (str[len-1] == '\n')
|
if (str[len-1] == '\n')
|
Line 112... |
Line 122... |
return;
|
return;
|
}
|
}
|
|
|
|
|
|
|
void display_opcodes(int total_unique_opcodes)
|
void display_opcodes(int total_unique_opcodes, int total_opcodes_counted)
|
{
|
{
|
|
|
|
#ifdef DISPLAY_STRING
|
|
// Totals
|
|
printf("Number of total opcodes: %d\n",total_opcodes_counted);
|
|
printf("Number unique opcodes: %d\n", total_unique_opcodes);
|
|
#endif
|
|
#ifdef DISPLAY_CSV
|
|
printf("\"Opcode\",\"Occurances\",\"%%'age of total\",\"Total opcodes counted:\",%d\n",total_opcodes_counted);
|
|
#endif
|
|
|
#ifdef SIMPLE_DISPLAY
|
#ifdef SIMPLE_DISPLAY
|
while (total_unique_opcodes)
|
while (total_unique_opcodes)
|
{
|
{
|
--total_unique_opcodes;
|
--total_unique_opcodes;
|
printf("Opcode:\t%s\tCount:\t%d\n",
|
printf("Opcode:\t%s\tCount:\t%d\n",
|
Line 138... |
Line 158... |
{
|
{
|
largest = opcode_count[i];
|
largest = opcode_count[i];
|
largest_index = i;
|
largest_index = i;
|
}
|
}
|
|
|
printf("Opcode:\t%s\tCount:\t%d\n",
|
printf(
|
|
#ifdef DISPLAY_STRING
|
|
"Opcode:\t%s\tCount:\t%d\t(%f%%)\n",
|
|
#endif
|
|
#ifdef DISPLAY_CSV
|
|
// CSV format - "opcode string",frequency,percentage
|
|
"\"%s\",%d,%f\n",
|
|
#endif
|
opcode_strings[largest_index],
|
opcode_strings[largest_index],
|
opcode_count[largest_index]);
|
opcode_count[largest_index],
|
|
(float)(((float)opcode_count[largest_index])/
|
|
((float)total_opcodes_counted))*100.f);
|
|
|
|
|
opcode_count[largest_index] = -1; // Eliminate this one
|
opcode_count[largest_index] = -1; // Eliminate this one
|
|
|
}
|
}
|
#endif
|
#endif
|
|
|
|
|
}
|
}
|
|
|
// Deal with opcode pair checking
|
// Deal with opcode pair checking
|
int opcode_pair_check( int previous_opcode_index, int current_opcode_index,
|
int opcode_pair_check( int previous_opcode_index, int current_opcode_index,
|
int total_pairs )
|
int total_pairs )
|
Line 178... |
Line 209... |
return 1;
|
return 1;
|
|
|
}
|
}
|
|
|
|
|
void opcode_pair_report(int total_opcode_pairs)
|
void opcode_pair_report(int total_opcode_sets)
|
{
|
{
|
|
|
int i, largest, largest_index;
|
int i, largest, largest_index;
|
int initial_total = total_opcode_pairs;
|
int initial_total = total_opcode_sets;
|
|
|
|
#ifdef DISPLAY_STRING
|
|
printf("Number of unique opcode pairs: %d\n", total_opcode_sets);
|
|
#endif
|
|
#ifdef DISPLAY_CSV
|
|
printf("\"Opcode pair\",\"Occurances\",\"Total unique pairs:\",%d\n",
|
|
total_opcode_sets);
|
|
#endif
|
|
|
while (total_opcode_pairs)
|
while (total_opcode_sets)
|
{
|
{
|
--total_opcode_pairs;
|
--total_opcode_sets;
|
largest=0;
|
largest=0;
|
// Go through the list, find the largest, print it, eliminate it
|
// Go through the list, find the largest, print it, eliminate it
|
for(i=0;i<initial_total;i++)
|
for(i=0;i<initial_total;i++)
|
if(opcode_pairs[i][2] > largest)
|
if(opcode_pairs[i][2] > largest)
|
{
|
{
|
largest = opcode_pairs[i][2];
|
largest = opcode_pairs[i][2];
|
largest_index = i;
|
largest_index = i;
|
}
|
}
|
|
printf(
|
|
#ifdef DISPLAY_STRING
|
|
"Opcode pair:\t%s\t%s\tCount:\t%d\n",
|
|
#endif
|
|
#ifdef DISPLAY_CSV
|
|
"\"%s %s\",%d\n",
|
|
#endif
|
|
|
printf("Opcode pair:\t%s\t%s\tCount:\t%d\n",
|
|
opcode_strings[opcode_pairs[largest_index][0]],
|
opcode_strings[opcode_pairs[largest_index][0]],
|
opcode_strings[opcode_pairs[largest_index][1]],
|
opcode_strings[opcode_pairs[largest_index][1]],
|
opcode_pairs[largest_index][2]);
|
opcode_pairs[largest_index][2]);
|
|
|
|
|
opcode_pairs[largest_index][2] = -1; // Eliminate this one
|
opcode_pairs[largest_index][2] = -1; // Eliminate this one
|
|
|
|
// If we've printed out the maximum we wanted then return
|
|
if ((initial_total - total_opcode_sets) == MAX_SETS_TO_REPORT)
|
|
return;
|
|
|
|
|
}
|
}
|
|
|
|
|
}
|
}
|
|
|
Line 247... |
Line 298... |
{
|
{
|
|
|
int i, largest, largest_index;
|
int i, largest, largest_index;
|
int initial_total = total_opcode_sets;
|
int initial_total = total_opcode_sets;
|
|
|
|
#ifdef DISPLAY_STRING
|
|
printf("Number of unique opcode triplets: %d\n", total_opcode_sets);
|
|
#endif
|
|
#ifdef DISPLAY_CSV
|
|
printf("\"Opcode triplet\",\"Occurances\",\"Total unique triplets:\",%d\n",
|
|
total_opcode_sets);
|
|
#endif
|
|
|
while (total_opcode_sets)
|
while (total_opcode_sets)
|
{
|
{
|
--total_opcode_sets;
|
--total_opcode_sets;
|
largest=0;
|
largest=0;
|
// Go through the list, find the largest, print it, eliminate it
|
// Go through the list, find the largest, print it, eliminate it
|
Line 259... |
Line 318... |
{
|
{
|
largest = opcode_triplets[i][3];
|
largest = opcode_triplets[i][3];
|
largest_index = i;
|
largest_index = i;
|
}
|
}
|
|
|
printf("Opcode triplet:\t%s\t%s\t%s\tCount:\t%d\n",
|
printf(
|
|
#ifdef DISPLAY_STRING
|
|
"Opcode triplet:\t%s\t%s\t%s\tCount:\t%d\n",
|
|
#endif
|
|
#ifdef DISPLAY_CSV
|
|
"\"%s %s %s\",%d\n",
|
|
#endif
|
opcode_strings[opcode_triplets[largest_index][0]],
|
opcode_strings[opcode_triplets[largest_index][0]],
|
opcode_strings[opcode_triplets[largest_index][1]],
|
opcode_strings[opcode_triplets[largest_index][1]],
|
opcode_strings[opcode_triplets[largest_index][2]],
|
opcode_strings[opcode_triplets[largest_index][2]],
|
opcode_triplets[largest_index][3]);
|
opcode_triplets[largest_index][3]);
|
|
|
opcode_triplets[largest_index][3] = -1; // Eliminate this one
|
opcode_triplets[largest_index][3] = -1; // Eliminate this one
|
|
|
|
// If we've printed out the maximum we wanted then return
|
|
if ((initial_total - total_opcode_sets) == MAX_SETS_TO_REPORT)
|
|
return;
|
|
|
}
|
}
|
}
|
}
|
|
|
// Deal with opcode triplet checking
|
// Deal with opcode triplet checking
|
int opcode_quad_check(int third_previous_opcode_index,
|
int opcode_quad_check(int third_previous_opcode_index,
|
Line 312... |
Line 381... |
{
|
{
|
|
|
int i, largest, largest_index;
|
int i, largest, largest_index;
|
int initial_total = total_opcode_sets;
|
int initial_total = total_opcode_sets;
|
|
|
|
#ifdef DISPLAY_STRING
|
|
printf("Number of unique opcode quads: %d\n", total_opcode_sets);
|
|
#endif
|
|
#ifdef DISPLAY_CSV
|
|
printf("\"Opcode quad\",\"Occurances\",\"Total unique quadruples:\",%d\n",
|
|
total_opcode_sets);
|
|
#endif
|
|
|
while (total_opcode_sets)
|
while (total_opcode_sets)
|
{
|
{
|
--total_opcode_sets;
|
--total_opcode_sets;
|
largest=0;
|
largest=0;
|
// Go through the list, find the largest, print it, eliminate it
|
// Go through the list, find the largest, print it, eliminate it
|
Line 324... |
Line 401... |
{
|
{
|
largest = opcode_quads[i][4];
|
largest = opcode_quads[i][4];
|
largest_index = i;
|
largest_index = i;
|
}
|
}
|
|
|
printf("Opcode triplet:\t%s\t%s\t%s\t%s\tCount:\t%d\n",
|
printf(
|
|
#ifdef DISPLAY_STRING
|
|
"Opcode triplet:\t%s\t%s\t%s\t%s\tCount:\t%d\n",
|
|
#endif
|
|
#ifdef DISPLAY_CSV
|
|
"\"%s %s %s %s\",%d\n",
|
|
#endif
|
opcode_strings[opcode_quads[largest_index][0]],
|
opcode_strings[opcode_quads[largest_index][0]],
|
opcode_strings[opcode_quads[largest_index][1]],
|
opcode_strings[opcode_quads[largest_index][1]],
|
opcode_strings[opcode_quads[largest_index][2]],
|
opcode_strings[opcode_quads[largest_index][2]],
|
opcode_strings[opcode_quads[largest_index][3]],
|
opcode_strings[opcode_quads[largest_index][3]],
|
opcode_quads[largest_index][4]);
|
opcode_quads[largest_index][4]);
|
|
|
opcode_quads[largest_index][4] = -1; // Eliminate this one
|
opcode_quads[largest_index][4] = -1; // Eliminate this one
|
|
|
|
// If we've printed out the maximum we wanted then return
|
|
if ((initial_total - total_opcode_sets) == MAX_SETS_TO_REPORT)
|
|
return;
|
|
|
}
|
}
|
}
|
}
|
|
|
|
|
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
Line 405... |
Line 492... |
//num_unique_opcodes, total_seen_opcodes);
|
//num_unique_opcodes, total_seen_opcodes);
|
|
|
}
|
}
|
}
|
}
|
|
|
|
|
// Totals
|
|
printf("Number of total opcodes: %d\n",total_seen_opcodes);
|
|
printf("Number unique opcodes: %d\n", num_unique_opcodes);
|
|
|
|
// Print some more detailed information
|
// Print some more detailed information
|
display_opcodes(num_unique_opcodes);
|
display_opcodes(num_unique_opcodes, total_seen_opcodes);
|
|
|
printf("Beginning groups analysis\n");
|
#ifdef DISPLAY_STRING
|
|
fprintf(stdout,"Beginning groups analysis\n");
|
|
#endif
|
|
|
// Now do groups analysis
|
// Now do groups analysis
|
rewind(fp);
|
rewind(fp);
|
|
|
// Reset total_seen_opcodes, we'll count through the list again
|
// Reset total_seen_opcodes, we'll count through the list again
|
Line 477... |
Line 561... |
previous_opcode_indexes[0] = opcode_index;
|
previous_opcode_indexes[0] = opcode_index;
|
|
|
}
|
}
|
}
|
}
|
|
|
|
|
printf("Number of unique opcode pairs: %d\n", num_opcode_pairs);
|
|
|
|
// Report opcode pairs (will be a lot, > 1000)
|
|
opcode_pair_report(num_opcode_pairs);
|
opcode_pair_report(num_opcode_pairs);
|
|
|
|
|
printf("Number of unique opcode triplets: %d\n", num_opcode_triplets);
|
|
|
|
// Report opcode pairs (will be a lot, > 1000)
|
|
opcode_triplet_report(num_opcode_pairs);
|
opcode_triplet_report(num_opcode_pairs);
|
|
|
printf("Number of opcode quads: %d\n", num_opcode_quads);
|
|
|
|
// Report opcode pairs (will be a lot, > 1000)
|
|
opcode_quad_report(num_opcode_quads);
|
opcode_quad_report(num_opcode_quads);
|
|
|
// Close file pointer, we're done with it
|
// Close file pointer, we're done with it
|
fclose(fp);
|
fclose(fp);
|
|
|
|
|
// Free all the strings we declared
|
// Free all the strings we declared
|
while(num_unique_opcodes)
|
while(num_unique_opcodes)
|
{
|
{
|
--num_unique_opcodes;
|
--num_unique_opcodes;
|
free(opcode_strings[num_unique_opcodes]);
|
free(opcode_strings[num_unique_opcodes]);
|