summaryrefslogtreecommitdiff
path: root/libdwelf
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2018-10-21 23:41:32 +0200
committerMark Wielaard <mark@klomp.org>2018-11-09 18:11:48 +0100
commitecbe3120cddb1b9597a19a68c4265e4f2c530444 (patch)
tree40f6549cda3aa5bff3df983f15ac88d0da597b72 /libdwelf
parent4b0342b85b5b1a3d3636e06e3b5320954828dfb1 (diff)
downloadelfutils-ecbe3120cddb1b9597a19a68c4265e4f2c530444.tar.gz
libdwelf: New function dwelf_elf_begin.
This introduces a new function dwelf_elf_begin which creates a (read-only) ELF handle from a possibly compressed file handle or a file that start with a linux kernel header. This can be used in eu-readelf to (re)open a (pure) ELF. eu-readelf uses libdwfl to relocate addresses in the original file in case it is ET_REL. But to show the "raw" data it might need to (re)open the file. Which could fail if the file was compressed. And produced an obscure error message: "cannot create EBL handle". This rewrites __libdw_open_file a little so that the given file handle will never be closed (whether on success or failure) and introduces a new internal function __libdw_open_elf that dwelf_elf_begin wraps. Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'libdwelf')
-rw-r--r--libdwelf/ChangeLog8
-rw-r--r--libdwelf/Makefile.am2
-rw-r--r--libdwelf/dwelf_elf_begin.c62
-rw-r--r--libdwelf/libdwelf.h10
4 files changed, 79 insertions, 3 deletions
diff --git a/libdwelf/ChangeLog b/libdwelf/ChangeLog
index ba921347..88be3421 100644
--- a/libdwelf/ChangeLog
+++ b/libdwelf/ChangeLog
@@ -1,9 +1,15 @@
+2018-10-21 Mark Wielaard <mark@klomp.org>
+
+ * libdwelf.h (dwelf_elf_begin): Add function declaration.
+ * dwelf_elf_begin.c: New file.
+ * Makefile.am (libdwelf_a_SOURCES): Add dwelf_elf_begin.c.
+
2018-10-18 Mark Wielaard <mark@klomp.org>
* dwelf_elf_gnu_build_id.c (find_elf_build_id): Check p_align to
set ELF type.
-2015-10-11 Akihiko Odaki <akihiko.odaki.4i@stu.hosei.ac.jp>
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i@stu.hosei.ac.jp>
* dwelf_strtab.c: Remove sys/param.h include.
(MIN): Remove definition.
diff --git a/libdwelf/Makefile.am b/libdwelf/Makefile.am
index 7ca767a9..a7933fda 100644
--- a/libdwelf/Makefile.am
+++ b/libdwelf/Makefile.am
@@ -41,7 +41,7 @@ noinst_HEADERS = libdwelfP.h
libdwelf_a_SOURCES = dwelf_elf_gnu_debuglink.c dwelf_dwarf_gnu_debugaltlink.c \
dwelf_elf_gnu_build_id.c dwelf_scn_gnu_compressed_size.c \
- dwelf_strtab.c
+ dwelf_strtab.c dwelf_elf_begin.c
libdwelf = $(libdw)
diff --git a/libdwelf/dwelf_elf_begin.c b/libdwelf/dwelf_elf_begin.c
new file mode 100644
index 00000000..79825338
--- /dev/null
+++ b/libdwelf/dwelf_elf_begin.c
@@ -0,0 +1,62 @@
+/* Creates an ELF handle from a possibly compressed file descriptor.
+ Copyright (C) 2018 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 "libdwelfP.h"
+#include "libdwflP.h"
+#include "libelfP.h"
+
+#include <unistd.h>
+
+Elf *
+dwelf_elf_begin (int fd)
+{
+ Elf *elf = NULL;
+ Dwfl_Error e = __libdw_open_elf (fd, &elf);
+ if (elf != NULL && elf_kind (elf) != ELF_K_NONE)
+ return elf;
+
+ /* Elf wasn't usable. Make sure there is a proper elf error message. */
+
+ if (elf != NULL)
+ elf_end (elf);
+
+ if (e != DWFL_E_LIBELF)
+ {
+ /* Force a bad ELF error. */
+ char badelf[EI_NIDENT] = { };
+ Elf *belf = elf_memory (badelf, EI_NIDENT);
+ elf32_getehdr (belf);
+ elf_end (belf);
+ }
+
+ return NULL;
+}
diff --git a/libdwelf/libdwelf.h b/libdwelf/libdwelf.h
index 72089dbf..6d491847 100644
--- a/libdwelf/libdwelf.h
+++ b/libdwelf/libdwelf.h
@@ -1,5 +1,5 @@
/* Interfaces for libdwelf. DWARF ELF Low-level Functions.
- Copyright (C) 2014, 2015, 2016 Red Hat, Inc.
+ Copyright (C) 2014, 2015, 2016, 2018 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -125,6 +125,14 @@ extern const char *dwelf_strent_str (Dwelf_Strent *se)
extern void dwelf_strtab_free (Dwelf_Strtab *st)
__nonnull_attribute__ (1);
+/* Creates a read-only Elf handle from the given file handle. The
+ file may be compressed and/or contain a linux kernel image header,
+ in which case it is eagerly decompressed in full and the Elf handle
+ is created as if created with elf_memory (). On error NULL is
+ returned. The Elf handle should be closed with elf_end (). The
+ file handle will not be closed. Does not return ELF_K_NONE handles. */
+extern Elf *dwelf_elf_begin (int fd);
+
#ifdef __cplusplus
}
#endif