libctf: by-kind tests

These tiny testcases test opening-and-dumping of single type kinds,
and also linking and then opening-and-dumping.
This commit is contained in:
Nick Alcock
2025-04-25 21:50:14 +01:00
parent 66bc737718
commit 4a4fbfd42e
34 changed files with 486 additions and 0 deletions

View File

@@ -0,0 +1 @@
int foo[16] __attribute__((used));

View File

@@ -0,0 +1,15 @@
# lookup: open-and-dump.c
# source: array.c
#...
Section \.bss:
0: 0x4: foo: 0x3: \(kind 3\) int \[16\] .*
Types:
0x1: \(kind 1\) int .*
0x2: \(kind 1\) long unsigned int .*
0x3: \(kind 3\) int \[16\] .*
0x4: \(kind 14\) int foo .*
0x5: \(kind 15\) DATASEC \(".bss", 1\)

View File

@@ -0,0 +1 @@
const int foo __attribute__((used));

View File

@@ -0,0 +1,14 @@
# lookup: open-and-dump.c
# source: const.c
#...
Section \.rodata:
0: 0x3: foo: 0x2: \(kind 10\) const int .*
Types:
0x1: \(kind 1\) int .*
0x2: \(kind 10\) const int .*
0x3: \(kind 14\) const int foo .*
0x4: \(kind 15\) DATASEC \(".rodata", 1\)

View File

@@ -0,0 +1 @@
int foo __attribute__((section(".BAR")));

View File

@@ -0,0 +1,14 @@
# lookup: open-and-dump.c
# source: datasec.c
#...
Section \.BAR:
0: 0x2: foo: 0x1: \(kind 1\) int .*
Types:
0x1: \(kind 1\) int .*
0x2: \(kind 14\) int foo .*
0x3: \(kind 15\) DATASEC \(".BAR", 1\)

View File

@@ -0,0 +1,7 @@
int foo __attribute__((btf_decl_tag("dtag")));
struct
{
char a;
char b __attribute__((btf_decl_tag("dtag2")));
} bar __attribute__((used));

View File

@@ -0,0 +1,23 @@
# lookup: open-and-dump.c
# source: decl-tag.c
#...
Section \.bss:
0: 0x[45]: bar: 0x2: \(kind 4\) struct .*
0: 0x[56]: foo: 0x1: \(kind 1\) int .*
Types:
0x1: \(kind 1\) int .*
0x2: \(kind 4\) struct .*
\[0x0\] a: ID 0x3: \(kind 1\) char .*
\[0x8\] b: ID 0x3: \(kind 1\) char .*
0x3: \(kind 1\) char .*
#...
0x[45]: \(kind 14\) struct bar .*
#...
0x[56]: \(kind 14\) int foo .*
0x[67]: \(kind 17\) int foo btf_decl_tag \("dtag"\) .* -> 0x[56]: \(kind 14\) int foo .*
0x[78]: \(kind 17\) struct btf_decl_tag \("dtag2"\) .* -> 0x2: \(kind 4\) struct .*
#...

View File

@@ -0,0 +1,2 @@
enum baz { Monday, Tuesday, Wednesday } foo __attribute__((used));
enum big { BigMonday = 66666666666, BigTuesday, BigWednesday, BigFrysday } bar __attribute__((used));

View File

@@ -0,0 +1,22 @@
# lookup: open-and-dump.c
# source: enum.c
#...
Section \.bss:
[0-9]*: 0x[0-9]*: bar: 0x3: \(kind 19\) enum big .*
[0-9]*: 0x[0-9]*: foo: 0x1: \(kind 6\) enum baz .*
Types:
0x1: \(kind 6\) enum baz .*
*Monday: 0
*Tuesday: 1
#...
0x2: .* unsigned int .*
0x3: \(kind 19\) enum big .*
*BigMonday: 66666666666
*BigTuesday: 66666666667
#...
0x4: .* long unsigned int .*
#...

View File

@@ -0,0 +1,2 @@
struct foo;
struct foo *bar;

View File

@@ -0,0 +1,14 @@
# lookup: open-and-dump.c
# source: forward.c
#...
Section \.bss:
0: 0x3: bar: 0x2: \(kind 2\) struct foo \* .* -> 0x1: \(kind 7\) struct foo
Types:
0x1: \(kind 7\) struct foo
0x2: \(kind 2\) struct foo \* .* -> 0x1: \(kind 7\) struct foo
0x3: \(kind 14\) struct foo bar .* -> 0x2: \(kind 2\) struct foo \* .* -> 0x1: \(kind 7\) struct foo
0x4: \(kind 15\) DATASEC \(".bss", 1\)

View File

@@ -0,0 +1,7 @@
int func (int) __attribute__((used));
int __attribute__ ((used))
func (int foo)
{
return foo + 1;
}

View File

@@ -0,0 +1,9 @@
# lookup: open-and-dump.c
# source: function.c
#...
Types:
0x1: \(kind 1\) int .*
0x2: \(kind 13\) int \(\*\) \(int foo\) .*
0x3: \(kind 12\) int \(\*\) \(int foo\) func .*

View File

@@ -0,0 +1 @@
int foo __attribute__((used));

View File

@@ -0,0 +1,13 @@
# lookup: open-and-dump.c
# source: integer.c
#...
Section \.bss:
0: 0x2: foo: 0x1: \(kind 1\) int .*
Types:
0x1: \(kind 1\) int .*
0x2: \(kind 14\) int foo .*
0x3: \(kind 15\) DATASEC \(".bss", 1\)

View File

@@ -0,0 +1,86 @@
#include <ctf-api.h>
#include <stdio.h>
#include <stdlib.h>
static void
dump_ctf_errs (ctf_dict_t *fp)
{
ctf_next_t *it = NULL;
char *errtext;
int is_warning;
int err;
/* Dump accumulated errors and warnings. */
while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
{
fprintf (stderr, "%s: %s\n", is_warning ? "warning": "error",
errtext);
free (errtext);
}
if (err != ECTF_NEXT_END)
{
fprintf (stderr, "CTF error: cannot get CTF errors: `%s'",
ctf_errmsg (err));
}
}
int main (int argc, char *argv[])
{
ctf_archive_t *arc;
ctf_dict_t *fp;
ctf_next_t *i = NULL;
const char *name;
int err;
if (argc != 2)
{
fprintf (stderr, "Syntax: open-and-dump FILE\n");
exit (1);
}
if ((arc = ctf_open (argv[1], NULL, &err)) == NULL)
goto open_err;
while ((fp = ctf_archive_next (arc, &i, &name, 0, &err)) != NULL)
{
ctf_dump_state_t *s = NULL;
char *item;
int j;
ctf_sect_names_t things[] = { CTF_SECT_HEADER, CTF_SECT_VAR, CTF_SECT_TYPE, 666 };
const char *thing_names[] = { "Header", "Variables", "Types", NULL };
fprintf (stderr, "\nArchive member: %s\n", name);
for (j = 0; things[j] != 666; j++)
{
printf ("\n%s: \n\n", thing_names[j]);
while ((item = ctf_dump (fp, &s, things[j], NULL, NULL)) != NULL)
{
printf ("%s", item);
free (item);
}
if (ctf_errno (fp))
{
fprintf (stderr, "Dumping failed: %s, %s\n", j,
ctf_errmsg (ctf_errno (fp)));
break;
}
}
dump_ctf_errs (fp);
ctf_dict_close (fp);
}
if (err != ECTF_NEXT_END)
{
ctf_next_destroy (i);
fprintf (stderr, "Iteration failed: %s\n", ctf_errmsg (ctf_errno (fp)));
}
ctf_close (arc);
return 0;
open_err:
fprintf (stderr, "%s: cannot open: %s\n", argv[0], ctf_errmsg (err));
return 1;
}

View File

@@ -0,0 +1 @@
int *foo __attribute__((used));

View File

@@ -0,0 +1,14 @@
# lookup: open-and-dump.c
# source: pointer.c
#...
Section \.bss:
0: 0x3: foo: 0x2: \(kind 2\) int \* .*
Types:
0x1: \(kind 1\) int .*
0x2: \(kind 2\) int \* .*
0x3: \(kind 14\) int foo .*
0x4: \(kind 15\) DATASEC \(".bss", 1\)

View File

@@ -0,0 +1 @@
int * restrict foo __attribute__((used));

View File

@@ -0,0 +1,15 @@
# lookup: open-and-dump.c
# source: restrict.c
#...
Section \.bss:
0: 0x4: foo: 0x3: \(kind 11\) int \*restrict .*
Types:
0x1: \(kind 1\) int .*
0x2: \(kind 2\) int \* .*
0x3: \(kind 11\) int \*restrict .*
0x4: \(kind 14\) int foo .*
0x5: \(kind 15\) DATASEC \(".bss", 1\)

View File

@@ -0,0 +1,6 @@
struct
{
int a:4;
int b:4;
int c;
} foo __attribute__((used));

View File

@@ -0,0 +1,17 @@
# lookup: open-and-dump.c
# source: struct.c
#...
Section \.bss:
0: 0x3: foo: 0x1: \(kind 4\) struct .*
Types:
0x1: \(kind 4\) struct .*
\[0x0\] a:4: .* int .*
\[0x4\] b:4: .* int .*
\[0x[0-9a-f]*\] c: .* int .*
0x2: \(kind 1\) int .*
0x3: \(kind 14\) struct foo .*
0x4: \(kind 15\) DATASEC \(".bss", 1\)

View File

@@ -0,0 +1 @@
int foo __attribute__((btf_type_tag("ttag")));

View File

@@ -0,0 +1,14 @@
# lookup: open-and-dump.c
# source: type-tag.c
#...
Section \.bss:
0: 0x[23]: foo: 0x[234]: \(kind 18\) ttag .* -> 0x1: \(kind 1\) int .*
Types:
0x1: \(kind 1\) int .*
#...
0x[23]: \(kind 18\) ttag .* -> 0x1: \(kind 1\) int .*
#...

View File

@@ -0,0 +1,6 @@
union bar
{
int a:4;
int b:4;
int c;
} foo __attribute__((used));

View File

@@ -0,0 +1,17 @@
# lookup: open-and-dump.c
# source: union.c
#...
Section \.bss:
0: 0x3: foo: 0x1: \(kind 5\) union bar .*
Types:
0x1: \(kind 5\) union bar .*
\[0x0\] a:4: .* int .*
\[0x0\] b:4: .* int .*
\[0x0\] c: .* int .*
0x2: \(kind 1\) int .*
0x3: \(kind 14\) union bar foo .*
0x4: \(kind 15\) DATASEC \(".bss", 1\)

View File

@@ -0,0 +1 @@
volatile int foo __attribute__((used));

View File

@@ -0,0 +1,14 @@
# lookup: open-and-dump.c
# source: volatile.c
#...
Section \.bss:
0: 0x3: foo: 0x2: \(kind 9\) volatile int .*
Types:
0x1: \(kind 1\) int .*
0x2: \(kind 9\) volatile int .*
0x3: \(kind 14\) volatile int foo .*
0x4: \(kind 15\) DATASEC \(".bss", 1\)

View File

@@ -0,0 +1,48 @@
# Copyright (C) 2021-2025 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
#
if ![is_elf_format] {
unsupported "CTF needs bfd changes to be emitted on non-ELF"
return 0
}
if {![check_ctf_available]} {
unsupported "no CTF format support in the compiler"
return 0
}
if {[info exists env(LC_ALL)]} {
set old_lc_all $env(LC_ALL)
}
set env(LC_ALL) "C"
set ctf_test_list [lsort [glob -nocomplain $srcdir/$subdir/by-kind/*.lk]]
foreach ctf_test $ctf_test_list {
verbose [file rootname $ctf_test]
verbose running lookup test on $ctf_test
run_lookup_test [file rootname $ctf_test ] {link: on}
}
if {[info exists old_lc_all]} {
set env(LC_ALL) $old_lc_all
} else {
unset env(LC_ALL)
}

View File

@@ -0,0 +1,48 @@
# Copyright (C) 2021-2025 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
#
if ![is_elf_format] {
unsupported "CTF needs bfd changes to be emitted on non-ELF"
return 0
}
if {![check_ctf_available]} {
unsupported "no CTF format support in the compiler"
return 0
}
if {[info exists env(LC_ALL)]} {
set old_lc_all $env(LC_ALL)
}
set env(LC_ALL) "C"
set ctf_test_list [lsort [glob -nocomplain $srcdir/$subdir/by-kind/*.lk]]
foreach ctf_test $ctf_test_list {
verbose [file rootname $ctf_test]
verbose running lookup test on $ctf_test
run_lookup_test [file rootname $ctf_test]
}
if {[info exists old_lc_all]} {
set env(LC_ALL) $old_lc_all
} else {
unset env(LC_ALL)
}

View File

@@ -0,0 +1,4 @@
#define __s __attribute__((section("NEW_SEC")))
int a;
int b __s;

View File

@@ -0,0 +1,45 @@
#include "config.h"
#include <ctf-api.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main (int argc, char *argv[])
{
ctf_archive_t *ctf;
ctf_dict_t *fp;
int err;
ctf_id_t id = 0;
ctf_next_t *it = NULL;
const char *name = NULL;
if (argc != 2)
{
fprintf (stderr, "Syntax: %s PROGRAM\n", argv[0]);
exit(1);
}
if ((ctf = ctf_open (argv[1], NULL, &err)) == NULL)
goto open_err;
if ((fp = ctf_dict_open (ctf, NULL, &err)) == NULL)
goto open_err;
while ((id = ctf_type_next(fp, &it, NULL, 1)) != CTF_ERR)
{
printf(ctf_type_aname(fp, id));
printf("\n");
}
ctf_dict_close(fp);
ctf_close (ctf);
return 0;
open_err:
fprintf (stderr, "%s: cannot open: %s\n", argv[0], ctf_errmsg (err));
return 1;
lookup_err:
fprintf (stderr, "Lookup failed: %s\n", ctf_errmsg (ctf_errno (fp)));
return 1;
}

View File

@@ -0,0 +1,2 @@
# lookup: lookup-datasec.c
# source: lookup-datasec-ctf.c