Line 3... |
Line 3... |
|
|
Julius Baxter, julius.baxter@orsoc.se
|
Julius Baxter, julius.baxter@orsoc.se
|
|
|
*/
|
*/
|
|
|
|
#include <ctype.h>
|
#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 <unistd.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
|
Line 29... |
Line 31... |
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, int record_unique)
|
{
|
{
|
or1k_32_collect_stats(insn, insn_props);
|
or1k_32_collect_stats(insn, insn_props, record_unique);
|
}
|
}
|
|
|
|
|
void generate_stats(FILE * stream)
|
void generate_stats(FILE * stream)
|
{
|
{
|
or1k_32_generate_stats(stream);
|
or1k_32_generate_stats(stream);
|
}
|
}
|
|
|
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
{
|
{
|
FILE *fp;
|
FILE *ifp, *ofp;
|
|
|
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
|
char *infilename = NULL;
|
if((fp = fopen(argv[ 1 ], "rb"))==NULL) {
|
char *outfilename = NULL;
|
printf("Cannot open file.\n");
|
|
|
int outfile_flag = 0; // default is not to use an output file
|
|
|
|
int opterr = 0;
|
|
|
|
int uniquecount_flag = 0;
|
|
|
|
int c;
|
|
|
|
// Look for:
|
|
// -f filename : Input file name (required)
|
|
// [ -o filename] : Output file name (optional)
|
|
// [ -u ] : Do unique instruction analysis (option)
|
|
while ((c = getopt(argc, argv, "f:o:u::")) != -1)
|
|
switch (c)
|
|
{
|
|
case 'f':
|
|
infilename = optarg;
|
|
break;
|
|
|
|
case 'o':
|
|
outfile_flag = 1;
|
|
outfilename = optarg;
|
|
break;
|
|
|
|
case 'u':
|
|
uniquecount_flag = 1;
|
|
break;
|
|
|
|
default:
|
|
abort();
|
|
}
|
|
|
|
|
|
// Try to open the input file
|
|
if((ifp = fopen(infilename, "rb"))==NULL) {
|
|
printf("Cannot open input file, %s\n", infilename);
|
exit(1);
|
exit(1);
|
}
|
}
|
|
|
int filesize_bytes, filesize_insns;
|
int filesize_bytes, filesize_insns;
|
// Determine filesize
|
// Determine filesize
|
if ( fseek(fp, 0, SEEK_END))
|
if ( fseek(ifp, 0, SEEK_END))
|
{
|
{
|
fclose(fp);
|
fclose(ifp);
|
fprintf(stderr, "Error detecting filesize\n");
|
fprintf(stderr, "Error detecting input file size\n");
|
return -1;
|
return -1;
|
}
|
}
|
|
|
filesize_bytes = ftell(fp);
|
filesize_bytes = ftell(ifp);
|
filesize_insns = filesize_bytes / INSN_SIZE_BYTES;
|
filesize_insns = filesize_bytes / INSN_SIZE_BYTES;
|
|
|
#ifdef DISPLAY_STRING
|
#ifdef DISPLAY_STRING
|
printf("\nAnalysing file:\t%s\tSize: %d MB\n",
|
printf("\nAnalysing file:\t%s\tSize: %d MB\n",
|
argv[1],((filesize_bytes/1024)/1024));
|
infilename,((filesize_bytes/1024)/1024));
|
#endif
|
#endif
|
|
|
// Reset pointer
|
// Reset pointer
|
rewind(fp);
|
rewind(ifp);
|
|
|
instruction * insn = (instruction *)insn_buff;
|
instruction * insn = (instruction *)insn_buff;
|
|
|
instruction_properties insn_props;
|
instruction_properties insn_props;
|
|
|
Line 86... |
Line 124... |
float file_one_percent = ((float)filesize_insns / 100.0f );
|
float file_one_percent = ((float)filesize_insns / 100.0f );
|
float percent_of_percent=0; int percent=0;
|
float percent_of_percent=0; int percent=0;
|
|
|
insn_lists_init();
|
insn_lists_init();
|
|
|
while(!feof(fp)) {
|
while(!feof(ifp)) {
|
|
|
if (fread(insn_buff, INSN_SIZE_BYTES, 1, fp) != 1)
|
if (fread(insn_buff, INSN_SIZE_BYTES, 1, ifp) != 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);
|
Line 105... |
Line 143... |
if (analyse_insn(*insn, &insn_props) == 0)
|
if (analyse_insn(*insn, &insn_props) == 0)
|
{
|
{
|
|
|
insns_seen_total++;
|
insns_seen_total++;
|
|
|
collect_stats(*insn, &insn_props);
|
collect_stats(*insn, &insn_props, uniquecount_flag);
|
|
|
}
|
}
|
else
|
else
|
{
|
{
|
// Non-zero return from analyse_insn(): problem analysing instruction.
|
// Non-zero return from analyse_insn(): problem analysing instruction.
|
|
|
Line 126... |
Line 165... |
fprintf(stderr, "\r%d%%", percent);
|
fprintf(stderr, "\r%d%%", percent);
|
percent_of_percent = 0;
|
percent_of_percent = 0;
|
}
|
}
|
}
|
}
|
|
|
fclose(fp);
|
fclose(ifp);
|
|
|
fprintf(stderr, "\rDone\n", percent);
|
fprintf(stderr, "\rDone\n", percent);
|
|
|
|
// Try to open the output file
|
|
if (outfile_flag)
|
|
{
|
|
if((ofp = fopen(outfilename, "wb+"))==NULL) {
|
|
printf("Cannot open output file.\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
else
|
|
// Otherwise we'll use stdout
|
|
ofp = (FILE *)stdout;
|
|
|
#ifdef DISPLAY_STRING
|
#ifdef DISPLAY_STRING
|
fprintf(stdout, "Saw %d instructions\n", insns_seen_total);
|
fprintf(ofp, "Saw %d instructions\n", insns_seen_total);
|
#endif
|
#endif
|
#ifdef DISPLAY_CSV
|
#ifdef DISPLAY_CSV
|
fprintf(stdout, "\"File:\",\"%s\",\"Num insns:\",%d,\n",
|
fprintf(ofp, "\"File:\",\"%s\",\"Num insns:\",%d,\n",
|
argv[1], insns_seen_total);
|
infilename, insns_seen_total);
|
#endif
|
#endif
|
generate_stats(stdout);
|
|
|
// Generate output
|
|
generate_stats(ofp);
|
|
|
insn_lists_free();
|
insn_lists_free();
|
|
|
return 0;
|
return 0;
|
|
|