This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
readelf: Large file support
- From: Bernhard Walle <bernhard dot walle at gmx dot de>
- To: binutils at sources dot redhat dot com
- Date: Wed, 04 Jul 2007 01:19:42 +0200
- Subject: readelf: Large file support
Hello,
even ELF32 files can represent 4 GiB since the Elf32_Off type is unsigned.
However, readelf.c uses the "normal" stdio API that can only handle 2 GiB
on 32 bit plaforms.
Following quick & dirty patch implements LFS. My questions:
- Is it worth to improve the patch to get it included in (mainline)
binutils or do you reject the approach in general?
- Should the #define _FILE_OFFSET_BITS be moved into the Makefile
with -D?
- Should the explicit API (lseek64(), etc.) be used? But this would require
to move from stdio API to "classic" Unix API to read the file.
Any comments appreciated.
Thanks,
Bernhard
---
binutils/configure.in | 1 +
binutils/readelf.c | 44 +++++++++++++++++++++++++++++++-------------
2 files changed, 32 insertions(+), 13 deletions(-)
--- a/binutils/configure.in
+++ b/binutils/configure.in
@@ -181,6 +181,7 @@ fi
AC_CHECK_DECLS([fprintf, stpcpy, strstr, sbrk, getenv, environ,
getc_unlocked,
snprintf, vsnprintf])
+AC_CHECK_DECLS(fseeko)
BFD_BINARY_FOPEN
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -41,6 +41,23 @@
ELF file than is provided by objdump. In particular it can display DWARF
debugging information which (at the moment) objdump cannot. */
+
+/*
+ * use LFS to read files larger than 2 GB on 32 bit platforms
+ * we need this before sysdep.h to only modify the compilation
+ * of this file
+ */
+#include "config.h"
+
+#ifdef HAVE_DECL_FSEEKO
+# define _FILE_OFFSET_BITS 64
+# define fseek_re(stream, offset, whence) \
+ fseeko(stream, offset, whence)
+#else
+# define fseek_re(stream, offset, whence) \
+ fseek(stream, offset, whence)
+#endif
+
#include "sysdep.h"
#include <assert.h>
#include <sys/stat.h>
@@ -159,7 +176,7 @@
#include "libiberty.h"
char *program_name = "readelf";
-static long archive_file_offset;
+static off_t archive_file_offset;
static unsigned long archive_file_size;
static unsigned long dynamic_addr;
static bfd_size_type dynamic_size;
@@ -306,7 +323,7 @@ static void (*byte_put) (unsigned char *
#define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
static void *
-get_data (void *var, FILE *file, long offset, size_t size, size_t nmemb,
+get_data (void *var, FILE *file, off_t offset, size_t size, size_t nmemb,
const char *reason)
{
void *mvar;
@@ -314,10 +331,10 @@ get_data (void *var, FILE *file, long of
if (size == 0 || nmemb == 0)
return NULL;
- if (fseek (file, archive_file_offset + offset, SEEK_SET))
+ if (fseek_re (file, archive_file_offset + offset, SEEK_SET))
{
- error (_("Unable to seek to 0x%lx for %s\n"),
- archive_file_offset + offset, reason);
+ error (_("Unable to seek to 0x%llx for %s\n"),
+ (long long)archive_file_offset + offset, reason);
return NULL;
}
@@ -687,7 +704,7 @@ guess_is_rela (unsigned long e_machine)
static int
slurp_rela_relocs (FILE *file,
- unsigned long rel_offset,
+ off_t rel_offset,
unsigned long rel_size,
Elf_Internal_Rela **relasp,
unsigned long *nrelasp)
@@ -759,7 +776,7 @@ slurp_rela_relocs (FILE *file,
static int
slurp_rel_relocs (FILE *file,
- unsigned long rel_offset,
+ off_t rel_offset,
unsigned long rel_size,
Elf_Internal_Rela **relsp,
unsigned long *nrelsp)
@@ -834,7 +851,7 @@ slurp_rel_relocs (FILE *file,
static int
dump_relocations (FILE *file,
- unsigned long rel_offset,
+ off_t rel_offset,
unsigned long rel_size,
Elf_Internal_Sym *symtab,
unsigned long nsyms,
@@ -4645,7 +4662,7 @@ static int
process_relocs (FILE *file)
{
unsigned long rel_size;
- unsigned long rel_offset;
+ off_t rel_offset;
if (!do_reloc)
@@ -4686,8 +4703,8 @@ process_relocs (FILE *file)
if (rel_size)
{
printf
- (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
- name, rel_offset, rel_size);
+ (_("\n'%s' relocation section at offset 0x%llx contains %ld bytes:\n"),
+ name, (long long)rel_offset, rel_size);
dump_relocations (file,
offset_from_vma (file, rel_offset, rel_size),
@@ -4729,8 +4746,9 @@ process_relocs (FILE *file)
else
printf (_("'%s'"), SECTION_NAME (section));
- printf (_(" at offset 0x%lx contains %lu entries:\n"),
- rel_offset, (unsigned long) (rel_size / section->sh_entsize));
+ printf (_(" at offset 0x%llx contains %lu entries:\n"),
+ (long long)rel_offset, (unsigned long)
+ (rel_size / section->sh_entsize));
is_rela = section->sh_type == SHT_RELA;