summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfche <fche>2005-11-24 22:45:52 +0000
committerfche <fche>2005-11-24 22:45:52 +0000
commit44ce8ed5cb963d4cb6bf085d7ee60b90afdb93f4 (patch)
tree27bc17286b34736e821dc7221a5dd11969ef87c0
parentded98b334e86a6f6aed6a30a20b67aecc0ae1bf4 (diff)
downloadsystemtap-steved-44ce8ed5cb963d4cb6bf085d7ee60b90afdb93f4.tar.gz
systemtap-steved-44ce8ed5cb963d4cb6bf085d7ee60b90afdb93f4.tar.xz
systemtap-steved-44ce8ed5cb963d4cb6bf085d7ee60b90afdb93f4.zip
2005-11-24 Frank Ch. Eigler <fche@redhat.com>
PR 1903 * parse.cxx (eval_pp_conditional): Support %( arch == "i686" %) form. * stap.1.in: Document it. * testsuite/parseok/fourteen.stp: Test it. * session.h (architecture): New field. * main.cxx (main): Initialize it.
-rw-r--r--ChangeLog9
-rw-r--r--main.cxx1
-rw-r--r--parse.cxx105
-rw-r--r--session.h1
-rw-r--r--stap.1.in27
-rwxr-xr-xtestsuite/parseok/fourteen.stp7
6 files changed, 103 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index f7b43b69..822a379a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2005-11-24 Frank Ch. Eigler <fche@redhat.com>
+ PR 1903
+ * parse.cxx (eval_pp_conditional): Support %( arch == "i686" %) form.
+ * stap.1.in: Document it.
+ * testsuite/parseok/fourteen.stp: Test it.
+ * session.h (architecture): New field.
+ * main.cxx (main): Initialize it.
+
+2005-11-24 Frank Ch. Eigler <fche@redhat.com>
+
PR 1917
* translate.cxx (emit_common_header, emit_module_init,
emit_module_exit): Switch context array to per-cpu kmalloc variant.
diff --git a/main.cxx b/main.cxx
index cd641588..1ecefa2e 100644
--- a/main.cxx
+++ b/main.cxx
@@ -118,6 +118,7 @@ main (int argc, char * const argv [])
struct utsname buf;
(void) uname (& buf);
s.kernel_release = string (buf.release);
+ s.architecture = string (buf.machine);
s.verbose = false;
s.test_mode = false;
s.guru_mode = false;
diff --git a/parse.cxx b/parse.cxx
index 2ceb6f5f..628fe420 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -133,10 +133,12 @@ parser::last ()
// Here, we perform on-the-fly preprocessing.
// The basic form is %( CONDITION %? THEN-TOKENS %: ELSE-TOKENS %)
-// where CONDITION is "kernel_v[r]" COMPARISON-OP "version-string", and
-// the %: ELSE-TOKENS part is optional.
+// where CONDITION is: kernel_v[r] COMPARISON-OP "version-string"
+// or: arch COMPARISON-OP "arch-string"
+// The %: ELSE-TOKENS part is optional.
//
// e.g. %( kernel_v > "2.5" %? "foo" %: "baz" %)
+// e.g. %( arch != "i686" %? "foo" %: "baz" %)
//
// Up to an entire %( ... %) expression is processed by a single call
// to this function. Tokens included by any nested conditions are
@@ -145,46 +147,67 @@ parser::last ()
bool eval_pp_conditional (systemtap_session& s,
const token* l, const token* op, const token* r)
{
- if (! (l->type == tok_identifier && (l->content == "kernel_v" ||
- l->content == "kernel_vr")))
- throw parse_error ("expected 'kernel_v' or 'kernel_vr'", l);
- string target_kernel_vr = s.kernel_release;
- string target_kernel_v = target_kernel_vr;
- // cut off any release code suffix
- string::size_type dr = target_kernel_vr.rfind ('-');
- if (dr > 0 && dr != string::npos)
- target_kernel_v = target_kernel_vr.substr (0, dr);
-
- if (! (r->type == tok_string))
- throw parse_error ("expected string literal", r);
- string query_kernel_vr = r->content;
-
- // collect acceptable strverscmp results.
- int rvc_ok1, rvc_ok2;
- if (op->type == tok_operator && op->content == "<=")
- { rvc_ok1 = -1; rvc_ok2 = 0; }
- else if (op->type == tok_operator && op->content == ">=")
- { rvc_ok1 = 1; rvc_ok2 = 0; }
- else if (op->type == tok_operator && op->content == "<")
- { rvc_ok1 = -1; rvc_ok2 = -1; }
- else if (op->type == tok_operator && op->content == ">")
- { rvc_ok1 = 1; rvc_ok2 = 1; }
- else if (op->type == tok_operator && op->content == "==")
- { rvc_ok1 = 0; rvc_ok2 = 0; }
- else if (op->type == tok_operator && op->content == "!=")
- { rvc_ok1 = -1; rvc_ok2 = 1; }
+ if (l->type == tok_identifier && (l->content == "kernel_v" ||
+ l->content == "kernel_vr"))
+ {
+ string target_kernel_vr = s.kernel_release;
+ string target_kernel_v = target_kernel_vr;
+ // cut off any release code suffix
+ string::size_type dr = target_kernel_vr.rfind ('-');
+ if (dr > 0 && dr != string::npos)
+ target_kernel_v = target_kernel_vr.substr (0, dr);
+
+ if (! (r->type == tok_string))
+ throw parse_error ("expected string literal", r);
+ string query_kernel_vr = r->content;
+
+ // collect acceptable strverscmp results.
+ int rvc_ok1, rvc_ok2;
+ if (op->type == tok_operator && op->content == "<=")
+ { rvc_ok1 = -1; rvc_ok2 = 0; }
+ else if (op->type == tok_operator && op->content == ">=")
+ { rvc_ok1 = 1; rvc_ok2 = 0; }
+ else if (op->type == tok_operator && op->content == "<")
+ { rvc_ok1 = -1; rvc_ok2 = -1; }
+ else if (op->type == tok_operator && op->content == ">")
+ { rvc_ok1 = 1; rvc_ok2 = 1; }
+ else if (op->type == tok_operator && op->content == "==")
+ { rvc_ok1 = 0; rvc_ok2 = 0; }
+ else if (op->type == tok_operator && op->content == "!=")
+ { rvc_ok1 = -1; rvc_ok2 = 1; }
+ else
+ throw parse_error ("expected comparison operator", op);
+
+ int rvc_result = strverscmp ((l->content == "kernel_vr" ?
+ target_kernel_vr.c_str() :
+ target_kernel_v.c_str()),
+ query_kernel_vr.c_str());
+ // normalize rvc_result
+ if (rvc_result < 0) rvc_result = -1;
+ if (rvc_result > 0) rvc_result = 1;
+
+ return (rvc_result == rvc_ok1 || rvc_result == rvc_ok2);
+ }
+ else if (l->type == tok_identifier && l->content == "arch")
+ {
+ string target_architecture = s.architecture;
+ if (! (r->type == tok_string))
+ throw parse_error ("expected string literal", r);
+ string query_architecture = r->content;
+
+ bool result;
+ if (op->type == tok_operator && op->content == "==")
+ result = target_architecture == query_architecture;
+ else if (op->type == tok_operator && op->content == "!=")
+ result = target_architecture != query_architecture;
+ else
+ throw parse_error ("expected '==' or '!='", op);
+
+ return result;
+ }
+ // XXX: support other forms? "CONFIG_SMP" ?
else
- throw parse_error ("expected comparison operator", op);
-
- int rvc_result = strverscmp ((l->content == "kernel_vr" ?
- target_kernel_vr.c_str() :
- target_kernel_v.c_str()),
- query_kernel_vr.c_str());
- // normalize rvc_result
- if (rvc_result < 0) rvc_result = -1;
- if (rvc_result > 0) rvc_result = 1;
-
- return (rvc_result == rvc_ok1 || rvc_result == rvc_ok2);
+ throw parse_error ("expected 'arch' or 'kernel_v' or 'kernel_vr'", l);
}
diff --git a/session.h b/session.h
index 6e507dd7..0c9a0082 100644
--- a/session.h
+++ b/session.h
@@ -62,6 +62,7 @@ struct systemtap_session
std::vector<std::string> macros;
std::vector<std::string> args;
std::string kernel_release;
+ std::string architecture;
std::string runtime_path;
std::string module_name;
std::string output_file;
diff --git a/stap.1.in b/stap.1.in
index fe954d10..28c20dd5 100644
--- a/stap.1.in
+++ b/stap.1.in
@@ -163,20 +163,31 @@ ternary operator:
.BR %( " CONDITION " %? " TRUE-TOKENS " %)
.BR %( " CONDITION " %? " TRUE-TOKENS " %: " FALSE-TOKENS " %)
.ESAMPLE
-The CONDITION is a very limited expression consisting of three
-parts. The first part is the identifier
+The CONDITION is a very limited expression whose format is determined
+by its first keyword.
+.PP
+If the first part is the identifier
.BR kernel_vr " or " kernel_v
to refer to the kernel version number, with ("2.6.13-1.322FC3smp") or
-without ("2.6.13") the release code suffix.
-The second part is one of the six standard numeric comparison operators
-.BR < ", " <= ", " == ", " != ", " > ", and " >= .
-The third part is a string literal that contains an RPM-style
+without ("2.6.13") the release code suffix, then
+the second part is one of the six standard numeric comparison operators
+.BR < ", " <= ", " == ", " != ", " > ", and " >= ,
+and the third part is a string literal that contains an RPM-style
version-release value. The condition is deemed satisfied if the
version of the target kernel (as optionally overridden by the
.BR \-r
option) compares to the given version string. The comparison is
performed by the glibc function
.BR strverscmp .
+.PP
+If, on the other hand, the first part is the identifier
+.BR arch
+to refer to the processor architecture, then the second part
+then the second part is one of the two string comparison operatorsn
+.BR == " or " != ,
+and the third part is a string literal for matching it. This
+comparison is simple string (in)equality.
+.PP
The TRUE-TOKENS and FALSE-TOKENS are zero or more general parser
tokens (possibly including nested preprocessor conditionals), and are
pasted into the input stream if the condition is true or false. For
@@ -192,6 +203,10 @@ probe kernel.function (
%( kernel_vr == "2.6.13-1.8273FC3smp" %? "do_page_fault" %:
UNSUPPORTED %) %)
) { /* ... */ }
+
+%( arch == "ia64" %?
+ probe syscall.vliw = kernel.function("vliw_widget") {}
+%)
.ESAMPLE
.SS VARIABLES
diff --git a/testsuite/parseok/fourteen.stp b/testsuite/parseok/fourteen.stp
index e68aa4fe..cc51b90b 100755
--- a/testsuite/parseok/fourteen.stp
+++ b/testsuite/parseok/fourteen.stp
@@ -8,3 +8,10 @@ global
%: "FAIL2" %)
%: "FAIL3" %)
%: "FAIL4" %)
+
+global
+%( arch == "i386" %? i386
+%: %( arch == "i686" %? i686
+ %: %( arch != "x86_64" %? other %: x86_64 %)
+ %)
+%)