aboutsummaryrefslogtreecommitdiff
path: root/libctf/ctf-error.c
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2020-06-02 19:07:08 +0100
committerNick Alcock <nick.alcock@oracle.com>2020-07-22 17:57:20 +0100
commit7eea9d3bdb037a3953101eccdb05826daf2da39a (patch)
tree9146958b0707822dabf56fc5e30381b0122f16e3 /libctf/ctf-error.c
parentb64751cf0bc4466066c35e6c63348f900ce10272 (diff)
downloadgdb-7eea9d3bdb037a3953101eccdb05826daf2da39a.zip
gdb-7eea9d3bdb037a3953101eccdb05826daf2da39a.tar.gz
gdb-7eea9d3bdb037a3953101eccdb05826daf2da39a.tar.bz2
libctf: restructure error handling to reduce relocations
Jose Marchesi noted that the traditional-Unix error array in ctf-error.c introduces one reloc per error to initialize the array: 58 so far. We can reduce this to zero using an array of carefully-sized individual members which is used to construct a string table, that is then referenced by the lookup functions: but doing this automatically is a pain. Bruno Haible wrote suitable code years ago: I got permission to reuse it (Bruno says "... which I hereby put in the public domain"); I modified it a tiny bit (similarly to what Ulrich Drepper did in the dsohowto text, but I redid it from scratch), commented it up a bit, and shifted the error table into that form, migrating it into the new file ctf-error.h. This has the advantage that it spotted both typos in the text of the errors in the comments in ctf-api.h and typos in the error defines in the comments in ctf-error.c, and places where the two were simply not in sync. All are now fixed. One new constant exists in ctf-api.h: CTF_NERR, since the old method of working out the number of errors in ctf-error.c was no longer usable, and it seems that the number of CTF errors is something users might reasonably want as well. It should be pretty easy to keep up to date as new errors are introduced. include/ * ctf-api.h (ECTF_*): Improve comments. (ECTF_NERR): New. libctf/ * ctf-error.c: Include <stddef.h>, 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.
Diffstat (limited to 'libctf/ctf-error.c')
-rw-r--r--libctf/ctf-error.c99
1 files changed, 41 insertions, 58 deletions
diff --git a/libctf/ctf-error.c b/libctf/ctf-error.c
index c457aa0..84d14d5 100644
--- a/libctf/ctf-error.c
+++ b/libctf/ctf-error.c
@@ -18,71 +18,54 @@
<http://www.gnu.org/licenses/>. */
#include <ctf-impl.h>
+#include <stddef.h>
-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 */
-};
-
-static const int _ctf_nerr = sizeof (_ctf_errlist) / sizeof (_ctf_errlist[0]);
+/* This construct is due to Bruno Haible: much thanks. */
+
+/* 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);