xref: /netbsd-src/external/gpl3/gdb.old/dist/sim/bfin/interp.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* Simulator for Analog Devices Blackfin processors.
2 
3    Copyright (C) 2005-2023 Free Software Foundation, Inc.
4    Contributed by Analog Devices, Inc.
5 
6    This file is part of simulators.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20 
21 /* This must come before any other includes.  */
22 #include "defs.h"
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <signal.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <sys/time.h>
32 
33 #include "portability.h"
34 #include "sim/callback.h"
35 #include "gdb/signals.h"
36 #include "sim-main.h"
37 #include "sim-syscall.h"
38 #include "sim-hw.h"
39 
40 /* The numbers here do not matter.  They just need to be unique.  They also
41    need not be static across releases -- they're used internally only.  The
42    mapping from the Linux ABI to the CB values is in linux-targ-map.h.  */
43 #define CB_SYS_ioctl        201
44 #define CB_SYS_mmap2        202
45 #define CB_SYS_munmap       203
46 #define CB_SYS_dup2         204
47 #define CB_SYS_getuid       205
48 #define CB_SYS_getuid32     206
49 #define CB_SYS_getgid       207
50 #define CB_SYS_getgid32     208
51 #define CB_SYS_setuid       209
52 #define CB_SYS_setuid32     210
53 #define CB_SYS_setgid       211
54 #define CB_SYS_setgid32     212
55 #define CB_SYS_pread        213
56 #define CB_SYS__llseek      214
57 #define CB_SYS_getcwd       215
58 #define CB_SYS_stat64       216
59 #define CB_SYS_lstat64      217
60 #define CB_SYS_fstat64      218
61 #define CB_SYS_ftruncate64  219
62 #define CB_SYS_gettimeofday 220
63 #define CB_SYS_access       221
64 #include "linux-targ-map.h"
65 #include "linux-fixed-code.h"
66 
67 #include "elf/common.h"
68 #include "elf/external.h"
69 #include "elf/internal.h"
70 #include "elf/bfin.h"
71 #include "elf-bfd.h"
72 
73 #include "dv-bfin_cec.h"
74 #include "dv-bfin_mmu.h"
75 
76 static const char cb_linux_stat_map_32[] =
77 /* Linux kernel 32bit layout:  */
78 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
79 "space,2:st_size,4:st_blksize,4:st_blocks,4:st_atime,4:st_atimensec,4:"
80 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:space,4";
81 /* uClibc public ABI 32bit layout:
82 "st_dev,8:space,2:space,2:st_ino,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:"
83 "st_rdev,8:space,2:space,2:st_size,4:st_blksiez,4:st_blocks,4:st_atime,4:"
84 "st_atimensec,4:st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:"
85 "space,4";  */
86 static const char cb_linux_stat_map_64[] =
87 "st_dev,8:space,4:space,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:st_rdev,8:"
88 "space,4:st_size,8:st_blksize,4:st_blocks,8:st_atime,4:st_atimensec,4:"
89 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:st_ino,8";
90 static const char cb_libgloss_stat_map_32[] =
91 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
92 "st_size,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:"
93 "space,4:st_blksize,4:st_blocks,4:space,8";
94 static const char *stat_map_32, *stat_map_64;
95 
96 /* Simulate a monitor trap, put the result into r0 and errno into r1
97    return offset by which to adjust pc.  */
98 
99 void
100 bfin_syscall (SIM_CPU *cpu)
101 {
102   SIM_DESC sd = CPU_STATE (cpu);
103   char * const *argv = (void *)STATE_PROG_ARGV (sd);
104   host_callback *cb = STATE_CALLBACK (sd);
105   bu32 args[6];
106   CB_SYSCALL sc;
107   char *p;
108   char _tbuf[1024 * 3], *tbuf = _tbuf, tstr[1024];
109   int fmt_ret_hex = 0;
110 
111   CB_SYSCALL_INIT (&sc);
112 
113   if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
114     {
115       /* Linux syscall.  */
116       sc.func = PREG (0);
117       sc.arg1 = args[0] = DREG (0);
118       sc.arg2 = args[1] = DREG (1);
119       sc.arg3 = args[2] = DREG (2);
120       sc.arg4 = args[3] = DREG (3);
121       sc.arg5 = args[4] = DREG (4);
122       sc.arg6 = args[5] = DREG (5);
123     }
124   else
125     {
126       /* libgloss syscall.  */
127       sc.func = PREG (0);
128       sc.arg1 = args[0] = GET_LONG (DREG (0));
129       sc.arg2 = args[1] = GET_LONG (DREG (0) + 4);
130       sc.arg3 = args[2] = GET_LONG (DREG (0) + 8);
131       sc.arg4 = args[3] = GET_LONG (DREG (0) + 12);
132       sc.arg5 = args[4] = GET_LONG (DREG (0) + 16);
133       sc.arg6 = args[5] = GET_LONG (DREG (0) + 20);
134     }
135   sc.p1 = sd;
136   sc.p2 = cpu;
137   sc.read_mem = sim_syscall_read_mem;
138   sc.write_mem = sim_syscall_write_mem;
139 
140   /* Common cb_syscall() handles most functions.  */
141   switch (cb_target_to_host_syscall (cb, sc.func))
142     {
143     case CB_SYS_exit:
144       tbuf += sprintf (tbuf, "exit(%i)", args[0]);
145       sim_engine_halt (sd, cpu, NULL, PCREG, sim_exited, sc.arg1);
146 
147     case CB_SYS_gettimeofday:
148       {
149 	struct timeval _tv, *tv = &_tv;
150 	struct timezone _tz, *tz = &_tz;
151 
152 	tbuf += sprintf (tbuf, "gettimeofday(%#x, %#x)", args[0], args[1]);
153 
154 	if (sc.arg1 == 0)
155 	  tv = NULL;
156 	if (sc.arg2 == 0)
157 	  tz = NULL;
158 	sc.result = gettimeofday (tv, tz);
159 
160 	if (sc.result == 0)
161 	  {
162 	    bu32 t;
163 
164 	    if (tv)
165 	      {
166 		t = tv->tv_sec;
167 		sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
168 		t = tv->tv_usec;
169 		sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
170 	      }
171 
172 	    if (sc.arg2)
173 	      {
174 		t = tz->tz_minuteswest;
175 		sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
176 		t = tz->tz_dsttime;
177 		sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
178 	      }
179 	  }
180 	else
181 	  goto sys_finish;
182       }
183       break;
184 
185     case CB_SYS_ioctl:
186       /* XXX: hack just enough to get basic stdio w/uClibc ...  */
187       tbuf += sprintf (tbuf, "ioctl(%i, %#x, %u)", args[0], args[1], args[2]);
188       if (sc.arg2 == 0x5401)
189 	{
190 	  sc.result = !isatty (sc.arg1);
191 	  sc.errcode = 0;
192 	}
193       else
194 	{
195 	  sc.result = -1;
196 	  sc.errcode = cb_host_to_target_errno (cb, EINVAL);
197 	}
198       break;
199 
200     case CB_SYS_mmap2:
201       {
202 	static bu32 heap = BFIN_DEFAULT_MEM_SIZE / 2;
203 
204 	fmt_ret_hex = 1;
205 	tbuf += sprintf (tbuf, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
206 			 args[0], args[1], args[2], args[3], args[4], args[5]);
207 
208 	sc.errcode = 0;
209 
210 	if (sc.arg4 & 0x20 /*MAP_ANONYMOUS*/)
211 	  /* XXX: We don't handle zeroing, but default is all zeros.  */;
212 	else if (args[4] >= MAX_CALLBACK_FDS)
213 	  sc.errcode = cb_host_to_target_errno (cb, ENOSYS);
214 	else
215 	  {
216 #ifdef HAVE_PREAD
217 	    char *data = xmalloc (sc.arg2);
218 
219 	    /* XXX: Should add a cb->pread.  */
220 	    if (pread (cb->fdmap[args[4]], data, sc.arg2, args[5] << 12) == sc.arg2)
221 	      sc.write_mem (cb, &sc, heap, data, sc.arg2);
222 	    else
223 	      sc.errcode = cb_host_to_target_errno (cb, EINVAL);
224 
225 	    free (data);
226 #else
227 	    sc.errcode = cb_host_to_target_errno (cb, ENOSYS);
228 #endif
229 	  }
230 
231 	if (sc.errcode)
232 	  {
233 	    sc.result = -1;
234 	    break;
235 	  }
236 
237 	sc.result = heap;
238 	heap += sc.arg2;
239 	/* Keep it page aligned.  */
240 	heap = align_up (heap, 4096);
241 
242 	break;
243       }
244 
245     case CB_SYS_munmap:
246       /* XXX: meh, just lie for mmap().  */
247       tbuf += sprintf (tbuf, "munmap(%#x, %u)", args[0], args[1]);
248       sc.result = 0;
249       break;
250 
251     case CB_SYS_dup2:
252       tbuf += sprintf (tbuf, "dup2(%i, %i)", args[0], args[1]);
253       if (sc.arg1 >= MAX_CALLBACK_FDS || sc.arg2 >= MAX_CALLBACK_FDS)
254 	{
255 	  sc.result = -1;
256 	  sc.errcode = cb_host_to_target_errno (cb, EINVAL);
257 	}
258       else
259 	{
260 	  sc.result = dup2 (cb->fdmap[sc.arg1], cb->fdmap[sc.arg2]);
261 	  goto sys_finish;
262 	}
263       break;
264 
265     case CB_SYS__llseek:
266       tbuf += sprintf (tbuf, "llseek(%i, %u, %u, %#x, %u)",
267 		       args[0], args[1], args[2], args[3], args[4]);
268       sc.func = TARGET_LINUX_SYS_lseek;
269       if (sc.arg2)
270 	{
271 	  sc.result = -1;
272 	  sc.errcode = cb_host_to_target_errno (cb, EINVAL);
273 	}
274       else
275 	{
276 	  sc.arg2 = sc.arg3;
277 	  sc.arg3 = args[4];
278 	  cb_syscall (cb, &sc);
279 	  if (sc.result != -1)
280 	    {
281 	      bu32 z = 0;
282 	      sc.write_mem (cb, &sc, args[3], (void *)&sc.result, 4);
283 	      sc.write_mem (cb, &sc, args[3] + 4, (void *)&z, 4);
284 	    }
285 	}
286       break;
287 
288     /* XXX: Should add a cb->pread.  */
289     case CB_SYS_pread:
290       tbuf += sprintf (tbuf, "pread(%i, %#x, %u, %i)",
291 		       args[0], args[1], args[2], args[3]);
292       if (sc.arg1 >= MAX_CALLBACK_FDS)
293 	{
294 	  sc.result = -1;
295 	  sc.errcode = cb_host_to_target_errno (cb, EINVAL);
296 	}
297       else
298 	{
299 	  long old_pos, read_result, read_errcode;
300 
301 	  /* Get current filepos.  */
302 	  sc.func = TARGET_LINUX_SYS_lseek;
303 	  sc.arg2 = 0;
304 	  sc.arg3 = SEEK_CUR;
305 	  cb_syscall (cb, &sc);
306 	  if (sc.result == -1)
307 	    break;
308 	  old_pos = sc.result;
309 
310 	  /* Move to the new pos.  */
311 	  sc.func = TARGET_LINUX_SYS_lseek;
312 	  sc.arg2 = args[3];
313 	  sc.arg3 = SEEK_SET;
314 	  cb_syscall (cb, &sc);
315 	  if (sc.result == -1)
316 	    break;
317 
318 	  /* Read the data.  */
319 	  sc.func = TARGET_LINUX_SYS_read;
320 	  sc.arg2 = args[1];
321 	  sc.arg3 = args[2];
322 	  cb_syscall (cb, &sc);
323 	  read_result = sc.result;
324 	  read_errcode = sc.errcode;
325 
326 	  /* Move back to the old pos.  */
327 	  sc.func = TARGET_LINUX_SYS_lseek;
328 	  sc.arg2 = old_pos;
329 	  sc.arg3 = SEEK_SET;
330 	  cb_syscall (cb, &sc);
331 
332 	  sc.result = read_result;
333 	  sc.errcode = read_errcode;
334 	}
335       break;
336 
337     case CB_SYS_getcwd:
338       tbuf += sprintf (tbuf, "getcwd(%#x, %u)", args[0], args[1]);
339 
340       p = alloca (sc.arg2);
341       if (getcwd (p, sc.arg2) == NULL)
342 	{
343 	  sc.result = -1;
344 	  sc.errcode = cb_host_to_target_errno (cb, EINVAL);
345 	}
346       else
347 	{
348 	  sc.write_mem (cb, &sc, sc.arg1, p, sc.arg2);
349 	  sc.result = sc.arg1;
350 	}
351       break;
352 
353     case CB_SYS_stat64:
354       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
355 	strcpy (tstr, "???");
356       tbuf += sprintf (tbuf, "stat64(%#x:\"%s\", %u)", args[0], tstr, args[1]);
357       cb->stat_map = stat_map_64;
358       sc.func = TARGET_LINUX_SYS_stat;
359       cb_syscall (cb, &sc);
360       cb->stat_map = stat_map_32;
361       break;
362     case CB_SYS_lstat64:
363       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
364 	strcpy (tstr, "???");
365       tbuf += sprintf (tbuf, "lstat64(%#x:\"%s\", %u)", args[0], tstr, args[1]);
366       cb->stat_map = stat_map_64;
367       sc.func = TARGET_LINUX_SYS_lstat;
368       cb_syscall (cb, &sc);
369       cb->stat_map = stat_map_32;
370       break;
371     case CB_SYS_fstat64:
372       tbuf += sprintf (tbuf, "fstat64(%#x, %u)", args[0], args[1]);
373       cb->stat_map = stat_map_64;
374       sc.func = TARGET_LINUX_SYS_fstat;
375       cb_syscall (cb, &sc);
376       cb->stat_map = stat_map_32;
377       break;
378 
379     case CB_SYS_ftruncate64:
380       tbuf += sprintf (tbuf, "ftruncate64(%u, %u)", args[0], args[1]);
381       sc.func = TARGET_LINUX_SYS_ftruncate;
382       cb_syscall (cb, &sc);
383       break;
384 
385     case CB_SYS_getuid:
386     case CB_SYS_getuid32:
387       tbuf += sprintf (tbuf, "getuid()");
388       sc.result = getuid ();
389       goto sys_finish;
390     case CB_SYS_getgid:
391     case CB_SYS_getgid32:
392       tbuf += sprintf (tbuf, "getgid()");
393       sc.result = getgid ();
394       goto sys_finish;
395     case CB_SYS_setuid:
396       sc.arg1 &= 0xffff;
397     case CB_SYS_setuid32:
398       tbuf += sprintf (tbuf, "setuid(%u)", args[0]);
399       sc.result = setuid (sc.arg1);
400       goto sys_finish;
401     case CB_SYS_setgid:
402       sc.arg1 &= 0xffff;
403     case CB_SYS_setgid32:
404       tbuf += sprintf (tbuf, "setgid(%u)", args[0]);
405       sc.result = setgid (sc.arg1);
406       goto sys_finish;
407 
408     case CB_SYS_kill:
409       tbuf += sprintf (tbuf, "kill(%u, %i)", args[0], args[1]);
410       /* Only let the app kill itself.  */
411       if (sc.arg1 != getpid ())
412 	{
413 	  sc.result = -1;
414 	  sc.errcode = cb_host_to_target_errno (cb, EPERM);
415 	}
416       else
417 	{
418 #ifdef HAVE_KILL
419 	  sc.result = kill (sc.arg1, sc.arg2);
420 	  goto sys_finish;
421 #else
422 	  sc.result = -1;
423 	  sc.errcode = cb_host_to_target_errno (cb, ENOSYS);
424 #endif
425 	}
426       break;
427 
428     case CB_SYS_open:
429       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
430 	strcpy (tstr, "???");
431       tbuf += sprintf (tbuf, "open(%#x:\"%s\", %#x, %o)",
432 		       args[0], tstr, args[1], args[2]);
433       goto case_default;
434     case CB_SYS_close:
435       tbuf += sprintf (tbuf, "close(%i)", args[0]);
436       goto case_default;
437     case CB_SYS_read:
438       tbuf += sprintf (tbuf, "read(%i, %#x, %u)", args[0], args[1], args[2]);
439       goto case_default;
440     case CB_SYS_write:
441       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[1]))
442 	strcpy (tstr, "???");
443       tbuf += sprintf (tbuf, "write(%i, %#x:\"%s\", %u)",
444 		       args[0], args[1], tstr, args[2]);
445       goto case_default;
446     case CB_SYS_lseek:
447       tbuf += sprintf (tbuf, "lseek(%i, %i, %i)", args[0], args[1], args[2]);
448       goto case_default;
449     case CB_SYS_unlink:
450       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
451 	strcpy (tstr, "???");
452       tbuf += sprintf (tbuf, "unlink(%#x:\"%s\")", args[0], tstr);
453       goto case_default;
454     case CB_SYS_truncate:
455       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
456 	strcpy (tstr, "???");
457       tbuf += sprintf (tbuf, "truncate(%#x:\"%s\", %i)", args[0], tstr, args[1]);
458       goto case_default;
459     case CB_SYS_ftruncate:
460       tbuf += sprintf (tbuf, "ftruncate(%i, %i)", args[0], args[1]);
461       goto case_default;
462     case CB_SYS_rename:
463       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
464 	strcpy (tstr, "???");
465       tbuf += sprintf (tbuf, "rename(%#x:\"%s\", ", args[0], tstr);
466       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[1]))
467 	strcpy (tstr, "???");
468       tbuf += sprintf (tbuf, "%#x:\"%s\")", args[1], tstr);
469       goto case_default;
470     case CB_SYS_stat:
471       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
472 	strcpy (tstr, "???");
473       tbuf += sprintf (tbuf, "stat(%#x:\"%s\", %#x)", args[0], tstr, args[1]);
474       goto case_default;
475     case CB_SYS_fstat:
476       tbuf += sprintf (tbuf, "fstat(%i, %#x)", args[0], args[1]);
477       goto case_default;
478     case CB_SYS_lstat:
479       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
480 	strcpy (tstr, "???");
481       tbuf += sprintf (tbuf, "lstat(%#x:\"%s\", %#x)", args[0], tstr, args[1]);
482       goto case_default;
483     case CB_SYS_pipe:
484       tbuf += sprintf (tbuf, "pipe(%#x, %#x)", args[0], args[1]);
485       goto case_default;
486 
487     default:
488       tbuf += sprintf (tbuf, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc.func,
489 		       args[0], args[1], args[2], args[3], args[4], args[5]);
490     case_default:
491       cb_syscall (cb, &sc);
492       break;
493 
494     sys_finish:
495       if (sc.result == -1)
496 	{
497 	  cb->last_errno = errno;
498 	  sc.errcode = cb->get_errno (cb);
499 	}
500     }
501 
502   TRACE_EVENTS (cpu, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
503 		sc.func, args[0], args[1], args[2], args[3], args[4], args[5],
504 		sc.result, sc.errcode);
505 
506   tbuf += sprintf (tbuf, " = ");
507   if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
508     {
509       if (sc.result == -1)
510 	{
511 	  tbuf += sprintf (tbuf, "-1 (error = %i)", sc.errcode);
512 	  if (sc.errcode == cb_host_to_target_errno (cb, ENOSYS))
513 	    {
514 	      sim_io_eprintf (sd, "bfin-sim: %#x: unimplemented syscall %i\n",
515 			      PCREG, sc.func);
516 	    }
517 	  SET_DREG (0, -sc.errcode);
518 	}
519       else
520 	{
521 	  if (fmt_ret_hex)
522 	    tbuf += sprintf (tbuf, "%#lx", sc.result);
523 	  else
524 	    tbuf += sprintf (tbuf, "%lu", sc.result);
525 	  SET_DREG (0, sc.result);
526 	}
527     }
528   else
529     {
530       tbuf += sprintf (tbuf, "%lu (error = %i)", sc.result, sc.errcode);
531       SET_DREG (0, sc.result);
532       SET_DREG (1, sc.result2);
533       SET_DREG (2, sc.errcode);
534     }
535 
536   TRACE_SYSCALL (cpu, "%s", _tbuf);
537 }
538 
539 /* Execute a single instruction.  */
540 
541 static sim_cia
542 step_once (SIM_CPU *cpu)
543 {
544   SIM_DESC sd = CPU_STATE (cpu);
545   bu32 insn_len, oldpc = PCREG;
546   int i;
547   bool ssstep;
548 
549   if (TRACE_ANY_P (cpu))
550     trace_prefix (sd, cpu, NULL_CIA, oldpc, TRACE_LINENUM_P (cpu),
551 		  NULL, 0, " "); /* Use a space for gcc warnings.  */
552 
553   TRACE_DISASM (cpu, oldpc);
554 
555   /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
556      has already had the SSSTEP bit enabled.  */
557   ssstep = false;
558   if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT
559       && (SYSCFGREG & SYSCFG_SSSTEP))
560     {
561       int ivg = cec_get_ivg (cpu);
562       if (ivg == -1 || ivg > 3)
563 	ssstep = true;
564     }
565 
566 #if 0
567   /* XXX: Is this what happens on the hardware ?  */
568   if (cec_get_ivg (cpu) == EVT_EMU)
569     cec_return (cpu, EVT_EMU);
570 #endif
571 
572   BFIN_CPU_STATE.did_jump = false;
573 
574   insn_len = interp_insn_bfin (cpu, oldpc);
575 
576   /* If we executed this insn successfully, then we always decrement
577      the loop counter.  We don't want to update the PC though if the
578      last insn happened to be a change in code flow (jump/etc...).  */
579   if (!BFIN_CPU_STATE.did_jump)
580     SET_PCREG (hwloop_get_next_pc (cpu, oldpc, insn_len));
581   for (i = 1; i >= 0; --i)
582     if (LCREG (i) && oldpc == LBREG (i))
583       {
584 	SET_LCREG (i, LCREG (i) - 1);
585 	if (LCREG (i))
586 	  break;
587       }
588 
589   ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu));
590 
591   /* Handle hardware single stepping only if we're still lower than EVT3.
592      XXX: May not be entirely correct wrt EXCPT insns.  */
593   if (ssstep)
594     {
595       int ivg = cec_get_ivg (cpu);
596       if (ivg == -1 || ivg > 3)
597 	{
598 	  INSN_LEN = 0;
599 	  cec_exception (cpu, VEC_STEP);
600 	}
601     }
602 
603   return oldpc;
604 }
605 
606 void
607 sim_engine_run (SIM_DESC sd,
608 		int next_cpu_nr, /* ignore  */
609 		int nr_cpus, /* ignore  */
610 		int siggnal) /* ignore  */
611 {
612   bu32 ticks;
613   SIM_CPU *cpu;
614 
615   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
616 
617   cpu = STATE_CPU (sd, 0);
618 
619   while (1)
620     {
621       step_once (cpu);
622       /* Process any events -- can't use tickn because it may
623          advance right over the next event.  */
624       for (ticks = 0; ticks < CYCLE_DELAY; ++ticks)
625 	if (sim_events_tick (sd))
626 	  sim_events_process (sd);
627     }
628 }
629 
630 /* Cover function of sim_state_free to free the cpu buffers as well.  */
631 
632 static void
633 free_state (SIM_DESC sd)
634 {
635   if (STATE_MODULES (sd) != NULL)
636     sim_module_uninstall (sd);
637   sim_cpu_free_all (sd);
638   sim_state_free (sd);
639 }
640 
641 /* Create an instance of the simulator.  */
642 
643 static void
644 bfin_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
645 {
646   memset (&cpu->state, 0, sizeof (cpu->state));
647 
648   PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu)) = 0;
649 
650   bfin_model_cpu_init (sd, cpu);
651 
652   /* Set default stack to top of scratch pad.  */
653   SET_SPREG (BFIN_DEFAULT_MEM_SIZE);
654   SET_KSPREG (BFIN_DEFAULT_MEM_SIZE);
655   SET_USPREG (BFIN_DEFAULT_MEM_SIZE);
656 
657   /* This is what the hardware likes.  */
658   SET_SYSCFGREG (0x30);
659 }
660 
661 SIM_DESC
662 sim_open (SIM_OPEN_KIND kind, host_callback *callback,
663 	  struct bfd *abfd, char * const *argv)
664 {
665   char c;
666   int i;
667   SIM_DESC sd = sim_state_alloc_extra (kind, callback,
668 				       sizeof (struct bfin_board_data));
669 
670   /* Set default options before parsing user options.  */
671   STATE_MACHS (sd) = bfin_sim_machs;
672   STATE_MODEL_NAME (sd) = "bf537";
673   current_alignment = STRICT_ALIGNMENT;
674   current_target_byte_order = BFD_ENDIAN_LITTLE;
675 
676   /* The cpu data is kept in a separately allocated chunk of memory.  */
677   if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
678     {
679       free_state (sd);
680       return 0;
681     }
682 
683   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
684     {
685       free_state (sd);
686       return 0;
687     }
688 
689   /* XXX: Default to the Virtual environment.  */
690   if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
691     STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT;
692 
693   /* The parser will print an error message for us, so we silently return.  */
694   if (sim_parse_args (sd, argv) != SIM_RC_OK)
695     {
696       free_state (sd);
697       return 0;
698     }
699 
700   /* Allocate external memory if none specified by user.
701      Use address 4 here in case the user wanted address 0 unmapped.  */
702   if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
703     {
704       bu16 emuexcpt = 0x25;
705       sim_do_commandf (sd, "memory-size 0x%x", BFIN_DEFAULT_MEM_SIZE);
706       sim_write (sd, 0, &emuexcpt, 2);
707     }
708 
709   /* Check for/establish the a reference program image.  */
710   if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
711     {
712       free_state (sd);
713       return 0;
714     }
715 
716   /* Establish any remaining configuration options.  */
717   if (sim_config (sd) != SIM_RC_OK)
718     {
719       free_state (sd);
720       return 0;
721     }
722 
723   if (sim_post_argv_init (sd) != SIM_RC_OK)
724     {
725       free_state (sd);
726       return 0;
727     }
728 
729   /* CPU specific initialization.  */
730   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
731     {
732       SIM_CPU *cpu = STATE_CPU (sd, i);
733       bfin_initialize_cpu (sd, cpu);
734     }
735 
736   return sd;
737 }
738 
739 /* Some utils don't like having a NULL environ.  */
740 static char * const simple_env[] = { "HOME=/", "PATH=/bin", NULL };
741 
742 static bu32 fdpic_load_offset;
743 
744 static bool
745 bfin_fdpic_load (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd, bu32 *sp,
746 		 bu32 *elf_addrs, char **ldso_path)
747 {
748   bool ret;
749   int i;
750 
751   Elf_Internal_Ehdr *iehdr;
752   Elf32_External_Ehdr ehdr;
753   Elf_Internal_Phdr *phdrs;
754   unsigned char *data;
755   long phdr_size;
756   int phdrc;
757   bu32 nsegs;
758 
759   bu32 max_load_addr;
760 
761   unsigned char null[4] = { 0, 0, 0, 0 };
762 
763   ret = false;
764   *ldso_path = NULL;
765 
766   /* See if this an FDPIC ELF.  */
767   phdrs = NULL;
768   if (!abfd)
769     goto skip_fdpic_init;
770   if (bfd_seek (abfd, 0, SEEK_SET) != 0)
771     goto skip_fdpic_init;
772   if (bfd_bread (&ehdr, sizeof (ehdr), abfd) != sizeof (ehdr))
773     goto skip_fdpic_init;
774   iehdr = elf_elfheader (abfd);
775   if (!(iehdr->e_flags & EF_BFIN_FDPIC))
776     goto skip_fdpic_init;
777 
778   if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
779     sim_io_printf (sd, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
780 		   bfd_get_filename (abfd), fdpic_load_offset, elf_addrs[0]);
781 
782   /* Grab the Program Headers to set up the loadsegs on the stack.  */
783   phdr_size = bfd_get_elf_phdr_upper_bound (abfd);
784   if (phdr_size == -1)
785     goto skip_fdpic_init;
786   phdrs = xmalloc (phdr_size);
787   phdrc = bfd_get_elf_phdrs (abfd, phdrs);
788   if (phdrc == -1)
789     goto skip_fdpic_init;
790 
791   /* Push the Ehdr onto the stack.  */
792   *sp -= sizeof (ehdr);
793   elf_addrs[3] = *sp;
794   sim_write (sd, *sp, &ehdr, sizeof (ehdr));
795   if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
796     sim_io_printf (sd, " Elf_Ehdr: %#x\n", *sp);
797 
798   /* Since we're relocating things ourselves, we need to relocate
799      the start address as well.  */
800   elf_addrs[0] = bfd_get_start_address (abfd) + fdpic_load_offset;
801 
802   /* And the Exec's Phdrs onto the stack.  */
803   if (STATE_PROG_BFD (sd) == abfd)
804     {
805       elf_addrs[4] = elf_addrs[0];
806 
807       phdr_size = iehdr->e_phentsize * iehdr->e_phnum;
808       if (bfd_seek (abfd, iehdr->e_phoff, SEEK_SET) != 0)
809 	goto skip_fdpic_init;
810       data = xmalloc (phdr_size);
811       if (bfd_bread (data, phdr_size, abfd) != phdr_size)
812 	goto skip_fdpic_init;
813       *sp -= phdr_size;
814       elf_addrs[1] = *sp;
815       elf_addrs[2] = phdrc;
816       sim_write (sd, *sp, data, phdr_size);
817       free (data);
818       if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
819 	sim_io_printf (sd, " Elf_Phdrs: %#x\n", *sp);
820     }
821 
822   /* Now push all the loadsegs.  */
823   nsegs = 0;
824   max_load_addr = 0;
825   for (i = phdrc; i >= 0; --i)
826     if (phdrs[i].p_type == PT_LOAD)
827       {
828 	Elf_Internal_Phdr *p = &phdrs[i];
829 	bu32 paddr, vaddr, memsz, filesz;
830 
831 	paddr = p->p_paddr + fdpic_load_offset;
832 	vaddr = p->p_vaddr;
833 	memsz = p->p_memsz;
834 	filesz = p->p_filesz;
835 
836 	if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
837 	  sim_io_printf (sd, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
838 			 i, vaddr, paddr, filesz, memsz);
839 
840 	data = xmalloc (memsz);
841 	if (memsz != filesz)
842 	  memset (data + filesz, 0, memsz - filesz);
843 
844 	if (bfd_seek (abfd, p->p_offset, SEEK_SET) == 0
845 	    && bfd_bread (data, filesz, abfd) == filesz)
846 	  sim_write (sd, paddr, data, memsz);
847 
848 	free (data);
849 
850 	max_load_addr = max (paddr + memsz, max_load_addr);
851 
852 	*sp -= 12;
853 	sim_write (sd, *sp+0, &paddr, 4); /* loadseg.addr  */
854 	sim_write (sd, *sp+4, &vaddr, 4); /* loadseg.p_vaddr  */
855 	sim_write (sd, *sp+8, &memsz, 4); /* loadseg.p_memsz  */
856 	++nsegs;
857       }
858     else if (phdrs[i].p_type == PT_DYNAMIC)
859       {
860 	elf_addrs[5] = phdrs[i].p_paddr + fdpic_load_offset;
861 	if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
862 	  sim_io_printf (sd, " PT_DYNAMIC: %#x\n", elf_addrs[5]);
863       }
864     else if (phdrs[i].p_type == PT_INTERP)
865       {
866 	uint32_t off = phdrs[i].p_offset;
867 	uint32_t len = phdrs[i].p_filesz;
868 
869 	*ldso_path = xmalloc (len);
870 	if (bfd_seek (abfd, off, SEEK_SET) != 0
871 	    || bfd_bread (*ldso_path, len, abfd) != len)
872 	  {
873 	    free (*ldso_path);
874 	    *ldso_path = NULL;
875 	  }
876 	else if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
877 	  sim_io_printf (sd, " PT_INTERP: %s\n", *ldso_path);
878       }
879 
880   /* Update the load offset with a few extra pages.  */
881   fdpic_load_offset = align_up (max (max_load_addr, fdpic_load_offset),
882 				0x10000);
883   fdpic_load_offset += 0x10000;
884 
885   /* Push the summary loadmap info onto the stack last.  */
886   *sp -= 4;
887   sim_write (sd, *sp+0, null, 2); /* loadmap.version  */
888   sim_write (sd, *sp+2, &nsegs, 2); /* loadmap.nsegs  */
889 
890   ret = true;
891  skip_fdpic_init:
892   free (phdrs);
893 
894   return ret;
895 }
896 
897 static void
898 bfin_user_init (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd,
899 		char * const *argv, char * const *env)
900 {
901   /* XXX: Missing host -> target endian ...  */
902   /* Linux starts the user app with the stack:
903        argc
904        argv[0]          -- pointers to the actual strings
905        argv[1..N]
906        NULL
907        env[0]
908        env[1..N]
909        NULL
910        auxvt[0].type    -- ELF Auxiliary Vector Table
911        auxvt[0].value
912        auxvt[1..N]
913        AT_NULL
914        0
915        argv[0..N][0..M] -- actual argv/env strings
916        env[0..N][0..M]
917        FDPIC loadmaps   -- for FDPIC apps
918      So set things up the same way.  */
919   int i, argc, envc;
920   bu32 argv_flat, env_flat;
921 
922   bu32 sp, sp_flat;
923 
924   /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic  */
925   bu32 elf_addrs[6];
926   bu32 auxvt;
927   bu32 exec_loadmap, ldso_loadmap;
928   char *ldso_path;
929 
930   unsigned char null[4] = { 0, 0, 0, 0 };
931 
932   host_callback *cb = STATE_CALLBACK (sd);
933 
934   elf_addrs[0] = elf_addrs[4] = bfd_get_start_address (abfd);
935   elf_addrs[1] = elf_addrs[2] = elf_addrs[3] = elf_addrs[5] = 0;
936 
937   /* Keep the load addresses consistent between runs.  Also make sure we make
938      space for the fixed code region (part of the Blackfin Linux ABI).  */
939   fdpic_load_offset = 0x1000;
940 
941   /* First try to load this as an FDPIC executable.  */
942   sp = SPREG;
943   if (!bfin_fdpic_load (sd, cpu, STATE_PROG_BFD (sd), &sp, elf_addrs, &ldso_path))
944     goto skip_fdpic_init;
945   exec_loadmap = sp;
946 
947   /* If that worked, then load the fixed code region.  We only do this for
948      FDPIC ELFs atm because they are PIEs and let us relocate them without
949      manual fixups.  FLAT files however require location processing which
950      we do not do ourselves, and they link with a VMA of 0.  */
951   sim_write (sd, 0x400, bfin_linux_fixed_code, sizeof (bfin_linux_fixed_code));
952 
953   /* If the FDPIC needs an interpreter, then load it up too.  */
954   if (ldso_path)
955     {
956       const char *ldso_full_path = concat (simulator_sysroot, ldso_path, NULL);
957       struct bfd *ldso_bfd;
958 
959       ldso_bfd = bfd_openr (ldso_full_path, STATE_TARGET (sd));
960       if (!ldso_bfd)
961 	{
962 	  sim_io_eprintf (sd, "bfin-sim: bfd open failed: %s\n", ldso_full_path);
963 	  goto static_fdpic;
964 	}
965       if (!bfd_check_format (ldso_bfd, bfd_object))
966 	sim_io_eprintf (sd, "bfin-sim: bfd format not valid: %s\n", ldso_full_path);
967       bfd_set_arch_info (ldso_bfd, STATE_ARCHITECTURE (sd));
968 
969       if (!bfin_fdpic_load (sd, cpu, ldso_bfd, &sp, elf_addrs, &ldso_path))
970 	sim_io_eprintf (sd, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path);
971       if (ldso_path)
972 	sim_io_eprintf (sd, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
973 			ldso_full_path, ldso_path);
974 
975       ldso_loadmap = sp;
976     }
977   else
978  static_fdpic:
979     ldso_loadmap = 0;
980 
981   /* Finally setup the registers required by the FDPIC ABI.  */
982   SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up.  */
983   SET_PREG (0, exec_loadmap); /* Exec loadmap addr.  */
984   SET_PREG (1, ldso_loadmap); /* Interp loadmap addr.  */
985   SET_PREG (2, elf_addrs[5]); /* PT_DYNAMIC map addr.  */
986 
987   auxvt = 1;
988   SET_SPREG (sp);
989  skip_fdpic_init:
990   sim_pc_set (cpu, elf_addrs[0]);
991 
992   /* Figure out how much storage the argv/env strings need.  */
993   argc = countargv ((char **)argv);
994   if (argc == -1)
995     argc = 0;
996   argv_flat = argc; /* NUL bytes  */
997   for (i = 0; i < argc; ++i)
998     argv_flat += strlen (argv[i]);
999 
1000   if (!env)
1001     env = simple_env;
1002   envc = countargv ((char **)env);
1003   env_flat = envc; /* NUL bytes  */
1004   for (i = 0; i < envc; ++i)
1005     env_flat += strlen (env[i]);
1006 
1007   /* Push the Auxiliary Vector Table between argv/env and actual strings.  */
1008   sp_flat = sp = align_up (SPREG - argv_flat - env_flat - 4, 4);
1009   if (auxvt)
1010     {
1011 # define AT_PUSH(at, val) \
1012   auxvt_size += 8; \
1013   sp -= 4; \
1014   auxvt = (val); \
1015   sim_write (sd, sp, &auxvt, 4); \
1016   sp -= 4; \
1017   auxvt = (at); \
1018   sim_write (sd, sp, &auxvt, 4)
1019       unsigned int egid = getegid (), gid = getgid ();
1020       unsigned int euid = geteuid (), uid = getuid ();
1021       bu32 auxvt_size = 0;
1022       AT_PUSH (AT_NULL, 0);
1023       AT_PUSH (AT_SECURE, egid != gid || euid != uid);
1024       AT_PUSH (AT_EGID, egid);
1025       AT_PUSH (AT_GID, gid);
1026       AT_PUSH (AT_EUID, euid);
1027       AT_PUSH (AT_UID, uid);
1028       AT_PUSH (AT_ENTRY, elf_addrs[4]);
1029       AT_PUSH (AT_FLAGS, 0);
1030       AT_PUSH (AT_BASE, elf_addrs[3]);
1031       AT_PUSH (AT_PHNUM, elf_addrs[2]);
1032       AT_PUSH (AT_PHENT, sizeof (Elf32_External_Phdr));
1033       AT_PUSH (AT_PHDR, elf_addrs[1]);
1034       AT_PUSH (AT_CLKTCK, 100); /* XXX: This ever not 100 ?  */
1035       AT_PUSH (AT_PAGESZ, 4096);
1036       AT_PUSH (AT_HWCAP, 0);
1037 #undef AT_PUSH
1038     }
1039   SET_SPREG (sp);
1040 
1041   /* Push the argc/argv/env after the auxvt.  */
1042   sp -= ((1 + argc + 1 + envc + 1) * 4);
1043   SET_SPREG (sp);
1044 
1045   /* First push the argc value.  */
1046   sim_write (sd, sp, &argc, 4);
1047   sp += 4;
1048 
1049   /* Then the actual argv strings so we know where to point argv[].  */
1050   for (i = 0; i < argc; ++i)
1051     {
1052       unsigned len = strlen (argv[i]) + 1;
1053       sim_write (sd, sp_flat, argv[i], len);
1054       sim_write (sd, sp, &sp_flat, 4);
1055       sp_flat += len;
1056       sp += 4;
1057     }
1058   sim_write (sd, sp, null, 4);
1059   sp += 4;
1060 
1061   /* Then the actual env strings so we know where to point env[].  */
1062   for (i = 0; i < envc; ++i)
1063     {
1064       unsigned len = strlen (env[i]) + 1;
1065       sim_write (sd, sp_flat, env[i], len);
1066       sim_write (sd, sp, &sp_flat, 4);
1067       sp_flat += len;
1068       sp += 4;
1069     }
1070 
1071   /* Set some callbacks.  */
1072   cb->syscall_map = cb_linux_syscall_map;
1073   cb->errno_map = cb_linux_errno_map;
1074   cb->open_map = cb_linux_open_map;
1075   cb->signal_map = cb_linux_signal_map;
1076   cb->stat_map = stat_map_32 = cb_linux_stat_map_32;
1077   stat_map_64 = cb_linux_stat_map_64;
1078 }
1079 
1080 static void
1081 bfin_os_init (SIM_DESC sd, SIM_CPU *cpu, char * const *argv)
1082 {
1083   /* Pass the command line via a string in R0 like Linux expects.  */
1084   int i;
1085   bu8 byte;
1086   bu32 cmdline = BFIN_L1_SRAM_SCRATCH;
1087 
1088   SET_DREG (0, cmdline);
1089   if (argv && argv[0])
1090     {
1091       i = 1;
1092       byte = ' ';
1093       while (argv[i])
1094 	{
1095 	  bu32 len = strlen (argv[i]);
1096 	  sim_write (sd, cmdline, argv[i], len);
1097 	  cmdline += len;
1098 	  sim_write (sd, cmdline, &byte, 1);
1099 	  ++cmdline;
1100 	  ++i;
1101 	}
1102     }
1103   byte = 0;
1104   sim_write (sd, cmdline, &byte, 1);
1105 }
1106 
1107 static void
1108 bfin_virtual_init (SIM_DESC sd, SIM_CPU *cpu)
1109 {
1110   host_callback *cb = STATE_CALLBACK (sd);
1111 
1112   cb->stat_map = stat_map_32 = cb_libgloss_stat_map_32;
1113   stat_map_64 = NULL;
1114 }
1115 
1116 SIM_RC
1117 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
1118 		     char * const *argv, char * const *env)
1119 {
1120   SIM_CPU *cpu = STATE_CPU (sd, 0);
1121   host_callback *cb = STATE_CALLBACK (sd);
1122   SIM_ADDR addr;
1123 
1124   /* Set the PC.  */
1125   if (abfd != NULL)
1126     addr = bfd_get_start_address (abfd);
1127   else
1128     addr = 0;
1129   sim_pc_set (cpu, addr);
1130 
1131   /* Standalone mode (i.e. `run`) will take care of the argv for us in
1132      sim_open() -> sim_parse_args().  But in debug mode (i.e. 'target sim'
1133      with `gdb`), we need to handle it because the user can change the
1134      argv on the fly via gdb's 'run'.  */
1135   if (STATE_PROG_ARGV (sd) != argv)
1136     {
1137       freeargv (STATE_PROG_ARGV (sd));
1138       STATE_PROG_ARGV (sd) = dupargv (argv);
1139     }
1140 
1141   if (STATE_PROG_ENVP (sd) != env)
1142     {
1143       freeargv (STATE_PROG_ENVP (sd));
1144       STATE_PROG_ENVP (sd) = dupargv (env);
1145     }
1146 
1147   cb->argv = STATE_PROG_ARGV (sd);
1148   cb->envp = STATE_PROG_ENVP (sd);
1149 
1150   switch (STATE_ENVIRONMENT (sd))
1151     {
1152     case USER_ENVIRONMENT:
1153       bfin_user_init (sd, cpu, abfd, argv, env);
1154       break;
1155     case OPERATING_ENVIRONMENT:
1156       bfin_os_init (sd, cpu, argv);
1157       break;
1158     default:
1159       bfin_virtual_init (sd, cpu);
1160       break;
1161     }
1162 
1163   return SIM_RC_OK;
1164 }
1165