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.
This commit is contained in:
parent
c59e30ed17
commit
9bc769718d
@ -1,3 +1,9 @@
|
||||
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.
|
||||
|
1
libctf/testsuite/libctf-lookup/enum-symbol-ctf.c
Normal file
1
libctf/testsuite/libctf-lookup/enum-symbol-ctf.c
Normal file
@ -0,0 +1 @@
|
||||
enum {red1, green1, blue1} primary1;
|
153
libctf/testsuite/libctf-lookup/enum-symbol.c
Normal file
153
libctf/testsuite/libctf-lookup/enum-symbol.c
Normal file
@ -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;
|
||||
}
|
6
libctf/testsuite/libctf-lookup/enum-symbol.lk
Normal file
6
libctf/testsuite/libctf-lookup/enum-symbol.lk
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user