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
bfin_syscall(SIM_CPU * cpu)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
step_once(SIM_CPU * cpu)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
sim_engine_run(SIM_DESC sd,int next_cpu_nr,int nr_cpus,int siggnal)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
free_state(SIM_DESC sd)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
bfin_initialize_cpu(SIM_DESC sd,SIM_CPU * cpu)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
sim_open(SIM_OPEN_KIND kind,host_callback * callback,struct bfd * abfd,char * const * argv)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
bfin_fdpic_load(SIM_DESC sd,SIM_CPU * cpu,struct bfd * abfd,bu32 * sp,bu32 * elf_addrs,char ** ldso_path)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
bfin_user_init(SIM_DESC sd,SIM_CPU * cpu,struct bfd * abfd,char * const * argv,char * const * env)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
bfin_os_init(SIM_DESC sd,SIM_CPU * cpu,char * const * argv)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
bfin_virtual_init(SIM_DESC sd,SIM_CPU * cpu)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
sim_create_inferior(SIM_DESC sd,struct bfd * abfd,char * const * argv,char * const * env)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