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