[PATCH] libelf: Do not cast pointer to integer in gelf_newphdr
by Akihiko Odaki
unsigned long int is not always capable to have pointer in some cases
(LLP64, for example).
Signed-off-by: Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
---
libelf/gelf.h | 4 ++--
libelf/gelf_newehdr.c | 6 +++---
libelf/gelf_newphdr.c | 6 +++---
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/libelf/gelf.h b/libelf/gelf.h
index 1bc7ee7..0c31c27 100644
--- a/libelf/gelf.h
+++ b/libelf/gelf.h
@@ -166,7 +166,7 @@ extern GElf_Ehdr *gelf_getehdr (Elf *__elf, GElf_Ehdr *__dest);
extern int gelf_update_ehdr (Elf *__elf, GElf_Ehdr *__src);
/* Create new ELF header if none exists. */
-extern unsigned long int gelf_newehdr (Elf *__elf, int __class);
+extern void *gelf_newehdr (Elf *__elf, int __class);
/* Get section at OFFSET. */
extern Elf_Scn *gelf_offscn (Elf *__elf, GElf_Off __offset);
@@ -184,7 +184,7 @@ extern GElf_Phdr *gelf_getphdr (Elf *__elf, int __ndx, GElf_Phdr *__dst);
extern int gelf_update_phdr (Elf *__elf, int __ndx, GElf_Phdr *__src);
/* Create new program header with PHNUM entries. */
-extern unsigned long int gelf_newphdr (Elf *__elf, size_t __phnum);
+extern void *gelf_newphdr (Elf *__elf, size_t __phnum);
/* Get compression header of section if any. Returns NULL and sets
elf_errno if the section isn't compressed or an error occurred. */
diff --git a/libelf/gelf_newehdr.c b/libelf/gelf_newehdr.c
index cfa80e1..2788906 100644
--- a/libelf/gelf_newehdr.c
+++ b/libelf/gelf_newehdr.c
@@ -37,10 +37,10 @@
#include "libelfP.h"
-unsigned long int
+void *
gelf_newehdr (Elf *elf, int class)
{
return (class == ELFCLASS32
- ? (unsigned long int) INTUSE(elf32_newehdr) (elf)
- : (unsigned long int) INTUSE(elf64_newehdr) (elf));
+ ? (void *) INTUSE(elf32_newehdr) (elf)
+ : (void *) INTUSE(elf64_newehdr) (elf));
}
diff --git a/libelf/gelf_newphdr.c b/libelf/gelf_newphdr.c
index 4e95474..84aad78 100644
--- a/libelf/gelf_newphdr.c
+++ b/libelf/gelf_newphdr.c
@@ -37,10 +37,10 @@
#include "libelfP.h"
-unsigned long int
+void *
gelf_newphdr ( Elf *elf, size_t phnum)
{
return (elf->class == ELFCLASS32
- ? (unsigned long int) INTUSE(elf32_newphdr) (elf, phnum)
- : (unsigned long int) INTUSE(elf64_newphdr) (elf, phnum));
+ ? (void *) INTUSE(elf32_newphdr) (elf, phnum)
+ : (void *) INTUSE(elf64_newphdr) (elf, phnum));
}
--
2.10.0
6 years, 9 months
Analyzing process and core dump files in changed root environments
by h
Hello,
I have a question regarding analyzing processes running in a change root
environment or in an own mount namespace with re-mounted /.
I want to debug a process running in a non-system root using elfutils or gdb
from system root, and vice versa.
More precisely, I want to create a container shipping ABRT + GDB + elfutils
and the container should allow users to analyze core dump files on Fedora
Atomic. I need to run eu-stack on a core dump file generated by a program
from system root and I need to run it from a container (non-system root).
For example, if I run the following command on Fedora Atomic 25, it crashes
in the system namespace and ABRT saves its core file to /var/spool/abrt/
ccpp* in ABRT's namespace. If I enter the ABRT container and run eu-stack on
the core dump file, I get an error because the container misses some
libraries:
$ ostree admin instutil grub2-generate
$ eu-stack --core coredump -e binary
PID 1693 - core
TID 1693:
#0 0x00007fbd9c7c892f raise
#1 0x00007fbd9c7ca52a abort
#2 0x00007fbd9d2b0cc5 g_assertion_message
#3 0x00007fbd9d2b0d5a g_assertion_message_expr
#4 0x00007fbd9e713e7e
eu-stack: dwfl_thread_getframes tid 1693 at 0x7fbd9e713e7d in /usr/lib64/
libostree-1.so.1.0.0: Callback returned failure
You may ask what is the binary argument. It's a copy of the crashed program.
It can be replaced with the `/host/bin/ostree` path (I bind mount the hots'
/ to the container's /host).
GDB allows me to configure 'sysroot', so it knows where to look for
libraries. Thus if I run GDB on the same core dump file, I get the
following ouptut:
$ gdb --batch --ex 'set sysroot /host' --ex 'file binary' --ex 'core
coredump' --ex 'bt'
Core was generated by `ostree admin instutil grub2-generate'.
Program terminated with signal SIGABRT, Aborted.
#0 0x00007fbd9c7c892f in raise () from /host/lib64/libc.so.6
#0 0x00007fbd9c7c892f in raise () from /host/lib64/libc.so.6
#1 0x00007fbd9c7ca52a in abort () from /host/lib64/libc.so.6
#2 0x00007fbd9d2b0cc5 in g_assertion_message () from /host/lib64/libglib-
2.0.so.0
#3 0x00007fbd9d2b0d5a in g_assertion_message_expr () from /host/lib64/
libglib-2.0.so.0
#4 0x00007fbd9e713e7e in _ostree_bootloader_grub2_generate_config () from /
host/lib64/libostree-1.so.1
#5 0x000055b04f4300c1 in ot_admin_instutil_builtin_grub2_generate ()
#6 0x000055b04f42da53 in ot_admin_builtin_instutil ()
#7 0x000055b04f41fd93 in ostree_builtin_admin ()
#8 0x000055b04f4294d7 in ostree_run ()
#9 0x000055b04f41fae0 in main ()
Do elfutils support such an option too?
Kind regards,
Jakub Filak
6 years, 10 months
[PATCH] Only workaround fts.h if we have a bad version that doesn't handle LFS.
by Mark Wielaard
Older versions of glibc included an fts implementation that didn't have
Large File System support. We worked around that in linux-kernel-modules.c
by including it early before config.h and then redefining some symbols
to get the 64-bit versions. This is somewhat fragile and not necessary
with newer glibc. If possible we want the 64bit fts version always.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
ChangeLog | 5 +++++
configure.ac | 9 +++++++++
libdwfl/ChangeLog | 7 ++++++-
libdwfl/linux-kernel-modules.c | 20 +++++++++++++-------
4 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f21421f..c7e2a2a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2016-11-23 Mark Wielaard <mjw(a)redhat.com>
+
+ * configure.ac: Add test for bad fts.h. Add -DBAD_FTS=1 to CFLAGS
+ if necessary.
+
2016-11-02 Mark Wielaard <mjw(a)redhat.com>
* configure.ac: Add check for whether gcc accepts
diff --git a/configure.ac b/configure.ac
index c55fb9b..f535123 100644
--- a/configure.ac
+++ b/configure.ac
@@ -144,6 +144,15 @@ dnl tests, because the choice of the file model can (in principle) affect
dnl whether functions and headers are available, whether they work, etc.
AC_SYS_LARGEFILE
+dnl Older glibc had a broken fts that didn't work with Large File Systems.
+dnl We want the version that can handler LFS, but include workaround if we
+dnl get a bad one. Add define to CFLAGS (not AC_DEFINE it) since we need to
+dnl check it before including config.h (which might define _FILE_OFFSET_BITS).
+AC_CACHE_CHECK([whether fts.h is bad when included (with LFS)], ac_cv_bad_fts,
+ [AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <fts.h>]])],
+ ac_cv_bad_fts=no, ac_cv_bad_fts=yes)])
+AS_IF([test "x$ac_cv_bad_fts" = "xyes"], [CFLAGS="$CFLAGS -DBAD_FTS=1"])
+
dnl enable debugging of branch prediction.
AC_ARG_ENABLE([debugpred],
AS_HELP_STRING([--enable-debugpred],[build binaries with support to debug branch prediction]),
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 27c5d6e..bc627fe 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,4 +1,9 @@
-2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
+2016-11-23 Mark Wielaard <mjw(a)redhat.com>
+
+ * linux-kernel-modules.c: Only include fts.h early if BAD_FTS is
+ defined.
+
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* core-file.c: Remove sys/param.h.
* dwfl_segment_report_module.c: Likewise. Add system.h include.
diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c
index 54c0b90..9cd8ea9 100644
--- a/libdwfl/linux-kernel-modules.c
+++ b/libdwfl/linux-kernel-modules.c
@@ -26,10 +26,12 @@
the GNU Lesser General Public License along with this program. If
not, see <http://www.gnu.org/licenses/>. */
-/* We include this before config.h because it can't handle _FILE_OFFSET_BITS.
+/* In case we have a bad fts we include this before config.h because it
+ can't handle _FILE_OFFSET_BITS.
Everything we need here is fine if its declarations just come first. */
-
-#include <fts.h>
+#ifdef BAD_FTS
+ #include <fts.h>
+#endif
#include <config.h>
@@ -44,11 +46,15 @@
#include <fcntl.h>
#include <unistd.h>
-/* Since fts.h is included before config.h, its indirect inclusions may not
+/* If fts.h is included before config.h, its indirect inclusions may not
give us the right LFS aliases of these functions, so map them manually. */
-#ifdef _FILE_OFFSET_BITS
-#define open open64
-#define fopen fopen64
+#ifdef BAD_FTS
+ #ifdef _FILE_OFFSET_BITS
+ #define open open64
+ #define fopen fopen64
+ #endif
+#else
+ #include <fts.h>
#endif
--
2.9.3
6 years, 10 months
[PATCH] readelf: Add optional --symbols[=SECTION] argument to select section name.
by Mark Wielaard
Make it possible to display just the symbols from a named symbol section
instead of always displaying all symbol sections.
https://bugzilla.redhat.com/show_bug.cgi?id=1396092
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 7 +++++++
src/readelf.c | 20 +++++++++++++++++++-
tests/ChangeLog | 4 ++++
tests/run-readelf-s.sh | 11 +++++++++++
4 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 3314706..fe95ecb 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
+2016-11-17 Mark Wielaard <mjw(a)redhat.com>
+
+ * readelf.c (options): Add optional arg SECTION for symbols.
+ (symbol_table_section): New static variable.
+ (parse_opt): Set symbol_table_section on 's'.
+ (print_symtab): Filter on symbol_table_section name is set.
+
2016-11-10 Mark Wielaard <mjw(a)redhat.com>
* ar.c (write_member): Make sure tmpbuf is large enough to contain
diff --git a/src/readelf.c b/src/readelf.c
index 204aeec..a47b056 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -85,7 +85,8 @@ static const struct argp_option options[] =
{ "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
{ "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
{ "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
- { "symbols", 's', NULL, 0, N_("Display the symbol table"), 0 },
+ { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL,
+ N_("Display the symbol table sections"), 0 },
{ "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
{ "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
{ "arch-specific", 'A', NULL, 0,
@@ -157,6 +158,9 @@ static bool print_section_header;
/* True if the symbol table should be printed. */
static bool print_symbol_table;
+/* A specific section name, or NULL to print all symbol tables. */
+static char *symbol_table_section;
+
/* True if the version information should be printed. */
static bool print_version_info;
@@ -389,6 +393,7 @@ parse_opt (int key, char *arg,
case 's':
print_symbol_table = true;
any_control_option = true;
+ symbol_table_section = arg;
break;
case 'V':
print_version_info = true;
@@ -2236,6 +2241,19 @@ print_symtab (Ebl *ebl, int type)
if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
{
+ if (symbol_table_section != NULL)
+ {
+ /* Get the section header string table index. */
+ size_t shstrndx;
+ const char *sname;
+ if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get section header string table index"));
+ sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
+ if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
+ continue;
+ }
+
if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
{
if (elf_compress (scn, 0, 0) < 0)
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 5a9d537..7031cf5 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2016-11-17 Mark Wielaard <mjw(a)redhat.com>
+
+ * run-readelf-s.sh: Add --symbols=.dynsym and --symbols=.symtab tests.
+
2016-11-02 Mark Wielaard <mjw(a)redhat.com>
* backtrace-data.c (thread_callback): Add explicit break after error.
diff --git a/tests/run-readelf-s.sh b/tests/run-readelf-s.sh
index 59407d1..82c3417 100755
--- a/tests/run-readelf-s.sh
+++ b/tests/run-readelf-s.sh
@@ -273,9 +273,20 @@ Symbol table [28] '.symtab' contains 40 entries:
39: 0000000000000680 0 FUNC GLOBAL DEFAULT 11 _init
EOF
+# Display all symbol tables.
cat testfile.dynsym.in testfile.symtab.in \
| testrun_compare ${abs_top_builddir}/src/readelf -s testfilebaztab
+# Display just .dynsym
+cat testfile.dynsym.in \
+ | testrun_compare ${abs_top_builddir}/src/readelf \
+ --symbols=.dynsym testfilebaztab
+
+# Display just .symtab
+cat testfile.symtab.in \
+ | testrun_compare ${abs_top_builddir}/src/readelf \
+ --symbols=.symtab testfilebaztab
+
cat testfile.dynsym.in \
| testrun_compare ${abs_top_builddir}/src/readelf -s testfilebazdbg
--
1.8.3.1
6 years, 10 months
[PATCH] ar: Fix GCC7 -Wformat-length issues.
by Mark Wielaard
GCC7 adds warnings for snprintf formatting into too small buffers.
Fix the two issues pointed out by the new warning. The ar header
fields are fixed length containing left-justified strings without
zero terminator. snprintf always adds a '\0' char at the end (which
we then don't copy into the ar header field) and numbers are decimal
strings of fixed 10 chars (-Wformat-length thinks formatting
them as size_t might overflow on 64bit arches).
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 7 +++++++
src/ar.c | 15 +++++++++++----
src/arlib.c | 10 +++++++---
3 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index b2909b6..3314706 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
+2016-11-10 Mark Wielaard <mjw(a)redhat.com>
+
+ * ar.c (write_member): Make sure tmpbuf is large enough to contain
+ a starting '/' and ending '\0' char.
+ (do_oper_insert): Likewise.
+ * arlib.c (arlib_finalize): Format tmpbuf as PRId32 decimal.
+
2016-11-02 Mark Wielaard <mjw(a)redhat.com>
* addr2line.c (handle_address): Add fallthrough comment.
diff --git a/src/ar.c b/src/ar.c
index 1320d07..f2160d3 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -1,5 +1,5 @@
/* Create, modify, and extract from archives.
- Copyright (C) 2005-2012 Red Hat, Inc.
+ Copyright (C) 2005-2012, 2016 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper(a)redhat.com>, 2005.
@@ -853,7 +853,10 @@ write_member (struct armem *memb, off_t *startp, off_t *lenp, Elf *elf,
off_t end_off, int newfd)
{
struct ar_hdr arhdr;
- char tmpbuf[sizeof (arhdr.ar_name) + 1];
+ /* The ar_name is not actually zero teminated, but we need that for
+ snprintf. Also if the name is too long, then the string starts
+ with '/' plus an index off number (decimal). */
+ char tmpbuf[sizeof (arhdr.ar_name) + 2];
bool changed_header = memb->long_name_off != -1;
if (changed_header)
@@ -1455,7 +1458,11 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
/* Create the header. */
struct ar_hdr arhdr;
- char tmpbuf[sizeof (arhdr.ar_name) + 1];
+ /* The ar_name is not actually zero teminated, but we
+ need that for snprintf. Also if the name is too
+ long, then the string starts with '/' plus an index
+ off number (decimal). */
+ char tmpbuf[sizeof (arhdr.ar_name) + 2];
if (all->long_name_off == -1)
{
size_t namelen = strlen (all->name);
@@ -1465,7 +1472,7 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
}
else
{
- snprintf (tmpbuf, sizeof (arhdr.ar_name) + 1, "/%-*ld",
+ snprintf (tmpbuf, sizeof (tmpbuf), "/%-*ld",
(int) sizeof (arhdr.ar_name), all->long_name_off);
memcpy (arhdr.ar_name, tmpbuf, sizeof (arhdr.ar_name));
}
diff --git a/src/arlib.c b/src/arlib.c
index c3cf47f..fc62a77 100644
--- a/src/arlib.c
+++ b/src/arlib.c
@@ -1,5 +1,5 @@
/* Functions to handle creation of Linux archives.
- Copyright (C) 2007-2012 Red Hat, Inc.
+ Copyright (C) 2007-2012, 2016 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper(a)redhat.com>, 2007.
@@ -23,6 +23,7 @@
#include <assert.h>
#include <error.h>
#include <gelf.h>
+#include <inttypes.h>
#include <libintl.h>
#include <stdio.h>
#include <stdlib.h>
@@ -107,6 +108,9 @@ arlib_init (void)
void
arlib_finalize (void)
{
+ /* Note that the size is stored as decimal string in 10 chars,
+ without zero terminator (we add + 1 here only so snprintf can
+ put it at the end, we then don't use it when we memcpy it). */
char tmpbuf[sizeof (((struct ar_hdr *) NULL)->ar_size) + 1];
symtab.longnameslen = obstack_object_size (&symtab.longnamesob);
@@ -121,7 +125,7 @@ arlib_finalize (void)
symtab.longnames = obstack_finish (&symtab.longnamesob);
- int s = snprintf (tmpbuf, sizeof (tmpbuf), "%-*zu",
+ int s = snprintf (tmpbuf, sizeof (tmpbuf), "%-*" PRId32 "",
(int) sizeof (((struct ar_hdr *) NULL)->ar_size),
symtab.longnameslen - sizeof (struct ar_hdr));
memcpy (&((struct ar_hdr *) symtab.longnames)->ar_size, tmpbuf, s);
@@ -169,7 +173,7 @@ arlib_finalize (void)
/* See comment for ar_date above. */
memcpy (&((struct ar_hdr *) symtab.symsoff)->ar_size, tmpbuf,
- snprintf (tmpbuf, sizeof (tmpbuf), "%-*zu",
+ snprintf (tmpbuf, sizeof (tmpbuf), "%-*" PRId32 "",
(int) sizeof (((struct ar_hdr *) NULL)->ar_size),
symtab.symsofflen + symtab.symsnamelen
- sizeof (struct ar_hdr)));
--
1.8.3.1
6 years, 10 months
[PATCH] libelf: Always set ELF maxsize when reading an ELF file for sanity checks.
by Mark Wielaard
There are various sanity checks that depend on knowing the file size
of the underlying ELF file which we only used when mmapping the ELF file.
Although we probably won't crash if we use pread to try to read from
the file, we still might return completely bogus data structures. This
could cause us to malloc insane amounts of memory.
Always try to get the maxsize when unknown in elf_begin.c (read_file).
https://bugzilla.redhat.com/show_bug.cgi?id=1388057
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libelf/ChangeLog | 8 ++++++--
libelf/elf_begin.c | 37 +++++++++++++++++++++----------------
2 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 35af786..39fbccf 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,4 +1,8 @@
-2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
+2016-10-26 Mark Wielaard <mjw(a)redhat.com>
+
+ * elf_begin.c (read_file): Always set maxsize when parent == NULL.
+
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* elf_getarsym.c (elf_getarsym): Open code rawmemchr when not
available.
@@ -6,7 +10,7 @@
(validate_str): New function.
(elf_strptr): Use validate_str instead of memrchr.
-2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* elf32_updatefile.c: Remove sys/param.h include.
* elf32_updatenull.c: Likewise. Add system.h include.
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 8fdb376..5e9099c 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -1,5 +1,5 @@
/* Create descriptor for processing file.
- Copyright (C) 1998-2010, 2012, 2014, 2015 Red Hat, Inc.
+ Copyright (C) 1998-2010, 2012, 2014, 2015, 2016 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper(a)redhat.com>, 1998.
@@ -605,22 +605,30 @@ read_file (int fildes, off_t offset, size_t maxsize,
|| cmd == ELF_C_WRITE_MMAP
|| cmd == ELF_C_READ_MMAP_PRIVATE);
+ if (parent == NULL)
+ {
+ if (maxsize == ~((size_t) 0))
+ {
+ /* We don't know in the moment how large the file is.
+ Determine it now. */
+ struct stat st;
+
+ if (fstat (fildes, &st) == 0
+ && (sizeof (size_t) >= sizeof (st.st_size)
+ || st.st_size <= ~((size_t) 0)))
+ maxsize = (size_t) st.st_size;
+ }
+ }
+ else
+ {
+ /* The parent is already loaded. Use it. */
+ assert (maxsize != ~((size_t) 0));
+ }
+
if (use_mmap)
{
if (parent == NULL)
{
- if (maxsize == ~((size_t) 0))
- {
- /* We don't know in the moment how large the file is.
- Determine it now. */
- struct stat st;
-
- if (fstat (fildes, &st) == 0
- && (sizeof (size_t) >= sizeof (st.st_size)
- || st.st_size <= ~((size_t) 0)))
- maxsize = (size_t) st.st_size;
- }
-
/* We try to map the file ourself. */
map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP
? PROT_READ
@@ -635,9 +643,6 @@ read_file (int fildes, off_t offset, size_t maxsize,
}
else
{
- /* The parent is already loaded. Use it. */
- assert (maxsize != ~((size_t) 0));
-
map_address = parent->map_address;
}
}
--
1.8.3.1
6 years, 10 months
[PATCH] libelf: Sanity check offset and size before trying to malloc and read data.
by Mark Wielaard
Bad sh_off or sh_size could trigger a bad malloc or read. Sanity check
the header values first before trying to malloc a huge buffer or reading
any data that will certainly fail.
https://bugzilla.redhat.com/show_bug.cgi?id=1387584
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libelf/ChangeLog | 5 +++++
libelf/elf_getdata.c | 11 +++++++++++
2 files changed, 16 insertions(+)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 35af786..89546ab 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2016-10-21 Mark Wielaard <mjw(a)redhat.com>
+
+ * elf_getdata.c (__libelf_set_rawdata_wrlock): Sanity check
+ offset and size before trying to malloc and read data.
+
2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* elf_getarsym.c (elf_getarsym): Open code rawmemchr when not
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index d1fafbf..97c503b 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -312,6 +312,17 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn)
}
else if (likely (elf->fildes != -1))
{
+ /* First see whether the information in the section header is
+ valid and it does not ask for too much. Check for unsigned
+ overflow. */
+ if (unlikely (offset > elf->maximum_size
+ || elf->maximum_size - offset < size))
+ {
+ /* Something is wrong. */
+ __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+ return 1;
+ }
+
/* We have to read the data from the file. Allocate the needed
memory. */
scn->rawdata_base = scn->rawdata.d.d_buf
--
1.8.3.1
6 years, 10 months
[PATCH] libdw: Correct spelling of DW_LANG_PLI in dwarf.h.
by Mark Wielaard
The name used in the standard and other DWARF implementations for
Programming Language One, PL/I, is DW_LANG_PLI (not DW_LANG_PL1).
Fix usage in dwarf_aggregate_size.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
NEWS | 5 +++++
libdw/ChangeLog | 6 ++++++
libdw/dwarf.h | 4 ++--
libdw/dwarf_aggregate_size.c | 4 ++--
4 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/NEWS b/NEWS
index 599970b..6adb76f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+Version 0.168
+
+libdw: dwarf.h corrected the DW_LANG_PLI constant name (was DW_LANG_PL1).
+ Any existing sources using the old name will have to be updated.
+
Version 0.167
libasm: Add eBPF disassembler for EM_BPF files.
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index c2f25ea..01213c5 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,9 @@
+2016-10-22 Mark Wielaard <mjw(a)redhat.com>
+
+ * dwarf.h: Correct spelling of DW_LANG_PLI.
+ * dwarf_aggregate_size.c (array_size): Use correct spelling of
+ DW_LANG_PLI.
+
2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* dwarf_getpubnames.c: Remove sys/param.h include, add system.h.
diff --git a/libdw/dwarf.h b/libdw/dwarf.h
index b5c58d7..6354c39 100644
--- a/libdw/dwarf.h
+++ b/libdw/dwarf.h
@@ -1,5 +1,5 @@
/* This file defines standard DWARF types, structures, and macros.
- Copyright (C) 2000-2011, 2014 Red Hat, Inc.
+ Copyright (C) 2000-2011, 2014, 2016 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -582,7 +582,7 @@ enum
DW_LANG_C99 = 0x000c, /* ISO C:1999 */
DW_LANG_Ada95 = 0x000d, /* ISO Ada:1995 */
DW_LANG_Fortran95 = 0x000e, /* ISO Fortran 95 */
- DW_LANG_PL1 = 0x000f, /* ISO PL/1:1976 */
+ DW_LANG_PLI = 0x000f, /* ISO PL/1:1976 */
DW_LANG_ObjC = 0x0010, /* Objective-C */
DW_LANG_ObjC_plus_plus = 0x0011, /* Objective-C++ */
DW_LANG_UPC = 0x0012, /* Unified Parallel C */
diff --git a/libdw/dwarf_aggregate_size.c b/libdw/dwarf_aggregate_size.c
index aaeb7ed..52ef006 100644
--- a/libdw/dwarf_aggregate_size.c
+++ b/libdw/dwarf_aggregate_size.c
@@ -1,5 +1,5 @@
/* Compute size of an aggregate type from DWARF.
- Copyright (C) 2010, 2014 Red Hat, Inc.
+ Copyright (C) 2010, 2014, 2016 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -127,7 +127,7 @@ array_size (Dwarf_Die *die, Dwarf_Word *size,
case DW_LANG_Fortran08:
case DW_LANG_Pascal83:
case DW_LANG_Modula2:
- case DW_LANG_PL1:
+ case DW_LANG_PLI:
lower = 1;
break;
--
1.8.3.1
6 years, 10 months
[PATCH] Add GCC7 -Wimplicit-fallthrough support/fixes.
by Mark Wielaard
GCC7 will have a new -Wimplicit-fallthrough warning. It did catch one
small buglet in elflint option procession. So it seems useful to enable
to make sure all swatch case fallthroughs are deliberate.
Add configure check to detect whether gcc support -Wimplicit-fallthrough
and enable it. Add fixes and explicit fallthrough comments where necessary.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
ChangeLog | 7 ++++++-
backends/ChangeLog | 11 +++++++++++
backends/i386_regs.c | 1 +
backends/i386_retval.c | 3 +--
backends/linux-core-note.c | 4 ++--
backends/m68k_retval.c | 4 +---
backends/ppc_regs.c | 2 +-
backends/x86_64_regs.c | 1 +
config/ChangeLog | 5 +++++
config/eu.am | 8 +++++++-
configure.ac | 10 ++++++++++
libcpu/ChangeLog | 6 +++++-
libcpu/i386_disasm.c | 2 +-
libdw/ChangeLog | 10 +++++++++-
libdw/cfi.c | 2 ++
libdw/encoded-value.h | 1 +
libdwfl/dwfl_report_elf.c | 2 +-
src/ChangeLog | 8 ++++++++
src/addr2line.c | 1 +
src/elfcompress.c | 3 ++-
src/elflint.c | 4 +++-
src/objdump.c | 4 +++-
tests/ChangeLog | 5 +++++
tests/backtrace-data.c | 1 +
tests/backtrace.c | 2 +-
25 files changed, 89 insertions(+), 18 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 8d61572..f21421f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,9 @@
-2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
+2016-11-02 Mark Wielaard <mjw(a)redhat.com>
+
+ * configure.ac: Add check for whether gcc accepts
+ -Wimplict-fallthrough.
+
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* configure.ac: Add memrchr, rawmemchr and powerof2 checks.
diff --git a/backends/ChangeLog b/backends/ChangeLog
index 53d2908..1c561b5 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,14 @@
+2016-11-02 Mark Wielaard <mjw(a)redhat.com>
+
+ * i386_regs.c (i386_register_info): Add fallthrough comment.
+ * i386_retval.c (i386_return_value_location): Move fallthrough
+ comment.
+ * linux-core-note.c (core_note): Adjust fallthrough comment.
+ * m68k_retval.c (m68k_return_value_location): Move fallthrough
+ comment.
+ * ppc_regs.c (ppc_register_info): Add fallthrough comment.
+ * x86_64_regs.c (x86_64_register_info): Likewise.
+
2016-08-09 Jose E. Marchesi <jose.marchesi(a)oracle.com>
* sparc_attrs.c (sparc_check_object_attribute): Fix the
diff --git a/backends/i386_regs.c b/backends/i386_regs.c
index fb8ded3..fd963a6 100644
--- a/backends/i386_regs.c
+++ b/backends/i386_regs.c
@@ -92,6 +92,7 @@ i386_register_info (Ebl *ebl __attribute__ ((unused)),
case 5:
case 8:
*type = DW_ATE_address;
+ /* Fallthrough */
case 0 ... 3:
case 6 ... 7:
name[0] = 'e';
diff --git a/backends/i386_retval.c b/backends/i386_retval.c
index 9da797d..4aa646f 100644
--- a/backends/i386_retval.c
+++ b/backends/i386_retval.c
@@ -122,9 +122,8 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
return nloc_intreg;
if (size <= 8)
return nloc_intregpair;
-
- /* Else fall through. */
}
+ /* Fallthrough */
case DW_TAG_structure_type:
case DW_TAG_class_type:
diff --git a/backends/linux-core-note.c b/backends/linux-core-note.c
index a4ec0be..67638d7 100644
--- a/backends/linux-core-note.c
+++ b/backends/linux-core-note.c
@@ -225,8 +225,8 @@ EBLHOOK(core_note) (const GElf_Nhdr *nhdr, const char *name,
case sizeof "CORE":
if (memcmp (name, "CORE", nhdr->n_namesz) == 0)
break;
- /* Buggy old Linux kernels didn't terminate "LINUX".
- Fall through. */
+ /* Buggy old Linux kernels didn't terminate "LINUX". */
+ /* Fall through. */
case sizeof "LINUX":
if (memcmp (name, "LINUX", nhdr->n_namesz) == 0)
diff --git a/backends/m68k_retval.c b/backends/m68k_retval.c
index 2dd285a..c68ed02 100644
--- a/backends/m68k_retval.c
+++ b/backends/m68k_retval.c
@@ -134,10 +134,8 @@ m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
return nloc_intreg;
if (size <= 8)
return nloc_intregpair;
-
- /* Else fall through. */
}
-
+ /* Fallthrough */
case DW_TAG_structure_type:
case DW_TAG_class_type:
case DW_TAG_union_type:
diff --git a/backends/ppc_regs.c b/backends/ppc_regs.c
index 4b92a9a..bcf4f7a 100644
--- a/backends/ppc_regs.c
+++ b/backends/ppc_regs.c
@@ -140,7 +140,7 @@ ppc_register_info (Ebl *ebl __attribute__ ((unused)),
case 100:
if (*bits == 32)
return stpcpy (name, "mq") + 1 - name;
-
+ /* Fallthrough */
case 102 ... 107:
name[0] = 's';
name[1] = 'p';
diff --git a/backends/x86_64_regs.c b/backends/x86_64_regs.c
index 2172d9f..8430440 100644
--- a/backends/x86_64_regs.c
+++ b/backends/x86_64_regs.c
@@ -87,6 +87,7 @@ x86_64_register_info (Ebl *ebl __attribute__ ((unused)),
case 6 ... 7:
*type = DW_ATE_address;
+ /* Fallthrough */
case 0 ... 5:
name[0] = 'r';
name[1] = baseregs[regno][0];
diff --git a/config/ChangeLog b/config/ChangeLog
index 2ca25bc..a18fa84 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,8 @@
+2016-11-02 Mark Wielaard <mjw(a)redhat.com>
+
+ * eu.am: Check HAVE_IMPLICIT_FALLTHROUGH_WARNING.
+ (AM_CFLAGS): Add IMPLICIT_FALLTHROUGH_WARNING.
+
2016-08-04 Mark Wielaard <mjw(a)redhat.com>
* elfutils.spec.in: Update for 0.167.
diff --git a/config/eu.am b/config/eu.am
index 4998771..8fe1e25 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -61,10 +61,16 @@ else
NULL_DEREFERENCE_WARNING=
endif
+if HAVE_IMPLICIT_FALLTHROUGH_WARNING
+IMPLICIT_FALLTHROUGH_WARNING=-Wimplicit-fallthrough
+else
+IMPLICIT_FALLTHROUGH_WARNING=
+endif
+
AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
-Wold-style-definition -Wstrict-prototypes \
$(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \
- $(NULL_DEREFERENCE_WARNING) \
+ $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \
$(if $($(*F)_no_Werror),,-Werror) \
$(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
$(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \
diff --git a/configure.ac b/configure.ac
index c02d4c2..c55fb9b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -311,6 +311,16 @@ CFLAGS="$old_CFLAGS"])
AM_CONDITIONAL(HAVE_NULL_DEREFERENCE_WARNING,
[test "x$ac_cv_null_dereference" != "xno"])
+# -Wimplicit-fallthrough was added by GCC7
+AC_CACHE_CHECK([whether gcc accepts -Wimplicit-fallthrough], ac_cv_implicit_fallthrough, [dnl
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Wimplicit-fallthrough -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([])],
+ ac_cv_implicit_fallthrough=yes, ac_cv_implicit_fallthrough=no)
+CFLAGS="$old_CFLAGS"])
+AM_CONDITIONAL(HAVE_IMPLICIT_FALLTHROUGH_WARNING,
+ [test "x$ac_cv_implicit_fallthrough" != "xno"])
+
dnl Check if we have argp available from our libc
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog
index fff1d96..79110c2 100644
--- a/libcpu/ChangeLog
+++ b/libcpu/ChangeLog
@@ -1,4 +1,8 @@
-2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
+2016-11-02 Mark Wielaard <mjw(a)redhat.com>
+
+ * i386_disasm.c (i386_disasm): Add fallthrough comment.
+
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* i386_lex.l: Remove system.h include, add libeu.h include.
* i386_parse.y: Remove sys/param.h include, add libeu.h include.
diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c
index 699dd61..831afbe 100644
--- a/libcpu/i386_disasm.c
+++ b/libcpu/i386_disasm.c
@@ -819,7 +819,7 @@ i386_disasm (Ebl *ebl __attribute__((unused)),
++param_start;
break;
}
-
+ /* Fallthrough */
default:
assert (! "INVALID not handled");
}
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index c2f25ea..cc92f16 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,4 +1,12 @@
-2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
+2016-11-02 Mark Wielaard <mjw(a)redhat.com>
+
+ * cfi.c (execute_cfi): Add fallthrough comments.
+ * encoded-value.h (encoded_value_size): Add explicit return instead
+ of relying on fallthrough.
+ * dwfl_report_elf.c (__libdwfl_elf_address_range): Add fallthrough
+ comment.
+
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* dwarf_getpubnames.c: Remove sys/param.h include, add system.h.
* libdw_alloc.c: Likewise.
diff --git a/libdw/cfi.c b/libdw/cfi.c
index 1fd668d..daa845f 100644
--- a/libdw/cfi.c
+++ b/libdw/cfi.c
@@ -138,6 +138,7 @@ execute_cfi (Dwarf_CFI *cache,
case DW_CFA_advance_loc1:
operand = *program++;
+ /* Fallthrough */
case DW_CFA_advance_loc + 0 ... DW_CFA_advance_loc + CFI_PRIMARY_MAX:
advance_loc:
loc += operand * cie->code_alignment_factor;
@@ -300,6 +301,7 @@ execute_cfi (Dwarf_CFI *cache,
case DW_CFA_restore_extended:
get_uleb128 (operand, program, end);
+ /* Fallthrough */
case DW_CFA_restore + 0 ... DW_CFA_restore + CFI_PRIMARY_MAX:
if (unlikely (abi_cfi) && likely (opcode == DW_CFA_restore))
diff --git a/libdw/encoded-value.h b/libdw/encoded-value.h
index 48d868f..f0df4ce 100644
--- a/libdw/encoded-value.h
+++ b/libdw/encoded-value.h
@@ -64,6 +64,7 @@ encoded_value_size (const Elf_Data *data, const unsigned char e_ident[],
if (*end++ & 0x80u)
return end - p;
}
+ return 0;
default:
return 0;
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 1c6e401..73a5511 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -170,7 +170,7 @@ __libdwfl_elf_address_range (Elf *elf, GElf_Addr base, bool add_p_vaddr,
/* An assigned base address is meaningless for these. */
base = 0;
add_p_vaddr = true;
-
+ /* Fallthrough. */
case ET_DYN:
default:;
size_t phnum;
diff --git a/src/ChangeLog b/src/ChangeLog
index ee67cff..b2909b6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
+2016-11-02 Mark Wielaard <mjw(a)redhat.com>
+
+ * addr2line.c (handle_address): Add fallthrough comment.
+ * elfcompress.c (parse_opt): Adjust fallthrough comment.
+ * elflint.c (parse_opt): Add missing break after 'd' case.
+ (check_sections): Add fallthrough comments.
+ * objdump.c (parse_opt): Add explantion for fallthrough comment.
+
2016-10-22 Kevin Cernekee <cernekee(a)chromium.org>
* unstrip.c: Fix "invalid string offset" error caused by using the
diff --git a/src/addr2line.c b/src/addr2line.c
index 0ce854f..bea24ae 100644
--- a/src/addr2line.c
+++ b/src/addr2line.c
@@ -632,6 +632,7 @@ handle_address (const char *string, Dwfl *dwfl)
case 1:
addr = 0;
j = i;
+ /* Fallthrough */
case 2:
if (string[j] != '\0')
break;
diff --git a/src/elfcompress.c b/src/elfcompress.c
index 7392cb7..82ab965 100644
--- a/src/elfcompress.c
+++ b/src/elfcompress.c
@@ -155,7 +155,8 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
argp_error (state,
N_("Only one input file allowed together with '-o'"));
/* We only use this for checking the number of arguments, we don't
- actually want to consume them, so fallthrough. */
+ actually want to consume them. */
+ /* Fallthrough */
default:
return ARGP_ERR_UNKNOWN;
}
diff --git a/src/elflint.c b/src/elflint.c
index 8b52ee2..b304a30 100644
--- a/src/elflint.c
+++ b/src/elflint.c
@@ -210,6 +210,7 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
case 'd':
is_debuginfo = true;
+ break;
case ARGP_gnuld:
gnuld = true;
@@ -3963,6 +3964,7 @@ section [%2zu] '%s': merge flag set but entry size is zero\n"),
case SHT_NOBITS:
if (is_debuginfo)
break;
+ /* Fallthrough */
default:
ERROR (gettext ("\
section [%2zu] '%s' has unexpected type %d for an executable section\n"),
@@ -4305,7 +4307,7 @@ section [%2d] '%s': unknown core file note type %" PRIu32
if (nhdr.n_namesz == sizeof "Linux"
&& !memcmp (data->d_buf + name_offset, "Linux", sizeof "Linux"))
break;
-
+ /* Fallthrough */
default:
if (shndx == 0)
ERROR (gettext ("\
diff --git a/src/objdump.c b/src/objdump.c
index 1afcd57..f84513c 100644
--- a/src/objdump.c
+++ b/src/objdump.c
@@ -234,7 +234,9 @@ parse_opt (int key, char *arg,
program_invocation_short_name);
exit (EXIT_FAILURE);
}
-
+ /* We only use this for checking the number of arguments, we don't
+ actually want to consume them. */
+ /* Fallthrough */
default:
return ARGP_ERR_UNKNOWN;
}
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 3d34778..5a9d537 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2016-11-02 Mark Wielaard <mjw(a)redhat.com>
+
+ * backtrace-data.c (thread_callback): Add explicit break after error.
+ * backtrace.c (callback_verify): Change PASSTHRU to FALLTHRU.
+
2016-10-22 Kevin Cernekee <cernekee(a)chromium.org>
* Makefile.am (TESTS): Add run-unstrip-test4.sh.
diff --git a/tests/backtrace-data.c b/tests/backtrace-data.c
index bc5ceba..b7158da 100644
--- a/tests/backtrace-data.c
+++ b/tests/backtrace-data.c
@@ -250,6 +250,7 @@ thread_callback (Dwfl_Thread *thread, void *thread_arg __attribute__ ((unused)))
break;
case -1:
error (1, 0, "dwfl_thread_getframes: %s", dwfl_errmsg (-1));
+ break;
default:
abort ();
}
diff --git a/tests/backtrace.c b/tests/backtrace.c
index 2440ab3..1ff6353 100644
--- a/tests/backtrace.c
+++ b/tests/backtrace.c
@@ -123,7 +123,7 @@ callback_verify (pid_t tid, unsigned frameno, Dwarf_Addr pc,
assert (symname2 == NULL || strcmp (symname2, "jmp") != 0);
break;
}
- /* PASSTHRU */
+ /* FALLTHRU */
case 4:
assert (symname != NULL && strcmp (symname, "stdarg") == 0);
break;
--
1.8.3.1
6 years, 10 months