From 44ce8ed5cb963d4cb6bf085d7ee60b90afdb93f4 Mon Sep 17 00:00:00 2001 From: fche Date: Thu, 24 Nov 2005 22:45:52 +0000 Subject: [PATCH] 2005-11-24 Frank Ch. Eigler 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. --- ChangeLog | 9 +++ main.cxx | 1 + parse.cxx | 105 ++++++++++++++++++++------------- session.h | 1 + stap.1.in | 27 +++++++-- testsuite/parseok/fourteen.stp | 7 +++ 6 files changed, 103 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index f7b43b697..822a379aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2005-11-24 Frank Ch. Eigler + + 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 PR 1917 diff --git a/main.cxx b/main.cxx index cd641588d..1ecefa2ea 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 2ceb6f5f8..628fe4201 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 6e507dd70..0c9a00825 100644 --- a/session.h +++ b/session.h @@ -62,6 +62,7 @@ struct systemtap_session std::vector macros; std::vector 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 fe954d10f..28c20dd5b 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 e68aa4fe0..cc51b90b6 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 %) + %) +%) -- 2.43.5