Squashed 'third_party/elfutils/' content from commit 555e15e
Change-Id: I61cde98949e47e5c8c09c33260de17f30921be79
git-subtree-dir: third_party/elfutils
git-subtree-split: 555e15ebe8bf1eb33d00747173cfc80cc65648a4
diff --git a/lib/ChangeLog b/lib/ChangeLog
new file mode 100644
index 0000000..0f03dab
--- /dev/null
+++ b/lib/ChangeLog
@@ -0,0 +1,278 @@
+2018-02-09 Joshua Watt <JPEWhacker@gmail.com>
+
+ * eu-config.h (FALLTHROUGH): New macro.
+
+2017-10-16 Mark Wielaard <mark@klomp.org>
+
+ * md5.{c,h}: Removed.
+ * sha1.{c,h}: Likewise.
+ * Makefile.am (libeu_a_SOURCES): Remove md5.c and sha1.c.
+ (noinst_HEADERS): Remove md5.h and sha1.h.
+
+2017-08-18 Ulf Hermann <ulf.hermann@qt.io>
+
+ * eu-config.h: Define attribute_packed to either
+ __attribute__((packed)) or __attribute__((packed, gcc_struct)).
+
+2017-04-27 Ulf Hermann <ulf.hermann@qt.io>
+
+ * eu-config.h: Define attribute_hidden to be empty if the compiler
+ doesn't support it.
+
+2017-04-27 Ulf Hermann <ulf.hermann@qt.io>
+
+ * Makefile.am: Use fpic_CFLAGS.
+
+2017-07-18 Mark Wielaard <mark@klomp.org>
+
+ * bpf.h: New file.
+ * Makefile.am (noinst_HEADERS): Add bpf.h
+
+2017-05-05 Mark Wielaard <mark@klomp.org>
+
+ * printversion.c (print_version): Update copyright year.
+
+2017-04-20 Ulf Hermann <ulf.hermann@qt.io>
+
+ * crc32.c: include config.h.
+ * system.h: Don't include config.h.
+
+2017-02-16 Ulf Hermann <ulf.hermann@qt.io>
+
+ * Makefile.am (libeu_a_SOURCES): Remove version.c, add printversion.c
+ (noinst_HEADERS): Add printversion.h
+ * version.c: Moved to printversion.c.
+ * printversion.c: New file, moved from version.c,
+ remove stdio.h, argp.h, system.h includes,
+ add printversion.h include.
+ * printversion.h: New file.
+ * system.h: Remove argp.h include,
+ (ARGP_PROGRAM_VERSION_HOOK_DEF, ARGP_PROGRAM_BUG_ADDRESS_DEF): Remove.
+ (print_version): Remove.
+
+2017-02-15 Ulf Hermann <ulf.hermann@qt.io>
+
+ * system.h: Provide mempcpy if it doesn't exist.
+ * xstrndup.c: Include system.h.
+
+2017-02-15 Ulf Hermann <ulf.hermann@qt.io>
+
+ * crc32_file.c: Use _SC_PAGESIZE rather than _SC_PAGE_SIZE.
+
+2017-02-14 Ulf Hermann <ulf.hermann@qt.io>
+
+ * color.h: New file.
+ * color.c: Include color.h.
+ * libeu.h: Remove color handling.
+ * Makefile.am (noinst_HEADERS): Add color.h.
+
+2016-12-29 Luiz Angelo Daros de Luca <luizluca@gmail.com>
+
+ * crc32_file.c: Include system.h.
+ * system.h: Remove semi-colon after TEMP_FAILURE_RETRY definition.
+
+2016-12-24 Mark Wielaard <mark@klomp.org>
+
+ * version.c: New source file.
+ * Makefile.am (libeu_a_SOURCES): Add version.c
+ * system.h (print_version): New function definition.
+
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+ * fixedsizehash.h (CONCAT): Use __CONCAT when available.
+ * system.h: Include config.h and errno.h.
+ (powerof2): Define if not already defined.
+ (TEMP_FAILURE_RETRY): Define when not yet defined.
+
+2015-10-11 Akihiko Odaki <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+ * Makefile.am (noinst_HEADERS): Add libeu.h.
+ * color.c: Remove system.h include, add libeu.h include.
+ * crc32_file.c: Likewise.
+ * fixedsizehash.h: Remove sys/param.h include.
+ * libeu.h: New file.
+ * system.h: Include sys/param.h.
+ (xmalloc, xcalloc, xrealloc, xstrdup, xstrndup, crc32, crc32_file,
+ color_argp, color_enum, color_*): Move definitions to libeu.h.
+ * xstrdup.c: Remove system.h include, add libeu.h include.
+ * xstrndup.c: Remove system.h include, add libeu.h and stdint.h
+ includes.
+
+2015-09-24 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid relocation
+ overflows in some platforms.
+
+2015-09-22 Mark Wielaard <mjw@redhat.com>
+
+ * dynamicsizehash.c: Remove old-style function definitions.
+ * md5.c: Likewise.
+ * sha1.c: Likewise.
+ * xmalloc.c: Likewise.
+ * xstrdup.c: Likewise.
+ * xstrndup.c: Likewise.
+
+2015-05-31 Mark Wielaard <mjw@redhat.com>
+
+ * eu-config.h (ALLOW_UNALIGNED): Define when ! CHECK_UNDEFINED.
+
+2015-04-23 Max Filippov <jcmvbkbc@gmail.com>
+
+ * eu-config.h: Use SYMBOL_VERSIONING as guard.
+
+2014-01-17 Lei Zhang <thestig@google.com>
+
+ * crc32_file.c: Include config.h.
+
+2013-12-12 Josh Stone <jistone@redhat.com>
+
+ * dynamicsizehash.c (lookup): Add a shortcut around division.
+
+2013-04-30 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * eu-config.h (COMPAT_VERSION_NEWPROTO): New. Twice.
+
+2013-04-26 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * system.h (LE64, BE64): Move here the definitions from
+ libdwfl/link_map.c.
+
+2013-04-24 Mark Wielaard <mjw@redhat.com>
+
+ * Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
+
+2012-10-09 Adam Markey <adam@etinternational.com>
+
+ * system.h: Changed pwrite_retry, write_retry, and pread_retry to
+ handle case where not all data was read/written.
+
+2012-10-08 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * system.h (eu_static_assert): New macro.
+
+2012-01-21 Ulrich Drepper <drepper@gmail.com>
+
+ * Makefile.am (libeu_a_SOURCES): Add color.c.
+ * system.h: Declare color_argp. Define color_enum. Declare
+ color_* variables.
+ * color.c: New file.
+
+2011-10-02 Ulrich Drepper <drepper@gmail.com>
+
+ * system.h: Declare __cxa_demangle.
+
+2011-07-09 Roland McGrath <roland@hack.frob.com>
+
+ * sha1.c (be64_copy): New function.
+ (sha1_finish_ctx): Use it.
+ * md5.c (le64_copy): New function.
+ (md5_finish_ctx): Use it.
+ * system.h (LE32, BE32): New macros, using <endian.h> and <byteswap.h>.
+ * md5.c (SWAP): Use LE32.
+ * sha1.c (SWAP): Use BE32.
+
+2010-06-16 Roland McGrath <roland@redhat.com>
+
+ * dynamicsizehash.h (HASHTYPE): New macro.
+ (struct): Use size_t for table sizes.
+ * dynamicsizehash.c: Likewise. Use HASHTYPE for hash values.
+
+2010-02-15 Roland McGrath <roland@redhat.com>
+
+ * Makefile.am: Use config/eu.am for common stuff.
+
+2009-08-09 Roland McGrath <roland@redhat.com>
+
+ * eu-config.h (OLD_VERSION, NEW_VERSION, COMPAT_VERSION): New macros.
+
+2009-01-23 Roland McGrath <roland@redhat.com>
+
+ * eu-config.h: Add multiple inclusion protection.
+
+2009-01-17 Ulrich Drepper <drepper@redhat.com>
+
+ * system.h (ARGP_PROGRAM_VERSION_HOOK_DEF): Define.
+ (ARGP_PROGRAM_BUG_ADDRESS_DEF): Define.
+
+2009-01-10 Ulrich Drepper <drepper@redhat.com>
+
+ * eu-config.h: Remove tls_key_t, key_create, getspecific, setspecific,
+ once_define, and once_execute macros. Use USE_LOCKS instead of
+ USE_TLS.
+
+2008-08-25 Roland McGrath <roland@redhat.com>
+
+ * eu-config.h [USE_TLS] (RWLOCK_CALL): New macro.
+ (rwlock_init, rwlock_fini, rwlock_rdlock, rwlock_wrlock, rwlock_unlock):
+ Use it.
+
+2008-08-24 Roland McGrath <roland@redhat.com>
+
+ * eu-config.h: New file.
+ * Makefile.am (noinst_HEADERS): Add it.
+
+2008-02-01 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am (libeu_a_SOURCES): Add sha1.c.
+ (noinst_HEADERS): Add sha1.h.
+ * sha1.c: New file.
+ * sha1.h: New file.
+
+2008-01-31 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am (libeu_a_SOURCES): Add md5.c.
+ (noinst_HEADERS): Add md5.h.
+ * md5.c: New file.
+ * md5.h: New file.
+
+2006-04-04 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am (libeu_a_SOURCES): We don't need xstrdup in the moment.
+
+2005-08-28 Ulrich Drepper <drepper@redhat.com>
+
+ * system.h: Define pwrite_retry, write_retry, and pread_retry.
+
+2005-08-06 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am (xmalloc_CFLAGS): Define only if !GPROF.
+
+2005-05-03 Roland McGrath <roland@redhat.com>
+
+ * crc32_file.c: New file.
+ * Makefile.am (libeu_a_SOURCES): Add it.
+ * system.h: Declare crc32_file.
+
+2005-04-30 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am: Use -ffunction-sections for xmalloc.c.
+
+2005-02-15 Ulrich Drepper <drepper@redhat.com>
+
+ * dynamicsizehash.c (lookup): Mark val parameter as possibly unused.
+
+2005-02-06 Ulrich Drepper <drepper@redhat.com>
+
+ * fixedsizehash.h: Mark unused parameters. Correct CLASS and
+ const order for fshash_find.
+
+ * Makefile.am: Cleanup AM_CFLAGS handling. Add -Wunused -Wextra.
+
+2005-02-05 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am [MUDFLAP] (AM_CFLAGS): Add -fpic and -fmudflap.
+
+2004-01-17 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am: Support building with mudflap.
+
+2003-09-22 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am (AM_CFLAGS): Add -fpic.
+
+ * Makefile.am (noinst_HEADERS): Add list.h.
+ * list.h: New file.
+
+2003-08-11 Ulrich Drepper <drepper@redhat.com>
+
+ * Moved to CVS archive.
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 0000000..36d21a0
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1,46 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 1996-2011 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+## * the GNU Lesser General Public License as published by the Free
+## Software Foundation; either version 3 of the License, or (at
+## your option) any later version
+##
+## or
+##
+## * the GNU General Public License as published by the Free
+## Software Foundation; either version 2 of the License, or (at
+## your option) any later version
+##
+## or both in parallel, as here.
+##
+## elfutils is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+##
+## You should have received copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program. If
+## not, see <http://www.gnu.org/licenses/>.
+##
+include $(top_srcdir)/config/eu.am
+AM_CFLAGS += $(fpic_CFLAGS)
+AM_CPPFLAGS += -I$(srcdir)/../libelf
+
+noinst_LIBRARIES = libeu.a
+
+libeu_a_SOURCES = xstrdup.c xstrndup.c xmalloc.c next_prime.c \
+ crc32.c crc32_file.c \
+ color.c printversion.c
+
+noinst_HEADERS = fixedsizehash.h libeu.h system.h dynamicsizehash.h list.h \
+ eu-config.h color.h printversion.h bpf.h
+EXTRA_DIST = dynamicsizehash.c
+
+if !GPROF
+xmalloc_CFLAGS = -ffunction-sections
+endif
diff --git a/lib/bpf.h b/lib/bpf.h
new file mode 100644
index 0000000..db80a51
--- /dev/null
+++ b/lib/bpf.h
@@ -0,0 +1,82 @@
+/* Minimal extended BPF constants as alternative for linux/bpf.h. */
+
+#ifndef _ELFUTILS_BPF_H
+#define _ELFUTILS_BPF_H 1
+
+#include <stdint.h>
+
+#define BPF_CLASS(code) ((code) & 0x07)
+
+#define BPF_LD 0x00
+#define BPF_LDX 0x01
+#define BPF_ST 0x02
+#define BPF_STX 0x03
+#define BPF_ALU 0x04
+#define BPF_JMP 0x05
+#define BPF_RET 0x06
+#define BPF_MISC 0x07
+
+#define BPF_ALU64 0x07
+
+#define BPF_JNE 0x50
+#define BPF_JSGT 0x60
+#define BPF_JSGE 0x70
+#define BPF_CALL 0x80
+#define BPF_EXIT 0x90
+
+#define BPF_W 0x00
+#define BPF_H 0x08
+#define BPF_B 0x10
+
+#define BPF_IMM 0x00
+#define BPF_ABS 0x20
+#define BPF_IND 0x40
+#define BPF_MEM 0x60
+#define BPF_LEN 0x80
+#define BPF_MSH 0xa0
+
+#define BPF_DW 0x18
+#define BPF_XADD 0xc0
+
+#define BPF_ADD 0x00
+#define BPF_SUB 0x10
+#define BPF_MUL 0x20
+#define BPF_DIV 0x30
+#define BPF_OR 0x40
+#define BPF_AND 0x50
+#define BPF_LSH 0x60
+#define BPF_RSH 0x70
+#define BPF_NEG 0x80
+#define BPF_MOD 0x90
+#define BPF_XOR 0xa0
+
+#define BPF_MOV 0xb0
+#define BPF_ARSH 0xc0
+
+#define BPF_JA 0x00
+#define BPF_JEQ 0x10
+#define BPF_JGT 0x20
+#define BPF_JGE 0x30
+#define BPF_JSET 0x40
+
+#define BPF_K 0x00
+#define BPF_X 0x08
+
+#define BPF_END 0xd0
+#define BPF_TO_LE 0x00
+#define BPF_TO_BE 0x08
+
+#define BPF_PSEUDO_MAP_FD 1
+
+#define MAX_BPF_REG 10
+
+struct bpf_insn
+{
+ uint8_t code;
+ uint8_t dst_reg:4;
+ uint8_t src_reg:4;
+ int16_t off;
+ int32_t imm;
+};
+
+#endif
diff --git a/lib/color.c b/lib/color.c
new file mode 100644
index 0000000..f62389d
--- /dev/null
+++ b/lib/color.c
@@ -0,0 +1,230 @@
+/* Handling of color output.
+ Copyright (C) 2011 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2011.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <error.h>
+#include <libintl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "libeu.h"
+#include "color.h"
+
+/* Prototype for option handler. */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Option values. */
+#define OPT_COLOR 0x100100
+
+/* Definitions of arguments for argp functions. */
+static const struct argp_option options[] =
+{
+ { "color", OPT_COLOR, "WHEN", OPTION_ARG_OPTIONAL,
+ N_("colorize the output. WHEN defaults to 'always' or can be 'auto' or 'never'"), 0 },
+
+ { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Parser data structure. */
+const struct argp color_argp =
+ {
+ options, parse_opt, NULL, NULL, NULL, NULL, NULL
+ };
+
+/* Coloring mode. */
+enum color_enum color_mode;
+
+/* Colors to use for the various components. */
+char *color_address = "";
+char *color_bytes = "";
+char *color_mnemonic = "";
+char *color_operand = NULL;
+char *color_operand1 = "";
+char *color_operand2 = "";
+char *color_operand3 = "";
+char *color_label = "";
+char *color_undef = "";
+char *color_undef_tls = "";
+char *color_undef_weak = "";
+char *color_symbol = "";
+char *color_tls = "";
+char *color_weak = "";
+
+const char color_off[] = "\e[0m";
+
+
+/* Handle program arguments. */
+static error_t
+parse_opt (int key, char *arg,
+ struct argp_state *state __attribute__ ((unused)))
+{
+ switch (key)
+ {
+ case OPT_COLOR:
+ if (arg == NULL)
+ color_mode = color_always;
+ else
+ {
+ static const struct
+ {
+ const char str[7];
+ enum color_enum mode;
+ } values[] =
+ {
+ { "always", color_always },
+ { "yes", color_always },
+ { "force", color_always },
+ { "never", color_never },
+ { "no", color_never },
+ { "none", color_never },
+ { "auto", color_auto },
+ { "tty", color_auto },
+ { "if-tty", color_auto }
+ };
+ const int nvalues = sizeof (values) / sizeof (values[0]);
+ int i;
+ for (i = 0; i < nvalues; ++i)
+ if (strcmp (arg, values[i].str) == 0)
+ {
+ color_mode = values[i].mode;
+ if (color_mode == color_auto)
+ color_mode
+ = isatty (STDOUT_FILENO) ? color_always : color_never;
+ break;
+ }
+ if (i == nvalues)
+ {
+ error (0, 0, dgettext ("elfutils", "\
+%s: invalid argument '%s' for '--color'\n\
+valid arguments are:\n\
+ - 'always', 'yes', 'force'\n\
+ - 'never', 'no', 'none'\n\
+ - 'auto', 'tty', 'if-tty'\n"),
+ program_invocation_short_name, arg);
+ argp_help (&color_argp, stderr, ARGP_HELP_SEE,
+ program_invocation_short_name);
+ exit (EXIT_FAILURE);
+ }
+ }
+
+ if (color_mode == color_always)
+ {
+ const char *env = getenv ("ELFUTILS_COLORS");
+ if (env != NULL)
+ {
+ do
+ {
+ const char *start = env;
+ while (*env != '=' && *env != '\0')
+ ++env;
+ if (*env == '=' && env != start)
+ {
+ size_t name_len = env - start;
+ const char *val = ++env;
+ env = strchrnul (env, ':');
+ if (val != env)
+ {
+ static const struct
+ {
+ unsigned char len;
+ const char name[sizeof (char *) - 1];
+ char **varp;
+ } known[] =
+ {
+#define E(name, var) { sizeof (#name) - 1, #name, &color_##var }
+ E (a, address),
+ E (b, bytes),
+ E (m, mnemonic),
+ E (o, operand),
+ E (o1, operand1),
+ E (o1, operand2),
+ E (o1, operand3),
+ E (l, label),
+ E (u, undef),
+ E (ut, undef_tls),
+ E (uw, undef_weak),
+ E (sy, symbol),
+ E (st, tls),
+ E (sw, weak),
+ };
+ const size_t nknown = (sizeof (known)
+ / sizeof (known[0]));
+
+ for (size_t i = 0; i < nknown; ++i)
+ if (name_len == known[i].len
+ && memcmp (start, known[i].name, name_len) == 0)
+ {
+ if (asprintf (known[i].varp, "\e[%.*sm",
+ (int) (env - val), val) < 0)
+ error (EXIT_FAILURE, errno,
+ gettext ("cannot allocate memory"));
+ break;
+ }
+ }
+ if (*env == ':')
+ ++env;
+ }
+ }
+ while (*env != '\0');
+
+ if (color_operand != NULL)
+ {
+ if (color_operand1[0] == '\0')
+ color_operand1 = color_operand;
+ if (color_operand2[0] == '\0')
+ color_operand2 = color_operand;
+ if (color_operand3[0] == '\0')
+ color_operand3 = color_operand;
+ }
+ }
+#if 0
+ else
+ {
+ // XXX Just for testing.
+ color_address = xstrdup ("\e[38;5;166;1m");
+ color_bytes = xstrdup ("\e[38;5;141m");
+ color_mnemonic = xstrdup ("\e[38;5;202;1m");
+ color_operand1 = xstrdup ("\e[38;5;220m");
+ color_operand2 = xstrdup ("\e[38;5;48m");
+ color_operand3 = xstrdup ("\e[38;5;112m");
+ color_label = xstrdup ("\e[38;5;21m");
+ }
+#endif
+ }
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
diff --git a/lib/color.h b/lib/color.h
new file mode 100644
index 0000000..3872eb0
--- /dev/null
+++ b/lib/color.h
@@ -0,0 +1,63 @@
+/* Handling of color output.
+ Copyright (C) 2017 The Qt Company
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2011.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+
+#ifndef COLOR_H
+#define COLOR_H 1
+
+/* Command line parser. */
+extern const struct argp color_argp;
+
+/* Coloring mode. */
+enum color_enum
+ {
+ color_never = 0,
+ color_always,
+ color_auto
+ } __attribute__ ((packed));
+extern enum color_enum color_mode;
+
+/* Colors to use for the various components. */
+extern char *color_address;
+extern char *color_bytes;
+extern char *color_mnemonic;
+extern char *color_operand1;
+extern char *color_operand2;
+extern char *color_operand3;
+extern char *color_label;
+extern char *color_undef;
+extern char *color_undef_tls;
+extern char *color_undef_weak;
+extern char *color_symbol;
+extern char *color_tls;
+extern char *color_weak;
+
+extern const char color_off[];
+
+#endif /* color.h */
diff --git a/lib/crc32.c b/lib/crc32.c
new file mode 100644
index 0000000..758602e
--- /dev/null
+++ b/lib/crc32.c
@@ -0,0 +1,102 @@
+/* Copyright (C) 2002 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdint.h>
+#include "system.h"
+
+
+/* Table computed with Mark Adler's makecrc.c utility. */
+static const uint32_t crc32_table[256] =
+{
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+ 0x2d02ef8d
+};
+
+uint32_t
+crc32 (uint32_t crc, unsigned char *buf, size_t len)
+{
+ unsigned char *end;
+
+ crc = ~crc;
+ for (end = buf + len; buf < end; ++buf)
+ crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+ return ~crc;
+}
diff --git a/lib/crc32_file.c b/lib/crc32_file.c
new file mode 100644
index 0000000..f7607d0
--- /dev/null
+++ b/lib/crc32_file.c
@@ -0,0 +1,92 @@
+/* Compute CRC32 checksum of file contents.
+ Copyright (C) 2006 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libeu.h"
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include "system.h"
+
+int
+crc32_file (int fd, uint32_t *resp)
+{
+ unsigned char buffer[1024 * 8];
+ uint32_t crc = 0;
+ off_t off = 0;
+ ssize_t count;
+
+ struct stat st;
+ if (fstat (fd, &st) == 0)
+ {
+ /* Try mapping in the file data. */
+ size_t mapsize = st.st_size;
+ void *mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (mapped == MAP_FAILED && errno == ENOMEM)
+ {
+ const size_t pagesize = sysconf (_SC_PAGESIZE);
+ mapsize = ((mapsize / 2) + pagesize - 1) & -pagesize;
+ while (mapsize >= pagesize
+ && (mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE,
+ fd, 0)) == MAP_FAILED && errno == ENOMEM)
+ mapsize /= 2;
+ }
+ if (mapped != MAP_FAILED)
+ {
+ do
+ {
+ if (st.st_size <= (off_t) mapsize)
+ {
+ *resp = crc32 (crc, mapped, st.st_size);
+ munmap (mapped, mapsize);
+ return 0;
+ }
+ crc = crc32 (crc, mapped, mapsize);
+ off += mapsize;
+ st.st_size -= mapsize;
+ } while (mmap (mapped, mapsize, PROT_READ, MAP_FIXED|MAP_PRIVATE,
+ fd, off) == mapped);
+ munmap (mapped, mapsize);
+ }
+ }
+
+ while ((count = TEMP_FAILURE_RETRY (pread (fd, buffer, sizeof buffer,
+ off))) > 0)
+ {
+ off += count;
+ crc = crc32 (crc, buffer, count);
+ }
+
+ *resp = crc;
+
+ return count == 0 ? 0 : -1;
+}
diff --git a/lib/dynamicsizehash.c b/lib/dynamicsizehash.c
new file mode 100644
index 0000000..f9406eb
--- /dev/null
+++ b/lib/dynamicsizehash.c
@@ -0,0 +1,315 @@
+/* Copyright (C) 2000-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <system.h>
+
+/* Before including this file the following macros must be defined:
+
+ NAME name of the hash table structure.
+ TYPE data type of the hash table entries
+ COMPARE comparison function taking two pointers to TYPE objects
+
+ The following macros if present select features:
+
+ ITERATE iterating over the table entries is possible
+ REVERSE iterate in reverse order of insert
+ */
+
+
+static size_t
+lookup (NAME *htab, HASHTYPE hval, TYPE val __attribute__ ((unused)))
+{
+ /* First hash function: simply take the modul but prevent zero. Small values
+ can skip the division, which helps performance when this is common. */
+ size_t idx = 1 + (hval < htab->size ? hval : hval % htab->size);
+
+ if (htab->table[idx].hashval != 0)
+ {
+ HASHTYPE hash;
+
+ if (htab->table[idx].hashval == hval
+ && COMPARE (htab->table[idx].data, val) == 0)
+ return idx;
+
+ /* Second hash function as suggested in [Knuth]. */
+ hash = 1 + hval % (htab->size - 2);
+
+ do
+ {
+ if (idx <= hash)
+ idx = htab->size + idx - hash;
+ else
+ idx -= hash;
+
+ /* If entry is found use it. */
+ if (htab->table[idx].hashval == hval
+ && COMPARE (htab->table[idx].data, val) == 0)
+ return idx;
+ }
+ while (htab->table[idx].hashval);
+ }
+ return idx;
+}
+
+
+static void
+insert_entry_2 (NAME *htab, HASHTYPE hval, size_t idx, TYPE data)
+{
+#ifdef ITERATE
+ if (htab->table[idx].hashval == 0)
+ {
+# ifdef REVERSE
+ htab->table[idx].next = htab->first;
+ htab->first = &htab->table[idx];
+# else
+ /* Add the new value to the list. */
+ if (htab->first == NULL)
+ htab->first = htab->table[idx].next = &htab->table[idx];
+ else
+ {
+ htab->table[idx].next = htab->first->next;
+ htab->first = htab->first->next = &htab->table[idx];
+ }
+# endif
+ }
+#endif
+
+ htab->table[idx].hashval = hval;
+ htab->table[idx].data = data;
+
+ ++htab->filled;
+ if (100 * htab->filled > 90 * htab->size)
+ {
+ /* Table is filled more than 90%. Resize the table. */
+#ifdef ITERATE
+ __typeof__ (htab->first) first;
+# ifndef REVERSE
+ __typeof__ (htab->first) runp;
+# endif
+#else
+ size_t old_size = htab->size;
+#endif
+#define _TABLE(name) \
+ name##_ent *table = htab->table
+#define TABLE(name) _TABLE (name)
+ TABLE(NAME);
+
+ htab->size = next_prime (htab->size * 2);
+ htab->filled = 0;
+#ifdef ITERATE
+ first = htab->first;
+ htab->first = NULL;
+#endif
+ htab->table = calloc ((1 + htab->size), sizeof (htab->table[0]));
+ if (htab->table == NULL)
+ {
+ /* We cannot enlarge the table. Live with what we got. This
+ might lead to an infinite loop at some point, though. */
+ htab->table = table;
+ return;
+ }
+
+ /* Add the old entries to the new table. When iteration is
+ supported we maintain the order. */
+#ifdef ITERATE
+# ifdef REVERSE
+ while (first != NULL)
+ {
+ insert_entry_2 (htab, first->hashval,
+ lookup (htab, first->hashval, first->data),
+ first->data);
+
+ first = first->next;
+ }
+# else
+ assert (first != NULL);
+ runp = first = first->next;
+ do
+ insert_entry_2 (htab, runp->hashval,
+ lookup (htab, runp->hashval, runp->data), runp->data);
+ while ((runp = runp->next) != first);
+# endif
+#else
+ for (idx = 1; idx <= old_size; ++idx)
+ if (table[idx].hashval != 0)
+ insert_entry_2 (htab, table[idx].hashval,
+ lookup (htab, table[idx].hashval, table[idx].data),
+ table[idx].data);
+#endif
+
+ free (table);
+ }
+}
+
+
+int
+#define INIT(name) _INIT (name)
+#define _INIT(name) \
+ name##_init
+INIT(NAME) (NAME *htab, size_t init_size)
+{
+ /* We need the size to be a prime. */
+ init_size = next_prime (init_size);
+
+ /* Initialize the data structure. */
+ htab->size = init_size;
+ htab->filled = 0;
+#ifdef ITERATE
+ htab->first = NULL;
+#endif
+ htab->table = (void *) calloc ((init_size + 1), sizeof (htab->table[0]));
+ if (htab->table == NULL)
+ return -1;
+
+ return 0;
+}
+
+
+int
+#define FREE(name) _FREE (name)
+#define _FREE(name) \
+ name##_free
+FREE(NAME) (NAME *htab)
+{
+ free (htab->table);
+ return 0;
+}
+
+
+int
+#define INSERT(name) _INSERT (name)
+#define _INSERT(name) \
+ name##_insert
+INSERT(NAME) (NAME *htab, HASHTYPE hval, TYPE data)
+{
+ size_t idx;
+
+ /* Make the hash value nonzero. */
+ hval = hval ?: 1;
+
+ idx = lookup (htab, hval, data);
+
+ if (htab->table[idx].hashval != 0)
+ /* We don't want to overwrite the old value. */
+ return -1;
+
+ /* An empty bucket has been found. */
+ insert_entry_2 (htab, hval, idx, data);
+ return 0;
+}
+
+
+#ifdef OVERWRITE
+int
+#define INSERT(name) _INSERT (name)
+#define _INSERT(name) \
+ name##_overwrite
+INSERT(NAME) (NAME *htab, HASHTYPE hval, TYPE data)
+{
+ size_t idx;
+
+ /* Make the hash value nonzero. */
+ hval = hval ?: 1;
+
+ idx = lookup (htab, hval, data);
+
+ /* The correct bucket has been found. */
+ insert_entry_2 (htab, hval, idx, data);
+ return 0;
+}
+#endif
+
+
+TYPE
+#define FIND(name) _FIND (name)
+#define _FIND(name) \
+ name##_find
+FIND(NAME) (NAME *htab, HASHTYPE hval, TYPE val)
+{
+ size_t idx;
+
+ /* Make the hash value nonzero. */
+ hval = hval ?: 1;
+
+ idx = lookup (htab, hval, val);
+
+ if (htab->table[idx].hashval == 0)
+ return NULL;
+
+ return htab->table[idx].data;
+}
+
+
+#ifdef ITERATE
+# define ITERATEFCT(name) _ITERATEFCT (name)
+# define _ITERATEFCT(name) \
+ name##_iterate
+TYPE
+ITERATEFCT(NAME) (NAME *htab, void **ptr)
+{
+ void *p = *ptr;
+
+# define TYPENAME(name) _TYPENAME (name)
+# define _TYPENAME(name) name##_ent
+
+# ifdef REVERSE
+ if (p == NULL)
+ p = htab->first;
+ else
+ p = ((TYPENAME(NAME) *) p)->next;
+
+ if (p == NULL)
+ {
+ *ptr = NULL;
+ return NULL;
+ }
+# else
+ if (p == NULL)
+ {
+ if (htab->first == NULL)
+ return NULL;
+ p = htab->first->next;
+ }
+ else
+ {
+ if (p == htab->first)
+ return NULL;
+
+ p = ((TYPENAME(NAME) *) p)->next;
+ }
+# endif
+
+ /* Prepare the next element. If possible this will pull the data
+ into the cache, for reading. */
+ __builtin_prefetch (((TYPENAME(NAME) *) p)->next, 0, 2);
+
+ return ((TYPENAME(NAME) *) (*ptr = p))->data;
+}
+#endif
diff --git a/lib/dynamicsizehash.h b/lib/dynamicsizehash.h
new file mode 100644
index 0000000..ccd41d0
--- /dev/null
+++ b/lib/dynamicsizehash.h
@@ -0,0 +1,127 @@
+/* Copyright (C) 2000-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <stddef.h>
+
+/* Before including this file the following macros must be defined:
+
+ NAME name of the hash table structure.
+ TYPE data type of the hash table entries
+
+ The following macros if present select features:
+
+ ITERATE iterating over the table entries is possible
+ HASHTYPE integer type for hash values, default unsigned long int
+ */
+
+
+/* Optionally include an entry pointing to the first used entry. */
+#ifdef ITERATE
+# define FIRST(name) name##_ent *first;
+# define NEXT(name) struct name##_ent *next;
+#else
+# define FIRST(name)
+# define NEXT(name)
+#endif
+
+#ifndef HASHTYPE
+# define HASHTYPE unsigned long int
+#endif
+
+
+/* Defined separately. */
+extern size_t next_prime (size_t seed);
+
+
+/* Table entry type. */
+#define _DYNHASHENTTYPE(name) \
+ typedef struct name##_ent \
+ { \
+ HASHTYPE hashval; \
+ TYPE data; \
+ NEXT (name) \
+ } name##_ent
+#define DYNHASHENTTYPE(name) _DYNHASHENTTYPE (name)
+DYNHASHENTTYPE (NAME);
+
+
+/* Type of the dynamic hash table data structure. */
+#define _DYNHASHTYPE(name) \
+typedef struct \
+{ \
+ size_t size; \
+ size_t filled; \
+ name##_ent *table; \
+ FIRST (name) \
+} name
+#define DYNHASHTYPE(name) _DYNHASHTYPE (name)
+DYNHASHTYPE (NAME);
+
+
+
+#define _FUNCTIONS(name) \
+/* Initialize the hash table. */ \
+extern int name##_init (name *htab, size_t init_size); \
+ \
+/* Free resources allocated for hash table. */ \
+extern int name##_free (name *htab); \
+ \
+/* Insert new entry. */ \
+extern int name##_insert (name *htab, HASHTYPE hval, TYPE data); \
+ \
+/* Insert new entry, possibly overwrite old entry. */ \
+extern int name##_overwrite (name *htab, HASHTYPE hval, TYPE data); \
+ \
+/* Find entry in hash table. */ \
+extern TYPE name##_find (name *htab, HASHTYPE hval, TYPE val);
+#define FUNCTIONS(name) _FUNCTIONS (name)
+FUNCTIONS (NAME)
+
+
+#ifdef ITERATE
+# define _XFUNCTIONS(name) \
+/* Get next element in table. */ \
+extern TYPE name##_iterate (name *htab, void **ptr);
+# define XFUNCTIONS(name) _XFUNCTIONS (name)
+XFUNCTIONS (NAME)
+#endif
+
+#ifndef NO_UNDEF
+# undef DYNHASHENTTYPE
+# undef DYNHASHTYPE
+# undef FUNCTIONS
+# undef _FUNCTIONS
+# undef XFUNCTIONS
+# undef _XFUNCTIONS
+# undef NAME
+# undef TYPE
+# undef ITERATE
+# undef COMPARE
+# undef FIRST
+# undef NEXT
+#endif
diff --git a/lib/eu-config.h b/lib/eu-config.h
new file mode 100644
index 0000000..84b22d7
--- /dev/null
+++ b/lib/eu-config.h
@@ -0,0 +1,209 @@
+/* Configuration definitions.
+ Copyright (C) 2008, 2009 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef EU_CONFIG_H
+#define EU_CONFIG_H 1
+
+#ifdef USE_LOCKS
+# include <pthread.h>
+# include <assert.h>
+# define rwlock_define(class,name) class pthread_rwlock_t name
+# define RWLOCK_CALL(call) \
+ ({ int _err = pthread_rwlock_ ## call; assert_perror (_err); })
+# define rwlock_init(lock) RWLOCK_CALL (init (&lock, NULL))
+# define rwlock_fini(lock) RWLOCK_CALL (destroy (&lock))
+# define rwlock_rdlock(lock) RWLOCK_CALL (rdlock (&lock))
+# define rwlock_wrlock(lock) RWLOCK_CALL (wrlock (&lock))
+# define rwlock_unlock(lock) RWLOCK_CALL (unlock (&lock))
+#else
+/* Eventually we will allow multi-threaded applications to use the
+ libraries. Therefore we will add the necessary locking although
+ the macros used expand to nothing for now. */
+# define rwlock_define(class,name) class int name
+# define rwlock_init(lock) ((void) (lock))
+# define rwlock_fini(lock) ((void) (lock))
+# define rwlock_rdlock(lock) ((void) (lock))
+# define rwlock_wrlock(lock) ((void) (lock))
+# define rwlock_unlock(lock) ((void) (lock))
+#endif /* USE_LOCKS */
+
+/* gettext helper macro. */
+#define N_(Str) Str
+
+/* Compiler-specific definitions. */
+#define strong_alias(name, aliasname) \
+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+
+#ifdef __i386__
+# define internal_function __attribute__ ((regparm (3), stdcall))
+#else
+# define internal_function /* nothing */
+#endif
+
+#define internal_strong_alias(name, aliasname) \
+ extern __typeof (name) aliasname __attribute__ ((alias (#name))) internal_function;
+
+#ifdef HAVE_VISIBILITY
+#define attribute_hidden \
+ __attribute__ ((visibility ("hidden")))
+#else
+#define attribute_hidden /* empty */
+#endif
+
+#ifdef HAVE_GCC_STRUCT
+#define attribute_packed \
+ __attribute__ ((packed, gcc_struct))
+#else
+#define attribute_packed \
+ __attribute__ ((packed))
+#endif
+
+/* Define ALLOW_UNALIGNED if the architecture allows operations on
+ unaligned memory locations. */
+#define SANITIZE_UNDEFINED 1
+#if (defined __i386__ || defined __x86_64__) && ! CHECK_UNDEFINED
+# define ALLOW_UNALIGNED 1
+#else
+# define ALLOW_UNALIGNED 0
+#endif
+
+#if DEBUGPRED
+# ifdef __x86_64__
+asm (".section predict_data, \"aw\"; .previous\n"
+ ".section predict_line, \"a\"; .previous\n"
+ ".section predict_file, \"a\"; .previous");
+# ifndef PIC
+# define debugpred__(e, E) \
+ ({ long int _e = !!(e); \
+ asm volatile (".pushsection predict_data; ..predictcnt%=: .quad 0; .quad 0\n" \
+ ".section predict_line; .quad %c1\n" \
+ ".section predict_file; .quad %c2; .popsection\n" \
+ "addq $1,..predictcnt%=(,%0,8)" \
+ : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \
+ __builtin_expect (_e, E); \
+ })
+# endif
+# elif defined __i386__
+asm (".section predict_data, \"aw\"; .previous\n"
+ ".section predict_line, \"a\"; .previous\n"
+ ".section predict_file, \"a\"; .previous");
+# ifndef PIC
+# define debugpred__(e, E) \
+ ({ long int _e = !!(e); \
+ asm volatile (".pushsection predict_data; ..predictcnt%=: .long 0; .long 0\n" \
+ ".section predict_line; .long %c1\n" \
+ ".section predict_file; .long %c2; .popsection\n" \
+ "incl ..predictcnt%=(,%0,8)" \
+ : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \
+ __builtin_expect (_e, E); \
+ })
+# endif
+# endif
+# ifdef debugpred__
+# define unlikely(e) debugpred__ (e,0)
+# define likely(e) debugpred__ (e,1)
+# endif
+#endif
+#ifndef likely
+# define unlikely(expr) __builtin_expect (!!(expr), 0)
+# define likely(expr) __builtin_expect (!!(expr), 1)
+#endif
+
+#define obstack_calloc(ob, size) \
+ ({ size_t _s = (size); memset (obstack_alloc (ob, _s), '\0', _s); })
+#define obstack_strdup(ob, str) \
+ ({ const char *_s = (str); obstack_copy0 (ob, _s, strlen (_s)); })
+#define obstack_strndup(ob, str, n) \
+ ({ const char *_s = (str); obstack_copy0 (ob, _s, strnlen (_s, n)); })
+
+#if __STDC_VERSION__ >= 199901L
+# define flexarr_size /* empty */
+#else
+# define flexarr_size 0
+#endif
+
+/* Calling conventions. */
+#ifdef __i386__
+# define CALLING_CONVENTION regparm (3), stdcall
+# define AND_CALLING_CONVENTION , regparm (3), stdcall
+#else
+# define CALLING_CONVENTION
+# define AND_CALLING_CONVENTION
+#endif
+
+/* Avoid PLT entries. */
+#ifdef PIC
+# define INTUSE(name) _INTUSE(name)
+# define _INTUSE(name) __##name##_internal
+# define INTDEF(name) _INTDEF(name)
+# define _INTDEF(name) \
+ extern __typeof__ (name) __##name##_internal __attribute__ ((alias (#name)));
+# define INTDECL(name) _INTDECL(name)
+# define _INTDECL(name) \
+ extern __typeof__ (name) __##name##_internal attribute_hidden;
+#else
+# define INTUSE(name) name
+# define INTDEF(name) /* empty */
+# define INTDECL(name) /* empty */
+#endif
+
+/* This macro is used by the tests conditionalize for standalone building. */
+#define ELFUTILS_HEADER(name) <lib##name.h>
+
+
+#ifdef SYMBOL_VERSIONING
+# define OLD_VERSION(name, version) \
+ asm (".globl _compat." #version "." #name "\n" \
+ "_compat." #version "." #name " = " #name "\n" \
+ ".symver _compat." #version "." #name "," #name "@" #version);
+# define NEW_VERSION(name, version) \
+ asm (".symver " #name "," #name "@@@" #version);
+# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
+ asm (".symver _compat." #version "." #name "," #name "@" #version); \
+ __typeof (_compat_##prefix##_##name) _compat_##prefix##_##name \
+ asm ("_compat." #version "." #name);
+# define COMPAT_VERSION(name, version, prefix) \
+ asm (".symver _compat." #version "." #name "," #name "@" #version); \
+ __typeof (name) _compat_##prefix##_##name asm ("_compat." #version "." #name);
+#else
+# define OLD_VERSION(name, version) /* Nothing for static linking. */
+# define NEW_VERSION(name, version) /* Nothing for static linking. */
+# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
+ error "should use #ifdef SYMBOL_VERSIONING"
+# define COMPAT_VERSION(name, version, prefix) error "should use #ifdef SYMBOL_VERSIONING"
+#endif
+
+#ifndef FALLTHROUGH
+# ifdef HAVE_FALLTHROUGH
+# define FALLTHROUGH __attribute__ ((fallthrough))
+# else
+# define FALLTHROUGH ((void) 0)
+# endif
+#endif
+
+#endif /* eu-config.h */
diff --git a/lib/fixedsizehash.h b/lib/fixedsizehash.h
new file mode 100644
index 0000000..dac2a5f
--- /dev/null
+++ b/lib/fixedsizehash.h
@@ -0,0 +1,272 @@
+/* Fixed size hash table with internal linking.
+ Copyright (C) 2000, 2001, 2002, 2004, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/cdefs.h>
+
+#include <system.h>
+
+#ifdef __CONCAT
+#define CONCAT(t1,t2) __CONCAT (t1,t2)
+#else
+#define STROF(t2) t2
+#define CONCAT_EXPANDED(t1,t2) t1 ## t2
+#define CONCAT(t1,t2) CONCAT_EXPANDED(t1,t2)
+#endif
+
+/* Before including this file the following macros must be defined:
+
+ TYPE data type of the hash table entries
+ HASHFCT name of the hashing function to use
+ HASHTYPE type used for the hashing value
+ COMPARE comparison function taking two pointers to TYPE objects
+ CLASS can be defined to `static' to avoid exporting the functions
+ PREFIX prefix to be used for function and data type names
+ STORE_POINTER if defined the table stores a pointer and not an element
+ of type TYPE
+ INSERT_HASH if defined alternate insert function which takes a hash
+ value is defined
+ NO_FINI_FCT if defined the fini function is not defined
+*/
+
+
+/* Defined separately. */
+extern size_t next_prime (size_t seed);
+
+
+/* Set default values. */
+#ifndef HASHTYPE
+# define HASHTYPE size_t
+#endif
+
+#ifndef CLASS
+# define CLASS
+#endif
+
+#ifndef PREFIX
+# define PREFIX
+#endif
+
+
+/* The data structure. */
+struct CONCAT(PREFIX,fshash)
+{
+ size_t nslots;
+ struct CONCAT(PREFIX,fshashent)
+ {
+ HASHTYPE hval;
+#ifdef STORE_POINTER
+# define ENTRYP(el) (el).entry
+ TYPE *entry;
+#else
+# define ENTRYP(el) &(el).entry
+ TYPE entry;
+#endif
+ } table[0];
+};
+
+
+/* Constructor for the hashing table. */
+CLASS struct CONCAT(PREFIX,fshash) *
+CONCAT(PREFIX,fshash_init) (size_t nelems)
+{
+ struct CONCAT(PREFIX,fshash) *result;
+ /* We choose a size for the hashing table 150% over the number of
+ entries. This will guarantee short medium search lengths. */
+ const size_t max_size_t = ~((size_t) 0);
+
+ if (nelems >= (max_size_t / 3) * 2)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /* Adjust the size to be used for the hashing table. */
+ nelems = next_prime (MAX ((nelems * 3) / 2, 10));
+
+ /* Allocate the data structure for the result. */
+ result = (struct CONCAT(PREFIX,fshash) *)
+ xcalloc (sizeof (struct CONCAT(PREFIX,fshash))
+ + (nelems + 1) * sizeof (struct CONCAT(PREFIX,fshashent)), 1);
+ if (result == NULL)
+ return NULL;
+
+ result->nslots = nelems;
+
+ return result;
+}
+
+
+#ifndef NO_FINI_FCT
+CLASS void
+CONCAT(PREFIX,fshash_fini) (struct CONCAT(PREFIX,fshash) *htab)
+{
+ free (htab);
+}
+#endif
+
+
+static struct CONCAT(PREFIX,fshashent) *
+CONCAT(PREFIX,fshash_lookup) (struct CONCAT(PREFIX,fshash) *htab,
+ HASHTYPE hval, TYPE *data)
+{
+ size_t idx = 1 + hval % htab->nslots;
+
+ if (htab->table[idx].hval != 0)
+ {
+ HASHTYPE hash;
+
+ /* See whether this is the same entry. */
+ if (htab->table[idx].hval == hval
+ && COMPARE (data, ENTRYP (htab->table[idx])) == 0)
+ return &htab->table[idx];
+
+ /* Second hash function as suggested in [Knuth]. */
+ hash = 1 + hval % (htab->nslots - 2);
+
+ do
+ {
+ if (idx <= hash)
+ idx = htab->nslots + idx - hash;
+ else
+ idx -= hash;
+
+ if (htab->table[idx].hval == hval
+ && COMPARE (data, ENTRYP(htab->table[idx])) == 0)
+ return &htab->table[idx];
+ }
+ while (htab->table[idx].hval != 0);
+ }
+
+ return &htab->table[idx];
+}
+
+
+CLASS int
+__attribute__ ((unused))
+CONCAT(PREFIX,fshash_insert) (struct CONCAT(PREFIX,fshash) *htab,
+ const char *str,
+ size_t len __attribute__ ((unused)), TYPE *data)
+{
+ HASHTYPE hval = HASHFCT (str, len ?: strlen (str));
+ struct CONCAT(PREFIX,fshashent) *slot;
+
+ slot = CONCAT(PREFIX,fshash_lookup) (htab, hval, data);
+ if (slot->hval != 0)
+ /* We don't want to overwrite the old value. */
+ return -1;
+
+ slot->hval = hval;
+#ifdef STORE_POINTER
+ slot->entry = data;
+#else
+ slot->entry = *data;
+#endif
+
+ return 0;
+}
+
+
+#ifdef INSERT_HASH
+CLASS int
+__attribute__ ((unused))
+CONCAT(PREFIX,fshash_insert_hash) (struct CONCAT(PREFIX,fshash) *htab,
+ HASHTYPE hval, TYPE *data)
+{
+ struct CONCAT(PREFIX,fshashent) *slot;
+
+ slot = CONCAT(PREFIX,fshash_lookup) (htab, hval, data);
+ if (slot->hval != 0)
+ /* We don't want to overwrite the old value. */
+ return -1;
+
+ slot->hval = hval;
+#ifdef STORE_POINTER
+ slot->entry = data;
+#else
+ slot->entry = *data;
+#endif
+
+ return 0;
+}
+#endif
+
+
+CLASS int
+__attribute__ ((unused))
+CONCAT(PREFIX,fshash_overwrite) (struct CONCAT(PREFIX,fshash) *htab,
+ const char *str,
+ size_t len __attribute__ ((unused)),
+ TYPE *data)
+{
+ HASHTYPE hval = HASHFCT (str, len ?: strlen (str));
+ struct CONCAT(PREFIX,fshashent) *slot;
+
+ slot = CONCAT(PREFIX,fshash_lookup) (htab, hval, data);
+ slot->hval = hval;
+#ifdef STORE_POINTER
+ slot->entry = data;
+#else
+ slot->entry = *data;
+#endif
+
+ return 0;
+}
+
+
+CLASS const TYPE *
+CONCAT(PREFIX,fshash_find) (const struct CONCAT(PREFIX,fshash) *htab,
+ const char *str,
+ size_t len __attribute__ ((unused)), TYPE *data)
+{
+ HASHTYPE hval = HASHFCT (str, len ?: strlen (str));
+ struct CONCAT(PREFIX,fshashent) *slot;
+
+ slot = CONCAT(PREFIX,fshash_lookup) ((struct CONCAT(PREFIX,fshash) *) htab,
+ hval, data);
+ if (slot->hval == 0)
+ /* Not found. */
+ return NULL;
+
+ return ENTRYP(*slot);
+}
+
+
+/* Unset the macros we expect. */
+#undef TYPE
+#undef HASHFCT
+#undef HASHTYPE
+#undef COMPARE
+#undef CLASS
+#undef PREFIX
+#undef INSERT_HASH
+#undef STORE_POINTER
+#undef NO_FINI_FCT
diff --git a/lib/libeu.h b/lib/libeu.h
new file mode 100644
index 0000000..ecb4d01
--- /dev/null
+++ b/lib/libeu.h
@@ -0,0 +1,46 @@
+/* Declarations for the common library.
+ Copyright (C) 2006-2011 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef LIBEU_H
+#define LIBEU_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+extern void *xmalloc (size_t) __attribute__ ((__malloc__));
+extern void *xcalloc (size_t, size_t) __attribute__ ((__malloc__));
+extern void *xrealloc (void *, size_t) __attribute__ ((__malloc__));
+
+extern char *xstrdup (const char *) __attribute__ ((__malloc__));
+extern char *xstrndup (const char *, size_t) __attribute__ ((__malloc__));
+
+
+extern uint32_t crc32 (uint32_t crc, unsigned char *buf, size_t len);
+extern int crc32_file (int fd, uint32_t *resp);
+
+#endif
diff --git a/lib/list.h b/lib/list.h
new file mode 100644
index 0000000..fc5c73c
--- /dev/null
+++ b/lib/list.h
@@ -0,0 +1,100 @@
+/* Copyright (C) 2001, 2002, 2003 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef LIST_H
+#define LIST_H 1
+
+/* Add element to the end of a circular, double-linked list. */
+#define CDBL_LIST_ADD_REAR(first, newp) \
+ do { \
+ __typeof (newp) _newp = (newp); \
+ assert (_newp->next == NULL); \
+ assert (_newp->previous == NULL); \
+ if (unlikely ((first) == NULL)) \
+ (first) = _newp->next = _newp->previous = _newp; \
+ else \
+ { \
+ _newp->next = (first); \
+ _newp->previous = (first)->previous; \
+ _newp->previous->next = _newp->next->previous = _newp; \
+ } \
+ } while (0)
+
+/* Remove element from circular, double-linked list. */
+#define CDBL_LIST_DEL(first, elem) \
+ do { \
+ __typeof (elem) _elem = (elem); \
+ /* Check whether the element is indeed on the list. */ \
+ assert (first != NULL && _elem != NULL \
+ && (first != elem \
+ || ({ __typeof (elem) _runp = first->next; \
+ while (_runp != first) \
+ if (_runp == _elem) \
+ break; \
+ else \
+ _runp = _runp->next; \
+ _runp == _elem; }))); \
+ if (unlikely (_elem->next == _elem)) \
+ first = NULL; \
+ else \
+ { \
+ _elem->next->previous = _elem->previous; \
+ _elem->previous->next = _elem->next; \
+ if (unlikely (first == _elem)) \
+ first = _elem->next; \
+ } \
+ assert ((_elem->next = _elem->previous = NULL, 1)); \
+ } while (0)
+
+
+/* Add element to the front of a single-linked list. */
+#define SNGL_LIST_PUSH(first, newp) \
+ do { \
+ __typeof (newp) _newp = (newp); \
+ assert (_newp->next == NULL); \
+ _newp->next = first; \
+ first = _newp; \
+ } while (0)
+
+
+/* Add element to the rear of a circular single-linked list. */
+#define CSNGL_LIST_ADD_REAR(first, newp) \
+ do { \
+ __typeof (newp) _newp = (newp); \
+ assert (_newp->next == NULL); \
+ if (unlikely ((first) == NULL)) \
+ (first) = _newp->next = _newp; \
+ else \
+ { \
+ _newp->next = (first)->next; \
+ (first) = (first)->next = _newp; \
+ } \
+ } while (0)
+
+
+#endif /* list.h */
diff --git a/lib/next_prime.c b/lib/next_prime.c
new file mode 100644
index 0000000..f2c921e
--- /dev/null
+++ b/lib/next_prime.c
@@ -0,0 +1,66 @@
+/* Determine prime number.
+ Copyright (C) 2006 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <stddef.h>
+
+
+/* Test whether CANDIDATE is a prime. */
+static int
+is_prime (size_t candidate)
+{
+ /* No even number and none less than 10 will be passed here. */
+ size_t divn = 3;
+ size_t sq = divn * divn;
+
+ while (sq < candidate && candidate % divn != 0)
+ {
+ size_t old_sq = sq;
+ ++divn;
+ sq += 4 * divn;
+ if (sq < old_sq)
+ return 1;
+ ++divn;
+ }
+
+ return candidate % divn != 0;
+}
+
+
+/* We need primes for the table size. */
+size_t
+next_prime (size_t seed)
+{
+ /* Make it definitely odd. */
+ seed |= 1;
+
+ while (!is_prime (seed))
+ seed += 2;
+
+ return seed;
+}
diff --git a/lib/printversion.c b/lib/printversion.c
new file mode 100644
index 0000000..263c106
--- /dev/null
+++ b/lib/printversion.c
@@ -0,0 +1,45 @@
+/* Common argp_print_version_hook for all tools.
+ Copyright (C) 2016, 2017 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libintl.h>
+#include "printversion.h"
+
+void
+print_version (FILE *stream, struct argp_state *state)
+{
+ fprintf (stream, "%s (%s) %s\n", state->name, PACKAGE_NAME, PACKAGE_VERSION);
+ fprintf (stream, gettext ("\
+Copyright (C) %s The elfutils developers <%s>.\n\
+This is free software; see the source for copying conditions. There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+"), "2017", PACKAGE_URL);
+}
diff --git a/lib/printversion.h b/lib/printversion.h
new file mode 100644
index 0000000..a9e059f
--- /dev/null
+++ b/lib/printversion.h
@@ -0,0 +1,49 @@
+/* Common argp_print_version_hook for all tools.
+ Copyright (C) 2017 The Qt Company Ltd.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef PRINTVERSION_H
+#define PRINTVERSION_H 1
+
+#include <argp.h>
+#include <stdio.h>
+
+/* Defined in version.c. Common ARGP_PROGRAM_VERSION_HOOK_DEF. */
+void print_version (FILE *stream, struct argp_state *state);
+
+/* We need define two variables, argp_program_version_hook and
+ argp_program_bug_address, in all programs. argp.h declares these
+ variables as non-const (which is correct in general). But we can
+ do better, it is not going to change. So we want to move them into
+ the .rodata section. Define macros to do the trick. */
+#define ARGP_PROGRAM_VERSION_HOOK_DEF \
+ void (*const apvh) (FILE *, struct argp_state *) \
+ __asm ("argp_program_version_hook")
+#define ARGP_PROGRAM_BUG_ADDRESS_DEF \
+ const char *const apba__ __asm ("argp_program_bug_address")
+
+#endif // PRINTVERSION_H
diff --git a/lib/system.h b/lib/system.h
new file mode 100644
index 0000000..9203335
--- /dev/null
+++ b/lib/system.h
@@ -0,0 +1,154 @@
+/* Declarations for common convenience functions.
+ Copyright (C) 2006-2011 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef LIB_SYSTEM_H
+#define LIB_SYSTEM_H 1
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/param.h>
+#include <endian.h>
+#include <byteswap.h>
+#include <unistd.h>
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define LE32(n) (n)
+# define LE64(n) (n)
+# define BE32(n) bswap_32 (n)
+# define BE64(n) bswap_64 (n)
+#elif __BYTE_ORDER == __BIG_ENDIAN
+# define BE32(n) (n)
+# define BE64(n) (n)
+# define LE32(n) bswap_32 (n)
+# define LE64(n) bswap_64 (n)
+#else
+# error "Unknown byte order"
+#endif
+
+#ifndef MAX
+#define MAX(m, n) ((m) < (n) ? (n) : (m))
+#endif
+
+#ifndef MIN
+#define MIN(m, n) ((m) < (n) ? (m) : (n))
+#endif
+
+#if !HAVE_DECL_POWEROF2
+#define powerof2(x) (((x) & ((x) - 1)) == 0)
+#endif
+
+#if !HAVE_DECL_MEMPCPY
+#define mempcpy(dest, src, n) \
+ ((void *) ((char *) memcpy (dest, src, n) + (size_t) n))
+#endif
+
+/* A special gettext function we use if the strings are too short. */
+#define sgettext(Str) \
+ ({ const char *__res = strrchr (gettext (Str), '|'); \
+ __res ? __res + 1 : Str; })
+
+#define gettext_noop(Str) Str
+
+#ifndef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(expression) \
+ ({ ssize_t __res; \
+ do \
+ __res = expression; \
+ while (__res == -1 && errno == EINTR); \
+ __res; })
+#endif
+
+static inline ssize_t __attribute__ ((unused))
+pwrite_retry (int fd, const void *buf, size_t len, off_t off)
+{
+ ssize_t recvd = 0;
+
+ do
+ {
+ ssize_t ret = TEMP_FAILURE_RETRY (pwrite (fd, buf + recvd, len - recvd,
+ off + recvd));
+ if (ret <= 0)
+ return ret < 0 ? ret : recvd;
+
+ recvd += ret;
+ }
+ while ((size_t) recvd < len);
+
+ return recvd;
+}
+
+static inline ssize_t __attribute__ ((unused))
+write_retry (int fd, const void *buf, size_t len)
+{
+ ssize_t recvd = 0;
+
+ do
+ {
+ ssize_t ret = TEMP_FAILURE_RETRY (write (fd, buf + recvd, len - recvd));
+ if (ret <= 0)
+ return ret < 0 ? ret : recvd;
+
+ recvd += ret;
+ }
+ while ((size_t) recvd < len);
+
+ return recvd;
+}
+
+static inline ssize_t __attribute__ ((unused))
+pread_retry (int fd, void *buf, size_t len, off_t off)
+{
+ ssize_t recvd = 0;
+
+ do
+ {
+ ssize_t ret = TEMP_FAILURE_RETRY (pread (fd, buf + recvd, len - recvd,
+ off + recvd));
+ if (ret <= 0)
+ return ret < 0 ? ret : recvd;
+
+ recvd += ret;
+ }
+ while ((size_t) recvd < len);
+
+ return recvd;
+}
+
+/* The demangler from libstdc++. */
+extern char *__cxa_demangle (const char *mangled_name, char *output_buffer,
+ size_t *length, int *status);
+
+/* A static assertion. This will cause a compile-time error if EXPR,
+ which must be a compile-time constant, is false. */
+
+#define eu_static_assert(expr) \
+ extern int never_defined_just_used_for_checking[(expr) ? 1 : -1] \
+ __attribute__ ((unused))
+
+#endif /* system.h */
diff --git a/lib/xmalloc.c b/lib/xmalloc.c
new file mode 100644
index 0000000..0cde384
--- /dev/null
+++ b/lib/xmalloc.c
@@ -0,0 +1,80 @@
+/* Convenience functions for allocation.
+ Copyright (C) 2006, 2015 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <error.h>
+#include <libintl.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include "system.h"
+
+#ifndef _
+# define _(str) gettext (str)
+#endif
+
+
+/* Allocate N bytes of memory dynamically, with error checking. */
+void *
+xmalloc (size_t n)
+{
+ void *p;
+
+ p = malloc (n);
+ if (p == NULL)
+ error (EXIT_FAILURE, 0, _("memory exhausted"));
+ return p;
+}
+
+
+/* Allocate memory for N elements of S bytes, with error checking. */
+void *
+xcalloc (size_t n, size_t s)
+{
+ void *p;
+
+ p = calloc (n, s);
+ if (p == NULL)
+ error (EXIT_FAILURE, 0, _("memory exhausted"));
+ return p;
+}
+
+
+/* Change the size of an allocated block of memory P to N bytes,
+ with error checking. */
+void *
+xrealloc (void *p, size_t n)
+{
+ p = realloc (p, n);
+ if (p == NULL)
+ error (EXIT_FAILURE, 0, _("memory exhausted"));
+ return p;
+}
diff --git a/lib/xstrdup.c b/lib/xstrdup.c
new file mode 100644
index 0000000..ff1e3d4
--- /dev/null
+++ b/lib/xstrdup.c
@@ -0,0 +1,42 @@
+/* Convenience function for string allocation.
+ Copyright (C) 2006, 2015 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "libeu.h"
+
+
+/* Return a newly allocated copy of STRING. */
+char *
+xstrdup (const char *string)
+{
+ return strcpy (xmalloc (strlen (string) + 1), string);
+}
diff --git a/lib/xstrndup.c b/lib/xstrndup.c
new file mode 100644
index 0000000..a257aa9
--- /dev/null
+++ b/lib/xstrndup.c
@@ -0,0 +1,46 @@
+/* Convenience function for string allocation.
+ Copyright (C) 2006, 2015 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdint.h>
+#include <string.h>
+#include "libeu.h"
+#include "system.h"
+
+/* Return a newly allocated copy of STRING. */
+char *
+xstrndup (const char *string, size_t n)
+{
+ char *res;
+ size_t len = strnlen (string, n);
+ *((char *) mempcpy ((res = xmalloc (len + 1)), string, len)) = '\0';
+ return res;
+}