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