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