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>
This commit is contained in:
Mark Wielaard
2018-10-21 23:41:32 +02:00
parent 4b0342b85b
commit ecbe3120cd
14 changed files with 174 additions and 16 deletions
+7 -1
View File
@@ -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.
+1 -1
View File
@@ -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)
+62
View File
@@ -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;
}
+9 -1
View File
@@ -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