diff --git a/include/ChangeLog b/include/ChangeLog index e2aabdc36b7..f5be0c0154e 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2020-07-22 Nick Alcock + + * ctf-api.h (ECTF_*): Improve comments. + (ECTF_NERR): New. + 2020-07-22 Nick Alcock * ctf-api.h: Fix typos in comments. diff --git a/include/ctf-api.h b/include/ctf-api.h index bb1cf0f50eb..2e3e28b840c 100644 --- a/include/ctf-api.h +++ b/include/ctf-api.h @@ -153,60 +153,62 @@ typedef struct ctf_snapshot_id enum { - ECTF_FMT = ECTF_BASE, /* File is not in CTF or ELF format. */ - ECTF_BFDERR, /* BFD error. */ - ECTF_CTFVERS, /* CTF version is more recent than libctf. */ - ECTF_BFD_AMBIGUOUS, /* Ambiguous BFD target. */ - ECTF_SYMTAB, /* Symbol table uses invalid entry size. */ - ECTF_SYMBAD, /* Symbol table data buffer invalid. */ - ECTF_STRBAD, /* String table data buffer invalid. */ - ECTF_CORRUPT, /* File data corruption detected. */ - ECTF_NOCTFDATA, /* ELF file does not contain CTF data. */ - ECTF_NOCTFBUF, /* Buffer does not contain CTF data. */ - ECTF_NOSYMTAB, /* Symbol table data is not available. */ - ECTF_NOPARENT, /* Parent CTF container is not available. */ - ECTF_DMODEL, /* Data model mismatch. */ - ECTF_LINKADDEDLATE, /* File added to link too late. */ - ECTF_ZALLOC, /* Failed to allocate (de)compression buffer. */ - ECTF_DECOMPRESS, /* Failed to decompress CTF data. */ - ECTF_STRTAB, /* String table for this string is missing. */ - ECTF_BADNAME, /* String offset is corrupt w.r.t. strtab. */ - ECTF_BADID, /* Invalid type ID number. */ - ECTF_NOTSOU, /* Type is not a struct or union. */ - ECTF_NOTENUM, /* Type is not an enum. */ - ECTF_NOTSUE, /* Type is not a struct, union, or enum. */ - ECTF_NOTINTFP, /* Type is not an integer, float, or enum. */ - ECTF_NOTARRAY, /* Type is not an array. */ - ECTF_NOTREF, /* Type does not reference another type. */ - ECTF_NAMELEN, /* Buffer is too small to hold type name. */ - ECTF_NOTYPE, /* No type found corresponding to name. */ - ECTF_SYNTAX, /* Syntax error in type name. */ - ECTF_NOTFUNC, /* Symbol entry or type is not a function. */ - ECTF_NOFUNCDAT, /* No func info available for function. */ - ECTF_NOTDATA, /* Symtab entry does not refer to a data obj. */ - ECTF_NOTYPEDAT, /* No type info available for object. */ - ECTF_NOLABEL, /* No label found corresponding to name. */ - ECTF_NOLABELDATA, /* File does not contain any labels. */ - ECTF_NOTSUP, /* Feature not supported. */ - ECTF_NOENUMNAM, /* Enum element name not found. */ - ECTF_NOMEMBNAM, /* Member name not found. */ - ECTF_RDONLY, /* CTF container is read-only. */ - ECTF_DTFULL, /* CTF type is full (no more members allowed). */ - ECTF_FULL, /* CTF container is full. */ - ECTF_DUPLICATE, /* Duplicate member or variable name. */ - ECTF_CONFLICT, /* Conflicting type definition present. */ - ECTF_OVERROLLBACK, /* Attempt to roll back past a ctf_update. */ - ECTF_COMPRESS, /* Failed to compress CTF data. */ - ECTF_ARCREATE, /* Error creating CTF archive. */ - ECTF_ARNNAME, /* Name not found in CTF archive. */ - ECTF_SLICEOVERFLOW, /* Overflow of type bitness or offset in slice. */ - ECTF_DUMPSECTUNKNOWN, /* Unknown section number in dump. */ - ECTF_DUMPSECTCHANGED, /* Section changed in middle of dump. */ - ECTF_NOTYET, /* Feature not yet implemented. */ - ECTF_INTERNAL, /* Internal error in link. */ - ECTF_NONREPRESENTABLE /* Type not representable in CTF. */ + ECTF_FMT = ECTF_BASE, /* File is not in CTF or ELF format. */ + ECTF_BFDERR, /* BFD error. */ + ECTF_CTFVERS, /* CTF dict version is too new for libctf. */ + ECTF_BFD_AMBIGUOUS, /* Ambiguous BFD target. */ + ECTF_SYMTAB, /* Symbol table uses invalid entry size. */ + ECTF_SYMBAD, /* Symbol table data buffer is not valid. */ + ECTF_STRBAD, /* String table data buffer is not valid. */ + ECTF_CORRUPT, /* File data structure corruption detected. */ + ECTF_NOCTFDATA, /* File does not contain CTF data. */ + ECTF_NOCTFBUF, /* Buffer does not contain CTF data. */ + ECTF_NOSYMTAB, /* Symbol table information is not available. */ + ECTF_NOPARENT, /* The parent CTF dictionary is unavailable. */ + ECTF_DMODEL, /* Data model mismatch. */ + ECTF_LINKADDEDLATE, /* File added to link too late. */ + ECTF_ZALLOC, /* Failed to allocate (de)compression buffer. */ + ECTF_DECOMPRESS, /* Failed to decompress CTF data. */ + ECTF_STRTAB, /* External string table is not available. */ + ECTF_BADNAME, /* String name offset is corrupt. */ + ECTF_BADID, /* Invalid type identifier. */ + ECTF_NOTSOU, /* Type is not a struct or union. */ + ECTF_NOTENUM, /* Type is not an enum. */ + ECTF_NOTSUE, /* Type is not a struct, union, or enum. */ + ECTF_NOTINTFP, /* Type is not an integer, float, or enum. */ + ECTF_NOTARRAY, /* Type is not an array. */ + ECTF_NOTREF, /* Type does not reference another type. */ + ECTF_NAMELEN, /* Buffer is too small to hold type name. */ + ECTF_NOTYPE, /* No type found corresponding to name. */ + ECTF_SYNTAX, /* Syntax error in type name. */ + ECTF_NOTFUNC, /* Symbol table entry or type is not a function. */ + ECTF_NOFUNCDAT, /* No function information available for function. */ + ECTF_NOTDATA, /* Symbol table entry does not refer to a data object. */ + ECTF_NOTYPEDAT, /* No type information available for symbol. */ + ECTF_NOLABEL, /* No label found corresponding to name. */ + ECTF_NOLABELDATA, /* File does not contain any labels. */ + ECTF_NOTSUP, /* Feature not supported. */ + ECTF_NOENUMNAM, /* Enum element name not found. */ + ECTF_NOMEMBNAM, /* Member name not found. */ + ECTF_RDONLY, /* CTF container is read-only. */ + ECTF_DTFULL, /* CTF type is full (no more members allowed). */ + ECTF_FULL, /* CTF container is full. */ + ECTF_DUPLICATE, /* Duplicate member or variable name. */ + ECTF_CONFLICT, /* Conflicting type is already defined. */ + ECTF_OVERROLLBACK, /* Attempt to roll back past a ctf_update. */ + ECTF_COMPRESS, /* Failed to compress CTF data. */ + ECTF_ARCREATE, /* Error creating CTF archive. */ + ECTF_ARNNAME, /* Name not found in CTF archive. */ + ECTF_SLICEOVERFLOW, /* Overflow of type bitness or offset in slice. */ + ECTF_DUMPSECTUNKNOWN, /* Unknown section number in dump. */ + ECTF_DUMPSECTCHANGED, /* Section changed in middle of dump. */ + ECTF_NOTYET, /* Feature not yet implemented. */ + ECTF_INTERNAL, /* Internal error in link. */ + ECTF_NONREPRESENTABLE /* Type not representable in CTF. */ }; +#define ECTF_NERR (ECTF_NONREPRESENTABLE - ECTF_BASE + 1) /* Count of CTF errors. */ + /* The CTF data model is inferred to be the caller's data model or the data model of the given object, unless ctf_setmodel() is explicitly called. */ #define CTF_MODEL_ILP32 1 /* Object data model is ILP32. */ diff --git a/libctf/.gitignore b/libctf/.gitignore new file mode 100644 index 00000000000..b95386e97d3 --- /dev/null +++ b/libctf/.gitignore @@ -0,0 +1 @@ +ctf-error.h diff --git a/libctf/ChangeLog b/libctf/ChangeLog index 88884a255f1..74e977659a4 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,3 +1,17 @@ +2020-07-22 Nick Alcock + + * ctf-error.c: Include , for offsetof. + (_ctf_errlist): Migrate to... + (_ctf_errlist_t): ... this. + (_ctf_erridx): New, indexes into _ctf_errlist_t. + (_ctf_nerr): Remove. + (ctf_errmsg): Adjust accordingly. + * Makefile.am (BUILT_SOURCES): Note... + (ctf-error.h): ... this new rule. + * Makefile.in: Regenerate. + * mkerrors.sed: New, process ctf-api.h to generate ctf-error.h. + * .gitignore: New, ignore ctf-error.h. + 2020-07-22 Nick Alcock * ctf-impl.h: Fix typos in comments. diff --git a/libctf/Makefile.am b/libctf/Makefile.am index c672d07e142..cdd3a5c55d6 100644 --- a/libctf/Makefile.am +++ b/libctf/Makefile.am @@ -52,3 +52,8 @@ libctf_la_LIBADD = @BFD_LIBADD@ $(libctf_nobfd_la_LIBADD) libctf_la_DEPENDENCIES = @BFD_DEPENDENCIES@ libctf_la_LDFLAGS = $(libctf_nobfd_la_LDFLAGS) libctf_la_SOURCES = $(libctf_nobfd_la_SOURCES) ctf-open-bfd.c + +BUILT_SOURCES = ctf-error.h + +ctf-error.h: $(srcdir)/mkerrors.sed $(srcdir)/../include/ctf-api.h + sed -nf $(srcdir)/mkerrors.sed < $(srcdir)/../include/ctf-api.h > $@ diff --git a/libctf/Makefile.in b/libctf/Makefile.in index 9e6f2551a56..a26fa31da49 100644 --- a/libctf/Makefile.in +++ b/libctf/Makefile.in @@ -452,7 +452,8 @@ libctf_la_LIBADD = @BFD_LIBADD@ $(libctf_nobfd_la_LIBADD) libctf_la_DEPENDENCIES = @BFD_DEPENDENCIES@ libctf_la_LDFLAGS = $(libctf_nobfd_la_LDFLAGS) libctf_la_SOURCES = $(libctf_nobfd_la_SOURCES) ctf-open-bfd.c -all: config.h +BUILT_SOURCES = ctf-error.h +all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: @@ -855,13 +856,15 @@ distcleancheck: distclean $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am -check: check-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done -install: install-am +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am @@ -891,6 +894,7 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ @@ -965,7 +969,7 @@ ps-am: uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES -.MAKE: all install-am install-strip +.MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \ clean-cscope clean-generic clean-libLTLIBRARIES clean-libtool \ @@ -989,6 +993,9 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES .PRECIOUS: Makefile +ctf-error.h: $(srcdir)/mkerrors.sed $(srcdir)/../include/ctf-api.h + sed -nf $(srcdir)/mkerrors.sed < $(srcdir)/../include/ctf-api.h > $@ + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/libctf/ctf-error.c b/libctf/ctf-error.c index c457aa0a29f..84d14d59323 100644 --- a/libctf/ctf-error.c +++ b/libctf/ctf-error.c @@ -18,71 +18,54 @@ . */ #include +#include -static const char *const _ctf_errlist[] = { - "File is not in CTF or ELF format", /* ECTF_FMT */ - "BFD error", /* ECTF_BFDERR */ - "File uses more recent CTF version than libctf", /* ECTF_CTFVERS */ - "Ambiguous BFD target", /* ECTF_BFD_AMBIGUOUS */ - "Symbol table uses invalid entry size", /* ECTF_SYMTAB */ - "Symbol table data buffer is not valid", /* ECTF_SYMBAD */ - "String table data buffer is not valid", /* ECTF_STRBAD */ - "File data structure corruption detected", /* ECTF_CORRUPT */ - "File does not contain CTF data", /* ECTF_NOCTFDATA */ - "Buffer does not contain CTF data", /* ECTF_NOCTFBUF */ - "Symbol table information is not available", /* ECTF_NOSYMTAB */ - "Type information is in parent and unavailable", /* ECTF_NOPARENT */ - "Cannot import types with different data model", /* ECTF_DMODEL */ - "File added to link too late", /* ECTF_LINKADDEDLATE */ - "Failed to allocate (de)compression buffer", /* ECTF_ZALLOC */ - "Failed to decompress CTF data", /* ECTF_DECOMPRESS */ - "External string table is not available", /* ECTF_STRTAB */ - "String name offset is corrupt", /* ECTF_BADNAME */ - "Invalid type identifier", /* ECTF_BADID */ - "Type is not a struct or union", /* ECTF_NOTSOU */ - "Type is not an enum", /* ECTF_NOTENUM */ - "Type is not a struct, union, or enum", /* ECTF_NOTSUE */ - "Type is not an integer, float, or enum", /* ECTF_NOTINTFP */ - "Type is not an array", /* ECTF_NOTARRAY */ - "Type does not reference another type", /* ECTF_NOTREF */ - "Input buffer is too small for type name", /* ECTF_NAMELEN */ - "No type information available for that name", /* ECTF_NOTYPE */ - "Syntax error in type name", /* ECTF_SYNTAX */ - "Symbol table entry or type is not a function", /* ECTF_NOTFUNC */ - "No function information available for symbol", /* ECTF_NOFUNCDAT */ - "Symbol table entry is not a data object", /* ECTF_NOTDATA */ - "No type information available for symbol", /* ECTF_NOTYPEDAT */ - "No label information available for that name", /* ECTF_NOLABEL */ - "File does not contain any labels", /* ECTF_NOLABELDATA */ - "Feature not supported", /* ECTF_NOTSUP */ - "Invalid enum element name", /* ECTF_NOENUMNAM */ - "Invalid member name", /* ECTF_NOMEMBNAM */ - "CTF container is read-only", /* ECTF_RDONLY */ - "Limit on number of dynamic type members reached", /* ECTF_DTFULL */ - "Limit on number of dynamic types reached", /* ECTF_FULL */ - "Duplicate member or variable name", /* ECTF_DUPLICATE */ - "Conflicting type is already defined", /* ECTF_CONFLICT */ - "Attempt to roll back past a ctf_update", /* ECTF_OVERROLLBACK */ - "Failed to compress CTF data", /* ECTF_COMPRESS */ - "Failed to create CTF archive", /* ECTF_ARCREATE */ - "Name not found in CTF archive", /* ECTF_ARNNAME */ - "Overflow of type bitness or offset in slice", /* ECTF_SLICEOVERFLOW */ - "Unknown section number in dump", /* ECTF_DUMPSECTUNKNOWN */ - "Section changed in middle of dump", /* ECTF_DUMPSECTCHANGED */ - "Feature not yet implemented", /* ECTF_NOTYET */ - "Internal error in link", /* ECTF_INTERNAL */ - "Type not representable in CTF" /* ECTF_NONREPRESENTABLE */ -}; +/* This construct is due to Bruno Haible: much thanks. */ -static const int _ctf_nerr = sizeof (_ctf_errlist) / sizeof (_ctf_errlist[0]); +/* Give each structure member a unique name. The name does not matter, so we + use the line number in ctf-error.h to uniquify them. */ + +#define ERRSTRFIELD(line) ERRSTRFIELD1 (line) +#define ERRSTRFIELD1(line) ctf_errstr##line + +/* The error message strings, each in a unique structure member precisely big + enough for that error, plus a str member to access them all as a string + table. */ + +static const union _ctf_errlist_t +{ + __extension__ struct + { +#define _CTF_STR(n, s) char ERRSTRFIELD (__LINE__) [sizeof (s)]; +#include "ctf-error.h" +#undef _CTF_STR + }; + char str[1]; +} _ctf_errlist = + { + { +#define _CTF_STR(n, s) s, +#include "ctf-error.h" +#undef _CTF_STR + } + }; + +/* Offsets to each member in the string table, computed using offsetof. */ + +static const unsigned int _ctf_erridx[] = + { +#define _CTF_STR(n, s) [n - ECTF_BASE] = offsetof (union _ctf_errlist_t, ERRSTRFIELD (__LINE__)), +#include "ctf-error.h" +#undef _CTF_STR + }; const char * ctf_errmsg (int error) { const char *str; - if (error >= ECTF_BASE && (error - ECTF_BASE) < _ctf_nerr) - str = _ctf_errlist[error - ECTF_BASE]; + if (error >= ECTF_BASE && (error - ECTF_BASE) < ECTF_NERR) + str = _ctf_errlist.str + _ctf_erridx[error - ECTF_BASE]; else str = ctf_strerror (error); diff --git a/libctf/mkerrors.sed b/libctf/mkerrors.sed new file mode 100644 index 00000000000..ddd4d2286e7 --- /dev/null +++ b/libctf/mkerrors.sed @@ -0,0 +1,28 @@ +# +# Copyright (C) 2020 Free Software Foundation, Inc. +# +# This file 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 2 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; see the file COPYING. If not see +# . +# + +# Only process lines in the error-define block +/= ECTF_BASE/,/ECTF_NERR/ { + # Do not process non-errors (braces, ECTF_NERR, etc). + /^ *ECTF_/!n; + # Strip out the base initializer. + s, = ECTF_BASE,,; + # Transform errors into _STR(...). + s@^ *\(ECTF_[^[:blank:],]*\),\{0,1\}[[:blank:]]*/\* \(.*\). \*/$@_CTF_STR (\1, "\2")@; + p; + }