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