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