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