diff options
author | Andreas Sandberg <andreas.sandberg@arm.com> | 2018-02-21 12:07:01 +0000 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2018-05-16 17:20:27 +0000 |
commit | 23c6e60409a580e53834f90c1de1438a8ac94e88 (patch) | |
tree | de59605e447fa05621c6a41897cccb032e6c1b0e /src/arch/arm/semihosting.cc | |
parent | abb21ba99f3ae910101fc9f17341a52039c0547b (diff) | |
download | gem5-23c6e60409a580e53834f90c1de1438a8ac94e88.tar.xz |
arch-arm: Add support for semihosting STDIO redirection
The Arm Semihosting layer currently assumes that the guest application
shares STDIO with gem5. This makes it hard to distinguish application
output from gem5's output and makes it impossible to redirect STDIN
when running in interactive mode. Add support for custom STDIO
redirection when instantiating the Semihosting model.
Change-Id: I3411a6b9bfb008ffc3087d8837f59be72bd1e8ae
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Anouk Van Laer <anouk.vanlaer@arm.com>
Reviewed-by: Jack Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/10021
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Diffstat (limited to 'src/arch/arm/semihosting.cc')
-rw-r--r-- | src/arch/arm/semihosting.cc | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/src/arch/arm/semihosting.cc b/src/arch/arm/semihosting.cc index 89e1b2e7d..46d964d63 100644 --- a/src/arch/arm/semihosting.cc +++ b/src/arch/arm/semihosting.cc @@ -121,6 +121,15 @@ const std::vector<uint8_t> ArmSemihosting::features{ 0x3, // EXT_EXIT_EXTENDED, EXT_STDOUT_STDERR }; +const std::map<const std::string, FILE *> ArmSemihosting::stdioMap{ + {"cin", ::stdin}, + {"stdin", ::stdin}, + {"cout", ::stdout}, + {"stdout", ::stdout}, + {"cerr", ::stderr}, + {"stderr", ::stderr}, +}; + ArmSemihosting::ArmSemihosting(const ArmSemihostingParams *p) : SimObject(p), cmdLine(p->cmd_line), @@ -128,7 +137,11 @@ ArmSemihosting::ArmSemihosting(const ArmSemihostingParams *p) stackSize(p->stack_size), timeBase([p]{ struct tm t = p->time; return mkutctime(&t); }()), tickShift(calcTickShift()), - semiErrno(0) + semiErrno(0), + stdin(getSTDIO("stdin", p->stdin, "r")), + stdout(getSTDIO("stdout", p->stdout, "w")), + stderr(p->stderr == p->stdout ? + stdout : getSTDIO("stderr", p->stderr, "w")) { // Create an empty place-holder file for position 0 as semi-hosting // calls typically expect non-zero file handles. @@ -681,6 +694,23 @@ ArmSemihosting::getCall(uint32_t op, bool aarch64) } } +FILE * +ArmSemihosting::getSTDIO(const char *stream_name, + const std::string &name, const char *mode) +{ + auto it = stdioMap.find(name); + if (it == stdioMap.end()) { + FILE *f = fopen(name.c_str(), mode); + if (!f) { + fatal("Failed to open %s (%s): %s\n", + stream_name, name, strerror(errno)); + } + return f; + } else { + return it->second; + } +} + std::unique_ptr<ArmSemihosting::FileBase> ArmSemihosting::FileBase::create( ArmSemihosting &parent, const std::string &fname, const char *mode) @@ -819,11 +849,11 @@ ArmSemihosting::File::openImpl(bool in_cpt) if (_name == ":tt") { if (mode[0] == 'r') { - file = stdin; + file = parent.stdin; } else if (mode[0] == 'w') { - file = stdout; + file = parent.stdout; } else if (mode[0] == 'a') { - file = stderr; + file = parent.stderr; } else { warn("Unknown file mode for the ':tt' special file"); return -EINVAL; @@ -857,7 +887,9 @@ ArmSemihosting::File::close() bool ArmSemihosting::File::isTTY() const { - return file == stdout || file == stderr || file == stdin; + return file == parent.stdout || + file == parent.stderr || + file == parent.stdin; } int64_t |