Modified fctnl proto
[deliverable/binutils-gdb.git] / bfd / targets.c
index bbcdd5160dbffa5a23390f15dfd5c0fc98718282..4a0236e8e89ad000d6998284a3ab69e6cf318f29 100644 (file)
@@ -19,16 +19,266 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* $Id$ */
 
 
-/* This -*- C -*- source file will someday be machine-generated */
-
-/*** Defines the target vector through which operations dispatch */
-#include "sysdep.h"
+#include <sysdep.h>
 #include "bfd.h"
 #include "libbfd.h"
 
+/*doc*
+@section Targets
+Each port of BFD to a different machine requries the creation of a
+target back end. All the back end provides to the root part of bfd is
+a structure containing pointers to functions which perform certain low
+level operations on files. BFD translates the applications's requests
+through a pointer into calls to the back end routines.
+
+When a file is opened with @code{bfd_openr}, its format and target are
+unknown. BFD uses various mechanisms to determine how to interpret the
+file. The operatios performed are:
+@itemize @bullet
+@item
+First a bfd is created by calling the internal routine
+@code{new_bfd}, then @code{bfd_find_target} is called with the target
+string supplied to @code{bfd_openr} and the new bfd pointer. 
+@item
+If a null target string was provided to
+@code{bfd_find_target}, it looks up the environment variable
+@code{GNUTARGET} and uses that as the target string. 
+@item
+If the target string is still NULL, or the target string
+is @code{default}, then the first item in the target vector is used as
+the target type. @xref{targets}.
+@item
+Otherwise, the elements in the target vector are
+inspected one by one, until a match on target name is found. When
+found, that is used.
+@item 
+Otherwise the error @code{invalid_target} is returned to
+@code{bfd_openr}.
+@item 
+@code{bfd_openr} attempts to open the file using
+@code{bfd_open_file}, and returns the bfd.
+@end itemize
+Once the bfd has been opened and the target selected, the file format
+may be determined. This is done by calling @code{bfd_check_format} on
+the bfd with a suggested format. The routine returns @code{true} when
+the application guesses right.
+*/
+
+
+/*proto* bfd_target
+@node bfd_target
+@subsection bfd_target
+This structure contains everything that BFD knows about a target.
+It includes things like its byte order, name, what routines to call
+to do various operations, etc.   
+
+Every BFD points to a target structure with its "xvec" member. 
+
+
+Shortcut for declaring fields which are prototyped function pointers,
+while avoiding anguish on compilers that don't support protos.
+
+$#define SDEF(ret, name, arglist) \
+$                PROTO(ret,(*name),arglist)
+$#define SDEF_FMT(ret, name, arglist) \
+$                PROTO(ret,(*name[bfd_type_end]),arglist)
+
+These macros are used to dispatch to functions through the bfd_target
+vector. They are used in a number of macros further down in bfd.h, and
+are also used when calling various routines by hand inside the bfd
+implementation.  The "arglist" argument must be parenthesized; it
+contains all the arguments to the called function.
+
+$#define BFD_SEND(bfd, message, arglist) \
+$               ((*((bfd)->xvec->message)) arglist)
+
+For operations which index on the bfd format 
+
+$#define BFD_SEND_FMT(bfd, message, arglist) \
+$            (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
+
+This is the struct which defines the type of BFD this is.  The
+"xvec" member of the struct bfd itself points here.  Each module
+that implements access to a different target under BFD, defines
+one of these.
+
+FIXME, these names should be rationalised with the names of the
+entry points which call them. Too bad we can't have one macro to
+define them both! 
+
+*+++
+
+$typedef struct bfd_target
+${
+
+identifies the kind of target, eg SunOS4, Ultrix, etc 
+
+$  char *name;
+
+The "flavour" of a back end is a general indication about the contents
+of a file.
+
+$  enum target_flavour_enum {
+$    bfd_target_aout_flavour_enum,
+$    bfd_target_coff_flavour_enum,
+$    bfd_target_ieee_flavour_enum,
+$    bfd_target_oasys_flavour_enum,
+$    bfd_target_srec_flavour_enum} flavour;
+
+The order of bytes within the data area of a file.
+
+$  boolean byteorder_big_p;
+
+The order of bytes within the header parts of a file.
+
+$  boolean header_byteorder_big_p;
+
+This is a mask of all the flags which an executable may have set -
+from the set @code{NO_FLAGS}, @code{HAS_RELOC}, ...@code{D_PAGED}.
+
+$  flagword object_flags;       
+
+This is a mask of all the flags which a section may have set - from
+the set @code{SEC_NO_FLAGS}, @code{SEC_ALLOC}, ...@code{SET_NEVER_LOAD}.
+
+$  flagword section_flags;
+
+The pad character for filenames within an archive header.
+
+$  char ar_pad_char;            
+
+The maximum number of characters in an archive header.
+
+$ unsigned short ar_max_namelen;
+
+The minimum alignment restriction for any section.
+
+$  unsigned int align_power_min;
+
+Entries for byte swapping for data. These are different to the other
+entry points, since they don't take bfd as first arg.  Certain other handlers
+could do the same.
+
+$  SDEF (bfd_64_type,   bfd_getx64, (bfd_byte *));
+$  SDEF (void,          bfd_putx64, (bfd_64_type, bfd_byte *));
+$  SDEF (unsigned int,  bfd_getx32, (bfd_byte *));
+$  SDEF (void,          bfd_putx32, (unsigned long, bfd_byte *));
+$  SDEF (unsigned int,  bfd_getx16, (bfd_byte *));
+$  SDEF (void,          bfd_putx16, (int, bfd_byte *));
+
+Byte swapping for the headers
+
+$  SDEF (bfd_64_type,   bfd_h_getx64, (bfd_byte *));
+$  SDEF (void,          bfd_h_putx64, (bfd_64_type, bfd_byte *));
+$  SDEF (unsigned int,  bfd_h_getx32, (bfd_byte *));
+$  SDEF (void,          bfd_h_putx32, (unsigned long, bfd_byte *));
+$  SDEF (unsigned int,  bfd_h_getx16, (bfd_byte *));
+$  SDEF (void,          bfd_h_putx16, (int, bfd_byte *));
+
+Format dependent routines, these turn into vectors of entry points
+within the target vector structure; one for each format to check.
+
+Check the format of a file being read.  Return bfd_target * or zero. 
+
+$  SDEF_FMT (struct bfd_target *, _bfd_check_format, (bfd *));
+
+Set the format of a file being written.  
+
+$  SDEF_FMT (boolean,            _bfd_set_format, (bfd *));
+
+Write cached information into a file being written, at bfd_close. 
+
+$  SDEF_FMT (boolean,            _bfd_write_contents, (bfd *));
+
+The following functions are defined in @code{JUMP_TABLE}. The idea is
+that the back end writer of @code{foo} names all the routines
+@code{foo_}@var{entry_point}, @code{JUMP_TABLE} will built the entries
+in this structure in the right order.
+
+Core file entry points
+
+$  SDEF (char *, _core_file_failing_command, (bfd *));
+$  SDEF (int,    _core_file_failing_signal, (bfd *));
+$  SDEF (boolean, _core_file_matches_executable_p, (bfd *, bfd *));
+
+Archive entry points
+
+$ SDEF (boolean, _bfd_slurp_armap, (bfd *));
+$ SDEF (boolean, _bfd_slurp_extended_name_table, (bfd *));
+$ SDEF (void,   _bfd_truncate_arname, (bfd *, CONST char *, char *));
+$ SDEF (boolean, write_armap, (bfd *arch, 
+$                              unsigned int elength,
+$                              struct orl *map,
+$                              int orl_count, 
+$                              int stridx));
+
+Standard stuff.
+
+$  SDEF (boolean, _close_and_cleanup, (bfd *));
+$  SDEF (boolean, _bfd_set_section_contents, (bfd *, sec_ptr, PTR,
+$                                            file_ptr, bfd_size_type));
+$  SDEF (boolean, _bfd_get_section_contents, (bfd *, sec_ptr, PTR, 
+$                                            file_ptr, bfd_size_type));
+$  SDEF (boolean, _new_section_hook, (bfd *, sec_ptr));
+
+Symbols and reloctions
+
+$ SDEF (unsigned int, _get_symtab_upper_bound, (bfd *));
+$  SDEF (unsigned int, _bfd_canonicalize_symtab,
+$           (bfd *, struct symbol_cache_entry **));
+$  SDEF (unsigned int, _get_reloc_upper_bound, (bfd *, sec_ptr));
+$  SDEF (unsigned int, _bfd_canonicalize_reloc, (bfd *, sec_ptr, arelent **,
+$                                               struct symbol_cache_entry**));
+$  SDEF (struct symbol_cache_entry  *, _bfd_make_empty_symbol, (bfd *));
+$  SDEF (void,     _bfd_print_symbol, (bfd *, PTR, struct symbol_cache_entry  *,
+$                                      bfd_print_symbol_enum_type));
+$#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e))
+$  SDEF (alent *,   _get_lineno, (bfd *, struct symbol_cache_entry  *));
+$
+$  SDEF (boolean,   _bfd_set_arch_mach, (bfd *, enum bfd_architecture,
+$                                       unsigned long));
+$
+$  SDEF (bfd *,  openr_next_archived_file, (bfd *arch, bfd *prev));
+$  SDEF (boolean, _bfd_find_nearest_line,
+$        (bfd *abfd, struct sec  *section,
+$         struct symbol_cache_entry  **symbols,bfd_vma offset,
+$        CONST char **file, CONST char **func, unsigned int *line));
+$  SDEF (int,    _bfd_stat_arch_elt, (bfd *, struct stat *));
+$
+$  SDEF (int,    _bfd_sizeof_headers, (bfd *, boolean));
+$
+$  SDEF (void, _bfd_debug_info_start, (bfd *));
+$  SDEF (void, _bfd_debug_info_end, (bfd *));
+$  SDEF (void, _bfd_debug_info_accumulate, (bfd *, struct sec  *));
+
+Special entry points for gdb to swap in coff symbol table parts
+
+$  SDEF(void, _bfd_coff_swap_aux_in,(
+$       bfd            *abfd ,
+$       PTR             ext,
+$       int             type,
+$       int             class ,
+$       PTR             in));
+$
+$  SDEF(void, _bfd_coff_swap_sym_in,(
+$       bfd            *abfd ,
+$       PTR             ext,
+$       PTR             in));
+$
+$  SDEF(void, _bfd_coff_swap_lineno_in,  (
+$       bfd            *abfd,
+$       PTR            ext,
+$       PTR             in));
+$
+$} bfd_target;
+
+*---
+
+*/
 extern bfd_target ecoff_little_vec;
 extern bfd_target ecoff_big_vec;
 extern bfd_target sunos_big_vec;
+extern bfd_target demo_64_vec;
 extern bfd_target srec_vec;
 extern bfd_target b_out_vec_little_host;
 extern bfd_target b_out_vec_big_host;
@@ -38,79 +288,187 @@ extern bfd_target ieee_vec;
 extern bfd_target oasys_vec;
 extern bfd_target m88k_bcs_vec;
 extern bfd_target m68kcoff_vec;
+extern bfd_target i386coff_vec;
+
+#ifdef DEFAULT_VECTOR
+extern bfd_target DEFAULT_VECTOR;
+#endif
 
 #ifdef GNU960
-#define ICOFF_LITTLE_VEC       icoff_little_vec
-#define ICOFF_BIG_VEC          icoff_big_vec
-#define B_OUT_VEC_LITTLE_HOST  b_out_vec_little_host
-#define B_OUT_VEC_BIG_HOST     b_out_vec_big_host
+#define ICOFF_LITTLE_VEC        icoff_little_vec
+#define ICOFF_BIG_VEC           icoff_big_vec
+#define B_OUT_VEC_LITTLE_HOST   b_out_vec_little_host
+#define B_OUT_VEC_BIG_HOST      b_out_vec_big_host
 #endif /* GNU960 */
 
 #ifndef RESTRICTED
-#define ECOFF_LITTLE_VEC       ecoff_little_vec
-#define ECOFF_BIG_VEC          ecoff_big_vec
-#define ICOFF_LITTLE_VEC       icoff_little_vec
-#define ICOFF_BIG_VEC          icoff_big_vec
-#define B_OUT_VEC_LITTLE_HOST  b_out_vec_little_host
-#define B_OUT_VEC_BIG_HOST     b_out_vec_big_host
-#define SUNOS_VEC_BIG_HOST     sunos_big_vec
-#define OASYS_VEC              oasys_vec
-#define IEEE_VEC               ieee_vec
-#define M88K_BCS_VEC           m88k_bcs_vec
-#define SREC_VEC               srec_vec
-#define M68KCOFF_VEC           m68kcoff_vec
+#define ECOFF_LITTLE_VEC        ecoff_little_vec
+#define ECOFF_BIG_VEC           ecoff_big_vec
+#define ICOFF_LITTLE_VEC        icoff_little_vec
+#define ICOFF_BIG_VEC           icoff_big_vec
+#define ZB_OUT_VEC_LITTLE_HOST  b_out_vec_little_host
+#define ZB_OUT_VEC_BIG_HOST     b_out_vec_big_host
+#define SUNOS_VEC_BIG_HOST      sunos_big_vec
+#define DEMO_64_VEC             demo_64_vec
+#define OASYS_VEC               oasys_vec
+#define IEEE_VEC                ieee_vec
+#define M88K_BCS_VEC            m88k_bcs_vec
+#define SREC_VEC                srec_vec
+#define M68KCOFF_VEC            m68kcoff_vec
+#define I386COFF_VEC            i386coff_vec
 #endif
 bfd_target *target_vector[] = {
 
 #ifdef DEFAULT_VECTOR
-       &DEFAULT_VECTOR,
+        &DEFAULT_VECTOR,
 #endif /* DEFAULT_VECTOR */
 
+#ifdef  I386COFF_VEC
+        &I386COFF_VEC,
+#endif  /* I386COFF_VEC */
+
 #ifdef ECOFF_LITTLE_VEC
-       &ECOFF_LITTLE_VEC,
+        &ECOFF_LITTLE_VEC,
 #endif
 
 #ifdef ECOFF_BIG_VEC
-       &ECOFF_BIG_VEC,
-#endif
-#ifdef M68KCOFF_VEC
-       &M68KCOFF_VEC,
+        &ECOFF_BIG_VEC,
 #endif
 #ifdef IEEE_VEC
-       &IEEE_VEC,
+        &IEEE_VEC,
 #endif /* IEEE_VEC */
 
 #ifdef OASYS_VEC
-       &OASYS_VEC,
+        &OASYS_VEC,
 #endif /* OASYS_VEC */
 
 #ifdef SUNOS_VEC_BIG_HOST
-       &SUNOS_VEC_BIG_HOST,
+        &SUNOS_VEC_BIG_HOST,
 #endif /* SUNOS_BIG_VEC */
 
+
+#ifdef HOST_64_BIT
+#ifdef DEMO_64_VEC
+        &DEMO_64_VEC,
+#endif
+#endif
+
 #ifdef M88K_BCS_VEC
-       &M88K_BCS_VEC,
+        &M88K_BCS_VEC,
 #endif /* M88K_BCS_VEC */
 
 #ifdef SREC_VEC
-       &SREC_VEC,
+        &SREC_VEC,
 #endif /* SREC_VEC */
-       
+        
 #ifdef ICOFF_LITTLE_VEC
-       &ICOFF_LITTLE_VEC,
+        &ICOFF_LITTLE_VEC,
 #endif /* ICOFF_LITTLE_VEC */
 
 #ifdef ICOFF_BIG_VEC
-       &ICOFF_BIG_VEC,
+        &ICOFF_BIG_VEC,
 #endif /* ICOFF_BIG_VEC */
 
 #ifdef B_OUT_VEC_LITTLE_HOST
-       &B_OUT_VEC_LITTLE_HOST,
+        &B_OUT_VEC_LITTLE_HOST,
 #endif /* B_OUT_VEC_LITTLE_HOST */
 
 #ifdef B_OUT_VEC_BIG_HOST
-       &B_OUT_VEC_BIG_HOST,
+        &B_OUT_VEC_BIG_HOST,
 #endif /* B_OUT_VEC_BIG_HOST */
 
-       NULL, /* end of list marker */
+#ifdef  M68KCOFF_VEC
+        &M68KCOFF_VEC,
+#endif  /* M68KCOFF_VEC */
+
+        NULL, /* end of list marker */
 };
+
+
+/* default_vector[0] contains either the address of the default vector,
+   if there is one, or zero if there isn't.  */
+
+bfd_target *default_vector[] = {
+#ifdef DEFAULT_VECTOR
+        &DEFAULT_VECTOR,
+#endif
+        0,
+};
+
+
+
+
+/*proto*
+*i bfd_find_target
+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.  
+*; PROTO(bfd_target *, bfd_find_target,(CONST char *, bfd *));
+*-*/
+
+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;
+}
+
+
+/*proto*
+*i bfd_target_list
+This function returns a freshly malloced NULL-terminated vector of the
+names of all the valid bfd targets. Do not modify the names 
+*; PROTO(CONST char **,bfd_target_list,());
+
+*-*/
+
+CONST char **
+DEFUN_VOID(bfd_target_list)
+{
+  int vec_length= 0;
+  bfd_target **target;
+CONST  char **name_list, **name_ptr;
+
+  for (target = &target_vector[0]; *target != NULL; target++)
+    vec_length++;
+
+  name_ptr = 
+    name_list = (CONST 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;
+}
This page took 0.027834 seconds and 4 git commands to generate.