From: Nick Alcock Date: Tue, 5 Jan 2021 13:25:56 +0000 (+0000) Subject: libctf: new test of enum lookups with the _next iterator X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9bc769718db238c98f14aafc335426f47b52d4cd;p=binutils-gdb.git libctf: new test of enum lookups with the _next iterator I had reports that this doesn't work. This test shows it working (and also shows how annoying it is to do symbol lookup by name with the present API: we need a ctf_arc_lookup_symbol_name for users that don't already have a symtab handy). libctf/ChangeLog 2021-01-05 Nick Alcock * testsuite/libctf-lookup/enum-symbol.lk: New symbol-lookup test. * testsuite/libctf-lookup/enum-symbol-ctf.c: New CTF input. * testsuite/libctf-lookup/enum-symbol.c: New lookup test. --- diff --git a/libctf/ChangeLog b/libctf/ChangeLog index 42ca1c61491..f11b511922e 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,3 +1,9 @@ +2021-01-05 Nick Alcock + + * testsuite/libctf-lookup/enum-symbol.lk: New symbol-lookup test. + * testsuite/libctf-lookup/enum-symbol-ctf.c: New CTF input. + * testsuite/libctf-lookup/enum-symbol.c: New lookup test. + 2021-01-05 Nick Alcock * Makefile.am (EXPECT): New. diff --git a/libctf/testsuite/libctf-lookup/enum-symbol-ctf.c b/libctf/testsuite/libctf-lookup/enum-symbol-ctf.c new file mode 100644 index 00000000000..f7f99c67c16 --- /dev/null +++ b/libctf/testsuite/libctf-lookup/enum-symbol-ctf.c @@ -0,0 +1 @@ +enum {red1, green1, blue1} primary1; diff --git a/libctf/testsuite/libctf-lookup/enum-symbol.c b/libctf/testsuite/libctf-lookup/enum-symbol.c new file mode 100644 index 00000000000..4f63b61b803 --- /dev/null +++ b/libctf/testsuite/libctf-lookup/enum-symbol.c @@ -0,0 +1,153 @@ +#include "config.h" +#include +#include +#include +#include +#include +#include +#include + +ssize_t symidx_64 (ctf_sect_t *s, ctf_sect_t *strsect, int little_endian, const char *name) +{ + const char *strs = (const char *) strsect->cts_data; + size_t i; + Elf64_Sym *sym = (Elf64_Sym *) s->cts_data; + for (i = 0; i < s->cts_size / s->cts_entsize; i++, sym++) + { + Elf64_Word nameoff = sym->st_name; +#ifdef WORDS_BIGENDIAN + if (little_endian) + swap_thing (nameoff); +#else + if (!little_endian) + swap_thing (nameoff); +#endif + if (strcmp (strs + nameoff, name) == 0) + return i; + } + return -1; +} + +ssize_t symidx_32 (ctf_sect_t *s, ctf_sect_t *strsect, int little_endian, const char *name) +{ + const char *strs = (const char *) strsect->cts_data; + size_t i; + Elf32_Sym *sym = (Elf32_Sym *) s->cts_data; + for (i = 0; i < s->cts_size / s->cts_entsize; i++, sym++) + { + Elf32_Word nameoff = sym->st_name; +#ifdef WORDS_BIGENDIAN + if (little_endian) + swap_thing (nameoff); +#else + if (!little_endian) + swap_thing (nameoff); +#endif + if (strcmp (strs + nameoff, name) == 0) + return i; + } + return -1; +} + +int +main (int argc, char *argv[]) +{ + ctf_dict_t *fp; + bfd *abfd; + ctf_archive_t *ctf; + ctf_sect_t symsect; + ctf_sect_t strsect; + ssize_t symidx; + int err; + ctf_id_t type; + ctf_next_t *i = NULL; + const char *name; + int val; + int little_endian; + + ssize_t (*get_sym) (ctf_sect_t *s, ctf_sect_t *strsect, int little_endian, const char *name); + + if (argc != 2) + { + fprintf (stderr, "Syntax: %s PROGRAM\n", argv[0]); + exit(1); + } + + /* Figure out the endianness of the symtab(s). */ + if ((abfd = bfd_openr (argv[1], NULL)) == NULL + || !bfd_check_format (abfd, bfd_object)) + goto bfd_open_err; + little_endian = bfd_little_endian (abfd); + bfd_close_all_done (abfd); + + if ((ctf = ctf_open (argv[1], NULL, &err)) == NULL) + goto open_err; + + if ((fp = ctf_dict_open (ctf, NULL, &err)) == NULL) + goto open_err; + + symsect = ctf_getsymsect (fp); + strsect = ctf_getstrsect (fp); + if (symsect.cts_data == NULL + || strsect.cts_data == NULL) + { + fprintf (stderr, "%s: no symtab or strtab\n", argv[0]); + return 1; + } + + ctf_dict_close (fp); + + if (symsect.cts_entsize != sizeof (Elf64_Sym) && + symsect.cts_entsize != sizeof (Elf32_Sym)) + { + fprintf (stderr, "%s: unknown symsize: %lx\n", argv[0], + symsect.cts_size); + return 1; + } + + switch (symsect.cts_entsize) + { + case sizeof (Elf64_Sym): get_sym = symidx_64; break; + case sizeof (Elf32_Sym): get_sym = symidx_32; break; + } + + if ((symidx = get_sym (&symsect, &strsect, little_endian, "primary1")) < 0) + { + fprintf (stderr, "%s: symbol not found: primary1\n", argv[0]); + return 1; + } + + /* Fish it out, then fish out all its enumerand/value pairs. */ + + if ((fp = ctf_arc_lookup_symbol (ctf, symidx, &type, &err)) == NULL) + goto sym_err; + + while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL) + { + printf ("%s has value %i\n", name, val); + } + if (ctf_errno (fp) != ECTF_NEXT_END) + goto nerr; + + ctf_dict_close (fp); + ctf_close (ctf); + + return 0; + + bfd_open_err: + fprintf (stderr, "%s: cannot open: %s\n", argv[0], bfd_errmsg (bfd_get_error ())); + return 1; + + open_err: + fprintf (stderr, "%s: cannot open: %s\n", argv[0], ctf_errmsg (err)); + return 1; + sym_err: + fprintf (stderr, "%s: Symbol lookup error: %s\n", argv[0], ctf_errmsg (err)); + return 1; + err: + fprintf (stderr, "Lookup failed: %s\n", ctf_errmsg (ctf_errno (fp))); + return 1; + nerr: + fprintf (stderr, "iteration failed: %s\n", ctf_errmsg (ctf_errno (fp))); + return 1; +} diff --git a/libctf/testsuite/libctf-lookup/enum-symbol.lk b/libctf/testsuite/libctf-lookup/enum-symbol.lk new file mode 100644 index 00000000000..e83030ea28f --- /dev/null +++ b/libctf/testsuite/libctf-lookup/enum-symbol.lk @@ -0,0 +1,6 @@ +# lookup: enum-symbol.c +# source: enum-symbol-ctf.c +# link: on +red1 has value 0 +green1 has value 1 +blue1 has value 2