X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Ftargets.c;h=57ff69a1646c1a2a21871291023114f00ab5c6a6;hb=c3efeb9248ef37872670060c95454eb44610298b;hp=2036d5b3a620f6a60f297e75e25c62f99b9a8d7f;hpb=7ed4093abcbe329e94888b6ed1c0ead5bea4e7bf;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/targets.c b/bfd/targets.c index 2036d5b3a6..57ff69a164 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -1,125 +1,535 @@ -/* Copyright (C) 1990, 1991 Free Software Foundation, Inc. +/* Generic target-file-type support for the BFD library. + Copyright 1990, 1991, 1992 Free Software Foundation, Inc. + Written by Cygnus Support. -This file is part of BFD, the Binary File Diddler. +This file is part of BFD, the Binary File Descriptor library. -BFD is free software; you can redistribute it and/or modify +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. -BFD is distributed in the hope that it will be useful, +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 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. */ +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ */ +#include "bfd.h" +#include "sysdep.h" +#include "libbfd.h" +/* +SECTION + Targets -/* This -*- C -*- source file will someday be machine-generated */ +DESCRIPTION + 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. -/*** Defines the target vector through which operations dispatch */ -#include -#include "bfd.h" -#include "libbfd.h" + When a file is opened with <>, its format and + target are unknown. BFD uses various mechanisms to determine + how to interpret the file. The operations performed are: + + o First a BFD is created by calling the internal routine + <>, then <> is called with the + target string supplied to <> and the new BFD pointer. + + o If a null target string was provided to <>, + it looks up the environment variable <> and uses + that as the target string. + + o If the target string is still NULL, or the target string is + <>, then the first item in the target vector is used + as the target type, and <> is set to + cause <> to loop through all the targets. + @xref{bfd_target}. @xref{Formats}. + + o 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. + + o Otherwise the error <> is returned to + <>. + + o <> attempts to open the file using + <>, and returns the BFD. + + Once the BFD has been opened and the target selected, the file + format may be determined. This is done by calling + <> on the BFD with a suggested format. + If <> has been set, each possible target + type is tried to see if it recognizes the specified format. The + routine returns <> when the application guesses right. +@menu +@* bfd_target:: +@end menu +*/ + + +/* + +INODE + bfd_target, , Targets, Targets +DOCDD +SUBSECTION + bfd_target + +DESCRIPTION + 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 <> + member. + + These macros are used to dispatch to functions through the + bfd_target vector. They are used in a number of macros further + down in @file{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. + + They make the documentation (more) unpleasant to read, so if + someone wants to fix this and not break the above, please do. + +.#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 + <> member of the struct <> 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 { +. bfd_target_unknown_flavour, +. bfd_target_aout_flavour, +. bfd_target_coff_flavour, +. bfd_target_elf_flavour, +. bfd_target_ieee_flavour, +. bfd_target_oasys_flavour, +. bfd_target_tekhex_flavour, +. bfd_target_srec_flavour, +. bfd_target_hppa_flavour} 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 <>, <>, ...<>. + +. flagword object_flags; + +This is a mask of all the flags which a section may have set - from +the set <>, <>, ...<>. + +. flagword section_flags; + +The character normally found at the front of a symbol +(if any), perhaps _. + +. char symbol_leading_char; + +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. + +. bfd_vma (*bfd_getx64) PARAMS ((bfd_byte *)); +. void (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *)); +. bfd_vma (*bfd_getx32) PARAMS ((bfd_byte *)); +. void (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *)); +. bfd_vma (*bfd_getx16) PARAMS ((bfd_byte *)); +. void (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *)); + +Byte swapping for the headers + +. bfd_vma (*bfd_h_getx64) PARAMS ((bfd_byte *)); +. void (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *)); +. bfd_vma (*bfd_h_getx32) PARAMS ((bfd_byte *)); +. void (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *)); +. bfd_vma (*bfd_h_getx16) PARAMS ((bfd_byte *)); +. void (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *)); + +Format dependent routines: these are 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. + +. struct bfd_target * (*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *)); + +Set the format of a file being written. + +. boolean (*_bfd_set_format[bfd_type_end]) PARAMS ((bfd *)); + +Write cached information into a file being written, at bfd_close. + +. boolean (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *)); + +The following functions are defined in <>. The idea is +that the back end writer of <> names all the routines +<>@var{entry_point}, <> will built the entries +in this structure in the right order. + +Core file entry points + +. char * (*_core_file_failing_command) PARAMS ((bfd *)); +. int (*_core_file_failing_signal) PARAMS ((bfd *)); +. boolean (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *)); +Archive entry points + +. boolean (*_bfd_slurp_armap) PARAMS ((bfd *)); +. boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *)); +. void (*_bfd_truncate_arname) PARAMS ((bfd *, CONST char *, char *)); +. boolean (*write_armap) PARAMS ((bfd *arch, +. unsigned int elength, +. struct orl *map, +. unsigned int orl_count, +. int stridx)); + +Standard stuff. + +. boolean (*_close_and_cleanup) PARAMS ((bfd *)); +. boolean (*_bfd_set_section_contents) PARAMS ((bfd *, sec_ptr, PTR, +. file_ptr, bfd_size_type)); +. boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR, +. file_ptr, bfd_size_type)); +. boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr)); + +Symbols and relocations + +. unsigned int (*_get_symtab_upper_bound) PARAMS ((bfd *)); +. unsigned int (*_bfd_canonicalize_symtab) PARAMS ((bfd *, +. struct symbol_cache_entry **)); +. unsigned int (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr)); +. unsigned int (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, +. struct symbol_cache_entry **)); +. struct symbol_cache_entry * +. (*_bfd_make_empty_symbol) PARAMS ((bfd *)); +. void (*_bfd_print_symbol) PARAMS ((bfd *, PTR, +. struct symbol_cache_entry *, +. bfd_print_symbol_type)); +.#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e)) + +. alent * (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *)); +. +. boolean (*_bfd_set_arch_mach) PARAMS ((bfd *, enum bfd_architecture, +. unsigned long)); +. +. bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev)); +. +. boolean (*_bfd_find_nearest_line) PARAMS ((bfd *abfd, +. struct sec *section, struct symbol_cache_entry **symbols, +. bfd_vma offset, CONST char **file, CONST char **func, +. unsigned int *line)); +. +. int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *)); +. +. int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean)); +. +. void (*_bfd_debug_info_start) PARAMS ((bfd *)); +. void (*_bfd_debug_info_end) PARAMS ((bfd *)); +. void (*_bfd_debug_info_accumulate) PARAMS ((bfd *, struct sec *)); +. +. bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *, +. struct bfd_seclet *, bfd_byte *data)); +. +. boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *, +. struct symbol_cache_entry **)); + +. {* See documentation on reloc types. *} +. CONST struct reloc_howto_struct * +. (*reloc_type_lookup) PARAMS ((bfd *abfd, +. bfd_reloc_code_real_type code)); +. +. {* Back-door to allow format-aware applications to create debug symbols +. while using BFD for everything else. Currently used by the assembler +. when creating COFF files. *} +. asymbol * (*_bfd_make_debug_symbol) PARAMS (( +. bfd *abfd, +. void *ptr, +. unsigned long size)); + +Data for use by back-end routines; e.g., for a.out, includes whether +this particular target maps ZMAGIC files contiguously or with text and +data separated. Could perhaps also be used to eliminate some of the +above COFF-specific fields. + +. PTR backend_data; +.} bfd_target; + +*/ + +/* The default is to define a target_vector containing all the targets. + By setting MINIMIZE=1 on the "make" command line, the user can change this + to a vector containing just DEFAULT_VECTOR and any required + traditional-core-file handler. (This is to save space in the executables.) + The config files can also override the default large vector by giving an + explicit SELECT_VECS macro. */ + +#if MINIMIZE && defined(DEFAULT_VECTOR) && !defined(SELECT_VECS) +#ifdef TRAD_CORE +#define SELECT_VECS &DEFAULT_VECTOR,&trad_core_vec +#else +#ifdef SCO_CORE +#define SELECT_VECS &DEFAULT_VECTOR,&sco_core_vec +#else +#ifdef AIX386_CORE +#define SELECT_VECS &DEFAULT_VECTOR,&aix386_core_vec +#else +#define SELECT_VECS &DEFAULT_VECTOR +#endif +#endif +#endif +#endif + +/* All known xvecs. They are listed a second time below, since + we can't intermix extern's and initializers. */ 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 tekhex_vec; +extern bfd_target a_out_adobe_vec; extern bfd_target b_out_vec_little_host; extern bfd_target b_out_vec_big_host; extern bfd_target icoff_little_vec; extern bfd_target icoff_big_vec; +extern bfd_target elf_little_vec; +extern bfd_target elf_big_vec; extern bfd_target ieee_vec; extern bfd_target oasys_vec; -extern bfd_target m88k_bcs_vec; +extern bfd_target m88kbcs_vec; extern bfd_target m68kcoff_vec; +extern bfd_target i386coff_vec; +extern bfd_target i386aout_vec; +extern bfd_target i386linux_vec; +extern bfd_target a29kcoff_big_vec; +extern bfd_target trad_core_vec; +extern bfd_target sco_core_vec; +extern bfd_target aix386_core_vec; +extern bfd_target rs6000coff_vec; +extern bfd_target h8300coff_vec; +extern bfd_target z8kcoff_vec; +extern bfd_target we32kcoff_vec; +#ifdef hp9000s800 +extern bfd_target hppa_vec; +#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 -#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 +#ifdef DEFAULT_VECTOR +extern bfd_target DEFAULT_VECTOR; #endif + +#ifdef SELECT_VECS + +bfd_target *target_vector[] = { + SELECT_VECS, + 0 +}; + +#else + bfd_target *target_vector[] = { #ifdef DEFAULT_VECTOR &DEFAULT_VECTOR, -#endif /* DEFAULT_VECTOR */ - -#ifdef ECOFF_LITTLE_VEC - &ECOFF_LITTLE_VEC, #endif -#ifdef ECOFF_BIG_VEC - &ECOFF_BIG_VEC, + &i386coff_vec, + &i386aout_vec, + &ecoff_little_vec, + &ecoff_big_vec, + &ieee_vec, +#if 0 + /* We have no oasys tools anymore, so we can't test any of this + anymore. If you want to test the stuff yourself, go ahead... + steve@cygnus.com + Worse, since there is no magic number for archives, there + can annoying target mis-matches. */ + &oasys_vec, #endif -#ifdef M68KCOFF_VEC - &M68KCOFF_VEC, + &sunos_big_vec, +#ifdef HOST_64_BIT + &demo_64_vec, /* Only compiled if host has long-long support */ +#endif + &h8300coff_vec, + &z8kcoff_vec, + &m88kbcs_vec, + &srec_vec, +/* &tekhex_vec,*/ + &icoff_little_vec, + &icoff_big_vec, + &elf_little_vec, + &elf_big_vec, + &a_out_adobe_vec, + &b_out_vec_little_host, + &b_out_vec_big_host, + &m68kcoff_vec, + &a29kcoff_big_vec, + &rs6000coff_vec, +#ifdef hp9000s800 + &hppa_vec, #endif -#ifdef IEEE_VEC - &IEEE_VEC, -#endif /* IEEE_VEC */ + &we32kcoff_vec, -#ifdef OASYS_VEC - &OASYS_VEC, -#endif /* OASYS_VEC */ +#ifdef TRAD_CORE + &trad_core_vec, +#endif +#ifdef SCO_CORE + &sco_core_vec, +#endif +#ifdef AIX386_CORE + &aix386_core_vec, +#endif + NULL, /* end of list marker */ +}; -#ifdef SUNOS_VEC_BIG_HOST - &SUNOS_VEC_BIG_HOST, -#endif /* SUNOS_BIG_VEC */ +#endif +/* default_vector[0] contains either the address of the default vector, + if there is one, or zero if there isn't. */ -#ifdef HOST_64_BIT -#ifdef DEMO_64_VEC - &DEMO_64_VEC, -#endif +bfd_target *default_vector[] = { +#ifdef DEFAULT_VECTOR + &DEFAULT_VECTOR, #endif + 0, +}; -#ifdef M88K_BCS_VEC - &M88K_BCS_VEC, -#endif /* M88K_BCS_VEC */ -#ifdef SREC_VEC - &SREC_VEC, -#endif /* SREC_VEC */ - -#ifdef ICOFF_LITTLE_VEC - &ICOFF_LITTLE_VEC, -#endif /* ICOFF_LITTLE_VEC */ -#ifdef ICOFF_BIG_VEC - &ICOFF_BIG_VEC, -#endif /* ICOFF_BIG_VEC */ -#ifdef B_OUT_VEC_LITTLE_HOST - &B_OUT_VEC_LITTLE_HOST, -#endif /* B_OUT_VEC_LITTLE_HOST */ +/* +FUNCTION + bfd_find_target -#ifdef B_OUT_VEC_BIG_HOST - &B_OUT_VEC_BIG_HOST, -#endif /* B_OUT_VEC_BIG_HOST */ +DESCRIPTION + 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 thenthe 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 <> to loop over all the + targets to find the one that matches the file being read. - NULL, /* end of list marker */ -}; +SYNOPSIS + 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 : + (CONST char *) 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; +} + + +/* +FUNCTION + bfd_target_list + +DESCRIPTION + This function returns a freshly malloced NULL-terminated + vector of the names of all the valid BFD targets. Do not + modify the names + +SYNOPSIS + CONST char **bfd_target_list(void); + +*/ + +CONST char ** +DEFUN_VOID(bfd_target_list) +{ + int vec_length= 0; +#ifdef NATIVE_HPPAHPUX_COMPILER + /* The native compiler on the HP9000/700 has a bug which causes it + to loop endlessly when compiling this file. This avoids it. */ + volatile +#endif + 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; +}