diff options
-rw-r--r-- | arch/alpha/alpha_linux_process.cc | 12 | ||||
-rw-r--r-- | arch/alpha/alpha_tru64_process.cc | 9 | ||||
-rw-r--r-- | base/compression/null_compression.hh | 4 | ||||
-rw-r--r-- | base/cprintf_formats.hh | 2 | ||||
-rw-r--r-- | base/kgdb.h | 28 | ||||
-rw-r--r-- | base/range.cc | 83 | ||||
-rw-r--r-- | base/range.hh | 418 | ||||
-rw-r--r-- | base/remote_gdb.cc | 124 | ||||
-rw-r--r-- | base/remote_gdb.hh | 9 | ||||
-rw-r--r-- | base/trace.hh | 9 | ||||
-rw-r--r-- | cpu/simple_cpu/simple_cpu.cc | 14 | ||||
-rw-r--r-- | kern/tru64/tru64_system.cc | 2 | ||||
-rw-r--r-- | sim/serialize.cc | 4 | ||||
-rw-r--r-- | sim/serialize.hh | 6 | ||||
-rw-r--r-- | sim/syscall_emul.cc | 28 | ||||
-rw-r--r-- | sim/syscall_emul.hh | 10 | ||||
-rw-r--r-- | test/Makefile | 2 | ||||
-rw-r--r-- | test/rangetest.cc | 78 |
18 files changed, 521 insertions, 321 deletions
diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index d8a05849d..ae197d1ac 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -139,6 +139,8 @@ class Linux { static const unsigned TIOCGETC = 0x40067412; static const unsigned FIONREAD = 0x4004667f; static const unsigned TIOCISATTY = 0x2000745e; + static const unsigned TIOCGETS = 0x402c7413; + static const unsigned TIOCGETA = 0x40127417; //@} /// Resource enumeration for getrlimit(). @@ -421,7 +423,7 @@ SyscallDesc Linux::syscallDescs[] = { /* 7 */ SyscallDesc("osf_wait4", unimplementedFunc), /* 8 */ SyscallDesc("osf_old_creat", unimplementedFunc), /* 9 */ SyscallDesc("link", unimplementedFunc), - /* 10 */ SyscallDesc("unlink", unimplementedFunc), + /* 10 */ SyscallDesc("unlink", unlinkFunc), /* 11 */ SyscallDesc("osf_execve", unimplementedFunc), /* 12 */ SyscallDesc("chdir", unimplementedFunc), /* 13 */ SyscallDesc("fchdir", unimplementedFunc), @@ -539,7 +541,7 @@ SyscallDesc Linux::syscallDescs[] = { /* 125 */ SyscallDesc("recvfrom", unimplementedFunc), /* 126 */ SyscallDesc("setreuid", unimplementedFunc), /* 127 */ SyscallDesc("setregid", unimplementedFunc), - /* 128 */ SyscallDesc("rename", unimplementedFunc), + /* 128 */ SyscallDesc("rename", renameFunc), /* 129 */ SyscallDesc("truncate", unimplementedFunc), /* 130 */ SyscallDesc("ftruncate", unimplementedFunc), /* 131 */ SyscallDesc("flock", unimplementedFunc), @@ -556,7 +558,7 @@ SyscallDesc Linux::syscallDescs[] = { /* 142 */ SyscallDesc("osf_gethostid", unimplementedFunc), /* 143 */ SyscallDesc("osf_sethostid", unimplementedFunc), /* 144 */ SyscallDesc("getrlimit", getrlimitFunc<Linux>), - /* 145 */ SyscallDesc("setrlimit", unimplementedFunc), + /* 145 */ SyscallDesc("setrlimit", ignoreFunc), /* 146 */ SyscallDesc("osf_old_killpg", unimplementedFunc), /* 147 */ SyscallDesc("setsid", unimplementedFunc), /* 148 */ SyscallDesc("quotactl", unimplementedFunc), @@ -737,7 +739,7 @@ SyscallDesc Linux::syscallDescs[] = { /* 320 */ SyscallDesc("was sys_idle", unimplementedFunc), /* 321 */ SyscallDesc("oldumount", unimplementedFunc), /* 322 */ SyscallDesc("swapon", unimplementedFunc), - /* 323 */ SyscallDesc("times", unimplementedFunc), + /* 323 */ SyscallDesc("times", ignoreFunc), /* 324 */ SyscallDesc("personality", unimplementedFunc), /* 325 */ SyscallDesc("setfsuid", unimplementedFunc), /* 326 */ SyscallDesc("setfsgid", unimplementedFunc), @@ -766,7 +768,7 @@ SyscallDesc Linux::syscallDescs[] = { /* 349 */ SyscallDesc("pread", unimplementedFunc), /* 350 */ SyscallDesc("pwrite", unimplementedFunc), /* 351 */ SyscallDesc("rt_sigreturn", unimplementedFunc), - /* 352 */ SyscallDesc("rt_sigaction", unimplementedFunc), + /* 352 */ SyscallDesc("rt_sigaction", ignoreFunc), /* 353 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), /* 354 */ SyscallDesc("rt_sigpending", unimplementedFunc), /* 355 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index ccf4d4d6c..2366baed8 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -171,6 +171,9 @@ class Tru64 { static const unsigned TIOCGETC = 0x40067412; static const unsigned FIONREAD = 0x4004667f; static const unsigned TIOCISATTY = 0x2000745e; + // TIOCGETS not defined in tru64, so I made up a number + static const unsigned TIOCGETS = 0x40000000; + static const unsigned TIOCGETA = 0x402c7413; //@} /// Resource enumeration for getrlimit(). @@ -1356,7 +1359,7 @@ SyscallDesc Tru64::syscallDescs[] = { /* 7 */ SyscallDesc("wait4", unimplementedFunc), /* 8 */ SyscallDesc("old_creat", unimplementedFunc), /* 9 */ SyscallDesc("link", unimplementedFunc), - /* 10 */ SyscallDesc("unlink", unimplementedFunc), + /* 10 */ SyscallDesc("unlink", unlinkFunc), /* 11 */ SyscallDesc("execv", unimplementedFunc), /* 12 */ SyscallDesc("chdir", unimplementedFunc), /* 13 */ SyscallDesc("fchdir", unimplementedFunc), @@ -1475,7 +1478,7 @@ SyscallDesc Tru64::syscallDescs[] = { /* 125 */ SyscallDesc("old_recvfrom", unimplementedFunc), /* 126 */ SyscallDesc("setreuid", unimplementedFunc), /* 127 */ SyscallDesc("setregid", unimplementedFunc), - /* 128 */ SyscallDesc("rename", unimplementedFunc), + /* 128 */ SyscallDesc("rename", renameFunc), /* 129 */ SyscallDesc("truncate", unimplementedFunc), /* 130 */ SyscallDesc("ftruncate", unimplementedFunc), /* 131 */ SyscallDesc("flock", unimplementedFunc), @@ -1492,7 +1495,7 @@ SyscallDesc Tru64::syscallDescs[] = { /* 142 */ SyscallDesc("gethostid", unimplementedFunc), /* 143 */ SyscallDesc("sethostid", unimplementedFunc), /* 144 */ SyscallDesc("getrlimit", getrlimitFunc<Tru64>), - /* 145 */ SyscallDesc("setrlimit", unimplementedFunc), + /* 145 */ SyscallDesc("setrlimit", ignoreFunc), /* 146 */ SyscallDesc("old_killpg", unimplementedFunc), /* 147 */ SyscallDesc("setsid", unimplementedFunc), /* 148 */ SyscallDesc("quotactl", unimplementedFunc), diff --git a/base/compression/null_compression.hh b/base/compression/null_compression.hh index d2bc76eef..6a630b113 100644 --- a/base/compression/null_compression.hh +++ b/base/compression/null_compression.hh @@ -34,6 +34,10 @@ * This file defines a doNothing compression algorithm. */ +#include <inttypes.h> // for uint8_t +#include "base/misc.hh" // for fatal() + + /** * A dummy compression class to use when no data compression is desired. */ diff --git a/base/cprintf_formats.hh b/base/cprintf_formats.hh index c3e01c935..d8a8a552b 100644 --- a/base/cprintf_formats.hh +++ b/base/cprintf_formats.hh @@ -341,7 +341,7 @@ format_string(std::ostream &out, const T &data, Format &fmt) { _format_string(out, data, fmt); } inline void -format_string(std::ostream &out, const std::stringstream& data, Format &fmt) +format_string(std::ostream &out, const std::stringstream &data, Format &fmt) { _format_string(out, data.str(), fmt); } #endif // __CPRINTF_FORMATS_HH__ diff --git a/base/kgdb.h b/base/kgdb.h index 35f74f4ba..a358dfa16 100644 --- a/base/kgdb.h +++ b/base/kgdb.h @@ -172,32 +172,4 @@ #define ALPHA_KENTRY_UNA 4 #define ALPHA_KENTRY_SYS 5 -/* - * MMCSR Fault Type Codes. [OSF/1 PALcode Specific] - */ - -#define ALPHA_MMCSR_INVALTRANS 0 -#define ALPHA_MMCSR_ACCESS 1 -#define ALPHA_MMCSR_FOR 2 -#define ALPHA_MMCSR_FOE 3 -#define ALPHA_MMCSR_FOW 4 - -/* - * Instruction Fault Type Codes. [OSF/1 PALcode Specific] - */ - -#define ALPHA_IF_CODE_BPT 0 -#define ALPHA_IF_CODE_BUGCHK 1 -#define ALPHA_IF_CODE_GENTRAP 2 -#define ALPHA_IF_CODE_FEN 3 -#define ALPHA_IF_CODE_OPDEC 4 - -#define BKPT_INST 0x00000080 // breakpoint instruction -#define BKPT_SIZE (4) // size of breakpoint inst - -#define IS_BREAKPOINT_TRAP(type, code) ((type) == ALPHA_KENTRY_IF && \ - (code) == ALPHA_IF_CODE_BPT) -#define IS_WATCHPOINT_TRAP(type, code) 0 - - #endif /* __KGDB_H__ */ diff --git a/base/range.cc b/base/range.cc new file mode 100644 index 000000000..0a4876e89 --- /dev/null +++ b/base/range.cc @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "base/intmath.hh" +#include "base/range.hh" +#include "base/str.hh" + +using namespace std; + +template <class T> +bool +__x_parse_range(const std::string &str, T &start, T &end) +{ + std::vector<std::string> values; + tokenize(values, str, ':'); + + T thestart, theend; + + if (values.size() != 2) + return false; + + std::string s = values[0]; + std::string e = values[1]; + + if (!to_number(s, thestart)) + return false; + + bool increment = (e[0] == '+'); + if (increment) + e = e.substr(1); + + if (!to_number(e, theend)) + return false; + + if (increment) + theend += thestart; + + start = thestart; + end = theend; + + return true; +} + +#define RANGE_PARSE(type) \ +template<> bool \ +__parse_range(const std::string &s, type &start, type &end) \ +{ return __x_parse_range(s, start, end); } + +RANGE_PARSE(unsigned long long); +RANGE_PARSE(signed long long); +RANGE_PARSE(unsigned long); +RANGE_PARSE(signed long); +RANGE_PARSE(unsigned int); +RANGE_PARSE(signed int); +RANGE_PARSE(unsigned short); +RANGE_PARSE(signed short); +RANGE_PARSE(unsigned char); +RANGE_PARSE(signed char); diff --git a/base/range.hh b/base/range.hh index 3443bf246..34bd34136 100644 --- a/base/range.hh +++ b/base/range.hh @@ -29,232 +29,340 @@ #ifndef __RANGE_HH__ #define __RANGE_HH__ -#include <assert.h> +#include <cassert> +#include <string> -#include "base/intmath.hh" -#include "base/str.hh" +template <class T> +bool __parse_range(const std::string &s, T &start, T &end); -template<class T> -class Range +template <class T> +struct Range { private: - bool valid; + /** + * @param s range string + * Ranges are in the following format: + * <range> := {<start_val>}:{<end>} + * <end> := <end_val> | +<delta> + */ + void + parse(const std::string &s) + { + if (!__parse_range(s, start, end)) + invalidate(); + } public: T start; T end; public: - Range() {} + Range() + { + invalidate(); + } + + template <class U> + Range(const Range<U> &r) + : start(r.start), end(r.end) + {} - Range(const Range &r) { operator=(r); } + template <class U> + Range(const std::pair<U, U> &r) + : start(r.first), end(r.second) + {} - Range(const T &s, const T &e) - : start(s), end(e) + Range(const std::string &s) { - valid = (start <= end); + parse(s); } - Range(const std::string &s) { valid = parse(s); } + template <class U> + const Range<T> &operator=(const Range<U> &r) + { + start = r.start; + end = r.end; + return *this; + } - ~Range() {} + template <class U> + const Range<T> &operator=(const std::pair<U, U> &r) + { + start = r.first; + end = r.second; + return *this; + } - int compare(const T &p); - bool parse(const std::string &s); - const Range &operator=(const Range &r); + const Range &operator=(const std::string &s) + { + parse(s); + return *this; + } - bool isValid() const { return valid; } + void invalidate() { start = 0; end = 0; } + bool size() const { return end - start; } + bool valid() const { return start < end; } }; - template<class T> -inline int -Range<T>::compare(const T &p) +inline std::ostream & +operator<<(std::ostream &o, const Range<T> &r) { - assert(isValid()); - - if (p < start) - return -1; - else if (p > end) - return 1; - else - return 0; + // don't currently support output of invalid ranges + assert(r.valid()); + o << r.start << ":" << r.end; + return o; } -// Parse a range string +//////////////////////////////////////////////////////////////////////// // -// Ranges are in the following format: -// <range> := {<start_val>}:{<end>} -// <end> := <end_val> | +<delta> -template<class T> +// Range to Range Comparisons +// + +/** + * @param range1 is a range. + * @param range2 is a range. + * @return if range1 and range2 are identical. + */ +template<class T, class U> inline bool -Range<T>::parse(const std::string &str) +operator==(const Range<T> &range1, const Range<U> &range2) { - std::vector<std::string> values; - tokenize(values, str, ':'); - - T thestart, theend; - - if (values.size() != 2) - return false; - - std::string s = values[0]; - std::string e = values[1]; - - if (!to_number(s, thestart)) - return false; - - bool increment = (e[0] == '+'); - if (increment) - e = e.substr(1); - - if (!to_number(e, theend)) - return false; - - if (increment) - theend += thestart; - - start = thestart; - end = theend; - - if (start > end) - return false; - - return true; + assert(range1.valid() && range2.valid()); + return range1.start == range2.start && range1.end == range2.end; } - -template<class T> -inline const Range<T> & -Range<T>::operator=(const Range<T> &r) +/** + * @param range1 is a range. + * @param range2 is a range. + * @return if range1 and range2 are not identical. + */ +template<class T, class U> +inline bool +operator!=(const Range<T> &range1, const Range<U> &range2) { - if (this != &r) { - start = r.start; - end = r.end; - - valid = r.valid; - } - else { - valid = false; - } + assert(range1.valid() && range2.valid()); + return range1.start != range2.start || range1.end != range2.end; +} - return *this; +/** + * @param range1 is a range. + * @param range2 is a range. + * @return if range1 is less than range2 and does not overlap range1. + */ +template<class T, class U> +inline bool +operator<(const Range<T> &range1, const Range<U> &range2) +{ + assert(range1.valid() && range2.valid()); + return range1.end <= range2.start; } -template<class T> -inline std::ostream & -operator<<(std::ostream &o, const Range<T> &r) +/** + * @param range1 is a range. + * @param range2 is a range. + * @return if range1 is less than range2. range1 may overlap range2, + * but not extend beyond the end of range2. + */ +template<class T, class U> +inline bool +operator<=(const Range<T> &range1, const Range<U> &range2) { - // don't currently support output of invalid ranges - assert(r.isValid()); - o << r.start << ":" << r.end; - return o; + assert(range1.valid() && range2.valid()); + return range1.start <= range2.start && range1.end <= range2.end; } -////////////////////////////////////////// -// -// Compare two ranges -// -template<class T> +/** + * @param range1 is a range. + * @param range2 is a range. + * @return if range1 is greater than range2 and does not overlap range2. + */ +template<class T, class U> inline bool -operator==(const Range<T> &l, const Range<T> &r) +operator>(const Range<T> &range1, const Range<U> &range2) { - // ranges must both be valid to be equal - return (l.isValid() && r.isValid() && - (l.start == r.start) && (l.end == r.end)); + assert(range1.valid() && range2.valid()); + return range1.start >= range2.end; } -template<class T> +/** + * @param range1 is a range. + * @param range2 is a range. + * @return if range1 is greater than range2. range1 may overlap range2, + * but not extend beyond the beginning of range2. + */ +template<class T, class U> inline bool -operator!=(const Range<T> &l, const Range<T> &r) +operator>=(const Range<T> &range1, const Range<U> &range2) { - // for symmetry with ==, an invalid range is not equal to any other - return (!l.isValid() || !r.isValid() || - (l.start != r.start) || (l.end != r.end)); + assert(range1.valid() && range2.valid()); + return range1.start >= range2.start && range1.end >= range2.end; } -////////////////////////////////////////// -// -// Compare position to a range -// -// - 'pos == range' indicates that position pos is within the given range. -// This test always returns false if the range is invalid. -// -// - 'pos < range' and 'pos > range' indicate that the position is -// before the start of or after the end of the range, respectively. -// The range must be valid for these comparisons to be made. -// -// All other comparisons do the obvious thing based on these definitions. +//////////////////////////////////////////////////////////////////////// // +// Position to Range Comparisons // -// -// Basic comparisons -// -template<class T> +/** + * @param pos position compared to the range. + * @param range range compared against. + * @return indicates that position pos is within the range. + */ +template<class T, class U> inline bool -operator==(const T &pos, const Range<T> &range) -{ return range.isValid() && pos >= range.start && pos <= range.end; } +operator==(const T &pos, const Range<U> &range) +{ + assert(range.valid()); + return pos >= range.start && pos < range.end; +} -template<class T> +/** + * @param pos position compared to the range. + * @param range range compared against. + * @return indicates that position pos is not within the range. + */ +template<class T, class U> inline bool -operator<(const T &pos, const Range<T> &range) -{ assert(range.isValid()); return pos < range.start; } +operator!=(const T &pos, const Range<U> &range) +{ + assert(range.valid()); + return pos < range.start || pos >= range.end; +} -template<class T> +/** + * @param pos position compared to the range. + * @param range range compared against. + * @return indicates that position pos is below the range. + */ +template<class T, class U> inline bool -operator>(const T &pos, const Range<T> &range) -{ assert(range.isValid()); return pos > range.end; } +operator<(const T &pos, const Range<U> &range) +{ + assert(range.valid()); + return pos < range.start; +} -// -// Derived comparisons -// -template<class T> +/** + * @param pos position compared to the range. + * @param range range compared against. + * @return indicates that position pos is below or in the range. + */ +template<class T, class U> inline bool -operator<=(const T &pos, const Range<T> &range) -{ assert(range.isValid()); return pos <= range.end; } +operator<=(const T &pos, const Range<U> &range) +{ + assert(range.valid()); + return pos < range.end; +} -template<class T> +/** + * @param pos position compared to the range. + * @param range range compared against. + * @return indicates that position pos is above the range. + */ +template<class T, class U> inline bool -operator>=(const T &pos, const Range<T> &range) -{ assert(range.isValid()); return pos >= range.start; } +operator>(const T &pos, const Range<U> &range) +{ + assert(range.valid()); + return pos >= range.end; +} -template<class T> +/** + * @param pos position compared to the range. + * @param range range compared against. + * @return indicates that position pos is above or in the range. + */ +template<class T, class U> inline bool -operator!=(const T &pos, const Range<T> &range) -{ return !(pos == range); } +operator>=(const T &pos, const Range<U> &range) +{ + assert(range.valid()); + return pos >= range.start; +} +//////////////////////////////////////////////////////////////////////// // -// Define symmetric comparisons based on above +// Range to Position Comparisons (for symmetry) // -template<class T> + +/** + * @param range range compared against. + * @param pos position compared to the range. + * @return indicates that position pos is within the range. + */ +template<class T, class U> inline bool -operator>(const Range<T> &range, const T &pos) -{ return pos < range; } +operator==(const Range<T> &range, const U &pos) +{ + assert(range.valid()); + return pos >= range.start && pos < range.end; +} -template<class T> +/** + * @param range range compared against. + * @param pos position compared to the range. + * @return indicates that position pos is not within the range. + */ +template<class T, class U> inline bool -operator<(const Range<T> &range, const T &pos) -{ return pos > range; } +operator!=(const Range<T> &range, const U &pos) +{ + assert(range.valid()); + return pos < range.start || pos >= range.end; +} -template<class T> +/** + * @param range range compared against. + * @param pos position compared to the range. + * @return indicates that position pos is above the range. + */ +template<class T, class U> inline bool -operator<=(const Range<T> &range, const T &pos) -{ return pos >= range; } +operator<(const Range<T> &range, const U &pos) +{ + assert(range.valid()); + return range.end <= pos; +} -template<class T> +/** + * @param range range compared against. + * @param pos position compared to the range. + * @return indicates that position pos is above or in the range. + */ +template<class T, class U> inline bool -operator>=(const Range<T> &range, const T &pos) -{ return pos <= range; } +operator<=(const Range<T> &range, const U &pos) +{ + assert(range.valid()); + return range.start <= pos; +} -template<class T> +/** + * @param range range compared against. + * @param pos position compared to the range. + * 'range > pos' indicates that position pos is below the range. + */ +template<class T, class U> inline bool -operator==(const Range<T> &range, const T &pos) -{ return (pos == range); } +operator>(const Range<T> &range, const U &pos) +{ + assert(range.valid()); + return range.start > pos; +} -template<class T> +/** + * @param range range compared against. + * @param pos position compared to the range. + * 'range >= pos' indicates that position pos is below or in the range. + */ +template<class T, class U> inline bool -operator!=(const Range<T> &range, const T &pos) -{ return (pos != range); } +operator>=(const Range<T> &range, const U &pos) +{ + assert(range.valid()); + return range.end > pos; +} #endif // __RANGE_HH__ diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index 35a90073a..e701b5a01 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -171,11 +171,17 @@ GDBListener::~GDBListener() delete event; } +string +GDBListener::name() +{ + return gdb->name() + ".listener"; +} + void GDBListener::listen() { while (!listener.listen(port, true)) { - DPRINTF(RGDB, "GDBListener(listen): Can't bind port %d\n", port); + DPRINTF(GDBMisc, "Can't bind port %d\n", port); port++; } @@ -188,7 +194,7 @@ void GDBListener::accept() { if (!listener.islistening()) - panic("GDBListener(accept): cannot accept a connection if we're not listening!"); + panic("GDBListener::accept(): cannot accept if we're not listening!"); int sfd = listener.accept(true); @@ -216,7 +222,12 @@ RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e) void RemoteGDB::Event::process(int revent) -{ gdb->trap(ALPHA_KENTRY_IF); } +{ + if (revent & POLLIN) + gdb->trap(ALPHA_KENTRY_IF); + else if (revent & POLLNVAL) + gdb->detach(); +} RemoteGDB::RemoteGDB(System *_system, ExecContext *c) : event(NULL), fd(-1), active(false), attached(false), @@ -231,6 +242,12 @@ RemoteGDB::~RemoteGDB() delete event; } +string +RemoteGDB::name() +{ + return system->name() + ".remote_gdb"; +} + bool RemoteGDB::isattached() { return attached; } @@ -316,17 +333,17 @@ RemoteGDB::acc(Addr va, size_t len) do { if (va < ALPHA_K0SEG_BASE) { - DPRINTF(RGDB, "RGDB(acc): Mapping is invalid %#x < K0SEG\n", va); + DPRINTF(GDBAcc, "acc: Mapping is invalid %#x < K0SEG\n", va); return false; } if (va < ALPHA_K1SEG_BASE) { if (va < (ALPHA_K0SEG_BASE + pmem->getSize())) { - DPRINTF(RGDB, "RGDB(acc): Mapping is valid K0SEG <= " + DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= " "%#x < K0SEG + size\n", va); return true; } else { - DPRINTF(RGDB, "RGDB(acc): Mapping is invalid %#x < K0SEG\n", + DPRINTF(GDBAcc, "acc: Mapping is invalid %#x < K0SEG\n", va); return false; } @@ -335,13 +352,13 @@ RemoteGDB::acc(Addr va, size_t len) Addr ptbr = context->regs.ipr[AlphaISA::IPR_PALtemp20]; pte = kernel_pte_lookup(pmem, ptbr, va); if (!pte || !entry_valid(pmem->phys_read_qword(pte))) { - DPRINTF(RGDB, "RGDB(acc): %#x pte is invalid\n", va); + DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); return false; } va += ALPHA_PGBYTES; } while (va < last_va); - DPRINTF(RGDB, "RGDB(acc): %#x mapping is valid\n", va); + DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); return true; } @@ -355,6 +372,9 @@ int RemoteGDB::signal(int type) { switch (type) { + case ALPHA_KENTRY_INT: + return (SIGTRAP); + case ALPHA_KENTRY_UNA: return (SIGBUS); @@ -399,7 +419,8 @@ RemoteGDB::getregs() void RemoteGDB::setregs() { - memcpy(context->regs.intRegFile, &gdbregs[KGDB_REG_V0], 32 * sizeof(uint64_t)); + memcpy(context->regs.intRegFile, &gdbregs[KGDB_REG_V0], + 32 * sizeof(uint64_t)); #ifdef KGDB_FP_REGS memcpy(context->regs.floatRegFile.q, &gdbregs[KGDB_REG_F0], 32 * sizeof(uint64_t)); @@ -410,7 +431,7 @@ RemoteGDB::setregs() void RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr) { - DPRINTF(RGDB, "RGDB(setTempBreakpoint): addr=%#x\n", addr); + DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr); bkpt.address = addr; insertHardBreak(addr, 4); @@ -419,7 +440,7 @@ RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr) void RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt) { - DPRINTF(RGDB, "RGDB(setTempBreakpoint): addr=%#x\n", + DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt.address); @@ -430,7 +451,7 @@ RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt) void RemoteGDB::clearSingleStep() { - DPRINTF(RGDB, "clearSingleStep bt_addr=%#x nt_addr=%#x\n", + DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n", takenBkpt.address, notTakenBkpt.address); if (takenBkpt.address != 0) @@ -460,7 +481,7 @@ RemoteGDB::setSingleStep() set_bt = true; } - DPRINTF(RGDB, "setSingleStep bt_addr=%#x nt_addr=%#x\n", + DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n", takenBkpt.address, notTakenBkpt.address); setTempBreakpoint(notTakenBkpt, npc); @@ -494,7 +515,7 @@ RemoteGDB::send(const char *bp) const char *p; uint8_t csum, c; -// DPRINTF(RGDB, "RGDB(send): %s\n", bp); + DPRINTF(GDBSend, "send: %s\n", bp); do { p = bp; @@ -554,7 +575,7 @@ RemoteGDB::recv(char *bp, int maxlen) putbyte(KGDB_BADP); } while (1); -// DPRINTF(RGDB, "RGDB(recv): %s: %s\n", gdb_command(*bp), bp); + DPRINTF(GDBRecv, "recv: %s: %s\n", gdb_command(*bp), bp); return (len); } @@ -569,11 +590,11 @@ RemoteGDB::read(Addr vaddr, size_t size, char *data) uint8_t *maddr; if (vaddr < 10) { - DPRINTF(RGDB, "\nRGDB(read): reading memory location zero!\n"); + DPRINTF(GDBRead, "read: reading memory location zero!\n"); vaddr = lastaddr + lastsize; } - DPRINTF(RGDB, "RGDB(read): addr=%#x, size=%d", vaddr, size); + DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size); #if TRACING_ON char *d = data; size_t s = size; @@ -607,10 +628,13 @@ RemoteGDB::read(Addr vaddr, size_t size, char *data) } #if TRACING_ON - if (DTRACE(RGDB)) { - char buf[1024]; - mem2hex(buf, d, s); - cprintf(": %s\n", buf); + if (DTRACE(GDBRead)) { + if (DTRACE(GDBExtra)) { + char buf[1024]; + mem2hex(buf, d, s); + DPRINTFNR(": %s\n", buf); + } else + DPRINTFNR("\n"); } #endif @@ -627,14 +651,18 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data) uint8_t *maddr; if (vaddr < 10) { - DPRINTF(RGDB, "RGDB(write): writing memory location zero!\n"); + DPRINTF(GDBWrite, "write: writing memory location zero!\n"); vaddr = lastaddr + lastsize; } - if (DTRACE(RGDB)) { - char buf[1024]; - mem2hex(buf, data, size); - cprintf("RGDB(write): addr=%#x, size=%d: %s\n", vaddr, size, buf); + if (DTRACE(GDBWrite)) { + DPRINTFN("write: addr=%#x, size=%d", vaddr, size); + if (DTRACE(GDBExtra)) { + char buf[1024]; + mem2hex(buf, data, size); + DPRINTFNR(": %s\n", buf); + } else + DPRINTFNR("\n"); } lastaddr = vaddr; @@ -682,17 +710,17 @@ RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc) : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc), gdb(_gdb), refcount(0) { - DPRINTF(RGDB, "creating hardware breakpoint at %#x\n", evpc); + DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc); schedule(); } void RemoteGDB::HardBreakpoint::process(ExecContext *xc) { - DPRINTF(RGDB, "handling hardware breakpoint at %#x\n", pc()); + DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc()); if (xc == gdb->context) - gdb->trap(ALPHA_KENTRY_IF); + gdb->trap(ALPHA_KENTRY_INT); } bool @@ -719,7 +747,7 @@ RemoteGDB::insertHardBreak(Addr addr, size_t len) if (len != sizeof(MachInst)) panic("invalid length\n"); - DPRINTF(RGDB, "inserting hardware breakpoint at %#x\n", addr); + DPRINTF(GDBMisc, "inserting hardware breakpoint at %#x\n", addr); HardBreakpoint *&bkpt = hardBreakMap[addr]; if (bkpt == 0) @@ -728,19 +756,6 @@ RemoteGDB::insertHardBreak(Addr addr, size_t len) bkpt->refcount++; return true; - -#if 0 - break_iter_t i = hardBreakMap.find(addr); - if (i == hardBreakMap.end()) { - HardBreakpoint *bkpt = new HardBreakpoint(this, addr); - hardBreakMap[addr] = bkpt; - i = hardBreakMap.insert(make_pair(addr, bkpt)); - if (i == hardBreakMap.end()) - return false; - } - - (*i).second->refcount++; -#endif } bool @@ -749,7 +764,7 @@ RemoteGDB::removeHardBreak(Addr addr, size_t len) if (len != sizeof(MachInst)) panic("invalid length\n"); - DPRINTF(RGDB, "removing hardware breakpoint at %#x\n", addr); + DPRINTF(GDBMisc, "removing hardware breakpoint at %#x\n", addr); break_iter_t i = hardBreakMap.find(addr); if (i == hardBreakMap.end()) @@ -798,7 +813,7 @@ RemoteGDB::trap(int type) if (!attached) return false; - DPRINTF(RGDB, "RGDB(trap): PC=%#x NPC=%#x\n", + DPRINTF(GDBMisc, "trap: PC=%#x NPC=%#x\n", context->regs.pc, context->regs.npc); clearSingleStep(); @@ -813,17 +828,12 @@ RemoteGDB::trap(int type) * After the debugger is "active" (connected) it will be * waiting for a "signaled" message from us. */ - if (!active) { - if (!IS_BREAKPOINT_TRAP(type, 0)) { - // No debugger active -- let trap handle this. - return false; - } + if (!active) active = true; - } else { + else // Tell remote host that an exception has occurred. sprintf((char *)buffer, "S%02x", signal(type)); send(buffer); - } // Stick frame regs into our reg cache. getregs(); @@ -1000,7 +1010,7 @@ RemoteGDB::trap(int type) if (*p++ != ',') send("E0D"); len = hex2i(&p); - DPRINTF(RGDB, "kgdb: clear %s, addr=%#x, len=%d\n", + DPRINTF(GDBMisc, "clear %s, addr=%#x, len=%d\n", break_type(subcmd), val, len); ret = false; @@ -1032,7 +1042,7 @@ RemoteGDB::trap(int type) if (*p++ != ',') send("E0D"); len = hex2i(&p); - DPRINTF(RGDB, "kgdb: set %s, addr=%#x, len=%d\n", + DPRINTF(GDBMisc, "set %s, addr=%#x, len=%d\n", break_type(subcmd), val, len); ret = false; @@ -1077,15 +1087,15 @@ RemoteGDB::trap(int type) case KGDB_TARGET_EXIT: case KGDB_BINARY_DLOAD: // Unsupported command - DPRINTF(RGDB, "kgdb: Unsupported command: %s\n", + DPRINTF(GDBMisc, "Unsupported command: %s\n", gdb_command(command)); - DDUMP(RGDB, (uint8_t *)data, datalen); + DDUMP(GDBMisc, (uint8_t *)data, datalen); send(""); continue; default: // Unknown command. - DPRINTF(RGDB, "kgdb: Unknown command: %c(%#x)\n", + DPRINTF(GDBMisc, "Unknown command: %c(%#x)\n", command, command); send(""); continue; diff --git a/base/remote_gdb.hh b/base/remote_gdb.hh index 62fd52856..fcc1ee2a9 100644 --- a/base/remote_gdb.hh +++ b/base/remote_gdb.hh @@ -116,9 +116,12 @@ class RemoteGDB RemoteGDB *gdb; public: + int refcount; + + public: HardBreakpoint(RemoteGDB *_gdb, Addr addr); + std::string name() { return gdb->name() + ".hwbkpt"; } - int refcount; virtual void process(ExecContext *xc); }; friend class HardBreakpoint; @@ -145,6 +148,9 @@ class RemoteGDB void clearTempBreakpoint(TempBreakpoint &bkpt); void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr); + + public: + std::string name(); }; template <class T> @@ -188,6 +194,7 @@ class GDBListener void accept(); void listen(); + std::string name(); }; #endif /* __REMOTE_GDB_H__ */ diff --git a/base/trace.hh b/base/trace.hh index 5aeaac445..9e5952765 100644 --- a/base/trace.hh +++ b/base/trace.hh @@ -179,9 +179,8 @@ std::ostream &DebugOut(); #define DDUMP(x, data, count) \ do { \ - using namespace Trace; \ if (Trace::IsOn(Trace::x)) \ - rawDump(data, count); \ + Trace::rawDump(data, count); \ } while (0) #define __dprintf(cycle, name, format, args...) \ @@ -204,6 +203,11 @@ do { \ __dprintf(curTick, name(), args, cp::ArgListNull()); \ } while (0) +#define DPRINTFNR(args...) \ +do { \ + __dprintf((Tick)-1, string(), args, cp::ArgListNull()); \ +} while (0) + #else // !TRACING_ON #define DTRACE(x) (false) @@ -211,6 +215,7 @@ do { \ #define DPRINTF(x, args...) do {} while (0) #define DPRINTFR(args...) do {} while (0) #define DPRINTFN(args...) do {} while (0) +#define DPRINTFNR(args...) do {} while (0) #define DDUMP(x, data, count) do {} while (0) #endif // TRACING_ON diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 2e4dff280..efbe66020 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -364,32 +364,32 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) template Fault -SimpleCPU::read(Addr addr, uint64_t& data, unsigned flags); +SimpleCPU::read(Addr addr, uint64_t &data, unsigned flags); template Fault -SimpleCPU::read(Addr addr, uint32_t& data, unsigned flags); +SimpleCPU::read(Addr addr, uint32_t &data, unsigned flags); template Fault -SimpleCPU::read(Addr addr, uint16_t& data, unsigned flags); +SimpleCPU::read(Addr addr, uint16_t &data, unsigned flags); template Fault -SimpleCPU::read(Addr addr, uint8_t& data, unsigned flags); +SimpleCPU::read(Addr addr, uint8_t &data, unsigned flags); #endif //DOXYGEN_SHOULD_SKIP_THIS template<> Fault -SimpleCPU::read(Addr addr, double& data, unsigned flags) +SimpleCPU::read(Addr addr, double &data, unsigned flags) { return read(addr, *(uint64_t*)&data, flags); } template<> Fault -SimpleCPU::read(Addr addr, float& data, unsigned flags) +SimpleCPU::read(Addr addr, float &data, unsigned flags) { return read(addr, *(uint32_t*)&data, flags); } @@ -397,7 +397,7 @@ SimpleCPU::read(Addr addr, float& data, unsigned flags) template<> Fault -SimpleCPU::read(Addr addr, int32_t& data, unsigned flags) +SimpleCPU::read(Addr addr, int32_t &data, unsigned flags) { return read(addr, (uint32_t&)data, flags); } diff --git a/kern/tru64/tru64_system.cc b/kern/tru64/tru64_system.cc index 07c655385..1cd98fdc1 100644 --- a/kern/tru64/tru64_system.cc +++ b/kern/tru64/tru64_system.cc @@ -601,7 +601,7 @@ Tru64System::replaceExecContext(ExecContext *xc, int xcIndex) bool Tru64System::breakpoint() { - return remoteGDB[0]->trap(ALPHA_KENTRY_IF); + return remoteGDB[0]->trap(ALPHA_KENTRY_INT); } #ifdef FS_MEASURE diff --git a/sim/serialize.cc b/sim/serialize.cc index d836e7c20..f8d6b46bf 100644 --- a/sim/serialize.cc +++ b/sim/serialize.cc @@ -187,7 +187,7 @@ class Globals : public Serializable { public: const string name() const; - void serialize(ostream& os); + void serialize(ostream &os); void unserialize(Checkpoint *cp); }; @@ -201,7 +201,7 @@ Globals::name() const } void -Globals::serialize(ostream& os) +Globals::serialize(ostream &os) { nameOut(os); SERIALIZE_SCALAR(curTick); diff --git a/sim/serialize.hh b/sim/serialize.hh index 43dbd2c85..36622b7fe 100644 --- a/sim/serialize.hh +++ b/sim/serialize.hh @@ -103,8 +103,8 @@ objParamIn(Checkpoint *cp, const std::string §ion, class Serializable { protected: - void nameOut(std::ostream& os); - void nameOut(std::ostream& os, const std::string &_name); + void nameOut(std::ostream &os); + void nameOut(std::ostream &os, const std::string &_name); public: Serializable() {} @@ -113,7 +113,7 @@ class Serializable // manditory virtual function, so objects must provide names virtual const std::string name() const = 0; - virtual void serialize(std::ostream& os) {} + virtual void serialize(std::ostream &os) {} virtual void unserialize(Checkpoint *cp, const std::string §ion) {} static Serializable *create(Checkpoint *cp, diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index 9955d4421..e953a7308 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -185,4 +185,32 @@ gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) return 0; } +int +unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) +{ + std::string path; + + if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + return -EFAULT; + + int result = unlink(path.c_str()); + return (result == -1) ? -errno : result; +} + +int +renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) +{ + std::string old_name; + + if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != No_Fault) + return -EFAULT; + + std::string new_name; + + if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != No_Fault) + return -EFAULT; + + int result = rename(old_name.c_str(),new_name.c_str()); + return (result == -1) ? -errno : result; +} diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index df4038f71..b425ef83c 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -191,6 +191,12 @@ int munmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc); /// Target gethostname() handler. int gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc); +/// Target unlink() handler. +int unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc); + +/// Target rename() handler. +int renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc); + ////////////////////////////////////////////////////////////////////// // // The following emulation functions are generic, but need to be @@ -223,10 +229,12 @@ ioctlFunc(SyscallDesc *desc, int callnum, Process *process, case OS::TIOCSETN: case OS::TIOCSETC: case OS::TIOCGETC: + case OS::TIOCGETS: + case OS::TIOCGETA: return -ENOTTY; default: - fatal("Unsupported ioctl call: ioctl(%d, 0x%x, ...)\n", fd, req); + fatal("Unsupported ioctl call: ioctl(%d, 0x%x, ...) @ 0x%llx\n", fd, req, xc->readPC()); } } diff --git a/test/Makefile b/test/Makefile index 2c3780c93..d62dba64a 100644 --- a/test/Makefile +++ b/test/Makefile @@ -49,7 +49,7 @@ nmtest: nmtest.o object_file.o symtab.o misc.o str.o offtest: offtest.o $(CXX) $(LFLAGS) -o $@ $^ -rangetest: rangetest.o str.o +rangetest: rangetest.o range.o str.o $(CXX) $(LFLAGS) -o $@ $^ stattest: cprintf.o hostinfo.o misc.o python.o statistics.o stattest.o \ diff --git a/test/rangetest.cc b/test/rangetest.cc index f44d835b7..c38c13fd1 100644 --- a/test/rangetest.cc +++ b/test/rangetest.cc @@ -31,11 +31,12 @@ #include "base/range.hh" +using namespace std; int main() { - Range<int> r1(9, 28); + Range<int> r1(make_pair(9, 28)); Range<unsigned> r2("0x1000:+0x100"); cout << r1 << "\n" @@ -44,61 +45,30 @@ main() #define RANGETEST(X, C, Y) \ cout << X << " "#C" " << Y << " => " << ((X C Y) ? "true" : "false") << "\n" - int i1 = 10; - int i2 = 0x1001; - RANGETEST(i1, < , r1); - RANGETEST(i1, <=, r1); - RANGETEST(i1, > , r1); - RANGETEST(i1, >=, r1); - RANGETEST(i1, ==, r1); - RANGETEST(i1, !=, r1); - RANGETEST(r1, < , i1); - RANGETEST(r1, <=, i1); - RANGETEST(r1, > , i1); - RANGETEST(r1, >=, i1); - RANGETEST(r1, ==, i1); - RANGETEST(r1, !=, i1); +#define TESTEM(X, Y) do { \ + RANGETEST(X, < , Y); \ + RANGETEST(X, <=, Y); \ + RANGETEST(X, > , Y); \ + RANGETEST(X, >=, Y); \ + RANGETEST(X, ==, Y); \ + RANGETEST(X, !=, Y); \ + RANGETEST(Y, < , X); \ + RANGETEST(Y, <=, X); \ + RANGETEST(Y, > , X); \ + RANGETEST(Y, >=, X); \ + RANGETEST(Y, ==, X); \ + RANGETEST(Y, !=, X); \ +} while (0) - RANGETEST(i2, < , r1); - RANGETEST(i2, <=, r1); - RANGETEST(i2, > , r1); - RANGETEST(i2, >=, r1); - RANGETEST(i2, ==, r1); - RANGETEST(i2, !=, r1); - RANGETEST(r1, < , i2); - RANGETEST(r1, <=, i2); - RANGETEST(r1, > , i2); - RANGETEST(r1, >=, i2); - RANGETEST(r1, ==, i2); - RANGETEST(r1, !=, i2); + TESTEM(8, r1); + TESTEM(9, r1); + TESTEM(27, r1); + TESTEM(28, r1); - unsigned u1 = 10; - unsigned u2 = 0x1001; - RANGETEST(u1, < , r2); - RANGETEST(u1, <=, r2); - RANGETEST(u1, > , r2); - RANGETEST(u1, >=, r2); - RANGETEST(u1, ==, r2); - RANGETEST(u1, !=, r2); - RANGETEST(r2, < , u1); - RANGETEST(r2, <=, u1); - RANGETEST(r2, > , u1); - RANGETEST(r2, >=, u1); - RANGETEST(r2, ==, u1); - RANGETEST(r2, !=, u1); - - RANGETEST(u2, < , r2); - RANGETEST(u2, <=, r2); - RANGETEST(u2, > , r2); - RANGETEST(u2, >=, r2); - RANGETEST(u2, ==, r2); - RANGETEST(u2, !=, r2); - RANGETEST(r2, < , u2); - RANGETEST(r2, <=, u2); - RANGETEST(r2, > , u2); - RANGETEST(r2, >=, u2); - RANGETEST(r2, ==, u2); - RANGETEST(r2, !=, u2); + TESTEM(0x0fff, r2); + TESTEM(0x1000, r2); + TESTEM(0x10ff, r2); + TESTEM(0x1100, r2); return 0; } |