Branch data Line data Source code
1 : : /* Error handling in libdwfl.
2 : : Copyright (C) 2005-2010 Red Hat, Inc.
3 : : This file is part of elfutils.
4 : :
5 : : This file is free software; you can redistribute it and/or modify
6 : : it under the terms of either
7 : :
8 : : * the GNU Lesser General Public License as published by the Free
9 : : Software Foundation; either version 3 of the License, or (at
10 : : your option) any later version
11 : :
12 : : or
13 : :
14 : : * the GNU General Public License as published by the Free
15 : : Software Foundation; either version 2 of the License, or (at
16 : : your option) any later version
17 : :
18 : : or both in parallel, as here.
19 : :
20 : : elfutils is distributed in the hope that it will be useful, but
21 : : WITHOUT ANY WARRANTY; without even the implied warranty of
22 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 : : General Public License for more details.
24 : :
25 : : You should have received copies of the GNU General Public License and
26 : : the GNU Lesser General Public License along with this program. If
27 : : not, see <http://www.gnu.org/licenses/>. */
28 : :
29 : : #ifdef HAVE_CONFIG_H
30 : : # include <config.h>
31 : : #endif
32 : :
33 : : #include <assert.h>
34 : : #include <libintl.h>
35 : : #include <stdbool.h>
36 : : #include <stdint.h>
37 : : #include <stdlib.h>
38 : : #include <errno.h>
39 : :
40 : : #include "libdwflP.h"
41 : :
42 : :
43 : : /* The error number. */
44 : : static __thread int global_error;
45 : :
46 : :
47 : : int
48 : 15 : dwfl_errno (void)
49 : : {
50 : 15 : int result = global_error;
51 : 15 : global_error = DWFL_E_NOERROR;
52 : 15 : return result;
53 : : }
54 : : INTDEF (dwfl_errno)
55 : :
56 : :
57 : : static const struct msgtable
58 : : {
59 : : #define DWFL_ERROR(name, text) char msg_##name[sizeof text];
60 : : DWFL_ERRORS
61 : : #undef DWFL_ERROR
62 : : } msgtable =
63 : : {
64 : : #define DWFL_ERROR(name, text) text,
65 : : DWFL_ERRORS
66 : : #undef DWFL_ERROR
67 : : };
68 : : #define msgstr (&msgtable.msg_NOERROR[0])
69 : :
70 : : static const uint_fast16_t msgidx[] =
71 : : {
72 : : #define DWFL_ERROR(name, text) \
73 : : [DWFL_E_##name] = offsetof (struct msgtable, msg_##name),
74 : : DWFL_ERRORS
75 : : #undef DWFL_ERROR
76 : : };
77 : : #define nmsgidx (sizeof msgidx / sizeof msgidx[0])
78 : :
79 : :
80 : : static inline int
81 : 152 : canonicalize (Dwfl_Error error)
82 : : {
83 : : unsigned int value;
84 : :
85 [ + - - - ]: 152 : switch (error)
86 : : {
87 : : default:
88 : 152 : value = error;
89 [ + + ]: 152 : if ((value &~ 0xffff) != 0)
90 : : break;
91 [ - + ]: 150 : assert (value < nmsgidx);
92 : : break;
93 : : case DWFL_E_ERRNO:
94 : 0 : value = DWFL_E (ERRNO, errno);
95 : 0 : break;
96 : : case DWFL_E_LIBELF:
97 : 0 : value = DWFL_E (LIBELF, elf_errno ());
98 : 0 : break;
99 : : case DWFL_E_LIBDW:
100 : 0 : value = DWFL_E (LIBDW, INTUSE(dwarf_errno) ());
101 : 0 : break;
102 : : #if 0
103 : : DWFL_E_LIBEBL:
104 : : value = DWFL_E (LIBEBL, ebl_errno ());
105 : : break;
106 : : #endif
107 : : }
108 : :
109 : 152 : return value;
110 : : }
111 : :
112 : : int
113 : : internal_function
114 : 29 : __libdwfl_canon_error (Dwfl_Error error)
115 : : {
116 : 29 : return canonicalize (error);
117 : : }
118 : :
119 : : void
120 : : internal_function
121 : 123 : __libdwfl_seterrno (Dwfl_Error error)
122 : : {
123 : 123 : global_error = canonicalize (error);
124 : 123 : }
125 : :
126 : :
127 : : const char *
128 : 1 : dwfl_errmsg (error)
129 : : int error;
130 : : {
131 [ + - ]: 1 : if (error == 0 || error == -1)
132 : : {
133 : 1 : int last_error = global_error;
134 : :
135 [ + - ]: 1 : if (error == 0 && last_error == 0)
136 : : return NULL;
137 : :
138 : 1 : error = last_error;
139 : 1 : global_error = DWFL_E_NOERROR;
140 : : }
141 : :
142 [ - - - + ]: 1 : switch (error &~ 0xffff)
143 : : {
144 : : case OTHER_ERROR (ERRNO):
145 : 0 : return strerror_r (error & 0xffff, "bad", 0);
146 : : case OTHER_ERROR (LIBELF):
147 : 0 : return elf_errmsg (error & 0xffff);
148 : : case OTHER_ERROR (LIBDW):
149 : 0 : return INTUSE(dwarf_errmsg) (error & 0xffff);
150 : : #if 0
151 : : case OTHER_ERROR (LIBEBL):
152 : : return ebl_errmsg (error & 0xffff);
153 : : #endif
154 : : }
155 : :
156 [ + - ]: 1 : return _(&msgstr[msgidx[(unsigned int) error < nmsgidx
157 : : ? error : DWFL_E_UNKNOWN_ERROR]]);
158 : : }
159 : : INTDEF (dwfl_errmsg)
|