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