Now full of documentation. Yum Yum.
[deliverable/binutils-gdb.git] / bfd / bfd.c
index b05ec9cedca6d78cedd7aa234837d6f93b0e642c..eb435c85da7eddfe70e750e4ea5d3f0c2f30bdb0 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1,11 +1,3 @@
-                          /* -*- C -*- */
-
-/*** bfd -- binary file diddling routines by Gumby Wallace of Cygnus Support.
-           Every definition in this file should be exported and declared
-           in bfd.h.  If you don't want it to be user-visible, put it in
-           libbfd.c!
-*/
-
 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Diddler.
@@ -24,55 +16,198 @@ You should have received a copy of the GNU General Public License
 along with BFD; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+
 /* $Id$ */
+
+/*proto*
+@section typedef bfd
+
+Pointers to bfd structs are the cornerstone of any application using
+libbfd. References though the bfd and to data in the bfd give the
+entire bfd functionality.
+
+Finally!  The BFD struct itself.  This contains the major data about
+the file, and contains pointers to the rest of the data.
+
+*+++
+
+$struct _bfd 
+${
+  The filename the application opened the bfd with.
+
+$  CONST char *filename;                
+
+A pointer to the target jump table.
+
+$  struct bfd_target *xvec;
+
+
+To avoid dragging too many header files into every file that
+includes bfd.h, IOSTREAM has been declared as a "char *", and MTIME
+as a "long".  Their correct types, to which they are cast when used,
+are "FILE *" and "time_t".  
+
+The iostream is the result of an fopen on the filename.
+
+$  char *iostream;
+
+Is the file being cached @xref{File Caching}.
+
+$  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.
+
+$  boolean target_defaulted;
+
+The caching routines use these to maintain an LRU list of bfds.
+
+$  struct _bfd *lru_prev, *lru_next;
+
+When a file is closed by the caching routines, it retains the state
+here:
+
+$  file_ptr where;              
+
+and here:
+
+$  boolean opened_once;
+
+$  boolean mtime_set;
+File modified time 
+
+$  long mtime;          
+
+For output files, channel we locked (is this used?).
+
+$int ifd;
+
+The format which belongs to the bfd.
+
+$  bfd_format format;
+
+The direction the bfd was opened with
+
+$  enum bfd_direction {no_direction = 0,
+$                       read_direction = 1,
+$                       write_direction = 2,
+$                       both_direction = 3} direction;
+
+Format_specific flags
+
+$  flagword flags;              
+
+Currently my_archive is tested before adding origin to anything. I
+believe that this can become always an add of origin, with origin set
+to 0 for non archive files.  
+
+$  file_ptr origin;             
+
+Remember when output has begun, to stop strange things happening.
+
+$  boolean output_has_begun;
+
+Pointer to linked list of sections
+
+$  struct sec  *sections;
+
+The number of sections 
+
+$  unsigned int section_count;
+
+Stuff only usefull for object files:
+The start address.
+
+$  bfd_vma start_address;
+Used for input and output
+
+$  unsigned int symcount;
+Symtab for output bfd
+
+$  struct symbol_cache_entry  **outsymbols;             
+
+Architecture of object machine, eg m68k 
+
+$  enum bfd_architecture obj_arch;
+
+Particular machine within arch, e.g. 68010
+
+$  unsigned long obj_machine;
+
+Stuff only usefull for archives:
+
+$  PTR arelt_data;              
+$  struct _bfd *my_archive;     
+$  struct _bfd *next;           
+$  struct _bfd *archive_head;   
+$  boolean has_armap;           
+
+Used by the back end to hold private data.
+
+$  PTR tdata;
+
+Used by the application to hold private data
+
+$  PTR usrdata;
+
+Where all the allocated stuff under this BFD goes 
+
+$  struct obstack memory;
+$};
+
+*---
+
+*/
 #include <sysdep.h>
 #include "bfd.h"
 #include "libbfd.h"
 
+
 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.)  */
+        /* 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.
+        precise semantics); 0 or NULL on error.
     o - Internal errors are documented by the value of bfd_error.
-       If that is system_call_error then check errno.
+        If that is system_call_error then check errno.
     o - The easiest way to report this to the user is to use bfd_perror.
 */
 
 bfd_ec bfd_error = no_error;
 
-char *bfd_errmsgs[] = {        "No error",
-                       "System call error",
-                       "Invalid target",
-                       "File in wrong format",
-                       "Invalid operation",
-                       "Memory exhausted",
-                       "No symbols",
-                       "No relocation info",
-                       "No more archived files",
-                       "Malformed archive",
-                       "Symbol not found",
-                       "File format not recognized",
-                       "File format is ambiguous",
-                       "Section has no contents",
-                       "Nonrepresentable section on output",
-                       "#<Invalid error code>"
-                      };
+char *bfd_errmsgs[] = { "No error",
+                        "System call error",
+                        "Invalid target",
+                        "File in wrong format",
+                        "Invalid operation",
+                        "Memory exhausted",
+                        "No symbols",
+                        "No relocation info",
+                        "No more archived files",
+                        "Malformed archive",
+                        "Symbol not found",
+                        "File format not recognized",
+                        "File format is ambiguous",
+                        "Section has no contents",
+                        "Nonrepresentable section on output",
+                        "#<Invalid error code>"
+                       };
 
 static 
 void 
 DEFUN(bfd_nonrepresentable_section,(abfd, name),
-        CONST  bfd * CONST abfd AND
-        CONST  char * CONST 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);
+         abfd->filename, 
+         abfd->xvec->name,
+         name);
   exit(1);
 }
 
@@ -90,7 +225,7 @@ strerror (code)
   extern char *sys_errlist[];
 
   return (((code < 0) || (code >= sys_nerr)) ? "(unknown error)" :
-         sys_errlist [code]);
+          sys_errlist [code]);
 }
 #endif /* not ANSI_LIBRARIES */
 
@@ -127,7 +262,7 @@ DEFUN(bfd_perror,(message),
       CONST char *message)
 {
   if (bfd_error == system_call_error)
-    perror((char *)message);           /* must be system error then... */
+    perror((char *)message);            /* must be system error then... */
   else {
     if (message == NULL || *message == '\0')
       fprintf (stderr, "%s\n", bfd_errmsg (bfd_error));
@@ -136,415 +271,11 @@ DEFUN(bfd_perror,(message),
   }
 }
 
-/* for error messages */
-char *
-bfd_format_string (format)
-     bfd_format format;
-{
-  if (((int)format <(int) bfd_unknown) || ((int)format >=(int) bfd_type_end)) return "invalid";
-  
-  switch (format) {
-  case bfd_object: return "object"; /* linker/assember/compiler output */
-  case bfd_archive: return "archive"; /* object archive file */
-  case bfd_core: return "core";        /* core dump */
-  default: return "unknown";
-  }
-}
-\f
-/** Target configurations */
-
-extern bfd_target *target_vector[];
-extern bfd_target *default_vector[];
-
-/* Returns a pointer to the transfer vector for the object target
-   named target_name.  If target_name is NULL, chooses the one in the
-   environment variable GNUTARGET; if that is null or not defined then
-   the first entry in the target list is chosen.  Passing in the
-   string "default" or setting the environment variable to "default"
-   will cause the first entry in the target list to be returned,
-   and "target_defaulted" will be set in the bfd.  This causes
-   bfd_check_format to loop over all the targets to find the one
-   that matches the file being read.  */
-
-bfd_target *
-DEFUN(bfd_find_target,(target_name, abfd),
-      CONST char *target_name AND
-      bfd *abfd)
-{
-  bfd_target **target;
-  extern char *getenv ();
-  CONST char *targname = (target_name ? target_name : getenv ("GNUTARGET"));
-
-  /* This is safe; the vector cannot be null */
-  if (targname == NULL || !strcmp (targname, "default")) {
-    abfd->target_defaulted = true;
-    return abfd->xvec = target_vector[0];
-  }
-
-  abfd->target_defaulted = false;
-
-  for (target = &target_vector[0]; *target != NULL; target++) {
-    if (!strcmp (targname, (*target)->name))
-      return abfd->xvec = *target;
-  }
-
-  bfd_error = invalid_target;
-  return NULL;
-}
-
-
-/* Returns a freshly-consed, NULL-terminated vector of the names of all the
-   valid bfd targets.  Do not modify the names */
-
-char **
-bfd_target_list ()
-{
-  int vec_length= 0;
-  bfd_target **target;
-  char **name_list, **name_ptr;
-
-  for (target = &target_vector[0]; *target != NULL; target++)
-    vec_length++;
-
-  name_ptr = name_list = (char **) zalloc ((vec_length + 1) * sizeof (char **));
-
-  if (name_list == NULL) {
-    bfd_error = no_memory;
-    return NULL;
-  }
-
-  for (target = &target_vector[0]; *target != NULL; target++)
-    *(name_ptr++) = (*target)->name;
-
-  return name_list;
-}
-
-/* Init a bfd for read of the proper format.  If the target was unspecified,
-   search all the possible targets.  */
-
-boolean
-DEFUN(bfd_check_format,(abfd, format),
-      bfd *abfd AND
-      bfd_format format)
-{
-  bfd_target **target, *save_targ, *right_targ;
-  int match_count;
-
-  if (!bfd_read_p (abfd) ||
-      ((int)(abfd->format) < (int)bfd_unknown) ||
-      ((int)(abfd->format) >= (int)bfd_type_end)) {
-    bfd_error = invalid_operation;
-    return false;
-  }
-
-  if (abfd->format != bfd_unknown)
-    return (abfd->format == format)? true: false;
-
-  /* presume the answer is yes */
-  abfd->format = format;
-
-  /* If the target type was explicitly specified, just check that target.  */
-
-  if (!abfd->target_defaulted) {
-    bfd_seek (abfd, (file_ptr)0, SEEK_SET);    /* rewind! */
-
-    right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
-    if (right_targ) {
-      abfd->xvec = right_targ;         /* Set the target as returned */
-      return true;                     /* File position has moved, BTW */
-    }
-    return false;                      /* Specified target is not right */
-  }
-
-  /* Since the target type was defaulted, check them 
-     all in the hope that one will be uniquely recognized.  */
-
-  save_targ = abfd->xvec;
-  match_count = 0;
-  right_targ = 0;
-
-  for (target = target_vector; *target != NULL; target++) {
-    bfd_target *temp;
-
-    abfd->xvec = *target;      /* Change BFD's target temporarily */
-    bfd_seek (abfd, (file_ptr)0, SEEK_SET);
-    temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
-    if (temp) {                                /* This format checks out as ok! */
-      right_targ = temp;
-      match_count++;
-      /* If this is the default target, accept it, even if other targets
-        might match.  People who want those other targets have to set 
-        the GNUTARGET variable.  */
-      if (temp == default_vector[0])
-       break;
-#ifdef GNU960
-      /* Big- and little-endian b.out archives look the same, but it doesn't
-       * matter: there is no difference in their headers, and member file byte
-       * orders will (I hope) be handled appropriately by bfd.  Ditto for big
-       * and little coff archives.  And the 4 coff/b.out object formats are
-       * unambiguous.  So accept the first match we find.
-       */
-      break;
-#endif
-    }
-  }
-
-  if (match_count == 1) {
-    abfd->xvec = right_targ;           /* Change BFD's target permanently */
-    return true;                       /* File position has moved, BTW */
-  }
-
-  abfd->xvec = save_targ;              /* Restore original target type */
-  abfd->format = bfd_unknown;          /* Restore original format */
-  bfd_error = ((match_count == 0) ? file_not_recognized :
-              file_ambiguously_recognized);
-  return false;
-}
-
-boolean
-DEFUN(bfd_set_format,(abfd, format),
-      bfd *abfd AND
-      bfd_format format)
-{
-
-  if (bfd_read_p (abfd) ||
-      ((int)abfd->format < (int)bfd_unknown) ||
-      ((int)abfd->format >= (int)bfd_type_end)) {
-    bfd_error = invalid_operation;
-    return false;
-  }
-
-  if (abfd->format != bfd_unknown) return (abfd->format == format) ? true:false;
-
-  /* presume the answer is yes */
-  abfd->format = format;
-
-  if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) {
-    abfd->format = bfd_unknown;
-    return false;
-  }
-
-  return true;
-}
-\f
-/* Hack object and core file sections */
-
-sec_ptr
-DEFUN(bfd_get_section_by_name,(abfd, name),
-      bfd *abfd AND
-      CONST char *name)
-{
-  asection *sect;
-  
-  for (sect = abfd->sections; sect != NULL; sect = sect->next)
-    if (!strcmp (sect->name, name)) return sect;
-  return NULL;
-}
-
-/* If you try to create a section with a name which is already in use,
-   returns the old section by that name instead. */
-sec_ptr
-DEFUN(bfd_make_section,(abfd, name),
-      bfd *abfd AND
-      CONST char *CONST name)
-{
-  asection *newsect;  
-  asection **  prev = &abfd->sections;
-  asection * sect = abfd->sections;
-  
-  if (abfd->output_has_begun) {
-    bfd_error = invalid_operation;
-    return NULL;
-  }
-
-  while (sect) {
-    if (!strcmp(sect->name, name)) return sect;
-    prev = &sect->next;
-    sect = sect->next;
-  }
-
-  newsect = (asection *) bfd_zalloc(abfd, sizeof (asection));
-  if (newsect == NULL) {
-    bfd_error = no_memory;
-    return NULL;
-  }
-
-  newsect->name = name;
-  newsect->index = abfd->section_count++;
-  newsect->flags = SEC_NO_FLAGS;
-
-  newsect->userdata = 0;
-  newsect->next = (asection *)NULL;
-  newsect->relocation = (arelent *)NULL;
-  newsect->reloc_count = 0;
-  newsect->line_filepos =0;
-
-  if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true) {
-    free (newsect);
-    return NULL;
-  }
-
-  *prev = newsect;
-  return newsect;
-}
-
-/* Call operation on each section.  Operation gets three args: the bfd,
-   the section, and a void * pointer (whatever the user supplied). */
-
-/* This is attractive except that without lexical closures its use is hard
-   to make reentrant. */
-/*VARARGS2*/
-void
-bfd_map_over_sections (abfd, operation, user_storage)
-     bfd *abfd;
-     void (*operation)();
-     PTR user_storage;
-{
-  asection *sect;
-  int i = 0;
-  
-  for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
-    (*operation) (abfd, sect, user_storage);
-
-  if (i != abfd->section_count)                /* Debugging */
-    abort();
-}
-
-boolean
-bfd_set_section_flags (abfd, section, flags)
-     bfd *abfd;
-     sec_ptr section;
-     flagword flags;
-{
-  if ((flags & bfd_applicable_section_flags (abfd)) != flags) {
-    bfd_error = invalid_operation;
-    return false;
-  }
-
-   section->flags = flags;
-return true;
-}
-
-
-boolean
-bfd_set_section_size (abfd, ptr, val)
-     bfd *abfd;
-     sec_ptr ptr;
-     unsigned long val;
-{
-  /* Once you've started writing to any section you cannot create or change
-     the size of any others. */
-
-  if (abfd->output_has_begun) {
-    bfd_error = invalid_operation;
-    return false;
-  }
-
-  ptr->size = val;
-  
-  return true;
-}
-
-boolean
-DEFUN(bfd_set_section_contents,(abfd, section, location, offset, count),
-      bfd *abfd AND
-      sec_ptr section AND
-      PTR location AND
-      file_ptr offset AND
-      bfd_size_type count)
-{
-       if (!(bfd_get_section_flags(abfd, section) &
-             SEC_HAS_CONTENTS)) {
-               bfd_error = no_contents;
-               return(false);
-       } /* if section has no contents */
-
-  if (BFD_SEND (abfd, _bfd_set_section_contents,
-           (abfd, section, location, offset, count))) {
-    abfd->output_has_begun = true;
-    return true;
-  }
-
-  return false;
-}
-
-boolean
-DEFUN(bfd_get_section_contents,(abfd, section, location, offset, count),
-      bfd *abfd AND
-      sec_ptr section AND
-      PTR location AND
-      file_ptr offset AND
-      bfd_size_type count)
-{
-  if (section->flags & SEC_CONSTRUCTOR) {
-    memset(location, 0, (unsigned)count);
-    return true;
-  }
-  else {
-    return  (BFD_SEND (abfd, _bfd_get_section_contents,
-                      (abfd, section, location, offset, count)));
-  }
-}
-
-\f
-/** Some core file info commands */
-
-/* Returns a read-only string explaining what program was running when
-   it failed. */
-
-char *
-bfd_core_file_failing_command (abfd)
-     bfd *abfd;
-{
-  if (abfd->format != bfd_core) {
-    bfd_error = invalid_operation;
-    return NULL;
-  }
-  return BFD_SEND (abfd, _core_file_failing_command, (abfd));
-}
-
-int
-bfd_core_file_failing_signal (abfd)
-     bfd *abfd;
-{
-  if (abfd->format != bfd_core) {
-    bfd_error = invalid_operation;
-    return 0;
-  }
-  return BFD_SEND (abfd, _core_file_failing_signal, (abfd));
-}
-
-boolean
-core_file_matches_executable_p (core_bfd, exec_bfd)
-     bfd *core_bfd, *exec_bfd;
-{
-  if ((core_bfd->format != bfd_core) || (exec_bfd->format != bfd_object)) {
-    bfd_error = wrong_format;
-    return false;
-  }
-
-  return BFD_SEND (core_bfd, _core_file_matches_executable_p, (core_bfd, exec_bfd));
-}
-\f
\f
 /** Symbols */
 
-boolean
-bfd_set_symtab (abfd, location, symcount)
-     bfd *abfd;
-     asymbol **location;
-     unsigned int symcount;
-{
-  if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) {
-    bfd_error = invalid_operation;
-    return false;
-  }
-
-  bfd_get_outsymbols (abfd) = location;
-  bfd_get_symcount (abfd) = symcount;
-  return true;
-}
-
 /* returns the number of octets of storage required */
+
 unsigned int
 get_reloc_upper_bound (abfd, asect)
      bfd *abfd;
@@ -573,32 +304,6 @@ bfd_canonicalize_reloc (abfd, asect, location, symbols)
   return BFD_SEND (abfd, _bfd_canonicalize_reloc, (abfd, asect, location, symbols));
 }
 
-void
-bfd_print_symbol_vandf(file, symbol)
-PTR file;
-asymbol *symbol;
-{
-  flagword type = symbol->flags;
-  if (symbol->section != (asection *)NULL)
-      {
-
-       fprintf_vma(file, symbol->value+symbol->section->vma);
-      }
-  else 
-      {
-       fprintf_vma(file, symbol->value);
-      }
-  fprintf(file," %c%c%c%c%c%c%c",
-         (type & BSF_LOCAL)  ? 'l':' ',
-         (type & BSF_GLOBAL) ? 'g' : ' ',
-         (type & BSF_IMPORT) ? 'i' : ' ',
-         (type & BSF_EXPORT) ? 'e' : ' ',
-         (type & BSF_UNDEFINED) ? 'u' : ' ',
-         (type & BSF_FORT_COMM) ? 'c' : ' ',
-         (type & BSF_DEBUGGING) ? 'd' :' ');
-
-}
-
 
 boolean
 bfd_set_file_flags (abfd, flags)
@@ -635,250 +340,6 @@ bfd_set_reloc (ignore_abfd, asect, location, count)
   asect->orelocation  = location;
   asect->reloc_count = count;
 }
-/*
-If an output_bfd is supplied to this function the generated image
-will be relocatable, the relocations are copied to the output file
-after they have been changed to reflect the new state of the world.
-There are two ways of reflecting the results of partial linkage in an
-output file; by modifying the output data in place, and by modifying
-the relocation record. Some native formats (eg basic a.out and basic
-coff) have no way of specifying an addend in the relocation type, so
-the addend has to go in the output data.  This is no big deal since in
-these formats the output data slot will always be big enough for the
-addend. Complex reloc types with addends were invented to solve just
-this problem.
-*/
-
-bfd_reloc_status_enum_type
-DEFUN(bfd_perform_relocation,(abfd,
-                             reloc_entry,
-                             data,
-                             input_section,
-                             output_bfd),
-      bfd *abfd AND
-      arelent *reloc_entry AND
-      PTR data AND
-      asection *input_section AND
-      bfd *output_bfd)
-{
-  bfd_vma relocation;
-  bfd_reloc_status_enum_type flag = bfd_reloc_ok;
-  bfd_vma addr = reloc_entry->address ;
-  bfd_vma output_base = 0;
-  reloc_howto_type *howto = reloc_entry->howto;
-  asection *reloc_target_output_section;
-  asection *reloc_target_input_section;
-  asymbol *symbol;
-
-  if (reloc_entry->sym_ptr_ptr) {
-    symbol = *( reloc_entry->sym_ptr_ptr);
-    if ((symbol->flags & BSF_UNDEFINED) && output_bfd == (bfd *)NULL) {
-      flag = bfd_reloc_undefined;
-    }
-  }
-  else {
-    symbol = (asymbol*)NULL;
-  }
-
-  if (howto->special_function){
-    bfd_reloc_status_enum_type cont;
-    cont = howto->special_function(abfd,
-                                  reloc_entry,
-                                  symbol,
-                                  data,
-                                  input_section);
-    if (cont != bfd_reloc_continue) return cont;
-  }
-
-  /* 
-    Work out which section the relocation is targetted at and the
-    initial relocation command value.
-    */
-
-
-  if (symbol != (asymbol *)NULL){
-    if (symbol->flags & BSF_FORT_COMM) {
-      relocation = 0;
-    }
-    else {
-      relocation = symbol->value;
-    }
-    if (symbol->section != (asection *)NULL)
-       {
-         reloc_target_input_section = symbol->section;
-       }
-    else {
-      reloc_target_input_section = (asection *)NULL;
-    }
-  }
-  else if (reloc_entry->section != (asection *)NULL)
-      {
-       relocation = 0;
-       reloc_target_input_section = reloc_entry->section;
-      }
-  else {
-    relocation = 0;
-    reloc_target_input_section = (asection *)NULL;
-  }
-
-
-  if (reloc_target_input_section != (asection *)NULL) {
-
-    reloc_target_output_section =
-      reloc_target_input_section->output_section;
-
-    if (output_bfd && howto->partial_inplace==false) {
-      output_base = 0;
-    }
-    else {
-      output_base = reloc_target_output_section->vma;
-
-    }
-
-    relocation += output_base +   reloc_target_input_section->output_offset;
-  }
-
-  relocation += reloc_entry->addend ;
-
-
-  if(reloc_entry->address > (bfd_vma)(input_section->size)) 
-      {
-       return bfd_reloc_outofrange;
-      }
-         
-
-  if (howto->pc_relative == true)
-      {
-       /*
-         Anything which started out as pc relative should end up that
-         way too. 
-
-         There are two ways we can see a pcrel instruction. Sometimes
-         the pcrel displacement has been partially calculated, it
-         includes the distance from the start of the section to the
-         instruction in it (eg sun3), and sometimes the field is
-         totally blank - eg m88kbcs.
-         */
-
-       
-       relocation -= 
-         output_base +   input_section->output_offset;
-
-       if (howto->pcrel_offset == true) {
-         relocation -= reloc_entry->address;
-       }
-
-      }
-
-  if (output_bfd!= (bfd *)NULL) {
-    if ( howto->partial_inplace == false)  {
-      /*
-       This is a partial relocation, and we want to apply the relocation
-       to the reloc entry rather than the raw data. Modify the reloc
-       inplace to reflect what we now know.
-       */
-      reloc_entry->addend = relocation  ;
-      reloc_entry->section = reloc_target_input_section;
-      if (reloc_target_input_section != (asection *)NULL) {
-       /* If we know the output section we can forget the symbol */
-       reloc_entry->sym_ptr_ptr = (asymbol**)NULL;
-      }
-      reloc_entry->address += 
-       input_section->output_offset;
-      return flag;
-    }
-    else 
-       {
-         /* This is a partial relocation, but inplace, so modify the
-            reloc record a bit
-            */
-
-       }
-  }
-
-  reloc_entry->addend = 0;
-
-
-  /* 
-    Either we are relocating all the way, or we don't want to apply
-    the relocation to the reloc entry (probably because there isn't
-    any room in the output format to describe addends to relocs)
-    */
-  relocation >>= howto->rightshift;
-
-  /* Shift everything up to where it's going to be used */
-   
-  relocation <<= howto->bitpos;
-
-  /* Wait for the day when all have the mask in them */
-
-  /* What we do:
-     i instruction to be left alone
-     o offset within instruction
-     r relocation offset to apply
-     S src mask
-     D dst mask
-     N ~dst mask
-     A part 1
-     B part 2
-     R result
-     
-     Do this:
-     i i i i i o o o o o       from bfd_get<size>
-     and           S S S S S   to get the size offset we want
-     +   r r r r r r r r r r  to get the final value to place
-     and           D D D D D  to chop to right size
-     -----------------------
-     A A A A A 
-     And this:
-     ...   i i i i i o o o o o from bfd_get<size>
-     and   N N N N N           get instruction
-     -----------------------
-     ...   B B B B B
-     
-     And then:      
-     B B B B B       
-     or             A A A A A     
-     -----------------------
-     R R R R R R R R R R       put into bfd_put<size>
-     */
-
-#define DOIT(x) \
-  x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
-
-    switch (howto->size)
-       {
-       case 0:
-           {
-             char x = bfd_get_8(abfd, (char *)data + addr);
-             DOIT(x);
-             bfd_put_8(abfd,x, (unsigned char *) data + addr);
-           }
-         break;
-
-       case 1:
-           { 
-             short x = bfd_get_16(abfd, (bfd_byte *)data + addr);
-             DOIT(x);
-             bfd_put_16(abfd, x,   (unsigned char *)data + addr);
-           }
-         break;
-       case 2:
-           {
-             long  x = bfd_get_32(abfd, (bfd_byte *) data + addr);
-             DOIT(x);
-             bfd_put_32(abfd,x,    (bfd_byte *)data + addr);
-           }      
-         break;
-       case 3:
-         /* Do nothing */
-         break;
-       default:
-         return bfd_reloc_other;
-       }
-
-  return flag;
-}
 
 void
 bfd_assert(file, line)
@@ -889,6 +350,14 @@ int line;
 }
 
 
+/*proto* bfd_set_start_address
+
+Marks the entry point of an output bfd. Returns @code{true} on
+success, @code{false} otherwise.
+
+*; PROTO(boolean, bfd_set_start_address,(bfd *, bfd_vma));
+*/
+
 boolean
 bfd_set_start_address(abfd, vma)
 bfd *abfd;
@@ -899,19 +368,15 @@ bfd_vma vma;
 }
 
 
-bfd_vma bfd_log2(x)
-bfd_vma x;
-{
-  bfd_vma  result = 0;
-  while ( (bfd_vma)(1<< result) < x)
-    result++;
-  return result;
-}
+/*proto*  bfd_get_mtime
+
+Return cached file modification time (e.g. as read from archive header
+for archive members, or from file system if we have been called
+before); else determine modify time, cache it, and return it.  
 
-/* bfd_get_mtime:  Return cached file modification time (e.g. as read
-   from archive header for archive members, or from file system if we have
-   been called before); else determine modify time, cache it, and
-   return it.  */
+*;PROTO(long, bfd_get_mtime, (bfd *));
+
+*/
 
 long
 bfd_get_mtime (abfd)
@@ -931,3 +396,33 @@ bfd_get_mtime (abfd)
   abfd->mtime = buf.st_mtime;
   return abfd->mtime;
 }
+
+/*proto*
+*i stuff
+*+
+#define bfd_sizeof_headers(abfd, reloc) \
+     BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
+
+#define bfd_find_nearest_line(abfd, section, symbols, offset, filename_ptr, func, line_ptr) \
+     BFD_SEND (abfd, _bfd_find_nearest_line,  (abfd, section, symbols, offset, filename_ptr, func, line_ptr))
+
+#define bfd_debug_info_start(abfd) \
+        BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
+
+#define bfd_debug_info_end(abfd) \
+        BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
+
+#define bfd_debug_info_accumulate(abfd, section) \
+        BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
+
+#define bfd_stat_arch_elt(abfd, stat) \
+        BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
+*-
+
+*/
+
+
+
+
+
+
This page took 0.035444 seconds and 4 git commands to generate.