summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libelf/ChangeLog4
-rw-r--r--libelf/elf_readall.c24
2 files changed, 26 insertions, 2 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 974afa15..8098f4e9 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,7 @@
+2009-11-10 Roland McGrath <[email protected]>
+
+ * elf_readall.c (__libelf_readall): Fetch file size if not yet known.
+
2009-11-06 Mark Wielaard <[email protected]>
* elf_next.c (elf_next): Mark the archive header as unusable when
diff --git a/libelf/elf_readall.c b/libelf/elf_readall.c
index 8f171b21..1f59932f 100644
--- a/libelf/elf_readall.c
+++ b/libelf/elf_readall.c
@@ -1,5 +1,5 @@
/* Read all of the file associated with the descriptor.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
+ Copyright (C) 1998-2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Contributed by Ulrich Drepper <[email protected]>, 1998.
@@ -54,6 +54,7 @@
#include <errno.h>
#include <unistd.h>
+#include <sys/stat.h>
#include <system.h>
#include "libelfP.h"
@@ -102,12 +103,30 @@ __libelf_readall (elf)
/* If the file is not mmap'ed and not previously loaded, do it now. */
if (elf->map_address == NULL)
{
- char *mem;
+ char *mem = NULL;
/* If this is an archive and we have derived descriptors get the
locks for all of them. */
libelf_acquire_all (elf);
+ if (elf->maximum_size == ~((size_t) 0))
+ {
+ /* We don't yet know how large the file is. Determine that now. */
+ struct stat st;
+
+ if (fstat (elf->fildes, &st) < 0)
+ goto read_error;
+
+ if (sizeof (size_t) >= sizeof (st.st_size)
+ || st.st_size <= ~((size_t) 0))
+ elf->maximum_size = (size_t) st.st_size;
+ else
+ {
+ errno = EOVERFLOW;
+ goto read_error;
+ }
+ }
+
/* Allocate all the memory we need. */
mem = (char *) malloc (elf->maximum_size);
if (mem != NULL)
@@ -119,6 +138,7 @@ __libelf_readall (elf)
!= elf->maximum_size))
{
/* Something went wrong. */
+ read_error:
__libelf_seterrno (ELF_E_READ_ERROR);
free (mem);
}