lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20241128133553.823722-5-yangjihong@bytedance.com>
Date: Thu, 28 Nov 2024 21:35:45 +0800
From: Yang Jihong <yangjihong@...edance.com>
To: peterz@...radead.org,
	mingo@...hat.com,
	acme@...nel.org,
	namhyung@...nel.org,
	mark.rutland@....com,
	alexander.shishkin@...ux.intel.com,
	jolsa@...nel.org,
	irogers@...gle.com,
	adrian.hunter@...el.com,
	kan.liang@...ux.intel.com,
	james.clark@....com,
	linux-perf-users@...r.kernel.org,
	linux-kernel@...r.kernel.org
Cc: yangjihong@...edance.com
Subject: [RFC 04/12] perf event action: Add parsing const string expr support

Support parsing of constant string expression.

Signed-off-by: Yang Jihong <yangjihong@...edance.com>
---
 tools/perf/util/parse-action.c |  39 ++++++++++++
 tools/perf/util/parse-action.h |   1 +
 tools/perf/util/parse-action.l | 108 +++++++++++++++++++++++++++++++++
 tools/perf/util/parse-action.y |  10 ++-
 4 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/parse-action.c b/tools/perf/util/parse-action.c
index 3b10cf9f99b3..7e5ca889d5b9 100644
--- a/tools/perf/util/parse-action.c
+++ b/tools/perf/util/parse-action.c
@@ -8,6 +8,7 @@
  * Supported expressions:
  *   - constant:
  *     - integer
+ *     - string
  */
 
 #include "util/debug.h"
@@ -169,8 +170,46 @@ static struct evtact_expr_ops expr_const_int_ops = {
 	.eval = expr_const_int_eval,
 };
 
+static int expr_const_str_new(struct evtact_expr *expr,
+			      void *data, int size __maybe_unused)
+{
+	if (data == NULL) {
+		pr_err("exper const string is NULL\n");
+		return -EINVAL;
+	}
+
+	expr->priv = data;
+	INIT_LIST_HEAD(&expr->opnds);
+	return 0;
+}
+
+static void expr_const_str_free(struct evtact_expr *expr)
+{
+	zfree(&expr->priv);
+}
+
+static int expr_const_str_eval(struct evtact_expr *expr,
+			       void *in __maybe_unused, int in_size __maybe_unused,
+			       void **out, int *out_size)
+{
+	if (out != NULL)
+		*out = expr->priv;
+
+	if (out_size != NULL)
+		*out_size = strlen(expr->priv);
+
+	return 0;
+}
+
+static struct evtact_expr_ops expr_const_str_ops = {
+	.new  = expr_const_str_new,
+	.free = expr_const_str_free,
+	.eval = expr_const_str_eval,
+};
+
 static struct evtact_expr_ops *expr_const_ops_list[EVTACT_EXPR_CONST_TYPE_MAX] = {
 	[EVTACT_EXPR_CONST_TYPE_INT] = &expr_const_int_ops,
+	[EVTACT_EXPR_CONST_TYPE_STR] = &expr_const_str_ops,
 };
 
 static int expr_const_set_ops(struct evtact_expr *expr, u32 opcode)
diff --git a/tools/perf/util/parse-action.h b/tools/perf/util/parse-action.h
index ac81278c590e..ec422f8a05a7 100644
--- a/tools/perf/util/parse-action.h
+++ b/tools/perf/util/parse-action.h
@@ -15,6 +15,7 @@ enum evtact_expr_type {
 
 enum evtact_expr_const_type {
 	EVTACT_EXPR_CONST_TYPE_INT,
+	EVTACT_EXPR_CONST_TYPE_STR,
 	EVTACT_EXPR_CONST_TYPE_MAX,
 };
 
diff --git a/tools/perf/util/parse-action.l b/tools/perf/util/parse-action.l
index 9237399a11ac..f76240276b61 100644
--- a/tools/perf/util/parse-action.l
+++ b/tools/perf/util/parse-action.l
@@ -28,6 +28,54 @@ static int value(int base)
 	return NUMBER;
 }
 
+static char *str_buf;
+static unsigned int str_buf_size = 64;
+static int str_begin(void)
+{
+	if (str_buf == NULL) {
+		str_buf = malloc(str_buf_size);
+		if (str_buf == NULL) {
+			pr_err("parse_action malloc string buffer failed\n");
+			return ERROR;
+		}
+	}
+
+	str_buf[0] = '\0';
+	return 0;
+}
+
+static int str_write(const char *s)
+{
+	char *new_buf;
+
+	if (strlen(str_buf) + strlen(s) >= str_buf_size) {
+		str_buf_size = strlen(str_buf) + strlen(s) + 1;
+		new_buf = realloc(str_buf, str_buf_size);
+		if (new_buf == NULL) {
+			free(str_buf);
+			str_buf = NULL;
+			pr_err("parse_action realloc string buffer failed\n");
+			return ERROR;
+                } else {
+			str_buf = new_buf;
+		}
+	}
+
+	strcat(str_buf, s);
+	return 0;
+}
+
+static int str_end(void)
+{
+	parse_action_lval.str = strdup(str_buf);
+	if (parse_action_lval.str == NULL) {
+		pr_err("parse_action strdup string buffer failed\n");
+		return ERROR;
+	}
+
+	return STRING;
+}
+
 %}
 
 num_dec		[0-9]+
@@ -35,6 +83,8 @@ num_hex		0[xX][0-9a-fA-F]+
 space		[ \t]
 ident		[_a-zA-Z][_a-zA-Z0-9]*
 
+%x STR_BEGIN
+
 %%
 
 {num_dec}	{ return value(10); }
@@ -43,6 +93,64 @@ ident		[_a-zA-Z][_a-zA-Z0-9]*
 
 ";"		{ return SEMI; }
 
+\"		{
+			int ret;
+			yy_push_state(STR_BEGIN);
+			ret = str_begin();
+			if (ret) {
+				yy_pop_state();
+				return ret;
+			}
+		}
+<STR_BEGIN>{
+  \"		{
+			yy_pop_state();
+			return str_end();
+		}
+  [^\\\n\"]+	{
+			int ret;
+			ret = str_write((const char *)yytext);
+			if (ret) {
+				yy_pop_state();
+				return ret;
+			}
+		}
+  \\n		{
+			int ret;
+			ret = str_write("\n");
+			if (ret) {
+				yy_pop_state();
+				return ret;
+                        }
+                }
+  \\t           {
+			int ret;
+			ret = str_write("\t");
+			if (ret) {
+				yy_pop_state();
+				return ret;
+			}
+		}
+  \\\\		{
+			int ret;
+			ret = str_write("\\");
+			if (ret) {
+				yy_pop_state();
+				return ret;
+			}
+		}
+  \\.		{
+			yy_pop_state();
+			pr_err("parse_action invalid escape character: '%s'\n", parse_action_text);
+			return ERROR;
+		}
+  .		{
+			yy_pop_state();
+			pr_err("parse_action invalid character: '%s'\n", parse_action_text);
+			return ERROR;
+		}
+}
+
 {ident}		{
 			parse_action_lval.str = strdup(parse_action_text);
 			if (parse_action_lval.str == NULL) {
diff --git a/tools/perf/util/parse-action.y b/tools/perf/util/parse-action.y
index 51e77e54f157..4922b2d94aee 100644
--- a/tools/perf/util/parse-action.y
+++ b/tools/perf/util/parse-action.y
@@ -37,12 +37,13 @@ static void parse_action_error(struct list_head *expr __maybe_unused,
 	unsigned long long num;
 }
 
-%token IDENT ERROR NUMBER
+%token IDENT ERROR NUMBER STRING
 %token SEMI
 %type <expr> action_term expr_term
 %destructor { parse_action_expr__free($$); } <expr>
 %type <str> IDENT
 %type <num> NUMBER
+%type <str> STRING
 
 %%
 
@@ -76,6 +77,13 @@ NUMBER
 		YYERROR;
 }
 |
+STRING
+{
+	$$ = parse_action_expr__new(expr_id(CONST, STR), NULL, (void *)$1, strlen($1));
+	if ($$ == NULL)
+		YYERROR;
+}
+|
 IDENT
 {
 	$$ = NULL;
-- 
2.25.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ