* elf32-arm.c (elf32_arm_symbian_plt_entry): Fix comment typo.
[binutils.git] / bfd / aoutx.h
blob34a2870175601254598abe703d0c151384a1bf72
1 /* BFD semi-generic back-end for a.out binaries.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
3 2001, 2002, 2003, 2004
4 Free Software Foundation, Inc.
5 Written by Cygnus Support.
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 SECTION
25 a.out backends
27 DESCRIPTION
29 BFD supports a number of different flavours of a.out format,
30 though the major differences are only the sizes of the
31 structures on disk, and the shape of the relocation
32 information.
34 The support is split into a basic support file @file{aoutx.h}
35 and other files which derive functions from the base. One
36 derivation file is @file{aoutf1.h} (for a.out flavour 1), and
37 adds to the basic a.out functions support for sun3, sun4, 386
38 and 29k a.out files, to create a target jump vector for a
39 specific target.
41 This information is further split out into more specific files
42 for each machine, including @file{sunos.c} for sun3 and sun4,
43 @file{newsos3.c} for the Sony NEWS, and @file{demo64.c} for a
44 demonstration of a 64 bit a.out format.
46 The base file @file{aoutx.h} defines general mechanisms for
47 reading and writing records to and from disk and various
48 other methods which BFD requires. It is included by
49 @file{aout32.c} and @file{aout64.c} to form the names
50 <<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc.
52 As an example, this is what goes on to make the back end for a
53 sun4, from @file{aout32.c}:
55 | #define ARCH_SIZE 32
56 | #include "aoutx.h"
58 Which exports names:
60 | ...
61 | aout_32_canonicalize_reloc
62 | aout_32_find_nearest_line
63 | aout_32_get_lineno
64 | aout_32_get_reloc_upper_bound
65 | ...
67 from @file{sunos.c}:
69 | #define TARGET_NAME "a.out-sunos-big"
70 | #define VECNAME sunos_big_vec
71 | #include "aoutf1.h"
73 requires all the names from @file{aout32.c}, and produces the jump vector
75 | sunos_big_vec
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
85 the object file.
87 When porting it to run on a new system, you must supply:
89 | HOST_PAGE_SIZE
90 | HOST_SEGMENT_SIZE
91 | HOST_MACHINE_ARCH (optional)
92 | HOST_MACHINE_MACHINE (optional)
93 | HOST_TEXT_START_ADDR
94 | HOST_STACK_END_ADDR
96 in the file @file{../include/sys/h-@var{XXX}.h} (for your host). These
97 values, plus the structures and macros defined in @file{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 @file{host-aout.c}, specify:
102 | TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
103 | TDEPFILES= host-aout.o trad-core.o
105 in the @file{config/@var{XXX}.mt} file, and modify @file{configure.in}
106 to use the
107 @file{@var{XXX}.mt} file (by setting "<<bfd_target=XXX>>") when your
108 configuration is selected. */
110 /* Some assumptions:
111 * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
112 Doesn't matter what the setting of WP_TEXT is on output, but it'll
113 get set on input.
114 * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
115 * Any BFD with both flags clear is OMAGIC.
116 (Just want to make these explicit, so the conditions tested in this
117 file make sense if you're more familiar with a.out than with BFD.) */
119 #define KEEPIT udata.i
121 #include "bfd.h"
122 #include "sysdep.h"
123 #include "safe-ctype.h"
124 #include "bfdlink.h"
126 #include "libaout.h"
127 #include "libbfd.h"
128 #include "aout/aout64.h"
129 #include "aout/stab_gnu.h"
130 #include "aout/ar.h"
132 static bfd_boolean aout_get_external_symbols
133 PARAMS ((bfd *));
134 static bfd_boolean translate_from_native_sym_flags
135 PARAMS ((bfd *, aout_symbol_type *));
136 static bfd_boolean translate_to_native_sym_flags
137 PARAMS ((bfd *, asymbol *, struct external_nlist *));
138 static void adjust_o_magic
139 PARAMS ((bfd *, struct internal_exec *));
140 static void adjust_z_magic
141 PARAMS ((bfd *, struct internal_exec *));
142 static void adjust_n_magic
143 PARAMS ((bfd *, struct internal_exec *));
144 reloc_howto_type * NAME(aout,reloc_type_lookup)
145 PARAMS ((bfd *, bfd_reloc_code_real_type));
148 SUBSECTION
149 Relocations
151 DESCRIPTION
152 The file @file{aoutx.h} provides for both the @emph{standard}
153 and @emph{extended} forms of a.out relocation records.
155 The standard records contain only an
156 address, a symbol index, and a type field. The extended records
157 (used on 29ks and sparcs) also have a full integer for an
158 addend. */
160 #ifndef CTOR_TABLE_RELOC_HOWTO
161 #define CTOR_TABLE_RELOC_IDX 2
162 #define CTOR_TABLE_RELOC_HOWTO(BFD) \
163 ((obj_reloc_entry_size (BFD) == RELOC_EXT_SIZE \
164 ? howto_table_ext : howto_table_std) \
165 + CTOR_TABLE_RELOC_IDX)
166 #endif
168 #ifndef MY_swap_std_reloc_in
169 #define MY_swap_std_reloc_in NAME(aout,swap_std_reloc_in)
170 #endif
172 #ifndef MY_swap_ext_reloc_in
173 #define MY_swap_ext_reloc_in NAME(aout,swap_ext_reloc_in)
174 #endif
176 #ifndef MY_swap_std_reloc_out
177 #define MY_swap_std_reloc_out NAME(aout,swap_std_reloc_out)
178 #endif
180 #ifndef MY_swap_ext_reloc_out
181 #define MY_swap_ext_reloc_out NAME(aout,swap_ext_reloc_out)
182 #endif
184 #ifndef MY_final_link_relocate
185 #define MY_final_link_relocate _bfd_final_link_relocate
186 #endif
188 #ifndef MY_relocate_contents
189 #define MY_relocate_contents _bfd_relocate_contents
190 #endif
192 #define howto_table_ext NAME(aout,ext_howto_table)
193 #define howto_table_std NAME(aout,std_howto_table)
195 reloc_howto_type howto_table_ext[] =
197 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone. */
198 HOWTO(RELOC_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,0,"8", FALSE, 0,0x000000ff, FALSE),
199 HOWTO(RELOC_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,0,"16", FALSE, 0,0x0000ffff, FALSE),
200 HOWTO(RELOC_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,"32", FALSE, 0,0xffffffff, FALSE),
201 HOWTO(RELOC_DISP8, 0, 0, 8, TRUE, 0, complain_overflow_signed,0,"DISP8", FALSE, 0,0x000000ff, FALSE),
202 HOWTO(RELOC_DISP16, 0, 1, 16, TRUE, 0, complain_overflow_signed,0,"DISP16", FALSE, 0,0x0000ffff, FALSE),
203 HOWTO(RELOC_DISP32, 0, 2, 32, TRUE, 0, complain_overflow_signed,0,"DISP32", FALSE, 0,0xffffffff, FALSE),
204 HOWTO(RELOC_WDISP30,2, 2, 30, TRUE, 0, complain_overflow_signed,0,"WDISP30", FALSE, 0,0x3fffffff, FALSE),
205 HOWTO(RELOC_WDISP22,2, 2, 22, TRUE, 0, complain_overflow_signed,0,"WDISP22", FALSE, 0,0x003fffff, FALSE),
206 HOWTO(RELOC_HI22, 10, 2, 22, FALSE, 0, complain_overflow_bitfield,0,"HI22", FALSE, 0,0x003fffff, FALSE),
207 HOWTO(RELOC_22, 0, 2, 22, FALSE, 0, complain_overflow_bitfield,0,"22", FALSE, 0,0x003fffff, FALSE),
208 HOWTO(RELOC_13, 0, 2, 13, FALSE, 0, complain_overflow_bitfield,0,"13", FALSE, 0,0x00001fff, FALSE),
209 HOWTO(RELOC_LO10, 0, 2, 10, FALSE, 0, complain_overflow_dont,0,"LO10", FALSE, 0,0x000003ff, FALSE),
210 HOWTO(RELOC_SFA_BASE,0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,"SFA_BASE", FALSE, 0,0xffffffff, FALSE),
211 HOWTO(RELOC_SFA_OFF13,0,2, 32, FALSE, 0, complain_overflow_bitfield,0,"SFA_OFF13",FALSE, 0,0xffffffff, FALSE),
212 HOWTO(RELOC_BASE10, 0, 2, 10, FALSE, 0, complain_overflow_dont,0,"BASE10", FALSE, 0,0x000003ff, FALSE),
213 HOWTO(RELOC_BASE13, 0, 2, 13, FALSE, 0, complain_overflow_signed,0,"BASE13", FALSE, 0,0x00001fff, FALSE),
214 HOWTO(RELOC_BASE22, 10, 2, 22, FALSE, 0, complain_overflow_bitfield,0,"BASE22", FALSE, 0,0x003fffff, FALSE),
215 HOWTO(RELOC_PC10, 0, 2, 10, TRUE, 0, complain_overflow_dont,0,"PC10", FALSE, 0,0x000003ff, TRUE),
216 HOWTO(RELOC_PC22, 10, 2, 22, TRUE, 0, complain_overflow_signed,0,"PC22", FALSE, 0,0x003fffff, TRUE),
217 HOWTO(RELOC_JMP_TBL,2, 2, 30, TRUE, 0, complain_overflow_signed,0,"JMP_TBL", FALSE, 0,0x3fffffff, FALSE),
218 HOWTO(RELOC_SEGOFF16,0, 2, 0, FALSE, 0, complain_overflow_bitfield,0,"SEGOFF16", FALSE, 0,0x00000000, FALSE),
219 HOWTO(RELOC_GLOB_DAT,0, 2, 0, FALSE, 0, complain_overflow_bitfield,0,"GLOB_DAT", FALSE, 0,0x00000000, FALSE),
220 HOWTO(RELOC_JMP_SLOT,0, 2, 0, FALSE, 0, complain_overflow_bitfield,0,"JMP_SLOT", FALSE, 0,0x00000000, FALSE),
221 HOWTO(RELOC_RELATIVE,0, 2, 0, FALSE, 0, complain_overflow_bitfield,0,"RELATIVE", FALSE, 0,0x00000000, FALSE),
222 HOWTO(0, 0, 0, 0, FALSE, 0, complain_overflow_dont, 0, "R_SPARC_NONE", FALSE,0,0x00000000,TRUE),
223 HOWTO(0, 0, 0, 0, FALSE, 0, complain_overflow_dont, 0, "R_SPARC_NONE", FALSE,0,0x00000000,TRUE),
224 #define RELOC_SPARC_REV32 RELOC_WDISP19
225 HOWTO(RELOC_SPARC_REV32, 0, 2, 32, FALSE, 0, complain_overflow_dont,0,"R_SPARC_REV32", FALSE, 0,0xffffffff, FALSE),
228 /* Convert standard reloc records to "arelent" format (incl byte swap). */
230 reloc_howto_type howto_table_std[] =
232 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone. */
233 HOWTO ( 0, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,0,"8", TRUE, 0x000000ff,0x000000ff, FALSE),
234 HOWTO ( 1, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,0,"16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
235 HOWTO ( 2, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,"32", TRUE, 0xffffffff,0xffffffff, FALSE),
236 HOWTO ( 3, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,0,"64", TRUE, 0xdeaddead,0xdeaddead, FALSE),
237 HOWTO ( 4, 0, 0, 8, TRUE, 0, complain_overflow_signed, 0,"DISP8", TRUE, 0x000000ff,0x000000ff, FALSE),
238 HOWTO ( 5, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0,"DISP16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
239 HOWTO ( 6, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0,"DISP32", TRUE, 0xffffffff,0xffffffff, FALSE),
240 HOWTO ( 7, 0, 4, 64, TRUE, 0, complain_overflow_signed, 0,"DISP64", TRUE, 0xfeedface,0xfeedface, FALSE),
241 HOWTO ( 8, 0, 2, 0, FALSE, 0, complain_overflow_bitfield,0,"GOT_REL", FALSE, 0,0x00000000, FALSE),
242 HOWTO ( 9, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,0,"BASE16", FALSE,0xffffffff,0xffffffff, FALSE),
243 HOWTO (10, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,"BASE32", FALSE,0xffffffff,0xffffffff, FALSE),
244 EMPTY_HOWTO (-1),
245 EMPTY_HOWTO (-1),
246 EMPTY_HOWTO (-1),
247 EMPTY_HOWTO (-1),
248 EMPTY_HOWTO (-1),
249 HOWTO (16, 0, 2, 0, FALSE, 0, complain_overflow_bitfield,0,"JMP_TABLE", FALSE, 0,0x00000000, FALSE),
250 EMPTY_HOWTO (-1),
251 EMPTY_HOWTO (-1),
252 EMPTY_HOWTO (-1),
253 EMPTY_HOWTO (-1),
254 EMPTY_HOWTO (-1),
255 EMPTY_HOWTO (-1),
256 EMPTY_HOWTO (-1),
257 EMPTY_HOWTO (-1),
258 EMPTY_HOWTO (-1),
259 EMPTY_HOWTO (-1),
260 EMPTY_HOWTO (-1),
261 EMPTY_HOWTO (-1),
262 EMPTY_HOWTO (-1),
263 EMPTY_HOWTO (-1),
264 EMPTY_HOWTO (-1),
265 HOWTO (32, 0, 2, 0, FALSE, 0, complain_overflow_bitfield,0,"RELATIVE", FALSE, 0,0x00000000, FALSE),
266 EMPTY_HOWTO (-1),
267 EMPTY_HOWTO (-1),
268 EMPTY_HOWTO (-1),
269 EMPTY_HOWTO (-1),
270 EMPTY_HOWTO (-1),
271 EMPTY_HOWTO (-1),
272 EMPTY_HOWTO (-1),
273 HOWTO (40, 0, 2, 0, FALSE, 0, complain_overflow_bitfield,0,"BASEREL", FALSE, 0,0x00000000, FALSE),
276 #define TABLE_SIZE(TABLE) (sizeof (TABLE) / sizeof (TABLE[0]))
278 reloc_howto_type *
279 NAME(aout,reloc_type_lookup) (abfd,code)
280 bfd *abfd;
281 bfd_reloc_code_real_type code;
283 #define EXT(i, j) case i: return &howto_table_ext[j]
284 #define STD(i, j) case i: return &howto_table_std[j]
285 int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
287 if (code == BFD_RELOC_CTOR)
288 switch (bfd_get_arch_info (abfd)->bits_per_address)
290 case 32:
291 code = BFD_RELOC_32;
292 break;
293 case 64:
294 code = BFD_RELOC_64;
295 break;
298 if (ext)
299 switch (code)
301 EXT (BFD_RELOC_8, 0);
302 EXT (BFD_RELOC_16, 1);
303 EXT (BFD_RELOC_32, 2);
304 EXT (BFD_RELOC_HI22, 8);
305 EXT (BFD_RELOC_LO10, 11);
306 EXT (BFD_RELOC_32_PCREL_S2, 6);
307 EXT (BFD_RELOC_SPARC_WDISP22, 7);
308 EXT (BFD_RELOC_SPARC13, 10);
309 EXT (BFD_RELOC_SPARC_GOT10, 14);
310 EXT (BFD_RELOC_SPARC_BASE13, 15);
311 EXT (BFD_RELOC_SPARC_GOT13, 15);
312 EXT (BFD_RELOC_SPARC_GOT22, 16);
313 EXT (BFD_RELOC_SPARC_PC10, 17);
314 EXT (BFD_RELOC_SPARC_PC22, 18);
315 EXT (BFD_RELOC_SPARC_WPLT30, 19);
316 EXT (BFD_RELOC_SPARC_REV32, 26);
317 default: return (reloc_howto_type *) NULL;
319 else
320 /* std relocs. */
321 switch (code)
323 STD (BFD_RELOC_8, 0);
324 STD (BFD_RELOC_16, 1);
325 STD (BFD_RELOC_32, 2);
326 STD (BFD_RELOC_8_PCREL, 4);
327 STD (BFD_RELOC_16_PCREL, 5);
328 STD (BFD_RELOC_32_PCREL, 6);
329 STD (BFD_RELOC_16_BASEREL, 9);
330 STD (BFD_RELOC_32_BASEREL, 10);
331 default: return (reloc_howto_type *) NULL;
336 SUBSECTION
337 Internal entry points
339 DESCRIPTION
340 @file{aoutx.h} exports several routines for accessing the
341 contents of an a.out file, which are gathered and exported in
342 turn by various format specific files (eg sunos.c).
347 FUNCTION
348 aout_@var{size}_swap_exec_header_in
350 SYNOPSIS
351 void aout_@var{size}_swap_exec_header_in,
352 (bfd *abfd,
353 struct external_exec *raw_bytes,
354 struct internal_exec *execp);
356 DESCRIPTION
357 Swap the information in an executable header @var{raw_bytes} taken
358 from a raw byte stream memory image into the internal exec header
359 structure @var{execp}.
362 #ifndef NAME_swap_exec_header_in
363 void
364 NAME(aout,swap_exec_header_in) (abfd, raw_bytes, execp)
365 bfd *abfd;
366 struct external_exec *raw_bytes;
367 struct internal_exec *execp;
369 struct external_exec *bytes = (struct external_exec *)raw_bytes;
371 /* The internal_exec structure has some fields that are unused in this
372 configuration (IE for i960), so ensure that all such uninitialized
373 fields are zero'd out. There are places where two of these structs
374 are memcmp'd, and thus the contents do matter. */
375 memset ((PTR) execp, 0, sizeof (struct internal_exec));
376 /* Now fill in fields in the execp, from the bytes in the raw data. */
377 execp->a_info = H_GET_32 (abfd, bytes->e_info);
378 execp->a_text = GET_WORD (abfd, bytes->e_text);
379 execp->a_data = GET_WORD (abfd, bytes->e_data);
380 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
381 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
382 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
383 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
384 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
386 #define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
387 #endif
390 FUNCTION
391 aout_@var{size}_swap_exec_header_out
393 SYNOPSIS
394 void aout_@var{size}_swap_exec_header_out
395 (bfd *abfd,
396 struct internal_exec *execp,
397 struct external_exec *raw_bytes);
399 DESCRIPTION
400 Swap the information in an internal exec header structure
401 @var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
403 void
404 NAME(aout,swap_exec_header_out) (abfd, execp, raw_bytes)
405 bfd *abfd;
406 struct internal_exec *execp;
407 struct external_exec *raw_bytes;
409 struct external_exec *bytes = (struct external_exec *)raw_bytes;
411 /* Now fill in fields in the raw data, from the fields in the exec struct. */
412 H_PUT_32 (abfd, execp->a_info , bytes->e_info);
413 PUT_WORD (abfd, execp->a_text , bytes->e_text);
414 PUT_WORD (abfd, execp->a_data , bytes->e_data);
415 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
416 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
417 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
418 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
419 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
422 /* Make all the section for an a.out file. */
424 bfd_boolean
425 NAME(aout,make_sections) (abfd)
426 bfd *abfd;
428 if (obj_textsec (abfd) == (asection *) NULL
429 && bfd_make_section (abfd, ".text") == (asection *) NULL)
430 return FALSE;
431 if (obj_datasec (abfd) == (asection *) NULL
432 && bfd_make_section (abfd, ".data") == (asection *) NULL)
433 return FALSE;
434 if (obj_bsssec (abfd) == (asection *) NULL
435 && bfd_make_section (abfd, ".bss") == (asection *) NULL)
436 return FALSE;
437 return TRUE;
441 FUNCTION
442 aout_@var{size}_some_aout_object_p
444 SYNOPSIS
445 const bfd_target *aout_@var{size}_some_aout_object_p
446 (bfd *abfd,
447 const bfd_target *(*callback_to_real_object_p) ());
449 DESCRIPTION
450 Some a.out variant thinks that the file open in @var{abfd}
451 checking is an a.out file. Do some more checking, and set up
452 for access if it really is. Call back to the calling
453 environment's "finish up" function just before returning, to
454 handle any last-minute setup.
457 const bfd_target *
458 NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
459 bfd *abfd;
460 struct internal_exec *execp;
461 const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *));
463 struct aout_data_struct *rawptr, *oldrawptr;
464 const bfd_target *result;
465 bfd_size_type amt = sizeof (struct aout_data_struct);
467 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
468 if (rawptr == NULL)
469 return 0;
471 oldrawptr = abfd->tdata.aout_data;
472 abfd->tdata.aout_data = rawptr;
474 /* Copy the contents of the old tdata struct.
475 In particular, we want the subformat, since for hpux it was set in
476 hp300hpux.c:swap_exec_header_in and will be used in
477 hp300hpux.c:callback. */
478 if (oldrawptr != NULL)
479 *abfd->tdata.aout_data = *oldrawptr;
481 abfd->tdata.aout_data->a.hdr = &rawptr->e;
482 /* Copy in the internal_exec struct. */
483 *(abfd->tdata.aout_data->a.hdr) = *execp;
484 execp = abfd->tdata.aout_data->a.hdr;
486 /* Set the file flags. */
487 abfd->flags = BFD_NO_FLAGS;
488 if (execp->a_drsize || execp->a_trsize)
489 abfd->flags |= HAS_RELOC;
490 /* Setting of EXEC_P has been deferred to the bottom of this function. */
491 if (execp->a_syms)
492 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
493 if (N_DYNAMIC (*execp))
494 abfd->flags |= DYNAMIC;
496 if (N_MAGIC (*execp) == ZMAGIC)
498 abfd->flags |= D_PAGED | WP_TEXT;
499 adata (abfd).magic = z_magic;
501 else if (N_MAGIC (*execp) == QMAGIC)
503 abfd->flags |= D_PAGED | WP_TEXT;
504 adata (abfd).magic = z_magic;
505 adata (abfd).subformat = q_magic_format;
507 else if (N_MAGIC (*execp) == NMAGIC)
509 abfd->flags |= WP_TEXT;
510 adata (abfd).magic = n_magic;
512 else if (N_MAGIC (*execp) == OMAGIC
513 || N_MAGIC (*execp) == BMAGIC)
514 adata (abfd).magic = o_magic;
515 else
517 /* Should have been checked with N_BADMAG before this routine
518 was called. */
519 abort ();
522 bfd_get_start_address (abfd) = execp->a_entry;
524 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
525 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
527 /* The default relocation entry size is that of traditional V7 Unix. */
528 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
530 /* The default symbol entry size is that of traditional Unix. */
531 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
533 #ifdef USE_MMAP
534 bfd_init_window (&obj_aout_sym_window (abfd));
535 bfd_init_window (&obj_aout_string_window (abfd));
536 #endif
537 obj_aout_external_syms (abfd) = NULL;
538 obj_aout_external_strings (abfd) = NULL;
539 obj_aout_sym_hashes (abfd) = NULL;
541 if (! NAME(aout,make_sections) (abfd))
542 goto error_ret;
544 obj_datasec (abfd)->size = execp->a_data;
545 obj_bsssec (abfd)->size = execp->a_bss;
547 obj_textsec (abfd)->flags =
548 (execp->a_trsize != 0
549 ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
550 : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
551 obj_datasec (abfd)->flags =
552 (execp->a_drsize != 0
553 ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
554 : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
555 obj_bsssec (abfd)->flags = SEC_ALLOC;
557 #ifdef THIS_IS_ONLY_DOCUMENTATION
558 /* The common code can't fill in these things because they depend
559 on either the start address of the text segment, the rounding
560 up of virtual addresses between segments, or the starting file
561 position of the text segment -- all of which varies among different
562 versions of a.out. */
564 /* Call back to the format-dependent code to fill in the rest of the
565 fields and do any further cleanup. Things that should be filled
566 in by the callback: */
568 struct exec *execp = exec_hdr (abfd);
570 obj_textsec (abfd)->size = N_TXTSIZE (*execp);
571 /* Data and bss are already filled in since they're so standard. */
573 /* The virtual memory addresses of the sections. */
574 obj_textsec (abfd)->vma = N_TXTADDR (*execp);
575 obj_datasec (abfd)->vma = N_DATADDR (*execp);
576 obj_bsssec (abfd)->vma = N_BSSADDR (*execp);
578 /* The file offsets of the sections. */
579 obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
580 obj_datasec (abfd)->filepos = N_DATOFF (*execp);
582 /* The file offsets of the relocation info. */
583 obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
584 obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
586 /* The file offsets of the string table and symbol table. */
587 obj_str_filepos (abfd) = N_STROFF (*execp);
588 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
590 /* Determine the architecture and machine type of the object file. */
591 switch (N_MACHTYPE (*exec_hdr (abfd)))
593 default:
594 abfd->obj_arch = bfd_arch_obscure;
595 break;
598 adata (abfd)->page_size = TARGET_PAGE_SIZE;
599 adata (abfd)->segment_size = SEGMENT_SIZE;
600 adata (abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
602 return abfd->xvec;
604 /* The architecture is encoded in various ways in various a.out variants,
605 or is not encoded at all in some of them. The relocation size depends
606 on the architecture and the a.out variant. Finally, the return value
607 is the bfd_target vector in use. If an error occurs, return zero and
608 set bfd_error to the appropriate error code.
610 Formats such as b.out, which have additional fields in the a.out
611 header, should cope with them in this callback as well. */
612 #endif /* DOCUMENTATION */
614 result = (*callback_to_real_object_p) (abfd);
616 /* Now that the segment addresses have been worked out, take a better
617 guess at whether the file is executable. If the entry point
618 is within the text segment, assume it is. (This makes files
619 executable even if their entry point address is 0, as long as
620 their text starts at zero.).
622 This test had to be changed to deal with systems where the text segment
623 runs at a different location than the default. The problem is that the
624 entry address can appear to be outside the text segment, thus causing an
625 erroneous conclusion that the file isn't executable.
627 To fix this, we now accept any non-zero entry point as an indication of
628 executability. This will work most of the time, since only the linker
629 sets the entry point, and that is likely to be non-zero for most systems. */
631 if (execp->a_entry != 0
632 || (execp->a_entry >= obj_textsec (abfd)->vma
633 && execp->a_entry < (obj_textsec (abfd)->vma
634 + obj_textsec (abfd)->size)))
635 abfd->flags |= EXEC_P;
636 #ifdef STAT_FOR_EXEC
637 else
639 struct stat stat_buf;
641 /* The original heuristic doesn't work in some important cases.
642 The a.out file has no information about the text start
643 address. For files (like kernels) linked to non-standard
644 addresses (ld -Ttext nnn) the entry point may not be between
645 the default text start (obj_textsec(abfd)->vma) and
646 (obj_textsec(abfd)->vma) + text size. This is not just a mach
647 issue. Many kernels are loaded at non standard addresses. */
648 if (abfd->iostream != NULL
649 && (abfd->flags & BFD_IN_MEMORY) == 0
650 && (fstat (fileno ((FILE *) (abfd->iostream)), &stat_buf) == 0)
651 && ((stat_buf.st_mode & 0111) != 0))
652 abfd->flags |= EXEC_P;
654 #endif /* STAT_FOR_EXEC */
656 if (result)
658 #if 0 /* These should be set correctly anyways. */
659 abfd->sections = obj_textsec (abfd);
660 obj_textsec (abfd)->next = obj_datasec (abfd);
661 obj_datasec (abfd)->next = obj_bsssec (abfd);
662 #endif
663 return result;
666 error_ret:
667 bfd_release (abfd, rawptr);
668 abfd->tdata.aout_data = oldrawptr;
669 return NULL;
673 FUNCTION
674 aout_@var{size}_mkobject
676 SYNOPSIS
677 bfd_boolean aout_@var{size}_mkobject, (bfd *abfd);
679 DESCRIPTION
680 Initialize BFD @var{abfd} for use with a.out files.
683 bfd_boolean
684 NAME(aout,mkobject) (abfd)
685 bfd *abfd;
687 struct aout_data_struct *rawptr;
688 bfd_size_type amt = sizeof (struct aout_data_struct);
690 bfd_set_error (bfd_error_system_call);
692 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
693 if (rawptr == NULL)
694 return FALSE;
696 abfd->tdata.aout_data = rawptr;
697 exec_hdr (abfd) = &(rawptr->e);
699 obj_textsec (abfd) = (asection *) NULL;
700 obj_datasec (abfd) = (asection *) NULL;
701 obj_bsssec (abfd) = (asection *) NULL;
703 return TRUE;
707 FUNCTION
708 aout_@var{size}_machine_type
710 SYNOPSIS
711 enum machine_type aout_@var{size}_machine_type
712 (enum bfd_architecture arch,
713 unsigned long machine));
715 DESCRIPTION
716 Keep track of machine architecture and machine type for
717 a.out's. Return the <<machine_type>> for a particular
718 architecture and machine, or <<M_UNKNOWN>> if that exact architecture
719 and machine can't be represented in a.out format.
721 If the architecture is understood, machine type 0 (default)
722 is always understood.
725 enum machine_type
726 NAME(aout,machine_type) (arch, machine, unknown)
727 enum bfd_architecture arch;
728 unsigned long machine;
729 bfd_boolean *unknown;
731 enum machine_type arch_flags;
733 arch_flags = M_UNKNOWN;
734 *unknown = TRUE;
736 switch (arch)
738 case bfd_arch_sparc:
739 if (machine == 0
740 || machine == bfd_mach_sparc
741 || machine == bfd_mach_sparc_sparclite
742 || machine == bfd_mach_sparc_sparclite_le
743 || machine == bfd_mach_sparc_v9)
744 arch_flags = M_SPARC;
745 else if (machine == bfd_mach_sparc_sparclet)
746 arch_flags = M_SPARCLET;
747 break;
749 case bfd_arch_m68k:
750 switch (machine)
752 case 0: arch_flags = M_68010; break;
753 case bfd_mach_m68000: arch_flags = M_UNKNOWN; *unknown = FALSE; break;
754 case bfd_mach_m68010: arch_flags = M_68010; break;
755 case bfd_mach_m68020: arch_flags = M_68020; break;
756 default: arch_flags = M_UNKNOWN; break;
758 break;
760 case bfd_arch_i386:
761 if (machine == 0
762 || machine == bfd_mach_i386_i386
763 || machine == bfd_mach_i386_i386_intel_syntax)
764 arch_flags = M_386;
765 break;
767 case bfd_arch_a29k:
768 if (machine == 0)
769 arch_flags = M_29K;
770 break;
772 case bfd_arch_arm:
773 if (machine == 0)
774 arch_flags = M_ARM;
775 break;
777 case bfd_arch_mips:
778 switch (machine)
780 case 0:
781 case bfd_mach_mips3000:
782 case bfd_mach_mips3900:
783 arch_flags = M_MIPS1;
784 break;
785 case bfd_mach_mips6000:
786 arch_flags = M_MIPS2;
787 break;
788 case bfd_mach_mips4000:
789 case bfd_mach_mips4010:
790 case bfd_mach_mips4100:
791 case bfd_mach_mips4300:
792 case bfd_mach_mips4400:
793 case bfd_mach_mips4600:
794 case bfd_mach_mips4650:
795 case bfd_mach_mips8000:
796 case bfd_mach_mips9000:
797 case bfd_mach_mips10000:
798 case bfd_mach_mips12000:
799 case bfd_mach_mips16:
800 case bfd_mach_mipsisa32:
801 case bfd_mach_mipsisa32r2:
802 case bfd_mach_mips5:
803 case bfd_mach_mipsisa64:
804 case bfd_mach_mipsisa64r2:
805 case bfd_mach_mips_sb1:
806 /* FIXME: These should be MIPS3, MIPS4, MIPS16, MIPS32, etc. */
807 arch_flags = M_MIPS2;
808 break;
809 default:
810 arch_flags = M_UNKNOWN;
811 break;
813 break;
815 case bfd_arch_ns32k:
816 switch (machine)
818 case 0: arch_flags = M_NS32532; break;
819 case 32032: arch_flags = M_NS32032; break;
820 case 32532: arch_flags = M_NS32532; break;
821 default: arch_flags = M_UNKNOWN; break;
823 break;
825 case bfd_arch_vax:
826 *unknown = FALSE;
827 break;
829 case bfd_arch_cris:
830 if (machine == 0 || machine == 255)
831 arch_flags = M_CRIS;
832 break;
834 case bfd_arch_m88k:
835 *unknown = FALSE;
836 break;
838 default:
839 arch_flags = M_UNKNOWN;
842 if (arch_flags != M_UNKNOWN)
843 *unknown = FALSE;
845 return arch_flags;
849 FUNCTION
850 aout_@var{size}_set_arch_mach
852 SYNOPSIS
853 bfd_boolean aout_@var{size}_set_arch_mach,
854 (bfd *,
855 enum bfd_architecture arch,
856 unsigned long machine));
858 DESCRIPTION
859 Set the architecture and the machine of the BFD @var{abfd} to the
860 values @var{arch} and @var{machine}. Verify that @var{abfd}'s format
861 can support the architecture required.
864 bfd_boolean
865 NAME(aout,set_arch_mach) (abfd, arch, machine)
866 bfd *abfd;
867 enum bfd_architecture arch;
868 unsigned long machine;
870 if (! bfd_default_set_arch_mach (abfd, arch, machine))
871 return FALSE;
873 if (arch != bfd_arch_unknown)
875 bfd_boolean unknown;
877 NAME(aout,machine_type) (arch, machine, &unknown);
878 if (unknown)
879 return FALSE;
882 /* Determine the size of a relocation entry. */
883 switch (arch)
885 case bfd_arch_sparc:
886 case bfd_arch_a29k:
887 case bfd_arch_mips:
888 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
889 break;
890 default:
891 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
892 break;
895 return (*aout_backend_info (abfd)->set_sizes) (abfd);
898 static void
899 adjust_o_magic (abfd, execp)
900 bfd *abfd;
901 struct internal_exec *execp;
903 file_ptr pos = adata (abfd).exec_bytes_size;
904 bfd_vma vma = 0;
905 int pad = 0;
907 /* Text. */
908 obj_textsec (abfd)->filepos = pos;
909 if (!obj_textsec (abfd)->user_set_vma)
910 obj_textsec (abfd)->vma = vma;
911 else
912 vma = obj_textsec (abfd)->vma;
914 pos += obj_textsec (abfd)->size;
915 vma += obj_textsec (abfd)->size;
917 /* Data. */
918 if (!obj_datasec (abfd)->user_set_vma)
920 #if 0 /* ?? Does alignment in the file image really matter? */
921 pad = align_power (vma, obj_datasec (abfd)->alignment_power) - vma;
922 #endif
923 obj_textsec (abfd)->size += pad;
924 pos += pad;
925 vma += pad;
926 obj_datasec (abfd)->vma = vma;
928 else
929 vma = obj_datasec (abfd)->vma;
930 obj_datasec (abfd)->filepos = pos;
931 pos += obj_datasec (abfd)->size;
932 vma += obj_datasec (abfd)->size;
934 /* BSS. */
935 if (!obj_bsssec (abfd)->user_set_vma)
937 #if 0
938 pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
939 #endif
940 obj_datasec (abfd)->size += pad;
941 pos += pad;
942 vma += pad;
943 obj_bsssec (abfd)->vma = vma;
945 else
947 /* The VMA of the .bss section is set by the VMA of the
948 .data section plus the size of the .data section. We may
949 need to add padding bytes to make this true. */
950 pad = obj_bsssec (abfd)->vma - vma;
951 if (pad > 0)
953 obj_datasec (abfd)->size += pad;
954 pos += pad;
957 obj_bsssec (abfd)->filepos = pos;
959 /* Fix up the exec header. */
960 execp->a_text = obj_textsec (abfd)->size;
961 execp->a_data = obj_datasec (abfd)->size;
962 execp->a_bss = obj_bsssec (abfd)->size;
963 N_SET_MAGIC (*execp, OMAGIC);
966 static void
967 adjust_z_magic (abfd, execp)
968 bfd *abfd;
969 struct internal_exec *execp;
971 bfd_size_type data_pad, text_pad;
972 file_ptr text_end;
973 const struct aout_backend_data *abdp;
974 int ztih; /* Nonzero if text includes exec header. */
976 abdp = aout_backend_info (abfd);
978 /* Text. */
979 ztih = (abdp != NULL
980 && (abdp->text_includes_header
981 || obj_aout_subformat (abfd) == q_magic_format));
982 obj_textsec (abfd)->filepos = (ztih
983 ? adata (abfd).exec_bytes_size
984 : adata (abfd).zmagic_disk_block_size);
985 if (! obj_textsec (abfd)->user_set_vma)
987 /* ?? Do we really need to check for relocs here? */
988 obj_textsec (abfd)->vma = ((abfd->flags & HAS_RELOC)
990 : (ztih
991 ? (abdp->default_text_vma
992 + adata (abfd).exec_bytes_size)
993 : abdp->default_text_vma));
994 text_pad = 0;
996 else
998 /* The .text section is being loaded at an unusual address. We
999 may need to pad it such that the .data section starts at a page
1000 boundary. */
1001 if (ztih)
1002 text_pad = ((obj_textsec (abfd)->filepos - obj_textsec (abfd)->vma)
1003 & (adata (abfd).page_size - 1));
1004 else
1005 text_pad = ((- obj_textsec (abfd)->vma)
1006 & (adata (abfd).page_size - 1));
1009 /* Find start of data. */
1010 if (ztih)
1012 text_end = obj_textsec (abfd)->filepos + obj_textsec (abfd)->size;
1013 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
1015 else
1017 /* Note that if page_size == zmagic_disk_block_size, then
1018 filepos == page_size, and this case is the same as the ztih
1019 case. */
1020 text_end = obj_textsec (abfd)->size;
1021 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
1022 text_end += obj_textsec (abfd)->filepos;
1024 obj_textsec (abfd)->size += text_pad;
1025 text_end += text_pad;
1027 /* Data. */
1028 if (!obj_datasec (abfd)->user_set_vma)
1030 bfd_vma vma;
1031 vma = obj_textsec (abfd)->vma + obj_textsec (abfd)->size;
1032 obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
1034 if (abdp && abdp->zmagic_mapped_contiguous)
1036 asection * text = obj_textsec (abfd);
1037 asection * data = obj_datasec (abfd);
1039 text_pad = data->vma - (text->vma + text->size);
1040 /* Only pad the text section if the data
1041 section is going to be placed after it. */
1042 if (text_pad > 0)
1043 text->size += text_pad;
1045 obj_datasec (abfd)->filepos = (obj_textsec (abfd)->filepos
1046 + obj_textsec (abfd)->size);
1048 /* Fix up exec header while we're at it. */
1049 execp->a_text = obj_textsec (abfd)->size;
1050 if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
1051 execp->a_text += adata (abfd).exec_bytes_size;
1052 if (obj_aout_subformat (abfd) == q_magic_format)
1053 N_SET_MAGIC (*execp, QMAGIC);
1054 else
1055 N_SET_MAGIC (*execp, ZMAGIC);
1057 /* Spec says data section should be rounded up to page boundary. */
1058 obj_datasec (abfd)->size
1059 = align_power (obj_datasec (abfd)->size,
1060 obj_bsssec (abfd)->alignment_power);
1061 execp->a_data = BFD_ALIGN (obj_datasec (abfd)->size,
1062 adata (abfd).page_size);
1063 data_pad = execp->a_data - obj_datasec (abfd)->size;
1065 /* BSS. */
1066 if (!obj_bsssec (abfd)->user_set_vma)
1067 obj_bsssec (abfd)->vma = (obj_datasec (abfd)->vma
1068 + obj_datasec (abfd)->size);
1069 /* If the BSS immediately follows the data section and extra space
1070 in the page is left after the data section, fudge data
1071 in the header so that the bss section looks smaller by that
1072 amount. We'll start the bss section there, and lie to the OS.
1073 (Note that a linker script, as well as the above assignment,
1074 could have explicitly set the BSS vma to immediately follow
1075 the data section.) */
1076 if (align_power (obj_bsssec (abfd)->vma, obj_bsssec (abfd)->alignment_power)
1077 == obj_datasec (abfd)->vma + obj_datasec (abfd)->size)
1078 execp->a_bss = (data_pad > obj_bsssec (abfd)->size
1079 ? 0 : obj_bsssec (abfd)->size - data_pad);
1080 else
1081 execp->a_bss = obj_bsssec (abfd)->size;
1084 static void
1085 adjust_n_magic (abfd, execp)
1086 bfd *abfd;
1087 struct internal_exec *execp;
1089 file_ptr pos = adata (abfd).exec_bytes_size;
1090 bfd_vma vma = 0;
1091 int pad;
1093 /* Text. */
1094 obj_textsec (abfd)->filepos = pos;
1095 if (!obj_textsec (abfd)->user_set_vma)
1096 obj_textsec (abfd)->vma = vma;
1097 else
1098 vma = obj_textsec (abfd)->vma;
1099 pos += obj_textsec (abfd)->size;
1100 vma += obj_textsec (abfd)->size;
1102 /* Data. */
1103 obj_datasec (abfd)->filepos = pos;
1104 if (!obj_datasec (abfd)->user_set_vma)
1105 obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
1106 vma = obj_datasec (abfd)->vma;
1108 /* Since BSS follows data immediately, see if it needs alignment. */
1109 vma += obj_datasec (abfd)->size;
1110 pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
1111 obj_datasec (abfd)->size += pad;
1112 pos += obj_datasec (abfd)->size;
1114 /* BSS. */
1115 if (!obj_bsssec (abfd)->user_set_vma)
1116 obj_bsssec (abfd)->vma = vma;
1117 else
1118 vma = obj_bsssec (abfd)->vma;
1120 /* Fix up exec header. */
1121 execp->a_text = obj_textsec (abfd)->size;
1122 execp->a_data = obj_datasec (abfd)->size;
1123 execp->a_bss = obj_bsssec (abfd)->size;
1124 N_SET_MAGIC (*execp, NMAGIC);
1127 bfd_boolean
1128 NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end)
1129 bfd *abfd;
1130 bfd_size_type *text_size;
1131 file_ptr *text_end ATTRIBUTE_UNUSED;
1133 struct internal_exec *execp = exec_hdr (abfd);
1135 if (! NAME(aout,make_sections) (abfd))
1136 return FALSE;
1138 if (adata (abfd).magic != undecided_magic)
1139 return TRUE;
1141 obj_textsec (abfd)->size =
1142 align_power (obj_textsec (abfd)->size,
1143 obj_textsec (abfd)->alignment_power);
1145 *text_size = obj_textsec (abfd)->size;
1146 /* Rule (heuristic) for when to pad to a new page. Note that there
1147 are (at least) two ways demand-paged (ZMAGIC) files have been
1148 handled. Most Berkeley-based systems start the text segment at
1149 (TARGET_PAGE_SIZE). However, newer versions of SUNOS start the text
1150 segment right after the exec header; the latter is counted in the
1151 text segment size, and is paged in by the kernel with the rest of
1152 the text. */
1154 /* This perhaps isn't the right way to do this, but made it simpler for me
1155 to understand enough to implement it. Better would probably be to go
1156 right from BFD flags to alignment/positioning characteristics. But the
1157 old code was sloppy enough about handling the flags, and had enough
1158 other magic, that it was a little hard for me to understand. I think
1159 I understand it better now, but I haven't time to do the cleanup this
1160 minute. */
1162 if (abfd->flags & D_PAGED)
1163 /* Whether or not WP_TEXT is set -- let D_PAGED override. */
1164 adata (abfd).magic = z_magic;
1165 else if (abfd->flags & WP_TEXT)
1166 adata (abfd).magic = n_magic;
1167 else
1168 adata (abfd).magic = o_magic;
1170 #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
1171 #if __GNUC__ >= 2
1172 fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
1173 ({ char *str;
1174 switch (adata (abfd).magic)
1176 case n_magic: str = "NMAGIC"; break;
1177 case o_magic: str = "OMAGIC"; break;
1178 case z_magic: str = "ZMAGIC"; break;
1179 default: abort ();
1181 str;
1183 obj_textsec (abfd)->vma, obj_textsec (abfd)->size,
1184 obj_textsec (abfd)->alignment_power,
1185 obj_datasec (abfd)->vma, obj_datasec (abfd)->size,
1186 obj_datasec (abfd)->alignment_power,
1187 obj_bsssec (abfd)->vma, obj_bsssec (abfd)->size,
1188 obj_bsssec (abfd)->alignment_power);
1189 #endif
1190 #endif
1192 switch (adata (abfd).magic)
1194 case o_magic:
1195 adjust_o_magic (abfd, execp);
1196 break;
1197 case z_magic:
1198 adjust_z_magic (abfd, execp);
1199 break;
1200 case n_magic:
1201 adjust_n_magic (abfd, execp);
1202 break;
1203 default:
1204 abort ();
1207 #ifdef BFD_AOUT_DEBUG
1208 fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
1209 obj_textsec (abfd)->vma, obj_textsec (abfd)->size,
1210 obj_textsec (abfd)->filepos,
1211 obj_datasec (abfd)->vma, obj_datasec (abfd)->size,
1212 obj_datasec (abfd)->filepos,
1213 obj_bsssec (abfd)->vma, obj_bsssec (abfd)->size);
1214 #endif
1216 return TRUE;
1220 FUNCTION
1221 aout_@var{size}_new_section_hook
1223 SYNOPSIS
1224 bfd_boolean aout_@var{size}_new_section_hook,
1225 (bfd *abfd,
1226 asection *newsect));
1228 DESCRIPTION
1229 Called by the BFD in response to a @code{bfd_make_section}
1230 request.
1232 bfd_boolean
1233 NAME(aout,new_section_hook) (abfd, newsect)
1234 bfd *abfd;
1235 asection *newsect;
1237 /* Align to double at least. */
1238 newsect->alignment_power = bfd_get_arch_info (abfd)->section_align_power;
1240 if (bfd_get_format (abfd) == bfd_object)
1242 if (obj_textsec (abfd) == NULL && !strcmp (newsect->name, ".text"))
1244 obj_textsec (abfd)= newsect;
1245 newsect->target_index = N_TEXT;
1246 return TRUE;
1249 if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data"))
1251 obj_datasec (abfd) = newsect;
1252 newsect->target_index = N_DATA;
1253 return TRUE;
1256 if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss"))
1258 obj_bsssec (abfd) = newsect;
1259 newsect->target_index = N_BSS;
1260 return TRUE;
1264 /* We allow more than three sections internally. */
1265 return TRUE;
1268 bfd_boolean
1269 NAME(aout,set_section_contents) (abfd, section, location, offset, count)
1270 bfd *abfd;
1271 sec_ptr section;
1272 const PTR location;
1273 file_ptr offset;
1274 bfd_size_type count;
1276 file_ptr text_end;
1277 bfd_size_type text_size;
1279 if (! abfd->output_has_begun)
1281 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
1282 return FALSE;
1285 if (section == obj_bsssec (abfd))
1287 bfd_set_error (bfd_error_no_contents);
1288 return FALSE;
1291 if (section != obj_textsec (abfd)
1292 && section != obj_datasec (abfd))
1294 if (aout_section_merge_with_text_p (abfd, section))
1295 section->filepos = obj_textsec (abfd)->filepos +
1296 (section->vma - obj_textsec (abfd)->vma);
1297 else
1299 (*_bfd_error_handler)
1300 (_("%s: can not represent section `%s' in a.out object file format"),
1301 bfd_get_filename (abfd), bfd_get_section_name (abfd, section));
1302 bfd_set_error (bfd_error_nonrepresentable_section);
1303 return FALSE;
1307 if (count != 0)
1309 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
1310 || bfd_bwrite (location, count, abfd) != count)
1311 return FALSE;
1314 return TRUE;
1317 /* Read the external symbols from an a.out file. */
1319 static bfd_boolean
1320 aout_get_external_symbols (abfd)
1321 bfd *abfd;
1323 if (obj_aout_external_syms (abfd) == (struct external_nlist *) NULL)
1325 bfd_size_type count;
1326 struct external_nlist *syms;
1327 bfd_size_type amt;
1329 count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
1331 #ifdef USE_MMAP
1332 if (! bfd_get_file_window (abfd, obj_sym_filepos (abfd),
1333 exec_hdr (abfd)->a_syms,
1334 &obj_aout_sym_window (abfd), TRUE))
1335 return FALSE;
1336 syms = (struct external_nlist *) obj_aout_sym_window (abfd).data;
1337 #else
1338 /* We allocate using malloc to make the values easy to free
1339 later on. If we put them on the objalloc it might not be
1340 possible to free them. */
1341 syms = ((struct external_nlist *)
1342 bfd_malloc (count * EXTERNAL_NLIST_SIZE));
1343 if (syms == (struct external_nlist *) NULL && count != 0)
1344 return FALSE;
1346 amt = exec_hdr (abfd)->a_syms;
1347 if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
1348 || bfd_bread (syms, amt, abfd) != amt)
1350 free (syms);
1351 return FALSE;
1353 #endif
1355 obj_aout_external_syms (abfd) = syms;
1356 obj_aout_external_sym_count (abfd) = count;
1359 if (obj_aout_external_strings (abfd) == NULL
1360 && exec_hdr (abfd)->a_syms != 0)
1362 unsigned char string_chars[BYTES_IN_WORD];
1363 bfd_size_type stringsize;
1364 char *strings;
1365 bfd_size_type amt = BYTES_IN_WORD;
1367 /* Get the size of the strings. */
1368 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
1369 || bfd_bread ((PTR) string_chars, amt, abfd) != amt)
1370 return FALSE;
1371 stringsize = GET_WORD (abfd, string_chars);
1373 #ifdef USE_MMAP
1374 if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
1375 &obj_aout_string_window (abfd), TRUE))
1376 return FALSE;
1377 strings = (char *) obj_aout_string_window (abfd).data;
1378 #else
1379 strings = (char *) bfd_malloc (stringsize + 1);
1380 if (strings == NULL)
1381 return FALSE;
1383 /* Skip space for the string count in the buffer for convenience
1384 when using indexes. */
1385 amt = stringsize - BYTES_IN_WORD;
1386 if (bfd_bread (strings + BYTES_IN_WORD, amt, abfd) != amt)
1388 free (strings);
1389 return FALSE;
1391 #endif
1393 /* Ensure that a zero index yields an empty string. */
1394 strings[0] = '\0';
1396 strings[stringsize - 1] = 0;
1398 obj_aout_external_strings (abfd) = strings;
1399 obj_aout_external_string_size (abfd) = stringsize;
1402 return TRUE;
1405 /* Translate an a.out symbol into a BFD symbol. The desc, other, type
1406 and symbol->value fields of CACHE_PTR will be set from the a.out
1407 nlist structure. This function is responsible for setting
1408 symbol->flags and symbol->section, and adjusting symbol->value. */
1410 static bfd_boolean
1411 translate_from_native_sym_flags (abfd, cache_ptr)
1412 bfd *abfd;
1413 aout_symbol_type *cache_ptr;
1415 flagword visible;
1417 if ((cache_ptr->type & N_STAB) != 0
1418 || cache_ptr->type == N_FN)
1420 asection *sec;
1422 /* This is a debugging symbol. */
1423 cache_ptr->symbol.flags = BSF_DEBUGGING;
1425 /* Work out the symbol section. */
1426 switch (cache_ptr->type & N_TYPE)
1428 case N_TEXT:
1429 case N_FN:
1430 sec = obj_textsec (abfd);
1431 break;
1432 case N_DATA:
1433 sec = obj_datasec (abfd);
1434 break;
1435 case N_BSS:
1436 sec = obj_bsssec (abfd);
1437 break;
1438 default:
1439 case N_ABS:
1440 sec = bfd_abs_section_ptr;
1441 break;
1444 cache_ptr->symbol.section = sec;
1445 cache_ptr->symbol.value -= sec->vma;
1447 return TRUE;
1450 /* Get the default visibility. This does not apply to all types, so
1451 we just hold it in a local variable to use if wanted. */
1452 if ((cache_ptr->type & N_EXT) == 0)
1453 visible = BSF_LOCAL;
1454 else
1455 visible = BSF_GLOBAL;
1457 switch (cache_ptr->type)
1459 default:
1460 case N_ABS: case N_ABS | N_EXT:
1461 cache_ptr->symbol.section = bfd_abs_section_ptr;
1462 cache_ptr->symbol.flags = visible;
1463 break;
1465 case N_UNDF | N_EXT:
1466 if (cache_ptr->symbol.value != 0)
1468 /* This is a common symbol. */
1469 cache_ptr->symbol.flags = BSF_GLOBAL;
1470 cache_ptr->symbol.section = bfd_com_section_ptr;
1472 else
1474 cache_ptr->symbol.flags = 0;
1475 cache_ptr->symbol.section = bfd_und_section_ptr;
1477 break;
1479 case N_TEXT: case N_TEXT | N_EXT:
1480 cache_ptr->symbol.section = obj_textsec (abfd);
1481 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1482 cache_ptr->symbol.flags = visible;
1483 break;
1485 /* N_SETV symbols used to represent set vectors placed in the
1486 data section. They are no longer generated. Theoretically,
1487 it was possible to extract the entries and combine them with
1488 new ones, although I don't know if that was ever actually
1489 done. Unless that feature is restored, treat them as data
1490 symbols. */
1491 case N_SETV: case N_SETV | N_EXT:
1492 case N_DATA: case N_DATA | N_EXT:
1493 cache_ptr->symbol.section = obj_datasec (abfd);
1494 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1495 cache_ptr->symbol.flags = visible;
1496 break;
1498 case N_BSS: case N_BSS | N_EXT:
1499 cache_ptr->symbol.section = obj_bsssec (abfd);
1500 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1501 cache_ptr->symbol.flags = visible;
1502 break;
1504 case N_SETA: case N_SETA | N_EXT:
1505 case N_SETT: case N_SETT | N_EXT:
1506 case N_SETD: case N_SETD | N_EXT:
1507 case N_SETB: case N_SETB | N_EXT:
1509 /* This code is no longer needed. It used to be used to make
1510 the linker handle set symbols, but they are now handled in
1511 the add_symbols routine instead. */
1512 #if 0
1513 asection *section;
1514 arelent_chain *reloc;
1515 asection *into_section;
1516 bfd_size_type amt;
1518 /* This is a set symbol. The name of the symbol is the name
1519 of the set (e.g., __CTOR_LIST__). The value of the symbol
1520 is the value to add to the set. We create a section with
1521 the same name as the symbol, and add a reloc to insert the
1522 appropriate value into the section.
1524 This action is actually obsolete; it used to make the
1525 linker do the right thing, but the linker no longer uses
1526 this function. */
1528 section = bfd_get_section_by_name (abfd, cache_ptr->symbol.name);
1529 if (section == NULL)
1531 char *copy;
1533 amt = strlen (cache_ptr->symbol.name) + 1;
1534 copy = bfd_alloc (abfd, amt);
1535 if (copy == NULL)
1536 return FALSE;
1538 strcpy (copy, cache_ptr->symbol.name);
1539 section = bfd_make_section (abfd, copy);
1540 if (section == NULL)
1541 return FALSE;
1544 amt = sizeof (arelent_chain);
1545 reloc = (arelent_chain *) bfd_alloc (abfd, amt);
1546 if (reloc == NULL)
1547 return FALSE;
1549 /* Build a relocation entry for the constructor. */
1550 switch (cache_ptr->type & N_TYPE)
1552 case N_SETA:
1553 into_section = bfd_abs_section_ptr;
1554 cache_ptr->type = N_ABS;
1555 break;
1556 case N_SETT:
1557 into_section = obj_textsec (abfd);
1558 cache_ptr->type = N_TEXT;
1559 break;
1560 case N_SETD:
1561 into_section = obj_datasec (abfd);
1562 cache_ptr->type = N_DATA;
1563 break;
1564 case N_SETB:
1565 into_section = obj_bsssec (abfd);
1566 cache_ptr->type = N_BSS;
1567 break;
1570 /* Build a relocation pointing into the constructor section
1571 pointing at the symbol in the set vector specified. */
1572 reloc->relent.addend = cache_ptr->symbol.value;
1573 cache_ptr->symbol.section = into_section;
1574 reloc->relent.sym_ptr_ptr = into_section->symbol_ptr_ptr;
1576 /* We modify the symbol to belong to a section depending upon
1577 the name of the symbol, and add to the size of the section
1578 to contain a pointer to the symbol. Build a reloc entry to
1579 relocate to this symbol attached to this section. */
1580 section->flags = SEC_CONSTRUCTOR | SEC_RELOC;
1582 section->reloc_count++;
1583 section->alignment_power = 2;
1585 reloc->next = section->constructor_chain;
1586 section->constructor_chain = reloc;
1587 reloc->relent.address = section->size;
1588 section->size += BYTES_IN_WORD;
1590 reloc->relent.howto = CTOR_TABLE_RELOC_HOWTO (abfd);
1592 #endif /* 0 */
1594 switch (cache_ptr->type & N_TYPE)
1596 case N_SETA:
1597 cache_ptr->symbol.section = bfd_abs_section_ptr;
1598 break;
1599 case N_SETT:
1600 cache_ptr->symbol.section = obj_textsec (abfd);
1601 break;
1602 case N_SETD:
1603 cache_ptr->symbol.section = obj_datasec (abfd);
1604 break;
1605 case N_SETB:
1606 cache_ptr->symbol.section = obj_bsssec (abfd);
1607 break;
1610 cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
1612 break;
1614 case N_WARNING:
1615 /* This symbol is the text of a warning message. The next
1616 symbol is the symbol to associate the warning with. If a
1617 reference is made to that symbol, a warning is issued. */
1618 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
1619 cache_ptr->symbol.section = bfd_abs_section_ptr;
1620 break;
1622 case N_INDR: case N_INDR | N_EXT:
1623 /* An indirect symbol. This consists of two symbols in a row.
1624 The first symbol is the name of the indirection. The second
1625 symbol is the name of the target. A reference to the first
1626 symbol becomes a reference to the second. */
1627 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible;
1628 cache_ptr->symbol.section = bfd_ind_section_ptr;
1629 break;
1631 case N_WEAKU:
1632 cache_ptr->symbol.section = bfd_und_section_ptr;
1633 cache_ptr->symbol.flags = BSF_WEAK;
1634 break;
1636 case N_WEAKA:
1637 cache_ptr->symbol.section = bfd_abs_section_ptr;
1638 cache_ptr->symbol.flags = BSF_WEAK;
1639 break;
1641 case N_WEAKT:
1642 cache_ptr->symbol.section = obj_textsec (abfd);
1643 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1644 cache_ptr->symbol.flags = BSF_WEAK;
1645 break;
1647 case N_WEAKD:
1648 cache_ptr->symbol.section = obj_datasec (abfd);
1649 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1650 cache_ptr->symbol.flags = BSF_WEAK;
1651 break;
1653 case N_WEAKB:
1654 cache_ptr->symbol.section = obj_bsssec (abfd);
1655 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1656 cache_ptr->symbol.flags = BSF_WEAK;
1657 break;
1660 return TRUE;
1663 /* Set the fields of SYM_POINTER according to CACHE_PTR. */
1665 static bfd_boolean
1666 translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
1667 bfd *abfd;
1668 asymbol *cache_ptr;
1669 struct external_nlist *sym_pointer;
1671 bfd_vma value = cache_ptr->value;
1672 asection *sec;
1673 bfd_vma off;
1675 /* Mask out any existing type bits in case copying from one section
1676 to another. */
1677 sym_pointer->e_type[0] &= ~N_TYPE;
1679 sec = bfd_get_section (cache_ptr);
1680 off = 0;
1682 if (sec == NULL)
1684 /* This case occurs, e.g., for the *DEBUG* section of a COFF
1685 file. */
1686 (*_bfd_error_handler)
1687 (_("%s: can not represent section for symbol `%s' in a.out object file format"),
1688 bfd_get_filename (abfd),
1689 cache_ptr->name != NULL ? cache_ptr->name : _("*unknown*"));
1690 bfd_set_error (bfd_error_nonrepresentable_section);
1691 return FALSE;
1694 if (sec->output_section != NULL)
1696 off = sec->output_offset;
1697 sec = sec->output_section;
1700 if (bfd_is_abs_section (sec))
1701 sym_pointer->e_type[0] |= N_ABS;
1702 else if (sec == obj_textsec (abfd))
1703 sym_pointer->e_type[0] |= N_TEXT;
1704 else if (sec == obj_datasec (abfd))
1705 sym_pointer->e_type[0] |= N_DATA;
1706 else if (sec == obj_bsssec (abfd))
1707 sym_pointer->e_type[0] |= N_BSS;
1708 else if (bfd_is_und_section (sec))
1709 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1710 else if (bfd_is_ind_section (sec))
1711 sym_pointer->e_type[0] = N_INDR;
1712 else if (bfd_is_com_section (sec))
1713 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1714 else
1716 if (aout_section_merge_with_text_p (abfd, sec))
1717 sym_pointer->e_type[0] |= N_TEXT;
1718 else
1720 (*_bfd_error_handler)
1721 (_("%s: can not represent section `%s' in a.out object file format"),
1722 bfd_get_filename (abfd), bfd_get_section_name (abfd, sec));
1723 bfd_set_error (bfd_error_nonrepresentable_section);
1724 return FALSE;
1728 /* Turn the symbol from section relative to absolute again. */
1729 value += sec->vma + off;
1731 if ((cache_ptr->flags & BSF_WARNING) != 0)
1732 sym_pointer->e_type[0] = N_WARNING;
1734 if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
1735 sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
1736 else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
1737 sym_pointer->e_type[0] |= N_EXT;
1738 else if ((cache_ptr->flags & BSF_LOCAL) != 0)
1739 sym_pointer->e_type[0] &= ~N_EXT;
1741 if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0)
1743 int type = ((aout_symbol_type *) cache_ptr)->type;
1745 switch (type)
1747 case N_ABS: type = N_SETA; break;
1748 case N_TEXT: type = N_SETT; break;
1749 case N_DATA: type = N_SETD; break;
1750 case N_BSS: type = N_SETB; break;
1752 sym_pointer->e_type[0] = type;
1755 if ((cache_ptr->flags & BSF_WEAK) != 0)
1757 int type;
1759 switch (sym_pointer->e_type[0] & N_TYPE)
1761 default:
1762 case N_ABS: type = N_WEAKA; break;
1763 case N_TEXT: type = N_WEAKT; break;
1764 case N_DATA: type = N_WEAKD; break;
1765 case N_BSS: type = N_WEAKB; break;
1766 case N_UNDF: type = N_WEAKU; break;
1768 sym_pointer->e_type[0] = type;
1771 PUT_WORD (abfd, value, sym_pointer->e_value);
1773 return TRUE;
1776 /* Native-level interface to symbols. */
1778 asymbol *
1779 NAME(aout,make_empty_symbol) (abfd)
1780 bfd *abfd;
1782 bfd_size_type amt = sizeof (aout_symbol_type);
1783 aout_symbol_type *new = (aout_symbol_type *) bfd_zalloc (abfd, amt);
1784 if (!new)
1785 return NULL;
1786 new->symbol.the_bfd = abfd;
1788 return &new->symbol;
1791 /* Translate a set of internal symbols into external symbols. */
1793 bfd_boolean
1794 NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic)
1795 bfd *abfd;
1796 aout_symbol_type *in;
1797 struct external_nlist *ext;
1798 bfd_size_type count;
1799 char *str;
1800 bfd_size_type strsize;
1801 bfd_boolean dynamic;
1803 struct external_nlist *ext_end;
1805 ext_end = ext + count;
1806 for (; ext < ext_end; ext++, in++)
1808 bfd_vma x;
1810 x = GET_WORD (abfd, ext->e_strx);
1811 in->symbol.the_bfd = abfd;
1813 /* For the normal symbols, the zero index points at the number
1814 of bytes in the string table but is to be interpreted as the
1815 null string. For the dynamic symbols, the number of bytes in
1816 the string table is stored in the __DYNAMIC structure and the
1817 zero index points at an actual string. */
1818 if (x == 0 && ! dynamic)
1819 in->symbol.name = "";
1820 else if (x < strsize)
1821 in->symbol.name = str + x;
1822 else
1823 return FALSE;
1825 in->symbol.value = GET_SWORD (abfd, ext->e_value);
1826 in->desc = H_GET_16 (abfd, ext->e_desc);
1827 in->other = H_GET_8 (abfd, ext->e_other);
1828 in->type = H_GET_8 (abfd, ext->e_type);
1829 in->symbol.udata.p = NULL;
1831 if (! translate_from_native_sym_flags (abfd, in))
1832 return FALSE;
1834 if (dynamic)
1835 in->symbol.flags |= BSF_DYNAMIC;
1838 return TRUE;
1841 /* We read the symbols into a buffer, which is discarded when this
1842 function exits. We read the strings into a buffer large enough to
1843 hold them all plus all the cached symbol entries. */
1845 bfd_boolean
1846 NAME(aout,slurp_symbol_table) (abfd)
1847 bfd *abfd;
1849 struct external_nlist *old_external_syms;
1850 aout_symbol_type *cached;
1851 bfd_size_type cached_size;
1853 /* If there's no work to be done, don't do any. */
1854 if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
1855 return TRUE;
1857 old_external_syms = obj_aout_external_syms (abfd);
1859 if (! aout_get_external_symbols (abfd))
1860 return FALSE;
1862 cached_size = obj_aout_external_sym_count (abfd);
1863 cached_size *= sizeof (aout_symbol_type);
1864 cached = (aout_symbol_type *) bfd_zmalloc (cached_size);
1865 if (cached == NULL && cached_size != 0)
1866 return FALSE;
1868 /* Convert from external symbol information to internal. */
1869 if (! (NAME(aout,translate_symbol_table)
1870 (abfd, cached,
1871 obj_aout_external_syms (abfd),
1872 obj_aout_external_sym_count (abfd),
1873 obj_aout_external_strings (abfd),
1874 obj_aout_external_string_size (abfd),
1875 FALSE)))
1877 free (cached);
1878 return FALSE;
1881 bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
1883 obj_aout_symbols (abfd) = cached;
1885 /* It is very likely that anybody who calls this function will not
1886 want the external symbol information, so if it was allocated
1887 because of our call to aout_get_external_symbols, we free it up
1888 right away to save space. */
1889 if (old_external_syms == (struct external_nlist *) NULL
1890 && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
1892 #ifdef USE_MMAP
1893 bfd_free_window (&obj_aout_sym_window (abfd));
1894 #else
1895 free (obj_aout_external_syms (abfd));
1896 #endif
1897 obj_aout_external_syms (abfd) = NULL;
1900 return TRUE;
1903 /* We use a hash table when writing out symbols so that we only write
1904 out a particular string once. This helps particularly when the
1905 linker writes out stabs debugging entries, because each different
1906 contributing object file tends to have many duplicate stabs
1907 strings.
1909 This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
1910 if BFD_TRADITIONAL_FORMAT is set. */
1912 static bfd_size_type add_to_stringtab
1913 PARAMS ((bfd *, struct bfd_strtab_hash *, const char *, bfd_boolean));
1914 static bfd_boolean emit_stringtab
1915 PARAMS ((bfd *, struct bfd_strtab_hash *));
1917 /* Get the index of a string in a strtab, adding it if it is not
1918 already present. */
1920 static INLINE bfd_size_type
1921 add_to_stringtab (abfd, tab, str, copy)
1922 bfd *abfd;
1923 struct bfd_strtab_hash *tab;
1924 const char *str;
1925 bfd_boolean copy;
1927 bfd_boolean hash;
1928 bfd_size_type index;
1930 /* An index of 0 always means the empty string. */
1931 if (str == 0 || *str == '\0')
1932 return 0;
1934 /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
1935 doesn't understand a hashed string table. */
1936 hash = TRUE;
1937 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
1938 hash = FALSE;
1940 index = _bfd_stringtab_add (tab, str, hash, copy);
1942 if (index != (bfd_size_type) -1)
1944 /* Add BYTES_IN_WORD to the return value to account for the
1945 space taken up by the string table size. */
1946 index += BYTES_IN_WORD;
1949 return index;
1952 /* Write out a strtab. ABFD is already at the right location in the
1953 file. */
1955 static bfd_boolean
1956 emit_stringtab (abfd, tab)
1957 register bfd *abfd;
1958 struct bfd_strtab_hash *tab;
1960 bfd_byte buffer[BYTES_IN_WORD];
1961 bfd_size_type amt = BYTES_IN_WORD;
1963 /* The string table starts with the size. */
1964 PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
1965 if (bfd_bwrite ((PTR) buffer, amt, abfd) != amt)
1966 return FALSE;
1968 return _bfd_stringtab_emit (abfd, tab);
1971 bfd_boolean
1972 NAME(aout,write_syms) (abfd)
1973 bfd *abfd;
1975 unsigned int count ;
1976 asymbol **generic = bfd_get_outsymbols (abfd);
1977 struct bfd_strtab_hash *strtab;
1979 strtab = _bfd_stringtab_init ();
1980 if (strtab == NULL)
1981 return FALSE;
1983 for (count = 0; count < bfd_get_symcount (abfd); count++)
1985 asymbol *g = generic[count];
1986 bfd_size_type indx;
1987 struct external_nlist nsp;
1988 bfd_size_type amt;
1990 indx = add_to_stringtab (abfd, strtab, g->name, FALSE);
1991 if (indx == (bfd_size_type) -1)
1992 goto error_return;
1993 PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
1995 if (bfd_asymbol_flavour (g) == abfd->xvec->flavour)
1997 H_PUT_16 (abfd, aout_symbol (g)->desc, nsp.e_desc);
1998 H_PUT_8 (abfd, aout_symbol (g)->other, nsp.e_other);
1999 H_PUT_8 (abfd, aout_symbol (g)->type, nsp.e_type);
2001 else
2003 H_PUT_16 (abfd, 0, nsp.e_desc);
2004 H_PUT_8 (abfd, 0, nsp.e_other);
2005 H_PUT_8 (abfd, 0, nsp.e_type);
2008 if (! translate_to_native_sym_flags (abfd, g, &nsp))
2009 goto error_return;
2011 amt = EXTERNAL_NLIST_SIZE;
2012 if (bfd_bwrite ((PTR) &nsp, amt, abfd) != amt)
2013 goto error_return;
2015 /* NB: `KEEPIT' currently overlays `udata.p', so set this only
2016 here, at the end. */
2017 g->KEEPIT = count;
2020 if (! emit_stringtab (abfd, strtab))
2021 goto error_return;
2023 _bfd_stringtab_free (strtab);
2025 return TRUE;
2027 error_return:
2028 _bfd_stringtab_free (strtab);
2029 return FALSE;
2032 long
2033 NAME(aout,canonicalize_symtab) (abfd, location)
2034 bfd *abfd;
2035 asymbol **location;
2037 unsigned int counter = 0;
2038 aout_symbol_type *symbase;
2040 if (!NAME(aout,slurp_symbol_table) (abfd))
2041 return -1;
2043 for (symbase = obj_aout_symbols (abfd);
2044 counter++ < bfd_get_symcount (abfd);
2046 *(location++) = (asymbol *) (symbase++);
2047 *location++ =0;
2048 return bfd_get_symcount (abfd);
2051 /* Standard reloc stuff. */
2052 /* Output standard relocation information to a file in target byte order. */
2054 extern void NAME(aout,swap_std_reloc_out)
2055 PARAMS ((bfd *, arelent *, struct reloc_std_external *));
2057 void
2058 NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
2059 bfd *abfd;
2060 arelent *g;
2061 struct reloc_std_external *natptr;
2063 int r_index;
2064 asymbol *sym = *(g->sym_ptr_ptr);
2065 int r_extern;
2066 unsigned int r_length;
2067 int r_pcrel;
2068 int r_baserel, r_jmptable, r_relative;
2069 asection *output_section = sym->section->output_section;
2071 PUT_WORD (abfd, g->address, natptr->r_address);
2073 r_length = g->howto->size ; /* Size as a power of two. */
2074 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
2075 /* XXX This relies on relocs coming from a.out files. */
2076 r_baserel = (g->howto->type & 8) != 0;
2077 r_jmptable = (g->howto->type & 16) != 0;
2078 r_relative = (g->howto->type & 32) != 0;
2080 #if 0
2081 /* For a standard reloc, the addend is in the object file. */
2082 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
2083 #endif
2085 /* Name was clobbered by aout_write_syms to be symbol index. */
2087 /* If this relocation is relative to a symbol then set the
2088 r_index to the symbols index, and the r_extern bit.
2090 Absolute symbols can come in in two ways, either as an offset
2091 from the abs section, or as a symbol which has an abs value.
2092 check for that here. */
2094 if (bfd_is_com_section (output_section)
2095 || bfd_is_abs_section (output_section)
2096 || bfd_is_und_section (output_section))
2098 if (bfd_abs_section_ptr->symbol == sym)
2100 /* Whoops, looked like an abs symbol, but is
2101 really an offset from the abs section. */
2102 r_index = N_ABS;
2103 r_extern = 0;
2105 else
2107 /* Fill in symbol. */
2108 r_extern = 1;
2109 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2112 else
2114 /* Just an ordinary section. */
2115 r_extern = 0;
2116 r_index = output_section->target_index;
2119 /* Now the fun stuff. */
2120 if (bfd_header_big_endian (abfd))
2122 natptr->r_index[0] = r_index >> 16;
2123 natptr->r_index[1] = r_index >> 8;
2124 natptr->r_index[2] = r_index;
2125 natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
2126 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
2127 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
2128 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
2129 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
2130 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
2132 else
2134 natptr->r_index[2] = r_index >> 16;
2135 natptr->r_index[1] = r_index >> 8;
2136 natptr->r_index[0] = r_index;
2137 natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
2138 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
2139 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
2140 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
2141 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
2142 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
2146 /* Extended stuff. */
2147 /* Output extended relocation information to a file in target byte order. */
2149 extern void NAME(aout,swap_ext_reloc_out)
2150 PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
2152 void
2153 NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
2154 bfd *abfd;
2155 arelent *g;
2156 register struct reloc_ext_external *natptr;
2158 int r_index;
2159 int r_extern;
2160 unsigned int r_type;
2161 bfd_vma r_addend;
2162 asymbol *sym = *(g->sym_ptr_ptr);
2163 asection *output_section = sym->section->output_section;
2165 PUT_WORD (abfd, g->address, natptr->r_address);
2167 r_type = (unsigned int) g->howto->type;
2169 r_addend = g->addend;
2170 if ((sym->flags & BSF_SECTION_SYM) != 0)
2171 r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma;
2173 /* If this relocation is relative to a symbol then set the
2174 r_index to the symbols index, and the r_extern bit.
2176 Absolute symbols can come in in two ways, either as an offset
2177 from the abs section, or as a symbol which has an abs value.
2178 check for that here. */
2179 if (bfd_is_abs_section (bfd_get_section (sym)))
2181 r_extern = 0;
2182 r_index = N_ABS;
2184 else if ((sym->flags & BSF_SECTION_SYM) == 0)
2186 if (bfd_is_und_section (bfd_get_section (sym))
2187 || (sym->flags & BSF_GLOBAL) != 0)
2188 r_extern = 1;
2189 else
2190 r_extern = 0;
2191 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2193 else
2195 /* Just an ordinary section. */
2196 r_extern = 0;
2197 r_index = output_section->target_index;
2200 /* Now the fun stuff. */
2201 if (bfd_header_big_endian (abfd))
2203 natptr->r_index[0] = r_index >> 16;
2204 natptr->r_index[1] = r_index >> 8;
2205 natptr->r_index[2] = r_index;
2206 natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
2207 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
2209 else
2211 natptr->r_index[2] = r_index >> 16;
2212 natptr->r_index[1] = r_index >> 8;
2213 natptr->r_index[0] = r_index;
2214 natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
2215 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE));
2218 PUT_WORD (abfd, r_addend, natptr->r_addend);
2221 /* BFD deals internally with all things based from the section they're
2222 in. so, something in 10 bytes into a text section with a base of
2223 50 would have a symbol (.text+10) and know .text vma was 50.
2225 Aout keeps all it's symbols based from zero, so the symbol would
2226 contain 60. This macro subs the base of each section from the value
2227 to give the true offset from the section. */
2229 #define MOVE_ADDRESS(ad) \
2230 if (r_extern) \
2232 /* Undefined symbol. */ \
2233 cache_ptr->sym_ptr_ptr = symbols + r_index; \
2234 cache_ptr->addend = ad; \
2236 else \
2238 /* Defined, section relative. Replace symbol with pointer to \
2239 symbol which points to section. */ \
2240 switch (r_index) \
2242 case N_TEXT: \
2243 case N_TEXT | N_EXT: \
2244 cache_ptr->sym_ptr_ptr = obj_textsec (abfd)->symbol_ptr_ptr; \
2245 cache_ptr->addend = ad - su->textsec->vma; \
2246 break; \
2247 case N_DATA: \
2248 case N_DATA | N_EXT: \
2249 cache_ptr->sym_ptr_ptr = obj_datasec (abfd)->symbol_ptr_ptr; \
2250 cache_ptr->addend = ad - su->datasec->vma; \
2251 break; \
2252 case N_BSS: \
2253 case N_BSS | N_EXT: \
2254 cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr; \
2255 cache_ptr->addend = ad - su->bsssec->vma; \
2256 break; \
2257 default: \
2258 case N_ABS: \
2259 case N_ABS | N_EXT: \
2260 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
2261 cache_ptr->addend = ad; \
2262 break; \
2266 void
2267 NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2268 bfd *abfd;
2269 struct reloc_ext_external *bytes;
2270 arelent *cache_ptr;
2271 asymbol **symbols;
2272 bfd_size_type symcount;
2274 unsigned int r_index;
2275 int r_extern;
2276 unsigned int r_type;
2277 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2279 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2281 /* Now the fun stuff. */
2282 if (bfd_header_big_endian (abfd))
2284 r_index = (((unsigned int) bytes->r_index[0] << 16)
2285 | ((unsigned int) bytes->r_index[1] << 8)
2286 | bytes->r_index[2]);
2287 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2288 r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2289 >> RELOC_EXT_BITS_TYPE_SH_BIG);
2291 else
2293 r_index = (((unsigned int) bytes->r_index[2] << 16)
2294 | ((unsigned int) bytes->r_index[1] << 8)
2295 | bytes->r_index[0]);
2296 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2297 r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2298 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
2301 cache_ptr->howto = howto_table_ext + r_type;
2303 /* Base relative relocs are always against the symbol table,
2304 regardless of the setting of r_extern. r_extern just reflects
2305 whether the symbol the reloc is against is local or global. */
2306 if (r_type == (unsigned int) RELOC_BASE10
2307 || r_type == (unsigned int) RELOC_BASE13
2308 || r_type == (unsigned int) RELOC_BASE22)
2309 r_extern = 1;
2311 if (r_extern && r_index > symcount)
2313 /* We could arrange to return an error, but it might be useful
2314 to see the file even if it is bad. */
2315 r_extern = 0;
2316 r_index = N_ABS;
2319 MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
2322 void
2323 NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2324 bfd *abfd;
2325 struct reloc_std_external *bytes;
2326 arelent *cache_ptr;
2327 asymbol **symbols;
2328 bfd_size_type symcount;
2330 unsigned int r_index;
2331 int r_extern;
2332 unsigned int r_length;
2333 int r_pcrel;
2334 int r_baserel, r_jmptable, r_relative;
2335 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2336 unsigned int howto_idx;
2338 cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
2340 /* Now the fun stuff. */
2341 if (bfd_header_big_endian (abfd))
2343 r_index = (((unsigned int) bytes->r_index[0] << 16)
2344 | ((unsigned int) bytes->r_index[1] << 8)
2345 | bytes->r_index[2]);
2346 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2347 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2348 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2349 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2350 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2351 r_length = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2352 >> RELOC_STD_BITS_LENGTH_SH_BIG);
2354 else
2356 r_index = (((unsigned int) bytes->r_index[2] << 16)
2357 | ((unsigned int) bytes->r_index[1] << 8)
2358 | bytes->r_index[0]);
2359 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2360 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2361 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2362 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2363 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2364 r_length = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2365 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
2368 howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
2369 + 16 * r_jmptable + 32 * r_relative);
2370 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
2371 cache_ptr->howto = howto_table_std + howto_idx;
2372 BFD_ASSERT (cache_ptr->howto->type != (unsigned int) -1);
2374 /* Base relative relocs are always against the symbol table,
2375 regardless of the setting of r_extern. r_extern just reflects
2376 whether the symbol the reloc is against is local or global. */
2377 if (r_baserel)
2378 r_extern = 1;
2380 if (r_extern && r_index > symcount)
2382 /* We could arrange to return an error, but it might be useful
2383 to see the file even if it is bad. */
2384 r_extern = 0;
2385 r_index = N_ABS;
2388 MOVE_ADDRESS (0);
2391 /* Read and swap the relocs for a section. */
2393 bfd_boolean
2394 NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
2395 bfd *abfd;
2396 sec_ptr asect;
2397 asymbol **symbols;
2399 bfd_size_type count;
2400 bfd_size_type reloc_size;
2401 PTR relocs;
2402 arelent *reloc_cache;
2403 size_t each_size;
2404 unsigned int counter = 0;
2405 arelent *cache_ptr;
2406 bfd_size_type amt;
2408 if (asect->relocation)
2409 return TRUE;
2411 if (asect->flags & SEC_CONSTRUCTOR)
2412 return TRUE;
2414 if (asect == obj_datasec (abfd))
2415 reloc_size = exec_hdr (abfd)->a_drsize;
2416 else if (asect == obj_textsec (abfd))
2417 reloc_size = exec_hdr (abfd)->a_trsize;
2418 else if (asect == obj_bsssec (abfd))
2419 reloc_size = 0;
2420 else
2422 bfd_set_error (bfd_error_invalid_operation);
2423 return FALSE;
2426 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
2427 return FALSE;
2429 each_size = obj_reloc_entry_size (abfd);
2431 count = reloc_size / each_size;
2433 amt = count * sizeof (arelent);
2434 reloc_cache = (arelent *) bfd_zmalloc (amt);
2435 if (reloc_cache == NULL && count != 0)
2436 return FALSE;
2438 relocs = bfd_malloc (reloc_size);
2439 if (relocs == NULL && reloc_size != 0)
2441 free (reloc_cache);
2442 return FALSE;
2445 if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
2447 free (relocs);
2448 free (reloc_cache);
2449 return FALSE;
2452 cache_ptr = reloc_cache;
2453 if (each_size == RELOC_EXT_SIZE)
2455 struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
2457 for (; counter < count; counter++, rptr++, cache_ptr++)
2458 MY_swap_ext_reloc_in (abfd, rptr, cache_ptr, symbols,
2459 (bfd_size_type) bfd_get_symcount (abfd));
2461 else
2463 struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
2465 for (; counter < count; counter++, rptr++, cache_ptr++)
2466 MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
2467 (bfd_size_type) bfd_get_symcount (abfd));
2470 free (relocs);
2472 asect->relocation = reloc_cache;
2473 asect->reloc_count = cache_ptr - reloc_cache;
2475 return TRUE;
2478 /* Write out a relocation section into an object file. */
2480 bfd_boolean
2481 NAME(aout,squirt_out_relocs) (abfd, section)
2482 bfd *abfd;
2483 asection *section;
2485 arelent **generic;
2486 unsigned char *native, *natptr;
2487 size_t each_size;
2489 unsigned int count = section->reloc_count;
2490 bfd_size_type natsize;
2492 if (count == 0 || section->orelocation == NULL)
2493 return TRUE;
2495 each_size = obj_reloc_entry_size (abfd);
2496 natsize = (bfd_size_type) each_size * count;
2497 native = (unsigned char *) bfd_zalloc (abfd, natsize);
2498 if (!native)
2499 return FALSE;
2501 generic = section->orelocation;
2503 if (each_size == RELOC_EXT_SIZE)
2505 for (natptr = native;
2506 count != 0;
2507 --count, natptr += each_size, ++generic)
2508 MY_swap_ext_reloc_out (abfd, *generic,
2509 (struct reloc_ext_external *) natptr);
2511 else
2513 for (natptr = native;
2514 count != 0;
2515 --count, natptr += each_size, ++generic)
2516 MY_swap_std_reloc_out (abfd, *generic,
2517 (struct reloc_std_external *) natptr);
2520 if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
2522 bfd_release (abfd, native);
2523 return FALSE;
2525 bfd_release (abfd, native);
2527 return TRUE;
2530 /* This is stupid. This function should be a boolean predicate. */
2532 long
2533 NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols)
2534 bfd *abfd;
2535 sec_ptr section;
2536 arelent **relptr;
2537 asymbol **symbols;
2539 arelent *tblptr = section->relocation;
2540 unsigned int count;
2542 if (section == obj_bsssec (abfd))
2544 *relptr = NULL;
2545 return 0;
2548 if (!(tblptr || NAME(aout,slurp_reloc_table) (abfd, section, symbols)))
2549 return -1;
2551 if (section->flags & SEC_CONSTRUCTOR)
2553 arelent_chain *chain = section->constructor_chain;
2554 for (count = 0; count < section->reloc_count; count ++)
2556 *relptr ++ = &chain->relent;
2557 chain = chain->next;
2560 else
2562 tblptr = section->relocation;
2564 for (count = 0; count++ < section->reloc_count; )
2566 *relptr++ = tblptr++;
2569 *relptr = 0;
2571 return section->reloc_count;
2574 long
2575 NAME(aout,get_reloc_upper_bound) (abfd, asect)
2576 bfd *abfd;
2577 sec_ptr asect;
2579 if (bfd_get_format (abfd) != bfd_object)
2581 bfd_set_error (bfd_error_invalid_operation);
2582 return -1;
2585 if (asect->flags & SEC_CONSTRUCTOR)
2586 return (sizeof (arelent *) * (asect->reloc_count+1));
2588 if (asect == obj_datasec (abfd))
2589 return (sizeof (arelent *)
2590 * ((exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd))
2591 + 1));
2593 if (asect == obj_textsec (abfd))
2594 return (sizeof (arelent *)
2595 * ((exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd))
2596 + 1));
2598 if (asect == obj_bsssec (abfd))
2599 return sizeof (arelent *);
2601 if (asect == obj_bsssec (abfd))
2602 return 0;
2604 bfd_set_error (bfd_error_invalid_operation);
2605 return -1;
2608 long
2609 NAME(aout,get_symtab_upper_bound) (abfd)
2610 bfd *abfd;
2612 if (!NAME(aout,slurp_symbol_table) (abfd))
2613 return -1;
2615 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2618 alent *
2619 NAME(aout,get_lineno) (ignore_abfd, ignore_symbol)
2620 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2621 asymbol *ignore_symbol ATTRIBUTE_UNUSED;
2623 return (alent *)NULL;
2626 void
2627 NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
2628 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2629 asymbol *symbol;
2630 symbol_info *ret;
2632 bfd_symbol_info (symbol, ret);
2634 if (ret->type == '?')
2636 int type_code = aout_symbol (symbol)->type & 0xff;
2637 const char *stab_name = bfd_get_stab_name (type_code);
2638 static char buf[10];
2640 if (stab_name == NULL)
2642 sprintf (buf, "(%d)", type_code);
2643 stab_name = buf;
2645 ret->type = '-';
2646 ret->stab_type = type_code;
2647 ret->stab_other = (unsigned) (aout_symbol (symbol)->other & 0xff);
2648 ret->stab_desc = (unsigned) (aout_symbol (symbol)->desc & 0xffff);
2649 ret->stab_name = stab_name;
2653 void
2654 NAME(aout,print_symbol) (abfd, afile, symbol, how)
2655 bfd *abfd;
2656 PTR afile;
2657 asymbol *symbol;
2658 bfd_print_symbol_type how;
2660 FILE *file = (FILE *)afile;
2662 switch (how)
2664 case bfd_print_symbol_name:
2665 if (symbol->name)
2666 fprintf (file,"%s", symbol->name);
2667 break;
2668 case bfd_print_symbol_more:
2669 fprintf (file,"%4x %2x %2x",
2670 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2671 (unsigned) (aout_symbol (symbol)->other & 0xff),
2672 (unsigned) (aout_symbol (symbol)->type));
2673 break;
2674 case bfd_print_symbol_all:
2676 const char *section_name = symbol->section->name;
2678 bfd_print_symbol_vandf (abfd, (PTR)file, symbol);
2680 fprintf (file," %-5s %04x %02x %02x",
2681 section_name,
2682 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2683 (unsigned) (aout_symbol (symbol)->other & 0xff),
2684 (unsigned) (aout_symbol (symbol)->type & 0xff));
2685 if (symbol->name)
2686 fprintf (file," %s", symbol->name);
2688 break;
2692 /* If we don't have to allocate more than 1MB to hold the generic
2693 symbols, we use the generic minisymbol methord: it's faster, since
2694 it only translates the symbols once, not multiple times. */
2695 #define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
2697 /* Read minisymbols. For minisymbols, we use the unmodified a.out
2698 symbols. The minisymbol_to_symbol function translates these into
2699 BFD asymbol structures. */
2701 long
2702 NAME(aout,read_minisymbols) (abfd, dynamic, minisymsp, sizep)
2703 bfd *abfd;
2704 bfd_boolean dynamic;
2705 PTR *minisymsp;
2706 unsigned int *sizep;
2708 if (dynamic)
2710 /* We could handle the dynamic symbols here as well, but it's
2711 easier to hand them off. */
2712 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2715 if (! aout_get_external_symbols (abfd))
2716 return -1;
2718 if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2719 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2721 *minisymsp = (PTR) obj_aout_external_syms (abfd);
2723 /* By passing the external symbols back from this routine, we are
2724 giving up control over the memory block. Clear
2725 obj_aout_external_syms, so that we do not try to free it
2726 ourselves. */
2727 obj_aout_external_syms (abfd) = NULL;
2729 *sizep = EXTERNAL_NLIST_SIZE;
2730 return obj_aout_external_sym_count (abfd);
2733 /* Convert a minisymbol to a BFD asymbol. A minisymbol is just an
2734 unmodified a.out symbol. The SYM argument is a structure returned
2735 by bfd_make_empty_symbol, which we fill in here. */
2737 asymbol *
2738 NAME(aout,minisymbol_to_symbol) (abfd, dynamic, minisym, sym)
2739 bfd *abfd;
2740 bfd_boolean dynamic;
2741 const PTR minisym;
2742 asymbol *sym;
2744 if (dynamic
2745 || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2746 return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
2748 memset (sym, 0, sizeof (aout_symbol_type));
2750 /* We call translate_symbol_table to translate a single symbol. */
2751 if (! (NAME(aout,translate_symbol_table)
2752 (abfd,
2753 (aout_symbol_type *) sym,
2754 (struct external_nlist *) minisym,
2755 (bfd_size_type) 1,
2756 obj_aout_external_strings (abfd),
2757 obj_aout_external_string_size (abfd),
2758 FALSE)))
2759 return NULL;
2761 return sym;
2764 /* Provided a BFD, a section and an offset into the section, calculate
2765 and return the name of the source file and the line nearest to the
2766 wanted location. */
2768 bfd_boolean
2769 NAME(aout,find_nearest_line)
2770 (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
2771 bfd *abfd;
2772 asection *section;
2773 asymbol **symbols;
2774 bfd_vma offset;
2775 const char **filename_ptr;
2776 const char **functionname_ptr;
2777 unsigned int *line_ptr;
2779 /* Run down the file looking for the filename, function and linenumber. */
2780 asymbol **p;
2781 const char *directory_name = NULL;
2782 const char *main_file_name = NULL;
2783 const char *current_file_name = NULL;
2784 const char *line_file_name = NULL; /* Value of current_file_name at line number. */
2785 const char *line_directory_name = NULL; /* Value of directory_name at line number. */
2786 bfd_vma low_line_vma = 0;
2787 bfd_vma low_func_vma = 0;
2788 asymbol *func = 0;
2789 bfd_size_type filelen, funclen;
2790 char *buf;
2792 *filename_ptr = abfd->filename;
2793 *functionname_ptr = 0;
2794 *line_ptr = 0;
2796 if (symbols != (asymbol **)NULL)
2798 for (p = symbols; *p; p++)
2800 aout_symbol_type *q = (aout_symbol_type *) (*p);
2801 next:
2802 switch (q->type)
2804 case N_TEXT:
2805 /* If this looks like a file name symbol, and it comes after
2806 the line number we have found so far, but before the
2807 offset, then we have probably not found the right line
2808 number. */
2809 if (q->symbol.value <= offset
2810 && ((q->symbol.value > low_line_vma
2811 && (line_file_name != NULL
2812 || *line_ptr != 0))
2813 || (q->symbol.value > low_func_vma
2814 && func != NULL)))
2816 const char *symname;
2818 symname = q->symbol.name;
2819 if (strcmp (symname + strlen (symname) - 2, ".o") == 0)
2821 if (q->symbol.value > low_line_vma)
2823 *line_ptr = 0;
2824 line_file_name = NULL;
2826 if (q->symbol.value > low_func_vma)
2827 func = NULL;
2830 break;
2832 case N_SO:
2833 /* If this symbol is less than the offset, but greater than
2834 the line number we have found so far, then we have not
2835 found the right line number. */
2836 if (q->symbol.value <= offset)
2838 if (q->symbol.value > low_line_vma)
2840 *line_ptr = 0;
2841 line_file_name = NULL;
2843 if (q->symbol.value > low_func_vma)
2844 func = NULL;
2847 main_file_name = current_file_name = q->symbol.name;
2848 /* Look ahead to next symbol to check if that too is an N_SO. */
2849 p++;
2850 if (*p == NULL)
2851 break;
2852 q = (aout_symbol_type *) (*p);
2853 if (q->type != (int)N_SO)
2854 goto next;
2856 /* Found a second N_SO First is directory; second is filename. */
2857 directory_name = current_file_name;
2858 main_file_name = current_file_name = q->symbol.name;
2859 if (obj_textsec (abfd) != section)
2860 goto done;
2861 break;
2862 case N_SOL:
2863 current_file_name = q->symbol.name;
2864 break;
2866 case N_SLINE:
2868 case N_DSLINE:
2869 case N_BSLINE:
2870 /* We'll keep this if it resolves nearer than the one we have
2871 already. */
2872 if (q->symbol.value >= low_line_vma
2873 && q->symbol.value <= offset)
2875 *line_ptr = q->desc;
2876 low_line_vma = q->symbol.value;
2877 line_file_name = current_file_name;
2878 line_directory_name = directory_name;
2880 break;
2881 case N_FUN:
2883 /* We'll keep this if it is nearer than the one we have already. */
2884 if (q->symbol.value >= low_func_vma &&
2885 q->symbol.value <= offset)
2887 low_func_vma = q->symbol.value;
2888 func = (asymbol *)q;
2890 else if (q->symbol.value > offset)
2891 goto done;
2893 break;
2898 done:
2899 if (*line_ptr != 0)
2901 main_file_name = line_file_name;
2902 directory_name = line_directory_name;
2905 if (main_file_name == NULL
2906 || IS_ABSOLUTE_PATH (main_file_name)
2907 || directory_name == NULL)
2908 filelen = 0;
2909 else
2910 filelen = strlen (directory_name) + strlen (main_file_name);
2912 if (func == NULL)
2913 funclen = 0;
2914 else
2915 funclen = strlen (bfd_asymbol_name (func));
2917 if (adata (abfd).line_buf != NULL)
2918 free (adata (abfd).line_buf);
2920 if (filelen + funclen == 0)
2921 adata (abfd).line_buf = buf = NULL;
2922 else
2924 buf = (char *) bfd_malloc (filelen + funclen + 3);
2925 adata (abfd).line_buf = buf;
2926 if (buf == NULL)
2927 return FALSE;
2930 if (main_file_name != NULL)
2932 if (IS_ABSOLUTE_PATH (main_file_name) || directory_name == NULL)
2933 *filename_ptr = main_file_name;
2934 else
2936 sprintf (buf, "%s%s", directory_name, main_file_name);
2937 *filename_ptr = buf;
2938 buf += filelen + 1;
2942 if (func)
2944 const char *function = func->name;
2945 char *colon;
2947 /* The caller expects a symbol name. We actually have a
2948 function name, without the leading underscore. Put the
2949 underscore back in, so that the caller gets a symbol name. */
2950 if (bfd_get_symbol_leading_char (abfd) == '\0')
2951 strcpy (buf, function);
2952 else
2954 buf[0] = bfd_get_symbol_leading_char (abfd);
2955 strcpy (buf + 1, function);
2957 /* Have to remove : stuff. */
2958 colon = strchr (buf, ':');
2959 if (colon != NULL)
2960 *colon = '\0';
2961 *functionname_ptr = buf;
2964 return TRUE;
2968 NAME(aout,sizeof_headers) (abfd, execable)
2969 bfd *abfd;
2970 bfd_boolean execable ATTRIBUTE_UNUSED;
2972 return adata (abfd).exec_bytes_size;
2975 /* Free all information we have cached for this BFD. We can always
2976 read it again later if we need it. */
2978 bfd_boolean
2979 NAME(aout,bfd_free_cached_info) (abfd)
2980 bfd *abfd;
2982 asection *o;
2984 if (bfd_get_format (abfd) != bfd_object
2985 || abfd->tdata.aout_data == NULL)
2986 return TRUE;
2988 #define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
2989 BFCI_FREE (obj_aout_symbols (abfd));
2990 #ifdef USE_MMAP
2991 obj_aout_external_syms (abfd) = 0;
2992 bfd_free_window (&obj_aout_sym_window (abfd));
2993 bfd_free_window (&obj_aout_string_window (abfd));
2994 obj_aout_external_strings (abfd) = 0;
2995 #else
2996 BFCI_FREE (obj_aout_external_syms (abfd));
2997 BFCI_FREE (obj_aout_external_strings (abfd));
2998 #endif
2999 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3000 BFCI_FREE (o->relocation);
3001 #undef BFCI_FREE
3003 return TRUE;
3006 /* a.out link code. */
3008 static bfd_boolean aout_link_add_object_symbols
3009 PARAMS ((bfd *, struct bfd_link_info *));
3010 static bfd_boolean aout_link_check_archive_element
3011 PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *));
3012 static bfd_boolean aout_link_free_symbols
3013 PARAMS ((bfd *));
3014 static bfd_boolean aout_link_check_ar_symbols
3015 PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *pneeded));
3016 static bfd_boolean aout_link_add_symbols
3017 PARAMS ((bfd *, struct bfd_link_info *));
3019 /* Routine to create an entry in an a.out link hash table. */
3021 struct bfd_hash_entry *
3022 NAME(aout,link_hash_newfunc) (entry, table, string)
3023 struct bfd_hash_entry *entry;
3024 struct bfd_hash_table *table;
3025 const char *string;
3027 struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
3029 /* Allocate the structure if it has not already been allocated by a
3030 subclass. */
3031 if (ret == (struct aout_link_hash_entry *) NULL)
3032 ret = ((struct aout_link_hash_entry *)
3033 bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
3034 if (ret == (struct aout_link_hash_entry *) NULL)
3035 return (struct bfd_hash_entry *) ret;
3037 /* Call the allocation method of the superclass. */
3038 ret = ((struct aout_link_hash_entry *)
3039 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
3040 table, string));
3041 if (ret)
3043 /* Set local fields. */
3044 ret->written = FALSE;
3045 ret->indx = -1;
3048 return (struct bfd_hash_entry *) ret;
3051 /* Initialize an a.out link hash table. */
3053 bfd_boolean
3054 NAME(aout,link_hash_table_init) (table, abfd, newfunc)
3055 struct aout_link_hash_table *table;
3056 bfd *abfd;
3057 struct bfd_hash_entry *(*newfunc)
3058 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
3059 const char *));
3061 return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
3064 /* Create an a.out link hash table. */
3066 struct bfd_link_hash_table *
3067 NAME(aout,link_hash_table_create) (abfd)
3068 bfd *abfd;
3070 struct aout_link_hash_table *ret;
3071 bfd_size_type amt = sizeof (struct aout_link_hash_table);
3073 ret = (struct aout_link_hash_table *) bfd_malloc (amt);
3074 if (ret == NULL)
3075 return (struct bfd_link_hash_table *) NULL;
3077 if (! NAME(aout,link_hash_table_init) (ret, abfd,
3078 NAME(aout,link_hash_newfunc)))
3080 free (ret);
3081 return (struct bfd_link_hash_table *) NULL;
3083 return &ret->root;
3086 /* Given an a.out BFD, add symbols to the global hash table as
3087 appropriate. */
3089 bfd_boolean
3090 NAME(aout,link_add_symbols) (abfd, info)
3091 bfd *abfd;
3092 struct bfd_link_info *info;
3094 switch (bfd_get_format (abfd))
3096 case bfd_object:
3097 return aout_link_add_object_symbols (abfd, info);
3098 case bfd_archive:
3099 return _bfd_generic_link_add_archive_symbols
3100 (abfd, info, aout_link_check_archive_element);
3101 default:
3102 bfd_set_error (bfd_error_wrong_format);
3103 return FALSE;
3107 /* Add symbols from an a.out object file. */
3109 static bfd_boolean
3110 aout_link_add_object_symbols (abfd, info)
3111 bfd *abfd;
3112 struct bfd_link_info *info;
3114 if (! aout_get_external_symbols (abfd))
3115 return FALSE;
3116 if (! aout_link_add_symbols (abfd, info))
3117 return FALSE;
3118 if (! info->keep_memory)
3120 if (! aout_link_free_symbols (abfd))
3121 return FALSE;
3123 return TRUE;
3126 /* Check a single archive element to see if we need to include it in
3127 the link. *PNEEDED is set according to whether this element is
3128 needed in the link or not. This is called from
3129 _bfd_generic_link_add_archive_symbols. */
3131 static bfd_boolean
3132 aout_link_check_archive_element (abfd, info, pneeded)
3133 bfd *abfd;
3134 struct bfd_link_info *info;
3135 bfd_boolean *pneeded;
3137 if (! aout_get_external_symbols (abfd))
3138 return FALSE;
3140 if (! aout_link_check_ar_symbols (abfd, info, pneeded))
3141 return FALSE;
3143 if (*pneeded)
3145 if (! aout_link_add_symbols (abfd, info))
3146 return FALSE;
3149 if (! info->keep_memory || ! *pneeded)
3151 if (! aout_link_free_symbols (abfd))
3152 return FALSE;
3155 return TRUE;
3158 /* Free up the internal symbols read from an a.out file. */
3160 static bfd_boolean
3161 aout_link_free_symbols (abfd)
3162 bfd *abfd;
3164 if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
3166 #ifdef USE_MMAP
3167 bfd_free_window (&obj_aout_sym_window (abfd));
3168 #else
3169 free ((PTR) obj_aout_external_syms (abfd));
3170 #endif
3171 obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
3173 if (obj_aout_external_strings (abfd) != (char *) NULL)
3175 #ifdef USE_MMAP
3176 bfd_free_window (&obj_aout_string_window (abfd));
3177 #else
3178 free ((PTR) obj_aout_external_strings (abfd));
3179 #endif
3180 obj_aout_external_strings (abfd) = (char *) NULL;
3182 return TRUE;
3185 /* Look through the internal symbols to see if this object file should
3186 be included in the link. We should include this object file if it
3187 defines any symbols which are currently undefined. If this object
3188 file defines a common symbol, then we may adjust the size of the
3189 known symbol but we do not include the object file in the link
3190 (unless there is some other reason to include it). */
3192 static bfd_boolean
3193 aout_link_check_ar_symbols (abfd, info, pneeded)
3194 bfd *abfd;
3195 struct bfd_link_info *info;
3196 bfd_boolean *pneeded;
3198 register struct external_nlist *p;
3199 struct external_nlist *pend;
3200 char *strings;
3202 *pneeded = FALSE;
3204 /* Look through all the symbols. */
3205 p = obj_aout_external_syms (abfd);
3206 pend = p + obj_aout_external_sym_count (abfd);
3207 strings = obj_aout_external_strings (abfd);
3208 for (; p < pend; p++)
3210 int type = H_GET_8 (abfd, p->e_type);
3211 const char *name;
3212 struct bfd_link_hash_entry *h;
3214 /* Ignore symbols that are not externally visible. This is an
3215 optimization only, as we check the type more thoroughly
3216 below. */
3217 if (((type & N_EXT) == 0
3218 || (type & N_STAB) != 0
3219 || type == N_FN)
3220 && type != N_WEAKA
3221 && type != N_WEAKT
3222 && type != N_WEAKD
3223 && type != N_WEAKB)
3225 if (type == N_WARNING
3226 || type == N_INDR)
3227 ++p;
3228 continue;
3231 name = strings + GET_WORD (abfd, p->e_strx);
3232 h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
3234 /* We are only interested in symbols that are currently
3235 undefined or common. */
3236 if (h == (struct bfd_link_hash_entry *) NULL
3237 || (h->type != bfd_link_hash_undefined
3238 && h->type != bfd_link_hash_common))
3240 if (type == (N_INDR | N_EXT))
3241 ++p;
3242 continue;
3245 if (type == (N_TEXT | N_EXT)
3246 || type == (N_DATA | N_EXT)
3247 || type == (N_BSS | N_EXT)
3248 || type == (N_ABS | N_EXT)
3249 || type == (N_INDR | N_EXT))
3251 /* This object file defines this symbol. We must link it
3252 in. This is true regardless of whether the current
3253 definition of the symbol is undefined or common.
3255 If the current definition is common, we have a case in
3256 which we have already seen an object file including:
3257 int a;
3258 and this object file from the archive includes:
3259 int a = 5;
3260 In such a case, whether to include this object is target
3261 dependant for backward compatibility.
3263 FIXME: The SunOS 4.1.3 linker will pull in the archive
3264 element if the symbol is defined in the .data section,
3265 but not if it is defined in the .text section. That
3266 seems a bit crazy to me, and it has not been implemented
3267 yet. However, it might be correct. */
3268 if (h->type == bfd_link_hash_common)
3270 int skip = 0;
3272 switch (info->common_skip_ar_aymbols)
3274 case bfd_link_common_skip_text:
3275 skip = (type == (N_TEXT | N_EXT));
3276 break;
3277 case bfd_link_common_skip_data:
3278 skip = (type == (N_DATA | N_EXT));
3279 break;
3280 default:
3281 case bfd_link_common_skip_all:
3282 skip = 1;
3283 break;
3286 if (skip)
3287 continue;
3290 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3291 return FALSE;
3292 *pneeded = TRUE;
3293 return TRUE;
3296 if (type == (N_UNDF | N_EXT))
3298 bfd_vma value;
3300 value = GET_WORD (abfd, p->e_value);
3301 if (value != 0)
3303 /* This symbol is common in the object from the archive
3304 file. */
3305 if (h->type == bfd_link_hash_undefined)
3307 bfd *symbfd;
3308 unsigned int power;
3310 symbfd = h->u.undef.abfd;
3311 if (symbfd == (bfd *) NULL)
3313 /* This symbol was created as undefined from
3314 outside BFD. We assume that we should link
3315 in the object file. This is done for the -u
3316 option in the linker. */
3317 if (! (*info->callbacks->add_archive_element) (info,
3318 abfd,
3319 name))
3320 return FALSE;
3321 *pneeded = TRUE;
3322 return TRUE;
3324 /* Turn the current link symbol into a common
3325 symbol. It is already on the undefs list. */
3326 h->type = bfd_link_hash_common;
3327 h->u.c.p = ((struct bfd_link_hash_common_entry *)
3328 bfd_hash_allocate (&info->hash->table,
3329 sizeof (struct bfd_link_hash_common_entry)));
3330 if (h->u.c.p == NULL)
3331 return FALSE;
3333 h->u.c.size = value;
3335 /* FIXME: This isn't quite right. The maximum
3336 alignment of a common symbol should be set by the
3337 architecture of the output file, not of the input
3338 file. */
3339 power = bfd_log2 (value);
3340 if (power > bfd_get_arch_info (abfd)->section_align_power)
3341 power = bfd_get_arch_info (abfd)->section_align_power;
3342 h->u.c.p->alignment_power = power;
3344 h->u.c.p->section = bfd_make_section_old_way (symbfd,
3345 "COMMON");
3347 else
3349 /* Adjust the size of the common symbol if
3350 necessary. */
3351 if (value > h->u.c.size)
3352 h->u.c.size = value;
3357 if (type == N_WEAKA
3358 || type == N_WEAKT
3359 || type == N_WEAKD
3360 || type == N_WEAKB)
3362 /* This symbol is weak but defined. We must pull it in if
3363 the current link symbol is undefined, but we don't want
3364 it if the current link symbol is common. */
3365 if (h->type == bfd_link_hash_undefined)
3367 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3368 return FALSE;
3369 *pneeded = TRUE;
3370 return TRUE;
3375 /* We do not need this object file. */
3376 return TRUE;
3379 /* Add all symbols from an object file to the hash table. */
3381 static bfd_boolean
3382 aout_link_add_symbols (abfd, info)
3383 bfd *abfd;
3384 struct bfd_link_info *info;
3386 bfd_boolean (*add_one_symbol)
3387 PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
3388 bfd_vma, const char *, bfd_boolean, bfd_boolean,
3389 struct bfd_link_hash_entry **));
3390 struct external_nlist *syms;
3391 bfd_size_type sym_count;
3392 char *strings;
3393 bfd_boolean copy;
3394 struct aout_link_hash_entry **sym_hash;
3395 register struct external_nlist *p;
3396 struct external_nlist *pend;
3397 bfd_size_type amt;
3399 syms = obj_aout_external_syms (abfd);
3400 sym_count = obj_aout_external_sym_count (abfd);
3401 strings = obj_aout_external_strings (abfd);
3402 if (info->keep_memory)
3403 copy = FALSE;
3404 else
3405 copy = TRUE;
3407 if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
3409 if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
3410 (abfd, info, &syms, &sym_count, &strings)))
3411 return FALSE;
3414 /* We keep a list of the linker hash table entries that correspond
3415 to particular symbols. We could just look them up in the hash
3416 table, but keeping the list is more efficient. Perhaps this
3417 should be conditional on info->keep_memory. */
3418 amt = sym_count * sizeof (struct aout_link_hash_entry *);
3419 sym_hash = (struct aout_link_hash_entry **) bfd_alloc (abfd, amt);
3420 if (sym_hash == NULL && sym_count != 0)
3421 return FALSE;
3422 obj_aout_sym_hashes (abfd) = sym_hash;
3424 add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
3425 if (add_one_symbol == NULL)
3426 add_one_symbol = _bfd_generic_link_add_one_symbol;
3428 p = syms;
3429 pend = p + sym_count;
3430 for (; p < pend; p++, sym_hash++)
3432 int type;
3433 const char *name;
3434 bfd_vma value;
3435 asection *section;
3436 flagword flags;
3437 const char *string;
3439 *sym_hash = NULL;
3441 type = H_GET_8 (abfd, p->e_type);
3443 /* Ignore debugging symbols. */
3444 if ((type & N_STAB) != 0)
3445 continue;
3447 name = strings + GET_WORD (abfd, p->e_strx);
3448 value = GET_WORD (abfd, p->e_value);
3449 flags = BSF_GLOBAL;
3450 string = NULL;
3451 switch (type)
3453 default:
3454 abort ();
3456 case N_UNDF:
3457 case N_ABS:
3458 case N_TEXT:
3459 case N_DATA:
3460 case N_BSS:
3461 case N_FN_SEQ:
3462 case N_COMM:
3463 case N_SETV:
3464 case N_FN:
3465 /* Ignore symbols that are not externally visible. */
3466 continue;
3467 case N_INDR:
3468 /* Ignore local indirect symbol. */
3469 ++p;
3470 ++sym_hash;
3471 continue;
3473 case N_UNDF | N_EXT:
3474 if (value == 0)
3476 section = bfd_und_section_ptr;
3477 flags = 0;
3479 else
3480 section = bfd_com_section_ptr;
3481 break;
3482 case N_ABS | N_EXT:
3483 section = bfd_abs_section_ptr;
3484 break;
3485 case N_TEXT | N_EXT:
3486 section = obj_textsec (abfd);
3487 value -= bfd_get_section_vma (abfd, section);
3488 break;
3489 case N_DATA | N_EXT:
3490 case N_SETV | N_EXT:
3491 /* Treat N_SETV symbols as N_DATA symbol; see comment in
3492 translate_from_native_sym_flags. */
3493 section = obj_datasec (abfd);
3494 value -= bfd_get_section_vma (abfd, section);
3495 break;
3496 case N_BSS | N_EXT:
3497 section = obj_bsssec (abfd);
3498 value -= bfd_get_section_vma (abfd, section);
3499 break;
3500 case N_INDR | N_EXT:
3501 /* An indirect symbol. The next symbol is the symbol
3502 which this one really is. */
3503 BFD_ASSERT (p + 1 < pend);
3504 ++p;
3505 string = strings + GET_WORD (abfd, p->e_strx);
3506 section = bfd_ind_section_ptr;
3507 flags |= BSF_INDIRECT;
3508 break;
3509 case N_COMM | N_EXT:
3510 section = bfd_com_section_ptr;
3511 break;
3512 case N_SETA: case N_SETA | N_EXT:
3513 section = bfd_abs_section_ptr;
3514 flags |= BSF_CONSTRUCTOR;
3515 break;
3516 case N_SETT: case N_SETT | N_EXT:
3517 section = obj_textsec (abfd);
3518 flags |= BSF_CONSTRUCTOR;
3519 value -= bfd_get_section_vma (abfd, section);
3520 break;
3521 case N_SETD: case N_SETD | N_EXT:
3522 section = obj_datasec (abfd);
3523 flags |= BSF_CONSTRUCTOR;
3524 value -= bfd_get_section_vma (abfd, section);
3525 break;
3526 case N_SETB: case N_SETB | N_EXT:
3527 section = obj_bsssec (abfd);
3528 flags |= BSF_CONSTRUCTOR;
3529 value -= bfd_get_section_vma (abfd, section);
3530 break;
3531 case N_WARNING:
3532 /* A warning symbol. The next symbol is the one to warn
3533 about. */
3534 BFD_ASSERT (p + 1 < pend);
3535 ++p;
3536 string = name;
3537 name = strings + GET_WORD (abfd, p->e_strx);
3538 section = bfd_und_section_ptr;
3539 flags |= BSF_WARNING;
3540 break;
3541 case N_WEAKU:
3542 section = bfd_und_section_ptr;
3543 flags = BSF_WEAK;
3544 break;
3545 case N_WEAKA:
3546 section = bfd_abs_section_ptr;
3547 flags = BSF_WEAK;
3548 break;
3549 case N_WEAKT:
3550 section = obj_textsec (abfd);
3551 value -= bfd_get_section_vma (abfd, section);
3552 flags = BSF_WEAK;
3553 break;
3554 case N_WEAKD:
3555 section = obj_datasec (abfd);
3556 value -= bfd_get_section_vma (abfd, section);
3557 flags = BSF_WEAK;
3558 break;
3559 case N_WEAKB:
3560 section = obj_bsssec (abfd);
3561 value -= bfd_get_section_vma (abfd, section);
3562 flags = BSF_WEAK;
3563 break;
3566 if (! ((*add_one_symbol)
3567 (info, abfd, name, flags, section, value, string, copy, FALSE,
3568 (struct bfd_link_hash_entry **) sym_hash)))
3569 return FALSE;
3571 /* Restrict the maximum alignment of a common symbol based on
3572 the architecture, since a.out has no way to represent
3573 alignment requirements of a section in a .o file. FIXME:
3574 This isn't quite right: it should use the architecture of the
3575 output file, not the input files. */
3576 if ((*sym_hash)->root.type == bfd_link_hash_common
3577 && ((*sym_hash)->root.u.c.p->alignment_power >
3578 bfd_get_arch_info (abfd)->section_align_power))
3579 (*sym_hash)->root.u.c.p->alignment_power =
3580 bfd_get_arch_info (abfd)->section_align_power;
3582 /* If this is a set symbol, and we are not building sets, then
3583 it is possible for the hash entry to not have been set. In
3584 such a case, treat the symbol as not globally defined. */
3585 if ((*sym_hash)->root.type == bfd_link_hash_new)
3587 BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
3588 *sym_hash = NULL;
3591 if (type == (N_INDR | N_EXT) || type == N_WARNING)
3592 ++sym_hash;
3595 return TRUE;
3598 /* A hash table used for header files with N_BINCL entries. */
3600 struct aout_link_includes_table
3602 struct bfd_hash_table root;
3605 /* A linked list of totals that we have found for a particular header
3606 file. */
3608 struct aout_link_includes_totals
3610 struct aout_link_includes_totals *next;
3611 bfd_vma total;
3614 /* An entry in the header file hash table. */
3616 struct aout_link_includes_entry
3618 struct bfd_hash_entry root;
3619 /* List of totals we have found for this file. */
3620 struct aout_link_includes_totals *totals;
3623 /* Look up an entry in an the header file hash table. */
3625 #define aout_link_includes_lookup(table, string, create, copy) \
3626 ((struct aout_link_includes_entry *) \
3627 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
3629 /* During the final link step we need to pass around a bunch of
3630 information, so we do it in an instance of this structure. */
3632 struct aout_final_link_info
3634 /* General link information. */
3635 struct bfd_link_info *info;
3636 /* Output bfd. */
3637 bfd *output_bfd;
3638 /* Reloc file positions. */
3639 file_ptr treloff, dreloff;
3640 /* File position of symbols. */
3641 file_ptr symoff;
3642 /* String table. */
3643 struct bfd_strtab_hash *strtab;
3644 /* Header file hash table. */
3645 struct aout_link_includes_table includes;
3646 /* A buffer large enough to hold the contents of any section. */
3647 bfd_byte *contents;
3648 /* A buffer large enough to hold the relocs of any section. */
3649 PTR relocs;
3650 /* A buffer large enough to hold the symbol map of any input BFD. */
3651 int *symbol_map;
3652 /* A buffer large enough to hold output symbols of any input BFD. */
3653 struct external_nlist *output_syms;
3656 static struct bfd_hash_entry *aout_link_includes_newfunc
3657 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
3658 static bfd_boolean aout_link_input_bfd
3659 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3660 static bfd_boolean aout_link_write_symbols
3661 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3662 static bfd_boolean aout_link_write_other_symbol
3663 PARAMS ((struct aout_link_hash_entry *, PTR));
3664 static bfd_boolean aout_link_input_section
3665 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3666 asection *input_section, file_ptr *reloff_ptr,
3667 bfd_size_type rel_size));
3668 static bfd_boolean aout_link_input_section_std
3669 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3670 asection *input_section, struct reloc_std_external *,
3671 bfd_size_type rel_size, bfd_byte *contents));
3672 static bfd_boolean aout_link_input_section_ext
3673 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3674 asection *input_section, struct reloc_ext_external *,
3675 bfd_size_type rel_size, bfd_byte *contents));
3676 static INLINE asection *aout_reloc_index_to_section
3677 PARAMS ((bfd *, int));
3678 static bfd_boolean aout_link_reloc_link_order
3679 PARAMS ((struct aout_final_link_info *, asection *,
3680 struct bfd_link_order *));
3682 /* The function to create a new entry in the header file hash table. */
3684 static struct bfd_hash_entry *
3685 aout_link_includes_newfunc (entry, table, string)
3686 struct bfd_hash_entry *entry;
3687 struct bfd_hash_table *table;
3688 const char *string;
3690 struct aout_link_includes_entry *ret =
3691 (struct aout_link_includes_entry *) entry;
3693 /* Allocate the structure if it has not already been allocated by a
3694 subclass. */
3695 if (ret == (struct aout_link_includes_entry *) NULL)
3696 ret = ((struct aout_link_includes_entry *)
3697 bfd_hash_allocate (table,
3698 sizeof (struct aout_link_includes_entry)));
3699 if (ret == (struct aout_link_includes_entry *) NULL)
3700 return (struct bfd_hash_entry *) ret;
3702 /* Call the allocation method of the superclass. */
3703 ret = ((struct aout_link_includes_entry *)
3704 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
3705 if (ret)
3707 /* Set local fields. */
3708 ret->totals = NULL;
3711 return (struct bfd_hash_entry *) ret;
3714 /* Do the final link step. This is called on the output BFD. The
3715 INFO structure should point to a list of BFDs linked through the
3716 link_next field which can be used to find each BFD which takes part
3717 in the output. Also, each section in ABFD should point to a list
3718 of bfd_link_order structures which list all the input sections for
3719 the output section. */
3721 bfd_boolean
3722 NAME(aout,final_link) (abfd, info, callback)
3723 bfd *abfd;
3724 struct bfd_link_info *info;
3725 void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
3727 struct aout_final_link_info aout_info;
3728 bfd_boolean includes_hash_initialized = FALSE;
3729 register bfd *sub;
3730 bfd_size_type trsize, drsize;
3731 bfd_size_type max_contents_size;
3732 bfd_size_type max_relocs_size;
3733 bfd_size_type max_sym_count;
3734 bfd_size_type text_size;
3735 file_ptr text_end;
3736 register struct bfd_link_order *p;
3737 asection *o;
3738 bfd_boolean have_link_order_relocs;
3740 if (info->shared)
3741 abfd->flags |= DYNAMIC;
3743 aout_info.info = info;
3744 aout_info.output_bfd = abfd;
3745 aout_info.contents = NULL;
3746 aout_info.relocs = NULL;
3747 aout_info.symbol_map = NULL;
3748 aout_info.output_syms = NULL;
3750 if (! bfd_hash_table_init_n (&aout_info.includes.root,
3751 aout_link_includes_newfunc,
3752 251))
3753 goto error_return;
3754 includes_hash_initialized = TRUE;
3756 /* Figure out the largest section size. Also, if generating
3757 relocatable output, count the relocs. */
3758 trsize = 0;
3759 drsize = 0;
3760 max_contents_size = 0;
3761 max_relocs_size = 0;
3762 max_sym_count = 0;
3763 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
3765 bfd_size_type sz;
3767 if (info->relocatable)
3769 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3771 trsize += exec_hdr (sub)->a_trsize;
3772 drsize += exec_hdr (sub)->a_drsize;
3774 else
3776 /* FIXME: We need to identify the .text and .data sections
3777 and call get_reloc_upper_bound and canonicalize_reloc to
3778 work out the number of relocs needed, and then multiply
3779 by the reloc size. */
3780 (*_bfd_error_handler)
3781 (_("%s: relocatable link from %s to %s not supported"),
3782 bfd_get_filename (abfd),
3783 sub->xvec->name, abfd->xvec->name);
3784 bfd_set_error (bfd_error_invalid_operation);
3785 goto error_return;
3789 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3791 sz = obj_textsec (sub)->size;
3792 if (sz > max_contents_size)
3793 max_contents_size = sz;
3794 sz = obj_datasec (sub)->size;
3795 if (sz > max_contents_size)
3796 max_contents_size = sz;
3798 sz = exec_hdr (sub)->a_trsize;
3799 if (sz > max_relocs_size)
3800 max_relocs_size = sz;
3801 sz = exec_hdr (sub)->a_drsize;
3802 if (sz > max_relocs_size)
3803 max_relocs_size = sz;
3805 sz = obj_aout_external_sym_count (sub);
3806 if (sz > max_sym_count)
3807 max_sym_count = sz;
3811 if (info->relocatable)
3813 if (obj_textsec (abfd) != (asection *) NULL)
3814 trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
3815 ->link_order_head)
3816 * obj_reloc_entry_size (abfd));
3817 if (obj_datasec (abfd) != (asection *) NULL)
3818 drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
3819 ->link_order_head)
3820 * obj_reloc_entry_size (abfd));
3823 exec_hdr (abfd)->a_trsize = trsize;
3824 exec_hdr (abfd)->a_drsize = drsize;
3826 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
3828 /* Adjust the section sizes and vmas according to the magic number.
3829 This sets a_text, a_data and a_bss in the exec_hdr and sets the
3830 filepos for each section. */
3831 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3832 goto error_return;
3834 /* The relocation and symbol file positions differ among a.out
3835 targets. We are passed a callback routine from the backend
3836 specific code to handle this.
3837 FIXME: At this point we do not know how much space the symbol
3838 table will require. This will not work for any (nonstandard)
3839 a.out target that needs to know the symbol table size before it
3840 can compute the relocation file positions. This may or may not
3841 be the case for the hp300hpux target, for example. */
3842 (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3843 &aout_info.symoff);
3844 obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3845 obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3846 obj_sym_filepos (abfd) = aout_info.symoff;
3848 /* We keep a count of the symbols as we output them. */
3849 obj_aout_external_sym_count (abfd) = 0;
3851 /* We accumulate the string table as we write out the symbols. */
3852 aout_info.strtab = _bfd_stringtab_init ();
3853 if (aout_info.strtab == NULL)
3854 goto error_return;
3856 /* Allocate buffers to hold section contents and relocs. */
3857 aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
3858 aout_info.relocs = (PTR) bfd_malloc (max_relocs_size);
3859 aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int *));
3860 aout_info.output_syms = ((struct external_nlist *)
3861 bfd_malloc ((max_sym_count + 1)
3862 * sizeof (struct external_nlist)));
3863 if ((aout_info.contents == NULL && max_contents_size != 0)
3864 || (aout_info.relocs == NULL && max_relocs_size != 0)
3865 || (aout_info.symbol_map == NULL && max_sym_count != 0)
3866 || aout_info.output_syms == NULL)
3867 goto error_return;
3869 /* If we have a symbol named __DYNAMIC, force it out now. This is
3870 required by SunOS. Doing this here rather than in sunos.c is a
3871 hack, but it's easier than exporting everything which would be
3872 needed. */
3874 struct aout_link_hash_entry *h;
3876 h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
3877 FALSE, FALSE, FALSE);
3878 if (h != NULL)
3879 aout_link_write_other_symbol (h, &aout_info);
3882 /* The most time efficient way to do the link would be to read all
3883 the input object files into memory and then sort out the
3884 information into the output file. Unfortunately, that will
3885 probably use too much memory. Another method would be to step
3886 through everything that composes the text section and write it
3887 out, and then everything that composes the data section and write
3888 it out, and then write out the relocs, and then write out the
3889 symbols. Unfortunately, that requires reading stuff from each
3890 input file several times, and we will not be able to keep all the
3891 input files open simultaneously, and reopening them will be slow.
3893 What we do is basically process one input file at a time. We do
3894 everything we need to do with an input file once--copy over the
3895 section contents, handle the relocation information, and write
3896 out the symbols--and then we throw away the information we read
3897 from it. This approach requires a lot of lseeks of the output
3898 file, which is unfortunate but still faster than reopening a lot
3899 of files.
3901 We use the output_has_begun field of the input BFDs to see
3902 whether we have already handled it. */
3903 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3904 sub->output_has_begun = FALSE;
3906 /* Mark all sections which are to be included in the link. This
3907 will normally be every section. We need to do this so that we
3908 can identify any sections which the linker has decided to not
3909 include. */
3910 for (o = abfd->sections; o != NULL; o = o->next)
3912 for (p = o->link_order_head; p != NULL; p = p->next)
3913 if (p->type == bfd_indirect_link_order)
3914 p->u.indirect.section->linker_mark = TRUE;
3917 have_link_order_relocs = FALSE;
3918 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3920 for (p = o->link_order_head;
3921 p != (struct bfd_link_order *) NULL;
3922 p = p->next)
3924 if (p->type == bfd_indirect_link_order
3925 && (bfd_get_flavour (p->u.indirect.section->owner)
3926 == bfd_target_aout_flavour))
3928 bfd *input_bfd;
3930 input_bfd = p->u.indirect.section->owner;
3931 if (! input_bfd->output_has_begun)
3933 if (! aout_link_input_bfd (&aout_info, input_bfd))
3934 goto error_return;
3935 input_bfd->output_has_begun = TRUE;
3938 else if (p->type == bfd_section_reloc_link_order
3939 || p->type == bfd_symbol_reloc_link_order)
3941 /* These are handled below. */
3942 have_link_order_relocs = TRUE;
3944 else
3946 if (! _bfd_default_link_order (abfd, info, o, p))
3947 goto error_return;
3952 /* Write out any symbols that we have not already written out. */
3953 aout_link_hash_traverse (aout_hash_table (info),
3954 aout_link_write_other_symbol,
3955 (PTR) &aout_info);
3957 /* Now handle any relocs we were asked to create by the linker.
3958 These did not come from any input file. We must do these after
3959 we have written out all the symbols, so that we know the symbol
3960 indices to use. */
3961 if (have_link_order_relocs)
3963 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3965 for (p = o->link_order_head;
3966 p != (struct bfd_link_order *) NULL;
3967 p = p->next)
3969 if (p->type == bfd_section_reloc_link_order
3970 || p->type == bfd_symbol_reloc_link_order)
3972 if (! aout_link_reloc_link_order (&aout_info, o, p))
3973 goto error_return;
3979 if (aout_info.contents != NULL)
3981 free (aout_info.contents);
3982 aout_info.contents = NULL;
3984 if (aout_info.relocs != NULL)
3986 free (aout_info.relocs);
3987 aout_info.relocs = NULL;
3989 if (aout_info.symbol_map != NULL)
3991 free (aout_info.symbol_map);
3992 aout_info.symbol_map = NULL;
3994 if (aout_info.output_syms != NULL)
3996 free (aout_info.output_syms);
3997 aout_info.output_syms = NULL;
3999 if (includes_hash_initialized)
4001 bfd_hash_table_free (&aout_info.includes.root);
4002 includes_hash_initialized = FALSE;
4005 /* Finish up any dynamic linking we may be doing. */
4006 if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
4008 if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
4009 goto error_return;
4012 /* Update the header information. */
4013 abfd->symcount = obj_aout_external_sym_count (abfd);
4014 exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
4015 obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
4016 obj_textsec (abfd)->reloc_count =
4017 exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
4018 obj_datasec (abfd)->reloc_count =
4019 exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
4021 /* Write out the string table, unless there are no symbols. */
4022 if (abfd->symcount > 0)
4024 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
4025 || ! emit_stringtab (abfd, aout_info.strtab))
4026 goto error_return;
4028 else if (obj_textsec (abfd)->reloc_count == 0
4029 && obj_datasec (abfd)->reloc_count == 0)
4031 bfd_byte b;
4032 file_ptr pos;
4034 b = 0;
4035 pos = obj_datasec (abfd)->filepos + exec_hdr (abfd)->a_data - 1;
4036 if (bfd_seek (abfd, pos, SEEK_SET) != 0
4037 || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
4038 goto error_return;
4041 return TRUE;
4043 error_return:
4044 if (aout_info.contents != NULL)
4045 free (aout_info.contents);
4046 if (aout_info.relocs != NULL)
4047 free (aout_info.relocs);
4048 if (aout_info.symbol_map != NULL)
4049 free (aout_info.symbol_map);
4050 if (aout_info.output_syms != NULL)
4051 free (aout_info.output_syms);
4052 if (includes_hash_initialized)
4053 bfd_hash_table_free (&aout_info.includes.root);
4054 return FALSE;
4057 /* Link an a.out input BFD into the output file. */
4059 static bfd_boolean
4060 aout_link_input_bfd (finfo, input_bfd)
4061 struct aout_final_link_info *finfo;
4062 bfd *input_bfd;
4064 bfd_size_type sym_count;
4066 BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
4068 /* If this is a dynamic object, it may need special handling. */
4069 if ((input_bfd->flags & DYNAMIC) != 0
4070 && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
4072 return ((*aout_backend_info (input_bfd)->link_dynamic_object)
4073 (finfo->info, input_bfd));
4076 /* Get the symbols. We probably have them already, unless
4077 finfo->info->keep_memory is FALSE. */
4078 if (! aout_get_external_symbols (input_bfd))
4079 return FALSE;
4081 sym_count = obj_aout_external_sym_count (input_bfd);
4083 /* Write out the symbols and get a map of the new indices. The map
4084 is placed into finfo->symbol_map. */
4085 if (! aout_link_write_symbols (finfo, input_bfd))
4086 return FALSE;
4088 /* Relocate and write out the sections. These functions use the
4089 symbol map created by aout_link_write_symbols. The linker_mark
4090 field will be set if these sections are to be included in the
4091 link, which will normally be the case. */
4092 if (obj_textsec (input_bfd)->linker_mark)
4094 if (! aout_link_input_section (finfo, input_bfd,
4095 obj_textsec (input_bfd),
4096 &finfo->treloff,
4097 exec_hdr (input_bfd)->a_trsize))
4098 return FALSE;
4100 if (obj_datasec (input_bfd)->linker_mark)
4102 if (! aout_link_input_section (finfo, input_bfd,
4103 obj_datasec (input_bfd),
4104 &finfo->dreloff,
4105 exec_hdr (input_bfd)->a_drsize))
4106 return FALSE;
4109 /* If we are not keeping memory, we don't need the symbols any
4110 longer. We still need them if we are keeping memory, because the
4111 strings in the hash table point into them. */
4112 if (! finfo->info->keep_memory)
4114 if (! aout_link_free_symbols (input_bfd))
4115 return FALSE;
4118 return TRUE;
4121 /* Adjust and write out the symbols for an a.out file. Set the new
4122 symbol indices into a symbol_map. */
4124 static bfd_boolean
4125 aout_link_write_symbols (finfo, input_bfd)
4126 struct aout_final_link_info *finfo;
4127 bfd *input_bfd;
4129 bfd *output_bfd;
4130 bfd_size_type sym_count;
4131 char *strings;
4132 enum bfd_link_strip strip;
4133 enum bfd_link_discard discard;
4134 struct external_nlist *outsym;
4135 bfd_size_type strtab_index;
4136 register struct external_nlist *sym;
4137 struct external_nlist *sym_end;
4138 struct aout_link_hash_entry **sym_hash;
4139 int *symbol_map;
4140 bfd_boolean pass;
4141 bfd_boolean skip_next;
4143 output_bfd = finfo->output_bfd;
4144 sym_count = obj_aout_external_sym_count (input_bfd);
4145 strings = obj_aout_external_strings (input_bfd);
4146 strip = finfo->info->strip;
4147 discard = finfo->info->discard;
4148 outsym = finfo->output_syms;
4150 /* First write out a symbol for this object file, unless we are
4151 discarding such symbols. */
4152 if (strip != strip_all
4153 && (strip != strip_some
4154 || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
4155 FALSE, FALSE) != NULL)
4156 && discard != discard_all)
4158 H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
4159 H_PUT_8 (output_bfd, 0, outsym->e_other);
4160 H_PUT_16 (output_bfd, 0, outsym->e_desc);
4161 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4162 input_bfd->filename, FALSE);
4163 if (strtab_index == (bfd_size_type) -1)
4164 return FALSE;
4165 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4166 PUT_WORD (output_bfd,
4167 (bfd_get_section_vma (output_bfd,
4168 obj_textsec (input_bfd)->output_section)
4169 + obj_textsec (input_bfd)->output_offset),
4170 outsym->e_value);
4171 ++obj_aout_external_sym_count (output_bfd);
4172 ++outsym;
4175 pass = FALSE;
4176 skip_next = FALSE;
4177 sym = obj_aout_external_syms (input_bfd);
4178 sym_end = sym + sym_count;
4179 sym_hash = obj_aout_sym_hashes (input_bfd);
4180 symbol_map = finfo->symbol_map;
4181 memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
4182 for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
4184 const char *name;
4185 int type;
4186 struct aout_link_hash_entry *h;
4187 bfd_boolean skip;
4188 asection *symsec;
4189 bfd_vma val = 0;
4190 bfd_boolean copy;
4192 /* We set *symbol_map to 0 above for all symbols. If it has
4193 already been set to -1 for this symbol, it means that we are
4194 discarding it because it appears in a duplicate header file.
4195 See the N_BINCL code below. */
4196 if (*symbol_map == -1)
4197 continue;
4199 /* Initialize *symbol_map to -1, which means that the symbol was
4200 not copied into the output file. We will change it later if
4201 we do copy the symbol over. */
4202 *symbol_map = -1;
4204 type = H_GET_8 (input_bfd, sym->e_type);
4205 name = strings + GET_WORD (input_bfd, sym->e_strx);
4207 h = NULL;
4209 if (pass)
4211 /* Pass this symbol through. It is the target of an
4212 indirect or warning symbol. */
4213 val = GET_WORD (input_bfd, sym->e_value);
4214 pass = FALSE;
4216 else if (skip_next)
4218 /* Skip this symbol, which is the target of an indirect
4219 symbol that we have changed to no longer be an indirect
4220 symbol. */
4221 skip_next = FALSE;
4222 continue;
4224 else
4226 struct aout_link_hash_entry *hresolve;
4228 /* We have saved the hash table entry for this symbol, if
4229 there is one. Note that we could just look it up again
4230 in the hash table, provided we first check that it is an
4231 external symbol. */
4232 h = *sym_hash;
4234 /* Use the name from the hash table, in case the symbol was
4235 wrapped. */
4236 if (h != NULL
4237 && h->root.type != bfd_link_hash_warning)
4238 name = h->root.root.string;
4240 /* If this is an indirect or warning symbol, then change
4241 hresolve to the base symbol. We also change *sym_hash so
4242 that the relocation routines relocate against the real
4243 symbol. */
4244 hresolve = h;
4245 if (h != (struct aout_link_hash_entry *) NULL
4246 && (h->root.type == bfd_link_hash_indirect
4247 || h->root.type == bfd_link_hash_warning))
4249 hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
4250 while (hresolve->root.type == bfd_link_hash_indirect
4251 || hresolve->root.type == bfd_link_hash_warning)
4252 hresolve = ((struct aout_link_hash_entry *)
4253 hresolve->root.u.i.link);
4254 *sym_hash = hresolve;
4257 /* If the symbol has already been written out, skip it. */
4258 if (h != (struct aout_link_hash_entry *) NULL
4259 && h->written)
4261 if ((type & N_TYPE) == N_INDR
4262 || type == N_WARNING)
4263 skip_next = TRUE;
4264 *symbol_map = h->indx;
4265 continue;
4268 /* See if we are stripping this symbol. */
4269 skip = FALSE;
4270 switch (strip)
4272 case strip_none:
4273 break;
4274 case strip_debugger:
4275 if ((type & N_STAB) != 0)
4276 skip = TRUE;
4277 break;
4278 case strip_some:
4279 if (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE)
4280 == NULL)
4281 skip = TRUE;
4282 break;
4283 case strip_all:
4284 skip = TRUE;
4285 break;
4287 if (skip)
4289 if (h != (struct aout_link_hash_entry *) NULL)
4290 h->written = TRUE;
4291 continue;
4294 /* Get the value of the symbol. */
4295 if ((type & N_TYPE) == N_TEXT
4296 || type == N_WEAKT)
4297 symsec = obj_textsec (input_bfd);
4298 else if ((type & N_TYPE) == N_DATA
4299 || type == N_WEAKD)
4300 symsec = obj_datasec (input_bfd);
4301 else if ((type & N_TYPE) == N_BSS
4302 || type == N_WEAKB)
4303 symsec = obj_bsssec (input_bfd);
4304 else if ((type & N_TYPE) == N_ABS
4305 || type == N_WEAKA)
4306 symsec = bfd_abs_section_ptr;
4307 else if (((type & N_TYPE) == N_INDR
4308 && (hresolve == (struct aout_link_hash_entry *) NULL
4309 || (hresolve->root.type != bfd_link_hash_defined
4310 && hresolve->root.type != bfd_link_hash_defweak
4311 && hresolve->root.type != bfd_link_hash_common)))
4312 || type == N_WARNING)
4314 /* Pass the next symbol through unchanged. The
4315 condition above for indirect symbols is so that if
4316 the indirect symbol was defined, we output it with
4317 the correct definition so the debugger will
4318 understand it. */
4319 pass = TRUE;
4320 val = GET_WORD (input_bfd, sym->e_value);
4321 symsec = NULL;
4323 else if ((type & N_STAB) != 0)
4325 val = GET_WORD (input_bfd, sym->e_value);
4326 symsec = NULL;
4328 else
4330 /* If we get here with an indirect symbol, it means that
4331 we are outputting it with a real definition. In such
4332 a case we do not want to output the next symbol,
4333 which is the target of the indirection. */
4334 if ((type & N_TYPE) == N_INDR)
4335 skip_next = TRUE;
4337 symsec = NULL;
4339 /* We need to get the value from the hash table. We use
4340 hresolve so that if we have defined an indirect
4341 symbol we output the final definition. */
4342 if (h == (struct aout_link_hash_entry *) NULL)
4344 switch (type & N_TYPE)
4346 case N_SETT:
4347 symsec = obj_textsec (input_bfd);
4348 break;
4349 case N_SETD:
4350 symsec = obj_datasec (input_bfd);
4351 break;
4352 case N_SETB:
4353 symsec = obj_bsssec (input_bfd);
4354 break;
4355 case N_SETA:
4356 symsec = bfd_abs_section_ptr;
4357 break;
4358 default:
4359 val = 0;
4360 break;
4363 else if (hresolve->root.type == bfd_link_hash_defined
4364 || hresolve->root.type == bfd_link_hash_defweak)
4366 asection *input_section;
4367 asection *output_section;
4369 /* This case usually means a common symbol which was
4370 turned into a defined symbol. */
4371 input_section = hresolve->root.u.def.section;
4372 output_section = input_section->output_section;
4373 BFD_ASSERT (bfd_is_abs_section (output_section)
4374 || output_section->owner == output_bfd);
4375 val = (hresolve->root.u.def.value
4376 + bfd_get_section_vma (output_bfd, output_section)
4377 + input_section->output_offset);
4379 /* Get the correct type based on the section. If
4380 this is a constructed set, force it to be
4381 globally visible. */
4382 if (type == N_SETT
4383 || type == N_SETD
4384 || type == N_SETB
4385 || type == N_SETA)
4386 type |= N_EXT;
4388 type &=~ N_TYPE;
4390 if (output_section == obj_textsec (output_bfd))
4391 type |= (hresolve->root.type == bfd_link_hash_defined
4392 ? N_TEXT
4393 : N_WEAKT);
4394 else if (output_section == obj_datasec (output_bfd))
4395 type |= (hresolve->root.type == bfd_link_hash_defined
4396 ? N_DATA
4397 : N_WEAKD);
4398 else if (output_section == obj_bsssec (output_bfd))
4399 type |= (hresolve->root.type == bfd_link_hash_defined
4400 ? N_BSS
4401 : N_WEAKB);
4402 else
4403 type |= (hresolve->root.type == bfd_link_hash_defined
4404 ? N_ABS
4405 : N_WEAKA);
4407 else if (hresolve->root.type == bfd_link_hash_common)
4408 val = hresolve->root.u.c.size;
4409 else if (hresolve->root.type == bfd_link_hash_undefweak)
4411 val = 0;
4412 type = N_WEAKU;
4414 else
4415 val = 0;
4417 if (symsec != (asection *) NULL)
4418 val = (symsec->output_section->vma
4419 + symsec->output_offset
4420 + (GET_WORD (input_bfd, sym->e_value)
4421 - symsec->vma));
4423 /* If this is a global symbol set the written flag, and if
4424 it is a local symbol see if we should discard it. */
4425 if (h != (struct aout_link_hash_entry *) NULL)
4427 h->written = TRUE;
4428 h->indx = obj_aout_external_sym_count (output_bfd);
4430 else if ((type & N_TYPE) != N_SETT
4431 && (type & N_TYPE) != N_SETD
4432 && (type & N_TYPE) != N_SETB
4433 && (type & N_TYPE) != N_SETA)
4435 switch (discard)
4437 case discard_none:
4438 case discard_sec_merge:
4439 break;
4440 case discard_l:
4441 if ((type & N_STAB) == 0
4442 && bfd_is_local_label_name (input_bfd, name))
4443 skip = TRUE;
4444 break;
4445 case discard_all:
4446 skip = TRUE;
4447 break;
4449 if (skip)
4451 pass = FALSE;
4452 continue;
4456 /* An N_BINCL symbol indicates the start of the stabs
4457 entries for a header file. We need to scan ahead to the
4458 next N_EINCL symbol, ignoring nesting, adding up all the
4459 characters in the symbol names, not including the file
4460 numbers in types (the first number after an open
4461 parenthesis). */
4462 if (type == (int) N_BINCL)
4464 struct external_nlist *incl_sym;
4465 int nest;
4466 struct aout_link_includes_entry *incl_entry;
4467 struct aout_link_includes_totals *t;
4469 val = 0;
4470 nest = 0;
4471 for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
4473 int incl_type;
4475 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
4476 if (incl_type == (int) N_EINCL)
4478 if (nest == 0)
4479 break;
4480 --nest;
4482 else if (incl_type == (int) N_BINCL)
4483 ++nest;
4484 else if (nest == 0)
4486 const char *s;
4488 s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
4489 for (; *s != '\0'; s++)
4491 val += *s;
4492 if (*s == '(')
4494 /* Skip the file number. */
4495 ++s;
4496 while (ISDIGIT (*s))
4497 ++s;
4498 --s;
4504 /* If we have already included a header file with the
4505 same value, then replace this one with an N_EXCL
4506 symbol. */
4507 copy = (bfd_boolean) (! finfo->info->keep_memory);
4508 incl_entry = aout_link_includes_lookup (&finfo->includes,
4509 name, TRUE, copy);
4510 if (incl_entry == NULL)
4511 return FALSE;
4512 for (t = incl_entry->totals; t != NULL; t = t->next)
4513 if (t->total == val)
4514 break;
4515 if (t == NULL)
4517 /* This is the first time we have seen this header
4518 file with this set of stabs strings. */
4519 t = ((struct aout_link_includes_totals *)
4520 bfd_hash_allocate (&finfo->includes.root,
4521 sizeof *t));
4522 if (t == NULL)
4523 return FALSE;
4524 t->total = val;
4525 t->next = incl_entry->totals;
4526 incl_entry->totals = t;
4528 else
4530 int *incl_map;
4532 /* This is a duplicate header file. We must change
4533 it to be an N_EXCL entry, and mark all the
4534 included symbols to prevent outputting them. */
4535 type = (int) N_EXCL;
4537 nest = 0;
4538 for (incl_sym = sym + 1, incl_map = symbol_map + 1;
4539 incl_sym < sym_end;
4540 incl_sym++, incl_map++)
4542 int incl_type;
4544 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
4545 if (incl_type == (int) N_EINCL)
4547 if (nest == 0)
4549 *incl_map = -1;
4550 break;
4552 --nest;
4554 else if (incl_type == (int) N_BINCL)
4555 ++nest;
4556 else if (nest == 0)
4557 *incl_map = -1;
4563 /* Copy this symbol into the list of symbols we are going to
4564 write out. */
4565 H_PUT_8 (output_bfd, type, outsym->e_type);
4566 H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_other), outsym->e_other);
4567 H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc);
4568 copy = FALSE;
4569 if (! finfo->info->keep_memory)
4571 /* name points into a string table which we are going to
4572 free. If there is a hash table entry, use that string.
4573 Otherwise, copy name into memory. */
4574 if (h != (struct aout_link_hash_entry *) NULL)
4575 name = h->root.root.string;
4576 else
4577 copy = TRUE;
4579 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4580 name, copy);
4581 if (strtab_index == (bfd_size_type) -1)
4582 return FALSE;
4583 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4584 PUT_WORD (output_bfd, val, outsym->e_value);
4585 *symbol_map = obj_aout_external_sym_count (output_bfd);
4586 ++obj_aout_external_sym_count (output_bfd);
4587 ++outsym;
4590 /* Write out the output symbols we have just constructed. */
4591 if (outsym > finfo->output_syms)
4593 bfd_size_type outsym_size;
4595 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
4596 return FALSE;
4597 outsym_size = outsym - finfo->output_syms;
4598 outsym_size *= EXTERNAL_NLIST_SIZE;
4599 if (bfd_bwrite ((PTR) finfo->output_syms, outsym_size, output_bfd)
4600 != outsym_size)
4601 return FALSE;
4602 finfo->symoff += outsym_size;
4605 return TRUE;
4608 /* Write out a symbol that was not associated with an a.out input
4609 object. */
4611 static bfd_boolean
4612 aout_link_write_other_symbol (h, data)
4613 struct aout_link_hash_entry *h;
4614 PTR data;
4616 struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
4617 bfd *output_bfd;
4618 int type;
4619 bfd_vma val;
4620 struct external_nlist outsym;
4621 bfd_size_type indx;
4622 bfd_size_type amt;
4624 if (h->root.type == bfd_link_hash_warning)
4626 h = (struct aout_link_hash_entry *) h->root.u.i.link;
4627 if (h->root.type == bfd_link_hash_new)
4628 return TRUE;
4631 output_bfd = finfo->output_bfd;
4633 if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
4635 if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
4636 (output_bfd, finfo->info, h)))
4638 /* FIXME: No way to handle errors. */
4639 abort ();
4643 if (h->written)
4644 return TRUE;
4646 h->written = TRUE;
4648 /* An indx of -2 means the symbol must be written. */
4649 if (h->indx != -2
4650 && (finfo->info->strip == strip_all
4651 || (finfo->info->strip == strip_some
4652 && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
4653 FALSE, FALSE) == NULL)))
4654 return TRUE;
4656 switch (h->root.type)
4658 default:
4659 case bfd_link_hash_warning:
4660 abort ();
4661 /* Avoid variable not initialized warnings. */
4662 return TRUE;
4663 case bfd_link_hash_new:
4664 /* This can happen for set symbols when sets are not being
4665 built. */
4666 return TRUE;
4667 case bfd_link_hash_undefined:
4668 type = N_UNDF | N_EXT;
4669 val = 0;
4670 break;
4671 case bfd_link_hash_defined:
4672 case bfd_link_hash_defweak:
4674 asection *sec;
4676 sec = h->root.u.def.section->output_section;
4677 BFD_ASSERT (bfd_is_abs_section (sec)
4678 || sec->owner == output_bfd);
4679 if (sec == obj_textsec (output_bfd))
4680 type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
4681 else if (sec == obj_datasec (output_bfd))
4682 type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
4683 else if (sec == obj_bsssec (output_bfd))
4684 type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
4685 else
4686 type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
4687 type |= N_EXT;
4688 val = (h->root.u.def.value
4689 + sec->vma
4690 + h->root.u.def.section->output_offset);
4692 break;
4693 case bfd_link_hash_common:
4694 type = N_UNDF | N_EXT;
4695 val = h->root.u.c.size;
4696 break;
4697 case bfd_link_hash_undefweak:
4698 type = N_WEAKU;
4699 val = 0;
4700 case bfd_link_hash_indirect:
4701 /* We ignore these symbols, since the indirected symbol is
4702 already in the hash table. */
4703 return TRUE;
4706 H_PUT_8 (output_bfd, type, outsym.e_type);
4707 H_PUT_8 (output_bfd, 0, outsym.e_other);
4708 H_PUT_16 (output_bfd, 0, outsym.e_desc);
4709 indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
4710 FALSE);
4711 if (indx == - (bfd_size_type) 1)
4713 /* FIXME: No way to handle errors. */
4714 abort ();
4716 PUT_WORD (output_bfd, indx, outsym.e_strx);
4717 PUT_WORD (output_bfd, val, outsym.e_value);
4719 amt = EXTERNAL_NLIST_SIZE;
4720 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
4721 || bfd_bwrite ((PTR) &outsym, amt, output_bfd) != amt)
4723 /* FIXME: No way to handle errors. */
4724 abort ();
4727 finfo->symoff += EXTERNAL_NLIST_SIZE;
4728 h->indx = obj_aout_external_sym_count (output_bfd);
4729 ++obj_aout_external_sym_count (output_bfd);
4731 return TRUE;
4734 /* Link an a.out section into the output file. */
4736 static bfd_boolean
4737 aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
4738 rel_size)
4739 struct aout_final_link_info *finfo;
4740 bfd *input_bfd;
4741 asection *input_section;
4742 file_ptr *reloff_ptr;
4743 bfd_size_type rel_size;
4745 bfd_size_type input_size;
4746 PTR relocs;
4748 /* Get the section contents. */
4749 input_size = input_section->size;
4750 if (! bfd_get_section_contents (input_bfd, input_section,
4751 (PTR) finfo->contents,
4752 (file_ptr) 0, input_size))
4753 return FALSE;
4755 /* Read in the relocs if we haven't already done it. */
4756 if (aout_section_data (input_section) != NULL
4757 && aout_section_data (input_section)->relocs != NULL)
4758 relocs = aout_section_data (input_section)->relocs;
4759 else
4761 relocs = finfo->relocs;
4762 if (rel_size > 0)
4764 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
4765 || bfd_bread (relocs, rel_size, input_bfd) != rel_size)
4766 return FALSE;
4770 /* Relocate the section contents. */
4771 if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4773 if (! aout_link_input_section_std (finfo, input_bfd, input_section,
4774 (struct reloc_std_external *) relocs,
4775 rel_size, finfo->contents))
4776 return FALSE;
4778 else
4780 if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
4781 (struct reloc_ext_external *) relocs,
4782 rel_size, finfo->contents))
4783 return FALSE;
4786 /* Write out the section contents. */
4787 if (! bfd_set_section_contents (finfo->output_bfd,
4788 input_section->output_section,
4789 (PTR) finfo->contents,
4790 (file_ptr) input_section->output_offset,
4791 input_size))
4792 return FALSE;
4794 /* If we are producing relocatable output, the relocs were
4795 modified, and we now write them out. */
4796 if (finfo->info->relocatable && rel_size > 0)
4798 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
4799 return FALSE;
4800 if (bfd_bwrite (relocs, rel_size, finfo->output_bfd) != rel_size)
4801 return FALSE;
4802 *reloff_ptr += rel_size;
4804 /* Assert that the relocs have not run into the symbols, and
4805 that if these are the text relocs they have not run into the
4806 data relocs. */
4807 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
4808 && (reloff_ptr != &finfo->treloff
4809 || (*reloff_ptr
4810 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
4813 return TRUE;
4816 /* Get the section corresponding to a reloc index. */
4818 static INLINE asection *
4819 aout_reloc_index_to_section (abfd, indx)
4820 bfd *abfd;
4821 int indx;
4823 switch (indx & N_TYPE)
4825 case N_TEXT:
4826 return obj_textsec (abfd);
4827 case N_DATA:
4828 return obj_datasec (abfd);
4829 case N_BSS:
4830 return obj_bsssec (abfd);
4831 case N_ABS:
4832 case N_UNDF:
4833 return bfd_abs_section_ptr;
4834 default:
4835 abort ();
4837 /*NOTREACHED*/
4838 return NULL;
4841 /* Relocate an a.out section using standard a.out relocs. */
4843 static bfd_boolean
4844 aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
4845 rel_size, contents)
4846 struct aout_final_link_info *finfo;
4847 bfd *input_bfd;
4848 asection *input_section;
4849 struct reloc_std_external *relocs;
4850 bfd_size_type rel_size;
4851 bfd_byte *contents;
4853 bfd_boolean (*check_dynamic_reloc)
4854 PARAMS ((struct bfd_link_info *, bfd *, asection *,
4855 struct aout_link_hash_entry *, PTR, bfd_byte *, bfd_boolean *,
4856 bfd_vma *));
4857 bfd *output_bfd;
4858 bfd_boolean relocatable;
4859 struct external_nlist *syms;
4860 char *strings;
4861 struct aout_link_hash_entry **sym_hashes;
4862 int *symbol_map;
4863 bfd_size_type reloc_count;
4864 register struct reloc_std_external *rel;
4865 struct reloc_std_external *rel_end;
4867 output_bfd = finfo->output_bfd;
4868 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4870 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
4871 BFD_ASSERT (input_bfd->xvec->header_byteorder
4872 == output_bfd->xvec->header_byteorder);
4874 relocatable = finfo->info->relocatable;
4875 syms = obj_aout_external_syms (input_bfd);
4876 strings = obj_aout_external_strings (input_bfd);
4877 sym_hashes = obj_aout_sym_hashes (input_bfd);
4878 symbol_map = finfo->symbol_map;
4880 reloc_count = rel_size / RELOC_STD_SIZE;
4881 rel = relocs;
4882 rel_end = rel + reloc_count;
4883 for (; rel < rel_end; rel++)
4885 bfd_vma r_addr;
4886 int r_index;
4887 int r_extern;
4888 int r_pcrel;
4889 int r_baserel = 0;
4890 reloc_howto_type *howto;
4891 struct aout_link_hash_entry *h = NULL;
4892 bfd_vma relocation;
4893 bfd_reloc_status_type r;
4895 r_addr = GET_SWORD (input_bfd, rel->r_address);
4897 #ifdef MY_reloc_howto
4898 howto = MY_reloc_howto (input_bfd, rel, r_index, r_extern, r_pcrel);
4899 #else
4901 int r_jmptable;
4902 int r_relative;
4903 int r_length;
4904 unsigned int howto_idx;
4906 if (bfd_header_big_endian (input_bfd))
4908 r_index = (((unsigned int) rel->r_index[0] << 16)
4909 | ((unsigned int) rel->r_index[1] << 8)
4910 | rel->r_index[2]);
4911 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
4912 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
4913 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
4914 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
4915 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
4916 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
4917 >> RELOC_STD_BITS_LENGTH_SH_BIG);
4919 else
4921 r_index = (((unsigned int) rel->r_index[2] << 16)
4922 | ((unsigned int) rel->r_index[1] << 8)
4923 | rel->r_index[0]);
4924 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
4925 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
4926 r_baserel = (0 != (rel->r_type[0]
4927 & RELOC_STD_BITS_BASEREL_LITTLE));
4928 r_jmptable= (0 != (rel->r_type[0]
4929 & RELOC_STD_BITS_JMPTABLE_LITTLE));
4930 r_relative= (0 != (rel->r_type[0]
4931 & RELOC_STD_BITS_RELATIVE_LITTLE));
4932 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
4933 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
4936 howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
4937 + 16 * r_jmptable + 32 * r_relative);
4938 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
4939 howto = howto_table_std + howto_idx;
4941 #endif
4943 if (relocatable)
4945 /* We are generating a relocatable output file, and must
4946 modify the reloc accordingly. */
4947 if (r_extern)
4949 /* If we know the symbol this relocation is against,
4950 convert it into a relocation against a section. This
4951 is what the native linker does. */
4952 h = sym_hashes[r_index];
4953 if (h != (struct aout_link_hash_entry *) NULL
4954 && (h->root.type == bfd_link_hash_defined
4955 || h->root.type == bfd_link_hash_defweak))
4957 asection *output_section;
4959 /* Change the r_extern value. */
4960 if (bfd_header_big_endian (output_bfd))
4961 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
4962 else
4963 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
4965 /* Compute a new r_index. */
4966 output_section = h->root.u.def.section->output_section;
4967 if (output_section == obj_textsec (output_bfd))
4968 r_index = N_TEXT;
4969 else if (output_section == obj_datasec (output_bfd))
4970 r_index = N_DATA;
4971 else if (output_section == obj_bsssec (output_bfd))
4972 r_index = N_BSS;
4973 else
4974 r_index = N_ABS;
4976 /* Add the symbol value and the section VMA to the
4977 addend stored in the contents. */
4978 relocation = (h->root.u.def.value
4979 + output_section->vma
4980 + h->root.u.def.section->output_offset);
4982 else
4984 /* We must change r_index according to the symbol
4985 map. */
4986 r_index = symbol_map[r_index];
4988 if (r_index == -1)
4990 if (h != NULL)
4992 /* We decided to strip this symbol, but it
4993 turns out that we can't. Note that we
4994 lose the other and desc information here.
4995 I don't think that will ever matter for a
4996 global symbol. */
4997 if (h->indx < 0)
4999 h->indx = -2;
5000 h->written = FALSE;
5001 if (! aout_link_write_other_symbol (h,
5002 (PTR) finfo))
5003 return FALSE;
5005 r_index = h->indx;
5007 else
5009 const char *name;
5011 name = strings + GET_WORD (input_bfd,
5012 syms[r_index].e_strx);
5013 if (! ((*finfo->info->callbacks->unattached_reloc)
5014 (finfo->info, name, input_bfd, input_section,
5015 r_addr)))
5016 return FALSE;
5017 r_index = 0;
5021 relocation = 0;
5024 /* Write out the new r_index value. */
5025 if (bfd_header_big_endian (output_bfd))
5027 rel->r_index[0] = r_index >> 16;
5028 rel->r_index[1] = r_index >> 8;
5029 rel->r_index[2] = r_index;
5031 else
5033 rel->r_index[2] = r_index >> 16;
5034 rel->r_index[1] = r_index >> 8;
5035 rel->r_index[0] = r_index;
5038 else
5040 asection *section;
5042 /* This is a relocation against a section. We must
5043 adjust by the amount that the section moved. */
5044 section = aout_reloc_index_to_section (input_bfd, r_index);
5045 relocation = (section->output_section->vma
5046 + section->output_offset
5047 - section->vma);
5050 /* Change the address of the relocation. */
5051 PUT_WORD (output_bfd,
5052 r_addr + input_section->output_offset,
5053 rel->r_address);
5055 /* Adjust a PC relative relocation by removing the reference
5056 to the original address in the section and including the
5057 reference to the new address. */
5058 if (r_pcrel)
5059 relocation -= (input_section->output_section->vma
5060 + input_section->output_offset
5061 - input_section->vma);
5063 #ifdef MY_relocatable_reloc
5064 MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
5065 #endif
5067 if (relocation == 0)
5068 r = bfd_reloc_ok;
5069 else
5070 r = MY_relocate_contents (howto,
5071 input_bfd, relocation,
5072 contents + r_addr);
5074 else
5076 bfd_boolean hundef;
5078 /* We are generating an executable, and must do a full
5079 relocation. */
5080 hundef = FALSE;
5082 if (r_extern)
5084 h = sym_hashes[r_index];
5086 if (h != (struct aout_link_hash_entry *) NULL
5087 && (h->root.type == bfd_link_hash_defined
5088 || h->root.type == bfd_link_hash_defweak))
5090 relocation = (h->root.u.def.value
5091 + h->root.u.def.section->output_section->vma
5092 + h->root.u.def.section->output_offset);
5094 else if (h != (struct aout_link_hash_entry *) NULL
5095 && h->root.type == bfd_link_hash_undefweak)
5096 relocation = 0;
5097 else
5099 hundef = TRUE;
5100 relocation = 0;
5103 else
5105 asection *section;
5107 section = aout_reloc_index_to_section (input_bfd, r_index);
5108 relocation = (section->output_section->vma
5109 + section->output_offset
5110 - section->vma);
5111 if (r_pcrel)
5112 relocation += input_section->vma;
5115 if (check_dynamic_reloc != NULL)
5117 bfd_boolean skip;
5119 if (! ((*check_dynamic_reloc)
5120 (finfo->info, input_bfd, input_section, h,
5121 (PTR) rel, contents, &skip, &relocation)))
5122 return FALSE;
5123 if (skip)
5124 continue;
5127 /* Now warn if a global symbol is undefined. We could not
5128 do this earlier, because check_dynamic_reloc might want
5129 to skip this reloc. */
5130 if (hundef && ! finfo->info->shared && ! r_baserel)
5132 const char *name;
5134 if (h != NULL)
5135 name = h->root.root.string;
5136 else
5137 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5138 if (! ((*finfo->info->callbacks->undefined_symbol)
5139 (finfo->info, name, input_bfd, input_section,
5140 r_addr, TRUE)))
5141 return FALSE;
5144 r = MY_final_link_relocate (howto,
5145 input_bfd, input_section,
5146 contents, r_addr, relocation,
5147 (bfd_vma) 0);
5150 if (r != bfd_reloc_ok)
5152 switch (r)
5154 default:
5155 case bfd_reloc_outofrange:
5156 abort ();
5157 case bfd_reloc_overflow:
5159 const char *name;
5161 if (h != NULL)
5162 name = NULL;
5163 else if (r_extern)
5164 name = strings + GET_WORD (input_bfd,
5165 syms[r_index].e_strx);
5166 else
5168 asection *s;
5170 s = aout_reloc_index_to_section (input_bfd, r_index);
5171 name = bfd_section_name (input_bfd, s);
5173 if (! ((*finfo->info->callbacks->reloc_overflow)
5174 (finfo->info, (h ? &h->root : NULL), name,
5175 howto->name, (bfd_vma) 0, input_bfd,
5176 input_section, r_addr)))
5177 return FALSE;
5179 break;
5184 return TRUE;
5187 /* Relocate an a.out section using extended a.out relocs. */
5189 static bfd_boolean
5190 aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
5191 rel_size, contents)
5192 struct aout_final_link_info *finfo;
5193 bfd *input_bfd;
5194 asection *input_section;
5195 struct reloc_ext_external *relocs;
5196 bfd_size_type rel_size;
5197 bfd_byte *contents;
5199 bfd_boolean (*check_dynamic_reloc)
5200 PARAMS ((struct bfd_link_info *, bfd *, asection *,
5201 struct aout_link_hash_entry *, PTR, bfd_byte *, bfd_boolean *,
5202 bfd_vma *));
5203 bfd *output_bfd;
5204 bfd_boolean relocatable;
5205 struct external_nlist *syms;
5206 char *strings;
5207 struct aout_link_hash_entry **sym_hashes;
5208 int *symbol_map;
5209 bfd_size_type reloc_count;
5210 register struct reloc_ext_external *rel;
5211 struct reloc_ext_external *rel_end;
5213 output_bfd = finfo->output_bfd;
5214 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
5216 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
5217 BFD_ASSERT (input_bfd->xvec->header_byteorder
5218 == output_bfd->xvec->header_byteorder);
5220 relocatable = finfo->info->relocatable;
5221 syms = obj_aout_external_syms (input_bfd);
5222 strings = obj_aout_external_strings (input_bfd);
5223 sym_hashes = obj_aout_sym_hashes (input_bfd);
5224 symbol_map = finfo->symbol_map;
5226 reloc_count = rel_size / RELOC_EXT_SIZE;
5227 rel = relocs;
5228 rel_end = rel + reloc_count;
5229 for (; rel < rel_end; rel++)
5231 bfd_vma r_addr;
5232 int r_index;
5233 int r_extern;
5234 unsigned int r_type;
5235 bfd_vma r_addend;
5236 struct aout_link_hash_entry *h = NULL;
5237 asection *r_section = NULL;
5238 bfd_vma relocation;
5240 r_addr = GET_SWORD (input_bfd, rel->r_address);
5242 if (bfd_header_big_endian (input_bfd))
5244 r_index = (((unsigned int) rel->r_index[0] << 16)
5245 | ((unsigned int) rel->r_index[1] << 8)
5246 | rel->r_index[2]);
5247 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
5248 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
5249 >> RELOC_EXT_BITS_TYPE_SH_BIG);
5251 else
5253 r_index = (((unsigned int) rel->r_index[2] << 16)
5254 | ((unsigned int) rel->r_index[1] << 8)
5255 | rel->r_index[0]);
5256 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
5257 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
5258 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
5261 r_addend = GET_SWORD (input_bfd, rel->r_addend);
5263 BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
5265 if (relocatable)
5267 /* We are generating a relocatable output file, and must
5268 modify the reloc accordingly. */
5269 if (r_extern
5270 || r_type == (unsigned int) RELOC_BASE10
5271 || r_type == (unsigned int) RELOC_BASE13
5272 || r_type == (unsigned int) RELOC_BASE22)
5274 /* If we know the symbol this relocation is against,
5275 convert it into a relocation against a section. This
5276 is what the native linker does. */
5277 if (r_type == (unsigned int) RELOC_BASE10
5278 || r_type == (unsigned int) RELOC_BASE13
5279 || r_type == (unsigned int) RELOC_BASE22)
5280 h = NULL;
5281 else
5282 h = sym_hashes[r_index];
5283 if (h != (struct aout_link_hash_entry *) NULL
5284 && (h->root.type == bfd_link_hash_defined
5285 || h->root.type == bfd_link_hash_defweak))
5287 asection *output_section;
5289 /* Change the r_extern value. */
5290 if (bfd_header_big_endian (output_bfd))
5291 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
5292 else
5293 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
5295 /* Compute a new r_index. */
5296 output_section = h->root.u.def.section->output_section;
5297 if (output_section == obj_textsec (output_bfd))
5298 r_index = N_TEXT;
5299 else if (output_section == obj_datasec (output_bfd))
5300 r_index = N_DATA;
5301 else if (output_section == obj_bsssec (output_bfd))
5302 r_index = N_BSS;
5303 else
5304 r_index = N_ABS;
5306 /* Add the symbol value and the section VMA to the
5307 addend. */
5308 relocation = (h->root.u.def.value
5309 + output_section->vma
5310 + h->root.u.def.section->output_offset);
5312 /* Now RELOCATION is the VMA of the final
5313 destination. If this is a PC relative reloc,
5314 then ADDEND is the negative of the source VMA.
5315 We want to set ADDEND to the difference between
5316 the destination VMA and the source VMA, which
5317 means we must adjust RELOCATION by the change in
5318 the source VMA. This is done below. */
5320 else
5322 /* We must change r_index according to the symbol
5323 map. */
5324 r_index = symbol_map[r_index];
5326 if (r_index == -1)
5328 if (h != NULL)
5330 /* We decided to strip this symbol, but it
5331 turns out that we can't. Note that we
5332 lose the other and desc information here.
5333 I don't think that will ever matter for a
5334 global symbol. */
5335 if (h->indx < 0)
5337 h->indx = -2;
5338 h->written = FALSE;
5339 if (! aout_link_write_other_symbol (h,
5340 (PTR) finfo))
5341 return FALSE;
5343 r_index = h->indx;
5345 else
5347 const char *name;
5349 name = strings + GET_WORD (input_bfd,
5350 syms[r_index].e_strx);
5351 if (! ((*finfo->info->callbacks->unattached_reloc)
5352 (finfo->info, name, input_bfd, input_section,
5353 r_addr)))
5354 return FALSE;
5355 r_index = 0;
5359 relocation = 0;
5361 /* If this is a PC relative reloc, then the addend
5362 is the negative of the source VMA. We must
5363 adjust it by the change in the source VMA. This
5364 is done below. */
5367 /* Write out the new r_index value. */
5368 if (bfd_header_big_endian (output_bfd))
5370 rel->r_index[0] = r_index >> 16;
5371 rel->r_index[1] = r_index >> 8;
5372 rel->r_index[2] = r_index;
5374 else
5376 rel->r_index[2] = r_index >> 16;
5377 rel->r_index[1] = r_index >> 8;
5378 rel->r_index[0] = r_index;
5381 else
5383 /* This is a relocation against a section. We must
5384 adjust by the amount that the section moved. */
5385 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5386 relocation = (r_section->output_section->vma
5387 + r_section->output_offset
5388 - r_section->vma);
5390 /* If this is a PC relative reloc, then the addend is
5391 the difference in VMA between the destination and the
5392 source. We have just adjusted for the change in VMA
5393 of the destination, so we must also adjust by the
5394 change in VMA of the source. This is done below. */
5397 /* As described above, we must always adjust a PC relative
5398 reloc by the change in VMA of the source. However, if
5399 pcrel_offset is set, then the addend does not include the
5400 location within the section, in which case we don't need
5401 to adjust anything. */
5402 if (howto_table_ext[r_type].pc_relative
5403 && ! howto_table_ext[r_type].pcrel_offset)
5404 relocation -= (input_section->output_section->vma
5405 + input_section->output_offset
5406 - input_section->vma);
5408 /* Change the addend if necessary. */
5409 if (relocation != 0)
5410 PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
5412 /* Change the address of the relocation. */
5413 PUT_WORD (output_bfd,
5414 r_addr + input_section->output_offset,
5415 rel->r_address);
5417 else
5419 bfd_boolean hundef;
5420 bfd_reloc_status_type r;
5422 /* We are generating an executable, and must do a full
5423 relocation. */
5424 hundef = FALSE;
5426 if (r_extern)
5428 h = sym_hashes[r_index];
5430 if (h != (struct aout_link_hash_entry *) NULL
5431 && (h->root.type == bfd_link_hash_defined
5432 || h->root.type == bfd_link_hash_defweak))
5434 relocation = (h->root.u.def.value
5435 + h->root.u.def.section->output_section->vma
5436 + h->root.u.def.section->output_offset);
5438 else if (h != (struct aout_link_hash_entry *) NULL
5439 && h->root.type == bfd_link_hash_undefweak)
5440 relocation = 0;
5441 else
5443 hundef = TRUE;
5444 relocation = 0;
5447 else if (r_type == (unsigned int) RELOC_BASE10
5448 || r_type == (unsigned int) RELOC_BASE13
5449 || r_type == (unsigned int) RELOC_BASE22)
5451 struct external_nlist *sym;
5452 int type;
5454 /* For base relative relocs, r_index is always an index
5455 into the symbol table, even if r_extern is 0. */
5456 sym = syms + r_index;
5457 type = H_GET_8 (input_bfd, sym->e_type);
5458 if ((type & N_TYPE) == N_TEXT
5459 || type == N_WEAKT)
5460 r_section = obj_textsec (input_bfd);
5461 else if ((type & N_TYPE) == N_DATA
5462 || type == N_WEAKD)
5463 r_section = obj_datasec (input_bfd);
5464 else if ((type & N_TYPE) == N_BSS
5465 || type == N_WEAKB)
5466 r_section = obj_bsssec (input_bfd);
5467 else if ((type & N_TYPE) == N_ABS
5468 || type == N_WEAKA)
5469 r_section = bfd_abs_section_ptr;
5470 else
5471 abort ();
5472 relocation = (r_section->output_section->vma
5473 + r_section->output_offset
5474 + (GET_WORD (input_bfd, sym->e_value)
5475 - r_section->vma));
5477 else
5479 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5481 /* If this is a PC relative reloc, then R_ADDEND is the
5482 difference between the two vmas, or
5483 old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
5484 where
5485 old_dest_sec == section->vma
5487 old_src_sec == input_section->vma
5489 old_src_off == r_addr
5491 _bfd_final_link_relocate expects RELOCATION +
5492 R_ADDEND to be the VMA of the destination minus
5493 r_addr (the minus r_addr is because this relocation
5494 is not pcrel_offset, which is a bit confusing and
5495 should, perhaps, be changed), or
5496 new_dest_sec
5497 where
5498 new_dest_sec == output_section->vma + output_offset
5499 We arrange for this to happen by setting RELOCATION to
5500 new_dest_sec + old_src_sec - old_dest_sec
5502 If this is not a PC relative reloc, then R_ADDEND is
5503 simply the VMA of the destination, so we set
5504 RELOCATION to the change in the destination VMA, or
5505 new_dest_sec - old_dest_sec
5507 relocation = (r_section->output_section->vma
5508 + r_section->output_offset
5509 - r_section->vma);
5510 if (howto_table_ext[r_type].pc_relative)
5511 relocation += input_section->vma;
5514 if (check_dynamic_reloc != NULL)
5516 bfd_boolean skip;
5518 if (! ((*check_dynamic_reloc)
5519 (finfo->info, input_bfd, input_section, h,
5520 (PTR) rel, contents, &skip, &relocation)))
5521 return FALSE;
5522 if (skip)
5523 continue;
5526 /* Now warn if a global symbol is undefined. We could not
5527 do this earlier, because check_dynamic_reloc might want
5528 to skip this reloc. */
5529 if (hundef
5530 && ! finfo->info->shared
5531 && r_type != (unsigned int) RELOC_BASE10
5532 && r_type != (unsigned int) RELOC_BASE13
5533 && r_type != (unsigned int) RELOC_BASE22)
5535 const char *name;
5537 if (h != NULL)
5538 name = h->root.root.string;
5539 else
5540 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5541 if (! ((*finfo->info->callbacks->undefined_symbol)
5542 (finfo->info, name, input_bfd, input_section,
5543 r_addr, TRUE)))
5544 return FALSE;
5547 if (r_type != (unsigned int) RELOC_SPARC_REV32)
5548 r = MY_final_link_relocate (howto_table_ext + r_type,
5549 input_bfd, input_section,
5550 contents, r_addr, relocation,
5551 r_addend);
5552 else
5554 bfd_vma x;
5556 x = bfd_get_32 (input_bfd, contents + r_addr);
5557 x = x + relocation + r_addend;
5558 bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
5559 r = bfd_reloc_ok;
5562 if (r != bfd_reloc_ok)
5564 switch (r)
5566 default:
5567 case bfd_reloc_outofrange:
5568 abort ();
5569 case bfd_reloc_overflow:
5571 const char *name;
5573 if (h != NULL)
5574 name = NULL;
5575 else if (r_extern
5576 || r_type == (unsigned int) RELOC_BASE10
5577 || r_type == (unsigned int) RELOC_BASE13
5578 || r_type == (unsigned int) RELOC_BASE22)
5579 name = strings + GET_WORD (input_bfd,
5580 syms[r_index].e_strx);
5581 else
5583 asection *s;
5585 s = aout_reloc_index_to_section (input_bfd, r_index);
5586 name = bfd_section_name (input_bfd, s);
5588 if (! ((*finfo->info->callbacks->reloc_overflow)
5589 (finfo->info, (h ? &h->root : NULL), name,
5590 howto_table_ext[r_type].name,
5591 r_addend, input_bfd, input_section, r_addr)))
5592 return FALSE;
5594 break;
5600 return TRUE;
5603 /* Handle a link order which is supposed to generate a reloc. */
5605 static bfd_boolean
5606 aout_link_reloc_link_order (finfo, o, p)
5607 struct aout_final_link_info *finfo;
5608 asection *o;
5609 struct bfd_link_order *p;
5611 struct bfd_link_order_reloc *pr;
5612 int r_index;
5613 int r_extern;
5614 reloc_howto_type *howto;
5615 file_ptr *reloff_ptr = NULL;
5616 struct reloc_std_external srel;
5617 struct reloc_ext_external erel;
5618 PTR rel_ptr;
5619 bfd_size_type amt;
5621 pr = p->u.reloc.p;
5623 if (p->type == bfd_section_reloc_link_order)
5625 r_extern = 0;
5626 if (bfd_is_abs_section (pr->u.section))
5627 r_index = N_ABS | N_EXT;
5628 else
5630 BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
5631 r_index = pr->u.section->target_index;
5634 else
5636 struct aout_link_hash_entry *h;
5638 BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
5639 r_extern = 1;
5640 h = ((struct aout_link_hash_entry *)
5641 bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
5642 pr->u.name, FALSE, FALSE, TRUE));
5643 if (h != (struct aout_link_hash_entry *) NULL
5644 && h->indx >= 0)
5645 r_index = h->indx;
5646 else if (h != NULL)
5648 /* We decided to strip this symbol, but it turns out that we
5649 can't. Note that we lose the other and desc information
5650 here. I don't think that will ever matter for a global
5651 symbol. */
5652 h->indx = -2;
5653 h->written = FALSE;
5654 if (! aout_link_write_other_symbol (h, (PTR) finfo))
5655 return FALSE;
5656 r_index = h->indx;
5658 else
5660 if (! ((*finfo->info->callbacks->unattached_reloc)
5661 (finfo->info, pr->u.name, (bfd *) NULL,
5662 (asection *) NULL, (bfd_vma) 0)))
5663 return FALSE;
5664 r_index = 0;
5668 howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
5669 if (howto == 0)
5671 bfd_set_error (bfd_error_bad_value);
5672 return FALSE;
5675 if (o == obj_textsec (finfo->output_bfd))
5676 reloff_ptr = &finfo->treloff;
5677 else if (o == obj_datasec (finfo->output_bfd))
5678 reloff_ptr = &finfo->dreloff;
5679 else
5680 abort ();
5682 if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
5684 #ifdef MY_put_reloc
5685 MY_put_reloc (finfo->output_bfd, r_extern, r_index, p->offset, howto,
5686 &srel);
5687 #else
5689 int r_pcrel;
5690 int r_baserel;
5691 int r_jmptable;
5692 int r_relative;
5693 int r_length;
5695 r_pcrel = (int) howto->pc_relative;
5696 r_baserel = (howto->type & 8) != 0;
5697 r_jmptable = (howto->type & 16) != 0;
5698 r_relative = (howto->type & 32) != 0;
5699 r_length = howto->size;
5701 PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
5702 if (bfd_header_big_endian (finfo->output_bfd))
5704 srel.r_index[0] = r_index >> 16;
5705 srel.r_index[1] = r_index >> 8;
5706 srel.r_index[2] = r_index;
5707 srel.r_type[0] =
5708 ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
5709 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
5710 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
5711 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
5712 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
5713 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
5715 else
5717 srel.r_index[2] = r_index >> 16;
5718 srel.r_index[1] = r_index >> 8;
5719 srel.r_index[0] = r_index;
5720 srel.r_type[0] =
5721 ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
5722 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
5723 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
5724 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
5725 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
5726 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
5729 #endif
5730 rel_ptr = (PTR) &srel;
5732 /* We have to write the addend into the object file, since
5733 standard a.out relocs are in place. It would be more
5734 reliable if we had the current contents of the file here,
5735 rather than assuming zeroes, but we can't read the file since
5736 it was opened using bfd_openw. */
5737 if (pr->addend != 0)
5739 bfd_size_type size;
5740 bfd_reloc_status_type r;
5741 bfd_byte *buf;
5742 bfd_boolean ok;
5744 size = bfd_get_reloc_size (howto);
5745 buf = (bfd_byte *) bfd_zmalloc (size);
5746 if (buf == (bfd_byte *) NULL)
5747 return FALSE;
5748 r = MY_relocate_contents (howto, finfo->output_bfd,
5749 (bfd_vma) pr->addend, buf);
5750 switch (r)
5752 case bfd_reloc_ok:
5753 break;
5754 default:
5755 case bfd_reloc_outofrange:
5756 abort ();
5757 case bfd_reloc_overflow:
5758 if (! ((*finfo->info->callbacks->reloc_overflow)
5759 (finfo->info, NULL,
5760 (p->type == bfd_section_reloc_link_order
5761 ? bfd_section_name (finfo->output_bfd,
5762 pr->u.section)
5763 : pr->u.name),
5764 howto->name, pr->addend, (bfd *) NULL,
5765 (asection *) NULL, (bfd_vma) 0)))
5767 free (buf);
5768 return FALSE;
5770 break;
5772 ok = bfd_set_section_contents (finfo->output_bfd, o, (PTR) buf,
5773 (file_ptr) p->offset, size);
5774 free (buf);
5775 if (! ok)
5776 return FALSE;
5779 else
5781 #ifdef MY_put_ext_reloc
5782 MY_put_ext_reloc (finfo->output_bfd, r_extern, r_index, p->offset,
5783 howto, &erel, pr->addend);
5784 #else
5785 PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
5787 if (bfd_header_big_endian (finfo->output_bfd))
5789 erel.r_index[0] = r_index >> 16;
5790 erel.r_index[1] = r_index >> 8;
5791 erel.r_index[2] = r_index;
5792 erel.r_type[0] =
5793 ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
5794 | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
5796 else
5798 erel.r_index[2] = r_index >> 16;
5799 erel.r_index[1] = r_index >> 8;
5800 erel.r_index[0] = r_index;
5801 erel.r_type[0] =
5802 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
5803 | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
5806 PUT_WORD (finfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend);
5807 #endif /* MY_put_ext_reloc */
5809 rel_ptr = (PTR) &erel;
5812 amt = obj_reloc_entry_size (finfo->output_bfd);
5813 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
5814 || bfd_bwrite (rel_ptr, amt, finfo->output_bfd) != amt)
5815 return FALSE;
5817 *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
5819 /* Assert that the relocs have not run into the symbols, and that n
5820 the text relocs have not run into the data relocs. */
5821 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
5822 && (reloff_ptr != &finfo->treloff
5823 || (*reloff_ptr
5824 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
5826 return TRUE;