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