source: trunk/src/binutils/bfd/aoutx.h@ 536

Last change on this file since 536 was 100, checked in by bird, 22 years ago

review. Added some comments and #ifs.

  • Property cvs2svn:cvs-rev set to 1.3
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 166.3 KB
Line 
1/* BFD semi-generic back-end for a.out binaries.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
3 2001
4 Free Software Foundation, Inc.
5 Written by Cygnus Support.
6
7This file is part of BFD, the Binary File Descriptor library.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23/*
24SECTION
25 a.out backends
26
27DESCRIPTION
28
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.
33
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.
40
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.
45
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.
51
52 As an example, this is what goes on to make the back end for a
53 sun4, from @file{aout32.c}:
54
55| #define ARCH_SIZE 32
56| #include "aoutx.h"
57
58 Which exports names:
59
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| ...
66
67 from @file{sunos.c}:
68
69| #define TARGET_NAME "a.out-sunos-big"
70| #define VECNAME sunos_big_vec
71| #include "aoutf1.h"
72
73 requires all the names from @file{aout32.c}, and produces the jump vector
74
75| sunos_big_vec
76
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.
86
87 When porting it to run on a new system, you must supply:
88
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
95
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:
101
102| TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
103| TDEPFILES= host-aout.o trad-core.o
104
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.
109
110*/
111
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.) */
120
121#define KEEPIT udata.i
122
123#include <ctype.h>
124#include "bfd.h"
125#include "sysdep.h"
126#include "bfdlink.h"
127
128#include "libaout.h"
129#include "libbfd.h"
130#include "aout/aout64.h"
131#include "aout/stab_gnu.h"
132#include "aout/ar.h"
133
134static boolean aout_get_external_symbols PARAMS ((bfd *));
135static boolean translate_from_native_sym_flags
136 PARAMS ((bfd *, aout_symbol_type *));
137static boolean translate_to_native_sym_flags
138 PARAMS ((bfd *, asymbol *, struct external_nlist *));
139static void adjust_o_magic PARAMS ((bfd *, struct internal_exec *));
140static void adjust_z_magic PARAMS ((bfd *, struct internal_exec *));
141static void adjust_n_magic PARAMS ((bfd *, struct internal_exec *));
142
143/*
144SUBSECTION
145 Relocations
146
147DESCRIPTION
148 The file @file{aoutx.h} provides for both the @emph{standard}
149 and @emph{extended} forms of a.out relocation records.
150
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.
155
156*/
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
163
164#ifndef MY_swap_std_reloc_in
165#define MY_swap_std_reloc_in NAME(aout,swap_std_reloc_in)
166#endif
167
168#ifndef MY_swap_ext_reloc_in
169#define MY_swap_ext_reloc_in NAME(aout,swap_ext_reloc_in)
170#endif
171
172#ifndef MY_swap_std_reloc_out
173#define MY_swap_std_reloc_out NAME(aout,swap_std_reloc_out)
174#endif
175
176#ifndef MY_swap_ext_reloc_out
177#define MY_swap_ext_reloc_out NAME(aout,swap_ext_reloc_out)
178#endif
179
180#ifndef MY_final_link_relocate
181#define MY_final_link_relocate _bfd_final_link_relocate
182#endif
183
184#ifndef MY_relocate_contents
185#define MY_relocate_contents _bfd_relocate_contents
186#endif
187
188#define howto_table_ext NAME(aout,ext_howto_table)
189#define howto_table_std NAME(aout,std_howto_table)
190
191reloc_howto_type howto_table_ext[] =
192{
193 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
194 HOWTO(RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", false, 0,0x000000ff, false),
195 HOWTO(RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", false, 0,0x0000ffff, false),
196 HOWTO(RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", false, 0,0xffffffff, false),
197 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, complain_overflow_signed,0,"DISP8", false, 0,0x000000ff, false),
198 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, complain_overflow_signed,0,"DISP16", false, 0,0x0000ffff, false),
199 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, complain_overflow_signed,0,"DISP32", false, 0,0xffffffff, false),
200 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, complain_overflow_signed,0,"WDISP30", false, 0,0x3fffffff, false),
201 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, complain_overflow_signed,0,"WDISP22", false, 0,0x003fffff, false),
202 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"HI22", false, 0,0x003fffff, false),
203 HOWTO(RELOC_22, 0, 2, 22, false, 0, complain_overflow_bitfield,0,"22", false, 0,0x003fffff, false),
204 HOWTO(RELOC_13, 0, 2, 13, false, 0, complain_overflow_bitfield,0,"13", false, 0,0x00001fff, false),
205 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, complain_overflow_dont,0,"LO10", false, 0,0x000003ff, false),
206 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, complain_overflow_bitfield,0,"SFA_BASE", false, 0,0xffffffff, false),
207 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, complain_overflow_bitfield,0,"SFA_OFF13",false, 0,0xffffffff, false),
208 HOWTO(RELOC_BASE10, 0, 2, 10, false, 0, complain_overflow_dont,0,"BASE10", false, 0,0x000003ff, false),
209 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, complain_overflow_signed,0,"BASE13", false, 0,0x00001fff, false),
210 HOWTO(RELOC_BASE22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"BASE22", false, 0,0x003fffff, false),
211 HOWTO(RELOC_PC10, 0, 2, 10, true, 0, complain_overflow_dont,0,"PC10", false, 0,0x000003ff, true),
212 HOWTO(RELOC_PC22, 10, 2, 22, true, 0, complain_overflow_signed,0,"PC22", false, 0,0x003fffff, true),
213 HOWTO(RELOC_JMP_TBL,2, 2, 30, true, 0, complain_overflow_signed,0,"JMP_TBL", false, 0,0x3fffffff, false),
214 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, complain_overflow_bitfield,0,"SEGOFF16", false, 0,0x00000000, false),
215 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"GLOB_DAT", false, 0,0x00000000, false),
216 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_SLOT", false, 0,0x00000000, false),
217 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false),
218 HOWTO(0, 0, 0, 0, false, 0, complain_overflow_dont, 0, "R_SPARC_NONE", false,0,0x00000000,true),
219 HOWTO(0, 0, 0, 0, false, 0, complain_overflow_dont, 0, "R_SPARC_NONE", false,0,0x00000000,true),
220#define RELOC_SPARC_REV32 RELOC_WDISP19
221 HOWTO(RELOC_SPARC_REV32, 0, 2, 32, false, 0, complain_overflow_dont,0,"R_SPARC_REV32", false, 0,0xffffffff, false),
222};
223
224/* Convert standard reloc records to "arelent" format (incl byte swap). */
225
226reloc_howto_type howto_table_std[] = {
227 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
228HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false),
229HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false),
230HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false),
231HOWTO( 3, 0, 4, 64, false, 0, complain_overflow_bitfield,0,"64", true, 0xdeaddead,0xdeaddead, false),
232HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, false),
233HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
234HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, false),
235HOWTO( 7, 0, 4, 64, true, 0, complain_overflow_signed, 0,"DISP64", true, 0xfeedface,0xfeedface, false),
236HOWTO( 8, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"GOT_REL", false, 0,0x00000000, false),
237HOWTO( 9, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"BASE16", false,0xffffffff,0xffffffff, false),
238HOWTO(10, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"BASE32", false,0xffffffff,0xffffffff, false),
239EMPTY_HOWTO (-1),
240EMPTY_HOWTO (-1),
241EMPTY_HOWTO (-1),
242EMPTY_HOWTO (-1),
243EMPTY_HOWTO (-1),
244 HOWTO(16, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_TABLE", false, 0,0x00000000, false),
245EMPTY_HOWTO (-1),
246EMPTY_HOWTO (-1),
247EMPTY_HOWTO (-1),
248EMPTY_HOWTO (-1),
249EMPTY_HOWTO (-1),
250EMPTY_HOWTO (-1),
251EMPTY_HOWTO (-1),
252EMPTY_HOWTO (-1),
253EMPTY_HOWTO (-1),
254EMPTY_HOWTO (-1),
255EMPTY_HOWTO (-1),
256EMPTY_HOWTO (-1),
257EMPTY_HOWTO (-1),
258EMPTY_HOWTO (-1),
259EMPTY_HOWTO (-1),
260 HOWTO(32, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false),
261EMPTY_HOWTO (-1),
262EMPTY_HOWTO (-1),
263EMPTY_HOWTO (-1),
264EMPTY_HOWTO (-1),
265EMPTY_HOWTO (-1),
266EMPTY_HOWTO (-1),
267EMPTY_HOWTO (-1),
268 HOWTO(40, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"BASEREL", false, 0,0x00000000, false),
269};
270
271#define TABLE_SIZE(TABLE) (sizeof (TABLE)/sizeof (TABLE[0]))
272
273#ifndef IS_STAB
274# define IS_STAB(flags) ((flags) & N_STAB)
275#endif
276
277reloc_howto_type *
278NAME(aout,reloc_type_lookup) (abfd,code)
279 bfd *abfd;
280 bfd_reloc_code_real_type code;
281{
282#define EXT(i,j) case i: return &howto_table_ext[j]
283#define STD(i,j) case i: return &howto_table_std[j]
284 int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
285 if (code == BFD_RELOC_CTOR)
286 switch (bfd_get_arch_info (abfd)->bits_per_address)
287 {
288 case 32:
289 code = BFD_RELOC_32;
290 break;
291 case 64:
292 code = BFD_RELOC_64;
293 break;
294 }
295 if (ext)
296 switch (code)
297 {
298 EXT (BFD_RELOC_8, 0);
299 EXT (BFD_RELOC_16, 1);
300 EXT (BFD_RELOC_32, 2);
301 EXT (BFD_RELOC_HI22, 8);
302 EXT (BFD_RELOC_LO10, 11);
303 EXT (BFD_RELOC_32_PCREL_S2, 6);
304 EXT (BFD_RELOC_SPARC_WDISP22, 7);
305 EXT (BFD_RELOC_SPARC13, 10);
306 EXT (BFD_RELOC_SPARC_GOT10, 14);
307 EXT (BFD_RELOC_SPARC_BASE13, 15);
308 EXT (BFD_RELOC_SPARC_GOT13, 15);
309 EXT (BFD_RELOC_SPARC_GOT22, 16);
310 EXT (BFD_RELOC_SPARC_PC10, 17);
311 EXT (BFD_RELOC_SPARC_PC22, 18);
312 EXT (BFD_RELOC_SPARC_WPLT30, 19);
313 EXT (BFD_RELOC_SPARC_REV32, 26);
314 default: return (reloc_howto_type *) NULL;
315 }
316 else
317 /* std relocs */
318 switch (code)
319 {
320 STD (BFD_RELOC_16, 1);
321 STD (BFD_RELOC_32, 2);
322 STD (BFD_RELOC_8_PCREL, 4);
323 STD (BFD_RELOC_16_PCREL, 5);
324 STD (BFD_RELOC_32_PCREL, 6);
325 STD (BFD_RELOC_16_BASEREL, 9);
326 STD (BFD_RELOC_32_BASEREL, 10);
327 default: return (reloc_howto_type *) NULL;
328 }
329}
330
331/*
332SUBSECTION
333 Internal entry points
334
335DESCRIPTION
336 @file{aoutx.h} exports several routines for accessing the
337 contents of an a.out file, which are gathered and exported in
338 turn by various format specific files (eg sunos.c).
339
340*/
341
342/*
343FUNCTION
344 aout_@var{size}_swap_exec_header_in
345
346SYNOPSIS
347 void aout_@var{size}_swap_exec_header_in,
348 (bfd *abfd,
349 struct external_exec *raw_bytes,
350 struct internal_exec *execp);
351
352DESCRIPTION
353 Swap the information in an executable header @var{raw_bytes} taken
354 from a raw byte stream memory image into the internal exec header
355 structure @var{execp}.
356*/
357
358#ifndef NAME_swap_exec_header_in
359void
360NAME(aout,swap_exec_header_in) (abfd, raw_bytes, execp)
361 bfd *abfd;
362 struct external_exec *raw_bytes;
363 struct internal_exec *execp;
364{
365 struct external_exec *bytes = (struct external_exec *)raw_bytes;
366
367 /* The internal_exec structure has some fields that are unused in this
368 configuration (IE for i960), so ensure that all such uninitialized
369 fields are zero'd out. There are places where two of these structs
370 are memcmp'd, and thus the contents do matter. */
371 memset ((PTR) execp, 0, sizeof (struct internal_exec));
372 /* Now fill in fields in the execp, from the bytes in the raw data. */
373 execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
374 execp->a_text = GET_WORD (abfd, bytes->e_text);
375 execp->a_data = GET_WORD (abfd, bytes->e_data);
376 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
377 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
378 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
379 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
380 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
381}
382#define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
383#endif
384
385/*
386FUNCTION
387 aout_@var{size}_swap_exec_header_out
388
389SYNOPSIS
390 void aout_@var{size}_swap_exec_header_out
391 (bfd *abfd,
392 struct internal_exec *execp,
393 struct external_exec *raw_bytes);
394
395DESCRIPTION
396 Swap the information in an internal exec header structure
397 @var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
398*/
399void
400NAME(aout,swap_exec_header_out) (abfd, execp, raw_bytes)
401 bfd *abfd;
402 struct internal_exec *execp;
403 struct external_exec *raw_bytes;
404{
405 struct external_exec *bytes = (struct external_exec *)raw_bytes;
406
407 /* Now fill in fields in the raw data, from the fields in the exec struct. */
408 bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
409 PUT_WORD (abfd, execp->a_text , bytes->e_text);
410 PUT_WORD (abfd, execp->a_data , bytes->e_data);
411 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
412 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
413 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
414 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
415 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
416}
417
418/* Make all the section for an a.out file. */
419
420boolean
421NAME(aout,make_sections) (abfd)
422 bfd *abfd;
423{
424 if (obj_textsec (abfd) == (asection *) NULL
425 && bfd_make_section (abfd, ".text") == (asection *) NULL)
426 return false;
427 if (obj_datasec (abfd) == (asection *) NULL
428 && bfd_make_section (abfd, ".data") == (asection *) NULL)
429 return false;
430 if (obj_bsssec (abfd) == (asection *) NULL
431 && bfd_make_section (abfd, ".bss") == (asection *) NULL)
432 return false;
433 return true;
434}
435
436/*
437FUNCTION
438 aout_@var{size}_some_aout_object_p
439
440SYNOPSIS
441 const bfd_target *aout_@var{size}_some_aout_object_p
442 (bfd *abfd,
443 const bfd_target *(*callback_to_real_object_p) ());
444
445DESCRIPTION
446 Some a.out variant thinks that the file open in @var{abfd}
447 checking is an a.out file. Do some more checking, and set up
448 for access if it really is. Call back to the calling
449 environment's "finish up" function just before returning, to
450 handle any last-minute setup.
451*/
452
453const bfd_target *
454NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
455 bfd *abfd;
456 struct internal_exec *execp;
457 const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *));
458{
459 struct aout_data_struct *rawptr, *oldrawptr;
460 const bfd_target *result;
461
462 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
463 if (rawptr == NULL)
464 return 0;
465
466 oldrawptr = abfd->tdata.aout_data;
467 abfd->tdata.aout_data = rawptr;
468
469 /* Copy the contents of the old tdata struct.
470 In particular, we want the subformat, since for hpux it was set in
471 hp300hpux.c:swap_exec_header_in and will be used in
472 hp300hpux.c:callback. */
473 if (oldrawptr != NULL)
474 *abfd->tdata.aout_data = *oldrawptr;
475
476 abfd->tdata.aout_data->a.hdr = &rawptr->e;
477 *(abfd->tdata.aout_data->a.hdr) = *execp; /* Copy in the internal_exec struct */
478 execp = abfd->tdata.aout_data->a.hdr;
479
480 /* Set the file flags */
481 abfd->flags = BFD_NO_FLAGS;
482 if (execp->a_drsize || execp->a_trsize)
483 abfd->flags |= HAS_RELOC;
484 /* Setting of EXEC_P has been deferred to the bottom of this function */
485 if (execp->a_syms)
486 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
487 if (N_DYNAMIC(*execp))
488 abfd->flags |= DYNAMIC;
489
490 if (N_MAGIC (*execp) == ZMAGIC)
491 {
492 abfd->flags |= D_PAGED | WP_TEXT;
493 adata (abfd).magic = z_magic;
494 }
495 else if (N_MAGIC (*execp) == QMAGIC)
496 {
497 abfd->flags |= D_PAGED | WP_TEXT;
498 adata (abfd).magic = z_magic;
499 adata (abfd).subformat = q_magic_format;
500 }
501 else if (N_MAGIC (*execp) == NMAGIC)
502 {
503 abfd->flags |= WP_TEXT;
504 adata (abfd).magic = n_magic;
505 }
506 else if (N_MAGIC (*execp) == OMAGIC
507 || N_MAGIC (*execp) == BMAGIC)
508 adata (abfd).magic = o_magic;
509 else
510 {
511 /* Should have been checked with N_BADMAG before this routine
512 was called. */
513 abort ();
514 }
515
516 bfd_get_start_address (abfd) = execp->a_entry;
517
518 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
519 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
520
521 /* The default relocation entry size is that of traditional V7 Unix. */
522 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
523
524 /* The default symbol entry size is that of traditional Unix. */
525 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
526
527#ifdef USE_MMAP
528 bfd_init_window (&obj_aout_sym_window (abfd));
529 bfd_init_window (&obj_aout_string_window (abfd));
530#endif
531 obj_aout_external_syms (abfd) = NULL;
532 obj_aout_external_strings (abfd) = NULL;
533 obj_aout_sym_hashes (abfd) = NULL;
534
535 if (! NAME(aout,make_sections) (abfd))
536 return NULL;
537
538 obj_datasec (abfd)->_raw_size = execp->a_data;
539 obj_bsssec (abfd)->_raw_size = execp->a_bss;
540
541 obj_textsec (abfd)->flags =
542 (execp->a_trsize != 0
543 ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
544 : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
545 obj_datasec (abfd)->flags =
546 (execp->a_drsize != 0
547 ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
548 : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
549 obj_bsssec (abfd)->flags = SEC_ALLOC;
550
551#ifdef THIS_IS_ONLY_DOCUMENTATION
552 /* The common code can't fill in these things because they depend
553 on either the start address of the text segment, the rounding
554 up of virtual addresses between segments, or the starting file
555 position of the text segment -- all of which varies among different
556 versions of a.out. */
557
558 /* Call back to the format-dependent code to fill in the rest of the
559 fields and do any further cleanup. Things that should be filled
560 in by the callback: */
561
562 struct exec *execp = exec_hdr (abfd);
563
564 obj_textsec (abfd)->size = N_TXTSIZE(*execp);
565 obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp);
566 /* data and bss are already filled in since they're so standard */
567
568 /* The virtual memory addresses of the sections */
569 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
570 obj_datasec (abfd)->vma = N_DATADDR(*execp);
571 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
572
573 /* The file offsets of the sections */
574 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
575 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
576
577 /* The file offsets of the relocation info */
578 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
579 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
580
581 /* The file offsets of the string table and symbol table. */
582 obj_str_filepos (abfd) = N_STROFF (*execp);
583 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
584
585 /* Determine the architecture and machine type of the object file. */
586 switch (N_MACHTYPE (*exec_hdr (abfd))) {
587 default:
588 abfd->obj_arch = bfd_arch_obscure;
589 break;
590 }
591
592 adata(abfd)->page_size = TARGET_PAGE_SIZE;
593 adata(abfd)->segment_size = SEGMENT_SIZE;
594 adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
595
596 return abfd->xvec;
597
598 /* The architecture is encoded in various ways in various a.out variants,
599 or is not encoded at all in some of them. The relocation size depends
600 on the architecture and the a.out variant. Finally, the return value
601 is the bfd_target vector in use. If an error occurs, return zero and
602 set bfd_error to the appropriate error code.
603
604 Formats such as b.out, which have additional fields in the a.out
605 header, should cope with them in this callback as well. */
606#endif /* DOCUMENTATION */
607
608 result = (*callback_to_real_object_p) (abfd);
609
610 /* Now that the segment addresses have been worked out, take a better
611 guess at whether the file is executable. If the entry point
612 is within the text segment, assume it is. (This makes files
613 executable even if their entry point address is 0, as long as
614 their text starts at zero.).
615
616 This test had to be changed to deal with systems where the text segment
617 runs at a different location than the default. The problem is that the
618 entry address can appear to be outside the text segment, thus causing an
619 erroneous conclusion that the file isn't executable.
620
621 To fix this, we now accept any non-zero entry point as an indication of
622 executability. This will work most of the time, since only the linker
623 sets the entry point, and that is likely to be non-zero for most systems. */
624
625 if (execp->a_entry != 0
626 || (execp->a_entry >= obj_textsec(abfd)->vma
627 && execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
628 abfd->flags |= EXEC_P;
629#ifdef STAT_FOR_EXEC
630 else
631 {
632 struct stat stat_buf;
633
634 /* The original heuristic doesn't work in some important cases.
635 The a.out file has no information about the text start
636 address. For files (like kernels) linked to non-standard
637 addresses (ld -Ttext nnn) the entry point may not be between
638 the default text start (obj_textsec(abfd)->vma) and
639 (obj_textsec(abfd)->vma) + text size. This is not just a mach
640 issue. Many kernels are loaded at non standard addresses. */
641 if (abfd->iostream != NULL
642 && (abfd->flags & BFD_IN_MEMORY) == 0
643 && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
644 && ((stat_buf.st_mode & 0111) != 0))
645 abfd->flags |= EXEC_P;
646 }
647#endif /* STAT_FOR_EXEC */
648
649 if (result)
650 {
651#if 0 /* These should be set correctly anyways. */
652 abfd->sections = obj_textsec (abfd);
653 obj_textsec (abfd)->next = obj_datasec (abfd);
654 obj_datasec (abfd)->next = obj_bsssec (abfd);
655#endif
656 }
657 else
658 {
659 free (rawptr);
660 abfd->tdata.aout_data = oldrawptr;
661 }
662 return result;
663}
664
665/*
666FUNCTION
667 aout_@var{size}_mkobject
668
669SYNOPSIS
670 boolean aout_@var{size}_mkobject, (bfd *abfd);
671
672DESCRIPTION
673 Initialize BFD @var{abfd} for use with a.out files.
674*/
675
676boolean
677NAME(aout,mkobject) (abfd)
678 bfd *abfd;
679{
680 struct aout_data_struct *rawptr;
681
682 bfd_set_error (bfd_error_system_call);
683
684 /* Use an intermediate variable for clarity */
685 rawptr = (struct aout_data_struct *)bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
686
687 if (rawptr == NULL)
688 return false;
689
690 abfd->tdata.aout_data = rawptr;
691 exec_hdr (abfd) = &(rawptr->e);
692
693 obj_textsec (abfd) = (asection *)NULL;
694 obj_datasec (abfd) = (asection *)NULL;
695 obj_bsssec (abfd) = (asection *)NULL;
696
697 return true;
698}
699
700/*
701FUNCTION
702 aout_@var{size}_machine_type
703
704SYNOPSIS
705 enum machine_type aout_@var{size}_machine_type
706 (enum bfd_architecture arch,
707 unsigned long machine));
708
709DESCRIPTION
710 Keep track of machine architecture and machine type for
711 a.out's. Return the <<machine_type>> for a particular
712 architecture and machine, or <<M_UNKNOWN>> if that exact architecture
713 and machine can't be represented in a.out format.
714
715 If the architecture is understood, machine type 0 (default)
716 is always understood.
717*/
718
719enum machine_type
720NAME(aout,machine_type) (arch, machine, unknown)
721 enum bfd_architecture arch;
722 unsigned long machine;
723 boolean *unknown;
724{
725 enum machine_type arch_flags;
726
727 arch_flags = M_UNKNOWN;
728 *unknown = true;
729
730 switch (arch) {
731 case bfd_arch_sparc:
732 if (machine == 0
733 || machine == bfd_mach_sparc
734 || machine == bfd_mach_sparc_sparclite
735 || machine == bfd_mach_sparc_sparclite_le
736 || machine == bfd_mach_sparc_v9)
737 arch_flags = M_SPARC;
738 else if (machine == bfd_mach_sparc_sparclet)
739 arch_flags = M_SPARCLET;
740 break;
741
742 case bfd_arch_m68k:
743 switch (machine) {
744 case 0: arch_flags = M_68010; break;
745 case bfd_mach_m68000: arch_flags = M_UNKNOWN; *unknown = false; break;
746 case bfd_mach_m68010: arch_flags = M_68010; break;
747 case bfd_mach_m68020: arch_flags = M_68020; break;
748 default: arch_flags = M_UNKNOWN; break;
749 }
750 break;
751
752 case bfd_arch_i386:
753 if (machine == 0) arch_flags = M_386;
754 break;
755
756 case bfd_arch_a29k:
757 if (machine == 0) arch_flags = M_29K;
758 break;
759
760 case bfd_arch_arm:
761 if (machine == 0) arch_flags = M_ARM;
762 break;
763
764 case bfd_arch_mips:
765 switch (machine) {
766 case 0:
767 case bfd_mach_mips3000:
768 case bfd_mach_mips3900:
769 arch_flags = M_MIPS1;
770 break;
771 case bfd_mach_mips6000:
772 arch_flags = M_MIPS2;
773 break;
774 case bfd_mach_mips4000:
775 case bfd_mach_mips4010:
776 case bfd_mach_mips4100:
777 case bfd_mach_mips4300:
778 case bfd_mach_mips4400:
779 case bfd_mach_mips4600:
780 case bfd_mach_mips4650:
781 case bfd_mach_mips8000:
782 case bfd_mach_mips10000:
783 case bfd_mach_mips12000:
784 case bfd_mach_mips16:
785 case bfd_mach_mips32:
786 case bfd_mach_mips32_4k:
787 case bfd_mach_mips5:
788 case bfd_mach_mips64:
789 case bfd_mach_mips_sb1:
790 /* FIXME: These should be MIPS3, MIPS4, MIPS16, MIPS32, etc. */
791 arch_flags = M_MIPS2;
792 break;
793 default:
794 arch_flags = M_UNKNOWN;
795 break;
796 }
797 break;
798
799 case bfd_arch_ns32k:
800 switch (machine) {
801 case 0: arch_flags = M_NS32532; break;
802 case 32032: arch_flags = M_NS32032; break;
803 case 32532: arch_flags = M_NS32532; break;
804 default: arch_flags = M_UNKNOWN; break;
805 }
806 break;
807
808 case bfd_arch_vax:
809 *unknown = false;
810 break;
811
812 case bfd_arch_cris:
813 if (machine == 0 || machine == 255) arch_flags = M_CRIS;
814 break;
815
816 default:
817 arch_flags = M_UNKNOWN;
818 }
819
820 if (arch_flags != M_UNKNOWN)
821 *unknown = false;
822
823 return arch_flags;
824}
825
826/*
827FUNCTION
828 aout_@var{size}_set_arch_mach
829
830SYNOPSIS
831 boolean aout_@var{size}_set_arch_mach,
832 (bfd *,
833 enum bfd_architecture arch,
834 unsigned long machine));
835
836DESCRIPTION
837 Set the architecture and the machine of the BFD @var{abfd} to the
838 values @var{arch} and @var{machine}. Verify that @var{abfd}'s format
839 can support the architecture required.
840*/
841
842boolean
843NAME(aout,set_arch_mach) (abfd, arch, machine)
844 bfd *abfd;
845 enum bfd_architecture arch;
846 unsigned long machine;
847{
848 if (! bfd_default_set_arch_mach (abfd, arch, machine))
849 return false;
850
851 if (arch != bfd_arch_unknown)
852 {
853 boolean unknown;
854
855 NAME(aout,machine_type) (arch, machine, &unknown);
856 if (unknown)
857 return false;
858 }
859
860 /* Determine the size of a relocation entry */
861 switch (arch) {
862 case bfd_arch_sparc:
863 case bfd_arch_a29k:
864 case bfd_arch_mips:
865 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
866 break;
867 default:
868 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
869 break;
870 }
871
872 return (*aout_backend_info(abfd)->set_sizes) (abfd);
873}
874
875static void
876adjust_o_magic (abfd, execp)
877 bfd *abfd;
878 struct internal_exec *execp;
879{
880 file_ptr pos = adata (abfd).exec_bytes_size;
881 bfd_vma vma = 0;
882 int pad = 0;
883
884 /* Text. */
885 obj_textsec(abfd)->filepos = pos;
886 if (!obj_textsec(abfd)->user_set_vma)
887 obj_textsec(abfd)->vma = vma;
888 else
889 vma = obj_textsec(abfd)->vma;
890
891 pos += obj_textsec(abfd)->_raw_size;
892 vma += obj_textsec(abfd)->_raw_size;
893
894 /* Data. */
895 if (!obj_datasec(abfd)->user_set_vma)
896 {
897#if 0 /* ?? Does alignment in the file image really matter? */
898 pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
899#endif
900 obj_textsec(abfd)->_raw_size += pad;
901 pos += pad;
902 vma += pad;
903 obj_datasec(abfd)->vma = vma;
904 }
905 else
906 vma = obj_datasec(abfd)->vma;
907 obj_datasec(abfd)->filepos = pos;
908 pos += obj_datasec(abfd)->_raw_size;
909 vma += obj_datasec(abfd)->_raw_size;
910
911 /* BSS. */
912 if (!obj_bsssec(abfd)->user_set_vma)
913 {
914#if 0
915 pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
916#endif
917 obj_datasec(abfd)->_raw_size += pad;
918 pos += pad;
919 vma += pad;
920 obj_bsssec(abfd)->vma = vma;
921 }
922 else
923 {
924 /* The VMA of the .bss section is set by the the VMA of the
925 .data section plus the size of the .data section. We may
926 need to add padding bytes to make this true. */
927 pad = obj_bsssec (abfd)->vma - vma;
928 if (pad > 0)
929 {
930 obj_datasec (abfd)->_raw_size += pad;
931 pos += pad;
932 }
933 }
934 obj_bsssec(abfd)->filepos = pos;
935
936 /* Fix up the exec header. */
937 execp->a_text = obj_textsec(abfd)->_raw_size;
938 execp->a_data = obj_datasec(abfd)->_raw_size;
939 execp->a_bss = obj_bsssec(abfd)->_raw_size;
940 N_SET_MAGIC (*execp, OMAGIC);
941}
942
943static void
944adjust_z_magic (abfd, execp)
945 bfd *abfd;
946 struct internal_exec *execp;
947{
948 bfd_size_type data_pad, text_pad;
949 file_ptr text_end;
950 CONST struct aout_backend_data *abdp;
951 int ztih; /* Nonzero if text includes exec header. */
952
953 abdp = aout_backend_info (abfd);
954
955 /* Text. */
956 ztih = (abdp != NULL
957 && (abdp->text_includes_header
958 || obj_aout_subformat (abfd) == q_magic_format));
959 obj_textsec(abfd)->filepos = (ztih
960 ? adata(abfd).exec_bytes_size
961 : adata(abfd).zmagic_disk_block_size);
962 if (! obj_textsec(abfd)->user_set_vma)
963 {
964 /* ?? Do we really need to check for relocs here? */
965 obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
966 ? 0
967 : (ztih
968 ? (abdp->default_text_vma
969 + adata(abfd).exec_bytes_size)
970 : abdp->default_text_vma));
971 text_pad = 0;
972 }
973 else
974 {
975 /* The .text section is being loaded at an unusual address. We
976 may need to pad it such that the .data section starts at a page
977 boundary. */
978 if (ztih)
979 text_pad = ((obj_textsec (abfd)->filepos - obj_textsec (abfd)->vma)
980 & (adata (abfd).page_size - 1));
981 else
982 text_pad = ((- obj_textsec (abfd)->vma)
983 & (adata (abfd).page_size - 1));
984 }
985
986 /* Find start of data. */
987 if (ztih)
988 {
989 text_end = obj_textsec (abfd)->filepos + obj_textsec (abfd)->_raw_size;
990 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
991 }
992 else
993 {
994 /* Note that if page_size == zmagic_disk_block_size, then
995 filepos == page_size, and this case is the same as the ztih
996 case. */
997 text_end = obj_textsec (abfd)->_raw_size;
998 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
999 text_end += obj_textsec (abfd)->filepos;
1000 }
1001 obj_textsec(abfd)->_raw_size += text_pad;
1002 text_end += text_pad;
1003
1004 /* Data. */
1005 if (!obj_datasec(abfd)->user_set_vma)
1006 {
1007 bfd_vma vma;
1008 vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size;
1009 obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
1010 }
1011 if (abdp && abdp->zmagic_mapped_contiguous)
1012 {
1013 text_pad = (obj_datasec(abfd)->vma
1014 - obj_textsec(abfd)->vma
1015 - obj_textsec(abfd)->_raw_size);
1016 obj_textsec(abfd)->_raw_size += text_pad;
1017 }
1018 obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos
1019 + obj_textsec(abfd)->_raw_size);
1020
1021 /* Fix up exec header while we're at it. */
1022 execp->a_text = obj_textsec(abfd)->_raw_size;
1023 if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
1024 execp->a_text += adata(abfd).exec_bytes_size;
1025 if (obj_aout_subformat (abfd) == q_magic_format)
1026 N_SET_MAGIC (*execp, QMAGIC);
1027 else
1028 N_SET_MAGIC (*execp, ZMAGIC);
1029
1030 /* Spec says data section should be rounded up to page boundary. */
1031 obj_datasec(abfd)->_raw_size
1032 = align_power (obj_datasec(abfd)->_raw_size,
1033 obj_bsssec(abfd)->alignment_power);
1034 execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size,
1035 adata(abfd).page_size);
1036 data_pad = execp->a_data - obj_datasec(abfd)->_raw_size;
1037
1038 /* BSS. */
1039 if (!obj_bsssec(abfd)->user_set_vma)
1040 obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
1041 + obj_datasec(abfd)->_raw_size);
1042 /* If the BSS immediately follows the data section and extra space
1043 in the page is left after the data section, fudge data
1044 in the header so that the bss section looks smaller by that
1045 amount. We'll start the bss section there, and lie to the OS.
1046 (Note that a linker script, as well as the above assignment,
1047 could have explicitly set the BSS vma to immediately follow
1048 the data section.) */
1049 if (align_power (obj_bsssec(abfd)->vma, obj_bsssec(abfd)->alignment_power)
1050 == obj_datasec(abfd)->vma + obj_datasec(abfd)->_raw_size)
1051 execp->a_bss = (data_pad > obj_bsssec(abfd)->_raw_size) ? 0 :
1052 obj_bsssec(abfd)->_raw_size - data_pad;
1053 else
1054 execp->a_bss = obj_bsssec(abfd)->_raw_size;
1055}
1056
1057static void
1058adjust_n_magic (abfd, execp)
1059 bfd *abfd;
1060 struct internal_exec *execp;
1061{
1062 file_ptr pos = adata(abfd).exec_bytes_size;
1063 bfd_vma vma = 0;
1064 int pad;
1065
1066 /* Text. */
1067 obj_textsec(abfd)->filepos = pos;
1068 if (!obj_textsec(abfd)->user_set_vma)
1069 obj_textsec(abfd)->vma = vma;
1070 else
1071 vma = obj_textsec(abfd)->vma;
1072 pos += obj_textsec(abfd)->_raw_size;
1073 vma += obj_textsec(abfd)->_raw_size;
1074
1075 /* Data. */
1076 obj_datasec(abfd)->filepos = pos;
1077 if (!obj_datasec(abfd)->user_set_vma)
1078 obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
1079 vma = obj_datasec(abfd)->vma;
1080
1081 /* Since BSS follows data immediately, see if it needs alignment. */
1082 vma += obj_datasec(abfd)->_raw_size;
1083 pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
1084 obj_datasec(abfd)->_raw_size += pad;
1085 pos += obj_datasec(abfd)->_raw_size;
1086
1087 /* BSS. */
1088 if (!obj_bsssec(abfd)->user_set_vma)
1089 obj_bsssec(abfd)->vma = vma;
1090 else
1091 vma = obj_bsssec(abfd)->vma;
1092
1093 /* Fix up exec header. */
1094 execp->a_text = obj_textsec(abfd)->_raw_size;
1095 execp->a_data = obj_datasec(abfd)->_raw_size;
1096 execp->a_bss = obj_bsssec(abfd)->_raw_size;
1097 N_SET_MAGIC (*execp, NMAGIC);
1098}
1099
1100boolean
1101NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end)
1102 bfd *abfd;
1103 bfd_size_type *text_size;
1104 file_ptr *text_end ATTRIBUTE_UNUSED;
1105{
1106 struct internal_exec *execp = exec_hdr (abfd);
1107
1108 if (! NAME(aout,make_sections) (abfd))
1109 return false;
1110
1111 if (adata(abfd).magic != undecided_magic)
1112 return true;
1113
1114 obj_textsec(abfd)->_raw_size =
1115 align_power(obj_textsec(abfd)->_raw_size,
1116 obj_textsec(abfd)->alignment_power);
1117
1118 *text_size = obj_textsec (abfd)->_raw_size;
1119 /* Rule (heuristic) for when to pad to a new page. Note that there
1120 are (at least) two ways demand-paged (ZMAGIC) files have been
1121 handled. Most Berkeley-based systems start the text segment at
1122 (TARGET_PAGE_SIZE). However, newer versions of SUNOS start the text
1123 segment right after the exec header; the latter is counted in the
1124 text segment size, and is paged in by the kernel with the rest of
1125 the text. */
1126
1127 /* This perhaps isn't the right way to do this, but made it simpler for me
1128 to understand enough to implement it. Better would probably be to go
1129 right from BFD flags to alignment/positioning characteristics. But the
1130 old code was sloppy enough about handling the flags, and had enough
1131 other magic, that it was a little hard for me to understand. I think
1132 I understand it better now, but I haven't time to do the cleanup this
1133 minute. */
1134
1135 if (abfd->flags & D_PAGED)
1136 /* Whether or not WP_TEXT is set -- let D_PAGED override. */
1137 adata(abfd).magic = z_magic;
1138 else if (abfd->flags & WP_TEXT)
1139 adata(abfd).magic = n_magic;
1140 else
1141 adata(abfd).magic = o_magic;
1142
1143#ifdef BFD_AOUT_DEBUG /* requires gcc2 */
1144#if __GNUC__ >= 2
1145 fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
1146 ({ char *str;
1147 switch (adata(abfd).magic) {
1148 case n_magic: str = "NMAGIC"; break;
1149 case o_magic: str = "OMAGIC"; break;
1150 case z_magic: str = "ZMAGIC"; break;
1151 default: abort ();
1152 }
1153 str;
1154 }),
1155 obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size,
1156 obj_textsec(abfd)->alignment_power,
1157 obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size,
1158 obj_datasec(abfd)->alignment_power,
1159 obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size,
1160 obj_bsssec(abfd)->alignment_power);
1161#endif
1162#endif
1163
1164 switch (adata(abfd).magic)
1165 {
1166 case o_magic:
1167 adjust_o_magic (abfd, execp);
1168 break;
1169 case z_magic:
1170 adjust_z_magic (abfd, execp);
1171 break;
1172 case n_magic:
1173 adjust_n_magic (abfd, execp);
1174 break;
1175 default:
1176 abort ();
1177 }
1178
1179#ifdef BFD_AOUT_DEBUG
1180 fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
1181 obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size,
1182 obj_textsec(abfd)->filepos,
1183 obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size,
1184 obj_datasec(abfd)->filepos,
1185 obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size);
1186#endif
1187
1188 return true;
1189}
1190
1191/*
1192FUNCTION
1193 aout_@var{size}_new_section_hook
1194
1195SYNOPSIS
1196 boolean aout_@var{size}_new_section_hook,
1197 (bfd *abfd,
1198 asection *newsect));
1199
1200DESCRIPTION
1201 Called by the BFD in response to a @code{bfd_make_section}
1202 request.
1203*/
1204boolean
1205NAME(aout,new_section_hook) (abfd, newsect)
1206 bfd *abfd;
1207 asection *newsect;
1208{
1209 /* align to double at least */
1210 newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
1211
1212 if (bfd_get_format (abfd) == bfd_object)
1213 {
1214 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
1215 obj_textsec(abfd)= newsect;
1216 newsect->target_index = N_TEXT;
1217 return true;
1218 }
1219
1220 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
1221 obj_datasec(abfd) = newsect;
1222 newsect->target_index = N_DATA;
1223 return true;
1224 }
1225
1226 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
1227 obj_bsssec(abfd) = newsect;
1228 newsect->target_index = N_BSS;
1229 return true;
1230 }
1231
1232 }
1233
1234 /* We allow more than three sections internally */
1235 return true;
1236}
1237
1238boolean
1239NAME(aout,set_section_contents) (abfd, section, location, offset, count)
1240 bfd *abfd;
1241 sec_ptr section;
1242 PTR location;
1243 file_ptr offset;
1244 bfd_size_type count;
1245{
1246 file_ptr text_end;
1247 bfd_size_type text_size;
1248
1249 if (! abfd->output_has_begun)
1250 {
1251 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
1252 return false;
1253 }
1254
1255 if (section == obj_bsssec (abfd))
1256 {
1257 bfd_set_error (bfd_error_no_contents);
1258 return false;
1259 }
1260
1261 if (section != obj_textsec (abfd)
1262 && section != obj_datasec (abfd))
1263 {
1264 (*_bfd_error_handler)
1265 (_("%s: can not represent section `%s' in a.out object file format"),
1266 bfd_get_filename (abfd), bfd_get_section_name (abfd, section));
1267 bfd_set_error (bfd_error_nonrepresentable_section);
1268 return false;
1269 }
1270
1271 if (count != 0)
1272 {
1273 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
1274 || bfd_write (location, 1, count, abfd) != count)
1275 return false;
1276 }
1277
1278 return true;
1279}
1280
1281
1282/* Read the external symbols from an a.out file. */
1283
1284static boolean
1285aout_get_external_symbols (abfd)
1286 bfd *abfd;
1287{
1288 if (obj_aout_external_syms (abfd) == (struct external_nlist *) NULL)
1289 {
1290 bfd_size_type count;
1291 struct external_nlist *syms;
1292
1293 count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
1294
1295#ifdef USE_MMAP
1296 if (bfd_get_file_window (abfd,
1297 obj_sym_filepos (abfd), exec_hdr (abfd)->a_syms,
1298 &obj_aout_sym_window (abfd), true) == false)
1299 return false;
1300 syms = (struct external_nlist *) obj_aout_sym_window (abfd).data;
1301#else
1302 /* We allocate using malloc to make the values easy to free
1303 later on. If we put them on the objalloc it might not be
1304 possible to free them. */
1305 syms = ((struct external_nlist *)
1306 bfd_malloc ((size_t) count * EXTERNAL_NLIST_SIZE));
1307 if (syms == (struct external_nlist *) NULL && count != 0)
1308 return false;
1309
1310 if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
1311 || (bfd_read (syms, 1, exec_hdr (abfd)->a_syms, abfd)
1312 != exec_hdr (abfd)->a_syms))
1313 {
1314 free (syms);
1315 return false;
1316 }
1317#endif
1318
1319 obj_aout_external_syms (abfd) = syms;
1320 obj_aout_external_sym_count (abfd) = count;
1321 }
1322
1323 if (obj_aout_external_strings (abfd) == NULL
1324 && exec_hdr (abfd)->a_syms != 0)
1325 {
1326 unsigned char string_chars[BYTES_IN_WORD];
1327 bfd_size_type stringsize;
1328 char *strings;
1329
1330 /* Get the size of the strings. */
1331 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
1332 || (bfd_read ((PTR) string_chars, BYTES_IN_WORD, 1, abfd)
1333 != BYTES_IN_WORD))
1334 return false;
1335 stringsize = GET_WORD (abfd, string_chars);
1336
1337#ifdef USE_MMAP
1338 if (bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
1339 &obj_aout_string_window (abfd), true) == false)
1340 return false;
1341 strings = (char *) obj_aout_string_window (abfd).data;
1342#else
1343 strings = (char *) bfd_malloc ((size_t) stringsize + 1);
1344 if (strings == NULL)
1345 return false;
1346
1347 /* Skip space for the string count in the buffer for convenience
1348 when using indexes. */
1349 if (bfd_read (strings + BYTES_IN_WORD, 1, stringsize - BYTES_IN_WORD,
1350 abfd)
1351 != stringsize - BYTES_IN_WORD)
1352 {
1353 free (strings);
1354 return false;
1355 }
1356#endif
1357
1358 /* Ensure that a zero index yields an empty string. */
1359 strings[0] = '\0';
1360
1361 strings[stringsize - 1] = 0;
1362
1363 obj_aout_external_strings (abfd) = strings;
1364 obj_aout_external_string_size (abfd) = stringsize;
1365 }
1366
1367 return true;
1368}
1369
1370/* Translate an a.out symbol into a BFD symbol. The desc, other, type
1371 and symbol->value fields of CACHE_PTR will be set from the a.out
1372 nlist structure. This function is responsible for setting
1373 symbol->flags and symbol->section, and adjusting symbol->value. */
1374
1375static boolean
1376translate_from_native_sym_flags (abfd, cache_ptr)
1377 bfd *abfd;
1378 aout_symbol_type *cache_ptr;
1379{
1380 flagword visible;
1381
1382 if (IS_STAB(cache_ptr->type)
1383 || cache_ptr->type == N_FN)
1384 {
1385 asection *sec;
1386
1387 /* This is a debugging symbol. */
1388
1389 cache_ptr->symbol.flags = BSF_DEBUGGING;
1390
1391 /* Work out the symbol section. */
1392 switch (cache_ptr->type & N_TYPE)
1393 {
1394 case N_TEXT:
1395 case N_FN:
1396 sec = obj_textsec (abfd);
1397 break;
1398 case N_DATA:
1399 sec = obj_datasec (abfd);
1400 break;
1401 case N_BSS:
1402 sec = obj_bsssec (abfd);
1403 break;
1404 default:
1405 case N_ABS:
1406 sec = bfd_abs_section_ptr;
1407 break;
1408 }
1409
1410 cache_ptr->symbol.section = sec;
1411 cache_ptr->symbol.value -= sec->vma;
1412
1413 return true;
1414 }
1415
1416 /* Get the default visibility. This does not apply to all types, so
1417 we just hold it in a local variable to use if wanted. */
1418 if ((cache_ptr->type & N_EXT) == 0)
1419 visible = BSF_LOCAL;
1420 else
1421 visible = BSF_GLOBAL;
1422
1423 switch (cache_ptr->type)
1424 {
1425 default:
1426 case N_ABS: case N_ABS | N_EXT:
1427 cache_ptr->symbol.section = bfd_abs_section_ptr;
1428 cache_ptr->symbol.flags = visible;
1429 break;
1430
1431 case N_UNDF | N_EXT:
1432 if (cache_ptr->symbol.value != 0)
1433 {
1434 /* This is a common symbol. */
1435 cache_ptr->symbol.flags = BSF_GLOBAL;
1436 cache_ptr->symbol.section = bfd_com_section_ptr;
1437 }
1438 else
1439 {
1440 cache_ptr->symbol.flags = 0;
1441 cache_ptr->symbol.section = bfd_und_section_ptr;
1442 }
1443 break;
1444
1445 case N_TEXT: case N_TEXT | N_EXT:
1446 cache_ptr->symbol.section = obj_textsec (abfd);
1447 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1448 cache_ptr->symbol.flags = visible;
1449 break;
1450
1451 /* N_SETV symbols used to represent set vectors placed in the
1452 data section. They are no longer generated. Theoretically,
1453 it was possible to extract the entries and combine them with
1454 new ones, although I don't know if that was ever actually
1455 done. Unless that feature is restored, treat them as data
1456 symbols. */
1457 case N_SETV: case N_SETV | N_EXT:
1458 case N_DATA: case N_DATA | N_EXT:
1459 cache_ptr->symbol.section = obj_datasec (abfd);
1460 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1461 cache_ptr->symbol.flags = visible;
1462 break;
1463
1464 case N_BSS: case N_BSS | N_EXT:
1465 cache_ptr->symbol.section = obj_bsssec (abfd);
1466 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1467 cache_ptr->symbol.flags = visible;
1468 break;
1469
1470 case N_SETA: case N_SETA | N_EXT:
1471 case N_SETT: case N_SETT | N_EXT:
1472 case N_SETD: case N_SETD | N_EXT:
1473 case N_SETB: case N_SETB | N_EXT:
1474 {
1475 /* This code is no longer needed. It used to be used to make
1476 the linker handle set symbols, but they are now handled in
1477 the add_symbols routine instead. */
1478#if 0
1479 asection *section;
1480 arelent_chain *reloc;
1481 asection *into_section;
1482
1483 /* This is a set symbol. The name of the symbol is the name
1484 of the set (e.g., __CTOR_LIST__). The value of the symbol
1485 is the value to add to the set. We create a section with
1486 the same name as the symbol, and add a reloc to insert the
1487 appropriate value into the section.
1488
1489 This action is actually obsolete; it used to make the
1490 linker do the right thing, but the linker no longer uses
1491 this function. */
1492
1493 section = bfd_get_section_by_name (abfd, cache_ptr->symbol.name);
1494 if (section == NULL)
1495 {
1496 char *copy;
1497
1498 copy = bfd_alloc (abfd, strlen (cache_ptr->symbol.name) + 1);
1499 if (copy == NULL)
1500 return false;
1501
1502 strcpy (copy, cache_ptr->symbol.name);
1503 section = bfd_make_section (abfd, copy);
1504 if (section == NULL)
1505 return false;
1506 }
1507
1508 reloc = (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain));
1509 if (reloc == NULL)
1510 return false;
1511
1512 /* Build a relocation entry for the constructor. */
1513 switch (cache_ptr->type & N_TYPE)
1514 {
1515 case N_SETA:
1516 into_section = bfd_abs_section_ptr;
1517 cache_ptr->type = N_ABS;
1518 break;
1519 case N_SETT:
1520 into_section = obj_textsec (abfd);
1521 cache_ptr->type = N_TEXT;
1522 break;
1523 case N_SETD:
1524 into_section = obj_datasec (abfd);
1525 cache_ptr->type = N_DATA;
1526 break;
1527 case N_SETB:
1528 into_section = obj_bsssec (abfd);
1529 cache_ptr->type = N_BSS;
1530 break;
1531 }
1532
1533 /* Build a relocation pointing into the constructor section
1534 pointing at the symbol in the set vector specified. */
1535 reloc->relent.addend = cache_ptr->symbol.value;
1536 cache_ptr->symbol.section = into_section;
1537 reloc->relent.sym_ptr_ptr = into_section->symbol_ptr_ptr;
1538
1539 /* We modify the symbol to belong to a section depending upon
1540 the name of the symbol, and add to the size of the section
1541 to contain a pointer to the symbol. Build a reloc entry to
1542 relocate to this symbol attached to this section. */
1543 section->flags = SEC_CONSTRUCTOR | SEC_RELOC;
1544
1545 section->reloc_count++;
1546 section->alignment_power = 2;
1547
1548 reloc->next = section->constructor_chain;
1549 section->constructor_chain = reloc;
1550 reloc->relent.address = section->_raw_size;
1551 section->_raw_size += BYTES_IN_WORD;
1552
1553 reloc->relent.howto = CTOR_TABLE_RELOC_HOWTO(abfd);
1554
1555#endif /* 0 */
1556
1557 switch (cache_ptr->type & N_TYPE)
1558 {
1559 case N_SETA:
1560 cache_ptr->symbol.section = bfd_abs_section_ptr;
1561 break;
1562 case N_SETT:
1563 cache_ptr->symbol.section = obj_textsec (abfd);
1564 break;
1565 case N_SETD:
1566 cache_ptr->symbol.section = obj_datasec (abfd);
1567 break;
1568 case N_SETB:
1569 cache_ptr->symbol.section = obj_bsssec (abfd);
1570 break;
1571 }
1572
1573 cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
1574 }
1575 break;
1576
1577 case N_WARNING:
1578 /* This symbol is the text of a warning message. The next
1579 symbol is the symbol to associate the warning with. If a
1580 reference is made to that symbol, a warning is issued. */
1581 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
1582 cache_ptr->symbol.section = bfd_abs_section_ptr;
1583 break;
1584
1585 case N_INDR: case N_INDR | N_EXT:
1586 /* An indirect symbol. This consists of two symbols in a row.
1587 The first symbol is the name of the indirection. The second
1588 symbol is the name of the target. A reference to the first
1589 symbol becomes a reference to the second. */
1590 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible;
1591 cache_ptr->symbol.section = bfd_ind_section_ptr;
1592 break;
1593
1594 case N_WEAKU:
1595 cache_ptr->symbol.section = bfd_und_section_ptr;
1596 cache_ptr->symbol.flags = BSF_WEAK;
1597 break;
1598
1599 case N_WEAKA:
1600 cache_ptr->symbol.section = bfd_abs_section_ptr;
1601 cache_ptr->symbol.flags = BSF_WEAK;
1602 break;
1603
1604 case N_WEAKT:
1605 cache_ptr->symbol.section = obj_textsec (abfd);
1606 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1607 cache_ptr->symbol.flags = BSF_WEAK;
1608 break;
1609
1610 case N_WEAKD:
1611 cache_ptr->symbol.section = obj_datasec (abfd);
1612 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1613 cache_ptr->symbol.flags = BSF_WEAK;
1614 break;
1615
1616 case N_WEAKB:
1617 cache_ptr->symbol.section = obj_bsssec (abfd);
1618 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1619 cache_ptr->symbol.flags = BSF_WEAK;
1620 break;
1621
1622#ifdef EMX
1623 case N_IMP1 | N_EXT:
1624 cache_ptr->symbol.section = bfd_abs_section_ptr;
1625 cache_ptr->symbol.flags = BSF_EMX_IMPORT1;
1626 break;
1627
1628 case N_IMP2 | N_EXT:
1629 cache_ptr->symbol.section = bfd_abs_section_ptr;
1630 cache_ptr->symbol.flags = BSF_EMX_IMPORT2;
1631 break;
1632#endif /* EMX */
1633 }
1634
1635 return true;
1636}
1637
1638/* Set the fields of SYM_POINTER according to CACHE_PTR. */
1639
1640static boolean
1641translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
1642 bfd *abfd;
1643 asymbol *cache_ptr;
1644 struct external_nlist *sym_pointer;
1645{
1646 bfd_vma value = cache_ptr->value;
1647 asection *sec;
1648 bfd_vma off;
1649
1650 /* Mask out any existing type bits in case copying from one section
1651 to another. */
1652 sym_pointer->e_type[0] &= ~N_TYPE;
1653
1654 sec = bfd_get_section (cache_ptr);
1655 off = 0;
1656
1657 if (sec == NULL)
1658 {
1659 /* This case occurs, e.g., for the *DEBUG* section of a COFF
1660 file. */
1661 (*_bfd_error_handler)
1662 (_("%s: can not represent section for symbol `%s' in a.out object file format"),
1663 bfd_get_filename (abfd),
1664 cache_ptr->name != NULL ? cache_ptr->name : _("*unknown*"));
1665 bfd_set_error (bfd_error_nonrepresentable_section);
1666 return false;
1667 }
1668
1669 if (sec->output_section != NULL)
1670 {
1671 off = sec->output_offset;
1672 sec = sec->output_section;
1673 }
1674
1675 if (bfd_is_abs_section (sec))
1676 sym_pointer->e_type[0] |= N_ABS;
1677 else if (sec == obj_textsec (abfd))
1678 sym_pointer->e_type[0] |= N_TEXT;
1679 else if (sec == obj_datasec (abfd))
1680 sym_pointer->e_type[0] |= N_DATA;
1681 else if (sec == obj_bsssec (abfd))
1682 sym_pointer->e_type[0] |= N_BSS;
1683 else if (bfd_is_und_section (sec))
1684 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1685 else if (bfd_is_ind_section (sec))
1686 sym_pointer->e_type[0] = N_INDR;
1687 else if (bfd_is_com_section (sec))
1688 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1689 else
1690 {
1691 (*_bfd_error_handler)
1692 (_("%s: can not represent section `%s' in a.out object file format"),
1693 bfd_get_filename (abfd), bfd_get_section_name (abfd, sec));
1694 bfd_set_error (bfd_error_nonrepresentable_section);
1695 return false;
1696 }
1697
1698 /* Turn the symbol from section relative to absolute again */
1699 value += sec->vma + off;
1700
1701 if ((cache_ptr->flags & BSF_WARNING) != 0)
1702 sym_pointer->e_type[0] = N_WARNING;
1703
1704 if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
1705 sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
1706 else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
1707 sym_pointer->e_type[0] |= N_EXT;
1708 else if ((cache_ptr->flags & BSF_LOCAL) != 0)
1709 sym_pointer->e_type[0] &= ~N_EXT;
1710
1711 if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0)
1712 {
1713 int type = ((aout_symbol_type *) cache_ptr)->type;
1714 switch (type)
1715 {
1716 case N_ABS: type = N_SETA; break;
1717 case N_TEXT: type = N_SETT; break;
1718 case N_DATA: type = N_SETD; break;
1719 case N_BSS: type = N_SETB; break;
1720 }
1721 sym_pointer->e_type[0] = type;
1722 }
1723
1724 if ((cache_ptr->flags & BSF_WEAK) != 0)
1725 {
1726 int type;
1727
1728 switch (sym_pointer->e_type[0] & N_TYPE)
1729 {
1730 default:
1731 case N_ABS: type = N_WEAKA; break;
1732 case N_TEXT: type = N_WEAKT; break;
1733 case N_DATA: type = N_WEAKD; break;
1734 case N_BSS: type = N_WEAKB; break;
1735 case N_UNDF: type = N_WEAKU; break;
1736 }
1737 sym_pointer->e_type[0] = type;
1738 }
1739
1740 PUT_WORD(abfd, value, sym_pointer->e_value);
1741
1742 return true;
1743}
1744
1745
1746/* Native-level interface to symbols. */
1747
1748asymbol *
1749NAME(aout,make_empty_symbol) (abfd)
1750 bfd *abfd;
1751{
1752 aout_symbol_type *new =
1753 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1754 if (!new)
1755 return NULL;
1756 new->symbol.the_bfd = abfd;
1757
1758 return &new->symbol;
1759}
1760
1761/* Translate a set of internal symbols into external symbols. */
1762
1763boolean
1764NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic)
1765 bfd *abfd;
1766 aout_symbol_type *in;
1767 struct external_nlist *ext;
1768 bfd_size_type count;
1769 char *str;
1770 bfd_size_type strsize;
1771 boolean dynamic;
1772{
1773 struct external_nlist *ext_end;
1774
1775 ext_end = ext + count;
1776 for (; ext < ext_end; ext++, in++)
1777 {
1778 bfd_vma x;
1779
1780 x = GET_WORD (abfd, ext->e_strx);
1781 in->symbol.the_bfd = abfd;
1782
1783 /* For the normal symbols, the zero index points at the number
1784 of bytes in the string table but is to be interpreted as the
1785 null string. For the dynamic symbols, the number of bytes in
1786 the string table is stored in the __DYNAMIC structure and the
1787 zero index points at an actual string. */
1788 if (x == 0 && ! dynamic)
1789 in->symbol.name = "";
1790 else if (x < strsize)
1791 in->symbol.name = str + x;
1792 else
1793 return false;
1794
1795 in->symbol.value = GET_SWORD (abfd, ext->e_value);
1796 in->desc = bfd_h_get_16 (abfd, ext->e_desc);
1797 in->other = bfd_h_get_8 (abfd, ext->e_other);
1798 in->type = bfd_h_get_8 (abfd, ext->e_type);
1799 in->symbol.udata.p = NULL;
1800
1801 if (! translate_from_native_sym_flags (abfd, in))
1802 return false;
1803
1804 if (dynamic)
1805 in->symbol.flags |= BSF_DYNAMIC;
1806 }
1807
1808 return true;
1809}
1810
1811/* We read the symbols into a buffer, which is discarded when this
1812 function exits. We read the strings into a buffer large enough to
1813 hold them all plus all the cached symbol entries. */
1814
1815boolean
1816NAME(aout,slurp_symbol_table) (abfd)
1817 bfd *abfd;
1818{
1819 struct external_nlist *old_external_syms;
1820 aout_symbol_type *cached;
1821 size_t cached_size;
1822
1823 /* If there's no work to be done, don't do any */
1824 if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
1825 return true;
1826
1827 old_external_syms = obj_aout_external_syms (abfd);
1828
1829 if (! aout_get_external_symbols (abfd))
1830 return false;
1831
1832 cached_size = (obj_aout_external_sym_count (abfd)
1833 * sizeof (aout_symbol_type));
1834 cached = (aout_symbol_type *) bfd_malloc (cached_size);
1835 if (cached == NULL && cached_size != 0)
1836 return false;
1837 if (cached_size != 0)
1838 memset (cached, 0, cached_size);
1839
1840 /* Convert from external symbol information to internal. */
1841 if (! (NAME(aout,translate_symbol_table)
1842 (abfd, cached,
1843 obj_aout_external_syms (abfd),
1844 obj_aout_external_sym_count (abfd),
1845 obj_aout_external_strings (abfd),
1846 obj_aout_external_string_size (abfd),
1847 false)))
1848 {
1849 free (cached);
1850 return false;
1851 }
1852
1853 bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
1854
1855 obj_aout_symbols (abfd) = cached;
1856
1857 /* It is very likely that anybody who calls this function will not
1858 want the external symbol information, so if it was allocated
1859 because of our call to aout_get_external_symbols, we free it up
1860 right away to save space. */
1861 if (old_external_syms == (struct external_nlist *) NULL
1862 && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
1863 {
1864#ifdef USE_MMAP
1865 bfd_free_window (&obj_aout_sym_window (abfd));
1866#else
1867 free (obj_aout_external_syms (abfd));
1868#endif
1869 obj_aout_external_syms (abfd) = NULL;
1870 }
1871
1872 return true;
1873}
1874
1875
1876/* We use a hash table when writing out symbols so that we only write
1877 out a particular string once. This helps particularly when the
1878 linker writes out stabs debugging entries, because each different
1879 contributing object file tends to have many duplicate stabs
1880 strings.
1881
1882 This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
1883 if BFD_TRADITIONAL_FORMAT is set. */
1884
1885static bfd_size_type add_to_stringtab
1886 PARAMS ((bfd *, struct bfd_strtab_hash *, const char *, boolean));
1887static boolean emit_stringtab PARAMS ((bfd *, struct bfd_strtab_hash *));
1888
1889/* Get the index of a string in a strtab, adding it if it is not
1890 already present. */
1891
1892static INLINE bfd_size_type
1893add_to_stringtab (abfd, tab, str, copy)
1894 bfd *abfd;
1895 struct bfd_strtab_hash *tab;
1896 const char *str;
1897 boolean copy;
1898{
1899 boolean hash;
1900 bfd_size_type index;
1901
1902 /* An index of 0 always means the empty string. */
1903 if (str == 0 || *str == '\0')
1904 return 0;
1905
1906 /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
1907 doesn't understand a hashed string table. */
1908 hash = true;
1909 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
1910 hash = false;
1911
1912 index = _bfd_stringtab_add (tab, str, hash, copy);
1913
1914 if (index != (bfd_size_type) -1)
1915 {
1916 /* Add BYTES_IN_WORD to the return value to account for the
1917 space taken up by the string table size. */
1918 index += BYTES_IN_WORD;
1919 }
1920
1921 return index;
1922}
1923
1924/* Write out a strtab. ABFD is already at the right location in the
1925 file. */
1926
1927static boolean
1928emit_stringtab (abfd, tab)
1929 register bfd *abfd;
1930 struct bfd_strtab_hash *tab;
1931{
1932 bfd_byte buffer[BYTES_IN_WORD];
1933
1934 /* The string table starts with the size. */
1935 PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
1936 if (bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
1937 return false;
1938
1939 return _bfd_stringtab_emit (abfd, tab);
1940}
1941
1942
1943boolean
1944NAME(aout,write_syms) (abfd)
1945 bfd *abfd;
1946{
1947 unsigned int count ;
1948 asymbol **generic = bfd_get_outsymbols (abfd);
1949 struct bfd_strtab_hash *strtab;
1950
1951 strtab = _bfd_stringtab_init ();
1952 if (strtab == NULL)
1953 return false;
1954
1955 for (count = 0; count < bfd_get_symcount (abfd); count++)
1956 {
1957 asymbol *g = generic[count];
1958 bfd_size_type indx;
1959 struct external_nlist nsp;
1960
1961 indx = add_to_stringtab (abfd, strtab, g->name, false);
1962 if (indx == (bfd_size_type) -1)
1963 goto error_return;
1964 PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
1965
1966 if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
1967 {
1968 bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc);
1969 bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other);
1970 bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type);
1971 }
1972 else
1973 {
1974 bfd_h_put_16(abfd,0, nsp.e_desc);
1975 bfd_h_put_8(abfd, 0, nsp.e_other);
1976 bfd_h_put_8(abfd, 0, nsp.e_type);
1977 }
1978
1979 if (! translate_to_native_sym_flags (abfd, g, &nsp))
1980 goto error_return;
1981
1982 if (bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd)
1983 != EXTERNAL_NLIST_SIZE)
1984 goto error_return;
1985
1986 /* NB: `KEEPIT' currently overlays `udata.p', so set this only
1987 here, at the end. */
1988 g->KEEPIT = count;
1989 }
1990
1991 if (! emit_stringtab (abfd, strtab))
1992 goto error_return;
1993
1994 _bfd_stringtab_free (strtab);
1995
1996 return true;
1997
1998error_return:
1999 _bfd_stringtab_free (strtab);
2000 return false;
2001}
2002
2003
2004long
2005NAME(aout,get_symtab) (abfd, location)
2006 bfd *abfd;
2007 asymbol **location;
2008{
2009 unsigned int counter = 0;
2010 aout_symbol_type *symbase;
2011
2012 if (!NAME(aout,slurp_symbol_table) (abfd))
2013 return -1;
2014
2015 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
2016 *(location++) = (asymbol *) ( symbase++);
2017 *location++ =0;
2018 return bfd_get_symcount (abfd);
2019}
2020
2021
2022/* Standard reloc stuff */
2023/* Output standard relocation information to a file in target byte order. */
2024
2025extern void NAME(aout,swap_std_reloc_out)
2026 PARAMS ((bfd *, arelent *, struct reloc_std_external *));
2027
2028void
2029NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
2030 bfd *abfd;
2031 arelent *g;
2032 struct reloc_std_external *natptr;
2033{
2034 int r_index;
2035 asymbol *sym = *(g->sym_ptr_ptr);
2036 int r_extern;
2037 unsigned int r_length;
2038 int r_pcrel;
2039 int r_baserel, r_jmptable, r_relative;
2040 asection *output_section = sym->section->output_section;
2041
2042 PUT_WORD(abfd, g->address, natptr->r_address);
2043
2044 r_length = g->howto->size ; /* Size as a power of two */
2045 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
2046 /* XXX This relies on relocs coming from a.out files. */
2047 r_baserel = (g->howto->type & 8) != 0;
2048 r_jmptable = (g->howto->type & 16) != 0;
2049 r_relative = (g->howto->type & 32) != 0;
2050
2051#if 0
2052 /* For a standard reloc, the addend is in the object file. */
2053 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
2054#endif
2055
2056 /* name was clobbered by aout_write_syms to be symbol index */
2057
2058 /* If this relocation is relative to a symbol then set the
2059 r_index to the symbols index, and the r_extern bit.
2060
2061 Absolute symbols can come in in two ways, either as an offset
2062 from the abs section, or as a symbol which has an abs value.
2063 check for that here
2064 */
2065
2066 if (bfd_is_com_section (output_section)
2067 || bfd_is_abs_section (output_section)
2068 || bfd_is_und_section (output_section))
2069 {
2070 if (bfd_abs_section_ptr->symbol == sym)
2071 {
2072 /* Whoops, looked like an abs symbol, but is really an offset
2073 from the abs section */
2074 r_index = N_ABS;
2075 r_extern = 0;
2076 }
2077 else
2078 {
2079 /* Fill in symbol */
2080 r_extern = 1;
2081 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2082
2083 }
2084 }
2085 else
2086 {
2087 /* Just an ordinary section */
2088 r_extern = 0;
2089 r_index = output_section->target_index;
2090 }
2091
2092 /* now the fun stuff */
2093 if (bfd_header_big_endian (abfd)) {
2094 natptr->r_index[0] = r_index >> 16;
2095 natptr->r_index[1] = r_index >> 8;
2096 natptr->r_index[2] = r_index;
2097 natptr->r_type[0] =
2098 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
2099 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
2100 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
2101 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
2102 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
2103 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
2104 } else {
2105 natptr->r_index[2] = r_index >> 16;
2106 natptr->r_index[1] = r_index >> 8;
2107 natptr->r_index[0] = r_index;
2108 natptr->r_type[0] =
2109 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
2110 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
2111 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
2112 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
2113 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
2114 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
2115 }
2116}
2117
2118/* Extended stuff */
2119/* Output extended relocation information to a file in target byte order. */
2120
2121extern void NAME(aout,swap_ext_reloc_out)
2122 PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
2123
2124void
2125NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
2126 bfd *abfd;
2127 arelent *g;
2128 register struct reloc_ext_external *natptr;
2129{
2130 int r_index;
2131 int r_extern;
2132 unsigned int r_type;
2133 unsigned int r_addend;
2134 asymbol *sym = *(g->sym_ptr_ptr);
2135 asection *output_section = sym->section->output_section;
2136
2137 PUT_WORD (abfd, g->address, natptr->r_address);
2138
2139 r_type = (unsigned int) g->howto->type;
2140
2141 r_addend = g->addend;
2142 if ((sym->flags & BSF_SECTION_SYM) != 0)
2143 r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma;
2144
2145 /* If this relocation is relative to a symbol then set the
2146 r_index to the symbols index, and the r_extern bit.
2147
2148 Absolute symbols can come in in two ways, either as an offset
2149 from the abs section, or as a symbol which has an abs value.
2150 check for that here. */
2151
2152 if (bfd_is_abs_section (bfd_get_section (sym)))
2153 {
2154 r_extern = 0;
2155 r_index = N_ABS;
2156 }
2157 else if ((sym->flags & BSF_SECTION_SYM) == 0)
2158 {
2159 if (bfd_is_und_section (bfd_get_section (sym))
2160 || (sym->flags & BSF_GLOBAL) != 0)
2161 r_extern = 1;
2162 else
2163 r_extern = 0;
2164 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2165 }
2166 else
2167 {
2168 /* Just an ordinary section */
2169 r_extern = 0;
2170 r_index = output_section->target_index;
2171 }
2172
2173 /* now the fun stuff */
2174 if (bfd_header_big_endian (abfd)) {
2175 natptr->r_index[0] = r_index >> 16;
2176 natptr->r_index[1] = r_index >> 8;
2177 natptr->r_index[2] = r_index;
2178 natptr->r_type[0] =
2179 ((r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
2180 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
2181 } else {
2182 natptr->r_index[2] = r_index >> 16;
2183 natptr->r_index[1] = r_index >> 8;
2184 natptr->r_index[0] = r_index;
2185 natptr->r_type[0] =
2186 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
2187 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
2188 }
2189
2190 PUT_WORD (abfd, r_addend, natptr->r_addend);
2191}
2192
2193/* BFD deals internally with all things based from the section they're
2194 in. so, something in 10 bytes into a text section with a base of
2195 50 would have a symbol (.text+10) and know .text vma was 50.
2196
2197 Aout keeps all it's symbols based from zero, so the symbol would
2198 contain 60. This macro subs the base of each section from the value
2199 to give the true offset from the section */
2200
2201#define MOVE_ADDRESS(ad) \
2202 if (r_extern) { \
2203 /* undefined symbol */ \
2204 cache_ptr->sym_ptr_ptr = symbols + r_index; \
2205 cache_ptr->addend = ad; \
2206 } else { \
2207 /* defined, section relative. replace symbol with pointer to \
2208 symbol which points to section */ \
2209 switch (r_index) { \
2210 case N_TEXT: \
2211 case N_TEXT | N_EXT: \
2212 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
2213 cache_ptr->addend = ad - su->textsec->vma; \
2214 break; \
2215 case N_DATA: \
2216 case N_DATA | N_EXT: \
2217 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
2218 cache_ptr->addend = ad - su->datasec->vma; \
2219 break; \
2220 case N_BSS: \
2221 case N_BSS | N_EXT: \
2222 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
2223 cache_ptr->addend = ad - su->bsssec->vma; \
2224 break; \
2225 default: \
2226 case N_ABS: \
2227 case N_ABS | N_EXT: \
2228 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
2229 cache_ptr->addend = ad; \
2230 break; \
2231 } \
2232 } \
2233
2234void
2235NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2236 bfd *abfd;
2237 struct reloc_ext_external *bytes;
2238 arelent *cache_ptr;
2239 asymbol **symbols;
2240 bfd_size_type symcount;
2241{
2242 unsigned int r_index;
2243 int r_extern;
2244 unsigned int r_type;
2245 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2246
2247 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2248
2249 /* now the fun stuff */
2250 if (bfd_header_big_endian (abfd)) {
2251 r_index = (bytes->r_index[0] << 16)
2252 | (bytes->r_index[1] << 8)
2253 | bytes->r_index[2];
2254 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2255 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2256 >> RELOC_EXT_BITS_TYPE_SH_BIG;
2257 } else {
2258 r_index = (bytes->r_index[2] << 16)
2259 | (bytes->r_index[1] << 8)
2260 | bytes->r_index[0];
2261 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2262 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2263 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
2264 }
2265
2266 cache_ptr->howto = howto_table_ext + r_type;
2267
2268 /* Base relative relocs are always against the symbol table,
2269 regardless of the setting of r_extern. r_extern just reflects
2270 whether the symbol the reloc is against is local or global. */
2271 if (r_type == RELOC_BASE10
2272 || r_type == RELOC_BASE13
2273 || r_type == RELOC_BASE22)
2274 r_extern = 1;
2275
2276 if (r_extern && r_index > symcount)
2277 {
2278 /* We could arrange to return an error, but it might be useful
2279 to see the file even if it is bad. */
2280 r_extern = 0;
2281 r_index = N_ABS;
2282 }
2283
2284 MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
2285}
2286
2287void
2288NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2289 bfd *abfd;
2290 struct reloc_std_external *bytes;
2291 arelent *cache_ptr;
2292 asymbol **symbols;
2293 bfd_size_type symcount;
2294{
2295 unsigned int r_index;
2296 int r_extern;
2297 unsigned int r_length;
2298 int r_pcrel;
2299 int r_baserel, r_jmptable, r_relative;
2300 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2301 unsigned int howto_idx;
2302
2303 cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
2304
2305 /* now the fun stuff */
2306 if (bfd_header_big_endian (abfd)) {
2307 r_index = (bytes->r_index[0] << 16)
2308 | (bytes->r_index[1] << 8)
2309 | bytes->r_index[2];
2310 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2311 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2312 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2313 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2314 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2315 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2316 >> RELOC_STD_BITS_LENGTH_SH_BIG;
2317 } else {
2318 r_index = (bytes->r_index[2] << 16)
2319 | (bytes->r_index[1] << 8)
2320 | bytes->r_index[0];
2321 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2322 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2323 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2324 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2325 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2326 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2327 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
2328 }
2329
2330 howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel
2331 + 16 * r_jmptable + 32 * r_relative;
2332 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
2333 cache_ptr->howto = howto_table_std + howto_idx;
2334 BFD_ASSERT (cache_ptr->howto->type != (unsigned int) -1);
2335
2336 /* Base relative relocs are always against the symbol table,
2337 regardless of the setting of r_extern. r_extern just reflects
2338 whether the symbol the reloc is against is local or global. */
2339 if (r_baserel)
2340 r_extern = 1;
2341
2342 if (r_extern && r_index > symcount)
2343 {
2344 /* We could arrange to return an error, but it might be useful
2345 to see the file even if it is bad. */
2346 r_extern = 0;
2347 r_index = N_ABS;
2348 }
2349
2350 MOVE_ADDRESS(0);
2351}
2352
2353/* Read and swap the relocs for a section. */
2354
2355boolean
2356NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
2357 bfd *abfd;
2358 sec_ptr asect;
2359 asymbol **symbols;
2360{
2361 unsigned int count;
2362 bfd_size_type reloc_size;
2363 PTR relocs;
2364 arelent *reloc_cache;
2365 size_t each_size;
2366 unsigned int counter = 0;
2367 arelent *cache_ptr;
2368
2369 if (asect->relocation)
2370 return true;
2371
2372 if (asect->flags & SEC_CONSTRUCTOR)
2373 return true;
2374
2375 if (asect == obj_datasec (abfd))
2376 reloc_size = exec_hdr(abfd)->a_drsize;
2377 else if (asect == obj_textsec (abfd))
2378 reloc_size = exec_hdr(abfd)->a_trsize;
2379 else if (asect == obj_bsssec (abfd))
2380 reloc_size = 0;
2381 else
2382 {
2383 bfd_set_error (bfd_error_invalid_operation);
2384 return false;
2385 }
2386
2387 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
2388 return false;
2389
2390 each_size = obj_reloc_entry_size (abfd);
2391
2392 count = reloc_size / each_size;
2393
2394 reloc_cache = (arelent *) bfd_malloc ((size_t) (count * sizeof (arelent)));
2395 if (reloc_cache == NULL && count != 0)
2396 return false;
2397 memset (reloc_cache, 0, count * sizeof (arelent));
2398
2399 relocs = bfd_malloc ((size_t) reloc_size);
2400 if (relocs == NULL && reloc_size != 0)
2401 {
2402 free (reloc_cache);
2403 return false;
2404 }
2405
2406 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)
2407 {
2408 free (relocs);
2409 free (reloc_cache);
2410 return false;
2411 }
2412
2413 cache_ptr = reloc_cache;
2414 if (each_size == RELOC_EXT_SIZE)
2415 {
2416 register struct reloc_ext_external *rptr =
2417 (struct reloc_ext_external *) relocs;
2418
2419 for (; counter < count; counter++, rptr++, cache_ptr++)
2420 MY_swap_ext_reloc_in (abfd, rptr, cache_ptr, symbols,
2421 bfd_get_symcount (abfd));
2422 }
2423 else
2424 {
2425 register struct reloc_std_external *rptr =
2426 (struct reloc_std_external *) relocs;
2427
2428 for (; counter < count; counter++, rptr++, cache_ptr++)
2429 MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
2430 bfd_get_symcount (abfd));
2431 }
2432
2433 free (relocs);
2434
2435 asect->relocation = reloc_cache;
2436 asect->reloc_count = cache_ptr - reloc_cache;
2437
2438 return true;
2439}
2440
2441/* Write out a relocation section into an object file. */
2442
2443boolean
2444NAME(aout,squirt_out_relocs) (abfd, section)
2445 bfd *abfd;
2446 asection *section;
2447{
2448 arelent **generic;
2449 unsigned char *native, *natptr;
2450 size_t each_size;
2451
2452 unsigned int count = section->reloc_count;
2453 size_t natsize;
2454
2455 if (count == 0 || section->orelocation == NULL)
2456 return true;
2457
2458 each_size = obj_reloc_entry_size (abfd);
2459 natsize = each_size * count;
2460 native = (unsigned char *) bfd_zalloc (abfd, natsize);
2461 if (!native)
2462 return false;
2463
2464 generic = section->orelocation;
2465
2466 if (each_size == RELOC_EXT_SIZE)
2467 {
2468 for (natptr = native;
2469 count != 0;
2470 --count, natptr += each_size, ++generic)
2471 MY_swap_ext_reloc_out (abfd, *generic,
2472 (struct reloc_ext_external *) natptr);
2473 }
2474 else
2475 {
2476 for (natptr = native;
2477 count != 0;
2478 --count, natptr += each_size, ++generic)
2479 MY_swap_std_reloc_out(abfd, *generic, (struct reloc_std_external *)natptr);
2480 }
2481
2482 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
2483 bfd_release(abfd, native);
2484 return false;
2485 }
2486 bfd_release (abfd, native);
2487
2488 return true;
2489}
2490
2491/* This is stupid. This function should be a boolean predicate */
2492long
2493NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols)
2494 bfd *abfd;
2495 sec_ptr section;
2496 arelent **relptr;
2497 asymbol **symbols;
2498{
2499 arelent *tblptr = section->relocation;
2500 unsigned int count;
2501
2502 if (section == obj_bsssec (abfd))
2503 {
2504 *relptr = NULL;
2505 return 0;
2506 }
2507
2508 if (!(tblptr || NAME(aout,slurp_reloc_table) (abfd, section, symbols)))
2509 return -1;
2510
2511 if (section->flags & SEC_CONSTRUCTOR) {
2512 arelent_chain *chain = section->constructor_chain;
2513 for (count = 0; count < section->reloc_count; count ++) {
2514 *relptr ++ = &chain->relent;
2515 chain = chain->next;
2516 }
2517 }
2518 else {
2519 tblptr = section->relocation;
2520
2521 for (count = 0; count++ < section->reloc_count;)
2522 {
2523 *relptr++ = tblptr++;
2524 }
2525 }
2526 *relptr = 0;
2527
2528 return section->reloc_count;
2529}
2530
2531long
2532NAME(aout,get_reloc_upper_bound) (abfd, asect)
2533 bfd *abfd;
2534 sec_ptr asect;
2535{
2536 if (bfd_get_format (abfd) != bfd_object) {
2537 bfd_set_error (bfd_error_invalid_operation);
2538 return -1;
2539 }
2540 if (asect->flags & SEC_CONSTRUCTOR) {
2541 return (sizeof (arelent *) * (asect->reloc_count+1));
2542 }
2543
2544 if (asect == obj_datasec (abfd))
2545 return (sizeof (arelent *)
2546 * ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
2547 + 1));
2548
2549 if (asect == obj_textsec (abfd))
2550 return (sizeof (arelent *)
2551 * ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
2552 + 1));
2553
2554 if (asect == obj_bsssec (abfd))
2555 return sizeof (arelent *);
2556
2557 if (asect == obj_bsssec (abfd))
2558 return 0;
2559
2560 bfd_set_error (bfd_error_invalid_operation);
2561 return -1;
2562}
2563
2564
2565long
2566NAME(aout,get_symtab_upper_bound) (abfd)
2567 bfd *abfd;
2568{
2569 if (!NAME(aout,slurp_symbol_table) (abfd))
2570 return -1;
2571
2572 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2573}
2574
2575 alent *
2576NAME(aout,get_lineno) (ignore_abfd, ignore_symbol)
2577 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2578 asymbol *ignore_symbol ATTRIBUTE_UNUSED;
2579{
2580 return (alent *)NULL;
2581}
2582
2583void
2584NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
2585 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2586 asymbol *symbol;
2587 symbol_info *ret;
2588{
2589 bfd_symbol_info (symbol, ret);
2590
2591 if (ret->type == '?')
2592 {
2593 int type_code = aout_symbol(symbol)->type & 0xff;
2594 const char *stab_name = bfd_get_stab_name (type_code);
2595 static char buf[10];
2596
2597 if (stab_name == NULL)
2598 {
2599 sprintf (buf, "(%d)", type_code);
2600 stab_name = buf;
2601 }
2602 ret->type = '-';
2603 ret->stab_type = type_code;
2604 ret->stab_other = (unsigned) (aout_symbol(symbol)->other & 0xff);
2605 ret->stab_desc = (unsigned) (aout_symbol(symbol)->desc & 0xffff);
2606 ret->stab_name = stab_name;
2607 }
2608}
2609
2610void
2611NAME(aout,print_symbol) (ignore_abfd, afile, symbol, how)
2612 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2613 PTR afile;
2614 asymbol *symbol;
2615 bfd_print_symbol_type how;
2616{
2617 FILE *file = (FILE *)afile;
2618
2619 switch (how) {
2620 case bfd_print_symbol_name:
2621 if (symbol->name)
2622 fprintf (file,"%s", symbol->name);
2623 break;
2624 case bfd_print_symbol_more:
2625 fprintf (file,"%4x %2x %2x",(unsigned) (aout_symbol(symbol)->desc & 0xffff),
2626 (unsigned) (aout_symbol(symbol)->other & 0xff),
2627 (unsigned) (aout_symbol(symbol)->type));
2628 break;
2629 case bfd_print_symbol_all:
2630 {
2631 CONST char *section_name = symbol->section->name;
2632
2633 bfd_print_symbol_vandf((PTR)file,symbol);
2634
2635 fprintf (file," %-5s %04x %02x %02x",
2636 section_name,
2637 (unsigned) (aout_symbol(symbol)->desc & 0xffff),
2638 (unsigned) (aout_symbol(symbol)->other & 0xff),
2639 (unsigned) (aout_symbol(symbol)->type & 0xff));
2640 if (symbol->name)
2641 fprintf (file," %s", symbol->name);
2642 }
2643 break;
2644 }
2645}
2646
2647/* If we don't have to allocate more than 1MB to hold the generic
2648 symbols, we use the generic minisymbol methord: it's faster, since
2649 it only translates the symbols once, not multiple times. */
2650#define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
2651
2652/* Read minisymbols. For minisymbols, we use the unmodified a.out
2653 symbols. The minisymbol_to_symbol function translates these into
2654 BFD asymbol structures. */
2655
2656long
2657NAME(aout,read_minisymbols) (abfd, dynamic, minisymsp, sizep)
2658 bfd *abfd;
2659 boolean dynamic;
2660 PTR *minisymsp;
2661 unsigned int *sizep;
2662{
2663 if (dynamic)
2664 {
2665 /* We could handle the dynamic symbols here as well, but it's
2666 easier to hand them off. */
2667 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2668 }
2669
2670 if (! aout_get_external_symbols (abfd))
2671 return -1;
2672
2673 if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2674 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2675
2676 *minisymsp = (PTR) obj_aout_external_syms (abfd);
2677
2678 /* By passing the external symbols back from this routine, we are
2679 giving up control over the memory block. Clear
2680 obj_aout_external_syms, so that we do not try to free it
2681 ourselves. */
2682 obj_aout_external_syms (abfd) = NULL;
2683
2684 *sizep = EXTERNAL_NLIST_SIZE;
2685 return obj_aout_external_sym_count (abfd);
2686}
2687
2688/* Convert a minisymbol to a BFD asymbol. A minisymbol is just an
2689 unmodified a.out symbol. The SYM argument is a structure returned
2690 by bfd_make_empty_symbol, which we fill in here. */
2691
2692asymbol *
2693NAME(aout,minisymbol_to_symbol) (abfd, dynamic, minisym, sym)
2694 bfd *abfd;
2695 boolean dynamic;
2696 const PTR minisym;
2697 asymbol *sym;
2698{
2699 if (dynamic
2700 || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2701 return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
2702
2703 memset (sym, 0, sizeof (aout_symbol_type));
2704
2705 /* We call translate_symbol_table to translate a single symbol. */
2706 if (! (NAME(aout,translate_symbol_table)
2707 (abfd,
2708 (aout_symbol_type *) sym,
2709 (struct external_nlist *) minisym,
2710 (bfd_size_type) 1,
2711 obj_aout_external_strings (abfd),
2712 obj_aout_external_string_size (abfd),
2713 false)))
2714 return NULL;
2715
2716 return sym;
2717}
2718
2719/*
2720 provided a BFD, a section and an offset into the section, calculate
2721 and return the name of the source file and the line nearest to the
2722 wanted location.
2723*/
2724
2725boolean
2726NAME(aout,find_nearest_line)
2727 (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
2728 bfd *abfd;
2729 asection *section;
2730 asymbol **symbols;
2731 bfd_vma offset;
2732 CONST char **filename_ptr;
2733 CONST char **functionname_ptr;
2734 unsigned int *line_ptr;
2735{
2736 /* Run down the file looking for the filename, function and linenumber */
2737 asymbol **p;
2738 CONST char *directory_name = NULL;
2739 CONST char *main_file_name = NULL;
2740 CONST char *current_file_name = NULL;
2741 CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
2742 CONST char *line_directory_name = NULL; /* Value of directory_name at line number. */
2743 bfd_vma low_line_vma = 0;
2744 bfd_vma low_func_vma = 0;
2745 asymbol *func = 0;
2746 size_t filelen, funclen;
2747 char *buf;
2748
2749 *filename_ptr = abfd->filename;
2750 *functionname_ptr = 0;
2751 *line_ptr = 0;
2752 if (symbols != (asymbol **)NULL) {
2753 for (p = symbols; *p; p++) {
2754 aout_symbol_type *q = (aout_symbol_type *) (*p);
2755 next:
2756 switch (q->type){
2757 case N_TEXT:
2758 /* If this looks like a file name symbol, and it comes after
2759 the line number we have found so far, but before the
2760 offset, then we have probably not found the right line
2761 number. */
2762 if (q->symbol.value <= offset
2763 && ((q->symbol.value > low_line_vma
2764 && (line_file_name != NULL
2765 || *line_ptr != 0))
2766 || (q->symbol.value > low_func_vma
2767 && func != NULL)))
2768 {
2769 const char *symname;
2770
2771 symname = q->symbol.name;
2772 if (strcmp (symname + strlen (symname) - 2, ".o") == 0)
2773 {
2774 if (q->symbol.value > low_line_vma)
2775 {
2776 *line_ptr = 0;
2777 line_file_name = NULL;
2778 }
2779 if (q->symbol.value > low_func_vma)
2780 func = NULL;
2781 }
2782 }
2783 break;
2784
2785 case N_SO:
2786 /* If this symbol is less than the offset, but greater than
2787 the line number we have found so far, then we have not
2788 found the right line number. */
2789 if (q->symbol.value <= offset)
2790 {
2791 if (q->symbol.value > low_line_vma)
2792 {
2793 *line_ptr = 0;
2794 line_file_name = NULL;
2795 }
2796 if (q->symbol.value > low_func_vma)
2797 func = NULL;
2798 }
2799
2800 main_file_name = current_file_name = q->symbol.name;
2801 /* Look ahead to next symbol to check if that too is an N_SO. */
2802 p++;
2803 if (*p == NULL)
2804 break;
2805 q = (aout_symbol_type *) (*p);
2806 if (q->type != (int)N_SO)
2807 goto next;
2808
2809 /* Found a second N_SO First is directory; second is filename. */
2810 directory_name = current_file_name;
2811 main_file_name = current_file_name = q->symbol.name;
2812 if (obj_textsec(abfd) != section)
2813 goto done;
2814 break;
2815 case N_SOL:
2816 current_file_name = q->symbol.name;
2817 break;
2818
2819 case N_SLINE:
2820
2821 case N_DSLINE:
2822 case N_BSLINE:
2823 /* We'll keep this if it resolves nearer than the one we have
2824 already. */
2825 if (q->symbol.value >= low_line_vma
2826 && q->symbol.value <= offset)
2827 {
2828 *line_ptr = q->desc;
2829 low_line_vma = q->symbol.value;
2830 line_file_name = current_file_name;
2831 line_directory_name = directory_name;
2832 }
2833 break;
2834 case N_FUN:
2835 {
2836 /* We'll keep this if it is nearer than the one we have already */
2837 if (q->symbol.value >= low_func_vma &&
2838 q->symbol.value <= offset) {
2839 low_func_vma = q->symbol.value;
2840 func = (asymbol *)q;
2841 }
2842 else if (q->symbol.value > offset)
2843 goto done;
2844 }
2845 break;
2846 }
2847 }
2848 }
2849
2850 done:
2851 if (*line_ptr != 0)
2852 {
2853 main_file_name = line_file_name;
2854 directory_name = line_directory_name;
2855 }
2856
2857 if (main_file_name == NULL
2858 || IS_ABSOLUTE_PATH (main_file_name)
2859 || directory_name == NULL)
2860 filelen = 0;
2861 else
2862 filelen = strlen (directory_name) + strlen (main_file_name);
2863 if (func == NULL)
2864 funclen = 0;
2865 else
2866 funclen = strlen (bfd_asymbol_name (func));
2867
2868 if (adata (abfd).line_buf != NULL)
2869 free (adata (abfd).line_buf);
2870 if (filelen + funclen == 0)
2871 adata (abfd).line_buf = buf = NULL;
2872 else
2873 {
2874 buf = (char *) bfd_malloc (filelen + funclen + 3);
2875 adata (abfd).line_buf = buf;
2876 if (buf == NULL)
2877 return false;
2878 }
2879
2880 if (main_file_name != NULL)
2881 {
2882 if (IS_ABSOLUTE_PATH (main_file_name) || directory_name == NULL)
2883 *filename_ptr = main_file_name;
2884 else
2885 {
2886 sprintf (buf, "%s%s", directory_name, main_file_name);
2887 *filename_ptr = buf;
2888 buf += filelen + 1;
2889 }
2890 }
2891
2892 if (func)
2893 {
2894 const char *function = func->name;
2895 char *p;
2896
2897 /* The caller expects a symbol name. We actually have a
2898 function name, without the leading underscore. Put the
2899 underscore back in, so that the caller gets a symbol name. */
2900 if (bfd_get_symbol_leading_char (abfd) == '\0')
2901 strcpy (buf, function);
2902 else
2903 {
2904 buf[0] = bfd_get_symbol_leading_char (abfd);
2905 strcpy (buf + 1, function);
2906 }
2907 /* Have to remove : stuff */
2908 p = strchr (buf, ':');
2909 if (p != NULL)
2910 *p = '\0';
2911 *functionname_ptr = buf;
2912 }
2913
2914 return true;
2915}
2916
2917int
2918NAME(aout,sizeof_headers) (abfd, execable)
2919 bfd *abfd;
2920 boolean execable ATTRIBUTE_UNUSED;
2921{
2922 return adata(abfd).exec_bytes_size;
2923}
2924
2925/* Free all information we have cached for this BFD. We can always
2926 read it again later if we need it. */
2927
2928boolean
2929NAME(aout,bfd_free_cached_info) (abfd)
2930 bfd *abfd;
2931{
2932 asection *o;
2933
2934 if (bfd_get_format (abfd) != bfd_object
2935 || abfd->tdata.aout_data == NULL)
2936 return true;
2937
2938#define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
2939 BFCI_FREE (obj_aout_symbols (abfd));
2940#ifdef USE_MMAP
2941 obj_aout_external_syms (abfd) = 0;
2942 bfd_free_window (&obj_aout_sym_window (abfd));
2943 bfd_free_window (&obj_aout_string_window (abfd));
2944 obj_aout_external_strings (abfd) = 0;
2945#else
2946 BFCI_FREE (obj_aout_external_syms (abfd));
2947 BFCI_FREE (obj_aout_external_strings (abfd));
2948#endif
2949 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
2950 BFCI_FREE (o->relocation);
2951#undef BFCI_FREE
2952
2953 return true;
2954}
2955
2956
2957/* a.out link code. */
2958
2959static boolean aout_link_add_object_symbols
2960 PARAMS ((bfd *, struct bfd_link_info *));
2961static boolean aout_link_check_archive_element
2962 PARAMS ((bfd *, struct bfd_link_info *, boolean *));
2963static boolean aout_link_free_symbols PARAMS ((bfd *));
2964static boolean aout_link_check_ar_symbols
2965 PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
2966static boolean aout_link_add_symbols
2967 PARAMS ((bfd *, struct bfd_link_info *));
2968
2969/* Routine to create an entry in an a.out link hash table. */
2970
2971struct bfd_hash_entry *
2972NAME(aout,link_hash_newfunc) (entry, table, string)
2973 struct bfd_hash_entry *entry;
2974 struct bfd_hash_table *table;
2975 const char *string;
2976{
2977 struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
2978
2979 /* Allocate the structure if it has not already been allocated by a
2980 subclass. */
2981 if (ret == (struct aout_link_hash_entry *) NULL)
2982 ret = ((struct aout_link_hash_entry *)
2983 bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
2984 if (ret == (struct aout_link_hash_entry *) NULL)
2985 return (struct bfd_hash_entry *) ret;
2986
2987 /* Call the allocation method of the superclass. */
2988 ret = ((struct aout_link_hash_entry *)
2989 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2990 table, string));
2991 if (ret)
2992 {
2993 /* Set local fields. */
2994 ret->written = false;
2995 ret->indx = -1;
2996 }
2997
2998 return (struct bfd_hash_entry *) ret;
2999}
3000
3001/* Initialize an a.out link hash table. */
3002
3003boolean
3004NAME(aout,link_hash_table_init) (table, abfd, newfunc)
3005 struct aout_link_hash_table *table;
3006 bfd *abfd;
3007 struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
3008 struct bfd_hash_table *,
3009 const char *));
3010{
3011 return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
3012}
3013
3014/* Create an a.out link hash table. */
3015
3016struct bfd_link_hash_table *
3017NAME(aout,link_hash_table_create) (abfd)
3018 bfd *abfd;
3019{
3020 struct aout_link_hash_table *ret;
3021
3022 ret = ((struct aout_link_hash_table *)
3023 bfd_alloc (abfd, sizeof (struct aout_link_hash_table)));
3024 if (ret == NULL)
3025 return (struct bfd_link_hash_table *) NULL;
3026 if (! NAME(aout,link_hash_table_init) (ret, abfd,
3027 NAME(aout,link_hash_newfunc)))
3028 {
3029 free (ret);
3030 return (struct bfd_link_hash_table *) NULL;
3031 }
3032 return &ret->root;
3033}
3034
3035/* Given an a.out BFD, add symbols to the global hash table as
3036 appropriate. */
3037
3038boolean
3039NAME(aout,link_add_symbols) (abfd, info)
3040 bfd *abfd;
3041 struct bfd_link_info *info;
3042{
3043 switch (bfd_get_format (abfd))
3044 {
3045 case bfd_object:
3046 return aout_link_add_object_symbols (abfd, info);
3047 case bfd_archive:
3048 return _bfd_generic_link_add_archive_symbols
3049 (abfd, info, aout_link_check_archive_element);
3050 default:
3051 bfd_set_error (bfd_error_wrong_format);
3052 return false;
3053 }
3054}
3055
3056/* Add symbols from an a.out object file. */
3057
3058static boolean
3059aout_link_add_object_symbols (abfd, info)
3060 bfd *abfd;
3061 struct bfd_link_info *info;
3062{
3063 if (! aout_get_external_symbols (abfd))
3064 return false;
3065 if (! aout_link_add_symbols (abfd, info))
3066 return false;
3067 if (! info->keep_memory)
3068 {
3069 if (! aout_link_free_symbols (abfd))
3070 return false;
3071 }
3072 return true;
3073}
3074
3075/* Check a single archive element to see if we need to include it in
3076 the link. *PNEEDED is set according to whether this element is
3077 needed in the link or not. This is called from
3078 _bfd_generic_link_add_archive_symbols. */
3079
3080static boolean
3081aout_link_check_archive_element (abfd, info, pneeded)
3082 bfd *abfd;
3083 struct bfd_link_info *info;
3084 boolean *pneeded;
3085{
3086 if (! aout_get_external_symbols (abfd))
3087 return false;
3088
3089 if (! aout_link_check_ar_symbols (abfd, info, pneeded))
3090 return false;
3091
3092 if (*pneeded)
3093 {
3094 if (! aout_link_add_symbols (abfd, info))
3095 return false;
3096 }
3097
3098 if (! info->keep_memory || ! *pneeded)
3099 {
3100 if (! aout_link_free_symbols (abfd))
3101 return false;
3102 }
3103
3104 return true;
3105}
3106
3107/* Free up the internal symbols read from an a.out file. */
3108
3109static boolean
3110aout_link_free_symbols (abfd)
3111 bfd *abfd;
3112{
3113 if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
3114 {
3115#ifdef USE_MMAP
3116 bfd_free_window (&obj_aout_sym_window (abfd));
3117#else
3118 free ((PTR) obj_aout_external_syms (abfd));
3119#endif
3120 obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
3121 }
3122 if (obj_aout_external_strings (abfd) != (char *) NULL)
3123 {
3124#ifdef USE_MMAP
3125 bfd_free_window (&obj_aout_string_window (abfd));
3126#else
3127 free ((PTR) obj_aout_external_strings (abfd));
3128#endif
3129 obj_aout_external_strings (abfd) = (char *) NULL;
3130 }
3131 return true;
3132}
3133
3134/* Look through the internal symbols to see if this object file should
3135 be included in the link. We should include this object file if it
3136 defines any symbols which are currently undefined. If this object
3137 file defines a common symbol, then we may adjust the size of the
3138 known symbol but we do not include the object file in the link
3139 (unless there is some other reason to include it). */
3140
3141static boolean
3142aout_link_check_ar_symbols (abfd, info, pneeded)
3143 bfd *abfd;
3144 struct bfd_link_info *info;
3145 boolean *pneeded;
3146{
3147 register struct external_nlist *p;
3148 struct external_nlist *pend;
3149 char *strings;
3150
3151 *pneeded = false;
3152
3153 /* Look through all the symbols. */
3154 p = obj_aout_external_syms (abfd);
3155 pend = p + obj_aout_external_sym_count (abfd);
3156 strings = obj_aout_external_strings (abfd);
3157 for (; p < pend; p++)
3158 {
3159 int type = bfd_h_get_8 (abfd, p->e_type);
3160 const char *name;
3161 struct bfd_link_hash_entry *h;
3162
3163 /* Ignore symbols that are not externally visible. This is an
3164 optimization only, as we check the type more thoroughly
3165 below. */
3166 if (((type & N_EXT) == 0
3167 || IS_STAB(type)
3168 || type == N_FN)
3169 && type != N_WEAKA
3170 && type != N_WEAKT
3171 && type != N_WEAKD
3172 && type != N_WEAKB)
3173 {
3174 if (type == N_WARNING
3175 || type == N_INDR)
3176 ++p;
3177 continue;
3178 }
3179
3180 name = strings + GET_WORD (abfd, p->e_strx);
3181 h = bfd_link_hash_lookup (info->hash, name, false, false, true);
3182
3183 /* We are only interested in symbols that are currently
3184 undefined or common. */
3185 if (h == (struct bfd_link_hash_entry *) NULL
3186 || (h->type != bfd_link_hash_undefined
3187 && h->type != bfd_link_hash_common))
3188 {
3189 if (type == (N_INDR | N_EXT))
3190 ++p;
3191 continue;
3192 }
3193
3194 if (type == (N_TEXT | N_EXT)
3195 || type == (N_DATA | N_EXT)
3196 || type == (N_BSS | N_EXT)
3197 || type == (N_ABS | N_EXT)
3198 || type == (N_INDR | N_EXT)
3199#if defined (EMX)
3200 || type == (N_IMP1 | N_EXT)
3201#endif
3202 )
3203 {
3204 /* This object file defines this symbol. We must link it
3205 in. This is true regardless of whether the current
3206 definition of the symbol is undefined or common. If the
3207 current definition is common, we have a case in which we
3208 have already seen an object file including
3209 int a;
3210 and this object file from the archive includes
3211 int a = 5;
3212 In such a case we must include this object file.
3213
3214 FIXME: The SunOS 4.1.3 linker will pull in the archive
3215 element if the symbol is defined in the .data section,
3216 but not if it is defined in the .text section. That
3217 seems a bit crazy to me, and I haven't implemented it.
3218 However, it might be correct. */
3219 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3220 return false;
3221 *pneeded = true;
3222 return true;
3223 }
3224
3225 if (type == (N_UNDF | N_EXT))
3226 {
3227 bfd_vma value;
3228
3229 value = GET_WORD (abfd, p->e_value);
3230 if (value != 0)
3231 {
3232 /* This symbol is common in the object from the archive
3233 file. */
3234 if (h->type == bfd_link_hash_undefined)
3235 {
3236 bfd *symbfd;
3237 unsigned int power;
3238
3239 symbfd = h->u.undef.abfd;
3240 if (symbfd == (bfd *) NULL)
3241 {
3242 /* This symbol was created as undefined from
3243 outside BFD. We assume that we should link
3244 in the object file. This is done for the -u
3245 option in the linker. */
3246 if (! (*info->callbacks->add_archive_element) (info,
3247 abfd,
3248 name))
3249 return false;
3250 *pneeded = true;
3251 return true;
3252 }
3253 /* Turn the current link symbol into a common
3254 symbol. It is already on the undefs list. */
3255 h->type = bfd_link_hash_common;
3256 h->u.c.p = ((struct bfd_link_hash_common_entry *)
3257 bfd_hash_allocate (&info->hash->table,
3258 sizeof (struct bfd_link_hash_common_entry)));
3259 if (h->u.c.p == NULL)
3260 return false;
3261
3262 h->u.c.size = value;
3263
3264 /* FIXME: This isn't quite right. The maximum
3265 alignment of a common symbol should be set by the
3266 architecture of the output file, not of the input
3267 file. */
3268 power = bfd_log2 (value);
3269 if (power > bfd_get_arch_info (abfd)->section_align_power)
3270 power = bfd_get_arch_info (abfd)->section_align_power;
3271 h->u.c.p->alignment_power = power;
3272
3273 h->u.c.p->section = bfd_make_section_old_way (symbfd,
3274 "COMMON");
3275 }
3276 else
3277 {
3278 /* Adjust the size of the common symbol if
3279 necessary. */
3280 if (value > h->u.c.size)
3281 h->u.c.size = value;
3282 }
3283 }
3284 }
3285
3286 if (type == N_WEAKA
3287 || type == N_WEAKT
3288 || type == N_WEAKD
3289 || type == N_WEAKB)
3290 {
3291 /* This symbol is weak but defined. We must pull it in if
3292 the current link symbol is undefined, but we don't want
3293 it if the current link symbol is common. */
3294 if (h->type == bfd_link_hash_undefined)
3295 {
3296 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3297 return false;
3298 *pneeded = true;
3299 return true;
3300 }
3301 }
3302 }
3303
3304 /* We do not need this object file. */
3305 return true;
3306}
3307
3308/* Add all symbols from an object file to the hash table. */
3309
3310static boolean
3311aout_link_add_symbols (abfd, info)
3312 bfd *abfd;
3313 struct bfd_link_info *info;
3314{
3315 boolean (*add_one_symbol) PARAMS ((struct bfd_link_info *, bfd *,
3316 const char *, flagword, asection *,
3317 bfd_vma, const char *, boolean,
3318 boolean,
3319 struct bfd_link_hash_entry **));
3320 struct external_nlist *syms;
3321 bfd_size_type sym_count;
3322 char *strings;
3323 boolean copy;
3324 struct aout_link_hash_entry **sym_hash;
3325 register struct external_nlist *p;
3326 struct external_nlist *pend;
3327
3328 syms = obj_aout_external_syms (abfd);
3329 sym_count = obj_aout_external_sym_count (abfd);
3330 strings = obj_aout_external_strings (abfd);
3331 if (info->keep_memory)
3332 copy = false;
3333 else
3334 copy = true;
3335
3336 if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
3337 {
3338 if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
3339 (abfd, info, &syms, &sym_count, &strings)))
3340 return false;
3341 }
3342
3343 /* We keep a list of the linker hash table entries that correspond
3344 to particular symbols. We could just look them up in the hash
3345 table, but keeping the list is more efficient. Perhaps this
3346 should be conditional on info->keep_memory. */
3347 sym_hash = ((struct aout_link_hash_entry **)
3348 bfd_alloc (abfd,
3349 ((size_t) sym_count
3350 * sizeof (struct aout_link_hash_entry *))));
3351 if (sym_hash == NULL && sym_count != 0)
3352 return false;
3353 obj_aout_sym_hashes (abfd) = sym_hash;
3354
3355 add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
3356 if (add_one_symbol == NULL)
3357 add_one_symbol = _bfd_generic_link_add_one_symbol;
3358
3359 p = syms;
3360 pend = p + sym_count;
3361 for (; p < pend; p++, sym_hash++)
3362 {
3363 int type;
3364 const char *name;
3365 bfd_vma value;
3366 asection *section;
3367 flagword flags;
3368 const char *string;
3369
3370 *sym_hash = NULL;
3371
3372 type = bfd_h_get_8 (abfd, p->e_type);
3373
3374 /* Ignore debugging symbols. */
3375 if (IS_STAB(type))
3376 continue;
3377
3378 name = strings + GET_WORD (abfd, p->e_strx);
3379 value = GET_WORD (abfd, p->e_value);
3380 flags = BSF_GLOBAL;
3381 string = NULL;
3382 switch (type)
3383 {
3384 default:
3385 abort ();
3386
3387 case N_UNDF:
3388 case N_ABS:
3389 case N_TEXT:
3390 case N_DATA:
3391 case N_BSS:
3392 case N_FN_SEQ:
3393 case N_COMM:
3394 case N_SETV:
3395 case N_FN:
3396 /* Ignore symbols that are not externally visible. */
3397 continue;
3398 case N_INDR:
3399 /* Ignore local indirect symbol. */
3400 ++p;
3401 ++sym_hash;
3402 continue;
3403
3404 case N_UNDF | N_EXT:
3405 if (value == 0)
3406 {
3407 section = bfd_und_section_ptr;
3408 flags = 0;
3409 }
3410 else
3411 section = bfd_com_section_ptr;
3412 break;
3413 case N_ABS | N_EXT:
3414 section = bfd_abs_section_ptr;
3415 break;
3416 case N_TEXT | N_EXT:
3417 section = obj_textsec (abfd);
3418 value -= bfd_get_section_vma (abfd, section);
3419 break;
3420 case N_DATA | N_EXT:
3421 case N_SETV | N_EXT:
3422 /* Treat N_SETV symbols as N_DATA symbol; see comment in
3423 translate_from_native_sym_flags. */
3424 section = obj_datasec (abfd);
3425 value -= bfd_get_section_vma (abfd, section);
3426 break;
3427 case N_BSS | N_EXT:
3428 section = obj_bsssec (abfd);
3429 value -= bfd_get_section_vma (abfd, section);
3430 break;
3431 case N_INDR | N_EXT:
3432 /* An indirect symbol. The next symbol is the symbol
3433 which this one really is. */
3434 BFD_ASSERT (p + 1 < pend);
3435 ++p;
3436 string = strings + GET_WORD (abfd, p->e_strx);
3437 section = bfd_ind_section_ptr;
3438 flags |= BSF_INDIRECT;
3439 break;
3440 case N_COMM | N_EXT:
3441 section = bfd_com_section_ptr;
3442 break;
3443 case N_SETA: case N_SETA | N_EXT:
3444 section = bfd_abs_section_ptr;
3445 flags |= BSF_CONSTRUCTOR;
3446 break;
3447 case N_SETT: case N_SETT | N_EXT:
3448 section = obj_textsec (abfd);
3449 flags |= BSF_CONSTRUCTOR;
3450 value -= bfd_get_section_vma (abfd, section);
3451 break;
3452 case N_SETD: case N_SETD | N_EXT:
3453 section = obj_datasec (abfd);
3454 flags |= BSF_CONSTRUCTOR;
3455 value -= bfd_get_section_vma (abfd, section);
3456 break;
3457 case N_SETB: case N_SETB | N_EXT:
3458 section = obj_bsssec (abfd);
3459 flags |= BSF_CONSTRUCTOR;
3460 value -= bfd_get_section_vma (abfd, section);
3461 break;
3462 case N_WARNING:
3463 /* A warning symbol. The next symbol is the one to warn
3464 about. */
3465 BFD_ASSERT (p + 1 < pend);
3466 ++p;
3467 string = name;
3468 name = strings + GET_WORD (abfd, p->e_strx);
3469 section = bfd_und_section_ptr;
3470 flags |= BSF_WARNING;
3471 break;
3472 case N_WEAKU:
3473 section = bfd_und_section_ptr;
3474 flags = BSF_WEAK;
3475 break;
3476 case N_WEAKA:
3477 section = bfd_abs_section_ptr;
3478 flags = BSF_WEAK;
3479 break;
3480 case N_WEAKT:
3481 section = obj_textsec (abfd);
3482 value -= bfd_get_section_vma (abfd, section);
3483 flags = BSF_WEAK;
3484 break;
3485 case N_WEAKD:
3486 section = obj_datasec (abfd);
3487 value -= bfd_get_section_vma (abfd, section);
3488 flags = BSF_WEAK;
3489 break;
3490 case N_WEAKB:
3491 section = obj_bsssec (abfd);
3492 value -= bfd_get_section_vma (abfd, section);
3493 flags = BSF_WEAK;
3494 break;
3495#ifdef EMX
3496 case N_IMP1 | N_EXT:
3497 section = bfd_abs_section_ptr;
3498 flags = BSF_EMX_IMPORT1;
3499 value = -1; /* -1 in *ABS* means external imported symbol */
3500 break;
3501 case N_IMP2 | N_EXT:
3502 section = bfd_abs_section_ptr;
3503 flags = BSF_EMX_IMPORT2;
3504 break;
3505#endif /* EMX */
3506 }
3507
3508 if (! ((*add_one_symbol)
3509 (info, abfd, name, flags, section, value, string, copy, false,
3510 (struct bfd_link_hash_entry **) sym_hash)))
3511 return false;
3512
3513 /* Restrict the maximum alignment of a common symbol based on
3514 the architecture, since a.out has no way to represent
3515 alignment requirements of a section in a .o file. FIXME:
3516 This isn't quite right: it should use the architecture of the
3517 output file, not the input files. */
3518 if ((*sym_hash)->root.type == bfd_link_hash_common
3519 && ((*sym_hash)->root.u.c.p->alignment_power >
3520 bfd_get_arch_info (abfd)->section_align_power))
3521 (*sym_hash)->root.u.c.p->alignment_power =
3522 bfd_get_arch_info (abfd)->section_align_power;
3523
3524 /* If this is a set symbol, and we are not building sets, then
3525 it is possible for the hash entry to not have been set. In
3526 such a case, treat the symbol as not globally defined. */
3527 if ((*sym_hash)->root.type == bfd_link_hash_new)
3528 {
3529 BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
3530 *sym_hash = NULL;
3531 }
3532
3533 if (type == (N_INDR | N_EXT) || type == N_WARNING)
3534 ++sym_hash;
3535 }
3536
3537 return true;
3538}
3539
3540
3541/* A hash table used for header files with N_BINCL entries. */
3542
3543struct aout_link_includes_table
3544{
3545 struct bfd_hash_table root;
3546};
3547
3548/* A linked list of totals that we have found for a particular header
3549 file. */
3550
3551struct aout_link_includes_totals
3552{
3553 struct aout_link_includes_totals *next;
3554 bfd_vma total;
3555};
3556
3557/* An entry in the header file hash table. */
3558
3559struct aout_link_includes_entry
3560{
3561 struct bfd_hash_entry root;
3562 /* List of totals we have found for this file. */
3563 struct aout_link_includes_totals *totals;
3564};
3565
3566/* Look up an entry in an the header file hash table. */
3567
3568#define aout_link_includes_lookup(table, string, create, copy) \
3569 ((struct aout_link_includes_entry *) \
3570 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
3571
3572/* During the final link step we need to pass around a bunch of
3573 information, so we do it in an instance of this structure. */
3574
3575struct aout_final_link_info
3576{
3577 /* General link information. */
3578 struct bfd_link_info *info;
3579 /* Output bfd. */
3580 bfd *output_bfd;
3581 /* Reloc file positions. */
3582 file_ptr treloff, dreloff;
3583 /* File position of symbols. */
3584 file_ptr symoff;
3585 /* String table. */
3586 struct bfd_strtab_hash *strtab;
3587 /* Header file hash table. */
3588 struct aout_link_includes_table includes;
3589 /* A buffer large enough to hold the contents of any section. */
3590 bfd_byte *contents;
3591 /* A buffer large enough to hold the relocs of any section. */
3592 PTR relocs;
3593 /* A buffer large enough to hold the symbol map of any input BFD. */
3594 int *symbol_map;
3595 /* A buffer large enough to hold output symbols of any input BFD. */
3596 struct external_nlist *output_syms;
3597};
3598
3599static struct bfd_hash_entry *aout_link_includes_newfunc
3600 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
3601static boolean aout_link_input_bfd
3602 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3603static boolean aout_link_write_symbols
3604 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3605static boolean aout_link_write_other_symbol
3606 PARAMS ((struct aout_link_hash_entry *, PTR));
3607static boolean aout_link_input_section
3608 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3609 asection *input_section, file_ptr *reloff_ptr,
3610 bfd_size_type rel_size));
3611static boolean aout_link_input_section_std
3612 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3613 asection *input_section, struct reloc_std_external *,
3614 bfd_size_type rel_size, bfd_byte *contents));
3615static boolean aout_link_input_section_ext
3616 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3617 asection *input_section, struct reloc_ext_external *,
3618 bfd_size_type rel_size, bfd_byte *contents));
3619static INLINE asection *aout_reloc_index_to_section
3620 PARAMS ((bfd *, int));
3621static boolean aout_link_reloc_link_order
3622 PARAMS ((struct aout_final_link_info *, asection *,
3623 struct bfd_link_order *));
3624
3625/* The function to create a new entry in the header file hash table. */
3626
3627static struct bfd_hash_entry *
3628aout_link_includes_newfunc (entry, table, string)
3629 struct bfd_hash_entry *entry;
3630 struct bfd_hash_table *table;
3631 const char *string;
3632{
3633 struct aout_link_includes_entry *ret =
3634 (struct aout_link_includes_entry *) entry;
3635
3636 /* Allocate the structure if it has not already been allocated by a
3637 subclass. */
3638 if (ret == (struct aout_link_includes_entry *) NULL)
3639 ret = ((struct aout_link_includes_entry *)
3640 bfd_hash_allocate (table,
3641 sizeof (struct aout_link_includes_entry)));
3642 if (ret == (struct aout_link_includes_entry *) NULL)
3643 return (struct bfd_hash_entry *) ret;
3644
3645 /* Call the allocation method of the superclass. */
3646 ret = ((struct aout_link_includes_entry *)
3647 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
3648 if (ret)
3649 {
3650 /* Set local fields. */
3651 ret->totals = NULL;
3652 }
3653
3654 return (struct bfd_hash_entry *) ret;
3655}
3656
3657/* Do the final link step. This is called on the output BFD. The
3658 INFO structure should point to a list of BFDs linked through the
3659 link_next field which can be used to find each BFD which takes part
3660 in the output. Also, each section in ABFD should point to a list
3661 of bfd_link_order structures which list all the input sections for
3662 the output section. */
3663
3664boolean
3665NAME(aout,final_link) (abfd, info, callback)
3666 bfd *abfd;
3667 struct bfd_link_info *info;
3668 void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
3669{
3670 struct aout_final_link_info aout_info;
3671 boolean includes_hash_initialized = false;
3672 register bfd *sub;
3673 bfd_size_type trsize, drsize;
3674 size_t max_contents_size;
3675 size_t max_relocs_size;
3676 size_t max_sym_count;
3677 bfd_size_type text_size;
3678 file_ptr text_end;
3679 register struct bfd_link_order *p;
3680 asection *o;
3681 boolean have_link_order_relocs;
3682
3683 if (info->shared)
3684 abfd->flags |= DYNAMIC;
3685
3686 aout_info.info = info;
3687 aout_info.output_bfd = abfd;
3688 aout_info.contents = NULL;
3689 aout_info.relocs = NULL;
3690 aout_info.symbol_map = NULL;
3691 aout_info.output_syms = NULL;
3692
3693 if (! bfd_hash_table_init_n (&aout_info.includes.root,
3694 aout_link_includes_newfunc,
3695 251))
3696 goto error_return;
3697 includes_hash_initialized = true;
3698
3699 /* Figure out the largest section size. Also, if generating
3700 relocateable output, count the relocs. */
3701 trsize = 0;
3702 drsize = 0;
3703 max_contents_size = 0;
3704 max_relocs_size = 0;
3705 max_sym_count = 0;
3706 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
3707 {
3708 size_t sz;
3709
3710 if (info->relocateable)
3711 {
3712 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3713 {
3714 trsize += exec_hdr (sub)->a_trsize;
3715 drsize += exec_hdr (sub)->a_drsize;
3716 }
3717 else
3718 {
3719 /* FIXME: We need to identify the .text and .data sections
3720 and call get_reloc_upper_bound and canonicalize_reloc to
3721 work out the number of relocs needed, and then multiply
3722 by the reloc size. */
3723 (*_bfd_error_handler)
3724 (_("%s: relocateable link from %s to %s not supported"),
3725 bfd_get_filename (abfd),
3726 sub->xvec->name, abfd->xvec->name);
3727 bfd_set_error (bfd_error_invalid_operation);
3728 goto error_return;
3729 }
3730 }
3731
3732 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3733 {
3734 sz = bfd_section_size (sub, obj_textsec (sub));
3735 if (sz > max_contents_size)
3736 max_contents_size = sz;
3737 sz = bfd_section_size (sub, obj_datasec (sub));
3738 if (sz > max_contents_size)
3739 max_contents_size = sz;
3740
3741 sz = exec_hdr (sub)->a_trsize;
3742 if (sz > max_relocs_size)
3743 max_relocs_size = sz;
3744 sz = exec_hdr (sub)->a_drsize;
3745 if (sz > max_relocs_size)
3746 max_relocs_size = sz;
3747
3748 sz = obj_aout_external_sym_count (sub);
3749 if (sz > max_sym_count)
3750 max_sym_count = sz;
3751 }
3752 }
3753
3754 if (info->relocateable)
3755 {
3756 if (obj_textsec (abfd) != (asection *) NULL)
3757 trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
3758 ->link_order_head)
3759 * obj_reloc_entry_size (abfd));
3760 if (obj_datasec (abfd) != (asection *) NULL)
3761 drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
3762 ->link_order_head)
3763 * obj_reloc_entry_size (abfd));
3764 }
3765
3766 exec_hdr (abfd)->a_trsize = trsize;
3767 exec_hdr (abfd)->a_drsize = drsize;
3768
3769 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
3770
3771 /* Adjust the section sizes and vmas according to the magic number.
3772 This sets a_text, a_data and a_bss in the exec_hdr and sets the
3773 filepos for each section. */
3774 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3775 goto error_return;
3776
3777 /* The relocation and symbol file positions differ among a.out
3778 targets. We are passed a callback routine from the backend
3779 specific code to handle this.
3780 FIXME: At this point we do not know how much space the symbol
3781 table will require. This will not work for any (nonstandard)
3782 a.out target that needs to know the symbol table size before it
3783 can compute the relocation file positions. This may or may not
3784 be the case for the hp300hpux target, for example. */
3785 (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3786 &aout_info.symoff);
3787 obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3788 obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3789 obj_sym_filepos (abfd) = aout_info.symoff;
3790
3791 /* We keep a count of the symbols as we output them. */
3792 obj_aout_external_sym_count (abfd) = 0;
3793
3794 /* We accumulate the string table as we write out the symbols. */
3795 aout_info.strtab = _bfd_stringtab_init ();
3796 if (aout_info.strtab == NULL)
3797 goto error_return;
3798
3799 /* Allocate buffers to hold section contents and relocs. */
3800 aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
3801 aout_info.relocs = (PTR) bfd_malloc (max_relocs_size);
3802 aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int *));
3803 aout_info.output_syms = ((struct external_nlist *)
3804 bfd_malloc ((max_sym_count + 1)
3805 * sizeof (struct external_nlist)));
3806 if ((aout_info.contents == NULL && max_contents_size != 0)
3807 || (aout_info.relocs == NULL && max_relocs_size != 0)
3808 || (aout_info.symbol_map == NULL && max_sym_count != 0)
3809 || aout_info.output_syms == NULL)
3810 goto error_return;
3811
3812 /* If we have a symbol named __DYNAMIC, force it out now. This is
3813 required by SunOS. Doing this here rather than in sunos.c is a
3814 hack, but it's easier than exporting everything which would be
3815 needed. */
3816 {
3817 struct aout_link_hash_entry *h;
3818
3819 h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
3820 false, false, false);
3821 if (h != NULL)
3822 aout_link_write_other_symbol (h, &aout_info);
3823 }
3824
3825 /* The most time efficient way to do the link would be to read all
3826 the input object files into memory and then sort out the
3827 information into the output file. Unfortunately, that will
3828 probably use too much memory. Another method would be to step
3829 through everything that composes the text section and write it
3830 out, and then everything that composes the data section and write
3831 it out, and then write out the relocs, and then write out the
3832 symbols. Unfortunately, that requires reading stuff from each
3833 input file several times, and we will not be able to keep all the
3834 input files open simultaneously, and reopening them will be slow.
3835
3836 What we do is basically process one input file at a time. We do
3837 everything we need to do with an input file once--copy over the
3838 section contents, handle the relocation information, and write
3839 out the symbols--and then we throw away the information we read
3840 from it. This approach requires a lot of lseeks of the output
3841 file, which is unfortunate but still faster than reopening a lot
3842 of files.
3843
3844 We use the output_has_begun field of the input BFDs to see
3845 whether we have already handled it. */
3846 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3847 sub->output_has_begun = false;
3848
3849 /* Mark all sections which are to be included in the link. This
3850 will normally be every section. We need to do this so that we
3851 can identify any sections which the linker has decided to not
3852 include. */
3853 for (o = abfd->sections; o != NULL; o = o->next)
3854 {
3855 for (p = o->link_order_head; p != NULL; p = p->next)
3856 {
3857 if (p->type == bfd_indirect_link_order)
3858 p->u.indirect.section->linker_mark = true;
3859 }
3860 }
3861
3862 have_link_order_relocs = false;
3863 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3864 {
3865 for (p = o->link_order_head;
3866 p != (struct bfd_link_order *) NULL;
3867 p = p->next)
3868 {
3869 if (p->type == bfd_indirect_link_order
3870 && (bfd_get_flavour (p->u.indirect.section->owner)
3871 == bfd_target_aout_flavour))
3872 {
3873 bfd *input_bfd;
3874
3875 input_bfd = p->u.indirect.section->owner;
3876 if (! input_bfd->output_has_begun)
3877 {
3878 if (! aout_link_input_bfd (&aout_info, input_bfd))
3879 goto error_return;
3880 input_bfd->output_has_begun = true;
3881 }
3882 }
3883 else if (p->type == bfd_section_reloc_link_order
3884 || p->type == bfd_symbol_reloc_link_order)
3885 {
3886 /* These are handled below. */
3887 have_link_order_relocs = true;
3888 }
3889 else
3890 {
3891 if (! _bfd_default_link_order (abfd, info, o, p))
3892 goto error_return;
3893 }
3894 }
3895 }
3896
3897 /* Write out any symbols that we have not already written out. */
3898 aout_link_hash_traverse (aout_hash_table (info),
3899 aout_link_write_other_symbol,
3900 (PTR) &aout_info);
3901
3902 /* Now handle any relocs we were asked to create by the linker.
3903 These did not come from any input file. We must do these after
3904 we have written out all the symbols, so that we know the symbol
3905 indices to use. */
3906 if (have_link_order_relocs)
3907 {
3908 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3909 {
3910 for (p = o->link_order_head;
3911 p != (struct bfd_link_order *) NULL;
3912 p = p->next)
3913 {
3914 if (p->type == bfd_section_reloc_link_order
3915 || p->type == bfd_symbol_reloc_link_order)
3916 {
3917 if (! aout_link_reloc_link_order (&aout_info, o, p))
3918 goto error_return;
3919 }
3920 }
3921 }
3922 }
3923
3924 if (aout_info.contents != NULL)
3925 {
3926 free (aout_info.contents);
3927 aout_info.contents = NULL;
3928 }
3929 if (aout_info.relocs != NULL)
3930 {
3931 free (aout_info.relocs);
3932 aout_info.relocs = NULL;
3933 }
3934 if (aout_info.symbol_map != NULL)
3935 {
3936 free (aout_info.symbol_map);
3937 aout_info.symbol_map = NULL;
3938 }
3939 if (aout_info.output_syms != NULL)
3940 {
3941 free (aout_info.output_syms);
3942 aout_info.output_syms = NULL;
3943 }
3944 if (includes_hash_initialized)
3945 {
3946 bfd_hash_table_free (&aout_info.includes.root);
3947 includes_hash_initialized = false;
3948 }
3949
3950 /* Finish up any dynamic linking we may be doing. */
3951 if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
3952 {
3953 if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
3954 goto error_return;
3955 }
3956
3957 /* Update the header information. */
3958 abfd->symcount = obj_aout_external_sym_count (abfd);
3959 exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
3960 obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
3961 obj_textsec (abfd)->reloc_count =
3962 exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
3963 obj_datasec (abfd)->reloc_count =
3964 exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
3965
3966 /* Write out the string table, unless there are no symbols. */
3967 if (abfd->symcount > 0)
3968 {
3969 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
3970 || ! emit_stringtab (abfd, aout_info.strtab))
3971 goto error_return;
3972 }
3973 else if (obj_textsec (abfd)->reloc_count == 0
3974 && obj_datasec (abfd)->reloc_count == 0)
3975 {
3976 bfd_byte b;
3977
3978 b = 0;
3979 if (bfd_seek (abfd,
3980 (obj_datasec (abfd)->filepos
3981 + exec_hdr (abfd)->a_data
3982 - 1),
3983 SEEK_SET) != 0
3984 || bfd_write (&b, 1, 1, abfd) != 1)
3985 goto error_return;
3986 }
3987
3988 return true;
3989
3990 error_return:
3991 if (aout_info.contents != NULL)
3992 free (aout_info.contents);
3993 if (aout_info.relocs != NULL)
3994 free (aout_info.relocs);
3995 if (aout_info.symbol_map != NULL)
3996 free (aout_info.symbol_map);
3997 if (aout_info.output_syms != NULL)
3998 free (aout_info.output_syms);
3999 if (includes_hash_initialized)
4000 bfd_hash_table_free (&aout_info.includes.root);
4001 return false;
4002}
4003
4004/* Link an a.out input BFD into the output file. */
4005
4006static boolean
4007aout_link_input_bfd (finfo, input_bfd)
4008 struct aout_final_link_info *finfo;
4009 bfd *input_bfd;
4010{
4011 bfd_size_type sym_count;
4012
4013 BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
4014
4015 /* If this is a dynamic object, it may need special handling. */
4016 if ((input_bfd->flags & DYNAMIC) != 0
4017 && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
4018 {
4019 return ((*aout_backend_info (input_bfd)->link_dynamic_object)
4020 (finfo->info, input_bfd));
4021 }
4022
4023 /* Get the symbols. We probably have them already, unless
4024 finfo->info->keep_memory is false. */
4025 if (! aout_get_external_symbols (input_bfd))
4026 return false;
4027
4028 sym_count = obj_aout_external_sym_count (input_bfd);
4029
4030 /* Write out the symbols and get a map of the new indices. The map
4031 is placed into finfo->symbol_map. */
4032 if (! aout_link_write_symbols (finfo, input_bfd))
4033 return false;
4034
4035 /* Relocate and write out the sections. These functions use the
4036 symbol map created by aout_link_write_symbols. The linker_mark
4037 field will be set if these sections are to be included in the
4038 link, which will normally be the case. */
4039 if (obj_textsec (input_bfd)->linker_mark)
4040 {
4041 if (! aout_link_input_section (finfo, input_bfd,
4042 obj_textsec (input_bfd),
4043 &finfo->treloff,
4044 exec_hdr (input_bfd)->a_trsize))
4045 return false;
4046 }
4047 if (obj_datasec (input_bfd)->linker_mark)
4048 {
4049 if (! aout_link_input_section (finfo, input_bfd,
4050 obj_datasec (input_bfd),
4051 &finfo->dreloff,
4052 exec_hdr (input_bfd)->a_drsize))
4053 return false;
4054 }
4055
4056 /* If we are not keeping memory, we don't need the symbols any
4057 longer. We still need them if we are keeping memory, because the
4058 strings in the hash table point into them. */
4059 if (! finfo->info->keep_memory)
4060 {
4061 if (! aout_link_free_symbols (input_bfd))
4062 return false;
4063 }
4064
4065 return true;
4066}
4067
4068/* Adjust and write out the symbols for an a.out file. Set the new
4069 symbol indices into a symbol_map. */
4070
4071static boolean
4072aout_link_write_symbols (finfo, input_bfd)
4073 struct aout_final_link_info *finfo;
4074 bfd *input_bfd;
4075{
4076 bfd *output_bfd;
4077 bfd_size_type sym_count;
4078 char *strings;
4079 enum bfd_link_strip strip;
4080 enum bfd_link_discard discard;
4081 struct external_nlist *outsym;
4082 bfd_size_type strtab_index;
4083 register struct external_nlist *sym;
4084 struct external_nlist *sym_end;
4085 struct aout_link_hash_entry **sym_hash;
4086 int *symbol_map;
4087 boolean pass;
4088 boolean skip_next;
4089
4090 output_bfd = finfo->output_bfd;
4091 sym_count = obj_aout_external_sym_count (input_bfd);
4092 strings = obj_aout_external_strings (input_bfd);
4093 strip = finfo->info->strip;
4094 discard = finfo->info->discard;
4095 outsym = finfo->output_syms;
4096
4097 /* First write out a symbol for this object file, unless we are
4098 discarding such symbols. */
4099 if (strip != strip_all
4100 && (strip != strip_some
4101 || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
4102 false, false) != NULL)
4103 && discard != discard_all)
4104 {
4105 bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type);
4106 bfd_h_put_8 (output_bfd, 0, outsym->e_other);
4107 bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc);
4108 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4109 input_bfd->filename, false);
4110 if (strtab_index == (bfd_size_type) -1)
4111 return false;
4112 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4113 PUT_WORD (output_bfd,
4114 (bfd_get_section_vma (output_bfd,
4115 obj_textsec (input_bfd)->output_section)
4116 + obj_textsec (input_bfd)->output_offset),
4117 outsym->e_value);
4118 ++obj_aout_external_sym_count (output_bfd);
4119 ++outsym;
4120 }
4121
4122 pass = false;
4123 skip_next = false;
4124 sym = obj_aout_external_syms (input_bfd);
4125 sym_end = sym + sym_count;
4126 sym_hash = obj_aout_sym_hashes (input_bfd);
4127 symbol_map = finfo->symbol_map;
4128 memset (symbol_map, 0, sym_count * sizeof *symbol_map);
4129 for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
4130 {
4131 const char *name;
4132 int type;
4133 struct aout_link_hash_entry *h;
4134 boolean skip;
4135 asection *symsec;
4136 bfd_vma val = 0;
4137 boolean copy;
4138
4139 /* We set *symbol_map to 0 above for all symbols. If it has
4140 already been set to -1 for this symbol, it means that we are
4141 discarding it because it appears in a duplicate header file.
4142 See the N_BINCL code below. */
4143 if (*symbol_map == -1)
4144 continue;
4145
4146 /* Initialize *symbol_map to -1, which means that the symbol was
4147 not copied into the output file. We will change it later if
4148 we do copy the symbol over. */
4149 *symbol_map = -1;
4150
4151 type = bfd_h_get_8 (input_bfd, sym->e_type);
4152 name = strings + GET_WORD (input_bfd, sym->e_strx);
4153
4154 h = NULL;
4155
4156 if (pass)
4157 {
4158 /* Pass this symbol through. It is the target of an
4159 indirect or warning symbol. */
4160 val = GET_WORD (input_bfd, sym->e_value);
4161 pass = false;
4162 }
4163 else if (skip_next)
4164 {
4165 /* Skip this symbol, which is the target of an indirect
4166 symbol that we have changed to no longer be an indirect
4167 symbol. */
4168 skip_next = false;
4169 continue;
4170 }
4171 else
4172 {
4173 struct aout_link_hash_entry *hresolve;
4174
4175 /* We have saved the hash table entry for this symbol, if
4176 there is one. Note that we could just look it up again
4177 in the hash table, provided we first check that it is an
4178 external symbol. */
4179 h = *sym_hash;
4180
4181 /* Use the name from the hash table, in case the symbol was
4182 wrapped. */
4183 if (h != NULL)
4184 name = h->root.root.string;
4185
4186 /* If this is an indirect or warning symbol, then change
4187 hresolve to the base symbol. We also change *sym_hash so
4188 that the relocation routines relocate against the real
4189 symbol. */
4190 hresolve = h;
4191 if (h != (struct aout_link_hash_entry *) NULL
4192 && (h->root.type == bfd_link_hash_indirect
4193 || h->root.type == bfd_link_hash_warning))
4194 {
4195 hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
4196 while (hresolve->root.type == bfd_link_hash_indirect
4197 || hresolve->root.type == bfd_link_hash_warning)
4198 hresolve = ((struct aout_link_hash_entry *)
4199 hresolve->root.u.i.link);
4200 *sym_hash = hresolve;
4201 }
4202
4203 /* If the symbol has already been written out, skip it. */
4204 if (h != (struct aout_link_hash_entry *) NULL
4205 && h->root.type != bfd_link_hash_warning
4206 && h->written)
4207 {
4208 if ((type & N_TYPE) == N_INDR
4209 || type == N_WARNING)
4210 skip_next = true;
4211 *symbol_map = h->indx;
4212 continue;
4213 }
4214
4215 /* See if we are stripping this symbol. */
4216 skip = false;
4217 switch (strip)
4218 {
4219 case strip_none:
4220 break;
4221 case strip_debugger:
4222 if (IS_STAB(type))
4223 skip = true;
4224 break;
4225 case strip_some:
4226 if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
4227 == NULL)
4228 skip = true;
4229 break;
4230 case strip_all:
4231 skip = true;
4232 break;
4233 }
4234 if (skip)
4235 {
4236 if (h != (struct aout_link_hash_entry *) NULL)
4237 h->written = true;
4238 continue;
4239 }
4240
4241 /* Get the value of the symbol. */
4242 if ((type & N_TYPE) == N_TEXT
4243 || type == N_WEAKT)
4244 symsec = obj_textsec (input_bfd);
4245 else if ((type & N_TYPE) == N_DATA
4246 || type == N_WEAKD)
4247 symsec = obj_datasec (input_bfd);
4248 else if ((type & N_TYPE) == N_BSS
4249 || type == N_WEAKB)
4250 symsec = obj_bsssec (input_bfd);
4251 else if ((type & N_TYPE) == N_ABS
4252 || type == N_WEAKA)
4253 symsec = bfd_abs_section_ptr;
4254 else if (((type & N_TYPE) == N_INDR
4255 && (hresolve == (struct aout_link_hash_entry *) NULL
4256 || (hresolve->root.type != bfd_link_hash_defined
4257 && hresolve->root.type != bfd_link_hash_defweak
4258 && hresolve->root.type != bfd_link_hash_common)))
4259 || type == N_WARNING)
4260 {
4261 /* Pass the next symbol through unchanged. The
4262 condition above for indirect symbols is so that if
4263 the indirect symbol was defined, we output it with
4264 the correct definition so the debugger will
4265 understand it. */
4266 pass = true;
4267 val = GET_WORD (input_bfd, sym->e_value);
4268 symsec = NULL;
4269 }
4270#ifdef EMX
4271 else if ((type == (N_IMP1 | N_EXT))
4272 || (type == (N_IMP2 | N_EXT)))
4273 symsec = bfd_abs_section_ptr;
4274#endif
4275 else if (IS_STAB(type))
4276 {
4277 val = GET_WORD (input_bfd, sym->e_value);
4278 symsec = NULL;
4279 }
4280 else
4281 {
4282 /* If we get here with an indirect symbol, it means that
4283 we are outputting it with a real definition. In such
4284 a case we do not want to output the next symbol,
4285 which is the target of the indirection. */
4286 if ((type & N_TYPE) == N_INDR)
4287 skip_next = true;
4288
4289 symsec = NULL;
4290
4291 /* We need to get the value from the hash table. We use
4292 hresolve so that if we have defined an indirect
4293 symbol we output the final definition. */
4294 if (h == (struct aout_link_hash_entry *) NULL)
4295 {
4296 switch (type & N_TYPE)
4297 {
4298 case N_SETT:
4299 symsec = obj_textsec (input_bfd);
4300 break;
4301 case N_SETD:
4302 symsec = obj_datasec (input_bfd);
4303 break;
4304 case N_SETB:
4305 symsec = obj_bsssec (input_bfd);
4306 break;
4307 case N_SETA:
4308 symsec = bfd_abs_section_ptr;
4309 break;
4310 default:
4311 val = 0;
4312 break;
4313 }
4314 }
4315 else if (hresolve->root.type == bfd_link_hash_defined
4316 || hresolve->root.type == bfd_link_hash_defweak)
4317 {
4318 asection *input_section;
4319 asection *output_section;
4320
4321 /* This case usually means a common symbol which was
4322 turned into a defined symbol. */
4323 input_section = hresolve->root.u.def.section;
4324 output_section = input_section->output_section;
4325 BFD_ASSERT (bfd_is_abs_section (output_section)
4326 || output_section->owner == output_bfd);
4327 val = (hresolve->root.u.def.value
4328 + bfd_get_section_vma (output_bfd, output_section)
4329 + input_section->output_offset);
4330
4331 /* Get the correct type based on the section. If
4332 this is a constructed set, force it to be
4333 globally visible. */
4334 if (type == N_SETT
4335 || type == N_SETD
4336 || type == N_SETB
4337 || type == N_SETA)
4338 type |= N_EXT;
4339
4340 type &=~ N_TYPE;
4341
4342 if (output_section == obj_textsec (output_bfd))
4343 type |= (hresolve->root.type == bfd_link_hash_defined
4344 ? N_TEXT
4345 : N_WEAKT);
4346 else if (output_section == obj_datasec (output_bfd))
4347 type |= (hresolve->root.type == bfd_link_hash_defined
4348 ? N_DATA
4349 : N_WEAKD);
4350 else if (output_section == obj_bsssec (output_bfd))
4351 type |= (hresolve->root.type == bfd_link_hash_defined
4352 ? N_BSS
4353 : N_WEAKB);
4354 else
4355 type |= (hresolve->root.type == bfd_link_hash_defined
4356 ? N_ABS
4357 : N_WEAKA);
4358 }
4359 else if (hresolve->root.type == bfd_link_hash_common)
4360 val = hresolve->root.u.c.size;
4361 else if (hresolve->root.type == bfd_link_hash_undefweak)
4362 {
4363 val = 0;
4364 type = N_WEAKU;
4365 }
4366 else
4367 val = 0;
4368 }
4369 if (symsec != (asection *) NULL)
4370 val = (symsec->output_section->vma
4371 + symsec->output_offset
4372 + (GET_WORD (input_bfd, sym->e_value)
4373 - symsec->vma));
4374
4375 /* If this is a global symbol set the written flag, and if
4376 it is a local symbol see if we should discard it. */
4377 if (h != (struct aout_link_hash_entry *) NULL)
4378 {
4379 h->written = true;
4380 h->indx = obj_aout_external_sym_count (output_bfd);
4381 }
4382 else if ((type & N_TYPE) != N_SETT
4383 && (type & N_TYPE) != N_SETD
4384 && (type & N_TYPE) != N_SETB
4385 && (type & N_TYPE) != N_SETA)
4386 {
4387 switch (discard)
4388 {
4389 case discard_none:
4390 break;
4391 case discard_l:
4392 if (!IS_STAB(type)
4393 && bfd_is_local_label_name (input_bfd, name))
4394 skip = true;
4395 break;
4396 case discard_all:
4397 skip = true;
4398 break;
4399 }
4400 if (skip)
4401 {
4402 pass = false;
4403 continue;
4404 }
4405 }
4406
4407 /* An N_BINCL symbol indicates the start of the stabs
4408 entries for a header file. We need to scan ahead to the
4409 next N_EINCL symbol, ignoring nesting, adding up all the
4410 characters in the symbol names, not including the file
4411 numbers in types (the first number after an open
4412 parenthesis). */
4413 if (type == N_BINCL)
4414 {
4415 struct external_nlist *incl_sym;
4416 int nest;
4417 struct aout_link_includes_entry *incl_entry;
4418 struct aout_link_includes_totals *t;
4419
4420 val = 0;
4421 nest = 0;
4422 for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
4423 {
4424 int incl_type;
4425
4426 incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
4427 if (incl_type == N_EINCL)
4428 {
4429 if (nest == 0)
4430 break;
4431 --nest;
4432 }
4433 else if (incl_type == N_BINCL)
4434 ++nest;
4435 else if (nest == 0)
4436 {
4437 const char *s;
4438
4439 s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
4440 for (; *s != '\0'; s++)
4441 {
4442 val += *s;
4443 if (*s == '(')
4444 {
4445 /* Skip the file number. */
4446 ++s;
4447 while (isdigit ((unsigned char) *s))
4448 ++s;
4449 --s;
4450 }
4451 }
4452 }
4453 }
4454
4455 /* If we have already included a header file with the
4456 same value, then replace this one with an N_EXCL
4457 symbol. */
4458 copy = ! finfo->info->keep_memory;
4459 incl_entry = aout_link_includes_lookup (&finfo->includes,
4460 name, true, copy);
4461 if (incl_entry == NULL)
4462 return false;
4463 for (t = incl_entry->totals; t != NULL; t = t->next)
4464 if (t->total == val)
4465 break;
4466 if (t == NULL)
4467 {
4468 /* This is the first time we have seen this header
4469 file with this set of stabs strings. */
4470 t = ((struct aout_link_includes_totals *)
4471 bfd_hash_allocate (&finfo->includes.root,
4472 sizeof *t));
4473 if (t == NULL)
4474 return false;
4475 t->total = val;
4476 t->next = incl_entry->totals;
4477 incl_entry->totals = t;
4478 }
4479 else
4480 {
4481 int *incl_map;
4482
4483 /* This is a duplicate header file. We must change
4484 it to be an N_EXCL entry, and mark all the
4485 included symbols to prevent outputting them. */
4486 type = N_EXCL;
4487
4488 nest = 0;
4489 for (incl_sym = sym + 1, incl_map = symbol_map + 1;
4490 incl_sym < sym_end;
4491 incl_sym++, incl_map++)
4492 {
4493 int incl_type;
4494
4495 incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
4496 if (incl_type == N_EINCL)
4497 {
4498 if (nest == 0)
4499 {
4500 *incl_map = -1;
4501 break;
4502 }
4503 --nest;
4504 }
4505 else if (incl_type == N_BINCL)
4506 ++nest;
4507 else if (nest == 0)
4508 *incl_map = -1;
4509 }
4510 }
4511 }
4512 }
4513
4514 /* Copy this symbol into the list of symbols we are going to
4515 write out. */
4516 bfd_h_put_8 (output_bfd, type, outsym->e_type);
4517 bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other),
4518 outsym->e_other);
4519 bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc),
4520 outsym->e_desc);
4521 copy = false;
4522 if (! finfo->info->keep_memory)
4523 {
4524 /* name points into a string table which we are going to
4525 free. If there is a hash table entry, use that string.
4526 Otherwise, copy name into memory. */
4527 if (h != (struct aout_link_hash_entry *) NULL)
4528 name = h->root.root.string;
4529 else
4530 copy = true;
4531 }
4532 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4533 name, copy);
4534 if (strtab_index == (bfd_size_type) -1)
4535 return false;
4536 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4537 PUT_WORD (output_bfd, val, outsym->e_value);
4538 *symbol_map = obj_aout_external_sym_count (output_bfd);
4539 ++obj_aout_external_sym_count (output_bfd);
4540 ++outsym;
4541 }
4542
4543 /* Write out the output symbols we have just constructed. */
4544 if (outsym > finfo->output_syms)
4545 {
4546 bfd_size_type outsym_count;
4547
4548 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
4549 return false;
4550 outsym_count = outsym - finfo->output_syms;
4551 if (bfd_write ((PTR) finfo->output_syms,
4552 (bfd_size_type) EXTERNAL_NLIST_SIZE,
4553 (bfd_size_type) outsym_count, output_bfd)
4554 != outsym_count * EXTERNAL_NLIST_SIZE)
4555 return false;
4556 finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
4557 }
4558
4559 return true;
4560}
4561
4562/* Write out a symbol that was not associated with an a.out input
4563 object. */
4564
4565static boolean
4566aout_link_write_other_symbol (h, data)
4567 struct aout_link_hash_entry *h;
4568 PTR data;
4569{
4570 struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
4571 bfd *output_bfd;
4572 int type;
4573 bfd_vma val;
4574 struct external_nlist outsym;
4575 bfd_size_type indx;
4576
4577 output_bfd = finfo->output_bfd;
4578
4579 if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
4580 {
4581 if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
4582 (output_bfd, finfo->info, h)))
4583 {
4584 /* FIXME: No way to handle errors. */
4585 abort ();
4586 }
4587 }
4588
4589 if (h->written)
4590 return true;
4591
4592 h->written = true;
4593
4594 /* An indx of -2 means the symbol must be written. */
4595 if (h->indx != -2
4596 && (finfo->info->strip == strip_all
4597 || (finfo->info->strip == strip_some
4598 && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
4599 false, false) == NULL)))
4600 return true;
4601
4602 switch (h->root.type)
4603 {
4604 default:
4605 abort ();
4606 /* Avoid variable not initialized warnings. */
4607 return true;
4608 case bfd_link_hash_new:
4609 /* This can happen for set symbols when sets are not being
4610 built. */
4611 return true;
4612 case bfd_link_hash_undefined:
4613 type = N_UNDF | N_EXT;
4614 val = 0;
4615 break;
4616 case bfd_link_hash_defined:
4617 case bfd_link_hash_defweak:
4618 {
4619 asection *sec;
4620
4621 sec = h->root.u.def.section->output_section;
4622 BFD_ASSERT (bfd_is_abs_section (sec)
4623 || sec->owner == output_bfd);
4624 if (sec == obj_textsec (output_bfd))
4625 type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
4626 else if (sec == obj_datasec (output_bfd))
4627 type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
4628 else if (sec == obj_bsssec (output_bfd))
4629 type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
4630 else
4631 type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
4632 type |= N_EXT;
4633 val = (h->root.u.def.value
4634 + sec->vma
4635 + h->root.u.def.section->output_offset);
4636 }
4637 break;
4638 case bfd_link_hash_common:
4639 type = N_UNDF | N_EXT;
4640 val = h->root.u.c.size;
4641 break;
4642 case bfd_link_hash_undefweak:
4643 type = N_WEAKU;
4644 val = 0;
4645 case bfd_link_hash_indirect:
4646 case bfd_link_hash_warning:
4647 /* FIXME: Ignore these for now. The circumstances under which
4648 they should be written out are not clear to me. */
4649 return true;
4650 }
4651
4652 bfd_h_put_8 (output_bfd, type, outsym.e_type);
4653 bfd_h_put_8 (output_bfd, 0, outsym.e_other);
4654 bfd_h_put_16 (output_bfd, 0, outsym.e_desc);
4655 indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
4656 false);
4657 if (indx == (bfd_size_type) -1)
4658 {
4659 /* FIXME: No way to handle errors. */
4660 abort ();
4661 }
4662 PUT_WORD (output_bfd, indx, outsym.e_strx);
4663 PUT_WORD (output_bfd, val, outsym.e_value);
4664
4665 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
4666 || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE,
4667 (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE)
4668 {
4669 /* FIXME: No way to handle errors. */
4670 abort ();
4671 }
4672
4673 finfo->symoff += EXTERNAL_NLIST_SIZE;
4674 h->indx = obj_aout_external_sym_count (output_bfd);
4675 ++obj_aout_external_sym_count (output_bfd);
4676
4677 return true;
4678}
4679
4680/* Link an a.out section into the output file. */
4681
4682static boolean
4683aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
4684 rel_size)
4685 struct aout_final_link_info *finfo;
4686 bfd *input_bfd;
4687 asection *input_section;
4688 file_ptr *reloff_ptr;
4689 bfd_size_type rel_size;
4690{
4691 bfd_size_type input_size;
4692 PTR relocs;
4693
4694 /* Get the section contents. */
4695 input_size = bfd_section_size (input_bfd, input_section);
4696 if (! bfd_get_section_contents (input_bfd, input_section,
4697 (PTR) finfo->contents,
4698 (file_ptr) 0, input_size))
4699 return false;
4700
4701 /* Read in the relocs if we haven't already done it. */
4702 if (aout_section_data (input_section) != NULL
4703 && aout_section_data (input_section)->relocs != NULL)
4704 relocs = aout_section_data (input_section)->relocs;
4705 else
4706 {
4707 relocs = finfo->relocs;
4708 if (rel_size > 0)
4709 {
4710 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
4711 || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
4712 return false;
4713 }
4714 }
4715
4716 /* Relocate the section contents. */
4717 if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4718 {
4719 if (! aout_link_input_section_std (finfo, input_bfd, input_section,
4720 (struct reloc_std_external *) relocs,
4721 rel_size, finfo->contents))
4722 return false;
4723 }
4724 else
4725 {
4726 if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
4727 (struct reloc_ext_external *) relocs,
4728 rel_size, finfo->contents))
4729 return false;
4730 }
4731
4732 /* Write out the section contents. */
4733 if (! bfd_set_section_contents (finfo->output_bfd,
4734 input_section->output_section,
4735 (PTR) finfo->contents,
4736 input_section->output_offset,
4737 input_size))
4738 return false;
4739
4740 /* If we are producing relocateable output, the relocs were
4741 modified, and we now write them out. */
4742 if (finfo->info->relocateable && rel_size > 0)
4743 {
4744 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
4745 return false;
4746 if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
4747 != rel_size)
4748 return false;
4749 *reloff_ptr += rel_size;
4750
4751 /* Assert that the relocs have not run into the symbols, and
4752 that if these are the text relocs they have not run into the
4753 data relocs. */
4754 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
4755 && (reloff_ptr != &finfo->treloff
4756 || (*reloff_ptr
4757 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
4758 }
4759
4760 return true;
4761}
4762
4763/* Get the section corresponding to a reloc index. */
4764
4765static INLINE asection *
4766aout_reloc_index_to_section (abfd, indx)
4767 bfd *abfd;
4768 int indx;
4769{
4770 switch (indx & N_TYPE)
4771 {
4772 case N_TEXT:
4773 return obj_textsec (abfd);
4774 case N_DATA:
4775 return obj_datasec (abfd);
4776 case N_BSS:
4777 return obj_bsssec (abfd);
4778 case N_ABS:
4779 case N_UNDF:
4780 return bfd_abs_section_ptr;
4781 default:
4782 abort ();
4783 }
4784 /*NOTREACHED*/
4785 return NULL;
4786}
4787
4788/* Relocate an a.out section using standard a.out relocs. */
4789
4790static boolean
4791aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
4792 rel_size, contents)
4793 struct aout_final_link_info *finfo;
4794 bfd *input_bfd;
4795 asection *input_section;
4796 struct reloc_std_external *relocs;
4797 bfd_size_type rel_size;
4798 bfd_byte *contents;
4799{
4800 boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
4801 bfd *, asection *,
4802 struct aout_link_hash_entry *,
4803 PTR, bfd_byte *, boolean *,
4804 bfd_vma *));
4805 bfd *output_bfd;
4806 boolean relocateable;
4807 struct external_nlist *syms;
4808 char *strings;
4809 struct aout_link_hash_entry **sym_hashes;
4810 int *symbol_map;
4811 bfd_size_type reloc_count;
4812 register struct reloc_std_external *rel;
4813 struct reloc_std_external *rel_end;
4814
4815 output_bfd = finfo->output_bfd;
4816 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4817
4818 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
4819 BFD_ASSERT (input_bfd->xvec->header_byteorder
4820 == output_bfd->xvec->header_byteorder);
4821
4822 relocateable = finfo->info->relocateable;
4823 syms = obj_aout_external_syms (input_bfd);
4824 strings = obj_aout_external_strings (input_bfd);
4825 sym_hashes = obj_aout_sym_hashes (input_bfd);
4826 symbol_map = finfo->symbol_map;
4827
4828 reloc_count = rel_size / RELOC_STD_SIZE;
4829 rel = relocs;
4830 rel_end = rel + reloc_count;
4831 for (; rel < rel_end; rel++)
4832 {
4833 bfd_vma r_addr;
4834 int r_index;
4835 int r_extern;
4836 int r_pcrel;
4837 int r_baserel = 0;
4838 reloc_howto_type *howto;
4839 struct aout_link_hash_entry *h = NULL;
4840 bfd_vma relocation;
4841 bfd_reloc_status_type r;
4842
4843 r_addr = GET_SWORD (input_bfd, rel->r_address);
4844
4845#ifdef MY_reloc_howto
4846 howto = MY_reloc_howto(input_bfd, rel, r_index, r_extern, r_pcrel);
4847#else
4848 {
4849 int r_jmptable;
4850 int r_relative;
4851 int r_length;
4852 unsigned int howto_idx;
4853
4854 if (bfd_header_big_endian (input_bfd))
4855 {
4856 r_index = ((rel->r_index[0] << 16)
4857 | (rel->r_index[1] << 8)
4858 | rel->r_index[2]);
4859 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
4860 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
4861 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
4862 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
4863 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
4864 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
4865 >> RELOC_STD_BITS_LENGTH_SH_BIG);
4866 }
4867 else
4868 {
4869 r_index = ((rel->r_index[2] << 16)
4870 | (rel->r_index[1] << 8)
4871 | rel->r_index[0]);
4872 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
4873 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
4874 r_baserel = (0 != (rel->r_type[0]
4875 & RELOC_STD_BITS_BASEREL_LITTLE));
4876 r_jmptable= (0 != (rel->r_type[0]
4877 & RELOC_STD_BITS_JMPTABLE_LITTLE));
4878 r_relative= (0 != (rel->r_type[0]
4879 & RELOC_STD_BITS_RELATIVE_LITTLE));
4880 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
4881 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
4882 }
4883
4884 howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
4885 + 16 * r_jmptable + 32 * r_relative);
4886 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
4887 howto = howto_table_std + howto_idx;
4888 }
4889#endif
4890
4891 if (relocateable)
4892 {
4893 /* We are generating a relocateable output file, and must
4894 modify the reloc accordingly. */
4895 if (r_extern)
4896 {
4897 /* If we know the symbol this relocation is against,
4898 convert it into a relocation against a section. This
4899 is what the native linker does. */
4900 h = sym_hashes[r_index];
4901 if (h != (struct aout_link_hash_entry *) NULL
4902#ifdef EMX
4903 /* Don't touch imported symbols */
4904 && (!bfd_is_abs_section (h->root.u.def.section)
4905 || (h->root.u.def.value != -1))
4906#endif
4907 && (h->root.type == bfd_link_hash_defined
4908 || h->root.type == bfd_link_hash_defweak))
4909 {
4910 asection *output_section;
4911
4912 /* Change the r_extern value. */
4913 if (bfd_header_big_endian (output_bfd))
4914 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
4915 else
4916 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
4917
4918 /* Compute a new r_index. */
4919 output_section = h->root.u.def.section->output_section;
4920 if (output_section == obj_textsec (output_bfd))
4921 r_index = N_TEXT;
4922 else if (output_section == obj_datasec (output_bfd))
4923 r_index = N_DATA;
4924 else if (output_section == obj_bsssec (output_bfd))
4925 r_index = N_BSS;
4926 else
4927 r_index = N_ABS;
4928
4929 /* Add the symbol value and the section VMA to the
4930 addend stored in the contents. */
4931 relocation = (h->root.u.def.value
4932 + output_section->vma
4933 + h->root.u.def.section->output_offset);
4934 }
4935 else
4936 {
4937 /* We must change r_index according to the symbol
4938 map. */
4939 r_index = symbol_map[r_index];
4940
4941 if (r_index == -1)
4942 {
4943 if (h != NULL)
4944 {
4945 /* We decided to strip this symbol, but it
4946 turns out that we can't. Note that we
4947 lose the other and desc information here.
4948 I don't think that will ever matter for a
4949 global symbol. */
4950 if (h->indx < 0)
4951 {
4952 h->indx = -2;
4953 h->written = false;
4954 if (! aout_link_write_other_symbol (h,
4955 (PTR) finfo))
4956 return false;
4957 }
4958 r_index = h->indx;
4959 }
4960 else
4961 {
4962 const char *name;
4963
4964 name = strings + GET_WORD (input_bfd,
4965 syms[r_index].e_strx);
4966 if (! ((*finfo->info->callbacks->unattached_reloc)
4967 (finfo->info, name, input_bfd, input_section,
4968 r_addr)))
4969 return false;
4970 r_index = 0;
4971 }
4972 }
4973
4974 relocation = 0;
4975 }
4976
4977 /* Write out the new r_index value. */
4978 if (bfd_header_big_endian (output_bfd))
4979 {
4980 rel->r_index[0] = r_index >> 16;
4981 rel->r_index[1] = r_index >> 8;
4982 rel->r_index[2] = r_index;
4983 }
4984 else
4985 {
4986 rel->r_index[2] = r_index >> 16;
4987 rel->r_index[1] = r_index >> 8;
4988 rel->r_index[0] = r_index;
4989 }
4990 }
4991 else
4992 {
4993 asection *section;
4994
4995 /* This is a relocation against a section. We must
4996 adjust by the amount that the section moved. */
4997 section = aout_reloc_index_to_section (input_bfd, r_index);
4998 relocation = (section->output_section->vma
4999 + section->output_offset
5000 - section->vma);
5001 }
5002
5003 /* Change the address of the relocation. */
5004 PUT_WORD (output_bfd,
5005 r_addr + input_section->output_offset,
5006 rel->r_address);
5007
5008 /* Adjust a PC relative relocation by removing the reference
5009 to the original address in the section and including the
5010 reference to the new address. */
5011 if (r_pcrel)
5012 relocation -= (input_section->output_section->vma
5013 + input_section->output_offset
5014 - input_section->vma);
5015
5016#ifdef MY_relocatable_reloc
5017 MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
5018#endif
5019
5020 if (relocation == 0)
5021 r = bfd_reloc_ok;
5022 else
5023 r = MY_relocate_contents (howto,
5024 input_bfd, relocation,
5025 contents + r_addr);
5026 }
5027 else
5028 {
5029 boolean hundef;
5030
5031 /* We are generating an executable, and must do a full
5032 relocation. */
5033 hundef = false;
5034
5035 if (r_extern)
5036 {
5037 h = sym_hashes[r_index];
5038
5039 if (h != (struct aout_link_hash_entry *) NULL
5040 && (h->root.type == bfd_link_hash_defined
5041 || h->root.type == bfd_link_hash_defweak))
5042 {
5043 relocation = (h->root.u.def.value
5044 + h->root.u.def.section->output_section->vma
5045 + h->root.u.def.section->output_offset);
5046 }
5047 else if (h != (struct aout_link_hash_entry *) NULL
5048 && h->root.type == bfd_link_hash_undefweak)
5049 relocation = 0;
5050 else
5051 {
5052 hundef = true;
5053 relocation = 0;
5054 }
5055 }
5056 else
5057 {
5058 asection *section;
5059
5060 section = aout_reloc_index_to_section (input_bfd, r_index);
5061 relocation = (section->output_section->vma
5062 + section->output_offset
5063 - section->vma);
5064 if (r_pcrel)
5065 relocation += input_section->vma;
5066 }
5067
5068 if (check_dynamic_reloc != NULL)
5069 {
5070 boolean skip;
5071
5072 if (! ((*check_dynamic_reloc)
5073 (finfo->info, input_bfd, input_section, h,
5074 (PTR) rel, contents, &skip, &relocation)))
5075 return false;
5076 if (skip)
5077 continue;
5078 }
5079
5080 /* Now warn if a global symbol is undefined. We could not
5081 do this earlier, because check_dynamic_reloc might want
5082 to skip this reloc. */
5083 if (hundef && ! finfo->info->shared && ! r_baserel)
5084 {
5085 const char *name;
5086
5087 if (h != NULL)
5088 name = h->root.root.string;
5089 else
5090 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5091 if (! ((*finfo->info->callbacks->undefined_symbol)
5092 (finfo->info, name, input_bfd, input_section,
5093 r_addr, true)))
5094 return false;
5095 }
5096
5097 r = MY_final_link_relocate (howto,
5098 input_bfd, input_section,
5099 contents, r_addr, relocation,
5100 (bfd_vma) 0);
5101 }
5102
5103 if (r != bfd_reloc_ok)
5104 {
5105 switch (r)
5106 {
5107 default:
5108 case bfd_reloc_outofrange:
5109 abort ();
5110 case bfd_reloc_overflow:
5111 {
5112 const char *name;
5113
5114 if (h != NULL)
5115 name = h->root.root.string;
5116 else if (r_extern)
5117 name = strings + GET_WORD (input_bfd,
5118 syms[r_index].e_strx);
5119 else
5120 {
5121 asection *s;
5122
5123 s = aout_reloc_index_to_section (input_bfd, r_index);
5124 name = bfd_section_name (input_bfd, s);
5125 }
5126 if (! ((*finfo->info->callbacks->reloc_overflow)
5127 (finfo->info, name, howto->name,
5128 (bfd_vma) 0, input_bfd, input_section, r_addr)))
5129 return false;
5130 }
5131 break;
5132 }
5133 }
5134 }
5135
5136 return true;
5137}
5138
5139/* Relocate an a.out section using extended a.out relocs. */
5140
5141static boolean
5142aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
5143 rel_size, contents)
5144 struct aout_final_link_info *finfo;
5145 bfd *input_bfd;
5146 asection *input_section;
5147 struct reloc_ext_external *relocs;
5148 bfd_size_type rel_size;
5149 bfd_byte *contents;
5150{
5151 boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
5152 bfd *, asection *,
5153 struct aout_link_hash_entry *,
5154 PTR, bfd_byte *, boolean *,
5155 bfd_vma *));
5156 bfd *output_bfd;
5157 boolean relocateable;
5158 struct external_nlist *syms;
5159 char *strings;
5160 struct aout_link_hash_entry **sym_hashes;
5161 int *symbol_map;
5162 bfd_size_type reloc_count;
5163 register struct reloc_ext_external *rel;
5164 struct reloc_ext_external *rel_end;
5165
5166 output_bfd = finfo->output_bfd;
5167 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
5168
5169 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
5170 BFD_ASSERT (input_bfd->xvec->header_byteorder
5171 == output_bfd->xvec->header_byteorder);
5172
5173 relocateable = finfo->info->relocateable;
5174 syms = obj_aout_external_syms (input_bfd);
5175 strings = obj_aout_external_strings (input_bfd);
5176 sym_hashes = obj_aout_sym_hashes (input_bfd);
5177 symbol_map = finfo->symbol_map;
5178
5179 reloc_count = rel_size / RELOC_EXT_SIZE;
5180 rel = relocs;
5181 rel_end = rel + reloc_count;
5182 for (; rel < rel_end; rel++)
5183 {
5184 bfd_vma r_addr;
5185 int r_index;
5186 int r_extern;
5187 unsigned int r_type;
5188 bfd_vma r_addend;
5189 struct aout_link_hash_entry *h = NULL;
5190 asection *r_section = NULL;
5191 bfd_vma relocation;
5192
5193 r_addr = GET_SWORD (input_bfd, rel->r_address);
5194
5195 if (bfd_header_big_endian (input_bfd))
5196 {
5197 r_index = ((rel->r_index[0] << 16)
5198 | (rel->r_index[1] << 8)
5199 | rel->r_index[2]);
5200 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
5201 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
5202 >> RELOC_EXT_BITS_TYPE_SH_BIG);
5203 }
5204 else
5205 {
5206 r_index = ((rel->r_index[2] << 16)
5207 | (rel->r_index[1] << 8)
5208 | rel->r_index[0]);
5209 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
5210 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
5211 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
5212 }
5213
5214 r_addend = GET_SWORD (input_bfd, rel->r_addend);
5215
5216 BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
5217
5218 if (relocateable)
5219 {
5220 /* We are generating a relocateable output file, and must
5221 modify the reloc accordingly. */
5222 if (r_extern
5223 || r_type == RELOC_BASE10
5224 || r_type == RELOC_BASE13
5225 || r_type == RELOC_BASE22)
5226 {
5227 /* If we know the symbol this relocation is against,
5228 convert it into a relocation against a section. This
5229 is what the native linker does. */
5230 if (r_type == RELOC_BASE10
5231 || r_type == RELOC_BASE13
5232 || r_type == RELOC_BASE22)
5233 h = NULL;
5234 else
5235 h = sym_hashes[r_index];
5236 if (h != (struct aout_link_hash_entry *) NULL
5237 && (h->root.type == bfd_link_hash_defined
5238 || h->root.type == bfd_link_hash_defweak))
5239 {
5240 asection *output_section;
5241
5242 /* Change the r_extern value. */
5243 if (bfd_header_big_endian (output_bfd))
5244 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
5245 else
5246 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
5247
5248 /* Compute a new r_index. */
5249 output_section = h->root.u.def.section->output_section;
5250 if (output_section == obj_textsec (output_bfd))
5251 r_index = N_TEXT;
5252 else if (output_section == obj_datasec (output_bfd))
5253 r_index = N_DATA;
5254 else if (output_section == obj_bsssec (output_bfd))
5255 r_index = N_BSS;
5256 else
5257 r_index = N_ABS;
5258
5259 /* Add the symbol value and the section VMA to the
5260 addend. */
5261 relocation = (h->root.u.def.value
5262 + output_section->vma
5263 + h->root.u.def.section->output_offset);
5264
5265 /* Now RELOCATION is the VMA of the final
5266 destination. If this is a PC relative reloc,
5267 then ADDEND is the negative of the source VMA.
5268 We want to set ADDEND to the difference between
5269 the destination VMA and the source VMA, which
5270 means we must adjust RELOCATION by the change in
5271 the source VMA. This is done below. */
5272 }
5273 else
5274 {
5275 /* We must change r_index according to the symbol
5276 map. */
5277 r_index = symbol_map[r_index];
5278
5279 if (r_index == -1)
5280 {
5281 if (h != NULL)
5282 {
5283 /* We decided to strip this symbol, but it
5284 turns out that we can't. Note that we
5285 lose the other and desc information here.
5286 I don't think that will ever matter for a
5287 global symbol. */
5288 if (h->indx < 0)
5289 {
5290 h->indx = -2;
5291 h->written = false;
5292 if (! aout_link_write_other_symbol (h,
5293 (PTR) finfo))
5294 return false;
5295 }
5296 r_index = h->indx;
5297 }
5298 else
5299 {
5300 const char *name;
5301
5302 name = strings + GET_WORD (input_bfd,
5303 syms[r_index].e_strx);
5304 if (! ((*finfo->info->callbacks->unattached_reloc)
5305 (finfo->info, name, input_bfd, input_section,
5306 r_addr)))
5307 return false;
5308 r_index = 0;
5309 }
5310 }
5311
5312 relocation = 0;
5313
5314 /* If this is a PC relative reloc, then the addend
5315 is the negative of the source VMA. We must
5316 adjust it by the change in the source VMA. This
5317 is done below. */
5318 }
5319
5320 /* Write out the new r_index value. */
5321 if (bfd_header_big_endian (output_bfd))
5322 {
5323 rel->r_index[0] = r_index >> 16;
5324 rel->r_index[1] = r_index >> 8;
5325 rel->r_index[2] = r_index;
5326 }
5327 else
5328 {
5329 rel->r_index[2] = r_index >> 16;
5330 rel->r_index[1] = r_index >> 8;
5331 rel->r_index[0] = r_index;
5332 }
5333 }
5334 else
5335 {
5336 /* This is a relocation against a section. We must
5337 adjust by the amount that the section moved. */
5338 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5339 relocation = (r_section->output_section->vma
5340 + r_section->output_offset
5341 - r_section->vma);
5342
5343 /* If this is a PC relative reloc, then the addend is
5344 the difference in VMA between the destination and the
5345 source. We have just adjusted for the change in VMA
5346 of the destination, so we must also adjust by the
5347 change in VMA of the source. This is done below. */
5348 }
5349
5350 /* As described above, we must always adjust a PC relative
5351 reloc by the change in VMA of the source. However, if
5352 pcrel_offset is set, then the addend does not include the
5353 location within the section, in which case we don't need
5354 to adjust anything. */
5355 if (howto_table_ext[r_type].pc_relative
5356 && ! howto_table_ext[r_type].pcrel_offset)
5357 relocation -= (input_section->output_section->vma
5358 + input_section->output_offset
5359 - input_section->vma);
5360
5361 /* Change the addend if necessary. */
5362 if (relocation != 0)
5363 PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
5364
5365 /* Change the address of the relocation. */
5366 PUT_WORD (output_bfd,
5367 r_addr + input_section->output_offset,
5368 rel->r_address);
5369 }
5370 else
5371 {
5372 boolean hundef;
5373 bfd_reloc_status_type r;
5374
5375 /* We are generating an executable, and must do a full
5376 relocation. */
5377 hundef = false;
5378
5379 if (r_extern)
5380 {
5381 h = sym_hashes[r_index];
5382
5383 if (h != (struct aout_link_hash_entry *) NULL
5384 && (h->root.type == bfd_link_hash_defined
5385 || h->root.type == bfd_link_hash_defweak))
5386 {
5387 relocation = (h->root.u.def.value
5388 + h->root.u.def.section->output_section->vma
5389 + h->root.u.def.section->output_offset);
5390 }
5391 else if (h != (struct aout_link_hash_entry *) NULL
5392 && h->root.type == bfd_link_hash_undefweak)
5393 relocation = 0;
5394 else
5395 {
5396 hundef = true;
5397 relocation = 0;
5398 }
5399 }
5400 else if (r_type == RELOC_BASE10
5401 || r_type == RELOC_BASE13
5402 || r_type == RELOC_BASE22)
5403 {
5404 struct external_nlist *sym;
5405 int type;
5406
5407 /* For base relative relocs, r_index is always an index
5408 into the symbol table, even if r_extern is 0. */
5409 sym = syms + r_index;
5410 type = bfd_h_get_8 (input_bfd, sym->e_type);
5411 if ((type & N_TYPE) == N_TEXT
5412 || type == N_WEAKT)
5413 r_section = obj_textsec (input_bfd);
5414 else if ((type & N_TYPE) == N_DATA
5415 || type == N_WEAKD)
5416 r_section = obj_datasec (input_bfd);
5417 else if ((type & N_TYPE) == N_BSS
5418 || type == N_WEAKB)
5419 r_section = obj_bsssec (input_bfd);
5420 else if ((type & N_TYPE) == N_ABS
5421 || type == N_WEAKA)
5422 r_section = bfd_abs_section_ptr;
5423 else
5424 abort ();
5425 relocation = (r_section->output_section->vma
5426 + r_section->output_offset
5427 + (GET_WORD (input_bfd, sym->e_value)
5428 - r_section->vma));
5429 }
5430 else
5431 {
5432 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5433
5434 /* If this is a PC relative reloc, then R_ADDEND is the
5435 difference between the two vmas, or
5436 old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
5437 where
5438 old_dest_sec == section->vma
5439 and
5440 old_src_sec == input_section->vma
5441 and
5442 old_src_off == r_addr
5443
5444 _bfd_final_link_relocate expects RELOCATION +
5445 R_ADDEND to be the VMA of the destination minus
5446 r_addr (the minus r_addr is because this relocation
5447 is not pcrel_offset, which is a bit confusing and
5448 should, perhaps, be changed), or
5449 new_dest_sec
5450 where
5451 new_dest_sec == output_section->vma + output_offset
5452 We arrange for this to happen by setting RELOCATION to
5453 new_dest_sec + old_src_sec - old_dest_sec
5454
5455 If this is not a PC relative reloc, then R_ADDEND is
5456 simply the VMA of the destination, so we set
5457 RELOCATION to the change in the destination VMA, or
5458 new_dest_sec - old_dest_sec
5459 */
5460 relocation = (r_section->output_section->vma
5461 + r_section->output_offset
5462 - r_section->vma);
5463 if (howto_table_ext[r_type].pc_relative)
5464 relocation += input_section->vma;
5465 }
5466
5467 if (check_dynamic_reloc != NULL)
5468 {
5469 boolean skip;
5470
5471 if (! ((*check_dynamic_reloc)
5472 (finfo->info, input_bfd, input_section, h,
5473 (PTR) rel, contents, &skip, &relocation)))
5474 return false;
5475 if (skip)
5476 continue;
5477 }
5478
5479 /* Now warn if a global symbol is undefined. We could not
5480 do this earlier, because check_dynamic_reloc might want
5481 to skip this reloc. */
5482 if (hundef
5483 && ! finfo->info->shared
5484 && r_type != RELOC_BASE10
5485 && r_type != RELOC_BASE13
5486 && r_type != RELOC_BASE22)
5487 {
5488 const char *name;
5489
5490 if (h != NULL)
5491 name = h->root.root.string;
5492 else
5493 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5494 if (! ((*finfo->info->callbacks->undefined_symbol)
5495 (finfo->info, name, input_bfd, input_section,
5496 r_addr, true)))
5497 return false;
5498 }
5499
5500 if (r_type != RELOC_SPARC_REV32)
5501 r = MY_final_link_relocate (howto_table_ext + r_type,
5502 input_bfd, input_section,
5503 contents, r_addr, relocation,
5504 r_addend);
5505 else
5506 {
5507 bfd_vma x;
5508
5509 x = bfd_get_32 (input_bfd, contents + r_addr);
5510 x = x + relocation + r_addend;
5511 bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
5512 r = bfd_reloc_ok;
5513 }
5514
5515 if (r != bfd_reloc_ok)
5516 {
5517 switch (r)
5518 {
5519 default:
5520 case bfd_reloc_outofrange:
5521 abort ();
5522 case bfd_reloc_overflow:
5523 {
5524 const char *name;
5525
5526 if (h != NULL)
5527 name = h->root.root.string;
5528 else if (r_extern
5529 || r_type == RELOC_BASE10
5530 || r_type == RELOC_BASE13
5531 || r_type == RELOC_BASE22)
5532 name = strings + GET_WORD (input_bfd,
5533 syms[r_index].e_strx);
5534 else
5535 {
5536 asection *s;
5537
5538 s = aout_reloc_index_to_section (input_bfd, r_index);
5539 name = bfd_section_name (input_bfd, s);
5540 }
5541 if (! ((*finfo->info->callbacks->reloc_overflow)
5542 (finfo->info, name, howto_table_ext[r_type].name,
5543 r_addend, input_bfd, input_section, r_addr)))
5544 return false;
5545 }
5546 break;
5547 }
5548 }
5549 }
5550 }
5551
5552 return true;
5553}
5554
5555/* Handle a link order which is supposed to generate a reloc. */
5556
5557static boolean
5558aout_link_reloc_link_order (finfo, o, p)
5559 struct aout_final_link_info *finfo;
5560 asection *o;
5561 struct bfd_link_order *p;
5562{
5563 struct bfd_link_order_reloc *pr;
5564 int r_index;
5565 int r_extern;
5566 reloc_howto_type *howto;
5567 file_ptr *reloff_ptr = NULL;
5568 struct reloc_std_external srel;
5569 struct reloc_ext_external erel;
5570 PTR rel_ptr;
5571
5572 pr = p->u.reloc.p;
5573
5574 if (p->type == bfd_section_reloc_link_order)
5575 {
5576 r_extern = 0;
5577 if (bfd_is_abs_section (pr->u.section))
5578 r_index = N_ABS | N_EXT;
5579 else
5580 {
5581 BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
5582 r_index = pr->u.section->target_index;
5583 }
5584 }
5585 else
5586 {
5587 struct aout_link_hash_entry *h;
5588
5589 BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
5590 r_extern = 1;
5591 h = ((struct aout_link_hash_entry *)
5592 bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
5593 pr->u.name, false, false, true));
5594 if (h != (struct aout_link_hash_entry *) NULL
5595 && h->indx >= 0)
5596 r_index = h->indx;
5597 else if (h != NULL)
5598 {
5599 /* We decided to strip this symbol, but it turns out that we
5600 can't. Note that we lose the other and desc information
5601 here. I don't think that will ever matter for a global
5602 symbol. */
5603 h->indx = -2;
5604 h->written = false;
5605 if (! aout_link_write_other_symbol (h, (PTR) finfo))
5606 return false;
5607 r_index = h->indx;
5608 }
5609 else
5610 {
5611 if (! ((*finfo->info->callbacks->unattached_reloc)
5612 (finfo->info, pr->u.name, (bfd *) NULL,
5613 (asection *) NULL, (bfd_vma) 0)))
5614 return false;
5615 r_index = 0;
5616 }
5617 }
5618
5619 howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
5620 if (howto == 0)
5621 {
5622 bfd_set_error (bfd_error_bad_value);
5623 return false;
5624 }
5625
5626 if (o == obj_textsec (finfo->output_bfd))
5627 reloff_ptr = &finfo->treloff;
5628 else if (o == obj_datasec (finfo->output_bfd))
5629 reloff_ptr = &finfo->dreloff;
5630 else
5631 abort ();
5632
5633 if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
5634 {
5635#ifdef MY_put_reloc
5636 MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto,
5637 &srel);
5638#else
5639 {
5640 int r_pcrel;
5641 int r_baserel;
5642 int r_jmptable;
5643 int r_relative;
5644 int r_length;
5645
5646 r_pcrel = howto->pc_relative;
5647 r_baserel = (howto->type & 8) != 0;
5648 r_jmptable = (howto->type & 16) != 0;
5649 r_relative = (howto->type & 32) != 0;
5650 r_length = howto->size;
5651
5652 PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
5653 if (bfd_header_big_endian (finfo->output_bfd))
5654 {
5655 srel.r_index[0] = r_index >> 16;
5656 srel.r_index[1] = r_index >> 8;
5657 srel.r_index[2] = r_index;
5658 srel.r_type[0] =
5659 ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
5660 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
5661 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
5662 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
5663 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
5664 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
5665 }
5666 else
5667 {
5668 srel.r_index[2] = r_index >> 16;
5669 srel.r_index[1] = r_index >> 8;
5670 srel.r_index[0] = r_index;
5671 srel.r_type[0] =
5672 ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
5673 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
5674 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
5675 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
5676 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
5677 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
5678 }
5679 }
5680#endif
5681 rel_ptr = (PTR) &srel;
5682
5683 /* We have to write the addend into the object file, since
5684 standard a.out relocs are in place. It would be more
5685 reliable if we had the current contents of the file here,
5686 rather than assuming zeroes, but we can't read the file since
5687 it was opened using bfd_openw. */
5688 if (pr->addend != 0)
5689 {
5690 bfd_size_type size;
5691 bfd_reloc_status_type r;
5692 bfd_byte *buf;
5693 boolean ok;
5694
5695 size = bfd_get_reloc_size (howto);
5696 buf = (bfd_byte *) bfd_zmalloc (size);
5697 if (buf == (bfd_byte *) NULL)
5698 return false;
5699 r = MY_relocate_contents (howto, finfo->output_bfd,
5700 pr->addend, buf);
5701 switch (r)
5702 {
5703 case bfd_reloc_ok:
5704 break;
5705 default:
5706 case bfd_reloc_outofrange:
5707 abort ();
5708 case bfd_reloc_overflow:
5709 if (! ((*finfo->info->callbacks->reloc_overflow)
5710 (finfo->info,
5711 (p->type == bfd_section_reloc_link_order
5712 ? bfd_section_name (finfo->output_bfd,
5713 pr->u.section)
5714 : pr->u.name),
5715 howto->name, pr->addend, (bfd *) NULL,
5716 (asection *) NULL, (bfd_vma) 0)))
5717 {
5718 free (buf);
5719 return false;
5720 }
5721 break;
5722 }
5723 ok = bfd_set_section_contents (finfo->output_bfd, o,
5724 (PTR) buf,
5725 (file_ptr) p->offset,
5726 size);
5727 free (buf);
5728 if (! ok)
5729 return false;
5730 }
5731 }
5732 else
5733 {
5734#ifdef MY_put_ext_reloc
5735 MY_put_ext_reloc (finfo->output_bfd, r_extern, r_index, p->offset,
5736 howto, &erel, pr->addend);
5737#else
5738 PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
5739
5740 if (bfd_header_big_endian (finfo->output_bfd))
5741 {
5742 erel.r_index[0] = r_index >> 16;
5743 erel.r_index[1] = r_index >> 8;
5744 erel.r_index[2] = r_index;
5745 erel.r_type[0] =
5746 ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
5747 | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
5748 }
5749 else
5750 {
5751 erel.r_index[2] = r_index >> 16;
5752 erel.r_index[1] = r_index >> 8;
5753 erel.r_index[0] = r_index;
5754 erel.r_type[0] =
5755 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
5756 | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
5757 }
5758
5759 PUT_WORD (finfo->output_bfd, pr->addend, erel.r_addend);
5760#endif /* MY_put_ext_reloc */
5761
5762 rel_ptr = (PTR) &erel;
5763 }
5764
5765 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
5766 || (bfd_write (rel_ptr, (bfd_size_type) 1,
5767 obj_reloc_entry_size (finfo->output_bfd),
5768 finfo->output_bfd)
5769 != obj_reloc_entry_size (finfo->output_bfd)))
5770 return false;
5771
5772 *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
5773
5774 /* Assert that the relocs have not run into the symbols, and that n
5775 the text relocs have not run into the data relocs. */
5776 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
5777 && (reloff_ptr != &finfo->treloff
5778 || (*reloff_ptr
5779 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
5780
5781 return true;
5782}
Note: See TracBrowser for help on using the repository browser.