This is the mail archive of the binutils@sources.redhat.com 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]

[wip:binutils] Large corefile support


Hello,

On the i386, GDB has problems when a corefile is >2gb. The problems are directly attributable to BFD's use of:
typedef long file_ptr;
and
fseek (FILE *stream, long int offset, int whence)
The attached, when combined with a BFD/GDB configured / built with --enable-64-bit-bfd, lets GDB handle corefiles >2gb, per this test:
http://sources.redhat.com/ml/gdb-patches/2004-01/msg00358.html


Of note in the patch are:

- it scatters #ifdef's to handle fseek et.al. variants
Is there a better way of doing this?

- is requires --enable-64-bit-bfd
A 32-bit BFD has a 32-bit signed file_ptr (limiting SEEK_SET to files up to 2gb). I think the only robust way of handling files larger than that 2gb is to require a 64-bit file_ptr (and hence --enable-64-bit-bfd).


- it turns out that --enable-64-bit-bfd tickles some bugs in GDB's thread code :-/

- given a 3gb core file, 32-bit objdump isn't very helpful
objdump prints zero's instead of error for the sections contents :-( Someone might want to look at this.


Anyway, is this "in principal" ok for BFD (assuming I can track down the regressions :-)?

Andrew
2004-01-16  Andrew Cagney  <cagney@redhat.com>

	* configure.in (bfd_cv_has_long_long): Check for fseeko, ftello,
	fseeko64, and ftello64.
	* configure, config.in: Re-generate.
	* cache.c (close_one): Use ftello or ftello64 when applicable.
	* bfdio.c (bfd_tell): Ditto.
	(bfd_seek) [0]: Ditto.
	* cache.c (bfd_cache_lookup_worker): Use fseeko or fseeko64 when
	applicable.
	* bfdio.c (bfd_seek): Change type of "file_position" to
	"file_ptr".  Use fseeko or fseeko64 when applicable.

Index: bfdio.c
===================================================================
RCS file: /cvs/src/src/bfd/bfdio.c,v
retrieving revision 1.4
diff -u -r1.4 bfdio.c
--- bfdio.c	24 Nov 2003 18:06:39 -0000	1.4
+++ bfdio.c	16 Jan 2004 23:18:12 -0000
@@ -170,7 +170,13 @@
   if ((abfd->flags & BFD_IN_MEMORY) != 0)
     return abfd->where;
 
+#if defined HAVE_FTELLO64 && defined BFD64
+  ptr = ftello64 (bfd_cache_lookup (abfd));
+#elif defined HAVE_FTELLO && defined BFD64
+  ptr = ftello (bfd_cache_lookup (abfd));
+#else
   ptr = ftell (bfd_cache_lookup (abfd));
+#endif
 
   if (abfd->my_archive)
     ptr -= abfd->origin;
@@ -217,7 +223,7 @@
 {
   int result;
   FILE *f;
-  long file_position;
+  file_ptr file_position;
   /* For the time being, a BFD may not seek to it's end.  The problem
      is that we don't easily have a way to recognize the end of an
      element in an archive.  */
@@ -278,7 +284,13 @@
 	 tripping the abort, we can probably safely disable this code,
 	 so that the real optimizations happen.  */
       file_ptr where_am_i_now;
+#if defined HAVE_FTELLO64 && defined BFD64
+      where_am_i_now = ftello64 (bfd_cache_lookup (abfd));
+#elif defined HAVE_FTELLO && defined BFD64
+      where_am_i_now = ftello (bfd_cache_lookup (abfd));
+#else
       where_am_i_now = ftell (bfd_cache_lookup (abfd));
+#endif
       if (abfd->my_archive)
 	where_am_i_now -= abfd->origin;
       if (where_am_i_now != abfd->where)
@@ -307,7 +319,17 @@
   if (direction == SEEK_SET && abfd->my_archive != NULL)
     file_position += abfd->origin;
 
+#if defined HAVE_FSEEKO64 && defined BFD64
+  /* NOTE: 64-bit seek is really only useful when BFD has been built
+     64-bit.  A 32-bit BFD build will have a 32-bit file_ptr which
+     limits the SEEK_SET range to 0..2^31.  */
+  result = fseeko64 (f, file_position, direction);
+#elif defined HAVE_FSEEKO && defined BFD64
+  /* For a BFD built 64-bit, hopefully off_t is 64-bit.  */
+  result = fseeko (f, file_position, direction);
+#else
   result = fseek (f, file_position, direction);
+#endif
   if (result != 0)
     {
       int hold_errno = errno;
Index: cache.c
===================================================================
RCS file: /cvs/src/src/bfd/cache.c,v
retrieving revision 1.10
diff -u -r1.10 cache.c
--- cache.c	29 Jun 2003 10:06:39 -0000	1.10
+++ cache.c	16 Jan 2004 23:18:12 -0000
@@ -155,7 +155,13 @@
       return TRUE;
     }
 
+#if defined HAVE_FTELLO64 && defined BFD64
+  kill->where = ftello64 ((FILE *) kill->iostream);
+#elif defined HAVE_FTELLO && defined BFD64
+  kill->where = ftello ((FILE *) kill->iostream);
+#else
   kill->where = ftell ((FILE *) kill->iostream);
+#endif
 
   return bfd_cache_delete (kill);
 }
@@ -356,8 +362,20 @@
 	return NULL;
       if (abfd->where != (unsigned long) abfd->where)
 	return NULL;
+#if defined HAVE_FSEEKO64 && defined BFD64
+      /* NOTE: 64-bit seek is really only useful when BFD has been
+         built 64-bit.  A 32-bit BFD build will have a 32-bit file_ptr
+         which limits the SEEK_SET range to 0..2^31.  */
+      if (fseeko64 ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0)
+	return NULL;
+#elif defined HAVE_FSEEKO && defined BFD64
+      /* For a BFD built 64-bit, hopefully off_t is 64-bit.  */
+      if (fseeko ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0)
+	return NULL;
+#else
       if (fseek ((FILE *) abfd->iostream, (long) abfd->where, SEEK_SET) != 0)
 	return NULL;
+#endif
     }
 
   return (FILE *) abfd->iostream;
Index: configure.in
===================================================================
RCS file: /cvs/src/src/bfd/configure.in,v
retrieving revision 1.142
diff -u -r1.142 configure.in
--- configure.in	19 Dec 2003 11:43:53 -0000	1.142
+++ configure.in	16 Jan 2004 23:18:12 -0000
@@ -159,7 +159,7 @@
 AC_HEADER_TIME
 AC_HEADER_DIRENT
 AC_CHECK_FUNCS(fcntl getpagesize setitimer sysconf fdopen getuid getgid)
-AC_CHECK_FUNCS(strtoull)
+AC_CHECK_FUNCS(strtoull fseeko fseeko64)
 
 BFD_BINARY_FOPEN
 

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