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