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);