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