2000-11-14 Kazu Hirata <kazu@hxi.com>
[deliverable/binutils-gdb.git] / bfd / libbfd.c
index 9620cda70686d7688e92d64fa9a4510cfae0adcf..47f1ebbe2bd3506742bf8e4eb6716f8ec6197b6b 100644 (file)
@@ -274,7 +274,10 @@ bfd_read (ptr, size, nitems, abfd)
       get = size * nitems;
       if (abfd->where + get > bim->size)
        {
-         get = bim->size - abfd->where;
+         if (bim->size < (bfd_size_type) abfd->where)
+           get = 0;
+         else
+           get = bim->size - abfd->where;
          bfd_set_error (bfd_error_file_truncated);
        }
       memcpy (ptr, bim->buffer + abfd->where, get);
@@ -293,7 +296,7 @@ bfd_read (ptr, size, nitems, abfd)
 
      A BFD backend may wish to override bfd_error_file_truncated to
      provide something more useful (eg. no_symbols or wrong_format).  */
-  if (nread < (int)(size * nitems))
+  if (nread != (int) (size * nitems))
     {
       if (ferror (bfd_cache_lookup (abfd)))
        bfd_set_error (bfd_error_system_call);
@@ -677,10 +680,42 @@ bfd_seek (abfd, position, direction)
 
   if ((abfd->flags & BFD_IN_MEMORY) != 0)
     {
+      struct bfd_in_memory *bim;
+
+      bim = (struct bfd_in_memory *) abfd->iostream;
+      
       if (direction == SEEK_SET)
        abfd->where = position;
       else
        abfd->where += position;
+      
+      if ((bfd_size_type) abfd->where > bim->size)
+       {
+         if ((abfd->direction == write_direction) || 
+             (abfd->direction == both_direction))
+           {
+             long newsize, oldsize = (bim->size + 127) & ~127;
+             bim->size = abfd->where;
+             /* Round up to cut down on memory fragmentation */
+             newsize = (bim->size + 127) & ~127;
+             if (newsize > oldsize)
+               {
+                 bim->buffer = bfd_realloc (bim->buffer, newsize);
+                 if (bim->buffer == 0)
+                   {
+                     bim->size = 0;
+                     bfd_set_error (bfd_error_no_memory);
+                     return -1;
+                   }
+               }
+           }
+         else
+           {
+             abfd->where = bim->size;
+             bfd_set_error (bfd_error_file_truncated);
+             return -1;
+           }   
+       }
       return 0;
     }
 
@@ -1166,13 +1201,20 @@ _bfd_generic_get_section_contents (abfd, section, location, offset, count)
      file_ptr offset;
      bfd_size_type count;
 {
-    if (count == 0)
-        return true;
-    if ((bfd_size_type)(offset+count) > section->_raw_size
-        || bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1
-        || bfd_read(location, (bfd_size_type)1, count, abfd) != count)
-        return (false); /* on error */
-    return (true);
+  if (count == 0)
+    return true;
+
+  if ((bfd_size_type) (offset + count) > section->_raw_size)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return false;
+    }
+
+  if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
+      || bfd_read (location, (bfd_size_type) 1, count, abfd) != count)
+    return false;
+
+  return true;
 }
 
 boolean
@@ -1284,13 +1326,17 @@ _bfd_generic_verify_endian_match (ibfd, obfd)
      bfd *obfd;
 {
   if (ibfd->xvec->byteorder != obfd->xvec->byteorder
+      && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
       && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
     {
-      (*_bfd_error_handler)
-       ("%s: compiled for a %s endian system and target is %s endian",
-        bfd_get_filename (ibfd),
-        bfd_big_endian (ibfd) ? "big" : "little",
-        bfd_big_endian (obfd) ? "big" : "little");
+      const char *msg;
+
+      if (bfd_big_endian (ibfd))
+       msg = _("%s: compiled for a big endian system and target is little endian");
+      else
+       msg = _("%s: compiled for a little endian system and target is big endian");
+
+      (*_bfd_error_handler) (msg, bfd_get_filename (ibfd));
 
       bfd_set_error (bfd_error_wrong_format);
       return false;
This page took 0.027702 seconds and 4 git commands to generate.