| 1 | /* Generic target-file-type support for the BFD library. |
| 2 | Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. |
| 3 | Written by Cygnus Support. |
| 4 | |
| 5 | This file is part of BFD, the Binary File Descriptor library. |
| 6 | |
| 7 | This program is free software; you can redistribute it and/or modify |
| 8 | it under the terms of the GNU General Public License as published by |
| 9 | the Free Software Foundation; either version 2 of the License, or |
| 10 | (at your option) any later version. |
| 11 | |
| 12 | This program is distributed in the hope that it will be useful, |
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | GNU General Public License for more details. |
| 16 | |
| 17 | You should have received a copy of the GNU General Public License |
| 18 | along with this program; if not, write to the Free Software |
| 19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
| 20 | |
| 21 | #include "bfd.h" |
| 22 | #include "sysdep.h" |
| 23 | #include "libbfd.h" |
| 24 | |
| 25 | /* |
| 26 | SECTION |
| 27 | Targets |
| 28 | |
| 29 | DESCRIPTION |
| 30 | Each port of BFD to a different machine requries the creation |
| 31 | of a target back end. All the back end provides to the root |
| 32 | part of BFD is a structure containing pointers to functions |
| 33 | which perform certain low level operations on files. BFD |
| 34 | translates the applications's requests through a pointer into |
| 35 | calls to the back end routines. |
| 36 | |
| 37 | When a file is opened with <<bfd_openr>>, its format and |
| 38 | target are unknown. BFD uses various mechanisms to determine |
| 39 | how to interpret the file. The operations performed are: |
| 40 | |
| 41 | o First a BFD is created by calling the internal routine |
| 42 | <<new_bfd>>, then <<bfd_find_target>> is called with the |
| 43 | target string supplied to <<bfd_openr>> and the new BFD pointer. |
| 44 | |
| 45 | o If a null target string was provided to <<bfd_find_target>>, |
| 46 | it looks up the environment variable <<GNUTARGET>> and uses |
| 47 | that as the target string. |
| 48 | |
| 49 | o If the target string is still NULL, or the target string is |
| 50 | <<default>>, then the first item in the target vector is used |
| 51 | as the target type, and <<target_defaulted>> is set to |
| 52 | cause <<bfd_check_format>> to loop through all the targets. |
| 53 | @xref{bfd_target}. @xref{Formats}. |
| 54 | |
| 55 | o Otherwise, the elements in the target vector are inspected |
| 56 | one by one, until a match on target name is found. When found, |
| 57 | that is used. |
| 58 | |
| 59 | o Otherwise the error <<invalid_target>> is returned to |
| 60 | <<bfd_openr>>. |
| 61 | |
| 62 | o <<bfd_openr>> attempts to open the file using |
| 63 | <<bfd_open_file>>, and returns the BFD. |
| 64 | |
| 65 | Once the BFD has been opened and the target selected, the file |
| 66 | format may be determined. This is done by calling |
| 67 | <<bfd_check_format>> on the BFD with a suggested format. |
| 68 | If <<target_defaulted>> has been set, each possible target |
| 69 | type is tried to see if it recognizes the specified format. The |
| 70 | routine returns <<true>> when the application guesses right. |
| 71 | @menu |
| 72 | @* bfd_target:: |
| 73 | @end menu |
| 74 | */ |
| 75 | |
| 76 | |
| 77 | /* |
| 78 | |
| 79 | INODE |
| 80 | bfd_target, , Targets, Targets |
| 81 | DOCDD |
| 82 | SUBSECTION |
| 83 | bfd_target |
| 84 | |
| 85 | DESCRIPTION |
| 86 | This structure contains everything that BFD knows about a |
| 87 | target. It includes things like its byte order, name, what |
| 88 | routines to call to do various operations, etc. |
| 89 | |
| 90 | Every BFD points to a target structure with its <<xvec>> |
| 91 | member. |
| 92 | |
| 93 | These macros are used to dispatch to functions through the |
| 94 | bfd_target vector. They are used in a number of macros further |
| 95 | down in @file{bfd.h}, and are also used when calling various |
| 96 | routines by hand inside the BFD implementation. The "arglist" |
| 97 | argument must be parenthesized; it contains all the arguments |
| 98 | to the called function. |
| 99 | |
| 100 | They make the documentation (more) unpleasant to read, so if |
| 101 | someone wants to fix this and not break the above, please do. |
| 102 | |
| 103 | .#define BFD_SEND(bfd, message, arglist) \ |
| 104 | . ((*((bfd)->xvec->message)) arglist) |
| 105 | |
| 106 | For operations which index on the BFD format |
| 107 | |
| 108 | .#define BFD_SEND_FMT(bfd, message, arglist) \ |
| 109 | . (((bfd)->xvec->message[(int)((bfd)->format)]) arglist) |
| 110 | |
| 111 | This is the struct which defines the type of BFD this is. The |
| 112 | <<xvec>> member of the struct <<bfd>> itself points here. Each |
| 113 | module that implements access to a different target under BFD, |
| 114 | defines one of these. |
| 115 | |
| 116 | |
| 117 | FIXME, these names should be rationalised with the names of |
| 118 | the entry points which call them. Too bad we can't have one |
| 119 | macro to define them both! |
| 120 | |
| 121 | .typedef struct bfd_target |
| 122 | .{ |
| 123 | |
| 124 | Identifies the kind of target, eg SunOS4, Ultrix, etc. |
| 125 | |
| 126 | . char *name; |
| 127 | |
| 128 | The "flavour" of a back end is a general indication about the contents |
| 129 | of a file. |
| 130 | |
| 131 | . enum target_flavour { |
| 132 | . bfd_target_unknown_flavour, |
| 133 | . bfd_target_aout_flavour, |
| 134 | . bfd_target_coff_flavour, |
| 135 | . bfd_target_ecoff_flavour, |
| 136 | . bfd_target_elf_flavour, |
| 137 | . bfd_target_ieee_flavour, |
| 138 | . bfd_target_oasys_flavour, |
| 139 | . bfd_target_tekhex_flavour, |
| 140 | . bfd_target_srec_flavour, |
| 141 | . bfd_target_hppa_flavour} flavour; |
| 142 | |
| 143 | The order of bytes within the data area of a file. |
| 144 | |
| 145 | . boolean byteorder_big_p; |
| 146 | |
| 147 | The order of bytes within the header parts of a file. |
| 148 | |
| 149 | . boolean header_byteorder_big_p; |
| 150 | |
| 151 | This is a mask of all the flags which an executable may have set - |
| 152 | from the set <<NO_FLAGS>>, <<HAS_RELOC>>, ...<<D_PAGED>>. |
| 153 | |
| 154 | . flagword object_flags; |
| 155 | |
| 156 | This is a mask of all the flags which a section may have set - from |
| 157 | the set <<SEC_NO_FLAGS>>, <<SEC_ALLOC>>, ...<<SET_NEVER_LOAD>>. |
| 158 | |
| 159 | . flagword section_flags; |
| 160 | |
| 161 | The character normally found at the front of a symbol |
| 162 | (if any), perhaps _. |
| 163 | |
| 164 | . char symbol_leading_char; |
| 165 | |
| 166 | The pad character for filenames within an archive header. |
| 167 | |
| 168 | . char ar_pad_char; |
| 169 | |
| 170 | The maximum number of characters in an archive header. |
| 171 | |
| 172 | . unsigned short ar_max_namelen; |
| 173 | |
| 174 | The minimum alignment restriction for any section. |
| 175 | |
| 176 | . unsigned int align_power_min; |
| 177 | |
| 178 | Entries for byte swapping for data. These are different to the other |
| 179 | entry points, since they don't take BFD as first arg. Certain other handlers |
| 180 | could do the same. |
| 181 | |
| 182 | . bfd_vma (*bfd_getx64) PARAMS ((bfd_byte *)); |
| 183 | . bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((bfd_byte *)); |
| 184 | . void (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *)); |
| 185 | . bfd_vma (*bfd_getx32) PARAMS ((bfd_byte *)); |
| 186 | . bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((bfd_byte *)); |
| 187 | . void (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *)); |
| 188 | . bfd_vma (*bfd_getx16) PARAMS ((bfd_byte *)); |
| 189 | . bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((bfd_byte *)); |
| 190 | . void (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *)); |
| 191 | |
| 192 | Byte swapping for the headers |
| 193 | |
| 194 | . bfd_vma (*bfd_h_getx64) PARAMS ((bfd_byte *)); |
| 195 | . bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((bfd_byte *)); |
| 196 | . void (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *)); |
| 197 | . bfd_vma (*bfd_h_getx32) PARAMS ((bfd_byte *)); |
| 198 | . bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((bfd_byte *)); |
| 199 | . void (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *)); |
| 200 | . bfd_vma (*bfd_h_getx16) PARAMS ((bfd_byte *)); |
| 201 | . bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((bfd_byte *)); |
| 202 | . void (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *)); |
| 203 | |
| 204 | Format dependent routines: these are vectors of entry points |
| 205 | within the target vector structure, one for each format to check. |
| 206 | |
| 207 | Check the format of a file being read. Return bfd_target * or zero. |
| 208 | |
| 209 | . struct bfd_target * (*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *)); |
| 210 | |
| 211 | Set the format of a file being written. |
| 212 | |
| 213 | . boolean (*_bfd_set_format[bfd_type_end]) PARAMS ((bfd *)); |
| 214 | |
| 215 | Write cached information into a file being written, at bfd_close. |
| 216 | |
| 217 | . boolean (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *)); |
| 218 | |
| 219 | The following functions are defined in <<JUMP_TABLE>>. The idea is |
| 220 | that the back end writer of <<foo>> names all the routines |
| 221 | <<foo_>>@var{entry_point}, <<JUMP_TABLE>> will built the entries |
| 222 | in this structure in the right order. |
| 223 | |
| 224 | Core file entry points |
| 225 | |
| 226 | . char * (*_core_file_failing_command) PARAMS ((bfd *)); |
| 227 | . int (*_core_file_failing_signal) PARAMS ((bfd *)); |
| 228 | . boolean (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *)); |
| 229 | |
| 230 | Archive entry points |
| 231 | |
| 232 | . boolean (*_bfd_slurp_armap) PARAMS ((bfd *)); |
| 233 | . boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *)); |
| 234 | . void (*_bfd_truncate_arname) PARAMS ((bfd *, CONST char *, char *)); |
| 235 | . boolean (*write_armap) PARAMS ((bfd *arch, |
| 236 | . unsigned int elength, |
| 237 | . struct orl *map, |
| 238 | . unsigned int orl_count, |
| 239 | . int stridx)); |
| 240 | |
| 241 | Standard stuff. |
| 242 | |
| 243 | . boolean (*_close_and_cleanup) PARAMS ((bfd *)); |
| 244 | . boolean (*_bfd_set_section_contents) PARAMS ((bfd *, sec_ptr, PTR, |
| 245 | . file_ptr, bfd_size_type)); |
| 246 | . boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR, |
| 247 | . file_ptr, bfd_size_type)); |
| 248 | . boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr)); |
| 249 | |
| 250 | Symbols and relocations |
| 251 | |
| 252 | . unsigned int (*_get_symtab_upper_bound) PARAMS ((bfd *)); |
| 253 | . unsigned int (*_bfd_canonicalize_symtab) PARAMS ((bfd *, |
| 254 | . struct symbol_cache_entry **)); |
| 255 | . unsigned int (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr)); |
| 256 | . unsigned int (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, |
| 257 | . struct symbol_cache_entry **)); |
| 258 | . struct symbol_cache_entry * |
| 259 | . (*_bfd_make_empty_symbol) PARAMS ((bfd *)); |
| 260 | . void (*_bfd_print_symbol) PARAMS ((bfd *, PTR, |
| 261 | . struct symbol_cache_entry *, |
| 262 | . bfd_print_symbol_type)); |
| 263 | .#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e)) |
| 264 | . void (*_bfd_get_symbol_info) PARAMS ((bfd *, |
| 265 | . struct symbol_cache_entry *, |
| 266 | . symbol_info *)); |
| 267 | .#define bfd_get_symbol_info(b,p,e) BFD_SEND(b, _bfd_get_symbol_info, (b,p,e)) |
| 268 | |
| 269 | . alent * (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *)); |
| 270 | . |
| 271 | . boolean (*_bfd_set_arch_mach) PARAMS ((bfd *, enum bfd_architecture, |
| 272 | . unsigned long)); |
| 273 | . |
| 274 | . bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev)); |
| 275 | . |
| 276 | . boolean (*_bfd_find_nearest_line) PARAMS ((bfd *abfd, |
| 277 | . struct sec *section, struct symbol_cache_entry **symbols, |
| 278 | . bfd_vma offset, CONST char **file, CONST char **func, |
| 279 | . unsigned int *line)); |
| 280 | . |
| 281 | . int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *)); |
| 282 | . |
| 283 | . int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean)); |
| 284 | . |
| 285 | . void (*_bfd_debug_info_start) PARAMS ((bfd *)); |
| 286 | . void (*_bfd_debug_info_end) PARAMS ((bfd *)); |
| 287 | . void (*_bfd_debug_info_accumulate) PARAMS ((bfd *, struct sec *)); |
| 288 | . |
| 289 | . bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *, |
| 290 | . struct bfd_seclet *, bfd_byte *data, |
| 291 | . boolean relocateable)); |
| 292 | . |
| 293 | . boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *, |
| 294 | . struct symbol_cache_entry **)); |
| 295 | . |
| 296 | . boolean (*_bfd_seclet_link) PARAMS ((bfd *, PTR data, |
| 297 | . boolean relocateable)); |
| 298 | |
| 299 | . {* See documentation on reloc types. *} |
| 300 | . CONST struct reloc_howto_struct * |
| 301 | . (*reloc_type_lookup) PARAMS ((bfd *abfd, |
| 302 | . bfd_reloc_code_real_type code)); |
| 303 | . |
| 304 | . {* Back-door to allow format-aware applications to create debug symbols |
| 305 | . while using BFD for everything else. Currently used by the assembler |
| 306 | . when creating COFF files. *} |
| 307 | . asymbol * (*_bfd_make_debug_symbol) PARAMS (( |
| 308 | . bfd *abfd, |
| 309 | . void *ptr, |
| 310 | . unsigned long size)); |
| 311 | |
| 312 | Data for use by back-end routines, which isn't generic enough to belong |
| 313 | in this structure. |
| 314 | |
| 315 | . PTR backend_data; |
| 316 | .} bfd_target; |
| 317 | |
| 318 | */ |
| 319 | |
| 320 | /* The default is to define a target_vector containing all the targets. |
| 321 | By setting MINIMIZE=1 on the "make" command line, the user can change this |
| 322 | to a vector containing just DEFAULT_VECTOR and any required |
| 323 | traditional-core-file handler. (This is to save space in the executables.) |
| 324 | The config files can also override the default large vector by giving an |
| 325 | explicit SELECT_VECS macro. */ |
| 326 | |
| 327 | #if MINIMIZE && defined(DEFAULT_VECTOR) && !defined(SELECT_VECS) |
| 328 | #ifdef TRAD_CORE |
| 329 | #define SELECT_VECS &DEFAULT_VECTOR,&trad_core_vec |
| 330 | #else |
| 331 | #ifdef SCO_CORE |
| 332 | #define SELECT_VECS &DEFAULT_VECTOR,&sco_core_vec |
| 333 | #else |
| 334 | #ifdef AIX386_CORE |
| 335 | #define SELECT_VECS &DEFAULT_VECTOR,&aix386_core_vec |
| 336 | #else |
| 337 | #define SELECT_VECS &DEFAULT_VECTOR |
| 338 | #endif |
| 339 | #endif |
| 340 | #endif |
| 341 | #endif |
| 342 | |
| 343 | /* All known xvecs. They are listed a second time below, since |
| 344 | we can't intermix extern's and initializers. */ |
| 345 | extern bfd_target i386lynx_vec; |
| 346 | extern bfd_target ecoff_little_vec; |
| 347 | extern bfd_target ecoff_big_vec; |
| 348 | extern bfd_target aout_mips_little_vec; |
| 349 | extern bfd_target aout_mips_big_vec; |
| 350 | extern bfd_target sunos_big_vec; |
| 351 | extern bfd_target demo_64_vec; |
| 352 | extern bfd_target srec_vec; |
| 353 | extern bfd_target symbolsrec_vec; |
| 354 | extern bfd_target tekhex_vec; |
| 355 | extern bfd_target a_out_adobe_vec; |
| 356 | extern bfd_target b_out_vec_little_host; |
| 357 | extern bfd_target b_out_vec_big_host; |
| 358 | extern bfd_target icoff_little_vec; |
| 359 | extern bfd_target icoff_big_vec; |
| 360 | extern bfd_target bfd_elf32_sparc_vec; |
| 361 | extern bfd_target bfd_elf32_i386_vec; |
| 362 | extern bfd_target bfd_elf32_m68k_vec; |
| 363 | extern bfd_target bfd_elf32_i860_vec; |
| 364 | extern bfd_target bfd_elf32_m88k_vec; |
| 365 | extern bfd_target bfd_elf32_bigmips_vec; |
| 366 | extern bfd_target bfd_elf32_littlemips_vec; |
| 367 | extern bfd_target ieee_vec; |
| 368 | extern bfd_target oasys_vec; |
| 369 | extern bfd_target m88kbcs_vec; |
| 370 | extern bfd_target m68kcoff_vec; |
| 371 | extern bfd_target i386coff_vec; |
| 372 | extern bfd_target i386aout_vec; |
| 373 | extern bfd_target i386linux_vec; |
| 374 | extern bfd_target a29kcoff_big_vec; |
| 375 | extern bfd_target trad_core_vec; |
| 376 | extern bfd_target sco_core_vec; |
| 377 | extern bfd_target aix386_core_vec; |
| 378 | extern bfd_target rs6000coff_vec; |
| 379 | extern bfd_target h8300coff_vec; |
| 380 | extern bfd_target h8500coff_vec; |
| 381 | extern bfd_target z8kcoff_vec; |
| 382 | extern bfd_target we32kcoff_vec; |
| 383 | extern bfd_target shcoff_vec; |
| 384 | |
| 385 | #if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) |
| 386 | extern bfd_target hppa_vec; |
| 387 | #endif |
| 388 | |
| 389 | #ifdef DEFAULT_VECTOR |
| 390 | extern bfd_target DEFAULT_VECTOR; |
| 391 | #endif |
| 392 | |
| 393 | bfd_target *target_vector[] = { |
| 394 | |
| 395 | #ifdef SELECT_VECS |
| 396 | |
| 397 | SELECT_VECS, |
| 398 | |
| 399 | #else /* not SELECT_VECS */ |
| 400 | |
| 401 | #ifdef DEFAULT_VECTOR |
| 402 | &DEFAULT_VECTOR, |
| 403 | #endif |
| 404 | |
| 405 | &i386coff_vec, |
| 406 | &i386aout_vec, |
| 407 | &i386lynx_vec, |
| 408 | &ecoff_little_vec, |
| 409 | &ecoff_big_vec, |
| 410 | &aout_mips_little_vec, |
| 411 | &aout_mips_big_vec, |
| 412 | &ieee_vec, |
| 413 | #if 0 |
| 414 | /* We have no oasys tools anymore, so we can't test any of this |
| 415 | anymore. If you want to test the stuff yourself, go ahead... |
| 416 | steve@cygnus.com |
| 417 | Worse, since there is no magic number for archives, there |
| 418 | can annoying target mis-matches. */ |
| 419 | &oasys_vec, |
| 420 | #endif |
| 421 | &sunos_big_vec, |
| 422 | #ifdef BFD64 |
| 423 | &demo_64_vec, /* Only compiled if host has long-long support */ |
| 424 | #endif |
| 425 | &h8300coff_vec, |
| 426 | &z8kcoff_vec, |
| 427 | &m88kbcs_vec, |
| 428 | &srec_vec, |
| 429 | &symbolsrec_vec, |
| 430 | /* &tekhex_vec,*/ |
| 431 | &icoff_little_vec, |
| 432 | &icoff_big_vec, |
| 433 | &bfd_elf32_sparc_vec, |
| 434 | &bfd_elf32_i386_vec, |
| 435 | &bfd_elf32_m68k_vec, |
| 436 | &bfd_elf32_i860_vec, |
| 437 | &bfd_elf32_m88k_vec, |
| 438 | &bfd_elf32_littlemips_vec, |
| 439 | &bfd_elf32_bigmips_vec, |
| 440 | &a_out_adobe_vec, |
| 441 | &b_out_vec_little_host, |
| 442 | &b_out_vec_big_host, |
| 443 | &m68kcoff_vec, |
| 444 | &a29kcoff_big_vec, |
| 445 | &rs6000coff_vec, |
| 446 | #if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) |
| 447 | &hppa_vec, |
| 448 | #endif |
| 449 | &we32kcoff_vec, |
| 450 | |
| 451 | #ifdef TRAD_CORE |
| 452 | &trad_core_vec, |
| 453 | #endif |
| 454 | #ifdef SCO_CORE |
| 455 | &sco_core_vec, |
| 456 | #endif |
| 457 | #ifdef AIX386_CORE |
| 458 | &aix386_core_vec, |
| 459 | #endif |
| 460 | |
| 461 | #endif /* not SELECT_VECS */ |
| 462 | NULL, /* end of list marker */ |
| 463 | }; |
| 464 | |
| 465 | /* default_vector[0] contains either the address of the default vector, |
| 466 | if there is one, or zero if there isn't. */ |
| 467 | |
| 468 | bfd_target *default_vector[] = { |
| 469 | #ifdef DEFAULT_VECTOR |
| 470 | &DEFAULT_VECTOR, |
| 471 | #endif |
| 472 | 0, |
| 473 | }; |
| 474 | |
| 475 | |
| 476 | |
| 477 | |
| 478 | /* |
| 479 | FUNCTION |
| 480 | bfd_find_target |
| 481 | |
| 482 | DESCRIPTION |
| 483 | Returns a pointer to the transfer vector for the object target |
| 484 | named target_name. If target_name is NULL, chooses the one in |
| 485 | the environment variable GNUTARGET; if that is null or not |
| 486 | defined thenthe first entry in the target list is chosen. |
| 487 | Passing in the string "default" or setting the environment |
| 488 | variable to "default" will cause the first entry in the target |
| 489 | list to be returned, and "target_defaulted" will be set in the |
| 490 | BFD. This causes <<bfd_check_format>> to loop over all the |
| 491 | targets to find the one that matches the file being read. |
| 492 | |
| 493 | SYNOPSIS |
| 494 | bfd_target *bfd_find_target(CONST char *, bfd *); |
| 495 | */ |
| 496 | |
| 497 | bfd_target * |
| 498 | DEFUN(bfd_find_target,(target_name, abfd), |
| 499 | CONST char *target_name AND |
| 500 | bfd *abfd) |
| 501 | { |
| 502 | bfd_target **target; |
| 503 | extern char *getenv (); |
| 504 | CONST char *targname = (target_name ? target_name : |
| 505 | (CONST char *) getenv ("GNUTARGET")); |
| 506 | |
| 507 | /* This is safe; the vector cannot be null */ |
| 508 | if (targname == NULL || !strcmp (targname, "default")) { |
| 509 | abfd->target_defaulted = true; |
| 510 | return abfd->xvec = target_vector[0]; |
| 511 | } |
| 512 | |
| 513 | abfd->target_defaulted = false; |
| 514 | |
| 515 | for (target = &target_vector[0]; *target != NULL; target++) { |
| 516 | if (!strcmp (targname, (*target)->name)) |
| 517 | return abfd->xvec = *target; |
| 518 | } |
| 519 | |
| 520 | bfd_error = invalid_target; |
| 521 | return NULL; |
| 522 | } |
| 523 | |
| 524 | |
| 525 | /* |
| 526 | FUNCTION |
| 527 | bfd_target_list |
| 528 | |
| 529 | DESCRIPTION |
| 530 | This function returns a freshly malloced NULL-terminated |
| 531 | vector of the names of all the valid BFD targets. Do not |
| 532 | modify the names |
| 533 | |
| 534 | SYNOPSIS |
| 535 | CONST char **bfd_target_list(void); |
| 536 | |
| 537 | */ |
| 538 | |
| 539 | CONST char ** |
| 540 | DEFUN_VOID(bfd_target_list) |
| 541 | { |
| 542 | int vec_length= 0; |
| 543 | #ifdef NATIVE_HPPAHPUX_COMPILER |
| 544 | /* The native compiler on the HP9000/700 has a bug which causes it |
| 545 | to loop endlessly when compiling this file. This avoids it. */ |
| 546 | volatile |
| 547 | #endif |
| 548 | bfd_target **target; |
| 549 | CONST char **name_list, **name_ptr; |
| 550 | |
| 551 | for (target = &target_vector[0]; *target != NULL; target++) |
| 552 | vec_length++; |
| 553 | |
| 554 | name_ptr = |
| 555 | name_list = (CONST char **) zalloc ((vec_length + 1) * sizeof (char **)); |
| 556 | |
| 557 | if (name_list == NULL) { |
| 558 | bfd_error = no_memory; |
| 559 | return NULL; |
| 560 | } |
| 561 | |
| 562 | for (target = &target_vector[0]; *target != NULL; target++) |
| 563 | *(name_ptr++) = (*target)->name; |
| 564 | |
| 565 | return name_list; |
| 566 | } |