diff options
author | Mark Wielaard <mark@klomp.org> | 2018-10-21 23:41:32 +0200 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2018-11-09 18:11:48 +0100 |
commit | ecbe3120cddb1b9597a19a68c4265e4f2c530444 (patch) | |
tree | 40f6549cda3aa5bff3df983f15ac88d0da597b72 /libdwelf | |
parent | 4b0342b85b5b1a3d3636e06e3b5320954828dfb1 (diff) | |
download | elfutils-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/ChangeLog | 8 | ||||
-rw-r--r-- | libdwelf/Makefile.am | 2 | ||||
-rw-r--r-- | libdwelf/dwelf_elf_begin.c | 62 | ||||
-rw-r--r-- | libdwelf/libdwelf.h | 10 |
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 |