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