This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]