/*
|
/*
|
File for analysis of an architecture's instructions in binary format
|
File for analysis of an architecture's instructions in binary format
|
|
|
Julius Baxter, julius.baxter@orsoc.se
|
Julius Baxter, julius.baxter@orsoc.se
|
|
|
*/
|
*/
|
|
|
#include<stdio.h>
|
#include<stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <string.h>
|
#include <stdint.h>
|
#include <stdint.h>
|
#include <arpa/inet.h> // for htonl()
|
#include <arpa/inet.h> // for htonl()
|
|
|
#include "insnanalysis.h"
|
#include "insnanalysis.h"
|
|
|
// Access to list management functions
|
// Access to list management functions
|
#include "insn-lists.h"
|
#include "insn-lists.h"
|
|
|
int analyse_insn(instruction insn,
|
int analyse_insn(instruction insn,
|
instruction_properties *insn_props)
|
instruction_properties *insn_props)
|
{
|
{
|
// For now no other instruction sets supported
|
// For now no other instruction sets supported
|
return or1k_32_analyse_insn(insn, insn_props);
|
return or1k_32_analyse_insn(insn, insn_props);
|
}
|
}
|
|
|
|
|
void print_insn(instruction_properties *insn_props)
|
void print_insn(instruction_properties *insn_props)
|
{
|
{
|
if (insn_props->insn_string != NULL)
|
if (insn_props->insn_string != NULL)
|
printf("%s", insn_props->insn_string);
|
printf("%s", insn_props->insn_string);
|
}
|
}
|
|
|
void collect_stats(instruction insn,
|
void collect_stats(instruction insn,
|
instruction_properties *insn_props)
|
instruction_properties *insn_props)
|
{
|
{
|
or1k_32_collect_stats(insn, insn_props);
|
or1k_32_collect_stats(insn, insn_props);
|
}
|
}
|
|
|
|
|
|
void generate_stats(FILE * stream)
|
|
{
|
|
or1k_32_generate_stats(stream);
|
|
}
|
|
|
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
{
|
{
|
FILE *fp;
|
FILE *fp;
|
|
|
char insn_buff[INSN_SIZE_BYTES]; // Buffer for instruction data
|
char insn_buff[INSN_SIZE_BYTES]; // Buffer for instruction data
|
|
|
int insns_seen_total = 0; // Keep track of total number of instructions read
|
int insns_seen_total = 0; // Keep track of total number of instructions read
|
|
|
// Try to open the file passed as first parameter
|
// Try to open the file passed as first parameter
|
if((fp = fopen(argv[ 1 ], "rb"))==NULL) {
|
if((fp = fopen(argv[ 1 ], "rb"))==NULL) {
|
printf("Cannot open file.\n");
|
printf("Cannot open file.\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
|
|
instruction * insn = (instruction *)insn_buff;
|
instruction * insn = (instruction *)insn_buff;
|
|
|
instruction_properties insn_props;
|
instruction_properties insn_props;
|
|
|
// Do initial analysis - frequency of each instruction
|
// Do initial analysis - frequency of each instruction
|
|
|
insn_lists_init();
|
insn_lists_init();
|
|
|
while(!feof(fp)) {
|
while(!feof(fp)) {
|
|
|
if (fread(insn_buff, INSN_SIZE_BYTES, 1, fp) != 1)
|
if (fread(insn_buff, INSN_SIZE_BYTES, 1, fp) != 1)
|
break;
|
break;
|
|
|
// Endianness is little when read in from binary file created with
|
// Endianness is little when read in from binary file created with
|
// or32-elf-objcopy, so swap;
|
// or32-elf-objcopy, so swap;
|
*insn = htonl(*insn);
|
*insn = htonl(*insn);
|
|
|
reset_instruction_properties(&insn_props);
|
if (*insn == 0) // most probably dead space in binary, skip
|
|
continue;
|
|
|
analyse_insn(*insn, &insn_props);
|
reset_instruction_properties(&insn_props);
|
|
|
print_insn(&insn_props);
|
|
printf("\n");
|
|
|
|
|
if (analyse_insn(*insn, &insn_props) == 0)
|
|
{
|
|
/*
|
|
print_insn(&insn_props);
|
|
printf("\n");
|
|
*/
|
insns_seen_total++;
|
insns_seen_total++;
|
|
|
collect_stats(*insn, &insn_props);
|
collect_stats(*insn, &insn_props);
|
|
}
|
|
else
|
|
{
|
|
printf("\n");
|
}
|
}
|
|
|
insn_lists_free();
|
}
|
|
|
fclose(fp);
|
fclose(fp);
|
|
|
printf("Saw %d instructions\n", insns_seen_total);
|
printf("Saw %d instructions\n", insns_seen_total);
|
|
|
|
generate_stats(stdout);
|
|
|
|
insn_lists_free();
|
|
|
return 0;
|
return 0;
|
|
|
}
|
}
|
|
|