2000-03-09 Andreas Jaeger <aj@suse.de>
[binutils.git] / bfd / aoutx.h
blobfa107a7cb942ee5a07ebab635362bfffd43af9bc
1 /* BFD semi-generic back-end for a.out binaries.
2 Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
3 Free Software Foundation, Inc.
4 Written by Cygnus Support.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 SECTION
24 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.
112 /* Some assumptions:
113 * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
114 Doesn't matter what the setting of WP_TEXT is on output, but it'll
115 get set on input.
116 * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
117 * Any BFD with both flags clear is OMAGIC.
118 (Just want to make these explicit, so the conditions tested in this
119 file make sense if you're more familiar with a.out than with BFD.) */
121 #define KEEPIT udata.i
123 #include <ctype.h>
124 #include "bfd.h"
125 #include "sysdep.h"
126 #include "bfdlink.h"
128 #include "libaout.h"
129 #include "libbfd.h"
130 #include "aout/aout64.h"
131 #include "aout/stab_gnu.h"
132 #include "aout/ar.h"
134 static boolean aout_get_external_symbols PARAMS ((bfd *));
135 static boolean translate_from_native_sym_flags
136 PARAMS ((bfd *, aout_symbol_type *));
137 static boolean translate_to_native_sym_flags
138 PARAMS ((bfd *, asymbol *, struct external_nlist *));
139 static void adjust_o_magic PARAMS ((bfd *, struct internal_exec *));
140 static void adjust_z_magic PARAMS ((bfd *, struct internal_exec *));
141 static void adjust_n_magic PARAMS ((bfd *, struct internal_exec *));
144 SUBSECTION
145 Relocations
147 DESCRIPTION
148 The file @file{aoutx.h} provides for both the @emph{standard}
149 and @emph{extended} forms of a.out relocation records.
151 The standard records contain only an
152 address, a symbol index, and a type field. The extended records
153 (used on 29ks and sparcs) also have a full integer for an
154 addend.
157 #ifndef CTOR_TABLE_RELOC_HOWTO
158 #define CTOR_TABLE_RELOC_IDX 2
159 #define CTOR_TABLE_RELOC_HOWTO(BFD) ((obj_reloc_entry_size(BFD) == RELOC_EXT_SIZE \
160 ? howto_table_ext : howto_table_std) \
161 + CTOR_TABLE_RELOC_IDX)
162 #endif
164 #ifndef MY_swap_std_reloc_in
165 #define MY_swap_std_reloc_in NAME(aout,swap_std_reloc_in)
166 #endif
168 #ifndef MY_swap_std_reloc_out
169 #define MY_swap_std_reloc_out NAME(aout,swap_std_reloc_out)
170 #endif
172 #ifndef MY_final_link_relocate
173 #define MY_final_link_relocate _bfd_final_link_relocate
174 #endif
176 #ifndef MY_relocate_contents
177 #define MY_relocate_contents _bfd_relocate_contents
178 #endif
180 #define howto_table_ext NAME(aout,ext_howto_table)
181 #define howto_table_std NAME(aout,std_howto_table)
183 reloc_howto_type howto_table_ext[] =
185 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
186 HOWTO(RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", false, 0,0x000000ff, false),
187 HOWTO(RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", false, 0,0x0000ffff, false),
188 HOWTO(RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", false, 0,0xffffffff, false),
189 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, complain_overflow_signed,0,"DISP8", false, 0,0x000000ff, false),
190 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, complain_overflow_signed,0,"DISP16", false, 0,0x0000ffff, false),
191 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, complain_overflow_signed,0,"DISP32", false, 0,0xffffffff, false),
192 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, complain_overflow_signed,0,"WDISP30", false, 0,0x3fffffff, false),
193 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, complain_overflow_signed,0,"WDISP22", false, 0,0x003fffff, false),
194 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"HI22", false, 0,0x003fffff, false),
195 HOWTO(RELOC_22, 0, 2, 22, false, 0, complain_overflow_bitfield,0,"22", false, 0,0x003fffff, false),
196 HOWTO(RELOC_13, 0, 2, 13, false, 0, complain_overflow_bitfield,0,"13", false, 0,0x00001fff, false),
197 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, complain_overflow_dont,0,"LO10", false, 0,0x000003ff, false),
198 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, complain_overflow_bitfield,0,"SFA_BASE", false, 0,0xffffffff, false),
199 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, complain_overflow_bitfield,0,"SFA_OFF13",false, 0,0xffffffff, false),
200 HOWTO(RELOC_BASE10, 0, 2, 10, false, 0, complain_overflow_dont,0,"BASE10", false, 0,0x000003ff, false),
201 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, complain_overflow_signed,0,"BASE13", false, 0,0x00001fff, false),
202 HOWTO(RELOC_BASE22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"BASE22", false, 0,0x003fffff, false),
203 HOWTO(RELOC_PC10, 0, 2, 10, true, 0, complain_overflow_dont,0,"PC10", false, 0,0x000003ff, true),
204 HOWTO(RELOC_PC22, 10, 2, 22, true, 0, complain_overflow_signed,0,"PC22", false, 0,0x003fffff, true),
205 HOWTO(RELOC_JMP_TBL,2, 2, 30, true, 0, complain_overflow_signed,0,"JMP_TBL", false, 0,0x3fffffff, false),
206 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, complain_overflow_bitfield,0,"SEGOFF16", false, 0,0x00000000, false),
207 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"GLOB_DAT", false, 0,0x00000000, false),
208 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_SLOT", false, 0,0x00000000, false),
209 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false),
210 HOWTO(0, 0, 0, 0, false, 0, complain_overflow_dont, 0, "R_SPARC_NONE", false,0,0x00000000,true),
211 HOWTO(0, 0, 0, 0, false, 0, complain_overflow_dont, 0, "R_SPARC_NONE", false,0,0x00000000,true),
212 #define RELOC_SPARC_REV32 RELOC_WDISP19
213 HOWTO(RELOC_SPARC_REV32, 0, 2, 32, false, 0, complain_overflow_dont,0,"R_SPARC_REV32", false, 0,0xffffffff, false),
216 /* Convert standard reloc records to "arelent" format (incl byte swap). */
218 reloc_howto_type howto_table_std[] = {
219 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
220 HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false),
221 HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false),
222 HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false),
223 HOWTO( 3, 0, 4, 64, false, 0, complain_overflow_bitfield,0,"64", true, 0xdeaddead,0xdeaddead, false),
224 HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, false),
225 HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
226 HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, false),
227 HOWTO( 7, 0, 4, 64, true, 0, complain_overflow_signed, 0,"DISP64", true, 0xfeedface,0xfeedface, false),
228 HOWTO( 8, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"GOT_REL", false, 0,0x00000000, false),
229 HOWTO( 9, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"BASE16", false,0xffffffff,0xffffffff, false),
230 HOWTO(10, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"BASE32", false,0xffffffff,0xffffffff, false),
231 EMPTY_HOWTO (-1),
232 EMPTY_HOWTO (-1),
233 EMPTY_HOWTO (-1),
234 EMPTY_HOWTO (-1),
235 EMPTY_HOWTO (-1),
236 HOWTO(16, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_TABLE", false, 0,0x00000000, false),
237 EMPTY_HOWTO (-1),
238 EMPTY_HOWTO (-1),
239 EMPTY_HOWTO (-1),
240 EMPTY_HOWTO (-1),
241 EMPTY_HOWTO (-1),
242 EMPTY_HOWTO (-1),
243 EMPTY_HOWTO (-1),
244 EMPTY_HOWTO (-1),
245 EMPTY_HOWTO (-1),
246 EMPTY_HOWTO (-1),
247 EMPTY_HOWTO (-1),
248 EMPTY_HOWTO (-1),
249 EMPTY_HOWTO (-1),
250 EMPTY_HOWTO (-1),
251 EMPTY_HOWTO (-1),
252 HOWTO(32, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false),
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 HOWTO(40, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"BASEREL", false, 0,0x00000000, false),
263 #define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0]))
265 reloc_howto_type *
266 NAME(aout,reloc_type_lookup) (abfd,code)
267 bfd *abfd;
268 bfd_reloc_code_real_type code;
270 #define EXT(i,j) case i: return &howto_table_ext[j]
271 #define STD(i,j) case i: return &howto_table_std[j]
272 int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
273 if (code == BFD_RELOC_CTOR)
274 switch (bfd_get_arch_info (abfd)->bits_per_address)
276 case 32:
277 code = BFD_RELOC_32;
278 break;
279 case 64:
280 code = BFD_RELOC_64;
281 break;
283 if (ext)
284 switch (code)
286 EXT (BFD_RELOC_32, 2);
287 EXT (BFD_RELOC_HI22, 8);
288 EXT (BFD_RELOC_LO10, 11);
289 EXT (BFD_RELOC_32_PCREL_S2, 6);
290 EXT (BFD_RELOC_SPARC_WDISP22, 7);
291 EXT (BFD_RELOC_SPARC13, 10);
292 EXT (BFD_RELOC_SPARC_GOT10, 14);
293 EXT (BFD_RELOC_SPARC_BASE13, 15);
294 EXT (BFD_RELOC_SPARC_GOT13, 15);
295 EXT (BFD_RELOC_SPARC_GOT22, 16);
296 EXT (BFD_RELOC_SPARC_PC10, 17);
297 EXT (BFD_RELOC_SPARC_PC22, 18);
298 EXT (BFD_RELOC_SPARC_WPLT30, 19);
299 EXT (BFD_RELOC_SPARC_REV32, 26);
300 default: return (reloc_howto_type *) NULL;
302 else
303 /* std relocs */
304 switch (code)
306 STD (BFD_RELOC_16, 1);
307 STD (BFD_RELOC_32, 2);
308 STD (BFD_RELOC_8_PCREL, 4);
309 STD (BFD_RELOC_16_PCREL, 5);
310 STD (BFD_RELOC_32_PCREL, 6);
311 STD (BFD_RELOC_16_BASEREL, 9);
312 STD (BFD_RELOC_32_BASEREL, 10);
313 default: return (reloc_howto_type *) NULL;
318 SUBSECTION
319 Internal entry points
321 DESCRIPTION
322 @file{aoutx.h} exports several routines for accessing the
323 contents of an a.out file, which are gathered and exported in
324 turn by various format specific files (eg sunos.c).
329 FUNCTION
330 aout_@var{size}_swap_exec_header_in
332 SYNOPSIS
333 void aout_@var{size}_swap_exec_header_in,
334 (bfd *abfd,
335 struct external_exec *raw_bytes,
336 struct internal_exec *execp);
338 DESCRIPTION
339 Swap the information in an executable header @var{raw_bytes} taken
340 from a raw byte stream memory image into the internal exec header
341 structure @var{execp}.
344 #ifndef NAME_swap_exec_header_in
345 void
346 NAME(aout,swap_exec_header_in) (abfd, raw_bytes, execp)
347 bfd *abfd;
348 struct external_exec *raw_bytes;
349 struct internal_exec *execp;
351 struct external_exec *bytes = (struct external_exec *)raw_bytes;
353 /* The internal_exec structure has some fields that are unused in this
354 configuration (IE for i960), so ensure that all such uninitialized
355 fields are zero'd out. There are places where two of these structs
356 are memcmp'd, and thus the contents do matter. */
357 memset ((PTR) execp, 0, sizeof (struct internal_exec));
358 /* Now fill in fields in the execp, from the bytes in the raw data. */
359 execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
360 execp->a_text = GET_WORD (abfd, bytes->e_text);
361 execp->a_data = GET_WORD (abfd, bytes->e_data);
362 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
363 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
364 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
365 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
366 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
368 #define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
369 #endif
372 FUNCTION
373 aout_@var{size}_swap_exec_header_out
375 SYNOPSIS
376 void aout_@var{size}_swap_exec_header_out
377 (bfd *abfd,
378 struct internal_exec *execp,
379 struct external_exec *raw_bytes);
381 DESCRIPTION
382 Swap the information in an internal exec header structure
383 @var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
385 void
386 NAME(aout,swap_exec_header_out) (abfd, execp, raw_bytes)
387 bfd *abfd;
388 struct internal_exec *execp;
389 struct external_exec *raw_bytes;
391 struct external_exec *bytes = (struct external_exec *)raw_bytes;
393 /* Now fill in fields in the raw data, from the fields in the exec struct. */
394 bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
395 PUT_WORD (abfd, execp->a_text , bytes->e_text);
396 PUT_WORD (abfd, execp->a_data , bytes->e_data);
397 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
398 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
399 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
400 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
401 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
404 /* Make all the section for an a.out file. */
406 boolean
407 NAME(aout,make_sections) (abfd)
408 bfd *abfd;
410 if (obj_textsec (abfd) == (asection *) NULL
411 && bfd_make_section (abfd, ".text") == (asection *) NULL)
412 return false;
413 if (obj_datasec (abfd) == (asection *) NULL
414 && bfd_make_section (abfd, ".data") == (asection *) NULL)
415 return false;
416 if (obj_bsssec (abfd) == (asection *) NULL
417 && bfd_make_section (abfd, ".bss") == (asection *) NULL)
418 return false;
419 return true;
423 FUNCTION
424 aout_@var{size}_some_aout_object_p
426 SYNOPSIS
427 const bfd_target *aout_@var{size}_some_aout_object_p
428 (bfd *abfd,
429 const bfd_target *(*callback_to_real_object_p)());
431 DESCRIPTION
432 Some a.out variant thinks that the file open in @var{abfd}
433 checking is an a.out file. Do some more checking, and set up
434 for access if it really is. Call back to the calling
435 environment's "finish up" function just before returning, to
436 handle any last-minute setup.
439 const bfd_target *
440 NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
441 bfd *abfd;
442 struct internal_exec *execp;
443 const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *));
445 struct aout_data_struct *rawptr, *oldrawptr;
446 const bfd_target *result;
448 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
449 if (rawptr == NULL)
450 return 0;
452 oldrawptr = abfd->tdata.aout_data;
453 abfd->tdata.aout_data = rawptr;
455 /* Copy the contents of the old tdata struct.
456 In particular, we want the subformat, since for hpux it was set in
457 hp300hpux.c:swap_exec_header_in and will be used in
458 hp300hpux.c:callback. */
459 if (oldrawptr != NULL)
460 *abfd->tdata.aout_data = *oldrawptr;
462 abfd->tdata.aout_data->a.hdr = &rawptr->e;
463 *(abfd->tdata.aout_data->a.hdr) = *execp; /* Copy in the internal_exec struct */
464 execp = abfd->tdata.aout_data->a.hdr;
466 /* Set the file flags */
467 abfd->flags = BFD_NO_FLAGS;
468 if (execp->a_drsize || execp->a_trsize)
469 abfd->flags |= HAS_RELOC;
470 /* Setting of EXEC_P has been deferred to the bottom of this function */
471 if (execp->a_syms)
472 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
473 if (N_DYNAMIC(*execp))
474 abfd->flags |= DYNAMIC;
476 if (N_MAGIC (*execp) == ZMAGIC)
478 abfd->flags |= D_PAGED | WP_TEXT;
479 adata (abfd).magic = z_magic;
481 else if (N_MAGIC (*execp) == QMAGIC)
483 abfd->flags |= D_PAGED | WP_TEXT;
484 adata (abfd).magic = z_magic;
485 adata (abfd).subformat = q_magic_format;
487 else if (N_MAGIC (*execp) == NMAGIC)
489 abfd->flags |= WP_TEXT;
490 adata (abfd).magic = n_magic;
492 else if (N_MAGIC (*execp) == OMAGIC
493 || N_MAGIC (*execp) == BMAGIC)
494 adata (abfd).magic = o_magic;
495 else
497 /* Should have been checked with N_BADMAG before this routine
498 was called. */
499 abort ();
502 bfd_get_start_address (abfd) = execp->a_entry;
504 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
505 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
507 /* The default relocation entry size is that of traditional V7 Unix. */
508 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
510 /* The default symbol entry size is that of traditional Unix. */
511 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
513 #ifdef USE_MMAP
514 bfd_init_window (&obj_aout_sym_window (abfd));
515 bfd_init_window (&obj_aout_string_window (abfd));
516 #endif
517 obj_aout_external_syms (abfd) = NULL;
518 obj_aout_external_strings (abfd) = NULL;
519 obj_aout_sym_hashes (abfd) = NULL;
521 if (! NAME(aout,make_sections) (abfd))
522 return NULL;
524 obj_datasec (abfd)->_raw_size = execp->a_data;
525 obj_bsssec (abfd)->_raw_size = execp->a_bss;
527 obj_textsec (abfd)->flags =
528 (execp->a_trsize != 0
529 ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
530 : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
531 obj_datasec (abfd)->flags =
532 (execp->a_drsize != 0
533 ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
534 : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
535 obj_bsssec (abfd)->flags = SEC_ALLOC;
537 #ifdef THIS_IS_ONLY_DOCUMENTATION
538 /* The common code can't fill in these things because they depend
539 on either the start address of the text segment, the rounding
540 up of virtual addresses between segments, or the starting file
541 position of the text segment -- all of which varies among different
542 versions of a.out. */
544 /* Call back to the format-dependent code to fill in the rest of the
545 fields and do any further cleanup. Things that should be filled
546 in by the callback: */
548 struct exec *execp = exec_hdr (abfd);
550 obj_textsec (abfd)->size = N_TXTSIZE(*execp);
551 obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp);
552 /* data and bss are already filled in since they're so standard */
554 /* The virtual memory addresses of the sections */
555 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
556 obj_datasec (abfd)->vma = N_DATADDR(*execp);
557 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
559 /* The file offsets of the sections */
560 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
561 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
563 /* The file offsets of the relocation info */
564 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
565 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
567 /* The file offsets of the string table and symbol table. */
568 obj_str_filepos (abfd) = N_STROFF (*execp);
569 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
571 /* Determine the architecture and machine type of the object file. */
572 switch (N_MACHTYPE (*exec_hdr (abfd))) {
573 default:
574 abfd->obj_arch = bfd_arch_obscure;
575 break;
578 adata(abfd)->page_size = TARGET_PAGE_SIZE;
579 adata(abfd)->segment_size = SEGMENT_SIZE;
580 adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
582 return abfd->xvec;
584 /* The architecture is encoded in various ways in various a.out variants,
585 or is not encoded at all in some of them. The relocation size depends
586 on the architecture and the a.out variant. Finally, the return value
587 is the bfd_target vector in use. If an error occurs, return zero and
588 set bfd_error to the appropriate error code.
590 Formats such as b.out, which have additional fields in the a.out
591 header, should cope with them in this callback as well. */
592 #endif /* DOCUMENTATION */
594 result = (*callback_to_real_object_p)(abfd);
596 /* Now that the segment addresses have been worked out, take a better
597 guess at whether the file is executable. If the entry point
598 is within the text segment, assume it is. (This makes files
599 executable even if their entry point address is 0, as long as
600 their text starts at zero.).
602 This test had to be changed to deal with systems where the text segment
603 runs at a different location than the default. The problem is that the
604 entry address can appear to be outside the text segment, thus causing an
605 erroneous conclusion that the file isn't executable.
607 To fix this, we now accept any non-zero entry point as an indication of
608 executability. This will work most of the time, since only the linker
609 sets the entry point, and that is likely to be non-zero for most systems. */
611 if (execp->a_entry != 0
612 || (execp->a_entry >= obj_textsec(abfd)->vma
613 && execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
614 abfd->flags |= EXEC_P;
615 #ifdef STAT_FOR_EXEC
616 else
618 struct stat stat_buf;
620 /* The original heuristic doesn't work in some important cases.
621 The a.out file has no information about the text start
622 address. For files (like kernels) linked to non-standard
623 addresses (ld -Ttext nnn) the entry point may not be between
624 the default text start (obj_textsec(abfd)->vma) and
625 (obj_textsec(abfd)->vma) + text size. This is not just a mach
626 issue. Many kernels are loaded at non standard addresses. */
627 if (abfd->iostream != NULL
628 && (abfd->flags & BFD_IN_MEMORY) == 0
629 && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
630 && ((stat_buf.st_mode & 0111) != 0))
631 abfd->flags |= EXEC_P;
633 #endif /* STAT_FOR_EXEC */
635 if (result)
637 #if 0 /* These should be set correctly anyways. */
638 abfd->sections = obj_textsec (abfd);
639 obj_textsec (abfd)->next = obj_datasec (abfd);
640 obj_datasec (abfd)->next = obj_bsssec (abfd);
641 #endif
643 else
645 free (rawptr);
646 abfd->tdata.aout_data = oldrawptr;
648 return result;
652 FUNCTION
653 aout_@var{size}_mkobject
655 SYNOPSIS
656 boolean aout_@var{size}_mkobject, (bfd *abfd);
658 DESCRIPTION
659 Initialize BFD @var{abfd} for use with a.out files.
662 boolean
663 NAME(aout,mkobject) (abfd)
664 bfd *abfd;
666 struct aout_data_struct *rawptr;
668 bfd_set_error (bfd_error_system_call);
670 /* Use an intermediate variable for clarity */
671 rawptr = (struct aout_data_struct *)bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
673 if (rawptr == NULL)
674 return false;
676 abfd->tdata.aout_data = rawptr;
677 exec_hdr (abfd) = &(rawptr->e);
679 obj_textsec (abfd) = (asection *)NULL;
680 obj_datasec (abfd) = (asection *)NULL;
681 obj_bsssec (abfd) = (asection *)NULL;
683 return true;
688 FUNCTION
689 aout_@var{size}_machine_type
691 SYNOPSIS
692 enum machine_type aout_@var{size}_machine_type
693 (enum bfd_architecture arch,
694 unsigned long machine));
696 DESCRIPTION
697 Keep track of machine architecture and machine type for
698 a.out's. Return the <<machine_type>> for a particular
699 architecture and machine, or <<M_UNKNOWN>> if that exact architecture
700 and machine can't be represented in a.out format.
702 If the architecture is understood, machine type 0 (default)
703 is always understood.
706 enum machine_type
707 NAME(aout,machine_type) (arch, machine, unknown)
708 enum bfd_architecture arch;
709 unsigned long machine;
710 boolean *unknown;
712 enum machine_type arch_flags;
714 arch_flags = M_UNKNOWN;
715 *unknown = true;
717 switch (arch) {
718 case bfd_arch_sparc:
719 if (machine == 0
720 || machine == bfd_mach_sparc
721 || machine == bfd_mach_sparc_sparclite
722 || machine == bfd_mach_sparc_sparclite_le
723 || machine == bfd_mach_sparc_v9)
724 arch_flags = M_SPARC;
725 else if (machine == bfd_mach_sparc_sparclet)
726 arch_flags = M_SPARCLET;
727 break;
729 case bfd_arch_m68k:
730 switch (machine) {
731 case 0: arch_flags = M_68010; break;
732 case bfd_mach_m68000: arch_flags = M_UNKNOWN; *unknown = false; break;
733 case bfd_mach_m68010: arch_flags = M_68010; break;
734 case bfd_mach_m68020: arch_flags = M_68020; break;
735 default: arch_flags = M_UNKNOWN; break;
737 break;
739 case bfd_arch_i386:
740 if (machine == 0) arch_flags = M_386;
741 break;
743 case bfd_arch_a29k:
744 if (machine == 0) arch_flags = M_29K;
745 break;
747 case bfd_arch_arm:
748 if (machine == 0) arch_flags = M_ARM;
749 break;
751 case bfd_arch_mips:
752 switch (machine) {
753 case 0:
754 case bfd_mach_mips3000:
755 case bfd_mach_mips3900:
756 arch_flags = M_MIPS1;
757 break;
758 case bfd_mach_mips6000:
759 arch_flags = M_MIPS2;
760 break;
761 case bfd_mach_mips4000:
762 case bfd_mach_mips4010:
763 case bfd_mach_mips4100:
764 case bfd_mach_mips4300:
765 case bfd_mach_mips4400:
766 case bfd_mach_mips4600:
767 case bfd_mach_mips4650:
768 case bfd_mach_mips8000:
769 case bfd_mach_mips10000:
770 case bfd_mach_mips16:
771 /* FIXME: These should be MIPS3 or MIPS4. */
772 arch_flags = M_MIPS2;
773 break;
774 default:
775 arch_flags = M_UNKNOWN;
776 break;
778 break;
780 case bfd_arch_ns32k:
781 switch (machine) {
782 case 0: arch_flags = M_NS32532; break;
783 case 32032: arch_flags = M_NS32032; break;
784 case 32532: arch_flags = M_NS32532; break;
785 default: arch_flags = M_UNKNOWN; break;
787 break;
789 case bfd_arch_vax:
790 *unknown = false;
791 break;
793 default:
794 arch_flags = M_UNKNOWN;
797 if (arch_flags != M_UNKNOWN)
798 *unknown = false;
800 return arch_flags;
805 FUNCTION
806 aout_@var{size}_set_arch_mach
808 SYNOPSIS
809 boolean aout_@var{size}_set_arch_mach,
810 (bfd *,
811 enum bfd_architecture arch,
812 unsigned long machine));
814 DESCRIPTION
815 Set the architecture and the machine of the BFD @var{abfd} to the
816 values @var{arch} and @var{machine}. Verify that @var{abfd}'s format
817 can support the architecture required.
820 boolean
821 NAME(aout,set_arch_mach) (abfd, arch, machine)
822 bfd *abfd;
823 enum bfd_architecture arch;
824 unsigned long machine;
826 if (! bfd_default_set_arch_mach (abfd, arch, machine))
827 return false;
829 if (arch != bfd_arch_unknown)
831 boolean unknown;
833 NAME(aout,machine_type) (arch, machine, &unknown);
834 if (unknown)
835 return false;
838 /* Determine the size of a relocation entry */
839 switch (arch) {
840 case bfd_arch_sparc:
841 case bfd_arch_a29k:
842 case bfd_arch_mips:
843 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
844 break;
845 default:
846 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
847 break;
850 return (*aout_backend_info(abfd)->set_sizes) (abfd);
853 static void
854 adjust_o_magic (abfd, execp)
855 bfd *abfd;
856 struct internal_exec *execp;
858 file_ptr pos = adata (abfd).exec_bytes_size;
859 bfd_vma vma = 0;
860 int pad = 0;
862 /* Text. */
863 obj_textsec(abfd)->filepos = pos;
864 if (!obj_textsec(abfd)->user_set_vma)
865 obj_textsec(abfd)->vma = vma;
866 else
867 vma = obj_textsec(abfd)->vma;
869 pos += obj_textsec(abfd)->_raw_size;
870 vma += obj_textsec(abfd)->_raw_size;
872 /* Data. */
873 if (!obj_datasec(abfd)->user_set_vma)
875 #if 0 /* ?? Does alignment in the file image really matter? */
876 pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
877 #endif
878 obj_textsec(abfd)->_raw_size += pad;
879 pos += pad;
880 vma += pad;
881 obj_datasec(abfd)->vma = vma;
883 else
884 vma = obj_datasec(abfd)->vma;
885 obj_datasec(abfd)->filepos = pos;
886 pos += obj_datasec(abfd)->_raw_size;
887 vma += obj_datasec(abfd)->_raw_size;
889 /* BSS. */
890 if (!obj_bsssec(abfd)->user_set_vma)
892 #if 0
893 pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
894 #endif
895 obj_datasec(abfd)->_raw_size += pad;
896 pos += pad;
897 vma += pad;
898 obj_bsssec(abfd)->vma = vma;
900 else
902 /* The VMA of the .bss section is set by the the VMA of the
903 .data section plus the size of the .data section. We may
904 need to add padding bytes to make this true. */
905 pad = obj_bsssec (abfd)->vma - vma;
906 if (pad > 0)
908 obj_datasec (abfd)->_raw_size += pad;
909 pos += pad;
912 obj_bsssec(abfd)->filepos = pos;
914 /* Fix up the exec header. */
915 execp->a_text = obj_textsec(abfd)->_raw_size;
916 execp->a_data = obj_datasec(abfd)->_raw_size;
917 execp->a_bss = obj_bsssec(abfd)->_raw_size;
918 N_SET_MAGIC (*execp, OMAGIC);
921 static void
922 adjust_z_magic (abfd, execp)
923 bfd *abfd;
924 struct internal_exec *execp;
926 bfd_size_type data_pad, text_pad;
927 file_ptr text_end;
928 CONST struct aout_backend_data *abdp;
929 int ztih; /* Nonzero if text includes exec header. */
931 abdp = aout_backend_info (abfd);
933 /* Text. */
934 ztih = (abdp != NULL
935 && (abdp->text_includes_header
936 || obj_aout_subformat (abfd) == q_magic_format));
937 obj_textsec(abfd)->filepos = (ztih
938 ? adata(abfd).exec_bytes_size
939 : adata(abfd).zmagic_disk_block_size);
940 if (! obj_textsec(abfd)->user_set_vma)
942 /* ?? Do we really need to check for relocs here? */
943 obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
945 : (ztih
946 ? (abdp->default_text_vma
947 + adata(abfd).exec_bytes_size)
948 : abdp->default_text_vma));
949 text_pad = 0;
951 else
953 /* The .text section is being loaded at an unusual address. We
954 may need to pad it such that the .data section starts at a page
955 boundary. */
956 if (ztih)
957 text_pad = ((obj_textsec (abfd)->filepos - obj_textsec (abfd)->vma)
958 & (adata (abfd).page_size - 1));
959 else
960 text_pad = ((- obj_textsec (abfd)->vma)
961 & (adata (abfd).page_size - 1));
964 /* Find start of data. */
965 if (ztih)
967 text_end = obj_textsec (abfd)->filepos + obj_textsec (abfd)->_raw_size;
968 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
970 else
972 /* Note that if page_size == zmagic_disk_block_size, then
973 filepos == page_size, and this case is the same as the ztih
974 case. */
975 text_end = obj_textsec (abfd)->_raw_size;
976 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
977 text_end += obj_textsec (abfd)->filepos;
979 obj_textsec(abfd)->_raw_size += text_pad;
980 text_end += text_pad;
982 /* Data. */
983 if (!obj_datasec(abfd)->user_set_vma)
985 bfd_vma vma;
986 vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size;
987 obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
989 if (abdp && abdp->zmagic_mapped_contiguous)
991 text_pad = (obj_datasec(abfd)->vma
992 - obj_textsec(abfd)->vma
993 - obj_textsec(abfd)->_raw_size);
994 obj_textsec(abfd)->_raw_size += text_pad;
996 obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos
997 + obj_textsec(abfd)->_raw_size);
999 /* Fix up exec header while we're at it. */
1000 execp->a_text = obj_textsec(abfd)->_raw_size;
1001 if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
1002 execp->a_text += adata(abfd).exec_bytes_size;
1003 if (obj_aout_subformat (abfd) == q_magic_format)
1004 N_SET_MAGIC (*execp, QMAGIC);
1005 else
1006 N_SET_MAGIC (*execp, ZMAGIC);
1008 /* Spec says data section should be rounded up to page boundary. */
1009 obj_datasec(abfd)->_raw_size
1010 = align_power (obj_datasec(abfd)->_raw_size,
1011 obj_bsssec(abfd)->alignment_power);
1012 execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size,
1013 adata(abfd).page_size);
1014 data_pad = execp->a_data - obj_datasec(abfd)->_raw_size;
1016 /* BSS. */
1017 if (!obj_bsssec(abfd)->user_set_vma)
1018 obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
1019 + obj_datasec(abfd)->_raw_size);
1020 /* If the BSS immediately follows the data section and extra space
1021 in the page is left after the data section, fudge data
1022 in the header so that the bss section looks smaller by that
1023 amount. We'll start the bss section there, and lie to the OS.
1024 (Note that a linker script, as well as the above assignment,
1025 could have explicitly set the BSS vma to immediately follow
1026 the data section.) */
1027 if (align_power (obj_bsssec(abfd)->vma, obj_bsssec(abfd)->alignment_power)
1028 == obj_datasec(abfd)->vma + obj_datasec(abfd)->_raw_size)
1029 execp->a_bss = (data_pad > obj_bsssec(abfd)->_raw_size) ? 0 :
1030 obj_bsssec(abfd)->_raw_size - data_pad;
1031 else
1032 execp->a_bss = obj_bsssec(abfd)->_raw_size;
1035 static void
1036 adjust_n_magic (abfd, execp)
1037 bfd *abfd;
1038 struct internal_exec *execp;
1040 file_ptr pos = adata(abfd).exec_bytes_size;
1041 bfd_vma vma = 0;
1042 int pad;
1044 /* Text. */
1045 obj_textsec(abfd)->filepos = pos;
1046 if (!obj_textsec(abfd)->user_set_vma)
1047 obj_textsec(abfd)->vma = vma;
1048 else
1049 vma = obj_textsec(abfd)->vma;
1050 pos += obj_textsec(abfd)->_raw_size;
1051 vma += obj_textsec(abfd)->_raw_size;
1053 /* Data. */
1054 obj_datasec(abfd)->filepos = pos;
1055 if (!obj_datasec(abfd)->user_set_vma)
1056 obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
1057 vma = obj_datasec(abfd)->vma;
1059 /* Since BSS follows data immediately, see if it needs alignment. */
1060 vma += obj_datasec(abfd)->_raw_size;
1061 pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
1062 obj_datasec(abfd)->_raw_size += pad;
1063 pos += obj_datasec(abfd)->_raw_size;
1065 /* BSS. */
1066 if (!obj_bsssec(abfd)->user_set_vma)
1067 obj_bsssec(abfd)->vma = vma;
1068 else
1069 vma = obj_bsssec(abfd)->vma;
1071 /* Fix up exec header. */
1072 execp->a_text = obj_textsec(abfd)->_raw_size;
1073 execp->a_data = obj_datasec(abfd)->_raw_size;
1074 execp->a_bss = obj_bsssec(abfd)->_raw_size;
1075 N_SET_MAGIC (*execp, NMAGIC);
1078 boolean
1079 NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end)
1080 bfd *abfd;
1081 bfd_size_type *text_size;
1082 file_ptr *text_end ATTRIBUTE_UNUSED;
1084 struct internal_exec *execp = exec_hdr (abfd);
1086 if (! NAME(aout,make_sections) (abfd))
1087 return false;
1089 if (adata(abfd).magic != undecided_magic)
1090 return true;
1092 obj_textsec(abfd)->_raw_size =
1093 align_power(obj_textsec(abfd)->_raw_size,
1094 obj_textsec(abfd)->alignment_power);
1096 *text_size = obj_textsec (abfd)->_raw_size;
1097 /* Rule (heuristic) for when to pad to a new page. Note that there
1098 are (at least) two ways demand-paged (ZMAGIC) files have been
1099 handled. Most Berkeley-based systems start the text segment at
1100 (TARGET_PAGE_SIZE). However, newer versions of SUNOS start the text
1101 segment right after the exec header; the latter is counted in the
1102 text segment size, and is paged in by the kernel with the rest of
1103 the text. */
1105 /* This perhaps isn't the right way to do this, but made it simpler for me
1106 to understand enough to implement it. Better would probably be to go
1107 right from BFD flags to alignment/positioning characteristics. But the
1108 old code was sloppy enough about handling the flags, and had enough
1109 other magic, that it was a little hard for me to understand. I think
1110 I understand it better now, but I haven't time to do the cleanup this
1111 minute. */
1113 if (abfd->flags & D_PAGED)
1114 /* Whether or not WP_TEXT is set -- let D_PAGED override. */
1115 adata(abfd).magic = z_magic;
1116 else if (abfd->flags & WP_TEXT)
1117 adata(abfd).magic = n_magic;
1118 else
1119 adata(abfd).magic = o_magic;
1121 #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
1122 #if __GNUC__ >= 2
1123 fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
1124 ({ char *str;
1125 switch (adata(abfd).magic) {
1126 case n_magic: str = "NMAGIC"; break;
1127 case o_magic: str = "OMAGIC"; break;
1128 case z_magic: str = "ZMAGIC"; break;
1129 default: abort ();
1131 str;
1133 obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size,
1134 obj_textsec(abfd)->alignment_power,
1135 obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size,
1136 obj_datasec(abfd)->alignment_power,
1137 obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size,
1138 obj_bsssec(abfd)->alignment_power);
1139 #endif
1140 #endif
1142 switch (adata(abfd).magic)
1144 case o_magic:
1145 adjust_o_magic (abfd, execp);
1146 break;
1147 case z_magic:
1148 adjust_z_magic (abfd, execp);
1149 break;
1150 case n_magic:
1151 adjust_n_magic (abfd, execp);
1152 break;
1153 default:
1154 abort ();
1157 #ifdef BFD_AOUT_DEBUG
1158 fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
1159 obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size,
1160 obj_textsec(abfd)->filepos,
1161 obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size,
1162 obj_datasec(abfd)->filepos,
1163 obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size);
1164 #endif
1166 return true;
1170 FUNCTION
1171 aout_@var{size}_new_section_hook
1173 SYNOPSIS
1174 boolean aout_@var{size}_new_section_hook,
1175 (bfd *abfd,
1176 asection *newsect));
1178 DESCRIPTION
1179 Called by the BFD in response to a @code{bfd_make_section}
1180 request.
1182 boolean
1183 NAME(aout,new_section_hook) (abfd, newsect)
1184 bfd *abfd;
1185 asection *newsect;
1187 /* align to double at least */
1188 newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
1191 if (bfd_get_format (abfd) == bfd_object)
1193 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
1194 obj_textsec(abfd)= newsect;
1195 newsect->target_index = N_TEXT;
1196 return true;
1199 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
1200 obj_datasec(abfd) = newsect;
1201 newsect->target_index = N_DATA;
1202 return true;
1205 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
1206 obj_bsssec(abfd) = newsect;
1207 newsect->target_index = N_BSS;
1208 return true;
1213 /* We allow more than three sections internally */
1214 return true;
1217 boolean
1218 NAME(aout,set_section_contents) (abfd, section, location, offset, count)
1219 bfd *abfd;
1220 sec_ptr section;
1221 PTR location;
1222 file_ptr offset;
1223 bfd_size_type count;
1225 file_ptr text_end;
1226 bfd_size_type text_size;
1228 if (! abfd->output_has_begun)
1230 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
1231 return false;
1234 if (section == obj_bsssec (abfd))
1236 bfd_set_error (bfd_error_no_contents);
1237 return false;
1240 if (section != obj_textsec (abfd)
1241 && section != obj_datasec (abfd))
1243 (*_bfd_error_handler)
1244 (_("%s: can not represent section `%s' in a.out object file format"),
1245 bfd_get_filename (abfd), bfd_get_section_name (abfd, section));
1246 bfd_set_error (bfd_error_nonrepresentable_section);
1247 return false;
1250 if (count != 0)
1252 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
1253 || bfd_write (location, 1, count, abfd) != count)
1254 return false;
1257 return true;
1260 /* Read the external symbols from an a.out file. */
1262 static boolean
1263 aout_get_external_symbols (abfd)
1264 bfd *abfd;
1266 if (obj_aout_external_syms (abfd) == (struct external_nlist *) NULL)
1268 bfd_size_type count;
1269 struct external_nlist *syms;
1271 count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
1273 #ifdef USE_MMAP
1274 if (bfd_get_file_window (abfd,
1275 obj_sym_filepos (abfd), exec_hdr (abfd)->a_syms,
1276 &obj_aout_sym_window (abfd), true) == false)
1277 return false;
1278 syms = (struct external_nlist *) obj_aout_sym_window (abfd).data;
1279 #else
1280 /* We allocate using malloc to make the values easy to free
1281 later on. If we put them on the objalloc it might not be
1282 possible to free them. */
1283 syms = ((struct external_nlist *)
1284 bfd_malloc ((size_t) count * EXTERNAL_NLIST_SIZE));
1285 if (syms == (struct external_nlist *) NULL && count != 0)
1286 return false;
1288 if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
1289 || (bfd_read (syms, 1, exec_hdr (abfd)->a_syms, abfd)
1290 != exec_hdr (abfd)->a_syms))
1292 free (syms);
1293 return false;
1295 #endif
1297 obj_aout_external_syms (abfd) = syms;
1298 obj_aout_external_sym_count (abfd) = count;
1301 if (obj_aout_external_strings (abfd) == NULL
1302 && exec_hdr (abfd)->a_syms != 0)
1304 unsigned char string_chars[BYTES_IN_WORD];
1305 bfd_size_type stringsize;
1306 char *strings;
1308 /* Get the size of the strings. */
1309 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
1310 || (bfd_read ((PTR) string_chars, BYTES_IN_WORD, 1, abfd)
1311 != BYTES_IN_WORD))
1312 return false;
1313 stringsize = GET_WORD (abfd, string_chars);
1315 #ifdef USE_MMAP
1316 if (bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
1317 &obj_aout_string_window (abfd), true) == false)
1318 return false;
1319 strings = (char *) obj_aout_string_window (abfd).data;
1320 #else
1321 strings = (char *) bfd_malloc ((size_t) stringsize + 1);
1322 if (strings == NULL)
1323 return false;
1325 /* Skip space for the string count in the buffer for convenience
1326 when using indexes. */
1327 if (bfd_read (strings + BYTES_IN_WORD, 1, stringsize - BYTES_IN_WORD,
1328 abfd)
1329 != stringsize - BYTES_IN_WORD)
1331 free (strings);
1332 return false;
1334 #endif
1336 /* Ensure that a zero index yields an empty string. */
1337 strings[0] = '\0';
1339 strings[stringsize - 1] = 0;
1341 obj_aout_external_strings (abfd) = strings;
1342 obj_aout_external_string_size (abfd) = stringsize;
1345 return true;
1348 /* Translate an a.out symbol into a BFD symbol. The desc, other, type
1349 and symbol->value fields of CACHE_PTR will be set from the a.out
1350 nlist structure. This function is responsible for setting
1351 symbol->flags and symbol->section, and adjusting symbol->value. */
1353 static boolean
1354 translate_from_native_sym_flags (abfd, cache_ptr)
1355 bfd *abfd;
1356 aout_symbol_type *cache_ptr;
1358 flagword visible;
1360 if ((cache_ptr->type & N_STAB) != 0
1361 || cache_ptr->type == N_FN)
1363 asection *sec;
1365 /* This is a debugging symbol. */
1367 cache_ptr->symbol.flags = BSF_DEBUGGING;
1369 /* Work out the symbol section. */
1370 switch (cache_ptr->type & N_TYPE)
1372 case N_TEXT:
1373 case N_FN:
1374 sec = obj_textsec (abfd);
1375 break;
1376 case N_DATA:
1377 sec = obj_datasec (abfd);
1378 break;
1379 case N_BSS:
1380 sec = obj_bsssec (abfd);
1381 break;
1382 default:
1383 case N_ABS:
1384 sec = bfd_abs_section_ptr;
1385 break;
1388 cache_ptr->symbol.section = sec;
1389 cache_ptr->symbol.value -= sec->vma;
1391 return true;
1394 /* Get the default visibility. This does not apply to all types, so
1395 we just hold it in a local variable to use if wanted. */
1396 if ((cache_ptr->type & N_EXT) == 0)
1397 visible = BSF_LOCAL;
1398 else
1399 visible = BSF_GLOBAL;
1401 switch (cache_ptr->type)
1403 default:
1404 case N_ABS: case N_ABS | N_EXT:
1405 cache_ptr->symbol.section = bfd_abs_section_ptr;
1406 cache_ptr->symbol.flags = visible;
1407 break;
1409 case N_UNDF | N_EXT:
1410 if (cache_ptr->symbol.value != 0)
1412 /* This is a common symbol. */
1413 cache_ptr->symbol.flags = BSF_GLOBAL;
1414 cache_ptr->symbol.section = bfd_com_section_ptr;
1416 else
1418 cache_ptr->symbol.flags = 0;
1419 cache_ptr->symbol.section = bfd_und_section_ptr;
1421 break;
1423 case N_TEXT: case N_TEXT | N_EXT:
1424 cache_ptr->symbol.section = obj_textsec (abfd);
1425 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1426 cache_ptr->symbol.flags = visible;
1427 break;
1429 /* N_SETV symbols used to represent set vectors placed in the
1430 data section. They are no longer generated. Theoretically,
1431 it was possible to extract the entries and combine them with
1432 new ones, although I don't know if that was ever actually
1433 done. Unless that feature is restored, treat them as data
1434 symbols. */
1435 case N_SETV: case N_SETV | N_EXT:
1436 case N_DATA: case N_DATA | N_EXT:
1437 cache_ptr->symbol.section = obj_datasec (abfd);
1438 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1439 cache_ptr->symbol.flags = visible;
1440 break;
1442 case N_BSS: case N_BSS | N_EXT:
1443 cache_ptr->symbol.section = obj_bsssec (abfd);
1444 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1445 cache_ptr->symbol.flags = visible;
1446 break;
1448 case N_SETA: case N_SETA | N_EXT:
1449 case N_SETT: case N_SETT | N_EXT:
1450 case N_SETD: case N_SETD | N_EXT:
1451 case N_SETB: case N_SETB | N_EXT:
1453 /* This code is no longer needed. It used to be used to make
1454 the linker handle set symbols, but they are now handled in
1455 the add_symbols routine instead. */
1456 #if 0
1457 asection *section;
1458 arelent_chain *reloc;
1459 asection *into_section;
1461 /* This is a set symbol. The name of the symbol is the name
1462 of the set (e.g., __CTOR_LIST__). The value of the symbol
1463 is the value to add to the set. We create a section with
1464 the same name as the symbol, and add a reloc to insert the
1465 appropriate value into the section.
1467 This action is actually obsolete; it used to make the
1468 linker do the right thing, but the linker no longer uses
1469 this function. */
1471 section = bfd_get_section_by_name (abfd, cache_ptr->symbol.name);
1472 if (section == NULL)
1474 char *copy;
1476 copy = bfd_alloc (abfd, strlen (cache_ptr->symbol.name) + 1);
1477 if (copy == NULL)
1478 return false;
1480 strcpy (copy, cache_ptr->symbol.name);
1481 section = bfd_make_section (abfd, copy);
1482 if (section == NULL)
1483 return false;
1486 reloc = (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain));
1487 if (reloc == NULL)
1488 return false;
1490 /* Build a relocation entry for the constructor. */
1491 switch (cache_ptr->type & N_TYPE)
1493 case N_SETA:
1494 into_section = bfd_abs_section_ptr;
1495 cache_ptr->type = N_ABS;
1496 break;
1497 case N_SETT:
1498 into_section = obj_textsec (abfd);
1499 cache_ptr->type = N_TEXT;
1500 break;
1501 case N_SETD:
1502 into_section = obj_datasec (abfd);
1503 cache_ptr->type = N_DATA;
1504 break;
1505 case N_SETB:
1506 into_section = obj_bsssec (abfd);
1507 cache_ptr->type = N_BSS;
1508 break;
1511 /* Build a relocation pointing into the constructor section
1512 pointing at the symbol in the set vector specified. */
1513 reloc->relent.addend = cache_ptr->symbol.value;
1514 cache_ptr->symbol.section = into_section;
1515 reloc->relent.sym_ptr_ptr = into_section->symbol_ptr_ptr;
1517 /* We modify the symbol to belong to a section depending upon
1518 the name of the symbol, and add to the size of the section
1519 to contain a pointer to the symbol. Build a reloc entry to
1520 relocate to this symbol attached to this section. */
1521 section->flags = SEC_CONSTRUCTOR | SEC_RELOC;
1523 section->reloc_count++;
1524 section->alignment_power = 2;
1526 reloc->next = section->constructor_chain;
1527 section->constructor_chain = reloc;
1528 reloc->relent.address = section->_raw_size;
1529 section->_raw_size += BYTES_IN_WORD;
1531 reloc->relent.howto = CTOR_TABLE_RELOC_HOWTO(abfd);
1533 #endif /* 0 */
1535 switch (cache_ptr->type & N_TYPE)
1537 case N_SETA:
1538 cache_ptr->symbol.section = bfd_abs_section_ptr;
1539 break;
1540 case N_SETT:
1541 cache_ptr->symbol.section = obj_textsec (abfd);
1542 break;
1543 case N_SETD:
1544 cache_ptr->symbol.section = obj_datasec (abfd);
1545 break;
1546 case N_SETB:
1547 cache_ptr->symbol.section = obj_bsssec (abfd);
1548 break;
1551 cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
1553 break;
1555 case N_WARNING:
1556 /* This symbol is the text of a warning message. The next
1557 symbol is the symbol to associate the warning with. If a
1558 reference is made to that symbol, a warning is issued. */
1559 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
1560 cache_ptr->symbol.section = bfd_abs_section_ptr;
1561 break;
1563 case N_INDR: case N_INDR | N_EXT:
1564 /* An indirect symbol. This consists of two symbols in a row.
1565 The first symbol is the name of the indirection. The second
1566 symbol is the name of the target. A reference to the first
1567 symbol becomes a reference to the second. */
1568 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible;
1569 cache_ptr->symbol.section = bfd_ind_section_ptr;
1570 break;
1572 case N_WEAKU:
1573 cache_ptr->symbol.section = bfd_und_section_ptr;
1574 cache_ptr->symbol.flags = BSF_WEAK;
1575 break;
1577 case N_WEAKA:
1578 cache_ptr->symbol.section = bfd_abs_section_ptr;
1579 cache_ptr->symbol.flags = BSF_WEAK;
1580 break;
1582 case N_WEAKT:
1583 cache_ptr->symbol.section = obj_textsec (abfd);
1584 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1585 cache_ptr->symbol.flags = BSF_WEAK;
1586 break;
1588 case N_WEAKD:
1589 cache_ptr->symbol.section = obj_datasec (abfd);
1590 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1591 cache_ptr->symbol.flags = BSF_WEAK;
1592 break;
1594 case N_WEAKB:
1595 cache_ptr->symbol.section = obj_bsssec (abfd);
1596 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1597 cache_ptr->symbol.flags = BSF_WEAK;
1598 break;
1601 return true;
1604 /* Set the fields of SYM_POINTER according to CACHE_PTR. */
1606 static boolean
1607 translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
1608 bfd *abfd;
1609 asymbol *cache_ptr;
1610 struct external_nlist *sym_pointer;
1612 bfd_vma value = cache_ptr->value;
1613 asection *sec;
1614 bfd_vma off;
1616 /* Mask out any existing type bits in case copying from one section
1617 to another. */
1618 sym_pointer->e_type[0] &= ~N_TYPE;
1620 sec = bfd_get_section (cache_ptr);
1621 off = 0;
1623 if (sec == NULL)
1625 /* This case occurs, e.g., for the *DEBUG* section of a COFF
1626 file. */
1627 (*_bfd_error_handler)
1628 (_("%s: can not represent section for symbol `%s' in a.out object file format"),
1629 bfd_get_filename (abfd),
1630 cache_ptr->name != NULL ? cache_ptr->name : _("*unknown*"));
1631 bfd_set_error (bfd_error_nonrepresentable_section);
1632 return false;
1635 if (sec->output_section != NULL)
1637 off = sec->output_offset;
1638 sec = sec->output_section;
1641 if (bfd_is_abs_section (sec))
1642 sym_pointer->e_type[0] |= N_ABS;
1643 else if (sec == obj_textsec (abfd))
1644 sym_pointer->e_type[0] |= N_TEXT;
1645 else if (sec == obj_datasec (abfd))
1646 sym_pointer->e_type[0] |= N_DATA;
1647 else if (sec == obj_bsssec (abfd))
1648 sym_pointer->e_type[0] |= N_BSS;
1649 else if (bfd_is_und_section (sec))
1650 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1651 else if (bfd_is_ind_section (sec))
1652 sym_pointer->e_type[0] = N_INDR;
1653 else if (bfd_is_com_section (sec))
1654 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1655 else
1657 (*_bfd_error_handler)
1658 (_("%s: can not represent section `%s' in a.out object file format"),
1659 bfd_get_filename (abfd), bfd_get_section_name (abfd, sec));
1660 bfd_set_error (bfd_error_nonrepresentable_section);
1661 return false;
1664 /* Turn the symbol from section relative to absolute again */
1665 value += sec->vma + off;
1667 if ((cache_ptr->flags & BSF_WARNING) != 0)
1668 sym_pointer->e_type[0] = N_WARNING;
1670 if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
1671 sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
1672 else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
1673 sym_pointer->e_type[0] |= N_EXT;
1675 if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0)
1677 int type = ((aout_symbol_type *) cache_ptr)->type;
1678 switch (type)
1680 case N_ABS: type = N_SETA; break;
1681 case N_TEXT: type = N_SETT; break;
1682 case N_DATA: type = N_SETD; break;
1683 case N_BSS: type = N_SETB; break;
1685 sym_pointer->e_type[0] = type;
1688 if ((cache_ptr->flags & BSF_WEAK) != 0)
1690 int type;
1692 switch (sym_pointer->e_type[0] & N_TYPE)
1694 default:
1695 case N_ABS: type = N_WEAKA; break;
1696 case N_TEXT: type = N_WEAKT; break;
1697 case N_DATA: type = N_WEAKD; break;
1698 case N_BSS: type = N_WEAKB; break;
1699 case N_UNDF: type = N_WEAKU; break;
1701 sym_pointer->e_type[0] = type;
1704 PUT_WORD(abfd, value, sym_pointer->e_value);
1706 return true;
1709 /* Native-level interface to symbols. */
1711 asymbol *
1712 NAME(aout,make_empty_symbol) (abfd)
1713 bfd *abfd;
1715 aout_symbol_type *new =
1716 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1717 if (!new)
1718 return NULL;
1719 new->symbol.the_bfd = abfd;
1721 return &new->symbol;
1724 /* Translate a set of internal symbols into external symbols. */
1726 boolean
1727 NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic)
1728 bfd *abfd;
1729 aout_symbol_type *in;
1730 struct external_nlist *ext;
1731 bfd_size_type count;
1732 char *str;
1733 bfd_size_type strsize;
1734 boolean dynamic;
1736 struct external_nlist *ext_end;
1738 ext_end = ext + count;
1739 for (; ext < ext_end; ext++, in++)
1741 bfd_vma x;
1743 x = GET_WORD (abfd, ext->e_strx);
1744 in->symbol.the_bfd = abfd;
1746 /* For the normal symbols, the zero index points at the number
1747 of bytes in the string table but is to be interpreted as the
1748 null string. For the dynamic symbols, the number of bytes in
1749 the string table is stored in the __DYNAMIC structure and the
1750 zero index points at an actual string. */
1751 if (x == 0 && ! dynamic)
1752 in->symbol.name = "";
1753 else if (x < strsize)
1754 in->symbol.name = str + x;
1755 else
1756 return false;
1758 in->symbol.value = GET_SWORD (abfd, ext->e_value);
1759 in->desc = bfd_h_get_16 (abfd, ext->e_desc);
1760 in->other = bfd_h_get_8 (abfd, ext->e_other);
1761 in->type = bfd_h_get_8 (abfd, ext->e_type);
1762 in->symbol.udata.p = NULL;
1764 if (! translate_from_native_sym_flags (abfd, in))
1765 return false;
1767 if (dynamic)
1768 in->symbol.flags |= BSF_DYNAMIC;
1771 return true;
1774 /* We read the symbols into a buffer, which is discarded when this
1775 function exits. We read the strings into a buffer large enough to
1776 hold them all plus all the cached symbol entries. */
1778 boolean
1779 NAME(aout,slurp_symbol_table) (abfd)
1780 bfd *abfd;
1782 struct external_nlist *old_external_syms;
1783 aout_symbol_type *cached;
1784 size_t cached_size;
1786 /* If there's no work to be done, don't do any */
1787 if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
1788 return true;
1790 old_external_syms = obj_aout_external_syms (abfd);
1792 if (! aout_get_external_symbols (abfd))
1793 return false;
1795 cached_size = (obj_aout_external_sym_count (abfd)
1796 * sizeof (aout_symbol_type));
1797 cached = (aout_symbol_type *) bfd_malloc (cached_size);
1798 if (cached == NULL && cached_size != 0)
1799 return false;
1800 if (cached_size != 0)
1801 memset (cached, 0, cached_size);
1803 /* Convert from external symbol information to internal. */
1804 if (! (NAME(aout,translate_symbol_table)
1805 (abfd, cached,
1806 obj_aout_external_syms (abfd),
1807 obj_aout_external_sym_count (abfd),
1808 obj_aout_external_strings (abfd),
1809 obj_aout_external_string_size (abfd),
1810 false)))
1812 free (cached);
1813 return false;
1816 bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
1818 obj_aout_symbols (abfd) = cached;
1820 /* It is very likely that anybody who calls this function will not
1821 want the external symbol information, so if it was allocated
1822 because of our call to aout_get_external_symbols, we free it up
1823 right away to save space. */
1824 if (old_external_syms == (struct external_nlist *) NULL
1825 && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
1827 #ifdef USE_MMAP
1828 bfd_free_window (&obj_aout_sym_window (abfd));
1829 #else
1830 free (obj_aout_external_syms (abfd));
1831 #endif
1832 obj_aout_external_syms (abfd) = NULL;
1835 return true;
1838 /* We use a hash table when writing out symbols so that we only write
1839 out a particular string once. This helps particularly when the
1840 linker writes out stabs debugging entries, because each different
1841 contributing object file tends to have many duplicate stabs
1842 strings.
1844 This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
1845 if BFD_TRADITIONAL_FORMAT is set. */
1847 static bfd_size_type add_to_stringtab
1848 PARAMS ((bfd *, struct bfd_strtab_hash *, const char *, boolean));
1849 static boolean emit_stringtab PARAMS ((bfd *, struct bfd_strtab_hash *));
1851 /* Get the index of a string in a strtab, adding it if it is not
1852 already present. */
1854 static INLINE bfd_size_type
1855 add_to_stringtab (abfd, tab, str, copy)
1856 bfd *abfd;
1857 struct bfd_strtab_hash *tab;
1858 const char *str;
1859 boolean copy;
1861 boolean hash;
1862 bfd_size_type index;
1864 /* An index of 0 always means the empty string. */
1865 if (str == 0 || *str == '\0')
1866 return 0;
1868 /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
1869 doesn't understand a hashed string table. */
1870 hash = true;
1871 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
1872 hash = false;
1874 index = _bfd_stringtab_add (tab, str, hash, copy);
1876 if (index != (bfd_size_type) -1)
1878 /* Add BYTES_IN_WORD to the return value to account for the
1879 space taken up by the string table size. */
1880 index += BYTES_IN_WORD;
1883 return index;
1886 /* Write out a strtab. ABFD is already at the right location in the
1887 file. */
1889 static boolean
1890 emit_stringtab (abfd, tab)
1891 register bfd *abfd;
1892 struct bfd_strtab_hash *tab;
1894 bfd_byte buffer[BYTES_IN_WORD];
1896 /* The string table starts with the size. */
1897 PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
1898 if (bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
1899 return false;
1901 return _bfd_stringtab_emit (abfd, tab);
1904 boolean
1905 NAME(aout,write_syms) (abfd)
1906 bfd *abfd;
1908 unsigned int count ;
1909 asymbol **generic = bfd_get_outsymbols (abfd);
1910 struct bfd_strtab_hash *strtab;
1912 strtab = _bfd_stringtab_init ();
1913 if (strtab == NULL)
1914 return false;
1916 for (count = 0; count < bfd_get_symcount (abfd); count++)
1918 asymbol *g = generic[count];
1919 bfd_size_type indx;
1920 struct external_nlist nsp;
1922 indx = add_to_stringtab (abfd, strtab, g->name, false);
1923 if (indx == (bfd_size_type) -1)
1924 goto error_return;
1925 PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
1927 if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
1929 bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc);
1930 bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other);
1931 bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type);
1933 else
1935 bfd_h_put_16(abfd,0, nsp.e_desc);
1936 bfd_h_put_8(abfd, 0, nsp.e_other);
1937 bfd_h_put_8(abfd, 0, nsp.e_type);
1940 if (! translate_to_native_sym_flags (abfd, g, &nsp))
1941 goto error_return;
1943 if (bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd)
1944 != EXTERNAL_NLIST_SIZE)
1945 goto error_return;
1947 /* NB: `KEEPIT' currently overlays `udata.p', so set this only
1948 here, at the end. */
1949 g->KEEPIT = count;
1952 if (! emit_stringtab (abfd, strtab))
1953 goto error_return;
1955 _bfd_stringtab_free (strtab);
1957 return true;
1959 error_return:
1960 _bfd_stringtab_free (strtab);
1961 return false;
1965 long
1966 NAME(aout,get_symtab) (abfd, location)
1967 bfd *abfd;
1968 asymbol **location;
1970 unsigned int counter = 0;
1971 aout_symbol_type *symbase;
1973 if (!NAME(aout,slurp_symbol_table)(abfd))
1974 return -1;
1976 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1977 *(location++) = (asymbol *)( symbase++);
1978 *location++ =0;
1979 return bfd_get_symcount (abfd);
1983 /* Standard reloc stuff */
1984 /* Output standard relocation information to a file in target byte order. */
1986 extern void NAME(aout,swap_std_reloc_out)
1987 PARAMS ((bfd *, arelent *, struct reloc_std_external *));
1989 void
1990 NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
1991 bfd *abfd;
1992 arelent *g;
1993 struct reloc_std_external *natptr;
1995 int r_index;
1996 asymbol *sym = *(g->sym_ptr_ptr);
1997 int r_extern;
1998 unsigned int r_length;
1999 int r_pcrel;
2000 int r_baserel, r_jmptable, r_relative;
2001 asection *output_section = sym->section->output_section;
2003 PUT_WORD(abfd, g->address, natptr->r_address);
2005 r_length = g->howto->size ; /* Size as a power of two */
2006 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
2007 /* XXX This relies on relocs coming from a.out files. */
2008 r_baserel = (g->howto->type & 8) != 0;
2009 r_jmptable = (g->howto->type & 16) != 0;
2010 r_relative = (g->howto->type & 32) != 0;
2012 #if 0
2013 /* For a standard reloc, the addend is in the object file. */
2014 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
2015 #endif
2017 /* name was clobbered by aout_write_syms to be symbol index */
2019 /* If this relocation is relative to a symbol then set the
2020 r_index to the symbols index, and the r_extern bit.
2022 Absolute symbols can come in in two ways, either as an offset
2023 from the abs section, or as a symbol which has an abs value.
2024 check for that here
2028 if (bfd_is_com_section (output_section)
2029 || bfd_is_abs_section (output_section)
2030 || bfd_is_und_section (output_section))
2032 if (bfd_abs_section_ptr->symbol == sym)
2034 /* Whoops, looked like an abs symbol, but is really an offset
2035 from the abs section */
2036 r_index = N_ABS;
2037 r_extern = 0;
2039 else
2041 /* Fill in symbol */
2042 r_extern = 1;
2043 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2047 else
2049 /* Just an ordinary section */
2050 r_extern = 0;
2051 r_index = output_section->target_index;
2054 /* now the fun stuff */
2055 if (bfd_header_big_endian (abfd)) {
2056 natptr->r_index[0] = r_index >> 16;
2057 natptr->r_index[1] = r_index >> 8;
2058 natptr->r_index[2] = r_index;
2059 natptr->r_type[0] =
2060 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
2061 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
2062 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
2063 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
2064 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
2065 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
2066 } else {
2067 natptr->r_index[2] = r_index >> 16;
2068 natptr->r_index[1] = r_index >> 8;
2069 natptr->r_index[0] = r_index;
2070 natptr->r_type[0] =
2071 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
2072 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
2073 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
2074 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
2075 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
2076 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
2081 /* Extended stuff */
2082 /* Output extended relocation information to a file in target byte order. */
2084 extern void NAME(aout,swap_ext_reloc_out)
2085 PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
2087 void
2088 NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
2089 bfd *abfd;
2090 arelent *g;
2091 register struct reloc_ext_external *natptr;
2093 int r_index;
2094 int r_extern;
2095 unsigned int r_type;
2096 unsigned int r_addend;
2097 asymbol *sym = *(g->sym_ptr_ptr);
2098 asection *output_section = sym->section->output_section;
2100 PUT_WORD (abfd, g->address, natptr->r_address);
2102 r_type = (unsigned int) g->howto->type;
2104 r_addend = g->addend;
2105 if ((sym->flags & BSF_SECTION_SYM) != 0)
2106 r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma;
2108 /* If this relocation is relative to a symbol then set the
2109 r_index to the symbols index, and the r_extern bit.
2111 Absolute symbols can come in in two ways, either as an offset
2112 from the abs section, or as a symbol which has an abs value.
2113 check for that here. */
2115 if (bfd_is_abs_section (bfd_get_section (sym)))
2117 r_extern = 0;
2118 r_index = N_ABS;
2120 else if ((sym->flags & BSF_SECTION_SYM) == 0)
2122 if (bfd_is_und_section (bfd_get_section (sym))
2123 || (sym->flags & BSF_GLOBAL) != 0)
2124 r_extern = 1;
2125 else
2126 r_extern = 0;
2127 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2129 else
2131 /* Just an ordinary section */
2132 r_extern = 0;
2133 r_index = output_section->target_index;
2136 /* now the fun stuff */
2137 if (bfd_header_big_endian (abfd)) {
2138 natptr->r_index[0] = r_index >> 16;
2139 natptr->r_index[1] = r_index >> 8;
2140 natptr->r_index[2] = r_index;
2141 natptr->r_type[0] =
2142 ((r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
2143 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
2144 } else {
2145 natptr->r_index[2] = r_index >> 16;
2146 natptr->r_index[1] = r_index >> 8;
2147 natptr->r_index[0] = r_index;
2148 natptr->r_type[0] =
2149 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
2150 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
2153 PUT_WORD (abfd, r_addend, natptr->r_addend);
2156 /* BFD deals internally with all things based from the section they're
2157 in. so, something in 10 bytes into a text section with a base of
2158 50 would have a symbol (.text+10) and know .text vma was 50.
2160 Aout keeps all it's symbols based from zero, so the symbol would
2161 contain 60. This macro subs the base of each section from the value
2162 to give the true offset from the section */
2165 #define MOVE_ADDRESS(ad) \
2166 if (r_extern) { \
2167 /* undefined symbol */ \
2168 cache_ptr->sym_ptr_ptr = symbols + r_index; \
2169 cache_ptr->addend = ad; \
2170 } else { \
2171 /* defined, section relative. replace symbol with pointer to \
2172 symbol which points to section */ \
2173 switch (r_index) { \
2174 case N_TEXT: \
2175 case N_TEXT | N_EXT: \
2176 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
2177 cache_ptr->addend = ad - su->textsec->vma; \
2178 break; \
2179 case N_DATA: \
2180 case N_DATA | N_EXT: \
2181 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
2182 cache_ptr->addend = ad - su->datasec->vma; \
2183 break; \
2184 case N_BSS: \
2185 case N_BSS | N_EXT: \
2186 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
2187 cache_ptr->addend = ad - su->bsssec->vma; \
2188 break; \
2189 default: \
2190 case N_ABS: \
2191 case N_ABS | N_EXT: \
2192 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
2193 cache_ptr->addend = ad; \
2194 break; \
2198 void
2199 NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2200 bfd *abfd;
2201 struct reloc_ext_external *bytes;
2202 arelent *cache_ptr;
2203 asymbol **symbols;
2204 bfd_size_type symcount;
2206 unsigned int r_index;
2207 int r_extern;
2208 unsigned int r_type;
2209 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2211 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2213 /* now the fun stuff */
2214 if (bfd_header_big_endian (abfd)) {
2215 r_index = (bytes->r_index[0] << 16)
2216 | (bytes->r_index[1] << 8)
2217 | bytes->r_index[2];
2218 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2219 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2220 >> RELOC_EXT_BITS_TYPE_SH_BIG;
2221 } else {
2222 r_index = (bytes->r_index[2] << 16)
2223 | (bytes->r_index[1] << 8)
2224 | bytes->r_index[0];
2225 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2226 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2227 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
2230 cache_ptr->howto = howto_table_ext + r_type;
2232 /* Base relative relocs are always against the symbol table,
2233 regardless of the setting of r_extern. r_extern just reflects
2234 whether the symbol the reloc is against is local or global. */
2235 if (r_type == RELOC_BASE10
2236 || r_type == RELOC_BASE13
2237 || r_type == RELOC_BASE22)
2238 r_extern = 1;
2240 if (r_extern && r_index > symcount)
2242 /* We could arrange to return an error, but it might be useful
2243 to see the file even if it is bad. */
2244 r_extern = 0;
2245 r_index = N_ABS;
2248 MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
2251 void
2252 NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2253 bfd *abfd;
2254 struct reloc_std_external *bytes;
2255 arelent *cache_ptr;
2256 asymbol **symbols;
2257 bfd_size_type symcount;
2259 unsigned int r_index;
2260 int r_extern;
2261 unsigned int r_length;
2262 int r_pcrel;
2263 int r_baserel, r_jmptable, r_relative;
2264 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2265 unsigned int howto_idx;
2267 cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
2269 /* now the fun stuff */
2270 if (bfd_header_big_endian (abfd)) {
2271 r_index = (bytes->r_index[0] << 16)
2272 | (bytes->r_index[1] << 8)
2273 | bytes->r_index[2];
2274 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2275 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2276 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2277 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2278 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2279 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2280 >> RELOC_STD_BITS_LENGTH_SH_BIG;
2281 } else {
2282 r_index = (bytes->r_index[2] << 16)
2283 | (bytes->r_index[1] << 8)
2284 | bytes->r_index[0];
2285 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2286 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2287 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2288 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2289 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2290 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2291 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
2294 howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel
2295 + 16 * r_jmptable + 32 * r_relative;
2296 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
2297 cache_ptr->howto = howto_table_std + howto_idx;
2298 BFD_ASSERT (cache_ptr->howto->type != (unsigned int) -1);
2300 /* Base relative relocs are always against the symbol table,
2301 regardless of the setting of r_extern. r_extern just reflects
2302 whether the symbol the reloc is against is local or global. */
2303 if (r_baserel)
2304 r_extern = 1;
2306 if (r_extern && r_index > symcount)
2308 /* We could arrange to return an error, but it might be useful
2309 to see the file even if it is bad. */
2310 r_extern = 0;
2311 r_index = N_ABS;
2314 MOVE_ADDRESS(0);
2317 /* Read and swap the relocs for a section. */
2319 boolean
2320 NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
2321 bfd *abfd;
2322 sec_ptr asect;
2323 asymbol **symbols;
2325 unsigned int count;
2326 bfd_size_type reloc_size;
2327 PTR relocs;
2328 arelent *reloc_cache;
2329 size_t each_size;
2330 unsigned int counter = 0;
2331 arelent *cache_ptr;
2333 if (asect->relocation)
2334 return true;
2336 if (asect->flags & SEC_CONSTRUCTOR)
2337 return true;
2339 if (asect == obj_datasec (abfd))
2340 reloc_size = exec_hdr(abfd)->a_drsize;
2341 else if (asect == obj_textsec (abfd))
2342 reloc_size = exec_hdr(abfd)->a_trsize;
2343 else if (asect == obj_bsssec (abfd))
2344 reloc_size = 0;
2345 else
2347 bfd_set_error (bfd_error_invalid_operation);
2348 return false;
2351 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
2352 return false;
2354 each_size = obj_reloc_entry_size (abfd);
2356 count = reloc_size / each_size;
2358 reloc_cache = (arelent *) bfd_malloc ((size_t) (count * sizeof (arelent)));
2359 if (reloc_cache == NULL && count != 0)
2360 return false;
2361 memset (reloc_cache, 0, count * sizeof (arelent));
2363 relocs = bfd_malloc ((size_t) reloc_size);
2364 if (relocs == NULL && reloc_size != 0)
2366 free (reloc_cache);
2367 return false;
2370 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)
2372 free (relocs);
2373 free (reloc_cache);
2374 return false;
2377 cache_ptr = reloc_cache;
2378 if (each_size == RELOC_EXT_SIZE)
2380 register struct reloc_ext_external *rptr =
2381 (struct reloc_ext_external *) relocs;
2383 for (; counter < count; counter++, rptr++, cache_ptr++)
2384 NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
2385 bfd_get_symcount (abfd));
2387 else
2389 register struct reloc_std_external *rptr =
2390 (struct reloc_std_external *) relocs;
2392 for (; counter < count; counter++, rptr++, cache_ptr++)
2393 MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
2394 bfd_get_symcount (abfd));
2397 free (relocs);
2399 asect->relocation = reloc_cache;
2400 asect->reloc_count = cache_ptr - reloc_cache;
2402 return true;
2405 /* Write out a relocation section into an object file. */
2407 boolean
2408 NAME(aout,squirt_out_relocs) (abfd, section)
2409 bfd *abfd;
2410 asection *section;
2412 arelent **generic;
2413 unsigned char *native, *natptr;
2414 size_t each_size;
2416 unsigned int count = section->reloc_count;
2417 size_t natsize;
2419 if (count == 0 || section->orelocation == NULL)
2420 return true;
2422 each_size = obj_reloc_entry_size (abfd);
2423 natsize = each_size * count;
2424 native = (unsigned char *) bfd_zalloc (abfd, natsize);
2425 if (!native)
2426 return false;
2428 generic = section->orelocation;
2430 if (each_size == RELOC_EXT_SIZE)
2432 for (natptr = native;
2433 count != 0;
2434 --count, natptr += each_size, ++generic)
2435 NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
2437 else
2439 for (natptr = native;
2440 count != 0;
2441 --count, natptr += each_size, ++generic)
2442 MY_swap_std_reloc_out(abfd, *generic, (struct reloc_std_external *)natptr);
2445 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
2446 bfd_release(abfd, native);
2447 return false;
2449 bfd_release (abfd, native);
2451 return true;
2454 /* This is stupid. This function should be a boolean predicate */
2455 long
2456 NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols)
2457 bfd *abfd;
2458 sec_ptr section;
2459 arelent **relptr;
2460 asymbol **symbols;
2462 arelent *tblptr = section->relocation;
2463 unsigned int count;
2465 if (section == obj_bsssec (abfd))
2467 *relptr = NULL;
2468 return 0;
2471 if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
2472 return -1;
2474 if (section->flags & SEC_CONSTRUCTOR) {
2475 arelent_chain *chain = section->constructor_chain;
2476 for (count = 0; count < section->reloc_count; count ++) {
2477 *relptr ++ = &chain->relent;
2478 chain = chain->next;
2481 else {
2482 tblptr = section->relocation;
2484 for (count = 0; count++ < section->reloc_count;)
2486 *relptr++ = tblptr++;
2489 *relptr = 0;
2491 return section->reloc_count;
2494 long
2495 NAME(aout,get_reloc_upper_bound) (abfd, asect)
2496 bfd *abfd;
2497 sec_ptr asect;
2499 if (bfd_get_format (abfd) != bfd_object) {
2500 bfd_set_error (bfd_error_invalid_operation);
2501 return -1;
2503 if (asect->flags & SEC_CONSTRUCTOR) {
2504 return (sizeof (arelent *) * (asect->reloc_count+1));
2507 if (asect == obj_datasec (abfd))
2508 return (sizeof (arelent *)
2509 * ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
2510 + 1));
2512 if (asect == obj_textsec (abfd))
2513 return (sizeof (arelent *)
2514 * ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
2515 + 1));
2517 if (asect == obj_bsssec (abfd))
2518 return sizeof (arelent *);
2520 if (asect == obj_bsssec (abfd))
2521 return 0;
2523 bfd_set_error (bfd_error_invalid_operation);
2524 return -1;
2528 long
2529 NAME(aout,get_symtab_upper_bound) (abfd)
2530 bfd *abfd;
2532 if (!NAME(aout,slurp_symbol_table)(abfd))
2533 return -1;
2535 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2538 /*ARGSUSED*/
2539 alent *
2540 NAME(aout,get_lineno) (ignore_abfd, ignore_symbol)
2541 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2542 asymbol *ignore_symbol ATTRIBUTE_UNUSED;
2544 return (alent *)NULL;
2547 /*ARGSUSED*/
2548 void
2549 NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
2550 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2551 asymbol *symbol;
2552 symbol_info *ret;
2554 bfd_symbol_info (symbol, ret);
2556 if (ret->type == '?')
2558 int type_code = aout_symbol(symbol)->type & 0xff;
2559 const char *stab_name = bfd_get_stab_name (type_code);
2560 static char buf[10];
2562 if (stab_name == NULL)
2564 sprintf(buf, "(%d)", type_code);
2565 stab_name = buf;
2567 ret->type = '-';
2568 ret->stab_type = type_code;
2569 ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
2570 ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
2571 ret->stab_name = stab_name;
2575 /*ARGSUSED*/
2576 void
2577 NAME(aout,print_symbol) (ignore_abfd, afile, symbol, how)
2578 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2579 PTR afile;
2580 asymbol *symbol;
2581 bfd_print_symbol_type how;
2583 FILE *file = (FILE *)afile;
2585 switch (how) {
2586 case bfd_print_symbol_name:
2587 if (symbol->name)
2588 fprintf(file,"%s", symbol->name);
2589 break;
2590 case bfd_print_symbol_more:
2591 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
2592 (unsigned)(aout_symbol(symbol)->other & 0xff),
2593 (unsigned)(aout_symbol(symbol)->type));
2594 break;
2595 case bfd_print_symbol_all:
2597 CONST char *section_name = symbol->section->name;
2600 bfd_print_symbol_vandf((PTR)file,symbol);
2602 fprintf(file," %-5s %04x %02x %02x",
2603 section_name,
2604 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
2605 (unsigned)(aout_symbol(symbol)->other & 0xff),
2606 (unsigned)(aout_symbol(symbol)->type & 0xff));
2607 if (symbol->name)
2608 fprintf(file," %s", symbol->name);
2610 break;
2614 /* If we don't have to allocate more than 1MB to hold the generic
2615 symbols, we use the generic minisymbol methord: it's faster, since
2616 it only translates the symbols once, not multiple times. */
2617 #define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
2619 /* Read minisymbols. For minisymbols, we use the unmodified a.out
2620 symbols. The minisymbol_to_symbol function translates these into
2621 BFD asymbol structures. */
2623 long
2624 NAME(aout,read_minisymbols) (abfd, dynamic, minisymsp, sizep)
2625 bfd *abfd;
2626 boolean dynamic;
2627 PTR *minisymsp;
2628 unsigned int *sizep;
2630 if (dynamic)
2632 /* We could handle the dynamic symbols here as well, but it's
2633 easier to hand them off. */
2634 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2637 if (! aout_get_external_symbols (abfd))
2638 return -1;
2640 if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2641 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2643 *minisymsp = (PTR) obj_aout_external_syms (abfd);
2645 /* By passing the external symbols back from this routine, we are
2646 giving up control over the memory block. Clear
2647 obj_aout_external_syms, so that we do not try to free it
2648 ourselves. */
2649 obj_aout_external_syms (abfd) = NULL;
2651 *sizep = EXTERNAL_NLIST_SIZE;
2652 return obj_aout_external_sym_count (abfd);
2655 /* Convert a minisymbol to a BFD asymbol. A minisymbol is just an
2656 unmodified a.out symbol. The SYM argument is a structure returned
2657 by bfd_make_empty_symbol, which we fill in here. */
2659 asymbol *
2660 NAME(aout,minisymbol_to_symbol) (abfd, dynamic, minisym, sym)
2661 bfd *abfd;
2662 boolean dynamic;
2663 const PTR minisym;
2664 asymbol *sym;
2666 if (dynamic
2667 || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2668 return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
2670 memset (sym, 0, sizeof (aout_symbol_type));
2672 /* We call translate_symbol_table to translate a single symbol. */
2673 if (! (NAME(aout,translate_symbol_table)
2674 (abfd,
2675 (aout_symbol_type *) sym,
2676 (struct external_nlist *) minisym,
2677 (bfd_size_type) 1,
2678 obj_aout_external_strings (abfd),
2679 obj_aout_external_string_size (abfd),
2680 false)))
2681 return NULL;
2683 return sym;
2687 provided a BFD, a section and an offset into the section, calculate
2688 and return the name of the source file and the line nearest to the
2689 wanted location.
2692 boolean
2693 NAME(aout,find_nearest_line)
2694 (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
2695 bfd *abfd;
2696 asection *section;
2697 asymbol **symbols;
2698 bfd_vma offset;
2699 CONST char **filename_ptr;
2700 CONST char **functionname_ptr;
2701 unsigned int *line_ptr;
2703 /* Run down the file looking for the filename, function and linenumber */
2704 asymbol **p;
2705 CONST char *directory_name = NULL;
2706 CONST char *main_file_name = NULL;
2707 CONST char *current_file_name = NULL;
2708 CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
2709 CONST char *line_directory_name = NULL; /* Value of directory_name at line number. */
2710 bfd_vma low_line_vma = 0;
2711 bfd_vma low_func_vma = 0;
2712 asymbol *func = 0;
2713 size_t filelen, funclen;
2714 char *buf;
2716 *filename_ptr = abfd->filename;
2717 *functionname_ptr = 0;
2718 *line_ptr = 0;
2719 if (symbols != (asymbol **)NULL) {
2720 for (p = symbols; *p; p++) {
2721 aout_symbol_type *q = (aout_symbol_type *)(*p);
2722 next:
2723 switch (q->type){
2724 case N_TEXT:
2725 /* If this looks like a file name symbol, and it comes after
2726 the line number we have found so far, but before the
2727 offset, then we have probably not found the right line
2728 number. */
2729 if (q->symbol.value <= offset
2730 && ((q->symbol.value > low_line_vma
2731 && (line_file_name != NULL
2732 || *line_ptr != 0))
2733 || (q->symbol.value > low_func_vma
2734 && func != NULL)))
2736 const char *symname;
2738 symname = q->symbol.name;
2739 if (strcmp (symname + strlen (symname) - 2, ".o") == 0)
2741 if (q->symbol.value > low_line_vma)
2743 *line_ptr = 0;
2744 line_file_name = NULL;
2746 if (q->symbol.value > low_func_vma)
2747 func = NULL;
2750 break;
2752 case N_SO:
2753 /* If this symbol is less than the offset, but greater than
2754 the line number we have found so far, then we have not
2755 found the right line number. */
2756 if (q->symbol.value <= offset)
2758 if (q->symbol.value > low_line_vma)
2760 *line_ptr = 0;
2761 line_file_name = NULL;
2763 if (q->symbol.value > low_func_vma)
2764 func = NULL;
2767 main_file_name = current_file_name = q->symbol.name;
2768 /* Look ahead to next symbol to check if that too is an N_SO. */
2769 p++;
2770 if (*p == NULL)
2771 break;
2772 q = (aout_symbol_type *)(*p);
2773 if (q->type != (int)N_SO)
2774 goto next;
2776 /* Found a second N_SO First is directory; second is filename. */
2777 directory_name = current_file_name;
2778 main_file_name = current_file_name = q->symbol.name;
2779 if (obj_textsec(abfd) != section)
2780 goto done;
2781 break;
2782 case N_SOL:
2783 current_file_name = q->symbol.name;
2784 break;
2786 case N_SLINE:
2788 case N_DSLINE:
2789 case N_BSLINE:
2790 /* We'll keep this if it resolves nearer than the one we have
2791 already. */
2792 if (q->symbol.value >= low_line_vma
2793 && q->symbol.value <= offset)
2795 *line_ptr = q->desc;
2796 low_line_vma = q->symbol.value;
2797 line_file_name = current_file_name;
2798 line_directory_name = directory_name;
2800 break;
2801 case N_FUN:
2803 /* We'll keep this if it is nearer than the one we have already */
2804 if (q->symbol.value >= low_func_vma &&
2805 q->symbol.value <= offset) {
2806 low_func_vma = q->symbol.value;
2807 func = (asymbol *)q;
2809 else if (q->symbol.value > offset)
2810 goto done;
2812 break;
2817 done:
2818 if (*line_ptr != 0)
2820 main_file_name = line_file_name;
2821 directory_name = line_directory_name;
2824 if (main_file_name == NULL
2825 || main_file_name[0] == '/'
2826 || directory_name == NULL)
2827 filelen = 0;
2828 else
2829 filelen = strlen (directory_name) + strlen (main_file_name);
2830 if (func == NULL)
2831 funclen = 0;
2832 else
2833 funclen = strlen (bfd_asymbol_name (func));
2835 if (adata (abfd).line_buf != NULL)
2836 free (adata (abfd).line_buf);
2837 if (filelen + funclen == 0)
2838 adata (abfd).line_buf = buf = NULL;
2839 else
2841 buf = (char *) bfd_malloc (filelen + funclen + 3);
2842 adata (abfd).line_buf = buf;
2843 if (buf == NULL)
2844 return false;
2847 if (main_file_name != NULL)
2849 if (main_file_name[0] == '/' || directory_name == NULL)
2850 *filename_ptr = main_file_name;
2851 else
2853 sprintf (buf, "%s%s", directory_name, main_file_name);
2854 *filename_ptr = buf;
2855 buf += filelen + 1;
2859 if (func)
2861 const char *function = func->name;
2862 char *p;
2864 /* The caller expects a symbol name. We actually have a
2865 function name, without the leading underscore. Put the
2866 underscore back in, so that the caller gets a symbol name. */
2867 if (bfd_get_symbol_leading_char (abfd) == '\0')
2868 strcpy (buf, function);
2869 else
2871 buf[0] = bfd_get_symbol_leading_char (abfd);
2872 strcpy (buf + 1, function);
2874 /* Have to remove : stuff */
2875 p = strchr (buf, ':');
2876 if (p != NULL)
2877 *p = '\0';
2878 *functionname_ptr = buf;
2881 return true;
2884 /*ARGSUSED*/
2886 NAME(aout,sizeof_headers) (abfd, execable)
2887 bfd *abfd;
2888 boolean execable ATTRIBUTE_UNUSED;
2890 return adata(abfd).exec_bytes_size;
2893 /* Free all information we have cached for this BFD. We can always
2894 read it again later if we need it. */
2896 boolean
2897 NAME(aout,bfd_free_cached_info) (abfd)
2898 bfd *abfd;
2900 asection *o;
2902 if (bfd_get_format (abfd) != bfd_object)
2903 return true;
2905 #define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
2906 BFCI_FREE (obj_aout_symbols (abfd));
2907 #ifdef USE_MMAP
2908 obj_aout_external_syms (abfd) = 0;
2909 bfd_free_window (&obj_aout_sym_window (abfd));
2910 bfd_free_window (&obj_aout_string_window (abfd));
2911 obj_aout_external_strings (abfd) = 0;
2912 #else
2913 BFCI_FREE (obj_aout_external_syms (abfd));
2914 BFCI_FREE (obj_aout_external_strings (abfd));
2915 #endif
2916 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
2917 BFCI_FREE (o->relocation);
2918 #undef BFCI_FREE
2920 return true;
2923 /* a.out link code. */
2925 static boolean aout_link_add_object_symbols
2926 PARAMS ((bfd *, struct bfd_link_info *));
2927 static boolean aout_link_check_archive_element
2928 PARAMS ((bfd *, struct bfd_link_info *, boolean *));
2929 static boolean aout_link_free_symbols PARAMS ((bfd *));
2930 static boolean aout_link_check_ar_symbols
2931 PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
2932 static boolean aout_link_add_symbols
2933 PARAMS ((bfd *, struct bfd_link_info *));
2935 /* Routine to create an entry in an a.out link hash table. */
2937 struct bfd_hash_entry *
2938 NAME(aout,link_hash_newfunc) (entry, table, string)
2939 struct bfd_hash_entry *entry;
2940 struct bfd_hash_table *table;
2941 const char *string;
2943 struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
2945 /* Allocate the structure if it has not already been allocated by a
2946 subclass. */
2947 if (ret == (struct aout_link_hash_entry *) NULL)
2948 ret = ((struct aout_link_hash_entry *)
2949 bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
2950 if (ret == (struct aout_link_hash_entry *) NULL)
2951 return (struct bfd_hash_entry *) ret;
2953 /* Call the allocation method of the superclass. */
2954 ret = ((struct aout_link_hash_entry *)
2955 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2956 table, string));
2957 if (ret)
2959 /* Set local fields. */
2960 ret->written = false;
2961 ret->indx = -1;
2964 return (struct bfd_hash_entry *) ret;
2967 /* Initialize an a.out link hash table. */
2969 boolean
2970 NAME(aout,link_hash_table_init) (table, abfd, newfunc)
2971 struct aout_link_hash_table *table;
2972 bfd *abfd;
2973 struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
2974 struct bfd_hash_table *,
2975 const char *));
2977 return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
2980 /* Create an a.out link hash table. */
2982 struct bfd_link_hash_table *
2983 NAME(aout,link_hash_table_create) (abfd)
2984 bfd *abfd;
2986 struct aout_link_hash_table *ret;
2988 ret = ((struct aout_link_hash_table *)
2989 bfd_alloc (abfd, sizeof (struct aout_link_hash_table)));
2990 if (ret == NULL)
2991 return (struct bfd_link_hash_table *) NULL;
2992 if (! NAME(aout,link_hash_table_init) (ret, abfd,
2993 NAME(aout,link_hash_newfunc)))
2995 free (ret);
2996 return (struct bfd_link_hash_table *) NULL;
2998 return &ret->root;
3001 /* Given an a.out BFD, add symbols to the global hash table as
3002 appropriate. */
3004 boolean
3005 NAME(aout,link_add_symbols) (abfd, info)
3006 bfd *abfd;
3007 struct bfd_link_info *info;
3009 switch (bfd_get_format (abfd))
3011 case bfd_object:
3012 return aout_link_add_object_symbols (abfd, info);
3013 case bfd_archive:
3014 return _bfd_generic_link_add_archive_symbols
3015 (abfd, info, aout_link_check_archive_element);
3016 default:
3017 bfd_set_error (bfd_error_wrong_format);
3018 return false;
3022 /* Add symbols from an a.out object file. */
3024 static boolean
3025 aout_link_add_object_symbols (abfd, info)
3026 bfd *abfd;
3027 struct bfd_link_info *info;
3029 if (! aout_get_external_symbols (abfd))
3030 return false;
3031 if (! aout_link_add_symbols (abfd, info))
3032 return false;
3033 if (! info->keep_memory)
3035 if (! aout_link_free_symbols (abfd))
3036 return false;
3038 return true;
3041 /* Check a single archive element to see if we need to include it in
3042 the link. *PNEEDED is set according to whether this element is
3043 needed in the link or not. This is called from
3044 _bfd_generic_link_add_archive_symbols. */
3046 static boolean
3047 aout_link_check_archive_element (abfd, info, pneeded)
3048 bfd *abfd;
3049 struct bfd_link_info *info;
3050 boolean *pneeded;
3052 if (! aout_get_external_symbols (abfd))
3053 return false;
3055 if (! aout_link_check_ar_symbols (abfd, info, pneeded))
3056 return false;
3058 if (*pneeded)
3060 if (! aout_link_add_symbols (abfd, info))
3061 return false;
3064 if (! info->keep_memory || ! *pneeded)
3066 if (! aout_link_free_symbols (abfd))
3067 return false;
3070 return true;
3073 /* Free up the internal symbols read from an a.out file. */
3075 static boolean
3076 aout_link_free_symbols (abfd)
3077 bfd *abfd;
3079 if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
3081 #ifdef USE_MMAP
3082 bfd_free_window (&obj_aout_sym_window (abfd));
3083 #else
3084 free ((PTR) obj_aout_external_syms (abfd));
3085 #endif
3086 obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
3088 if (obj_aout_external_strings (abfd) != (char *) NULL)
3090 #ifdef USE_MMAP
3091 bfd_free_window (&obj_aout_string_window (abfd));
3092 #else
3093 free ((PTR) obj_aout_external_strings (abfd));
3094 #endif
3095 obj_aout_external_strings (abfd) = (char *) NULL;
3097 return true;
3100 /* Look through the internal symbols to see if this object file should
3101 be included in the link. We should include this object file if it
3102 defines any symbols which are currently undefined. If this object
3103 file defines a common symbol, then we may adjust the size of the
3104 known symbol but we do not include the object file in the link
3105 (unless there is some other reason to include it). */
3107 static boolean
3108 aout_link_check_ar_symbols (abfd, info, pneeded)
3109 bfd *abfd;
3110 struct bfd_link_info *info;
3111 boolean *pneeded;
3113 register struct external_nlist *p;
3114 struct external_nlist *pend;
3115 char *strings;
3117 *pneeded = false;
3119 /* Look through all the symbols. */
3120 p = obj_aout_external_syms (abfd);
3121 pend = p + obj_aout_external_sym_count (abfd);
3122 strings = obj_aout_external_strings (abfd);
3123 for (; p < pend; p++)
3125 int type = bfd_h_get_8 (abfd, p->e_type);
3126 const char *name;
3127 struct bfd_link_hash_entry *h;
3129 /* Ignore symbols that are not externally visible. This is an
3130 optimization only, as we check the type more thoroughly
3131 below. */
3132 if (((type & N_EXT) == 0
3133 || (type & N_STAB) != 0
3134 || type == N_FN)
3135 && type != N_WEAKA
3136 && type != N_WEAKT
3137 && type != N_WEAKD
3138 && type != N_WEAKB)
3140 if (type == N_WARNING
3141 || type == N_INDR)
3142 ++p;
3143 continue;
3146 name = strings + GET_WORD (abfd, p->e_strx);
3147 h = bfd_link_hash_lookup (info->hash, name, false, false, true);
3149 /* We are only interested in symbols that are currently
3150 undefined or common. */
3151 if (h == (struct bfd_link_hash_entry *) NULL
3152 || (h->type != bfd_link_hash_undefined
3153 && h->type != bfd_link_hash_common))
3155 if (type == (N_INDR | N_EXT))
3156 ++p;
3157 continue;
3160 if (type == (N_TEXT | N_EXT)
3161 || type == (N_DATA | N_EXT)
3162 || type == (N_BSS | N_EXT)
3163 || type == (N_ABS | N_EXT)
3164 || type == (N_INDR | N_EXT))
3166 /* This object file defines this symbol. We must link it
3167 in. This is true regardless of whether the current
3168 definition of the symbol is undefined or common. If the
3169 current definition is common, we have a case in which we
3170 have already seen an object file including
3171 int a;
3172 and this object file from the archive includes
3173 int a = 5;
3174 In such a case we must include this object file.
3176 FIXME: The SunOS 4.1.3 linker will pull in the archive
3177 element if the symbol is defined in the .data section,
3178 but not if it is defined in the .text section. That
3179 seems a bit crazy to me, and I haven't implemented it.
3180 However, it might be correct. */
3181 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3182 return false;
3183 *pneeded = true;
3184 return true;
3187 if (type == (N_UNDF | N_EXT))
3189 bfd_vma value;
3191 value = GET_WORD (abfd, p->e_value);
3192 if (value != 0)
3194 /* This symbol is common in the object from the archive
3195 file. */
3196 if (h->type == bfd_link_hash_undefined)
3198 bfd *symbfd;
3199 unsigned int power;
3201 symbfd = h->u.undef.abfd;
3202 if (symbfd == (bfd *) NULL)
3204 /* This symbol was created as undefined from
3205 outside BFD. We assume that we should link
3206 in the object file. This is done for the -u
3207 option in the linker. */
3208 if (! (*info->callbacks->add_archive_element) (info,
3209 abfd,
3210 name))
3211 return false;
3212 *pneeded = true;
3213 return true;
3215 /* Turn the current link symbol into a common
3216 symbol. It is already on the undefs list. */
3217 h->type = bfd_link_hash_common;
3218 h->u.c.p = ((struct bfd_link_hash_common_entry *)
3219 bfd_hash_allocate (&info->hash->table,
3220 sizeof (struct bfd_link_hash_common_entry)));
3221 if (h->u.c.p == NULL)
3222 return false;
3224 h->u.c.size = value;
3226 /* FIXME: This isn't quite right. The maximum
3227 alignment of a common symbol should be set by the
3228 architecture of the output file, not of the input
3229 file. */
3230 power = bfd_log2 (value);
3231 if (power > bfd_get_arch_info (abfd)->section_align_power)
3232 power = bfd_get_arch_info (abfd)->section_align_power;
3233 h->u.c.p->alignment_power = power;
3235 h->u.c.p->section = bfd_make_section_old_way (symbfd,
3236 "COMMON");
3238 else
3240 /* Adjust the size of the common symbol if
3241 necessary. */
3242 if (value > h->u.c.size)
3243 h->u.c.size = value;
3248 if (type == N_WEAKA
3249 || type == N_WEAKT
3250 || type == N_WEAKD
3251 || type == N_WEAKB)
3253 /* This symbol is weak but defined. We must pull it in if
3254 the current link symbol is undefined, but we don't want
3255 it if the current link symbol is common. */
3256 if (h->type == bfd_link_hash_undefined)
3258 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3259 return false;
3260 *pneeded = true;
3261 return true;
3266 /* We do not need this object file. */
3267 return true;
3270 /* Add all symbols from an object file to the hash table. */
3272 static boolean
3273 aout_link_add_symbols (abfd, info)
3274 bfd *abfd;
3275 struct bfd_link_info *info;
3277 boolean (*add_one_symbol) PARAMS ((struct bfd_link_info *, bfd *,
3278 const char *, flagword, asection *,
3279 bfd_vma, const char *, boolean,
3280 boolean,
3281 struct bfd_link_hash_entry **));
3282 struct external_nlist *syms;
3283 bfd_size_type sym_count;
3284 char *strings;
3285 boolean copy;
3286 struct aout_link_hash_entry **sym_hash;
3287 register struct external_nlist *p;
3288 struct external_nlist *pend;
3290 syms = obj_aout_external_syms (abfd);
3291 sym_count = obj_aout_external_sym_count (abfd);
3292 strings = obj_aout_external_strings (abfd);
3293 if (info->keep_memory)
3294 copy = false;
3295 else
3296 copy = true;
3298 if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
3300 if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
3301 (abfd, info, &syms, &sym_count, &strings)))
3302 return false;
3305 /* We keep a list of the linker hash table entries that correspond
3306 to particular symbols. We could just look them up in the hash
3307 table, but keeping the list is more efficient. Perhaps this
3308 should be conditional on info->keep_memory. */
3309 sym_hash = ((struct aout_link_hash_entry **)
3310 bfd_alloc (abfd,
3311 ((size_t) sym_count
3312 * sizeof (struct aout_link_hash_entry *))));
3313 if (sym_hash == NULL && sym_count != 0)
3314 return false;
3315 obj_aout_sym_hashes (abfd) = sym_hash;
3317 add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
3318 if (add_one_symbol == NULL)
3319 add_one_symbol = _bfd_generic_link_add_one_symbol;
3321 p = syms;
3322 pend = p + sym_count;
3323 for (; p < pend; p++, sym_hash++)
3325 int type;
3326 const char *name;
3327 bfd_vma value;
3328 asection *section;
3329 flagword flags;
3330 const char *string;
3332 *sym_hash = NULL;
3334 type = bfd_h_get_8 (abfd, p->e_type);
3336 /* Ignore debugging symbols. */
3337 if ((type & N_STAB) != 0)
3338 continue;
3340 name = strings + GET_WORD (abfd, p->e_strx);
3341 value = GET_WORD (abfd, p->e_value);
3342 flags = BSF_GLOBAL;
3343 string = NULL;
3344 switch (type)
3346 default:
3347 abort ();
3349 case N_UNDF:
3350 case N_ABS:
3351 case N_TEXT:
3352 case N_DATA:
3353 case N_BSS:
3354 case N_FN_SEQ:
3355 case N_COMM:
3356 case N_SETV:
3357 case N_FN:
3358 /* Ignore symbols that are not externally visible. */
3359 continue;
3360 case N_INDR:
3361 /* Ignore local indirect symbol. */
3362 ++p;
3363 ++sym_hash;
3364 continue;
3366 case N_UNDF | N_EXT:
3367 if (value == 0)
3369 section = bfd_und_section_ptr;
3370 flags = 0;
3372 else
3373 section = bfd_com_section_ptr;
3374 break;
3375 case N_ABS | N_EXT:
3376 section = bfd_abs_section_ptr;
3377 break;
3378 case N_TEXT | N_EXT:
3379 section = obj_textsec (abfd);
3380 value -= bfd_get_section_vma (abfd, section);
3381 break;
3382 case N_DATA | N_EXT:
3383 case N_SETV | N_EXT:
3384 /* Treat N_SETV symbols as N_DATA symbol; see comment in
3385 translate_from_native_sym_flags. */
3386 section = obj_datasec (abfd);
3387 value -= bfd_get_section_vma (abfd, section);
3388 break;
3389 case N_BSS | N_EXT:
3390 section = obj_bsssec (abfd);
3391 value -= bfd_get_section_vma (abfd, section);
3392 break;
3393 case N_INDR | N_EXT:
3394 /* An indirect symbol. The next symbol is the symbol
3395 which this one really is. */
3396 BFD_ASSERT (p + 1 < pend);
3397 ++p;
3398 string = strings + GET_WORD (abfd, p->e_strx);
3399 section = bfd_ind_section_ptr;
3400 flags |= BSF_INDIRECT;
3401 break;
3402 case N_COMM | N_EXT:
3403 section = bfd_com_section_ptr;
3404 break;
3405 case N_SETA: case N_SETA | N_EXT:
3406 section = bfd_abs_section_ptr;
3407 flags |= BSF_CONSTRUCTOR;
3408 break;
3409 case N_SETT: case N_SETT | N_EXT:
3410 section = obj_textsec (abfd);
3411 flags |= BSF_CONSTRUCTOR;
3412 value -= bfd_get_section_vma (abfd, section);
3413 break;
3414 case N_SETD: case N_SETD | N_EXT:
3415 section = obj_datasec (abfd);
3416 flags |= BSF_CONSTRUCTOR;
3417 value -= bfd_get_section_vma (abfd, section);
3418 break;
3419 case N_SETB: case N_SETB | N_EXT:
3420 section = obj_bsssec (abfd);
3421 flags |= BSF_CONSTRUCTOR;
3422 value -= bfd_get_section_vma (abfd, section);
3423 break;
3424 case N_WARNING:
3425 /* A warning symbol. The next symbol is the one to warn
3426 about. */
3427 BFD_ASSERT (p + 1 < pend);
3428 ++p;
3429 string = name;
3430 name = strings + GET_WORD (abfd, p->e_strx);
3431 section = bfd_und_section_ptr;
3432 flags |= BSF_WARNING;
3433 break;
3434 case N_WEAKU:
3435 section = bfd_und_section_ptr;
3436 flags = BSF_WEAK;
3437 break;
3438 case N_WEAKA:
3439 section = bfd_abs_section_ptr;
3440 flags = BSF_WEAK;
3441 break;
3442 case N_WEAKT:
3443 section = obj_textsec (abfd);
3444 value -= bfd_get_section_vma (abfd, section);
3445 flags = BSF_WEAK;
3446 break;
3447 case N_WEAKD:
3448 section = obj_datasec (abfd);
3449 value -= bfd_get_section_vma (abfd, section);
3450 flags = BSF_WEAK;
3451 break;
3452 case N_WEAKB:
3453 section = obj_bsssec (abfd);
3454 value -= bfd_get_section_vma (abfd, section);
3455 flags = BSF_WEAK;
3456 break;
3459 if (! ((*add_one_symbol)
3460 (info, abfd, name, flags, section, value, string, copy, false,
3461 (struct bfd_link_hash_entry **) sym_hash)))
3462 return false;
3464 /* Restrict the maximum alignment of a common symbol based on
3465 the architecture, since a.out has no way to represent
3466 alignment requirements of a section in a .o file. FIXME:
3467 This isn't quite right: it should use the architecture of the
3468 output file, not the input files. */
3469 if ((*sym_hash)->root.type == bfd_link_hash_common
3470 && ((*sym_hash)->root.u.c.p->alignment_power >
3471 bfd_get_arch_info (abfd)->section_align_power))
3472 (*sym_hash)->root.u.c.p->alignment_power =
3473 bfd_get_arch_info (abfd)->section_align_power;
3475 /* If this is a set symbol, and we are not building sets, then
3476 it is possible for the hash entry to not have been set. In
3477 such a case, treat the symbol as not globally defined. */
3478 if ((*sym_hash)->root.type == bfd_link_hash_new)
3480 BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
3481 *sym_hash = NULL;
3484 if (type == (N_INDR | N_EXT) || type == N_WARNING)
3485 ++sym_hash;
3488 return true;
3491 /* A hash table used for header files with N_BINCL entries. */
3493 struct aout_link_includes_table
3495 struct bfd_hash_table root;
3498 /* A linked list of totals that we have found for a particular header
3499 file. */
3501 struct aout_link_includes_totals
3503 struct aout_link_includes_totals *next;
3504 bfd_vma total;
3507 /* An entry in the header file hash table. */
3509 struct aout_link_includes_entry
3511 struct bfd_hash_entry root;
3512 /* List of totals we have found for this file. */
3513 struct aout_link_includes_totals *totals;
3516 /* Look up an entry in an the header file hash table. */
3518 #define aout_link_includes_lookup(table, string, create, copy) \
3519 ((struct aout_link_includes_entry *) \
3520 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
3522 /* During the final link step we need to pass around a bunch of
3523 information, so we do it in an instance of this structure. */
3525 struct aout_final_link_info
3527 /* General link information. */
3528 struct bfd_link_info *info;
3529 /* Output bfd. */
3530 bfd *output_bfd;
3531 /* Reloc file positions. */
3532 file_ptr treloff, dreloff;
3533 /* File position of symbols. */
3534 file_ptr symoff;
3535 /* String table. */
3536 struct bfd_strtab_hash *strtab;
3537 /* Header file hash table. */
3538 struct aout_link_includes_table includes;
3539 /* A buffer large enough to hold the contents of any section. */
3540 bfd_byte *contents;
3541 /* A buffer large enough to hold the relocs of any section. */
3542 PTR relocs;
3543 /* A buffer large enough to hold the symbol map of any input BFD. */
3544 int *symbol_map;
3545 /* A buffer large enough to hold output symbols of any input BFD. */
3546 struct external_nlist *output_syms;
3549 static struct bfd_hash_entry *aout_link_includes_newfunc
3550 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
3551 static boolean aout_link_input_bfd
3552 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3553 static boolean aout_link_write_symbols
3554 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3555 static boolean aout_link_write_other_symbol
3556 PARAMS ((struct aout_link_hash_entry *, PTR));
3557 static boolean aout_link_input_section
3558 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3559 asection *input_section, file_ptr *reloff_ptr,
3560 bfd_size_type rel_size));
3561 static boolean aout_link_input_section_std
3562 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3563 asection *input_section, struct reloc_std_external *,
3564 bfd_size_type rel_size, bfd_byte *contents));
3565 static boolean aout_link_input_section_ext
3566 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3567 asection *input_section, struct reloc_ext_external *,
3568 bfd_size_type rel_size, bfd_byte *contents));
3569 static INLINE asection *aout_reloc_index_to_section
3570 PARAMS ((bfd *, int));
3571 static boolean aout_link_reloc_link_order
3572 PARAMS ((struct aout_final_link_info *, asection *,
3573 struct bfd_link_order *));
3575 /* The function to create a new entry in the header file hash table. */
3577 static struct bfd_hash_entry *
3578 aout_link_includes_newfunc (entry, table, string)
3579 struct bfd_hash_entry *entry;
3580 struct bfd_hash_table *table;
3581 const char *string;
3583 struct aout_link_includes_entry *ret =
3584 (struct aout_link_includes_entry *) entry;
3586 /* Allocate the structure if it has not already been allocated by a
3587 subclass. */
3588 if (ret == (struct aout_link_includes_entry *) NULL)
3589 ret = ((struct aout_link_includes_entry *)
3590 bfd_hash_allocate (table,
3591 sizeof (struct aout_link_includes_entry)));
3592 if (ret == (struct aout_link_includes_entry *) NULL)
3593 return (struct bfd_hash_entry *) ret;
3595 /* Call the allocation method of the superclass. */
3596 ret = ((struct aout_link_includes_entry *)
3597 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
3598 if (ret)
3600 /* Set local fields. */
3601 ret->totals = NULL;
3604 return (struct bfd_hash_entry *) ret;
3607 /* Do the final link step. This is called on the output BFD. The
3608 INFO structure should point to a list of BFDs linked through the
3609 link_next field which can be used to find each BFD which takes part
3610 in the output. Also, each section in ABFD should point to a list
3611 of bfd_link_order structures which list all the input sections for
3612 the output section. */
3614 boolean
3615 NAME(aout,final_link) (abfd, info, callback)
3616 bfd *abfd;
3617 struct bfd_link_info *info;
3618 void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
3620 struct aout_final_link_info aout_info;
3621 boolean includes_hash_initialized = false;
3622 register bfd *sub;
3623 bfd_size_type trsize, drsize;
3624 size_t max_contents_size;
3625 size_t max_relocs_size;
3626 size_t max_sym_count;
3627 bfd_size_type text_size;
3628 file_ptr text_end;
3629 register struct bfd_link_order *p;
3630 asection *o;
3631 boolean have_link_order_relocs;
3633 if (info->shared)
3634 abfd->flags |= DYNAMIC;
3636 aout_info.info = info;
3637 aout_info.output_bfd = abfd;
3638 aout_info.contents = NULL;
3639 aout_info.relocs = NULL;
3640 aout_info.symbol_map = NULL;
3641 aout_info.output_syms = NULL;
3643 if (! bfd_hash_table_init_n (&aout_info.includes.root,
3644 aout_link_includes_newfunc,
3645 251))
3646 goto error_return;
3647 includes_hash_initialized = true;
3649 /* Figure out the largest section size. Also, if generating
3650 relocateable output, count the relocs. */
3651 trsize = 0;
3652 drsize = 0;
3653 max_contents_size = 0;
3654 max_relocs_size = 0;
3655 max_sym_count = 0;
3656 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
3658 size_t sz;
3660 if (info->relocateable)
3662 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3664 trsize += exec_hdr (sub)->a_trsize;
3665 drsize += exec_hdr (sub)->a_drsize;
3667 else
3669 /* FIXME: We need to identify the .text and .data sections
3670 and call get_reloc_upper_bound and canonicalize_reloc to
3671 work out the number of relocs needed, and then multiply
3672 by the reloc size. */
3673 (*_bfd_error_handler)
3674 (_("%s: relocateable link from %s to %s not supported"),
3675 bfd_get_filename (abfd),
3676 sub->xvec->name, abfd->xvec->name);
3677 bfd_set_error (bfd_error_invalid_operation);
3678 goto error_return;
3682 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3684 sz = bfd_section_size (sub, obj_textsec (sub));
3685 if (sz > max_contents_size)
3686 max_contents_size = sz;
3687 sz = bfd_section_size (sub, obj_datasec (sub));
3688 if (sz > max_contents_size)
3689 max_contents_size = sz;
3691 sz = exec_hdr (sub)->a_trsize;
3692 if (sz > max_relocs_size)
3693 max_relocs_size = sz;
3694 sz = exec_hdr (sub)->a_drsize;
3695 if (sz > max_relocs_size)
3696 max_relocs_size = sz;
3698 sz = obj_aout_external_sym_count (sub);
3699 if (sz > max_sym_count)
3700 max_sym_count = sz;
3704 if (info->relocateable)
3706 if (obj_textsec (abfd) != (asection *) NULL)
3707 trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
3708 ->link_order_head)
3709 * obj_reloc_entry_size (abfd));
3710 if (obj_datasec (abfd) != (asection *) NULL)
3711 drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
3712 ->link_order_head)
3713 * obj_reloc_entry_size (abfd));
3716 exec_hdr (abfd)->a_trsize = trsize;
3717 exec_hdr (abfd)->a_drsize = drsize;
3719 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
3721 /* Adjust the section sizes and vmas according to the magic number.
3722 This sets a_text, a_data and a_bss in the exec_hdr and sets the
3723 filepos for each section. */
3724 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3725 goto error_return;
3727 /* The relocation and symbol file positions differ among a.out
3728 targets. We are passed a callback routine from the backend
3729 specific code to handle this.
3730 FIXME: At this point we do not know how much space the symbol
3731 table will require. This will not work for any (nonstandard)
3732 a.out target that needs to know the symbol table size before it
3733 can compute the relocation file positions. This may or may not
3734 be the case for the hp300hpux target, for example. */
3735 (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3736 &aout_info.symoff);
3737 obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3738 obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3739 obj_sym_filepos (abfd) = aout_info.symoff;
3741 /* We keep a count of the symbols as we output them. */
3742 obj_aout_external_sym_count (abfd) = 0;
3744 /* We accumulate the string table as we write out the symbols. */
3745 aout_info.strtab = _bfd_stringtab_init ();
3746 if (aout_info.strtab == NULL)
3747 goto error_return;
3749 /* Allocate buffers to hold section contents and relocs. */
3750 aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
3751 aout_info.relocs = (PTR) bfd_malloc (max_relocs_size);
3752 aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int *));
3753 aout_info.output_syms = ((struct external_nlist *)
3754 bfd_malloc ((max_sym_count + 1)
3755 * sizeof (struct external_nlist)));
3756 if ((aout_info.contents == NULL && max_contents_size != 0)
3757 || (aout_info.relocs == NULL && max_relocs_size != 0)
3758 || (aout_info.symbol_map == NULL && max_sym_count != 0)
3759 || aout_info.output_syms == NULL)
3760 goto error_return;
3762 /* If we have a symbol named __DYNAMIC, force it out now. This is
3763 required by SunOS. Doing this here rather than in sunos.c is a
3764 hack, but it's easier than exporting everything which would be
3765 needed. */
3767 struct aout_link_hash_entry *h;
3769 h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
3770 false, false, false);
3771 if (h != NULL)
3772 aout_link_write_other_symbol (h, &aout_info);
3775 /* The most time efficient way to do the link would be to read all
3776 the input object files into memory and then sort out the
3777 information into the output file. Unfortunately, that will
3778 probably use too much memory. Another method would be to step
3779 through everything that composes the text section and write it
3780 out, and then everything that composes the data section and write
3781 it out, and then write out the relocs, and then write out the
3782 symbols. Unfortunately, that requires reading stuff from each
3783 input file several times, and we will not be able to keep all the
3784 input files open simultaneously, and reopening them will be slow.
3786 What we do is basically process one input file at a time. We do
3787 everything we need to do with an input file once--copy over the
3788 section contents, handle the relocation information, and write
3789 out the symbols--and then we throw away the information we read
3790 from it. This approach requires a lot of lseeks of the output
3791 file, which is unfortunate but still faster than reopening a lot
3792 of files.
3794 We use the output_has_begun field of the input BFDs to see
3795 whether we have already handled it. */
3796 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3797 sub->output_has_begun = false;
3799 /* Mark all sections which are to be included in the link. This
3800 will normally be every section. We need to do this so that we
3801 can identify any sections which the linker has decided to not
3802 include. */
3803 for (o = abfd->sections; o != NULL; o = o->next)
3805 for (p = o->link_order_head; p != NULL; p = p->next)
3807 if (p->type == bfd_indirect_link_order)
3808 p->u.indirect.section->linker_mark = true;
3812 have_link_order_relocs = false;
3813 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3815 for (p = o->link_order_head;
3816 p != (struct bfd_link_order *) NULL;
3817 p = p->next)
3819 if (p->type == bfd_indirect_link_order
3820 && (bfd_get_flavour (p->u.indirect.section->owner)
3821 == bfd_target_aout_flavour))
3823 bfd *input_bfd;
3825 input_bfd = p->u.indirect.section->owner;
3826 if (! input_bfd->output_has_begun)
3828 if (! aout_link_input_bfd (&aout_info, input_bfd))
3829 goto error_return;
3830 input_bfd->output_has_begun = true;
3833 else if (p->type == bfd_section_reloc_link_order
3834 || p->type == bfd_symbol_reloc_link_order)
3836 /* These are handled below. */
3837 have_link_order_relocs = true;
3839 else
3841 if (! _bfd_default_link_order (abfd, info, o, p))
3842 goto error_return;
3847 /* Write out any symbols that we have not already written out. */
3848 aout_link_hash_traverse (aout_hash_table (info),
3849 aout_link_write_other_symbol,
3850 (PTR) &aout_info);
3852 /* Now handle any relocs we were asked to create by the linker.
3853 These did not come from any input file. We must do these after
3854 we have written out all the symbols, so that we know the symbol
3855 indices to use. */
3856 if (have_link_order_relocs)
3858 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3860 for (p = o->link_order_head;
3861 p != (struct bfd_link_order *) NULL;
3862 p = p->next)
3864 if (p->type == bfd_section_reloc_link_order
3865 || p->type == bfd_symbol_reloc_link_order)
3867 if (! aout_link_reloc_link_order (&aout_info, o, p))
3868 goto error_return;
3874 if (aout_info.contents != NULL)
3876 free (aout_info.contents);
3877 aout_info.contents = NULL;
3879 if (aout_info.relocs != NULL)
3881 free (aout_info.relocs);
3882 aout_info.relocs = NULL;
3884 if (aout_info.symbol_map != NULL)
3886 free (aout_info.symbol_map);
3887 aout_info.symbol_map = NULL;
3889 if (aout_info.output_syms != NULL)
3891 free (aout_info.output_syms);
3892 aout_info.output_syms = NULL;
3894 if (includes_hash_initialized)
3896 bfd_hash_table_free (&aout_info.includes.root);
3897 includes_hash_initialized = false;
3900 /* Finish up any dynamic linking we may be doing. */
3901 if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
3903 if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
3904 goto error_return;
3907 /* Update the header information. */
3908 abfd->symcount = obj_aout_external_sym_count (abfd);
3909 exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
3910 obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
3911 obj_textsec (abfd)->reloc_count =
3912 exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
3913 obj_datasec (abfd)->reloc_count =
3914 exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
3916 /* Write out the string table, unless there are no symbols. */
3917 if (abfd->symcount > 0)
3919 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
3920 || ! emit_stringtab (abfd, aout_info.strtab))
3921 goto error_return;
3923 else if (obj_textsec (abfd)->reloc_count == 0
3924 && obj_datasec (abfd)->reloc_count == 0)
3926 bfd_byte b;
3928 b = 0;
3929 if (bfd_seek (abfd,
3930 (obj_datasec (abfd)->filepos
3931 + exec_hdr (abfd)->a_data
3932 - 1),
3933 SEEK_SET) != 0
3934 || bfd_write (&b, 1, 1, abfd) != 1)
3935 goto error_return;
3938 return true;
3940 error_return:
3941 if (aout_info.contents != NULL)
3942 free (aout_info.contents);
3943 if (aout_info.relocs != NULL)
3944 free (aout_info.relocs);
3945 if (aout_info.symbol_map != NULL)
3946 free (aout_info.symbol_map);
3947 if (aout_info.output_syms != NULL)
3948 free (aout_info.output_syms);
3949 if (includes_hash_initialized)
3950 bfd_hash_table_free (&aout_info.includes.root);
3951 return false;
3954 /* Link an a.out input BFD into the output file. */
3956 static boolean
3957 aout_link_input_bfd (finfo, input_bfd)
3958 struct aout_final_link_info *finfo;
3959 bfd *input_bfd;
3961 bfd_size_type sym_count;
3963 BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
3965 /* If this is a dynamic object, it may need special handling. */
3966 if ((input_bfd->flags & DYNAMIC) != 0
3967 && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
3969 return ((*aout_backend_info (input_bfd)->link_dynamic_object)
3970 (finfo->info, input_bfd));
3973 /* Get the symbols. We probably have them already, unless
3974 finfo->info->keep_memory is false. */
3975 if (! aout_get_external_symbols (input_bfd))
3976 return false;
3978 sym_count = obj_aout_external_sym_count (input_bfd);
3980 /* Write out the symbols and get a map of the new indices. The map
3981 is placed into finfo->symbol_map. */
3982 if (! aout_link_write_symbols (finfo, input_bfd))
3983 return false;
3985 /* Relocate and write out the sections. These functions use the
3986 symbol map created by aout_link_write_symbols. The linker_mark
3987 field will be set if these sections are to be included in the
3988 link, which will normally be the case. */
3989 if (obj_textsec (input_bfd)->linker_mark)
3991 if (! aout_link_input_section (finfo, input_bfd,
3992 obj_textsec (input_bfd),
3993 &finfo->treloff,
3994 exec_hdr (input_bfd)->a_trsize))
3995 return false;
3997 if (obj_datasec (input_bfd)->linker_mark)
3999 if (! aout_link_input_section (finfo, input_bfd,
4000 obj_datasec (input_bfd),
4001 &finfo->dreloff,
4002 exec_hdr (input_bfd)->a_drsize))
4003 return false;
4006 /* If we are not keeping memory, we don't need the symbols any
4007 longer. We still need them if we are keeping memory, because the
4008 strings in the hash table point into them. */
4009 if (! finfo->info->keep_memory)
4011 if (! aout_link_free_symbols (input_bfd))
4012 return false;
4015 return true;
4018 /* Adjust and write out the symbols for an a.out file. Set the new
4019 symbol indices into a symbol_map. */
4021 static boolean
4022 aout_link_write_symbols (finfo, input_bfd)
4023 struct aout_final_link_info *finfo;
4024 bfd *input_bfd;
4026 bfd *output_bfd;
4027 bfd_size_type sym_count;
4028 char *strings;
4029 enum bfd_link_strip strip;
4030 enum bfd_link_discard discard;
4031 struct external_nlist *outsym;
4032 bfd_size_type strtab_index;
4033 register struct external_nlist *sym;
4034 struct external_nlist *sym_end;
4035 struct aout_link_hash_entry **sym_hash;
4036 int *symbol_map;
4037 boolean pass;
4038 boolean skip_next;
4040 output_bfd = finfo->output_bfd;
4041 sym_count = obj_aout_external_sym_count (input_bfd);
4042 strings = obj_aout_external_strings (input_bfd);
4043 strip = finfo->info->strip;
4044 discard = finfo->info->discard;
4045 outsym = finfo->output_syms;
4047 /* First write out a symbol for this object file, unless we are
4048 discarding such symbols. */
4049 if (strip != strip_all
4050 && (strip != strip_some
4051 || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
4052 false, false) != NULL)
4053 && discard != discard_all)
4055 bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type);
4056 bfd_h_put_8 (output_bfd, 0, outsym->e_other);
4057 bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc);
4058 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4059 input_bfd->filename, false);
4060 if (strtab_index == (bfd_size_type) -1)
4061 return false;
4062 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4063 PUT_WORD (output_bfd,
4064 (bfd_get_section_vma (output_bfd,
4065 obj_textsec (input_bfd)->output_section)
4066 + obj_textsec (input_bfd)->output_offset),
4067 outsym->e_value);
4068 ++obj_aout_external_sym_count (output_bfd);
4069 ++outsym;
4072 pass = false;
4073 skip_next = false;
4074 sym = obj_aout_external_syms (input_bfd);
4075 sym_end = sym + sym_count;
4076 sym_hash = obj_aout_sym_hashes (input_bfd);
4077 symbol_map = finfo->symbol_map;
4078 memset (symbol_map, 0, sym_count * sizeof *symbol_map);
4079 for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
4081 const char *name;
4082 int type;
4083 struct aout_link_hash_entry *h;
4084 boolean skip;
4085 asection *symsec;
4086 bfd_vma val = 0;
4087 boolean copy;
4089 /* We set *symbol_map to 0 above for all symbols. If it has
4090 already been set to -1 for this symbol, it means that we are
4091 discarding it because it appears in a duplicate header file.
4092 See the N_BINCL code below. */
4093 if (*symbol_map == -1)
4094 continue;
4096 /* Initialize *symbol_map to -1, which means that the symbol was
4097 not copied into the output file. We will change it later if
4098 we do copy the symbol over. */
4099 *symbol_map = -1;
4101 type = bfd_h_get_8 (input_bfd, sym->e_type);
4102 name = strings + GET_WORD (input_bfd, sym->e_strx);
4104 h = NULL;
4106 if (pass)
4108 /* Pass this symbol through. It is the target of an
4109 indirect or warning symbol. */
4110 val = GET_WORD (input_bfd, sym->e_value);
4111 pass = false;
4113 else if (skip_next)
4115 /* Skip this symbol, which is the target of an indirect
4116 symbol that we have changed to no longer be an indirect
4117 symbol. */
4118 skip_next = false;
4119 continue;
4121 else
4123 struct aout_link_hash_entry *hresolve;
4125 /* We have saved the hash table entry for this symbol, if
4126 there is one. Note that we could just look it up again
4127 in the hash table, provided we first check that it is an
4128 external symbol. */
4129 h = *sym_hash;
4131 /* Use the name from the hash table, in case the symbol was
4132 wrapped. */
4133 if (h != NULL)
4134 name = h->root.root.string;
4136 /* If this is an indirect or warning symbol, then change
4137 hresolve to the base symbol. We also change *sym_hash so
4138 that the relocation routines relocate against the real
4139 symbol. */
4140 hresolve = h;
4141 if (h != (struct aout_link_hash_entry *) NULL
4142 && (h->root.type == bfd_link_hash_indirect
4143 || h->root.type == bfd_link_hash_warning))
4145 hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
4146 while (hresolve->root.type == bfd_link_hash_indirect
4147 || hresolve->root.type == bfd_link_hash_warning)
4148 hresolve = ((struct aout_link_hash_entry *)
4149 hresolve->root.u.i.link);
4150 *sym_hash = hresolve;
4153 /* If the symbol has already been written out, skip it. */
4154 if (h != (struct aout_link_hash_entry *) NULL
4155 && h->root.type != bfd_link_hash_warning
4156 && h->written)
4158 if ((type & N_TYPE) == N_INDR
4159 || type == N_WARNING)
4160 skip_next = true;
4161 *symbol_map = h->indx;
4162 continue;
4165 /* See if we are stripping this symbol. */
4166 skip = false;
4167 switch (strip)
4169 case strip_none:
4170 break;
4171 case strip_debugger:
4172 if ((type & N_STAB) != 0)
4173 skip = true;
4174 break;
4175 case strip_some:
4176 if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
4177 == NULL)
4178 skip = true;
4179 break;
4180 case strip_all:
4181 skip = true;
4182 break;
4184 if (skip)
4186 if (h != (struct aout_link_hash_entry *) NULL)
4187 h->written = true;
4188 continue;
4191 /* Get the value of the symbol. */
4192 if ((type & N_TYPE) == N_TEXT
4193 || type == N_WEAKT)
4194 symsec = obj_textsec (input_bfd);
4195 else if ((type & N_TYPE) == N_DATA
4196 || type == N_WEAKD)
4197 symsec = obj_datasec (input_bfd);
4198 else if ((type & N_TYPE) == N_BSS
4199 || type == N_WEAKB)
4200 symsec = obj_bsssec (input_bfd);
4201 else if ((type & N_TYPE) == N_ABS
4202 || type == N_WEAKA)
4203 symsec = bfd_abs_section_ptr;
4204 else if (((type & N_TYPE) == N_INDR
4205 && (hresolve == (struct aout_link_hash_entry *) NULL
4206 || (hresolve->root.type != bfd_link_hash_defined
4207 && hresolve->root.type != bfd_link_hash_defweak
4208 && hresolve->root.type != bfd_link_hash_common)))
4209 || type == N_WARNING)
4211 /* Pass the next symbol through unchanged. The
4212 condition above for indirect symbols is so that if
4213 the indirect symbol was defined, we output it with
4214 the correct definition so the debugger will
4215 understand it. */
4216 pass = true;
4217 val = GET_WORD (input_bfd, sym->e_value);
4218 symsec = NULL;
4220 else if ((type & N_STAB) != 0)
4222 val = GET_WORD (input_bfd, sym->e_value);
4223 symsec = NULL;
4225 else
4227 /* If we get here with an indirect symbol, it means that
4228 we are outputting it with a real definition. In such
4229 a case we do not want to output the next symbol,
4230 which is the target of the indirection. */
4231 if ((type & N_TYPE) == N_INDR)
4232 skip_next = true;
4234 symsec = NULL;
4236 /* We need to get the value from the hash table. We use
4237 hresolve so that if we have defined an indirect
4238 symbol we output the final definition. */
4239 if (h == (struct aout_link_hash_entry *) NULL)
4241 switch (type & N_TYPE)
4243 case N_SETT:
4244 symsec = obj_textsec (input_bfd);
4245 break;
4246 case N_SETD:
4247 symsec = obj_datasec (input_bfd);
4248 break;
4249 case N_SETB:
4250 symsec = obj_bsssec (input_bfd);
4251 break;
4252 case N_SETA:
4253 symsec = bfd_abs_section_ptr;
4254 break;
4255 default:
4256 val = 0;
4257 break;
4260 else if (hresolve->root.type == bfd_link_hash_defined
4261 || hresolve->root.type == bfd_link_hash_defweak)
4263 asection *input_section;
4264 asection *output_section;
4266 /* This case usually means a common symbol which was
4267 turned into a defined symbol. */
4268 input_section = hresolve->root.u.def.section;
4269 output_section = input_section->output_section;
4270 BFD_ASSERT (bfd_is_abs_section (output_section)
4271 || output_section->owner == output_bfd);
4272 val = (hresolve->root.u.def.value
4273 + bfd_get_section_vma (output_bfd, output_section)
4274 + input_section->output_offset);
4276 /* Get the correct type based on the section. If
4277 this is a constructed set, force it to be
4278 globally visible. */
4279 if (type == N_SETT
4280 || type == N_SETD
4281 || type == N_SETB
4282 || type == N_SETA)
4283 type |= N_EXT;
4285 type &=~ N_TYPE;
4287 if (output_section == obj_textsec (output_bfd))
4288 type |= (hresolve->root.type == bfd_link_hash_defined
4289 ? N_TEXT
4290 : N_WEAKT);
4291 else if (output_section == obj_datasec (output_bfd))
4292 type |= (hresolve->root.type == bfd_link_hash_defined
4293 ? N_DATA
4294 : N_WEAKD);
4295 else if (output_section == obj_bsssec (output_bfd))
4296 type |= (hresolve->root.type == bfd_link_hash_defined
4297 ? N_BSS
4298 : N_WEAKB);
4299 else
4300 type |= (hresolve->root.type == bfd_link_hash_defined
4301 ? N_ABS
4302 : N_WEAKA);
4304 else if (hresolve->root.type == bfd_link_hash_common)
4305 val = hresolve->root.u.c.size;
4306 else if (hresolve->root.type == bfd_link_hash_undefweak)
4308 val = 0;
4309 type = N_WEAKU;
4311 else
4312 val = 0;
4314 if (symsec != (asection *) NULL)
4315 val = (symsec->output_section->vma
4316 + symsec->output_offset
4317 + (GET_WORD (input_bfd, sym->e_value)
4318 - symsec->vma));
4320 /* If this is a global symbol set the written flag, and if
4321 it is a local symbol see if we should discard it. */
4322 if (h != (struct aout_link_hash_entry *) NULL)
4324 h->written = true;
4325 h->indx = obj_aout_external_sym_count (output_bfd);
4327 else if ((type & N_TYPE) != N_SETT
4328 && (type & N_TYPE) != N_SETD
4329 && (type & N_TYPE) != N_SETB
4330 && (type & N_TYPE) != N_SETA)
4332 switch (discard)
4334 case discard_none:
4335 break;
4336 case discard_l:
4337 if ((type & N_STAB) == 0
4338 && bfd_is_local_label_name (input_bfd, name))
4339 skip = true;
4340 break;
4341 case discard_all:
4342 skip = true;
4343 break;
4345 if (skip)
4347 pass = false;
4348 continue;
4352 /* An N_BINCL symbol indicates the start of the stabs
4353 entries for a header file. We need to scan ahead to the
4354 next N_EINCL symbol, ignoring nesting, adding up all the
4355 characters in the symbol names, not including the file
4356 numbers in types (the first number after an open
4357 parenthesis). */
4358 if (type == N_BINCL)
4360 struct external_nlist *incl_sym;
4361 int nest;
4362 struct aout_link_includes_entry *incl_entry;
4363 struct aout_link_includes_totals *t;
4365 val = 0;
4366 nest = 0;
4367 for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
4369 int incl_type;
4371 incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
4372 if (incl_type == N_EINCL)
4374 if (nest == 0)
4375 break;
4376 --nest;
4378 else if (incl_type == N_BINCL)
4379 ++nest;
4380 else if (nest == 0)
4382 const char *s;
4384 s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
4385 for (; *s != '\0'; s++)
4387 val += *s;
4388 if (*s == '(')
4390 /* Skip the file number. */
4391 ++s;
4392 while (isdigit ((unsigned char) *s))
4393 ++s;
4394 --s;
4400 /* If we have already included a header file with the
4401 same value, then replace this one with an N_EXCL
4402 symbol. */
4403 copy = ! finfo->info->keep_memory;
4404 incl_entry = aout_link_includes_lookup (&finfo->includes,
4405 name, true, copy);
4406 if (incl_entry == NULL)
4407 return false;
4408 for (t = incl_entry->totals; t != NULL; t = t->next)
4409 if (t->total == val)
4410 break;
4411 if (t == NULL)
4413 /* This is the first time we have seen this header
4414 file with this set of stabs strings. */
4415 t = ((struct aout_link_includes_totals *)
4416 bfd_hash_allocate (&finfo->includes.root,
4417 sizeof *t));
4418 if (t == NULL)
4419 return false;
4420 t->total = val;
4421 t->next = incl_entry->totals;
4422 incl_entry->totals = t;
4424 else
4426 int *incl_map;
4428 /* This is a duplicate header file. We must change
4429 it to be an N_EXCL entry, and mark all the
4430 included symbols to prevent outputting them. */
4431 type = N_EXCL;
4433 nest = 0;
4434 for (incl_sym = sym + 1, incl_map = symbol_map + 1;
4435 incl_sym < sym_end;
4436 incl_sym++, incl_map++)
4438 int incl_type;
4440 incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
4441 if (incl_type == N_EINCL)
4443 if (nest == 0)
4445 *incl_map = -1;
4446 break;
4448 --nest;
4450 else if (incl_type == N_BINCL)
4451 ++nest;
4452 else if (nest == 0)
4453 *incl_map = -1;
4459 /* Copy this symbol into the list of symbols we are going to
4460 write out. */
4461 bfd_h_put_8 (output_bfd, type, outsym->e_type);
4462 bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other),
4463 outsym->e_other);
4464 bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc),
4465 outsym->e_desc);
4466 copy = false;
4467 if (! finfo->info->keep_memory)
4469 /* name points into a string table which we are going to
4470 free. If there is a hash table entry, use that string.
4471 Otherwise, copy name into memory. */
4472 if (h != (struct aout_link_hash_entry *) NULL)
4473 name = h->root.root.string;
4474 else
4475 copy = true;
4477 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4478 name, copy);
4479 if (strtab_index == (bfd_size_type) -1)
4480 return false;
4481 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4482 PUT_WORD (output_bfd, val, outsym->e_value);
4483 *symbol_map = obj_aout_external_sym_count (output_bfd);
4484 ++obj_aout_external_sym_count (output_bfd);
4485 ++outsym;
4488 /* Write out the output symbols we have just constructed. */
4489 if (outsym > finfo->output_syms)
4491 bfd_size_type outsym_count;
4493 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
4494 return false;
4495 outsym_count = outsym - finfo->output_syms;
4496 if (bfd_write ((PTR) finfo->output_syms,
4497 (bfd_size_type) EXTERNAL_NLIST_SIZE,
4498 (bfd_size_type) outsym_count, output_bfd)
4499 != outsym_count * EXTERNAL_NLIST_SIZE)
4500 return false;
4501 finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
4504 return true;
4507 /* Write out a symbol that was not associated with an a.out input
4508 object. */
4510 static boolean
4511 aout_link_write_other_symbol (h, data)
4512 struct aout_link_hash_entry *h;
4513 PTR data;
4515 struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
4516 bfd *output_bfd;
4517 int type;
4518 bfd_vma val;
4519 struct external_nlist outsym;
4520 bfd_size_type indx;
4522 output_bfd = finfo->output_bfd;
4524 if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
4526 if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
4527 (output_bfd, finfo->info, h)))
4529 /* FIXME: No way to handle errors. */
4530 abort ();
4534 if (h->written)
4535 return true;
4537 h->written = true;
4539 /* An indx of -2 means the symbol must be written. */
4540 if (h->indx != -2
4541 && (finfo->info->strip == strip_all
4542 || (finfo->info->strip == strip_some
4543 && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
4544 false, false) == NULL)))
4545 return true;
4547 switch (h->root.type)
4549 default:
4550 abort ();
4551 /* Avoid variable not initialized warnings. */
4552 return true;
4553 case bfd_link_hash_new:
4554 /* This can happen for set symbols when sets are not being
4555 built. */
4556 return true;
4557 case bfd_link_hash_undefined:
4558 type = N_UNDF | N_EXT;
4559 val = 0;
4560 break;
4561 case bfd_link_hash_defined:
4562 case bfd_link_hash_defweak:
4564 asection *sec;
4566 sec = h->root.u.def.section->output_section;
4567 BFD_ASSERT (bfd_is_abs_section (sec)
4568 || sec->owner == output_bfd);
4569 if (sec == obj_textsec (output_bfd))
4570 type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
4571 else if (sec == obj_datasec (output_bfd))
4572 type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
4573 else if (sec == obj_bsssec (output_bfd))
4574 type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
4575 else
4576 type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
4577 type |= N_EXT;
4578 val = (h->root.u.def.value
4579 + sec->vma
4580 + h->root.u.def.section->output_offset);
4582 break;
4583 case bfd_link_hash_common:
4584 type = N_UNDF | N_EXT;
4585 val = h->root.u.c.size;
4586 break;
4587 case bfd_link_hash_undefweak:
4588 type = N_WEAKU;
4589 val = 0;
4590 case bfd_link_hash_indirect:
4591 case bfd_link_hash_warning:
4592 /* FIXME: Ignore these for now. The circumstances under which
4593 they should be written out are not clear to me. */
4594 return true;
4597 bfd_h_put_8 (output_bfd, type, outsym.e_type);
4598 bfd_h_put_8 (output_bfd, 0, outsym.e_other);
4599 bfd_h_put_16 (output_bfd, 0, outsym.e_desc);
4600 indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
4601 false);
4602 if (indx == (bfd_size_type) -1)
4604 /* FIXME: No way to handle errors. */
4605 abort ();
4607 PUT_WORD (output_bfd, indx, outsym.e_strx);
4608 PUT_WORD (output_bfd, val, outsym.e_value);
4610 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
4611 || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE,
4612 (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE)
4614 /* FIXME: No way to handle errors. */
4615 abort ();
4618 finfo->symoff += EXTERNAL_NLIST_SIZE;
4619 h->indx = obj_aout_external_sym_count (output_bfd);
4620 ++obj_aout_external_sym_count (output_bfd);
4622 return true;
4625 /* Link an a.out section into the output file. */
4627 static boolean
4628 aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
4629 rel_size)
4630 struct aout_final_link_info *finfo;
4631 bfd *input_bfd;
4632 asection *input_section;
4633 file_ptr *reloff_ptr;
4634 bfd_size_type rel_size;
4636 bfd_size_type input_size;
4637 PTR relocs;
4639 /* Get the section contents. */
4640 input_size = bfd_section_size (input_bfd, input_section);
4641 if (! bfd_get_section_contents (input_bfd, input_section,
4642 (PTR) finfo->contents,
4643 (file_ptr) 0, input_size))
4644 return false;
4646 /* Read in the relocs if we haven't already done it. */
4647 if (aout_section_data (input_section) != NULL
4648 && aout_section_data (input_section)->relocs != NULL)
4649 relocs = aout_section_data (input_section)->relocs;
4650 else
4652 relocs = finfo->relocs;
4653 if (rel_size > 0)
4655 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
4656 || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
4657 return false;
4661 /* Relocate the section contents. */
4662 if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4664 if (! aout_link_input_section_std (finfo, input_bfd, input_section,
4665 (struct reloc_std_external *) relocs,
4666 rel_size, finfo->contents))
4667 return false;
4669 else
4671 if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
4672 (struct reloc_ext_external *) relocs,
4673 rel_size, finfo->contents))
4674 return false;
4677 /* Write out the section contents. */
4678 if (! bfd_set_section_contents (finfo->output_bfd,
4679 input_section->output_section,
4680 (PTR) finfo->contents,
4681 input_section->output_offset,
4682 input_size))
4683 return false;
4685 /* If we are producing relocateable output, the relocs were
4686 modified, and we now write them out. */
4687 if (finfo->info->relocateable && rel_size > 0)
4689 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
4690 return false;
4691 if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
4692 != rel_size)
4693 return false;
4694 *reloff_ptr += rel_size;
4696 /* Assert that the relocs have not run into the symbols, and
4697 that if these are the text relocs they have not run into the
4698 data relocs. */
4699 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
4700 && (reloff_ptr != &finfo->treloff
4701 || (*reloff_ptr
4702 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
4705 return true;
4708 /* Get the section corresponding to a reloc index. */
4710 static INLINE asection *
4711 aout_reloc_index_to_section (abfd, indx)
4712 bfd *abfd;
4713 int indx;
4715 switch (indx & N_TYPE)
4717 case N_TEXT:
4718 return obj_textsec (abfd);
4719 case N_DATA:
4720 return obj_datasec (abfd);
4721 case N_BSS:
4722 return obj_bsssec (abfd);
4723 case N_ABS:
4724 case N_UNDF:
4725 return bfd_abs_section_ptr;
4726 default:
4727 abort ();
4729 /*NOTREACHED*/
4730 return NULL;
4733 /* Relocate an a.out section using standard a.out relocs. */
4735 static boolean
4736 aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
4737 rel_size, contents)
4738 struct aout_final_link_info *finfo;
4739 bfd *input_bfd;
4740 asection *input_section;
4741 struct reloc_std_external *relocs;
4742 bfd_size_type rel_size;
4743 bfd_byte *contents;
4745 boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
4746 bfd *, asection *,
4747 struct aout_link_hash_entry *,
4748 PTR, bfd_byte *, boolean *,
4749 bfd_vma *));
4750 bfd *output_bfd;
4751 boolean relocateable;
4752 struct external_nlist *syms;
4753 char *strings;
4754 struct aout_link_hash_entry **sym_hashes;
4755 int *symbol_map;
4756 bfd_size_type reloc_count;
4757 register struct reloc_std_external *rel;
4758 struct reloc_std_external *rel_end;
4760 output_bfd = finfo->output_bfd;
4761 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4763 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
4764 BFD_ASSERT (input_bfd->xvec->header_byteorder
4765 == output_bfd->xvec->header_byteorder);
4767 relocateable = finfo->info->relocateable;
4768 syms = obj_aout_external_syms (input_bfd);
4769 strings = obj_aout_external_strings (input_bfd);
4770 sym_hashes = obj_aout_sym_hashes (input_bfd);
4771 symbol_map = finfo->symbol_map;
4773 reloc_count = rel_size / RELOC_STD_SIZE;
4774 rel = relocs;
4775 rel_end = rel + reloc_count;
4776 for (; rel < rel_end; rel++)
4778 bfd_vma r_addr;
4779 int r_index;
4780 int r_extern;
4781 int r_pcrel;
4782 int r_baserel = 0;
4783 reloc_howto_type *howto;
4784 struct aout_link_hash_entry *h = NULL;
4785 bfd_vma relocation;
4786 bfd_reloc_status_type r;
4788 r_addr = GET_SWORD (input_bfd, rel->r_address);
4790 #ifdef MY_reloc_howto
4791 howto = MY_reloc_howto(input_bfd, rel, r_index, r_extern, r_pcrel);
4792 #else
4794 int r_jmptable;
4795 int r_relative;
4796 int r_length;
4797 unsigned int howto_idx;
4799 if (bfd_header_big_endian (input_bfd))
4801 r_index = ((rel->r_index[0] << 16)
4802 | (rel->r_index[1] << 8)
4803 | rel->r_index[2]);
4804 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
4805 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
4806 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
4807 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
4808 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
4809 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
4810 >> RELOC_STD_BITS_LENGTH_SH_BIG);
4812 else
4814 r_index = ((rel->r_index[2] << 16)
4815 | (rel->r_index[1] << 8)
4816 | rel->r_index[0]);
4817 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
4818 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
4819 r_baserel = (0 != (rel->r_type[0]
4820 & RELOC_STD_BITS_BASEREL_LITTLE));
4821 r_jmptable= (0 != (rel->r_type[0]
4822 & RELOC_STD_BITS_JMPTABLE_LITTLE));
4823 r_relative= (0 != (rel->r_type[0]
4824 & RELOC_STD_BITS_RELATIVE_LITTLE));
4825 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
4826 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
4829 howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
4830 + 16 * r_jmptable + 32 * r_relative);
4831 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
4832 howto = howto_table_std + howto_idx;
4834 #endif
4836 if (relocateable)
4838 /* We are generating a relocateable output file, and must
4839 modify the reloc accordingly. */
4840 if (r_extern)
4842 /* If we know the symbol this relocation is against,
4843 convert it into a relocation against a section. This
4844 is what the native linker does. */
4845 h = sym_hashes[r_index];
4846 if (h != (struct aout_link_hash_entry *) NULL
4847 && (h->root.type == bfd_link_hash_defined
4848 || h->root.type == bfd_link_hash_defweak))
4850 asection *output_section;
4852 /* Change the r_extern value. */
4853 if (bfd_header_big_endian (output_bfd))
4854 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
4855 else
4856 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
4858 /* Compute a new r_index. */
4859 output_section = h->root.u.def.section->output_section;
4860 if (output_section == obj_textsec (output_bfd))
4861 r_index = N_TEXT;
4862 else if (output_section == obj_datasec (output_bfd))
4863 r_index = N_DATA;
4864 else if (output_section == obj_bsssec (output_bfd))
4865 r_index = N_BSS;
4866 else
4867 r_index = N_ABS;
4869 /* Add the symbol value and the section VMA to the
4870 addend stored in the contents. */
4871 relocation = (h->root.u.def.value
4872 + output_section->vma
4873 + h->root.u.def.section->output_offset);
4875 else
4877 /* We must change r_index according to the symbol
4878 map. */
4879 r_index = symbol_map[r_index];
4881 if (r_index == -1)
4883 if (h != NULL)
4885 /* We decided to strip this symbol, but it
4886 turns out that we can't. Note that we
4887 lose the other and desc information here.
4888 I don't think that will ever matter for a
4889 global symbol. */
4890 if (h->indx < 0)
4892 h->indx = -2;
4893 h->written = false;
4894 if (! aout_link_write_other_symbol (h,
4895 (PTR) finfo))
4896 return false;
4898 r_index = h->indx;
4900 else
4902 const char *name;
4904 name = strings + GET_WORD (input_bfd,
4905 syms[r_index].e_strx);
4906 if (! ((*finfo->info->callbacks->unattached_reloc)
4907 (finfo->info, name, input_bfd, input_section,
4908 r_addr)))
4909 return false;
4910 r_index = 0;
4914 relocation = 0;
4917 /* Write out the new r_index value. */
4918 if (bfd_header_big_endian (output_bfd))
4920 rel->r_index[0] = r_index >> 16;
4921 rel->r_index[1] = r_index >> 8;
4922 rel->r_index[2] = r_index;
4924 else
4926 rel->r_index[2] = r_index >> 16;
4927 rel->r_index[1] = r_index >> 8;
4928 rel->r_index[0] = r_index;
4931 else
4933 asection *section;
4935 /* This is a relocation against a section. We must
4936 adjust by the amount that the section moved. */
4937 section = aout_reloc_index_to_section (input_bfd, r_index);
4938 relocation = (section->output_section->vma
4939 + section->output_offset
4940 - section->vma);
4943 /* Change the address of the relocation. */
4944 PUT_WORD (output_bfd,
4945 r_addr + input_section->output_offset,
4946 rel->r_address);
4948 /* Adjust a PC relative relocation by removing the reference
4949 to the original address in the section and including the
4950 reference to the new address. */
4951 if (r_pcrel)
4952 relocation -= (input_section->output_section->vma
4953 + input_section->output_offset
4954 - input_section->vma);
4956 #ifdef MY_relocatable_reloc
4957 MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
4958 #endif
4960 if (relocation == 0)
4961 r = bfd_reloc_ok;
4962 else
4963 r = MY_relocate_contents (howto,
4964 input_bfd, relocation,
4965 contents + r_addr);
4967 else
4969 boolean hundef;
4971 /* We are generating an executable, and must do a full
4972 relocation. */
4973 hundef = false;
4975 if (r_extern)
4977 h = sym_hashes[r_index];
4979 if (h != (struct aout_link_hash_entry *) NULL
4980 && (h->root.type == bfd_link_hash_defined
4981 || h->root.type == bfd_link_hash_defweak))
4983 relocation = (h->root.u.def.value
4984 + h->root.u.def.section->output_section->vma
4985 + h->root.u.def.section->output_offset);
4987 else if (h != (struct aout_link_hash_entry *) NULL
4988 && h->root.type == bfd_link_hash_undefweak)
4989 relocation = 0;
4990 else
4992 hundef = true;
4993 relocation = 0;
4996 else
4998 asection *section;
5000 section = aout_reloc_index_to_section (input_bfd, r_index);
5001 relocation = (section->output_section->vma
5002 + section->output_offset
5003 - section->vma);
5004 if (r_pcrel)
5005 relocation += input_section->vma;
5008 if (check_dynamic_reloc != NULL)
5010 boolean skip;
5012 if (! ((*check_dynamic_reloc)
5013 (finfo->info, input_bfd, input_section, h,
5014 (PTR) rel, contents, &skip, &relocation)))
5015 return false;
5016 if (skip)
5017 continue;
5020 /* Now warn if a global symbol is undefined. We could not
5021 do this earlier, because check_dynamic_reloc might want
5022 to skip this reloc. */
5023 if (hundef && ! finfo->info->shared && ! r_baserel)
5025 const char *name;
5027 if (h != NULL)
5028 name = h->root.root.string;
5029 else
5030 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5031 if (! ((*finfo->info->callbacks->undefined_symbol)
5032 (finfo->info, name, input_bfd, input_section,
5033 r_addr, true)))
5034 return false;
5037 r = MY_final_link_relocate (howto,
5038 input_bfd, input_section,
5039 contents, r_addr, relocation,
5040 (bfd_vma) 0);
5043 if (r != bfd_reloc_ok)
5045 switch (r)
5047 default:
5048 case bfd_reloc_outofrange:
5049 abort ();
5050 case bfd_reloc_overflow:
5052 const char *name;
5054 if (h != NULL)
5055 name = h->root.root.string;
5056 else if (r_extern)
5057 name = strings + GET_WORD (input_bfd,
5058 syms[r_index].e_strx);
5059 else
5061 asection *s;
5063 s = aout_reloc_index_to_section (input_bfd, r_index);
5064 name = bfd_section_name (input_bfd, s);
5066 if (! ((*finfo->info->callbacks->reloc_overflow)
5067 (finfo->info, name, howto->name,
5068 (bfd_vma) 0, input_bfd, input_section, r_addr)))
5069 return false;
5071 break;
5076 return true;
5079 /* Relocate an a.out section using extended a.out relocs. */
5081 static boolean
5082 aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
5083 rel_size, contents)
5084 struct aout_final_link_info *finfo;
5085 bfd *input_bfd;
5086 asection *input_section;
5087 struct reloc_ext_external *relocs;
5088 bfd_size_type rel_size;
5089 bfd_byte *contents;
5091 boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
5092 bfd *, asection *,
5093 struct aout_link_hash_entry *,
5094 PTR, bfd_byte *, boolean *,
5095 bfd_vma *));
5096 bfd *output_bfd;
5097 boolean relocateable;
5098 struct external_nlist *syms;
5099 char *strings;
5100 struct aout_link_hash_entry **sym_hashes;
5101 int *symbol_map;
5102 bfd_size_type reloc_count;
5103 register struct reloc_ext_external *rel;
5104 struct reloc_ext_external *rel_end;
5106 output_bfd = finfo->output_bfd;
5107 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
5109 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
5110 BFD_ASSERT (input_bfd->xvec->header_byteorder
5111 == output_bfd->xvec->header_byteorder);
5113 relocateable = finfo->info->relocateable;
5114 syms = obj_aout_external_syms (input_bfd);
5115 strings = obj_aout_external_strings (input_bfd);
5116 sym_hashes = obj_aout_sym_hashes (input_bfd);
5117 symbol_map = finfo->symbol_map;
5119 reloc_count = rel_size / RELOC_EXT_SIZE;
5120 rel = relocs;
5121 rel_end = rel + reloc_count;
5122 for (; rel < rel_end; rel++)
5124 bfd_vma r_addr;
5125 int r_index;
5126 int r_extern;
5127 unsigned int r_type;
5128 bfd_vma r_addend;
5129 struct aout_link_hash_entry *h = NULL;
5130 asection *r_section = NULL;
5131 bfd_vma relocation;
5133 r_addr = GET_SWORD (input_bfd, rel->r_address);
5135 if (bfd_header_big_endian (input_bfd))
5137 r_index = ((rel->r_index[0] << 16)
5138 | (rel->r_index[1] << 8)
5139 | rel->r_index[2]);
5140 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
5141 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
5142 >> RELOC_EXT_BITS_TYPE_SH_BIG);
5144 else
5146 r_index = ((rel->r_index[2] << 16)
5147 | (rel->r_index[1] << 8)
5148 | rel->r_index[0]);
5149 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
5150 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
5151 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
5154 r_addend = GET_SWORD (input_bfd, rel->r_addend);
5156 BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
5158 if (relocateable)
5160 /* We are generating a relocateable output file, and must
5161 modify the reloc accordingly. */
5162 if (r_extern
5163 || r_type == RELOC_BASE10
5164 || r_type == RELOC_BASE13
5165 || r_type == RELOC_BASE22)
5167 /* If we know the symbol this relocation is against,
5168 convert it into a relocation against a section. This
5169 is what the native linker does. */
5170 if (r_type == RELOC_BASE10
5171 || r_type == RELOC_BASE13
5172 || r_type == RELOC_BASE22)
5173 h = NULL;
5174 else
5175 h = sym_hashes[r_index];
5176 if (h != (struct aout_link_hash_entry *) NULL
5177 && (h->root.type == bfd_link_hash_defined
5178 || h->root.type == bfd_link_hash_defweak))
5180 asection *output_section;
5182 /* Change the r_extern value. */
5183 if (bfd_header_big_endian (output_bfd))
5184 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
5185 else
5186 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
5188 /* Compute a new r_index. */
5189 output_section = h->root.u.def.section->output_section;
5190 if (output_section == obj_textsec (output_bfd))
5191 r_index = N_TEXT;
5192 else if (output_section == obj_datasec (output_bfd))
5193 r_index = N_DATA;
5194 else if (output_section == obj_bsssec (output_bfd))
5195 r_index = N_BSS;
5196 else
5197 r_index = N_ABS;
5199 /* Add the symbol value and the section VMA to the
5200 addend. */
5201 relocation = (h->root.u.def.value
5202 + output_section->vma
5203 + h->root.u.def.section->output_offset);
5205 /* Now RELOCATION is the VMA of the final
5206 destination. If this is a PC relative reloc,
5207 then ADDEND is the negative of the source VMA.
5208 We want to set ADDEND to the difference between
5209 the destination VMA and the source VMA, which
5210 means we must adjust RELOCATION by the change in
5211 the source VMA. This is done below. */
5213 else
5215 /* We must change r_index according to the symbol
5216 map. */
5217 r_index = symbol_map[r_index];
5219 if (r_index == -1)
5221 if (h != NULL)
5223 /* We decided to strip this symbol, but it
5224 turns out that we can't. Note that we
5225 lose the other and desc information here.
5226 I don't think that will ever matter for a
5227 global symbol. */
5228 if (h->indx < 0)
5230 h->indx = -2;
5231 h->written = false;
5232 if (! aout_link_write_other_symbol (h,
5233 (PTR) finfo))
5234 return false;
5236 r_index = h->indx;
5238 else
5240 const char *name;
5242 name = strings + GET_WORD (input_bfd,
5243 syms[r_index].e_strx);
5244 if (! ((*finfo->info->callbacks->unattached_reloc)
5245 (finfo->info, name, input_bfd, input_section,
5246 r_addr)))
5247 return false;
5248 r_index = 0;
5252 relocation = 0;
5254 /* If this is a PC relative reloc, then the addend
5255 is the negative of the source VMA. We must
5256 adjust it by the change in the source VMA. This
5257 is done below. */
5260 /* Write out the new r_index value. */
5261 if (bfd_header_big_endian (output_bfd))
5263 rel->r_index[0] = r_index >> 16;
5264 rel->r_index[1] = r_index >> 8;
5265 rel->r_index[2] = r_index;
5267 else
5269 rel->r_index[2] = r_index >> 16;
5270 rel->r_index[1] = r_index >> 8;
5271 rel->r_index[0] = r_index;
5274 else
5276 /* This is a relocation against a section. We must
5277 adjust by the amount that the section moved. */
5278 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5279 relocation = (r_section->output_section->vma
5280 + r_section->output_offset
5281 - r_section->vma);
5283 /* If this is a PC relative reloc, then the addend is
5284 the difference in VMA between the destination and the
5285 source. We have just adjusted for the change in VMA
5286 of the destination, so we must also adjust by the
5287 change in VMA of the source. This is done below. */
5290 /* As described above, we must always adjust a PC relative
5291 reloc by the change in VMA of the source. However, if
5292 pcrel_offset is set, then the addend does not include the
5293 location within the section, in which case we don't need
5294 to adjust anything. */
5295 if (howto_table_ext[r_type].pc_relative
5296 && ! howto_table_ext[r_type].pcrel_offset)
5297 relocation -= (input_section->output_section->vma
5298 + input_section->output_offset
5299 - input_section->vma);
5301 /* Change the addend if necessary. */
5302 if (relocation != 0)
5303 PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
5305 /* Change the address of the relocation. */
5306 PUT_WORD (output_bfd,
5307 r_addr + input_section->output_offset,
5308 rel->r_address);
5310 else
5312 boolean hundef;
5313 bfd_reloc_status_type r;
5315 /* We are generating an executable, and must do a full
5316 relocation. */
5317 hundef = false;
5319 if (r_extern)
5321 h = sym_hashes[r_index];
5323 if (h != (struct aout_link_hash_entry *) NULL
5324 && (h->root.type == bfd_link_hash_defined
5325 || h->root.type == bfd_link_hash_defweak))
5327 relocation = (h->root.u.def.value
5328 + h->root.u.def.section->output_section->vma
5329 + h->root.u.def.section->output_offset);
5331 else if (h != (struct aout_link_hash_entry *) NULL
5332 && h->root.type == bfd_link_hash_undefweak)
5333 relocation = 0;
5334 else
5336 hundef = true;
5337 relocation = 0;
5340 else if (r_type == RELOC_BASE10
5341 || r_type == RELOC_BASE13
5342 || r_type == RELOC_BASE22)
5344 struct external_nlist *sym;
5345 int type;
5347 /* For base relative relocs, r_index is always an index
5348 into the symbol table, even if r_extern is 0. */
5349 sym = syms + r_index;
5350 type = bfd_h_get_8 (input_bfd, sym->e_type);
5351 if ((type & N_TYPE) == N_TEXT
5352 || type == N_WEAKT)
5353 r_section = obj_textsec (input_bfd);
5354 else if ((type & N_TYPE) == N_DATA
5355 || type == N_WEAKD)
5356 r_section = obj_datasec (input_bfd);
5357 else if ((type & N_TYPE) == N_BSS
5358 || type == N_WEAKB)
5359 r_section = obj_bsssec (input_bfd);
5360 else if ((type & N_TYPE) == N_ABS
5361 || type == N_WEAKA)
5362 r_section = bfd_abs_section_ptr;
5363 else
5364 abort ();
5365 relocation = (r_section->output_section->vma
5366 + r_section->output_offset
5367 + (GET_WORD (input_bfd, sym->e_value)
5368 - r_section->vma));
5370 else
5372 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5374 /* If this is a PC relative reloc, then R_ADDEND is the
5375 difference between the two vmas, or
5376 old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
5377 where
5378 old_dest_sec == section->vma
5380 old_src_sec == input_section->vma
5382 old_src_off == r_addr
5384 _bfd_final_link_relocate expects RELOCATION +
5385 R_ADDEND to be the VMA of the destination minus
5386 r_addr (the minus r_addr is because this relocation
5387 is not pcrel_offset, which is a bit confusing and
5388 should, perhaps, be changed), or
5389 new_dest_sec
5390 where
5391 new_dest_sec == output_section->vma + output_offset
5392 We arrange for this to happen by setting RELOCATION to
5393 new_dest_sec + old_src_sec - old_dest_sec
5395 If this is not a PC relative reloc, then R_ADDEND is
5396 simply the VMA of the destination, so we set
5397 RELOCATION to the change in the destination VMA, or
5398 new_dest_sec - old_dest_sec
5400 relocation = (r_section->output_section->vma
5401 + r_section->output_offset
5402 - r_section->vma);
5403 if (howto_table_ext[r_type].pc_relative)
5404 relocation += input_section->vma;
5407 if (check_dynamic_reloc != NULL)
5409 boolean skip;
5411 if (! ((*check_dynamic_reloc)
5412 (finfo->info, input_bfd, input_section, h,
5413 (PTR) rel, contents, &skip, &relocation)))
5414 return false;
5415 if (skip)
5416 continue;
5419 /* Now warn if a global symbol is undefined. We could not
5420 do this earlier, because check_dynamic_reloc might want
5421 to skip this reloc. */
5422 if (hundef
5423 && ! finfo->info->shared
5424 && r_type != RELOC_BASE10
5425 && r_type != RELOC_BASE13
5426 && r_type != RELOC_BASE22)
5428 const char *name;
5430 if (h != NULL)
5431 name = h->root.root.string;
5432 else
5433 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5434 if (! ((*finfo->info->callbacks->undefined_symbol)
5435 (finfo->info, name, input_bfd, input_section,
5436 r_addr, true)))
5437 return false;
5440 if (r_type != RELOC_SPARC_REV32)
5441 r = MY_final_link_relocate (howto_table_ext + r_type,
5442 input_bfd, input_section,
5443 contents, r_addr, relocation,
5444 r_addend);
5445 else
5447 bfd_vma x;
5449 x = bfd_get_32 (input_bfd, contents + r_addr);
5450 x = x + relocation + r_addend;
5451 bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
5452 r = bfd_reloc_ok;
5455 if (r != bfd_reloc_ok)
5457 switch (r)
5459 default:
5460 case bfd_reloc_outofrange:
5461 abort ();
5462 case bfd_reloc_overflow:
5464 const char *name;
5466 if (h != NULL)
5467 name = h->root.root.string;
5468 else if (r_extern
5469 || r_type == RELOC_BASE10
5470 || r_type == RELOC_BASE13
5471 || r_type == RELOC_BASE22)
5472 name = strings + GET_WORD (input_bfd,
5473 syms[r_index].e_strx);
5474 else
5476 asection *s;
5478 s = aout_reloc_index_to_section (input_bfd, r_index);
5479 name = bfd_section_name (input_bfd, s);
5481 if (! ((*finfo->info->callbacks->reloc_overflow)
5482 (finfo->info, name, howto_table_ext[r_type].name,
5483 r_addend, input_bfd, input_section, r_addr)))
5484 return false;
5486 break;
5492 return true;
5495 /* Handle a link order which is supposed to generate a reloc. */
5497 static boolean
5498 aout_link_reloc_link_order (finfo, o, p)
5499 struct aout_final_link_info *finfo;
5500 asection *o;
5501 struct bfd_link_order *p;
5503 struct bfd_link_order_reloc *pr;
5504 int r_index;
5505 int r_extern;
5506 reloc_howto_type *howto;
5507 file_ptr *reloff_ptr = NULL;
5508 struct reloc_std_external srel;
5509 struct reloc_ext_external erel;
5510 PTR rel_ptr;
5512 pr = p->u.reloc.p;
5514 if (p->type == bfd_section_reloc_link_order)
5516 r_extern = 0;
5517 if (bfd_is_abs_section (pr->u.section))
5518 r_index = N_ABS | N_EXT;
5519 else
5521 BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
5522 r_index = pr->u.section->target_index;
5525 else
5527 struct aout_link_hash_entry *h;
5529 BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
5530 r_extern = 1;
5531 h = ((struct aout_link_hash_entry *)
5532 bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
5533 pr->u.name, false, false, true));
5534 if (h != (struct aout_link_hash_entry *) NULL
5535 && h->indx >= 0)
5536 r_index = h->indx;
5537 else if (h != NULL)
5539 /* We decided to strip this symbol, but it turns out that we
5540 can't. Note that we lose the other and desc information
5541 here. I don't think that will ever matter for a global
5542 symbol. */
5543 h->indx = -2;
5544 h->written = false;
5545 if (! aout_link_write_other_symbol (h, (PTR) finfo))
5546 return false;
5547 r_index = h->indx;
5549 else
5551 if (! ((*finfo->info->callbacks->unattached_reloc)
5552 (finfo->info, pr->u.name, (bfd *) NULL,
5553 (asection *) NULL, (bfd_vma) 0)))
5554 return false;
5555 r_index = 0;
5559 howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
5560 if (howto == 0)
5562 bfd_set_error (bfd_error_bad_value);
5563 return false;
5566 if (o == obj_textsec (finfo->output_bfd))
5567 reloff_ptr = &finfo->treloff;
5568 else if (o == obj_datasec (finfo->output_bfd))
5569 reloff_ptr = &finfo->dreloff;
5570 else
5571 abort ();
5573 if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
5575 #ifdef MY_put_reloc
5576 MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto,
5577 &srel);
5578 #else
5580 int r_pcrel;
5581 int r_baserel;
5582 int r_jmptable;
5583 int r_relative;
5584 int r_length;
5586 r_pcrel = howto->pc_relative;
5587 r_baserel = (howto->type & 8) != 0;
5588 r_jmptable = (howto->type & 16) != 0;
5589 r_relative = (howto->type & 32) != 0;
5590 r_length = howto->size;
5592 PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
5593 if (bfd_header_big_endian (finfo->output_bfd))
5595 srel.r_index[0] = r_index >> 16;
5596 srel.r_index[1] = r_index >> 8;
5597 srel.r_index[2] = r_index;
5598 srel.r_type[0] =
5599 ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
5600 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
5601 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
5602 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
5603 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
5604 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
5606 else
5608 srel.r_index[2] = r_index >> 16;
5609 srel.r_index[1] = r_index >> 8;
5610 srel.r_index[0] = r_index;
5611 srel.r_type[0] =
5612 ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
5613 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
5614 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
5615 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
5616 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
5617 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
5620 #endif
5621 rel_ptr = (PTR) &srel;
5623 /* We have to write the addend into the object file, since
5624 standard a.out relocs are in place. It would be more
5625 reliable if we had the current contents of the file here,
5626 rather than assuming zeroes, but we can't read the file since
5627 it was opened using bfd_openw. */
5628 if (pr->addend != 0)
5630 bfd_size_type size;
5631 bfd_reloc_status_type r;
5632 bfd_byte *buf;
5633 boolean ok;
5635 size = bfd_get_reloc_size (howto);
5636 buf = (bfd_byte *) bfd_zmalloc (size);
5637 if (buf == (bfd_byte *) NULL)
5638 return false;
5639 r = MY_relocate_contents (howto, finfo->output_bfd,
5640 pr->addend, buf);
5641 switch (r)
5643 case bfd_reloc_ok:
5644 break;
5645 default:
5646 case bfd_reloc_outofrange:
5647 abort ();
5648 case bfd_reloc_overflow:
5649 if (! ((*finfo->info->callbacks->reloc_overflow)
5650 (finfo->info,
5651 (p->type == bfd_section_reloc_link_order
5652 ? bfd_section_name (finfo->output_bfd,
5653 pr->u.section)
5654 : pr->u.name),
5655 howto->name, pr->addend, (bfd *) NULL,
5656 (asection *) NULL, (bfd_vma) 0)))
5658 free (buf);
5659 return false;
5661 break;
5663 ok = bfd_set_section_contents (finfo->output_bfd, o,
5664 (PTR) buf,
5665 (file_ptr) p->offset,
5666 size);
5667 free (buf);
5668 if (! ok)
5669 return false;
5672 else
5674 PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
5676 if (bfd_header_big_endian (finfo->output_bfd))
5678 erel.r_index[0] = r_index >> 16;
5679 erel.r_index[1] = r_index >> 8;
5680 erel.r_index[2] = r_index;
5681 erel.r_type[0] =
5682 ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
5683 | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
5685 else
5687 erel.r_index[2] = r_index >> 16;
5688 erel.r_index[1] = r_index >> 8;
5689 erel.r_index[0] = r_index;
5690 erel.r_type[0] =
5691 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
5692 | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
5695 PUT_WORD (finfo->output_bfd, pr->addend, erel.r_addend);
5697 rel_ptr = (PTR) &erel;
5700 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
5701 || (bfd_write (rel_ptr, (bfd_size_type) 1,
5702 obj_reloc_entry_size (finfo->output_bfd),
5703 finfo->output_bfd)
5704 != obj_reloc_entry_size (finfo->output_bfd)))
5705 return false;
5707 *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
5709 /* Assert that the relocs have not run into the symbols, and that n
5710 the text relocs have not run into the data relocs. */
5711 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
5712 && (reloff_ptr != &finfo->treloff
5713 || (*reloff_ptr
5714 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
5716 return true;