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