256 lines
5.6 KiB
C
256 lines
5.6 KiB
C
/*
|
|
Copyright (c) 1992-1993 The Regents of the University of California.
|
|
All rights reserved. See copyright.h for copyright notice and limitation
|
|
of liability and disclaimer of warranty provisions.
|
|
*/
|
|
|
|
#define MAIN
|
|
#include "copyright.h"
|
|
#undef MAIN
|
|
|
|
/*
|
|
* OUT.C
|
|
* Looking at a.out formats.
|
|
*
|
|
* First task:
|
|
* Look at mips COFF stuff:
|
|
* Print out the contents of a file and do the following:
|
|
* For data, print the value and give relocation information
|
|
* For code, disassemble and give relocation information
|
|
*/
|
|
|
|
#include <filehdr.h>
|
|
#include <aouthdr.h>
|
|
#include <scnhdr.h>
|
|
#include <reloc.h>
|
|
#include <syms.h>
|
|
#include <stdio.h>
|
|
|
|
#define read_struct(f,s) (fread(&s,sizeof(s),1,f)==1)
|
|
|
|
#define MAXRELOCS 1000
|
|
|
|
|
|
#define MAXDATA 10000
|
|
|
|
struct data {
|
|
long data[MAXDATA];
|
|
struct reloc reloc[MAXRELOCS];
|
|
int length;
|
|
int relocs;
|
|
};
|
|
|
|
#define MAXSCNS 10
|
|
#define MAXSYMS 300
|
|
#define MAXSSPACE 20000
|
|
|
|
struct filehdr filehdr;
|
|
struct aouthdr aouthdr;
|
|
struct scnhdr scnhdr[MAXSCNS];
|
|
struct data section[MAXSCNS];
|
|
HDRR symhdr;
|
|
EXTR symbols[MAXSYMS];
|
|
char sspace[20000];
|
|
|
|
char *symbol_type[] = {
|
|
"Nil", "Global", "Static", "Param", "Local", "Label", "Proc", "Block",
|
|
"End", "Member", "Type", "File", "Register", "Forward", "StaticProc",
|
|
"Constant" };
|
|
|
|
char *storage_class[] = {
|
|
"Nil", "Text", "Data", "Bss", "Register", "Abs", "Undefined", "CdbLocal",
|
|
"Bits", "CdbSystem", "RegImage", "Info", "UserStruct", "SData", "SBss",
|
|
"RData", "Var", "Common", "SCommon", "VarRegister", "Variant", "SUndefined",
|
|
"Init" };
|
|
|
|
main(argc,argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
char *filename = "a.out";
|
|
FILE *f;
|
|
int i;
|
|
long l;
|
|
/* EXTR filesym; */
|
|
char buf[100];
|
|
|
|
if (argc == 2) filename = argv[1];
|
|
if ((f = fopen(filename,"r")) == NULL) {
|
|
printf("out: could not open %s\n",filename);
|
|
perror("out");
|
|
exit(1);
|
|
}
|
|
if (!read_struct(f,filehdr) ||
|
|
!read_struct(f,aouthdr) ||
|
|
filehdr.f_magic != MIPSELMAGIC) {
|
|
printf("out: %s is not a MIPS Little-Endian COFF object file\n",filename);
|
|
exit(1);
|
|
}
|
|
if (filehdr.f_nscns > MAXSCNS) {
|
|
printf("out: Too many COFF sections.\n");
|
|
exit(1);
|
|
}
|
|
for (i=0; i < filehdr.f_nscns; ++i) {
|
|
read_struct(f,scnhdr[i]);
|
|
if (scnhdr[i].s_size > MAXDATA*sizeof(long) &&
|
|
scnhdr[i].s_scnptr != 0 ||
|
|
scnhdr[i].s_nreloc > MAXRELOCS) {
|
|
printf("section %s is too big.\n",scnhdr[i].s_name);
|
|
exit(1);
|
|
}
|
|
}
|
|
for (i=0; i < filehdr.f_nscns; ++i) {
|
|
if (scnhdr[i].s_scnptr != 0) {
|
|
section[i].length = scnhdr[i].s_size/4;
|
|
fseek(f,scnhdr[i].s_scnptr,0);
|
|
fread(section[i].data,sizeof(long),section[i].length,f);
|
|
section[i].relocs = scnhdr[i].s_nreloc;
|
|
fseek(f,scnhdr[i].s_relptr,0);
|
|
fread(section[i].reloc,sizeof(struct reloc),section[i].relocs,f);
|
|
} else {
|
|
section[i].length = 0;
|
|
}
|
|
}
|
|
fseek(f,filehdr.f_symptr,0);
|
|
read_struct(f,symhdr);
|
|
if (symhdr.iextMax > MAXSYMS) {
|
|
printf("too many symbols to store.\n");
|
|
}
|
|
fseek(f,symhdr.cbExtOffset,0);
|
|
for (i=0; i < MAXSYMS && i<symhdr.iextMax; ++i) {
|
|
read_struct(f,symbols[i]);
|
|
}
|
|
if (symhdr.issExtMax > MAXSSPACE) {
|
|
printf("too large a string space.\n");
|
|
exit(1);
|
|
}
|
|
fseek(f,symhdr.cbSsExtOffset,0);
|
|
fread(sspace,1,symhdr.issExtMax,f);
|
|
|
|
for (i=0; i<filehdr.f_nscns; ++i) {
|
|
print_section(i);
|
|
}
|
|
|
|
printf("External Symbols:\nValue\t Type\t\tStorage Class\tName\n");
|
|
for (i=0; i < MAXSYMS && i < symhdr.iextMax; ++i) {
|
|
SYMR *sym = &symbols[i].asym;
|
|
if (sym->sc == scUndefined) myprintf("\t ");
|
|
else myprintf("%08x ",sym->value);
|
|
myprintf("%s",symbol_type[sym->st]);
|
|
mytab(25);
|
|
myprintf("%s",storage_class[sym->sc]);
|
|
mytab(41);
|
|
myprintf("%s\n",&sspace[sym->iss]);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static column = 1;
|
|
static FILE *outfile = stdout;
|
|
|
|
#include <varargs.h>
|
|
/*VARARGS0*/
|
|
myprintf(va_alist)
|
|
va_dcl
|
|
{
|
|
va_list ap;
|
|
char *form;
|
|
char buf[100];
|
|
|
|
va_start(ap);
|
|
form = va_arg(ap,char *);
|
|
vsprintf(buf,form,ap);
|
|
va_end(ap);
|
|
|
|
fputs(buf,outfile);
|
|
|
|
for (form = buf; *form != '\0'; ++form) {
|
|
if (*form == '\n') column = 1;
|
|
else if (*form == '\t') column = ((column + 7)&~7)+1;
|
|
else column += 1;
|
|
}
|
|
}
|
|
|
|
mytab(n)
|
|
int n;
|
|
{
|
|
while (column < n) {
|
|
fputc(' ',outfile);
|
|
++column;
|
|
}
|
|
return column == n;
|
|
}
|
|
|
|
mysetfile(f)
|
|
FILE *f;
|
|
{
|
|
outfile = f;
|
|
}
|
|
|
|
#define printf myprintf
|
|
#include "d.c"
|
|
|
|
print_section(i)
|
|
int i;
|
|
{
|
|
int j,k;
|
|
int is_text;
|
|
long pc;
|
|
long word;
|
|
char *s;
|
|
|
|
printf("Section: %s\t%d/%d\n",scnhdr[i].s_name,
|
|
scnhdr[i].s_size,section[i].relocs);
|
|
is_text = (strncmp(scnhdr[i].s_name,".text",5) == 0);
|
|
|
|
for (j=0; j < section[i].length; ++j) {
|
|
pc = scnhdr[i].s_vaddr+j*4;
|
|
word = section[i].data[j];
|
|
if (is_text) {
|
|
dump_ascii(word,pc);
|
|
} else {
|
|
printf("%08x: %08x ", pc,word);
|
|
s = (char *)&word;
|
|
for (k=0;k<4;++k) {
|
|
if (s[k] >= ' ' && s[k] < 127) printf("%c",s[k]);
|
|
else printf(".");
|
|
}
|
|
printf("\t%d",word);
|
|
}
|
|
print_reloc(pc,i,j);
|
|
}
|
|
}
|
|
|
|
char *section_name[] = {
|
|
"(null)", ".text", ".rdata", ".data", ".sdata", ".sbss", ".bss",
|
|
".init", ".lit8", ".lit4"
|
|
};
|
|
|
|
char *reloc_type[] = {
|
|
"abs", "16", "32", "26", "hi16", "lo16", "gpdata", "gplit"
|
|
};
|
|
|
|
print_reloc(vaddr,i,j)
|
|
int i,j;
|
|
{
|
|
int k;
|
|
struct reloc *rp;
|
|
for (k=0; k < section[i].relocs; ++k) {
|
|
rp = §ion[i].reloc[k];
|
|
if (vaddr == rp->r_vaddr) {
|
|
mytab(57);
|
|
if (rp->r_extern) {
|
|
if (rp->r_symndx >= MAXSYMS) {
|
|
printf("sym $%d",rp->r_symndx);
|
|
} else {
|
|
printf("\"%s\"",&sspace[symbols[rp->r_symndx].asym.iss]);
|
|
}
|
|
} else {
|
|
printf("%s",section_name[rp->r_symndx]);
|
|
}
|
|
printf(" %s",reloc_type[rp->r_type]);
|
|
break;
|
|
}
|
|
}
|
|
printf("\n");
|
|
}
|