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