]> Git Repo - binutils.git/blob - sim/bfin/interp.c
Automatic date update in version.in
[binutils.git] / sim / bfin / interp.c
1 /* Simulator for Analog Devices Blackfin processors.
2
3    Copyright (C) 2005-2022 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 }
This page took 0.085274 seconds and 4 git commands to generate.