1 /* BFD semi-generic back-end for a.out binaries.
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3 Written by Cygnus Support.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
28 BFD supports a number of different flavours of a.out format,
29 though the major differences are only the sizes of the
30 structures on disk, and the shape of the relocation
33 The support is split into a basic support file @file{aoutx.h}
34 and other files which derive functions from the base. One
35 derivation file is @file{aoutf1.h} (for a.out flavour 1), and
36 adds to the basic a.out functions support for sun3, sun4, 386
37 and 29k a.out files, to create a target jump vector for a
40 This information is further split out into more specific files
41 for each machine, including @file{sunos.c} for sun3 and sun4,
42 @file{newsos3.c} for the Sony NEWS, and @file{demo64.c} for a
43 demonstration of a 64 bit a.out format.
45 The base file @file{aoutx.h} defines general mechanisms for
46 reading and writing records to and from disk and various
47 other methods which BFD requires. It is included by
48 @file{aout32.c} and @file{aout64.c} to form the names
49 <<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc.
51 As an example, this is what goes on to make the back end for a
52 sun4, from @file{aout32.c}:
54 | #define ARCH_SIZE 32
60 | aout_32_canonicalize_reloc
61 | aout_32_find_nearest_line
63 | aout_32_get_reloc_upper_bound
69 | #define TARGET_NAME "a.out-sunos-big"
70 | #define VECNAME sunos_big_vec
73 requires all the names from @file{aout32.c}, and produces the jump vector
77 The file @file{host-aout.c} is a special case. It is for a large set
78 of hosts that use ``more or less standard'' a.out files, and
79 for which cross-debugging is not interesting. It uses the
80 standard 32-bit a.out support routines, but determines the
81 file offsets and addresses of the text, data, and BSS
82 sections, the machine architecture and machine type, and the
83 entry point address, in a host-dependent manner. Once these
84 values have been determined, generic code is used to handle
87 When porting it to run on a new system, you must supply:
91 | HOST_MACHINE_ARCH (optional)
92 | HOST_MACHINE_MACHINE (optional)
93 | HOST_TEXT_START_ADDR
96 in the file <<../include/sys/h-XXX.h>> (for your host). These
97 values, plus the structures and macros defined in <<a.out.h>> on
98 your host system, will produce a BFD target that will access
99 ordinary a.out files on your host. To configure a new machine
100 to use <<host-aout.c>., specify:
102 | TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
103 | TDEPFILES= host-aout.o trad-core.o
105 in the <<config/mt-XXX>> file, and modify @file{configure.in} to use the
106 <<mt-XXX>> file (by setting "<<bfd_target=XXX>>") when your
107 configuration is selected.
112 * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
113 Doesn't matter what the setting of WP_TEXT is on output, but it'll
115 * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
116 * Any BFD with both flags clear is OMAGIC.
117 (Just want to make these explicit, so the conditions tested in this
118 file make sense if you're more familiar with a.out than with BFD.) */
121 #define KEEPITTYPE int
124 #include <string.h> /* For strchr and friends */
127 #include <ansidecl.h>
129 struct external_exec
;
132 #include "aout/aout64.h"
133 #include "aout/stab_gnu.h"
136 extern void (*bfd_error_trap
)();
143 The file @file{aoutx.h} provides for both the @emph{standard}
144 and @emph{extended} forms of a.out relocation records.
146 The standard records contain only an
147 address, a symbol index, and a type field. The extended records
148 (used on 29ks and sparcs) also have a full integer for an
152 #define CTOR_TABLE_RELOC_IDX 2
154 #define howto_table_ext NAME(aout,ext_howto_table)
155 #define howto_table_std NAME(aout,std_howto_table)
157 reloc_howto_type howto_table_ext
[] =
159 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
160 HOWTO(RELOC_8
, 0, 0, 8, false, 0, complain_overflow_bitfield
,0,"8", false, 0,0x000000ff, false),
161 HOWTO(RELOC_16
, 0, 1, 16, false, 0, complain_overflow_bitfield
,0,"16", false, 0,0x0000ffff, false),
162 HOWTO(RELOC_32
, 0, 2, 32, false, 0, complain_overflow_bitfield
,0,"32", false, 0,0xffffffff, false),
163 HOWTO(RELOC_DISP8
, 0, 0, 8, true, 0, complain_overflow_signed
,0,"DISP8", false, 0,0x000000ff, false),
164 HOWTO(RELOC_DISP16
, 0, 1, 16, true, 0, complain_overflow_signed
,0,"DISP16", false, 0,0x0000ffff, false),
165 HOWTO(RELOC_DISP32
, 0, 2, 32, true, 0, complain_overflow_signed
,0,"DISP32", false, 0,0xffffffff, false),
166 HOWTO(RELOC_WDISP30
,2, 2, 30, true, 0, complain_overflow_signed
,0,"WDISP30", false, 0,0x3fffffff, false),
167 HOWTO(RELOC_WDISP22
,2, 2, 22, true, 0, complain_overflow_signed
,0,"WDISP22", false, 0,0x003fffff, false),
168 HOWTO(RELOC_HI22
, 10, 2, 22, false, 0, complain_overflow_bitfield
,0,"HI22", false, 0,0x003fffff, false),
169 HOWTO(RELOC_22
, 0, 2, 22, false, 0, complain_overflow_bitfield
,0,"22", false, 0,0x003fffff, false),
170 HOWTO(RELOC_13
, 0, 2, 13, false, 0, complain_overflow_bitfield
,0,"13", false, 0,0x00001fff, false),
171 HOWTO(RELOC_LO10
, 0, 2, 10, false, 0, complain_overflow_dont
,0,"LO10", false, 0,0x000003ff, false),
172 HOWTO(RELOC_SFA_BASE
,0, 2, 32, false, 0, complain_overflow_bitfield
,0,"SFA_BASE", false, 0,0xffffffff, false),
173 HOWTO(RELOC_SFA_OFF13
,0,2, 32, false, 0, complain_overflow_bitfield
,0,"SFA_OFF13",false, 0,0xffffffff, false),
174 HOWTO(RELOC_BASE10
, 0, 2, 16, false, 0, complain_overflow_bitfield
,0,"BASE10", false, 0,0x0000ffff, false),
175 HOWTO(RELOC_BASE13
, 0, 2, 13, false, 0, complain_overflow_bitfield
,0,"BASE13", false, 0,0x00001fff, false),
176 HOWTO(RELOC_BASE22
, 0, 2, 0, false, 0, complain_overflow_bitfield
,0,"BASE22", false, 0,0x00000000, false),
177 HOWTO(RELOC_PC10
, 0, 2, 10, false, 0, complain_overflow_bitfield
,0,"PC10", false, 0,0x000003ff, false),
178 HOWTO(RELOC_PC22
, 0, 2, 22, false, 0, complain_overflow_bitfield
,0,"PC22", false, 0,0x003fffff, false),
179 HOWTO(RELOC_JMP_TBL
,0, 2, 32, false, 0, complain_overflow_bitfield
,0,"JMP_TBL", false, 0,0xffffffff, false),
180 HOWTO(RELOC_SEGOFF16
,0, 2, 0, false, 0, complain_overflow_bitfield
,0,"SEGOFF16", false, 0,0x00000000, false),
181 HOWTO(RELOC_GLOB_DAT
,0, 2, 0, false, 0, complain_overflow_bitfield
,0,"GLOB_DAT", false, 0,0x00000000, false),
182 HOWTO(RELOC_JMP_SLOT
,0, 2, 0, false, 0, complain_overflow_bitfield
,0,"JMP_SLOT", false, 0,0x00000000, false),
183 HOWTO(RELOC_RELATIVE
,0, 2, 0, false, 0, complain_overflow_bitfield
,0,"RELATIVE", false, 0,0x00000000, false),
186 /* Convert standard reloc records to "arelent" format (incl byte swap). */
188 reloc_howto_type howto_table_std
[] = {
189 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
190 HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield
,0,"8", true, 0x000000ff,0x000000ff, false),
191 HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield
,0,"16", true, 0x0000ffff,0x0000ffff, false),
192 HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield
,0,"32", true, 0xffffffff,0xffffffff, false),
193 HOWTO( 3, 0, 4, 64, false, 0, complain_overflow_bitfield
,0,"64", true, 0xdeaddead,0xdeaddead, false),
194 HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed
, 0,"DISP8", true, 0x000000ff,0x000000ff, false),
195 HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed
, 0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
196 HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed
, 0,"DISP32", true, 0xffffffff,0xffffffff, false),
197 HOWTO( 7, 0, 4, 64, true, 0, complain_overflow_signed
, 0,"DISP64", true, 0xfeedface,0xfeedface, false),
199 HOWTO( 9, 0, 1, 16, false, 0, complain_overflow_bitfield
,0,"BASE16", false,0xffffffff,0xffffffff, false),
200 HOWTO(10, 0, 2, 32, false, 0, complain_overflow_bitfield
,0,"BASE32", false,0xffffffff,0xffffffff, false),
203 #define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0]))
205 CONST
struct reloc_howto_struct
*
206 DEFUN(NAME(aout
,reloc_type_lookup
),(abfd
,code
),
208 bfd_reloc_code_real_type code
)
210 #define EXT(i,j) case i: return &howto_table_ext[j]
211 #define STD(i,j) case i: return &howto_table_std[j]
212 int ext
= obj_reloc_entry_size (abfd
) == RELOC_EXT_SIZE
;
213 if (code
== BFD_RELOC_CTOR
)
214 switch (bfd_get_arch_info (abfd
)->bits_per_address
)
223 EXT (BFD_RELOC_32
, 2);
224 EXT (BFD_RELOC_HI22
, 8);
225 EXT (BFD_RELOC_LO10
, 11);
226 EXT (BFD_RELOC_32_PCREL_S2
, 6);
227 EXT (BFD_RELOC_SPARC_WDISP22
, 7);
228 default: return (CONST
struct reloc_howto_struct
*) 0;
234 STD (BFD_RELOC_16
, 1);
235 STD (BFD_RELOC_32
, 2);
236 STD (BFD_RELOC_8_PCREL
, 4);
237 STD (BFD_RELOC_16_PCREL
, 5);
238 STD (BFD_RELOC_32_PCREL
, 6);
239 STD (BFD_RELOC_16_BASEREL
, 9);
240 STD (BFD_RELOC_32_BASEREL
, 10);
241 default: return (CONST
struct reloc_howto_struct
*) 0;
245 extern bfd_error_vector_type bfd_error_vector
;
249 Internal Entry Points
252 @file{aoutx.h} exports several routines for accessing the
253 contents of an a.out file, which are gathered and exported in
254 turn by various format specific files (eg sunos.c).
260 aout_@var{size}_swap_exec_header_in
263 void aout_@var{size}_swap_exec_header_in,
265 struct external_exec *raw_bytes,
266 struct internal_exec *execp);
269 Swap the information in an executable header @var{raw_bytes} taken
270 from a raw byte stream memory image into the internal exec header
271 structure @var{execp}.
274 #ifndef NAME_swap_exec_header_in
276 DEFUN(NAME(aout
,swap_exec_header_in
),(abfd
, raw_bytes
, execp
),
278 struct external_exec
*raw_bytes AND
279 struct internal_exec
*execp
)
281 struct external_exec
*bytes
= (struct external_exec
*)raw_bytes
;
283 /* The internal_exec structure has some fields that are unused in this
284 configuration (IE for i960), so ensure that all such uninitialized
285 fields are zero'd out. There are places where two of these structs
286 are memcmp'd, and thus the contents do matter. */
287 memset (execp
, 0, sizeof (struct internal_exec
));
288 /* Now fill in fields in the execp, from the bytes in the raw data. */
289 execp
->a_info
= bfd_h_get_32 (abfd
, bytes
->e_info
);
290 execp
->a_text
= GET_WORD (abfd
, bytes
->e_text
);
291 execp
->a_data
= GET_WORD (abfd
, bytes
->e_data
);
292 execp
->a_bss
= GET_WORD (abfd
, bytes
->e_bss
);
293 execp
->a_syms
= GET_WORD (abfd
, bytes
->e_syms
);
294 execp
->a_entry
= GET_WORD (abfd
, bytes
->e_entry
);
295 execp
->a_trsize
= GET_WORD (abfd
, bytes
->e_trsize
);
296 execp
->a_drsize
= GET_WORD (abfd
, bytes
->e_drsize
);
298 #define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
303 aout_@var{size}_swap_exec_header_out
306 void aout_@var{size}_swap_exec_header_out
308 struct internal_exec *execp,
309 struct external_exec *raw_bytes);
312 Swap the information in an internal exec header structure
313 @var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
316 DEFUN(NAME(aout
,swap_exec_header_out
),(abfd
, execp
, raw_bytes
),
318 struct internal_exec
*execp AND
319 struct external_exec
*raw_bytes
)
321 struct external_exec
*bytes
= (struct external_exec
*)raw_bytes
;
323 /* Now fill in fields in the raw data, from the fields in the exec struct. */
324 bfd_h_put_32 (abfd
, execp
->a_info
, bytes
->e_info
);
325 PUT_WORD (abfd
, execp
->a_text
, bytes
->e_text
);
326 PUT_WORD (abfd
, execp
->a_data
, bytes
->e_data
);
327 PUT_WORD (abfd
, execp
->a_bss
, bytes
->e_bss
);
328 PUT_WORD (abfd
, execp
->a_syms
, bytes
->e_syms
);
329 PUT_WORD (abfd
, execp
->a_entry
, bytes
->e_entry
);
330 PUT_WORD (abfd
, execp
->a_trsize
, bytes
->e_trsize
);
331 PUT_WORD (abfd
, execp
->a_drsize
, bytes
->e_drsize
);
338 aout_@var{size}_some_aout_object_p
341 bfd_target *aout_@var{size}_some_aout_object_p
343 bfd_target *(*callback_to_real_object_p)());
346 Some a.out variant thinks that the file open in @var{abfd}
347 checking is an a.out file. Do some more checking, and set up
348 for access if it really is. Call back to the calling
349 environment's "finish up" function just before returning, to
350 handle any last-minute setup.
354 DEFUN(NAME(aout
,some_aout_object_p
),(abfd
, execp
, callback_to_real_object_p
),
356 struct internal_exec
*execp AND
357 bfd_target
*(*callback_to_real_object_p
) PARAMS ((bfd
*)))
359 struct aout_data_struct
*rawptr
, *oldrawptr
;
362 rawptr
= (struct aout_data_struct
*) bfd_zalloc (abfd
, sizeof (struct aout_data_struct
));
363 if (rawptr
== NULL
) {
364 bfd_error
= no_memory
;
368 oldrawptr
= abfd
->tdata
.aout_data
;
369 abfd
->tdata
.aout_data
= rawptr
;
371 /* Copy the contents of the old tdata struct.
372 In particular, we want the subformat, since for hpux it was set in
373 hp300hpux.c:swap_exec_header_in and will be used in
374 hp300hpux.c:callback. */
375 if (oldrawptr
!= NULL
)
376 *abfd
->tdata
.aout_data
= *oldrawptr
;
378 abfd
->tdata
.aout_data
->a
.hdr
= &rawptr
->e
;
379 *(abfd
->tdata
.aout_data
->a
.hdr
) = *execp
; /* Copy in the internal_exec struct */
380 execp
= abfd
->tdata
.aout_data
->a
.hdr
;
382 /* Set the file flags */
383 abfd
->flags
= NO_FLAGS
;
384 if (execp
->a_drsize
|| execp
->a_trsize
)
385 abfd
->flags
|= HAS_RELOC
;
386 /* Setting of EXEC_P has been deferred to the bottom of this function */
388 abfd
->flags
|= HAS_LINENO
| HAS_DEBUG
| HAS_SYMS
| HAS_LOCALS
;
390 if (N_MAGIC (*execp
) == ZMAGIC
)
392 abfd
->flags
|= D_PAGED
|WP_TEXT
;
393 adata(abfd
).magic
= z_magic
;
395 else if (N_MAGIC (*execp
) == NMAGIC
)
397 abfd
->flags
|= WP_TEXT
;
398 adata(abfd
).magic
= n_magic
;
401 adata(abfd
).magic
= o_magic
;
403 bfd_get_start_address (abfd
) = execp
->a_entry
;
405 obj_aout_symbols (abfd
) = (aout_symbol_type
*)NULL
;
406 bfd_get_symcount (abfd
) = execp
->a_syms
/ sizeof (struct external_nlist
);
408 /* The default relocation entry size is that of traditional V7 Unix. */
409 obj_reloc_entry_size (abfd
) = RELOC_STD_SIZE
;
411 /* The default symbol entry size is that of traditional Unix. */
412 obj_symbol_entry_size (abfd
) = EXTERNAL_NLIST_SIZE
;
414 /* Create the sections. This is raunchy, but bfd_close wants to reclaim
417 obj_textsec (abfd
) = bfd_make_section_old_way (abfd
, ".text");
418 obj_datasec (abfd
) = bfd_make_section_old_way (abfd
, ".data");
419 obj_bsssec (abfd
) = bfd_make_section_old_way (abfd
, ".bss");
422 (void)bfd_make_section (abfd
, ".text");
423 (void)bfd_make_section (abfd
, ".data");
424 (void)bfd_make_section (abfd
, ".bss");
427 obj_datasec (abfd
)->_raw_size
= execp
->a_data
;
428 obj_bsssec (abfd
)->_raw_size
= execp
->a_bss
;
430 obj_textsec (abfd
)->flags
= (execp
->a_trsize
!= 0 ?
431 (SEC_ALLOC
| SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
| SEC_RELOC
) :
432 (SEC_ALLOC
| SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
));
433 obj_datasec (abfd
)->flags
= (execp
->a_drsize
!= 0 ?
434 (SEC_ALLOC
| SEC_LOAD
| SEC_DATA
| SEC_HAS_CONTENTS
| SEC_RELOC
) :
435 (SEC_ALLOC
| SEC_LOAD
| SEC_DATA
| SEC_HAS_CONTENTS
));
436 obj_bsssec (abfd
)->flags
= SEC_ALLOC
;
438 #ifdef THIS_IS_ONLY_DOCUMENTATION
439 /* The common code can't fill in these things because they depend
440 on either the start address of the text segment, the rounding
441 up of virtual addersses between segments, or the starting file
442 position of the text segment -- all of which varies among different
443 versions of a.out. */
445 /* Call back to the format-dependent code to fill in the rest of the
446 fields and do any further cleanup. Things that should be filled
447 in by the callback: */
449 struct exec
*execp
= exec_hdr (abfd
);
451 obj_textsec (abfd
)->size
= N_TXTSIZE(*execp
);
452 obj_textsec (abfd
)->raw_size
= N_TXTSIZE(*execp
);
453 /* data and bss are already filled in since they're so standard */
455 /* The virtual memory addresses of the sections */
456 obj_textsec (abfd
)->vma
= N_TXTADDR(*execp
);
457 obj_datasec (abfd
)->vma
= N_DATADDR(*execp
);
458 obj_bsssec (abfd
)->vma
= N_BSSADDR(*execp
);
460 /* The file offsets of the sections */
461 obj_textsec (abfd
)->filepos
= N_TXTOFF(*execp
);
462 obj_datasec (abfd
)->filepos
= N_DATOFF(*execp
);
464 /* The file offsets of the relocation info */
465 obj_textsec (abfd
)->rel_filepos
= N_TRELOFF(*execp
);
466 obj_datasec (abfd
)->rel_filepos
= N_DRELOFF(*execp
);
468 /* The file offsets of the string table and symbol table. */
469 obj_str_filepos (abfd
) = N_STROFF (*execp
);
470 obj_sym_filepos (abfd
) = N_SYMOFF (*execp
);
472 /* Determine the architecture and machine type of the object file. */
473 switch (N_MACHTYPE (*exec_hdr (abfd
))) {
475 abfd
->obj_arch
= bfd_arch_obscure
;
479 adata(abfd
)->page_size
= PAGE_SIZE
;
480 adata(abfd
)->segment_size
= SEGMENT_SIZE
;
481 adata(abfd
)->exec_bytes_size
= EXEC_BYTES_SIZE
;
485 /* The architecture is encoded in various ways in various a.out variants,
486 or is not encoded at all in some of them. The relocation size depends
487 on the architecture and the a.out variant. Finally, the return value
488 is the bfd_target vector in use. If an error occurs, return zero and
489 set bfd_error to the appropriate error code.
491 Formats such as b.out, which have additional fields in the a.out
492 header, should cope with them in this callback as well. */
493 #endif /* DOCUMENTATION */
495 result
= (*callback_to_real_object_p
)(abfd
);
497 /* Now that the segment addresses have been worked out, take a better
498 guess at whether the file is executable. If the entry point
499 is within the text segment, assume it is. (This makes files
500 executable even if their entry point address is 0, as long as
501 their text starts at zero.)
503 At some point we should probably break down and stat the file and
504 declare it executable if (one of) its 'x' bits are on... */
505 if ((execp
->a_entry
>= obj_textsec(abfd
)->vma
) &&
506 (execp
->a_entry
< obj_textsec(abfd
)->vma
+ obj_textsec(abfd
)->_raw_size
))
507 abfd
->flags
|= EXEC_P
;
510 #if 0 /* These should be set correctly anyways. */
511 abfd
->sections
= obj_textsec (abfd
);
512 obj_textsec (abfd
)->next
= obj_datasec (abfd
);
513 obj_datasec (abfd
)->next
= obj_bsssec (abfd
);
519 abfd
->tdata
.aout_data
= oldrawptr
;
526 aout_@var{size}_mkobject
529 boolean aout_@var{size}_mkobject, (bfd *abfd);
532 Initialize BFD @var{abfd} for use with a.out files.
536 DEFUN(NAME(aout
,mkobject
),(abfd
),
539 struct aout_data_struct
*rawptr
;
541 bfd_error
= system_call_error
;
543 /* Use an intermediate variable for clarity */
544 rawptr
= (struct aout_data_struct
*)bfd_zalloc (abfd
, sizeof (struct aout_data_struct
));
546 if (rawptr
== NULL
) {
547 bfd_error
= no_memory
;
551 abfd
->tdata
.aout_data
= rawptr
;
552 exec_hdr (abfd
) = &(rawptr
->e
);
554 /* For simplicity's sake we just make all the sections right here. */
556 obj_textsec (abfd
) = (asection
*)NULL
;
557 obj_datasec (abfd
) = (asection
*)NULL
;
558 obj_bsssec (abfd
) = (asection
*)NULL
;
559 bfd_make_section (abfd
, ".text");
560 bfd_make_section (abfd
, ".data");
561 bfd_make_section (abfd
, ".bss");
562 bfd_make_section (abfd
, BFD_ABS_SECTION_NAME
);
563 bfd_make_section (abfd
, BFD_UND_SECTION_NAME
);
564 bfd_make_section (abfd
, BFD_COM_SECTION_NAME
);
572 aout_@var{size}_machine_type
575 enum machine_type aout_@var{size}_machine_type
576 (enum bfd_architecture arch,
577 unsigned long machine));
580 Keep track of machine architecture and machine type for
581 a.out's. Return the <<machine_type>> for a particular
582 architecture and machine, or <<M_UNKNOWN>> if that exact architecture
583 and machine can't be represented in a.out format.
585 If the architecture is understood, machine type 0 (default)
586 is always understood.
590 DEFUN(NAME(aout
,machine_type
),(arch
, machine
),
591 enum bfd_architecture arch AND
592 unsigned long machine
)
594 enum machine_type arch_flags
;
596 arch_flags
= M_UNKNOWN
;
600 if (machine
== 0) arch_flags
= M_SPARC
;
605 case 0: arch_flags
= M_68010
; break;
606 case 68000: arch_flags
= M_UNKNOWN
; break;
607 case 68010: arch_flags
= M_68010
; break;
608 case 68020: arch_flags
= M_68020
; break;
609 default: arch_flags
= M_UNKNOWN
; break;
614 if (machine
== 0) arch_flags
= M_386
;
618 if (machine
== 0) arch_flags
= M_29K
;
625 case 3000: arch_flags
= M_MIPS1
; break;
628 case 6000: arch_flags
= M_MIPS2
; break;
629 default: arch_flags
= M_UNKNOWN
; break;
634 arch_flags
= M_UNKNOWN
;
642 aout_@var{size}_set_arch_mach
645 boolean aout_@var{size}_set_arch_mach,
647 enum bfd_architecture arch,
648 unsigned long machine));
651 Set the architecture and the machine of the BFD @var{abfd} to the
652 values @var{arch} and @var{machine}. Verify that @var{abfd}'s format
653 can support the architecture required.
657 DEFUN(NAME(aout
,set_arch_mach
),(abfd
, arch
, machine
),
659 enum bfd_architecture arch AND
660 unsigned long machine
)
662 if (! bfd_default_set_arch_mach (abfd
, arch
, machine
))
665 if (arch
!= bfd_arch_unknown
&&
666 NAME(aout
,machine_type
) (arch
, machine
) == M_UNKNOWN
)
667 return false; /* We can't represent this type */
669 /* Determine the size of a relocation entry */
674 obj_reloc_entry_size (abfd
) = RELOC_EXT_SIZE
;
677 obj_reloc_entry_size (abfd
) = RELOC_STD_SIZE
;
681 return (*aout_backend_info(abfd
)->set_sizes
) (abfd
);
685 DEFUN (NAME (aout
,adjust_sizes_and_vmas
), (abfd
, text_size
, text_end
),
686 bfd
*abfd AND bfd_size_type
*text_size AND file_ptr
*text_end
)
688 struct internal_exec
*execp
= exec_hdr (abfd
);
689 if ((obj_textsec (abfd
) == NULL
) || (obj_datasec (abfd
) == NULL
))
691 bfd_error
= invalid_operation
;
694 if (adata(abfd
).magic
!= undecided_magic
) return true;
695 obj_textsec(abfd
)->_raw_size
=
696 align_power(obj_textsec(abfd
)->_raw_size
,
697 obj_textsec(abfd
)->alignment_power
);
699 *text_size
= obj_textsec (abfd
)->_raw_size
;
700 /* Rule (heuristic) for when to pad to a new page. Note that there
701 * are (at least) two ways demand-paged (ZMAGIC) files have been
702 * handled. Most Berkeley-based systems start the text segment at
703 * (PAGE_SIZE). However, newer versions of SUNOS start the text
704 * segment right after the exec header; the latter is counted in the
705 * text segment size, and is paged in by the kernel with the rest of
708 /* This perhaps isn't the right way to do this, but made it simpler for me
709 to understand enough to implement it. Better would probably be to go
710 right from BFD flags to alignment/positioning characteristics. But the
711 old code was sloppy enough about handling the flags, and had enough
712 other magic, that it was a little hard for me to understand. I think
713 I understand it better now, but I haven't time to do the cleanup this
715 if (adata(abfd
).magic
== undecided_magic
)
717 if (abfd
->flags
& D_PAGED
)
718 /* Whether or not WP_TEXT is set -- let D_PAGED override. */
719 /* @@ What about QMAGIC? */
720 adata(abfd
).magic
= z_magic
;
721 else if (abfd
->flags
& WP_TEXT
)
722 adata(abfd
).magic
= n_magic
;
724 adata(abfd
).magic
= o_magic
;
727 #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
729 fprintf (stderr
, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
731 switch (adata(abfd
).magic
) {
732 case n_magic
: str
= "NMAGIC"; break;
733 case o_magic
: str
= "OMAGIC"; break;
734 case z_magic
: str
= "ZMAGIC"; break;
739 obj_textsec(abfd
)->vma
, obj_textsec(abfd
)->_raw_size
, obj_textsec(abfd
)->alignment_power
,
740 obj_datasec(abfd
)->vma
, obj_datasec(abfd
)->_raw_size
, obj_datasec(abfd
)->alignment_power
,
741 obj_bsssec(abfd
)->vma
, obj_bsssec(abfd
)->_raw_size
, obj_bsssec(abfd
)->alignment_power
);
745 switch (adata(abfd
).magic
)
749 file_ptr pos
= adata (abfd
).exec_bytes_size
;
753 obj_textsec(abfd
)->filepos
= pos
;
754 pos
+= obj_textsec(abfd
)->_raw_size
;
755 vma
+= obj_textsec(abfd
)->_raw_size
;
756 if (!obj_datasec(abfd
)->user_set_vma
)
758 #if 0 /* ?? Does alignment in the file image really matter? */
759 pad
= align_power (vma
, obj_datasec(abfd
)->alignment_power
) - vma
;
761 obj_textsec(abfd
)->_raw_size
+= pad
;
764 obj_datasec(abfd
)->vma
= vma
;
766 obj_datasec(abfd
)->filepos
= pos
;
767 pos
+= obj_datasec(abfd
)->_raw_size
;
768 vma
+= obj_datasec(abfd
)->_raw_size
;
769 if (!obj_bsssec(abfd
)->user_set_vma
)
772 pad
= align_power (vma
, obj_bsssec(abfd
)->alignment_power
) - vma
;
774 obj_datasec(abfd
)->_raw_size
+= pad
;
777 obj_bsssec(abfd
)->vma
= vma
;
779 obj_bsssec(abfd
)->filepos
= pos
;
780 execp
->a_text
= obj_textsec(abfd
)->_raw_size
;
781 execp
->a_data
= obj_datasec(abfd
)->_raw_size
;
782 execp
->a_bss
= obj_bsssec(abfd
)->_raw_size
;
783 N_SET_MAGIC (*execp
, OMAGIC
);
788 bfd_size_type data_pad
, text_pad
;
790 CONST
struct aout_backend_data
*abdp
;
794 abdp
= aout_backend_info (abfd
);
795 ztih
= abdp
&& abdp
->text_includes_header
;
796 obj_textsec(abfd
)->filepos
= (ztih
797 ? adata(abfd
).exec_bytes_size
798 : adata(abfd
).page_size
);
799 if (! obj_textsec(abfd
)->user_set_vma
)
800 /* ?? Do we really need to check for relocs here? */
801 obj_textsec(abfd
)->vma
= ((abfd
->flags
& HAS_RELOC
)
804 ? (abdp
->default_text_vma
805 + adata(abfd
).exec_bytes_size
)
806 : abdp
->default_text_vma
));
807 /* Could take strange alignment of text section into account here? */
809 /* Find start of data. */
810 text_end
= obj_textsec(abfd
)->filepos
+ obj_textsec(abfd
)->_raw_size
;
811 text_pad
= BFD_ALIGN (text_end
, adata(abfd
).page_size
) - text_end
;
812 obj_textsec(abfd
)->_raw_size
+= text_pad
;
813 text_end
+= text_pad
;
815 if (!obj_datasec(abfd
)->user_set_vma
)
818 vma
= obj_textsec(abfd
)->vma
+ obj_textsec(abfd
)->_raw_size
;
819 obj_datasec(abfd
)->vma
= BFD_ALIGN (vma
, adata(abfd
).segment_size
);
821 data_vma
= obj_datasec(abfd
)->vma
;
822 if (abdp
&& abdp
->zmagic_mapped_contiguous
)
824 text_pad
= (obj_datasec(abfd
)->vma
825 - obj_textsec(abfd
)->vma
826 - obj_textsec(abfd
)->_raw_size
);
827 obj_textsec(abfd
)->_raw_size
+= text_pad
;
829 obj_datasec(abfd
)->filepos
= (obj_textsec(abfd
)->filepos
830 + obj_textsec(abfd
)->_raw_size
);
832 /* Fix up exec header while we're at it. */
833 execp
->a_text
= obj_textsec(abfd
)->_raw_size
;
834 if (ztih
&& (!abdp
|| (abdp
&& !abdp
->exec_header_not_counted
)))
835 execp
->a_text
+= adata(abfd
).exec_bytes_size
;
836 N_SET_MAGIC (*execp
, ZMAGIC
);
837 /* Spec says data section should be rounded up to page boundary. */
838 /* If extra space in page is left after data section, fudge data
839 in the header so that the bss section looks smaller by that
840 amount. We'll start the bss section there, and lie to the OS. */
841 obj_datasec(abfd
)->_raw_size
842 = align_power (obj_datasec(abfd
)->_raw_size
,
843 obj_bsssec(abfd
)->alignment_power
);
844 execp
->a_data
= BFD_ALIGN (obj_datasec(abfd
)->_raw_size
,
845 adata(abfd
).page_size
);
846 data_pad
= execp
->a_data
- obj_datasec(abfd
)->_raw_size
;
848 if (!obj_bsssec(abfd
)->user_set_vma
)
849 obj_bsssec(abfd
)->vma
= (obj_datasec(abfd
)->vma
850 + obj_datasec(abfd
)->_raw_size
);
851 if (data_pad
> obj_bsssec(abfd
)->_raw_size
)
854 execp
->a_bss
= obj_bsssec(abfd
)->_raw_size
- data_pad
;
859 file_ptr pos
= adata(abfd
).exec_bytes_size
;
863 obj_textsec(abfd
)->filepos
= pos
;
864 if (!obj_textsec(abfd
)->user_set_vma
)
865 obj_textsec(abfd
)->vma
= vma
;
867 vma
= obj_textsec(abfd
)->vma
;
868 pos
+= obj_textsec(abfd
)->_raw_size
;
869 vma
+= obj_textsec(abfd
)->_raw_size
;
870 obj_datasec(abfd
)->filepos
= pos
;
871 if (!obj_datasec(abfd
)->user_set_vma
)
872 obj_datasec(abfd
)->vma
= BFD_ALIGN (vma
, adata(abfd
).segment_size
);
873 vma
= obj_datasec(abfd
)->vma
;
875 /* Since BSS follows data immediately, see if it needs alignment. */
876 vma
+= obj_datasec(abfd
)->_raw_size
;
877 pad
= align_power (vma
, obj_bsssec(abfd
)->alignment_power
) - vma
;
878 obj_datasec(abfd
)->_raw_size
+= pad
;
879 pos
+= obj_datasec(abfd
)->_raw_size
;
881 if (!obj_bsssec(abfd
)->user_set_vma
)
882 obj_bsssec(abfd
)->vma
= vma
;
884 vma
= obj_bsssec(abfd
)->vma
;
886 execp
->a_text
= obj_textsec(abfd
)->_raw_size
;
887 execp
->a_data
= obj_datasec(abfd
)->_raw_size
;
888 execp
->a_bss
= obj_bsssec(abfd
)->_raw_size
;
889 N_SET_MAGIC (*execp
, NMAGIC
);
894 #ifdef BFD_AOUT_DEBUG
895 fprintf (stderr
, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
896 obj_textsec(abfd
)->vma
, obj_textsec(abfd
)->_raw_size
, obj_textsec(abfd
)->filepos
,
897 obj_datasec(abfd
)->vma
, obj_datasec(abfd
)->_raw_size
, obj_datasec(abfd
)->filepos
,
898 obj_bsssec(abfd
)->vma
, obj_bsssec(abfd
)->_raw_size
);
905 aout_@var{size}_new_section_hook
908 boolean aout_@var{size}_new_section_hook,
913 Called by the BFD in response to a @code{bfd_make_section}
917 DEFUN(NAME(aout
,new_section_hook
),(abfd
, newsect
),
921 /* align to double at least */
922 newsect
->alignment_power
= bfd_get_arch_info(abfd
)->section_align_power
;
925 if (bfd_get_format (abfd
) == bfd_object
)
927 if (obj_textsec(abfd
) == NULL
&& !strcmp(newsect
->name
, ".text")) {
928 obj_textsec(abfd
)= newsect
;
929 newsect
->target_index
= N_TEXT
| N_EXT
;
933 if (obj_datasec(abfd
) == NULL
&& !strcmp(newsect
->name
, ".data")) {
934 obj_datasec(abfd
) = newsect
;
935 newsect
->target_index
= N_DATA
| N_EXT
;
939 if (obj_bsssec(abfd
) == NULL
&& !strcmp(newsect
->name
, ".bss")) {
940 obj_bsssec(abfd
) = newsect
;
941 newsect
->target_index
= N_BSS
| N_EXT
;
947 /* We allow more than three sections internally */
952 DEFUN(NAME(aout
,set_section_contents
),(abfd
, section
, location
, offset
, count
),
960 bfd_size_type text_size
;
962 if (abfd
->output_has_begun
== false)
964 if (NAME(aout
,adjust_sizes_and_vmas
) (abfd
,
970 /* regardless, once we know what we're doing, we might as well get going */
971 if (section
!= obj_bsssec(abfd
))
973 bfd_seek (abfd
, section
->filepos
+ offset
, SEEK_SET
);
976 return (bfd_write ((PTR
)location
, 1, count
, abfd
) == count
) ?
984 /* Classify stabs symbols */
986 #define sym_in_text_section(sym) \
987 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
989 #define sym_in_data_section(sym) \
990 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
992 #define sym_in_bss_section(sym) \
993 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
995 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
996 zero in the "value" field. Nonzeroes there are fortrancommon
998 #define sym_is_undefined(sym) \
999 ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
1001 /* Symbol is a global definition if N_EXT is on and if it has
1002 a nonzero type field. */
1003 #define sym_is_global_defn(sym) \
1004 (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
1006 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
1008 #define sym_is_debugger_info(sym) \
1009 (((sym)->type & ~(N_EXT | N_TYPE)) || (sym)->type == N_FN)
1011 #define sym_is_fortrancommon(sym) \
1012 (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
1014 /* Symbol is absolute if it has N_ABS set */
1015 #define sym_is_absolute(sym) \
1016 (((sym)->type & N_TYPE)== N_ABS)
1019 #define sym_is_indirect(sym) \
1020 (((sym)->type & N_ABS)== N_ABS)
1022 /* Only in their own functions for ease of debugging; when sym flags have
1023 stabilised these should be inlined into their (single) caller */
1026 DEFUN (translate_from_native_sym_flags
, (sym_pointer
, cache_ptr
, abfd
),
1027 struct external_nlist
*sym_pointer AND
1028 aout_symbol_type
* cache_ptr AND
1031 cache_ptr
->symbol
.section
= 0;
1032 switch (cache_ptr
->type
& N_TYPE
)
1039 char *copy
= bfd_alloc (abfd
, strlen (cache_ptr
->symbol
.name
) + 1);
1041 asection
*into_section
;
1043 arelent_chain
*reloc
= (arelent_chain
*) bfd_alloc (abfd
, sizeof (arelent_chain
));
1044 strcpy (copy
, cache_ptr
->symbol
.name
);
1046 /* Make sure that this bfd has a section with the right contructor
1048 section
= bfd_get_section_by_name (abfd
, copy
);
1050 section
= bfd_make_section (abfd
, copy
);
1052 /* Build a relocation entry for the constructor */
1053 switch ((cache_ptr
->type
& N_TYPE
))
1056 into_section
= &bfd_abs_section
;
1057 cache_ptr
->type
= N_ABS
;
1060 into_section
= (asection
*) obj_textsec (abfd
);
1061 cache_ptr
->type
= N_TEXT
;
1064 into_section
= (asection
*) obj_datasec (abfd
);
1065 cache_ptr
->type
= N_DATA
;
1068 into_section
= (asection
*) obj_bsssec (abfd
);
1069 cache_ptr
->type
= N_BSS
;
1075 /* Build a relocation pointing into the constuctor section
1076 pointing at the symbol in the set vector specified */
1078 reloc
->relent
.addend
= cache_ptr
->symbol
.value
;
1079 cache_ptr
->symbol
.section
= into_section
->symbol
->section
;
1080 reloc
->relent
.sym_ptr_ptr
= into_section
->symbol_ptr_ptr
;
1083 /* We modify the symbol to belong to a section depending upon the
1084 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
1085 really care, and add to the size of the section to contain a
1086 pointer to the symbol. Build a reloc entry to relocate to this
1087 symbol attached to this section. */
1089 section
->flags
= SEC_CONSTRUCTOR
;
1092 section
->reloc_count
++;
1093 section
->alignment_power
= 2;
1095 reloc
->next
= section
->constructor_chain
;
1096 section
->constructor_chain
= reloc
;
1097 reloc
->relent
.address
= section
->_raw_size
;
1098 section
->_raw_size
+= sizeof (int *);
1101 = (obj_reloc_entry_size(abfd
) == RELOC_EXT_SIZE
1102 ? howto_table_ext
: howto_table_std
)
1103 + CTOR_TABLE_RELOC_IDX
;
1104 cache_ptr
->symbol
.flags
|= BSF_CONSTRUCTOR
;
1108 if (cache_ptr
->type
== N_WARNING
)
1110 /* This symbol is the text of a warning message, the next symbol
1111 is the symbol to associate the warning with */
1112 cache_ptr
->symbol
.flags
= BSF_DEBUGGING
| BSF_WARNING
;
1114 /* @@ Stuffing pointers into integers is a no-no.
1115 We can usually get away with it if the integer is
1116 large enough though. */
1117 if (sizeof (cache_ptr
+ 1) > sizeof (bfd_vma
))
1119 cache_ptr
->symbol
.value
= (bfd_vma
) ((cache_ptr
+ 1));
1121 /* We furgle with the next symbol in place.
1122 We don't want it to be undefined, we'll trample the type */
1123 (sym_pointer
+ 1)->e_type
[0] = 0xff;
1126 if ((cache_ptr
->type
| N_EXT
) == (N_INDR
| N_EXT
))
1128 /* Two symbols in a row for an INDR message. The first symbol
1129 contains the name we will match, the second symbol contains
1130 the name the first name is translated into. It is supplied to
1131 us undefined. This is good, since we want to pull in any files
1133 cache_ptr
->symbol
.flags
= BSF_DEBUGGING
| BSF_INDIRECT
;
1135 /* @@ Stuffing pointers into integers is a no-no.
1136 We can usually get away with it if the integer is
1137 large enough though. */
1138 if (sizeof (cache_ptr
+ 1) > sizeof (bfd_vma
))
1141 cache_ptr
->symbol
.value
= (bfd_vma
) ((cache_ptr
+ 1));
1142 cache_ptr
->symbol
.section
= &bfd_ind_section
;
1145 else if (sym_is_debugger_info (cache_ptr
))
1147 cache_ptr
->symbol
.flags
= BSF_DEBUGGING
;
1148 /* Work out the section correct for this symbol */
1149 switch (cache_ptr
->type
& N_TYPE
)
1153 cache_ptr
->symbol
.section
= obj_textsec (abfd
);
1154 cache_ptr
->symbol
.value
-= obj_textsec (abfd
)->vma
;
1157 cache_ptr
->symbol
.value
-= obj_datasec (abfd
)->vma
;
1158 cache_ptr
->symbol
.section
= obj_datasec (abfd
);
1161 cache_ptr
->symbol
.section
= obj_bsssec (abfd
);
1162 cache_ptr
->symbol
.value
-= obj_bsssec (abfd
)->vma
;
1167 cache_ptr
->symbol
.section
= &bfd_abs_section
;
1174 if (sym_is_fortrancommon (cache_ptr
))
1176 cache_ptr
->symbol
.flags
= 0;
1177 cache_ptr
->symbol
.section
= &bfd_com_section
;
1185 /* In a.out, the value of a symbol is always relative to the
1186 * start of the file, if this is a data symbol we'll subtract
1187 * the size of the text section to get the section relative
1188 * value. If this is a bss symbol (which would be strange)
1189 * we'll subtract the size of the previous two sections
1190 * to find the section relative address.
1193 if (sym_in_text_section (cache_ptr
))
1195 cache_ptr
->symbol
.value
-= obj_textsec (abfd
)->vma
;
1196 cache_ptr
->symbol
.section
= obj_textsec (abfd
);
1198 else if (sym_in_data_section (cache_ptr
))
1200 cache_ptr
->symbol
.value
-= obj_datasec (abfd
)->vma
;
1201 cache_ptr
->symbol
.section
= obj_datasec (abfd
);
1203 else if (sym_in_bss_section (cache_ptr
))
1205 cache_ptr
->symbol
.section
= obj_bsssec (abfd
);
1206 cache_ptr
->symbol
.value
-= obj_bsssec (abfd
)->vma
;
1208 else if (sym_is_undefined (cache_ptr
))
1210 cache_ptr
->symbol
.flags
= 0;
1211 cache_ptr
->symbol
.section
= &bfd_und_section
;
1213 else if (sym_is_absolute (cache_ptr
))
1215 cache_ptr
->symbol
.section
= &bfd_abs_section
;
1218 if (sym_is_global_defn (cache_ptr
))
1220 cache_ptr
->symbol
.flags
= BSF_GLOBAL
| BSF_EXPORT
;
1224 cache_ptr
->symbol
.flags
= BSF_LOCAL
;
1228 if (cache_ptr
->symbol
.section
== 0)
1235 DEFUN(translate_to_native_sym_flags
,(sym_pointer
, cache_ptr
, abfd
),
1236 struct external_nlist
*sym_pointer AND
1237 asymbol
*cache_ptr AND
1240 bfd_vma value
= cache_ptr
->value
;
1242 /* mask out any existing type bits in case copying from one section
1244 sym_pointer
->e_type
[0] &= ~N_TYPE
;
1247 /* We attempt to order these tests by decreasing frequency of success,
1248 according to tcov when linking the linker. */
1249 if (bfd_get_output_section(cache_ptr
) == &bfd_abs_section
) {
1250 sym_pointer
->e_type
[0] |= N_ABS
;
1252 else if (bfd_get_output_section(cache_ptr
) == obj_textsec (abfd
)) {
1253 sym_pointer
->e_type
[0] |= N_TEXT
;
1255 else if (bfd_get_output_section(cache_ptr
) == obj_datasec (abfd
)) {
1256 sym_pointer
->e_type
[0] |= N_DATA
;
1258 else if (bfd_get_output_section(cache_ptr
) == obj_bsssec (abfd
)) {
1259 sym_pointer
->e_type
[0] |= N_BSS
;
1261 else if (bfd_get_output_section(cache_ptr
) == &bfd_und_section
)
1263 sym_pointer
->e_type
[0] = (N_UNDF
| N_EXT
);
1265 else if (bfd_get_output_section(cache_ptr
) == &bfd_ind_section
)
1267 sym_pointer
->e_type
[0] = N_INDR
;
1269 else if (bfd_is_com_section (bfd_get_output_section (cache_ptr
))) {
1270 sym_pointer
->e_type
[0] = (N_UNDF
| N_EXT
);
1273 if (cache_ptr
->section
->output_section
)
1276 bfd_error_vector
.nonrepresentable_section(abfd
,
1277 bfd_get_output_section(cache_ptr
)->name
);
1281 bfd_error_vector
.nonrepresentable_section(abfd
,
1282 cache_ptr
->section
->name
);
1287 /* Turn the symbol from section relative to absolute again */
1289 value
+= cache_ptr
->section
->output_section
->vma
+ cache_ptr
->section
->output_offset
;
1292 if (cache_ptr
->flags
& (BSF_WARNING
)) {
1293 (sym_pointer
+1)->e_type
[0] = 1;
1296 if (cache_ptr
->flags
& BSF_DEBUGGING
) {
1297 sym_pointer
->e_type
[0] = ((aout_symbol_type
*)cache_ptr
)->type
;
1299 else if (cache_ptr
->flags
& (BSF_GLOBAL
| BSF_EXPORT
)) {
1300 sym_pointer
->e_type
[0] |= N_EXT
;
1302 if (cache_ptr
->flags
& BSF_CONSTRUCTOR
) {
1303 int type
= ((aout_symbol_type
*)cache_ptr
)->type
;
1306 case N_ABS
: type
= N_SETA
; break;
1307 case N_TEXT
: type
= N_SETT
; break;
1308 case N_DATA
: type
= N_SETD
; break;
1309 case N_BSS
: type
= N_SETB
; break;
1311 sym_pointer
->e_type
[0] = type
;
1314 PUT_WORD(abfd
, value
, sym_pointer
->e_value
);
1317 /* Native-level interface to symbols. */
1319 /* We read the symbols into a buffer, which is discarded when this
1320 function exits. We read the strings into a buffer large enough to
1321 hold them all plus all the cached symbol entries. */
1324 DEFUN(NAME(aout
,make_empty_symbol
),(abfd
),
1327 aout_symbol_type
*new =
1328 (aout_symbol_type
*)bfd_zalloc (abfd
, sizeof (aout_symbol_type
));
1329 new->symbol
.the_bfd
= abfd
;
1331 return &new->symbol
;
1335 DEFUN(NAME(aout
,slurp_symbol_table
),(abfd
),
1338 bfd_size_type symbol_size
;
1339 bfd_size_type string_size
;
1340 unsigned char string_chars
[BYTES_IN_WORD
];
1341 struct external_nlist
*syms
;
1343 aout_symbol_type
*cached
;
1345 /* If there's no work to be done, don't do any */
1346 if (obj_aout_symbols (abfd
) != (aout_symbol_type
*)NULL
) return true;
1347 symbol_size
= exec_hdr(abfd
)->a_syms
;
1348 if (symbol_size
== 0)
1350 bfd_error
= no_symbols
;
1354 bfd_seek (abfd
, obj_str_filepos (abfd
), SEEK_SET
);
1355 if (bfd_read ((PTR
)string_chars
, BYTES_IN_WORD
, 1, abfd
) != BYTES_IN_WORD
)
1357 string_size
= GET_WORD (abfd
, string_chars
);
1359 strings
=(char *) bfd_alloc(abfd
, string_size
+ 1);
1360 cached
= (aout_symbol_type
*)
1361 bfd_zalloc(abfd
, (bfd_size_type
)(bfd_get_symcount (abfd
) * sizeof(aout_symbol_type
)));
1363 /* malloc this, so we can free it if simply. The symbol caching
1364 might want to allocate onto the bfd's obstack */
1365 syms
= (struct external_nlist
*) bfd_xmalloc(symbol_size
);
1366 bfd_seek (abfd
, obj_sym_filepos (abfd
), SEEK_SET
);
1367 if (bfd_read ((PTR
)syms
, 1, symbol_size
, abfd
) != symbol_size
)
1373 bfd_release (abfd
, cached
);
1375 bfd_release (abfd
, strings
);
1379 bfd_seek (abfd
, obj_str_filepos (abfd
), SEEK_SET
);
1380 if (bfd_read ((PTR
)strings
, 1, string_size
, abfd
) != string_size
)
1384 strings
[string_size
] = 0; /* Just in case. */
1386 /* OK, now walk the new symtable, cacheing symbol properties */
1388 register struct external_nlist
*sym_pointer
;
1389 register struct external_nlist
*sym_end
= syms
+ bfd_get_symcount (abfd
);
1390 register aout_symbol_type
*cache_ptr
= cached
;
1392 /* Run through table and copy values */
1393 for (sym_pointer
= syms
, cache_ptr
= cached
;
1394 sym_pointer
< sym_end
; sym_pointer
++, cache_ptr
++)
1396 long x
= GET_WORD(abfd
, sym_pointer
->e_strx
);
1397 cache_ptr
->symbol
.the_bfd
= abfd
;
1399 cache_ptr
->symbol
.name
= "";
1400 else if (x
>= 0 && x
< string_size
)
1401 cache_ptr
->symbol
.name
= x
+ strings
;
1405 cache_ptr
->symbol
.value
= GET_SWORD(abfd
, sym_pointer
->e_value
);
1406 cache_ptr
->desc
= bfd_h_get_16(abfd
, sym_pointer
->e_desc
);
1407 cache_ptr
->other
= bfd_h_get_8(abfd
, sym_pointer
->e_other
);
1408 cache_ptr
->type
= bfd_h_get_8(abfd
, sym_pointer
->e_type
);
1409 cache_ptr
->symbol
.udata
= 0;
1410 translate_from_native_sym_flags (sym_pointer
, cache_ptr
, abfd
);
1414 obj_aout_symbols (abfd
) = cached
;
1421 /* Possible improvements:
1422 + look for strings matching trailing substrings of other strings
1423 + better data structures? balanced trees?
1424 + smaller per-string or per-symbol data? re-use some of the symbol's
1426 + also look at reducing memory use elsewhere -- maybe if we didn't have to
1427 construct the entire symbol table at once, we could get by with smaller
1428 amounts of VM? (What effect does that have on the string table
1430 + rip this out of here, put it into its own file in bfd or libiberty, so
1431 coff and elf can use it too. I'll work on this soon, but have more
1432 pressing tasks right now.
1434 A hash table might(?) be more efficient for handling exactly the cases that
1435 are handled now, but for trailing substring matches, I think we want to
1436 examine the `nearest' values (reverse-)lexically, not merely impose a strict
1437 order, nor look only for exact-match or not-match. I don't think a hash
1438 table would be very useful for that, and I don't feel like fleshing out two
1439 completely different implementations. [raeburn:930419.0331EDT] */
1441 struct stringtab_entry
{
1442 /* Hash value for this string. Only useful so long as we aren't doing
1443 substring matches. */
1446 /* Next node to look at, depending on whether the hash value of the string
1447 being searched for is less than or greater than the hash value of the
1448 current node. For now, `equal to' is lumped in with `greater than', for
1449 space efficiency. It's not a common enough case to warrant another field
1450 to be used for all nodes. */
1451 struct stringtab_entry
*less
;
1452 struct stringtab_entry
*greater
;
1454 /* The string itself. */
1457 /* The index allocated for this string. */
1458 bfd_size_type index
;
1460 #ifdef GATHER_STATISTICS
1461 /* How many references have there been to this string? (Not currently used;
1462 could be dumped out for anaylsis, if anyone's interested.) */
1463 unsigned long count
;
1466 /* Next node in linked list, in suggested output order. */
1467 struct stringtab_entry
*next_to_output
;
1470 struct stringtab_data
{
1471 /* Tree of string table entries. */
1472 struct stringtab_entry
*strings
;
1474 /* Fudge factor used to center top node of tree. */
1477 /* Next index value to issue. */
1478 bfd_size_type index
;
1480 /* Index used for empty strings. Cached here because checking for them
1481 is really easy, and we can avoid searching the tree. */
1482 bfd_size_type empty_string_index
;
1484 /* These fields indicate the two ends of a singly-linked list that indicates
1485 the order strings should be written out in. Use this order, and no
1486 seeking will need to be done, so output efficiency should be maximized. */
1487 struct stringtab_entry
**end
;
1488 struct stringtab_entry
*output_order
;
1490 #ifdef GATHER_STATISTICS
1491 /* Number of strings which duplicate strings already in the table. */
1492 unsigned long duplicates
;
1494 /* Number of bytes saved by not having to write all the duplicate strings. */
1495 unsigned long bytes_saved
;
1497 /* Number of zero-length strings. Currently, these all turn into
1498 references to the null byte at the end of the first string. In some
1499 cases (possibly not all? explore this...), it should be possible to
1500 simply write out a zero index value. */
1501 unsigned long empty_strings
;
1503 /* Number of times the hash values matched but the strings were different.
1504 Note that this includes the number of times the other string(s) occurs, so
1505 there may only be two strings hashing to the same value, even if this
1506 number is very large. */
1507 unsigned long bad_hash_matches
;
1509 /* Null strings aren't counted in this one.
1510 This will probably only be nonzero if we've got an input file
1511 which was produced by `ld -r' (i.e., it's already been processed
1512 through this code). Under some operating systems, native tools
1513 may make all empty strings have the same index; but the pointer
1514 check won't catch those, because to get to that stage we'd already
1515 have to compute the checksum, which requires reading the string,
1516 so we short-circuit that case with empty_string_index above. */
1517 unsigned long pointer_matches
;
1519 /* Number of comparisons done. I figure with the algorithms in use below,
1520 the average number of comparisons done (per symbol) should be roughly
1521 log-base-2 of the number of unique strings. */
1522 unsigned long n_compares
;
1526 /* Some utility functions for the string table code. */
1528 /* For speed, only hash on the first this many bytes of strings.
1529 This number was chosen by profiling ld linking itself, with -g. */
1530 #define HASHMAXLEN 25
1532 #define HASH_CHAR(c) (sum ^= sum >> 20, sum ^= sum << 7, sum += (c))
1534 static INLINE
unsigned int
1536 unsigned char *string
;
1537 register unsigned int len
;
1539 register unsigned int sum
= 0;
1541 if (len
> HASHMAXLEN
)
1549 HASH_CHAR (*string
++);
1555 stringtab_init (tab
)
1556 struct stringtab_data
*tab
;
1559 tab
->output_order
= 0;
1560 tab
->end
= &tab
->output_order
;
1562 /* Initial string table length includes size of length field. */
1563 tab
->index
= BYTES_IN_WORD
;
1564 tab
->empty_string_index
= -1;
1565 #ifdef GATHER_STATISTICS
1566 tab
->duplicates
= 0;
1567 tab
->empty_strings
= 0;
1568 tab
->bad_hash_matches
= 0;
1569 tab
->pointer_matches
= 0;
1570 tab
->bytes_saved
= 0;
1571 tab
->n_compares
= 0;
1576 compare (entry
, str
, hash
)
1577 struct stringtab_entry
*entry
;
1581 return hash
- entry
->hash
;
1584 #ifdef GATHER_STATISTICS
1585 /* Don't want to have to link in math library with all bfd applications... */
1586 static INLINE
double
1594 return ((d
> 1.41) ? 0.5 : 0) + n
;
1598 /* Main string table routines. */
1599 /* Returns index in string table. Whether or not this actually adds an
1600 entry into the string table should be irrelevant -- it just has to
1601 return a valid index. */
1602 static bfd_size_type
1603 add_to_stringtab (abfd
, str
, tab
, check
)
1606 struct stringtab_data
*tab
;
1609 struct stringtab_entry
**ep
;
1610 register struct stringtab_entry
*entry
;
1611 unsigned int hashval
, len
;
1615 bfd_size_type index
;
1616 CONST bfd_size_type minus_one
= -1;
1618 #ifdef GATHER_STATISTICS
1619 tab
->empty_strings
++;
1621 index
= tab
->empty_string_index
;
1622 if (index
!= minus_one
)
1625 #ifdef GATHER_STATISTICS
1632 /* Need to find it. */
1633 entry
= tab
->strings
;
1636 index
= entry
->index
+ strlen (entry
->string
);
1637 tab
->empty_string_index
= index
;
1645 /* The hash_zero value is chosen such that the first symbol gets a value of
1646 zero. With a balanced tree, this wouldn't be very useful, but without it,
1647 we might get a more even split at the top level, instead of skewing it
1648 badly should hash("/usr/lib/crt0.o") (or whatever) be far from zero. */
1649 hashval
= hash (str
, len
) ^ tab
->hash_zero
;
1653 tab
->hash_zero
= hashval
;
1663 #ifdef GATHER_STATISTICS
1666 cmp
= compare (entry
, str
, hashval
);
1667 /* The not-equal cases are more frequent, so check them first. */
1669 ep
= &entry
->greater
;
1674 if (entry
->string
== str
)
1676 #ifdef GATHER_STATISTICS
1677 tab
->pointer_matches
++;
1681 /* Compare the first bytes to save a function call if they
1683 if (entry
->string
[0] == str
[0] && !strcmp (entry
->string
, str
))
1686 #ifdef GATHER_STATISTICS
1688 tab
->bytes_saved
+= len
+ 1;
1691 /* If we're in the linker, and the new string is from a new
1692 input file which might have already had these reductions
1693 run over it, we want to keep the new string pointer. I
1694 don't think we're likely to see any (or nearly as many,
1695 at least) cases where a later string is in the same location
1696 as an earlier one rather than this one. */
1697 entry
->string
= str
;
1698 return entry
->index
;
1700 #ifdef GATHER_STATISTICS
1701 tab
->bad_hash_matches
++;
1703 ep
= &entry
->greater
;
1707 /* If we get here, nothing that's in the table already matched.
1708 EP points to the `next' field at the end of the chain; stick a
1709 new entry on here. */
1711 entry
= (struct stringtab_entry
*)
1712 bfd_alloc_by_size_t (abfd
, sizeof (struct stringtab_entry
));
1714 entry
->less
= entry
->greater
= 0;
1715 entry
->hash
= hashval
;
1716 entry
->index
= tab
->index
;
1717 entry
->string
= str
;
1718 entry
->next_to_output
= 0;
1719 #ifdef GATHER_STATISTICS
1723 assert (*tab
->end
== 0);
1724 *(tab
->end
) = entry
;
1725 tab
->end
= &entry
->next_to_output
;
1726 assert (*tab
->end
== 0);
1729 tab
->index
+= len
+ 1;
1731 tab
->empty_string_index
= entry
->index
;
1735 return entry
->index
;
1739 emit_strtab (abfd
, tab
)
1741 struct stringtab_data
*tab
;
1743 struct stringtab_entry
*entry
;
1744 #ifdef GATHER_STATISTICS
1748 /* Be sure to put string length into correct byte ordering before writing
1750 char buffer
[BYTES_IN_WORD
];
1752 PUT_WORD (abfd
, tab
->index
, (unsigned char *) buffer
);
1753 bfd_write ((PTR
) buffer
, 1, BYTES_IN_WORD
, abfd
);
1755 for (entry
= tab
->output_order
; entry
; entry
= entry
->next_to_output
)
1757 bfd_write ((PTR
) entry
->string
, 1, strlen (entry
->string
) + 1, abfd
);
1758 #ifdef GATHER_STATISTICS
1763 #ifdef GATHER_STATISTICS
1764 /* Short form only, for now.
1765 To do: Specify output file. Conditionalize on environment? Detailed
1766 analysis if desired. */
1768 int n_syms
= bfd_get_symcount (abfd
);
1770 fprintf (stderr
, "String table data for output file:\n");
1771 fprintf (stderr
, " %8d symbols output\n", n_syms
);
1772 fprintf (stderr
, " %8d duplicate strings\n", tab
->duplicates
);
1773 fprintf (stderr
, " %8d empty strings\n", tab
->empty_strings
);
1774 fprintf (stderr
, " %8d unique strings output\n", count
);
1775 fprintf (stderr
, " %8d pointer matches\n", tab
->pointer_matches
);
1776 fprintf (stderr
, " %8d bytes saved\n", tab
->bytes_saved
);
1777 fprintf (stderr
, " %8d bad hash matches\n", tab
->bad_hash_matches
);
1778 fprintf (stderr
, " %8d hash-val comparisons\n", tab
->n_compares
);
1781 double n_compares
= tab
->n_compares
;
1782 double avg_compares
= n_compares
/ n_syms
;
1783 /* The second value here should usually be near one. */
1785 "\t average %f comparisons per symbol (%f * log2 nstrings)\n",
1786 avg_compares
, avg_compares
/ log2 (count
));
1793 generic = bfd_get_outsymbols(abfd);
1794 for (count = 0; count < bfd_get_symcount(abfd); count++)
1796 asymbol *g = *(generic++);
1800 size_t length = strlen(g->name)+1;
1801 bfd_write((PTR)g->name, 1, length, abfd);
1803 g->KEEPIT = (KEEPITTYPE) count;
1808 DEFUN(NAME(aout
,write_syms
),(abfd
),
1811 unsigned int count
;
1812 asymbol
**generic
= bfd_get_outsymbols (abfd
);
1813 struct stringtab_data strtab
;
1815 stringtab_init (&strtab
);
1817 for (count
= 0; count
< bfd_get_symcount (abfd
); count
++)
1819 asymbol
*g
= generic
[count
];
1820 struct external_nlist nsp
;
1823 PUT_WORD (abfd
, add_to_stringtab (abfd
, g
->name
, &strtab
),
1824 (unsigned char *) nsp
.e_strx
);
1826 PUT_WORD (abfd
, 0, (unsigned char *)nsp
.e_strx
);
1828 if (bfd_asymbol_flavour(g
) == abfd
->xvec
->flavour
)
1830 bfd_h_put_16(abfd
, aout_symbol(g
)->desc
, nsp
.e_desc
);
1831 bfd_h_put_8(abfd
, aout_symbol(g
)->other
, nsp
.e_other
);
1832 bfd_h_put_8(abfd
, aout_symbol(g
)->type
, nsp
.e_type
);
1836 bfd_h_put_16(abfd
,0, nsp
.e_desc
);
1837 bfd_h_put_8(abfd
, 0, nsp
.e_other
);
1838 bfd_h_put_8(abfd
, 0, nsp
.e_type
);
1841 translate_to_native_sym_flags (&nsp
, g
, abfd
);
1843 bfd_write((PTR
)&nsp
,1,EXTERNAL_NLIST_SIZE
, abfd
);
1845 /* NB: `KEEPIT' currently overlays `flags', so set this only
1846 here, at the end. */
1850 emit_strtab (abfd
, &strtab
);
1855 DEFUN(NAME(aout
,get_symtab
),(abfd
, location
),
1859 unsigned int counter
= 0;
1860 aout_symbol_type
*symbase
;
1862 if (!NAME(aout
,slurp_symbol_table
)(abfd
)) return 0;
1864 for (symbase
= obj_aout_symbols(abfd
); counter
++ < bfd_get_symcount (abfd
);)
1865 *(location
++) = (asymbol
*)( symbase
++);
1867 return bfd_get_symcount (abfd
);
1871 /* Standard reloc stuff */
1872 /* Output standard relocation information to a file in target byte order. */
1875 DEFUN(NAME(aout
,swap_std_reloc_out
),(abfd
, g
, natptr
),
1878 struct reloc_std_external
*natptr
)
1881 asymbol
*sym
= *(g
->sym_ptr_ptr
);
1883 unsigned int r_length
;
1885 int r_baserel
, r_jmptable
, r_relative
;
1886 unsigned int r_addend
;
1887 asection
*output_section
= sym
->section
->output_section
;
1889 PUT_WORD(abfd
, g
->address
, natptr
->r_address
);
1891 r_length
= g
->howto
->size
; /* Size as a power of two */
1892 r_pcrel
= (int) g
->howto
->pc_relative
; /* Relative to PC? */
1893 /* XXX This relies on relocs coming from a.out files. */
1894 r_baserel
= (g
->howto
->type
& 8) != 0;
1895 /* r_jmptable, r_relative??? FIXME-soon */
1899 r_addend
= g
->addend
+ (*(g
->sym_ptr_ptr
))->section
->output_section
->vma
;
1901 /* name was clobbered by aout_write_syms to be symbol index */
1903 /* If this relocation is relative to a symbol then set the
1904 r_index to the symbols index, and the r_extern bit.
1906 Absolute symbols can come in in two ways, either as an offset
1907 from the abs section, or as a symbol which has an abs value.
1912 if (bfd_is_com_section (output_section
)
1913 || output_section
== &bfd_abs_section
1914 || output_section
== &bfd_und_section
)
1916 if (bfd_abs_section
.symbol
== sym
)
1918 /* Whoops, looked like an abs symbol, but is really an offset
1919 from the abs section */
1925 /* Fill in symbol */
1927 r_index
= stoi((*(g
->sym_ptr_ptr
))->KEEPIT
);
1933 /* Just an ordinary section */
1935 r_index
= output_section
->target_index
;
1938 /* now the fun stuff */
1939 if (abfd
->xvec
->header_byteorder_big_p
!= false) {
1940 natptr
->r_index
[0] = r_index
>> 16;
1941 natptr
->r_index
[1] = r_index
>> 8;
1942 natptr
->r_index
[2] = r_index
;
1944 (r_extern
? RELOC_STD_BITS_EXTERN_BIG
: 0)
1945 | (r_pcrel
? RELOC_STD_BITS_PCREL_BIG
: 0)
1946 | (r_baserel
? RELOC_STD_BITS_BASEREL_BIG
: 0)
1947 | (r_jmptable
? RELOC_STD_BITS_JMPTABLE_BIG
: 0)
1948 | (r_relative
? RELOC_STD_BITS_RELATIVE_BIG
: 0)
1949 | (r_length
<< RELOC_STD_BITS_LENGTH_SH_BIG
);
1951 natptr
->r_index
[2] = r_index
>> 16;
1952 natptr
->r_index
[1] = r_index
>> 8;
1953 natptr
->r_index
[0] = r_index
;
1955 (r_extern
? RELOC_STD_BITS_EXTERN_LITTLE
: 0)
1956 | (r_pcrel
? RELOC_STD_BITS_PCREL_LITTLE
: 0)
1957 | (r_baserel
? RELOC_STD_BITS_BASEREL_LITTLE
: 0)
1958 | (r_jmptable
? RELOC_STD_BITS_JMPTABLE_LITTLE
: 0)
1959 | (r_relative
? RELOC_STD_BITS_RELATIVE_LITTLE
: 0)
1960 | (r_length
<< RELOC_STD_BITS_LENGTH_SH_LITTLE
);
1965 /* Extended stuff */
1966 /* Output extended relocation information to a file in target byte order. */
1969 DEFUN(NAME(aout
,swap_ext_reloc_out
),(abfd
, g
, natptr
),
1972 register struct reloc_ext_external
*natptr
)
1976 unsigned int r_type
;
1977 unsigned int r_addend
;
1978 asymbol
*sym
= *(g
->sym_ptr_ptr
);
1979 asection
*output_section
= sym
->section
->output_section
;
1981 PUT_WORD (abfd
, g
->address
, natptr
->r_address
);
1983 r_type
= (unsigned int) g
->howto
->type
;
1985 r_addend
= g
->addend
+ (*(g
->sym_ptr_ptr
))->section
->output_section
->vma
;
1987 /* If this relocation is relative to a symbol then set the
1988 r_index to the symbols index, and the r_extern bit.
1990 Absolute symbols can come in in two ways, either as an offset
1991 from the abs section, or as a symbol which has an abs value.
1992 check for that here. */
1994 if (bfd_is_com_section (output_section
)
1995 || output_section
== &bfd_abs_section
1996 || output_section
== &bfd_und_section
)
1998 if (bfd_abs_section
.symbol
== sym
)
2000 /* Whoops, looked like an abs symbol, but is really an offset
2001 from the abs section */
2008 r_index
= stoi((*(g
->sym_ptr_ptr
))->KEEPIT
);
2013 /* Just an ordinary section */
2015 r_index
= output_section
->target_index
;
2018 /* now the fun stuff */
2019 if (abfd
->xvec
->header_byteorder_big_p
!= false) {
2020 natptr
->r_index
[0] = r_index
>> 16;
2021 natptr
->r_index
[1] = r_index
>> 8;
2022 natptr
->r_index
[2] = r_index
;
2024 ((r_extern
? RELOC_EXT_BITS_EXTERN_BIG
: 0)
2025 | (r_type
<< RELOC_EXT_BITS_TYPE_SH_BIG
));
2027 natptr
->r_index
[2] = r_index
>> 16;
2028 natptr
->r_index
[1] = r_index
>> 8;
2029 natptr
->r_index
[0] = r_index
;
2031 (r_extern
? RELOC_EXT_BITS_EXTERN_LITTLE
: 0)
2032 | (r_type
<< RELOC_EXT_BITS_TYPE_SH_LITTLE
);
2035 PUT_WORD (abfd
, r_addend
, natptr
->r_addend
);
2038 /* BFD deals internally with all things based from the section they're
2039 in. so, something in 10 bytes into a text section with a base of
2040 50 would have a symbol (.text+10) and know .text vma was 50.
2042 Aout keeps all it's symbols based from zero, so the symbol would
2043 contain 60. This macro subs the base of each section from the value
2044 to give the true offset from the section */
2047 #define MOVE_ADDRESS(ad) \
2049 /* undefined symbol */ \
2050 cache_ptr->sym_ptr_ptr = symbols + r_index; \
2051 cache_ptr->addend = ad; \
2053 /* defined, section relative. replace symbol with pointer to \
2054 symbol which points to section */ \
2055 switch (r_index) { \
2057 case N_TEXT | N_EXT: \
2058 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
2059 cache_ptr->addend = ad - su->textsec->vma; \
2062 case N_DATA | N_EXT: \
2063 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
2064 cache_ptr->addend = ad - su->datasec->vma; \
2067 case N_BSS | N_EXT: \
2068 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
2069 cache_ptr->addend = ad - su->bsssec->vma; \
2073 case N_ABS | N_EXT: \
2074 cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; \
2075 cache_ptr->addend = ad; \
2081 DEFUN(NAME(aout
,swap_ext_reloc_in
), (abfd
, bytes
, cache_ptr
, symbols
),
2083 struct reloc_ext_external
*bytes AND
2084 arelent
*cache_ptr AND
2089 unsigned int r_type
;
2090 struct aoutdata
*su
= &(abfd
->tdata
.aout_data
->a
);
2092 cache_ptr
->address
= (GET_SWORD (abfd
, bytes
->r_address
));
2094 /* now the fun stuff */
2095 if (abfd
->xvec
->header_byteorder_big_p
!= false) {
2096 r_index
= (bytes
->r_index
[0] << 16)
2097 | (bytes
->r_index
[1] << 8)
2098 | bytes
->r_index
[2];
2099 r_extern
= (0 != (bytes
->r_type
[0] & RELOC_EXT_BITS_EXTERN_BIG
));
2100 r_type
= (bytes
->r_type
[0] & RELOC_EXT_BITS_TYPE_BIG
)
2101 >> RELOC_EXT_BITS_TYPE_SH_BIG
;
2103 r_index
= (bytes
->r_index
[2] << 16)
2104 | (bytes
->r_index
[1] << 8)
2105 | bytes
->r_index
[0];
2106 r_extern
= (0 != (bytes
->r_type
[0] & RELOC_EXT_BITS_EXTERN_LITTLE
));
2107 r_type
= (bytes
->r_type
[0] & RELOC_EXT_BITS_TYPE_LITTLE
)
2108 >> RELOC_EXT_BITS_TYPE_SH_LITTLE
;
2111 cache_ptr
->howto
= howto_table_ext
+ r_type
;
2112 MOVE_ADDRESS(GET_SWORD(abfd
, bytes
->r_addend
));
2116 DEFUN(NAME(aout
,swap_std_reloc_in
), (abfd
, bytes
, cache_ptr
, symbols
),
2118 struct reloc_std_external
*bytes AND
2119 arelent
*cache_ptr AND
2124 unsigned int r_length
;
2126 int r_baserel
, r_jmptable
, r_relative
;
2127 struct aoutdata
*su
= &(abfd
->tdata
.aout_data
->a
);
2130 cache_ptr
->address
= bfd_h_get_32 (abfd
, bytes
->r_address
);
2132 /* now the fun stuff */
2133 if (abfd
->xvec
->header_byteorder_big_p
!= false) {
2134 r_index
= (bytes
->r_index
[0] << 16)
2135 | (bytes
->r_index
[1] << 8)
2136 | bytes
->r_index
[2];
2137 r_extern
= (0 != (bytes
->r_type
[0] & RELOC_STD_BITS_EXTERN_BIG
));
2138 r_pcrel
= (0 != (bytes
->r_type
[0] & RELOC_STD_BITS_PCREL_BIG
));
2139 r_baserel
= (0 != (bytes
->r_type
[0] & RELOC_STD_BITS_BASEREL_BIG
));
2140 r_jmptable
= (0 != (bytes
->r_type
[0] & RELOC_STD_BITS_JMPTABLE_BIG
));
2141 r_relative
= (0 != (bytes
->r_type
[0] & RELOC_STD_BITS_RELATIVE_BIG
));
2142 r_length
= (bytes
->r_type
[0] & RELOC_STD_BITS_LENGTH_BIG
)
2143 >> RELOC_STD_BITS_LENGTH_SH_BIG
;
2145 r_index
= (bytes
->r_index
[2] << 16)
2146 | (bytes
->r_index
[1] << 8)
2147 | bytes
->r_index
[0];
2148 r_extern
= (0 != (bytes
->r_type
[0] & RELOC_STD_BITS_EXTERN_LITTLE
));
2149 r_pcrel
= (0 != (bytes
->r_type
[0] & RELOC_STD_BITS_PCREL_LITTLE
));
2150 r_baserel
= (0 != (bytes
->r_type
[0] & RELOC_STD_BITS_BASEREL_LITTLE
));
2151 r_jmptable
= (0 != (bytes
->r_type
[0] & RELOC_STD_BITS_JMPTABLE_LITTLE
));
2152 r_relative
= (0 != (bytes
->r_type
[0] & RELOC_STD_BITS_RELATIVE_LITTLE
));
2153 r_length
= (bytes
->r_type
[0] & RELOC_STD_BITS_LENGTH_LITTLE
)
2154 >> RELOC_STD_BITS_LENGTH_SH_LITTLE
;
2157 howto_idx
= r_length
+ 4 * r_pcrel
+ 8 * r_baserel
;
2158 BFD_ASSERT (howto_idx
< TABLE_SIZE (howto_table_std
));
2159 cache_ptr
->howto
= howto_table_std
+ howto_idx
;
2160 BFD_ASSERT (cache_ptr
->howto
->type
!= -1);
2161 BFD_ASSERT (r_jmptable
== 0);
2162 BFD_ASSERT (r_relative
== 0);
2163 /* FIXME-soon: Roll jmptable, relative bits into howto setting */
2171 DEFUN(NAME(aout
,slurp_reloc_table
),(abfd
, asect
, symbols
),
2177 bfd_size_type reloc_size
;
2179 arelent
*reloc_cache
;
2182 if (asect
->relocation
) return true;
2184 if (asect
->flags
& SEC_CONSTRUCTOR
) return true;
2186 if (asect
== obj_datasec (abfd
)) {
2187 reloc_size
= exec_hdr(abfd
)->a_drsize
;
2188 } else if (asect
== obj_textsec (abfd
)) {
2189 reloc_size
= exec_hdr(abfd
)->a_trsize
;
2191 bfd_error
= invalid_operation
;
2195 bfd_seek (abfd
, asect
->rel_filepos
, SEEK_SET
);
2196 each_size
= obj_reloc_entry_size (abfd
);
2198 count
= reloc_size
/ each_size
;
2201 reloc_cache
= (arelent
*) bfd_zalloc (abfd
, (size_t)(count
* sizeof
2205 bfd_error
= no_memory
;
2209 relocs
= (PTR
) bfd_alloc (abfd
, reloc_size
);
2211 bfd_release (abfd
, reloc_cache
);
2215 if (bfd_read (relocs
, 1, reloc_size
, abfd
) != reloc_size
) {
2216 bfd_release (abfd
, relocs
);
2217 bfd_release (abfd
, reloc_cache
);
2218 bfd_error
= system_call_error
;
2222 if (each_size
== RELOC_EXT_SIZE
) {
2223 register struct reloc_ext_external
*rptr
= (struct reloc_ext_external
*) relocs
;
2224 unsigned int counter
= 0;
2225 arelent
*cache_ptr
= reloc_cache
;
2227 for (; counter
< count
; counter
++, rptr
++, cache_ptr
++) {
2228 NAME(aout
,swap_ext_reloc_in
)(abfd
, rptr
, cache_ptr
, symbols
);
2231 register struct reloc_std_external
*rptr
= (struct reloc_std_external
*) relocs
;
2232 unsigned int counter
= 0;
2233 arelent
*cache_ptr
= reloc_cache
;
2235 for (; counter
< count
; counter
++, rptr
++, cache_ptr
++) {
2236 NAME(aout
,swap_std_reloc_in
)(abfd
, rptr
, cache_ptr
, symbols
);
2241 bfd_release (abfd
,relocs
);
2242 asect
->relocation
= reloc_cache
;
2243 asect
->reloc_count
= count
;
2249 /* Write out a relocation section into an object file. */
2252 DEFUN(NAME(aout
,squirt_out_relocs
),(abfd
, section
),
2257 unsigned char *native
, *natptr
;
2260 unsigned int count
= section
->reloc_count
;
2263 if (count
== 0) return true;
2265 each_size
= obj_reloc_entry_size (abfd
);
2266 natsize
= each_size
* count
;
2267 native
= (unsigned char *) bfd_zalloc (abfd
, natsize
);
2269 bfd_error
= no_memory
;
2273 generic
= section
->orelocation
;
2275 if (each_size
== RELOC_EXT_SIZE
)
2277 for (natptr
= native
;
2279 --count
, natptr
+= each_size
, ++generic
)
2280 NAME(aout
,swap_ext_reloc_out
) (abfd
, *generic
, (struct reloc_ext_external
*)natptr
);
2284 for (natptr
= native
;
2286 --count
, natptr
+= each_size
, ++generic
)
2287 NAME(aout
,swap_std_reloc_out
)(abfd
, *generic
, (struct reloc_std_external
*)natptr
);
2290 if ( bfd_write ((PTR
) native
, 1, natsize
, abfd
) != natsize
) {
2291 bfd_release(abfd
, native
);
2294 bfd_release (abfd
, native
);
2299 /* This is stupid. This function should be a boolean predicate */
2301 DEFUN(NAME(aout
,canonicalize_reloc
),(abfd
, section
, relptr
, symbols
),
2304 arelent
**relptr AND
2307 arelent
*tblptr
= section
->relocation
;
2310 if (!(tblptr
|| NAME(aout
,slurp_reloc_table
)(abfd
, section
, symbols
)))
2313 if (section
->flags
& SEC_CONSTRUCTOR
) {
2314 arelent_chain
*chain
= section
->constructor_chain
;
2315 for (count
= 0; count
< section
->reloc_count
; count
++) {
2316 *relptr
++ = &chain
->relent
;
2317 chain
= chain
->next
;
2321 tblptr
= section
->relocation
;
2322 if (!tblptr
) return 0;
2324 for (count
= 0; count
++ < section
->reloc_count
;)
2326 *relptr
++ = tblptr
++;
2331 return section
->reloc_count
;
2335 DEFUN(NAME(aout
,get_reloc_upper_bound
),(abfd
, asect
),
2339 if (bfd_get_format (abfd
) != bfd_object
) {
2340 bfd_error
= invalid_operation
;
2343 if (asect
->flags
& SEC_CONSTRUCTOR
) {
2344 return (sizeof (arelent
*) * (asect
->reloc_count
+1));
2348 if (asect
== obj_datasec (abfd
))
2349 return (sizeof (arelent
*) *
2350 ((exec_hdr(abfd
)->a_drsize
/ obj_reloc_entry_size (abfd
))
2353 if (asect
== obj_textsec (abfd
))
2354 return (sizeof (arelent
*) *
2355 ((exec_hdr(abfd
)->a_trsize
/ obj_reloc_entry_size (abfd
))
2358 bfd_error
= invalid_operation
;
2364 DEFUN(NAME(aout
,get_symtab_upper_bound
),(abfd
),
2367 if (!NAME(aout
,slurp_symbol_table
)(abfd
)) return 0;
2369 return (bfd_get_symcount (abfd
)+1) * (sizeof (aout_symbol_type
*));
2372 DEFUN(NAME(aout
,get_lineno
),(ignore_abfd
, ignore_symbol
),
2373 bfd
*ignore_abfd AND
2374 asymbol
*ignore_symbol
)
2376 return (alent
*)NULL
;
2380 DEFUN(NAME(aout
,get_symbol_info
),(ignore_abfd
, symbol
, ret
),
2381 bfd
*ignore_abfd AND
2385 bfd_symbol_info (symbol
, ret
);
2387 if (ret
->type
== '?')
2389 int type_code
= aout_symbol(symbol
)->type
& 0xff;
2390 CONST
char *stab_name
= aout_stab_name(type_code
);
2391 static char buf
[10];
2393 if (stab_name
== NULL
)
2395 sprintf(buf
, "(%d)", type_code
);
2399 ret
->stab_other
= (unsigned)(aout_symbol(symbol
)->other
& 0xff);
2400 ret
->stab_desc
= (unsigned)(aout_symbol(symbol
)->desc
& 0xffff);
2401 ret
->stab_name
= stab_name
;
2406 DEFUN(NAME(aout
,print_symbol
),(ignore_abfd
, afile
, symbol
, how
),
2407 bfd
*ignore_abfd AND
2410 bfd_print_symbol_type how
)
2412 FILE *file
= (FILE *)afile
;
2415 case bfd_print_symbol_name
:
2417 fprintf(file
,"%s", symbol
->name
);
2419 case bfd_print_symbol_more
:
2420 fprintf(file
,"%4x %2x %2x",(unsigned)(aout_symbol(symbol
)->desc
& 0xffff),
2421 (unsigned)(aout_symbol(symbol
)->other
& 0xff),
2422 (unsigned)(aout_symbol(symbol
)->type
));
2424 case bfd_print_symbol_all
:
2426 CONST
char *section_name
= symbol
->section
->name
;
2429 bfd_print_symbol_vandf((PTR
)file
,symbol
);
2431 fprintf(file
," %-5s %04x %02x %02x",
2433 (unsigned)(aout_symbol(symbol
)->desc
& 0xffff),
2434 (unsigned)(aout_symbol(symbol
)->other
& 0xff),
2435 (unsigned)(aout_symbol(symbol
)->type
& 0xff));
2437 fprintf(file
," %s", symbol
->name
);
2444 provided a BFD, a section and an offset into the section, calculate
2445 and return the name of the source file and the line nearest to the
2450 DEFUN(NAME(aout
,find_nearest_line
),(abfd
,
2458 asection
*section AND
2459 asymbol
**symbols AND
2461 CONST
char **filename_ptr AND
2462 CONST
char **functionname_ptr AND
2463 unsigned int *line_ptr
)
2465 /* Run down the file looking for the filename, function and linenumber */
2467 static char buffer
[100];
2468 static char filename_buffer
[200];
2469 CONST
char *directory_name
= NULL
;
2470 CONST
char *main_file_name
= NULL
;
2471 CONST
char *current_file_name
= NULL
;
2472 CONST
char *line_file_name
= NULL
; /* Value of current_file_name at line number. */
2473 bfd_vma high_line_vma
= ~0;
2474 bfd_vma low_func_vma
= 0;
2476 *filename_ptr
= abfd
->filename
;
2477 *functionname_ptr
= 0;
2479 if (symbols
!= (asymbol
**)NULL
) {
2480 for (p
= symbols
; *p
; p
++) {
2481 aout_symbol_type
*q
= (aout_symbol_type
*)(*p
);
2485 main_file_name
= current_file_name
= q
->symbol
.name
;
2486 /* Look ahead to next symbol to check if that too is an N_SO. */
2490 q
= (aout_symbol_type
*)(*p
);
2491 if (q
->type
!= (int)N_SO
)
2494 /* Found a second N_SO First is directory; second is filename. */
2495 directory_name
= current_file_name
;
2496 main_file_name
= current_file_name
= q
->symbol
.name
;
2497 if (obj_textsec(abfd
) != section
)
2501 current_file_name
= q
->symbol
.name
;
2508 /* We'll keep this if it resolves nearer than the one we have already */
2509 if (q
->symbol
.value
>= offset
&&
2510 q
->symbol
.value
< high_line_vma
) {
2511 *line_ptr
= q
->desc
;
2512 high_line_vma
= q
->symbol
.value
;
2513 line_file_name
= current_file_name
;
2518 /* We'll keep this if it is nearer than the one we have already */
2519 if (q
->symbol
.value
>= low_func_vma
&&
2520 q
->symbol
.value
<= offset
) {
2521 low_func_vma
= q
->symbol
.value
;
2522 func
= (asymbol
*)q
;
2524 if (*line_ptr
&& func
) {
2525 CONST
char *function
= func
->name
;
2527 strncpy(buffer
, function
, sizeof(buffer
)-1);
2528 buffer
[sizeof(buffer
)-1] = 0;
2529 /* Have to remove : stuff */
2530 p
= strchr(buffer
,':');
2531 if (p
!= NULL
) { *p
= '\0'; }
2532 *functionname_ptr
= buffer
;
2544 main_file_name
= line_file_name
;
2545 if (main_file_name
) {
2546 if (main_file_name
[0] == '/' || directory_name
== NULL
)
2547 *filename_ptr
= main_file_name
;
2549 sprintf(filename_buffer
, "%.140s%.50s",
2550 directory_name
, main_file_name
);
2551 *filename_ptr
= filename_buffer
;
2559 DEFUN(NAME(aout
,sizeof_headers
),(abfd
, execable
),
2563 return adata(abfd
).exec_bytes_size
;