From 9cf28e4f899f97ecdc983a0af8e2be62f3d69058 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 30 Sep 2008 06:35:35 +0000 Subject: libdwfl/ 2008-09-29 Roland McGrath * segment.c (insert): Must realloc DWFL->lookup_module here too. (dwfl_report_segment): Clear DWFL->lookup_module before insert calls. --- libdwfl/ChangeLog | 14 ++++++++++++++ libdwfl/linux-proc-maps.c | 3 +++ libdwfl/segment.c | 40 +++++++++++++++++++++++++++++++--------- libelf/ChangeLog | 6 ++++++ libelf/elf_begin.c | 20 +++++++++++++++----- libelf/libelfP.h | 2 +- 6 files changed, 70 insertions(+), 15 deletions(-) diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 9e54a831..e29c7d60 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,17 @@ +2008-09-29 Roland McGrath + + * segment.c (insert): Must realloc DWFL->lookup_module here too. + (dwfl_report_segment): Clear DWFL->lookup_module before insert calls. + +2008-08-28 Roland McGrath + + * segment.c (reify_segments): Fix last change. + +2008-08-27 Roland McGrath + + * linux-proc-maps.c (read_proc_memory): Return 0 for EINVAL or EPERM + failure from pread64. + 2008-08-26 Roland McGrath * segment.c (reify_segments): Insert a trailing segment for a module diff --git a/libdwfl/linux-proc-maps.c b/libdwfl/linux-proc-maps.c index b4bb6cfc..2206f63c 100644 --- a/libdwfl/linux-proc-maps.c +++ b/libdwfl/linux-proc-maps.c @@ -267,6 +267,9 @@ read_proc_memory (void *arg, void *data, GElf_Addr address, { const int fd = *(const int *) arg; ssize_t nread = pread64 (fd, data, maxread, (off64_t) address); + /* Some kernels don't actually let us do this read, ignore those errors. */ + if (nread < 0 && (errno == EINVAL || errno == EPERM)) + return 0; if (nread > 0 && (size_t) nread < minread) nread = 0; return nread; diff --git a/libdwfl/segment.c b/libdwfl/segment.c index 78220e3b..cb520e64 100644 --- a/libdwfl/segment.c +++ b/libdwfl/segment.c @@ -83,12 +83,26 @@ insert (Dwfl *dwfl, size_t i, GElf_Addr start, GElf_Addr end, int segndx) int *nsegndx = realloc (dwfl->lookup_segndx, sizeof nsegndx[0] * n); if (unlikely (nsegndx == NULL)) { - free (naddr); + if (naddr != dwfl->lookup_addr) + free (naddr); return true; } dwfl->lookup_alloc = n; dwfl->lookup_addr = naddr; dwfl->lookup_segndx = nsegndx; + + if (dwfl->lookup_module != NULL) + { + /* Make sure this array is big enough too. */ + Dwfl_Module **old = dwfl->lookup_module; + dwfl->lookup_module = realloc (dwfl->lookup_module, + sizeof dwfl->lookup_module[0] * n); + if (unlikely (dwfl->lookup_module == NULL)) + { + free (old); + return true; + } + } } if (unlikely (i < dwfl->lookup_elts)) @@ -175,9 +189,17 @@ reify_segments (Dwfl *dwfl) return true; ++idx; } + else if (dwfl->lookup_addr[idx] < start) + { + /* The module starts past the end of this segment. + Add a new one. */ + if (unlikely (insert (dwfl, idx + 1, start, end, -1))) + return true; + ++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))) @@ -261,6 +283,12 @@ dwfl_report_segment (Dwfl *dwfl, int ndx, const GElf_Phdr *phdr, GElf_Addr bias, phdr->p_align < dwfl->segment_align)) dwfl->segment_align = phdr->p_align; + if (unlikely (dwfl->lookup_module != NULL)) + { + free (dwfl->lookup_module); + dwfl->lookup_module = NULL; + } + GElf_Addr start = segment_start (dwfl, bias + phdr->p_vaddr); GElf_Addr end = segment_end (dwfl, bias + phdr->p_vaddr + phdr->p_memsz); @@ -289,12 +317,6 @@ dwfl_report_segment (Dwfl *dwfl, int ndx, const GElf_Phdr *phdr, GElf_Addr bias, dwfl->lookup_tail_offset = end - bias - phdr->p_vaddr + phdr->p_offset; dwfl->lookup_tail_ndx = ndx + 1; - if (unlikely (dwfl->lookup_module != NULL)) - { - free (dwfl->lookup_module); - dwfl->lookup_module = NULL; - } - return ndx; } INTDEF (dwfl_report_segment) diff --git a/libelf/ChangeLog b/libelf/ChangeLog index d258de8d..18c34fcc 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,9 @@ +2008-08-27 Roland McGrath + + * elf_begin.c (get_shnum): Avoid misaligned reads for matching endian. + + * libelfP.h [!ALLOW_UNALIGNED] (__libelf_type_align): Fix CLASS index. + 2008-08-25 Roland McGrath * Makefile.am (libelf_so_LDLIBS): New variable. diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c index b95b06bf..bd385306 100644 --- a/libelf/elf_begin.c +++ b/libelf/elf_begin.c @@ -111,7 +111,11 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset, bool is32 = e_ident[EI_CLASS] == ELFCLASS32; /* Make the ELF header available. */ - if (e_ident[EI_DATA] == MY_ELFDATA) + if (e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((size_t) e_ident + & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr)) + - 1)) == 0))) ehdr.p = e_ident; else { @@ -130,8 +134,11 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset, else memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr)); - CONVERT (ehdr_mem.e32.e_shnum); - CONVERT (ehdr_mem.e32.e_shoff); + if (e_ident[EI_DATA] != MY_ELFDATA) + { + CONVERT (ehdr_mem.e32.e_shnum); + CONVERT (ehdr_mem.e32.e_shoff); + } } else { @@ -143,8 +150,11 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset, else memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr)); - CONVERT (ehdr_mem.e64.e_shnum); - CONVERT (ehdr_mem.e64.e_shoff); + if (e_ident[EI_DATA] != MY_ELFDATA) + { + CONVERT (ehdr_mem.e64.e_shnum); + CONVERT (ehdr_mem.e64.e_shoff); + } } } diff --git a/libelf/libelfP.h b/libelf/libelfP.h index 1dc331fc..4cab3f38 100644 --- a/libelf/libelfP.h +++ b/libelf/libelfP.h @@ -460,7 +460,7 @@ extern int __libelf_version_initialized attribute_hidden; version, binary class, and type. */ extern const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden; # define __libelf_type_align(class, type) \ - (__libelf_type_aligns[LIBELF_EV_IDX][class][type] ?: 1) + (__libelf_type_aligns[LIBELF_EV_IDX][class - 1][type] ?: 1) #else # define __libelf_type_align(class, type) 1 #endif -- cgit v1.2.1