syscall_emul.hh (11906:4b99c1bb3b72) | syscall_emul.hh (11907:48a3d32da9d8) |
---|---|
1/* 2 * Copyright (c) 2012-2013, 2015 ARM Limited 3 * Copyright (c) 2015 Advanced Micro Devices, Inc. 4 * All rights reserved 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating --- 599 unchanged lines hidden (view full) --- 608 * return something better here, but at least we issue the warning. 609 */ 610 warn("Unsupported ioctl call (return ENOTTY): ioctl(%d, 0x%x, ...) @ \n", 611 tgt_fd, req, tc->pcState()); 612 return -ENOTTY; 613} 614 615template <class OS> | 1/* 2 * Copyright (c) 2012-2013, 2015 ARM Limited 3 * Copyright (c) 2015 Advanced Micro Devices, Inc. 4 * All rights reserved 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating --- 599 unchanged lines hidden (view full) --- 608 * return something better here, but at least we issue the warning. 609 */ 610 warn("Unsupported ioctl call (return ENOTTY): ioctl(%d, 0x%x, ...) @ \n", 611 tgt_fd, req, tc->pcState()); 612 return -ENOTTY; 613} 614 615template <class OS> |
616static SyscallReturn 617openFunc(SyscallDesc *desc, int callnum, Process *process, 618 ThreadContext *tc, int index) | 616SyscallReturn 617openImpl(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc, 618 bool isopenat) |
619{ | 619{ |
620 std::string path; | 620 int index = 0; 621 int tgt_dirfd = -1; |
621 | 622 |
622 if (!tc->getMemProxy().tryReadString(path, 623 process->getSyscallArg(tc, index))) | 623 /** 624 * If using the openat variant, read in the target directory file 625 * descriptor from the simulated process. 626 */ 627 if (isopenat) 628 tgt_dirfd = p->getSyscallArg(tc, index); 629 630 /** 631 * Retrieve the simulated process' memory proxy and then read in the path 632 * string from that memory space into the host's working memory space. 633 */ 634 std::string path; 635 if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index))) |
624 return -EFAULT; 625 | 636 return -EFAULT; 637 |
626 int tgtFlags = process->getSyscallArg(tc, index); 627 int mode = process->getSyscallArg(tc, index); 628 int hostFlags = 0; 629 630 // translate open flags | 638#ifdef __CYGWIN32__ 639 int host_flags = O_BINARY; 640#else 641 int host_flags = 0; 642#endif 643 /** 644 * Translate target flags into host flags. Flags exist which are not 645 * ported between architectures which can cause check failures. 646 */ 647 int tgt_flags = p->getSyscallArg(tc, index); |
631 for (int i = 0; i < OS::NUM_OPEN_FLAGS; i++) { | 648 for (int i = 0; i < OS::NUM_OPEN_FLAGS; i++) { |
632 if (tgtFlags & OS::openFlagTable[i].tgtFlag) { 633 tgtFlags &= ~OS::openFlagTable[i].tgtFlag; 634 hostFlags |= OS::openFlagTable[i].hostFlag; | 649 if (tgt_flags & OS::openFlagTable[i].tgtFlag) { 650 tgt_flags &= ~OS::openFlagTable[i].tgtFlag; 651 host_flags |= OS::openFlagTable[i].hostFlag; |
635 } 636 } | 652 } 653 } |
637 638 // any target flags left? 639 if (tgtFlags != 0) 640 warn("Syscall: open: cannot decode flags 0x%x", tgtFlags); 641 | 654 if (tgt_flags) { 655 warn("open%s: cannot decode flags 0x%x", 656 isopenat ? "at" : "", tgt_flags); 657 } |
642#ifdef __CYGWIN32__ | 658#ifdef __CYGWIN32__ |
643 hostFlags |= O_BINARY; | 659 host_flags |= O_BINARY; |
644#endif 645 | 660#endif 661 |
646 // Adjust path for current working directory 647 path = process->fullPath(path); | 662 int mode = p->getSyscallArg(tc, index); |
648 | 663 |
649 DPRINTF(SyscallVerbose, "opening file %s\n", path.c_str()); | 664 /** 665 * If the simulated process called open or openat with AT_FDCWD specified, 666 * take the current working directory value which was passed into the 667 * process class as a Python parameter and append the current path to 668 * create a full path. 669 * Otherwise, openat with a valid target directory file descriptor has 670 * been called. If the path option, which was passed in as a parameter, 671 * is not absolute, retrieve the directory file descriptor's path and 672 * prepend it to the path passed in as a parameter. 673 * In every case, we should have a full path (which is relevant to the 674 * host) to work with after this block has been passed. 675 */ 676 if (!isopenat || (isopenat && tgt_dirfd == OS::TGT_AT_FDCWD)) { 677 path = p->fullPath(path); 678 } else if (!startswith(path, "/")) { 679 std::shared_ptr<FDEntry> fdep = ((*p->fds)[tgt_dirfd]); 680 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep); 681 if (!ffdp) 682 return -EBADF; 683 path.insert(0, ffdp->getFileName()); 684 } |
650 | 685 |
686 /** 687 * Since this is an emulated environment, we create pseudo file 688 * descriptors for device requests that have been registered with 689 * the process class through Python; this allows us to create a file 690 * descriptor for subsequent ioctl or mmap calls. 691 */ |
|
651 if (startswith(path, "/dev/")) { 652 std::string filename = path.substr(strlen("/dev/")); | 692 if (startswith(path, "/dev/")) { 693 std::string filename = path.substr(strlen("/dev/")); |
653 if (filename == "sysdev0") { 654 // This is a memory-mapped high-resolution timer device on Alpha. 655 // We don't support it, so just punt. 656 warn("Ignoring open(%s, ...)\n", path); 657 return -ENOENT; 658 } 659 660 EmulatedDriver *drv = process->findDriver(filename); | 694 EmulatedDriver *drv = p->findDriver(filename); |
661 if (drv) { | 695 if (drv) { |
662 // the driver's open method will allocate a fd from the 663 // process if necessary. 664 return drv->open(process, tc, mode, hostFlags); | 696 DPRINTF_SYSCALL(Verbose, "open%s: passing call to " 697 "driver open with path[%s]\n", 698 isopenat ? "at" : "", path.c_str()); 699 return drv->open(p, tc, mode, host_flags); |
665 } | 700 } |
701 /** 702 * Fall through here for pass through to host devices, such 703 * as /dev/zero 704 */ 705 } |
|
666 | 706 |
667 // fall through here for pass through to host devices, such as 668 // /dev/zero | 707 /** 708 * Some special paths and files cannot be called on the host and need 709 * to be handled as special cases inside the simulator. 710 * If the full path that was created above does not match any of the 711 * special cases, pass it through to the open call on the host to let 712 * the host open the file on our behalf. 713 * If the host cannot open the file, return the host's error code back 714 * through the system call to the simulated process. 715 */ 716 int sim_fd = -1; 717 std::vector<std::string> special_paths = 718 { "/proc/", "/system/", "/sys/", "/platform/", "/etc/passwd" }; 719 for (auto entry : special_paths) { 720 if (startswith(path, entry)) 721 sim_fd = OS::openSpecialFile(path, p, tc); |
669 } | 722 } |
723 if (sim_fd == -1) { 724 sim_fd = open(path.c_str(), host_flags, mode); 725 } 726 if (sim_fd == -1) { 727 int local = -errno; 728 DPRINTF_SYSCALL(Verbose, "open%s: failed -> path:%s\n", 729 isopenat ? "at" : "", path.c_str()); 730 return local; 731 } |
|
670 | 732 |
671 int fd; 672 int local_errno; 673 if (startswith(path, "/proc/") || startswith(path, "/system/") || 674 startswith(path, "/platform/") || startswith(path, "/sys/")) { 675 // It's a proc/sys entry and requires special handling 676 fd = OS::openSpecialFile(path, process, tc); 677 local_errno = ENOENT; 678 } else { 679 // open the file 680 fd = open(path.c_str(), hostFlags, mode); 681 local_errno = errno; 682 } 683 684 if (fd == -1) 685 return -local_errno; 686 687 std::shared_ptr<FileFDEntry> ffdp = 688 std::make_shared<FileFDEntry>(fd, hostFlags, path.c_str(), false); 689 return process->fds->allocFD(ffdp); | 733 /** 734 * The file was opened successfully and needs to be recorded in the 735 * process' file descriptor array so that it can be retrieved later. 736 * The target file descriptor that is chosen will be the lowest unused 737 * file descriptor. 738 * Return the indirect target file descriptor back to the simulated 739 * process to act as a handle for the opened file. 740 */ 741 auto ffdp = std::make_shared<FileFDEntry>(sim_fd, host_flags, path, 0); 742 int tgt_fd = p->fds->allocFD(ffdp); 743 DPRINTF_SYSCALL(Verbose, "open%s: sim_fd[%d], target_fd[%d] -> path:%s\n", 744 isopenat ? "at" : "", sim_fd, tgt_fd, path.c_str()); 745 return tgt_fd; |
690} 691 692/// Target open() handler. 693template <class OS> 694SyscallReturn 695openFunc(SyscallDesc *desc, int callnum, Process *process, 696 ThreadContext *tc) 697{ | 746} 747 748/// Target open() handler. 749template <class OS> 750SyscallReturn 751openFunc(SyscallDesc *desc, int callnum, Process *process, 752 ThreadContext *tc) 753{ |
698 return openFunc<OS>(desc, callnum, process, tc, 0); | 754 return openImpl<OS>(desc, callnum, process, tc, false); |
699} 700 701/// Target openat() handler. 702template <class OS> 703SyscallReturn 704openatFunc(SyscallDesc *desc, int callnum, Process *process, 705 ThreadContext *tc) 706{ | 755} 756 757/// Target openat() handler. 758template <class OS> 759SyscallReturn 760openatFunc(SyscallDesc *desc, int callnum, Process *process, 761 ThreadContext *tc) 762{ |
707 int index = 0; 708 int dirfd = process->getSyscallArg(tc, index); 709 if (dirfd != OS::TGT_AT_FDCWD) 710 warn("openat: first argument not AT_FDCWD; unlikely to work"); 711 return openFunc<OS>(desc, callnum, process, tc, 1); | 763 return openImpl<OS>(desc, callnum, process, tc, true); |
712} 713 714/// Target unlinkat() handler. 715template <class OS> 716SyscallReturn 717unlinkatFunc(SyscallDesc *desc, int callnum, Process *process, 718 ThreadContext *tc) 719{ --- 1194 unchanged lines hidden --- | 764} 765 766/// Target unlinkat() handler. 767template <class OS> 768SyscallReturn 769unlinkatFunc(SyscallDesc *desc, int callnum, Process *process, 770 ThreadContext *tc) 771{ --- 1194 unchanged lines hidden --- |