* elfcode.h (map_program_segments): Restore check of file_size !=
[deliverable/binutils-gdb.git] / bfd / bfd.c
index 8dbf96e64c3bebbac6bcc621bd08d46e7f8f77e9..21588408cf6033b9b44f40b2972934ed71bcf48d 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1,5 +1,5 @@
 /* Generic BFD library interface and support routines.
-   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+   Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -22,13 +22,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 SECTION
        <<typedef bfd>>
 
-       A BFD is has type <<bfd>>; objects of this type are the
-       cornerstone of any application using <<libbfd>>. References
-       though the BFD and to data in the BFD give the entire BFD
-       functionality.
+       A BFD has type <<bfd>>; objects of this type are the
+       cornerstone of any application using <<libbfd>>. Using BFD
+       consists of making references though the BFD and to data in the BFD.
 
-       Here is the struct used to define the type <<bfd>>.  This
-       contains the major data about the file, and contains pointers
+       Here is the structure that defines the type <<bfd>>.  It
+       contains the major data about the file and pointers
        to the rest of the data.
 
 CODE_FRAGMENT
@@ -48,13 +47,14 @@ CODE_FRAGMENT
 .       is the result of an fopen on the filename. *}
 .    char *iostream;
 .
-.    {* Is the file being cached *}
+.    {* Is the file descriptor being cached?  That is, can it be closed as
+.       needed, and re-opened when accessed later?  *}
 .
 .    boolean cacheable;
 .
 .    {* Marks whether there was a default target specified when the
-.       BFD was opened. This is used to select what matching algorithm
-.       to use to chose the back end. *}
+.       BFD was opened. This is used to select which matching algorithm
+.       to use to choose the back end. *}
 .
 .    boolean target_defaulted;
 .
@@ -64,12 +64,11 @@ CODE_FRAGMENT
 .    struct _bfd *lru_prev, *lru_next;
 .
 .    {* When a file is closed by the caching routines, BFD retains
-.       state information on the file here: 
-.     *}
+.       state information on the file here: *}
 .
 .    file_ptr where;              
 .
-.    {* and here:*}
+.    {* and here: (``once'' means at least once) *}
 .
 .    boolean opened_once;
 .
@@ -86,7 +85,7 @@ CODE_FRAGMENT
 .
 .    int ifd;
 .
-.    {* The format which belongs to the BFD.*}
+.    {* The format which belongs to the BFD. (object, core, etc.) *}
 .
 .    bfd_format format;
 .
@@ -108,7 +107,7 @@ CODE_FRAGMENT
 .    file_ptr origin;             
 .
 .    {* Remember when output has begun, to stop strange things
-.       happening. *}
+.       from happening. *}
 .    boolean output_has_begun;
 .
 .    {* Pointer to linked list of sections*}
@@ -124,7 +123,7 @@ CODE_FRAGMENT
 .    {* Used for input and output*}
 .    unsigned int symcount;
 .
-.    {* Symbol table for output BFD*}
+.    {* Symbol table for output BFD (with symcount entries) *}
 .    struct symbol_cache_entry  **outsymbols;             
 .
 .    {* Pointer to structure which contains architecture information*}
@@ -132,9 +131,9 @@ CODE_FRAGMENT
 .
 .    {* Stuff only useful for archives:*}
 .    PTR arelt_data;              
-.    struct _bfd *my_archive;     
-.    struct _bfd *next;           
-.    struct _bfd *archive_head;   
+.    struct _bfd *my_archive;     {* The containing archive BFD.  *}
+.    struct _bfd *next;           {* The next BFD in the archive.  *}
+.    struct _bfd *archive_head;   {* The first BFD in the archive.  *}
 .    boolean has_armap;           
 .
 .    {* Used by the back end to hold private data. *}
@@ -146,15 +145,21 @@ CODE_FRAGMENT
 .      struct _oasys_data *oasys_obj_data;
 .      struct _oasys_ar_data *oasys_ar_data;
 .      struct coff_tdata *coff_obj_data;
+.      struct ecoff_tdata *ecoff_obj_data;
 .      struct ieee_data_struct *ieee_data;
 .      struct ieee_ar_data_struct *ieee_ar_data;
 .      struct srec_data_struct *srec_data;
 .      struct tekhex_data_struct *tekhex_data;
 .      struct elf_obj_tdata *elf_obj_data;
+.      struct nlm_obj_tdata *nlm_obj_data;
 .      struct bout_data_struct *bout_data;
 .      struct sun_core_struct *sun_core_data;
 .      struct trad_core_struct *trad_core_data;
-.      struct hppa_data_struct *hppa_data;
+.      struct som_data_struct *som_data;
+.      struct hpux_core_struct *hpux_core_data;
+.      struct sgi_core_struct *sgi_core_data;
+.      struct lynx_core_struct *lynx_core_data;
+.      struct osf_core_struct *osf_core_data;
 .      PTR any;
 .      } tdata;
 .  
@@ -173,17 +178,16 @@ CODE_FRAGMENT
 #include "bfd.h"
 #include "sysdep.h"
 #include "libbfd.h"
+#include "coff/internal.h"
+#include "coff/sym.h"
+#include "libcoff.h"
+#include "libecoff.h"
+#undef obj_symbols
+#include "libelf.h"
 
 #undef strerror
 extern char *strerror();
 
-
-CONST short _bfd_host_big_endian = 0x0100;
-        /* Accessing the above as (*(char*)&_bfd_host_big_endian), will
-           return 1 if the host is big-endian, 0 otherwise.
-           (assuming that a short is two bytes long!!!  FIXME)
-           (See HOST_IS_BIG_ENDIAN_P in bfd.h.)  */
-\f
 /** Error handling
     o - Most functions return nonzero on success (check doc for
         precise semantics); 0 or NULL on error.
@@ -194,7 +198,8 @@ CONST short _bfd_host_big_endian = 0x0100;
 
 bfd_ec bfd_error = no_error;
 
-CONST char *CONST bfd_errmsgs[] = { "No error",
+CONST char *CONST bfd_errmsgs[] = {
+                        "No error",
                         "System call error",
                         "Invalid target",
                         "File in wrong format",
@@ -211,6 +216,7 @@ CONST char *CONST bfd_errmsgs[] = { "No error",
                         "Nonrepresentable section on output",
                        "Symbol needs debug section which does not exist",
                        "Bad value",
+                       "File truncated",
                         "#<Invalid error code>"
                        };
 
@@ -220,10 +226,11 @@ DEFUN(bfd_nonrepresentable_section,(abfd, name),
          CONST  bfd * CONST abfd AND
          CONST  char * CONST name)
 {
-  printf("bfd error writing file %s, format %s can't represent section %s\n",
-         abfd->filename, 
-         abfd->xvec->name,
-         name);
+  fprintf(stderr,
+         "bfd error writing file %s, format %s can't represent section %s\n",
+         abfd->filename, 
+         abfd->xvec->name,
+         name);
   exit(1);
 }
 
@@ -235,8 +242,8 @@ DEFUN(bfd_undefined_symbol,(relent, seclet),
       CONST  struct bfd_seclet *seclet)
 {
   asymbol *symbol = *(relent->sym_ptr_ptr);
-  printf("bfd error relocating, symbol %s is undefined\n",
-         symbol->name);
+  fprintf(stderr, "bfd error relocating, symbol %s is undefined\n",
+         symbol->name);
   exit(1);
 }
 /*ARGSUSED*/
@@ -246,7 +253,7 @@ DEFUN(bfd_reloc_value_truncated,(relent, seclet),
          CONST  arelent *relent AND
       struct bfd_seclet *seclet)
 {
-  printf("bfd error relocating, value truncated\n");
+  fprintf(stderr, "bfd error relocating, value truncated\n");
   exit(1);
 }
 /*ARGSUSED*/
@@ -256,7 +263,7 @@ DEFUN(bfd_reloc_is_dangerous,(relent, seclet),
       CONST  arelent *relent AND
      CONST  struct bfd_seclet *seclet)
 {
-  printf("bfd error relocating, dangerous\n");
+  fprintf(stderr, "bfd error relocating, dangerous\n");
   exit(1);
 }
 
@@ -286,15 +293,15 @@ bfd_errmsg (error_tag)
   return bfd_errmsgs [(int)error_tag];
 }
 
-
-void bfd_default_error_trap(error_tag)
-bfd_ec error_tag;
+void
+DEFUN (bfd_default_error_trap, (error_tag),
+       bfd_ec error_tag)
 {
-  printf("bfd assert fail (%s)\n", bfd_errmsg(error_tag));
+  fprintf(stderr, "bfd assert fail (%s)\n", bfd_errmsg(error_tag));
 }
 
-void (*bfd_error_trap)() = bfd_default_error_trap;
-void (*bfd_error_nonrepresentabltrap)() = bfd_default_error_trap;
+void (*bfd_error_trap) PARAMS ((bfd_ec)) = bfd_default_error_trap;
+void (*bfd_error_nonrepresentabltrap) PARAMS ((bfd_ec)) = bfd_default_error_trap;
 
 void
 DEFUN(bfd_perror,(message),
@@ -322,9 +329,9 @@ SYNOPSIS
        unsigned int bfd_get_reloc_upper_bound(bfd *abfd, asection *sect);
 
 DESCRIPTION
-       This function return the number of bytes required to store the
-       relocation information associated with section <<sect>>
-       attached to bfd <<abfd>>
+       Return the number of bytes required to store the
+       relocation information associated with section @var{sect}
+       attached to bfd @var{abfd}.
 
 */
 
@@ -354,14 +361,14 @@ SYNOPSIS
                asymbol **syms);
 
 DESCRIPTION
-       This function calls the back end associated with the open
-       <<abfd>> and translates the external form of the relocation
-       information attached to <<sec>> into the internal canonical
-       form.  The table is placed into memory at <<loc>>, which has
+       Call the back end associated with the open BFD
+       @var{abfd} and translate the external form of the relocation
+       information attached to @var{sec} into the internal canonical
+       form.  Place the table into memory at @var{loc}, which has
        been preallocated, usually by a call to
        <<bfd_get_reloc_upper_bound>>.
 
-       The <<syms>> table is also needed for horrible internal magic
+       The @var{syms} table is also needed for horrible internal magic
        reasons.
 
 
@@ -373,14 +380,39 @@ DEFUN(bfd_canonicalize_reloc,(abfd, asect, location, symbols),
      arelent **location AND
      asymbol **symbols)
 {
-    if (abfd->format != bfd_object) {
-           bfd_error = invalid_operation;
-           return 0;
-       }
-    return BFD_SEND (abfd, _bfd_canonicalize_reloc,
-                    (abfd, asect, location, symbols));
+  if (abfd->format != bfd_object) {
+    bfd_error = invalid_operation;
+    return 0;
   }
+  return BFD_SEND (abfd, _bfd_canonicalize_reloc,
+                  (abfd, asect, location, symbols));
+}
 
+/*
+FUNCTION
+       bfd_set_reloc
+
+SYNOPSIS
+       void bfd_set_reloc
+         (bfd *abfd, asection *sec, arelent **rel, unsigned int count)
+
+DESCRIPTION
+       Set the relocation pointer and count within
+       section @var{sec} to the values @var{rel} and @var{count}.
+       The argument @var{abfd} is ignored.
+
+*/
+/*ARGSUSED*/
+void
+bfd_set_reloc (ignore_abfd, asect, location, count)
+     bfd *ignore_abfd;
+     sec_ptr asect;
+     arelent **location;
+     unsigned int count;
+{
+  asect->orelocation  = location;
+  asect->reloc_count = count;
+}
 
 /*
 FUNCTION
@@ -390,16 +422,15 @@ SYNOPSIS
        boolean bfd_set_file_flags(bfd *abfd, flagword flags);
 
 DESCRIPTION
-       This function attempts to set the flag word in the referenced
-       BFD structure to the value supplied.
+       Set the flag word in the BFD @var{abfd} to the value @var{flags}.
 
        Possible errors are:
        o wrong_format - The target bfd was not of object format.
        o invalid_operation - The target bfd was open for reading.
        o invalid_operation -
        The flag word contained a bit which was not applicable to the
-       type of file. eg, an attempt was made to set the D_PAGED bit
-       on a bfd format which does not support demand paging
+       type of file.  E.g., an attempt was made to set the D_PAGED bit
+       on a bfd format which does not support demand paging.
 
 */
 
@@ -427,37 +458,12 @@ bfd_set_file_flags (abfd, flags)
 return true;
 }
 
-/*
-FUNCTION
-       bfd_set_reloc
-
-SYNOPSIS
-       void bfd_set_reloc
-         (bfd *abfd, asection *sec, arelent **rel, unsigned int count)
-
-DESCRIPTION
-       This function sets the relocation pointer and count within a
-       section to the supplied values.
-
-*/
-/*ARGSUSED*/
-void
-bfd_set_reloc (ignore_abfd, asect, location, count)
-     bfd *ignore_abfd;
-     sec_ptr asect;
-     arelent **location;
-     unsigned int count;
-{
-  asect->orelocation  = location;
-  asect->reloc_count = count;
-}
-
 void
 bfd_assert(file, line)
 char *file;
 int line;
 {
-  printf("bfd assertion fail %s:%d\n",file,line);
+  fprintf(stderr, "bfd assertion fail %s:%d\n",file,line);
 }
 
 
@@ -465,14 +471,14 @@ int line;
 FUNCTION
        bfd_set_start_address
 
+SYNOPSIS
+       boolean bfd_set_start_address(bfd *abfd, bfd_vma vma);
+
 DESCRIPTION
-       Marks the entry point of an output BFD.
+       Make @var{vma} the entry point of output BFD @var{abfd}.
 
 RETURNS
        Returns <<true>> on success, <<false>> otherwise.
-
-SYNOPSIS
-       boolean bfd_set_start_address(bfd *, bfd_vma);
 */
 
 boolean
@@ -487,14 +493,14 @@ bfd_vma vma;
 
 /*
 FUNCTION
-       The bfd_get_mtime function
+       bfd_get_mtime
 
 SYNOPSIS
-       long bfd_get_mtime(bfd *);
+       long bfd_get_mtime(bfd *abfd);
 
 DESCRIPTION
-       Return file modification time (as read from file system, or
-       from archive header for archive members).
+       Return the file modification time (as read from the file system, or
+       from the archive header for archive members).
 
 */
 
@@ -516,12 +522,179 @@ bfd_get_mtime (abfd)
   return buf.st_mtime;
 }
 
+/*
+FUNCTION
+       bfd_get_size
+
+SYNOPSIS
+       long bfd_get_size(bfd *abfd);
+
+DESCRIPTION
+       Return the file size (as read from file system) for the file
+       associated with BFD @var{abfd}.
+
+       The initial motivation for, and use of, this routine is not
+       so we can get the exact size of the object the BFD applies to, since
+       that might not be generally possible (archive members for example).
+       It would be ideal if someone could eventually modify
+       it so that such results were guaranteed.
+
+       Instead, we want to ask questions like "is this NNN byte sized
+       object I'm about to try read from file offset YYY reasonable?"
+       As as example of where we might do this, some object formats
+       use string tables for which the first <<sizeof(long)>> bytes of the
+       table contain the size of the table itself, including the size bytes.
+       If an application tries to read what it thinks is one of these
+       string tables, without some way to validate the size, and for
+       some reason the size is wrong (byte swapping error, wrong location
+       for the string table, etc.), the only clue is likely to be a read
+       error when it tries to read the table, or a "virtual memory
+       exhausted" error when it tries to allocate 15 bazillon bytes
+       of space for the 15 bazillon byte table it is about to read.
+       This function at least allows us to answer the quesion, "is the
+       size reasonable?".
+*/
+
+long
+bfd_get_size (abfd)
+     bfd *abfd;
+{
+  FILE *fp;
+  struct stat buf;
+
+  fp = bfd_cache_lookup (abfd);
+  if (0 != fstat (fileno (fp), &buf))
+    return 0;
+
+  return buf.st_size;
+}
+
+/*
+FUNCTION
+       bfd_get_gp_size
+
+SYNOPSIS
+       int bfd_get_gp_size(bfd *abfd);
+
+DESCRIPTION
+       Return the maximum size of objects to be optimized using the GP
+       register under MIPS ECOFF.  This is typically set by the -G
+       argument to the compiler, assembler or linker.
+*/
+
+int
+bfd_get_gp_size (abfd)
+     bfd *abfd;
+{
+  if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
+    return ecoff_data (abfd)->gp_size;
+  return 0;
+}
+
+/*
+FUNCTION
+       bfd_set_gp_size
+
+SYNOPSIS
+       void bfd_set_gp_size(bfd *abfd, int i);
+
+DESCRIPTION
+       Set the maximum size of objects to be optimized using the GP
+       register under ECOFF or MIPS ELF.  This is typically set by
+       the -G argument to the compiler, assembler or linker.
+*/
+
+void
+bfd_set_gp_size (abfd, i)
+     bfd *abfd;
+     int i;
+{
+  if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
+    ecoff_data (abfd)->gp_size = i;
+  else if (abfd->xvec->flavour == bfd_target_elf_flavour)
+    elf_gp_size (abfd) = i;
+}
+
+/*
+FUNCTION
+       bfd_scan_vma
+
+SYNOPSIS
+       bfd_vma bfd_scan_vma(CONST char *string, CONST char **end, int base);
+
+DESCRIPTION
+       Convert, like <<strtoul>>, a numerical expression
+       @var{string} into a bfd_vma integer, and returns that integer.
+       (Though without as many bells and whistles as <<strtoul>>.)
+       The expression is assumed to be unsigned (i.e. positive).
+       If given a @var{base}, it is used as the base for conversion.
+       A base of 0 causes the function to interpret the string
+       in hex if a leading "0x" or "0X" is found, otherwise
+       in octal if a leading zero is found, otherwise in decimal.
+
+       Overflow is not detected.
+*/
+
+bfd_vma
+DEFUN(bfd_scan_vma,(string, end, base),
+      CONST char *string AND
+      CONST char **end AND
+      int base)
+{
+  bfd_vma value;
+  int digit;
+
+  /* Let the host do it if possible.  */
+  if (sizeof(bfd_vma) <= sizeof(unsigned long))
+    return (bfd_vma) strtoul (string, 0, base);
+
+  /* A negative base makes no sense, and we only need to go as high as hex.  */
+  if ((base < 0) || (base > 16))
+    return (bfd_vma) 0;
+
+  if (base == 0)
+    {
+      if (string[0] == '0')
+       {
+         if ((string[1] == 'x') || (string[1] == 'X'))
+           base = 16;
+         /* XXX should we also allow "0b" or "0B" to set base to 2? */
+         else
+           base = 8;
+       }
+      else
+       base = 10;
+    }
+  if ((base == 16) &&
+      (string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X')))
+    string += 2;
+  /* XXX should we also skip over "0b" or "0B" if base is 2? */
+    
+/* Speed could be improved with a table like hex_value[] in gas.  */
+#define HEX_VALUE(c) \
+  (isxdigit(c) ?                               \
+    (isdigit(c) ?                              \
+      (c - '0') :                              \
+      (10 + c - (islower(c) ? 'a' : 'A'))) :   \
+    42)
+
+  for (value = 0; (digit = HEX_VALUE(*string)) < base; string++)
+    {
+      value = value * base + digit;
+    }
+
+  if (end)
+    *end = string;
+
+  return value;
+}
+
 /*
 FUNCTION
        stuff
 
 DESCRIPTION
-       stuff which should be documented
+       Stuff which should be documented:
 
 .#define bfd_sizeof_headers(abfd, reloc) \
 .     BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
@@ -546,16 +719,13 @@ DESCRIPTION
 .#define bfd_set_arch_mach(abfd, arch, mach)\
 .        BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
 .
-.#define bfd_get_relocated_section_contents(abfd, seclet, data) \
-.      BFD_SEND (abfd, _bfd_get_relocated_section_contents, (abfd, seclet, data))
+.#define bfd_get_relocated_section_contents(abfd, seclet, data, relocateable) \
+.      BFD_SEND (abfd, _bfd_get_relocated_section_contents, (abfd, seclet, data, relocateable))
 . 
 .#define bfd_relax_section(abfd, section, symbols) \
 .       BFD_SEND (abfd, _bfd_relax_section, (abfd, section, symbols))
+.
+.#define bfd_seclet_link(abfd, data, relocateable) \
+.       BFD_SEND (abfd, _bfd_seclet_link, (abfd, data, relocateable))
 
 */
-
-
-
-
-
-
This page took 0.032468 seconds and 4 git commands to generate.