summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJose E. Marchesi <jose.marchesi@oracle.com>2023-11-18 18:12:44 +0100
committerJose E. Marchesi <jose.marchesi@oracle.com>2023-11-18 18:17:26 +0100
commit8fbb497b7202f404d8914252d44d2ee190a0e172 (patch)
treef66854caee10fdcb22186c67eedae3aebe24f1f5
parent26c7a0ea380bedb86ff3b5a9ed252d8d2557a0c5 (diff)
gas: bpf: do not allow referring to register names as symbols in operands
2023-11-18 Jose E. Marchesi <jemarch@gnu.org> * config/tc-bpf.c (parse_bpf_register): Move before bpf_parse_name. (bpf_parse_name): Do not allow using symbols that are also register names as operands in pseudo-c syntax. * testsuite/gas/bpf/regs-for-symbols-pseudoc.d: New file. * testsuite/gas/bpf/regs-for-symbols-pseudoc.s: Likewise. * testsuite/gas/bpf/regs-for-symbols-pseudoc.l: Likewise. * doc/c-bpf.texi (BPF Registers): Document that it is not possible to refer to register names as symbols in instruction operands.
-rw-r--r--gas/ChangeLog12
-rw-r--r--gas/config/tc-bpf.c113
-rw-r--r--gas/doc/c-bpf.texi7
-rw-r--r--gas/testsuite/gas/bpf/bpf.exp4
-rw-r--r--gas/testsuite/gas/bpf/regs-for-symbols-pseudoc.d3
-rw-r--r--gas/testsuite/gas/bpf/regs-for-symbols-pseudoc.l8
-rw-r--r--gas/testsuite/gas/bpf/regs-for-symbols-pseudoc.s4
7 files changed, 102 insertions, 49 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index cbe2a57dfee..9f966be40b5 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,15 @@
+2023-11-18 Jose E. Marchesi <jemarch@gnu.org>
+
+ * config/tc-bpf.c (parse_bpf_register): Move before
+ bpf_parse_name.
+ (bpf_parse_name): Do not allow using symbols that are also
+ register names as operands in pseudo-c syntax.
+ * testsuite/gas/bpf/regs-for-symbols-pseudoc.d: New file.
+ * testsuite/gas/bpf/regs-for-symbols-pseudoc.s: Likewise.
+ * testsuite/gas/bpf/regs-for-symbols-pseudoc.l: Likewise.
+ * doc/c-bpf.texi (BPF Registers): Document that it is not possible
+ to refer to register names as symbols in instruction operands.
+
2023-11-15 YunQiang Su <yunqiang.su@cipunited.com>
* testsuite/gas/mips/mips.exp (mips_arch_create): Add "--defsym
diff --git a/gas/config/tc-bpf.c b/gas/config/tc-bpf.c
index 3122f80804a..45abc3c9578 100644
--- a/gas/config/tc-bpf.c
+++ b/gas/config/tc-bpf.c
@@ -1255,6 +1255,54 @@ parse_expression (char *s, expressionS *exp)
return s;
}
+/* Parse a BPF register name and return the corresponding register
+ number. Return NULL in case of parse error, or a pointer to the
+ first character in S that is not part of the register name. */
+
+static char *
+parse_bpf_register (char *s, char rw, uint8_t *regno)
+{
+ if (asm_dialect == DIALECT_NORMAL)
+ {
+ rw = 'r';
+ if (*s != '%')
+ return NULL;
+ s += 1;
+
+ if (*s == 'f' && *(s + 1) == 'p')
+ {
+ *regno = 10;
+ s += 2;
+ return s;
+ }
+ }
+
+ if (*s != rw)
+ return NULL;
+ s += 1;
+
+ if (*s == '1')
+ {
+ if (*(s + 1) == '0')
+ {
+ *regno = 10;
+ s += 2;
+ }
+ else
+ {
+ *regno = 1;
+ s += 1;
+ }
+ }
+ else if (*s >= '0' && *s <= '9')
+ {
+ *regno = *s - '0';
+ s += 1;
+ }
+
+ return s;
+}
+
/* Symbols created by this parse, but not yet committed to the real
symbol table. */
static symbolS *deferred_sym_rootP;
@@ -1283,6 +1331,23 @@ bpf_parse_name (const char *name, expressionS *exp, enum expr_mode mode)
gas_assert (mode == expr_normal);
+ /* Pseudo-C syntax uses unprefixed register names like r2 or w3.
+ Since many instructions take either a register or an
+ immediate/expression, we should not allow references to symbols
+ with these names in operands. */
+ if (asm_dialect == DIALECT_PSEUDOC)
+ {
+ uint8_t regno;
+
+ if (parse_bpf_register ((char *) name, 'r', &regno)
+ || parse_bpf_register ((char *) name, 'w', &regno))
+ {
+ as_bad (_("unexpected register name `%s' in expression"),
+ name);
+ return false;
+ }
+ }
+
if (symbol_find (name) != NULL)
return false;
@@ -1320,54 +1385,6 @@ bpf_parse_name (const char *name, expressionS *exp, enum expr_mode mode)
return true;
}
-/* Parse a BPF register name and return the corresponding register
- number. Return NULL in case of parse error, or a pointer to the
- first character in S that is not part of the register name. */
-
-static char *
-parse_bpf_register (char *s, char rw, uint8_t *regno)
-{
- if (asm_dialect == DIALECT_NORMAL)
- {
- rw = 'r';
- if (*s != '%')
- return NULL;
- s += 1;
-
- if (*s == 'f' && *(s + 1) == 'p')
- {
- *regno = 10;
- s += 2;
- return s;
- }
- }
-
- if (*s != rw)
- return NULL;
- s += 1;
-
- if (*s == '1')
- {
- if (*(s + 1) == '0')
- {
- *regno = 10;
- s += 2;
- }
- else
- {
- *regno = 1;
- s += 1;
- }
- }
- else if (*s >= '0' && *s <= '9')
- {
- *regno = *s - '0';
- s += 1;
- }
-
- return s;
-}
-
/* Collect a parse error message. */
static int partial_match_length = 0;
diff --git a/gas/doc/c-bpf.texi b/gas/doc/c-bpf.texi
index bdd9fde0f5a..25ae231d19c 100644
--- a/gas/doc/c-bpf.texi
+++ b/gas/doc/c-bpf.texi
@@ -113,7 +113,12 @@ Read-only frame pointer register.
@noindent
Note that in the Pseudo-C syntax register names are not preceded by
-@code{%} characters.
+@code{%} characters. A consequence of that is that in contexts like
+instruction operands, where both register names and expressions
+involving symbols are expected, there is no way to disambiguate
+between them. In order to keep things simple, this assembler does not
+allow to refer to symbols whose names collide with register names in
+instruction operands.
@node BPF Directives
@section BPF Directives
diff --git a/gas/testsuite/gas/bpf/bpf.exp b/gas/testsuite/gas/bpf/bpf.exp
index fcbeccd8ecd..5bcd8c483a0 100644
--- a/gas/testsuite/gas/bpf/bpf.exp
+++ b/gas/testsuite/gas/bpf/bpf.exp
@@ -73,6 +73,10 @@ if {[istarget bpf*-*-*]} {
run_dump_test disp32-overflow
run_dump_test imm32-overflow
+ # In Pseudo-C it is not possible to refer to symbols
+ # as operands that have the same name than registers.
+ run_dump_test regs-for-symbols-pseudoc
+
# Test that parser does not create undefined symbols
run_dump_test asm-extra-sym-1
}
diff --git a/gas/testsuite/gas/bpf/regs-for-symbols-pseudoc.d b/gas/testsuite/gas/bpf/regs-for-symbols-pseudoc.d
new file mode 100644
index 00000000000..d99ec8f94c2
--- /dev/null
+++ b/gas/testsuite/gas/bpf/regs-for-symbols-pseudoc.d
@@ -0,0 +1,3 @@
+#as: -EL -mdialect=pseudoc
+#source: regs-for-symbols-pseudoc.s
+#error_output: regs-for-symbols-pseudoc.l
diff --git a/gas/testsuite/gas/bpf/regs-for-symbols-pseudoc.l b/gas/testsuite/gas/bpf/regs-for-symbols-pseudoc.l
new file mode 100644
index 00000000000..eeda735fb99
--- /dev/null
+++ b/gas/testsuite/gas/bpf/regs-for-symbols-pseudoc.l
@@ -0,0 +1,8 @@
+.*: Assembler messages:
+.*:1: Error: unexpected register name `w3' in expression
+.*:2: Error: unexpected register name `r3' in expression
+.*:2: Error: unexpected register name `r3' in expression
+.*:3: Error: unexpected register name `r3' in expression
+.*:3: Error: unexpected register name `r3' in expression
+.*:4: Error: unexpected register name `r3' in expression
+.*:4: Error: unexpected register name `r3' in expression
diff --git a/gas/testsuite/gas/bpf/regs-for-symbols-pseudoc.s b/gas/testsuite/gas/bpf/regs-for-symbols-pseudoc.s
new file mode 100644
index 00000000000..693787d5479
--- /dev/null
+++ b/gas/testsuite/gas/bpf/regs-for-symbols-pseudoc.s
@@ -0,0 +1,4 @@
+ goto w3
+ r2 = r3 ll
+ r2 = r3+1 ll
+ r2 = 1+r3 ll