*** empty log message ***
[deliverable/binutils-gdb.git] / bfd / aoutx.h
CommitLineData
252b5132 1/* BFD semi-generic back-end for a.out binaries.
7898deda 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
e92d460e 3 2001, 2002
252b5132
RH
4 Free Software Foundation, Inc.
5 Written by Cygnus Support.
6
f7c33884 7 This file is part of BFD, the Binary File Descriptor library.
252b5132 8
f7c33884
NC
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
252b5132 13
f7c33884
NC
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
252b5132 18
f7c33884
NC
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
252b5132
RH
22
23/*
24SECTION
25 a.out backends
26
252b5132
RH
27DESCRIPTION
28
29 BFD supports a number of different flavours of a.out format,
30 though the major differences are only the sizes of the
31 structures on disk, and the shape of the relocation
32 information.
33
34 The support is split into a basic support file @file{aoutx.h}
35 and other files which derive functions from the base. One
36 derivation file is @file{aoutf1.h} (for a.out flavour 1), and
37 adds to the basic a.out functions support for sun3, sun4, 386
38 and 29k a.out files, to create a target jump vector for a
39 specific target.
40
41 This information is further split out into more specific files
42 for each machine, including @file{sunos.c} for sun3 and sun4,
43 @file{newsos3.c} for the Sony NEWS, and @file{demo64.c} for a
44 demonstration of a 64 bit a.out format.
45
46 The base file @file{aoutx.h} defines general mechanisms for
47 reading and writing records to and from disk and various
48 other methods which BFD requires. It is included by
49 @file{aout32.c} and @file{aout64.c} to form the names
50 <<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc.
51
52 As an example, this is what goes on to make the back end for a
53 sun4, from @file{aout32.c}:
54
55| #define ARCH_SIZE 32
56| #include "aoutx.h"
57
58 Which exports names:
59
60| ...
61| aout_32_canonicalize_reloc
62| aout_32_find_nearest_line
63| aout_32_get_lineno
64| aout_32_get_reloc_upper_bound
65| ...
66
67 from @file{sunos.c}:
68
69| #define TARGET_NAME "a.out-sunos-big"
70| #define VECNAME sunos_big_vec
71| #include "aoutf1.h"
72
73 requires all the names from @file{aout32.c}, and produces the jump vector
74
75| sunos_big_vec
76
77 The file @file{host-aout.c} is a special case. It is for a large set
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
85 the object file.
86
87 When porting it to run on a new system, you must supply:
88
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
95
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
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
100 to use @file{host-aout.c}, specify:
101
102| TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
103| TDEPFILES= host-aout.o trad-core.o
104
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
108 configuration is selected.
109
110*/
111
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
121#define KEEPIT udata.i
122
252b5132
RH
123#include "bfd.h"
124#include "sysdep.h"
3882b010 125#include "safe-ctype.h"
252b5132
RH
126#include "bfdlink.h"
127
128#include "libaout.h"
129#include "libbfd.h"
130#include "aout/aout64.h"
131#include "aout/stab_gnu.h"
132#include "aout/ar.h"
133
134static boolean aout_get_external_symbols PARAMS ((bfd *));
135static boolean translate_from_native_sym_flags
136 PARAMS ((bfd *, aout_symbol_type *));
137static boolean translate_to_native_sym_flags
138 PARAMS ((bfd *, asymbol *, struct external_nlist *));
139static void adjust_o_magic PARAMS ((bfd *, struct internal_exec *));
140static void adjust_z_magic PARAMS ((bfd *, struct internal_exec *));
141static void adjust_n_magic PARAMS ((bfd *, struct internal_exec *));
923f08ff
AM
142reloc_howto_type * NAME(aout,reloc_type_lookup)
143 PARAMS ((bfd *, bfd_reloc_code_real_type));
252b5132
RH
144
145/*
146SUBSECTION
147 Relocations
148
149DESCRIPTION
150 The file @file{aoutx.h} provides for both the @emph{standard}
151 and @emph{extended} forms of a.out relocation records.
152
153 The standard records contain only an
154 address, a symbol index, and a type field. The extended records
155 (used on 29ks and sparcs) also have a full integer for an
156 addend.
157
158*/
159#ifndef CTOR_TABLE_RELOC_HOWTO
160#define CTOR_TABLE_RELOC_IDX 2
923f08ff
AM
161#define CTOR_TABLE_RELOC_HOWTO(BFD) \
162 ((obj_reloc_entry_size (BFD) == RELOC_EXT_SIZE \
163 ? howto_table_ext : howto_table_std) \
164 + CTOR_TABLE_RELOC_IDX)
252b5132
RH
165#endif
166
167#ifndef MY_swap_std_reloc_in
168#define MY_swap_std_reloc_in NAME(aout,swap_std_reloc_in)
169#endif
170
1642229e
HPN
171#ifndef MY_swap_ext_reloc_in
172#define MY_swap_ext_reloc_in NAME(aout,swap_ext_reloc_in)
173#endif
174
252b5132
RH
175#ifndef MY_swap_std_reloc_out
176#define MY_swap_std_reloc_out NAME(aout,swap_std_reloc_out)
177#endif
178
1642229e
HPN
179#ifndef MY_swap_ext_reloc_out
180#define MY_swap_ext_reloc_out NAME(aout,swap_ext_reloc_out)
181#endif
182
252b5132
RH
183#ifndef MY_final_link_relocate
184#define MY_final_link_relocate _bfd_final_link_relocate
185#endif
186
187#ifndef MY_relocate_contents
188#define MY_relocate_contents _bfd_relocate_contents
189#endif
190
191#define howto_table_ext NAME(aout,ext_howto_table)
192#define howto_table_std NAME(aout,std_howto_table)
193
194reloc_howto_type howto_table_ext[] =
195{
f7c33884 196 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone. */
252b5132
RH
197 HOWTO(RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", false, 0,0x000000ff, false),
198 HOWTO(RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", false, 0,0x0000ffff, false),
199 HOWTO(RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", false, 0,0xffffffff, false),
200 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, complain_overflow_signed,0,"DISP8", false, 0,0x000000ff, false),
201 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, complain_overflow_signed,0,"DISP16", false, 0,0x0000ffff, false),
202 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, complain_overflow_signed,0,"DISP32", false, 0,0xffffffff, false),
203 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, complain_overflow_signed,0,"WDISP30", false, 0,0x3fffffff, false),
204 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, complain_overflow_signed,0,"WDISP22", false, 0,0x003fffff, false),
205 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"HI22", false, 0,0x003fffff, false),
206 HOWTO(RELOC_22, 0, 2, 22, false, 0, complain_overflow_bitfield,0,"22", false, 0,0x003fffff, false),
207 HOWTO(RELOC_13, 0, 2, 13, false, 0, complain_overflow_bitfield,0,"13", false, 0,0x00001fff, false),
208 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, complain_overflow_dont,0,"LO10", false, 0,0x000003ff, false),
209 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, complain_overflow_bitfield,0,"SFA_BASE", false, 0,0xffffffff, false),
210 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, complain_overflow_bitfield,0,"SFA_OFF13",false, 0,0xffffffff, false),
211 HOWTO(RELOC_BASE10, 0, 2, 10, false, 0, complain_overflow_dont,0,"BASE10", false, 0,0x000003ff, false),
212 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, complain_overflow_signed,0,"BASE13", false, 0,0x00001fff, false),
213 HOWTO(RELOC_BASE22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"BASE22", false, 0,0x003fffff, false),
214 HOWTO(RELOC_PC10, 0, 2, 10, true, 0, complain_overflow_dont,0,"PC10", false, 0,0x000003ff, true),
215 HOWTO(RELOC_PC22, 10, 2, 22, true, 0, complain_overflow_signed,0,"PC22", false, 0,0x003fffff, true),
216 HOWTO(RELOC_JMP_TBL,2, 2, 30, true, 0, complain_overflow_signed,0,"JMP_TBL", false, 0,0x3fffffff, false),
217 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, complain_overflow_bitfield,0,"SEGOFF16", false, 0,0x00000000, false),
218 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"GLOB_DAT", false, 0,0x00000000, false),
219 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_SLOT", false, 0,0x00000000, false),
220 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false),
221 HOWTO(0, 0, 0, 0, false, 0, complain_overflow_dont, 0, "R_SPARC_NONE", false,0,0x00000000,true),
222 HOWTO(0, 0, 0, 0, false, 0, complain_overflow_dont, 0, "R_SPARC_NONE", false,0,0x00000000,true),
223#define RELOC_SPARC_REV32 RELOC_WDISP19
224 HOWTO(RELOC_SPARC_REV32, 0, 2, 32, false, 0, complain_overflow_dont,0,"R_SPARC_REV32", false, 0,0xffffffff, false),
225};
226
227/* Convert standard reloc records to "arelent" format (incl byte swap). */
228
229reloc_howto_type howto_table_std[] = {
f7c33884 230 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone. */
923f08ff
AM
231HOWTO ( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false),
232HOWTO ( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false),
233HOWTO ( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false),
234HOWTO ( 3, 0, 4, 64, false, 0, complain_overflow_bitfield,0,"64", true, 0xdeaddead,0xdeaddead, false),
235HOWTO ( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, false),
236HOWTO ( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
237HOWTO ( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, false),
238HOWTO ( 7, 0, 4, 64, true, 0, complain_overflow_signed, 0,"DISP64", true, 0xfeedface,0xfeedface, false),
239HOWTO ( 8, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"GOT_REL", false, 0,0x00000000, false),
240HOWTO ( 9, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"BASE16", false,0xffffffff,0xffffffff, false),
241HOWTO (10, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"BASE32", false,0xffffffff,0xffffffff, false),
5f771d47
ILT
242EMPTY_HOWTO (-1),
243EMPTY_HOWTO (-1),
244EMPTY_HOWTO (-1),
245EMPTY_HOWTO (-1),
246EMPTY_HOWTO (-1),
923f08ff 247 HOWTO (16, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_TABLE", false, 0,0x00000000, false),
5f771d47
ILT
248EMPTY_HOWTO (-1),
249EMPTY_HOWTO (-1),
250EMPTY_HOWTO (-1),
251EMPTY_HOWTO (-1),
252EMPTY_HOWTO (-1),
253EMPTY_HOWTO (-1),
254EMPTY_HOWTO (-1),
255EMPTY_HOWTO (-1),
256EMPTY_HOWTO (-1),
257EMPTY_HOWTO (-1),
258EMPTY_HOWTO (-1),
259EMPTY_HOWTO (-1),
260EMPTY_HOWTO (-1),
261EMPTY_HOWTO (-1),
262EMPTY_HOWTO (-1),
923f08ff 263 HOWTO (32, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false),
5f771d47
ILT
264EMPTY_HOWTO (-1),
265EMPTY_HOWTO (-1),
266EMPTY_HOWTO (-1),
267EMPTY_HOWTO (-1),
268EMPTY_HOWTO (-1),
269EMPTY_HOWTO (-1),
270EMPTY_HOWTO (-1),
923f08ff 271 HOWTO (40, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"BASEREL", false, 0,0x00000000, false),
252b5132
RH
272};
273
923f08ff 274#define TABLE_SIZE(TABLE) (sizeof (TABLE) / sizeof (TABLE[0]))
252b5132
RH
275
276reloc_howto_type *
277NAME(aout,reloc_type_lookup) (abfd,code)
278 bfd *abfd;
279 bfd_reloc_code_real_type code;
280{
923f08ff
AM
281#define EXT(i, j) case i: return &howto_table_ext[j]
282#define STD(i, j) case i: return &howto_table_std[j]
252b5132 283 int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
f7c33884 284
252b5132
RH
285 if (code == BFD_RELOC_CTOR)
286 switch (bfd_get_arch_info (abfd)->bits_per_address)
287 {
288 case 32:
289 code = BFD_RELOC_32;
290 break;
291 case 64:
292 code = BFD_RELOC_64;
293 break;
294 }
f7c33884 295
252b5132
RH
296 if (ext)
297 switch (code)
298 {
1642229e
HPN
299 EXT (BFD_RELOC_8, 0);
300 EXT (BFD_RELOC_16, 1);
252b5132
RH
301 EXT (BFD_RELOC_32, 2);
302 EXT (BFD_RELOC_HI22, 8);
303 EXT (BFD_RELOC_LO10, 11);
304 EXT (BFD_RELOC_32_PCREL_S2, 6);
305 EXT (BFD_RELOC_SPARC_WDISP22, 7);
306 EXT (BFD_RELOC_SPARC13, 10);
307 EXT (BFD_RELOC_SPARC_GOT10, 14);
308 EXT (BFD_RELOC_SPARC_BASE13, 15);
309 EXT (BFD_RELOC_SPARC_GOT13, 15);
310 EXT (BFD_RELOC_SPARC_GOT22, 16);
311 EXT (BFD_RELOC_SPARC_PC10, 17);
312 EXT (BFD_RELOC_SPARC_PC22, 18);
313 EXT (BFD_RELOC_SPARC_WPLT30, 19);
314 EXT (BFD_RELOC_SPARC_REV32, 26);
315 default: return (reloc_howto_type *) NULL;
316 }
317 else
f7c33884 318 /* std relocs. */
252b5132
RH
319 switch (code)
320 {
321 STD (BFD_RELOC_16, 1);
322 STD (BFD_RELOC_32, 2);
323 STD (BFD_RELOC_8_PCREL, 4);
324 STD (BFD_RELOC_16_PCREL, 5);
325 STD (BFD_RELOC_32_PCREL, 6);
326 STD (BFD_RELOC_16_BASEREL, 9);
327 STD (BFD_RELOC_32_BASEREL, 10);
328 default: return (reloc_howto_type *) NULL;
329 }
330}
331
332/*
333SUBSECTION
334 Internal entry points
335
336DESCRIPTION
337 @file{aoutx.h} exports several routines for accessing the
338 contents of an a.out file, which are gathered and exported in
339 turn by various format specific files (eg sunos.c).
340
341*/
342
343/*
344FUNCTION
345 aout_@var{size}_swap_exec_header_in
346
347SYNOPSIS
348 void aout_@var{size}_swap_exec_header_in,
349 (bfd *abfd,
350 struct external_exec *raw_bytes,
351 struct internal_exec *execp);
352
353DESCRIPTION
354 Swap the information in an executable header @var{raw_bytes} taken
355 from a raw byte stream memory image into the internal exec header
356 structure @var{execp}.
357*/
358
359#ifndef NAME_swap_exec_header_in
360void
361NAME(aout,swap_exec_header_in) (abfd, raw_bytes, execp)
362 bfd *abfd;
363 struct external_exec *raw_bytes;
364 struct internal_exec *execp;
365{
366 struct external_exec *bytes = (struct external_exec *)raw_bytes;
367
368 /* The internal_exec structure has some fields that are unused in this
369 configuration (IE for i960), so ensure that all such uninitialized
370 fields are zero'd out. There are places where two of these structs
0ef5a5bd 371 are memcmp'd, and thus the contents do matter. */
252b5132
RH
372 memset ((PTR) execp, 0, sizeof (struct internal_exec));
373 /* Now fill in fields in the execp, from the bytes in the raw data. */
dc810e39 374 execp->a_info = H_GET_32 (abfd, bytes->e_info);
252b5132
RH
375 execp->a_text = GET_WORD (abfd, bytes->e_text);
376 execp->a_data = GET_WORD (abfd, bytes->e_data);
377 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
378 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
379 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
380 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
381 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
382}
383#define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
384#endif
385
386/*
387FUNCTION
388 aout_@var{size}_swap_exec_header_out
389
390SYNOPSIS
391 void aout_@var{size}_swap_exec_header_out
392 (bfd *abfd,
393 struct internal_exec *execp,
394 struct external_exec *raw_bytes);
395
396DESCRIPTION
397 Swap the information in an internal exec header structure
398 @var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
399*/
400void
401NAME(aout,swap_exec_header_out) (abfd, execp, raw_bytes)
402 bfd *abfd;
403 struct internal_exec *execp;
404 struct external_exec *raw_bytes;
405{
406 struct external_exec *bytes = (struct external_exec *)raw_bytes;
407
0ef5a5bd 408 /* Now fill in fields in the raw data, from the fields in the exec struct. */
dc810e39 409 H_PUT_32 (abfd, execp->a_info , bytes->e_info);
252b5132
RH
410 PUT_WORD (abfd, execp->a_text , bytes->e_text);
411 PUT_WORD (abfd, execp->a_data , bytes->e_data);
412 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
413 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
414 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
415 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
416 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
417}
418
419/* Make all the section for an a.out file. */
420
421boolean
422NAME(aout,make_sections) (abfd)
423 bfd *abfd;
424{
425 if (obj_textsec (abfd) == (asection *) NULL
426 && bfd_make_section (abfd, ".text") == (asection *) NULL)
427 return false;
428 if (obj_datasec (abfd) == (asection *) NULL
429 && bfd_make_section (abfd, ".data") == (asection *) NULL)
430 return false;
431 if (obj_bsssec (abfd) == (asection *) NULL
432 && bfd_make_section (abfd, ".bss") == (asection *) NULL)
433 return false;
434 return true;
435}
436
437/*
438FUNCTION
439 aout_@var{size}_some_aout_object_p
440
441SYNOPSIS
442 const bfd_target *aout_@var{size}_some_aout_object_p
443 (bfd *abfd,
beb0d161 444 const bfd_target *(*callback_to_real_object_p) ());
252b5132
RH
445
446DESCRIPTION
447 Some a.out variant thinks that the file open in @var{abfd}
448 checking is an a.out file. Do some more checking, and set up
449 for access if it really is. Call back to the calling
450 environment's "finish up" function just before returning, to
451 handle any last-minute setup.
452*/
453
454const bfd_target *
455NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
456 bfd *abfd;
457 struct internal_exec *execp;
458 const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *));
459{
460 struct aout_data_struct *rawptr, *oldrawptr;
461 const bfd_target *result;
dc810e39 462 bfd_size_type amt = sizeof (struct aout_data_struct);
252b5132 463
dc810e39 464 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
252b5132
RH
465 if (rawptr == NULL)
466 return 0;
467
468 oldrawptr = abfd->tdata.aout_data;
469 abfd->tdata.aout_data = rawptr;
470
471 /* Copy the contents of the old tdata struct.
472 In particular, we want the subformat, since for hpux it was set in
473 hp300hpux.c:swap_exec_header_in and will be used in
474 hp300hpux.c:callback. */
475 if (oldrawptr != NULL)
476 *abfd->tdata.aout_data = *oldrawptr;
477
478 abfd->tdata.aout_data->a.hdr = &rawptr->e;
f7c33884
NC
479 /* Copy in the internal_exec struct. */
480 *(abfd->tdata.aout_data->a.hdr) = *execp;
252b5132
RH
481 execp = abfd->tdata.aout_data->a.hdr;
482
f7c33884 483 /* Set the file flags. */
252b5132
RH
484 abfd->flags = BFD_NO_FLAGS;
485 if (execp->a_drsize || execp->a_trsize)
486 abfd->flags |= HAS_RELOC;
f7c33884 487 /* Setting of EXEC_P has been deferred to the bottom of this function. */
252b5132
RH
488 if (execp->a_syms)
489 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
923f08ff 490 if (N_DYNAMIC (*execp))
252b5132
RH
491 abfd->flags |= DYNAMIC;
492
493 if (N_MAGIC (*execp) == ZMAGIC)
494 {
495 abfd->flags |= D_PAGED | WP_TEXT;
496 adata (abfd).magic = z_magic;
497 }
498 else if (N_MAGIC (*execp) == QMAGIC)
499 {
500 abfd->flags |= D_PAGED | WP_TEXT;
501 adata (abfd).magic = z_magic;
502 adata (abfd).subformat = q_magic_format;
503 }
504 else if (N_MAGIC (*execp) == NMAGIC)
505 {
506 abfd->flags |= WP_TEXT;
507 adata (abfd).magic = n_magic;
508 }
509 else if (N_MAGIC (*execp) == OMAGIC
510 || N_MAGIC (*execp) == BMAGIC)
511 adata (abfd).magic = o_magic;
512 else
513 {
514 /* Should have been checked with N_BADMAG before this routine
515 was called. */
516 abort ();
517 }
518
519 bfd_get_start_address (abfd) = execp->a_entry;
520
521 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
522 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
523
524 /* The default relocation entry size is that of traditional V7 Unix. */
525 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
526
0ef5a5bd 527 /* The default symbol entry size is that of traditional Unix. */
252b5132
RH
528 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
529
530#ifdef USE_MMAP
531 bfd_init_window (&obj_aout_sym_window (abfd));
532 bfd_init_window (&obj_aout_string_window (abfd));
533#endif
534 obj_aout_external_syms (abfd) = NULL;
535 obj_aout_external_strings (abfd) = NULL;
536 obj_aout_sym_hashes (abfd) = NULL;
537
538 if (! NAME(aout,make_sections) (abfd))
487e54f2 539 goto error_ret;
252b5132
RH
540
541 obj_datasec (abfd)->_raw_size = execp->a_data;
542 obj_bsssec (abfd)->_raw_size = execp->a_bss;
543
544 obj_textsec (abfd)->flags =
545 (execp->a_trsize != 0
546 ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
547 : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
548 obj_datasec (abfd)->flags =
549 (execp->a_drsize != 0
550 ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
551 : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
552 obj_bsssec (abfd)->flags = SEC_ALLOC;
553
554#ifdef THIS_IS_ONLY_DOCUMENTATION
555 /* The common code can't fill in these things because they depend
556 on either the start address of the text segment, the rounding
557 up of virtual addresses between segments, or the starting file
558 position of the text segment -- all of which varies among different
559 versions of a.out. */
560
561 /* Call back to the format-dependent code to fill in the rest of the
562 fields and do any further cleanup. Things that should be filled
563 in by the callback: */
564
565 struct exec *execp = exec_hdr (abfd);
566
923f08ff
AM
567 obj_textsec (abfd)->size = N_TXTSIZE (*execp);
568 obj_textsec (abfd)->raw_size = N_TXTSIZE (*execp);
f7c33884 569 /* Data and bss are already filled in since they're so standard. */
252b5132 570
f7c33884 571 /* The virtual memory addresses of the sections. */
923f08ff
AM
572 obj_textsec (abfd)->vma = N_TXTADDR (*execp);
573 obj_datasec (abfd)->vma = N_DATADDR (*execp);
574 obj_bsssec (abfd)->vma = N_BSSADDR (*execp);
252b5132 575
f7c33884 576 /* The file offsets of the sections. */
923f08ff
AM
577 obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
578 obj_datasec (abfd)->filepos = N_DATOFF (*execp);
252b5132 579
f7c33884 580 /* The file offsets of the relocation info. */
923f08ff
AM
581 obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
582 obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
252b5132
RH
583
584 /* The file offsets of the string table and symbol table. */
585 obj_str_filepos (abfd) = N_STROFF (*execp);
586 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
587
588 /* Determine the architecture and machine type of the object file. */
923f08ff
AM
589 switch (N_MACHTYPE (*exec_hdr (abfd)))
590 {
591 default:
592 abfd->obj_arch = bfd_arch_obscure;
593 break;
594 }
252b5132 595
923f08ff
AM
596 adata (abfd)->page_size = TARGET_PAGE_SIZE;
597 adata (abfd)->segment_size = SEGMENT_SIZE;
598 adata (abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
252b5132
RH
599
600 return abfd->xvec;
601
602 /* The architecture is encoded in various ways in various a.out variants,
603 or is not encoded at all in some of them. The relocation size depends
604 on the architecture and the a.out variant. Finally, the return value
605 is the bfd_target vector in use. If an error occurs, return zero and
606 set bfd_error to the appropriate error code.
607
608 Formats such as b.out, which have additional fields in the a.out
609 header, should cope with them in this callback as well. */
610#endif /* DOCUMENTATION */
611
beb0d161 612 result = (*callback_to_real_object_p) (abfd);
252b5132
RH
613
614 /* Now that the segment addresses have been worked out, take a better
615 guess at whether the file is executable. If the entry point
616 is within the text segment, assume it is. (This makes files
617 executable even if their entry point address is 0, as long as
618 their text starts at zero.).
619
620 This test had to be changed to deal with systems where the text segment
621 runs at a different location than the default. The problem is that the
622 entry address can appear to be outside the text segment, thus causing an
623 erroneous conclusion that the file isn't executable.
624
625 To fix this, we now accept any non-zero entry point as an indication of
626 executability. This will work most of the time, since only the linker
0ef5a5bd 627 sets the entry point, and that is likely to be non-zero for most systems. */
252b5132
RH
628
629 if (execp->a_entry != 0
923f08ff
AM
630 || (execp->a_entry >= obj_textsec (abfd)->vma
631 && execp->a_entry < (obj_textsec (abfd)->vma
632 + obj_textsec (abfd)->_raw_size)))
252b5132
RH
633 abfd->flags |= EXEC_P;
634#ifdef STAT_FOR_EXEC
635 else
636 {
637 struct stat stat_buf;
638
639 /* The original heuristic doesn't work in some important cases.
640 The a.out file has no information about the text start
641 address. For files (like kernels) linked to non-standard
642 addresses (ld -Ttext nnn) the entry point may not be between
643 the default text start (obj_textsec(abfd)->vma) and
644 (obj_textsec(abfd)->vma) + text size. This is not just a mach
645 issue. Many kernels are loaded at non standard addresses. */
646 if (abfd->iostream != NULL
647 && (abfd->flags & BFD_IN_MEMORY) == 0
923f08ff 648 && (fstat (fileno ((FILE *) (abfd->iostream)), &stat_buf) == 0)
252b5132
RH
649 && ((stat_buf.st_mode & 0111) != 0))
650 abfd->flags |= EXEC_P;
651 }
652#endif /* STAT_FOR_EXEC */
653
654 if (result)
655 {
656#if 0 /* These should be set correctly anyways. */
657 abfd->sections = obj_textsec (abfd);
658 obj_textsec (abfd)->next = obj_datasec (abfd);
659 obj_datasec (abfd)->next = obj_bsssec (abfd);
660#endif
487e54f2 661 return result;
252b5132 662 }
487e54f2
AM
663
664 error_ret:
665 bfd_release (abfd, rawptr);
666 abfd->tdata.aout_data = oldrawptr;
667 return NULL;
252b5132
RH
668}
669
670/*
671FUNCTION
672 aout_@var{size}_mkobject
673
674SYNOPSIS
675 boolean aout_@var{size}_mkobject, (bfd *abfd);
676
677DESCRIPTION
678 Initialize BFD @var{abfd} for use with a.out files.
679*/
680
681boolean
682NAME(aout,mkobject) (abfd)
683 bfd *abfd;
684{
dc810e39
AM
685 struct aout_data_struct *rawptr;
686 bfd_size_type amt = sizeof (struct aout_data_struct);
252b5132
RH
687
688 bfd_set_error (bfd_error_system_call);
689
dc810e39 690 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
252b5132
RH
691 if (rawptr == NULL)
692 return false;
693
694 abfd->tdata.aout_data = rawptr;
695 exec_hdr (abfd) = &(rawptr->e);
696
dc810e39
AM
697 obj_textsec (abfd) = (asection *) NULL;
698 obj_datasec (abfd) = (asection *) NULL;
699 obj_bsssec (abfd) = (asection *) NULL;
252b5132
RH
700
701 return true;
702}
703
252b5132
RH
704/*
705FUNCTION
706 aout_@var{size}_machine_type
707
708SYNOPSIS
709 enum machine_type aout_@var{size}_machine_type
710 (enum bfd_architecture arch,
711 unsigned long machine));
712
713DESCRIPTION
714 Keep track of machine architecture and machine type for
715 a.out's. Return the <<machine_type>> for a particular
716 architecture and machine, or <<M_UNKNOWN>> if that exact architecture
717 and machine can't be represented in a.out format.
718
719 If the architecture is understood, machine type 0 (default)
720 is always understood.
721*/
722
723enum machine_type
724NAME(aout,machine_type) (arch, machine, unknown)
725 enum bfd_architecture arch;
726 unsigned long machine;
727 boolean *unknown;
728{
729 enum machine_type arch_flags;
730
731 arch_flags = M_UNKNOWN;
732 *unknown = true;
733
923f08ff
AM
734 switch (arch)
735 {
736 case bfd_arch_sparc:
737 if (machine == 0
738 || machine == bfd_mach_sparc
739 || machine == bfd_mach_sparc_sparclite
740 || machine == bfd_mach_sparc_sparclite_le
741 || machine == bfd_mach_sparc_v9)
742 arch_flags = M_SPARC;
743 else if (machine == bfd_mach_sparc_sparclet)
744 arch_flags = M_SPARCLET;
745 break;
746
747 case bfd_arch_m68k:
748 switch (machine)
749 {
750 case 0: arch_flags = M_68010; break;
751 case bfd_mach_m68000: arch_flags = M_UNKNOWN; *unknown = false; break;
752 case bfd_mach_m68010: arch_flags = M_68010; break;
753 case bfd_mach_m68020: arch_flags = M_68020; break;
754 default: arch_flags = M_UNKNOWN; break;
755 }
252b5132 756 break;
923f08ff
AM
757
758 case bfd_arch_i386:
759 if (machine == 0)
760 arch_flags = M_386;
252b5132 761 break;
923f08ff
AM
762
763 case bfd_arch_a29k:
764 if (machine == 0)
765 arch_flags = M_29K;
252b5132 766 break;
923f08ff
AM
767
768 case bfd_arch_arm:
769 if (machine == 0)
770 arch_flags = M_ARM;
252b5132 771 break;
252b5132 772
923f08ff
AM
773 case bfd_arch_mips:
774 switch (machine)
775 {
776 case 0:
777 case bfd_mach_mips3000:
778 case bfd_mach_mips3900:
779 arch_flags = M_MIPS1;
780 break;
781 case bfd_mach_mips6000:
782 arch_flags = M_MIPS2;
783 break;
784 case bfd_mach_mips4000:
785 case bfd_mach_mips4010:
786 case bfd_mach_mips4100:
787 case bfd_mach_mips4300:
788 case bfd_mach_mips4400:
789 case bfd_mach_mips4600:
790 case bfd_mach_mips4650:
791 case bfd_mach_mips8000:
792 case bfd_mach_mips10000:
793 case bfd_mach_mips12000:
794 case bfd_mach_mips16:
795 case bfd_mach_mipsisa32:
796 case bfd_mach_mips5:
797 case bfd_mach_mipsisa64:
798 case bfd_mach_mips_sb1:
799 /* FIXME: These should be MIPS3, MIPS4, MIPS16, MIPS32, etc. */
800 arch_flags = M_MIPS2;
801 break;
802 default:
803 arch_flags = M_UNKNOWN;
804 break;
805 }
806 break;
807
808 case bfd_arch_ns32k:
809 switch (machine)
810 {
811 case 0: arch_flags = M_NS32532; break;
812 case 32032: arch_flags = M_NS32032; break;
813 case 32532: arch_flags = M_NS32532; break;
814 default: arch_flags = M_UNKNOWN; break;
815 }
816 break;
252b5132 817
923f08ff
AM
818 case bfd_arch_vax:
819 *unknown = false;
820 break;
06c15ad7 821
923f08ff
AM
822 case bfd_arch_cris:
823 if (machine == 0 || machine == 255)
824 arch_flags = M_CRIS;
825 break;
826
827 default:
828 arch_flags = M_UNKNOWN;
829 }
252b5132
RH
830
831 if (arch_flags != M_UNKNOWN)
832 *unknown = false;
833
834 return arch_flags;
835}
836
252b5132
RH
837/*
838FUNCTION
839 aout_@var{size}_set_arch_mach
840
841SYNOPSIS
842 boolean aout_@var{size}_set_arch_mach,
843 (bfd *,
844 enum bfd_architecture arch,
845 unsigned long machine));
846
847DESCRIPTION
848 Set the architecture and the machine of the BFD @var{abfd} to the
849 values @var{arch} and @var{machine}. Verify that @var{abfd}'s format
850 can support the architecture required.
851*/
852
853boolean
854NAME(aout,set_arch_mach) (abfd, arch, machine)
855 bfd *abfd;
856 enum bfd_architecture arch;
857 unsigned long machine;
858{
859 if (! bfd_default_set_arch_mach (abfd, arch, machine))
860 return false;
861
862 if (arch != bfd_arch_unknown)
863 {
864 boolean unknown;
865
866 NAME(aout,machine_type) (arch, machine, &unknown);
867 if (unknown)
868 return false;
869 }
870
f7c33884 871 /* Determine the size of a relocation entry. */
923f08ff
AM
872 switch (arch)
873 {
874 case bfd_arch_sparc:
875 case bfd_arch_a29k:
876 case bfd_arch_mips:
877 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
878 break;
879 default:
880 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
881 break;
882 }
252b5132 883
923f08ff 884 return (*aout_backend_info (abfd)->set_sizes) (abfd);
252b5132
RH
885}
886
887static void
888adjust_o_magic (abfd, execp)
889 bfd *abfd;
890 struct internal_exec *execp;
891{
892 file_ptr pos = adata (abfd).exec_bytes_size;
893 bfd_vma vma = 0;
894 int pad = 0;
895
896 /* Text. */
923f08ff
AM
897 obj_textsec (abfd)->filepos = pos;
898 if (!obj_textsec (abfd)->user_set_vma)
899 obj_textsec (abfd)->vma = vma;
252b5132 900 else
923f08ff 901 vma = obj_textsec (abfd)->vma;
252b5132 902
923f08ff
AM
903 pos += obj_textsec (abfd)->_raw_size;
904 vma += obj_textsec (abfd)->_raw_size;
252b5132
RH
905
906 /* Data. */
923f08ff 907 if (!obj_datasec (abfd)->user_set_vma)
252b5132 908 {
f7c33884 909#if 0 /* ?? Does alignment in the file image really matter? */
923f08ff 910 pad = align_power (vma, obj_datasec (abfd)->alignment_power) - vma;
252b5132 911#endif
923f08ff 912 obj_textsec (abfd)->_raw_size += pad;
252b5132
RH
913 pos += pad;
914 vma += pad;
923f08ff 915 obj_datasec (abfd)->vma = vma;
252b5132
RH
916 }
917 else
923f08ff
AM
918 vma = obj_datasec (abfd)->vma;
919 obj_datasec (abfd)->filepos = pos;
920 pos += obj_datasec (abfd)->_raw_size;
921 vma += obj_datasec (abfd)->_raw_size;
252b5132
RH
922
923 /* BSS. */
923f08ff 924 if (!obj_bsssec (abfd)->user_set_vma)
252b5132
RH
925 {
926#if 0
923f08ff 927 pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
252b5132 928#endif
923f08ff 929 obj_datasec (abfd)->_raw_size += pad;
252b5132
RH
930 pos += pad;
931 vma += pad;
923f08ff 932 obj_bsssec (abfd)->vma = vma;
252b5132
RH
933 }
934 else
935 {
08da05b0 936 /* The VMA of the .bss section is set by the VMA of the
252b5132
RH
937 .data section plus the size of the .data section. We may
938 need to add padding bytes to make this true. */
939 pad = obj_bsssec (abfd)->vma - vma;
940 if (pad > 0)
941 {
942 obj_datasec (abfd)->_raw_size += pad;
943 pos += pad;
944 }
945 }
923f08ff 946 obj_bsssec (abfd)->filepos = pos;
252b5132
RH
947
948 /* Fix up the exec header. */
923f08ff
AM
949 execp->a_text = obj_textsec (abfd)->_raw_size;
950 execp->a_data = obj_datasec (abfd)->_raw_size;
951 execp->a_bss = obj_bsssec (abfd)->_raw_size;
252b5132
RH
952 N_SET_MAGIC (*execp, OMAGIC);
953}
954
955static void
956adjust_z_magic (abfd, execp)
957 bfd *abfd;
958 struct internal_exec *execp;
959{
960 bfd_size_type data_pad, text_pad;
961 file_ptr text_end;
dc810e39 962 const struct aout_backend_data *abdp;
252b5132 963 int ztih; /* Nonzero if text includes exec header. */
0ef5a5bd 964
252b5132
RH
965 abdp = aout_backend_info (abfd);
966
967 /* Text. */
968 ztih = (abdp != NULL
969 && (abdp->text_includes_header
970 || obj_aout_subformat (abfd) == q_magic_format));
923f08ff
AM
971 obj_textsec (abfd)->filepos = (ztih
972 ? adata (abfd).exec_bytes_size
973 : adata (abfd).zmagic_disk_block_size);
974 if (! obj_textsec (abfd)->user_set_vma)
252b5132
RH
975 {
976 /* ?? Do we really need to check for relocs here? */
923f08ff
AM
977 obj_textsec (abfd)->vma = ((abfd->flags & HAS_RELOC)
978 ? 0
979 : (ztih
980 ? (abdp->default_text_vma
981 + adata (abfd).exec_bytes_size)
982 : abdp->default_text_vma));
252b5132
RH
983 text_pad = 0;
984 }
985 else
986 {
987 /* The .text section is being loaded at an unusual address. We
988 may need to pad it such that the .data section starts at a page
989 boundary. */
990 if (ztih)
991 text_pad = ((obj_textsec (abfd)->filepos - obj_textsec (abfd)->vma)
992 & (adata (abfd).page_size - 1));
993 else
994 text_pad = ((- obj_textsec (abfd)->vma)
995 & (adata (abfd).page_size - 1));
996 }
997
998 /* Find start of data. */
999 if (ztih)
1000 {
1001 text_end = obj_textsec (abfd)->filepos + obj_textsec (abfd)->_raw_size;
1002 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
1003 }
1004 else
1005 {
1006 /* Note that if page_size == zmagic_disk_block_size, then
1007 filepos == page_size, and this case is the same as the ztih
1008 case. */
1009 text_end = obj_textsec (abfd)->_raw_size;
1010 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
1011 text_end += obj_textsec (abfd)->filepos;
1012 }
923f08ff 1013 obj_textsec (abfd)->_raw_size += text_pad;
252b5132
RH
1014 text_end += text_pad;
1015
1016 /* Data. */
923f08ff 1017 if (!obj_datasec (abfd)->user_set_vma)
252b5132
RH
1018 {
1019 bfd_vma vma;
923f08ff
AM
1020 vma = obj_textsec (abfd)->vma + obj_textsec (abfd)->_raw_size;
1021 obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
252b5132
RH
1022 }
1023 if (abdp && abdp->zmagic_mapped_contiguous)
1024 {
dee0a8f4
NC
1025 asection * text = obj_textsec (abfd);
1026 asection * data = obj_datasec (abfd);
1027
1028 text_pad = data->vma - (text->vma + text->_raw_size);
1029 /* Only pad the text section if the data
1030 section is going to be placed after it. */
1031 if (text_pad > 0)
1032 text->_raw_size += text_pad;
252b5132 1033 }
923f08ff
AM
1034 obj_datasec (abfd)->filepos = (obj_textsec (abfd)->filepos
1035 + obj_textsec (abfd)->_raw_size);
0ef5a5bd 1036
252b5132 1037 /* Fix up exec header while we're at it. */
923f08ff 1038 execp->a_text = obj_textsec (abfd)->_raw_size;
252b5132 1039 if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
923f08ff 1040 execp->a_text += adata (abfd).exec_bytes_size;
252b5132
RH
1041 if (obj_aout_subformat (abfd) == q_magic_format)
1042 N_SET_MAGIC (*execp, QMAGIC);
1043 else
1044 N_SET_MAGIC (*execp, ZMAGIC);
1045
1046 /* Spec says data section should be rounded up to page boundary. */
923f08ff
AM
1047 obj_datasec (abfd)->_raw_size
1048 = align_power (obj_datasec (abfd)->_raw_size,
1049 obj_bsssec (abfd)->alignment_power);
1050 execp->a_data = BFD_ALIGN (obj_datasec (abfd)->_raw_size,
1051 adata (abfd).page_size);
1052 data_pad = execp->a_data - obj_datasec (abfd)->_raw_size;
252b5132
RH
1053
1054 /* BSS. */
923f08ff
AM
1055 if (!obj_bsssec (abfd)->user_set_vma)
1056 obj_bsssec (abfd)->vma = (obj_datasec (abfd)->vma
1057 + obj_datasec (abfd)->_raw_size);
252b5132
RH
1058 /* If the BSS immediately follows the data section and extra space
1059 in the page is left after the data section, fudge data
1060 in the header so that the bss section looks smaller by that
1061 amount. We'll start the bss section there, and lie to the OS.
1062 (Note that a linker script, as well as the above assignment,
1063 could have explicitly set the BSS vma to immediately follow
1064 the data section.) */
923f08ff
AM
1065 if (align_power (obj_bsssec (abfd)->vma, obj_bsssec (abfd)->alignment_power)
1066 == obj_datasec (abfd)->vma + obj_datasec (abfd)->_raw_size)
1067 execp->a_bss = (data_pad > obj_bsssec (abfd)->_raw_size
1068 ? 0 : obj_bsssec (abfd)->_raw_size - data_pad);
252b5132 1069 else
923f08ff 1070 execp->a_bss = obj_bsssec (abfd)->_raw_size;
252b5132
RH
1071}
1072
1073static void
1074adjust_n_magic (abfd, execp)
1075 bfd *abfd;
1076 struct internal_exec *execp;
1077{
923f08ff 1078 file_ptr pos = adata (abfd).exec_bytes_size;
252b5132
RH
1079 bfd_vma vma = 0;
1080 int pad;
0ef5a5bd 1081
252b5132 1082 /* Text. */
923f08ff
AM
1083 obj_textsec (abfd)->filepos = pos;
1084 if (!obj_textsec (abfd)->user_set_vma)
1085 obj_textsec (abfd)->vma = vma;
252b5132 1086 else
923f08ff
AM
1087 vma = obj_textsec (abfd)->vma;
1088 pos += obj_textsec (abfd)->_raw_size;
1089 vma += obj_textsec (abfd)->_raw_size;
252b5132
RH
1090
1091 /* Data. */
923f08ff
AM
1092 obj_datasec (abfd)->filepos = pos;
1093 if (!obj_datasec (abfd)->user_set_vma)
1094 obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
1095 vma = obj_datasec (abfd)->vma;
0ef5a5bd 1096
252b5132 1097 /* Since BSS follows data immediately, see if it needs alignment. */
923f08ff
AM
1098 vma += obj_datasec (abfd)->_raw_size;
1099 pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
1100 obj_datasec (abfd)->_raw_size += pad;
1101 pos += obj_datasec (abfd)->_raw_size;
252b5132
RH
1102
1103 /* BSS. */
923f08ff
AM
1104 if (!obj_bsssec (abfd)->user_set_vma)
1105 obj_bsssec (abfd)->vma = vma;
252b5132 1106 else
923f08ff 1107 vma = obj_bsssec (abfd)->vma;
252b5132
RH
1108
1109 /* Fix up exec header. */
923f08ff
AM
1110 execp->a_text = obj_textsec (abfd)->_raw_size;
1111 execp->a_data = obj_datasec (abfd)->_raw_size;
1112 execp->a_bss = obj_bsssec (abfd)->_raw_size;
252b5132
RH
1113 N_SET_MAGIC (*execp, NMAGIC);
1114}
1115
1116boolean
1117NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end)
1118 bfd *abfd;
1119 bfd_size_type *text_size;
7442e600 1120 file_ptr *text_end ATTRIBUTE_UNUSED;
252b5132
RH
1121{
1122 struct internal_exec *execp = exec_hdr (abfd);
1123
1124 if (! NAME(aout,make_sections) (abfd))
1125 return false;
1126
923f08ff 1127 if (adata (abfd).magic != undecided_magic)
252b5132
RH
1128 return true;
1129
923f08ff
AM
1130 obj_textsec (abfd)->_raw_size =
1131 align_power (obj_textsec (abfd)->_raw_size,
1132 obj_textsec (abfd)->alignment_power);
252b5132
RH
1133
1134 *text_size = obj_textsec (abfd)->_raw_size;
1135 /* Rule (heuristic) for when to pad to a new page. Note that there
1136 are (at least) two ways demand-paged (ZMAGIC) files have been
1137 handled. Most Berkeley-based systems start the text segment at
1138 (TARGET_PAGE_SIZE). However, newer versions of SUNOS start the text
1139 segment right after the exec header; the latter is counted in the
1140 text segment size, and is paged in by the kernel with the rest of
0ef5a5bd 1141 the text. */
252b5132
RH
1142
1143 /* This perhaps isn't the right way to do this, but made it simpler for me
1144 to understand enough to implement it. Better would probably be to go
1145 right from BFD flags to alignment/positioning characteristics. But the
1146 old code was sloppy enough about handling the flags, and had enough
1147 other magic, that it was a little hard for me to understand. I think
1148 I understand it better now, but I haven't time to do the cleanup this
1149 minute. */
1150
1151 if (abfd->flags & D_PAGED)
1152 /* Whether or not WP_TEXT is set -- let D_PAGED override. */
923f08ff 1153 adata (abfd).magic = z_magic;
252b5132 1154 else if (abfd->flags & WP_TEXT)
923f08ff 1155 adata (abfd).magic = n_magic;
252b5132 1156 else
923f08ff 1157 adata (abfd).magic = o_magic;
252b5132
RH
1158
1159#ifdef BFD_AOUT_DEBUG /* requires gcc2 */
1160#if __GNUC__ >= 2
1161 fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
1162 ({ char *str;
923f08ff
AM
1163 switch (adata (abfd).magic)
1164 {
1165 case n_magic: str = "NMAGIC"; break;
1166 case o_magic: str = "OMAGIC"; break;
1167 case z_magic: str = "ZMAGIC"; break;
1168 default: abort ();
1169 }
252b5132
RH
1170 str;
1171 }),
923f08ff
AM
1172 obj_textsec (abfd)->vma, obj_textsec (abfd)->_raw_size,
1173 obj_textsec (abfd)->alignment_power,
1174 obj_datasec (abfd)->vma, obj_datasec (abfd)->_raw_size,
1175 obj_datasec (abfd)->alignment_power,
1176 obj_bsssec (abfd)->vma, obj_bsssec (abfd)->_raw_size,
1177 obj_bsssec (abfd)->alignment_power);
252b5132
RH
1178#endif
1179#endif
1180
923f08ff 1181 switch (adata (abfd).magic)
252b5132
RH
1182 {
1183 case o_magic:
1184 adjust_o_magic (abfd, execp);
1185 break;
1186 case z_magic:
1187 adjust_z_magic (abfd, execp);
1188 break;
1189 case n_magic:
1190 adjust_n_magic (abfd, execp);
1191 break;
1192 default:
1193 abort ();
1194 }
1195
1196#ifdef BFD_AOUT_DEBUG
1197 fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
923f08ff
AM
1198 obj_textsec (abfd)->vma, obj_textsec (abfd)->_raw_size,
1199 obj_textsec (abfd)->filepos,
1200 obj_datasec (abfd)->vma, obj_datasec (abfd)->_raw_size,
1201 obj_datasec (abfd)->filepos,
1202 obj_bsssec (abfd)->vma, obj_bsssec (abfd)->_raw_size);
252b5132
RH
1203#endif
1204
1205 return true;
1206}
1207
1208/*
1209FUNCTION
1210 aout_@var{size}_new_section_hook
1211
1212SYNOPSIS
1213 boolean aout_@var{size}_new_section_hook,
1214 (bfd *abfd,
1215 asection *newsect));
1216
1217DESCRIPTION
1218 Called by the BFD in response to a @code{bfd_make_section}
1219 request.
1220*/
1221boolean
1222NAME(aout,new_section_hook) (abfd, newsect)
1223 bfd *abfd;
1224 asection *newsect;
1225{
f7c33884 1226 /* Align to double at least. */
923f08ff 1227 newsect->alignment_power = bfd_get_arch_info (abfd)->section_align_power;
252b5132 1228
252b5132 1229 if (bfd_get_format (abfd) == bfd_object)
f7c33884
NC
1230 {
1231 if (obj_textsec (abfd) == NULL && !strcmp (newsect->name, ".text"))
1232 {
1233 obj_textsec (abfd)= newsect;
1234 newsect->target_index = N_TEXT;
1235 return true;
1236 }
252b5132 1237
f7c33884
NC
1238 if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data"))
1239 {
1240 obj_datasec (abfd) = newsect;
1241 newsect->target_index = N_DATA;
1242 return true;
1243 }
252b5132 1244
f7c33884
NC
1245 if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss"))
1246 {
1247 obj_bsssec (abfd) = newsect;
1248 newsect->target_index = N_BSS;
1249 return true;
1250 }
1251 }
252b5132 1252
f7c33884 1253 /* We allow more than three sections internally. */
252b5132
RH
1254 return true;
1255}
1256
1257boolean
1258NAME(aout,set_section_contents) (abfd, section, location, offset, count)
1259 bfd *abfd;
1260 sec_ptr section;
1261 PTR location;
1262 file_ptr offset;
1263 bfd_size_type count;
1264{
1265 file_ptr text_end;
1266 bfd_size_type text_size;
1267
1268 if (! abfd->output_has_begun)
1269 {
1270 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
1271 return false;
1272 }
1273
1274 if (section == obj_bsssec (abfd))
1275 {
1276 bfd_set_error (bfd_error_no_contents);
1277 return false;
1278 }
1279
1280 if (section != obj_textsec (abfd)
1281 && section != obj_datasec (abfd))
1282 {
1283 (*_bfd_error_handler)
1284 (_("%s: can not represent section `%s' in a.out object file format"),
1285 bfd_get_filename (abfd), bfd_get_section_name (abfd, section));
1286 bfd_set_error (bfd_error_nonrepresentable_section);
1287 return false;
1288 }
1289
1290 if (count != 0)
1291 {
1292 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
dc810e39 1293 || bfd_bwrite (location, count, abfd) != count)
252b5132
RH
1294 return false;
1295 }
1296
1297 return true;
1298}
1299\f
1300/* Read the external symbols from an a.out file. */
1301
1302static boolean
1303aout_get_external_symbols (abfd)
1304 bfd *abfd;
1305{
1306 if (obj_aout_external_syms (abfd) == (struct external_nlist *) NULL)
1307 {
1308 bfd_size_type count;
1309 struct external_nlist *syms;
dc810e39 1310 bfd_size_type amt;
252b5132
RH
1311
1312 count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
1313
1314#ifdef USE_MMAP
82e51918
AM
1315 if (! bfd_get_file_window (abfd, obj_sym_filepos (abfd),
1316 exec_hdr (abfd)->a_syms,
1317 &obj_aout_sym_window (abfd), true))
252b5132
RH
1318 return false;
1319 syms = (struct external_nlist *) obj_aout_sym_window (abfd).data;
1320#else
1321 /* We allocate using malloc to make the values easy to free
1322 later on. If we put them on the objalloc it might not be
1323 possible to free them. */
1324 syms = ((struct external_nlist *)
dc810e39 1325 bfd_malloc (count * EXTERNAL_NLIST_SIZE));
252b5132
RH
1326 if (syms == (struct external_nlist *) NULL && count != 0)
1327 return false;
1328
dc810e39 1329 amt = exec_hdr (abfd)->a_syms;
252b5132 1330 if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
dc810e39 1331 || bfd_bread (syms, amt, abfd) != amt)
252b5132
RH
1332 {
1333 free (syms);
1334 return false;
1335 }
1336#endif
1337
1338 obj_aout_external_syms (abfd) = syms;
1339 obj_aout_external_sym_count (abfd) = count;
1340 }
0ef5a5bd 1341
252b5132
RH
1342 if (obj_aout_external_strings (abfd) == NULL
1343 && exec_hdr (abfd)->a_syms != 0)
1344 {
1345 unsigned char string_chars[BYTES_IN_WORD];
1346 bfd_size_type stringsize;
1347 char *strings;
dc810e39 1348 bfd_size_type amt = BYTES_IN_WORD;
252b5132
RH
1349
1350 /* Get the size of the strings. */
1351 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
dc810e39 1352 || bfd_bread ((PTR) string_chars, amt, abfd) != amt)
252b5132
RH
1353 return false;
1354 stringsize = GET_WORD (abfd, string_chars);
1355
1356#ifdef USE_MMAP
82e51918
AM
1357 if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
1358 &obj_aout_string_window (abfd), true))
252b5132
RH
1359 return false;
1360 strings = (char *) obj_aout_string_window (abfd).data;
1361#else
dc810e39 1362 strings = (char *) bfd_malloc (stringsize + 1);
252b5132
RH
1363 if (strings == NULL)
1364 return false;
1365
1366 /* Skip space for the string count in the buffer for convenience
1367 when using indexes. */
dc810e39
AM
1368 amt = stringsize - BYTES_IN_WORD;
1369 if (bfd_bread (strings + BYTES_IN_WORD, amt, abfd) != amt)
252b5132
RH
1370 {
1371 free (strings);
1372 return false;
1373 }
1374#endif
1375
1376 /* Ensure that a zero index yields an empty string. */
1377 strings[0] = '\0';
1378
1379 strings[stringsize - 1] = 0;
1380
1381 obj_aout_external_strings (abfd) = strings;
1382 obj_aout_external_string_size (abfd) = stringsize;
1383 }
1384
1385 return true;
1386}
1387
1388/* Translate an a.out symbol into a BFD symbol. The desc, other, type
1389 and symbol->value fields of CACHE_PTR will be set from the a.out
1390 nlist structure. This function is responsible for setting
1391 symbol->flags and symbol->section, and adjusting symbol->value. */
1392
1393static boolean
1394translate_from_native_sym_flags (abfd, cache_ptr)
1395 bfd *abfd;
1396 aout_symbol_type *cache_ptr;
1397{
1398 flagword visible;
1399
1400 if ((cache_ptr->type & N_STAB) != 0
1401 || cache_ptr->type == N_FN)
1402 {
1403 asection *sec;
1404
1405 /* This is a debugging symbol. */
252b5132
RH
1406 cache_ptr->symbol.flags = BSF_DEBUGGING;
1407
1408 /* Work out the symbol section. */
1409 switch (cache_ptr->type & N_TYPE)
1410 {
1411 case N_TEXT:
1412 case N_FN:
1413 sec = obj_textsec (abfd);
1414 break;
1415 case N_DATA:
1416 sec = obj_datasec (abfd);
1417 break;
1418 case N_BSS:
1419 sec = obj_bsssec (abfd);
1420 break;
1421 default:
1422 case N_ABS:
1423 sec = bfd_abs_section_ptr;
1424 break;
1425 }
1426
1427 cache_ptr->symbol.section = sec;
1428 cache_ptr->symbol.value -= sec->vma;
1429
1430 return true;
1431 }
1432
1433 /* Get the default visibility. This does not apply to all types, so
1434 we just hold it in a local variable to use if wanted. */
1435 if ((cache_ptr->type & N_EXT) == 0)
1436 visible = BSF_LOCAL;
1437 else
1438 visible = BSF_GLOBAL;
1439
1440 switch (cache_ptr->type)
1441 {
1442 default:
1443 case N_ABS: case N_ABS | N_EXT:
1444 cache_ptr->symbol.section = bfd_abs_section_ptr;
1445 cache_ptr->symbol.flags = visible;
1446 break;
1447
1448 case N_UNDF | N_EXT:
1449 if (cache_ptr->symbol.value != 0)
1450 {
1451 /* This is a common symbol. */
1452 cache_ptr->symbol.flags = BSF_GLOBAL;
1453 cache_ptr->symbol.section = bfd_com_section_ptr;
1454 }
1455 else
1456 {
1457 cache_ptr->symbol.flags = 0;
1458 cache_ptr->symbol.section = bfd_und_section_ptr;
1459 }
1460 break;
1461
1462 case N_TEXT: case N_TEXT | N_EXT:
1463 cache_ptr->symbol.section = obj_textsec (abfd);
1464 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1465 cache_ptr->symbol.flags = visible;
1466 break;
1467
1468 /* N_SETV symbols used to represent set vectors placed in the
1469 data section. They are no longer generated. Theoretically,
1470 it was possible to extract the entries and combine them with
1471 new ones, although I don't know if that was ever actually
1472 done. Unless that feature is restored, treat them as data
1473 symbols. */
1474 case N_SETV: case N_SETV | N_EXT:
1475 case N_DATA: case N_DATA | N_EXT:
1476 cache_ptr->symbol.section = obj_datasec (abfd);
1477 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1478 cache_ptr->symbol.flags = visible;
1479 break;
1480
1481 case N_BSS: case N_BSS | N_EXT:
1482 cache_ptr->symbol.section = obj_bsssec (abfd);
1483 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1484 cache_ptr->symbol.flags = visible;
1485 break;
1486
1487 case N_SETA: case N_SETA | N_EXT:
1488 case N_SETT: case N_SETT | N_EXT:
1489 case N_SETD: case N_SETD | N_EXT:
1490 case N_SETB: case N_SETB | N_EXT:
1491 {
1492 /* This code is no longer needed. It used to be used to make
1493 the linker handle set symbols, but they are now handled in
1494 the add_symbols routine instead. */
1495#if 0
1496 asection *section;
1497 arelent_chain *reloc;
1498 asection *into_section;
dc810e39 1499 bfd_size_type amt;
252b5132
RH
1500
1501 /* This is a set symbol. The name of the symbol is the name
1502 of the set (e.g., __CTOR_LIST__). The value of the symbol
1503 is the value to add to the set. We create a section with
1504 the same name as the symbol, and add a reloc to insert the
1505 appropriate value into the section.
1506
1507 This action is actually obsolete; it used to make the
1508 linker do the right thing, but the linker no longer uses
1509 this function. */
1510
1511 section = bfd_get_section_by_name (abfd, cache_ptr->symbol.name);
1512 if (section == NULL)
1513 {
1514 char *copy;
1515
dc810e39
AM
1516 amt = strlen (cache_ptr->symbol.name) + 1;
1517 copy = bfd_alloc (abfd, amt);
252b5132
RH
1518 if (copy == NULL)
1519 return false;
1520
1521 strcpy (copy, cache_ptr->symbol.name);
1522 section = bfd_make_section (abfd, copy);
1523 if (section == NULL)
1524 return false;
1525 }
1526
dc810e39
AM
1527 amt = sizeof (arelent_chain);
1528 reloc = (arelent_chain *) bfd_alloc (abfd, amt);
252b5132
RH
1529 if (reloc == NULL)
1530 return false;
1531
1532 /* Build a relocation entry for the constructor. */
1533 switch (cache_ptr->type & N_TYPE)
1534 {
1535 case N_SETA:
1536 into_section = bfd_abs_section_ptr;
1537 cache_ptr->type = N_ABS;
1538 break;
1539 case N_SETT:
1540 into_section = obj_textsec (abfd);
1541 cache_ptr->type = N_TEXT;
1542 break;
1543 case N_SETD:
1544 into_section = obj_datasec (abfd);
1545 cache_ptr->type = N_DATA;
1546 break;
1547 case N_SETB:
1548 into_section = obj_bsssec (abfd);
1549 cache_ptr->type = N_BSS;
1550 break;
1551 }
1552
1553 /* Build a relocation pointing into the constructor section
1554 pointing at the symbol in the set vector specified. */
1555 reloc->relent.addend = cache_ptr->symbol.value;
1556 cache_ptr->symbol.section = into_section;
1557 reloc->relent.sym_ptr_ptr = into_section->symbol_ptr_ptr;
1558
1559 /* We modify the symbol to belong to a section depending upon
1560 the name of the symbol, and add to the size of the section
1561 to contain a pointer to the symbol. Build a reloc entry to
1562 relocate to this symbol attached to this section. */
1563 section->flags = SEC_CONSTRUCTOR | SEC_RELOC;
1564
1565 section->reloc_count++;
1566 section->alignment_power = 2;
1567
1568 reloc->next = section->constructor_chain;
1569 section->constructor_chain = reloc;
1570 reloc->relent.address = section->_raw_size;
1571 section->_raw_size += BYTES_IN_WORD;
1572
923f08ff 1573 reloc->relent.howto = CTOR_TABLE_RELOC_HOWTO (abfd);
252b5132
RH
1574
1575#endif /* 0 */
1576
1577 switch (cache_ptr->type & N_TYPE)
1578 {
1579 case N_SETA:
1580 cache_ptr->symbol.section = bfd_abs_section_ptr;
1581 break;
1582 case N_SETT:
1583 cache_ptr->symbol.section = obj_textsec (abfd);
1584 break;
1585 case N_SETD:
1586 cache_ptr->symbol.section = obj_datasec (abfd);
1587 break;
1588 case N_SETB:
1589 cache_ptr->symbol.section = obj_bsssec (abfd);
1590 break;
1591 }
1592
1593 cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
1594 }
1595 break;
1596
1597 case N_WARNING:
1598 /* This symbol is the text of a warning message. The next
1599 symbol is the symbol to associate the warning with. If a
1600 reference is made to that symbol, a warning is issued. */
1601 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
1602 cache_ptr->symbol.section = bfd_abs_section_ptr;
1603 break;
1604
1605 case N_INDR: case N_INDR | N_EXT:
1606 /* An indirect symbol. This consists of two symbols in a row.
1607 The first symbol is the name of the indirection. The second
1608 symbol is the name of the target. A reference to the first
1609 symbol becomes a reference to the second. */
1610 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible;
1611 cache_ptr->symbol.section = bfd_ind_section_ptr;
1612 break;
1613
1614 case N_WEAKU:
1615 cache_ptr->symbol.section = bfd_und_section_ptr;
1616 cache_ptr->symbol.flags = BSF_WEAK;
1617 break;
1618
1619 case N_WEAKA:
1620 cache_ptr->symbol.section = bfd_abs_section_ptr;
1621 cache_ptr->symbol.flags = BSF_WEAK;
1622 break;
1623
1624 case N_WEAKT:
1625 cache_ptr->symbol.section = obj_textsec (abfd);
1626 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1627 cache_ptr->symbol.flags = BSF_WEAK;
1628 break;
1629
1630 case N_WEAKD:
1631 cache_ptr->symbol.section = obj_datasec (abfd);
1632 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1633 cache_ptr->symbol.flags = BSF_WEAK;
1634 break;
1635
1636 case N_WEAKB:
1637 cache_ptr->symbol.section = obj_bsssec (abfd);
1638 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1639 cache_ptr->symbol.flags = BSF_WEAK;
1640 break;
1641 }
1642
1643 return true;
1644}
1645
1646/* Set the fields of SYM_POINTER according to CACHE_PTR. */
1647
1648static boolean
1649translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
1650 bfd *abfd;
1651 asymbol *cache_ptr;
1652 struct external_nlist *sym_pointer;
1653{
1654 bfd_vma value = cache_ptr->value;
1655 asection *sec;
1656 bfd_vma off;
1657
1658 /* Mask out any existing type bits in case copying from one section
1659 to another. */
1660 sym_pointer->e_type[0] &= ~N_TYPE;
1661
1662 sec = bfd_get_section (cache_ptr);
1663 off = 0;
1664
1665 if (sec == NULL)
1666 {
1667 /* This case occurs, e.g., for the *DEBUG* section of a COFF
1668 file. */
1669 (*_bfd_error_handler)
1670 (_("%s: can not represent section for symbol `%s' in a.out object file format"),
0ef5a5bd 1671 bfd_get_filename (abfd),
252b5132
RH
1672 cache_ptr->name != NULL ? cache_ptr->name : _("*unknown*"));
1673 bfd_set_error (bfd_error_nonrepresentable_section);
1674 return false;
1675 }
1676
1677 if (sec->output_section != NULL)
1678 {
1679 off = sec->output_offset;
1680 sec = sec->output_section;
1681 }
1682
1683 if (bfd_is_abs_section (sec))
1684 sym_pointer->e_type[0] |= N_ABS;
1685 else if (sec == obj_textsec (abfd))
1686 sym_pointer->e_type[0] |= N_TEXT;
1687 else if (sec == obj_datasec (abfd))
1688 sym_pointer->e_type[0] |= N_DATA;
1689 else if (sec == obj_bsssec (abfd))
1690 sym_pointer->e_type[0] |= N_BSS;
1691 else if (bfd_is_und_section (sec))
1692 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1693 else if (bfd_is_ind_section (sec))
1694 sym_pointer->e_type[0] = N_INDR;
1695 else if (bfd_is_com_section (sec))
1696 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1697 else
1698 {
1699 (*_bfd_error_handler)
1700 (_("%s: can not represent section `%s' in a.out object file format"),
1701 bfd_get_filename (abfd), bfd_get_section_name (abfd, sec));
1702 bfd_set_error (bfd_error_nonrepresentable_section);
1703 return false;
1704 }
1705
f7c33884 1706 /* Turn the symbol from section relative to absolute again. */
252b5132
RH
1707 value += sec->vma + off;
1708
1709 if ((cache_ptr->flags & BSF_WARNING) != 0)
1710 sym_pointer->e_type[0] = N_WARNING;
1711
1712 if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
1713 sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
1714 else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
1715 sym_pointer->e_type[0] |= N_EXT;
930d924d
L
1716 else if ((cache_ptr->flags & BSF_LOCAL) != 0)
1717 sym_pointer->e_type[0] &= ~N_EXT;
252b5132
RH
1718
1719 if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0)
1720 {
1721 int type = ((aout_symbol_type *) cache_ptr)->type;
f7c33884 1722
252b5132
RH
1723 switch (type)
1724 {
1725 case N_ABS: type = N_SETA; break;
1726 case N_TEXT: type = N_SETT; break;
1727 case N_DATA: type = N_SETD; break;
1728 case N_BSS: type = N_SETB; break;
1729 }
1730 sym_pointer->e_type[0] = type;
1731 }
1732
1733 if ((cache_ptr->flags & BSF_WEAK) != 0)
1734 {
1735 int type;
1736
1737 switch (sym_pointer->e_type[0] & N_TYPE)
1738 {
1739 default:
1740 case N_ABS: type = N_WEAKA; break;
1741 case N_TEXT: type = N_WEAKT; break;
1742 case N_DATA: type = N_WEAKD; break;
1743 case N_BSS: type = N_WEAKB; break;
1744 case N_UNDF: type = N_WEAKU; break;
1745 }
1746 sym_pointer->e_type[0] = type;
1747 }
1748
923f08ff 1749 PUT_WORD (abfd, value, sym_pointer->e_value);
252b5132
RH
1750
1751 return true;
1752}
1753\f
0ef5a5bd 1754/* Native-level interface to symbols. */
252b5132
RH
1755
1756asymbol *
1757NAME(aout,make_empty_symbol) (abfd)
1758 bfd *abfd;
1759{
dc810e39
AM
1760 bfd_size_type amt = sizeof (aout_symbol_type);
1761 aout_symbol_type *new = (aout_symbol_type *) bfd_zalloc (abfd, amt);
252b5132
RH
1762 if (!new)
1763 return NULL;
1764 new->symbol.the_bfd = abfd;
1765
1766 return &new->symbol;
1767}
1768
1769/* Translate a set of internal symbols into external symbols. */
1770
1771boolean
1772NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic)
1773 bfd *abfd;
1774 aout_symbol_type *in;
1775 struct external_nlist *ext;
1776 bfd_size_type count;
1777 char *str;
1778 bfd_size_type strsize;
1779 boolean dynamic;
1780{
1781 struct external_nlist *ext_end;
1782
1783 ext_end = ext + count;
1784 for (; ext < ext_end; ext++, in++)
1785 {
1786 bfd_vma x;
1787
1788 x = GET_WORD (abfd, ext->e_strx);
1789 in->symbol.the_bfd = abfd;
1790
1791 /* For the normal symbols, the zero index points at the number
1792 of bytes in the string table but is to be interpreted as the
1793 null string. For the dynamic symbols, the number of bytes in
1794 the string table is stored in the __DYNAMIC structure and the
1795 zero index points at an actual string. */
1796 if (x == 0 && ! dynamic)
1797 in->symbol.name = "";
1798 else if (x < strsize)
1799 in->symbol.name = str + x;
1800 else
1801 return false;
1802
1803 in->symbol.value = GET_SWORD (abfd, ext->e_value);
dc810e39
AM
1804 in->desc = H_GET_16 (abfd, ext->e_desc);
1805 in->other = H_GET_8 (abfd, ext->e_other);
1806 in->type = H_GET_8 (abfd, ext->e_type);
252b5132
RH
1807 in->symbol.udata.p = NULL;
1808
1809 if (! translate_from_native_sym_flags (abfd, in))
1810 return false;
1811
1812 if (dynamic)
1813 in->symbol.flags |= BSF_DYNAMIC;
1814 }
1815
1816 return true;
1817}
1818
1819/* We read the symbols into a buffer, which is discarded when this
1820 function exits. We read the strings into a buffer large enough to
0ef5a5bd 1821 hold them all plus all the cached symbol entries. */
252b5132
RH
1822
1823boolean
1824NAME(aout,slurp_symbol_table) (abfd)
1825 bfd *abfd;
1826{
1827 struct external_nlist *old_external_syms;
1828 aout_symbol_type *cached;
dc810e39 1829 bfd_size_type cached_size;
252b5132 1830
f7c33884 1831 /* If there's no work to be done, don't do any. */
252b5132
RH
1832 if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
1833 return true;
1834
1835 old_external_syms = obj_aout_external_syms (abfd);
1836
1837 if (! aout_get_external_symbols (abfd))
1838 return false;
1839
dc810e39
AM
1840 cached_size = obj_aout_external_sym_count (abfd);
1841 cached_size *= sizeof (aout_symbol_type);
9bab7074 1842 cached = (aout_symbol_type *) bfd_zmalloc (cached_size);
252b5132
RH
1843 if (cached == NULL && cached_size != 0)
1844 return false;
252b5132
RH
1845
1846 /* Convert from external symbol information to internal. */
1847 if (! (NAME(aout,translate_symbol_table)
1848 (abfd, cached,
1849 obj_aout_external_syms (abfd),
1850 obj_aout_external_sym_count (abfd),
1851 obj_aout_external_strings (abfd),
1852 obj_aout_external_string_size (abfd),
1853 false)))
1854 {
1855 free (cached);
1856 return false;
1857 }
1858
1859 bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
1860
1861 obj_aout_symbols (abfd) = cached;
1862
1863 /* It is very likely that anybody who calls this function will not
1864 want the external symbol information, so if it was allocated
1865 because of our call to aout_get_external_symbols, we free it up
1866 right away to save space. */
1867 if (old_external_syms == (struct external_nlist *) NULL
1868 && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
1869 {
1870#ifdef USE_MMAP
1871 bfd_free_window (&obj_aout_sym_window (abfd));
1872#else
1873 free (obj_aout_external_syms (abfd));
1874#endif
1875 obj_aout_external_syms (abfd) = NULL;
1876 }
1877
1878 return true;
1879}
1880\f
1881/* We use a hash table when writing out symbols so that we only write
1882 out a particular string once. This helps particularly when the
1883 linker writes out stabs debugging entries, because each different
1884 contributing object file tends to have many duplicate stabs
1885 strings.
1886
1887 This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
1888 if BFD_TRADITIONAL_FORMAT is set. */
1889
1890static bfd_size_type add_to_stringtab
1891 PARAMS ((bfd *, struct bfd_strtab_hash *, const char *, boolean));
1892static boolean emit_stringtab PARAMS ((bfd *, struct bfd_strtab_hash *));
1893
1894/* Get the index of a string in a strtab, adding it if it is not
1895 already present. */
1896
1897static INLINE bfd_size_type
1898add_to_stringtab (abfd, tab, str, copy)
1899 bfd *abfd;
1900 struct bfd_strtab_hash *tab;
1901 const char *str;
1902 boolean copy;
1903{
1904 boolean hash;
1905 bfd_size_type index;
1906
1907 /* An index of 0 always means the empty string. */
1908 if (str == 0 || *str == '\0')
1909 return 0;
1910
1911 /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
1912 doesn't understand a hashed string table. */
1913 hash = true;
1914 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
1915 hash = false;
1916
1917 index = _bfd_stringtab_add (tab, str, hash, copy);
1918
1919 if (index != (bfd_size_type) -1)
1920 {
1921 /* Add BYTES_IN_WORD to the return value to account for the
1922 space taken up by the string table size. */
1923 index += BYTES_IN_WORD;
1924 }
1925
1926 return index;
1927}
1928
1929/* Write out a strtab. ABFD is already at the right location in the
1930 file. */
1931
1932static boolean
1933emit_stringtab (abfd, tab)
1934 register bfd *abfd;
1935 struct bfd_strtab_hash *tab;
1936{
1937 bfd_byte buffer[BYTES_IN_WORD];
dc810e39 1938 bfd_size_type amt = BYTES_IN_WORD;
252b5132
RH
1939
1940 /* The string table starts with the size. */
1941 PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
dc810e39 1942 if (bfd_bwrite ((PTR) buffer, amt, abfd) != amt)
252b5132
RH
1943 return false;
1944
1945 return _bfd_stringtab_emit (abfd, tab);
1946}
1947\f
1948boolean
1949NAME(aout,write_syms) (abfd)
1950 bfd *abfd;
1951{
1952 unsigned int count ;
1953 asymbol **generic = bfd_get_outsymbols (abfd);
1954 struct bfd_strtab_hash *strtab;
1955
1956 strtab = _bfd_stringtab_init ();
1957 if (strtab == NULL)
1958 return false;
1959
1960 for (count = 0; count < bfd_get_symcount (abfd); count++)
1961 {
1962 asymbol *g = generic[count];
1963 bfd_size_type indx;
1964 struct external_nlist nsp;
dc810e39 1965 bfd_size_type amt;
252b5132
RH
1966
1967 indx = add_to_stringtab (abfd, strtab, g->name, false);
1968 if (indx == (bfd_size_type) -1)
1969 goto error_return;
1970 PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
1971
923f08ff 1972 if (bfd_asymbol_flavour (g) == abfd->xvec->flavour)
252b5132 1973 {
923f08ff
AM
1974 H_PUT_16 (abfd, aout_symbol (g)->desc, nsp.e_desc);
1975 H_PUT_8 (abfd, aout_symbol (g)->other, nsp.e_other);
1976 H_PUT_8 (abfd, aout_symbol (g)->type, nsp.e_type);
252b5132
RH
1977 }
1978 else
1979 {
dc810e39
AM
1980 H_PUT_16 (abfd, 0, nsp.e_desc);
1981 H_PUT_8 (abfd, 0, nsp.e_other);
1982 H_PUT_8 (abfd, 0, nsp.e_type);
252b5132
RH
1983 }
1984
1985 if (! translate_to_native_sym_flags (abfd, g, &nsp))
1986 goto error_return;
1987
dc810e39
AM
1988 amt = EXTERNAL_NLIST_SIZE;
1989 if (bfd_bwrite ((PTR) &nsp, amt, abfd) != amt)
252b5132
RH
1990 goto error_return;
1991
1992 /* NB: `KEEPIT' currently overlays `udata.p', so set this only
1993 here, at the end. */
1994 g->KEEPIT = count;
1995 }
1996
1997 if (! emit_stringtab (abfd, strtab))
1998 goto error_return;
1999
2000 _bfd_stringtab_free (strtab);
2001
2002 return true;
2003
2004error_return:
2005 _bfd_stringtab_free (strtab);
2006 return false;
2007}
252b5132
RH
2008\f
2009long
2010NAME(aout,get_symtab) (abfd, location)
2011 bfd *abfd;
2012 asymbol **location;
2013{
2014 unsigned int counter = 0;
2015 aout_symbol_type *symbase;
2016
beb0d161 2017 if (!NAME(aout,slurp_symbol_table) (abfd))
252b5132
RH
2018 return -1;
2019
923f08ff
AM
2020 for (symbase = obj_aout_symbols (abfd);
2021 counter++ < bfd_get_symcount (abfd);
2022 )
2023 *(location++) = (asymbol *) (symbase++);
252b5132
RH
2024 *location++ =0;
2025 return bfd_get_symcount (abfd);
2026}
252b5132 2027\f
f7c33884 2028/* Standard reloc stuff. */
0ef5a5bd 2029/* Output standard relocation information to a file in target byte order. */
252b5132
RH
2030
2031extern void NAME(aout,swap_std_reloc_out)
2032 PARAMS ((bfd *, arelent *, struct reloc_std_external *));
2033
2034void
2035NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
2036 bfd *abfd;
2037 arelent *g;
2038 struct reloc_std_external *natptr;
2039{
2040 int r_index;
2041 asymbol *sym = *(g->sym_ptr_ptr);
2042 int r_extern;
2043 unsigned int r_length;
2044 int r_pcrel;
2045 int r_baserel, r_jmptable, r_relative;
2046 asection *output_section = sym->section->output_section;
2047
923f08ff 2048 PUT_WORD (abfd, g->address, natptr->r_address);
252b5132 2049
f7c33884
NC
2050 r_length = g->howto->size ; /* Size as a power of two. */
2051 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
252b5132
RH
2052 /* XXX This relies on relocs coming from a.out files. */
2053 r_baserel = (g->howto->type & 8) != 0;
2054 r_jmptable = (g->howto->type & 16) != 0;
2055 r_relative = (g->howto->type & 32) != 0;
2056
2057#if 0
2058 /* For a standard reloc, the addend is in the object file. */
2059 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
2060#endif
2061
f7c33884 2062 /* Name was clobbered by aout_write_syms to be symbol index. */
252b5132
RH
2063
2064 /* If this relocation is relative to a symbol then set the
2065 r_index to the symbols index, and the r_extern bit.
2066
2067 Absolute symbols can come in in two ways, either as an offset
2068 from the abs section, or as a symbol which has an abs value.
f7c33884 2069 check for that here. */
252b5132 2070
252b5132
RH
2071 if (bfd_is_com_section (output_section)
2072 || bfd_is_abs_section (output_section)
2073 || bfd_is_und_section (output_section))
2074 {
2075 if (bfd_abs_section_ptr->symbol == sym)
f7c33884
NC
2076 {
2077 /* Whoops, looked like an abs symbol, but is
2078 really an offset from the abs section. */
2079 r_index = N_ABS;
2080 r_extern = 0;
2081 }
252b5132 2082 else
f7c33884
NC
2083 {
2084 /* Fill in symbol. */
2085 r_extern = 1;
2086 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2087 }
252b5132
RH
2088 }
2089 else
2090 {
f7c33884 2091 /* Just an ordinary section. */
252b5132
RH
2092 r_extern = 0;
2093 r_index = output_section->target_index;
2094 }
2095
f7c33884 2096 /* Now the fun stuff. */
923f08ff
AM
2097 if (bfd_header_big_endian (abfd))
2098 {
252b5132
RH
2099 natptr->r_index[0] = r_index >> 16;
2100 natptr->r_index[1] = r_index >> 8;
2101 natptr->r_index[2] = r_index;
923f08ff
AM
2102 natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
2103 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
2104 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
2105 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
2106 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
2107 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
2108 }
2109 else
2110 {
2111 natptr->r_index[2] = r_index >> 16;
2112 natptr->r_index[1] = r_index >> 8;
2113 natptr->r_index[0] = r_index;
2114 natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
2115 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
2116 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
2117 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
2118 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
2119 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
2120 }
252b5132
RH
2121}
2122
f7c33884 2123/* Extended stuff. */
0ef5a5bd 2124/* Output extended relocation information to a file in target byte order. */
252b5132
RH
2125
2126extern void NAME(aout,swap_ext_reloc_out)
2127 PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
2128
2129void
2130NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
2131 bfd *abfd;
2132 arelent *g;
2133 register struct reloc_ext_external *natptr;
2134{
2135 int r_index;
2136 int r_extern;
2137 unsigned int r_type;
dc810e39 2138 bfd_vma r_addend;
252b5132
RH
2139 asymbol *sym = *(g->sym_ptr_ptr);
2140 asection *output_section = sym->section->output_section;
2141
2142 PUT_WORD (abfd, g->address, natptr->r_address);
2143
2144 r_type = (unsigned int) g->howto->type;
2145
2146 r_addend = g->addend;
2147 if ((sym->flags & BSF_SECTION_SYM) != 0)
2148 r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma;
2149
2150 /* If this relocation is relative to a symbol then set the
2151 r_index to the symbols index, and the r_extern bit.
2152
2153 Absolute symbols can come in in two ways, either as an offset
2154 from the abs section, or as a symbol which has an abs value.
2155 check for that here. */
252b5132
RH
2156 if (bfd_is_abs_section (bfd_get_section (sym)))
2157 {
2158 r_extern = 0;
2159 r_index = N_ABS;
2160 }
2161 else if ((sym->flags & BSF_SECTION_SYM) == 0)
2162 {
2163 if (bfd_is_und_section (bfd_get_section (sym))
2164 || (sym->flags & BSF_GLOBAL) != 0)
2165 r_extern = 1;
2166 else
2167 r_extern = 0;
2168 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2169 }
2170 else
2171 {
f7c33884 2172 /* Just an ordinary section. */
252b5132
RH
2173 r_extern = 0;
2174 r_index = output_section->target_index;
2175 }
2176
f7c33884 2177 /* Now the fun stuff. */
923f08ff
AM
2178 if (bfd_header_big_endian (abfd))
2179 {
2180 natptr->r_index[0] = r_index >> 16;
2181 natptr->r_index[1] = r_index >> 8;
2182 natptr->r_index[2] = r_index;
2183 natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
2184 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
2185 }
2186 else
2187 {
2188 natptr->r_index[2] = r_index >> 16;
2189 natptr->r_index[1] = r_index >> 8;
2190 natptr->r_index[0] = r_index;
2191 natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
2192 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE));
2193 }
252b5132
RH
2194
2195 PUT_WORD (abfd, r_addend, natptr->r_addend);
2196}
2197
2198/* BFD deals internally with all things based from the section they're
2199 in. so, something in 10 bytes into a text section with a base of
2200 50 would have a symbol (.text+10) and know .text vma was 50.
2201
2202 Aout keeps all it's symbols based from zero, so the symbol would
2203 contain 60. This macro subs the base of each section from the value
923f08ff
AM
2204 to give the true offset from the section. */
2205
2206#define MOVE_ADDRESS(ad) \
2207 if (r_extern) \
2208 { \
2209 /* Undefined symbol. */ \
2210 cache_ptr->sym_ptr_ptr = symbols + r_index; \
252b5132 2211 cache_ptr->addend = ad; \
252b5132 2212 } \
923f08ff
AM
2213 else \
2214 { \
2215 /* Defined, section relative. Replace symbol with pointer to \
2216 symbol which points to section. */ \
2217 switch (r_index) \
2218 { \
2219 case N_TEXT: \
2220 case N_TEXT | N_EXT: \
2221 cache_ptr->sym_ptr_ptr = obj_textsec (abfd)->symbol_ptr_ptr; \
2222 cache_ptr->addend = ad - su->textsec->vma; \
2223 break; \
2224 case N_DATA: \
2225 case N_DATA | N_EXT: \
2226 cache_ptr->sym_ptr_ptr = obj_datasec (abfd)->symbol_ptr_ptr; \
2227 cache_ptr->addend = ad - su->datasec->vma; \
2228 break; \
2229 case N_BSS: \
2230 case N_BSS | N_EXT: \
2231 cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr; \
2232 cache_ptr->addend = ad - su->bsssec->vma; \
2233 break; \
2234 default: \
2235 case N_ABS: \
2236 case N_ABS | N_EXT: \
2237 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
2238 cache_ptr->addend = ad; \
2239 break; \
2240 } \
2241 }
252b5132
RH
2242
2243void
2244NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2245 bfd *abfd;
2246 struct reloc_ext_external *bytes;
2247 arelent *cache_ptr;
2248 asymbol **symbols;
2249 bfd_size_type symcount;
2250{
2251 unsigned int r_index;
2252 int r_extern;
2253 unsigned int r_type;
2254 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2255
2256 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2257
f7c33884 2258 /* Now the fun stuff. */
923f08ff
AM
2259 if (bfd_header_big_endian (abfd))
2260 {
2261 r_index = ((bytes->r_index[0] << 16)
2262 | (bytes->r_index[1] << 8)
2263 | bytes->r_index[2]);
2264 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2265 r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2266 >> RELOC_EXT_BITS_TYPE_SH_BIG);
2267 }
2268 else
2269 {
2270 r_index = ((bytes->r_index[2] << 16)
2271 | (bytes->r_index[1] << 8)
2272 | bytes->r_index[0]);
2273 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2274 r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2275 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
2276 }
252b5132
RH
2277
2278 cache_ptr->howto = howto_table_ext + r_type;
2279
2280 /* Base relative relocs are always against the symbol table,
2281 regardless of the setting of r_extern. r_extern just reflects
2282 whether the symbol the reloc is against is local or global. */
2283 if (r_type == RELOC_BASE10
2284 || r_type == RELOC_BASE13
2285 || r_type == RELOC_BASE22)
2286 r_extern = 1;
2287
2288 if (r_extern && r_index > symcount)
2289 {
2290 /* We could arrange to return an error, but it might be useful
2291 to see the file even if it is bad. */
2292 r_extern = 0;
2293 r_index = N_ABS;
2294 }
2295
923f08ff 2296 MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
252b5132
RH
2297}
2298
2299void
2300NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2301 bfd *abfd;
2302 struct reloc_std_external *bytes;
2303 arelent *cache_ptr;
2304 asymbol **symbols;
2305 bfd_size_type symcount;
2306{
2307 unsigned int r_index;
2308 int r_extern;
2309 unsigned int r_length;
2310 int r_pcrel;
2311 int r_baserel, r_jmptable, r_relative;
2312 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2313 unsigned int howto_idx;
2314
dc810e39 2315 cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
252b5132 2316
f7c33884 2317 /* Now the fun stuff. */
923f08ff
AM
2318 if (bfd_header_big_endian (abfd))
2319 {
2320 r_index = ((bytes->r_index[0] << 16)
2321 | (bytes->r_index[1] << 8)
2322 | bytes->r_index[2]);
2323 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2324 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2325 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2326 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2327 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2328 r_length = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2329 >> RELOC_STD_BITS_LENGTH_SH_BIG);
2330 }
2331 else
2332 {
2333 r_index = ((bytes->r_index[2] << 16)
2334 | (bytes->r_index[1] << 8)
2335 | bytes->r_index[0]);
2336 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2337 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2338 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2339 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2340 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2341 r_length = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2342 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
2343 }
252b5132 2344
923f08ff
AM
2345 howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
2346 + 16 * r_jmptable + 32 * r_relative);
252b5132
RH
2347 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
2348 cache_ptr->howto = howto_table_std + howto_idx;
2349 BFD_ASSERT (cache_ptr->howto->type != (unsigned int) -1);
2350
2351 /* Base relative relocs are always against the symbol table,
2352 regardless of the setting of r_extern. r_extern just reflects
2353 whether the symbol the reloc is against is local or global. */
2354 if (r_baserel)
2355 r_extern = 1;
2356
2357 if (r_extern && r_index > symcount)
2358 {
2359 /* We could arrange to return an error, but it might be useful
2360 to see the file even if it is bad. */
2361 r_extern = 0;
2362 r_index = N_ABS;
2363 }
2364
923f08ff 2365 MOVE_ADDRESS (0);
252b5132
RH
2366}
2367
2368/* Read and swap the relocs for a section. */
2369
2370boolean
2371NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
2372 bfd *abfd;
2373 sec_ptr asect;
2374 asymbol **symbols;
2375{
dc810e39 2376 bfd_size_type count;
252b5132
RH
2377 bfd_size_type reloc_size;
2378 PTR relocs;
2379 arelent *reloc_cache;
2380 size_t each_size;
2381 unsigned int counter = 0;
2382 arelent *cache_ptr;
dc810e39 2383 bfd_size_type amt;
252b5132
RH
2384
2385 if (asect->relocation)
2386 return true;
2387
2388 if (asect->flags & SEC_CONSTRUCTOR)
2389 return true;
2390
2391 if (asect == obj_datasec (abfd))
923f08ff 2392 reloc_size = exec_hdr (abfd)->a_drsize;
252b5132 2393 else if (asect == obj_textsec (abfd))
923f08ff 2394 reloc_size = exec_hdr (abfd)->a_trsize;
252b5132
RH
2395 else if (asect == obj_bsssec (abfd))
2396 reloc_size = 0;
2397 else
2398 {
2399 bfd_set_error (bfd_error_invalid_operation);
2400 return false;
2401 }
2402
2403 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
2404 return false;
2405
2406 each_size = obj_reloc_entry_size (abfd);
2407
2408 count = reloc_size / each_size;
2409
dc810e39 2410 amt = count * sizeof (arelent);
9bab7074 2411 reloc_cache = (arelent *) bfd_zmalloc (amt);
252b5132
RH
2412 if (reloc_cache == NULL && count != 0)
2413 return false;
252b5132 2414
dc810e39 2415 relocs = bfd_malloc (reloc_size);
252b5132
RH
2416 if (relocs == NULL && reloc_size != 0)
2417 {
2418 free (reloc_cache);
2419 return false;
2420 }
2421
dc810e39 2422 if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
252b5132
RH
2423 {
2424 free (relocs);
2425 free (reloc_cache);
2426 return false;
2427 }
2428
2429 cache_ptr = reloc_cache;
2430 if (each_size == RELOC_EXT_SIZE)
2431 {
dc810e39 2432 struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
252b5132
RH
2433
2434 for (; counter < count; counter++, rptr++, cache_ptr++)
1642229e 2435 MY_swap_ext_reloc_in (abfd, rptr, cache_ptr, symbols,
dc810e39 2436 (bfd_size_type) bfd_get_symcount (abfd));
252b5132
RH
2437 }
2438 else
2439 {
dc810e39 2440 struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
252b5132
RH
2441
2442 for (; counter < count; counter++, rptr++, cache_ptr++)
2443 MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
dc810e39 2444 (bfd_size_type) bfd_get_symcount (abfd));
252b5132
RH
2445 }
2446
2447 free (relocs);
2448
2449 asect->relocation = reloc_cache;
2450 asect->reloc_count = cache_ptr - reloc_cache;
2451
2452 return true;
2453}
2454
2455/* Write out a relocation section into an object file. */
2456
2457boolean
2458NAME(aout,squirt_out_relocs) (abfd, section)
2459 bfd *abfd;
2460 asection *section;
2461{
2462 arelent **generic;
2463 unsigned char *native, *natptr;
2464 size_t each_size;
2465
2466 unsigned int count = section->reloc_count;
dc810e39 2467 bfd_size_type natsize;
252b5132
RH
2468
2469 if (count == 0 || section->orelocation == NULL)
2470 return true;
2471
2472 each_size = obj_reloc_entry_size (abfd);
dc810e39 2473 natsize = (bfd_size_type) each_size * count;
252b5132
RH
2474 native = (unsigned char *) bfd_zalloc (abfd, natsize);
2475 if (!native)
2476 return false;
2477
2478 generic = section->orelocation;
2479
2480 if (each_size == RELOC_EXT_SIZE)
2481 {
2482 for (natptr = native;
2483 count != 0;
2484 --count, natptr += each_size, ++generic)
1642229e
HPN
2485 MY_swap_ext_reloc_out (abfd, *generic,
2486 (struct reloc_ext_external *) natptr);
252b5132
RH
2487 }
2488 else
2489 {
2490 for (natptr = native;
2491 count != 0;
2492 --count, natptr += each_size, ++generic)
923f08ff
AM
2493 MY_swap_std_reloc_out (abfd, *generic,
2494 (struct reloc_std_external *) natptr);
252b5132
RH
2495 }
2496
dc810e39
AM
2497 if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
2498 {
923f08ff 2499 bfd_release (abfd, native);
dc810e39
AM
2500 return false;
2501 }
252b5132
RH
2502 bfd_release (abfd, native);
2503
2504 return true;
2505}
2506
f7c33884
NC
2507/* This is stupid. This function should be a boolean predicate. */
2508
252b5132
RH
2509long
2510NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols)
2511 bfd *abfd;
2512 sec_ptr section;
2513 arelent **relptr;
2514 asymbol **symbols;
2515{
2516 arelent *tblptr = section->relocation;
2517 unsigned int count;
2518
2519 if (section == obj_bsssec (abfd))
2520 {
2521 *relptr = NULL;
2522 return 0;
2523 }
2524
beb0d161 2525 if (!(tblptr || NAME(aout,slurp_reloc_table) (abfd, section, symbols)))
252b5132
RH
2526 return -1;
2527
923f08ff
AM
2528 if (section->flags & SEC_CONSTRUCTOR)
2529 {
2530 arelent_chain *chain = section->constructor_chain;
2531 for (count = 0; count < section->reloc_count; count ++)
2532 {
2533 *relptr ++ = &chain->relent;
2534 chain = chain->next;
2535 }
252b5132 2536 }
923f08ff
AM
2537 else
2538 {
2539 tblptr = section->relocation;
252b5132 2540
923f08ff
AM
2541 for (count = 0; count++ < section->reloc_count; )
2542 {
2543 *relptr++ = tblptr++;
2544 }
2545 }
252b5132
RH
2546 *relptr = 0;
2547
2548 return section->reloc_count;
2549}
2550
2551long
2552NAME(aout,get_reloc_upper_bound) (abfd, asect)
2553 bfd *abfd;
2554 sec_ptr asect;
2555{
923f08ff
AM
2556 if (bfd_get_format (abfd) != bfd_object)
2557 {
2558 bfd_set_error (bfd_error_invalid_operation);
2559 return -1;
2560 }
f7c33884 2561
923f08ff 2562 if (asect->flags & SEC_CONSTRUCTOR)
f7c33884 2563 return (sizeof (arelent *) * (asect->reloc_count+1));
252b5132
RH
2564
2565 if (asect == obj_datasec (abfd))
2566 return (sizeof (arelent *)
923f08ff 2567 * ((exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd))
252b5132
RH
2568 + 1));
2569
2570 if (asect == obj_textsec (abfd))
2571 return (sizeof (arelent *)
923f08ff 2572 * ((exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd))
252b5132
RH
2573 + 1));
2574
2575 if (asect == obj_bsssec (abfd))
2576 return sizeof (arelent *);
2577
2578 if (asect == obj_bsssec (abfd))
2579 return 0;
2580
2581 bfd_set_error (bfd_error_invalid_operation);
2582 return -1;
2583}
252b5132
RH
2584\f
2585long
2586NAME(aout,get_symtab_upper_bound) (abfd)
2587 bfd *abfd;
2588{
beb0d161 2589 if (!NAME(aout,slurp_symbol_table) (abfd))
252b5132
RH
2590 return -1;
2591
2592 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2593}
2594
1725a96e 2595alent *
252b5132 2596NAME(aout,get_lineno) (ignore_abfd, ignore_symbol)
7442e600
ILT
2597 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2598 asymbol *ignore_symbol ATTRIBUTE_UNUSED;
252b5132 2599{
7442e600 2600 return (alent *)NULL;
252b5132
RH
2601}
2602
252b5132
RH
2603void
2604NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
7442e600 2605 bfd *ignore_abfd ATTRIBUTE_UNUSED;
252b5132
RH
2606 asymbol *symbol;
2607 symbol_info *ret;
2608{
2609 bfd_symbol_info (symbol, ret);
2610
2611 if (ret->type == '?')
2612 {
923f08ff 2613 int type_code = aout_symbol (symbol)->type & 0xff;
252b5132
RH
2614 const char *stab_name = bfd_get_stab_name (type_code);
2615 static char buf[10];
2616
2617 if (stab_name == NULL)
2618 {
e60b52c6 2619 sprintf (buf, "(%d)", type_code);
252b5132
RH
2620 stab_name = buf;
2621 }
2622 ret->type = '-';
2623 ret->stab_type = type_code;
923f08ff
AM
2624 ret->stab_other = (unsigned) (aout_symbol (symbol)->other & 0xff);
2625 ret->stab_desc = (unsigned) (aout_symbol (symbol)->desc & 0xffff);
252b5132
RH
2626 ret->stab_name = stab_name;
2627 }
2628}
2629
252b5132 2630void
60b89a18
L
2631NAME(aout,print_symbol) (abfd, afile, symbol, how)
2632 bfd *abfd;
252b5132
RH
2633 PTR afile;
2634 asymbol *symbol;
2635 bfd_print_symbol_type how;
2636{
2637 FILE *file = (FILE *)afile;
2638
923f08ff 2639 switch (how)
252b5132 2640 {
923f08ff
AM
2641 case bfd_print_symbol_name:
2642 if (symbol->name)
2643 fprintf (file,"%s", symbol->name);
2644 break;
2645 case bfd_print_symbol_more:
2646 fprintf (file,"%4x %2x %2x",
2647 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2648 (unsigned) (aout_symbol (symbol)->other & 0xff),
2649 (unsigned) (aout_symbol (symbol)->type));
2650 break;
2651 case bfd_print_symbol_all:
2652 {
2653 const char *section_name = symbol->section->name;
252b5132 2654
923f08ff 2655 bfd_print_symbol_vandf (abfd, (PTR)file, symbol);
252b5132 2656
923f08ff
AM
2657 fprintf (file," %-5s %04x %02x %02x",
2658 section_name,
2659 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2660 (unsigned) (aout_symbol (symbol)->other & 0xff),
2661 (unsigned) (aout_symbol (symbol)->type & 0xff));
2662 if (symbol->name)
2663 fprintf (file," %s", symbol->name);
2664 }
2665 break;
252b5132 2666 }
252b5132
RH
2667}
2668
2669/* If we don't have to allocate more than 1MB to hold the generic
2670 symbols, we use the generic minisymbol methord: it's faster, since
2671 it only translates the symbols once, not multiple times. */
2672#define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
2673
2674/* Read minisymbols. For minisymbols, we use the unmodified a.out
2675 symbols. The minisymbol_to_symbol function translates these into
2676 BFD asymbol structures. */
2677
2678long
2679NAME(aout,read_minisymbols) (abfd, dynamic, minisymsp, sizep)
2680 bfd *abfd;
2681 boolean dynamic;
2682 PTR *minisymsp;
2683 unsigned int *sizep;
2684{
2685 if (dynamic)
2686 {
2687 /* We could handle the dynamic symbols here as well, but it's
2688 easier to hand them off. */
2689 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2690 }
2691
2692 if (! aout_get_external_symbols (abfd))
2693 return -1;
2694
2695 if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2696 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2697
2698 *minisymsp = (PTR) obj_aout_external_syms (abfd);
2699
2700 /* By passing the external symbols back from this routine, we are
2701 giving up control over the memory block. Clear
2702 obj_aout_external_syms, so that we do not try to free it
2703 ourselves. */
2704 obj_aout_external_syms (abfd) = NULL;
2705
2706 *sizep = EXTERNAL_NLIST_SIZE;
2707 return obj_aout_external_sym_count (abfd);
2708}
2709
2710/* Convert a minisymbol to a BFD asymbol. A minisymbol is just an
2711 unmodified a.out symbol. The SYM argument is a structure returned
2712 by bfd_make_empty_symbol, which we fill in here. */
2713
2714asymbol *
2715NAME(aout,minisymbol_to_symbol) (abfd, dynamic, minisym, sym)
2716 bfd *abfd;
2717 boolean dynamic;
2718 const PTR minisym;
2719 asymbol *sym;
2720{
2721 if (dynamic
2722 || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2723 return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
2724
2725 memset (sym, 0, sizeof (aout_symbol_type));
2726
2727 /* We call translate_symbol_table to translate a single symbol. */
2728 if (! (NAME(aout,translate_symbol_table)
2729 (abfd,
2730 (aout_symbol_type *) sym,
2731 (struct external_nlist *) minisym,
2732 (bfd_size_type) 1,
2733 obj_aout_external_strings (abfd),
2734 obj_aout_external_string_size (abfd),
2735 false)))
2736 return NULL;
2737
2738 return sym;
2739}
2740
f7c33884
NC
2741/* Provided a BFD, a section and an offset into the section, calculate
2742 and return the name of the source file and the line nearest to the
2743 wanted location. */
252b5132
RH
2744
2745boolean
2746NAME(aout,find_nearest_line)
2747 (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
2748 bfd *abfd;
2749 asection *section;
2750 asymbol **symbols;
2751 bfd_vma offset;
dc810e39
AM
2752 const char **filename_ptr;
2753 const char **functionname_ptr;
252b5132
RH
2754 unsigned int *line_ptr;
2755{
f7c33884 2756 /* Run down the file looking for the filename, function and linenumber. */
252b5132 2757 asymbol **p;
dc810e39
AM
2758 const char *directory_name = NULL;
2759 const char *main_file_name = NULL;
2760 const char *current_file_name = NULL;
2761 const char *line_file_name = NULL; /* Value of current_file_name at line number. */
2762 const char *line_directory_name = NULL; /* Value of directory_name at line number. */
252b5132
RH
2763 bfd_vma low_line_vma = 0;
2764 bfd_vma low_func_vma = 0;
2765 asymbol *func = 0;
dc810e39 2766 bfd_size_type filelen, funclen;
252b5132
RH
2767 char *buf;
2768
2769 *filename_ptr = abfd->filename;
2770 *functionname_ptr = 0;
2771 *line_ptr = 0;
f7c33884 2772
923f08ff
AM
2773 if (symbols != (asymbol **)NULL)
2774 {
2775 for (p = symbols; *p; p++)
2776 {
2777 aout_symbol_type *q = (aout_symbol_type *) (*p);
2778 next:
2779 switch (q->type)
2780 {
2781 case N_TEXT:
2782 /* If this looks like a file name symbol, and it comes after
2783 the line number we have found so far, but before the
2784 offset, then we have probably not found the right line
2785 number. */
2786 if (q->symbol.value <= offset
2787 && ((q->symbol.value > low_line_vma
2788 && (line_file_name != NULL
2789 || *line_ptr != 0))
2790 || (q->symbol.value > low_func_vma
2791 && func != NULL)))
2792 {
2793 const char *symname;
252b5132 2794
923f08ff
AM
2795 symname = q->symbol.name;
2796 if (strcmp (symname + strlen (symname) - 2, ".o") == 0)
2797 {
2798 if (q->symbol.value > low_line_vma)
2799 {
2800 *line_ptr = 0;
2801 line_file_name = NULL;
2802 }
2803 if (q->symbol.value > low_func_vma)
2804 func = NULL;
2805 }
2806 }
2807 break;
252b5132 2808
923f08ff
AM
2809 case N_SO:
2810 /* If this symbol is less than the offset, but greater than
2811 the line number we have found so far, then we have not
2812 found the right line number. */
2813 if (q->symbol.value <= offset)
2814 {
2815 if (q->symbol.value > low_line_vma)
2816 {
2817 *line_ptr = 0;
2818 line_file_name = NULL;
2819 }
2820 if (q->symbol.value > low_func_vma)
2821 func = NULL;
2822 }
252b5132 2823
923f08ff
AM
2824 main_file_name = current_file_name = q->symbol.name;
2825 /* Look ahead to next symbol to check if that too is an N_SO. */
2826 p++;
2827 if (*p == NULL)
2828 break;
2829 q = (aout_symbol_type *) (*p);
2830 if (q->type != (int)N_SO)
2831 goto next;
2832
2833 /* Found a second N_SO First is directory; second is filename. */
2834 directory_name = current_file_name;
2835 main_file_name = current_file_name = q->symbol.name;
2836 if (obj_textsec (abfd) != section)
2837 goto done;
2838 break;
2839 case N_SOL:
2840 current_file_name = q->symbol.name;
2841 break;
252b5132 2842
923f08ff 2843 case N_SLINE:
252b5132 2844
923f08ff
AM
2845 case N_DSLINE:
2846 case N_BSLINE:
2847 /* We'll keep this if it resolves nearer than the one we have
2848 already. */
2849 if (q->symbol.value >= low_line_vma
2850 && q->symbol.value <= offset)
2851 {
2852 *line_ptr = q->desc;
2853 low_line_vma = q->symbol.value;
2854 line_file_name = current_file_name;
2855 line_directory_name = directory_name;
2856 }
2857 break;
2858 case N_FUN:
2859 {
f7c33884 2860 /* We'll keep this if it is nearer than the one we have already. */
923f08ff 2861 if (q->symbol.value >= low_func_vma &&
f7c33884
NC
2862 q->symbol.value <= offset)
2863 {
2864 low_func_vma = q->symbol.value;
2865 func = (asymbol *)q;
2866 }
923f08ff
AM
2867 else if (q->symbol.value > offset)
2868 goto done;
2869 }
2870 break;
2871 }
252b5132 2872 }
252b5132 2873 }
252b5132
RH
2874
2875 done:
2876 if (*line_ptr != 0)
2877 {
2878 main_file_name = line_file_name;
2879 directory_name = line_directory_name;
2880 }
2881
2882 if (main_file_name == NULL
5af11cab 2883 || IS_ABSOLUTE_PATH (main_file_name)
252b5132
RH
2884 || directory_name == NULL)
2885 filelen = 0;
2886 else
2887 filelen = strlen (directory_name) + strlen (main_file_name);
f7c33884 2888
252b5132
RH
2889 if (func == NULL)
2890 funclen = 0;
2891 else
2892 funclen = strlen (bfd_asymbol_name (func));
2893
2894 if (adata (abfd).line_buf != NULL)
2895 free (adata (abfd).line_buf);
f7c33884 2896
252b5132
RH
2897 if (filelen + funclen == 0)
2898 adata (abfd).line_buf = buf = NULL;
2899 else
2900 {
2901 buf = (char *) bfd_malloc (filelen + funclen + 3);
2902 adata (abfd).line_buf = buf;
2903 if (buf == NULL)
2904 return false;
2905 }
2906
2907 if (main_file_name != NULL)
2908 {
5af11cab 2909 if (IS_ABSOLUTE_PATH (main_file_name) || directory_name == NULL)
252b5132
RH
2910 *filename_ptr = main_file_name;
2911 else
2912 {
2913 sprintf (buf, "%s%s", directory_name, main_file_name);
2914 *filename_ptr = buf;
2915 buf += filelen + 1;
2916 }
2917 }
2918
2919 if (func)
2920 {
2921 const char *function = func->name;
dc810e39 2922 char *colon;
252b5132
RH
2923
2924 /* The caller expects a symbol name. We actually have a
2925 function name, without the leading underscore. Put the
2926 underscore back in, so that the caller gets a symbol name. */
2927 if (bfd_get_symbol_leading_char (abfd) == '\0')
2928 strcpy (buf, function);
2929 else
2930 {
2931 buf[0] = bfd_get_symbol_leading_char (abfd);
2932 strcpy (buf + 1, function);
2933 }
f7c33884 2934 /* Have to remove : stuff. */
dc810e39
AM
2935 colon = strchr (buf, ':');
2936 if (colon != NULL)
2937 *colon = '\0';
252b5132
RH
2938 *functionname_ptr = buf;
2939 }
2940
2941 return true;
2942}
2943
252b5132
RH
2944int
2945NAME(aout,sizeof_headers) (abfd, execable)
2946 bfd *abfd;
7442e600 2947 boolean execable ATTRIBUTE_UNUSED;
252b5132 2948{
923f08ff 2949 return adata (abfd).exec_bytes_size;
252b5132
RH
2950}
2951
2952/* Free all information we have cached for this BFD. We can always
2953 read it again later if we need it. */
2954
2955boolean
2956NAME(aout,bfd_free_cached_info) (abfd)
2957 bfd *abfd;
2958{
2959 asection *o;
2960
920581c5
L
2961 if (bfd_get_format (abfd) != bfd_object
2962 || abfd->tdata.aout_data == NULL)
252b5132
RH
2963 return true;
2964
2965#define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
2966 BFCI_FREE (obj_aout_symbols (abfd));
2967#ifdef USE_MMAP
2968 obj_aout_external_syms (abfd) = 0;
2969 bfd_free_window (&obj_aout_sym_window (abfd));
2970 bfd_free_window (&obj_aout_string_window (abfd));
2971 obj_aout_external_strings (abfd) = 0;
2972#else
2973 BFCI_FREE (obj_aout_external_syms (abfd));
2974 BFCI_FREE (obj_aout_external_strings (abfd));
2975#endif
2976 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
2977 BFCI_FREE (o->relocation);
2978#undef BFCI_FREE
2979
2980 return true;
2981}
2982\f
2983/* a.out link code. */
2984
2985static boolean aout_link_add_object_symbols
2986 PARAMS ((bfd *, struct bfd_link_info *));
2987static boolean aout_link_check_archive_element
2988 PARAMS ((bfd *, struct bfd_link_info *, boolean *));
2989static boolean aout_link_free_symbols PARAMS ((bfd *));
2990static boolean aout_link_check_ar_symbols
2991 PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
2992static boolean aout_link_add_symbols
2993 PARAMS ((bfd *, struct bfd_link_info *));
2994
2995/* Routine to create an entry in an a.out link hash table. */
2996
2997struct bfd_hash_entry *
2998NAME(aout,link_hash_newfunc) (entry, table, string)
2999 struct bfd_hash_entry *entry;
3000 struct bfd_hash_table *table;
3001 const char *string;
3002{
3003 struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
3004
3005 /* Allocate the structure if it has not already been allocated by a
3006 subclass. */
3007 if (ret == (struct aout_link_hash_entry *) NULL)
3008 ret = ((struct aout_link_hash_entry *)
3009 bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
3010 if (ret == (struct aout_link_hash_entry *) NULL)
3011 return (struct bfd_hash_entry *) ret;
3012
3013 /* Call the allocation method of the superclass. */
3014 ret = ((struct aout_link_hash_entry *)
3015 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
3016 table, string));
3017 if (ret)
3018 {
3019 /* Set local fields. */
3020 ret->written = false;
3021 ret->indx = -1;
3022 }
3023
3024 return (struct bfd_hash_entry *) ret;
3025}
3026
3027/* Initialize an a.out link hash table. */
3028
3029boolean
3030NAME(aout,link_hash_table_init) (table, abfd, newfunc)
3031 struct aout_link_hash_table *table;
3032 bfd *abfd;
3033 struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
3034 struct bfd_hash_table *,
3035 const char *));
3036{
3037 return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
3038}
3039
3040/* Create an a.out link hash table. */
3041
3042struct bfd_link_hash_table *
3043NAME(aout,link_hash_table_create) (abfd)
3044 bfd *abfd;
3045{
3046 struct aout_link_hash_table *ret;
dc810e39 3047 bfd_size_type amt = sizeof (struct aout_link_hash_table);
252b5132 3048
dc810e39 3049 ret = (struct aout_link_hash_table *) bfd_alloc (abfd, amt);
252b5132
RH
3050 if (ret == NULL)
3051 return (struct bfd_link_hash_table *) NULL;
3052 if (! NAME(aout,link_hash_table_init) (ret, abfd,
3053 NAME(aout,link_hash_newfunc)))
3054 {
3055 free (ret);
3056 return (struct bfd_link_hash_table *) NULL;
3057 }
3058 return &ret->root;
3059}
3060
3061/* Given an a.out BFD, add symbols to the global hash table as
3062 appropriate. */
3063
3064boolean
3065NAME(aout,link_add_symbols) (abfd, info)
3066 bfd *abfd;
3067 struct bfd_link_info *info;
3068{
3069 switch (bfd_get_format (abfd))
3070 {
3071 case bfd_object:
3072 return aout_link_add_object_symbols (abfd, info);
3073 case bfd_archive:
3074 return _bfd_generic_link_add_archive_symbols
3075 (abfd, info, aout_link_check_archive_element);
3076 default:
3077 bfd_set_error (bfd_error_wrong_format);
3078 return false;
3079 }
3080}
3081
3082/* Add symbols from an a.out object file. */
3083
3084static boolean
3085aout_link_add_object_symbols (abfd, info)
3086 bfd *abfd;
3087 struct bfd_link_info *info;
3088{
3089 if (! aout_get_external_symbols (abfd))
3090 return false;
3091 if (! aout_link_add_symbols (abfd, info))
3092 return false;
3093 if (! info->keep_memory)
3094 {
3095 if (! aout_link_free_symbols (abfd))
3096 return false;
3097 }
3098 return true;
3099}
3100
3101/* Check a single archive element to see if we need to include it in
3102 the link. *PNEEDED is set according to whether this element is
3103 needed in the link or not. This is called from
3104 _bfd_generic_link_add_archive_symbols. */
3105
3106static boolean
3107aout_link_check_archive_element (abfd, info, pneeded)
3108 bfd *abfd;
3109 struct bfd_link_info *info;
3110 boolean *pneeded;
3111{
3112 if (! aout_get_external_symbols (abfd))
3113 return false;
3114
3115 if (! aout_link_check_ar_symbols (abfd, info, pneeded))
3116 return false;
3117
3118 if (*pneeded)
3119 {
3120 if (! aout_link_add_symbols (abfd, info))
3121 return false;
3122 }
3123
3124 if (! info->keep_memory || ! *pneeded)
3125 {
3126 if (! aout_link_free_symbols (abfd))
3127 return false;
3128 }
3129
3130 return true;
3131}
3132
3133/* Free up the internal symbols read from an a.out file. */
3134
3135static boolean
3136aout_link_free_symbols (abfd)
3137 bfd *abfd;
3138{
3139 if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
3140 {
3141#ifdef USE_MMAP
3142 bfd_free_window (&obj_aout_sym_window (abfd));
3143#else
3144 free ((PTR) obj_aout_external_syms (abfd));
3145#endif
3146 obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
3147 }
3148 if (obj_aout_external_strings (abfd) != (char *) NULL)
3149 {
3150#ifdef USE_MMAP
3151 bfd_free_window (&obj_aout_string_window (abfd));
3152#else
3153 free ((PTR) obj_aout_external_strings (abfd));
3154#endif
3155 obj_aout_external_strings (abfd) = (char *) NULL;
3156 }
3157 return true;
3158}
3159
3160/* Look through the internal symbols to see if this object file should
3161 be included in the link. We should include this object file if it
3162 defines any symbols which are currently undefined. If this object
3163 file defines a common symbol, then we may adjust the size of the
3164 known symbol but we do not include the object file in the link
3165 (unless there is some other reason to include it). */
3166
3167static boolean
3168aout_link_check_ar_symbols (abfd, info, pneeded)
3169 bfd *abfd;
3170 struct bfd_link_info *info;
3171 boolean *pneeded;
3172{
3173 register struct external_nlist *p;
3174 struct external_nlist *pend;
3175 char *strings;
3176
3177 *pneeded = false;
3178
3179 /* Look through all the symbols. */
3180 p = obj_aout_external_syms (abfd);
3181 pend = p + obj_aout_external_sym_count (abfd);
3182 strings = obj_aout_external_strings (abfd);
3183 for (; p < pend; p++)
3184 {
dc810e39 3185 int type = H_GET_8 (abfd, p->e_type);
252b5132
RH
3186 const char *name;
3187 struct bfd_link_hash_entry *h;
3188
3189 /* Ignore symbols that are not externally visible. This is an
3190 optimization only, as we check the type more thoroughly
3191 below. */
3192 if (((type & N_EXT) == 0
3193 || (type & N_STAB) != 0
3194 || type == N_FN)
3195 && type != N_WEAKA
3196 && type != N_WEAKT
3197 && type != N_WEAKD
3198 && type != N_WEAKB)
3199 {
3200 if (type == N_WARNING
3201 || type == N_INDR)
3202 ++p;
3203 continue;
3204 }
3205
3206 name = strings + GET_WORD (abfd, p->e_strx);
3207 h = bfd_link_hash_lookup (info->hash, name, false, false, true);
3208
3209 /* We are only interested in symbols that are currently
3210 undefined or common. */
3211 if (h == (struct bfd_link_hash_entry *) NULL
3212 || (h->type != bfd_link_hash_undefined
3213 && h->type != bfd_link_hash_common))
3214 {
3215 if (type == (N_INDR | N_EXT))
3216 ++p;
3217 continue;
3218 }
3219
3220 if (type == (N_TEXT | N_EXT)
3221 || type == (N_DATA | N_EXT)
3222 || type == (N_BSS | N_EXT)
3223 || type == (N_ABS | N_EXT)
3224 || type == (N_INDR | N_EXT))
3225 {
3226 /* This object file defines this symbol. We must link it
3227 in. This is true regardless of whether the current
f7c33884
NC
3228 definition of the symbol is undefined or common.
3229
3230 If the current definition is common, we have a case in
3231 which we have already seen an object file including:
252b5132 3232 int a;
f7c33884 3233 and this object file from the archive includes:
252b5132 3234 int a = 5;
f7c33884
NC
3235 In such a case, whether to include this object is target
3236 dependant for backward compatability.
252b5132
RH
3237
3238 FIXME: The SunOS 4.1.3 linker will pull in the archive
3239 element if the symbol is defined in the .data section,
3240 but not if it is defined in the .text section. That
f7c33884
NC
3241 seems a bit crazy to me, and it has not been implemented
3242 yet. However, it might be correct. */
3243 if (h->type == bfd_link_hash_common)
3244 {
3245 int skip = 0;
3246
3247 switch (info->common_skip_ar_aymbols)
3248 {
3249 case bfd_link_common_skip_text:
3250 skip = (type == (N_TEXT | N_EXT));
3251 break;
3252 case bfd_link_common_skip_data:
3253 skip = (type == (N_DATA | N_EXT));
3254 break;
3255 default:
3256 case bfd_link_common_skip_all:
3257 skip = 1;
3258 break;
3259 }
3260
3261 if (skip)
3262 continue;
3263 }
3264
252b5132
RH
3265 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3266 return false;
3267 *pneeded = true;
3268 return true;
3269 }
3270
3271 if (type == (N_UNDF | N_EXT))
3272 {
3273 bfd_vma value;
3274
3275 value = GET_WORD (abfd, p->e_value);
3276 if (value != 0)
3277 {
3278 /* This symbol is common in the object from the archive
3279 file. */
3280 if (h->type == bfd_link_hash_undefined)
3281 {
3282 bfd *symbfd;
3283 unsigned int power;
3284
3285 symbfd = h->u.undef.abfd;
3286 if (symbfd == (bfd *) NULL)
3287 {
3288 /* This symbol was created as undefined from
3289 outside BFD. We assume that we should link
3290 in the object file. This is done for the -u
3291 option in the linker. */
3292 if (! (*info->callbacks->add_archive_element) (info,
3293 abfd,
3294 name))
3295 return false;
3296 *pneeded = true;
3297 return true;
3298 }
3299 /* Turn the current link symbol into a common
3300 symbol. It is already on the undefs list. */
3301 h->type = bfd_link_hash_common;
3302 h->u.c.p = ((struct bfd_link_hash_common_entry *)
3303 bfd_hash_allocate (&info->hash->table,
3304 sizeof (struct bfd_link_hash_common_entry)));
3305 if (h->u.c.p == NULL)
3306 return false;
3307
3308 h->u.c.size = value;
3309
3310 /* FIXME: This isn't quite right. The maximum
3311 alignment of a common symbol should be set by the
3312 architecture of the output file, not of the input
3313 file. */
3314 power = bfd_log2 (value);
3315 if (power > bfd_get_arch_info (abfd)->section_align_power)
3316 power = bfd_get_arch_info (abfd)->section_align_power;
3317 h->u.c.p->alignment_power = power;
3318
3319 h->u.c.p->section = bfd_make_section_old_way (symbfd,
3320 "COMMON");
3321 }
3322 else
3323 {
3324 /* Adjust the size of the common symbol if
3325 necessary. */
3326 if (value > h->u.c.size)
3327 h->u.c.size = value;
3328 }
3329 }
3330 }
3331
3332 if (type == N_WEAKA
3333 || type == N_WEAKT
3334 || type == N_WEAKD
3335 || type == N_WEAKB)
3336 {
3337 /* This symbol is weak but defined. We must pull it in if
3338 the current link symbol is undefined, but we don't want
3339 it if the current link symbol is common. */
3340 if (h->type == bfd_link_hash_undefined)
3341 {
3342 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3343 return false;
3344 *pneeded = true;
3345 return true;
3346 }
3347 }
3348 }
3349
3350 /* We do not need this object file. */
3351 return true;
3352}
3353
3354/* Add all symbols from an object file to the hash table. */
3355
3356static boolean
3357aout_link_add_symbols (abfd, info)
3358 bfd *abfd;
3359 struct bfd_link_info *info;
3360{
3361 boolean (*add_one_symbol) PARAMS ((struct bfd_link_info *, bfd *,
3362 const char *, flagword, asection *,
3363 bfd_vma, const char *, boolean,
3364 boolean,
3365 struct bfd_link_hash_entry **));
3366 struct external_nlist *syms;
3367 bfd_size_type sym_count;
3368 char *strings;
3369 boolean copy;
3370 struct aout_link_hash_entry **sym_hash;
3371 register struct external_nlist *p;
3372 struct external_nlist *pend;
dc810e39 3373 bfd_size_type amt;
252b5132
RH
3374
3375 syms = obj_aout_external_syms (abfd);
3376 sym_count = obj_aout_external_sym_count (abfd);
3377 strings = obj_aout_external_strings (abfd);
3378 if (info->keep_memory)
3379 copy = false;
3380 else
3381 copy = true;
3382
3383 if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
3384 {
3385 if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
3386 (abfd, info, &syms, &sym_count, &strings)))
3387 return false;
3388 }
3389
3390 /* We keep a list of the linker hash table entries that correspond
3391 to particular symbols. We could just look them up in the hash
3392 table, but keeping the list is more efficient. Perhaps this
3393 should be conditional on info->keep_memory. */
dc810e39
AM
3394 amt = sym_count * sizeof (struct aout_link_hash_entry *);
3395 sym_hash = (struct aout_link_hash_entry **) bfd_alloc (abfd, amt);
252b5132
RH
3396 if (sym_hash == NULL && sym_count != 0)
3397 return false;
3398 obj_aout_sym_hashes (abfd) = sym_hash;
3399
3400 add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
3401 if (add_one_symbol == NULL)
3402 add_one_symbol = _bfd_generic_link_add_one_symbol;
3403
3404 p = syms;
3405 pend = p + sym_count;
3406 for (; p < pend; p++, sym_hash++)
3407 {
3408 int type;
3409 const char *name;
3410 bfd_vma value;
3411 asection *section;
3412 flagword flags;
3413 const char *string;
3414
3415 *sym_hash = NULL;
3416
dc810e39 3417 type = H_GET_8 (abfd, p->e_type);
252b5132
RH
3418
3419 /* Ignore debugging symbols. */
3420 if ((type & N_STAB) != 0)
3421 continue;
3422
3423 name = strings + GET_WORD (abfd, p->e_strx);
3424 value = GET_WORD (abfd, p->e_value);
3425 flags = BSF_GLOBAL;
3426 string = NULL;
3427 switch (type)
3428 {
3429 default:
3430 abort ();
3431
3432 case N_UNDF:
3433 case N_ABS:
3434 case N_TEXT:
3435 case N_DATA:
3436 case N_BSS:
3437 case N_FN_SEQ:
3438 case N_COMM:
3439 case N_SETV:
3440 case N_FN:
3441 /* Ignore symbols that are not externally visible. */
3442 continue;
3443 case N_INDR:
3444 /* Ignore local indirect symbol. */
3445 ++p;
3446 ++sym_hash;
3447 continue;
3448
3449 case N_UNDF | N_EXT:
3450 if (value == 0)
3451 {
3452 section = bfd_und_section_ptr;
3453 flags = 0;
3454 }
3455 else
3456 section = bfd_com_section_ptr;
3457 break;
3458 case N_ABS | N_EXT:
3459 section = bfd_abs_section_ptr;
3460 break;
3461 case N_TEXT | N_EXT:
3462 section = obj_textsec (abfd);
3463 value -= bfd_get_section_vma (abfd, section);
3464 break;
3465 case N_DATA | N_EXT:
3466 case N_SETV | N_EXT:
3467 /* Treat N_SETV symbols as N_DATA symbol; see comment in
3468 translate_from_native_sym_flags. */
3469 section = obj_datasec (abfd);
3470 value -= bfd_get_section_vma (abfd, section);
3471 break;
3472 case N_BSS | N_EXT:
3473 section = obj_bsssec (abfd);
3474 value -= bfd_get_section_vma (abfd, section);
3475 break;
3476 case N_INDR | N_EXT:
3477 /* An indirect symbol. The next symbol is the symbol
3478 which this one really is. */
3479 BFD_ASSERT (p + 1 < pend);
3480 ++p;
3481 string = strings + GET_WORD (abfd, p->e_strx);
3482 section = bfd_ind_section_ptr;
3483 flags |= BSF_INDIRECT;
3484 break;
3485 case N_COMM | N_EXT:
3486 section = bfd_com_section_ptr;
3487 break;
3488 case N_SETA: case N_SETA | N_EXT:
3489 section = bfd_abs_section_ptr;
3490 flags |= BSF_CONSTRUCTOR;
3491 break;
3492 case N_SETT: case N_SETT | N_EXT:
3493 section = obj_textsec (abfd);
3494 flags |= BSF_CONSTRUCTOR;
3495 value -= bfd_get_section_vma (abfd, section);
3496 break;
3497 case N_SETD: case N_SETD | N_EXT:
3498 section = obj_datasec (abfd);
3499 flags |= BSF_CONSTRUCTOR;
3500 value -= bfd_get_section_vma (abfd, section);
3501 break;
3502 case N_SETB: case N_SETB | N_EXT:
3503 section = obj_bsssec (abfd);
3504 flags |= BSF_CONSTRUCTOR;
3505 value -= bfd_get_section_vma (abfd, section);
3506 break;
3507 case N_WARNING:
3508 /* A warning symbol. The next symbol is the one to warn
3509 about. */
3510 BFD_ASSERT (p + 1 < pend);
3511 ++p;
3512 string = name;
3513 name = strings + GET_WORD (abfd, p->e_strx);
3514 section = bfd_und_section_ptr;
3515 flags |= BSF_WARNING;
3516 break;
3517 case N_WEAKU:
3518 section = bfd_und_section_ptr;
3519 flags = BSF_WEAK;
3520 break;
3521 case N_WEAKA:
3522 section = bfd_abs_section_ptr;
3523 flags = BSF_WEAK;
3524 break;
3525 case N_WEAKT:
3526 section = obj_textsec (abfd);
3527 value -= bfd_get_section_vma (abfd, section);
3528 flags = BSF_WEAK;
3529 break;
3530 case N_WEAKD:
3531 section = obj_datasec (abfd);
3532 value -= bfd_get_section_vma (abfd, section);
3533 flags = BSF_WEAK;
3534 break;
3535 case N_WEAKB:
3536 section = obj_bsssec (abfd);
3537 value -= bfd_get_section_vma (abfd, section);
3538 flags = BSF_WEAK;
3539 break;
3540 }
3541
3542 if (! ((*add_one_symbol)
3543 (info, abfd, name, flags, section, value, string, copy, false,
3544 (struct bfd_link_hash_entry **) sym_hash)))
3545 return false;
3546
3547 /* Restrict the maximum alignment of a common symbol based on
3548 the architecture, since a.out has no way to represent
3549 alignment requirements of a section in a .o file. FIXME:
3550 This isn't quite right: it should use the architecture of the
3551 output file, not the input files. */
3552 if ((*sym_hash)->root.type == bfd_link_hash_common
3553 && ((*sym_hash)->root.u.c.p->alignment_power >
3554 bfd_get_arch_info (abfd)->section_align_power))
3555 (*sym_hash)->root.u.c.p->alignment_power =
3556 bfd_get_arch_info (abfd)->section_align_power;
3557
3558 /* If this is a set symbol, and we are not building sets, then
3559 it is possible for the hash entry to not have been set. In
3560 such a case, treat the symbol as not globally defined. */
3561 if ((*sym_hash)->root.type == bfd_link_hash_new)
3562 {
3563 BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
3564 *sym_hash = NULL;
3565 }
3566
3567 if (type == (N_INDR | N_EXT) || type == N_WARNING)
3568 ++sym_hash;
3569 }
3570
3571 return true;
3572}
3573\f
3574/* A hash table used for header files with N_BINCL entries. */
3575
3576struct aout_link_includes_table
3577{
3578 struct bfd_hash_table root;
3579};
3580
3581/* A linked list of totals that we have found for a particular header
3582 file. */
3583
3584struct aout_link_includes_totals
3585{
3586 struct aout_link_includes_totals *next;
3587 bfd_vma total;
3588};
3589
3590/* An entry in the header file hash table. */
3591
3592struct aout_link_includes_entry
3593{
3594 struct bfd_hash_entry root;
3595 /* List of totals we have found for this file. */
3596 struct aout_link_includes_totals *totals;
3597};
3598
3599/* Look up an entry in an the header file hash table. */
3600
923f08ff
AM
3601#define aout_link_includes_lookup(table, string, create, copy) \
3602 ((struct aout_link_includes_entry *) \
252b5132
RH
3603 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
3604
3605/* During the final link step we need to pass around a bunch of
3606 information, so we do it in an instance of this structure. */
3607
3608struct aout_final_link_info
3609{
3610 /* General link information. */
3611 struct bfd_link_info *info;
3612 /* Output bfd. */
3613 bfd *output_bfd;
3614 /* Reloc file positions. */
3615 file_ptr treloff, dreloff;
3616 /* File position of symbols. */
3617 file_ptr symoff;
3618 /* String table. */
3619 struct bfd_strtab_hash *strtab;
3620 /* Header file hash table. */
3621 struct aout_link_includes_table includes;
3622 /* A buffer large enough to hold the contents of any section. */
3623 bfd_byte *contents;
3624 /* A buffer large enough to hold the relocs of any section. */
3625 PTR relocs;
3626 /* A buffer large enough to hold the symbol map of any input BFD. */
3627 int *symbol_map;
3628 /* A buffer large enough to hold output symbols of any input BFD. */
3629 struct external_nlist *output_syms;
3630};
3631
3632static struct bfd_hash_entry *aout_link_includes_newfunc
3633 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
3634static boolean aout_link_input_bfd
3635 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3636static boolean aout_link_write_symbols
3637 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3638static boolean aout_link_write_other_symbol
3639 PARAMS ((struct aout_link_hash_entry *, PTR));
3640static boolean aout_link_input_section
3641 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3642 asection *input_section, file_ptr *reloff_ptr,
3643 bfd_size_type rel_size));
3644static boolean aout_link_input_section_std
3645 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3646 asection *input_section, struct reloc_std_external *,
3647 bfd_size_type rel_size, bfd_byte *contents));
3648static boolean aout_link_input_section_ext
3649 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3650 asection *input_section, struct reloc_ext_external *,
3651 bfd_size_type rel_size, bfd_byte *contents));
3652static INLINE asection *aout_reloc_index_to_section
3653 PARAMS ((bfd *, int));
3654static boolean aout_link_reloc_link_order
3655 PARAMS ((struct aout_final_link_info *, asection *,
3656 struct bfd_link_order *));
3657
3658/* The function to create a new entry in the header file hash table. */
3659
3660static struct bfd_hash_entry *
3661aout_link_includes_newfunc (entry, table, string)
3662 struct bfd_hash_entry *entry;
3663 struct bfd_hash_table *table;
3664 const char *string;
3665{
3666 struct aout_link_includes_entry *ret =
3667 (struct aout_link_includes_entry *) entry;
3668
3669 /* Allocate the structure if it has not already been allocated by a
3670 subclass. */
3671 if (ret == (struct aout_link_includes_entry *) NULL)
3672 ret = ((struct aout_link_includes_entry *)
3673 bfd_hash_allocate (table,
3674 sizeof (struct aout_link_includes_entry)));
3675 if (ret == (struct aout_link_includes_entry *) NULL)
3676 return (struct bfd_hash_entry *) ret;
3677
3678 /* Call the allocation method of the superclass. */
3679 ret = ((struct aout_link_includes_entry *)
3680 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
3681 if (ret)
3682 {
3683 /* Set local fields. */
3684 ret->totals = NULL;
3685 }
3686
3687 return (struct bfd_hash_entry *) ret;
3688}
3689
3690/* Do the final link step. This is called on the output BFD. The
3691 INFO structure should point to a list of BFDs linked through the
3692 link_next field which can be used to find each BFD which takes part
3693 in the output. Also, each section in ABFD should point to a list
3694 of bfd_link_order structures which list all the input sections for
3695 the output section. */
3696
3697boolean
3698NAME(aout,final_link) (abfd, info, callback)
3699 bfd *abfd;
3700 struct bfd_link_info *info;
3701 void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
3702{
3703 struct aout_final_link_info aout_info;
3704 boolean includes_hash_initialized = false;
3705 register bfd *sub;
3706 bfd_size_type trsize, drsize;
dc810e39
AM
3707 bfd_size_type max_contents_size;
3708 bfd_size_type max_relocs_size;
3709 bfd_size_type max_sym_count;
252b5132
RH
3710 bfd_size_type text_size;
3711 file_ptr text_end;
3712 register struct bfd_link_order *p;
3713 asection *o;
3714 boolean have_link_order_relocs;
3715
3716 if (info->shared)
3717 abfd->flags |= DYNAMIC;
3718
3719 aout_info.info = info;
3720 aout_info.output_bfd = abfd;
3721 aout_info.contents = NULL;
3722 aout_info.relocs = NULL;
3723 aout_info.symbol_map = NULL;
3724 aout_info.output_syms = NULL;
3725
3726 if (! bfd_hash_table_init_n (&aout_info.includes.root,
3727 aout_link_includes_newfunc,
3728 251))
3729 goto error_return;
3730 includes_hash_initialized = true;
3731
3732 /* Figure out the largest section size. Also, if generating
3733 relocateable output, count the relocs. */
3734 trsize = 0;
3735 drsize = 0;
3736 max_contents_size = 0;
3737 max_relocs_size = 0;
3738 max_sym_count = 0;
3739 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
3740 {
dc810e39 3741 bfd_size_type sz;
252b5132
RH
3742
3743 if (info->relocateable)
3744 {
3745 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3746 {
3747 trsize += exec_hdr (sub)->a_trsize;
3748 drsize += exec_hdr (sub)->a_drsize;
3749 }
3750 else
3751 {
3752 /* FIXME: We need to identify the .text and .data sections
3753 and call get_reloc_upper_bound and canonicalize_reloc to
3754 work out the number of relocs needed, and then multiply
3755 by the reloc size. */
3756 (*_bfd_error_handler)
3757 (_("%s: relocateable link from %s to %s not supported"),
3758 bfd_get_filename (abfd),
3759 sub->xvec->name, abfd->xvec->name);
3760 bfd_set_error (bfd_error_invalid_operation);
3761 goto error_return;
3762 }
3763 }
3764
3765 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3766 {
3767 sz = bfd_section_size (sub, obj_textsec (sub));
3768 if (sz > max_contents_size)
3769 max_contents_size = sz;
3770 sz = bfd_section_size (sub, obj_datasec (sub));
3771 if (sz > max_contents_size)
3772 max_contents_size = sz;
3773
3774 sz = exec_hdr (sub)->a_trsize;
3775 if (sz > max_relocs_size)
3776 max_relocs_size = sz;
3777 sz = exec_hdr (sub)->a_drsize;
3778 if (sz > max_relocs_size)
3779 max_relocs_size = sz;
3780
3781 sz = obj_aout_external_sym_count (sub);
3782 if (sz > max_sym_count)
3783 max_sym_count = sz;
3784 }
3785 }
3786
3787 if (info->relocateable)
3788 {
3789 if (obj_textsec (abfd) != (asection *) NULL)
3790 trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
3791 ->link_order_head)
3792 * obj_reloc_entry_size (abfd));
3793 if (obj_datasec (abfd) != (asection *) NULL)
3794 drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
3795 ->link_order_head)
3796 * obj_reloc_entry_size (abfd));
3797 }
3798
3799 exec_hdr (abfd)->a_trsize = trsize;
3800 exec_hdr (abfd)->a_drsize = drsize;
3801
3802 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
3803
3804 /* Adjust the section sizes and vmas according to the magic number.
3805 This sets a_text, a_data and a_bss in the exec_hdr and sets the
3806 filepos for each section. */
3807 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3808 goto error_return;
3809
3810 /* The relocation and symbol file positions differ among a.out
3811 targets. We are passed a callback routine from the backend
3812 specific code to handle this.
3813 FIXME: At this point we do not know how much space the symbol
3814 table will require. This will not work for any (nonstandard)
3815 a.out target that needs to know the symbol table size before it
3816 can compute the relocation file positions. This may or may not
3817 be the case for the hp300hpux target, for example. */
3818 (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3819 &aout_info.symoff);
3820 obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3821 obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3822 obj_sym_filepos (abfd) = aout_info.symoff;
3823
3824 /* We keep a count of the symbols as we output them. */
3825 obj_aout_external_sym_count (abfd) = 0;
3826
3827 /* We accumulate the string table as we write out the symbols. */
3828 aout_info.strtab = _bfd_stringtab_init ();
3829 if (aout_info.strtab == NULL)
3830 goto error_return;
3831
3832 /* Allocate buffers to hold section contents and relocs. */
3833 aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
3834 aout_info.relocs = (PTR) bfd_malloc (max_relocs_size);
3835 aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int *));
3836 aout_info.output_syms = ((struct external_nlist *)
3837 bfd_malloc ((max_sym_count + 1)
3838 * sizeof (struct external_nlist)));
3839 if ((aout_info.contents == NULL && max_contents_size != 0)
3840 || (aout_info.relocs == NULL && max_relocs_size != 0)
3841 || (aout_info.symbol_map == NULL && max_sym_count != 0)
3842 || aout_info.output_syms == NULL)
3843 goto error_return;
3844
3845 /* If we have a symbol named __DYNAMIC, force it out now. This is
3846 required by SunOS. Doing this here rather than in sunos.c is a
3847 hack, but it's easier than exporting everything which would be
3848 needed. */
3849 {
3850 struct aout_link_hash_entry *h;
3851
3852 h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
3853 false, false, false);
3854 if (h != NULL)
3855 aout_link_write_other_symbol (h, &aout_info);
3856 }
3857
3858 /* The most time efficient way to do the link would be to read all
3859 the input object files into memory and then sort out the
3860 information into the output file. Unfortunately, that will
3861 probably use too much memory. Another method would be to step
3862 through everything that composes the text section and write it
3863 out, and then everything that composes the data section and write
3864 it out, and then write out the relocs, and then write out the
3865 symbols. Unfortunately, that requires reading stuff from each
3866 input file several times, and we will not be able to keep all the
3867 input files open simultaneously, and reopening them will be slow.
3868
3869 What we do is basically process one input file at a time. We do
3870 everything we need to do with an input file once--copy over the
3871 section contents, handle the relocation information, and write
3872 out the symbols--and then we throw away the information we read
3873 from it. This approach requires a lot of lseeks of the output
3874 file, which is unfortunate but still faster than reopening a lot
3875 of files.
3876
3877 We use the output_has_begun field of the input BFDs to see
3878 whether we have already handled it. */
3879 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3880 sub->output_has_begun = false;
3881
3882 /* Mark all sections which are to be included in the link. This
3883 will normally be every section. We need to do this so that we
3884 can identify any sections which the linker has decided to not
3885 include. */
3886 for (o = abfd->sections; o != NULL; o = o->next)
3887 {
3888 for (p = o->link_order_head; p != NULL; p = p->next)
3889 {
3890 if (p->type == bfd_indirect_link_order)
3891 p->u.indirect.section->linker_mark = true;
3892 }
3893 }
3894
3895 have_link_order_relocs = false;
3896 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3897 {
3898 for (p = o->link_order_head;
3899 p != (struct bfd_link_order *) NULL;
3900 p = p->next)
3901 {
3902 if (p->type == bfd_indirect_link_order
3903 && (bfd_get_flavour (p->u.indirect.section->owner)
3904 == bfd_target_aout_flavour))
3905 {
3906 bfd *input_bfd;
3907
3908 input_bfd = p->u.indirect.section->owner;
3909 if (! input_bfd->output_has_begun)
3910 {
3911 if (! aout_link_input_bfd (&aout_info, input_bfd))
3912 goto error_return;
3913 input_bfd->output_has_begun = true;
3914 }
3915 }
3916 else if (p->type == bfd_section_reloc_link_order
3917 || p->type == bfd_symbol_reloc_link_order)
3918 {
3919 /* These are handled below. */
3920 have_link_order_relocs = true;
3921 }
3922 else
3923 {
3924 if (! _bfd_default_link_order (abfd, info, o, p))
3925 goto error_return;
3926 }
3927 }
3928 }
3929
3930 /* Write out any symbols that we have not already written out. */
3931 aout_link_hash_traverse (aout_hash_table (info),
3932 aout_link_write_other_symbol,
3933 (PTR) &aout_info);
3934
3935 /* Now handle any relocs we were asked to create by the linker.
3936 These did not come from any input file. We must do these after
3937 we have written out all the symbols, so that we know the symbol
3938 indices to use. */
3939 if (have_link_order_relocs)
3940 {
3941 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3942 {
3943 for (p = o->link_order_head;
3944 p != (struct bfd_link_order *) NULL;
3945 p = p->next)
3946 {
3947 if (p->type == bfd_section_reloc_link_order
3948 || p->type == bfd_symbol_reloc_link_order)
3949 {
3950 if (! aout_link_reloc_link_order (&aout_info, o, p))
3951 goto error_return;
3952 }
3953 }
3954 }
3955 }
3956
3957 if (aout_info.contents != NULL)
3958 {
3959 free (aout_info.contents);
3960 aout_info.contents = NULL;
3961 }
3962 if (aout_info.relocs != NULL)
3963 {
3964 free (aout_info.relocs);
3965 aout_info.relocs = NULL;
3966 }
3967 if (aout_info.symbol_map != NULL)
3968 {
3969 free (aout_info.symbol_map);
3970 aout_info.symbol_map = NULL;
3971 }
3972 if (aout_info.output_syms != NULL)
3973 {
3974 free (aout_info.output_syms);
3975 aout_info.output_syms = NULL;
3976 }
3977 if (includes_hash_initialized)
3978 {
3979 bfd_hash_table_free (&aout_info.includes.root);
3980 includes_hash_initialized = false;
3981 }
3982
3983 /* Finish up any dynamic linking we may be doing. */
3984 if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
3985 {
3986 if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
3987 goto error_return;
3988 }
3989
3990 /* Update the header information. */
3991 abfd->symcount = obj_aout_external_sym_count (abfd);
3992 exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
3993 obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
3994 obj_textsec (abfd)->reloc_count =
3995 exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
3996 obj_datasec (abfd)->reloc_count =
3997 exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
3998
3999 /* Write out the string table, unless there are no symbols. */
4000 if (abfd->symcount > 0)
4001 {
4002 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
4003 || ! emit_stringtab (abfd, aout_info.strtab))
4004 goto error_return;
4005 }
4006 else if (obj_textsec (abfd)->reloc_count == 0
4007 && obj_datasec (abfd)->reloc_count == 0)
4008 {
4009 bfd_byte b;
dc810e39 4010 file_ptr pos;
252b5132
RH
4011
4012 b = 0;
dc810e39
AM
4013 pos = obj_datasec (abfd)->filepos + exec_hdr (abfd)->a_data - 1;
4014 if (bfd_seek (abfd, pos, SEEK_SET) != 0
4015 || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
252b5132
RH
4016 goto error_return;
4017 }
4018
4019 return true;
4020
4021 error_return:
4022 if (aout_info.contents != NULL)
4023 free (aout_info.contents);
4024 if (aout_info.relocs != NULL)
4025 free (aout_info.relocs);
4026 if (aout_info.symbol_map != NULL)
4027 free (aout_info.symbol_map);
4028 if (aout_info.output_syms != NULL)
4029 free (aout_info.output_syms);
4030 if (includes_hash_initialized)
4031 bfd_hash_table_free (&aout_info.includes.root);
4032 return false;
4033}
4034
4035/* Link an a.out input BFD into the output file. */
4036
4037static boolean
4038aout_link_input_bfd (finfo, input_bfd)
4039 struct aout_final_link_info *finfo;
4040 bfd *input_bfd;
4041{
4042 bfd_size_type sym_count;
4043
4044 BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
4045
4046 /* If this is a dynamic object, it may need special handling. */
4047 if ((input_bfd->flags & DYNAMIC) != 0
4048 && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
4049 {
4050 return ((*aout_backend_info (input_bfd)->link_dynamic_object)
4051 (finfo->info, input_bfd));
4052 }
4053
4054 /* Get the symbols. We probably have them already, unless
4055 finfo->info->keep_memory is false. */
4056 if (! aout_get_external_symbols (input_bfd))
4057 return false;
4058
4059 sym_count = obj_aout_external_sym_count (input_bfd);
4060
4061 /* Write out the symbols and get a map of the new indices. The map
4062 is placed into finfo->symbol_map. */
4063 if (! aout_link_write_symbols (finfo, input_bfd))
4064 return false;
4065
4066 /* Relocate and write out the sections. These functions use the
4067 symbol map created by aout_link_write_symbols. The linker_mark
4068 field will be set if these sections are to be included in the
4069 link, which will normally be the case. */
4070 if (obj_textsec (input_bfd)->linker_mark)
4071 {
4072 if (! aout_link_input_section (finfo, input_bfd,
4073 obj_textsec (input_bfd),
4074 &finfo->treloff,
4075 exec_hdr (input_bfd)->a_trsize))
4076 return false;
4077 }
4078 if (obj_datasec (input_bfd)->linker_mark)
4079 {
4080 if (! aout_link_input_section (finfo, input_bfd,
4081 obj_datasec (input_bfd),
4082 &finfo->dreloff,
4083 exec_hdr (input_bfd)->a_drsize))
4084 return false;
4085 }
4086
4087 /* If we are not keeping memory, we don't need the symbols any
4088 longer. We still need them if we are keeping memory, because the
4089 strings in the hash table point into them. */
4090 if (! finfo->info->keep_memory)
4091 {
4092 if (! aout_link_free_symbols (input_bfd))
4093 return false;
4094 }
4095
4096 return true;
4097}
4098
4099/* Adjust and write out the symbols for an a.out file. Set the new
4100 symbol indices into a symbol_map. */
4101
4102static boolean
4103aout_link_write_symbols (finfo, input_bfd)
4104 struct aout_final_link_info *finfo;
4105 bfd *input_bfd;
4106{
4107 bfd *output_bfd;
4108 bfd_size_type sym_count;
4109 char *strings;
4110 enum bfd_link_strip strip;
4111 enum bfd_link_discard discard;
4112 struct external_nlist *outsym;
4113 bfd_size_type strtab_index;
4114 register struct external_nlist *sym;
4115 struct external_nlist *sym_end;
4116 struct aout_link_hash_entry **sym_hash;
4117 int *symbol_map;
4118 boolean pass;
4119 boolean skip_next;
4120
4121 output_bfd = finfo->output_bfd;
4122 sym_count = obj_aout_external_sym_count (input_bfd);
4123 strings = obj_aout_external_strings (input_bfd);
4124 strip = finfo->info->strip;
4125 discard = finfo->info->discard;
4126 outsym = finfo->output_syms;
4127
4128 /* First write out a symbol for this object file, unless we are
4129 discarding such symbols. */
4130 if (strip != strip_all
4131 && (strip != strip_some
4132 || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
4133 false, false) != NULL)
4134 && discard != discard_all)
4135 {
dc810e39
AM
4136 H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
4137 H_PUT_8 (output_bfd, 0, outsym->e_other);
4138 H_PUT_16 (output_bfd, 0, outsym->e_desc);
252b5132
RH
4139 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4140 input_bfd->filename, false);
4141 if (strtab_index == (bfd_size_type) -1)
4142 return false;
4143 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4144 PUT_WORD (output_bfd,
4145 (bfd_get_section_vma (output_bfd,
4146 obj_textsec (input_bfd)->output_section)
4147 + obj_textsec (input_bfd)->output_offset),
4148 outsym->e_value);
4149 ++obj_aout_external_sym_count (output_bfd);
4150 ++outsym;
4151 }
4152
4153 pass = false;
4154 skip_next = false;
4155 sym = obj_aout_external_syms (input_bfd);
4156 sym_end = sym + sym_count;
4157 sym_hash = obj_aout_sym_hashes (input_bfd);
4158 symbol_map = finfo->symbol_map;
dc810e39 4159 memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
252b5132
RH
4160 for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
4161 {
4162 const char *name;
4163 int type;
4164 struct aout_link_hash_entry *h;
4165 boolean skip;
4166 asection *symsec;
4167 bfd_vma val = 0;
4168 boolean copy;
4169
4170 /* We set *symbol_map to 0 above for all symbols. If it has
4171 already been set to -1 for this symbol, it means that we are
4172 discarding it because it appears in a duplicate header file.
4173 See the N_BINCL code below. */
4174 if (*symbol_map == -1)
4175 continue;
4176
4177 /* Initialize *symbol_map to -1, which means that the symbol was
4178 not copied into the output file. We will change it later if
4179 we do copy the symbol over. */
4180 *symbol_map = -1;
4181
dc810e39 4182 type = H_GET_8 (input_bfd, sym->e_type);
252b5132
RH
4183 name = strings + GET_WORD (input_bfd, sym->e_strx);
4184
4185 h = NULL;
4186
4187 if (pass)
4188 {
4189 /* Pass this symbol through. It is the target of an
4190 indirect or warning symbol. */
4191 val = GET_WORD (input_bfd, sym->e_value);
4192 pass = false;
4193 }
4194 else if (skip_next)
4195 {
4196 /* Skip this symbol, which is the target of an indirect
4197 symbol that we have changed to no longer be an indirect
4198 symbol. */
4199 skip_next = false;
4200 continue;
4201 }
4202 else
4203 {
4204 struct aout_link_hash_entry *hresolve;
4205
4206 /* We have saved the hash table entry for this symbol, if
4207 there is one. Note that we could just look it up again
4208 in the hash table, provided we first check that it is an
0ef5a5bd 4209 external symbol. */
252b5132
RH
4210 h = *sym_hash;
4211
4212 /* Use the name from the hash table, in case the symbol was
4213 wrapped. */
0f3bd64f
AM
4214 if (h != NULL
4215 && h->root.type != bfd_link_hash_warning)
252b5132
RH
4216 name = h->root.root.string;
4217
4218 /* If this is an indirect or warning symbol, then change
4219 hresolve to the base symbol. We also change *sym_hash so
4220 that the relocation routines relocate against the real
4221 symbol. */
4222 hresolve = h;
4223 if (h != (struct aout_link_hash_entry *) NULL
4224 && (h->root.type == bfd_link_hash_indirect
4225 || h->root.type == bfd_link_hash_warning))
4226 {
4227 hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
4228 while (hresolve->root.type == bfd_link_hash_indirect
4229 || hresolve->root.type == bfd_link_hash_warning)
4230 hresolve = ((struct aout_link_hash_entry *)
4231 hresolve->root.u.i.link);
4232 *sym_hash = hresolve;
4233 }
4234
4235 /* If the symbol has already been written out, skip it. */
4236 if (h != (struct aout_link_hash_entry *) NULL
252b5132
RH
4237 && h->written)
4238 {
4239 if ((type & N_TYPE) == N_INDR
4240 || type == N_WARNING)
4241 skip_next = true;
4242 *symbol_map = h->indx;
4243 continue;
4244 }
4245
4246 /* See if we are stripping this symbol. */
4247 skip = false;
4248 switch (strip)
4249 {
4250 case strip_none:
4251 break;
4252 case strip_debugger:
4253 if ((type & N_STAB) != 0)
4254 skip = true;
4255 break;
4256 case strip_some:
4257 if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
4258 == NULL)
4259 skip = true;
4260 break;
4261 case strip_all:
4262 skip = true;
4263 break;
4264 }
4265 if (skip)
4266 {
4267 if (h != (struct aout_link_hash_entry *) NULL)
4268 h->written = true;
4269 continue;
4270 }
4271
4272 /* Get the value of the symbol. */
4273 if ((type & N_TYPE) == N_TEXT
4274 || type == N_WEAKT)
4275 symsec = obj_textsec (input_bfd);
4276 else if ((type & N_TYPE) == N_DATA
4277 || type == N_WEAKD)
4278 symsec = obj_datasec (input_bfd);
4279 else if ((type & N_TYPE) == N_BSS
4280 || type == N_WEAKB)
4281 symsec = obj_bsssec (input_bfd);
4282 else if ((type & N_TYPE) == N_ABS
4283 || type == N_WEAKA)
4284 symsec = bfd_abs_section_ptr;
4285 else if (((type & N_TYPE) == N_INDR
4286 && (hresolve == (struct aout_link_hash_entry *) NULL
4287 || (hresolve->root.type != bfd_link_hash_defined
4288 && hresolve->root.type != bfd_link_hash_defweak
4289 && hresolve->root.type != bfd_link_hash_common)))
4290 || type == N_WARNING)
4291 {
4292 /* Pass the next symbol through unchanged. The
4293 condition above for indirect symbols is so that if
4294 the indirect symbol was defined, we output it with
4295 the correct definition so the debugger will
4296 understand it. */
4297 pass = true;
4298 val = GET_WORD (input_bfd, sym->e_value);
4299 symsec = NULL;
4300 }
4301 else if ((type & N_STAB) != 0)
4302 {
4303 val = GET_WORD (input_bfd, sym->e_value);
4304 symsec = NULL;
4305 }
4306 else
4307 {
4308 /* If we get here with an indirect symbol, it means that
4309 we are outputting it with a real definition. In such
4310 a case we do not want to output the next symbol,
4311 which is the target of the indirection. */
4312 if ((type & N_TYPE) == N_INDR)
4313 skip_next = true;
4314
4315 symsec = NULL;
4316
4317 /* We need to get the value from the hash table. We use
4318 hresolve so that if we have defined an indirect
4319 symbol we output the final definition. */
4320 if (h == (struct aout_link_hash_entry *) NULL)
4321 {
4322 switch (type & N_TYPE)
4323 {
4324 case N_SETT:
4325 symsec = obj_textsec (input_bfd);
4326 break;
4327 case N_SETD:
4328 symsec = obj_datasec (input_bfd);
4329 break;
4330 case N_SETB:
4331 symsec = obj_bsssec (input_bfd);
4332 break;
4333 case N_SETA:
4334 symsec = bfd_abs_section_ptr;
4335 break;
4336 default:
4337 val = 0;
4338 break;
4339 }
4340 }
4341 else if (hresolve->root.type == bfd_link_hash_defined
4342 || hresolve->root.type == bfd_link_hash_defweak)
4343 {
4344 asection *input_section;
4345 asection *output_section;
4346
4347 /* This case usually means a common symbol which was
4348 turned into a defined symbol. */
4349 input_section = hresolve->root.u.def.section;
4350 output_section = input_section->output_section;
4351 BFD_ASSERT (bfd_is_abs_section (output_section)
4352 || output_section->owner == output_bfd);
4353 val = (hresolve->root.u.def.value
4354 + bfd_get_section_vma (output_bfd, output_section)
4355 + input_section->output_offset);
4356
4357 /* Get the correct type based on the section. If
4358 this is a constructed set, force it to be
4359 globally visible. */
4360 if (type == N_SETT
4361 || type == N_SETD
4362 || type == N_SETB
4363 || type == N_SETA)
4364 type |= N_EXT;
4365
4366 type &=~ N_TYPE;
4367
4368 if (output_section == obj_textsec (output_bfd))
4369 type |= (hresolve->root.type == bfd_link_hash_defined
4370 ? N_TEXT
4371 : N_WEAKT);
4372 else if (output_section == obj_datasec (output_bfd))
4373 type |= (hresolve->root.type == bfd_link_hash_defined
4374 ? N_DATA
4375 : N_WEAKD);
4376 else if (output_section == obj_bsssec (output_bfd))
4377 type |= (hresolve->root.type == bfd_link_hash_defined
4378 ? N_BSS
4379 : N_WEAKB);
4380 else
4381 type |= (hresolve->root.type == bfd_link_hash_defined
4382 ? N_ABS
4383 : N_WEAKA);
4384 }
4385 else if (hresolve->root.type == bfd_link_hash_common)
4386 val = hresolve->root.u.c.size;
4387 else if (hresolve->root.type == bfd_link_hash_undefweak)
4388 {
4389 val = 0;
4390 type = N_WEAKU;
4391 }
4392 else
4393 val = 0;
4394 }
4395 if (symsec != (asection *) NULL)
4396 val = (symsec->output_section->vma
4397 + symsec->output_offset
4398 + (GET_WORD (input_bfd, sym->e_value)
4399 - symsec->vma));
4400
4401 /* If this is a global symbol set the written flag, and if
4402 it is a local symbol see if we should discard it. */
4403 if (h != (struct aout_link_hash_entry *) NULL)
4404 {
4405 h->written = true;
4406 h->indx = obj_aout_external_sym_count (output_bfd);
4407 }
4408 else if ((type & N_TYPE) != N_SETT
4409 && (type & N_TYPE) != N_SETD
4410 && (type & N_TYPE) != N_SETB
4411 && (type & N_TYPE) != N_SETA)
4412 {
4413 switch (discard)
4414 {
4415 case discard_none:
f5fa8ca2 4416 case discard_sec_merge:
252b5132
RH
4417 break;
4418 case discard_l:
4419 if ((type & N_STAB) == 0
4420 && bfd_is_local_label_name (input_bfd, name))
4421 skip = true;
4422 break;
4423 case discard_all:
4424 skip = true;
4425 break;
4426 }
4427 if (skip)
4428 {
4429 pass = false;
4430 continue;
4431 }
4432 }
4433
4434 /* An N_BINCL symbol indicates the start of the stabs
4435 entries for a header file. We need to scan ahead to the
4436 next N_EINCL symbol, ignoring nesting, adding up all the
4437 characters in the symbol names, not including the file
4438 numbers in types (the first number after an open
4439 parenthesis). */
4440 if (type == N_BINCL)
4441 {
4442 struct external_nlist *incl_sym;
4443 int nest;
4444 struct aout_link_includes_entry *incl_entry;
4445 struct aout_link_includes_totals *t;
4446
4447 val = 0;
4448 nest = 0;
4449 for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
4450 {
4451 int incl_type;
4452
dc810e39 4453 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
252b5132
RH
4454 if (incl_type == N_EINCL)
4455 {
4456 if (nest == 0)
4457 break;
4458 --nest;
4459 }
4460 else if (incl_type == N_BINCL)
4461 ++nest;
4462 else if (nest == 0)
4463 {
4464 const char *s;
4465
4466 s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
4467 for (; *s != '\0'; s++)
4468 {
4469 val += *s;
4470 if (*s == '(')
4471 {
4472 /* Skip the file number. */
4473 ++s;
3882b010 4474 while (ISDIGIT (*s))
252b5132
RH
4475 ++s;
4476 --s;
4477 }
4478 }
4479 }
4480 }
4481
4482 /* If we have already included a header file with the
4483 same value, then replace this one with an N_EXCL
4484 symbol. */
4485 copy = ! finfo->info->keep_memory;
4486 incl_entry = aout_link_includes_lookup (&finfo->includes,
4487 name, true, copy);
4488 if (incl_entry == NULL)
4489 return false;
4490 for (t = incl_entry->totals; t != NULL; t = t->next)
4491 if (t->total == val)
4492 break;
4493 if (t == NULL)
4494 {
4495 /* This is the first time we have seen this header
4496 file with this set of stabs strings. */
4497 t = ((struct aout_link_includes_totals *)
4498 bfd_hash_allocate (&finfo->includes.root,
4499 sizeof *t));
4500 if (t == NULL)
4501 return false;
4502 t->total = val;
4503 t->next = incl_entry->totals;
4504 incl_entry->totals = t;
4505 }
4506 else
4507 {
4508 int *incl_map;
4509
4510 /* This is a duplicate header file. We must change
4511 it to be an N_EXCL entry, and mark all the
4512 included symbols to prevent outputting them. */
4513 type = N_EXCL;
4514
4515 nest = 0;
4516 for (incl_sym = sym + 1, incl_map = symbol_map + 1;
4517 incl_sym < sym_end;
4518 incl_sym++, incl_map++)
4519 {
4520 int incl_type;
4521
dc810e39 4522 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
252b5132
RH
4523 if (incl_type == N_EINCL)
4524 {
4525 if (nest == 0)
4526 {
4527 *incl_map = -1;
4528 break;
4529 }
4530 --nest;
4531 }
4532 else if (incl_type == N_BINCL)
4533 ++nest;
4534 else if (nest == 0)
4535 *incl_map = -1;
4536 }
4537 }
4538 }
4539 }
4540
4541 /* Copy this symbol into the list of symbols we are going to
4542 write out. */
dc810e39
AM
4543 H_PUT_8 (output_bfd, type, outsym->e_type);
4544 H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_other), outsym->e_other);
4545 H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc);
252b5132
RH
4546 copy = false;
4547 if (! finfo->info->keep_memory)
4548 {
4549 /* name points into a string table which we are going to
4550 free. If there is a hash table entry, use that string.
4551 Otherwise, copy name into memory. */
4552 if (h != (struct aout_link_hash_entry *) NULL)
4553 name = h->root.root.string;
4554 else
4555 copy = true;
4556 }
4557 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4558 name, copy);
4559 if (strtab_index == (bfd_size_type) -1)
4560 return false;
4561 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4562 PUT_WORD (output_bfd, val, outsym->e_value);
4563 *symbol_map = obj_aout_external_sym_count (output_bfd);
4564 ++obj_aout_external_sym_count (output_bfd);
4565 ++outsym;
4566 }
4567
4568 /* Write out the output symbols we have just constructed. */
4569 if (outsym > finfo->output_syms)
4570 {
dc810e39 4571 bfd_size_type outsym_size;
252b5132
RH
4572
4573 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
4574 return false;
dc810e39
AM
4575 outsym_size = outsym - finfo->output_syms;
4576 outsym_size *= EXTERNAL_NLIST_SIZE;
4577 if (bfd_bwrite ((PTR) finfo->output_syms, outsym_size, output_bfd)
4578 != outsym_size)
252b5132 4579 return false;
dc810e39 4580 finfo->symoff += outsym_size;
252b5132
RH
4581 }
4582
4583 return true;
4584}
4585
4586/* Write out a symbol that was not associated with an a.out input
4587 object. */
4588
4589static boolean
4590aout_link_write_other_symbol (h, data)
4591 struct aout_link_hash_entry *h;
4592 PTR data;
4593{
4594 struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
4595 bfd *output_bfd;
4596 int type;
4597 bfd_vma val;
4598 struct external_nlist outsym;
4599 bfd_size_type indx;
dc810e39 4600 bfd_size_type amt;
252b5132 4601
e92d460e
AM
4602 if (h->root.type == bfd_link_hash_warning)
4603 {
4604 h = (struct aout_link_hash_entry *) h->root.u.i.link;
4605 if (h->root.type == bfd_link_hash_new)
4606 return true;
4607 }
4608
252b5132
RH
4609 output_bfd = finfo->output_bfd;
4610
4611 if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
4612 {
4613 if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
4614 (output_bfd, finfo->info, h)))
4615 {
4616 /* FIXME: No way to handle errors. */
4617 abort ();
4618 }
4619 }
4620
4621 if (h->written)
4622 return true;
4623
4624 h->written = true;
4625
4626 /* An indx of -2 means the symbol must be written. */
4627 if (h->indx != -2
4628 && (finfo->info->strip == strip_all
4629 || (finfo->info->strip == strip_some
4630 && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
4631 false, false) == NULL)))
4632 return true;
4633
4634 switch (h->root.type)
4635 {
4636 default:
e92d460e 4637 case bfd_link_hash_warning:
252b5132
RH
4638 abort ();
4639 /* Avoid variable not initialized warnings. */
4640 return true;
4641 case bfd_link_hash_new:
4642 /* This can happen for set symbols when sets are not being
4643 built. */
4644 return true;
4645 case bfd_link_hash_undefined:
4646 type = N_UNDF | N_EXT;
4647 val = 0;
4648 break;
4649 case bfd_link_hash_defined:
4650 case bfd_link_hash_defweak:
4651 {
4652 asection *sec;
4653
4654 sec = h->root.u.def.section->output_section;
4655 BFD_ASSERT (bfd_is_abs_section (sec)
4656 || sec->owner == output_bfd);
4657 if (sec == obj_textsec (output_bfd))
4658 type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
4659 else if (sec == obj_datasec (output_bfd))
4660 type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
4661 else if (sec == obj_bsssec (output_bfd))
4662 type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
4663 else
4664 type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
4665 type |= N_EXT;
4666 val = (h->root.u.def.value
4667 + sec->vma
4668 + h->root.u.def.section->output_offset);
4669 }
4670 break;
4671 case bfd_link_hash_common:
4672 type = N_UNDF | N_EXT;
4673 val = h->root.u.c.size;
4674 break;
4675 case bfd_link_hash_undefweak:
4676 type = N_WEAKU;
4677 val = 0;
4678 case bfd_link_hash_indirect:
e92d460e
AM
4679 /* We ignore these symbols, since the indirected symbol is
4680 already in the hash table. */
252b5132
RH
4681 return true;
4682 }
4683
dc810e39
AM
4684 H_PUT_8 (output_bfd, type, outsym.e_type);
4685 H_PUT_8 (output_bfd, 0, outsym.e_other);
4686 H_PUT_16 (output_bfd, 0, outsym.e_desc);
252b5132
RH
4687 indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
4688 false);
dc810e39 4689 if (indx == - (bfd_size_type) 1)
252b5132
RH
4690 {
4691 /* FIXME: No way to handle errors. */
4692 abort ();
4693 }
4694 PUT_WORD (output_bfd, indx, outsym.e_strx);
4695 PUT_WORD (output_bfd, val, outsym.e_value);
4696
dc810e39 4697 amt = EXTERNAL_NLIST_SIZE;
252b5132 4698 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
dc810e39 4699 || bfd_bwrite ((PTR) &outsym, amt, output_bfd) != amt)
252b5132
RH
4700 {
4701 /* FIXME: No way to handle errors. */
4702 abort ();
4703 }
4704
4705 finfo->symoff += EXTERNAL_NLIST_SIZE;
4706 h->indx = obj_aout_external_sym_count (output_bfd);
4707 ++obj_aout_external_sym_count (output_bfd);
4708
4709 return true;
4710}
4711
4712/* Link an a.out section into the output file. */
4713
4714static boolean
4715aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
4716 rel_size)
4717 struct aout_final_link_info *finfo;
4718 bfd *input_bfd;
4719 asection *input_section;
4720 file_ptr *reloff_ptr;
4721 bfd_size_type rel_size;
4722{
4723 bfd_size_type input_size;
4724 PTR relocs;
4725
4726 /* Get the section contents. */
4727 input_size = bfd_section_size (input_bfd, input_section);
4728 if (! bfd_get_section_contents (input_bfd, input_section,
4729 (PTR) finfo->contents,
4730 (file_ptr) 0, input_size))
4731 return false;
4732
4733 /* Read in the relocs if we haven't already done it. */
4734 if (aout_section_data (input_section) != NULL
4735 && aout_section_data (input_section)->relocs != NULL)
4736 relocs = aout_section_data (input_section)->relocs;
4737 else
4738 {
4739 relocs = finfo->relocs;
4740 if (rel_size > 0)
4741 {
4742 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
dc810e39 4743 || bfd_bread (relocs, rel_size, input_bfd) != rel_size)
252b5132
RH
4744 return false;
4745 }
4746 }
4747
4748 /* Relocate the section contents. */
4749 if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4750 {
4751 if (! aout_link_input_section_std (finfo, input_bfd, input_section,
4752 (struct reloc_std_external *) relocs,
4753 rel_size, finfo->contents))
4754 return false;
4755 }
4756 else
4757 {
4758 if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
4759 (struct reloc_ext_external *) relocs,
4760 rel_size, finfo->contents))
4761 return false;
4762 }
4763
4764 /* Write out the section contents. */
4765 if (! bfd_set_section_contents (finfo->output_bfd,
4766 input_section->output_section,
4767 (PTR) finfo->contents,
dc810e39 4768 (file_ptr) input_section->output_offset,
252b5132
RH
4769 input_size))
4770 return false;
4771
4772 /* If we are producing relocateable output, the relocs were
4773 modified, and we now write them out. */
4774 if (finfo->info->relocateable && rel_size > 0)
4775 {
4776 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
4777 return false;
dc810e39 4778 if (bfd_bwrite (relocs, rel_size, finfo->output_bfd) != rel_size)
252b5132
RH
4779 return false;
4780 *reloff_ptr += rel_size;
4781
4782 /* Assert that the relocs have not run into the symbols, and
4783 that if these are the text relocs they have not run into the
4784 data relocs. */
4785 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
4786 && (reloff_ptr != &finfo->treloff
4787 || (*reloff_ptr
4788 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
4789 }
4790
4791 return true;
4792}
4793
4794/* Get the section corresponding to a reloc index. */
4795
4796static INLINE asection *
4797aout_reloc_index_to_section (abfd, indx)
4798 bfd *abfd;
4799 int indx;
4800{
4801 switch (indx & N_TYPE)
4802 {
4803 case N_TEXT:
4804 return obj_textsec (abfd);
4805 case N_DATA:
4806 return obj_datasec (abfd);
4807 case N_BSS:
4808 return obj_bsssec (abfd);
4809 case N_ABS:
4810 case N_UNDF:
4811 return bfd_abs_section_ptr;
4812 default:
4813 abort ();
4814 }
7442e600
ILT
4815 /*NOTREACHED*/
4816 return NULL;
252b5132
RH
4817}
4818
4819/* Relocate an a.out section using standard a.out relocs. */
4820
4821static boolean
4822aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
4823 rel_size, contents)
4824 struct aout_final_link_info *finfo;
4825 bfd *input_bfd;
4826 asection *input_section;
4827 struct reloc_std_external *relocs;
4828 bfd_size_type rel_size;
4829 bfd_byte *contents;
4830{
4831 boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
4832 bfd *, asection *,
4833 struct aout_link_hash_entry *,
4834 PTR, bfd_byte *, boolean *,
4835 bfd_vma *));
4836 bfd *output_bfd;
4837 boolean relocateable;
4838 struct external_nlist *syms;
4839 char *strings;
4840 struct aout_link_hash_entry **sym_hashes;
4841 int *symbol_map;
4842 bfd_size_type reloc_count;
4843 register struct reloc_std_external *rel;
4844 struct reloc_std_external *rel_end;
4845
4846 output_bfd = finfo->output_bfd;
4847 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4848
4849 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
4850 BFD_ASSERT (input_bfd->xvec->header_byteorder
4851 == output_bfd->xvec->header_byteorder);
4852
4853 relocateable = finfo->info->relocateable;
4854 syms = obj_aout_external_syms (input_bfd);
4855 strings = obj_aout_external_strings (input_bfd);
4856 sym_hashes = obj_aout_sym_hashes (input_bfd);
4857 symbol_map = finfo->symbol_map;
4858
4859 reloc_count = rel_size / RELOC_STD_SIZE;
4860 rel = relocs;
4861 rel_end = rel + reloc_count;
4862 for (; rel < rel_end; rel++)
4863 {
4864 bfd_vma r_addr;
4865 int r_index;
4866 int r_extern;
4867 int r_pcrel;
4868 int r_baserel = 0;
4869 reloc_howto_type *howto;
4870 struct aout_link_hash_entry *h = NULL;
4871 bfd_vma relocation;
4872 bfd_reloc_status_type r;
4873
4874 r_addr = GET_SWORD (input_bfd, rel->r_address);
4875
4876#ifdef MY_reloc_howto
923f08ff 4877 howto = MY_reloc_howto (input_bfd, rel, r_index, r_extern, r_pcrel);
0ef5a5bd 4878#else
252b5132
RH
4879 {
4880 int r_jmptable;
4881 int r_relative;
4882 int r_length;
4883 unsigned int howto_idx;
4884
4885 if (bfd_header_big_endian (input_bfd))
4886 {
4887 r_index = ((rel->r_index[0] << 16)
4888 | (rel->r_index[1] << 8)
4889 | rel->r_index[2]);
4890 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
4891 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
4892 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
4893 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
4894 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
4895 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
4896 >> RELOC_STD_BITS_LENGTH_SH_BIG);
4897 }
4898 else
4899 {
4900 r_index = ((rel->r_index[2] << 16)
4901 | (rel->r_index[1] << 8)
4902 | rel->r_index[0]);
4903 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
4904 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
4905 r_baserel = (0 != (rel->r_type[0]
4906 & RELOC_STD_BITS_BASEREL_LITTLE));
4907 r_jmptable= (0 != (rel->r_type[0]
4908 & RELOC_STD_BITS_JMPTABLE_LITTLE));
4909 r_relative= (0 != (rel->r_type[0]
4910 & RELOC_STD_BITS_RELATIVE_LITTLE));
4911 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
4912 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
4913 }
4914
4915 howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
4916 + 16 * r_jmptable + 32 * r_relative);
4917 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
4918 howto = howto_table_std + howto_idx;
4919 }
4920#endif
4921
4922 if (relocateable)
4923 {
4924 /* We are generating a relocateable output file, and must
4925 modify the reloc accordingly. */
4926 if (r_extern)
4927 {
4928 /* If we know the symbol this relocation is against,
4929 convert it into a relocation against a section. This
4930 is what the native linker does. */
4931 h = sym_hashes[r_index];
4932 if (h != (struct aout_link_hash_entry *) NULL
4933 && (h->root.type == bfd_link_hash_defined
4934 || h->root.type == bfd_link_hash_defweak))
4935 {
4936 asection *output_section;
4937
4938 /* Change the r_extern value. */
4939 if (bfd_header_big_endian (output_bfd))
4940 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
4941 else
4942 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
4943
4944 /* Compute a new r_index. */
4945 output_section = h->root.u.def.section->output_section;
4946 if (output_section == obj_textsec (output_bfd))
4947 r_index = N_TEXT;
4948 else if (output_section == obj_datasec (output_bfd))
4949 r_index = N_DATA;
4950 else if (output_section == obj_bsssec (output_bfd))
4951 r_index = N_BSS;
4952 else
4953 r_index = N_ABS;
4954
4955 /* Add the symbol value and the section VMA to the
4956 addend stored in the contents. */
4957 relocation = (h->root.u.def.value
4958 + output_section->vma
4959 + h->root.u.def.section->output_offset);
4960 }
4961 else
4962 {
4963 /* We must change r_index according to the symbol
4964 map. */
4965 r_index = symbol_map[r_index];
4966
4967 if (r_index == -1)
4968 {
4969 if (h != NULL)
4970 {
4971 /* We decided to strip this symbol, but it
4972 turns out that we can't. Note that we
4973 lose the other and desc information here.
4974 I don't think that will ever matter for a
4975 global symbol. */
4976 if (h->indx < 0)
4977 {
4978 h->indx = -2;
4979 h->written = false;
4980 if (! aout_link_write_other_symbol (h,
4981 (PTR) finfo))
4982 return false;
4983 }
4984 r_index = h->indx;
4985 }
4986 else
4987 {
4988 const char *name;
4989
4990 name = strings + GET_WORD (input_bfd,
4991 syms[r_index].e_strx);
4992 if (! ((*finfo->info->callbacks->unattached_reloc)
4993 (finfo->info, name, input_bfd, input_section,
4994 r_addr)))
4995 return false;
4996 r_index = 0;
4997 }
4998 }
4999
5000 relocation = 0;
5001 }
5002
5003 /* Write out the new r_index value. */
5004 if (bfd_header_big_endian (output_bfd))
5005 {
5006 rel->r_index[0] = r_index >> 16;
5007 rel->r_index[1] = r_index >> 8;
5008 rel->r_index[2] = r_index;
5009 }
5010 else
5011 {
5012 rel->r_index[2] = r_index >> 16;
5013 rel->r_index[1] = r_index >> 8;
5014 rel->r_index[0] = r_index;
5015 }
5016 }
5017 else
5018 {
5019 asection *section;
5020
5021 /* This is a relocation against a section. We must
5022 adjust by the amount that the section moved. */
5023 section = aout_reloc_index_to_section (input_bfd, r_index);
5024 relocation = (section->output_section->vma
5025 + section->output_offset
5026 - section->vma);
5027 }
5028
5029 /* Change the address of the relocation. */
5030 PUT_WORD (output_bfd,
5031 r_addr + input_section->output_offset,
5032 rel->r_address);
5033
5034 /* Adjust a PC relative relocation by removing the reference
5035 to the original address in the section and including the
5036 reference to the new address. */
5037 if (r_pcrel)
5038 relocation -= (input_section->output_section->vma
5039 + input_section->output_offset
5040 - input_section->vma);
5041
5042#ifdef MY_relocatable_reloc
5043 MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
5044#endif
5045
5046 if (relocation == 0)
5047 r = bfd_reloc_ok;
5048 else
5049 r = MY_relocate_contents (howto,
5050 input_bfd, relocation,
5051 contents + r_addr);
5052 }
5053 else
5054 {
5055 boolean hundef;
5056
5057 /* We are generating an executable, and must do a full
5058 relocation. */
5059 hundef = false;
5060
5061 if (r_extern)
5062 {
5063 h = sym_hashes[r_index];
5064
5065 if (h != (struct aout_link_hash_entry *) NULL
5066 && (h->root.type == bfd_link_hash_defined
5067 || h->root.type == bfd_link_hash_defweak))
5068 {
5069 relocation = (h->root.u.def.value
5070 + h->root.u.def.section->output_section->vma
5071 + h->root.u.def.section->output_offset);
5072 }
5073 else if (h != (struct aout_link_hash_entry *) NULL
5074 && h->root.type == bfd_link_hash_undefweak)
5075 relocation = 0;
5076 else
5077 {
5078 hundef = true;
5079 relocation = 0;
5080 }
5081 }
5082 else
5083 {
5084 asection *section;
5085
5086 section = aout_reloc_index_to_section (input_bfd, r_index);
5087 relocation = (section->output_section->vma
5088 + section->output_offset
5089 - section->vma);
5090 if (r_pcrel)
5091 relocation += input_section->vma;
5092 }
5093
5094 if (check_dynamic_reloc != NULL)
5095 {
5096 boolean skip;
5097
5098 if (! ((*check_dynamic_reloc)
5099 (finfo->info, input_bfd, input_section, h,
5100 (PTR) rel, contents, &skip, &relocation)))
5101 return false;
5102 if (skip)
5103 continue;
5104 }
5105
5106 /* Now warn if a global symbol is undefined. We could not
5107 do this earlier, because check_dynamic_reloc might want
5108 to skip this reloc. */
5109 if (hundef && ! finfo->info->shared && ! r_baserel)
5110 {
5111 const char *name;
5112
5113 if (h != NULL)
5114 name = h->root.root.string;
5115 else
5116 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5117 if (! ((*finfo->info->callbacks->undefined_symbol)
5cc7c785
L
5118 (finfo->info, name, input_bfd, input_section,
5119 r_addr, true)))
252b5132
RH
5120 return false;
5121 }
5122
5123 r = MY_final_link_relocate (howto,
5124 input_bfd, input_section,
5125 contents, r_addr, relocation,
5126 (bfd_vma) 0);
5127 }
5128
5129 if (r != bfd_reloc_ok)
5130 {
5131 switch (r)
5132 {
5133 default:
5134 case bfd_reloc_outofrange:
5135 abort ();
5136 case bfd_reloc_overflow:
5137 {
5138 const char *name;
5139
5140 if (h != NULL)
5141 name = h->root.root.string;
5142 else if (r_extern)
5143 name = strings + GET_WORD (input_bfd,
5144 syms[r_index].e_strx);
5145 else
5146 {
5147 asection *s;
5148
5149 s = aout_reloc_index_to_section (input_bfd, r_index);
5150 name = bfd_section_name (input_bfd, s);
5151 }
5152 if (! ((*finfo->info->callbacks->reloc_overflow)
5153 (finfo->info, name, howto->name,
5154 (bfd_vma) 0, input_bfd, input_section, r_addr)))
5155 return false;
5156 }
5157 break;
5158 }
5159 }
5160 }
5161
5162 return true;
5163}
5164
5165/* Relocate an a.out section using extended a.out relocs. */
5166
5167static boolean
5168aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
5169 rel_size, contents)
5170 struct aout_final_link_info *finfo;
5171 bfd *input_bfd;
5172 asection *input_section;
5173 struct reloc_ext_external *relocs;
5174 bfd_size_type rel_size;
5175 bfd_byte *contents;
5176{
5177 boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
5178 bfd *, asection *,
5179 struct aout_link_hash_entry *,
5180 PTR, bfd_byte *, boolean *,
5181 bfd_vma *));
5182 bfd *output_bfd;
5183 boolean relocateable;
5184 struct external_nlist *syms;
5185 char *strings;
5186 struct aout_link_hash_entry **sym_hashes;
5187 int *symbol_map;
5188 bfd_size_type reloc_count;
5189 register struct reloc_ext_external *rel;
5190 struct reloc_ext_external *rel_end;
5191
5192 output_bfd = finfo->output_bfd;
5193 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
5194
5195 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
5196 BFD_ASSERT (input_bfd->xvec->header_byteorder
5197 == output_bfd->xvec->header_byteorder);
5198
5199 relocateable = finfo->info->relocateable;
5200 syms = obj_aout_external_syms (input_bfd);
5201 strings = obj_aout_external_strings (input_bfd);
5202 sym_hashes = obj_aout_sym_hashes (input_bfd);
5203 symbol_map = finfo->symbol_map;
5204
5205 reloc_count = rel_size / RELOC_EXT_SIZE;
5206 rel = relocs;
5207 rel_end = rel + reloc_count;
5208 for (; rel < rel_end; rel++)
5209 {
5210 bfd_vma r_addr;
5211 int r_index;
5212 int r_extern;
5213 unsigned int r_type;
5214 bfd_vma r_addend;
5215 struct aout_link_hash_entry *h = NULL;
5216 asection *r_section = NULL;
5217 bfd_vma relocation;
5218
5219 r_addr = GET_SWORD (input_bfd, rel->r_address);
5220
5221 if (bfd_header_big_endian (input_bfd))
5222 {
5223 r_index = ((rel->r_index[0] << 16)
5224 | (rel->r_index[1] << 8)
5225 | rel->r_index[2]);
5226 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
5227 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
5228 >> RELOC_EXT_BITS_TYPE_SH_BIG);
5229 }
5230 else
5231 {
5232 r_index = ((rel->r_index[2] << 16)
5233 | (rel->r_index[1] << 8)
5234 | rel->r_index[0]);
5235 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
5236 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
5237 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
5238 }
5239
5240 r_addend = GET_SWORD (input_bfd, rel->r_addend);
5241
5242 BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
5243
5244 if (relocateable)
5245 {
5246 /* We are generating a relocateable output file, and must
5247 modify the reloc accordingly. */
5248 if (r_extern
5249 || r_type == RELOC_BASE10
5250 || r_type == RELOC_BASE13
5251 || r_type == RELOC_BASE22)
5252 {
5253 /* If we know the symbol this relocation is against,
5254 convert it into a relocation against a section. This
5255 is what the native linker does. */
5256 if (r_type == RELOC_BASE10
5257 || r_type == RELOC_BASE13
5258 || r_type == RELOC_BASE22)
5259 h = NULL;
5260 else
5261 h = sym_hashes[r_index];
5262 if (h != (struct aout_link_hash_entry *) NULL
5263 && (h->root.type == bfd_link_hash_defined
5264 || h->root.type == bfd_link_hash_defweak))
5265 {
5266 asection *output_section;
5267
5268 /* Change the r_extern value. */
5269 if (bfd_header_big_endian (output_bfd))
5270 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
5271 else
5272 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
5273
5274 /* Compute a new r_index. */
5275 output_section = h->root.u.def.section->output_section;
5276 if (output_section == obj_textsec (output_bfd))
5277 r_index = N_TEXT;
5278 else if (output_section == obj_datasec (output_bfd))
5279 r_index = N_DATA;
5280 else if (output_section == obj_bsssec (output_bfd))
5281 r_index = N_BSS;
5282 else
5283 r_index = N_ABS;
5284
5285 /* Add the symbol value and the section VMA to the
5286 addend. */
5287 relocation = (h->root.u.def.value
5288 + output_section->vma
5289 + h->root.u.def.section->output_offset);
5290
5291 /* Now RELOCATION is the VMA of the final
5292 destination. If this is a PC relative reloc,
5293 then ADDEND is the negative of the source VMA.
5294 We want to set ADDEND to the difference between
5295 the destination VMA and the source VMA, which
5296 means we must adjust RELOCATION by the change in
5297 the source VMA. This is done below. */
5298 }
5299 else
5300 {
5301 /* We must change r_index according to the symbol
5302 map. */
5303 r_index = symbol_map[r_index];
5304
5305 if (r_index == -1)
5306 {
5307 if (h != NULL)
5308 {
5309 /* We decided to strip this symbol, but it
5310 turns out that we can't. Note that we
5311 lose the other and desc information here.
5312 I don't think that will ever matter for a
5313 global symbol. */
5314 if (h->indx < 0)
5315 {
5316 h->indx = -2;
5317 h->written = false;
5318 if (! aout_link_write_other_symbol (h,
5319 (PTR) finfo))
5320 return false;
5321 }
5322 r_index = h->indx;
5323 }
5324 else
5325 {
5326 const char *name;
5327
5328 name = strings + GET_WORD (input_bfd,
5329 syms[r_index].e_strx);
5330 if (! ((*finfo->info->callbacks->unattached_reloc)
5331 (finfo->info, name, input_bfd, input_section,
5332 r_addr)))
5333 return false;
5334 r_index = 0;
5335 }
5336 }
5337
5338 relocation = 0;
5339
5340 /* If this is a PC relative reloc, then the addend
5341 is the negative of the source VMA. We must
5342 adjust it by the change in the source VMA. This
5343 is done below. */
5344 }
5345
5346 /* Write out the new r_index value. */
5347 if (bfd_header_big_endian (output_bfd))
5348 {
5349 rel->r_index[0] = r_index >> 16;
5350 rel->r_index[1] = r_index >> 8;
5351 rel->r_index[2] = r_index;
5352 }
5353 else
5354 {
5355 rel->r_index[2] = r_index >> 16;
5356 rel->r_index[1] = r_index >> 8;
5357 rel->r_index[0] = r_index;
5358 }
5359 }
5360 else
5361 {
5362 /* This is a relocation against a section. We must
5363 adjust by the amount that the section moved. */
5364 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5365 relocation = (r_section->output_section->vma
5366 + r_section->output_offset
5367 - r_section->vma);
5368
5369 /* If this is a PC relative reloc, then the addend is
5370 the difference in VMA between the destination and the
5371 source. We have just adjusted for the change in VMA
5372 of the destination, so we must also adjust by the
5373 change in VMA of the source. This is done below. */
5374 }
5375
5376 /* As described above, we must always adjust a PC relative
5377 reloc by the change in VMA of the source. However, if
5378 pcrel_offset is set, then the addend does not include the
5379 location within the section, in which case we don't need
5380 to adjust anything. */
5381 if (howto_table_ext[r_type].pc_relative
5382 && ! howto_table_ext[r_type].pcrel_offset)
5383 relocation -= (input_section->output_section->vma
5384 + input_section->output_offset
5385 - input_section->vma);
5386
5387 /* Change the addend if necessary. */
5388 if (relocation != 0)
5389 PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
5390
5391 /* Change the address of the relocation. */
5392 PUT_WORD (output_bfd,
5393 r_addr + input_section->output_offset,
5394 rel->r_address);
5395 }
5396 else
5397 {
5398 boolean hundef;
5399 bfd_reloc_status_type r;
5400
5401 /* We are generating an executable, and must do a full
5402 relocation. */
5403 hundef = false;
5404
5405 if (r_extern)
5406 {
5407 h = sym_hashes[r_index];
5408
5409 if (h != (struct aout_link_hash_entry *) NULL
5410 && (h->root.type == bfd_link_hash_defined
5411 || h->root.type == bfd_link_hash_defweak))
5412 {
5413 relocation = (h->root.u.def.value
5414 + h->root.u.def.section->output_section->vma
5415 + h->root.u.def.section->output_offset);
5416 }
5417 else if (h != (struct aout_link_hash_entry *) NULL
5418 && h->root.type == bfd_link_hash_undefweak)
5419 relocation = 0;
5420 else
5421 {
5422 hundef = true;
5423 relocation = 0;
5424 }
5425 }
5426 else if (r_type == RELOC_BASE10
5427 || r_type == RELOC_BASE13
5428 || r_type == RELOC_BASE22)
5429 {
5430 struct external_nlist *sym;
5431 int type;
5432
5433 /* For base relative relocs, r_index is always an index
5434 into the symbol table, even if r_extern is 0. */
5435 sym = syms + r_index;
dc810e39 5436 type = H_GET_8 (input_bfd, sym->e_type);
252b5132
RH
5437 if ((type & N_TYPE) == N_TEXT
5438 || type == N_WEAKT)
5439 r_section = obj_textsec (input_bfd);
5440 else if ((type & N_TYPE) == N_DATA
5441 || type == N_WEAKD)
5442 r_section = obj_datasec (input_bfd);
5443 else if ((type & N_TYPE) == N_BSS
5444 || type == N_WEAKB)
5445 r_section = obj_bsssec (input_bfd);
5446 else if ((type & N_TYPE) == N_ABS
5447 || type == N_WEAKA)
5448 r_section = bfd_abs_section_ptr;
5449 else
5450 abort ();
5451 relocation = (r_section->output_section->vma
5452 + r_section->output_offset
5453 + (GET_WORD (input_bfd, sym->e_value)
5454 - r_section->vma));
5455 }
5456 else
5457 {
5458 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5459
5460 /* If this is a PC relative reloc, then R_ADDEND is the
5461 difference between the two vmas, or
5462 old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
5463 where
5464 old_dest_sec == section->vma
5465 and
5466 old_src_sec == input_section->vma
5467 and
5468 old_src_off == r_addr
5469
5470 _bfd_final_link_relocate expects RELOCATION +
5471 R_ADDEND to be the VMA of the destination minus
5472 r_addr (the minus r_addr is because this relocation
5473 is not pcrel_offset, which is a bit confusing and
5474 should, perhaps, be changed), or
5475 new_dest_sec
5476 where
5477 new_dest_sec == output_section->vma + output_offset
5478 We arrange for this to happen by setting RELOCATION to
5479 new_dest_sec + old_src_sec - old_dest_sec
5480
5481 If this is not a PC relative reloc, then R_ADDEND is
5482 simply the VMA of the destination, so we set
5483 RELOCATION to the change in the destination VMA, or
5484 new_dest_sec - old_dest_sec
5485 */
5486 relocation = (r_section->output_section->vma
5487 + r_section->output_offset
5488 - r_section->vma);
5489 if (howto_table_ext[r_type].pc_relative)
5490 relocation += input_section->vma;
5491 }
5492
5493 if (check_dynamic_reloc != NULL)
5494 {
5495 boolean skip;
5496
5497 if (! ((*check_dynamic_reloc)
5498 (finfo->info, input_bfd, input_section, h,
5499 (PTR) rel, contents, &skip, &relocation)))
5500 return false;
5501 if (skip)
5502 continue;
5503 }
5504
5505 /* Now warn if a global symbol is undefined. We could not
5506 do this earlier, because check_dynamic_reloc might want
5507 to skip this reloc. */
5508 if (hundef
5509 && ! finfo->info->shared
5510 && r_type != RELOC_BASE10
5511 && r_type != RELOC_BASE13
5512 && r_type != RELOC_BASE22)
5513 {
5514 const char *name;
5515
5516 if (h != NULL)
5517 name = h->root.root.string;
5518 else
5519 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5520 if (! ((*finfo->info->callbacks->undefined_symbol)
5cc7c785
L
5521 (finfo->info, name, input_bfd, input_section,
5522 r_addr, true)))
252b5132
RH
5523 return false;
5524 }
5525
5526 if (r_type != RELOC_SPARC_REV32)
5527 r = MY_final_link_relocate (howto_table_ext + r_type,
5528 input_bfd, input_section,
5529 contents, r_addr, relocation,
5530 r_addend);
5531 else
5532 {
5533 bfd_vma x;
5534
5535 x = bfd_get_32 (input_bfd, contents + r_addr);
5536 x = x + relocation + r_addend;
5537 bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
5538 r = bfd_reloc_ok;
5539 }
5540
5541 if (r != bfd_reloc_ok)
5542 {
5543 switch (r)
5544 {
5545 default:
5546 case bfd_reloc_outofrange:
5547 abort ();
5548 case bfd_reloc_overflow:
5549 {
5550 const char *name;
5551
5552 if (h != NULL)
5553 name = h->root.root.string;
5554 else if (r_extern
5555 || r_type == RELOC_BASE10
5556 || r_type == RELOC_BASE13
5557 || r_type == RELOC_BASE22)
5558 name = strings + GET_WORD (input_bfd,
5559 syms[r_index].e_strx);
5560 else
5561 {
5562 asection *s;
5563
5564 s = aout_reloc_index_to_section (input_bfd, r_index);
5565 name = bfd_section_name (input_bfd, s);
5566 }
5567 if (! ((*finfo->info->callbacks->reloc_overflow)
5568 (finfo->info, name, howto_table_ext[r_type].name,
5569 r_addend, input_bfd, input_section, r_addr)))
5570 return false;
5571 }
5572 break;
5573 }
5574 }
5575 }
5576 }
5577
5578 return true;
5579}
5580
5581/* Handle a link order which is supposed to generate a reloc. */
5582
5583static boolean
5584aout_link_reloc_link_order (finfo, o, p)
5585 struct aout_final_link_info *finfo;
5586 asection *o;
5587 struct bfd_link_order *p;
5588{
5589 struct bfd_link_order_reloc *pr;
5590 int r_index;
5591 int r_extern;
5592 reloc_howto_type *howto;
7442e600 5593 file_ptr *reloff_ptr = NULL;
252b5132
RH
5594 struct reloc_std_external srel;
5595 struct reloc_ext_external erel;
5596 PTR rel_ptr;
dc810e39 5597 bfd_size_type amt;
252b5132
RH
5598
5599 pr = p->u.reloc.p;
5600
5601 if (p->type == bfd_section_reloc_link_order)
5602 {
5603 r_extern = 0;
5604 if (bfd_is_abs_section (pr->u.section))
5605 r_index = N_ABS | N_EXT;
5606 else
5607 {
5608 BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
5609 r_index = pr->u.section->target_index;
5610 }
5611 }
5612 else
5613 {
5614 struct aout_link_hash_entry *h;
5615
5616 BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
5617 r_extern = 1;
5618 h = ((struct aout_link_hash_entry *)
5619 bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
5620 pr->u.name, false, false, true));
5621 if (h != (struct aout_link_hash_entry *) NULL
5622 && h->indx >= 0)
5623 r_index = h->indx;
5624 else if (h != NULL)
5625 {
5626 /* We decided to strip this symbol, but it turns out that we
5627 can't. Note that we lose the other and desc information
5628 here. I don't think that will ever matter for a global
5629 symbol. */
5630 h->indx = -2;
5631 h->written = false;
5632 if (! aout_link_write_other_symbol (h, (PTR) finfo))
5633 return false;
5634 r_index = h->indx;
5635 }
5636 else
5637 {
5638 if (! ((*finfo->info->callbacks->unattached_reloc)
5639 (finfo->info, pr->u.name, (bfd *) NULL,
5640 (asection *) NULL, (bfd_vma) 0)))
5641 return false;
5642 r_index = 0;
5643 }
5644 }
5645
5646 howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
5647 if (howto == 0)
5648 {
5649 bfd_set_error (bfd_error_bad_value);
5650 return false;
5651 }
5652
5653 if (o == obj_textsec (finfo->output_bfd))
5654 reloff_ptr = &finfo->treloff;
5655 else if (o == obj_datasec (finfo->output_bfd))
5656 reloff_ptr = &finfo->dreloff;
5657 else
5658 abort ();
5659
5660 if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
5661 {
5662#ifdef MY_put_reloc
923f08ff
AM
5663 MY_put_reloc (finfo->output_bfd, r_extern, r_index, p->offset, howto,
5664 &srel);
252b5132
RH
5665#else
5666 {
5667 int r_pcrel;
5668 int r_baserel;
5669 int r_jmptable;
5670 int r_relative;
5671 int r_length;
5672
5673 r_pcrel = howto->pc_relative;
5674 r_baserel = (howto->type & 8) != 0;
5675 r_jmptable = (howto->type & 16) != 0;
5676 r_relative = (howto->type & 32) != 0;
5677 r_length = howto->size;
5678
5679 PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
5680 if (bfd_header_big_endian (finfo->output_bfd))
5681 {
5682 srel.r_index[0] = r_index >> 16;
5683 srel.r_index[1] = r_index >> 8;
5684 srel.r_index[2] = r_index;
5685 srel.r_type[0] =
5686 ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
5687 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
5688 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
5689 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
5690 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
5691 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
5692 }
5693 else
5694 {
5695 srel.r_index[2] = r_index >> 16;
5696 srel.r_index[1] = r_index >> 8;
5697 srel.r_index[0] = r_index;
5698 srel.r_type[0] =
5699 ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
5700 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
5701 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
5702 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
5703 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
5704 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
5705 }
5706 }
5707#endif
5708 rel_ptr = (PTR) &srel;
5709
5710 /* We have to write the addend into the object file, since
5711 standard a.out relocs are in place. It would be more
5712 reliable if we had the current contents of the file here,
5713 rather than assuming zeroes, but we can't read the file since
5714 it was opened using bfd_openw. */
5715 if (pr->addend != 0)
5716 {
5717 bfd_size_type size;
5718 bfd_reloc_status_type r;
5719 bfd_byte *buf;
5720 boolean ok;
5721
5722 size = bfd_get_reloc_size (howto);
5723 buf = (bfd_byte *) bfd_zmalloc (size);
5724 if (buf == (bfd_byte *) NULL)
5725 return false;
5726 r = MY_relocate_contents (howto, finfo->output_bfd,
dc810e39 5727 (bfd_vma) pr->addend, buf);
252b5132
RH
5728 switch (r)
5729 {
5730 case bfd_reloc_ok:
5731 break;
5732 default:
5733 case bfd_reloc_outofrange:
5734 abort ();
5735 case bfd_reloc_overflow:
5736 if (! ((*finfo->info->callbacks->reloc_overflow)
5737 (finfo->info,
5738 (p->type == bfd_section_reloc_link_order
5739 ? bfd_section_name (finfo->output_bfd,
5740 pr->u.section)
5741 : pr->u.name),
5742 howto->name, pr->addend, (bfd *) NULL,
5743 (asection *) NULL, (bfd_vma) 0)))
5744 {
5745 free (buf);
5746 return false;
5747 }
5748 break;
5749 }
dc810e39
AM
5750 ok = bfd_set_section_contents (finfo->output_bfd, o, (PTR) buf,
5751 (file_ptr) p->offset, size);
252b5132
RH
5752 free (buf);
5753 if (! ok)
5754 return false;
5755 }
5756 }
5757 else
5758 {
1642229e
HPN
5759#ifdef MY_put_ext_reloc
5760 MY_put_ext_reloc (finfo->output_bfd, r_extern, r_index, p->offset,
5761 howto, &erel, pr->addend);
5762#else
252b5132
RH
5763 PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
5764
5765 if (bfd_header_big_endian (finfo->output_bfd))
5766 {
5767 erel.r_index[0] = r_index >> 16;
5768 erel.r_index[1] = r_index >> 8;
5769 erel.r_index[2] = r_index;
5770 erel.r_type[0] =
5771 ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
5772 | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
5773 }
5774 else
5775 {
5776 erel.r_index[2] = r_index >> 16;
5777 erel.r_index[1] = r_index >> 8;
5778 erel.r_index[0] = r_index;
5779 erel.r_type[0] =
5780 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
5781 | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
5782 }
5783
dc810e39 5784 PUT_WORD (finfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend);
1642229e 5785#endif /* MY_put_ext_reloc */
252b5132
RH
5786
5787 rel_ptr = (PTR) &erel;
5788 }
5789
dc810e39 5790 amt = obj_reloc_entry_size (finfo->output_bfd);
252b5132 5791 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
dc810e39 5792 || bfd_bwrite (rel_ptr, amt, finfo->output_bfd) != amt)
252b5132
RH
5793 return false;
5794
5795 *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
5796
5797 /* Assert that the relocs have not run into the symbols, and that n
5798 the text relocs have not run into the data relocs. */
5799 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
5800 && (reloff_ptr != &finfo->treloff
5801 || (*reloff_ptr
5802 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
5803
5804 return true;
5805}
This page took 0.439195 seconds and 4 git commands to generate.