Line 31... |
Line 31... |
#include "port.h"
|
#include "port.h"
|
#include "arch.h"
|
#include "arch.h"
|
#include "abstract.h"
|
#include "abstract.h"
|
#include "dmmu.h"
|
#include "dmmu.h"
|
#include "coff.h"
|
#include "coff.h"
|
|
|
|
#define OR32_TYPES
|
#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 "labels.h"
|
Line 55... |
Line 58... |
|
|
/* Translation table provided by microkernel. Only used if simulating microkernel. */
|
/* Translation table provided by microkernel. Only used if simulating microkernel. */
|
static oraddr_t transl_table;
|
static oraddr_t transl_table;
|
|
|
/* Used to signal whether during loading of programs a translation fault occured. */
|
/* Used to signal whether during loading of programs a translation fault occured. */
|
static unsigned long transl_error;
|
static uint32_t transl_error;
|
|
|
char *
|
char *
|
stripwhite (string)
|
stripwhite (string)
|
char *string;
|
char *string;
|
{
|
{
|
Line 142... |
Line 145... |
}
|
}
|
|
|
#if IMM_STATS
|
#if IMM_STATS
|
int bcnt[33][3] = {0};
|
int bcnt[33][3] = {0};
|
int bsum[3] = {0};
|
int bsum[3] = {0};
|
unsigned long movhi = 0;
|
uint32_t movhi = 0;
|
|
|
int bits (unsigned long val) {
|
int bits (uint32_t val) {
|
int i = 1;
|
int i = 1;
|
if (!val) return 0;
|
if (!val) return 0;
|
while (val != 0 && (signed long)val != -1) {i++; val = (signed long)val >> 1;}
|
while (val != 0 && (int32_t)val != -1) {i++; val = (int32_t)val >> 1;}
|
return i;
|
return i;
|
}
|
}
|
|
|
void check_insn (uint32_t insn) {
|
void check_insn (uint32_t insn) {
|
int insn_index = insn_decode (insn);
|
int insn_index = insn_decode (insn);
|
Line 243... |
Line 246... |
void readfile_coff(char *filename, short sections)
|
void readfile_coff(char *filename, short sections)
|
{
|
{
|
FILE *inputfs;
|
FILE *inputfs;
|
char inputbuf[4];
|
char inputbuf[4];
|
uint32_t insn;
|
uint32_t insn;
|
signed long sectsize;
|
int32_t sectsize;
|
COFF_AOUTHDR coffaouthdr;
|
COFF_AOUTHDR coffaouthdr;
|
struct COFF_scnhdr coffscnhdr;
|
struct COFF_scnhdr coffscnhdr;
|
int len;
|
int len;
|
int firstthree = 0;
|
int firstthree = 0;
|
int breakpoint = 0;
|
int breakpoint = 0;
|
Line 268... |
Line 271... |
perror("readfile_coff");
|
perror("readfile_coff");
|
exit(1);
|
exit(1);
|
}
|
}
|
|
|
while(sections--) {
|
while(sections--) {
|
long scnhdr_pos = sizeof(struct COFF_filehdr) + sizeof(coffaouthdr)
|
uint32_t scnhdr_pos = sizeof(struct COFF_filehdr) + sizeof(coffaouthdr)
|
+ sizeof(struct COFF_scnhdr) * firstthree;
|
+ sizeof(struct COFF_scnhdr) * firstthree;
|
if (fseek(inputfs, scnhdr_pos, SEEK_SET) == -1) {
|
if (fseek(inputfs, scnhdr_pos, SEEK_SET) == -1) {
|
fclose(inputfs);
|
fclose(inputfs);
|
perror("readfile_coff");
|
perror("readfile_coff");
|
exit(1);
|
exit(1);
|
Line 332... |
Line 335... |
insn = COFF_LONG_H(inputbuf);
|
insn = COFF_LONG_H(inputbuf);
|
len = insn_len (insn_decode (insn));
|
len = insn_len (insn_decode (insn));
|
if (len == 2)
|
if (len == 2)
|
{
|
{
|
fseek(inputfs, -2, SEEK_CUR);
|
fseek(inputfs, -2, SEEK_CUR);
|
debug(8,"readfile_coff: %lx 0x%x \n", sectsize, insn >> 16);
|
debug(8,"readfile_coff: %"PRIx32" 0x%x \n", sectsize, insn >> 16);
|
}
|
}
|
else
|
else
|
debug(8,"readfile_coff: %lx 0x%x \n", sectsize, insn);
|
debug(8,"readfile_coff: %"PRIx32" 0x%x \n", sectsize, insn);
|
addprogram (freemem, insn, &breakpoint);
|
addprogram (freemem, insn, &breakpoint);
|
sectsize -= len;
|
sectsize -= len;
|
}
|
}
|
}
|
}
|
if (firstthree < 3) {
|
if (firstthree < 3) {
|
Line 357... |
Line 360... |
return;
|
return;
|
}
|
}
|
|
|
/* Load symbols from big-endian COFF file. */
|
/* Load symbols from big-endian COFF file. */
|
|
|
void readsyms_coff(char *filename, unsigned long symptr, long syms)
|
void readsyms_coff(char *filename, uint32_t symptr, uint32_t syms)
|
{
|
{
|
FILE *inputfs;
|
FILE *inputfs;
|
struct COFF_syment coffsymhdr;
|
struct COFF_syment coffsymhdr;
|
int count = 0;
|
int count = 0;
|
long nsyms = syms;
|
uint32_t nsyms = syms;
|
if (!(inputfs = fopen(filename, "r"))) {
|
if (!(inputfs = fopen(filename, "r"))) {
|
perror("readsyms_coff");
|
perror("readsyms_coff");
|
exit(1);
|
exit(1);
|
}
|
}
|
|
|
Line 391... |
Line 394... |
#if 0
|
#if 0
|
/* If not important or not in text, skip. */
|
/* If not important or not in text, skip. */
|
if(COFF_SHORT_H(coffsymhdr.e_type) & COFF_N_TMASK & COFF_STYP_TEXT) {
|
if(COFF_SHORT_H(coffsymhdr.e_type) & COFF_N_TMASK & COFF_STYP_TEXT) {
|
#endif
|
#endif
|
|
|
if (*((unsigned long *)coffsymhdr.e.e.e_zeroes)) {
|
if (*((uint32_t *)coffsymhdr.e.e.e_zeroes)) {
|
if (strlen(coffsymhdr.e.e_name) && strlen(coffsymhdr.e.e_name) < 9)
|
if (strlen(coffsymhdr.e.e_name) && strlen(coffsymhdr.e.e_name) < 9)
|
add_label(COFF_LONG_H(coffsymhdr.e_value), coffsymhdr.e.e_name);
|
add_label(COFF_LONG_H(coffsymhdr.e_value), coffsymhdr.e.e_name);
|
debug(8, "[%i] Symbol: %s,", count++, coffsymhdr.e.e_name);
|
debug(8, "[%i] Symbol: %s,", count++, coffsymhdr.e.e_name);
|
} else {
|
} else {
|
long fpos = ftell (inputfs);
|
uint32_t fpos = ftell (inputfs);
|
|
|
if (fseek(inputfs, symptr + nsyms * COFF_SYMESZ + COFF_LONG_H(coffsymhdr.e.e.e_offset), SEEK_SET) == 0) {
|
if (fseek(inputfs, symptr + nsyms * COFF_SYMESZ + COFF_LONG_H(coffsymhdr.e.e.e_offset), SEEK_SET) == 0) {
|
char tmp[33], *s = &tmp[0];
|
char tmp[33], *s = &tmp[0];
|
while (s != &tmp[32])
|
while (s != &tmp[32])
|
if ((*(s++) = fgetc(inputfs)) == 0) break;
|
if ((*(s++) = fgetc(inputfs)) == 0) break;
|
Line 436... |
Line 439... |
FILE *inputfs;
|
FILE *inputfs;
|
struct elf32_hdr elfhdr;
|
struct elf32_hdr elfhdr;
|
struct elf32_phdr *elf_phdata = NULL;
|
struct elf32_phdr *elf_phdata = NULL;
|
struct elf32_shdr *elf_spnt, *elf_shdata;
|
struct elf32_shdr *elf_spnt, *elf_shdata;
|
struct elf32_sym *sym_tbl = (struct elf32_sym *)0;
|
struct elf32_sym *sym_tbl = (struct elf32_sym *)0;
|
unsigned long syms = 0;
|
uint32_t syms = 0;
|
char *str_tbl = (char *)0;
|
char *str_tbl = (char *)0;
|
char *s_str = (char *)0;
|
char *s_str = (char *)0;
|
int breakpoint = 0;
|
int breakpoint = 0;
|
unsigned long inputbuf;
|
uint32_t inputbuf;
|
unsigned long padd;
|
uint32_t padd;
|
uint32_t insn;
|
uint32_t insn;
|
int i, j, sectsize, len;
|
int i, j, sectsize, len;
|
|
|
if (!(inputfs = fopen(filename, "r"))) {
|
if (!(inputfs = fopen(filename, "r"))) {
|
perror("readfile_elf");
|
perror("readfile_elf");
|
Line 567... |
Line 570... |
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%.8lx,", ELF_LONG_H(elf_spnt->sh_addr));
|
PRINTF(" vaddr: 0x%.8lx,", ELF_LONG_H(elf_spnt->sh_addr));
|
PRINTF(" paddr: 0x%.8lx,", padd);
|
PRINTF(" paddr: 0x%"PRIx32, padd);
|
PRINTF(" offset: 0x%.8lx,", ELF_LONG_H(elf_spnt->sh_offset));
|
PRINTF(" offset: 0x%.8lx,", ELF_LONG_H(elf_spnt->sh_offset));
|
PRINTF(" size: 0x%.8lx\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);
|
Line 625... |
Line 628... |
exit(1);
|
exit(1);
|
}
|
}
|
|
|
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;
|
uint32_t 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%.8lx\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%.2lx\n", opthdr_size);
|
PRINTF("COFF f_opthdr: 0x%"PRIx32"\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 677... |
Line 680... |
return;
|
return;
|
}
|
}
|
|
|
|
|
/* Loads file to memory starting at address startaddr and returns freemem. */
|
/* Loads file to memory starting at address startaddr and returns freemem. */
|
unsigned long loadcode(char *filename, oraddr_t startaddr, oraddr_t virtphy_transl)
|
uint32_t loadcode(char *filename, oraddr_t startaddr, oraddr_t virtphy_transl)
|
{
|
{
|
int breakpoint = 0;
|
int breakpoint = 0;
|
|
|
transl_error = 0;
|
transl_error = 0;
|
transl_table = virtphy_transl;
|
transl_table = virtphy_transl;
|