blob: d9ca9e7ea38c4ae2491fab55d6a5a7d0f02c4978 [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Error handling in libdwfl.
Roland McGrathed431dd2010-05-06 00:52:51 -07002 Copyright (C) 2005-2010 Red Hat, Inc.
Mark Wielaardde2ed972012-06-05 17:15:16 +02003 This file is part of elfutils.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00004
Mark Wielaardde2ed972012-06-05 17:15:16 +02005 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00007
Mark Wielaardde2ed972012-06-05 17:15:16 +02008 * 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
Ulrich Drepper361df7d2006-04-04 21:38:57 +000021 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
Mark Wielaardde2ed972012-06-05 17:15:16 +020025 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/>. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000028
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
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000043/* The error number. */
44static __thread int global_error;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000045
46
47int
48dwfl_errno (void)
49{
Ulrich Drepper7e678fa2009-01-10 18:02:05 -080050 int result = global_error;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000051 global_error = DWFL_E_NOERROR;
52 return result;
53}
Roland McGrathed431dd2010-05-06 00:52:51 -070054INTDEF (dwfl_errno)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000055
56
57static 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
70static 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
80static inline int
81canonicalize (Dwfl_Error error)
82{
83 unsigned int value;
84
85 switch (error)
86 {
87 default:
88 value = error;
89 if ((value &~ 0xffff) != 0)
90 break;
91 assert (value < nmsgidx);
92 break;
93 case DWFL_E_ERRNO:
94 value = DWFL_E (ERRNO, errno);
95 break;
96 case DWFL_E_LIBELF:
97 value = DWFL_E (LIBELF, elf_errno ());
98 break;
99 case DWFL_E_LIBDW:
Roland McGrath4959bf82005-08-09 10:31:08 +0000100 value = DWFL_E (LIBDW, INTUSE(dwarf_errno) ());
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000101 break;
102#if 0
103 DWFL_E_LIBEBL:
104 value = DWFL_E (LIBEBL, ebl_errno ());
105 break;
106#endif
107 }
108
109 return value;
110}
111
112int
Ulrich Drepper077c65f2006-07-12 19:54:51 +0000113internal_function
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000114__libdwfl_canon_error (Dwfl_Error error)
115{
116 return canonicalize (error);
117}
118
119void
Ulrich Drepper077c65f2006-07-12 19:54:51 +0000120internal_function
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000121__libdwfl_seterrno (Dwfl_Error error)
122{
Ulrich Drepper7e678fa2009-01-10 18:02:05 -0800123 global_error = canonicalize (error);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000124}
125
126
127const char *
128dwfl_errmsg (error)
129 int error;
130{
131 if (error == 0 || error == -1)
132 {
Ulrich Drepper7e678fa2009-01-10 18:02:05 -0800133 int last_error = global_error;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000134
135 if (error == 0 && last_error == 0)
136 return NULL;
137
138 error = last_error;
139 global_error = DWFL_E_NOERROR;
140 }
141
142 switch (error &~ 0xffff)
143 {
144 case OTHER_ERROR (ERRNO):
145 return strerror_r (error & 0xffff, "bad", 0);
146 case OTHER_ERROR (LIBELF):
147 return elf_errmsg (error & 0xffff);
148 case OTHER_ERROR (LIBDW):
Roland McGrath4959bf82005-08-09 10:31:08 +0000149 return INTUSE(dwarf_errmsg) (error & 0xffff);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000150#if 0
151 case OTHER_ERROR (LIBEBL):
152 return ebl_errmsg (error & 0xffff);
153#endif
154 }
155
156 return _(&msgstr[msgidx[(unsigned int) error < nmsgidx
157 ? error : DWFL_E_UNKNOWN_ERROR]]);
158}
159INTDEF (dwfl_errmsg)