source: trunk/src/binutils/bfd/aoutx.h@ 1330

Last change on this file since 1330 was 1257, checked in by bird, 22 years ago

Fixed a few N_IMP1/2 problems. Can now link simple program.

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