d56182
commit 65cefbd0793c0f9e90a326d7bebf0a47c93294ad
d56182
Author: Josh Stone <jistone@redhat.com>
d56182
Date:   Tue Mar 11 10:19:28 2014 -0700
d56182
d56182
    libdwfl: dwfl_module_getdwarf.c (open_elf) only (re)set mod->e_type once.
d56182
    
d56182
    As noted in https://sourceware.org/bugzilla/show_bug.cgi?id=16676#c2 for
d56182
    systemtap, the heuristic used by open_elf to set the kernel Dwfl_Module
d56182
    type to ET_DYN, even if the underlying ELF file e_type was set to
d56182
    ET_EXEC, could trigger erroneously for non-kernel/non-main (debug or
d56182
    aux) files.  Make sure we only set the e_type of the module once when
d56182
    processing the main file (when the phdrs can be trusted).
d56182
d56182
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
d56182
index c4bd739..f8de80b 100644
d56182
--- a/libdwfl/dwfl_module_getdwarf.c
d56182
+++ b/libdwfl/dwfl_module_getdwarf.c
d56182
@@ -1,5 +1,5 @@
d56182
 /* Find debugging and symbol information for a module in libdwfl.
d56182
-   Copyright (C) 2005-2012 Red Hat, Inc.
d56182
+   Copyright (C) 2005-2012, 2014 Red Hat, Inc.
d56182
    This file is part of elfutils.
d56182
 
d56182
    This file is free software; you can redistribute it and/or modify
d56182
@@ -77,7 +77,7 @@ open_elf (Dwfl_Module *mod, struct dwfl_file *file)
d56182
       return DWFL_E (LIBELF, elf_errno ());
d56182
     }
d56182
 
d56182
-  if (mod->e_type != ET_REL)
d56182
+  if (ehdr->e_type != ET_REL)
d56182
     {
d56182
       /* In any non-ET_REL file, we compute the "synchronization address".
d56182
 
d56182
@@ -131,11 +131,24 @@ open_elf (Dwfl_Module *mod, struct dwfl_file *file)
d56182
 	}
d56182
     }
d56182
 
d56182
-  mod->e_type = ehdr->e_type;
d56182
+  /* We only want to set the module e_type explictly once, derived from
d56182
+     the main ELF file.  (It might be changed for the kernel, because
d56182
+     that is special - see below.)  open_elf is always called first for
d56182
+     the main ELF file, because both find_dw and find_symtab call
d56182
+     __libdwfl_getelf first to open the main file.  So don't let debug
d56182
+     or aux files override the module e_type.  The kernel heuristic
d56182
+     below could otherwise trigger for non-kernel/non-main files, since
d56182
+     their phdrs might not match the actual load addresses.  */
d56182
+  if (file == &mod->main)
d56182
+    {
d56182
+      mod->e_type = ehdr->e_type;
d56182
 
d56182
-  /* Relocatable Linux kernels are ET_EXEC but act like ET_DYN.  */
d56182
-  if (mod->e_type == ET_EXEC && file->vaddr != mod->low_addr)
d56182
-    mod->e_type = ET_DYN;
d56182
+      /* Relocatable Linux kernels are ET_EXEC but act like ET_DYN.  */
d56182
+      if (mod->e_type == ET_EXEC && file->vaddr != mod->low_addr)
d56182
+	mod->e_type = ET_DYN;
d56182
+    }
d56182
+  else
d56182
+    assert (mod->main.elf != NULL);
d56182
 
d56182
   return DWFL_E_NOERROR;
d56182
 }