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