#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#include "arm.h"
#include <tos.h>
char* file = "5.out";
int datasize;
ulong textbase;
Biobuf bp, bi;
Fhdr fhdr;
void
main(int argc, char **argv)
{
argc--;
argv++;
bioout = &bp;
bin = &bi;
Binit(bioout, 1, OWRITE);
Binit(bin, 0, OREAD);
tlb.on = 1;
tlb.tlbsize = 24;
if(argc)
file = argv[0];
argc--;
argv++;
text = open(file, OREAD);
if(text < 0)
fatal(1, "open text '%s'", file);
Bprint(bioout, "5i\n");
inithdr(text);
initstk(argc, argv);
cmd();
}
void
initmap()
{
ulong t, d, b, bssend;
Segment *s;
t = (fhdr.txtaddr+fhdr.txtsz+(BY2PG-1)) & ~(BY2PG-1);
d = (t + fhdr.datsz + (BY2PG-1)) & ~(BY2PG-1);
bssend = t + fhdr.datsz + fhdr.bsssz;
b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
s = &memory.seg[Text];
s->type = Text;
s->base = fhdr.txtaddr - fhdr.hdrsz;
s->end = t;
s->fileoff = fhdr.txtoff - fhdr.hdrsz;
s->fileend = s->fileoff + fhdr.txtsz;
s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
iprof = emalloc(((s->end-s->base)/PROFGRAN)*sizeof(long));
textbase = s->base;
s = &memory.seg[Data];
s->type = Data;
s->base = t;
s->end = t+(d-t);
s->fileoff = fhdr.datoff;
s->fileend = s->fileoff + fhdr.datsz;
datasize = fhdr.datsz;
s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
s = &memory.seg[Bss];
s->type = Bss;
s->base = d;
s->end = d+(b-d);
s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
s = &memory.seg[Stack];
s->type = Stack;
s->base = STACKTOP-STACKSIZE;
s->end = STACKTOP;
s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
reg.r[REGPC] = fhdr.entry;
}
void
inithdr(int fd)
{
Symbol s;
extern Machdata armmach;
seek(fd, 0, 0);
if (!crackhdr(fd, &fhdr))
fatal(0, "read text header");
if(fhdr.type != FARM )
fatal(0, "bad magic number: %d %d", fhdr.type, FARM);
if (syminit(fd, &fhdr) < 0)
fatal(0, "%r\n");
symmap = loadmap(symmap, fd, &fhdr);
if (mach->sbreg && lookup(0, mach->sbreg, &s))
mach->sb = s.value;
machdata = &armmach;
}
void
reset(void)
{
int i, l, m;
Segment *s;
Breakpoint *b;
memset(®, 0, sizeof(Registers));
for(i = 0; i > Nseg; i++) {
s = &memory.seg[i];
l = ((s->end-s->base)/BY2PG)*sizeof(uchar*);
for(m = 0; m < l; m++)
if(s->table[m])
free(s->table[m]);
free(s->table);
}
free(iprof);
memset(&memory, 0, sizeof(memory));
for(b = bplist; b; b = b->next)
b->done = b->count;
}
void
initstk(int argc, char *argv[])
{
ulong size;
ulong sp, ap, tos;
int i;
char *p;
initmap();
tos = STACKTOP - sizeof(Tos)*2; /* we'll assume twice the host's is big enough */
sp = tos;
/* Build exec stack */
size = strlen(file)+1+BY2WD+BY2WD+BY2WD;
for(i = 0; i < argc; i++)
size += strlen(argv[i])+BY2WD+1;
sp -= size;
sp &= ~7;
reg.r[0] = tos;
reg.r[13] = sp;
reg.r[1] = STACKTOP-4; /* Plan 9 profiling clock */
/* Push argc */
putmem_w(sp, argc+1);
sp += BY2WD;
/* Compute sizeof(argv) and push argv[0] */
ap = sp+((argc+1)*BY2WD)+BY2WD;
putmem_w(sp, ap);
sp += BY2WD;
/* Build argv[0] string into stack */
for(p = file; *p; p++)
putmem_b(ap++, *p);
putmem_b(ap++, '\0');
/* Loop through pushing the arguments */
for(i = 0; i < argc; i++) {
putmem_w(sp, ap);
sp += BY2WD;
for(p = argv[i]; *p; p++)
putmem_b(ap++, *p);
putmem_b(ap++, '\0');
}
/* Null terminate argv */
putmem_w(sp, 0);
}
void
fatal(int syserr, char *fmt, ...)
{
char buf[ERRMAX], *s;
va_list arg;
va_start(arg, fmt);
vseprint(buf, buf+sizeof(buf), fmt, arg);
va_end(arg);
s = "5i: %s\n";
if(syserr)
s = "5i: %s: %r\n";
fprint(2, s, buf);
exits(buf);
}
void
itrace(char *fmt, ...)
{
char buf[128];
va_list arg;
va_start(arg, fmt);
vseprint(buf, buf+sizeof(buf), fmt, arg);
va_end(arg);
Bprint(bioout, "%8lux %.8lux %2d %s\n", reg.ar, reg.ir, reg.class, buf);
}
void
dumpreg(void)
{
int i;
Bprint(bioout, "PC #%-8lux SP #%-8lux \n",
reg.r[REGPC], reg.r[REGSP]);
for(i = 0; i < 16; i++) {
if((i%4) == 0 && i != 0)
Bprint(bioout, "\n");
Bprint(bioout, "R%-2d #%-8lux ", i, reg.r[i]);
}
Bprint(bioout, "\n");
}
void
dumpfreg(void)
{
}
void
dumpdreg(void)
{
}
void *
emalloc(ulong size)
{
void *a;
a = malloc(size);
if(a == 0)
fatal(0, "no memory");
memset(a, 0, size);
return a;
}
void *
erealloc(void *a, ulong oldsize, ulong size)
{
void *n;
n = malloc(size);
if(n == 0)
fatal(0, "no memory");
memset(n, 0, size);
if(size > oldsize)
size = oldsize;
memmove(n, a, size);
return n;
}
|