]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwfl: Special case core_file_read_eagerly for small ELF images.
authorMark Wielaard <mjw@redhat.com>
Tue, 31 Mar 2015 09:33:53 +0000 (11:33 +0200)
committerMark Wielaard <mjw@redhat.com>
Fri, 3 Apr 2015 11:23:06 +0000 (13:23 +0200)
Small ELF images, like linux-gate or linux-vdso, might be available in the
core file, but not on disk, even if we have a build-id. If the whole image
is small enough try to read them in from the core file to make sure symbols
and unwind information are always available for them. We would already map
them in if the core file was opened with ELF_C_READ_MMAP.

https://bugzilla.redhat.com/show_bug.cgi?id=1129756

Signed-off-by: Mark Wielaard <mjw@redhat.com>
libdwfl/ChangeLog
libdwfl/core-file.c

index d40dbae3e2eb7df0b7c7f8d20950f5ca4957de7d..143d38146c446ce35f9575735b6dd082ce180f55 100644 (file)
@@ -1,3 +1,7 @@
+2015-03-31  Mark Wielaard  <mjw@redhat.com>
+
+       * core-file.c (core_file_read_eagerly): Special case small images.
+
 2015-01-26  Mark Wielaard  <mjw@redhat.com>
 
        * dwfl_module_getdwarf.c (find_symtab): Explicitly clear symdata,
index 50031aed62162099cc470e3fd2527efd4026db54..324e9d2d45d2027259967c5a1b59e9b04518d448 100644 (file)
@@ -1,5 +1,5 @@
 /* Core file handling.
-   Copyright (C) 2008-2010, 2013 Red Hat, Inc.
+   Copyright (C) 2008-2010, 2013, 2015 Red Hat, Inc.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -161,6 +161,9 @@ dwfl_report_core_segments (Dwfl *dwfl, Elf *elf, size_t phnum, GElf_Phdr *notes)
 /* Never read more than this much without mmap.  */
 #define MAX_EAGER_COST 8192
 
+/* Dwfl_Module_Callback passed to and called by dwfl_segment_report_module
+   to read in a segment as ELF image directly if possible or indicate an
+   attempt must be made to read in the while segment right now.  */
 static bool
 core_file_read_eagerly (Dwfl_Module *mod,
                        void **userdata __attribute__ ((unused)),
@@ -174,6 +177,10 @@ core_file_read_eagerly (Dwfl_Module *mod,
 {
   Elf *core = arg;
 
+  /* The available buffer is often the whole segment when the core file
+     was mmap'd if used together with the dwfl_elf_phdr_memory_callback.
+     Which means that if it is complete we can just construct the whole
+     ELF image right now without having to read in anything more.  */
   if (whole <= *buffer_available)
     {
       /* All there ever was, we already have on hand.  */
@@ -198,8 +205,9 @@ core_file_read_eagerly (Dwfl_Module *mod,
       return *elfp != NULL;
     }
 
-  /* We don't have the whole file.
-     Figure out if this is better than nothing.  */
+  /* We don't have the whole file.  Which either means the core file
+     wasn't mmap'd, but needs to still be read in, or that the segment
+     is truncated.  Figure out if this is better than nothing.  */
 
   if (worthwhile == 0)
     /* Caller doesn't think so.  */
@@ -212,12 +220,16 @@ core_file_read_eagerly (Dwfl_Module *mod,
     requires find_elf hook re-doing the magic to fall back if no file found
   */
 
-  if (mod->build_id_len > 0)
-    /* There is a build ID that could help us find the whole file,
-       which might be more useful than what we have.
-       We'll just rely on that.  */
+  if (whole > MAX_EAGER_COST && mod->build_id_len > 0)
+    /* We can't cheaply read the whole file here, so we'd
+       be using a partial file.  But there is a build ID that could
+       help us find the whole file, which might be more useful than
+       what we have.  We'll just rely on that.  */
     return false;
 
+  /* The file is either small (most likely the vdso) or big and incomplete,
+     but we don't have a build-id.  */
+
   if (core->map_address != NULL)
     /* It's cheap to get, so get it.  */
     return true;