* targets.c (bfd_target): Add fields
[deliverable/binutils-gdb.git] / bfd / aoutx.h
CommitLineData
1f29e30b 1/* BFD semi-generic back-end for a.out binaries.
9783e04a 2 Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
88dfcd68 3 Written by Cygnus Support.
7ed4093a 4
88dfcd68 5This file is part of BFD, the Binary File Descriptor library.
7ed4093a 6
88dfcd68 7This program is free software; you can redistribute it and/or modify
7ed4093a 8it under the terms of the GNU General Public License as published by
88dfcd68
SC
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
7ed4093a 11
88dfcd68 12This program is distributed in the hope that it will be useful,
7ed4093a
SC
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
88dfcd68
SC
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
7ed4093a 20
4e41b5aa
SC
21/*
22SECTION
23 a.out backends
6f715d66 24
6f715d66 25
4e41b5aa 26DESCRIPTION
6f715d66 27
4e41b5aa
SC
28 BFD supports a number of different flavours of a.out format,
29 though the major differences are only the sizes of the
30 structures on disk, and the shape of the relocation
c188b0be 31 information.
6f715d66 32
c188b0be 33 The support is split into a basic support file @file{aoutx.h}
4e41b5aa 34 and other files which derive functions from the base. One
c188b0be 35 derivation file is @file{aoutf1.h} (for a.out flavour 1), and
4e41b5aa
SC
36 adds to the basic a.out functions support for sun3, sun4, 386
37 and 29k a.out files, to create a target jump vector for a
c188b0be 38 specific target.
6f715d66 39
4e41b5aa 40 This information is further split out into more specific files
c188b0be
DM
41 for each machine, including @file{sunos.c} for sun3 and sun4,
42 @file{newsos3.c} for the Sony NEWS, and @file{demo64.c} for a
4e41b5aa
SC
43 demonstration of a 64 bit a.out format.
44
c188b0be
DM
45 The base file @file{aoutx.h} defines general mechanisms for
46 reading and writing records to and from disk and various
4e41b5aa 47 other methods which BFD requires. It is included by
c188b0be
DM
48 @file{aout32.c} and @file{aout64.c} to form the names
49 <<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc.
4e41b5aa
SC
50
51 As an example, this is what goes on to make the back end for a
c188b0be 52 sun4, from @file{aout32.c}:
4e41b5aa 53
3f7607af
PB
54| #define ARCH_SIZE 32
55| #include "aoutx.h"
4e41b5aa
SC
56
57 Which exports names:
58
3f7607af
PB
59| ...
60| aout_32_canonicalize_reloc
61| aout_32_find_nearest_line
62| aout_32_get_lineno
63| aout_32_get_reloc_upper_bound
64| ...
6f715d66 65
c188b0be 66 from @file{sunos.c}:
4e41b5aa 67
3f7607af
PB
68| #define ARCH 32
69| #define TARGET_NAME "a.out-sunos-big"
70| #define VECNAME sunos_big_vec
71| #include "aoutf1.h"
4e41b5aa 72
c188b0be 73 requires all the names from @file{aout32.c}, and produces the jump vector
6f715d66 74
3f7607af 75| sunos_big_vec
c6705697 76
c188b0be 77 The file @file{host-aout.c} is a special case. It is for a large set
4e41b5aa
SC
78 of hosts that use ``more or less standard'' a.out files, and
79 for which cross-debugging is not interesting. It uses the
80 standard 32-bit a.out support routines, but determines the
81 file offsets and addresses of the text, data, and BSS
82 sections, the machine architecture and machine type, and the
83 entry point address, in a host-dependent manner. Once these
84 values have been determined, generic code is used to handle
c188b0be 85 the object file.
c6705697 86
4e41b5aa
SC
87 When porting it to run on a new system, you must supply:
88
3f7607af
PB
89| HOST_PAGE_SIZE
90| HOST_SEGMENT_SIZE
91| HOST_MACHINE_ARCH (optional)
92| HOST_MACHINE_MACHINE (optional)
93| HOST_TEXT_START_ADDR
94| HOST_STACK_END_ADDR
c6705697 95
4c3721d5
ILT
96 in the file @file{../include/sys/h-@var{XXX}.h} (for your host). These
97 values, plus the structures and macros defined in @file{a.out.h} on
4e41b5aa
SC
98 your host system, will produce a BFD target that will access
99 ordinary a.out files on your host. To configure a new machine
4c3721d5 100 to use @file{host-aout.c}, specify:
c6705697 101
3f7607af
PB
102| TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
103| TDEPFILES= host-aout.o trad-core.o
c6705697 104
4c3721d5
ILT
105 in the @file{config/@var{XXX}.mt} file, and modify @file{configure.in}
106 to use the
107 @file{@var{XXX}.mt} file (by setting "<<bfd_target=XXX>>") when your
4e41b5aa 108 configuration is selected.
c6705697 109
6f715d66
SC
110*/
111
ce07dd7c
KR
112/* Some assumptions:
113 * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
114 Doesn't matter what the setting of WP_TEXT is on output, but it'll
115 get set on input.
116 * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
117 * Any BFD with both flags clear is OMAGIC.
118 (Just want to make these explicit, so the conditions tested in this
119 file make sense if you're more familiar with a.out than with BFD.) */
120
c618de01
SC
121#define KEEPIT flags
122#define KEEPITTYPE int
67c060c3 123
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;
7ed4093a 2606
c188b0be 2607 for (count = 0; count++ < section->reloc_count;)
7ed4093a
SC
2608 {
2609 *relptr++ = tblptr++;
2610 }
2611 }
2612 *relptr = 0;
2613
2614 return section->reloc_count;
2615}
2616
326e32d7 2617long
8eb5d4be
JK
2618NAME(aout,get_reloc_upper_bound) (abfd, asect)
2619 bfd *abfd;
2620 sec_ptr asect;
7ed4093a 2621{
0ee75d02
ILT
2622 bfd_size_type dynrel_count = 0;
2623
7ed4093a 2624 if (bfd_get_format (abfd) != bfd_object) {
68241b2b 2625 bfd_set_error (bfd_error_invalid_operation);
326e32d7 2626 return -1;
7ed4093a
SC
2627 }
2628 if (asect->flags & SEC_CONSTRUCTOR) {
2629 return (sizeof (arelent *) * (asect->reloc_count+1));
2630 }
2631
0ee75d02
ILT
2632 if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0
2633 && aout_backend_info (abfd)->read_dynamic_relocs)
2634 {
2635 PTR dynrels;
2636
2637 dynrel_count = ((*aout_backend_info (abfd)->read_dynamic_relocs)
2638 (abfd, &dynrels));
2639 if (dynrel_count == (bfd_size_type) -1)
326e32d7 2640 return -1;
0ee75d02 2641 }
7ed4093a
SC
2642
2643 if (asect == obj_datasec (abfd))
2644 return (sizeof (arelent *) *
0ee75d02
ILT
2645 ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
2646 + dynrel_count + 1));
7ed4093a
SC
2647
2648 if (asect == obj_textsec (abfd))
2649 return (sizeof (arelent *) *
0ee75d02
ILT
2650 ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
2651 + dynrel_count + 1));
7ed4093a 2652
68241b2b 2653 bfd_set_error (bfd_error_invalid_operation);
326e32d7 2654 return -1;
7ed4093a
SC
2655}
2656
2657\f
326e32d7 2658long
8eb5d4be
JK
2659NAME(aout,get_symtab_upper_bound) (abfd)
2660 bfd *abfd;
7ed4093a 2661{
326e32d7
ILT
2662 if (!NAME(aout,slurp_symbol_table)(abfd))
2663 return -1;
7ed4093a
SC
2664
2665 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2666}
728472f1
ILT
2667
2668/*ARGSUSED*/
7ed4093a 2669 alent *
8eb5d4be
JK
2670NAME(aout,get_lineno) (ignore_abfd, ignore_symbol)
2671 bfd *ignore_abfd;
2672 asymbol *ignore_symbol;
7ed4093a
SC
2673{
2674return (alent *)NULL;
2675}
2676
728472f1 2677/*ARGSUSED*/
c188b0be 2678void
8eb5d4be
JK
2679NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
2680 bfd *ignore_abfd;
2681 asymbol *symbol;
2682 symbol_info *ret;
34dd8ba3
JG
2683{
2684 bfd_symbol_info (symbol, ret);
2685
2686 if (ret->type == '?')
2687 {
2688 int type_code = aout_symbol(symbol)->type & 0xff;
2689 CONST char *stab_name = aout_stab_name(type_code);
2690 static char buf[10];
2691
2692 if (stab_name == NULL)
2693 {
2694 sprintf(buf, "(%d)", type_code);
2695 stab_name = buf;
2696 }
2697 ret->type = '-';
2698 ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
2699 ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
2700 ret->stab_name = stab_name;
2701 }
2702}
7ed4093a 2703
728472f1 2704/*ARGSUSED*/
c188b0be 2705void
8eb5d4be
JK
2706NAME(aout,print_symbol) (ignore_abfd, afile, symbol, how)
2707 bfd *ignore_abfd;
2708 PTR afile;
2709 asymbol *symbol;
2710 bfd_print_symbol_type how;
7ed4093a
SC
2711{
2712 FILE *file = (FILE *)afile;
2713
2714 switch (how) {
9e2dad8e 2715 case bfd_print_symbol_name:
fb3be09b
JG
2716 if (symbol->name)
2717 fprintf(file,"%s", symbol->name);
7ed4093a 2718 break;
9e2dad8e 2719 case bfd_print_symbol_more:
7ed4093a
SC
2720 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
2721 (unsigned)(aout_symbol(symbol)->other & 0xff),
2722 (unsigned)(aout_symbol(symbol)->type));
2723 break;
9e2dad8e 2724 case bfd_print_symbol_all:
7ed4093a 2725 {
6db82ea7
SC
2726 CONST char *section_name = symbol->section->name;
2727
7ed4093a
SC
2728
2729 bfd_print_symbol_vandf((PTR)file,symbol);
2730
fb3be09b 2731 fprintf(file," %-5s %04x %02x %02x",
7ed4093a
SC
2732 section_name,
2733 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
2734 (unsigned)(aout_symbol(symbol)->other & 0xff),
9e2dad8e 2735 (unsigned)(aout_symbol(symbol)->type & 0xff));
fb3be09b
JG
2736 if (symbol->name)
2737 fprintf(file," %s", symbol->name);
7ed4093a
SC
2738 }
2739 break;
2740 }
2741}
2742
c188b0be 2743/*
6724ff46 2744 provided a BFD, a section and an offset into the section, calculate
7ed4093a
SC
2745 and return the name of the source file and the line nearest to the
2746 wanted location.
2747*/
c188b0be 2748
7ed4093a 2749boolean
8eb5d4be
JK
2750NAME(aout,find_nearest_line)
2751 (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
2752 bfd *abfd;
2753 asection *section;
2754 asymbol **symbols;
2755 bfd_vma offset;
2756 CONST char **filename_ptr;
2757 CONST char **functionname_ptr;
2758 unsigned int *line_ptr;
7ed4093a
SC
2759{
2760 /* Run down the file looking for the filename, function and linenumber */
2761 asymbol **p;
2762 static char buffer[100];
98d43107 2763 static char filename_buffer[200];
6db82ea7
SC
2764 CONST char *directory_name = NULL;
2765 CONST char *main_file_name = NULL;
2766 CONST char *current_file_name = NULL;
2767 CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
7ed4093a
SC
2768 bfd_vma high_line_vma = ~0;
2769 bfd_vma low_func_vma = 0;
2770 asymbol *func = 0;
2771 *filename_ptr = abfd->filename;
2772 *functionname_ptr = 0;
2773 *line_ptr = 0;
2774 if (symbols != (asymbol **)NULL) {
2775 for (p = symbols; *p; p++) {
2776 aout_symbol_type *q = (aout_symbol_type *)(*p);
98d43107 2777 next:
7ed4093a
SC
2778 switch (q->type){
2779 case N_SO:
3f7607af 2780 main_file_name = current_file_name = q->symbol.name;
98d43107
JG
2781 /* Look ahead to next symbol to check if that too is an N_SO. */
2782 p++;
2783 if (*p == NULL)
2784 break;
2785 q = (aout_symbol_type *)(*p);
6db82ea7 2786 if (q->type != (int)N_SO)
98d43107
JG
2787 goto next;
2788
2789 /* Found a second N_SO First is directory; second is filename. */
3f7607af
PB
2790 directory_name = current_file_name;
2791 main_file_name = current_file_name = q->symbol.name;
2792 if (obj_textsec(abfd) != section)
2793 goto done;
2794 break;
2795 case N_SOL:
2796 current_file_name = q->symbol.name;
7ed4093a 2797 break;
3f7607af 2798
7ed4093a
SC
2799 case N_SLINE:
2800
2801 case N_DSLINE:
2802 case N_BSLINE:
2803 /* We'll keep this if it resolves nearer than the one we have already */
2804 if (q->symbol.value >= offset &&
2805 q->symbol.value < high_line_vma) {
2806 *line_ptr = q->desc;
2807 high_line_vma = q->symbol.value;
3f7607af 2808 line_file_name = current_file_name;
7ed4093a
SC
2809 }
2810 break;
2811 case N_FUN:
2812 {
2813 /* We'll keep this if it is nearer than the one we have already */
2814 if (q->symbol.value >= low_func_vma &&
2815 q->symbol.value <= offset) {
2816 low_func_vma = q->symbol.value;
2817 func = (asymbol *)q;
2818 }
2819 if (*line_ptr && func) {
2820 CONST char *function = func->name;
2821 char *p;
ec099b4b 2822
91f300d6 2823 /* The caller expects a symbol name. We actually have a
ec099b4b
ILT
2824 function name, without the leading underscore. Put the
2825 underscore back in, so that the caller gets a symbol
2826 name. */
2827 if (bfd_get_symbol_leading_char (abfd) == '\0')
2828 strncpy (buffer, function, sizeof (buffer) - 1);
2829 else
2830 {
2831 buffer[0] = bfd_get_symbol_leading_char (abfd);
2832 strncpy (buffer + 1, function, sizeof (buffer) - 2);
2833 }
7ed4093a
SC
2834 buffer[sizeof(buffer)-1] = 0;
2835 /* Have to remove : stuff */
2836 p = strchr(buffer,':');
7b02b4ed 2837 if (p != NULL) { *p = '\0'; }
7ed4093a 2838 *functionname_ptr = buffer;
3f7607af 2839 goto done;
7ed4093a
SC
2840
2841 }
2842 }
2843 break;
2844 }
2845 }
2846 }
3f7607af
PB
2847
2848 done:
2849 if (*line_ptr)
2850 main_file_name = line_file_name;
2851 if (main_file_name) {
2852 if (main_file_name[0] == '/' || directory_name == NULL)
2853 *filename_ptr = main_file_name;
2854 else {
2855 sprintf(filename_buffer, "%.140s%.50s",
2856 directory_name, main_file_name);
2857 *filename_ptr = filename_buffer;
2858 }
2859 }
7ed4093a
SC
2860 return true;
2861
2862}
2863
728472f1 2864/*ARGSUSED*/
c188b0be 2865int
8eb5d4be
JK
2866NAME(aout,sizeof_headers) (abfd, execable)
2867 bfd *abfd;
2868 boolean execable;
7ed4093a 2869{
6db82ea7 2870 return adata(abfd).exec_bytes_size;
7ed4093a 2871}
5c8444f8
ILT
2872
2873/* Free all information we have cached for this BFD. We can always
2874 read it again later if we need it. */
2875
2876boolean
2877NAME(aout,bfd_free_cached_info) (abfd)
2878 bfd *abfd;
2879{
2880 asection *o;
2881
c4dd531f
ILT
2882 if (bfd_get_format (abfd) != bfd_object)
2883 return true;
2884
5c8444f8
ILT
2885#define FREE(x) if (x != NULL) { free (x); x = NULL; }
2886 FREE (obj_aout_symbols (abfd));
2887 FREE (obj_aout_external_syms (abfd));
2888 FREE (obj_aout_external_strings (abfd));
2889 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
2890 FREE (o->relocation);
2891#undef FREE
2892
2893 return true;
2894}
4c3721d5
ILT
2895\f
2896/* a.out link code. */
2897
2898/* a.out linker hash table entries. */
2899
2900struct aout_link_hash_entry
2901{
2902 struct bfd_link_hash_entry root;
2903 /* Symbol index in output file. */
2904 int indx;
2905};
2906
2907/* a.out linker hash table. */
2908
2909struct aout_link_hash_table
2910{
2911 struct bfd_link_hash_table root;
2912};
2913
2914static struct bfd_hash_entry *aout_link_hash_newfunc
2915 PARAMS ((struct bfd_hash_entry *entry,
2916 struct bfd_hash_table *table,
2917 const char *string));
2918static boolean aout_link_add_object_symbols
2919 PARAMS ((bfd *, struct bfd_link_info *));
2920static boolean aout_link_check_archive_element
2921 PARAMS ((bfd *, struct bfd_link_info *, boolean *));
4c3721d5
ILT
2922static boolean aout_link_free_symbols PARAMS ((bfd *));
2923static boolean aout_link_check_ar_symbols
2924 PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
2925static boolean aout_link_add_symbols
2926 PARAMS ((bfd *, struct bfd_link_info *));
2927
2928/* Routine to create an entry in an a.out link hash table. */
2929
2930static struct bfd_hash_entry *
2931aout_link_hash_newfunc (entry, table, string)
2932 struct bfd_hash_entry *entry;
2933 struct bfd_hash_table *table;
2934 const char *string;
2935{
2936 struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
2937
2938 /* Allocate the structure if it has not already been allocated by a
2939 subclass. */
2940 if (ret == (struct aout_link_hash_entry *) NULL)
2941 ret = ((struct aout_link_hash_entry *)
2942 bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
9783e04a
DM
2943 if (ret == (struct aout_link_hash_entry *) NULL)
2944 {
68241b2b 2945 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
2946 return (struct bfd_hash_entry *) ret;
2947 }
4c3721d5
ILT
2948
2949 /* Call the allocation method of the superclass. */
2950 ret = ((struct aout_link_hash_entry *)
2951 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2952 table, string));
9783e04a
DM
2953 if (ret)
2954 /* Set local fields. */
2955 ret->indx = -1;
4c3721d5
ILT
2956
2957 return (struct bfd_hash_entry *) ret;
2958}
2959
2960/* Create an a.out link hash table. */
2961
2962struct bfd_link_hash_table *
2963NAME(aout,link_hash_table_create) (abfd)
2964 bfd *abfd;
2965{
2966 struct aout_link_hash_table *ret;
2967
2968 ret = ((struct aout_link_hash_table *)
9783e04a
DM
2969 malloc (sizeof (struct aout_link_hash_table)));
2970 if (ret == (struct aout_link_hash_table *) NULL)
2971 {
68241b2b 2972 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
2973 return (struct bfd_link_hash_table *) NULL;
2974 }
4c3721d5
ILT
2975 if (! _bfd_link_hash_table_init (&ret->root, abfd,
2976 aout_link_hash_newfunc))
2977 {
2978 free (ret);
2979 return (struct bfd_link_hash_table *) NULL;
2980 }
2981 return &ret->root;
2982}
2983
2984/* Look up an entry in an a.out link hash table. */
2985
2986#define aout_link_hash_lookup(table, string, create, copy, follow) \
2987 ((struct aout_link_hash_entry *) \
2988 bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
2989
2990/* Traverse an a.out link hash table. */
2991
2992#define aout_link_hash_traverse(table, func, info) \
2993 (bfd_link_hash_traverse \
2994 (&(table)->root, \
2995 (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
2996 (info)))
2997
2998/* Get the a.out link hash table from the info structure. This is
2999 just a cast. */
3000
3001#define aout_hash_table(p) ((struct aout_link_hash_table *) ((p)->hash))
3002
3003/* Given an a.out BFD, add symbols to the global hash table as
3004 appropriate. */
3005
3006boolean
3007NAME(aout,link_add_symbols) (abfd, info)
3008 bfd *abfd;
3009 struct bfd_link_info *info;
3010{
3011 switch (bfd_get_format (abfd))
3012 {
3013 case bfd_object:
3014 return aout_link_add_object_symbols (abfd, info);
3015 case bfd_archive:
3016 return _bfd_generic_link_add_archive_symbols
3017 (abfd, info, aout_link_check_archive_element);
3018 default:
68241b2b 3019 bfd_set_error (bfd_error_wrong_format);
4c3721d5
ILT
3020 return false;
3021 }
3022}
3023
3024/* Add symbols from an a.out object file. */
3025
3026static boolean
3027aout_link_add_object_symbols (abfd, info)
3028 bfd *abfd;
3029 struct bfd_link_info *info;
3030{
5c8444f8 3031 if (! aout_get_external_symbols (abfd))
4c3721d5
ILT
3032 return false;
3033 if (! aout_link_add_symbols (abfd, info))
3034 return false;
3035 if (! info->keep_memory)
3036 {
3037 if (! aout_link_free_symbols (abfd))
3038 return false;
3039 }
3040 return true;
3041}
3042
3043/* Check a single archive element to see if we need to include it in
3044 the link. *PNEEDED is set according to whether this element is
3045 needed in the link or not. This is called from
3046 _bfd_generic_link_add_archive_symbols. */
3047
3048static boolean
3049aout_link_check_archive_element (abfd, info, pneeded)
3050 bfd *abfd;
3051 struct bfd_link_info *info;
3052 boolean *pneeded;
3053{
5c8444f8 3054 if (! aout_get_external_symbols (abfd))
4c3721d5
ILT
3055 return false;
3056
3057 if (! aout_link_check_ar_symbols (abfd, info, pneeded))
3058 return false;
3059
3060 if (*pneeded)
3061 {
3062 if (! aout_link_add_symbols (abfd, info))
3063 return false;
3064 }
3065
3066 /* We keep around the symbols even if we aren't going to use this
3067 object file, because we may want to reread it. This doesn't
3068 waste too much memory, because it isn't all that common to read
3069 an archive element but not need it. */
3070 if (! info->keep_memory)
3071 {
3072 if (! aout_link_free_symbols (abfd))
3073 return false;
3074 }
3075
3076 return true;
3077}
3078
4c3721d5
ILT
3079/* Free up the internal symbols read from an a.out file. */
3080
3081static boolean
3082aout_link_free_symbols (abfd)
3083 bfd *abfd;
3084{
3085 if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
3086 {
3087 free ((PTR) obj_aout_external_syms (abfd));
3088 obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
3089 }
3090 if (obj_aout_external_strings (abfd) != (char *) NULL)
3091 {
3092 free ((PTR) obj_aout_external_strings (abfd));
3093 obj_aout_external_strings (abfd) = (char *) NULL;
3094 }
3095 return true;
3096}
3097
3098/* Look through the internal symbols to see if this object file should
3099 be included in the link. We should include this object file if it
3100 defines any symbols which are currently undefined. If this object
3101 file defines a common symbol, then we may adjust the size of the
3102 known symbol but we do not include the object file in the link
3103 (unless there is some other reason to include it). */
3104
3105static boolean
3106aout_link_check_ar_symbols (abfd, info, pneeded)
3107 bfd *abfd;
3108 struct bfd_link_info *info;
3109 boolean *pneeded;
3110{
3111 register struct external_nlist *p;
3112 struct external_nlist *pend;
3113 char *strings;
3114
3115 *pneeded = false;
3116
3117 /* Look through all the symbols. */
3118 p = obj_aout_external_syms (abfd);
3119 pend = p + obj_aout_external_sym_count (abfd);
3120 strings = obj_aout_external_strings (abfd);
3121 for (; p < pend; p++)
3122 {
3123 int type = bfd_h_get_8 (abfd, p->e_type);
3124 const char *name;
3125 struct bfd_link_hash_entry *h;
3126
3127 /* Ignore symbols that are not externally visible. */
3128 if ((type & N_EXT) == 0)
9b39ed6b
ILT
3129 {
3130 if (type == N_WARNING
3131 || type == N_INDR)
3132 ++p;
3133 continue;
3134 }
4c3721d5
ILT
3135
3136 name = strings + GET_WORD (abfd, p->e_strx);
3137 h = bfd_link_hash_lookup (info->hash, name, false, false, true);
3138
3139 /* We are only interested in symbols that are currently
3140 undefined or common. */
3141 if (h == (struct bfd_link_hash_entry *) NULL
3142 || (h->type != bfd_link_hash_undefined
3143 && h->type != bfd_link_hash_common))
9b39ed6b
ILT
3144 {
3145 if (type == (N_INDR | N_EXT))
3146 ++p;
3147 continue;
3148 }
4c3721d5 3149
9b39ed6b
ILT
3150 if (type == (N_TEXT | N_EXT)
3151 || type == (N_DATA | N_EXT)
3152 || type == (N_BSS | N_EXT)
3153 || type == (N_ABS | N_EXT)
3154 || type == (N_INDR | N_EXT))
4c3721d5
ILT
3155 {
3156 /* This object file defines this symbol. We must link it
3157 in. This is true regardless of whether the current
3158 definition of the symbol is undefined or common. If the
3159 current definition is common, we have a case in which we
3160 have already seen an object file including
3161 int a;
3162 and this object file from the archive includes
3163 int a = 5;
3164 In such a case we must include this object file. */
3165 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3166 return false;
3167 *pneeded = true;
3168 return true;
3169 }
3170
9b39ed6b 3171 if (type == (N_UNDF | N_EXT))
4c3721d5
ILT
3172 {
3173 bfd_vma value;
3174
3175 value = GET_WORD (abfd, p->e_value);
3176 if (value != 0)
3177 {
3178 /* This symbol is common in the object from the archive
3179 file. */
3180 if (h->type == bfd_link_hash_undefined)
3181 {
3182 bfd *symbfd;
3183
3184 symbfd = h->u.undef.abfd;
3185 if (symbfd == (bfd *) NULL)
3186 {
3187 /* This symbol was created as undefined from
3188 outside BFD. We assume that we should link
3189 in the object file. This is done for the -u
3190 option in the linker. */
3191 if (! (*info->callbacks->add_archive_element) (info,
3192 abfd,
3193 name))
3194 return false;
3195 *pneeded = true;
3196 return true;
3197 }
3198 /* Turn the current link symbol into a common
3199 symbol. It is already on the undefs list. */
3200 h->type = bfd_link_hash_common;
3201 h->u.c.size = value;
3202 h->u.c.section = bfd_make_section_old_way (symbfd,
3203 "COMMON");
3204 }
3205 else
3206 {
3207 /* Adjust the size of the common symbol if
3208 necessary. */
3209 if (value > h->u.c.size)
3210 h->u.c.size = value;
3211 }
3212 }
3213 }
3214 }
3215
3216 /* We do not need this object file. */
3217 return true;
3218}
3219
3220/* Add all symbols from an object file to the hash table. */
3221
3222static boolean
3223aout_link_add_symbols (abfd, info)
3224 bfd *abfd;
3225 struct bfd_link_info *info;
3226{
3227 bfd_size_type sym_count;
3228 char *strings;
3229 boolean copy;
3230 struct aout_link_hash_entry **sym_hash;
3231 register struct external_nlist *p;
3232 struct external_nlist *pend;
3233
3234 sym_count = obj_aout_external_sym_count (abfd);
3235 strings = obj_aout_external_strings (abfd);
3236 if (info->keep_memory)
3237 copy = false;
3238 else
3239 copy = true;
3240
4c3721d5
ILT
3241 /* We keep a list of the linker hash table entries that correspond
3242 to particular symbols. We could just look them up in the hash
3243 table, but keeping the list is more efficient. Perhaps this
3244 should be conditional on info->keep_memory. */
3245 sym_hash = ((struct aout_link_hash_entry **)
3246 bfd_alloc (abfd,
3247 ((size_t) sym_count
3248 * sizeof (struct aout_link_hash_entry *))));
9783e04a
DM
3249 if (!sym_hash)
3250 {
68241b2b 3251 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
3252 return false;
3253 }
4c3721d5
ILT
3254 obj_aout_sym_hashes (abfd) = sym_hash;
3255
3256 p = obj_aout_external_syms (abfd);
3257 pend = p + sym_count;
3258 for (; p < pend; p++, sym_hash++)
3259 {
3260 int type;
3261 const char *name;
3262 bfd_vma value;
3263 asection *section;
3264 flagword flags;
3265 const char *string;
3266
3267 *sym_hash = NULL;
3268
3269 type = bfd_h_get_8 (abfd, p->e_type);
3270
3271 /* Ignore debugging symbols. */
3272 if ((type & N_STAB) != 0)
3273 continue;
3274
3275 /* Ignore symbols that are not external. */
3276 if ((type & N_EXT) == 0
3277 && type != N_WARNING
3278 && type != N_SETA
3279 && type != N_SETT
3280 && type != N_SETD
3281 && type != N_SETB)
3282 {
3283 /* If this is an N_INDR symbol we must skip the next entry,
3284 which is the symbol to indirect to (actually, an N_INDR
3285 symbol without N_EXT set is pretty useless). */
3286 if (type == N_INDR)
53155af1
ILT
3287 {
3288 ++p;
3289 ++sym_hash;
3290 }
4c3721d5
ILT
3291 continue;
3292 }
3293
3294 /* Ignore N_FN symbols (these appear to have N_EXT set). */
3295 if (type == N_FN)
3296 continue;
3297
3298 name = strings + GET_WORD (abfd, p->e_strx);
3299 value = GET_WORD (abfd, p->e_value);
3300 flags = BSF_GLOBAL;
3301 string = NULL;
3302 switch (type)
3303 {
3304 default:
3305 abort ();
3306 case N_UNDF | N_EXT:
3307 if (value != 0)
3308 section = &bfd_com_section;
3309 else
3310 section = &bfd_und_section;
3311 break;
3312 case N_ABS | N_EXT:
3313 section = &bfd_abs_section;
3314 break;
3315 case N_TEXT | N_EXT:
3316 section = obj_textsec (abfd);
3317 value -= bfd_get_section_vma (abfd, section);
3318 break;
3319 case N_DATA | N_EXT:
3320 section = obj_datasec (abfd);
3321 value -= bfd_get_section_vma (abfd, section);
3322 break;
3323 case N_BSS | N_EXT:
3324 section = obj_bsssec (abfd);
3325 value -= bfd_get_section_vma (abfd, section);
3326 break;
3327 case N_INDR | N_EXT:
3328 /* An indirect symbol. The next symbol is the symbol
3329 which this one really is. */
3330 BFD_ASSERT (p + 1 < pend);
3331 ++p;
3332 string = strings + GET_WORD (abfd, p->e_strx);
3333 section = &bfd_ind_section;
3334 flags |= BSF_INDIRECT;
3335 break;
3336 case N_COMM | N_EXT:
3337 section = &bfd_com_section;
3338 break;
964affdc 3339 case N_SETA: case N_SETA | N_EXT:
4c3721d5
ILT
3340 section = &bfd_abs_section;
3341 flags |= BSF_CONSTRUCTOR;
3342 break;
964affdc 3343 case N_SETT: case N_SETT | N_EXT:
4c3721d5
ILT
3344 section = obj_textsec (abfd);
3345 flags |= BSF_CONSTRUCTOR;
3346 value -= bfd_get_section_vma (abfd, section);
3347 break;
964affdc 3348 case N_SETD: case N_SETD | N_EXT:
4c3721d5
ILT
3349 section = obj_datasec (abfd);
3350 flags |= BSF_CONSTRUCTOR;
3351 value -= bfd_get_section_vma (abfd, section);
3352 break;
964affdc 3353 case N_SETB: case N_SETB | N_EXT:
4c3721d5
ILT
3354 section = obj_bsssec (abfd);
3355 flags |= BSF_CONSTRUCTOR;
3356 value -= bfd_get_section_vma (abfd, section);
3357 break;
3358 case N_WARNING:
3359 /* A warning symbol. The next symbol is the one to warn
3360 about. */
3361 BFD_ASSERT (p + 1 < pend);
3362 ++p;
3363 string = name;
3364 name = strings + GET_WORD (abfd, p->e_strx);
3365 section = &bfd_und_section;
3366 flags |= BSF_WARNING;
3367 break;
3368 }
3369
3370 if (! (_bfd_generic_link_add_one_symbol
e68de5d5 3371 (info, abfd, name, flags, section, value, string, copy, false,
ec099b4b 3372 (struct bfd_link_hash_entry **) sym_hash)))
4c3721d5 3373 return false;
53155af1
ILT
3374
3375 if (type == (N_INDR | N_EXT) || type == N_WARNING)
3376 ++sym_hash;
4c3721d5
ILT
3377 }
3378
3379 return true;
3380}
3381
3382/* During the final link step we need to pass around a bunch of
3383 information, so we do it in an instance of this structure. */
3384
3385struct aout_final_link_info
3386{
3387 /* General link information. */
3388 struct bfd_link_info *info;
3389 /* Output bfd. */
3390 bfd *output_bfd;
3391 /* Reloc file positions. */
3392 file_ptr treloff, dreloff;
3393 /* File position of symbols. */
3394 file_ptr symoff;
3395 /* String table. */
3396 struct stringtab_data strtab;
3397};
3398
3399static boolean aout_link_input_bfd
3400 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3401static boolean aout_link_write_symbols
3402 PARAMS ((struct aout_final_link_info *, bfd *input_bfd, int *symbol_map));
3403static boolean aout_link_write_other_symbol
3404 PARAMS ((struct aout_link_hash_entry *, PTR));
3405static boolean aout_link_input_section
3406 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3407 asection *input_section, file_ptr *reloff_ptr,
3408 bfd_size_type rel_size, int *symbol_map));
3409static boolean aout_link_input_section_std
3410 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3411 asection *input_section, struct reloc_std_external *,
3412 bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
3413static boolean aout_link_input_section_ext
3414 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3415 asection *input_section, struct reloc_ext_external *,
3416 bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
3417static INLINE asection *aout_reloc_index_to_section
3418 PARAMS ((bfd *, int));
ec099b4b
ILT
3419static boolean aout_link_reloc_link_order
3420 PARAMS ((struct aout_final_link_info *, asection *,
3421 struct bfd_link_order *));
4c3721d5
ILT
3422
3423/* Do the final link step. This is called on the output BFD. The
3424 INFO structure should point to a list of BFDs linked through the
3425 link_next field which can be used to find each BFD which takes part
3426 in the output. Also, each section in ABFD should point to a list
3427 of bfd_link_order structures which list all the input sections for
3428 the output section. */
3429
3430boolean
3431NAME(aout,final_link) (abfd, info, callback)
3432 bfd *abfd;
3433 struct bfd_link_info *info;
3434 void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
3435{
3436 struct aout_final_link_info aout_info;
3437 register bfd *sub;
3438 bfd_size_type text_size;
3439 file_ptr text_end;
3440 register struct bfd_link_order *p;
3441 asection *o;
ec099b4b 3442 boolean have_link_order_relocs;
4c3721d5
ILT
3443
3444 aout_info.info = info;
3445 aout_info.output_bfd = abfd;
3446
3447 if (! info->relocateable)
3448 {
3449 exec_hdr (abfd)->a_trsize = 0;
3450 exec_hdr (abfd)->a_drsize = 0;
3451 }
3452 else
3453 {
3454 bfd_size_type trsize, drsize;
3455
3456 /* Count up the relocation sizes. */
3457 trsize = 0;
3458 drsize = 0;
3459 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3460 {
3461 if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
3462 {
3463 trsize += exec_hdr (sub)->a_trsize;
3464 drsize += exec_hdr (sub)->a_drsize;
3465 }
3466 else
3467 {
3468 /* FIXME: We need to identify the .text and .data sections
3469 and call get_reloc_upper_bound and canonicalize_reloc to
3470 work out the number of relocs needed, and then multiply
3471 by the reloc size. */
3472 abort ();
3473 }
3474 }
ec099b4b
ILT
3475 trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
3476 ->link_order_head)
3477 * obj_reloc_entry_size (abfd));
4c3721d5 3478 exec_hdr (abfd)->a_trsize = trsize;
ec099b4b
ILT
3479 drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
3480 ->link_order_head)
3481 * obj_reloc_entry_size (abfd));
4c3721d5
ILT
3482 exec_hdr (abfd)->a_drsize = drsize;
3483 }
3484
964affdc
DM
3485 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
3486
4c3721d5
ILT
3487 /* Adjust the section sizes and vmas according to the magic number.
3488 This sets a_text, a_data and a_bss in the exec_hdr and sets the
3489 filepos for each section. */
3490 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3491 return false;
3492
3493 /* The relocation and symbol file positions differ among a.out
3494 targets. We are passed a callback routine from the backend
3495 specific code to handle this.
3496 FIXME: At this point we do not know how much space the symbol
3497 table will require. This will not work for any (nonstandard)
3498 a.out target that needs to know the symbol table size before it
3499 can compute the relocation file positions. This may or may not
3500 be the case for the hp300hpux target, for example. */
3501 (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3502 &aout_info.symoff);
3503 obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3504 obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3505 obj_sym_filepos (abfd) = aout_info.symoff;
3506
3507 /* We keep a count of the symbols as we output them. */
3508 obj_aout_external_sym_count (abfd) = 0;
3509
3510 /* We accumulate the string table as we write out the symbols. */
3511 stringtab_init (&aout_info.strtab);
3512
3513 /* The most time efficient way to do the link would be to read all
3514 the input object files into memory and then sort out the
3515 information into the output file. Unfortunately, that will
3516 probably use too much memory. Another method would be to step
3517 through everything that composes the text section and write it
3518 out, and then everything that composes the data section and write
3519 it out, and then write out the relocs, and then write out the
3520 symbols. Unfortunately, that requires reading stuff from each
3521 input file several times, and we will not be able to keep all the
3522 input files open simultaneously, and reopening them will be slow.
3523
3524 What we do is basically process one input file at a time. We do
3525 everything we need to do with an input file once--copy over the
3526 section contents, handle the relocation information, and write
3527 out the symbols--and then we throw away the information we read
3528 from it. This approach requires a lot of lseeks of the output
3529 file, which is unfortunate but still faster than reopening a lot
3530 of files.
3531
3532 We use the output_has_begun field of the input BFDs to see
3533 whether we have already handled it. */
3534 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3535 sub->output_has_begun = false;
3536
ec099b4b 3537 have_link_order_relocs = false;
4c3721d5
ILT
3538 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3539 {
4c3721d5
ILT
3540 for (p = o->link_order_head;
3541 p != (struct bfd_link_order *) NULL;
3542 p = p->next)
3543 {
e68de5d5
ILT
3544 if (p->type == bfd_indirect_link_order
3545 && (bfd_get_flavour (p->u.indirect.section->owner)
3546 == bfd_target_aout_flavour))
4c3721d5 3547 {
e68de5d5
ILT
3548 bfd *input_bfd;
3549
4c3721d5 3550 input_bfd = p->u.indirect.section->owner;
e68de5d5 3551 if (! input_bfd->output_has_begun)
4c3721d5 3552 {
e68de5d5
ILT
3553 if (! aout_link_input_bfd (&aout_info, input_bfd))
3554 return false;
3555 input_bfd->output_has_begun = true;
4c3721d5 3556 }
e68de5d5 3557 }
ec099b4b
ILT
3558 else if (p->type == bfd_section_reloc_link_order
3559 || p->type == bfd_symbol_reloc_link_order)
3560 {
3561 /* These are handled below. */
3562 have_link_order_relocs = true;
3563 }
e68de5d5
ILT
3564 else
3565 {
4c3721d5
ILT
3566 if (! _bfd_default_link_order (abfd, info, o, p))
3567 return false;
3568 }
3569 }
3570 }
3571
3572 /* Write out any symbols that we have not already written out. */
3573 aout_link_hash_traverse (aout_hash_table (info),
3574 aout_link_write_other_symbol,
3575 (PTR) &aout_info);
3576
ec099b4b
ILT
3577 /* Now handle any relocs we were asked to create by the linker.
3578 These did not come from any input file. We must do these after
3579 we have written out all the symbols, so that we know the symbol
3580 indices to use. */
3581 if (have_link_order_relocs)
3582 {
3583 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3584 {
3585 for (p = o->link_order_head;
3586 p != (struct bfd_link_order *) NULL;
3587 p = p->next)
3588 {
3589 if (p->type == bfd_section_reloc_link_order
3590 || p->type == bfd_symbol_reloc_link_order)
3591 {
3592 if (! aout_link_reloc_link_order (&aout_info, o, p))
3593 return false;
3594 }
3595 }
3596 }
3597 }
3598
4c3721d5
ILT
3599 /* Update the header information. */
3600 abfd->symcount = obj_aout_external_sym_count (abfd);
3601 exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
3602 obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
3603 obj_textsec (abfd)->reloc_count =
3604 exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
3605 obj_datasec (abfd)->reloc_count =
3606 exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
3607
3608 /* Write out the string table. */
3609 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
3610 return false;
29e626eb 3611 return emit_strtab (abfd, &aout_info.strtab);
4c3721d5
ILT
3612}
3613
3614/* Link an a.out input BFD into the output file. */
3615
3616static boolean
3617aout_link_input_bfd (finfo, input_bfd)
3618 struct aout_final_link_info *finfo;
3619 bfd *input_bfd;
3620{
3621 bfd_size_type sym_count;
80425e6c 3622 int *symbol_map = NULL;
4c3721d5
ILT
3623
3624 BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
3625
3626 /* Get the symbols. We probably have them already, unless
3627 finfo->info->keep_memory is false. */
5c8444f8 3628 if (! aout_get_external_symbols (input_bfd))
4c3721d5
ILT
3629 return false;
3630
3631 sym_count = obj_aout_external_sym_count (input_bfd);
80425e6c 3632 symbol_map = (int *) malloc ((size_t) sym_count * sizeof (int));
8eb5d4be 3633 if (symbol_map == NULL && sym_count != 0)
80425e6c
JK
3634 {
3635 bfd_set_error (bfd_error_no_memory);
3636 return false;
3637 }
4c3721d5
ILT
3638
3639 /* Write out the symbols and get a map of the new indices. */
3640 if (! aout_link_write_symbols (finfo, input_bfd, symbol_map))
80425e6c 3641 goto error_return;
4c3721d5
ILT
3642
3643 /* Relocate and write out the sections. */
3644 if (! aout_link_input_section (finfo, input_bfd,
3645 obj_textsec (input_bfd),
3646 &finfo->treloff,
3647 exec_hdr (input_bfd)->a_trsize,
3648 symbol_map)
3649 || ! aout_link_input_section (finfo, input_bfd,
3650 obj_datasec (input_bfd),
3651 &finfo->dreloff,
3652 exec_hdr (input_bfd)->a_drsize,
3653 symbol_map))
80425e6c 3654 goto error_return;
4c3721d5
ILT
3655
3656 /* If we are not keeping memory, we don't need the symbols any
3657 longer. We still need them if we are keeping memory, because the
3658 strings in the hash table point into them. */
3659 if (! finfo->info->keep_memory)
3660 {
3661 if (! aout_link_free_symbols (input_bfd))
80425e6c 3662 goto error_return;
4c3721d5
ILT
3663 }
3664
80425e6c
JK
3665 if (symbol_map != NULL)
3666 free (symbol_map);
4c3721d5 3667 return true;
80425e6c
JK
3668 error_return:
3669 if (symbol_map != NULL)
3670 free (symbol_map);
3671 return false;
4c3721d5
ILT
3672}
3673
3674/* Adjust and write out the symbols for an a.out file. Set the new
3675 symbol indices into a symbol_map. */
3676
3677static boolean
3678aout_link_write_symbols (finfo, input_bfd, symbol_map)
3679 struct aout_final_link_info *finfo;
3680 bfd *input_bfd;
3681 int *symbol_map;
3682{
3683 bfd *output_bfd;
3684 bfd_size_type sym_count;
3685 char *strings;
3686 enum bfd_link_strip strip;
3687 enum bfd_link_discard discard;
80425e6c 3688 struct external_nlist *output_syms = NULL;
4c3721d5
ILT
3689 struct external_nlist *outsym;
3690 register struct external_nlist *sym;
3691 struct external_nlist *sym_end;
3692 struct aout_link_hash_entry **sym_hash;
3693 boolean pass;
53155af1 3694 boolean skip_indirect;
4c3721d5
ILT
3695
3696 output_bfd = finfo->output_bfd;
3697 sym_count = obj_aout_external_sym_count (input_bfd);
3698 strings = obj_aout_external_strings (input_bfd);
3699 strip = finfo->info->strip;
3700 discard = finfo->info->discard;
3701 output_syms = ((struct external_nlist *)
80425e6c
JK
3702 malloc ((size_t) (sym_count + 1) * EXTERNAL_NLIST_SIZE));
3703 if (output_syms == NULL)
3704 {
3705 bfd_set_error (bfd_error_no_memory);
3706 goto error_return;
3707 }
4c3721d5
ILT
3708 outsym = output_syms;
3709
3710 /* First write out a symbol for this object file, unless we are
3711 discarding such symbols. */
3712 if (strip != strip_all
3713 && (strip != strip_some
3714 || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
3715 false, false) != NULL)
3716 && discard != discard_all)
3717 {
3718 bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type);
3719 bfd_h_put_8 (output_bfd, 0, outsym->e_other);
3720 bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc);
3721 PUT_WORD (output_bfd,
3722 add_to_stringtab (output_bfd, input_bfd->filename,
3723 &finfo->strtab),
3724 outsym->e_strx);
3725 PUT_WORD (output_bfd,
2edc8357
ILT
3726 (bfd_get_section_vma (output_bfd,
3727 obj_textsec (input_bfd)->output_section)
3728 + obj_textsec (input_bfd)->output_offset),
4c3721d5
ILT
3729 outsym->e_value);
3730 ++obj_aout_external_sym_count (output_bfd);
3731 ++outsym;
3732 }
3733
3734 pass = false;
53155af1 3735 skip_indirect = false;
4c3721d5
ILT
3736 sym = obj_aout_external_syms (input_bfd);
3737 sym_end = sym + sym_count;
3738 sym_hash = obj_aout_sym_hashes (input_bfd);
3739 for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
3740 {
3741 const char *name;
3742 int type;
d6d6b18a 3743 struct aout_link_hash_entry *h;
4c3721d5
ILT
3744 boolean skip;
3745 asection *symsec;
3746 bfd_vma val = 0;
3747
3748 *symbol_map = -1;
3749
3750 type = bfd_h_get_8 (input_bfd, sym->e_type);
3751 name = strings + GET_WORD (input_bfd, sym->e_strx);
3752
d6d6b18a
ILT
3753 h = NULL;
3754
4c3721d5
ILT
3755 if (pass)
3756 {
53155af1
ILT
3757 /* Pass this symbol through. It is the target of an
3758 indirect or warning symbol. */
4c3721d5
ILT
3759 val = GET_WORD (input_bfd, sym->e_value);
3760 pass = false;
3761 }
53155af1
ILT
3762 else if (skip_indirect)
3763 {
3764 /* Skip this symbol, which is the target of an indirect
3765 symbol that we have changed to no longer be an indirect
3766 symbol. */
3767 skip_indirect = false;
3768 continue;
3769 }
4c3721d5
ILT
3770 else
3771 {
53155af1 3772 struct aout_link_hash_entry *hresolve;
4c3721d5
ILT
3773
3774 /* We have saved the hash table entry for this symbol, if
3775 there is one. Note that we could just look it up again
3776 in the hash table, provided we first check that it is an
3777 external symbol. */
3778 h = *sym_hash;
3779
3a5b50f4
ILT
3780 /* If this is an indirect or warning symbol, then change
3781 hresolve to the base symbol. We also change *sym_hash so
3782 that the relocation routines relocate against the real
3783 symbol. */
53155af1
ILT
3784 hresolve = h;
3785 if (h != (struct aout_link_hash_entry *) NULL
3a5b50f4
ILT
3786 && (h->root.type == bfd_link_hash_indirect
3787 || h->root.type == bfd_link_hash_warning))
53155af1
ILT
3788 {
3789 hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
3790 while (hresolve->root.type == bfd_link_hash_indirect)
3791 hresolve = ((struct aout_link_hash_entry *)
3792 hresolve->root.u.i.link);
3793 *sym_hash = hresolve;
3794 }
3795
4c3721d5
ILT
3796 /* If the symbol has already been written out, skip it. */
3797 if (h != (struct aout_link_hash_entry *) NULL
3798 && h->root.written)
3799 {
3800 *symbol_map = h->indx;
3801 continue;
3802 }
3803
3804 /* See if we are stripping this symbol. */
3805 skip = false;
3806 switch (strip)
3807 {
3808 case strip_none:
3809 break;
3810 case strip_debugger:
3811 if ((type & N_STAB) != 0)
3812 skip = true;
3813 break;
3814 case strip_some:
3815 if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
3816 == NULL)
3817 skip = true;
3818 break;
3819 case strip_all:
3820 skip = true;
3821 break;
3822 }
3823 if (skip)
3824 {
3825 if (h != (struct aout_link_hash_entry *) NULL)
3826 h->root.written = true;
3827 continue;
3828 }
3829
3830 /* Get the value of the symbol. */
3831 if ((type & N_TYPE) == N_TEXT)
3832 symsec = obj_textsec (input_bfd);
3833 else if ((type & N_TYPE) == N_DATA)
3834 symsec = obj_datasec (input_bfd);
3835 else if ((type & N_TYPE) == N_BSS)
3836 symsec = obj_bsssec (input_bfd);
3837 else if ((type & N_TYPE) == N_ABS)
3838 symsec = &bfd_abs_section;
53155af1
ILT
3839 else if (((type & N_TYPE) == N_INDR
3840 && (hresolve == (struct aout_link_hash_entry *) NULL
3841 || (hresolve->root.type != bfd_link_hash_defined
3842 && hresolve->root.type != bfd_link_hash_common)))
4c3721d5
ILT
3843 || type == N_WARNING)
3844 {
53155af1
ILT
3845 /* Pass the next symbol through unchanged. The
3846 condition above for indirect symbols is so that if
3847 the indirect symbol was defined, we output it with
3848 the correct definition so the debugger will
3849 understand it. */
4c3721d5
ILT
3850 pass = true;
3851 val = GET_WORD (input_bfd, sym->e_value);
3852 symsec = NULL;
3853 }
3854 else if ((type & N_STAB) != 0)
3855 {
3856 val = GET_WORD (input_bfd, sym->e_value);
3857 symsec = NULL;
3858 }
3859 else
3860 {
53155af1
ILT
3861 /* If we get here with an indirect symbol, it means that
3862 we are outputting it with a real definition. In such
3863 a case we do not want to output the next symbol,
3864 which is the target of the indirection. */
3865 if ((type & N_TYPE) == N_INDR)
3866 skip_indirect = true;
3867
3868 /* We need to get the value from the hash table. We use
3869 hresolve so that if we have defined an indirect
3870 symbol we output the final definition. */
4c3721d5
ILT
3871 if (h == (struct aout_link_hash_entry *) NULL)
3872 val = 0;
53155af1 3873 else if (hresolve->root.type == bfd_link_hash_defined)
4c3721d5 3874 {
53155af1 3875 asection *input_section;
4c3721d5
ILT
3876 asection *output_section;
3877
3878 /* This case means a common symbol which was turned
3879 into a defined symbol. */
53155af1
ILT
3880 input_section = hresolve->root.u.def.section;
3881 output_section = input_section->output_section;
4c3721d5
ILT
3882 BFD_ASSERT (output_section == &bfd_abs_section
3883 || output_section->owner == output_bfd);
53155af1 3884 val = (hresolve->root.u.def.value
4c3721d5 3885 + bfd_get_section_vma (output_bfd, output_section)
53155af1 3886 + input_section->output_offset);
4c3721d5
ILT
3887
3888 /* Get the correct type based on the section. If
3889 this is a constructed set, force it to be
3890 globally visible. */
3891 if (type == N_SETT
3892 || type == N_SETD
3893 || type == N_SETB
3894 || type == N_SETA)
3895 type |= N_EXT;
3896
3897 type &=~ N_TYPE;
3898
3899 if (output_section == obj_textsec (output_bfd))
3900 type |= N_TEXT;
3901 else if (output_section == obj_datasec (output_bfd))
3902 type |= N_DATA;
3903 else if (output_section == obj_bsssec (output_bfd))
3904 type |= N_BSS;
3905 else
3906 type |= N_ABS;
3907 }
53155af1
ILT
3908 else if (hresolve->root.type == bfd_link_hash_common)
3909 val = hresolve->root.u.c.size;
4c3721d5
ILT
3910 else
3911 val = 0;
3912
3913 symsec = NULL;
3914 }
3915 if (symsec != (asection *) NULL)
3916 val = (symsec->output_section->vma
3917 + symsec->output_offset
3918 + (GET_WORD (input_bfd, sym->e_value)
3919 - symsec->vma));
3920
3921 /* If this is a global symbol set the written flag, and if
3922 it is a local symbol see if we should discard it. */
3923 if (h != (struct aout_link_hash_entry *) NULL)
3924 {
3925 h->root.written = true;
3926 h->indx = obj_aout_external_sym_count (output_bfd);
3927 }
3928 else
3929 {
3930 switch (discard)
3931 {
3932 case discard_none:
3933 break;
3934 case discard_l:
3935 if (*name == *finfo->info->lprefix
3936 && (finfo->info->lprefix_len == 1
3937 || strncmp (name, finfo->info->lprefix,
3938 finfo->info->lprefix_len) == 0))
3939 skip = true;
3940 break;
3941 case discard_all:
3942 skip = true;
3943 break;
3944 }
3945 if (skip)
3946 {
3947 pass = false;
3948 continue;
3949 }
3950 }
3951 }
3952
3953 /* Copy this symbol into the list of symbols we are going to
3954 write out. */
3955 bfd_h_put_8 (output_bfd, type, outsym->e_type);
3956 bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other),
3957 outsym->e_other);
3958 bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc),
3959 outsym->e_desc);
d6d6b18a
ILT
3960 if (! finfo->info->keep_memory)
3961 {
3962 /* name points into a string table which we are going to
3963 free. If there is a hash table entry, use that string.
3964 Otherwise, copy name into memory. */
3965 if (h != (struct aout_link_hash_entry *) NULL)
3966 name = (*sym_hash)->root.root.string;
3967 else
3968 {
3969 char *n;
3970
3971 n = bfd_alloc (output_bfd, strlen (name) + 1);
3972 strcpy (n, name);
3973 name = n;
3974 }
3975 }
4c3721d5
ILT
3976 PUT_WORD (output_bfd,
3977 add_to_stringtab (output_bfd, name, &finfo->strtab),
3978 outsym->e_strx);
3979 PUT_WORD (output_bfd, val, outsym->e_value);
3980 *symbol_map = obj_aout_external_sym_count (output_bfd);
3981 ++obj_aout_external_sym_count (output_bfd);
3982 ++outsym;
3983 }
3984
3985 /* Write out the output symbols we have just constructed. */
3986 if (outsym > output_syms)
3987 {
3988 bfd_size_type outsym_count;
3989
3990 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
80425e6c 3991 goto error_return;
4c3721d5
ILT
3992 outsym_count = outsym - output_syms;
3993 if (bfd_write ((PTR) output_syms, (bfd_size_type) EXTERNAL_NLIST_SIZE,
3994 (bfd_size_type) outsym_count, output_bfd)
3995 != outsym_count * EXTERNAL_NLIST_SIZE)
80425e6c 3996 goto error_return;
4c3721d5
ILT
3997 finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
3998 }
3999
80425e6c
JK
4000 if (output_syms != NULL)
4001 free (output_syms);
4c3721d5 4002 return true;
80425e6c
JK
4003 error_return:
4004 if (output_syms != NULL)
4005 free (output_syms);
4006 return false;
4c3721d5
ILT
4007}
4008
4009/* Write out a symbol that was not associated with an a.out input
4010 object. */
4011
4012static boolean
4013aout_link_write_other_symbol (h, data)
4014 struct aout_link_hash_entry *h;
4015 PTR data;
4016{
4017 struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
4018 bfd *output_bfd;
4019 int type;
4020 bfd_vma val;
4021 struct external_nlist outsym;
4022
4023 if (h->root.written)
4024 return true;
4025
9783e04a
DM
4026 h->root.written = true;
4027
4028 if (finfo->info->strip == strip_all
4029 || (finfo->info->strip == strip_some
4030 && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
4031 false, false) == NULL))
4032 return true;
4033
4c3721d5
ILT
4034 output_bfd = finfo->output_bfd;
4035
4036 switch (h->root.type)
4037 {
4038 default:
4039 case bfd_link_hash_new:
4040 abort ();
4041 /* Avoid variable not initialized warnings. */
4042 return true;
4043 case bfd_link_hash_undefined:
4044 type = N_UNDF | N_EXT;
4045 val = 0;
4046 break;
4047 case bfd_link_hash_defined:
4048 {
4049 asection *sec;
4050
4051 sec = h->root.u.def.section;
4052 BFD_ASSERT (sec == &bfd_abs_section
4053 || sec->owner == output_bfd);
4054 if (sec == obj_textsec (output_bfd))
4055 type = N_TEXT | N_EXT;
4056 else if (sec == obj_datasec (output_bfd))
4057 type = N_DATA | N_EXT;
4058 else if (sec == obj_bsssec (output_bfd))
4059 type = N_BSS | N_EXT;
4060 else
4061 type = N_ABS | N_EXT;
4062 val = (h->root.u.def.value
4063 + sec->output_section->vma
4064 + sec->output_offset);
4065 }
4066 break;
4067 case bfd_link_hash_common:
4068 type = N_UNDF | N_EXT;
4069 val = h->root.u.c.size;
4070 break;
4071 case bfd_link_hash_indirect:
4072 case bfd_link_hash_warning:
4073 /* FIXME: Ignore these for now. The circumstances under which
4074 they should be written out are not clear to me. */
4075 return true;
4076 }
4077
4078 bfd_h_put_8 (output_bfd, type, outsym.e_type);
4079 bfd_h_put_8 (output_bfd, 0, outsym.e_other);
4080 bfd_h_put_16 (output_bfd, 0, outsym.e_desc);
4081 PUT_WORD (output_bfd,
4082 add_to_stringtab (output_bfd, h->root.root.string, &finfo->strtab),
4083 outsym.e_strx);
4084 PUT_WORD (output_bfd, val, outsym.e_value);
4085
4086 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
4087 || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE,
4088 (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE)
4089 {
4090 /* FIXME: No way to handle errors. */
4091 abort ();
4092 }
4093
4094 finfo->symoff += EXTERNAL_NLIST_SIZE;
4095 h->indx = obj_aout_external_sym_count (output_bfd);
4096 ++obj_aout_external_sym_count (output_bfd);
4097
4098 return true;
4099}
4100
4101/* Link an a.out section into the output file. */
4102
4103static boolean
4104aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
4105 rel_size, symbol_map)
4106 struct aout_final_link_info *finfo;
4107 bfd *input_bfd;
4108 asection *input_section;
4109 file_ptr *reloff_ptr;
4110 bfd_size_type rel_size;
4111 int *symbol_map;
4112{
4113 bfd_size_type input_size;
80425e6c
JK
4114 bfd_byte *contents = NULL;
4115 PTR relocs = NULL;
4c3721d5
ILT
4116
4117 /* Get the section contents. */
4118 input_size = bfd_section_size (input_bfd, input_section);
80425e6c 4119 contents = (bfd_byte *) malloc (input_size);
8eb5d4be 4120 if (contents == NULL && input_size != 0)
80425e6c
JK
4121 {
4122 bfd_set_error (bfd_error_no_memory);
4123 goto error_return;
4124 }
728472f1 4125 if (! bfd_get_section_contents (input_bfd, input_section, (PTR) contents,
4c3721d5 4126 (file_ptr) 0, input_size))
80425e6c 4127 goto error_return;
4c3721d5
ILT
4128
4129 /* Read in the relocs. */
80425e6c 4130 relocs = (PTR) malloc (rel_size);
8eb5d4be 4131 if (relocs == NULL && rel_size != 0)
80425e6c
JK
4132 {
4133 bfd_set_error (bfd_error_no_memory);
4134 goto error_return;
4135 }
4c3721d5
ILT
4136 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
4137 || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
80425e6c 4138 goto error_return;
4c3721d5
ILT
4139
4140 /* Relocate the section contents. */
4141 if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4142 {
4143 if (! aout_link_input_section_std (finfo, input_bfd, input_section,
4144 (struct reloc_std_external *) relocs,
4145 rel_size, contents, symbol_map))
80425e6c 4146 goto error_return;
4c3721d5
ILT
4147 }
4148 else
4149 {
4150 if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
4151 (struct reloc_ext_external *) relocs,
4152 rel_size, contents, symbol_map))
5c8444f8 4153 goto error_return;
4c3721d5
ILT
4154 }
4155
4156 /* Write out the section contents. */
4157 if (! bfd_set_section_contents (finfo->output_bfd,
4158 input_section->output_section,
728472f1
ILT
4159 (PTR) contents,
4160 input_section->output_offset,
4c3721d5 4161 input_size))
80425e6c 4162 goto error_return;
4c3721d5
ILT
4163
4164 /* If we are producing relocateable output, the relocs were
4165 modified, and we now write them out. */
4166 if (finfo->info->relocateable)
4167 {
4168 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
80425e6c 4169 goto error_return;
4c3721d5
ILT
4170 if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
4171 != rel_size)
80425e6c 4172 goto error_return;
4c3721d5
ILT
4173 *reloff_ptr += rel_size;
4174
4175 /* Assert that the relocs have not run into the symbols, and
4176 that if these are the text relocs they have not run into the
4177 data relocs. */
4178 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
4179 && (reloff_ptr != &finfo->treloff
4180 || (*reloff_ptr
4181 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
4182 }
4183
80425e6c
JK
4184 if (relocs != NULL)
4185 free (relocs);
4186 if (contents != NULL)
4187 free (contents);
4c3721d5 4188 return true;
80425e6c
JK
4189 error_return:
4190 if (relocs != NULL)
4191 free (relocs);
4192 if (contents != NULL)
4193 free (contents);
4194 return false;
4c3721d5
ILT
4195}
4196
4197/* Get the section corresponding to a reloc index. */
4198
4199static INLINE asection *
4200aout_reloc_index_to_section (abfd, indx)
4201 bfd *abfd;
4202 int indx;
4203{
4204 switch (indx & N_TYPE)
4205 {
4206 case N_TEXT:
4207 return obj_textsec (abfd);
4208 case N_DATA:
4209 return obj_datasec (abfd);
4210 case N_BSS:
4211 return obj_bsssec (abfd);
4212 case N_ABS:
fa2302b8 4213 case N_UNDF:
4c3721d5
ILT
4214 return &bfd_abs_section;
4215 default:
4216 abort ();
4217 }
4218}
4219
4220/* Relocate an a.out section using standard a.out relocs. */
4221
4222static boolean
4223aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
4224 rel_size, contents, symbol_map)
4225 struct aout_final_link_info *finfo;
4226 bfd *input_bfd;
4227 asection *input_section;
4228 struct reloc_std_external *relocs;
4229 bfd_size_type rel_size;
4230 bfd_byte *contents;
4231 int *symbol_map;
4232{
4233 bfd *output_bfd;
4234 boolean relocateable;
4235 struct external_nlist *syms;
4236 char *strings;
4237 struct aout_link_hash_entry **sym_hashes;
4238 bfd_size_type reloc_count;
4239 register struct reloc_std_external *rel;
4240 struct reloc_std_external *rel_end;
4241
4242 output_bfd = finfo->output_bfd;
4243
4244 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
4245 BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
4246 == output_bfd->xvec->header_byteorder_big_p);
4247
4248 relocateable = finfo->info->relocateable;
4249 syms = obj_aout_external_syms (input_bfd);
4250 strings = obj_aout_external_strings (input_bfd);
4251 sym_hashes = obj_aout_sym_hashes (input_bfd);
4252
4253 reloc_count = rel_size / RELOC_STD_SIZE;
4254 rel = relocs;
4255 rel_end = rel + reloc_count;
4256 for (; rel < rel_end; rel++)
4257 {
4258 bfd_vma r_addr;
4259 int r_index;
4260 int r_extern;
4261 int r_pcrel;
4262 int r_baserel;
4263 int r_jmptable;
4264 int r_relative;
4265 int r_length;
4266 int howto_idx;
4267 bfd_vma relocation;
4268 bfd_reloc_status_type r;
4269
4270 r_addr = GET_SWORD (input_bfd, rel->r_address);
4271
4272 if (input_bfd->xvec->header_byteorder_big_p)
4273 {
4274 r_index = ((rel->r_index[0] << 16)
4275 | (rel->r_index[1] << 8)
4276 | rel->r_index[2]);
4277 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
4278 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
4279 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
4280 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
4281 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
4282 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
4283 >> RELOC_STD_BITS_LENGTH_SH_BIG);
4284 }
4285 else
4286 {
4287 r_index = ((rel->r_index[2] << 16)
4288 | (rel->r_index[1] << 8)
4289 | rel->r_index[0]);
4290 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
4291 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
4292 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
4293 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
4294 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
4295 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
4296 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
4297 }
4298
4299 howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel;
4300 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
4301 BFD_ASSERT (r_jmptable == 0);
4302 BFD_ASSERT (r_relative == 0);
4303
4304 if (relocateable)
4305 {
4306 /* We are generating a relocateable output file, and must
4307 modify the reloc accordingly. */
4308 if (r_extern)
4309 {
4310 struct aout_link_hash_entry *h;
4311
4312 /* If we know the symbol this relocation is against,
4313 convert it into a relocation against a section. This
4314 is what the native linker does. */
4315 h = sym_hashes[r_index];
4316 if (h != (struct aout_link_hash_entry *) NULL
4317 && h->root.type == bfd_link_hash_defined)
4318 {
4319 asection *output_section;
4320
4321 /* Change the r_extern value. */
4322 if (output_bfd->xvec->header_byteorder_big_p)
4323 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
4324 else
4325 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
4326
4327 /* Compute a new r_index. */
4328 output_section = h->root.u.def.section->output_section;
4329 if (output_section == obj_textsec (output_bfd))
4330 r_index = N_TEXT;
4331 else if (output_section == obj_datasec (output_bfd))
4332 r_index = N_DATA;
4333 else if (output_section == obj_bsssec (output_bfd))
4334 r_index = N_BSS;
4335 else
4336 r_index = N_ABS;
4337
4338 /* Add the symbol value and the section VMA to the
4339 addend stored in the contents. */
4340 relocation = (h->root.u.def.value
4341 + output_section->vma
4342 + h->root.u.def.section->output_offset);
4343 }
4344 else
4345 {
4346 /* We must change r_index according to the symbol
4347 map. */
4348 r_index = symbol_map[r_index];
4349
4350 if (r_index == -1)
4351 {
4352 const char *name;
4353
4354 name = strings + GET_WORD (input_bfd,
4355 syms[r_index].e_strx);
4356 if (! ((*finfo->info->callbacks->unattached_reloc)
4357 (finfo->info, name, input_bfd, input_section,
4358 r_addr)))
4359 return false;
4360 r_index = 0;
4361 }
4362
4363 relocation = 0;
4364 }
4365
4366 /* Write out the new r_index value. */
4367 if (output_bfd->xvec->header_byteorder_big_p)
4368 {
4369 rel->r_index[0] = r_index >> 16;
4370 rel->r_index[1] = r_index >> 8;
4371 rel->r_index[2] = r_index;
4372 }
4373 else
4374 {
4375 rel->r_index[2] = r_index >> 16;
4376 rel->r_index[1] = r_index >> 8;
4377 rel->r_index[0] = r_index;
4378 }
4379 }
4380 else
4381 {
4382 asection *section;
4383
4384 /* This is a relocation against a section. We must
4385 adjust by the amount that the section moved. */
4386 section = aout_reloc_index_to_section (input_bfd, r_index);
4387 relocation = (section->output_section->vma
4388 + section->output_offset
4389 - section->vma);
4390 }
4391
4392 /* Change the address of the relocation. */
4393 PUT_WORD (output_bfd,
4394 r_addr + input_section->output_offset,
4395 rel->r_address);
4396
4397 /* Adjust a PC relative relocation by removing the reference
e68de5d5
ILT
4398 to the original address in the section and including the
4399 reference to the new address. */
4c3721d5 4400 if (r_pcrel)
e68de5d5
ILT
4401 relocation -= (input_section->output_section->vma
4402 + input_section->output_offset
4403 - input_section->vma);
4c3721d5
ILT
4404
4405 if (relocation == 0)
4406 r = bfd_reloc_ok;
4407 else
4408 r = _bfd_relocate_contents (howto_table_std + howto_idx,
4409 input_bfd, relocation,
4410 contents + r_addr);
4411 }
4412 else
4413 {
4414 /* We are generating an executable, and must do a full
4415 relocation. */
4416 if (r_extern)
4417 {
4418 struct aout_link_hash_entry *h;
4419
4420 h = sym_hashes[r_index];
4421 if (h != (struct aout_link_hash_entry *) NULL
4422 && h->root.type == bfd_link_hash_defined)
4423 {
4424 relocation = (h->root.u.def.value
4425 + h->root.u.def.section->output_section->vma
4426 + h->root.u.def.section->output_offset);
4427 }
4428 else
4429 {
4430 const char *name;
4431
4432 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4433 if (! ((*finfo->info->callbacks->undefined_symbol)
4434 (finfo->info, name, input_bfd, input_section,
4435 r_addr)))
4436 return false;
4437 relocation = 0;
4438 }
4439 }
4440 else
4441 {
4442 asection *section;
4443
4444 section = aout_reloc_index_to_section (input_bfd, r_index);
4445 relocation = (section->output_section->vma
4446 + section->output_offset
4447 - section->vma);
e68de5d5
ILT
4448 if (r_pcrel)
4449 relocation += input_section->vma;
4c3721d5
ILT
4450 }
4451
4c3721d5
ILT
4452 r = _bfd_final_link_relocate (howto_table_std + howto_idx,
4453 input_bfd, input_section,
4454 contents, r_addr, relocation,
4455 (bfd_vma) 0);
4456 }
4457
4458 if (r != bfd_reloc_ok)
4459 {
4460 switch (r)
4461 {
4462 default:
4463 case bfd_reloc_outofrange:
4464 abort ();
4465 case bfd_reloc_overflow:
4991ebb9
ILT
4466 {
4467 const char *name;
4468
4469 if (r_extern)
4470 name = strings + GET_WORD (input_bfd,
4471 syms[r_index].e_strx);
4472 else
4473 {
4474 asection *s;
4475
4476 s = aout_reloc_index_to_section (input_bfd, r_index);
4477 name = bfd_section_name (input_bfd, s);
4478 }
4479 if (! ((*finfo->info->callbacks->reloc_overflow)
4480 (finfo->info, name, howto_table_std[howto_idx].name,
4481 (bfd_vma) 0, input_bfd, input_section, r_addr)))
4482 return false;
4483 }
4c3721d5
ILT
4484 break;
4485 }
4486 }
4487 }
4488
4489 return true;
4490}
4491
4492/* Relocate an a.out section using extended a.out relocs. */
4493
4494static boolean
4495aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
4496 rel_size, contents, symbol_map)
4497 struct aout_final_link_info *finfo;
4498 bfd *input_bfd;
4499 asection *input_section;
4500 struct reloc_ext_external *relocs;
4501 bfd_size_type rel_size;
4502 bfd_byte *contents;
4503 int *symbol_map;
4504{
4505 bfd *output_bfd;
4506 boolean relocateable;
4507 struct external_nlist *syms;
4508 char *strings;
4509 struct aout_link_hash_entry **sym_hashes;
4510 bfd_size_type reloc_count;
4511 register struct reloc_ext_external *rel;
4512 struct reloc_ext_external *rel_end;
4513
4514 output_bfd = finfo->output_bfd;
4515
4516 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
4517 BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
4518 == output_bfd->xvec->header_byteorder_big_p);
4519
4520 relocateable = finfo->info->relocateable;
4521 syms = obj_aout_external_syms (input_bfd);
4522 strings = obj_aout_external_strings (input_bfd);
4523 sym_hashes = obj_aout_sym_hashes (input_bfd);
4524
4525 reloc_count = rel_size / RELOC_EXT_SIZE;
4526 rel = relocs;
4527 rel_end = rel + reloc_count;
4528 for (; rel < rel_end; rel++)
4529 {
4530 bfd_vma r_addr;
4531 int r_index;
4532 int r_extern;
4533 int r_type;
4534 bfd_vma r_addend;
4535 bfd_vma relocation;
4536
4537 r_addr = GET_SWORD (input_bfd, rel->r_address);
4538
4539 if (input_bfd->xvec->header_byteorder_big_p)
4540 {
4541 r_index = ((rel->r_index[0] << 16)
4542 | (rel->r_index[1] << 8)
4543 | rel->r_index[2]);
4544 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
4545 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
4546 >> RELOC_EXT_BITS_TYPE_SH_BIG);
4547 }
4548 else
4549 {
4550 r_index = ((rel->r_index[2] << 16)
4551 | (rel->r_index[1] << 8)
4552 | rel->r_index[0]);
4553 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
4554 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
4555 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
4556 }
4557
4558 r_addend = GET_SWORD (input_bfd, rel->r_addend);
4559
e68de5d5
ILT
4560 BFD_ASSERT (r_type >= 0
4561 && r_type < TABLE_SIZE (howto_table_ext));
4562
4c3721d5
ILT
4563 if (relocateable)
4564 {
4565 /* We are generating a relocateable output file, and must
4566 modify the reloc accordingly. */
4567 if (r_extern)
4568 {
4569 struct aout_link_hash_entry *h;
4570
4571 /* If we know the symbol this relocation is against,
4572 convert it into a relocation against a section. This
4573 is what the native linker does. */
4574 h = sym_hashes[r_index];
4575 if (h != (struct aout_link_hash_entry *) NULL
4576 && h->root.type == bfd_link_hash_defined)
4577 {
4578 asection *output_section;
4579
4580 /* Change the r_extern value. */
4581 if (output_bfd->xvec->header_byteorder_big_p)
4582 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
4583 else
4584 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
4585
4586 /* Compute a new r_index. */
4587 output_section = h->root.u.def.section->output_section;
4588 if (output_section == obj_textsec (output_bfd))
4589 r_index = N_TEXT;
4590 else if (output_section == obj_datasec (output_bfd))
4591 r_index = N_DATA;
4592 else if (output_section == obj_bsssec (output_bfd))
4593 r_index = N_BSS;
4594 else
4595 r_index = N_ABS;
4596
4597 /* Add the symbol value and the section VMA to the
4598 addend. */
4599 relocation = (h->root.u.def.value
4600 + output_section->vma
4601 + h->root.u.def.section->output_offset);
e68de5d5
ILT
4602
4603 /* Now RELOCATION is the VMA of the final
4604 destination. If this is a PC relative reloc,
4605 then ADDEND is the negative of the source VMA.
4606 We want to set ADDEND to the difference between
4607 the destination VMA and the source VMA, which
4608 means we must adjust RELOCATION by the change in
4609 the source VMA. This is done below. */
4c3721d5
ILT
4610 }
4611 else
4612 {
4613 /* We must change r_index according to the symbol
4614 map. */
4615 r_index = symbol_map[r_index];
4616
4617 if (r_index == -1)
4618 {
4619 const char *name;
4620
4621 name = (strings
4622 + GET_WORD (input_bfd, syms[r_index].e_strx));
4623 if (! ((*finfo->info->callbacks->unattached_reloc)
4624 (finfo->info, name, input_bfd, input_section,
4625 r_addr)))
4626 return false;
4627 r_index = 0;
4628 }
4629
4630 relocation = 0;
e68de5d5
ILT
4631
4632 /* If this is a PC relative reloc, then the addend
4633 is the negative of the source VMA. We must
4634 adjust it by the change in the source VMA. This
4635 is done below. */
4c3721d5
ILT
4636 }
4637
4638 /* Write out the new r_index value. */
4639 if (output_bfd->xvec->header_byteorder_big_p)
4640 {
4641 rel->r_index[0] = r_index >> 16;
4642 rel->r_index[1] = r_index >> 8;
4643 rel->r_index[2] = r_index;
4644 }
4645 else
4646 {
4647 rel->r_index[2] = r_index >> 16;
4648 rel->r_index[1] = r_index >> 8;
4649 rel->r_index[0] = r_index;
4650 }
4651 }
4652 else
4653 {
4654 asection *section;
4655
4656 /* This is a relocation against a section. We must
4657 adjust by the amount that the section moved. */
4658 section = aout_reloc_index_to_section (input_bfd, r_index);
4659 relocation = (section->output_section->vma
4660 + section->output_offset
4661 - section->vma);
4c3721d5 4662
e68de5d5
ILT
4663 /* If this is a PC relative reloc, then the addend is
4664 the difference in VMA between the destination and the
4665 source. We have just adjusted for the change in VMA
4666 of the destination, so we must also adjust by the
4667 change in VMA of the source. This is done below. */
4c3721d5
ILT
4668 }
4669
e68de5d5
ILT
4670 /* As described above, we must always adjust a PC relative
4671 reloc by the change in VMA of the source. */
4672 if (howto_table_ext[r_type].pc_relative)
4673 relocation -= (input_section->output_section->vma
4674 + input_section->output_offset
4675 - input_section->vma);
4676
4c3721d5
ILT
4677 /* Change the addend if necessary. */
4678 if (relocation != 0)
4679 PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
4680
4681 /* Change the address of the relocation. */
4682 PUT_WORD (output_bfd,
4683 r_addr + input_section->output_offset,
4684 rel->r_address);
4685 }
4686 else
4687 {
4688 bfd_reloc_status_type r;
4689
4690 /* We are generating an executable, and must do a full
4691 relocation. */
4692 if (r_extern)
4693 {
4694 struct aout_link_hash_entry *h;
4695
4696 h = sym_hashes[r_index];
4697 if (h != (struct aout_link_hash_entry *) NULL
4698 && h->root.type == bfd_link_hash_defined)
4699 {
4700 relocation = (h->root.u.def.value
4701 + h->root.u.def.section->output_section->vma
4702 + h->root.u.def.section->output_offset);
4703 }
4704 else
4705 {
4706 const char *name;
4707
4708 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4709 if (! ((*finfo->info->callbacks->undefined_symbol)
4710 (finfo->info, name, input_bfd, input_section,
4711 r_addr)))
4712 return false;
4713 relocation = 0;
4714 }
4715 }
4716 else
4717 {
4718 asection *section;
4719
4720 section = aout_reloc_index_to_section (input_bfd, r_index);
e68de5d5
ILT
4721
4722 /* If this is a PC relative reloc, then R_ADDEND is the
4723 difference between the two vmas, or
4724 old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
4725 where
4726 old_dest_sec == section->vma
4727 and
4728 old_src_sec == input_section->vma
4729 and
4730 old_src_off == r_addr
4731
4732 _bfd_final_link_relocate expects RELOCATION +
4733 R_ADDEND to be the VMA of the destination minus
4734 r_addr (the minus r_addr is because this relocation
4735 is not pcrel_offset, which is a bit confusing and
4736 should, perhaps, be changed), or
4737 new_dest_sec
4738 where
4739 new_dest_sec == output_section->vma + output_offset
4740 We arrange for this to happen by setting RELOCATION to
4741 new_dest_sec + old_src_sec - old_dest_sec
4742
4743 If this is not a PC relative reloc, then R_ADDEND is
4744 simply the VMA of the destination, so we set
4745 RELOCATION to the change in the destination VMA, or
4746 new_dest_sec - old_dest_sec
4747 */
4c3721d5
ILT
4748 relocation = (section->output_section->vma
4749 + section->output_offset
4750 - section->vma);
e68de5d5
ILT
4751 if (howto_table_ext[r_type].pc_relative)
4752 relocation += input_section->vma;
4c3721d5
ILT
4753 }
4754
4c3721d5
ILT
4755 r = _bfd_final_link_relocate (howto_table_ext + r_type,
4756 input_bfd, input_section,
4757 contents, r_addr, relocation,
4758 r_addend);
4759 if (r != bfd_reloc_ok)
4760 {
4761 switch (r)
4762 {
4763 default:
4764 case bfd_reloc_outofrange:
4765 abort ();
4766 case bfd_reloc_overflow:
4991ebb9
ILT
4767 {
4768 const char *name;
4769
4770 if (r_extern)
4771 name = strings + GET_WORD (input_bfd,
4772 syms[r_index].e_strx);
4773 else
4774 {
4775 asection *s;
4776
4777 s = aout_reloc_index_to_section (input_bfd, r_index);
4778 name = bfd_section_name (input_bfd, s);
4779 }
4780 if (! ((*finfo->info->callbacks->reloc_overflow)
4781 (finfo->info, name, howto_table_ext[r_type].name,
4782 r_addend, input_bfd, input_section, r_addr)))
4783 return false;
4784 }
4c3721d5
ILT
4785 break;
4786 }
4787 }
4788 }
4789 }
4790
4791 return true;
4792}
ec099b4b
ILT
4793
4794/* Handle a link order which is supposed to generate a reloc. */
4795
4796static boolean
4797aout_link_reloc_link_order (finfo, o, p)
4798 struct aout_final_link_info *finfo;
4799 asection *o;
4800 struct bfd_link_order *p;
4801{
4802 struct bfd_link_order_reloc *pr;
4803 int r_index;
4804 int r_extern;
4805 const reloc_howto_type *howto;
4806 file_ptr *reloff_ptr;
4807 struct reloc_std_external srel;
4808 struct reloc_ext_external erel;
4809 PTR rel_ptr;
4810
4811 pr = p->u.reloc.p;
4812
4813 if (p->type == bfd_section_reloc_link_order)
4814 {
4815 r_extern = 0;
4816 if (pr->u.section == &bfd_abs_section)
4817 r_index = N_ABS | N_EXT;
4818 else
4819 {
4820 BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
4821 r_index = pr->u.section->target_index;
4822 }
4823 }
4824 else
4825 {
4826 struct aout_link_hash_entry *h;
4827
4828 BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
4829 r_extern = 1;
4830 h = aout_link_hash_lookup (aout_hash_table (finfo->info),
4831 pr->u.name, false, false, true);
4832 if (h != (struct aout_link_hash_entry *) NULL
4833 && h->indx == -1)
4834 r_index = h->indx;
4835 else
4836 {
4837 if (! ((*finfo->info->callbacks->unattached_reloc)
4838 (finfo->info, pr->u.name, (bfd *) NULL,
4839 (asection *) NULL, (bfd_vma) 0)))
4840 return false;
4841 r_index = 0;
4842 }
4843 }
4844
4845 howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
4846 if (howto == (const reloc_howto_type *) NULL)
4847 {
4848 bfd_set_error (bfd_error_bad_value);
4849 return false;
4850 }
4851
4852 if (o == obj_textsec (finfo->output_bfd))
4853 reloff_ptr = &finfo->treloff;
4854 else if (o == obj_datasec (finfo->output_bfd))
4855 reloff_ptr = &finfo->dreloff;
4856 else
4857 abort ();
4858
4859 if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
4860 {
4861 int r_pcrel;
4862 int r_baserel;
4863 int r_jmptable;
4864 int r_relative;
4865 int r_length;
4866
4867 r_pcrel = howto->pc_relative;
4868 r_baserel = (howto->type & 8) != 0;
4869 r_jmptable = 0;
4870 r_relative = 0;
4871 r_length = howto->size;
4872
4873 PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
4874 if (finfo->output_bfd->xvec->header_byteorder_big_p)
4875 {
4876 srel.r_index[0] = r_index >> 16;
4877 srel.r_index[1] = r_index >> 8;
4878 srel.r_index[2] = r_index;
4879 srel.r_type[0] =
4880 ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
4881 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
4882 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
4883 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
4884 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
4885 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
4886 }
4887 else
4888 {
4889 srel.r_index[2] = r_index >> 16;
4890 srel.r_index[1] = r_index >> 8;
4891 srel.r_index[0] = r_index;
4892 srel.r_type[0] =
4893 ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
4894 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
4895 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
4896 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
4897 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
4898 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
4899 }
4900
4901 rel_ptr = (PTR) &srel;
4902
4903 /* We have to write the addend into the object file, since
4904 standard a.out relocs are in place. It would be more
4905 reliable if we had the current contents of the file here,
4906 rather than assuming zeroes, but we can't read the file since
4907 it was opened using bfd_openw. */
4908 if (pr->addend != 0)
4909 {
4910 bfd_size_type size;
4911 bfd_reloc_status_type r;
4912 bfd_byte *buf;
4913 boolean ok;
4914
4915 size = bfd_get_reloc_size (howto);
4916 buf = (bfd_byte*) bfd_zmalloc (size);
4917 if (buf == (bfd_byte *) NULL)
4918 {
4919 bfd_set_error (bfd_error_no_memory);
4920 return false;
4921 }
4922 r = _bfd_relocate_contents (howto, finfo->output_bfd,
4923 pr->addend, buf);
4924 switch (r)
4925 {
4926 case bfd_reloc_ok:
4927 break;
4928 default:
4929 case bfd_reloc_outofrange:
4930 abort ();
4931 case bfd_reloc_overflow:
4932 if (! ((*finfo->info->callbacks->reloc_overflow)
4933 (finfo->info,
4934 (p->type == bfd_section_reloc_link_order
4935 ? bfd_section_name (finfo->output_bfd,
4936 pr->u.section)
4937 : pr->u.name),
4938 howto->name, pr->addend, (bfd *) NULL,
4939 (asection *) NULL, (bfd_vma) 0)))
4940 {
4941 free (buf);
4942 return false;
4943 }
4944 break;
4945 }
4946 ok = bfd_set_section_contents (finfo->output_bfd, o,
4947 (PTR) buf,
4948 (file_ptr) p->offset,
4949 size);
4950 free (buf);
4951 if (! ok)
4952 return false;
4953 }
4954 }
4955 else
4956 {
4957 PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
4958
4959 if (finfo->output_bfd->xvec->header_byteorder_big_p)
4960 {
4961 erel.r_index[0] = r_index >> 16;
4962 erel.r_index[1] = r_index >> 8;
4963 erel.r_index[2] = r_index;
4964 erel.r_type[0] =
4965 ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
4966 | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
4967 }
4968 else
4969 {
4970 erel.r_index[2] = r_index >> 16;
4971 erel.r_index[1] = r_index >> 8;
4972 erel.r_index[0] = r_index;
4973 erel.r_type[0] =
4974 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
4975 | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
4976 }
4977
4978 PUT_WORD (finfo->output_bfd, pr->addend, erel.r_addend);
4979
4980 rel_ptr = (PTR) &erel;
4981 }
4982
4983 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
4984 || (bfd_write (rel_ptr, (bfd_size_type) 1,
4985 obj_reloc_entry_size (finfo->output_bfd),
4986 finfo->output_bfd)
4987 != obj_reloc_entry_size (finfo->output_bfd)))
4988 return false;
4989
4990 *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
4991
4992 /* Assert that the relocs have not run into the symbols, and that n
4993 the text relocs have not run into the data relocs. */
4994 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
4995 && (reloff_ptr != &finfo->treloff
4996 || (*reloff_ptr
4997 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
4998
4999 return true;
5000}
This page took 0.361562 seconds and 4 git commands to generate.