Line 29... |
Line 29... |
#include "elf.h"
|
#include "elf.h"
|
#include "debug_unit.h"
|
#include "debug_unit.h"
|
#include "opcode/or32.h"
|
#include "opcode/or32.h"
|
#include "parse.h"
|
#include "parse.h"
|
#include "sim-config.h"
|
#include "sim-config.h"
|
|
#include "labels.h"
|
|
#include "debug.h"
|
|
|
#define MEMORY_LEN 0x100000000
|
#define MEMORY_LEN 0x100000000
|
#define MAXLINE_LEN 18000
|
#define MAXLINE_LEN 18000
|
|
|
/* Whether to do immediate statistics */
|
/* Whether to do immediate statistics */
|
Line 137... |
Line 139... |
equal to logical. */
|
equal to logical. */
|
static unsigned int translate(unsigned int laddr,int* breakpoint)
|
static unsigned int translate(unsigned int laddr,int* breakpoint)
|
{
|
{
|
int i;
|
int i;
|
|
|
/* No translation (i.e. when loading kernel into simulator)
|
/* No translation (i.e. when loading kernel into simulator) */
|
/* PRINTF("transl_table=%x laddr=%x\n", transl_table, laddr);
|
/* PRINTF("transl_table=%x laddr=%x\n", transl_table, laddr);
|
PRINTF("laddr=%x\n", laddr);*/
|
PRINTF("laddr=%x\n", laddr);*/
|
if (transl_table == 0)
|
if (transl_table == 0)
|
return laddr;
|
return laddr;
|
|
|
/* Try to find our translation in the table. */
|
/* Try to find our translation in the table. */
|
for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
|
for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
|
if ((laddr & ~(PAGE_SIZE - 1)) == evalsim_mem32(transl_table + i)) {
|
if ((laddr & ~(PAGE_SIZE - 1)) == evalsim_mem32(transl_table + i)) {
|
setsim_mem32(transl_table + i + 8, -2); /* Page modified */
|
setsim_mem32(transl_table + i + 8, -2); /* Page modified */
|
PRINTF("found paddr=%x\n", evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1)));
|
PRINTF("found paddr=%lx\n", evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1)));
|
return (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (unsigned long)(PAGE_SIZE - 1));
|
return (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (unsigned long)(PAGE_SIZE - 1));
|
}
|
}
|
|
|
/* Allocate new phy page for us. */
|
/* Allocate new phy page for us. */
|
for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
|
for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
|
if (evalsim_mem32(transl_table + i + 8) == 0) {
|
if (evalsim_mem32(transl_table + i + 8) == 0) {
|
setsim_mem32(transl_table + i, laddr & ~(PAGE_SIZE - 1)); /* VPN */
|
setsim_mem32(transl_table + i, laddr & ~(PAGE_SIZE - 1)); /* VPN */
|
setsim_mem32(transl_table + i + 4, (i/16) * PAGE_SIZE); /* PPN */
|
setsim_mem32(transl_table + i + 4, (i/16) * PAGE_SIZE); /* PPN */
|
setsim_mem32(transl_table + i + 8, -2); /* Page modified */
|
setsim_mem32(transl_table + i + 8, -2); /* Page modified */
|
PRINTF("newly allocated ppn=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4));
|
PRINTF("newly allocated ppn=%lx\n", (unsigned long)evalsim_mem32(transl_table + i + 4));
|
PRINTF("newly allocated .ppn=%x\n", (unsigned long)transl_table + i + 4);
|
PRINTF("newly allocated .ppn=%lx\n", (unsigned long)transl_table + i + 4);
|
PRINTF("newly allocated ofs=%x\n", (unsigned long)(laddr & (PAGE_SIZE - 1)));
|
PRINTF("newly allocated ofs=%lx\n", (unsigned long)(laddr & (PAGE_SIZE - 1)));
|
PRINTF("newly allocated paddr=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1)));
|
PRINTF("newly allocated paddr=%lx\n", (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1)));
|
return (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (unsigned long)(PAGE_SIZE - 1));
|
return (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (unsigned long)(PAGE_SIZE - 1));
|
}
|
}
|
/* If we come this far then all phy memory is used and we can't find our page
|
/* If we come this far then all phy memory is used and we can't find our page
|
nor allocate new page. */
|
nor allocate new page. */
|
transl_error = 1;
|
transl_error = 1;
|
|
|
PRINTF("can't translate\n", laddr);
|
PRINTF("can't translate %x\n", laddr);
|
exit(1);
|
exit(1);
|
return -1;
|
return -1;
|
}
|
}
|
|
|
#if IMM_STATS
|
#if IMM_STATS
|
Line 255... |
Line 257... |
/* Replaced several calls to translate(freemem) with vaddr */
|
/* Replaced several calls to translate(freemem) with vaddr */
|
/* Added new mode execution code */
|
/* Added new mode execution code */
|
/* Changed parameters so address can be passed as argument */
|
/* Changed parameters so address can be passed as argument */
|
void addprogram(unsigned long address, unsigned long insn, int* breakpoint)
|
void addprogram(unsigned long address, unsigned long insn, int* breakpoint)
|
{
|
{
|
char insn_first2_char[3];
|
|
int vaddr = (!runtime.sim.filename) ? translate(address,breakpoint) : translate(freemem,breakpoint);
|
int vaddr = (!runtime.sim.filename) ? translate(address,breakpoint) : translate(freemem,breakpoint);
|
|
|
setsim_mem32 (vaddr, insn);
|
setsim_mem32 (vaddr, insn);
|
#if IMM_STATS
|
#if IMM_STATS
|
check_insn (insn);
|
check_insn (insn);
|
Line 277... |
Line 278... |
unsigned long insn;
|
unsigned long insn;
|
signed long sectsize;
|
signed long sectsize;
|
COFF_AOUTHDR coffaouthdr;
|
COFF_AOUTHDR coffaouthdr;
|
struct COFF_scnhdr coffscnhdr;
|
struct COFF_scnhdr coffscnhdr;
|
int len;
|
int len;
|
char item[MAXLINE_LEN];
|
|
char item2[MAXLINE_LEN];
|
|
int firstthree = 0;
|
int firstthree = 0;
|
int breakpoint = 0;
|
int breakpoint = 0;
|
|
|
if (!(inputfs = fopen(filename, "r"))) {
|
if (!(inputfs = fopen(filename, "r"))) {
|
perror("readfile_coff");
|
perror("readfile_coff");
|
Line 313... |
Line 312... |
fclose(inputfs);
|
fclose(inputfs);
|
perror("readfile_coff");
|
perror("readfile_coff");
|
exit(1);
|
exit(1);
|
}
|
}
|
PRINTF("Section: %s,", coffscnhdr.s_name);
|
PRINTF("Section: %s,", coffscnhdr.s_name);
|
PRINTF(" paddr: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_paddr));
|
PRINTF(" paddr: 0x%.8lx,", COFF_LONG_H(coffscnhdr.s_paddr));
|
PRINTF(" vaddr: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_vaddr));
|
PRINTF(" vaddr: 0x%.8lx,", COFF_LONG_H(coffscnhdr.s_vaddr));
|
PRINTF(" size: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_size));
|
PRINTF(" size: 0x%.8lx,", COFF_LONG_H(coffscnhdr.s_size));
|
PRINTF(" scnptr: 0x%.8x\n", COFF_LONG_H(coffscnhdr.s_scnptr));
|
PRINTF(" scnptr: 0x%.8lx\n", COFF_LONG_H(coffscnhdr.s_scnptr));
|
|
|
sectsize = COFF_LONG_H(coffscnhdr.s_size);
|
sectsize = COFF_LONG_H(coffscnhdr.s_size);
|
#if 0
|
#if 0
|
/* A couple of sanity checks. */
|
/* A couple of sanity checks. */
|
if (translate(COFF_LONG_H(coffscnhdr.s_vaddr),&breakpoint) < MEMORY_START) {
|
if (translate(COFF_LONG_H(coffscnhdr.s_vaddr),&breakpoint) < MEMORY_START) {
|
Line 393... |
Line 392... |
|
|
void readsyms_coff(char *filename, unsigned long symptr, long syms)
|
void readsyms_coff(char *filename, unsigned long symptr, long syms)
|
{
|
{
|
FILE *inputfs;
|
FILE *inputfs;
|
struct COFF_syment coffsymhdr;
|
struct COFF_syment coffsymhdr;
|
int breakpoint = 0;
|
|
int count = 0;
|
int count = 0;
|
long nsyms = syms;
|
long nsyms = syms;
|
if (!(inputfs = fopen(filename, "r"))) {
|
if (!(inputfs = fopen(filename, "r"))) {
|
perror("readsyms_coff");
|
perror("readsyms_coff");
|
exit(1);
|
exit(1);
|
Line 598... |
Line 596... |
|
|
if (ELF_LONG_H(elf_spnt->sh_name) && s_str)
|
if (ELF_LONG_H(elf_spnt->sh_name) && s_str)
|
PRINTF("Section: %s,", &s_str[ELF_LONG_H(elf_spnt->sh_name)]);
|
PRINTF("Section: %s,", &s_str[ELF_LONG_H(elf_spnt->sh_name)]);
|
else
|
else
|
PRINTF("Section: noname,");
|
PRINTF("Section: noname,");
|
PRINTF(" vaddr: 0x%.8x,", ELF_LONG_H(elf_spnt->sh_addr));
|
PRINTF(" vaddr: 0x%.8lx,", ELF_LONG_H(elf_spnt->sh_addr));
|
PRINTF(" paddr: 0x%.8x,", padd);
|
PRINTF(" paddr: 0x%.8lx,", padd);
|
PRINTF(" offset: 0x%.8x,", ELF_LONG_H(elf_spnt->sh_offset));
|
PRINTF(" offset: 0x%.8lx,", ELF_LONG_H(elf_spnt->sh_offset));
|
PRINTF(" size: 0x%.8x\n", ELF_LONG_H(elf_spnt->sh_size));
|
PRINTF(" size: 0x%.8lx\n", ELF_LONG_H(elf_spnt->sh_size));
|
|
|
freemem = padd;
|
freemem = padd;
|
sectsize = ELF_LONG_H(elf_spnt->sh_size);
|
sectsize = ELF_LONG_H(elf_spnt->sh_size);
|
|
|
if (fseek(inputfs, ELF_LONG_H(elf_spnt->sh_offset), SEEK_SET) != 0) {
|
if (fseek(inputfs, ELF_LONG_H(elf_spnt->sh_offset), SEEK_SET) != 0) {
|
Line 647... |
Line 645... |
void identifyfile(char *filename)
|
void identifyfile(char *filename)
|
{
|
{
|
FILE *inputfs;
|
FILE *inputfs;
|
struct COFF_filehdr coffhdr;
|
struct COFF_filehdr coffhdr;
|
struct elf32_hdr elfhdr;
|
struct elf32_hdr elfhdr;
|
size_t len;
|
|
|
|
if (!(inputfs = fopen(filename, "r"))) {
|
if (!(inputfs = fopen(filename, "r"))) {
|
perror(filename);
|
perror(filename);
|
fflush(stdout);
|
fflush(stdout);
|
fflush(stderr);
|
fflush(stderr);
|
Line 661... |
Line 658... |
if (fread(&coffhdr, sizeof(coffhdr), 1, inputfs) == 1) {
|
if (fread(&coffhdr, sizeof(coffhdr), 1, inputfs) == 1) {
|
if (COFF_SHORT_H(coffhdr.f_magic) == 0x17a) {
|
if (COFF_SHORT_H(coffhdr.f_magic) == 0x17a) {
|
unsigned long opthdr_size;
|
unsigned long opthdr_size;
|
PRINTF("COFF magic: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_magic));
|
PRINTF("COFF magic: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_magic));
|
PRINTF("COFF flags: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_flags));
|
PRINTF("COFF flags: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_flags));
|
PRINTF("COFF symptr: 0x%.8x\n", COFF_LONG_H(coffhdr.f_symptr));
|
PRINTF("COFF symptr: 0x%.8lx\n", COFF_LONG_H(coffhdr.f_symptr));
|
if ((COFF_SHORT_H(coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC) {
|
if ((COFF_SHORT_H(coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC) {
|
PRINTF("This COFF is not an executable.\n");
|
PRINTF("This COFF is not an executable.\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
opthdr_size = COFF_SHORT_H(coffhdr.f_opthdr);
|
opthdr_size = COFF_SHORT_H(coffhdr.f_opthdr);
|
if (opthdr_size != sizeof(COFF_AOUTHDR)) {
|
if (opthdr_size != sizeof(COFF_AOUTHDR)) {
|
PRINTF("COFF optional header is missing or not recognized.\n");
|
PRINTF("COFF optional header is missing or not recognized.\n");
|
PRINTF("COFF f_opthdr: 0x%.2x\n", opthdr_size);
|
PRINTF("COFF f_opthdr: 0x%.2lx\n", opthdr_size);
|
exit(1);
|
exit(1);
|
}
|
}
|
fclose(inputfs);
|
fclose(inputfs);
|
readfile_coff(filename, COFF_SHORT_H(coffhdr.f_nscns));
|
readfile_coff(filename, COFF_SHORT_H(coffhdr.f_nscns));
|
readsyms_coff(filename, COFF_LONG_H(coffhdr.f_symptr), COFF_LONG_H(coffhdr.f_nsyms));
|
readsyms_coff(filename, COFF_LONG_H(coffhdr.f_symptr), COFF_LONG_H(coffhdr.f_nsyms));
|
Line 686... |
Line 683... |
}
|
}
|
if (fread(&elfhdr, sizeof(elfhdr), 1, inputfs) == 1) {
|
if (fread(&elfhdr, sizeof(elfhdr), 1, inputfs) == 1) {
|
if (elfhdr.e_ident[0] == 0x7f && elfhdr.e_ident[1] == 0x45 && elfhdr.e_ident[2] == 0x4c && elfhdr.e_ident[3] == 0x46) {
|
if (elfhdr.e_ident[0] == 0x7f && elfhdr.e_ident[1] == 0x45 && elfhdr.e_ident[2] == 0x4c && elfhdr.e_ident[3] == 0x46) {
|
PRINTF("ELF type: 0x%.4x\n", ELF_SHORT_H(elfhdr.e_type));
|
PRINTF("ELF type: 0x%.4x\n", ELF_SHORT_H(elfhdr.e_type));
|
PRINTF("ELF machine: 0x%.4x\n", ELF_SHORT_H(elfhdr.e_machine));
|
PRINTF("ELF machine: 0x%.4x\n", ELF_SHORT_H(elfhdr.e_machine));
|
PRINTF("ELF version: 0x%.8x\n", ELF_LONG_H(elfhdr.e_version));
|
PRINTF("ELF version: 0x%.8lx\n", ELF_LONG_H(elfhdr.e_version));
|
PRINTF("ELF sec = %d\n", ELF_SHORT_H(elfhdr.e_shnum));
|
PRINTF("ELF sec = %d\n", ELF_SHORT_H(elfhdr.e_shnum));
|
if (ELF_SHORT_H(elfhdr.e_type) != ET_EXEC ) {
|
if (ELF_SHORT_H(elfhdr.e_type) != ET_EXEC ) {
|
PRINTF("This ELF is not an executable.\n");
|
PRINTF("This ELF is not an executable.\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
Line 717... |
Line 714... |
int breakpoint = 0;
|
int breakpoint = 0;
|
|
|
transl_error = 0;
|
transl_error = 0;
|
transl_table = virtphy_transl;
|
transl_table = virtphy_transl;
|
freemem = startaddr;
|
freemem = startaddr;
|
PRINTF("loadcode: filename %s startaddr=%x virtphy_transl=%x\n", filename, startaddr, virtphy_transl);
|
PRINTF("loadcode: filename %s startaddr=%lx virtphy_transl=%lx\n", filename, startaddr, virtphy_transl);
|
identifyfile(filename);
|
identifyfile(filename);
|
|
|
#if IMM_STATS
|
#if IMM_STATS
|
{
|
{
|
int i = 0, a = 0, b = 0, c = 0;
|
int i = 0, a = 0, b = 0, c = 0;
|