1 /* Remote target callback routines. 2 Copyright 1995-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 file provides a standard way for targets to talk to the host OS 21 level. */ 22 23 /* This must come before any other includes. */ 24 #include "defs.h" 25 26 #include <errno.h> 27 #include <fcntl.h> 28 /* For PIPE_BUF. */ 29 #include <limits.h> 30 #include <signal.h> 31 #include <stdarg.h> 32 #include <stdint.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <time.h> 37 #ifdef HAVE_UNISTD_H 38 #include <unistd.h> 39 #endif 40 #include <sys/stat.h> 41 #include <sys/types.h> 42 43 #include "ansidecl.h" 44 /* For xmalloc. */ 45 #include "libiberty.h" 46 47 #include "sim/callback.h" 48 49 #ifndef PIPE_BUF 50 #define PIPE_BUF 512 51 #endif 52 53 extern CB_TARGET_DEFS_MAP cb_init_syscall_map[]; 54 extern CB_TARGET_DEFS_MAP cb_init_errno_map[]; 55 extern CB_TARGET_DEFS_MAP cb_init_signal_map[]; 56 extern CB_TARGET_DEFS_MAP cb_init_open_map[]; 57 58 /* Make sure the FD provided is ok. If not, return non-zero 59 and set errno. */ 60 61 static int 62 fdbad (host_callback *p, int fd) 63 { 64 if (fd < 0 || fd > MAX_CALLBACK_FDS || p->fd_buddy[fd] < 0) 65 { 66 p->last_errno = EBADF; 67 return -1; 68 } 69 return 0; 70 } 71 72 static int 73 fdmap (host_callback *p, int fd) 74 { 75 return p->fdmap[fd]; 76 } 77 78 static int 79 os_close (host_callback *p, int fd) 80 { 81 int result; 82 int i, next; 83 84 result = fdbad (p, fd); 85 if (result) 86 return result; 87 /* If this file descripter has one or more buddies (originals / 88 duplicates from a dup), just remove it from the circular list. */ 89 for (i = fd; (next = p->fd_buddy[i]) != fd; ) 90 i = next; 91 if (fd != i) 92 p->fd_buddy[i] = p->fd_buddy[fd]; 93 else 94 { 95 if (p->ispipe[fd]) 96 { 97 int other = p->ispipe[fd]; 98 int reader, writer; 99 100 if (other > 0) 101 { 102 /* Closing the read side. */ 103 reader = fd; 104 writer = other; 105 } 106 else 107 { 108 /* Closing the write side. */ 109 writer = fd; 110 reader = -other; 111 } 112 113 /* If there was data in the buffer, make a last "now empty" 114 call, then deallocate data. */ 115 if (p->pipe_buffer[writer].buffer != NULL) 116 { 117 (*p->pipe_empty) (p, reader, writer); 118 free (p->pipe_buffer[writer].buffer); 119 p->pipe_buffer[writer].buffer = NULL; 120 } 121 122 /* Clear pipe data for this side. */ 123 p->pipe_buffer[fd].size = 0; 124 p->ispipe[fd] = 0; 125 126 /* If this was the first close, mark the other side as the 127 only remaining side. */ 128 if (fd != abs (other)) 129 p->ispipe[abs (other)] = -other; 130 p->fd_buddy[fd] = -1; 131 return 0; 132 } 133 134 result = close (fdmap (p, fd)); 135 p->last_errno = errno; 136 } 137 p->fd_buddy[fd] = -1; 138 139 return result; 140 } 141 142 143 /* taken from gdb/util.c:notice_quit() - should be in a library */ 144 145 146 #if defined(_MSC_VER) 147 static int 148 os_poll_quit (host_callback *p) 149 { 150 /* NB - this will not compile! */ 151 int k = win32pollquit (); 152 if (k == 1) 153 return 1; 154 else if (k == 2) 155 return 1; 156 return 0; 157 } 158 #else 159 #define os_poll_quit 0 160 #endif /* defined(_MSC_VER) */ 161 162 static int 163 os_get_errno (host_callback *p) 164 { 165 return cb_host_to_target_errno (p, p->last_errno); 166 } 167 168 169 static int 170 os_isatty (host_callback *p, int fd) 171 { 172 int result; 173 174 result = fdbad (p, fd); 175 if (result) 176 return result; 177 178 result = isatty (fdmap (p, fd)); 179 p->last_errno = errno; 180 return result; 181 } 182 183 static int64_t 184 os_lseek (host_callback *p, int fd, int64_t off, int way) 185 { 186 int64_t result; 187 188 result = fdbad (p, fd); 189 if (result) 190 return result; 191 192 result = lseek (fdmap (p, fd), off, way); 193 p->last_errno = errno; 194 return result; 195 } 196 197 static int 198 os_open (host_callback *p, const char *name, int flags) 199 { 200 int i; 201 for (i = 0; i < MAX_CALLBACK_FDS; i++) 202 { 203 if (p->fd_buddy[i] < 0) 204 { 205 int f = open (name, cb_target_to_host_open (p, flags), 0644); 206 if (f < 0) 207 { 208 p->last_errno = errno; 209 return f; 210 } 211 p->fd_buddy[i] = i; 212 p->fdmap[i] = f; 213 return i; 214 } 215 } 216 p->last_errno = EMFILE; 217 return -1; 218 } 219 220 static int 221 os_read (host_callback *p, int fd, char *buf, int len) 222 { 223 int result; 224 225 result = fdbad (p, fd); 226 if (result) 227 return result; 228 if (p->ispipe[fd]) 229 { 230 int writer = p->ispipe[fd]; 231 232 /* Can't read from the write-end. */ 233 if (writer < 0) 234 { 235 p->last_errno = EBADF; 236 return -1; 237 } 238 239 /* Nothing to read if nothing is written. */ 240 if (p->pipe_buffer[writer].size == 0) 241 return 0; 242 243 /* Truncate read request size to buffer size minus what's already 244 read. */ 245 if (len > p->pipe_buffer[writer].size - p->pipe_buffer[fd].size) 246 len = p->pipe_buffer[writer].size - p->pipe_buffer[fd].size; 247 248 memcpy (buf, p->pipe_buffer[writer].buffer + p->pipe_buffer[fd].size, 249 len); 250 251 /* Account for what we just read. */ 252 p->pipe_buffer[fd].size += len; 253 254 /* If we've read everything, empty and deallocate the buffer and 255 signal buffer-empty to client. (This isn't expected to be a 256 hot path in the simulator, so we don't hold on to the buffer.) */ 257 if (p->pipe_buffer[fd].size == p->pipe_buffer[writer].size) 258 { 259 free (p->pipe_buffer[writer].buffer); 260 p->pipe_buffer[writer].buffer = NULL; 261 p->pipe_buffer[fd].size = 0; 262 p->pipe_buffer[writer].size = 0; 263 (*p->pipe_empty) (p, fd, writer); 264 } 265 266 return len; 267 } 268 269 result = read (fdmap (p, fd), buf, len); 270 p->last_errno = errno; 271 return result; 272 } 273 274 static int 275 os_read_stdin (host_callback *p, char *buf, int len) 276 { 277 int result; 278 279 result = read (0, buf, len); 280 p->last_errno = errno; 281 return result; 282 } 283 284 static int 285 os_write (host_callback *p, int fd, const char *buf, int len) 286 { 287 int result; 288 int real_fd; 289 290 result = fdbad (p, fd); 291 if (result) 292 return result; 293 294 if (p->ispipe[fd]) 295 { 296 int reader = -p->ispipe[fd]; 297 298 /* Can't write to the read-end. */ 299 if (reader < 0) 300 { 301 p->last_errno = EBADF; 302 return -1; 303 } 304 305 /* Can't write to pipe with closed read end. 306 FIXME: We should send a SIGPIPE. */ 307 if (reader == fd) 308 { 309 p->last_errno = EPIPE; 310 return -1; 311 } 312 313 /* As a sanity-check, we bail out it the buffered contents is much 314 larger than the size of the buffer on the host. We don't want 315 to run out of memory in the simulator due to a target program 316 bug if we can help it. Unfortunately, regarding the value that 317 reaches the simulated program, it's no use returning *less* 318 than the requested amount, because cb_syscall loops calling 319 this function until the whole amount is done. */ 320 if (p->pipe_buffer[fd].size + len > 10 * PIPE_BUF) 321 { 322 p->last_errno = EFBIG; 323 return -1; 324 } 325 326 p->pipe_buffer[fd].buffer 327 = xrealloc (p->pipe_buffer[fd].buffer, p->pipe_buffer[fd].size + len); 328 memcpy (p->pipe_buffer[fd].buffer + p->pipe_buffer[fd].size, 329 buf, len); 330 p->pipe_buffer[fd].size += len; 331 332 (*p->pipe_nonempty) (p, reader, fd); 333 return len; 334 } 335 336 real_fd = fdmap (p, fd); 337 switch (real_fd) 338 { 339 default: 340 result = write (real_fd, buf, len); 341 p->last_errno = errno; 342 break; 343 case 1: 344 result = p->write_stdout (p, buf, len); 345 break; 346 case 2: 347 result = p->write_stderr (p, buf, len); 348 break; 349 } 350 return result; 351 } 352 353 static int 354 os_write_stdout (host_callback *p ATTRIBUTE_UNUSED, const char *buf, int len) 355 { 356 return fwrite (buf, 1, len, stdout); 357 } 358 359 static void 360 os_flush_stdout (host_callback *p ATTRIBUTE_UNUSED) 361 { 362 fflush (stdout); 363 } 364 365 static int 366 os_write_stderr (host_callback *p ATTRIBUTE_UNUSED, const char *buf, int len) 367 { 368 return fwrite (buf, 1, len, stderr); 369 } 370 371 static void 372 os_flush_stderr (host_callback *p ATTRIBUTE_UNUSED) 373 { 374 fflush (stderr); 375 } 376 377 static int 378 os_rename (host_callback *p, const char *f1, const char *f2) 379 { 380 int result; 381 382 result = rename (f1, f2); 383 p->last_errno = errno; 384 return result; 385 } 386 387 388 static int 389 os_system (host_callback *p, const char *s) 390 { 391 int result; 392 393 result = system (s); 394 p->last_errno = errno; 395 return result; 396 } 397 398 static int64_t 399 os_time (host_callback *p) 400 { 401 int64_t result; 402 403 result = time (NULL); 404 p->last_errno = errno; 405 return result; 406 } 407 408 409 static int 410 os_unlink (host_callback *p, const char *f1) 411 { 412 int result; 413 414 result = unlink (f1); 415 p->last_errno = errno; 416 return result; 417 } 418 419 static int 420 os_stat (host_callback *p, const char *file, struct stat *buf) 421 { 422 int result; 423 424 /* ??? There is an issue of when to translate to the target layout. 425 One could do that inside this function, or one could have the 426 caller do it. It's more flexible to let the caller do it, though 427 I'm not sure the flexibility will ever be useful. */ 428 result = stat (file, buf); 429 p->last_errno = errno; 430 return result; 431 } 432 433 static int 434 os_fstat (host_callback *p, int fd, struct stat *buf) 435 { 436 int result; 437 438 if (fdbad (p, fd)) 439 return -1; 440 441 if (p->ispipe[fd]) 442 { 443 #if defined (HAVE_STRUCT_STAT_ST_ATIME) || defined (HAVE_STRUCT_STAT_ST_CTIME) || defined (HAVE_STRUCT_STAT_ST_MTIME) 444 time_t t = (*p->time) (p); 445 #endif 446 447 /* We have to fake the struct stat contents, since the pipe is 448 made up in the simulator. */ 449 memset (buf, 0, sizeof (*buf)); 450 451 #ifdef HAVE_STRUCT_STAT_ST_MODE 452 buf->st_mode = S_IFIFO; 453 #endif 454 455 /* If more accurate tracking than current-time is needed (for 456 example, on GNU/Linux we get accurate numbers), the p->time 457 callback (which may be something other than os_time) should 458 happen for each read and write, and we'd need to keep track of 459 atime, ctime and mtime. */ 460 #ifdef HAVE_STRUCT_STAT_ST_ATIME 461 buf->st_atime = t; 462 #endif 463 #ifdef HAVE_STRUCT_STAT_ST_CTIME 464 buf->st_ctime = t; 465 #endif 466 #ifdef HAVE_STRUCT_STAT_ST_MTIME 467 buf->st_mtime = t; 468 #endif 469 return 0; 470 } 471 472 /* ??? There is an issue of when to translate to the target layout. 473 One could do that inside this function, or one could have the 474 caller do it. It's more flexible to let the caller do it, though 475 I'm not sure the flexibility will ever be useful. */ 476 result = fstat (fdmap (p, fd), buf); 477 p->last_errno = errno; 478 return result; 479 } 480 481 static int 482 os_lstat (host_callback *p, const char *file, struct stat *buf) 483 { 484 int result; 485 486 /* NOTE: hpn/2004-12-12: Same issue here as with os_fstat. */ 487 #ifdef HAVE_LSTAT 488 result = lstat (file, buf); 489 #else 490 result = stat (file, buf); 491 #endif 492 p->last_errno = errno; 493 return result; 494 } 495 496 static int 497 os_ftruncate (host_callback *p, int fd, int64_t len) 498 { 499 int result; 500 501 result = fdbad (p, fd); 502 if (p->ispipe[fd]) 503 { 504 p->last_errno = EINVAL; 505 return -1; 506 } 507 if (result) 508 return result; 509 #ifdef HAVE_FTRUNCATE 510 result = ftruncate (fdmap (p, fd), len); 511 p->last_errno = errno; 512 #else 513 p->last_errno = EINVAL; 514 result = -1; 515 #endif 516 return result; 517 } 518 519 static int 520 os_truncate (host_callback *p, const char *file, int64_t len) 521 { 522 #ifdef HAVE_TRUNCATE 523 int result; 524 525 result = truncate (file, len); 526 p->last_errno = errno; 527 return result; 528 #else 529 p->last_errno = EINVAL; 530 return -1; 531 #endif 532 } 533 534 static int 535 os_getpid (host_callback *p) 536 { 537 int result; 538 539 result = getpid (); 540 /* POSIX says getpid always succeeds. */ 541 p->last_errno = 0; 542 return result; 543 } 544 545 static int 546 os_kill (host_callback *p, int pid, int signum) 547 { 548 #ifdef HAVE_KILL 549 int result; 550 551 result = kill (pid, signum); 552 p->last_errno = errno; 553 return result; 554 #else 555 p->last_errno = ENOSYS; 556 return -1; 557 #endif 558 } 559 560 static int 561 os_pipe (host_callback *p, int *filedes) 562 { 563 int i; 564 565 /* We deliberately don't use fd 0. It's probably stdin anyway. */ 566 for (i = 1; i < MAX_CALLBACK_FDS; i++) 567 { 568 int j; 569 570 if (p->fd_buddy[i] < 0) 571 for (j = i + 1; j < MAX_CALLBACK_FDS; j++) 572 if (p->fd_buddy[j] < 0) 573 { 574 /* Found two free fd:s. Set stat to allocated and mark 575 pipeness. */ 576 p->fd_buddy[i] = i; 577 p->fd_buddy[j] = j; 578 p->ispipe[i] = j; 579 p->ispipe[j] = -i; 580 filedes[0] = i; 581 filedes[1] = j; 582 583 /* Poison the FD map to make bugs apparent. */ 584 p->fdmap[i] = -1; 585 p->fdmap[j] = -1; 586 return 0; 587 } 588 } 589 590 p->last_errno = EMFILE; 591 return -1; 592 } 593 594 /* Stub functions for pipe support. They should always be overridden in 595 targets using the pipe support, but that's up to the target. */ 596 597 /* Called when the simulator says that the pipe at (reader, writer) is 598 now empty (so the writer should leave its waiting state). */ 599 600 static void 601 os_pipe_empty (host_callback *p, int reader, int writer) 602 { 603 } 604 605 /* Called when the simulator says the pipe at (reader, writer) is now 606 non-empty (so the writer should wait). */ 607 608 static void 609 os_pipe_nonempty (host_callback *p, int reader, int writer) 610 { 611 } 612 613 static int 614 os_shutdown (host_callback *p) 615 { 616 int i, next, j; 617 for (i = 0; i < MAX_CALLBACK_FDS; i++) 618 { 619 int do_close = 1; 620 621 /* Zero out all pipe state. Don't call callbacks for non-empty 622 pipes; the target program has likely terminated at this point 623 or we're called at initialization time. */ 624 p->ispipe[i] = 0; 625 p->pipe_buffer[i].size = 0; 626 p->pipe_buffer[i].buffer = NULL; 627 628 next = p->fd_buddy[i]; 629 if (next < 0) 630 continue; 631 do 632 { 633 j = next; 634 if (j == MAX_CALLBACK_FDS) 635 do_close = 0; 636 next = p->fd_buddy[j]; 637 p->fd_buddy[j] = -1; 638 /* At the initial call of os_init, we got -1, 0, 0, 0, ... */ 639 if (next < 0) 640 { 641 p->fd_buddy[i] = -1; 642 do_close = 0; 643 break; 644 } 645 } 646 while (j != i); 647 if (do_close) 648 close (p->fdmap[i]); 649 } 650 return 1; 651 } 652 653 static int 654 os_init (host_callback *p) 655 { 656 int i; 657 658 os_shutdown (p); 659 for (i = 0; i < 3; i++) 660 { 661 p->fdmap[i] = i; 662 p->fd_buddy[i] = i - 1; 663 } 664 p->fd_buddy[0] = MAX_CALLBACK_FDS; 665 p->fd_buddy[MAX_CALLBACK_FDS] = 2; 666 667 p->syscall_map = cb_init_syscall_map; 668 p->errno_map = cb_init_errno_map; 669 p->signal_map = cb_init_signal_map; 670 p->open_map = cb_init_open_map; 671 672 return 1; 673 } 674 675 /* DEPRECATED */ 676 677 /* VARARGS */ 678 static void ATTRIBUTE_PRINTF (2, 3) 679 os_printf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...) 680 { 681 va_list args; 682 va_start (args, format); 683 684 vfprintf (stdout, format, args); 685 va_end (args); 686 } 687 688 /* VARARGS */ 689 static void ATTRIBUTE_PRINTF (2, 0) 690 os_vprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args) 691 { 692 vprintf (format, args); 693 } 694 695 /* VARARGS */ 696 static void ATTRIBUTE_PRINTF (2, 0) 697 os_evprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args) 698 { 699 vfprintf (stderr, format, args); 700 } 701 702 /* VARARGS */ 703 static void ATTRIBUTE_PRINTF (2, 3) ATTRIBUTE_NORETURN 704 os_error (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...) 705 { 706 va_list args; 707 va_start (args, format); 708 709 vfprintf (stderr, format, args); 710 fprintf (stderr, "\n"); 711 712 va_end (args); 713 exit (1); 714 } 715 716 host_callback default_callback = 717 { 718 os_close, 719 os_get_errno, 720 os_isatty, 721 os_lseek, 722 os_open, 723 os_read, 724 os_read_stdin, 725 os_rename, 726 os_system, 727 os_time, 728 os_unlink, 729 os_write, 730 os_write_stdout, 731 os_flush_stdout, 732 os_write_stderr, 733 os_flush_stderr, 734 735 os_stat, 736 os_fstat, 737 os_lstat, 738 739 os_ftruncate, 740 os_truncate, 741 742 os_getpid, 743 os_kill, 744 745 os_pipe, 746 os_pipe_empty, 747 os_pipe_nonempty, 748 749 os_poll_quit, 750 751 os_shutdown, 752 os_init, 753 754 os_printf_filtered, /* deprecated */ 755 756 os_vprintf_filtered, 757 os_evprintf_filtered, 758 os_error, 759 760 0, /* last errno */ 761 762 { 0, }, /* fdmap */ 763 { -1, }, /* fd_buddy */ 764 { 0, }, /* ispipe */ 765 { { 0, 0 }, }, /* pipe_buffer */ 766 767 0, /* syscall_map */ 768 0, /* errno_map */ 769 0, /* open_map */ 770 0, /* signal_map */ 771 0, /* stat_map */ 772 773 /* Defaults expected to be overridden at initialization, where needed. */ 774 BFD_ENDIAN_UNKNOWN, /* target_endian */ 775 NULL, /* argv */ 776 NULL, /* envp */ 777 4, /* target_sizeof_int */ 778 779 HOST_CALLBACK_MAGIC, 780 }; 781 782 /* Read in a file describing the target's system call values. 783 E.g. maybe someone will want to use something other than newlib. 784 This assumes that the basic system call recognition and value passing/ 785 returning is supported. So maybe some coding/recompilation will be 786 necessary, but not as much. 787 788 If an error occurs, the existing mapping is not changed. */ 789 790 CB_RC 791 cb_read_target_syscall_maps (host_callback *cb, const char *file) 792 { 793 CB_TARGET_DEFS_MAP *syscall_map, *errno_map, *open_map, *signal_map; 794 const char *stat_map; 795 FILE *f; 796 797 if ((f = fopen (file, "r")) == NULL) 798 return CB_RC_ACCESS; 799 800 /* ... read in and parse file ... */ 801 802 fclose (f); 803 return CB_RC_NO_MEM; /* FIXME:wip */ 804 805 /* Free storage allocated for any existing maps. */ 806 if (cb->syscall_map) 807 free (cb->syscall_map); 808 if (cb->errno_map) 809 free (cb->errno_map); 810 if (cb->open_map) 811 free (cb->open_map); 812 if (cb->signal_map) 813 free (cb->signal_map); 814 if (cb->stat_map) 815 free ((void *) cb->stat_map); 816 817 cb->syscall_map = syscall_map; 818 cb->errno_map = errno_map; 819 cb->open_map = open_map; 820 cb->signal_map = signal_map; 821 cb->stat_map = stat_map; 822 823 return CB_RC_OK; 824 } 825 826 /* General utility functions to search a map for a value. */ 827 828 static const CB_TARGET_DEFS_MAP * 829 cb_target_map_entry (const CB_TARGET_DEFS_MAP map[], int target_val) 830 { 831 const CB_TARGET_DEFS_MAP *m; 832 833 for (m = &map[0]; m->target_val != -1; ++m) 834 if (m->target_val == target_val) 835 return m; 836 837 return NULL; 838 } 839 840 static const CB_TARGET_DEFS_MAP * 841 cb_host_map_entry (const CB_TARGET_DEFS_MAP map[], int host_val) 842 { 843 const CB_TARGET_DEFS_MAP *m; 844 845 for (m = &map[0]; m->host_val != -1; ++m) 846 if (m->host_val == host_val) 847 return m; 848 849 return NULL; 850 } 851 852 /* Translate the target's version of a syscall number to the host's. 853 This isn't actually the host's version, rather a canonical form. 854 ??? Perhaps this should be renamed to ..._canon_syscall. */ 855 856 int 857 cb_target_to_host_syscall (host_callback *cb, int target_val) 858 { 859 const CB_TARGET_DEFS_MAP *m = 860 cb_target_map_entry (cb->syscall_map, target_val); 861 862 return m ? m->host_val : -1; 863 } 864 865 /* FIXME: sort tables if large. 866 Alternatively, an obvious improvement for errno conversion is 867 to machine generate a function with a large switch(). */ 868 869 /* Translate the host's version of errno to the target's. */ 870 871 int 872 cb_host_to_target_errno (host_callback *cb, int host_val) 873 { 874 const CB_TARGET_DEFS_MAP *m = cb_host_map_entry (cb->errno_map, host_val); 875 876 /* ??? Which error to return in this case is up for grabs. 877 Note that some missing values may have standard alternatives. 878 For now return 0 and require caller to deal with it. */ 879 return m ? m->target_val : 0; 880 } 881 882 /* Given a set of target bitmasks for the open system call, 883 return the host equivalent. 884 Mapping open flag values is best done by looping so there's no need 885 to machine generate this function. */ 886 887 int 888 cb_target_to_host_open (host_callback *cb, int target_val) 889 { 890 int host_val = 0; 891 CB_TARGET_DEFS_MAP *m; 892 int o_rdonly = 0; 893 int o_wronly = 0; 894 int o_rdwr = 0; 895 int o_binary = 0; 896 int o_rdwrmask; 897 898 /* O_RDONLY can be (and usually is) 0 which needs to be treated specially. */ 899 for (m = &cb->open_map[0]; m->host_val != -1; ++m) 900 { 901 if (!strcmp (m->name, "O_RDONLY")) 902 o_rdonly = m->target_val; 903 else if (!strcmp (m->name, "O_WRONLY")) 904 o_wronly = m->target_val; 905 else if (!strcmp (m->name, "O_RDWR")) 906 o_rdwr = m->target_val; 907 else if (!strcmp (m->name, "O_BINARY")) 908 o_binary = m->target_val; 909 } 910 o_rdwrmask = o_rdonly | o_wronly | o_rdwr; 911 912 for (m = &cb->open_map[0]; m->host_val != -1; ++m) 913 { 914 if (m->target_val == o_rdonly || m->target_val == o_wronly 915 || m->target_val == o_rdwr) 916 { 917 if ((target_val & o_rdwrmask) == m->target_val) 918 host_val |= m->host_val; 919 /* Handle the host/target differentiating between binary and 920 text mode. Only one case is of importance */ 921 #ifdef O_BINARY 922 if (o_binary == 0) 923 host_val |= O_BINARY; 924 #endif 925 } 926 else 927 { 928 if ((m->target_val & target_val) == m->target_val) 929 host_val |= m->host_val; 930 } 931 } 932 933 return host_val; 934 } 935 936 /* Translate the target's version of a signal number to the host's. 937 This isn't actually the host's version, rather a canonical form. 938 ??? Perhaps this should be renamed to ..._canon_signal. */ 939 940 int 941 cb_target_to_host_signal (host_callback *cb, int target_val) 942 { 943 const CB_TARGET_DEFS_MAP *m = 944 cb_target_map_entry (cb->signal_map, target_val); 945 946 return m ? m->host_val : -1; 947 } 948 949 /* Utility for e.g. cb_host_to_target_stat to store values in the target's 950 stat struct. 951 952 ??? The "val" must be as big as target word size. */ 953 954 void 955 cb_store_target_endian (host_callback *cb, char *p, int size, long val) 956 { 957 if (cb->target_endian == BFD_ENDIAN_BIG) 958 { 959 p += size; 960 while (size-- > 0) 961 { 962 *--p = val; 963 val >>= 8; 964 } 965 } 966 else 967 { 968 while (size-- > 0) 969 { 970 *p++ = val; 971 val >>= 8; 972 } 973 } 974 } 975 976 /* Translate a host's stat struct into a target's. 977 If HS is NULL, just compute the length of the buffer required, 978 TS is ignored. 979 980 The result is the size of the target's stat struct, 981 or zero if an error occurred during the translation. */ 982 983 int 984 cb_host_to_target_stat (host_callback *cb, const struct stat *hs, void *ts) 985 { 986 const char *m = cb->stat_map; 987 char *p; 988 989 if (hs == NULL) 990 ts = NULL; 991 p = ts; 992 993 while (m) 994 { 995 char *q = strchr (m, ','); 996 int size; 997 998 /* FIXME: Use sscanf? */ 999 if (q == NULL) 1000 { 1001 /* FIXME: print error message */ 1002 return 0; 1003 } 1004 size = atoi (q + 1); 1005 if (size == 0) 1006 { 1007 /* FIXME: print error message */ 1008 return 0; 1009 } 1010 1011 if (hs != NULL) 1012 { 1013 if (0) 1014 ; 1015 /* Defined here to avoid emacs indigestion on a lone "else". */ 1016 #undef ST_x 1017 #define ST_x(FLD) \ 1018 else if (strncmp (m, #FLD, q - m) == 0) \ 1019 cb_store_target_endian (cb, p, size, hs->FLD) 1020 1021 #ifdef HAVE_STRUCT_STAT_ST_DEV 1022 ST_x (st_dev); 1023 #endif 1024 #ifdef HAVE_STRUCT_STAT_ST_INO 1025 ST_x (st_ino); 1026 #endif 1027 #ifdef HAVE_STRUCT_STAT_ST_MODE 1028 ST_x (st_mode); 1029 #endif 1030 #ifdef HAVE_STRUCT_STAT_ST_NLINK 1031 ST_x (st_nlink); 1032 #endif 1033 #ifdef HAVE_STRUCT_STAT_ST_UID 1034 ST_x (st_uid); 1035 #endif 1036 #ifdef HAVE_STRUCT_STAT_ST_GID 1037 ST_x (st_gid); 1038 #endif 1039 #ifdef HAVE_STRUCT_STAT_ST_RDEV 1040 ST_x (st_rdev); 1041 #endif 1042 #ifdef HAVE_STRUCT_STAT_ST_SIZE 1043 ST_x (st_size); 1044 #endif 1045 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE 1046 ST_x (st_blksize); 1047 #endif 1048 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS 1049 ST_x (st_blocks); 1050 #endif 1051 #ifdef HAVE_STRUCT_STAT_ST_ATIME 1052 ST_x (st_atime); 1053 #endif 1054 #ifdef HAVE_STRUCT_STAT_ST_MTIME 1055 ST_x (st_mtime); 1056 #endif 1057 #ifdef HAVE_STRUCT_STAT_ST_CTIME 1058 ST_x (st_ctime); 1059 #endif 1060 #undef ST_x 1061 /* FIXME:wip */ 1062 else 1063 /* Unsupported field, store 0. */ 1064 cb_store_target_endian (cb, p, size, 0); 1065 } 1066 1067 p += size; 1068 m = strchr (q, ':'); 1069 if (m) 1070 ++m; 1071 } 1072 1073 return p - (char *) ts; 1074 } 1075 1076 int 1077 cb_is_stdin (host_callback *cb, int fd) 1078 { 1079 return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 0; 1080 } 1081 1082 int 1083 cb_is_stdout (host_callback *cb, int fd) 1084 { 1085 return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 1; 1086 } 1087 1088 int 1089 cb_is_stderr (host_callback *cb, int fd) 1090 { 1091 return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 2; 1092 } 1093 1094 const char * 1095 cb_host_str_syscall (host_callback *cb, int host_val) 1096 { 1097 const CB_TARGET_DEFS_MAP *m = cb_host_map_entry (cb->syscall_map, host_val); 1098 1099 return m ? m->name : NULL; 1100 } 1101 1102 const char * 1103 cb_host_str_errno (host_callback *cb, int host_val) 1104 { 1105 const CB_TARGET_DEFS_MAP *m = cb_host_map_entry (cb->errno_map, host_val); 1106 1107 return m ? m->name : NULL; 1108 } 1109 1110 const char * 1111 cb_host_str_signal (host_callback *cb, int host_val) 1112 { 1113 const CB_TARGET_DEFS_MAP *m = cb_host_map_entry (cb->signal_map, host_val); 1114 1115 return m ? m->name : NULL; 1116 } 1117 1118 const char * 1119 cb_target_str_syscall (host_callback *cb, int target_val) 1120 { 1121 const CB_TARGET_DEFS_MAP *m = 1122 cb_target_map_entry (cb->syscall_map, target_val); 1123 1124 return m ? m->name : NULL; 1125 } 1126 1127 const char * 1128 cb_target_str_errno (host_callback *cb, int target_val) 1129 { 1130 const CB_TARGET_DEFS_MAP *m = 1131 cb_target_map_entry (cb->errno_map, target_val); 1132 1133 return m ? m->name : NULL; 1134 } 1135 1136 const char * 1137 cb_target_str_signal (host_callback *cb, int target_val) 1138 { 1139 const CB_TARGET_DEFS_MAP *m = 1140 cb_target_map_entry (cb->signal_map, target_val); 1141 1142 return m ? m->name : NULL; 1143 } 1144