Deleted Added
sdiff udiff text old ( 11906:4b99c1bb3b72 ) new ( 11907:48a3d32da9d8 )
full compact
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 ---