diff --git a/gcc/btfout.cc b/gcc/btfout.cc index a5e0d640e19..db4f1084f85 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -486,7 +486,15 @@ btf_collect_datasec (ctf_container_ref ctfc) /* Mark extern variables. */ if (DECL_EXTERNAL (node->decl)) - dvd->dvd_visibility = BTF_VAR_GLOBAL_EXTERN; + { + dvd->dvd_visibility = BTF_VAR_GLOBAL_EXTERN; + + /* PR112849: avoid assuming a section for extern decls without + an explicit section, which would result in incorrectly + emitting a BTF_KIND_DATASEC entry for them. */ + if (node->get_section () == NULL) + continue; + } const char *section_name = get_section_name (node); if (section_name == NULL) diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c new file mode 100644 index 00000000000..297340cabfa --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c @@ -0,0 +1,28 @@ +/* PR debug/112849 + Test that we do not incorrectly create BTF_KIND_DATASEC entries for + extern decls with no known section. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +extern int VERSION __attribute__((section (".version"))); + +extern int test_bss1; +extern int test_data1; + +int test_bss2; +int test_data2 = 2; + +int +foo (void) +{ + test_bss2 = VERSION; + return test_bss1 + test_data1 + test_data2; +} + +/* There should be 3 DATASEC entries total. Of the extern decls, only VERSION + has a known section; entries are not created for the other two. */ +/* { dg-final { scan-assembler-times "bts_type" 3 } } */ +/* { dg-final { scan-assembler-times "bts_type: \\(BTF_KIND_VAR 'test_data2'\\)" 1 } } */ +/* { dg-final { scan-assembler-times "bts_type: \\(BTF_KIND_VAR 'test_bss2'\\)" 1 } } */ +/* { dg-final { scan-assembler-times "bts_type: \\(BTF_KIND_VAR 'VERSION'\\)" 1 } } */