1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5 #include "arm.h"
6
7 #include <tos.h>
8
9 char* file = "5.out";
10 int datasize;
11 ulong textbase;
12 Biobuf bp, bi;
13 Fhdr fhdr;
14
15 void
main(int argc,char ** argv)16 main(int argc, char **argv)
17 {
18
19 argc--;
20 argv++;
21
22 bioout = &bp;
23 bin = &bi;
24 Binit(bioout, 1, OWRITE);
25 Binit(bin, 0, OREAD);
26
27 tlb.on = 1;
28 tlb.tlbsize = 24;
29
30 if(argc)
31 file = argv[0];
32 argc--;
33 argv++;
34
35 text = open(file, OREAD);
36 if(text < 0)
37 fatal(1, "open text '%s'", file);
38
39 Bprint(bioout, "5i\n");
40 inithdr(text);
41 initstk(argc, argv);
42
43 cmd();
44 }
45
46 void
initmap()47 initmap()
48 {
49 ulong t, d, b, bssend;
50 Segment *s;
51
52 t = (fhdr.txtaddr+fhdr.txtsz+(BY2PG-1)) & ~(BY2PG-1);
53 d = (t + fhdr.datsz + (BY2PG-1)) & ~(BY2PG-1);
54 bssend = t + fhdr.datsz + fhdr.bsssz;
55 b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
56
57 s = &memory.seg[Text];
58 s->type = Text;
59 s->base = fhdr.txtaddr - fhdr.hdrsz;
60 s->end = t;
61 s->fileoff = fhdr.txtoff - fhdr.hdrsz;
62 s->fileend = s->fileoff + fhdr.txtsz;
63 s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
64
65 iprof = emalloc(((s->end-s->base)/PROFGRAN)*sizeof(long));
66 textbase = s->base;
67
68 s = &memory.seg[Data];
69 s->type = Data;
70 s->base = t;
71 s->end = t+(d-t);
72 s->fileoff = fhdr.datoff;
73 s->fileend = s->fileoff + fhdr.datsz;
74 datasize = fhdr.datsz;
75 s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
76
77 s = &memory.seg[Bss];
78 s->type = Bss;
79 s->base = d;
80 s->end = d+(b-d);
81 s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
82
83 s = &memory.seg[Stack];
84 s->type = Stack;
85 s->base = STACKTOP-STACKSIZE;
86 s->end = STACKTOP;
87 s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
88
89 reg.r[REGPC] = fhdr.entry;
90 }
91
92 void
inithdr(int fd)93 inithdr(int fd)
94 {
95 Symbol s;
96
97 extern Machdata armmach;
98
99 seek(fd, 0, 0);
100 if (!crackhdr(fd, &fhdr))
101 fatal(0, "read text header");
102
103 if(fhdr.type != FARM )
104 fatal(0, "bad magic number: %d %d", fhdr.type, FARM);
105
106 if (syminit(fd, &fhdr) < 0)
107 fatal(0, "%r\n");
108
109 symmap = loadmap(symmap, fd, &fhdr);
110 if (mach->sbreg && lookup(0, mach->sbreg, &s))
111 mach->sb = s.value;
112 machdata = &armmach;
113 }
114
115 void
reset(void)116 reset(void)
117 {
118 int i, l, m;
119 Segment *s;
120 Breakpoint *b;
121
122 memset(®, 0, sizeof(Registers));
123
124 for(i = 0; i > Nseg; i++) {
125 s = &memory.seg[i];
126 l = ((s->end-s->base)/BY2PG)*sizeof(uchar*);
127 for(m = 0; m < l; m++)
128 if(s->table[m])
129 free(s->table[m]);
130 free(s->table);
131 }
132 free(iprof);
133 memset(&memory, 0, sizeof(memory));
134
135 for(b = bplist; b; b = b->next)
136 b->done = b->count;
137 }
138
139 void
initstk(int argc,char * argv[])140 initstk(int argc, char *argv[])
141 {
142 ulong size;
143 ulong sp, ap, tos;
144 int i;
145 char *p;
146
147 initmap();
148 tos = STACKTOP - sizeof(Tos)*2; /* we'll assume twice the host's is big enough */
149 sp = tos;
150 for (i = 0; i < sizeof(Tos)*2; i++)
151 putmem_b(tos + i, 0);
152
153 /*
154 * pid is second word from end of tos and needs to be set for nsec().
155 * we know arm is a 32-bit cpu, so we'll assume knowledge of the Tos
156 * struct for now, and use our pid.
157 */
158 putmem_w(tos + 4*4 + 2*sizeof(ulong) + 3*sizeof(uvlong), getpid());
159
160 /* Build exec stack */
161 size = strlen(file)+1+BY2WD+BY2WD+BY2WD;
162 for(i = 0; i < argc; i++)
163 size += strlen(argv[i])+BY2WD+1;
164
165 sp -= size;
166 sp &= ~7;
167 reg.r[0] = tos;
168 reg.r[13] = sp;
169 reg.r[1] = STACKTOP-4; /* Plan 9 profiling clock (why & why in R1?) */
170
171 /* Push argc */
172 putmem_w(sp, argc+1);
173 sp += BY2WD;
174
175 /* Compute sizeof(argv) and push argv[0] */
176 ap = sp+((argc+1)*BY2WD)+BY2WD;
177 putmem_w(sp, ap);
178 sp += BY2WD;
179
180 /* Build argv[0] string into stack */
181 for(p = file; *p; p++)
182 putmem_b(ap++, *p);
183
184 putmem_b(ap++, '\0');
185
186 /* Loop through pushing the arguments */
187 for(i = 0; i < argc; i++) {
188 putmem_w(sp, ap);
189 sp += BY2WD;
190 for(p = argv[i]; *p; p++)
191 putmem_b(ap++, *p);
192 putmem_b(ap++, '\0');
193 }
194 /* Null terminate argv */
195 putmem_w(sp, 0);
196
197 }
198
199 void
fatal(int syserr,char * fmt,...)200 fatal(int syserr, char *fmt, ...)
201 {
202 char buf[ERRMAX], *s;
203 va_list arg;
204
205 va_start(arg, fmt);
206 vseprint(buf, buf+sizeof(buf), fmt, arg);
207 va_end(arg);
208 s = "5i: %s\n";
209 if(syserr)
210 s = "5i: %s: %r\n";
211 fprint(2, s, buf);
212 exits(buf);
213 }
214
215 void
itrace(char * fmt,...)216 itrace(char *fmt, ...)
217 {
218 char buf[128];
219 va_list arg;
220
221 va_start(arg, fmt);
222 vseprint(buf, buf+sizeof(buf), fmt, arg);
223 va_end(arg);
224 Bprint(bioout, "%8lux %.8lux %2d %s\n", reg.ar, reg.ir, reg.class, buf);
225 }
226
227 void
dumpreg(void)228 dumpreg(void)
229 {
230 int i;
231
232 Bprint(bioout, "PC #%-8lux SP #%-8lux \n",
233 reg.r[REGPC], reg.r[REGSP]);
234
235 for(i = 0; i < 16; i++) {
236 if((i%4) == 0 && i != 0)
237 Bprint(bioout, "\n");
238 Bprint(bioout, "R%-2d #%-8lux ", i, reg.r[i]);
239 }
240 Bprint(bioout, "\n");
241 }
242
243 void
dumpfreg(void)244 dumpfreg(void)
245 {
246 }
247
248 void
dumpdreg(void)249 dumpdreg(void)
250 {
251 }
252
253 void *
emalloc(ulong size)254 emalloc(ulong size)
255 {
256 void *a;
257
258 a = malloc(size);
259 if(a == 0)
260 fatal(0, "no memory");
261
262 memset(a, 0, size);
263 return a;
264 }
265
266 void *
erealloc(void * a,ulong oldsize,ulong size)267 erealloc(void *a, ulong oldsize, ulong size)
268 {
269 void *n;
270
271 n = malloc(size);
272 if(n == 0)
273 fatal(0, "no memory");
274 memset(n, 0, size);
275 if(size > oldsize)
276 size = oldsize;
277 memmove(n, a, size);
278 return n;
279 }
280