aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJose E. Marchesi <jose.marchesi@oracle.com>2023-12-01 10:38:00 +0100
committerJose E. Marchesi <jose.marchesi@oracle.com>2023-12-01 10:42:40 +0100
commitb506834e7fa939e43f784d417f0e9b4ded91ebd2 (patch)
tree03678147503f1c013f751efa357894509109ca52
parent6563d6767ed0f702458f8975cd5d73676c4604cc (diff)
downloadgcc-b506834e7fa939e43f784d417f0e9b4ded91ebd2.zip
gcc-b506834e7fa939e43f784d417f0e9b4ded91ebd2.tar.gz
gcc-b506834e7fa939e43f784d417f0e9b4ded91ebd2.tar.bz2
bpf: quote section names whenever necessary in assembly output
In BPF section names are used to encode the kind of BPF program and other metadata, involving all sort of non alphanumeric characters. For example: /* use auto-attach format for section definition. */ SEC("uretprobe//proc/self/exe:trigger_func2") int handle_uretprobe_byname(struct pt_regs *ctx) { uretprobe_byname_res = 6; return 0; } The above requires to quote the section name in the output assembly file, since otherwise the // in the name would be interpreted by the assembler lexer as the beginning of a line comment. This patch makes the BPF backend to emit quoted section names in .section directives if the name requires to be quoted. Simple section names whose constituent characters are in the set [0-9a-zA-Z_] are still emitted unquoted. Tested in target bpf-unknown-none-gcc and host x86_64-linux-gnu. gcc/ChangeLog * config/bpf/bpf.cc (bpf_asm_named_section): New function. (TARGET_ASM_NAMED_SECTION): Set to bpf_asm_named_section. gcc/testsuite/ChangeLog * gcc.target/bpf/section-name-quoting-1.c: New test.
-rw-r--r--gcc/config/bpf/bpf.cc55
-rw-r--r--gcc/testsuite/gcc.target/bpf/section-name-quoting-1.c20
2 files changed, 75 insertions, 0 deletions
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 4bfba28..ffd83a7 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -1100,6 +1100,61 @@ bpf_debug_unwind_info ()
#undef TARGET_ASM_ALIGNED_DI_OP
#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
+/* Implement target hook TARGET_ASM_NAMED_SECTION. */
+
+static void
+bpf_asm_named_section (const char *name, unsigned int flags,
+ tree decl)
+{
+ /* In BPF section names are used to encode the kind of BPF program
+ and other metadata, involving all sort of non alphanumeric
+ characters. This includes for example names like /foo//bar/baz.
+ This makes it necessary to quote section names to make sure the
+ assembler doesn't get confused. For example, the example above
+ would be interpreted unqouted as a section name "/foo" followed
+ by a line comment "//bar/baz".
+
+ Note that we only quote the section name if it contains any
+ character not in the set [0-9a-zA-Z_]. This is because
+ default_elf_asm_named_section generally expects unquoted names
+ and checks for particular names like
+ __patchable_function_entries. */
+
+ bool needs_quoting = false;
+
+ for (const char *p = name; *p != '\0'; ++p)
+ if (!(*p == '_'
+ || (*p >= '0' && *p <= '9')
+ || (*p >= 'a' && *p <= 'z')
+ || (*p >= 'A' && *p <= 'Z')))
+ needs_quoting = true;
+
+ if (needs_quoting)
+ {
+ char *quoted_name
+ = (char *) xcalloc (1, strlen (name) * 2 + 2);
+ char *q = quoted_name;
+
+ *(q++) = '"';
+ for (const char *p = name; *p != '\0'; ++p)
+ {
+ if (*p == '"' || *p == '\\')
+ *(q++) = '\\';
+ *(q++) = *p;
+ }
+ *(q++) = '"';
+ *(q++) = '\0';
+
+ default_elf_asm_named_section (quoted_name, flags, decl);
+ free (quoted_name);
+ }
+ else
+ default_elf_asm_named_section (name, flags, decl);
+}
+
+#undef TARGET_ASM_NAMED_SECTION
+#define TARGET_ASM_NAMED_SECTION bpf_asm_named_section
+
/* Implement target hook small_register_classes_for_mode_p. */
static bool
diff --git a/gcc/testsuite/gcc.target/bpf/section-name-quoting-1.c b/gcc/testsuite/gcc.target/bpf/section-name-quoting-1.c
new file mode 100644
index 0000000..2fa48de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/section-name-quoting-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+/* Make sure that section names that contain characters not in the set
+ [0-9a-zA-Z_] get quoted for the assembler. */
+
+__attribute__((section ("uretprobe//proc/self/exe:trigger_func2")))
+void
+foo ()
+{
+}
+
+__attribute__((section ("trigger_func3")))
+void
+bar ()
+{
+}
+
+/* { dg-final { scan-assembler {\.section\t"uretprobe//proc/self/exe:trigger_func2"} } } */
+/* { dg-final { scan-assembler {\.section\ttrigger_func3} } } */