[PATCH] addr2line: Set scopes to NULL after free in handle_address.
by Mark Wielaard
If dwarf_getscopes_die () fails then scopes might not be reset and we
could cause a double free.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 4 ++++
src/addr2line.c | 1 +
2 files changed, 5 insertions(+)
diff --git a/src/ChangeLog b/src/ChangeLog
index c93d54d..ee18007 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2015-05-21 Mark Wielaard <mjw(a)redhat.com>
+
+ * addr2line.c (handle_address): Set scopes to NULL after free.
+
2015-05-20 Mark Wielaard <mjw(a)redhat.com>
* addr2line.c (OPT_PRETTY): New constant define.
diff --git a/src/addr2line.c b/src/addr2line.c
index fc2ff28..97f988f 100644
--- a/src/addr2line.c
+++ b/src/addr2line.c
@@ -744,6 +744,7 @@ handle_address (const char *string, Dwfl *dwfl)
dwarf_offdie (dwfl_module_getdwarf (mod, &bias),
dieoff, &subroutine);
free (scopes);
+ scopes = NULL;
nscopes = dwarf_getscopes_die (&subroutine, &scopes);
if (nscopes > 1)
--
1.8.3.1
8 years, 11 months
Some eu-addr2line improvements
by Mark Wielaard
Hi,
eu-addr2line is mostly nicer to use than binutils addr2line IMHO,
because it can work with symbol offsets, separate debuginfo, pids,
core files, process maps, etc. But binutils addr2line has a couple of
options that are also useful that prevented using eu-addr2line as a drop
in replacement.
This patch set cleans up a few things and adds three new options.
[PATCH 1/5] addr2line: Split options in input and output format
Is a simple cleanup of the --help output.
[PATCH 2/5] addr2line: Always parse addresses as hex numbers.
Matches what binutils addr2line does, which IMHO makes more sense than
trying to parse the input as octal or decimal if we aren't sure they
are hex.
[PATCH 3/5] addr2line: Add -a, --address. Print address before for each entry.
Is even more useful with our implementation since we accept symbol+offset
as input. So this then returns what address that really translates to.
[PATCH 4/5] addr2line: Add demangler support.
Implemented as was done for eu-stack and eu-nm earlier.
[PATCH 5/5] addr2line: Add --pretty-print option
A more compact output format that is easier to parse.
A couple of testcases were added. All patches can also be found on the
mjw/addr2line git branch.
Cheers,
Mark
8 years, 11 months
[PATCH] libelf: Use possix_fallocate instead of ftruncate to extend ELF file.
by Mark Wielaard
This fixes an obscure SIGBUS error when using ELF_C_WRITE_MMAP on an ELF
file that needs extending when the underlying file system is (nearly) full.
Use posix_fallocate to make sure the file content is really there. Using
ftruncate might mean the file is extended, but space isn't allocated yet.
This might cause a SIGBUS once we write into the mmapped space and the disk
is full.
Using fallocate might fail on some file systems. posix_fallocate is
required to extend the file and allocate enough space even if the
underlying filesystem would normally return EOPNOTSUPP or the kernel
doesn't implement the fallocate syscall. Also posix_fallocate has been in
glibc since 2.1.94, while support for fallocate was only added in 2.10
and kernel 2.6.23.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libelf/ChangeLog | 5 +++++
libelf/elf_update.c | 16 +++++++++++++---
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 2d10b83..5e7b104 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2015-05-14 Mark Wielaard <mjw(a)redhat.com>
+
+ * elf_update.c (write_file): Use possix_fallocate instead of
+ ftruncate to extend file if necessary.
+
2015-05-13 Mark Wielaard <mjw(a)redhat.com>
* elf32_updatenull.c (default_ehdr): If e_phnum is zero then set
diff --git a/libelf/elf_update.c b/libelf/elf_update.c
index 54c20f5..3674e72 100644
--- a/libelf/elf_update.c
+++ b/libelf/elf_update.c
@@ -1,5 +1,5 @@
/* Update data structures for changes and write them out.
- Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006 Red Hat, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2015 Red Hat, Inc.
This file is part of elfutils.
Contributed by Ulrich Drepper <drepper(a)redhat.com>, 1999.
@@ -32,6 +32,7 @@
#endif
#include <libelf.h>
+#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
@@ -56,11 +57,19 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
We cannot do this if this file is in an archive. We also don't
do it *now* if we are shortening the file since this would
prevent programs to use the data of the file in generating the
- new file. We truncate the file later in this case. */
+ new file. We truncate the file later in this case.
+
+ Note we use posix_fallocate to make sure the file content is really
+ there. Using ftruncate might mean the file is extended, but space
+ isn't allocated yet. This might cause a SIGBUS once we write into
+ the mmapped space and the disk is full. Using fallocate might fail
+ on some file systems. posix_fallocate is required to extend the file
+ and allocate enough space even if the underlying filesystem would
+ normally return EOPNOTSUPP. */
if (elf->parent == NULL
&& (elf->maximum_size == ~((size_t) 0)
|| (size_t) size > elf->maximum_size)
- && unlikely (ftruncate (elf->fildes, size) != 0))
+ && unlikely (possix_fallocate (elf->fildes, 0, size) != 0))
{
__libelf_seterrno (ELF_E_WRITE_ERROR);
return -1;
@@ -94,6 +103,7 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
size = -1;
}
+ /* Reduce the file size if necessary. */
if (size != -1
&& elf->parent == NULL
&& elf->maximum_size != ~((size_t) 0)
--
1.8.3.1
8 years, 11 months
[PATCH] configure: Add --enable-sanitize-undefined.
by Mark Wielaard
Now that we are -fsanitize=undefined clean make sure we keep it that way.
We do have to disable alignment checking. Because we might explicitly
use unaligned accesses (see ALLOW_UNALIGNED). And we have to disable
integer overflow checking when running the tests under valgrind. Because
those are unreliable under VEX emulation.
Rename DISTCHECK_CONFIGURE_FLAGS to AM_DISTCHECK_CONFIGURE_FLAGS, so the
user can override. And add --enable-sanitize-undefined.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
ChangeLog | 8 ++++++++
Makefile.am | 4 ++--
configure.ac | 23 +++++++++++++++++++++++
3 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d3e46fc..91b2259 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2015-05-21 Mark Wielaard <mjw(a)redhat.com>
+
+ * configure.ac: Add --enable-sanitize-undefined.
+ Add -fno-sanitize=signed-integer-overflow when both
+ --enable-sanitize-undefined and --enable-valgrind are given.
+ * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Rename to...
+ (AM_DISTCHECK_CONFIGURE_FLAGS): this. Add --enable-sanitize-undefined.
+
2015-05-04 Anthony G. Basile <blueness(a)gentoo.org>
* configure.ac (argp_LDADD): Check if libc has argp and set
diff --git a/Makefile.am b/Makefile.am
index d044a7c..1454d04 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -33,9 +33,9 @@ EXTRA_DIST = elfutils.spec GPG-KEY NOTES CONTRIBUTING \
# Make sure the test build uses the same compiler, which on e.g. ppc64
# determines which platform we are actually testing.
# Run all tests under valgrind.
-DISTCHECK_CONFIGURE_FLAGS = \
+AM_DISTCHECK_CONFIGURE_FLAGS = \
--libdir=`echo $(libdir) | sed "s,^$(exec_prefix),$$dc_install_base,"`\
- --enable-valgrind \
+ --enable-valgrind --enable-sanitize-undefined \
CC="$(CC)"
distcheck-hook:
diff --git a/configure.ac b/configure.ac
index 68b7f5b..7415233 100644
--- a/configure.ac
+++ b/configure.ac
@@ -193,10 +193,32 @@ if test "$use_gcov" = yes; then
fi
AM_CONDITIONAL(GCOV, test "$use_gcov" = yes)
+AC_ARG_ENABLE([sanitize-undefined],
+ AS_HELP_STRING([--enable-sanitize-undefined],
+ [Use gcc undefined behaviour sanitizer]),
+ [use_undefined=$enableval], [use_undefined=no])
+if test "$use_undefined" = yes; then
+ old_CFLAGS="$CFLAGS"
+ old_CXXFLAGS="$CXXFLAGS"
+ # We explicitly use unaligned access when possible (see ALLOW_UNALIGNED)
+ # We want to fail immediately on first error, don't try to recover.
+ CFLAGS="$CFLAGS -fsanitize=undefined -fno-sanitize=alignment -fno-sanitize-recover"
+ CXXFLAGS="$CXXFLAGS -fsanitize=undefined -fno-sanitize=alignment -fno-sanitize-recover"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([])], use_undefined=yes, use_undefined=no)
+ AS_IF([test "x$use_undefined" != xyes],
+ AC_MSG_WARN([gcc undefined behaviour sanitizer not available])
+ CFLAGS="$old_CFLAGS" CXXFLAGS="$old_CXXFLAGS")
+fi
+
AC_ARG_ENABLE([valgrind],
AS_HELP_STRING([--enable-valgrind],[run all tests under valgrind]),
[use_valgrind=$enableval], [use_valgrind=no])
if test "$use_valgrind" = yes; then
+ # signed overflow checking isn't reliable under valgrind
+ if test "$use_undefined" = yes; then
+ CFLAGS="$CFLAGS -fno-sanitize=signed-integer-overflow"
+ CXXFLAGS="$CXXFLAGS -fno-sanitize=signed-integer-overflow"
+ fi
AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
if test "$HAVE_VALGRIND" = "no"; then
AC_MSG_ERROR([valgrind not found])
@@ -421,6 +443,7 @@ AC_MSG_NOTICE([
gprof support : ${use_gprof}
gcov support : ${use_gcov}
run all tests under valgrind : ${use_valgrind}
+ gcc undefined behaviour sanitizer : ${use_undefined}
use rpath in tests : ${tests_use_rpath}
test biarch : ${utrace_cv_cc_biarch}
])
--
2.1.0
8 years, 11 months
[PATCH] strip: Harden against bogus input files. Don't leak temp debug file on error.
by Mark Wielaard
There were various places where a bogus/unexpected input file would cause
eu-strip to crash. Also on an unexpected error eu-strip would leak the temp
debug file it was writing.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 13 +++
src/strip.c | 262 +++++++++++++++++++++++++++++++++++++++++-----------------
2 files changed, 200 insertions(+), 75 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 55bd4cc..02f6584 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,16 @@
+2015-05-12 Mark Wielaard <mjw(a)redhat.com>
+
+ * strip.c (debug_fd): New static variable.
+ (tmp_debug_fname): Likewise.
+ (cleanup_debug): New function using the above to clean up temporary
+ debug file.
+ (INTERNAL_ERROR): Call cleanup_debug.
+ (handle_elf): Use debug_fd and tmp_debug_fname statics and call
+ cleanup_debug before any error. Use output_fname instead of fname in
+ error messages when it exists (-o was given). SHT_NOBITS sections
+ can also be moved freely even if SHF_ALLOC is set. Add various
+ sanity checks. Use elf_assert instead of plain assert.
+
2015-05-08 Mark Wielaard <mjw(a)redhat.com>
* nm.c (show_symbols): Call gelf_fsize with EV_CURRENT.
diff --git a/src/strip.c b/src/strip.c
index 365b18d..63f5b9f 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -115,9 +115,18 @@ static int handle_elf (int fd, Elf *elf, const char *prefix,
static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
struct timespec tvp[2]);
+static int debug_fd = -1;
+static char *tmp_debug_fname = NULL;
+
+/* Close debug file descriptor, if opened. And remove temporary debug file. */
+static void cleanup_debug ();
+
#define INTERNAL_ERROR(fname) \
- error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s): %s"), \
- fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1))
+ do { \
+ cleanup_debug (); \
+ error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s): %s"), \
+ fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1)); \
+ } while (0)
/* Name of the output file. */
@@ -395,7 +404,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
char *fullname = alloca (prefix_len + 1 + fname_len);
char *cp = fullname;
Elf *debugelf = NULL;
- char *tmp_debug_fname = NULL;
+ tmp_debug_fname = NULL;
int result = 0;
size_t shdridx = 0;
size_t shstrndx;
@@ -449,7 +458,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
}
}
- int debug_fd = -1;
+ debug_fd = -1;
/* Get the EBL handling. Removing all debugging symbols with the -g
option or resolving all relocations between debug sections with
@@ -474,7 +483,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
the debug file if the file would not contain any
information. */
size_t debug_fname_len = strlen (debug_fname);
- tmp_debug_fname = (char *) alloca (debug_fname_len + sizeof (".XXXXXX"));
+ tmp_debug_fname = (char *) xmalloc (debug_fname_len + sizeof (".XXXXXX"));
strcpy (mempcpy (tmp_debug_fname, debug_fname, debug_fname_len),
".XXXXXX");
@@ -495,13 +504,19 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* Get the section header string table index. */
if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0))
- error (EXIT_FAILURE, 0,
- gettext ("cannot get section header string table index"));
+ {
+ cleanup_debug ();
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get section header string table index"));
+ }
/* Get the number of phdrs in the old file. */
size_t phnum;
if (elf_getphdrnum (elf, &phnum) != 0)
- error (EXIT_FAILURE, 0, gettext ("cannot get number of phdrs"));
+ {
+ cleanup_debug ();
+ error (EXIT_FAILURE, 0, gettext ("cannot get number of phdrs"));
+ }
/* We now create a new ELF descriptor for the same file. We
construct it almost exactly in the same way with some information
@@ -517,7 +532,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
&& unlikely (gelf_newphdr (newelf, phnum) == 0)))
{
error (0, 0, gettext ("cannot create new file '%s': %s"),
- output_fname, elf_errmsg (-1));
+ output_fname ?: fname, elf_errmsg (-1));
goto fail;
}
@@ -619,9 +634,10 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
goto illformed;
/* Sections in files other than relocatable object files which
- are not loaded can be freely moved by us. In relocatable
- object files everything can be moved. */
+ don't contain any file content or are not loaded can be freely
+ moved by us. In relocatable object files everything can be moved. */
if (ehdr->e_type == ET_REL
+ || shdr_info[cnt].shdr.sh_type == SHT_NOBITS
|| (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
shdr_info[cnt].shdr.sh_offset = 0;
@@ -637,7 +653,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* Cross-reference the sections contained in the section
group. */
shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
- if (shdr_info[cnt].data == NULL)
+ if (shdr_info[cnt].data == NULL
+ || shdr_info[cnt].data->d_size < sizeof (Elf32_Word))
INTERNAL_ERROR (fname);
/* XXX Fix for unaligned access. */
@@ -708,7 +725,9 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
while (idx != 0)
{
/* The section group data is already loaded. */
- assert (shdr_info[idx].data != NULL);
+ elf_assert (shdr_info[idx].data != NULL
+ && shdr_info[idx].data->d_buf != NULL
+ && shdr_info[idx].data->d_size >= sizeof (Elf32_Word));
/* If the references section group is a normal section
group and has one element remaining, or if it is an
@@ -764,11 +783,16 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
for (size_t in = 1;
in < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
++in)
- if (shdr_info[grpref[in]].idx != 0)
+ if (grpref[in] < shnum)
{
- shdr_info[cnt].idx = 1;
- break;
+ if (shdr_info[grpref[in]].idx != 0)
+ {
+ shdr_info[cnt].idx = 1;
+ break;
+ }
}
+ else
+ goto illformed;
}
}
@@ -897,7 +921,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
inline void check_preserved (size_t i)
{
- if (i != 0 && shdr_info[i].idx != 0
+ if (i != 0 && i < shnum + 2 && shdr_info[i].idx != 0
&& shdr_info[i].debug_data == NULL)
{
if (shdr_info[i].data == NULL)
@@ -926,9 +950,12 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
{
scn = elf_newscn (debugelf);
if (scn == NULL)
- error (EXIT_FAILURE, 0,
- gettext ("while generating output file: %s"),
- elf_errmsg (-1));
+ {
+ cleanup_debug ();
+ error (EXIT_FAILURE, 0,
+ gettext ("while generating output file: %s"),
+ elf_errmsg (-1));
+ }
bool discard_section = (shdr_info[cnt].idx > 0
&& shdr_info[cnt].debug_data == NULL
@@ -968,6 +995,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
{
/* Copy the original data before it gets modified. */
shdr_info[cnt].debug_data = debugdata;
+ if (debugdata->d_buf == NULL)
+ INTERNAL_ERROR (fname);
debugdata->d_buf = memcpy (xmalloc (debugdata->d_size),
debugdata->d_buf, debugdata->d_size);
}
@@ -1003,8 +1032,11 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* We need a string table for the section headers. */
shst = ebl_strtabinit (true);
if (shst == NULL)
- error (EXIT_FAILURE, errno, gettext ("while preparing output for '%s'"),
- output_fname ?: fname);
+ {
+ cleanup_debug ();
+ error (EXIT_FAILURE, errno, gettext ("while preparing output for '%s'"),
+ output_fname ?: fname);
+ }
/* Assign new section numbers. */
shdr_info[0].idx = 0;
@@ -1016,8 +1048,12 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* Create a new section. */
shdr_info[cnt].newscn = elf_newscn (newelf);
if (shdr_info[cnt].newscn == NULL)
- error (EXIT_FAILURE, 0, gettext ("while generating output file: %s"),
- elf_errmsg (-1));
+ {
+ cleanup_debug ();
+ error (EXIT_FAILURE, 0,
+ gettext ("while generating output file: %s"),
+ elf_errmsg (-1));
+ }
elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
@@ -1053,15 +1089,21 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* Create the section. */
shdr_info[cnt].newscn = elf_newscn (newelf);
if (shdr_info[cnt].newscn == NULL)
- error (EXIT_FAILURE, 0,
- gettext ("while create section header section: %s"),
- elf_errmsg (-1));
+ {
+ cleanup_debug ();
+ error (EXIT_FAILURE, 0,
+ gettext ("while create section header section: %s"),
+ elf_errmsg (-1));
+ }
elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn);
if (shdr_info[cnt].data == NULL)
- error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"),
- elf_errmsg (-1));
+ {
+ cleanup_debug ();
+ error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"),
+ elf_errmsg (-1));
+ }
char *debug_basename = basename (debug_fname_embed ?: debug_fname);
off_t crc_offset = strlen (debug_basename) + 1;
@@ -1110,18 +1152,24 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* Create the section. */
shdr_info[cnt].newscn = elf_newscn (newelf);
if (shdr_info[cnt].newscn == NULL)
- error (EXIT_FAILURE, 0,
- gettext ("while create section header section: %s"),
- elf_errmsg (-1));
+ {
+ cleanup_debug ();
+ error (EXIT_FAILURE, 0,
+ gettext ("while create section header section: %s"),
+ elf_errmsg (-1));
+ }
elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
/* Finalize the string table and fill in the correct indices in the
section headers. */
shstrtab_data = elf_newdata (shdr_info[cnt].newscn);
if (shstrtab_data == NULL)
- error (EXIT_FAILURE, 0,
- gettext ("while create section header string table: %s"),
- elf_errmsg (-1));
+ {
+ cleanup_debug ();
+ error (EXIT_FAILURE, 0,
+ gettext ("while create section header string table: %s"),
+ elf_errmsg (-1));
+ }
ebl_strtabfinalize (shst, shstrtab_data);
/* We have to set the section size. */
@@ -1135,7 +1183,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
Elf_Data *newdata;
scn = elf_getscn (newelf, shdr_info[cnt].idx);
- assert (scn != NULL);
+ elf_assert (scn != NULL);
/* Update the name. */
shdr_info[cnt].shdr.sh_name = ebl_strtaboffset (shdr_info[cnt].se);
@@ -1148,13 +1196,17 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
{
- assert (shdr_info[cnt].data != NULL);
+ elf_assert (shdr_info[cnt].data != NULL
+ && shdr_info[cnt].data->d_buf != NULL);
Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
for (size_t inner = 0;
inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
++inner)
- grpref[inner] = shdr_info[grpref[inner]].idx;
+ if (grpref[inner] < shnum)
+ grpref[inner] = shdr_info[grpref[inner]].idx;
+ else
+ goto illformed;
}
/* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag. */
@@ -1196,14 +1248,14 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
if (shdr_info[cnt].symtab_idx != 0)
{
- assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX);
+ elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX);
/* This section has extended section information.
We have to modify that information, too. */
shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
NULL);
elf_assert ((versiondata->d_size / sizeof (Elf32_Word))
- >= shdr_info[cnt].data->d_size / elsize);
+ >= shdr_info[cnt].data->d_size / elsize);
}
if (shdr_info[cnt].version_idx != 0)
@@ -1215,8 +1267,10 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn,
NULL);
- elf_assert ((versiondata->d_size / sizeof (GElf_Versym))
- >= shdr_info[cnt].data->d_size / elsize);
+ elf_assert (versiondata != NULL
+ && versiondata->d_buf != NULL
+ && ((versiondata->d_size / sizeof (GElf_Versym))
+ >= shdr_info[cnt].data->d_size / elsize));
}
shdr_info[cnt].newsymidx
@@ -1270,7 +1324,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
sec = shdr_info[sym->st_shndx].idx;
else
{
- elf_assert (shndxdata != NULL);
+ elf_assert (shndxdata != NULL
+ && shndxdata->d_buf != NULL);
sec = shdr_info[xshndx].idx;
}
@@ -1379,6 +1434,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* libelf will use d_size to set sh_size. */
Elf_Data *debugdata = elf_getdata (elf_getscn (debugelf,
cnt), NULL);
+ if (debugdata == NULL)
+ INTERNAL_ERROR (fname);
debugdata->d_size = newdata->d_size;
}
}
@@ -1390,6 +1447,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
continue;
const Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
+ elf_assert (symtabidx < shnum + 2);
const Elf32_Word *const newsymidx = shdr_info[symtabidx].newsymidx;
switch (shdr_info[cnt].shdr.sh_type)
{
@@ -1416,10 +1474,14 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
: elf_getscn (newelf,
shdr_info[cnt].idx),
NULL);
- assert (d != NULL);
+ elf_assert (d != NULL && d->d_buf != NULL
+ && shdr_info[cnt].shdr.sh_entsize != 0);
size_t nrels = (shdr_info[cnt].shdr.sh_size
/ shdr_info[cnt].shdr.sh_entsize);
+ size_t symsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+ const Elf32_Word symidxn = (shdr_info[symtabidx].data->d_size
+ / symsize);
if (shdr_info[cnt].shdr.sh_type == SHT_REL)
for (size_t relidx = 0; relidx < nrels; ++relidx)
{
@@ -1428,6 +1490,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
INTERNAL_ERROR (fname);
size_t symidx = GELF_R_SYM (rel_mem.r_info);
+ elf_assert (symidx < symidxn);
if (newsymidx[symidx] != symidx)
{
rel_mem.r_info
@@ -1446,6 +1509,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
INTERNAL_ERROR (fname);
size_t symidx = GELF_R_SYM (rel_mem.r_info);
+ elf_assert (symidx < symidxn);
if (newsymidx[symidx] != symidx)
{
rel_mem.r_info
@@ -1464,7 +1528,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* We have to recompute the hash table. */
- assert (shdr_info[cnt].idx > 0);
+ elf_assert (shdr_info[cnt].idx > 0);
/* The hash section in the new file. */
scn = elf_getscn (newelf, shdr_info[cnt].idx);
@@ -1473,30 +1537,38 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
Elf_Data *symd = elf_getdata (elf_getscn (newelf,
shdr_info[symtabidx].idx),
NULL);
- assert (symd != NULL);
+ elf_assert (symd != NULL && symd->d_buf != NULL);
/* The hash table data. */
Elf_Data *hashd = elf_getdata (scn, NULL);
- assert (hashd != NULL);
+ elf_assert (hashd != NULL && hashd->d_buf != NULL);
if (shdr_info[cnt].shdr.sh_entsize == sizeof (Elf32_Word))
{
/* Sane arches first. */
+ elf_assert (hashd->d_size >= 2 * sizeof (Elf32_Word));
Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf;
size_t strshndx = shdr_info[symtabidx].old_sh_link;
size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+ Elf32_Word nchain = bucket[1];
+ Elf32_Word nbucket = bucket[0];
+ uint64_t used_buf = ((2ULL + nchain + nbucket)
+ * sizeof (Elf32_Word));
+ elf_assert (used_buf <= hashd->d_size);
+
/* Adjust the nchain value. The symbol table size
changed. We keep the same size for the bucket array. */
bucket[1] = symd->d_size / elsize;
- Elf32_Word nbucket = bucket[0];
bucket += 2;
Elf32_Word *chain = bucket + nbucket;
/* New size of the section. */
- hashd->d_size = ((2 + symd->d_size / elsize + nbucket)
+ size_t n_size = ((2 + symd->d_size / elsize + nbucket)
* sizeof (Elf32_Word));
+ elf_assert (n_size <= hashd->d_size);
+ hashd->d_size = n_size;
update_section_size (hashd);
/* Clear the arrays. */
@@ -1522,7 +1594,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
{
hidx = bucket[hidx];
- while (chain[hidx] != 0)
+ while (chain[hidx] != 0 && chain[hidx] < nchain)
hidx = chain[hidx];
chain[hidx] = inner;
@@ -1540,16 +1612,25 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
size_t strshndx = shdr_info[symtabidx].old_sh_link;
size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+ elf_assert (symd->d_size >= 2 * sizeof (Elf64_Xword));
+ Elf64_Xword nbucket = bucket[0];
+ Elf64_Xword nchain = bucket[1];
+ uint64_t maxwords = hashd->d_size / sizeof (Elf64_Xword);
+ elf_assert (maxwords >= 2
+ && maxwords - 2 >= nbucket
+ && maxwords - 2 - nbucket >= nchain);
+
/* Adjust the nchain value. The symbol table size
changed. We keep the same size for the bucket array. */
bucket[1] = symd->d_size / elsize;
- Elf64_Xword nbucket = bucket[0];
bucket += 2;
Elf64_Xword *chain = bucket + nbucket;
/* New size of the section. */
- hashd->d_size = ((2 + symd->d_size / elsize + nbucket)
+ size_t n_size = ((2 + symd->d_size / elsize + nbucket)
* sizeof (Elf64_Xword));
+ elf_assert (n_size <= hashd->d_size);
+ hashd->d_size = n_size;
update_section_size (hashd);
/* Clear the arrays. */
@@ -1575,7 +1656,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
{
hidx = bucket[hidx];
- while (chain[hidx] != 0)
+ while (chain[hidx] != 0 && chain[hidx] < nchain)
hidx = chain[hidx];
chain[hidx] = inner;
@@ -1589,7 +1670,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
if (no_symtab_updates ())
break;
- assert (shdr_info[cnt].idx > 0);
+ elf_assert (shdr_info[cnt].idx > 0);
/* The symbol version section in the new file. */
scn = elf_getscn (newelf, shdr_info[cnt].idx);
@@ -1597,19 +1678,22 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* The symbol table data. */
symd = elf_getdata (elf_getscn (newelf, shdr_info[symtabidx].idx),
NULL);
- assert (symd != NULL);
+ elf_assert (symd != NULL && symd->d_buf != NULL);
+ size_t symz = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+ const Elf32_Word syms = (shdr_info[symtabidx].data->d_size / symz);
/* The version symbol data. */
Elf_Data *verd = elf_getdata (scn, NULL);
- assert (verd != NULL);
+ elf_assert (verd != NULL && verd->d_buf != NULL);
/* The symbol version array. */
GElf_Half *verstab = (GElf_Half *) verd->d_buf;
/* Walk through the list and */
size_t elsize = gelf_fsize (elf, verd->d_type, 1, EV_CURRENT);
- for (size_t inner = 1; inner < verd->d_size / elsize; ++inner)
- if (newsymidx[inner] != 0)
+ Elf32_Word vers = verd->d_size / elsize;
+ for (size_t inner = 1; inner < vers && inner < syms; ++inner)
+ if (newsymidx[inner] != 0 && newsymidx[inner] < vers)
/* Overwriting the same array works since the
reordering can only move entries to lower indices
in the array. */
@@ -1633,8 +1717,12 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
scn = elf_getscn (newelf, shdr_info[cnt].idx);
GElf_Shdr shdr_mem;
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- assert (shdr != NULL);
+ elf_assert (shdr != NULL);
+ size_t symsz = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+ const Elf32_Word symn = (shdr_info[symtabidx].data->d_size
+ / symsz);
+ elf_assert (shdr->sh_info < symn);
shdr->sh_info = newsymidx[shdr->sh_info];
(void) gelf_update_shdr (scn, shdr);
@@ -1678,18 +1766,23 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* OK, lets relocate all trivial cross debug section
relocations. */
Elf_Data *reldata = elf_getdata (scn, NULL);
+ if (reldata == NULL || reldata->d_buf == NULL)
+ INTERNAL_ERROR (fname);
/* We actually wanted the rawdata, but since we already
accessed it earlier as elf_getdata () that won't
work. But debug sections are all ELF_T_BYTE, so it
doesn't really matter. */
Elf_Data *tdata = elf_getdata (tscn, NULL);
- if (tdata->d_type != ELF_T_BYTE)
+ if (tdata == NULL || tdata->d_buf == NULL
+ || tdata->d_type != ELF_T_BYTE)
INTERNAL_ERROR (fname);
/* Pick up the symbol table and shndx table to
resolve relocation symbol indexes. */
Elf64_Word symt = shdr->sh_link;
Elf_Data *symdata, *xndxdata;
+ elf_assert (symt < shnum + 2);
+ elf_assert (shdr_info[symt].symtab_idx < shnum + 2);
symdata = (shdr_info[symt].debug_data
?: shdr_info[symt].data);
xndxdata = (shdr_info[shdr_info[symt].symtab_idx].debug_data
@@ -1722,6 +1815,9 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
&xndx);
Elf32_Word sec = (sym->st_shndx == SHN_XINDEX
? xndx : sym->st_shndx);
+ if (sec >= shnum + 2)
+ INTERNAL_ERROR (fname);
+
if (ebl_debugscn_p (ebl, shdr_info[sec].name))
{
size_t size;
@@ -1745,7 +1841,10 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
if (offset > tdata->d_size
|| tdata->d_size - offset < size)
- error (0, 0, gettext ("bad relocation"));
+ {
+ cleanup_debug ();
+ error (EXIT_FAILURE, 0, gettext ("bad relocation"));
+ }
/* When the symbol value is zero then for SHT_REL
sections this is all that needs to be checked.
@@ -1817,6 +1916,9 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
return false;
}
+ if (shdr->sh_entsize == 0)
+ INTERNAL_ERROR (fname);
+
size_t nrels = shdr->sh_size / shdr->sh_entsize;
size_t next = 0;
if (shdr->sh_type == SHT_REL)
@@ -1863,7 +1965,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
if (unlikely (elf_update (debugelf, ELF_C_WRITE) == -1))
{
error (0, 0, gettext ("while writing '%s': %s"),
- debug_fname, elf_errmsg (-1));
+ tmp_debug_fname, elf_errmsg (-1));
result = 1;
goto fail_close;
}
@@ -1879,6 +1981,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
}
/* The temporary file does not exist anymore. */
+ free (tmp_debug_fname);
tmp_debug_fname = NULL;
if (!remove_shdrs)
@@ -1951,7 +2054,7 @@ while computing checksum for debug information"));
if (gelf_update_ehdr (newelf, newehdr) == 0)
{
error (0, 0, gettext ("%s: error while creating ELF header: %s"),
- fname, elf_errmsg (-1));
+ output_fname ?: fname, elf_errmsg (-1));
return 1;
}
@@ -1973,7 +2076,7 @@ while computing checksum for debug information"));
if (elf_update (newelf, ELF_C_WRITE) == -1)
{
error (0, 0, gettext ("while writing '%s': %s"),
- fname, elf_errmsg (-1));
+ output_fname ?: fname, elf_errmsg (-1));
result = 1;
}
@@ -1998,7 +2101,7 @@ while computing checksum for debug information"));
|| ftruncate64 (fd, shdr_info[shdridx].shdr.sh_offset) < 0)
{
error (0, errno, gettext ("while writing '%s'"),
- fname);
+ output_fname ?: fname);
result = 1;
}
}
@@ -2018,7 +2121,7 @@ while computing checksum for debug information"));
|| ftruncate64 (fd, shdr_info[shdridx].shdr.sh_offset) < 0)
{
error (0, errno, gettext ("while writing '%s'"),
- fname);
+ output_fname ?: fname);
result = 1;
}
}
@@ -2054,8 +2157,8 @@ while computing checksum for debug information"));
/* That was it. Close the descriptors. */
if (elf_end (newelf) != 0)
{
- error (0, 0, gettext ("error while finishing '%s': %s"), fname,
- elf_errmsg (-1));
+ error (0, 0, gettext ("error while finishing '%s': %s"),
+ output_fname ?: fname, elf_errmsg (-1));
result = 1;
}
@@ -2071,13 +2174,7 @@ while computing checksum for debug information"));
if (ebl != NULL)
ebl_closebackend (ebl);
- /* Close debug file descriptor, if opened */
- if (debug_fd >= 0)
- {
- if (tmp_debug_fname != NULL)
- unlink (tmp_debug_fname);
- close (debug_fd);
- }
+ cleanup_debug ();
/* If requested, preserve the timestamp. */
if (tvp != NULL)
@@ -2098,6 +2195,21 @@ cannot set access and modification date of '%s'"),
return result;
}
+static void
+cleanup_debug ()
+{
+ if (debug_fd >= 0)
+ {
+ if (tmp_debug_fname != NULL)
+ {
+ unlink (tmp_debug_fname);
+ free (tmp_debug_fname);
+ tmp_debug_fname = NULL;
+ }
+ close (debug_fd);
+ debug_fd = -1;
+ }
+}
static int
handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
--
2.1.0
8 years, 11 months
[PATCH] libelf: If e_phnum is zero then set e_phoff also to zero.
by Mark Wielaard
If phnum is zero make sure e_phoff is also zero and not some random value.
That would cause trouble in update_file. This could happen when ELF_F_LAYOUT
is set and the user copied over a ehdr from a bogus ELF file where the phdrs
are unreadable. In that case trying to write out the new ELF image would
crash trying to follow the bogus e_phdr value.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libelf/ChangeLog | 5 +++++
libelf/elf32_updatenull.c | 8 ++++++++
2 files changed, 13 insertions(+)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 0b9b478..2d10b83 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2015-05-13 Mark Wielaard <mjw(a)redhat.com>
+
+ * elf32_updatenull.c (default_ehdr): If e_phnum is zero then set
+ e_phoff also to zero.
+
2015-05-12 Mark Wielaard <mjw(a)redhat.com>
* elf32_updatenull.c (updatenull_wrlock): Check that sh_addralign
diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c
index a0de80e..c59ffcb 100644
--- a/libelf/elf32_updatenull.c
+++ b/libelf/elf32_updatenull.c
@@ -106,6 +106,14 @@ ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr,
elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
}
+ /* If phnum is zero make sure e_phoff is also zero and not some random
+ value. That would cause trouble in update_file. */
+ if (ehdr->e_phnum == 0 && ehdr->e_phoff != 0)
+ {
+ ehdr->e_phoff = 0;
+ elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+ }
+
return 0;
}
--
2.1.0
8 years, 11 months
[PATCH] libelf: More checking of valid sh_addralign values.
by Mark Wielaard
There were two issues with bogus sh_addralign values. First we would only
check the individual Elf_Data d_align values were powerof2. But not the
actual shdr addralign value. This would cause an issue if the shdr addralign
was bigger than all of the individual d_align values. Then we could write
out a bogus (! powerof2) shdr addralign value for the sections. Secondly
when reading in the Elf_Data we would set the d_align value to the value
of the shdr addralign value. But we would not check it was valid at all.
In practice there are ELF files with incorrect sh_addralign values (they
are a powerof2, but aren't aligned to the ELF image offset). We would try
to fix that up in elf_update by adding extra padding. But this could bloat
the ELF image a lot for large alignment values. So for too large alignments
that are bigger than the offset in the ELF file clamp them to the offset
value. This could lead us to reject to write out the data again when the
offset was not a powerof2. But this will only happen for aligment values
bigger than 64. Which are uncommon in practice.
---
libelf/ChangeLog | 7 +++++++
libelf/elf32_updatenull.c | 5 +++++
libelf/elf_getdata.c | 14 ++++++++++++++
3 files changed, 26 insertions(+)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index a7983a0..0b9b478 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,5 +1,12 @@
2015-05-12 Mark Wielaard <mjw(a)redhat.com>
+ * elf32_updatenull.c (updatenull_wrlock): Check that sh_addralign
+ is a powerof2.
+ * elf_getdata.c (__libelf_set_rawdata_wrlock): Clamp large d_aligns
+ to the elf image offset.
+
+2015-05-12 Mark Wielaard <mjw(a)redhat.com>
+
* elf32_newphdr.c (newphdr): Call __libelf_seterrno with
ELF_E_INVALID_INDEX before failing. Check whether section zero shdr
actually exists if we need to put extended phnum in section zero.
diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c
index d873a30..a0de80e 100644
--- a/libelf/elf32_updatenull.c
+++ b/libelf/elf32_updatenull.c
@@ -202,6 +202,11 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
assert (shdr != NULL);
ElfW2(LIBELFBITS,Word) sh_entsize = shdr->sh_entsize;
ElfW2(LIBELFBITS,Word) sh_align = shdr->sh_addralign ?: 1;
+ if (unlikely (! powerof2 (sh_align)))
+ {
+ __libelf_seterrno (ELF_E_INVALID_ALIGN);
+ return -1;
+ }
/* Set the sh_entsize value if we can reliably detect it. */
switch (shdr->sh_type)
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index e8f022f..8567da1 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -301,6 +301,20 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn)
else
scn->rawdata.d.d_type = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
scn->rawdata.d.d_off = 0;
+
+ /* Make sure the alignment makes sense. d_align should be aligned both
+ in the section (trivially true since d_off is zero) and in the file.
+ Unfortunately we cannot be too strict because there are ELF files
+ out there that fail this requirement. We will try to fix those up
+ in elf_update when writing out the image. But for very large
+ alignment values this can bloat the image considerably. So here
+ just check and clamp the alignment value to not be bigger than the
+ actual offset of the data in the file. Given that there is always
+ at least an ehdr this will only trigger for alignment values > 64
+ which should be uncommon. */
+ align = align ?: 1;
+ if (align > offset)
+ align = offset;
scn->rawdata.d.d_align = align;
if (elf->class == ELFCLASS32
|| (offsetof (struct Elf, state.elf32.ehdr)
--
2.1.0
8 years, 11 months
[PATCH] libelf: Make sure shdrs are valid before storing extended phnum in newphdr.
by Mark Wielaard
Creating phdr with more than PN_XNUM phnum requires a valid section zero
shdr to store the extended value. Make sure the shdrs are valid. Also fix
the error when count was too big to store by setting ELF_E_INVALID_INDEX
before failing.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libelf/ChangeLog | 6 ++++++
libelf/elf32_newphdr.c | 12 +++++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 312d5cf..a7983a0 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,9 @@
+2015-05-12 Mark Wielaard <mjw(a)redhat.com>
+
+ * elf32_newphdr.c (newphdr): Call __libelf_seterrno with
+ ELF_E_INVALID_INDEX before failing. Check whether section zero shdr
+ actually exists if we need to put extended phnum in section zero.
+
2015-05-08 Mark Wielaard <mjw(a)redhat.com>
* nlist.c (nlist): Call gelf_fsize with EV_CURRENT.
diff --git a/libelf/elf32_newphdr.c b/libelf/elf32_newphdr.c
index 01038e7..f89153b 100644
--- a/libelf/elf32_newphdr.c
+++ b/libelf/elf32_newphdr.c
@@ -116,6 +116,17 @@ elfw2(LIBELFBITS,newphdr) (elf, count)
{
if (unlikely (count > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))))
{
+ __libelf_seterrno (ELF_E_INVALID_INDEX);
+ result = NULL;
+ goto out;
+ }
+
+ Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
+ if (unlikely (count >= PN_XNUM && scn0->shdr.ELFW(e,LIBELFBITS) == NULL))
+ {
+ /* Something is wrong with section zero, but we need it to write
+ the extended phdr count. */
+ __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
result = NULL;
goto out;
}
@@ -134,7 +145,6 @@ elfw2(LIBELFBITS,newphdr) (elf, count)
if (count >= PN_XNUM)
{
/* We have to write COUNT into the zeroth section's sh_info. */
- Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
if (elf->state.ELFW(elf,LIBELFBITS).scns.cnt == 0)
{
assert (elf->state.ELFW(elf,LIBELFBITS).scns.max > 0);
--
2.1.0
8 years, 11 months
[PATCH 0/4] Improve elfutils diagnostics
by Jonathan Lebon
Hi,
This patch series attempts to improve elfutils feedback to help guide
the user towards fixing erroneous situations.
The first two patches enable elfutils to give a more specific error when
compressed sections fail to be decompressed.
The third patch add the new function dwfl_errmsg_details(), which can be
used to provide dynamic freeform information to the user to supplement
the static error message from dwfl_errmsg().
The fourth patch makes use of this facility to provide the user with all
the paths that were attempted while looking for the debug file.
Suggestions and comments welcome!
Related: RHBZ507682, RHBZ1184245.
Jonathan Lebon (4):
dwarf_begin_elf: decouple section searching from reading
dwarf_begin_elf: new error for compression failure
dwfl_error: support error details
dwfl_module_getdwarf: report paths tried
libdw/dwarf_begin_elf.c | 195 ++++++++++++++++++++++-----------------
libdw/dwarf_error.c | 1 +
libdw/libdw.map | 1 +
libdw/libdwP.h | 1 +
libdwfl/dwfl_build_id_find_elf.c | 21 +++++
libdwfl/dwfl_error.c | 27 ++++++
libdwfl/dwfl_module.c | 3 +
libdwfl/dwfl_module_getdwarf.c | 10 ++
libdwfl/find-debuginfo.c | 120 +++++++++++++++++-------
libdwfl/libdwfl.h | 3 +
libdwfl/libdwflP.h | 3 +
11 files changed, 269 insertions(+), 116 deletions(-)
--
2.1.0
8 years, 11 months
[PATCH 0/6] Fixes for building with uClibc-based toolchain
by Max Filippov
Mark, Anthony, Daniel,
this series fixes build errors that occur when building elfutils with
uClibc-based toolchain. Most of the patches are taken from [1] and
forward-ported to the current git master.
[1] https://bugs.gentoo.org/show_bug.cgi?id=470884
Anthony G. Basile (3):
Link against standalone argp library
Fall back on utimes if futimes is not available
Remove DL_CALL_FCT wrapper which is used in profiling
Daniel Guzman (1):
Use -lintl when libc doesn't provide dgettext
Max Filippov (2):
Drop mtrace calls.
Provide assert_perror when it's not defined
ChangeLog | 14 +++++++++++
configure.ac | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
libasm/ChangeLog | 4 ++++
libasm/Makefile.am | 1 +
libdw/ChangeLog | 10 ++++++++
libdw/Makefile.am | 2 +-
libelf/ChangeLog | 4 ++++
libelf/Makefile.am | 1 +
src/ChangeLog | 36 ++++++++++++++++++++++++++++
src/Makefile.am | 30 ++++++++++++------------
src/addr2line.c | 4 ----
src/ar.c | 12 ++++++----
src/ld.c | 6 -----
src/ld.h | 3 +++
src/nm.c | 4 ----
src/objdump.c | 4 ----
src/ranlib.c | 4 ----
src/size.c | 4 ----
src/strip.c | 22 +++++++++++++-----
src/unstrip.c | 4 ----
tests/ChangeLog | 22 ++++++++++++++++++
tests/Makefile.am | 30 ++++++++++++------------
tests/backtrace-child.c | 13 +++++++++++
tests/backtrace-data.c | 12 ++++++++++
tests/backtrace-dwarf.c | 12 ++++++++++
tests/backtrace.c | 12 ++++++++++
26 files changed, 260 insertions(+), 72 deletions(-)
--
1.8.1.4
8 years, 11 months