propagate from branch 'com.redhat.elfutils.pmachata.threads' (head 6db56f08d1ba946c22c9bcfaec0ddeb6532e1dcc)
            to branch 'com.redhat.elfutils.roland.pending' (head d0bf16e5588ef191b1541ac0d07d841c1cf52fc9)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index c7f0c4b..9e54a83 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,16 @@
+2008-08-26  Roland McGrath  <roland@redhat.com>
+
+	* segment.c (reify_segments): Insert a trailing segment for a module
+	end that is above the highest current segment.
+
+2008-08-25  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getdwarf.c (open_elf): Extract elf_errno () for
+	coded return value, not plain DWFL_E_LIBELF.  Return DWFL_E_BADELF
+	if FILE->elf is not ELF_K_ELF.
+
+	* dwfl_segment_report_module.c: Add a cast.
+
 2008-08-21  Denys Vlasenko  <dvlasenk@redhat.com>
 
 	* dwfl_module_addrsym.c (dwfl_module_addrsym): Improve logic
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index f5ee314..652383b 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -72,13 +72,20 @@
       file->elf = elf_begin (file->fd, ELF_C_READ_MMAP_PRIVATE, NULL);
     }
 
+  if (unlikely (elf_kind (file->elf) != ELF_K_ELF))
+    {
+      close (file->fd);
+      file->fd = -1;
+      return DWFL_E_BADELF;
+    }
+
   GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (file->elf, &ehdr_mem);
   if (ehdr == NULL)
     {
     elf_error:
       close (file->fd);
       file->fd = -1;
-      return DWFL_E_LIBELF;
+      return DWFL_E (LIBELF, elf_errno ());
     }
 
   /* The addresses in an ET_EXEC file are absolute.  The lowest p_vaddr of
diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c
index a627c47..50ed140 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -313,7 +313,8 @@
      {
 	const void *note_name = nh + 1;
 	const void *note_desc = note_name + NOTE_ALIGN (nh->n_namesz);
-	if (unlikely ((const void *) notes + filesz - note_desc < nh->n_descsz))
+	if (unlikely ((size_t) ((const void *) notes + filesz
+				- note_desc) < nh->n_descsz))
 	  break;
 
 	if (nh->n_type == NT_GNU_BUILD_ID
diff --git a/libdwfl/segment.c b/libdwfl/segment.c
index 3c1f8bc..78220e3 100644
--- a/libdwfl/segment.c
+++ b/libdwfl/segment.c
@@ -176,8 +176,8 @@
 	    ++idx;
 	  }
 
-	if ((size_t) idx + 1 < dwfl->lookup_elts
-	    && end < dwfl->lookup_addr[idx + 1]
+	if (((size_t) idx + 1 == dwfl->lookup_elts
+	     || end < dwfl->lookup_addr[idx + 1])
 	    /* The module ends in the middle of this segment.  Split it.  */
 	    && unlikely (insert (dwfl, idx + 1,
 				 end, dwfl->lookup_addr[idx + 1], -1)))
diff --git a/libelf/elf32_getphdr.c b/libelf/elf32_getphdr.c
index c0b28aa..c32c282 100644
--- a/libelf/elf32_getphdr.c
+++ b/libelf/elf32_getphdr.c
@@ -232,6 +232,22 @@
 {
   ElfW2(LIBELFBITS,Phdr) *result;
 
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* If the program header entry has already been filled in the code
+   * in getphdr_wrlock must already have been run.  So the class is
+   * set, too.  No need to waste any more time here.  */
+  result = elf->state.ELFW(elf,LIBELFBITS).phdr;
+  if (likely (result != NULL))
+    return result;
+
   rwlock_wrlock (elf->lock);
   result = __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
   rwlock_unlock (elf->lock);