Blame libdwfl/dwfl_error.c

Packit Service 97d2fb
/* Error handling in libdwfl.
Packit Service 97d2fb
   Copyright (C) 2005-2015 Red Hat, Inc.
Packit Service 97d2fb
   This file is part of elfutils.
Packit Service 97d2fb
Packit Service 97d2fb
   This file is free software; you can redistribute it and/or modify
Packit Service 97d2fb
   it under the terms of either
Packit Service 97d2fb
Packit Service 97d2fb
     * the GNU Lesser General Public License as published by the Free
Packit Service 97d2fb
       Software Foundation; either version 3 of the License, or (at
Packit Service 97d2fb
       your option) any later version
Packit Service 97d2fb
Packit Service 97d2fb
   or
Packit Service 97d2fb
Packit Service 97d2fb
     * the GNU General Public License as published by the Free
Packit Service 97d2fb
       Software Foundation; either version 2 of the License, or (at
Packit Service 97d2fb
       your option) any later version
Packit Service 97d2fb
Packit Service 97d2fb
   or both in parallel, as here.
Packit Service 97d2fb
Packit Service 97d2fb
   elfutils is distributed in the hope that it will be useful, but
Packit Service 97d2fb
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 97d2fb
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 97d2fb
   General Public License for more details.
Packit Service 97d2fb
Packit Service 97d2fb
   You should have received copies of the GNU General Public License and
Packit Service 97d2fb
   the GNU Lesser General Public License along with this program.  If
Packit Service 97d2fb
   not, see <http://www.gnu.org/licenses/>.  */
Packit Service 97d2fb
Packit Service 97d2fb
#ifdef HAVE_CONFIG_H
Packit Service 97d2fb
# include <config.h>
Packit Service 97d2fb
#endif
Packit Service 97d2fb
Packit Service 97d2fb
#include <assert.h>
Packit Service 97d2fb
#include <libintl.h>
Packit Service 97d2fb
#include <stdbool.h>
Packit Service 97d2fb
#include <stdint.h>
Packit Service 97d2fb
#include <stdlib.h>
Packit Service 97d2fb
#include <errno.h>
Packit Service 97d2fb
Packit Service 97d2fb
#include "libdwflP.h"
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
/* The error number.  */
Packit Service 97d2fb
static __thread int global_error;
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
int
Packit Service 97d2fb
dwfl_errno (void)
Packit Service 97d2fb
{
Packit Service 97d2fb
  int result = global_error;
Packit Service 97d2fb
  global_error = DWFL_E_NOERROR;
Packit Service 97d2fb
  return result;
Packit Service 97d2fb
}
Packit Service 97d2fb
INTDEF (dwfl_errno)
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
struct msgtable
Packit Service 97d2fb
{
Packit Service 97d2fb
#define DWFL_ERROR(name, text) char msg_##name[sizeof text];
Packit Service 97d2fb
  DWFL_ERRORS
Packit Service 97d2fb
#undef	DWFL_ERROR
Packit Service 97d2fb
};
Packit Service 97d2fb
Packit Service 97d2fb
static const union
Packit Service 97d2fb
{
Packit Service 97d2fb
  struct msgtable table;
Packit Service 97d2fb
  char strings[
Packit Service 97d2fb
#define DWFL_ERROR(name, text)	+ sizeof text
Packit Service 97d2fb
	       DWFL_ERRORS
Packit Service 97d2fb
#undef	DWFL_ERROR
Packit Service 97d2fb
	       ];
Packit Service 97d2fb
} msgtable =
Packit Service 97d2fb
  {
Packit Service 97d2fb
    .table =
Packit Service 97d2fb
    {
Packit Service 97d2fb
#define DWFL_ERROR(name, text) text,
Packit Service 97d2fb
      DWFL_ERRORS
Packit Service 97d2fb
#undef	DWFL_ERROR
Packit Service 97d2fb
    }
Packit Service 97d2fb
  };
Packit Service 97d2fb
#define msgstr (msgtable.strings)
Packit Service 97d2fb
Packit Service 97d2fb
static const uint_fast16_t msgidx[] =
Packit Service 97d2fb
{
Packit Service 97d2fb
#define DWFL_ERROR(name, text) \
Packit Service 97d2fb
  [DWFL_E_##name] = offsetof (struct msgtable, msg_##name),
Packit Service 97d2fb
  DWFL_ERRORS
Packit Service 97d2fb
#undef	DWFL_ERROR
Packit Service 97d2fb
};
Packit Service 97d2fb
#define nmsgidx (sizeof msgidx / sizeof msgidx[0])
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
static inline int
Packit Service 97d2fb
canonicalize (Dwfl_Error error)
Packit Service 97d2fb
{
Packit Service 97d2fb
  unsigned int value;
Packit Service 97d2fb
Packit Service 97d2fb
  switch (error)
Packit Service 97d2fb
    {
Packit Service 97d2fb
    default:
Packit Service 97d2fb
      value = error;
Packit Service 97d2fb
      if ((value &~ 0xffff) != 0)
Packit Service 97d2fb
	break;
Packit Service 97d2fb
      assert (value < nmsgidx);
Packit Service 97d2fb
      break;
Packit Service 97d2fb
    case DWFL_E_ERRNO:
Packit Service 97d2fb
      value = DWFL_E (ERRNO, errno);
Packit Service 97d2fb
      break;
Packit Service 97d2fb
    case DWFL_E_LIBELF:
Packit Service 97d2fb
      value = DWFL_E (LIBELF, elf_errno ());
Packit Service 97d2fb
      break;
Packit Service 97d2fb
    case DWFL_E_LIBDW:
Packit Service 97d2fb
      value = DWFL_E (LIBDW, INTUSE(dwarf_errno) ());
Packit Service 97d2fb
      break;
Packit Service 97d2fb
#if 0
Packit Service 97d2fb
    DWFL_E_LIBEBL:
Packit Service 97d2fb
      value = DWFL_E (LIBEBL, ebl_errno ());
Packit Service 97d2fb
      break;
Packit Service 97d2fb
#endif
Packit Service 97d2fb
    }
Packit Service 97d2fb
Packit Service 97d2fb
  return value;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
int
Packit Service 97d2fb
internal_function
Packit Service 97d2fb
__libdwfl_canon_error (Dwfl_Error error)
Packit Service 97d2fb
{
Packit Service 97d2fb
  return canonicalize (error);
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
void
Packit Service 97d2fb
internal_function
Packit Service 97d2fb
__libdwfl_seterrno (Dwfl_Error error)
Packit Service 97d2fb
{
Packit Service 97d2fb
  global_error = canonicalize (error);
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
const char *
Packit Service 97d2fb
dwfl_errmsg (int error)
Packit Service 97d2fb
{
Packit Service 97d2fb
  if (error == 0 || error == -1)
Packit Service 97d2fb
    {
Packit Service 97d2fb
      int last_error = global_error;
Packit Service 97d2fb
Packit Service 97d2fb
      if (error == 0 && last_error == 0)
Packit Service 97d2fb
	return NULL;
Packit Service 97d2fb
Packit Service 97d2fb
      error = last_error;
Packit Service 97d2fb
      global_error = DWFL_E_NOERROR;
Packit Service 97d2fb
    }
Packit Service 97d2fb
Packit Service 97d2fb
  switch (error &~ 0xffff)
Packit Service 97d2fb
    {
Packit Service 97d2fb
    case OTHER_ERROR (ERRNO):
Packit Service 97d2fb
      return strerror_r (error & 0xffff, "bad", 0);
Packit Service 97d2fb
    case OTHER_ERROR (LIBELF):
Packit Service 97d2fb
      return elf_errmsg (error & 0xffff);
Packit Service 97d2fb
    case OTHER_ERROR (LIBDW):
Packit Service 97d2fb
      return INTUSE(dwarf_errmsg) (error & 0xffff);
Packit Service 97d2fb
#if 0
Packit Service 97d2fb
    case OTHER_ERROR (LIBEBL):
Packit Service 97d2fb
      return ebl_errmsg (error & 0xffff);
Packit Service 97d2fb
#endif
Packit Service 97d2fb
    }
Packit Service 97d2fb
Packit Service 97d2fb
  return _(&msgstr[msgidx[(unsigned int) error < nmsgidx
Packit Service 97d2fb
			  ? error : DWFL_E_UNKNOWN_ERROR]]);
Packit Service 97d2fb
}
Packit Service 97d2fb
INTDEF (dwfl_errmsg)