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> |
616SyscallReturn 617openImpl(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc, 618 bool isopenat) |
619{ |
620 int index = 0; 621 int tgt_dirfd = -1; |
622 |
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))) |
636 return -EFAULT; 637 |
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); |
648 for (int i = 0; i < OS::NUM_OPEN_FLAGS; i++) { |
649 if (tgt_flags & OS::openFlagTable[i].tgtFlag) { 650 tgt_flags &= ~OS::openFlagTable[i].tgtFlag; 651 host_flags |= OS::openFlagTable[i].hostFlag; |
652 } 653 } |
654 if (tgt_flags) { 655 warn("open%s: cannot decode flags 0x%x", 656 isopenat ? "at" : "", tgt_flags); 657 } |
658#ifdef __CYGWIN32__ |
659 host_flags |= O_BINARY; |
660#endif 661 |
662 int mode = p->getSyscallArg(tc, index); |
663 |
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 } |
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 */ |
692 if (startswith(path, "/dev/")) { 693 std::string filename = path.substr(strlen("/dev/")); |
694 EmulatedDriver *drv = p->findDriver(filename); |
695 if (drv) { |
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); |
700 } |
701 /** 702 * Fall through here for pass through to host devices, such 703 * as /dev/zero 704 */ 705 } |
706 |
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); |
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 } |
732 |
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; |
746} 747 748/// Target open() handler. 749template <class OS> 750SyscallReturn 751openFunc(SyscallDesc *desc, int callnum, Process *process, 752 ThreadContext *tc) 753{ |
754 return openImpl<OS>(desc, callnum, process, tc, false); |
755} 756 757/// Target openat() handler. 758template <class OS> 759SyscallReturn 760openatFunc(SyscallDesc *desc, int callnum, Process *process, 761 ThreadContext *tc) 762{ |
763 return openImpl<OS>(desc, callnum, process, tc, true); |
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 --- |