xref: /plan9-contrib/sys/src/cmd/5i/5i.c (revision bb43afe423a7a925fe6bf0f50e9f0e6b24a63d80)
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(&reg, 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