diff options
author | Steve Chamberlain <steve@cygnus> | 1991-07-04 16:52:56 +0000 |
---|---|---|
committer | Steve Chamberlain <steve@cygnus> | 1991-07-04 16:52:56 +0000 |
commit | 6f715d66ad223169971e668f968db6774c41e52a (patch) | |
tree | ba2ed95455971316e40110307b839a3dccd06cdb /bfd/targets.c | |
parent | 985fca129365a7bfa8e8e91b4d8b57d65f308583 (diff) | |
download | gdb-6f715d66ad223169971e668f968db6774c41e52a.zip gdb-6f715d66ad223169971e668f968db6774c41e52a.tar.gz gdb-6f715d66ad223169971e668f968db6774c41e52a.tar.bz2 |
Now full of documentation. Yum Yum.
Diffstat (limited to 'bfd/targets.c')
-rw-r--r-- | bfd/targets.c | 415 |
1 files changed, 371 insertions, 44 deletions
diff --git a/bfd/targets.c b/bfd/targets.c index 22cda5c..4a0236e 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -19,13 +19,262 @@ 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 "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; @@ -46,93 +295,93 @@ 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 XB_OUT_VEC_LITTLE_HOST b_out_vec_little_host -#define XB_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 +#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 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, + &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, + &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 */ -#ifdef M68KCOFF_VEC - &M68KCOFF_VEC, -#endif /* M68KCOFF_VEC */ +#ifdef M68KCOFF_VEC + &M68KCOFF_VEC, +#endif /* M68KCOFF_VEC */ - NULL, /* end of list marker */ + NULL, /* end of list marker */ }; @@ -141,7 +390,85 @@ bfd_target *target_vector[] = { bfd_target *default_vector[] = { #ifdef DEFAULT_VECTOR - &DEFAULT_VECTOR, + &DEFAULT_VECTOR, #endif - 0, + 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; +} |