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

Last change on this file since 90 was 86, checked in by bird, 22 years ago

Applied the original 2.11.2 diff.

  • Property cvs2svn:cvs-rev set to 1.2
  • 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 else if ((type == (N_IMP1 | N_EXT))
4271 || (type == (N_IMP2 | N_EXT)))
4272 symsec = bfd_abs_section_ptr;
4273 else if (IS_STAB(type))
4274 {
4275 val = GET_WORD (input_bfd, sym->e_value);
4276 symsec = NULL;
4277 }
4278 else
4279 {
4280 /* If we get here with an indirect symbol, it means that
4281 we are outputting it with a real definition. In such
4282 a case we do not want to output the next symbol,
4283 which is the target of the indirection. */
4284 if ((type & N_TYPE) == N_INDR)
4285 skip_next = true;
4286
4287 symsec = NULL;
4288
4289 /* We need to get the value from the hash table. We use
4290 hresolve so that if we have defined an indirect
4291 symbol we output the final definition. */
4292 if (h == (struct aout_link_hash_entry *) NULL)
4293 {
4294 switch (type & N_TYPE)
4295 {
4296 case N_SETT:
4297 symsec = obj_textsec (input_bfd);
4298 break;
4299 case N_SETD:
4300 symsec = obj_datasec (input_bfd);
4301 break;
4302 case N_SETB:
4303 symsec = obj_bsssec (input_bfd);
4304 break;
4305 case N_SETA:
4306 symsec = bfd_abs_section_ptr;
4307 break;
4308 default:
4309 val = 0;
4310 break;
4311 }
4312 }
4313 else if (hresolve->root.type == bfd_link_hash_defined
4314 || hresolve->root.type == bfd_link_hash_defweak)
4315 {
4316 asection *input_section;
4317 asection *output_section;
4318
4319 /* This case usually means a common symbol which was
4320 turned into a defined symbol. */
4321 input_section = hresolve->root.u.def.section;
4322 output_section = input_section->output_section;
4323 BFD_ASSERT (bfd_is_abs_section (output_section)
4324 || output_section->owner == output_bfd);
4325 val = (hresolve->root.u.def.value
4326 + bfd_get_section_vma (output_bfd, output_section)
4327 + input_section->output_offset);
4328
4329 /* Get the correct type based on the section. If
4330 this is a constructed set, force it to be
4331 globally visible. */
4332 if (type == N_SETT
4333 || type == N_SETD
4334 || type == N_SETB
4335 || type == N_SETA)
4336 type |= N_EXT;
4337
4338 type &=~ N_TYPE;
4339
4340 if (output_section == obj_textsec (output_bfd))
4341 type |= (hresolve->root.type == bfd_link_hash_defined
4342 ? N_TEXT
4343 : N_WEAKT);
4344 else if (output_section == obj_datasec (output_bfd))
4345 type |= (hresolve->root.type == bfd_link_hash_defined
4346 ? N_DATA
4347 : N_WEAKD);
4348 else if (output_section == obj_bsssec (output_bfd))
4349 type |= (hresolve->root.type == bfd_link_hash_defined
4350 ? N_BSS
4351 : N_WEAKB);
4352 else
4353 type |= (hresolve->root.type == bfd_link_hash_defined
4354 ? N_ABS
4355 : N_WEAKA);
4356 }
4357 else if (hresolve->root.type == bfd_link_hash_common)
4358 val = hresolve->root.u.c.size;
4359 else if (hresolve->root.type == bfd_link_hash_undefweak)
4360 {
4361 val = 0;
4362 type = N_WEAKU;
4363 }
4364 else
4365 val = 0;
4366 }
4367 if (symsec != (asection *) NULL)
4368 val = (symsec->output_section->vma
4369 + symsec->output_offset
4370 + (GET_WORD (input_bfd, sym->e_value)
4371 - symsec->vma));
4372
4373 /* If this is a global symbol set the written flag, and if
4374 it is a local symbol see if we should discard it. */
4375 if (h != (struct aout_link_hash_entry *) NULL)
4376 {
4377 h->written = true;
4378 h->indx = obj_aout_external_sym_count (output_bfd);
4379 }
4380 else if ((type & N_TYPE) != N_SETT
4381 && (type & N_TYPE) != N_SETD
4382 && (type & N_TYPE) != N_SETB
4383 && (type & N_TYPE) != N_SETA)
4384 {
4385 switch (discard)
4386 {
4387 case discard_none:
4388 break;
4389 case discard_l:
4390 if (!IS_STAB(type)
4391 && bfd_is_local_label_name (input_bfd, name))
4392 skip = true;
4393 break;
4394 case discard_all:
4395 skip = true;
4396 break;
4397 }
4398 if (skip)
4399 {
4400 pass = false;
4401 continue;
4402 }
4403 }
4404
4405 /* An N_BINCL symbol indicates the start of the stabs
4406 entries for a header file. We need to scan ahead to the
4407 next N_EINCL symbol, ignoring nesting, adding up all the
4408 characters in the symbol names, not including the file
4409 numbers in types (the first number after an open
4410 parenthesis). */
4411 if (type == N_BINCL)
4412 {
4413 struct external_nlist *incl_sym;
4414 int nest;
4415 struct aout_link_includes_entry *incl_entry;
4416 struct aout_link_includes_totals *t;
4417
4418 val = 0;
4419 nest = 0;
4420 for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
4421 {
4422 int incl_type;
4423
4424 incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
4425 if (incl_type == N_EINCL)
4426 {
4427 if (nest == 0)
4428 break;
4429 --nest;
4430 }
4431 else if (incl_type == N_BINCL)
4432 ++nest;
4433 else if (nest == 0)
4434 {
4435 const char *s;
4436
4437 s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
4438 for (; *s != '\0'; s++)
4439 {
4440 val += *s;
4441 if (*s == '(')
4442 {
4443 /* Skip the file number. */
4444 ++s;
4445 while (isdigit ((unsigned char) *s))
4446 ++s;
4447 --s;
4448 }
4449 }
4450 }
4451 }
4452
4453 /* If we have already included a header file with the
4454 same value, then replace this one with an N_EXCL
4455 symbol. */
4456 copy = ! finfo->info->keep_memory;
4457 incl_entry = aout_link_includes_lookup (&finfo->includes,
4458 name, true, copy);
4459 if (incl_entry == NULL)
4460 return false;
4461 for (t = incl_entry->totals; t != NULL; t = t->next)
4462 if (t->total == val)
4463 break;
4464 if (t == NULL)
4465 {
4466 /* This is the first time we have seen this header
4467 file with this set of stabs strings. */
4468 t = ((struct aout_link_includes_totals *)
4469 bfd_hash_allocate (&finfo->includes.root,
4470 sizeof *t));
4471 if (t == NULL)
4472 return false;
4473 t->total = val;
4474 t->next = incl_entry->totals;
4475 incl_entry->totals = t;
4476 }
4477 else
4478 {
4479 int *incl_map;
4480
4481 /* This is a duplicate header file. We must change
4482 it to be an N_EXCL entry, and mark all the
4483 included symbols to prevent outputting them. */
4484 type = N_EXCL;
4485
4486 nest = 0;
4487 for (incl_sym = sym + 1, incl_map = symbol_map + 1;
4488 incl_sym < sym_end;
4489 incl_sym++, incl_map++)
4490 {
4491 int incl_type;
4492
4493 incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
4494 if (incl_type == N_EINCL)
4495 {
4496 if (nest == 0)
4497 {
4498 *incl_map = -1;
4499 break;
4500 }
4501 --nest;
4502 }
4503 else if (incl_type == N_BINCL)
4504 ++nest;
4505 else if (nest == 0)
4506 *incl_map = -1;
4507 }
4508 }
4509 }
4510 }
4511
4512 /* Copy this symbol into the list of symbols we are going to
4513 write out. */
4514 bfd_h_put_8 (output_bfd, type, outsym->e_type);
4515 bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other),
4516 outsym->e_other);
4517 bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc),
4518 outsym->e_desc);
4519 copy = false;
4520 if (! finfo->info->keep_memory)
4521 {
4522 /* name points into a string table which we are going to
4523 free. If there is a hash table entry, use that string.
4524 Otherwise, copy name into memory. */
4525 if (h != (struct aout_link_hash_entry *) NULL)
4526 name = h->root.root.string;
4527 else
4528 copy = true;
4529 }
4530 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4531 name, copy);
4532 if (strtab_index == (bfd_size_type) -1)
4533 return false;
4534 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4535 PUT_WORD (output_bfd, val, outsym->e_value);
4536 *symbol_map = obj_aout_external_sym_count (output_bfd);
4537 ++obj_aout_external_sym_count (output_bfd);
4538 ++outsym;
4539 }
4540
4541 /* Write out the output symbols we have just constructed. */
4542 if (outsym > finfo->output_syms)
4543 {
4544 bfd_size_type outsym_count;
4545
4546 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
4547 return false;
4548 outsym_count = outsym - finfo->output_syms;
4549 if (bfd_write ((PTR) finfo->output_syms,
4550 (bfd_size_type) EXTERNAL_NLIST_SIZE,
4551 (bfd_size_type) outsym_count, output_bfd)
4552 != outsym_count * EXTERNAL_NLIST_SIZE)
4553 return false;
4554 finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
4555 }
4556
4557 return true;
4558}
4559
4560/* Write out a symbol that was not associated with an a.out input
4561 object. */
4562
4563static boolean
4564aout_link_write_other_symbol (h, data)
4565 struct aout_link_hash_entry *h;
4566 PTR data;
4567{
4568 struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
4569 bfd *output_bfd;
4570 int type;
4571 bfd_vma val;
4572 struct external_nlist outsym;
4573 bfd_size_type indx;
4574
4575 output_bfd = finfo->output_bfd;
4576
4577 if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
4578 {
4579 if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
4580 (output_bfd, finfo->info, h)))
4581 {
4582 /* FIXME: No way to handle errors. */
4583 abort ();
4584 }
4585 }
4586
4587 if (h->written)
4588 return true;
4589
4590 h->written = true;
4591
4592 /* An indx of -2 means the symbol must be written. */
4593 if (h->indx != -2
4594 && (finfo->info->strip == strip_all
4595 || (finfo->info->strip == strip_some
4596 && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
4597 false, false) == NULL)))
4598 return true;
4599
4600 switch (h->root.type)
4601 {
4602 default:
4603 abort ();
4604 /* Avoid variable not initialized warnings. */
4605 return true;
4606 case bfd_link_hash_new:
4607 /* This can happen for set symbols when sets are not being
4608 built. */
4609 return true;
4610 case bfd_link_hash_undefined:
4611 type = N_UNDF | N_EXT;
4612 val = 0;
4613 break;
4614 case bfd_link_hash_defined:
4615 case bfd_link_hash_defweak:
4616 {
4617 asection *sec;
4618
4619 sec = h->root.u.def.section->output_section;
4620 BFD_ASSERT (bfd_is_abs_section (sec)
4621 || sec->owner == output_bfd);
4622 if (sec == obj_textsec (output_bfd))
4623 type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
4624 else if (sec == obj_datasec (output_bfd))
4625 type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
4626 else if (sec == obj_bsssec (output_bfd))
4627 type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
4628 else
4629 type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
4630 type |= N_EXT;
4631 val = (h->root.u.def.value
4632 + sec->vma
4633 + h->root.u.def.section->output_offset);
4634 }
4635 break;
4636 case bfd_link_hash_common:
4637 type = N_UNDF | N_EXT;
4638 val = h->root.u.c.size;
4639 break;
4640 case bfd_link_hash_undefweak:
4641 type = N_WEAKU;
4642 val = 0;
4643 case bfd_link_hash_indirect:
4644 case bfd_link_hash_warning:
4645 /* FIXME: Ignore these for now. The circumstances under which
4646 they should be written out are not clear to me. */
4647 return true;
4648 }
4649
4650 bfd_h_put_8 (output_bfd, type, outsym.e_type);
4651 bfd_h_put_8 (output_bfd, 0, outsym.e_other);
4652 bfd_h_put_16 (output_bfd, 0, outsym.e_desc);
4653 indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
4654 false);
4655 if (indx == (bfd_size_type) -1)
4656 {
4657 /* FIXME: No way to handle errors. */
4658 abort ();
4659 }
4660 PUT_WORD (output_bfd, indx, outsym.e_strx);
4661 PUT_WORD (output_bfd, val, outsym.e_value);
4662
4663 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
4664 || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE,
4665 (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE)
4666 {
4667 /* FIXME: No way to handle errors. */
4668 abort ();
4669 }
4670
4671 finfo->symoff += EXTERNAL_NLIST_SIZE;
4672 h->indx = obj_aout_external_sym_count (output_bfd);
4673 ++obj_aout_external_sym_count (output_bfd);
4674
4675 return true;
4676}
4677
4678/* Link an a.out section into the output file. */
4679
4680static boolean
4681aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
4682 rel_size)
4683 struct aout_final_link_info *finfo;
4684 bfd *input_bfd;
4685 asection *input_section;
4686 file_ptr *reloff_ptr;
4687 bfd_size_type rel_size;
4688{
4689 bfd_size_type input_size;
4690 PTR relocs;
4691
4692 /* Get the section contents. */
4693 input_size = bfd_section_size (input_bfd, input_section);
4694 if (! bfd_get_section_contents (input_bfd, input_section,
4695 (PTR) finfo->contents,
4696 (file_ptr) 0, input_size))
4697 return false;
4698
4699 /* Read in the relocs if we haven't already done it. */
4700 if (aout_section_data (input_section) != NULL
4701 && aout_section_data (input_section)->relocs != NULL)
4702 relocs = aout_section_data (input_section)->relocs;
4703 else
4704 {
4705 relocs = finfo->relocs;
4706 if (rel_size > 0)
4707 {
4708 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
4709 || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
4710 return false;
4711 }
4712 }
4713
4714 /* Relocate the section contents. */
4715 if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4716 {
4717 if (! aout_link_input_section_std (finfo, input_bfd, input_section,
4718 (struct reloc_std_external *) relocs,
4719 rel_size, finfo->contents))
4720 return false;
4721 }
4722 else
4723 {
4724 if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
4725 (struct reloc_ext_external *) relocs,
4726 rel_size, finfo->contents))
4727 return false;
4728 }
4729
4730 /* Write out the section contents. */
4731 if (! bfd_set_section_contents (finfo->output_bfd,
4732 input_section->output_section,
4733 (PTR) finfo->contents,
4734 input_section->output_offset,
4735 input_size))
4736 return false;
4737
4738 /* If we are producing relocateable output, the relocs were
4739 modified, and we now write them out. */
4740 if (finfo->info->relocateable && rel_size > 0)
4741 {
4742 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
4743 return false;
4744 if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
4745 != rel_size)
4746 return false;
4747 *reloff_ptr += rel_size;
4748
4749 /* Assert that the relocs have not run into the symbols, and
4750 that if these are the text relocs they have not run into the
4751 data relocs. */
4752 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
4753 && (reloff_ptr != &finfo->treloff
4754 || (*reloff_ptr
4755 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
4756 }
4757
4758 return true;
4759}
4760
4761/* Get the section corresponding to a reloc index. */
4762
4763static INLINE asection *
4764aout_reloc_index_to_section (abfd, indx)
4765 bfd *abfd;
4766 int indx;
4767{
4768 switch (indx & N_TYPE)
4769 {
4770 case N_TEXT:
4771 return obj_textsec (abfd);
4772 case N_DATA:
4773 return obj_datasec (abfd);
4774 case N_BSS:
4775 return obj_bsssec (abfd);
4776 case N_ABS:
4777 case N_UNDF:
4778 return bfd_abs_section_ptr;
4779 default:
4780 abort ();
4781 }
4782 /*NOTREACHED*/
4783 return NULL;
4784}
4785
4786/* Relocate an a.out section using standard a.out relocs. */
4787
4788static boolean
4789aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
4790 rel_size, contents)
4791 struct aout_final_link_info *finfo;
4792 bfd *input_bfd;
4793 asection *input_section;
4794 struct reloc_std_external *relocs;
4795 bfd_size_type rel_size;
4796 bfd_byte *contents;
4797{
4798 boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
4799 bfd *, asection *,
4800 struct aout_link_hash_entry *,
4801 PTR, bfd_byte *, boolean *,
4802 bfd_vma *));
4803 bfd *output_bfd;
4804 boolean relocateable;
4805 struct external_nlist *syms;
4806 char *strings;
4807 struct aout_link_hash_entry **sym_hashes;
4808 int *symbol_map;
4809 bfd_size_type reloc_count;
4810 register struct reloc_std_external *rel;
4811 struct reloc_std_external *rel_end;
4812
4813 output_bfd = finfo->output_bfd;
4814 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4815
4816 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
4817 BFD_ASSERT (input_bfd->xvec->header_byteorder
4818 == output_bfd->xvec->header_byteorder);
4819
4820 relocateable = finfo->info->relocateable;
4821 syms = obj_aout_external_syms (input_bfd);
4822 strings = obj_aout_external_strings (input_bfd);
4823 sym_hashes = obj_aout_sym_hashes (input_bfd);
4824 symbol_map = finfo->symbol_map;
4825
4826 reloc_count = rel_size / RELOC_STD_SIZE;
4827 rel = relocs;
4828 rel_end = rel + reloc_count;
4829 for (; rel < rel_end; rel++)
4830 {
4831 bfd_vma r_addr;
4832 int r_index;
4833 int r_extern;
4834 int r_pcrel;
4835 int r_baserel = 0;
4836 reloc_howto_type *howto;
4837 struct aout_link_hash_entry *h = NULL;
4838 bfd_vma relocation;
4839 bfd_reloc_status_type r;
4840
4841 r_addr = GET_SWORD (input_bfd, rel->r_address);
4842
4843#ifdef MY_reloc_howto
4844 howto = MY_reloc_howto(input_bfd, rel, r_index, r_extern, r_pcrel);
4845#else
4846 {
4847 int r_jmptable;
4848 int r_relative;
4849 int r_length;
4850 unsigned int howto_idx;
4851
4852 if (bfd_header_big_endian (input_bfd))
4853 {
4854 r_index = ((rel->r_index[0] << 16)
4855 | (rel->r_index[1] << 8)
4856 | rel->r_index[2]);
4857 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
4858 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
4859 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
4860 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
4861 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
4862 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
4863 >> RELOC_STD_BITS_LENGTH_SH_BIG);
4864 }
4865 else
4866 {
4867 r_index = ((rel->r_index[2] << 16)
4868 | (rel->r_index[1] << 8)
4869 | rel->r_index[0]);
4870 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
4871 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
4872 r_baserel = (0 != (rel->r_type[0]
4873 & RELOC_STD_BITS_BASEREL_LITTLE));
4874 r_jmptable= (0 != (rel->r_type[0]
4875 & RELOC_STD_BITS_JMPTABLE_LITTLE));
4876 r_relative= (0 != (rel->r_type[0]
4877 & RELOC_STD_BITS_RELATIVE_LITTLE));
4878 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
4879 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
4880 }
4881
4882 howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
4883 + 16 * r_jmptable + 32 * r_relative);
4884 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
4885 howto = howto_table_std + howto_idx;
4886 }
4887#endif
4888
4889 if (relocateable)
4890 {
4891 /* We are generating a relocateable output file, and must
4892 modify the reloc accordingly. */
4893 if (r_extern)
4894 {
4895 /* If we know the symbol this relocation is against,
4896 convert it into a relocation against a section. This
4897 is what the native linker does. */
4898 h = sym_hashes[r_index];
4899 if (h != (struct aout_link_hash_entry *) NULL
4900#ifdef EMX
4901 /* Don't touch imported symbols */
4902 && (!bfd_is_abs_section (h->root.u.def.section)
4903 || (h->root.u.def.value != -1))
4904#endif
4905 && (h->root.type == bfd_link_hash_defined
4906 || h->root.type == bfd_link_hash_defweak))
4907 {
4908 asection *output_section;
4909
4910 /* Change the r_extern value. */
4911 if (bfd_header_big_endian (output_bfd))
4912 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
4913 else
4914 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
4915
4916 /* Compute a new r_index. */
4917 output_section = h->root.u.def.section->output_section;
4918 if (output_section == obj_textsec (output_bfd))
4919 r_index = N_TEXT;
4920 else if (output_section == obj_datasec (output_bfd))
4921 r_index = N_DATA;
4922 else if (output_section == obj_bsssec (output_bfd))
4923 r_index = N_BSS;
4924 else
4925 r_index = N_ABS;
4926
4927 /* Add the symbol value and the section VMA to the
4928 addend stored in the contents. */
4929 relocation = (h->root.u.def.value
4930 + output_section->vma
4931 + h->root.u.def.section->output_offset);
4932 }
4933 else
4934 {
4935 /* We must change r_index according to the symbol
4936 map. */
4937 r_index = symbol_map[r_index];
4938
4939 if (r_index == -1)
4940 {
4941 if (h != NULL)
4942 {
4943 /* We decided to strip this symbol, but it
4944 turns out that we can't. Note that we
4945 lose the other and desc information here.
4946 I don't think that will ever matter for a
4947 global symbol. */
4948 if (h->indx < 0)
4949 {
4950 h->indx = -2;
4951 h->written = false;
4952 if (! aout_link_write_other_symbol (h,
4953 (PTR) finfo))
4954 return false;
4955 }
4956 r_index = h->indx;
4957 }
4958 else
4959 {
4960 const char *name;
4961
4962 name = strings + GET_WORD (input_bfd,
4963 syms[r_index].e_strx);
4964 if (! ((*finfo->info->callbacks->unattached_reloc)
4965 (finfo->info, name, input_bfd, input_section,
4966 r_addr)))
4967 return false;
4968 r_index = 0;
4969 }
4970 }
4971
4972 relocation = 0;
4973 }
4974
4975 /* Write out the new r_index value. */
4976 if (bfd_header_big_endian (output_bfd))
4977 {
4978 rel->r_index[0] = r_index >> 16;
4979 rel->r_index[1] = r_index >> 8;
4980 rel->r_index[2] = r_index;
4981 }
4982 else
4983 {
4984 rel->r_index[2] = r_index >> 16;
4985 rel->r_index[1] = r_index >> 8;
4986 rel->r_index[0] = r_index;
4987 }
4988 }
4989 else
4990 {
4991 asection *section;
4992
4993 /* This is a relocation against a section. We must
4994 adjust by the amount that the section moved. */
4995 section = aout_reloc_index_to_section (input_bfd, r_index);
4996 relocation = (section->output_section->vma
4997 + section->output_offset
4998 - section->vma);
4999 }
5000
5001 /* Change the address of the relocation. */
5002 PUT_WORD (output_bfd,
5003 r_addr + input_section->output_offset,
5004 rel->r_address);
5005
5006 /* Adjust a PC relative relocation by removing the reference
5007 to the original address in the section and including the
5008 reference to the new address. */
5009 if (r_pcrel)
5010 relocation -= (input_section->output_section->vma
5011 + input_section->output_offset
5012 - input_section->vma);
5013
5014#ifdef MY_relocatable_reloc
5015 MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
5016#endif
5017
5018 if (relocation == 0)
5019 r = bfd_reloc_ok;
5020 else
5021 r = MY_relocate_contents (howto,
5022 input_bfd, relocation,
5023 contents + r_addr);
5024 }
5025 else
5026 {
5027 boolean hundef;
5028
5029 /* We are generating an executable, and must do a full
5030 relocation. */
5031 hundef = false;
5032
5033 if (r_extern)
5034 {
5035 h = sym_hashes[r_index];
5036
5037 if (h != (struct aout_link_hash_entry *) NULL
5038 && (h->root.type == bfd_link_hash_defined
5039 || h->root.type == bfd_link_hash_defweak))
5040 {
5041 relocation = (h->root.u.def.value
5042 + h->root.u.def.section->output_section->vma
5043 + h->root.u.def.section->output_offset);
5044 }
5045 else if (h != (struct aout_link_hash_entry *) NULL
5046 && h->root.type == bfd_link_hash_undefweak)
5047 relocation = 0;
5048 else
5049 {
5050 hundef = true;
5051 relocation = 0;
5052 }
5053 }
5054 else
5055 {
5056 asection *section;
5057
5058 section = aout_reloc_index_to_section (input_bfd, r_index);
5059 relocation = (section->output_section->vma
5060 + section->output_offset
5061 - section->vma);
5062 if (r_pcrel)
5063 relocation += input_section->vma;
5064 }
5065
5066 if (check_dynamic_reloc != NULL)
5067 {
5068 boolean skip;
5069
5070 if (! ((*check_dynamic_reloc)
5071 (finfo->info, input_bfd, input_section, h,
5072 (PTR) rel, contents, &skip, &relocation)))
5073 return false;
5074 if (skip)
5075 continue;
5076 }
5077
5078 /* Now warn if a global symbol is undefined. We could not
5079 do this earlier, because check_dynamic_reloc might want
5080 to skip this reloc. */
5081 if (hundef && ! finfo->info->shared && ! r_baserel)
5082 {
5083 const char *name;
5084
5085 if (h != NULL)
5086 name = h->root.root.string;
5087 else
5088 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5089 if (! ((*finfo->info->callbacks->undefined_symbol)
5090 (finfo->info, name, input_bfd, input_section,
5091 r_addr, true)))
5092 return false;
5093 }
5094
5095 r = MY_final_link_relocate (howto,
5096 input_bfd, input_section,
5097 contents, r_addr, relocation,
5098 (bfd_vma) 0);
5099 }
5100
5101 if (r != bfd_reloc_ok)
5102 {
5103 switch (r)
5104 {
5105 default:
5106 case bfd_reloc_outofrange:
5107 abort ();
5108 case bfd_reloc_overflow:
5109 {
5110 const char *name;
5111
5112 if (h != NULL)
5113 name = h->root.root.string;
5114 else if (r_extern)
5115 name = strings + GET_WORD (input_bfd,
5116 syms[r_index].e_strx);
5117 else
5118 {
5119 asection *s;
5120
5121 s = aout_reloc_index_to_section (input_bfd, r_index);
5122 name = bfd_section_name (input_bfd, s);
5123 }
5124 if (! ((*finfo->info->callbacks->reloc_overflow)
5125 (finfo->info, name, howto->name,
5126 (bfd_vma) 0, input_bfd, input_section, r_addr)))
5127 return false;
5128 }
5129 break;
5130 }
5131 }
5132 }
5133
5134 return true;
5135}
5136
5137/* Relocate an a.out section using extended a.out relocs. */
5138
5139static boolean
5140aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
5141 rel_size, contents)
5142 struct aout_final_link_info *finfo;
5143 bfd *input_bfd;
5144 asection *input_section;
5145 struct reloc_ext_external *relocs;
5146 bfd_size_type rel_size;
5147 bfd_byte *contents;
5148{
5149 boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
5150 bfd *, asection *,
5151 struct aout_link_hash_entry *,
5152 PTR, bfd_byte *, boolean *,
5153 bfd_vma *));
5154 bfd *output_bfd;
5155 boolean relocateable;
5156 struct external_nlist *syms;
5157 char *strings;
5158 struct aout_link_hash_entry **sym_hashes;
5159 int *symbol_map;
5160 bfd_size_type reloc_count;
5161 register struct reloc_ext_external *rel;
5162 struct reloc_ext_external *rel_end;
5163
5164 output_bfd = finfo->output_bfd;
5165 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
5166
5167 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
5168 BFD_ASSERT (input_bfd->xvec->header_byteorder
5169 == output_bfd->xvec->header_byteorder);
5170
5171 relocateable = finfo->info->relocateable;
5172 syms = obj_aout_external_syms (input_bfd);
5173 strings = obj_aout_external_strings (input_bfd);
5174 sym_hashes = obj_aout_sym_hashes (input_bfd);
5175 symbol_map = finfo->symbol_map;
5176
5177 reloc_count = rel_size / RELOC_EXT_SIZE;
5178 rel = relocs;
5179 rel_end = rel + reloc_count;
5180 for (; rel < rel_end; rel++)
5181 {
5182 bfd_vma r_addr;
5183 int r_index;
5184 int r_extern;
5185 unsigned int r_type;
5186 bfd_vma r_addend;
5187 struct aout_link_hash_entry *h = NULL;
5188 asection *r_section = NULL;
5189 bfd_vma relocation;
5190
5191 r_addr = GET_SWORD (input_bfd, rel->r_address);
5192
5193 if (bfd_header_big_endian (input_bfd))
5194 {
5195 r_index = ((rel->r_index[0] << 16)
5196 | (rel->r_index[1] << 8)
5197 | rel->r_index[2]);
5198 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
5199 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
5200 >> RELOC_EXT_BITS_TYPE_SH_BIG);
5201 }
5202 else
5203 {
5204 r_index = ((rel->r_index[2] << 16)
5205 | (rel->r_index[1] << 8)
5206 | rel->r_index[0]);
5207 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
5208 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
5209 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
5210 }
5211
5212 r_addend = GET_SWORD (input_bfd, rel->r_addend);
5213
5214 BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
5215
5216 if (relocateable)
5217 {
5218 /* We are generating a relocateable output file, and must
5219 modify the reloc accordingly. */
5220 if (r_extern
5221 || r_type == RELOC_BASE10
5222 || r_type == RELOC_BASE13
5223 || r_type == RELOC_BASE22)
5224 {
5225 /* If we know the symbol this relocation is against,
5226 convert it into a relocation against a section. This
5227 is what the native linker does. */
5228 if (r_type == RELOC_BASE10
5229 || r_type == RELOC_BASE13
5230 || r_type == RELOC_BASE22)
5231 h = NULL;
5232 else
5233 h = sym_hashes[r_index];
5234 if (h != (struct aout_link_hash_entry *) NULL
5235 && (h->root.type == bfd_link_hash_defined
5236 || h->root.type == bfd_link_hash_defweak))
5237 {
5238 asection *output_section;
5239
5240 /* Change the r_extern value. */
5241 if (bfd_header_big_endian (output_bfd))
5242 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
5243 else
5244 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
5245
5246 /* Compute a new r_index. */
5247 output_section = h->root.u.def.section->output_section;
5248 if (output_section == obj_textsec (output_bfd))
5249 r_index = N_TEXT;
5250 else if (output_section == obj_datasec (output_bfd))
5251 r_index = N_DATA;
5252 else if (output_section == obj_bsssec (output_bfd))
5253 r_index = N_BSS;
5254 else
5255 r_index = N_ABS;
5256
5257 /* Add the symbol value and the section VMA to the
5258 addend. */
5259 relocation = (h->root.u.def.value
5260 + output_section->vma
5261 + h->root.u.def.section->output_offset);
5262
5263 /* Now RELOCATION is the VMA of the final
5264 destination. If this is a PC relative reloc,
5265 then ADDEND is the negative of the source VMA.
5266 We want to set ADDEND to the difference between
5267 the destination VMA and the source VMA, which
5268 means we must adjust RELOCATION by the change in
5269 the source VMA. This is done below. */
5270 }
5271 else
5272 {
5273 /* We must change r_index according to the symbol
5274 map. */
5275 r_index = symbol_map[r_index];
5276
5277 if (r_index == -1)
5278 {
5279 if (h != NULL)
5280 {
5281 /* We decided to strip this symbol, but it
5282 turns out that we can't. Note that we
5283 lose the other and desc information here.
5284 I don't think that will ever matter for a
5285 global symbol. */
5286 if (h->indx < 0)
5287 {
5288 h->indx = -2;
5289 h->written = false;
5290 if (! aout_link_write_other_symbol (h,
5291 (PTR) finfo))
5292 return false;
5293 }
5294 r_index = h->indx;
5295 }
5296 else
5297 {
5298 const char *name;
5299
5300 name = strings + GET_WORD (input_bfd,
5301 syms[r_index].e_strx);
5302 if (! ((*finfo->info->callbacks->unattached_reloc)
5303 (finfo->info, name, input_bfd, input_section,
5304 r_addr)))
5305 return false;
5306 r_index = 0;
5307 }
5308 }
5309
5310 relocation = 0;
5311
5312 /* If this is a PC relative reloc, then the addend
5313 is the negative of the source VMA. We must
5314 adjust it by the change in the source VMA. This
5315 is done below. */
5316 }
5317
5318 /* Write out the new r_index value. */
5319 if (bfd_header_big_endian (output_bfd))
5320 {
5321 rel->r_index[0] = r_index >> 16;
5322 rel->r_index[1] = r_index >> 8;
5323 rel->r_index[2] = r_index;
5324 }
5325 else
5326 {
5327 rel->r_index[2] = r_index >> 16;
5328 rel->r_index[1] = r_index >> 8;
5329 rel->r_index[0] = r_index;
5330 }
5331 }
5332 else
5333 {
5334 /* This is a relocation against a section. We must
5335 adjust by the amount that the section moved. */
5336 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5337 relocation = (r_section->output_section->vma
5338 + r_section->output_offset
5339 - r_section->vma);
5340
5341 /* If this is a PC relative reloc, then the addend is
5342 the difference in VMA between the destination and the
5343 source. We have just adjusted for the change in VMA
5344 of the destination, so we must also adjust by the
5345 change in VMA of the source. This is done below. */
5346 }
5347
5348 /* As described above, we must always adjust a PC relative
5349 reloc by the change in VMA of the source. However, if
5350 pcrel_offset is set, then the addend does not include the
5351 location within the section, in which case we don't need
5352 to adjust anything. */
5353 if (howto_table_ext[r_type].pc_relative
5354 && ! howto_table_ext[r_type].pcrel_offset)
5355 relocation -= (input_section->output_section->vma
5356 + input_section->output_offset
5357 - input_section->vma);
5358
5359 /* Change the addend if necessary. */
5360 if (relocation != 0)
5361 PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
5362
5363 /* Change the address of the relocation. */
5364 PUT_WORD (output_bfd,
5365 r_addr + input_section->output_offset,
5366 rel->r_address);
5367 }
5368 else
5369 {
5370 boolean hundef;
5371 bfd_reloc_status_type r;
5372
5373 /* We are generating an executable, and must do a full
5374 relocation. */
5375 hundef = false;
5376
5377 if (r_extern)
5378 {
5379 h = sym_hashes[r_index];
5380
5381 if (h != (struct aout_link_hash_entry *) NULL
5382 && (h->root.type == bfd_link_hash_defined
5383 || h->root.type == bfd_link_hash_defweak))
5384 {
5385 relocation = (h->root.u.def.value
5386 + h->root.u.def.section->output_section->vma
5387 + h->root.u.def.section->output_offset);
5388 }
5389 else if (h != (struct aout_link_hash_entry *) NULL
5390 && h->root.type == bfd_link_hash_undefweak)
5391 relocation = 0;
5392 else
5393 {
5394 hundef = true;
5395 relocation = 0;
5396 }
5397 }
5398 else if (r_type == RELOC_BASE10
5399 || r_type == RELOC_BASE13
5400 || r_type == RELOC_BASE22)
5401 {
5402 struct external_nlist *sym;
5403 int type;
5404
5405 /* For base relative relocs, r_index is always an index
5406 into the symbol table, even if r_extern is 0. */
5407 sym = syms + r_index;
5408 type = bfd_h_get_8 (input_bfd, sym->e_type);
5409 if ((type & N_TYPE) == N_TEXT
5410 || type == N_WEAKT)
5411 r_section = obj_textsec (input_bfd);
5412 else if ((type & N_TYPE) == N_DATA
5413 || type == N_WEAKD)
5414 r_section = obj_datasec (input_bfd);
5415 else if ((type & N_TYPE) == N_BSS
5416 || type == N_WEAKB)
5417 r_section = obj_bsssec (input_bfd);
5418 else if ((type & N_TYPE) == N_ABS
5419 || type == N_WEAKA)
5420 r_section = bfd_abs_section_ptr;
5421 else
5422 abort ();
5423 relocation = (r_section->output_section->vma
5424 + r_section->output_offset
5425 + (GET_WORD (input_bfd, sym->e_value)
5426 - r_section->vma));
5427 }
5428 else
5429 {
5430 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5431
5432 /* If this is a PC relative reloc, then R_ADDEND is the
5433 difference between the two vmas, or
5434 old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
5435 where
5436 old_dest_sec == section->vma
5437 and
5438 old_src_sec == input_section->vma
5439 and
5440 old_src_off == r_addr
5441
5442 _bfd_final_link_relocate expects RELOCATION +
5443 R_ADDEND to be the VMA of the destination minus
5444 r_addr (the minus r_addr is because this relocation
5445 is not pcrel_offset, which is a bit confusing and
5446 should, perhaps, be changed), or
5447 new_dest_sec
5448 where
5449 new_dest_sec == output_section->vma + output_offset
5450 We arrange for this to happen by setting RELOCATION to
5451 new_dest_sec + old_src_sec - old_dest_sec
5452
5453 If this is not a PC relative reloc, then R_ADDEND is
5454 simply the VMA of the destination, so we set
5455 RELOCATION to the change in the destination VMA, or
5456 new_dest_sec - old_dest_sec
5457 */
5458 relocation = (r_section->output_section->vma
5459 + r_section->output_offset
5460 - r_section->vma);
5461 if (howto_table_ext[r_type].pc_relative)
5462 relocation += input_section->vma;
5463 }
5464
5465 if (check_dynamic_reloc != NULL)
5466 {
5467 boolean skip;
5468
5469 if (! ((*check_dynamic_reloc)
5470 (finfo->info, input_bfd, input_section, h,
5471 (PTR) rel, contents, &skip, &relocation)))
5472 return false;
5473 if (skip)
5474 continue;
5475 }
5476
5477 /* Now warn if a global symbol is undefined. We could not
5478 do this earlier, because check_dynamic_reloc might want
5479 to skip this reloc. */
5480 if (hundef
5481 && ! finfo->info->shared
5482 && r_type != RELOC_BASE10
5483 && r_type != RELOC_BASE13
5484 && r_type != RELOC_BASE22)
5485 {
5486 const char *name;
5487
5488 if (h != NULL)
5489 name = h->root.root.string;
5490 else
5491 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5492 if (! ((*finfo->info->callbacks->undefined_symbol)
5493 (finfo->info, name, input_bfd, input_section,
5494 r_addr, true)))
5495 return false;
5496 }
5497
5498 if (r_type != RELOC_SPARC_REV32)
5499 r = MY_final_link_relocate (howto_table_ext + r_type,
5500 input_bfd, input_section,
5501 contents, r_addr, relocation,
5502 r_addend);
5503 else
5504 {
5505 bfd_vma x;
5506
5507 x = bfd_get_32 (input_bfd, contents + r_addr);
5508 x = x + relocation + r_addend;
5509 bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
5510 r = bfd_reloc_ok;
5511 }
5512
5513 if (r != bfd_reloc_ok)
5514 {
5515 switch (r)
5516 {
5517 default:
5518 case bfd_reloc_outofrange:
5519 abort ();
5520 case bfd_reloc_overflow:
5521 {
5522 const char *name;
5523
5524 if (h != NULL)
5525 name = h->root.root.string;
5526 else if (r_extern
5527 || r_type == RELOC_BASE10
5528 || r_type == RELOC_BASE13
5529 || r_type == RELOC_BASE22)
5530 name = strings + GET_WORD (input_bfd,
5531 syms[r_index].e_strx);
5532 else
5533 {
5534 asection *s;
5535
5536 s = aout_reloc_index_to_section (input_bfd, r_index);
5537 name = bfd_section_name (input_bfd, s);
5538 }
5539 if (! ((*finfo->info->callbacks->reloc_overflow)
5540 (finfo->info, name, howto_table_ext[r_type].name,
5541 r_addend, input_bfd, input_section, r_addr)))
5542 return false;
5543 }
5544 break;
5545 }
5546 }
5547 }
5548 }
5549
5550 return true;
5551}
5552
5553/* Handle a link order which is supposed to generate a reloc. */
5554
5555static boolean
5556aout_link_reloc_link_order (finfo, o, p)
5557 struct aout_final_link_info *finfo;
5558 asection *o;
5559 struct bfd_link_order *p;
5560{
5561 struct bfd_link_order_reloc *pr;
5562 int r_index;
5563 int r_extern;
5564 reloc_howto_type *howto;
5565 file_ptr *reloff_ptr = NULL;
5566 struct reloc_std_external srel;
5567 struct reloc_ext_external erel;
5568 PTR rel_ptr;
5569
5570 pr = p->u.reloc.p;
5571
5572 if (p->type == bfd_section_reloc_link_order)
5573 {
5574 r_extern = 0;
5575 if (bfd_is_abs_section (pr->u.section))
5576 r_index = N_ABS | N_EXT;
5577 else
5578 {
5579 BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
5580 r_index = pr->u.section->target_index;
5581 }
5582 }
5583 else
5584 {
5585 struct aout_link_hash_entry *h;
5586
5587 BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
5588 r_extern = 1;
5589 h = ((struct aout_link_hash_entry *)
5590 bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
5591 pr->u.name, false, false, true));
5592 if (h != (struct aout_link_hash_entry *) NULL
5593 && h->indx >= 0)
5594 r_index = h->indx;
5595 else if (h != NULL)
5596 {
5597 /* We decided to strip this symbol, but it turns out that we
5598 can't. Note that we lose the other and desc information
5599 here. I don't think that will ever matter for a global
5600 symbol. */
5601 h->indx = -2;
5602 h->written = false;
5603 if (! aout_link_write_other_symbol (h, (PTR) finfo))
5604 return false;
5605 r_index = h->indx;
5606 }
5607 else
5608 {
5609 if (! ((*finfo->info->callbacks->unattached_reloc)
5610 (finfo->info, pr->u.name, (bfd *) NULL,
5611 (asection *) NULL, (bfd_vma) 0)))
5612 return false;
5613 r_index = 0;
5614 }
5615 }
5616
5617 howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
5618 if (howto == 0)
5619 {
5620 bfd_set_error (bfd_error_bad_value);
5621 return false;
5622 }
5623
5624 if (o == obj_textsec (finfo->output_bfd))
5625 reloff_ptr = &finfo->treloff;
5626 else if (o == obj_datasec (finfo->output_bfd))
5627 reloff_ptr = &finfo->dreloff;
5628 else
5629 abort ();
5630
5631 if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
5632 {
5633#ifdef MY_put_reloc
5634 MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto,
5635 &srel);
5636#else
5637 {
5638 int r_pcrel;
5639 int r_baserel;
5640 int r_jmptable;
5641 int r_relative;
5642 int r_length;
5643
5644 r_pcrel = howto->pc_relative;
5645 r_baserel = (howto->type & 8) != 0;
5646 r_jmptable = (howto->type & 16) != 0;
5647 r_relative = (howto->type & 32) != 0;
5648 r_length = howto->size;
5649
5650 PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
5651 if (bfd_header_big_endian (finfo->output_bfd))
5652 {
5653 srel.r_index[0] = r_index >> 16;
5654 srel.r_index[1] = r_index >> 8;
5655 srel.r_index[2] = r_index;
5656 srel.r_type[0] =
5657 ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
5658 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
5659 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
5660 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
5661 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
5662 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
5663 }
5664 else
5665 {
5666 srel.r_index[2] = r_index >> 16;
5667 srel.r_index[1] = r_index >> 8;
5668 srel.r_index[0] = r_index;
5669 srel.r_type[0] =
5670 ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
5671 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
5672 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
5673 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
5674 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
5675 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
5676 }
5677 }
5678#endif
5679 rel_ptr = (PTR) &srel;
5680
5681 /* We have to write the addend into the object file, since
5682 standard a.out relocs are in place. It would be more
5683 reliable if we had the current contents of the file here,
5684 rather than assuming zeroes, but we can't read the file since
5685 it was opened using bfd_openw. */
5686 if (pr->addend != 0)
5687 {
5688 bfd_size_type size;
5689 bfd_reloc_status_type r;
5690 bfd_byte *buf;
5691 boolean ok;
5692
5693 size = bfd_get_reloc_size (howto);
5694 buf = (bfd_byte *) bfd_zmalloc (size);
5695 if (buf == (bfd_byte *) NULL)
5696 return false;
5697 r = MY_relocate_contents (howto, finfo->output_bfd,
5698 pr->addend, buf);
5699 switch (r)
5700 {
5701 case bfd_reloc_ok:
5702 break;
5703 default:
5704 case bfd_reloc_outofrange:
5705 abort ();
5706 case bfd_reloc_overflow:
5707 if (! ((*finfo->info->callbacks->reloc_overflow)
5708 (finfo->info,
5709 (p->type == bfd_section_reloc_link_order
5710 ? bfd_section_name (finfo->output_bfd,
5711 pr->u.section)
5712 : pr->u.name),
5713 howto->name, pr->addend, (bfd *) NULL,
5714 (asection *) NULL, (bfd_vma) 0)))
5715 {
5716 free (buf);
5717 return false;
5718 }
5719 break;
5720 }
5721 ok = bfd_set_section_contents (finfo->output_bfd, o,
5722 (PTR) buf,
5723 (file_ptr) p->offset,
5724 size);
5725 free (buf);
5726 if (! ok)
5727 return false;
5728 }
5729 }
5730 else
5731 {
5732#ifdef MY_put_ext_reloc
5733 MY_put_ext_reloc (finfo->output_bfd, r_extern, r_index, p->offset,
5734 howto, &erel, pr->addend);
5735#else
5736 PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
5737
5738 if (bfd_header_big_endian (finfo->output_bfd))
5739 {
5740 erel.r_index[0] = r_index >> 16;
5741 erel.r_index[1] = r_index >> 8;
5742 erel.r_index[2] = r_index;
5743 erel.r_type[0] =
5744 ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
5745 | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
5746 }
5747 else
5748 {
5749 erel.r_index[2] = r_index >> 16;
5750 erel.r_index[1] = r_index >> 8;
5751 erel.r_index[0] = r_index;
5752 erel.r_type[0] =
5753 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
5754 | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
5755 }
5756
5757 PUT_WORD (finfo->output_bfd, pr->addend, erel.r_addend);
5758#endif /* MY_put_ext_reloc */
5759
5760 rel_ptr = (PTR) &erel;
5761 }
5762
5763 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
5764 || (bfd_write (rel_ptr, (bfd_size_type) 1,
5765 obj_reloc_entry_size (finfo->output_bfd),
5766 finfo->output_bfd)
5767 != obj_reloc_entry_size (finfo->output_bfd)))
5768 return false;
5769
5770 *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
5771
5772 /* Assert that the relocs have not run into the symbols, and that n
5773 the text relocs have not run into the data relocs. */
5774 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
5775 && (reloff_ptr != &finfo->treloff
5776 || (*reloff_ptr
5777 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
5778
5779 return true;
5780}
Note: See TracBrowser for help on using the repository browser.