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