diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2021-01-05 13:25:56 +0000 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2021-01-05 14:53:40 +0000 |
commit | 9bc769718db238c98f14aafc335426f47b52d4cd (patch) | |
tree | 9816bab19bde2c832446c0ba8b4f8c11d4bfabd6 /libctf | |
parent | c59e30ed1727135f8efb79890f2c458f73709757 (diff) | |
download | gdb-9bc769718db238c98f14aafc335426f47b52d4cd.zip gdb-9bc769718db238c98f14aafc335426f47b52d4cd.tar.gz gdb-9bc769718db238c98f14aafc335426f47b52d4cd.tar.bz2 |
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 <nick.alcock@oracle.com>
* 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.
Diffstat (limited to 'libctf')
-rw-r--r-- | libctf/ChangeLog | 6 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/enum-symbol-ctf.c | 1 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/enum-symbol.c | 153 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/enum-symbol.lk | 6 |
4 files changed, 166 insertions, 0 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog index 42ca1c6..f11b511 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,5 +1,11 @@ 2021-01-05 Nick Alcock <nick.alcock@oracle.com> + * 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 <nick.alcock@oracle.com> + * Makefile.am (EXPECT): New. (RUNTEST): Likewise. (RUNTESTFLAGS): Likewise. 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 0000000..f7f99c6 --- /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 0000000..4f63b61 --- /dev/null +++ b/libctf/testsuite/libctf-lookup/enum-symbol.c @@ -0,0 +1,153 @@ +#include "config.h" +#include <bfd.h> +#include <elf.h> +#include <ctf-api.h> +#include <swap.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +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 0000000..e83030e --- /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 |