dwfl_error.c revision 7e678fa3f6051f7ef24b4610c9a66cab858b6b6e
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Error handling in libdwfl.
27e678fa3f6051f7ef24b4610c9a66cab858b6b6eUlrich Drepper   Copyright (C) 2005, 2006, 2009 Red Hat, Inc.
3361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   This file is part of Red Hat elfutils.
4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
5361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Red Hat elfutils is free software; you can redistribute it and/or modify
6361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   it under the terms of the GNU General Public License as published by the
7361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Free Software Foundation; version 2 of the License.
8b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
9361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Red Hat elfutils is distributed in the hope that it will be useful, but
10361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   WITHOUT ANY WARRANTY; without even the implied warranty of
11361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   General Public License for more details.
13361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper
14361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   You should have received a copy of the GNU General Public License along
15361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   with Red Hat elfutils; if not, write to the Free Software Foundation,
161e9ef50681e20ef14c2ba38aef37a71ff148be08Ulrich Drepper   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
17361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper
18361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   In addition, as a special exception, Red Hat, Inc. gives You the
19361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   additional right to link the code of Red Hat elfutils with code licensed
20361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   under any Open Source Initiative certified open source license
21361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   (http://www.opensource.org/licenses/index.php) which requires the
22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   distribution of source code with any binary distribution and to
23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   distribute linked combinations of the two.  Non-GPL Code permitted under
24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   this exception must only link to the code of Red Hat elfutils through
25361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   those well defined interfaces identified in the file named EXCEPTION
26361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   found in the source code files (the "Approved Interfaces").  The files
27361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   of Non-GPL Code may instantiate templates or use macros or inline
28361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   functions from the Approved Interfaces without causing the resulting
29361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   work to be covered by the GNU General Public License.  Only Red Hat,
30361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Inc. may make changes or additions to the list of Approved Interfaces.
31361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Red Hat's grant of this exception is conditioned upon your not adding
32361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   any new exceptions.  If you wish to add a new Approved Interface or
33361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   exception, please contact Red Hat.  You must obey the GNU General Public
34361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   License in all respects for all of the Red Hat elfutils code and other
35361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   code used in conjunction with Red Hat elfutils except the Non-GPL Code
36361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   covered by this exception.  If you modify this file, you may extend this
37361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   exception to your version of the file, but you are not obligated to do
38361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   so.  If you do not wish to provide this exception without modification,
39361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   you must delete this exception statement from your version and license
40361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   this file solely under the GPL without exception.
41361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper
42361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Red Hat elfutils is an included package of the Open Invention Network.
43361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   An included package of the Open Invention Network is a package for which
44361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Open Invention Network licensees cross-license their patents.  No patent
45361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   license is granted, either expressly or impliedly, by designation as an
46361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   included package.  Should you wish to participate in the Open Invention
47361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Network licensing program, please visit www.openinventionnetwork.com
48361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   <http://www.openinventionnetwork.com>.  */
49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H
51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h>
52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h>
55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libintl.h>
56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h>
57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdint.h>
58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h>
59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <errno.h>
60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "libdwflP.h"
62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* The error number.  */
65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic __thread int global_error;
66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperdwfl_errno (void)
70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
717e678fa3f6051f7ef24b4610c9a66cab858b6b6eUlrich Drepper  int result = global_error;
72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  global_error = DWFL_E_NOERROR;
73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return result;
74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const struct msgtable
78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define DWFL_ERROR(name, text) char msg_##name[sizeof text];
80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  DWFL_ERRORS
81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#undef	DWFL_ERROR
82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} msgtable =
83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  {
84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define DWFL_ERROR(name, text) text,
85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  DWFL_ERRORS
86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#undef	DWFL_ERROR
87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  };
88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define msgstr (&msgtable.msg_NOERROR[0])
89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const uint_fast16_t msgidx[] =
91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define DWFL_ERROR(name, text) \
93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [DWFL_E_##name] = offsetof (struct msgtable, msg_##name),
94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  DWFL_ERRORS
95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#undef	DWFL_ERROR
96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper};
97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define nmsgidx (sizeof msgidx / sizeof msgidx[0])
98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic inline int
101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercanonicalize (Dwfl_Error error)
102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  unsigned int value;
104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  switch (error)
106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    default:
108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      value = error;
109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if ((value &~ 0xffff) != 0)
110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	break;
111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      assert (value < nmsgidx);
112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DWFL_E_ERRNO:
114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      value = DWFL_E (ERRNO, errno);
115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DWFL_E_LIBELF:
117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      value = DWFL_E (LIBELF, elf_errno ());
118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DWFL_E_LIBDW:
1204959bf89d92b59ba72bea5786d7b3f9b5564f750Roland McGrath      value = DWFL_E (LIBDW, INTUSE(dwarf_errno) ());
121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if 0
123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    DWFL_E_LIBEBL:
124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      value = DWFL_E (LIBEBL, ebl_errno ());
125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return value;
130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
133077c65f3be02e5d01b0c4dea3f6c854077d156fcUlrich Drepperinternal_function
134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper__libdwfl_canon_error (Dwfl_Error error)
135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return canonicalize (error);
137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppervoid
140077c65f3be02e5d01b0c4dea3f6c854077d156fcUlrich Drepperinternal_function
141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper__libdwfl_seterrno (Dwfl_Error error)
142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1437e678fa3f6051f7ef24b4610c9a66cab858b6b6eUlrich Drepper  global_error = canonicalize (error);
144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperconst char *
148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperdwfl_errmsg (error)
149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     int error;
150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (error == 0 || error == -1)
152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1537e678fa3f6051f7ef24b4610c9a66cab858b6b6eUlrich Drepper      int last_error = global_error;
154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (error == 0 && last_error == 0)
156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return NULL;
157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      error = last_error;
159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      global_error = DWFL_E_NOERROR;
160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  switch (error &~ 0xffff)
163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case OTHER_ERROR (ERRNO):
165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return strerror_r (error & 0xffff, "bad", 0);
166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case OTHER_ERROR (LIBELF):
167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return elf_errmsg (error & 0xffff);
168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case OTHER_ERROR (LIBDW):
1694959bf89d92b59ba72bea5786d7b3f9b5564f750Roland McGrath      return INTUSE(dwarf_errmsg) (error & 0xffff);
170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if 0
171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case OTHER_ERROR (LIBEBL):
172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return ebl_errmsg (error & 0xffff);
173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return _(&msgstr[msgidx[(unsigned int) error < nmsgidx
177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  ? error : DWFL_E_UNKNOWN_ERROR]]);
178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
179b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperINTDEF (dwfl_errmsg)
180