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