Line 24... |
Line 24... |
|
|
#include "abstract.h"
|
#include "abstract.h"
|
#include "arch.h"
|
#include "arch.h"
|
#include "dmmu.h"
|
#include "dmmu.h"
|
#include "coff.h"
|
#include "coff.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"
|
|
|
Line 433... |
Line 434... |
fclose(inputfs);
|
fclose(inputfs);
|
printf("Finished loading symbols.\n");
|
printf("Finished loading symbols.\n");
|
return;
|
return;
|
}
|
}
|
|
|
|
void readfile_elf(char *filename)
|
|
{
|
|
|
|
FILE *inputfs;
|
|
struct elf32_hdr elfhdr;
|
|
struct elf32_phdr *elf_phdata;
|
|
struct elf32_shdr *elf_spnt, *elf_shdata;
|
|
struct elf32_sym *sym_tbl = (struct elf32_sym *)0;
|
|
unsigned long syms = 0;
|
|
char *str_tbl = (char *)0;
|
|
char *s_str = (char *)0;
|
|
int breakpoint = 0;
|
|
unsigned long inputbuf;
|
|
unsigned long insn, padd;
|
|
int i, j, sectsize, len;
|
|
|
|
if (!(inputfs = fopen(filename, "r"))) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if (fread(&elfhdr, sizeof(elfhdr), 1, inputfs) != 1) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if ((elf_shdata = (struct elf32_shdr *)malloc(ELF_SHORT_H(elfhdr.e_shentsize) * ELF_SHORT_H(elfhdr.e_shnum))) == NULL) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if (fseek(inputfs, ELF_LONG_H(elfhdr.e_shoff), SEEK_SET) != 0) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if (fread(elf_shdata, ELF_SHORT_H(elfhdr.e_shentsize) * ELF_SHORT_H(elfhdr.e_shnum), 1, inputfs) != 1) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if (ELF_LONG_H(elfhdr.e_phoff)) {
|
|
|
|
if((elf_phdata = (struct elf32_phdr *)malloc(ELF_SHORT_H(elfhdr.e_phnum) * ELF_SHORT_H(elfhdr.e_phentsize))) == NULL) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if (fseek(inputfs, ELF_LONG_H(elfhdr.e_phoff), SEEK_SET) != 0) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if (fread(elf_phdata, ELF_SHORT_H(elfhdr.e_phnum) * ELF_SHORT_H(elfhdr.e_phentsize), 1, inputfs) != 1) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
for(i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H(elfhdr.e_shnum); i++, elf_spnt++) {
|
|
|
|
if(ELF_LONG_H(elf_spnt->sh_type) == SHT_STRTAB) {
|
|
|
|
if((str_tbl = (char *)malloc(ELF_LONG_H(elf_spnt->sh_size))) == NULL) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if (fseek(inputfs, ELF_LONG_H(elf_spnt->sh_offset), SEEK_SET) != 0) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if (fread(str_tbl, ELF_LONG_H(elf_spnt->sh_size), 1, inputfs) != 1) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
}
|
|
else if(ELF_LONG_H(elf_spnt->sh_type) == SHT_SYMTAB) {
|
|
|
|
if((sym_tbl = (char *)malloc(ELF_LONG_H(elf_spnt->sh_size))) == NULL) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if (fseek(inputfs, ELF_LONG_H(elf_spnt->sh_offset), SEEK_SET) != 0) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if (fread(sym_tbl, ELF_LONG_H(elf_spnt->sh_size), 1, inputfs) != 1) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
syms = ELF_LONG_H(elf_spnt->sh_size) / ELF_LONG_H(elf_spnt->sh_entsize);
|
|
}
|
|
}
|
|
|
|
if (ELF_SHORT_H(elfhdr.e_shstrndx) != SHN_UNDEF) {
|
|
elf_spnt = &elf_shdata[ELF_SHORT_H(elfhdr.e_shstrndx)];
|
|
|
|
if((s_str = (char *)malloc(ELF_LONG_H(elf_spnt->sh_size))) == NULL) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if (fseek(inputfs, ELF_LONG_H(elf_spnt->sh_offset), SEEK_SET) != 0) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
if (fread(s_str, ELF_LONG_H(elf_spnt->sh_size), 1, inputfs) != 1) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
|
|
for(i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H(elfhdr.e_shnum); i++, elf_spnt++) {
|
|
|
|
if((ELF_LONG_H(elf_spnt->sh_type) & SHT_PROGBITS) && (ELF_LONG_H(elf_spnt->sh_flags) & SHF_ALLOC)) {
|
|
|
|
padd = ELF_LONG_H(elf_spnt->sh_addr);
|
|
for(j = 0; j < ELF_SHORT_H(elfhdr.e_phnum); j++) {
|
|
if(ELF_LONG_H(elf_phdata[j].p_offset) &&
|
|
ELF_LONG_H(elf_phdata[j].p_offset) <= ELF_LONG_H(elf_spnt->sh_offset) &&
|
|
(ELF_LONG_H(elf_phdata[j].p_offset) + ELF_LONG_H(elf_phdata[j].p_memsz)) > ELF_LONG_H(elf_spnt->sh_offset))
|
|
padd = ELF_LONG_H(elf_phdata[j].p_paddr) + ELF_LONG_H(elf_spnt->sh_offset) - ELF_LONG_H(elf_phdata[j].p_offset);
|
|
}
|
|
|
|
|
|
|
|
if (ELF_LONG_H(elf_spnt->sh_name) && s_str)
|
|
printf("Section: %s,", &s_str[ELF_LONG_H(elf_spnt->sh_name)]);
|
|
else
|
|
printf("Section: noname,");
|
|
printf(" vaddr: 0x%.8x,", ELF_LONG_H(elf_spnt->sh_addr));
|
|
printf(" paddr: 0x%.8x,", padd);
|
|
printf(" offset: 0x%.8x,", ELF_LONG_H(elf_spnt->sh_offset));
|
|
printf(" size: 0x%.8x\n", ELF_LONG_H(elf_spnt->sh_size));
|
|
|
|
freemem = ELF_LONG_H(elf_spnt->sh_addr);
|
|
sectsize = ELF_LONG_H(elf_spnt->sh_size);
|
|
|
|
if (fseek(inputfs, ELF_LONG_H(elf_spnt->sh_offset), SEEK_SET) != 0) {
|
|
perror("readfile_elf");
|
|
exit(1);
|
|
}
|
|
|
|
while (sectsize > 0 && (len = fread(&inputbuf, sizeof(inputbuf), 1, inputfs))) {
|
|
insn = ELF_LONG_H(inputbuf);
|
|
len = insn_len (insn_decode (insn));
|
|
if (len == 2)
|
|
{
|
|
fseek(inputfs, -2, SEEK_CUR);
|
|
debug(8, "readfile_elf: %x 0x%x \n", sectsize, insn >> 16);
|
|
}
|
|
else
|
|
debug(8, "readfile_elf: %x 0x%x \n", sectsize, insn);
|
|
addprogram (freemem, insn, &breakpoint);
|
|
sectsize -= len;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (str_tbl) {
|
|
i = 0;
|
|
while(syms--) {
|
|
if (sym_tbl[i].st_name)
|
|
add_label(ELF_LONG_H(sym_tbl[i].st_value), &str_tbl[ELF_LONG_H(sym_tbl[i].st_name)]);
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
/* Identify file type and call appropriate readfile_X routine. It only
|
/* Identify file type and call appropriate readfile_X routine. It only
|
handles orX-coff-big executables at the moment. */
|
handles orX-coff-big executables at the moment. */
|
|
|
void identifyfile(char *filename)
|
void identifyfile(char *filename)
|
{
|
{
|
FILE *inputfs;
|
FILE *inputfs;
|
struct COFF_filehdr coffhdr;
|
struct COFF_filehdr coffhdr;
|
|
struct elf32_hdr elfhdr;
|
size_t len;
|
size_t len;
|
|
|
if (!(inputfs = fopen(filename, "r"))) {
|
if (!(inputfs = fopen(filename, "r"))) {
|
fprintf(stderr, "xx %s", filename);
|
fprintf(stderr, "xx %s", filename);
|
perror("identifyfile1");
|
perror("identifyfile1");
|
Line 472... |
Line 650... |
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));
|
return;
|
return;
|
}
|
}
|
else {
|
else {
|
printf("Not COFF, quiting.\n");
|
printf("Not COFF file format\n");
|
fclose(inputfs);
|
fseek(inputfs, 0, SEEK_SET);
|
|
}
|
|
}
|
|
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) {
|
|
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 version: 0x%.8x\n", ELF_LONG_H(elfhdr.e_version));
|
|
printf("ELF sec = %d\n", ELF_SHORT_H(elfhdr.e_shnum));
|
|
if (ELF_SHORT_H(elfhdr.e_type) != ET_EXEC ) {
|
|
printf("This ELF is not an executable.\n");
|
exit (1);
|
exit (1);
|
}
|
}
|
|
fclose(inputfs);
|
|
readfile_elf(filename);
|
|
return;
|
}
|
}
|
else {
|
else {
|
printf("yy %s", filename);
|
printf("Not ELF file format.\n");
|
perror("identifyfile2");
|
fseek(inputfs, 0, SEEK_SET);
|
|
}
|
}
|
}
|
|
|
|
perror("identifyfile2");
|
fclose(inputfs);
|
fclose(inputfs);
|
|
|
return;
|
return;
|
}
|
}
|
|
|
Line 496... |
Line 689... |
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", filename, startaddr, virtphy_transl);
|
printf("loadcode: filename %s startaddr=%x virtphy_transl=%x\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;
|