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