]>
Commit | Line | Data |
---|---|---|
4e6f9223 SC |
1 | /* Generic target-file-type support for the BFD library. |
2 | Copyright (C) 1990-1991 Free Software Foundation, Inc. | |
3 | Written by Cygnus Support. | |
4a81b561 | 4 | |
4e6f9223 | 5 | This file is part of BFD, the Binary File Descriptor library. |
4a81b561 | 6 | |
4e6f9223 | 7 | This program is free software; you can redistribute it and/or modify |
4a81b561 | 8 | it under the terms of the GNU General Public License as published by |
4e6f9223 SC |
9 | the Free Software Foundation; either version 2 of the License, or |
10 | (at your option) any later version. | |
4a81b561 | 11 | |
4e6f9223 | 12 | This program is distributed in the hope that it will be useful, |
4a81b561 DHW |
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 | |
4e6f9223 SC |
18 | along with this program; if not, write to the Free Software |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
4a81b561 DHW |
20 | |
21 | /* $Id$ */ | |
22 | ||
7ed4093a | 23 | #include <sysdep.h> |
4a81b561 DHW |
24 | #include "bfd.h" |
25 | #include "libbfd.h" | |
26 | ||
6f715d66 SC |
27 | /*doc* |
28 | @section Targets | |
29 | Each port of BFD to a different machine requries the creation of a | |
4e6f9223 | 30 | target back end. All the back end provides to the root part of BFD is |
6f715d66 SC |
31 | a structure containing pointers to functions which perform certain low |
32 | level operations on files. BFD translates the applications's requests | |
33 | through a pointer into calls to the back end routines. | |
34 | ||
35 | When a file is opened with @code{bfd_openr}, its format and target are | |
36 | unknown. BFD uses various mechanisms to determine how to interpret the | |
3f85ebce | 37 | file. The operations performed are: |
6f715d66 SC |
38 | @itemize @bullet |
39 | @item | |
4e6f9223 | 40 | First a BFD is created by calling the internal routine |
6f715d66 | 41 | @code{new_bfd}, then @code{bfd_find_target} is called with the target |
4e6f9223 | 42 | string supplied to @code{bfd_openr} and the new BFD pointer. |
6f715d66 SC |
43 | @item |
44 | If a null target string was provided to | |
45 | @code{bfd_find_target}, it looks up the environment variable | |
46 | @code{GNUTARGET} and uses that as the target string. | |
47 | @item | |
48 | If the target string is still NULL, or the target string | |
49 | is @code{default}, then the first item in the target vector is used as | |
4e6f9223 | 50 | the target type. @xref{bfd_target}. |
6f715d66 SC |
51 | @item |
52 | Otherwise, the elements in the target vector are | |
53 | inspected one by one, until a match on target name is found. When | |
54 | found, that is used. | |
55 | @item | |
56 | Otherwise the error @code{invalid_target} is returned to | |
57 | @code{bfd_openr}. | |
58 | @item | |
59 | @code{bfd_openr} attempts to open the file using | |
4e6f9223 | 60 | @code{bfd_open_file}, and returns the BFD. |
6f715d66 | 61 | @end itemize |
4e6f9223 | 62 | Once the BFD has been opened and the target selected, the file format |
6f715d66 | 63 | may be determined. This is done by calling @code{bfd_check_format} on |
4e6f9223 | 64 | the BFD with a suggested format. The routine returns @code{true} when |
6f715d66 | 65 | the application guesses right. |
92c78ee6 RP |
66 | |
67 | @menu | |
68 | * bfd_target:: | |
69 | @end menu | |
6f715d66 SC |
70 | */ |
71 | ||
72 | ||
73 | /*proto* bfd_target | |
92c78ee6 | 74 | @node bfd_target, , Targets, Targets |
6f715d66 SC |
75 | @subsection bfd_target |
76 | This structure contains everything that BFD knows about a target. | |
77 | It includes things like its byte order, name, what routines to call | |
78 | to do various operations, etc. | |
79 | ||
80 | Every BFD points to a target structure with its "xvec" member. | |
81 | ||
82 | ||
83 | Shortcut for declaring fields which are prototyped function pointers, | |
84 | while avoiding anguish on compilers that don't support protos. | |
85 | ||
86 | $#define SDEF(ret, name, arglist) \ | |
87 | $ PROTO(ret,(*name),arglist) | |
88 | $#define SDEF_FMT(ret, name, arglist) \ | |
89 | $ PROTO(ret,(*name[bfd_type_end]),arglist) | |
90 | ||
91 | These macros are used to dispatch to functions through the bfd_target | |
4e6f9223 SC |
92 | vector. They are used in a number of macros further down in @file{bfd.h}, and |
93 | are also used when calling various routines by hand inside the BFD | |
6f715d66 SC |
94 | implementation. The "arglist" argument must be parenthesized; it |
95 | contains all the arguments to the called function. | |
96 | ||
97 | $#define BFD_SEND(bfd, message, arglist) \ | |
98 | $ ((*((bfd)->xvec->message)) arglist) | |
99 | ||
4e6f9223 | 100 | For operations which index on the BFD format |
6f715d66 SC |
101 | |
102 | $#define BFD_SEND_FMT(bfd, message, arglist) \ | |
103 | $ (((bfd)->xvec->message[(int)((bfd)->format)]) arglist) | |
104 | ||
105 | This is the struct which defines the type of BFD this is. The | |
4e6f9223 | 106 | "xvec" member of the struct @code{bfd} itself points here. Each module |
6f715d66 SC |
107 | that implements access to a different target under BFD, defines |
108 | one of these. | |
109 | ||
110 | FIXME, these names should be rationalised with the names of the | |
111 | entry points which call them. Too bad we can't have one macro to | |
112 | define them both! | |
113 | ||
114 | *+++ | |
115 | ||
116 | $typedef struct bfd_target | |
117 | ${ | |
118 | ||
119 | identifies the kind of target, eg SunOS4, Ultrix, etc | |
120 | ||
121 | $ char *name; | |
122 | ||
123 | The "flavour" of a back end is a general indication about the contents | |
124 | of a file. | |
125 | ||
92c78ee6 RP |
126 | $ enum target_flavour { |
127 | $ bfd_target_unknown_flavour, | |
128 | $ bfd_target_aout_flavour, | |
129 | $ bfd_target_coff_flavour, | |
130 | $ bfd_target_elf_flavour, | |
131 | $ bfd_target_ieee_flavour, | |
132 | $ bfd_target_oasys_flavour, | |
133 | $ bfd_target_srec_flavour} flavour; | |
6f715d66 SC |
134 | |
135 | The order of bytes within the data area of a file. | |
136 | ||
137 | $ boolean byteorder_big_p; | |
138 | ||
139 | The order of bytes within the header parts of a file. | |
140 | ||
141 | $ boolean header_byteorder_big_p; | |
142 | ||
143 | This is a mask of all the flags which an executable may have set - | |
144 | from the set @code{NO_FLAGS}, @code{HAS_RELOC}, ...@code{D_PAGED}. | |
145 | ||
146 | $ flagword object_flags; | |
147 | ||
148 | This is a mask of all the flags which a section may have set - from | |
149 | the set @code{SEC_NO_FLAGS}, @code{SEC_ALLOC}, ...@code{SET_NEVER_LOAD}. | |
150 | ||
151 | $ flagword section_flags; | |
152 | ||
153 | The pad character for filenames within an archive header. | |
154 | ||
155 | $ char ar_pad_char; | |
156 | ||
157 | The maximum number of characters in an archive header. | |
158 | ||
159 | $ unsigned short ar_max_namelen; | |
160 | ||
161 | The minimum alignment restriction for any section. | |
162 | ||
163 | $ unsigned int align_power_min; | |
164 | ||
165 | Entries for byte swapping for data. These are different to the other | |
4e6f9223 | 166 | entry points, since they don't take BFD as first arg. Certain other handlers |
6f715d66 SC |
167 | could do the same. |
168 | ||
81f3996f SC |
169 | $ SDEF (bfd_vma, bfd_getx64, (bfd_byte *)); |
170 | $ SDEF (void, bfd_putx64, (bfd_vma, bfd_byte *)); | |
171 | $ SDEF (bfd_vma, bfd_getx32, (bfd_byte *)); | |
172 | $ SDEF (void, bfd_putx32, (bfd_vma, bfd_byte *)); | |
173 | $ SDEF (bfd_vma, bfd_getx16, (bfd_byte *)); | |
174 | $ SDEF (void, bfd_putx16, (bfd_vma, bfd_byte *)); | |
6f715d66 SC |
175 | |
176 | Byte swapping for the headers | |
177 | ||
4e6f9223 | 178 | $ SDEF (bfd_vma, bfd_h_getx64, (bfd_byte *)); |
81f3996f SC |
179 | $ SDEF (void, bfd_h_putx64, (bfd_vma, bfd_byte *)); |
180 | $ SDEF (bfd_vma, bfd_h_getx32, (bfd_byte *)); | |
181 | $ SDEF (void, bfd_h_putx32, (bfd_vma, bfd_byte *)); | |
182 | $ SDEF (bfd_vma, bfd_h_getx16, (bfd_byte *)); | |
183 | $ SDEF (void, bfd_h_putx16, (bfd_vma, bfd_byte *)); | |
6f715d66 SC |
184 | |
185 | Format dependent routines, these turn into vectors of entry points | |
186 | within the target vector structure; one for each format to check. | |
187 | ||
188 | Check the format of a file being read. Return bfd_target * or zero. | |
189 | ||
190 | $ SDEF_FMT (struct bfd_target *, _bfd_check_format, (bfd *)); | |
191 | ||
192 | Set the format of a file being written. | |
193 | ||
194 | $ SDEF_FMT (boolean, _bfd_set_format, (bfd *)); | |
195 | ||
196 | Write cached information into a file being written, at bfd_close. | |
197 | ||
198 | $ SDEF_FMT (boolean, _bfd_write_contents, (bfd *)); | |
199 | ||
200 | The following functions are defined in @code{JUMP_TABLE}. The idea is | |
201 | that the back end writer of @code{foo} names all the routines | |
202 | @code{foo_}@var{entry_point}, @code{JUMP_TABLE} will built the entries | |
203 | in this structure in the right order. | |
204 | ||
205 | Core file entry points | |
206 | ||
207 | $ SDEF (char *, _core_file_failing_command, (bfd *)); | |
208 | $ SDEF (int, _core_file_failing_signal, (bfd *)); | |
209 | $ SDEF (boolean, _core_file_matches_executable_p, (bfd *, bfd *)); | |
210 | ||
211 | Archive entry points | |
212 | ||
213 | $ SDEF (boolean, _bfd_slurp_armap, (bfd *)); | |
214 | $ SDEF (boolean, _bfd_slurp_extended_name_table, (bfd *)); | |
215 | $ SDEF (void, _bfd_truncate_arname, (bfd *, CONST char *, char *)); | |
216 | $ SDEF (boolean, write_armap, (bfd *arch, | |
217 | $ unsigned int elength, | |
218 | $ struct orl *map, | |
219 | $ int orl_count, | |
220 | $ int stridx)); | |
221 | ||
222 | Standard stuff. | |
223 | ||
224 | $ SDEF (boolean, _close_and_cleanup, (bfd *)); | |
225 | $ SDEF (boolean, _bfd_set_section_contents, (bfd *, sec_ptr, PTR, | |
226 | $ file_ptr, bfd_size_type)); | |
227 | $ SDEF (boolean, _bfd_get_section_contents, (bfd *, sec_ptr, PTR, | |
228 | $ file_ptr, bfd_size_type)); | |
229 | $ SDEF (boolean, _new_section_hook, (bfd *, sec_ptr)); | |
230 | ||
231 | Symbols and reloctions | |
232 | ||
233 | $ SDEF (unsigned int, _get_symtab_upper_bound, (bfd *)); | |
234 | $ SDEF (unsigned int, _bfd_canonicalize_symtab, | |
235 | $ (bfd *, struct symbol_cache_entry **)); | |
236 | $ SDEF (unsigned int, _get_reloc_upper_bound, (bfd *, sec_ptr)); | |
237 | $ SDEF (unsigned int, _bfd_canonicalize_reloc, (bfd *, sec_ptr, arelent **, | |
238 | $ struct symbol_cache_entry**)); | |
239 | $ SDEF (struct symbol_cache_entry *, _bfd_make_empty_symbol, (bfd *)); | |
240 | $ SDEF (void, _bfd_print_symbol, (bfd *, PTR, struct symbol_cache_entry *, | |
92c78ee6 | 241 | $ bfd_print_symbol_type)); |
6f715d66 SC |
242 | $#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e)) |
243 | $ SDEF (alent *, _get_lineno, (bfd *, struct symbol_cache_entry *)); | |
244 | $ | |
245 | $ SDEF (boolean, _bfd_set_arch_mach, (bfd *, enum bfd_architecture, | |
246 | $ unsigned long)); | |
247 | $ | |
248 | $ SDEF (bfd *, openr_next_archived_file, (bfd *arch, bfd *prev)); | |
249 | $ SDEF (boolean, _bfd_find_nearest_line, | |
250 | $ (bfd *abfd, struct sec *section, | |
251 | $ struct symbol_cache_entry **symbols,bfd_vma offset, | |
252 | $ CONST char **file, CONST char **func, unsigned int *line)); | |
253 | $ SDEF (int, _bfd_stat_arch_elt, (bfd *, struct stat *)); | |
254 | $ | |
255 | $ SDEF (int, _bfd_sizeof_headers, (bfd *, boolean)); | |
256 | $ | |
257 | $ SDEF (void, _bfd_debug_info_start, (bfd *)); | |
258 | $ SDEF (void, _bfd_debug_info_end, (bfd *)); | |
259 | $ SDEF (void, _bfd_debug_info_accumulate, (bfd *, struct sec *)); | |
260 | ||
261 | Special entry points for gdb to swap in coff symbol table parts | |
262 | ||
263 | $ SDEF(void, _bfd_coff_swap_aux_in,( | |
264 | $ bfd *abfd , | |
265 | $ PTR ext, | |
266 | $ int type, | |
267 | $ int class , | |
268 | $ PTR in)); | |
269 | $ | |
270 | $ SDEF(void, _bfd_coff_swap_sym_in,( | |
271 | $ bfd *abfd , | |
272 | $ PTR ext, | |
273 | $ PTR in)); | |
274 | $ | |
275 | $ SDEF(void, _bfd_coff_swap_lineno_in, ( | |
276 | $ bfd *abfd, | |
277 | $ PTR ext, | |
278 | $ PTR in)); | |
279 | $ | |
280 | $} bfd_target; | |
281 | ||
282 | *--- | |
283 | ||
284 | */ | |
23b0b558 JG |
285 | extern bfd_target ecoff_little_vec; |
286 | extern bfd_target ecoff_big_vec; | |
2b1d8a50 | 287 | extern bfd_target sunos_big_vec; |
7ed4093a | 288 | extern bfd_target demo_64_vec; |
4a81b561 DHW |
289 | extern bfd_target srec_vec; |
290 | extern bfd_target b_out_vec_little_host; | |
291 | extern bfd_target b_out_vec_big_host; | |
292 | extern bfd_target icoff_little_vec; | |
293 | extern bfd_target icoff_big_vec; | |
3f85ebce JG |
294 | extern bfd_target elf_little_vec; |
295 | extern bfd_target elf_big_vec; | |
aacf30e3 DHW |
296 | extern bfd_target ieee_vec; |
297 | extern bfd_target oasys_vec; | |
298 | extern bfd_target m88k_bcs_vec; | |
c407897e | 299 | extern bfd_target m68kcoff_vec; |
20fdc627 | 300 | extern bfd_target i386coff_vec; |
41f50af0 | 301 | extern bfd_target a29kcoff_big_vec; |
4e6f9223 SC |
302 | |
303 | #ifdef SELECT_VECS | |
304 | ||
305 | bfd_target *target_vector[] = { | |
306 | SELECT_VECS, | |
307 | 0 | |
308 | ||
309 | }; | |
310 | #else | |
c0e5039e JG |
311 | #ifdef DEFAULT_VECTOR |
312 | extern bfd_target DEFAULT_VECTOR; | |
313 | #endif | |
314 | ||
7d774e01 | 315 | #ifdef GNU960 |
6f715d66 SC |
316 | #define ICOFF_LITTLE_VEC icoff_little_vec |
317 | #define ICOFF_BIG_VEC icoff_big_vec | |
318 | #define B_OUT_VEC_LITTLE_HOST b_out_vec_little_host | |
319 | #define B_OUT_VEC_BIG_HOST b_out_vec_big_host | |
7d774e01 | 320 | #endif /* GNU960 */ |
9846338e | 321 | |
9872a49c | 322 | #ifndef RESTRICTED |
6f715d66 SC |
323 | #define ECOFF_LITTLE_VEC ecoff_little_vec |
324 | #define ECOFF_BIG_VEC ecoff_big_vec | |
325 | #define ICOFF_LITTLE_VEC icoff_little_vec | |
326 | #define ICOFF_BIG_VEC icoff_big_vec | |
3f85ebce JG |
327 | #define ELF_LITTLE_VEC elf_little_vec |
328 | #define ELF_BIG_VEC elf_big_vec | |
6f715d66 SC |
329 | #define ZB_OUT_VEC_LITTLE_HOST b_out_vec_little_host |
330 | #define ZB_OUT_VEC_BIG_HOST b_out_vec_big_host | |
331 | #define SUNOS_VEC_BIG_HOST sunos_big_vec | |
332 | #define DEMO_64_VEC demo_64_vec | |
92c78ee6 RP |
333 | |
334 | /* We have no oasys tools anymore, so we can't test any of this | |
335 | anymore. If you want to test the stuff yourself, go ahead... | |
336 | [email protected] */ | |
337 | #if 0 | |
6f715d66 | 338 | #define OASYS_VEC oasys_vec |
92c78ee6 RP |
339 | #endif |
340 | ||
6f715d66 SC |
341 | #define IEEE_VEC ieee_vec |
342 | #define M88K_BCS_VEC m88k_bcs_vec | |
343 | #define SREC_VEC srec_vec | |
344 | #define M68KCOFF_VEC m68kcoff_vec | |
345 | #define I386COFF_VEC i386coff_vec | |
41f50af0 | 346 | #define A29KCOFF_BIG_VEC a29kcoff_big_vec |
9872a49c | 347 | #endif |
4e6f9223 | 348 | |
7d774e01 | 349 | bfd_target *target_vector[] = { |
9846338e | 350 | |
7d774e01 | 351 | #ifdef DEFAULT_VECTOR |
6f715d66 | 352 | &DEFAULT_VECTOR, |
92c78ee6 | 353 | #endif |
7d774e01 | 354 | |
6f715d66 SC |
355 | #ifdef I386COFF_VEC |
356 | &I386COFF_VEC, | |
92c78ee6 | 357 | #endif |
20fdc627 | 358 | |
23b0b558 | 359 | #ifdef ECOFF_LITTLE_VEC |
6f715d66 | 360 | &ECOFF_LITTLE_VEC, |
23b0b558 JG |
361 | #endif |
362 | ||
363 | #ifdef ECOFF_BIG_VEC | |
6f715d66 | 364 | &ECOFF_BIG_VEC, |
23b0b558 | 365 | #endif |
92c78ee6 | 366 | |
7d774e01 | 367 | #ifdef IEEE_VEC |
6f715d66 | 368 | &IEEE_VEC, |
92c78ee6 | 369 | #endif |
7d774e01 RP |
370 | |
371 | #ifdef OASYS_VEC | |
6f715d66 | 372 | &OASYS_VEC, |
92c78ee6 | 373 | #endif |
7d774e01 | 374 | |
2b1d8a50 | 375 | #ifdef SUNOS_VEC_BIG_HOST |
6f715d66 | 376 | &SUNOS_VEC_BIG_HOST, |
92c78ee6 | 377 | #endif |
7ed4093a SC |
378 | |
379 | #ifdef HOST_64_BIT | |
380 | #ifdef DEMO_64_VEC | |
6f715d66 | 381 | &DEMO_64_VEC, |
7ed4093a SC |
382 | #endif |
383 | #endif | |
384 | ||
7d774e01 | 385 | #ifdef M88K_BCS_VEC |
6f715d66 | 386 | &M88K_BCS_VEC, |
92c78ee6 | 387 | #endif |
7d774e01 RP |
388 | |
389 | #ifdef SREC_VEC | |
6f715d66 | 390 | &SREC_VEC, |
92c78ee6 | 391 | #endif |
6f715d66 | 392 | |
7d774e01 | 393 | #ifdef ICOFF_LITTLE_VEC |
6f715d66 | 394 | &ICOFF_LITTLE_VEC, |
92c78ee6 | 395 | #endif |
7d774e01 RP |
396 | |
397 | #ifdef ICOFF_BIG_VEC | |
6f715d66 | 398 | &ICOFF_BIG_VEC, |
92c78ee6 | 399 | #endif |
7d774e01 | 400 | |
3f85ebce JG |
401 | #ifdef ELF_LITTLE_VEC |
402 | &ELF_LITTLE_VEC, | |
92c78ee6 | 403 | #endif |
3f85ebce JG |
404 | |
405 | #ifdef ELF_BIG_VEC | |
406 | &ELF_BIG_VEC, | |
92c78ee6 | 407 | #endif |
3f85ebce | 408 | |
7d774e01 | 409 | #ifdef B_OUT_VEC_LITTLE_HOST |
6f715d66 | 410 | &B_OUT_VEC_LITTLE_HOST, |
92c78ee6 | 411 | #endif |
9846338e | 412 | |
7d774e01 | 413 | #ifdef B_OUT_VEC_BIG_HOST |
6f715d66 | 414 | &B_OUT_VEC_BIG_HOST, |
92c78ee6 | 415 | #endif |
9846338e | 416 | |
6f715d66 SC |
417 | #ifdef M68KCOFF_VEC |
418 | &M68KCOFF_VEC, | |
92c78ee6 | 419 | #endif |
20fdc627 | 420 | |
41f50af0 SC |
421 | #ifdef A29KCOFF_BIG_VEC |
422 | &A29KCOFF_BIG_VEC, | |
92c78ee6 RP |
423 | #endif |
424 | ||
425 | #ifdef TRAD_CORE | |
426 | &trad_core_big_vec, | |
427 | &trad_core_little_vec, | |
428 | #endif | |
41f50af0 | 429 | |
6f715d66 | 430 | NULL, /* end of list marker */ |
7d774e01 | 431 | }; |
c0e5039e | 432 | |
4e6f9223 | 433 | #endif |
c0e5039e JG |
434 | |
435 | /* default_vector[0] contains either the address of the default vector, | |
436 | if there is one, or zero if there isn't. */ | |
437 | ||
438 | bfd_target *default_vector[] = { | |
439 | #ifdef DEFAULT_VECTOR | |
6f715d66 | 440 | &DEFAULT_VECTOR, |
c0e5039e | 441 | #endif |
6f715d66 | 442 | 0, |
c0e5039e | 443 | }; |
6f715d66 SC |
444 | |
445 | ||
446 | ||
447 | ||
448 | /*proto* | |
449 | *i bfd_find_target | |
450 | Returns a pointer to the transfer vector for the object target | |
451 | named target_name. If target_name is NULL, chooses the one in the | |
452 | environment variable GNUTARGET; if that is null or not defined then | |
453 | the first entry in the target list is chosen. Passing in the | |
454 | string "default" or setting the environment variable to "default" | |
455 | will cause the first entry in the target list to be returned, | |
4e6f9223 SC |
456 | and "target_defaulted" will be set in the BFD. This causes |
457 | @code{bfd_check_format} to loop over all the targets to find the one | |
6f715d66 SC |
458 | that matches the file being read. |
459 | *; PROTO(bfd_target *, bfd_find_target,(CONST char *, bfd *)); | |
460 | *-*/ | |
461 | ||
462 | bfd_target * | |
463 | DEFUN(bfd_find_target,(target_name, abfd), | |
464 | CONST char *target_name AND | |
465 | bfd *abfd) | |
466 | { | |
467 | bfd_target **target; | |
468 | extern char *getenv (); | |
469 | CONST char *targname = (target_name ? target_name : getenv ("GNUTARGET")); | |
470 | ||
471 | /* This is safe; the vector cannot be null */ | |
472 | if (targname == NULL || !strcmp (targname, "default")) { | |
473 | abfd->target_defaulted = true; | |
474 | return abfd->xvec = target_vector[0]; | |
475 | } | |
476 | ||
477 | abfd->target_defaulted = false; | |
478 | ||
479 | for (target = &target_vector[0]; *target != NULL; target++) { | |
480 | if (!strcmp (targname, (*target)->name)) | |
481 | return abfd->xvec = *target; | |
482 | } | |
483 | ||
484 | bfd_error = invalid_target; | |
485 | return NULL; | |
486 | } | |
487 | ||
488 | ||
489 | /*proto* | |
490 | *i bfd_target_list | |
491 | This function returns a freshly malloced NULL-terminated vector of the | |
4e6f9223 | 492 | names of all the valid BFD targets. Do not modify the names |
6f715d66 SC |
493 | *; PROTO(CONST char **,bfd_target_list,()); |
494 | ||
495 | *-*/ | |
496 | ||
497 | CONST char ** | |
498 | DEFUN_VOID(bfd_target_list) | |
499 | { | |
500 | int vec_length= 0; | |
501 | bfd_target **target; | |
4e6f9223 | 502 | CONST char **name_list, **name_ptr; |
6f715d66 SC |
503 | |
504 | for (target = &target_vector[0]; *target != NULL; target++) | |
505 | vec_length++; | |
506 | ||
507 | name_ptr = | |
508 | name_list = (CONST char **) zalloc ((vec_length + 1) * sizeof (char **)); | |
509 | ||
510 | if (name_list == NULL) { | |
511 | bfd_error = no_memory; | |
512 | return NULL; | |
513 | } | |
514 | ||
6f715d66 SC |
515 | for (target = &target_vector[0]; *target != NULL; target++) |
516 | *(name_ptr++) = (*target)->name; | |
517 | ||
518 | return name_list; | |
519 | } |