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