1 /* Remote target system call support. 2 Copyright 1997-2024 Free Software Foundation, Inc. 3 Contributed by Cygnus Solutions. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 /* This interface isn't intended to be specific to any particular kind 21 of remote (hardware, simulator, whatever). As such, support for it 22 (e.g. sim/common/callback.c) should *not* live in the simulator source 23 tree, nor should it live in the gdb source tree. K&R C must be 24 supported. */ 25 26 /* This must come before any other includes. */ 27 #include "defs.h" 28 29 #include <errno.h> 30 #include <fcntl.h> 31 #include <stdarg.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <time.h> 36 #include <unistd.h> 37 #include <sys/stat.h> 38 #include <sys/types.h> 39 40 #include "ansidecl.h" 41 #include "libiberty.h" 42 43 #include "sim/callback.h" 44 45 #ifndef ENOSYS 46 #define ENOSYS EINVAL 47 #endif 48 #ifndef ENAMETOOLONG 49 #define ENAMETOOLONG EINVAL 50 #endif 51 52 /* Maximum length of a path name. */ 53 #ifndef MAX_PATH_LEN 54 #define MAX_PATH_LEN 1024 55 #endif 56 57 /* When doing file read/writes, do this many bytes at a time. */ 58 #define FILE_XFR_SIZE 4096 59 60 /* FIXME: for now, need to consider target word size. */ 61 #define TWORD long 62 #define TADDR unsigned long 63 64 /* Path to be prepended to syscalls with absolute paths, and to be 65 chdir:ed at startup, if not empty. */ 66 char *simulator_sysroot = ""; 67 68 /* Utility of cb_syscall to fetch a path name or other string from the target. 69 The result is 0 for success or a host errno value. */ 70 71 int 72 cb_get_string (host_callback *cb, CB_SYSCALL *sc, char *buf, int buflen, 73 TADDR addr) 74 { 75 char *p, *pend; 76 77 for (p = buf, pend = buf + buflen; p < pend; ++p, ++addr) 78 { 79 /* No, it isn't expected that this would cause one transaction with 80 the remote target for each byte. The target could send the 81 path name along with the syscall request, and cache the file 82 name somewhere (or otherwise tweak this as desired). */ 83 unsigned int count = (*sc->read_mem) (cb, sc, addr, p, 1); 84 85 if (count != 1) 86 return EINVAL; 87 if (*p == 0) 88 break; 89 } 90 if (p == pend) 91 return ENAMETOOLONG; 92 return 0; 93 } 94 95 /* Utility of cb_syscall to fetch a path name. 96 The buffer is malloc'd and the address is stored in BUFP. 97 The result is that of get_string, but prepended with 98 simulator_sysroot if the string starts with '/'. 99 If an error occurs, no buffer is left malloc'd. */ 100 101 static int 102 get_path (host_callback *cb, CB_SYSCALL *sc, TADDR addr, char **bufp) 103 { 104 char *buf = xmalloc (MAX_PATH_LEN); 105 int result; 106 int sysroot_len = strlen (simulator_sysroot); 107 108 result = cb_get_string (cb, sc, buf, MAX_PATH_LEN - sysroot_len, addr); 109 if (result == 0) 110 { 111 /* Prepend absolute paths with simulator_sysroot. Relative paths 112 are supposed to be relative to a chdir within that path, but at 113 this point unknown where. */ 114 if (simulator_sysroot[0] != '\0' && *buf == '/') 115 { 116 /* Considering expected rareness of syscalls with absolute 117 file paths (compared to relative file paths and insn 118 execution), it does not seem worthwhile to rearrange things 119 to get rid of the string moves here; we'd need at least an 120 extra call to check the initial '/' in the path. */ 121 memmove (buf + sysroot_len, buf, sysroot_len); 122 memcpy (buf, simulator_sysroot, sysroot_len); 123 } 124 125 *bufp = buf; 126 } 127 else 128 free (buf); 129 return result; 130 } 131 132 /* Perform a system call on behalf of the target. */ 133 134 CB_RC 135 cb_syscall (host_callback *cb, CB_SYSCALL *sc) 136 { 137 TWORD result = 0, errcode = 0; 138 139 if (sc->magic != CB_SYSCALL_MAGIC) 140 abort (); 141 142 switch (cb_target_to_host_syscall (cb, sc->func)) 143 { 144 case CB_SYS_argc: 145 result = countargv (cb->argv); 146 break; 147 148 case CB_SYS_argnlen: 149 { 150 if (sc->arg1 >= 0 && sc->arg1 < countargv (cb->argv)) 151 result = strlen (cb->argv[sc->arg1]); 152 else 153 { 154 result = -1; 155 errcode = EINVAL; 156 } 157 } 158 break; 159 160 case CB_SYS_argn: 161 { 162 if (sc->arg1 >= 0 && sc->arg1 < countargv (cb->argv)) 163 { 164 const char *argn = cb->argv[sc->arg1]; 165 int len = strlen (argn); 166 int written = sc->write_mem (cb, sc, sc->arg2, argn, len + 1); 167 168 if (written == len + 1) 169 result = sc->arg2; 170 else 171 { 172 result = -1; 173 errcode = EINVAL; 174 } 175 } 176 else 177 { 178 result = -1; 179 errcode = EINVAL; 180 } 181 } 182 break; 183 184 case CB_SYS_argvlen : 185 { 186 /* Compute how much space is required to store the argv,envp 187 strings so that the program can allocate the space and then 188 call SYS_argv to fetch the values. */ 189 int argc, envc, arglen, envlen; 190 char **argv = cb->argv; 191 char **envp = cb->envp; 192 193 argc = arglen = 0; 194 if (argv) 195 { 196 for ( ; argv[argc]; ++argc) 197 arglen += strlen (argv[argc]) + 1; 198 } 199 envc = envlen = 0; 200 if (envp) 201 { 202 for ( ; envp[envc]; ++envc) 203 envlen += strlen (envp[envc]) + 1; 204 } 205 result = arglen + 1 + envlen + 1; 206 break; 207 } 208 209 case CB_SYS_argv : 210 { 211 /* Pointer to target's buffer. */ 212 TADDR tbuf = sc->arg1; 213 /* Buffer size. */ 214 int bufsize = sc->arg2; 215 int written = 0; 216 int argc, envc, len, ret; 217 char **argv = cb->argv; 218 char **envp = cb->envp; 219 220 result = -1; 221 222 argc = 0; 223 if (argv) 224 { 225 for ( ; argv[argc]; ++argc) 226 { 227 len = strlen (argv[argc]) + 1; 228 if (written + len > bufsize) 229 goto efault; 230 231 ret = (*sc->write_mem) (cb, sc, tbuf + written, argv[argc], 232 len); 233 if (ret != len) 234 goto einval; 235 236 written += ret; 237 } 238 } 239 /* Double NUL bytes indicates end of strings. */ 240 if (written >= bufsize) 241 goto efault; 242 if ((*sc->write_mem) (cb, sc, tbuf + written, "", 1) != 1) 243 goto einval; 244 ++written; 245 246 envc = 0; 247 if (envp) 248 { 249 for ( ; envp[envc]; ++envc) 250 { 251 len = strlen (envp[envc]) + 1; 252 if (written + len > bufsize) 253 goto efault; 254 255 ret = (*sc->write_mem) (cb, sc, tbuf + written, envp[envc], 256 len); 257 if (ret != len) 258 goto einval; 259 written += ret; 260 } 261 } 262 /* Double NUL bytes indicates end of strings. */ 263 if (written >= bufsize) 264 goto efault; 265 if ((*sc->write_mem) (cb, sc, tbuf + written, "", 1) != 1) 266 goto einval; 267 268 result = argc; 269 sc->result2 = envc; 270 break; 271 272 efault: 273 errcode = EFAULT; 274 goto FinishSyscall; 275 276 einval: 277 errcode = EINVAL; 278 goto FinishSyscall; 279 } 280 281 case CB_SYS_exit : 282 /* Caller must catch and handle; see sim_syscall as an example. */ 283 break; 284 285 case CB_SYS_open : 286 { 287 char *path; 288 289 errcode = get_path (cb, sc, sc->arg1, &path); 290 if (errcode != 0) 291 { 292 result = -1; 293 goto FinishSyscall; 294 } 295 result = (*cb->open) (cb, path, sc->arg2 /*, sc->arg3*/); 296 free (path); 297 if (result < 0) 298 goto ErrorFinish; 299 } 300 break; 301 302 case CB_SYS_close : 303 result = (*cb->close) (cb, sc->arg1); 304 if (result < 0) 305 goto ErrorFinish; 306 break; 307 308 case CB_SYS_read : 309 { 310 /* ??? Perfect handling of error conditions may require only one 311 call to cb->read. One can't assume all the data is 312 contiguously stored in host memory so that would require 313 malloc'ing/free'ing the space. Maybe later. */ 314 char buf[FILE_XFR_SIZE]; 315 int fd = sc->arg1; 316 TADDR addr = sc->arg2; 317 size_t count = sc->arg3; 318 size_t bytes_read = 0; 319 int bytes_written; 320 321 while (count > 0) 322 { 323 if (cb_is_stdin (cb, fd)) 324 result = (int) (*cb->read_stdin) (cb, buf, 325 (count < FILE_XFR_SIZE 326 ? count : FILE_XFR_SIZE)); 327 else 328 result = (int) (*cb->read) (cb, fd, buf, 329 (count < FILE_XFR_SIZE 330 ? count : FILE_XFR_SIZE)); 331 if (result == -1) 332 goto ErrorFinish; 333 if (result == 0) /* EOF */ 334 break; 335 bytes_written = (*sc->write_mem) (cb, sc, addr, buf, result); 336 if (bytes_written != result) 337 { 338 result = -1; 339 errcode = EINVAL; 340 goto FinishSyscall; 341 } 342 bytes_read += result; 343 count -= result; 344 addr += result; 345 /* If this is a short read, don't go back for more */ 346 if (result != FILE_XFR_SIZE) 347 break; 348 } 349 result = bytes_read; 350 } 351 break; 352 353 case CB_SYS_write : 354 { 355 /* ??? Perfect handling of error conditions may require only one 356 call to cb->write. One can't assume all the data is 357 contiguously stored in host memory so that would require 358 malloc'ing/free'ing the space. Maybe later. */ 359 char buf[FILE_XFR_SIZE]; 360 int fd = sc->arg1; 361 TADDR addr = sc->arg2; 362 size_t count = sc->arg3; 363 int bytes_read; 364 size_t bytes_written = 0; 365 366 while (count > 0) 367 { 368 int bytes_to_read = count < FILE_XFR_SIZE ? count : FILE_XFR_SIZE; 369 bytes_read = (*sc->read_mem) (cb, sc, addr, buf, bytes_to_read); 370 if (bytes_read != bytes_to_read) 371 { 372 result = -1; 373 errcode = EINVAL; 374 goto FinishSyscall; 375 } 376 if (cb_is_stdout (cb, fd)) 377 { 378 result = (int) (*cb->write_stdout) (cb, buf, bytes_read); 379 (*cb->flush_stdout) (cb); 380 } 381 else if (cb_is_stderr (cb, fd)) 382 { 383 result = (int) (*cb->write_stderr) (cb, buf, bytes_read); 384 (*cb->flush_stderr) (cb); 385 } 386 else 387 result = (int) (*cb->write) (cb, fd, buf, bytes_read); 388 if (result == -1) 389 goto ErrorFinish; 390 bytes_written += result; 391 count -= result; 392 addr += result; 393 } 394 result = bytes_written; 395 } 396 break; 397 398 case CB_SYS_lseek : 399 { 400 int fd = sc->arg1; 401 unsigned long offset = sc->arg2; 402 int whence = sc->arg3; 403 404 result = (*cb->lseek) (cb, fd, offset, whence); 405 if (result < 0) 406 goto ErrorFinish; 407 } 408 break; 409 410 case CB_SYS_unlink : 411 { 412 char *path; 413 414 errcode = get_path (cb, sc, sc->arg1, &path); 415 if (errcode != 0) 416 { 417 result = -1; 418 goto FinishSyscall; 419 } 420 result = (*cb->unlink) (cb, path); 421 free (path); 422 if (result < 0) 423 goto ErrorFinish; 424 } 425 break; 426 427 case CB_SYS_truncate : 428 { 429 char *path; 430 long len = sc->arg2; 431 432 errcode = get_path (cb, sc, sc->arg1, &path); 433 if (errcode != 0) 434 { 435 result = -1; 436 errcode = EFAULT; 437 goto FinishSyscall; 438 } 439 result = (*cb->truncate) (cb, path, len); 440 free (path); 441 if (result < 0) 442 goto ErrorFinish; 443 } 444 break; 445 446 case CB_SYS_ftruncate : 447 { 448 int fd = sc->arg1; 449 long len = sc->arg2; 450 451 result = (*cb->ftruncate) (cb, fd, len); 452 if (result < 0) 453 goto ErrorFinish; 454 } 455 break; 456 457 case CB_SYS_rename : 458 { 459 char *path1, *path2; 460 461 errcode = get_path (cb, sc, sc->arg1, &path1); 462 if (errcode != 0) 463 { 464 result = -1; 465 errcode = EFAULT; 466 goto FinishSyscall; 467 } 468 errcode = get_path (cb, sc, sc->arg2, &path2); 469 if (errcode != 0) 470 { 471 result = -1; 472 errcode = EFAULT; 473 free (path1); 474 goto FinishSyscall; 475 } 476 result = (*cb->rename) (cb, path1, path2); 477 free (path1); 478 free (path2); 479 if (result < 0) 480 goto ErrorFinish; 481 } 482 break; 483 484 case CB_SYS_stat : 485 { 486 char *path,*buf; 487 int buflen; 488 struct stat statbuf; 489 TADDR addr = sc->arg2; 490 491 errcode = get_path (cb, sc, sc->arg1, &path); 492 if (errcode != 0) 493 { 494 result = -1; 495 goto FinishSyscall; 496 } 497 result = (*cb->to_stat) (cb, path, &statbuf); 498 free (path); 499 if (result < 0) 500 goto ErrorFinish; 501 buflen = cb_host_to_target_stat (cb, NULL, NULL); 502 buf = xmalloc (buflen); 503 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen) 504 { 505 /* The translation failed. This is due to an internal 506 host program error, not the target's fault. */ 507 free (buf); 508 errcode = ENOSYS; 509 result = -1; 510 goto FinishSyscall; 511 } 512 if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen) 513 { 514 free (buf); 515 errcode = EINVAL; 516 result = -1; 517 goto FinishSyscall; 518 } 519 free (buf); 520 } 521 break; 522 523 case CB_SYS_fstat : 524 { 525 char *buf; 526 int buflen; 527 struct stat statbuf; 528 TADDR addr = sc->arg2; 529 530 result = (*cb->to_fstat) (cb, sc->arg1, &statbuf); 531 if (result < 0) 532 goto ErrorFinish; 533 buflen = cb_host_to_target_stat (cb, NULL, NULL); 534 buf = xmalloc (buflen); 535 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen) 536 { 537 /* The translation failed. This is due to an internal 538 host program error, not the target's fault. */ 539 free (buf); 540 errcode = ENOSYS; 541 result = -1; 542 goto FinishSyscall; 543 } 544 if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen) 545 { 546 free (buf); 547 errcode = EINVAL; 548 result = -1; 549 goto FinishSyscall; 550 } 551 free (buf); 552 } 553 break; 554 555 case CB_SYS_lstat : 556 { 557 char *path, *buf; 558 int buflen; 559 struct stat statbuf; 560 TADDR addr = sc->arg2; 561 562 errcode = get_path (cb, sc, sc->arg1, &path); 563 if (errcode != 0) 564 { 565 result = -1; 566 goto FinishSyscall; 567 } 568 result = (*cb->to_lstat) (cb, path, &statbuf); 569 free (path); 570 if (result < 0) 571 goto ErrorFinish; 572 573 buflen = cb_host_to_target_stat (cb, NULL, NULL); 574 buf = xmalloc (buflen); 575 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen) 576 { 577 /* The translation failed. This is due to an internal 578 host program error, not the target's fault. 579 Unfortunately, it's hard to test this case, so there's no 580 test-case for this execution path. */ 581 free (buf); 582 errcode = ENOSYS; 583 result = -1; 584 goto FinishSyscall; 585 } 586 587 if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen) 588 { 589 free (buf); 590 errcode = EINVAL; 591 result = -1; 592 goto FinishSyscall; 593 } 594 595 free (buf); 596 } 597 break; 598 599 case CB_SYS_pipe : 600 { 601 int p[2]; 602 char *target_p = xcalloc (1, cb->target_sizeof_int * 2); 603 604 result = (*cb->pipe) (cb, p); 605 if (result != 0) 606 goto ErrorFinish; 607 608 cb_store_target_endian (cb, target_p, cb->target_sizeof_int, p[0]); 609 cb_store_target_endian (cb, target_p + cb->target_sizeof_int, 610 cb->target_sizeof_int, p[1]); 611 if ((*sc->write_mem) (cb, sc, sc->arg1, target_p, 612 cb->target_sizeof_int * 2) 613 != cb->target_sizeof_int * 2) 614 { 615 /* Close the pipe fd:s. */ 616 (*cb->close) (cb, p[0]); 617 (*cb->close) (cb, p[1]); 618 errcode = EFAULT; 619 result = -1; 620 } 621 622 free (target_p); 623 } 624 break; 625 626 case CB_SYS_getpid: 627 /* POSIX says getpid always succeeds. */ 628 result = (*cb->getpid) (cb); 629 break; 630 631 case CB_SYS_kill: 632 /* If killing self, leave it to the caller to process so it can send the 633 signal to the engine. */ 634 if (sc->arg1 == (*cb->getpid) (cb)) 635 { 636 result = -1; 637 errcode = ENOSYS; 638 } 639 else 640 { 641 int signum = cb_target_to_host_signal (cb, sc->arg2); 642 643 result = (*cb->kill) (cb, sc->arg1, signum); 644 cb->last_errno = errno; 645 goto ErrorFinish; 646 } 647 break; 648 649 case CB_SYS_time : 650 { 651 /* FIXME: May wish to change CB_SYS_time to something else. 652 We might also want gettimeofday or times, but if system calls 653 can be built on others, we can keep the number we have to support 654 here down. */ 655 time_t t = (*cb->time) (cb); 656 result = t; 657 /* It is up to target code to process the argument to time(). */ 658 } 659 break; 660 661 case CB_SYS_chdir : 662 case CB_SYS_chmod : 663 case CB_SYS_utime : 664 /* fall through for now */ 665 666 default : 667 result = -1; 668 errcode = ENOSYS; 669 break; 670 } 671 672 FinishSyscall: 673 sc->result = result; 674 if (errcode == 0) 675 sc->errcode = 0; 676 else 677 sc->errcode = cb_host_to_target_errno (cb, errcode); 678 return CB_RC_OK; 679 680 ErrorFinish: 681 sc->result = result; 682 sc->errcode = (*cb->get_errno) (cb); 683 return CB_RC_OK; 684 } 685