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

Last change on this file since 2016 was 2002, checked in by bird, 20 years ago

N_EXP - EMX extension for export declarations.

  • Property cvs2svn:cvs-rev set to 1.8
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 170.8 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: N_IMP[12] */
1675
1676#if defined(N_EXP)
1677 case N_EXP:
1678 case N_EXP | N_EXT:
1679 cache_ptr->symbol.section = bfd_abs_section_ptr;
1680 cache_ptr->symbol.flags = BSF_EMX_EXPORT;
1681 break;
1682#endif /* EMX: N_EXP */
1683 }
1684
1685 return TRUE;
1686}
1687
1688/* Set the fields of SYM_POINTER according to CACHE_PTR. */
1689
1690static bfd_boolean
1691translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
1692 bfd *abfd;
1693 asymbol *cache_ptr;
1694 struct external_nlist *sym_pointer;
1695{
1696 bfd_vma value = cache_ptr->value;
1697 asection *sec;
1698 bfd_vma off;
1699
1700 /* Mask out any existing type bits in case copying from one section
1701 to another. */
1702 sym_pointer->e_type[0] &= ~N_TYPE;
1703
1704 sec = bfd_get_section (cache_ptr);
1705 off = 0;
1706
1707 if (sec == NULL)
1708 {
1709 /* This case occurs, e.g., for the *DEBUG* section of a COFF
1710 file. */
1711 (*_bfd_error_handler)
1712 (_("%s: can not represent section for symbol `%s' in a.out object file format"),
1713 bfd_get_filename (abfd),
1714 cache_ptr->name != NULL ? cache_ptr->name : _("*unknown*"));
1715 bfd_set_error (bfd_error_nonrepresentable_section);
1716 return FALSE;
1717 }
1718
1719 if (sec->output_section != NULL)
1720 {
1721 off = sec->output_offset;
1722 sec = sec->output_section;
1723 }
1724
1725 if (bfd_is_abs_section (sec))
1726 {
1727#if defined (N_IMP1) && defined (N_IMP2)
1728 if (cache_ptr->flags & BSF_EMX_IMPORT1)
1729 sym_pointer->e_type[0] |= N_IMP1;
1730 else if (cache_ptr->flags & BSF_EMX_IMPORT2)
1731 sym_pointer->e_type[0] |= N_IMP2;
1732 else
1733#endif
1734#if defined(N_EXP)
1735 if (cache_ptr->flags & BSF_EMX_EXPORT)
1736 sym_pointer->e_type[0] |= N_EXP;
1737 else
1738#endif /* EMX: N_EXP */
1739 sym_pointer->e_type[0] |= N_ABS;
1740 }
1741 else if (sec == obj_textsec (abfd))
1742 sym_pointer->e_type[0] |= N_TEXT;
1743 else if (sec == obj_datasec (abfd))
1744 sym_pointer->e_type[0] |= N_DATA;
1745 else if (sec == obj_bsssec (abfd))
1746 sym_pointer->e_type[0] |= N_BSS;
1747 else if (bfd_is_und_section (sec))
1748 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1749 else if (bfd_is_ind_section (sec))
1750 sym_pointer->e_type[0] = N_INDR;
1751 else if (bfd_is_com_section (sec))
1752 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1753 else
1754 {
1755 if (aout_section_merge_with_text_p (abfd, sec))
1756 sym_pointer->e_type[0] |= N_TEXT;
1757 else
1758 {
1759 (*_bfd_error_handler)
1760 (_("%s: can not represent section `%s' in a.out object file format"),
1761 bfd_get_filename (abfd), bfd_get_section_name (abfd, sec));
1762 bfd_set_error (bfd_error_nonrepresentable_section);
1763 return FALSE;
1764 }
1765 }
1766
1767 /* Turn the symbol from section relative to absolute again. */
1768 value += sec->vma + off;
1769
1770 if ((cache_ptr->flags & BSF_WARNING) != 0)
1771 sym_pointer->e_type[0] = N_WARNING;
1772
1773 if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
1774 sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
1775 else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
1776 sym_pointer->e_type[0] |= N_EXT;
1777 else if ((cache_ptr->flags & BSF_LOCAL) != 0)
1778 sym_pointer->e_type[0] &= ~N_EXT;
1779
1780 if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0)
1781 {
1782 int type = ((aout_symbol_type *) cache_ptr)->type;
1783
1784 switch (type)
1785 {
1786 case N_ABS: type = N_SETA; break;
1787 case N_TEXT: type = N_SETT; break;
1788 case N_DATA: type = N_SETD; break;
1789 case N_BSS: type = N_SETB; break;
1790 }
1791 sym_pointer->e_type[0] = type;
1792 }
1793
1794 if ((cache_ptr->flags & BSF_WEAK) != 0)
1795 {
1796 int type;
1797
1798 switch (sym_pointer->e_type[0] & N_TYPE)
1799 {
1800 default:
1801 case N_ABS: type = N_WEAKA; break;
1802 case N_TEXT: type = N_WEAKT; break;
1803 case N_DATA: type = N_WEAKD; break;
1804 case N_BSS: type = N_WEAKB; break;
1805 case N_UNDF: type = N_WEAKU; break;
1806 }
1807 sym_pointer->e_type[0] = type;
1808 }
1809
1810 PUT_WORD (abfd, value, sym_pointer->e_value);
1811
1812 return TRUE;
1813}
1814
1815
1816/* Native-level interface to symbols. */
1817
1818asymbol *
1819NAME(aout,make_empty_symbol) (abfd)
1820 bfd *abfd;
1821{
1822 bfd_size_type amt = sizeof (aout_symbol_type);
1823 aout_symbol_type *new = (aout_symbol_type *) bfd_zalloc (abfd, amt);
1824 if (!new)
1825 return NULL;
1826 new->symbol.the_bfd = abfd;
1827
1828 return &new->symbol;
1829}
1830
1831/* Translate a set of internal symbols into external symbols. */
1832
1833bfd_boolean
1834NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic)
1835 bfd *abfd;
1836 aout_symbol_type *in;
1837 struct external_nlist *ext;
1838 bfd_size_type count;
1839 char *str;
1840 bfd_size_type strsize;
1841 bfd_boolean dynamic;
1842{
1843 struct external_nlist *ext_end;
1844
1845 ext_end = ext + count;
1846 for (; ext < ext_end; ext++, in++)
1847 {
1848 bfd_vma x;
1849
1850 x = GET_WORD (abfd, ext->e_strx);
1851 in->symbol.the_bfd = abfd;
1852
1853 /* For the normal symbols, the zero index points at the number
1854 of bytes in the string table but is to be interpreted as the
1855 null string. For the dynamic symbols, the number of bytes in
1856 the string table is stored in the __DYNAMIC structure and the
1857 zero index points at an actual string. */
1858 if (x == 0 && ! dynamic)
1859 in->symbol.name = "";
1860 else if (x < strsize)
1861 in->symbol.name = str + x;
1862 else
1863 return FALSE;
1864
1865 in->symbol.value = GET_SWORD (abfd, ext->e_value);
1866 in->desc = H_GET_16 (abfd, ext->e_desc);
1867 in->other = H_GET_8 (abfd, ext->e_other);
1868 in->type = H_GET_8 (abfd, ext->e_type);
1869 in->symbol.udata.p = NULL;
1870
1871 if (! translate_from_native_sym_flags (abfd, in))
1872 return FALSE;
1873
1874 if (dynamic)
1875 in->symbol.flags |= BSF_DYNAMIC;
1876 }
1877
1878 return TRUE;
1879}
1880
1881/* We read the symbols into a buffer, which is discarded when this
1882 function exits. We read the strings into a buffer large enough to
1883 hold them all plus all the cached symbol entries. */
1884
1885bfd_boolean
1886NAME(aout,slurp_symbol_table) (abfd)
1887 bfd *abfd;
1888{
1889 struct external_nlist *old_external_syms;
1890 aout_symbol_type *cached;
1891 bfd_size_type cached_size;
1892
1893 /* If there's no work to be done, don't do any. */
1894 if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
1895 return TRUE;
1896
1897 old_external_syms = obj_aout_external_syms (abfd);
1898
1899 if (! aout_get_external_symbols (abfd))
1900 return FALSE;
1901
1902 cached_size = obj_aout_external_sym_count (abfd);
1903 cached_size *= sizeof (aout_symbol_type);
1904 cached = (aout_symbol_type *) bfd_zmalloc (cached_size);
1905 if (cached == NULL && cached_size != 0)
1906 return FALSE;
1907
1908 /* Convert from external symbol information to internal. */
1909 if (! (NAME(aout,translate_symbol_table)
1910 (abfd, cached,
1911 obj_aout_external_syms (abfd),
1912 obj_aout_external_sym_count (abfd),
1913 obj_aout_external_strings (abfd),
1914 obj_aout_external_string_size (abfd),
1915 FALSE)))
1916 {
1917 free (cached);
1918 return FALSE;
1919 }
1920
1921 bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
1922
1923 obj_aout_symbols (abfd) = cached;
1924
1925 /* It is very likely that anybody who calls this function will not
1926 want the external symbol information, so if it was allocated
1927 because of our call to aout_get_external_symbols, we free it up
1928 right away to save space. */
1929 if (old_external_syms == (struct external_nlist *) NULL
1930 && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
1931 {
1932#ifdef USE_MMAP
1933 bfd_free_window (&obj_aout_sym_window (abfd));
1934#else
1935 free (obj_aout_external_syms (abfd));
1936#endif
1937 obj_aout_external_syms (abfd) = NULL;
1938 }
1939
1940 return TRUE;
1941}
1942
1943
1944/* We use a hash table when writing out symbols so that we only write
1945 out a particular string once. This helps particularly when the
1946 linker writes out stabs debugging entries, because each different
1947 contributing object file tends to have many duplicate stabs
1948 strings.
1949
1950 This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
1951 if BFD_TRADITIONAL_FORMAT is set. */
1952
1953static bfd_size_type add_to_stringtab
1954 PARAMS ((bfd *, struct bfd_strtab_hash *, const char *, bfd_boolean));
1955static bfd_boolean emit_stringtab
1956 PARAMS ((bfd *, struct bfd_strtab_hash *));
1957
1958/* Get the index of a string in a strtab, adding it if it is not
1959 already present. */
1960
1961static INLINE bfd_size_type
1962add_to_stringtab (abfd, tab, str, copy)
1963 bfd *abfd;
1964 struct bfd_strtab_hash *tab;
1965 const char *str;
1966 bfd_boolean copy;
1967{
1968 bfd_boolean hash;
1969 bfd_size_type index;
1970
1971 /* An index of 0 always means the empty string. */
1972 if (str == 0 || *str == '\0')
1973 return 0;
1974
1975 /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
1976 doesn't understand a hashed string table. */
1977 hash = TRUE;
1978 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
1979 hash = FALSE;
1980
1981 index = _bfd_stringtab_add (tab, str, hash, copy);
1982
1983 if (index != (bfd_size_type) -1)
1984 {
1985 /* Add BYTES_IN_WORD to the return value to account for the
1986 space taken up by the string table size. */
1987 index += BYTES_IN_WORD;
1988 }
1989
1990 return index;
1991}
1992
1993/* Write out a strtab. ABFD is already at the right location in the
1994 file. */
1995
1996static bfd_boolean
1997emit_stringtab (abfd, tab)
1998 register bfd *abfd;
1999 struct bfd_strtab_hash *tab;
2000{
2001 bfd_byte buffer[BYTES_IN_WORD];
2002 bfd_size_type amt = BYTES_IN_WORD;
2003
2004 /* The string table starts with the size. */
2005 PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
2006 if (bfd_bwrite ((PTR) buffer, amt, abfd) != amt)
2007 return FALSE;
2008
2009 return _bfd_stringtab_emit (abfd, tab);
2010}
2011
2012
2013bfd_boolean
2014NAME(aout,write_syms) (abfd)
2015 bfd *abfd;
2016{
2017 unsigned int count ;
2018 asymbol **generic = bfd_get_outsymbols (abfd);
2019 struct bfd_strtab_hash *strtab;
2020
2021 strtab = _bfd_stringtab_init ();
2022 if (strtab == NULL)
2023 return FALSE;
2024
2025 for (count = 0; count < bfd_get_symcount (abfd); count++)
2026 {
2027 asymbol *g = generic[count];
2028 bfd_size_type indx;
2029 struct external_nlist nsp;
2030 bfd_size_type amt;
2031
2032 indx = add_to_stringtab (abfd, strtab, g->name, FALSE);
2033 if (indx == (bfd_size_type) -1)
2034 goto error_return;
2035 PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
2036
2037 if (bfd_asymbol_flavour (g) == abfd->xvec->flavour)
2038 {
2039 H_PUT_16 (abfd, aout_symbol (g)->desc, nsp.e_desc);
2040 H_PUT_8 (abfd, aout_symbol (g)->other, nsp.e_other);
2041 H_PUT_8 (abfd, aout_symbol (g)->type, nsp.e_type);
2042 }
2043 else
2044 {
2045 H_PUT_16 (abfd, 0, nsp.e_desc);
2046 H_PUT_8 (abfd, 0, nsp.e_other);
2047 H_PUT_8 (abfd, 0, nsp.e_type);
2048 }
2049
2050 if (! translate_to_native_sym_flags (abfd, g, &nsp))
2051 goto error_return;
2052
2053 amt = EXTERNAL_NLIST_SIZE;
2054 if (bfd_bwrite ((PTR) &nsp, amt, abfd) != amt)
2055 goto error_return;
2056
2057 /* NB: `KEEPIT' currently overlays `udata.p', so set this only
2058 here, at the end. */
2059 g->KEEPIT = count;
2060 }
2061
2062 if (! emit_stringtab (abfd, strtab))
2063 goto error_return;
2064
2065 _bfd_stringtab_free (strtab);
2066
2067 return TRUE;
2068
2069error_return:
2070 _bfd_stringtab_free (strtab);
2071 return FALSE;
2072}
2073
2074
2075long
2076NAME(aout,get_symtab) (abfd, location)
2077 bfd *abfd;
2078 asymbol **location;
2079{
2080 unsigned int counter = 0;
2081 aout_symbol_type *symbase;
2082
2083 if (!NAME(aout,slurp_symbol_table) (abfd))
2084 return -1;
2085
2086 for (symbase = obj_aout_symbols (abfd);
2087 counter++ < bfd_get_symcount (abfd);
2088 )
2089 *(location++) = (asymbol *) (symbase++);
2090 *location++ =0;
2091 return bfd_get_symcount (abfd);
2092}
2093
2094
2095/* Standard reloc stuff. */
2096/* Output standard relocation information to a file in target byte order. */
2097
2098extern void NAME(aout,swap_std_reloc_out)
2099 PARAMS ((bfd *, arelent *, struct reloc_std_external *));
2100
2101void
2102NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
2103 bfd *abfd;
2104 arelent *g;
2105 struct reloc_std_external *natptr;
2106{
2107 int r_index;
2108 asymbol *sym = *(g->sym_ptr_ptr);
2109 int r_extern;
2110 unsigned int r_length;
2111 int r_pcrel;
2112 int r_baserel, r_jmptable, r_relative;
2113 asection *output_section = sym->section->output_section;
2114
2115 /* bird - start */
2116 /* Output reloctions to weak symbols as if they were undefined externals.
2117 The aoutx.h code relocates them as if they were nothing special and I can't
2118 see the linker doing the right thing either when it processes it. */
2119 int is_weak = g->sym_ptr_ptr
2120 && *g->sym_ptr_ptr
2121 && ((*g->sym_ptr_ptr)->flags & BSF_WEAK);
2122 /* bird - end */
2123
2124 PUT_WORD (abfd, g->address, natptr->r_address);
2125
2126 r_length = g->howto->size ; /* Size as a power of two. */
2127 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
2128 /* XXX This relies on relocs coming from a.out files. */
2129 r_baserel = (g->howto->type & 8) != 0;
2130 r_jmptable = (g->howto->type & 16) != 0;
2131 r_relative = (g->howto->type & 32) != 0;
2132
2133#if 0
2134 /* For a standard reloc, the addend is in the object file. */
2135 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
2136#endif
2137
2138 /* Name was clobbered by aout_write_syms to be symbol index. */
2139
2140 /* If this relocation is relative to a symbol then set the
2141 r_index to the symbols index, and the r_extern bit.
2142
2143 Absolute symbols can come in in two ways, either as an offset
2144 from the abs section, or as a symbol which has an abs value.
2145 check for that here. */
2146
2147 if (bfd_is_com_section (output_section)
2148 || bfd_is_abs_section (output_section)
2149 || bfd_is_und_section (output_section)
2150 || is_weak) /* bird */
2151 {
2152 if (bfd_abs_section_ptr->symbol == sym)
2153 {
2154 /* Whoops, looked like an abs symbol, but is
2155 really an offset from the abs section. */
2156 r_index = N_ABS;
2157 r_extern = 0;
2158 }
2159 else
2160 {
2161 /* Fill in symbol. */
2162 r_extern = 1;
2163 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2164 }
2165 }
2166 else
2167 {
2168 /* Just an ordinary section. */
2169 r_extern = 0;
2170 r_index = output_section->target_index;
2171 }
2172
2173 /* Now the fun stuff. */
2174 if (bfd_header_big_endian (abfd))
2175 {
2176 natptr->r_index[0] = r_index >> 16;
2177 natptr->r_index[1] = r_index >> 8;
2178 natptr->r_index[2] = r_index;
2179 natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
2180 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
2181 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
2182 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
2183 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
2184 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
2185 }
2186 else
2187 {
2188 natptr->r_index[2] = r_index >> 16;
2189 natptr->r_index[1] = r_index >> 8;
2190 natptr->r_index[0] = r_index;
2191 natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
2192 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
2193 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
2194 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
2195 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
2196 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
2197 }
2198}
2199
2200/* Extended stuff. */
2201/* Output extended relocation information to a file in target byte order. */
2202
2203extern void NAME(aout,swap_ext_reloc_out)
2204 PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
2205
2206void
2207NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
2208 bfd *abfd;
2209 arelent *g;
2210 register struct reloc_ext_external *natptr;
2211{
2212 int r_index;
2213 int r_extern;
2214 unsigned int r_type;
2215 bfd_vma r_addend;
2216 asymbol *sym = *(g->sym_ptr_ptr);
2217 asection *output_section = sym->section->output_section;
2218
2219 PUT_WORD (abfd, g->address, natptr->r_address);
2220
2221 r_type = (unsigned int) g->howto->type;
2222
2223 r_addend = g->addend;
2224 if ((sym->flags & BSF_SECTION_SYM) != 0)
2225 r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma;
2226
2227 /* If this relocation is relative to a symbol then set the
2228 r_index to the symbols index, and the r_extern bit.
2229
2230 Absolute symbols can come in in two ways, either as an offset
2231 from the abs section, or as a symbol which has an abs value.
2232 check for that here. */
2233 if (bfd_is_abs_section (bfd_get_section (sym)))
2234 {
2235 r_extern = 0;
2236 r_index = N_ABS;
2237 }
2238 else if ((sym->flags & BSF_SECTION_SYM) == 0)
2239 {
2240 if (bfd_is_und_section (bfd_get_section (sym))
2241 || (sym->flags & BSF_GLOBAL) != 0)
2242 r_extern = 1;
2243 else
2244 r_extern = 0;
2245 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2246 }
2247 else
2248 {
2249 /* Just an ordinary section. */
2250 r_extern = 0;
2251 r_index = output_section->target_index;
2252 }
2253
2254 /* Now the fun stuff. */
2255 if (bfd_header_big_endian (abfd))
2256 {
2257 natptr->r_index[0] = r_index >> 16;
2258 natptr->r_index[1] = r_index >> 8;
2259 natptr->r_index[2] = r_index;
2260 natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
2261 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
2262 }
2263 else
2264 {
2265 natptr->r_index[2] = r_index >> 16;
2266 natptr->r_index[1] = r_index >> 8;
2267 natptr->r_index[0] = r_index;
2268 natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
2269 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE));
2270 }
2271
2272 PUT_WORD (abfd, r_addend, natptr->r_addend);
2273}
2274
2275/* BFD deals internally with all things based from the section they're
2276 in. so, something in 10 bytes into a text section with a base of
2277 50 would have a symbol (.text+10) and know .text vma was 50.
2278
2279 Aout keeps all it's symbols based from zero, so the symbol would
2280 contain 60. This macro subs the base of each section from the value
2281 to give the true offset from the section. */
2282
2283#define MOVE_ADDRESS(ad) \
2284 if (r_extern) \
2285 { \
2286 /* Undefined symbol. */ \
2287 cache_ptr->sym_ptr_ptr = symbols + r_index; \
2288 cache_ptr->addend = ad; \
2289 } \
2290 else \
2291 { \
2292 /* Defined, section relative. Replace symbol with pointer to \
2293 symbol which points to section. */ \
2294 switch (r_index) \
2295 { \
2296 case N_TEXT: \
2297 case N_TEXT | N_EXT: \
2298 cache_ptr->sym_ptr_ptr = obj_textsec (abfd)->symbol_ptr_ptr; \
2299 cache_ptr->addend = ad - su->textsec->vma; \
2300 break; \
2301 case N_DATA: \
2302 case N_DATA | N_EXT: \
2303 cache_ptr->sym_ptr_ptr = obj_datasec (abfd)->symbol_ptr_ptr; \
2304 cache_ptr->addend = ad - su->datasec->vma; \
2305 break; \
2306 case N_BSS: \
2307 case N_BSS | N_EXT: \
2308 cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr; \
2309 cache_ptr->addend = ad - su->bsssec->vma; \
2310 break; \
2311 default: \
2312 case N_ABS: \
2313 case N_ABS | N_EXT: \
2314 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
2315 cache_ptr->addend = ad; \
2316 break; \
2317 } \
2318 }
2319
2320void
2321NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2322 bfd *abfd;
2323 struct reloc_ext_external *bytes;
2324 arelent *cache_ptr;
2325 asymbol **symbols;
2326 bfd_size_type symcount;
2327{
2328 unsigned int r_index;
2329 int r_extern;
2330 unsigned int r_type;
2331 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2332
2333 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2334
2335 /* Now the fun stuff. */
2336 if (bfd_header_big_endian (abfd))
2337 {
2338 r_index = (((unsigned int) bytes->r_index[0] << 16)
2339 | ((unsigned int) bytes->r_index[1] << 8)
2340 | bytes->r_index[2]);
2341 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2342 r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2343 >> RELOC_EXT_BITS_TYPE_SH_BIG);
2344 }
2345 else
2346 {
2347 r_index = (((unsigned int) bytes->r_index[2] << 16)
2348 | ((unsigned int) bytes->r_index[1] << 8)
2349 | bytes->r_index[0]);
2350 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2351 r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2352 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
2353 }
2354
2355 cache_ptr->howto = howto_table_ext + r_type;
2356
2357 /* Base relative relocs are always against the symbol table,
2358 regardless of the setting of r_extern. r_extern just reflects
2359 whether the symbol the reloc is against is local or global. */
2360 if (r_type == (unsigned int) RELOC_BASE10
2361 || r_type == (unsigned int) RELOC_BASE13
2362 || r_type == (unsigned int) RELOC_BASE22)
2363 r_extern = 1;
2364
2365 if (r_extern && r_index > symcount)
2366 {
2367 /* We could arrange to return an error, but it might be useful
2368 to see the file even if it is bad. */
2369 r_extern = 0;
2370 r_index = N_ABS;
2371 }
2372
2373 MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
2374}
2375
2376void
2377NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2378 bfd *abfd;
2379 struct reloc_std_external *bytes;
2380 arelent *cache_ptr;
2381 asymbol **symbols;
2382 bfd_size_type symcount;
2383{
2384 unsigned int r_index;
2385 int r_extern;
2386 unsigned int r_length;
2387 int r_pcrel;
2388 int r_baserel, r_jmptable, r_relative;
2389 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2390 unsigned int howto_idx;
2391
2392 cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
2393
2394 /* Now the fun stuff. */
2395 if (bfd_header_big_endian (abfd))
2396 {
2397 r_index = (((unsigned int) bytes->r_index[0] << 16)
2398 | ((unsigned int) bytes->r_index[1] << 8)
2399 | bytes->r_index[2]);
2400 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2401 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2402 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2403 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2404 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2405 r_length = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2406 >> RELOC_STD_BITS_LENGTH_SH_BIG);
2407 }
2408 else
2409 {
2410 r_index = (((unsigned int) bytes->r_index[2] << 16)
2411 | ((unsigned int) bytes->r_index[1] << 8)
2412 | bytes->r_index[0]);
2413 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2414 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2415 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2416 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2417 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2418 r_length = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2419 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
2420 }
2421
2422 howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
2423 + 16 * r_jmptable + 32 * r_relative);
2424 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
2425 cache_ptr->howto = howto_table_std + howto_idx;
2426 BFD_ASSERT (cache_ptr->howto->type != (unsigned int) -1);
2427
2428 /* Base relative relocs are always against the symbol table,
2429 regardless of the setting of r_extern. r_extern just reflects
2430 whether the symbol the reloc is against is local or global. */
2431 if (r_baserel)
2432 r_extern = 1;
2433
2434 if (r_extern && r_index > symcount)
2435 {
2436 /* We could arrange to return an error, but it might be useful
2437 to see the file even if it is bad. */
2438 r_extern = 0;
2439 r_index = N_ABS;
2440 }
2441
2442 MOVE_ADDRESS (0);
2443}
2444
2445/* Read and swap the relocs for a section. */
2446
2447bfd_boolean
2448NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
2449 bfd *abfd;
2450 sec_ptr asect;
2451 asymbol **symbols;
2452{
2453 bfd_size_type count;
2454 bfd_size_type reloc_size;
2455 PTR relocs;
2456 arelent *reloc_cache;
2457 size_t each_size;
2458 unsigned int counter = 0;
2459 arelent *cache_ptr;
2460 bfd_size_type amt;
2461
2462 if (asect->relocation)
2463 return TRUE;
2464
2465 if (asect->flags & SEC_CONSTRUCTOR)
2466 return TRUE;
2467
2468 if (asect == obj_datasec (abfd))
2469 reloc_size = exec_hdr (abfd)->a_drsize;
2470 else if (asect == obj_textsec (abfd))
2471 reloc_size = exec_hdr (abfd)->a_trsize;
2472 else if (asect == obj_bsssec (abfd))
2473 reloc_size = 0;
2474 else
2475 {
2476 bfd_set_error (bfd_error_invalid_operation);
2477 return FALSE;
2478 }
2479
2480 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
2481 return FALSE;
2482
2483 each_size = obj_reloc_entry_size (abfd);
2484
2485 count = reloc_size / each_size;
2486
2487 amt = count * sizeof (arelent);
2488 reloc_cache = (arelent *) bfd_zmalloc (amt);
2489 if (reloc_cache == NULL && count != 0)
2490 return FALSE;
2491
2492 relocs = bfd_malloc (reloc_size);
2493 if (relocs == NULL && reloc_size != 0)
2494 {
2495 free (reloc_cache);
2496 return FALSE;
2497 }
2498
2499 if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
2500 {
2501 free (relocs);
2502 free (reloc_cache);
2503 return FALSE;
2504 }
2505
2506 cache_ptr = reloc_cache;
2507 if (each_size == RELOC_EXT_SIZE)
2508 {
2509 struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
2510
2511 for (; counter < count; counter++, rptr++, cache_ptr++)
2512 MY_swap_ext_reloc_in (abfd, rptr, cache_ptr, symbols,
2513 (bfd_size_type) bfd_get_symcount (abfd));
2514 }
2515 else
2516 {
2517 struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
2518
2519 for (; counter < count; counter++, rptr++, cache_ptr++)
2520 MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
2521 (bfd_size_type) bfd_get_symcount (abfd));
2522 }
2523
2524 free (relocs);
2525
2526 asect->relocation = reloc_cache;
2527 asect->reloc_count = cache_ptr - reloc_cache;
2528
2529 return TRUE;
2530}
2531
2532/* Write out a relocation section into an object file. */
2533
2534bfd_boolean
2535NAME(aout,squirt_out_relocs) (abfd, section)
2536 bfd *abfd;
2537 asection *section;
2538{
2539 arelent **generic;
2540 unsigned char *native, *natptr;
2541 size_t each_size;
2542
2543 unsigned int count = section->reloc_count;
2544 bfd_size_type natsize;
2545
2546 if (count == 0 || section->orelocation == NULL)
2547 return TRUE;
2548
2549 each_size = obj_reloc_entry_size (abfd);
2550 natsize = (bfd_size_type) each_size * count;
2551 native = (unsigned char *) bfd_zalloc (abfd, natsize);
2552 if (!native)
2553 return FALSE;
2554
2555 generic = section->orelocation;
2556
2557 if (each_size == RELOC_EXT_SIZE)
2558 {
2559 for (natptr = native;
2560 count != 0;
2561 --count, natptr += each_size, ++generic)
2562 MY_swap_ext_reloc_out (abfd, *generic,
2563 (struct reloc_ext_external *) natptr);
2564 }
2565 else
2566 {
2567 for (natptr = native;
2568 count != 0;
2569 --count, natptr += each_size, ++generic)
2570 MY_swap_std_reloc_out (abfd, *generic,
2571 (struct reloc_std_external *) natptr);
2572 }
2573
2574 if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
2575 {
2576 bfd_release (abfd, native);
2577 return FALSE;
2578 }
2579 bfd_release (abfd, native);
2580
2581 return TRUE;
2582}
2583
2584/* This is stupid. This function should be a boolean predicate. */
2585
2586long
2587NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols)
2588 bfd *abfd;
2589 sec_ptr section;
2590 arelent **relptr;
2591 asymbol **symbols;
2592{
2593 arelent *tblptr = section->relocation;
2594 unsigned int count;
2595
2596 if (section == obj_bsssec (abfd))
2597 {
2598 *relptr = NULL;
2599 return 0;
2600 }
2601
2602 if (!(tblptr || NAME(aout,slurp_reloc_table) (abfd, section, symbols)))
2603 return -1;
2604
2605 if (section->flags & SEC_CONSTRUCTOR)
2606 {
2607 arelent_chain *chain = section->constructor_chain;
2608 for (count = 0; count < section->reloc_count; count ++)
2609 {
2610 *relptr ++ = &chain->relent;
2611 chain = chain->next;
2612 }
2613 }
2614 else
2615 {
2616 tblptr = section->relocation;
2617
2618 for (count = 0; count++ < section->reloc_count; )
2619 {
2620 *relptr++ = tblptr++;
2621 }
2622 }
2623 *relptr = 0;
2624
2625 return section->reloc_count;
2626}
2627
2628long
2629NAME(aout,get_reloc_upper_bound) (abfd, asect)
2630 bfd *abfd;
2631 sec_ptr asect;
2632{
2633 if (bfd_get_format (abfd) != bfd_object)
2634 {
2635 bfd_set_error (bfd_error_invalid_operation);
2636 return -1;
2637 }
2638
2639 if (asect->flags & SEC_CONSTRUCTOR)
2640 return (sizeof (arelent *) * (asect->reloc_count+1));
2641
2642 if (asect == obj_datasec (abfd))
2643 return (sizeof (arelent *)
2644 * ((exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd))
2645 + 1));
2646
2647 if (asect == obj_textsec (abfd))
2648 return (sizeof (arelent *)
2649 * ((exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd))
2650 + 1));
2651
2652 if (asect == obj_bsssec (abfd))
2653 return sizeof (arelent *);
2654
2655 if (asect == obj_bsssec (abfd))
2656 return 0;
2657
2658 bfd_set_error (bfd_error_invalid_operation);
2659 return -1;
2660}
2661
2662
2663long
2664NAME(aout,get_symtab_upper_bound) (abfd)
2665 bfd *abfd;
2666{
2667 if (!NAME(aout,slurp_symbol_table) (abfd))
2668 return -1;
2669
2670 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2671}
2672
2673alent *
2674NAME(aout,get_lineno) (ignore_abfd, ignore_symbol)
2675 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2676 asymbol *ignore_symbol ATTRIBUTE_UNUSED;
2677{
2678 return (alent *)NULL;
2679}
2680
2681void
2682NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
2683 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2684 asymbol *symbol;
2685 symbol_info *ret;
2686{
2687 bfd_symbol_info (symbol, ret);
2688
2689 if (ret->type == '?')
2690 {
2691 int type_code = aout_symbol (symbol)->type & 0xff;
2692 const char *stab_name = bfd_get_stab_name (type_code);
2693 static char buf[10];
2694
2695 if (stab_name == NULL)
2696 {
2697 sprintf (buf, "(%d)", type_code);
2698 stab_name = buf;
2699 }
2700 ret->type = '-';
2701 ret->stab_type = type_code;
2702 ret->stab_other = (unsigned) (aout_symbol (symbol)->other & 0xff);
2703 ret->stab_desc = (unsigned) (aout_symbol (symbol)->desc & 0xffff);
2704 ret->stab_name = stab_name;
2705 }
2706}
2707
2708void
2709NAME(aout,print_symbol) (abfd, afile, symbol, how)
2710 bfd *abfd;
2711 PTR afile;
2712 asymbol *symbol;
2713 bfd_print_symbol_type how;
2714{
2715 FILE *file = (FILE *)afile;
2716
2717 switch (how)
2718 {
2719 case bfd_print_symbol_name:
2720 if (symbol->name)
2721 fprintf (file,"%s", symbol->name);
2722 break;
2723 case bfd_print_symbol_more:
2724 fprintf (file,"%4x %2x %2x",
2725 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2726 (unsigned) (aout_symbol (symbol)->other & 0xff),
2727 (unsigned) (aout_symbol (symbol)->type));
2728 break;
2729 case bfd_print_symbol_all:
2730 {
2731 const char *section_name = symbol->section->name;
2732
2733 bfd_print_symbol_vandf (abfd, (PTR)file, symbol);
2734
2735 fprintf (file," %-5s %04x %02x %02x",
2736 section_name,
2737 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2738 (unsigned) (aout_symbol (symbol)->other & 0xff),
2739 (unsigned) (aout_symbol (symbol)->type & 0xff));
2740 if (symbol->name)
2741 fprintf (file," %s", symbol->name);
2742 }
2743 break;
2744 }
2745}
2746
2747/* If we don't have to allocate more than 1MB to hold the generic
2748 symbols, we use the generic minisymbol methord: it's faster, since
2749 it only translates the symbols once, not multiple times. */
2750#define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
2751
2752/* Read minisymbols. For minisymbols, we use the unmodified a.out
2753 symbols. The minisymbol_to_symbol function translates these into
2754 BFD asymbol structures. */
2755
2756long
2757NAME(aout,read_minisymbols) (abfd, dynamic, minisymsp, sizep)
2758 bfd *abfd;
2759 bfd_boolean dynamic;
2760 PTR *minisymsp;
2761 unsigned int *sizep;
2762{
2763 if (dynamic)
2764 {
2765 /* We could handle the dynamic symbols here as well, but it's
2766 easier to hand them off. */
2767 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2768 }
2769
2770 if (! aout_get_external_symbols (abfd))
2771 return -1;
2772
2773 if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2774 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2775
2776 *minisymsp = (PTR) obj_aout_external_syms (abfd);
2777
2778 /* By passing the external symbols back from this routine, we are
2779 giving up control over the memory block. Clear
2780 obj_aout_external_syms, so that we do not try to free it
2781 ourselves. */
2782 obj_aout_external_syms (abfd) = NULL;
2783
2784 *sizep = EXTERNAL_NLIST_SIZE;
2785 return obj_aout_external_sym_count (abfd);
2786}
2787
2788/* Convert a minisymbol to a BFD asymbol. A minisymbol is just an
2789 unmodified a.out symbol. The SYM argument is a structure returned
2790 by bfd_make_empty_symbol, which we fill in here. */
2791
2792asymbol *
2793NAME(aout,minisymbol_to_symbol) (abfd, dynamic, minisym, sym)
2794 bfd *abfd;
2795 bfd_boolean dynamic;
2796 const PTR minisym;
2797 asymbol *sym;
2798{
2799 if (dynamic
2800 || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2801 return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
2802
2803 memset (sym, 0, sizeof (aout_symbol_type));
2804
2805 /* We call translate_symbol_table to translate a single symbol. */
2806 if (! (NAME(aout,translate_symbol_table)
2807 (abfd,
2808 (aout_symbol_type *) sym,
2809 (struct external_nlist *) minisym,
2810 (bfd_size_type) 1,
2811 obj_aout_external_strings (abfd),
2812 obj_aout_external_string_size (abfd),
2813 FALSE)))
2814 return NULL;
2815
2816 return sym;
2817}
2818
2819/* Provided a BFD, a section and an offset into the section, calculate
2820 and return the name of the source file and the line nearest to the
2821 wanted location. */
2822
2823bfd_boolean
2824NAME(aout,find_nearest_line)
2825 (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
2826 bfd *abfd;
2827 asection *section;
2828 asymbol **symbols;
2829 bfd_vma offset;
2830 const char **filename_ptr;
2831 const char **functionname_ptr;
2832 unsigned int *line_ptr;
2833{
2834 /* Run down the file looking for the filename, function and linenumber. */
2835 asymbol **p;
2836 const char *directory_name = NULL;
2837 const char *main_file_name = NULL;
2838 const char *current_file_name = NULL;
2839 const char *line_file_name = NULL; /* Value of current_file_name at line number. */
2840 const char *line_directory_name = NULL; /* Value of directory_name at line number. */
2841 bfd_vma low_line_vma = 0;
2842 bfd_vma low_func_vma = 0;
2843 asymbol *func = 0;
2844 bfd_size_type filelen, funclen;
2845 char *buf;
2846
2847 *filename_ptr = abfd->filename;
2848 *functionname_ptr = 0;
2849 *line_ptr = 0;
2850
2851 if (symbols != (asymbol **)NULL)
2852 {
2853 for (p = symbols; *p; p++)
2854 {
2855 aout_symbol_type *q = (aout_symbol_type *) (*p);
2856 next:
2857 switch (q->type)
2858 {
2859 case N_TEXT:
2860 /* If this looks like a file name symbol, and it comes after
2861 the line number we have found so far, but before the
2862 offset, then we have probably not found the right line
2863 number. */
2864 if (q->symbol.value <= offset
2865 && ((q->symbol.value > low_line_vma
2866 && (line_file_name != NULL
2867 || *line_ptr != 0))
2868 || (q->symbol.value > low_func_vma
2869 && func != NULL)))
2870 {
2871 const char *symname;
2872
2873 symname = q->symbol.name;
2874 if (strcmp (symname + strlen (symname) - 2, ".o") == 0)
2875 {
2876 if (q->symbol.value > low_line_vma)
2877 {
2878 *line_ptr = 0;
2879 line_file_name = NULL;
2880 }
2881 if (q->symbol.value > low_func_vma)
2882 func = NULL;
2883 }
2884 }
2885 break;
2886
2887 case N_SO:
2888 /* If this symbol is less than the offset, but greater than
2889 the line number we have found so far, then we have not
2890 found the right line number. */
2891 if (q->symbol.value <= offset)
2892 {
2893 if (q->symbol.value > low_line_vma)
2894 {
2895 *line_ptr = 0;
2896 line_file_name = NULL;
2897 }
2898 if (q->symbol.value > low_func_vma)
2899 func = NULL;
2900 }
2901
2902 main_file_name = current_file_name = q->symbol.name;
2903 /* Look ahead to next symbol to check if that too is an N_SO. */
2904 p++;
2905 if (*p == NULL)
2906 break;
2907 q = (aout_symbol_type *) (*p);
2908 if (q->type != (int)N_SO)
2909 goto next;
2910
2911 /* Found a second N_SO First is directory; second is filename. */
2912 directory_name = current_file_name;
2913 main_file_name = current_file_name = q->symbol.name;
2914 if (obj_textsec (abfd) != section)
2915 goto done;
2916 break;
2917 case N_SOL:
2918 current_file_name = q->symbol.name;
2919 break;
2920
2921 case N_SLINE:
2922
2923 case N_DSLINE:
2924 case N_BSLINE:
2925 /* We'll keep this if it resolves nearer than the one we have
2926 already. */
2927 if (q->symbol.value >= low_line_vma
2928 && q->symbol.value <= offset)
2929 {
2930 *line_ptr = q->desc;
2931 low_line_vma = q->symbol.value;
2932 line_file_name = current_file_name;
2933 line_directory_name = directory_name;
2934 }
2935 break;
2936 case N_FUN:
2937 {
2938 /* We'll keep this if it is nearer than the one we have already. */
2939 if (q->symbol.value >= low_func_vma &&
2940 q->symbol.value <= offset)
2941 {
2942 low_func_vma = q->symbol.value;
2943 func = (asymbol *)q;
2944 }
2945 else if (q->symbol.value > offset)
2946 goto done;
2947 }
2948 break;
2949 }
2950 }
2951 }
2952
2953 done:
2954 if (*line_ptr != 0)
2955 {
2956 main_file_name = line_file_name;
2957 directory_name = line_directory_name;
2958 }
2959
2960 if (main_file_name == NULL
2961 || IS_ABSOLUTE_PATH (main_file_name)
2962 || directory_name == NULL)
2963 filelen = 0;
2964 else
2965 filelen = strlen (directory_name) + strlen (main_file_name);
2966
2967 if (func == NULL)
2968 funclen = 0;
2969 else
2970 funclen = strlen (bfd_asymbol_name (func));
2971
2972 if (adata (abfd).line_buf != NULL)
2973 free (adata (abfd).line_buf);
2974
2975 if (filelen + funclen == 0)
2976 adata (abfd).line_buf = buf = NULL;
2977 else
2978 {
2979 buf = (char *) bfd_malloc (filelen + funclen + 3);
2980 adata (abfd).line_buf = buf;
2981 if (buf == NULL)
2982 return FALSE;
2983 }
2984
2985 if (main_file_name != NULL)
2986 {
2987 if (IS_ABSOLUTE_PATH (main_file_name) || directory_name == NULL)
2988 *filename_ptr = main_file_name;
2989 else
2990 {
2991 sprintf (buf, "%s%s", directory_name, main_file_name);
2992 *filename_ptr = buf;
2993 buf += filelen + 1;
2994 }
2995 }
2996
2997 if (func)
2998 {
2999 const char *function = func->name;
3000 char *colon;
3001
3002 /* The caller expects a symbol name. We actually have a
3003 function name, without the leading underscore. Put the
3004 underscore back in, so that the caller gets a symbol name. */
3005 if (bfd_get_symbol_leading_char (abfd) == '\0')
3006 strcpy (buf, function);
3007 else
3008 {
3009 buf[0] = bfd_get_symbol_leading_char (abfd);
3010 strcpy (buf + 1, function);
3011 }
3012 /* Have to remove : stuff. */
3013 colon = strchr (buf, ':');
3014 if (colon != NULL)
3015 *colon = '\0';
3016 *functionname_ptr = buf;
3017 }
3018
3019 return TRUE;
3020}
3021
3022int
3023NAME(aout,sizeof_headers) (abfd, execable)
3024 bfd *abfd;
3025 bfd_boolean execable ATTRIBUTE_UNUSED;
3026{
3027 return adata (abfd).exec_bytes_size;
3028}
3029
3030/* Free all information we have cached for this BFD. We can always
3031 read it again later if we need it. */
3032
3033bfd_boolean
3034NAME(aout,bfd_free_cached_info) (abfd)
3035 bfd *abfd;
3036{
3037 asection *o;
3038
3039 if (bfd_get_format (abfd) != bfd_object
3040 || abfd->tdata.aout_data == NULL)
3041 return TRUE;
3042
3043#define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
3044 BFCI_FREE (obj_aout_symbols (abfd));
3045#ifdef USE_MMAP
3046 obj_aout_external_syms (abfd) = 0;
3047 bfd_free_window (&obj_aout_sym_window (abfd));
3048 bfd_free_window (&obj_aout_string_window (abfd));
3049 obj_aout_external_strings (abfd) = 0;
3050#else
3051 BFCI_FREE (obj_aout_external_syms (abfd));
3052 BFCI_FREE (obj_aout_external_strings (abfd));
3053#endif
3054 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3055 BFCI_FREE (o->relocation);
3056#undef BFCI_FREE
3057
3058 return TRUE;
3059}
3060
3061
3062/* a.out link code. */
3063
3064static bfd_boolean aout_link_add_object_symbols
3065 PARAMS ((bfd *, struct bfd_link_info *));
3066static bfd_boolean aout_link_check_archive_element
3067 PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *));
3068static bfd_boolean aout_link_free_symbols
3069 PARAMS ((bfd *));
3070static bfd_boolean aout_link_check_ar_symbols
3071 PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *pneeded));
3072static bfd_boolean aout_link_add_symbols
3073 PARAMS ((bfd *, struct bfd_link_info *));
3074
3075/* Routine to create an entry in an a.out link hash table. */
3076
3077struct bfd_hash_entry *
3078NAME(aout,link_hash_newfunc) (entry, table, string)
3079 struct bfd_hash_entry *entry;
3080 struct bfd_hash_table *table;
3081 const char *string;
3082{
3083 struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
3084
3085 /* Allocate the structure if it has not already been allocated by a
3086 subclass. */
3087 if (ret == (struct aout_link_hash_entry *) NULL)
3088 ret = ((struct aout_link_hash_entry *)
3089 bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
3090 if (ret == (struct aout_link_hash_entry *) NULL)
3091 return (struct bfd_hash_entry *) ret;
3092
3093 /* Call the allocation method of the superclass. */
3094 ret = ((struct aout_link_hash_entry *)
3095 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
3096 table, string));
3097 if (ret)
3098 {
3099 /* Set local fields. */
3100 ret->written = FALSE;
3101 ret->indx = -1;
3102 }
3103
3104 return (struct bfd_hash_entry *) ret;
3105}
3106
3107/* Initialize an a.out link hash table. */
3108
3109bfd_boolean
3110NAME(aout,link_hash_table_init) (table, abfd, newfunc)
3111 struct aout_link_hash_table *table;
3112 bfd *abfd;
3113 struct bfd_hash_entry *(*newfunc)
3114 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
3115 const char *));
3116{
3117 return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
3118}
3119
3120/* Create an a.out link hash table. */
3121
3122struct bfd_link_hash_table *
3123NAME(aout,link_hash_table_create) (abfd)
3124 bfd *abfd;
3125{
3126 struct aout_link_hash_table *ret;
3127 bfd_size_type amt = sizeof (struct aout_link_hash_table);
3128
3129 ret = (struct aout_link_hash_table *) bfd_malloc (amt);
3130 if (ret == NULL)
3131 return (struct bfd_link_hash_table *) NULL;
3132
3133 if (! NAME(aout,link_hash_table_init) (ret, abfd,
3134 NAME(aout,link_hash_newfunc)))
3135 {
3136 free (ret);
3137 return (struct bfd_link_hash_table *) NULL;
3138 }
3139 return &ret->root;
3140}
3141
3142/* Given an a.out BFD, add symbols to the global hash table as
3143 appropriate. */
3144
3145bfd_boolean
3146NAME(aout,link_add_symbols) (abfd, info)
3147 bfd *abfd;
3148 struct bfd_link_info *info;
3149{
3150 switch (bfd_get_format (abfd))
3151 {
3152 case bfd_object:
3153 return aout_link_add_object_symbols (abfd, info);
3154 case bfd_archive:
3155 return _bfd_generic_link_add_archive_symbols
3156 (abfd, info, aout_link_check_archive_element);
3157 default:
3158 bfd_set_error (bfd_error_wrong_format);
3159 return FALSE;
3160 }
3161}
3162
3163/* Add symbols from an a.out object file. */
3164
3165static bfd_boolean
3166aout_link_add_object_symbols (abfd, info)
3167 bfd *abfd;
3168 struct bfd_link_info *info;
3169{
3170 if (! aout_get_external_symbols (abfd))
3171 return FALSE;
3172 if (! aout_link_add_symbols (abfd, info))
3173 return FALSE;
3174 if (! info->keep_memory)
3175 {
3176 if (! aout_link_free_symbols (abfd))
3177 return FALSE;
3178 }
3179 return TRUE;
3180}
3181
3182/* Check a single archive element to see if we need to include it in
3183 the link. *PNEEDED is set according to whether this element is
3184 needed in the link or not. This is called from
3185 _bfd_generic_link_add_archive_symbols. */
3186
3187static bfd_boolean
3188aout_link_check_archive_element (abfd, info, pneeded)
3189 bfd *abfd;
3190 struct bfd_link_info *info;
3191 bfd_boolean *pneeded;
3192{
3193 if (! aout_get_external_symbols (abfd))
3194 return FALSE;
3195
3196 if (! aout_link_check_ar_symbols (abfd, info, pneeded))
3197 return FALSE;
3198
3199 if (*pneeded)
3200 {
3201 if (! aout_link_add_symbols (abfd, info))
3202 return FALSE;
3203 }
3204
3205 if (! info->keep_memory || ! *pneeded)
3206 {
3207 if (! aout_link_free_symbols (abfd))
3208 return FALSE;
3209 }
3210
3211 return TRUE;
3212}
3213
3214/* Free up the internal symbols read from an a.out file. */
3215
3216static bfd_boolean
3217aout_link_free_symbols (abfd)
3218 bfd *abfd;
3219{
3220 if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
3221 {
3222#ifdef USE_MMAP
3223 bfd_free_window (&obj_aout_sym_window (abfd));
3224#else
3225 free ((PTR) obj_aout_external_syms (abfd));
3226#endif
3227 obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
3228 }
3229 if (obj_aout_external_strings (abfd) != (char *) NULL)
3230 {
3231#ifdef USE_MMAP
3232 bfd_free_window (&obj_aout_string_window (abfd));
3233#else
3234 free ((PTR) obj_aout_external_strings (abfd));
3235#endif
3236 obj_aout_external_strings (abfd) = (char *) NULL;
3237 }
3238 return TRUE;
3239}
3240
3241/* Look through the internal symbols to see if this object file should
3242 be included in the link. We should include this object file if it
3243 defines any symbols which are currently undefined. If this object
3244 file defines a common symbol, then we may adjust the size of the
3245 known symbol but we do not include the object file in the link
3246 (unless there is some other reason to include it). */
3247
3248static bfd_boolean
3249aout_link_check_ar_symbols (abfd, info, pneeded)
3250 bfd *abfd;
3251 struct bfd_link_info *info;
3252 bfd_boolean *pneeded;
3253{
3254 register struct external_nlist *p;
3255 struct external_nlist *pend;
3256 char *strings;
3257
3258 *pneeded = FALSE;
3259
3260 /* Look through all the symbols. */
3261 p = obj_aout_external_syms (abfd);
3262 pend = p + obj_aout_external_sym_count (abfd);
3263 strings = obj_aout_external_strings (abfd);
3264 for (; p < pend; p++)
3265 {
3266 int type = H_GET_8 (abfd, p->e_type);
3267 const char *name;
3268 struct bfd_link_hash_entry *h;
3269
3270 /* Ignore symbols that are not externally visible. This is an
3271 optimization only, as we check the type more thoroughly
3272 below. */
3273 if (((type & N_EXT) == 0
3274 || IS_STAB(type)
3275 || type == N_FN)
3276 && type != N_WEAKA
3277 && type != N_WEAKT
3278 && type != N_WEAKD
3279 && type != N_WEAKB)
3280 {
3281 if (type == N_WARNING
3282 || type == N_INDR)
3283 ++p;
3284 continue;
3285 }
3286
3287 name = strings + GET_WORD (abfd, p->e_strx);
3288 h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
3289
3290 /* We are only interested in symbols that are currently
3291 undefined or common. */
3292 if (h == (struct bfd_link_hash_entry *) NULL
3293 || (h->type != bfd_link_hash_undefined
3294 && h->type != bfd_link_hash_common))
3295 {
3296 if (type == (N_INDR | N_EXT))
3297 ++p;
3298 continue;
3299 }
3300
3301 if (type == (N_TEXT | N_EXT)
3302 || type == (N_DATA | N_EXT)
3303 || type == (N_BSS | N_EXT)
3304 || type == (N_ABS | N_EXT)
3305 || type == (N_INDR | N_EXT)
3306#if defined(N_IMP1) && defined(N_IMP2)
3307 || type == (N_IMP1 | N_EXT)
3308#endif
3309 )
3310 {
3311 /* This object file defines this symbol. We must link it
3312 in. This is true regardless of whether the current
3313 definition of the symbol is undefined or common.
3314
3315 If the current definition is common, we have a case in
3316 which we have already seen an object file including:
3317 int a;
3318 and this object file from the archive includes:
3319 int a = 5;
3320 In such a case, whether to include this object is target
3321 dependant for backward compatability.
3322
3323 FIXME: The SunOS 4.1.3 linker will pull in the archive
3324 element if the symbol is defined in the .data section,
3325 but not if it is defined in the .text section. That
3326 seems a bit crazy to me, and it has not been implemented
3327 yet. However, it might be correct. */
3328 if (h->type == bfd_link_hash_common)
3329 {
3330 int skip = 0;
3331
3332 switch (info->common_skip_ar_aymbols)
3333 {
3334 case bfd_link_common_skip_text:
3335 skip = (type == (N_TEXT | N_EXT));
3336 break;
3337 case bfd_link_common_skip_data:
3338 skip = (type == (N_DATA | N_EXT));
3339 break;
3340 default:
3341 case bfd_link_common_skip_all:
3342 skip = 1;
3343 break;
3344 }
3345
3346 if (skip)
3347 continue;
3348 }
3349
3350 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3351 return FALSE;
3352 *pneeded = TRUE;
3353 return TRUE;
3354 }
3355
3356 if (type == (N_UNDF | N_EXT))
3357 {
3358 bfd_vma value;
3359
3360 value = GET_WORD (abfd, p->e_value);
3361 if (value != 0)
3362 {
3363 /* This symbol is common in the object from the archive
3364 file. */
3365 if (h->type == bfd_link_hash_undefined)
3366 {
3367 bfd *symbfd;
3368 unsigned int power;
3369
3370 symbfd = h->u.undef.abfd;
3371 if (symbfd == (bfd *) NULL)
3372 {
3373 /* This symbol was created as undefined from
3374 outside BFD. We assume that we should link
3375 in the object file. This is done for the -u
3376 option in the linker. */
3377 if (! (*info->callbacks->add_archive_element) (info,
3378 abfd,
3379 name))
3380 return FALSE;
3381 *pneeded = TRUE;
3382 return TRUE;
3383 }
3384 /* Turn the current link symbol into a common
3385 symbol. It is already on the undefs list. */
3386 h->type = bfd_link_hash_common;
3387 h->u.c.p = ((struct bfd_link_hash_common_entry *)
3388 bfd_hash_allocate (&info->hash->table,
3389 sizeof (struct bfd_link_hash_common_entry)));
3390 if (h->u.c.p == NULL)
3391 return FALSE;
3392
3393 h->u.c.size = value;
3394
3395 /* FIXME: This isn't quite right. The maximum
3396 alignment of a common symbol should be set by the
3397 architecture of the output file, not of the input
3398 file. */
3399 power = bfd_log2 (value);
3400 if (power > bfd_get_arch_info (abfd)->section_align_power)
3401 power = bfd_get_arch_info (abfd)->section_align_power;
3402 h->u.c.p->alignment_power = power;
3403
3404 h->u.c.p->section = bfd_make_section_old_way (symbfd,
3405 "COMMON");
3406 }
3407 else
3408 {
3409 /* Adjust the size of the common symbol if
3410 necessary. */
3411 if (value > h->u.c.size)
3412 h->u.c.size = value;
3413 }
3414 }
3415 }
3416
3417 if (type == N_WEAKA
3418 || type == N_WEAKT
3419 || type == N_WEAKD
3420 || type == N_WEAKB)
3421 {
3422 /* This symbol is weak but defined. We must pull it in if
3423 the current link symbol is undefined, but we don't want
3424 it if the current link symbol is common. */
3425 if (h->type == bfd_link_hash_undefined)
3426 {
3427 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3428 return FALSE;
3429 *pneeded = TRUE;
3430 return TRUE;
3431 }
3432 }
3433 }
3434
3435 /* We do not need this object file. */
3436 return TRUE;
3437}
3438
3439/* Add all symbols from an object file to the hash table. */
3440
3441static bfd_boolean
3442aout_link_add_symbols (abfd, info)
3443 bfd *abfd;
3444 struct bfd_link_info *info;
3445{
3446 bfd_boolean (*add_one_symbol)
3447 PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
3448 bfd_vma, const char *, bfd_boolean, bfd_boolean,
3449 struct bfd_link_hash_entry **));
3450 struct external_nlist *syms;
3451 bfd_size_type sym_count;
3452 char *strings;
3453 bfd_boolean copy;
3454 struct aout_link_hash_entry **sym_hash;
3455 register struct external_nlist *p;
3456 struct external_nlist *pend;
3457 bfd_size_type amt;
3458
3459 syms = obj_aout_external_syms (abfd);
3460 sym_count = obj_aout_external_sym_count (abfd);
3461 strings = obj_aout_external_strings (abfd);
3462 if (info->keep_memory)
3463 copy = FALSE;
3464 else
3465 copy = TRUE;
3466
3467 if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
3468 {
3469 if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
3470 (abfd, info, &syms, &sym_count, &strings)))
3471 return FALSE;
3472 }
3473
3474 /* We keep a list of the linker hash table entries that correspond
3475 to particular symbols. We could just look them up in the hash
3476 table, but keeping the list is more efficient. Perhaps this
3477 should be conditional on info->keep_memory. */
3478 amt = sym_count * sizeof (struct aout_link_hash_entry *);
3479 sym_hash = (struct aout_link_hash_entry **) bfd_alloc (abfd, amt);
3480 if (sym_hash == NULL && sym_count != 0)
3481 return FALSE;
3482 obj_aout_sym_hashes (abfd) = sym_hash;
3483
3484 add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
3485 if (add_one_symbol == NULL)
3486 add_one_symbol = _bfd_generic_link_add_one_symbol;
3487
3488 p = syms;
3489 pend = p + sym_count;
3490 for (; p < pend; p++, sym_hash++)
3491 {
3492 int type;
3493 const char *name;
3494 bfd_vma value;
3495 asection *section;
3496 flagword flags;
3497 const char *string;
3498
3499 *sym_hash = NULL;
3500
3501 type = H_GET_8 (abfd, p->e_type);
3502
3503 /* Ignore debugging symbols. */
3504 if (IS_STAB(type))
3505 continue;
3506
3507 name = strings + GET_WORD (abfd, p->e_strx);
3508 value = GET_WORD (abfd, p->e_value);
3509 flags = BSF_GLOBAL;
3510 string = NULL;
3511 switch (type)
3512 {
3513 default:
3514 abort ();
3515
3516 case N_UNDF:
3517 case N_ABS:
3518 case N_TEXT:
3519 case N_DATA:
3520 case N_BSS:
3521 case N_FN_SEQ:
3522 case N_COMM:
3523 case N_SETV:
3524 case N_FN:
3525 /* Ignore symbols that are not externally visible. */
3526 continue;
3527 case N_INDR:
3528 /* Ignore local indirect symbol. */
3529 ++p;
3530 ++sym_hash;
3531 continue;
3532
3533 case N_UNDF | N_EXT:
3534 if (value == 0)
3535 {
3536 section = bfd_und_section_ptr;
3537 flags = 0;
3538 }
3539 else
3540 section = bfd_com_section_ptr;
3541 break;
3542 case N_ABS | N_EXT:
3543 section = bfd_abs_section_ptr;
3544 break;
3545 case N_TEXT | N_EXT:
3546 section = obj_textsec (abfd);
3547 value -= bfd_get_section_vma (abfd, section);
3548 break;
3549 case N_DATA | N_EXT:
3550 case N_SETV | N_EXT:
3551 /* Treat N_SETV symbols as N_DATA symbol; see comment in
3552 translate_from_native_sym_flags. */
3553 section = obj_datasec (abfd);
3554 value -= bfd_get_section_vma (abfd, section);
3555 break;
3556 case N_BSS | N_EXT:
3557 section = obj_bsssec (abfd);
3558 value -= bfd_get_section_vma (abfd, section);
3559 break;
3560 case N_INDR | N_EXT:
3561 /* An indirect symbol. The next symbol is the symbol
3562 which this one really is. */
3563 BFD_ASSERT (p + 1 < pend);
3564 ++p;
3565 string = strings + GET_WORD (abfd, p->e_strx);
3566 section = bfd_ind_section_ptr;
3567 flags |= BSF_INDIRECT;
3568 break;
3569 case N_COMM | N_EXT:
3570 section = bfd_com_section_ptr;
3571 break;
3572 case N_SETA: case N_SETA | N_EXT:
3573 section = bfd_abs_section_ptr;
3574 flags |= BSF_CONSTRUCTOR;
3575 break;
3576 case N_SETT: case N_SETT | N_EXT:
3577 section = obj_textsec (abfd);
3578 flags |= BSF_CONSTRUCTOR;
3579 value -= bfd_get_section_vma (abfd, section);
3580 break;
3581 case N_SETD: case N_SETD | N_EXT:
3582 section = obj_datasec (abfd);
3583 flags |= BSF_CONSTRUCTOR;
3584 value -= bfd_get_section_vma (abfd, section);
3585 break;
3586 case N_SETB: case N_SETB | N_EXT:
3587 section = obj_bsssec (abfd);
3588 flags |= BSF_CONSTRUCTOR;
3589 value -= bfd_get_section_vma (abfd, section);
3590 break;
3591 case N_WARNING:
3592 /* A warning symbol. The next symbol is the one to warn
3593 about. */
3594 BFD_ASSERT (p + 1 < pend);
3595 ++p;
3596 string = name;
3597 name = strings + GET_WORD (abfd, p->e_strx);
3598 section = bfd_und_section_ptr;
3599 flags |= BSF_WARNING;
3600 break;
3601 case N_WEAKU:
3602 section = bfd_und_section_ptr;
3603 flags = BSF_WEAK;
3604 break;
3605 case N_WEAKA:
3606 section = bfd_abs_section_ptr;
3607 flags = BSF_WEAK;
3608 break;
3609 case N_WEAKT:
3610 section = obj_textsec (abfd);
3611 value -= bfd_get_section_vma (abfd, section);
3612 flags = BSF_WEAK;
3613 break;
3614 case N_WEAKD:
3615 section = obj_datasec (abfd);
3616 value -= bfd_get_section_vma (abfd, section);
3617 flags = BSF_WEAK;
3618 break;
3619 case N_WEAKB:
3620 section = obj_bsssec (abfd);
3621 value -= bfd_get_section_vma (abfd, section);
3622 flags = BSF_WEAK;
3623 break;
3624#if defined(N_IMP1) && defined(N_IMP2)
3625 case N_IMP1 | N_EXT:
3626 section = bfd_abs_section_ptr;
3627 flags = BSF_EMX_IMPORT1;
3628 /* VALUE_N_IMP1 in *ABS* means external imported symbol. This is
3629 a bit unreliable, but it's the best we can do in some cases. */
3630 value = VALUE_N_IMP1;
3631 break;
3632 case N_IMP2 | N_EXT:
3633 section = bfd_abs_section_ptr;
3634 flags = BSF_EMX_IMPORT2;
3635 break;
3636 case N_IMP2: case N_IMP1: BFD_ASSERT (!"very bad"); break;
3637#endif /* EMX: N_IMP[12] */
3638#if defined(N_EXP)
3639 case N_EXP | N_EXT:
3640 case N_EXP:
3641 section = bfd_abs_section_ptr;
3642 flags = BSF_EMX_EXPORT;
3643 break;
3644#endif /* EMX: N_EXP */
3645 }
3646
3647 if (! ((*add_one_symbol)
3648 (info, abfd, name, flags, section, value, string, copy, FALSE,
3649 (struct bfd_link_hash_entry **) sym_hash)))
3650 return FALSE;
3651
3652 /* Restrict the maximum alignment of a common symbol based on
3653 the architecture, since a.out has no way to represent
3654 alignment requirements of a section in a .o file. FIXME:
3655 This isn't quite right: it should use the architecture of the
3656 output file, not the input files. */
3657 if ((*sym_hash)->root.type == bfd_link_hash_common
3658 && ((*sym_hash)->root.u.c.p->alignment_power >
3659 bfd_get_arch_info (abfd)->section_align_power))
3660 (*sym_hash)->root.u.c.p->alignment_power =
3661 bfd_get_arch_info (abfd)->section_align_power;
3662
3663 /* If this is a set symbol, and we are not building sets, then
3664 it is possible for the hash entry to not have been set. In
3665 such a case, treat the symbol as not globally defined. */
3666 if ((*sym_hash)->root.type == bfd_link_hash_new)
3667 {
3668 BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
3669 *sym_hash = NULL;
3670 }
3671
3672 if (type == (N_INDR | N_EXT) || type == N_WARNING)
3673 ++sym_hash;
3674 }
3675
3676 return TRUE;
3677}
3678
3679
3680/* A hash table used for header files with N_BINCL entries. */
3681
3682struct aout_link_includes_table
3683{
3684 struct bfd_hash_table root;
3685};
3686
3687/* A linked list of totals that we have found for a particular header
3688 file. */
3689
3690struct aout_link_includes_totals
3691{
3692 struct aout_link_includes_totals *next;
3693 bfd_vma total;
3694};
3695
3696/* An entry in the header file hash table. */
3697
3698struct aout_link_includes_entry
3699{
3700 struct bfd_hash_entry root;
3701 /* List of totals we have found for this file. */
3702 struct aout_link_includes_totals *totals;
3703};
3704
3705/* Look up an entry in an the header file hash table. */
3706
3707#define aout_link_includes_lookup(table, string, create, copy) \
3708 ((struct aout_link_includes_entry *) \
3709 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
3710
3711/* During the final link step we need to pass around a bunch of
3712 information, so we do it in an instance of this structure. */
3713
3714struct aout_final_link_info
3715{
3716 /* General link information. */
3717 struct bfd_link_info *info;
3718 /* Output bfd. */
3719 bfd *output_bfd;
3720 /* Reloc file positions. */
3721 file_ptr treloff, dreloff;
3722 /* File position of symbols. */
3723 file_ptr symoff;
3724 /* String table. */
3725 struct bfd_strtab_hash *strtab;
3726 /* Header file hash table. */
3727 struct aout_link_includes_table includes;
3728 /* A buffer large enough to hold the contents of any section. */
3729 bfd_byte *contents;
3730 /* A buffer large enough to hold the relocs of any section. */
3731 PTR relocs;
3732 /* A buffer large enough to hold the symbol map of any input BFD. */
3733 int *symbol_map;
3734 /* A buffer large enough to hold output symbols of any input BFD. */
3735 struct external_nlist *output_syms;
3736};
3737
3738static struct bfd_hash_entry *aout_link_includes_newfunc
3739 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
3740static bfd_boolean aout_link_input_bfd
3741 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3742static bfd_boolean aout_link_write_symbols
3743 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3744static bfd_boolean aout_link_write_other_symbol
3745 PARAMS ((struct aout_link_hash_entry *, PTR));
3746static bfd_boolean aout_link_input_section
3747 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3748 asection *input_section, file_ptr *reloff_ptr,
3749 bfd_size_type rel_size));
3750static bfd_boolean aout_link_input_section_std
3751 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3752 asection *input_section, struct reloc_std_external *,
3753 bfd_size_type rel_size, bfd_byte *contents));
3754static bfd_boolean aout_link_input_section_ext
3755 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3756 asection *input_section, struct reloc_ext_external *,
3757 bfd_size_type rel_size, bfd_byte *contents));
3758static INLINE asection *aout_reloc_index_to_section
3759 PARAMS ((bfd *, int));
3760static bfd_boolean aout_link_reloc_link_order
3761 PARAMS ((struct aout_final_link_info *, asection *,
3762 struct bfd_link_order *));
3763
3764/* The function to create a new entry in the header file hash table. */
3765
3766static struct bfd_hash_entry *
3767aout_link_includes_newfunc (entry, table, string)
3768 struct bfd_hash_entry *entry;
3769 struct bfd_hash_table *table;
3770 const char *string;
3771{
3772 struct aout_link_includes_entry *ret =
3773 (struct aout_link_includes_entry *) entry;
3774
3775 /* Allocate the structure if it has not already been allocated by a
3776 subclass. */
3777 if (ret == (struct aout_link_includes_entry *) NULL)
3778 ret = ((struct aout_link_includes_entry *)
3779 bfd_hash_allocate (table,
3780 sizeof (struct aout_link_includes_entry)));
3781 if (ret == (struct aout_link_includes_entry *) NULL)
3782 return (struct bfd_hash_entry *) ret;
3783
3784 /* Call the allocation method of the superclass. */
3785 ret = ((struct aout_link_includes_entry *)
3786 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
3787 if (ret)
3788 {
3789 /* Set local fields. */
3790 ret->totals = NULL;
3791 }
3792
3793 return (struct bfd_hash_entry *) ret;
3794}
3795
3796/* Do the final link step. This is called on the output BFD. The
3797 INFO structure should point to a list of BFDs linked through the
3798 link_next field which can be used to find each BFD which takes part
3799 in the output. Also, each section in ABFD should point to a list
3800 of bfd_link_order structures which list all the input sections for
3801 the output section. */
3802
3803bfd_boolean
3804NAME(aout,final_link) (abfd, info, callback)
3805 bfd *abfd;
3806 struct bfd_link_info *info;
3807 void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
3808{
3809 struct aout_final_link_info aout_info;
3810 bfd_boolean includes_hash_initialized = FALSE;
3811 register bfd *sub;
3812 bfd_size_type trsize, drsize;
3813 bfd_size_type max_contents_size;
3814 bfd_size_type max_relocs_size;
3815 bfd_size_type max_sym_count;
3816 bfd_size_type text_size;
3817 file_ptr text_end;
3818 register struct bfd_link_order *p;
3819 asection *o;
3820 bfd_boolean have_link_order_relocs;
3821
3822 if (info->shared)
3823 abfd->flags |= DYNAMIC;
3824
3825 aout_info.info = info;
3826 aout_info.output_bfd = abfd;
3827 aout_info.contents = NULL;
3828 aout_info.relocs = NULL;
3829 aout_info.symbol_map = NULL;
3830 aout_info.output_syms = NULL;
3831
3832 if (! bfd_hash_table_init_n (&aout_info.includes.root,
3833 aout_link_includes_newfunc,
3834 251))
3835 goto error_return;
3836 includes_hash_initialized = TRUE;
3837
3838 /* Figure out the largest section size. Also, if generating
3839 relocateable output, count the relocs. */
3840 trsize = 0;
3841 drsize = 0;
3842 max_contents_size = 0;
3843 max_relocs_size = 0;
3844 max_sym_count = 0;
3845 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
3846 {
3847 bfd_size_type sz;
3848
3849 if (info->relocateable)
3850 {
3851 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3852 {
3853 trsize += exec_hdr (sub)->a_trsize;
3854 drsize += exec_hdr (sub)->a_drsize;
3855 }
3856 else
3857 {
3858 /* FIXME: We need to identify the .text and .data sections
3859 and call get_reloc_upper_bound and canonicalize_reloc to
3860 work out the number of relocs needed, and then multiply
3861 by the reloc size. */
3862 (*_bfd_error_handler)
3863 (_("%s: relocateable link from %s to %s not supported"),
3864 bfd_get_filename (abfd),
3865 sub->xvec->name, abfd->xvec->name);
3866 bfd_set_error (bfd_error_invalid_operation);
3867 goto error_return;
3868 }
3869 }
3870
3871 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3872 {
3873 sz = bfd_section_size (sub, obj_textsec (sub));
3874 if (sz > max_contents_size)
3875 max_contents_size = sz;
3876 sz = bfd_section_size (sub, obj_datasec (sub));
3877 if (sz > max_contents_size)
3878 max_contents_size = sz;
3879
3880 sz = exec_hdr (sub)->a_trsize;
3881 if (sz > max_relocs_size)
3882 max_relocs_size = sz;
3883 sz = exec_hdr (sub)->a_drsize;
3884 if (sz > max_relocs_size)
3885 max_relocs_size = sz;
3886
3887 sz = obj_aout_external_sym_count (sub);
3888 if (sz > max_sym_count)
3889 max_sym_count = sz;
3890 }
3891 }
3892
3893 if (info->relocateable)
3894 {
3895 if (obj_textsec (abfd) != (asection *) NULL)
3896 trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
3897 ->link_order_head)
3898 * obj_reloc_entry_size (abfd));
3899 if (obj_datasec (abfd) != (asection *) NULL)
3900 drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
3901 ->link_order_head)
3902 * obj_reloc_entry_size (abfd));
3903 }
3904
3905 exec_hdr (abfd)->a_trsize = trsize;
3906 exec_hdr (abfd)->a_drsize = drsize;
3907
3908 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
3909
3910 /* Adjust the section sizes and vmas according to the magic number.
3911 This sets a_text, a_data and a_bss in the exec_hdr and sets the
3912 filepos for each section. */
3913 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3914 goto error_return;
3915
3916 /* The relocation and symbol file positions differ among a.out
3917 targets. We are passed a callback routine from the backend
3918 specific code to handle this.
3919 FIXME: At this point we do not know how much space the symbol
3920 table will require. This will not work for any (nonstandard)
3921 a.out target that needs to know the symbol table size before it
3922 can compute the relocation file positions. This may or may not
3923 be the case for the hp300hpux target, for example. */
3924 (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3925 &aout_info.symoff);
3926 obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3927 obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3928 obj_sym_filepos (abfd) = aout_info.symoff;
3929
3930 /* We keep a count of the symbols as we output them. */
3931 obj_aout_external_sym_count (abfd) = 0;
3932
3933 /* We accumulate the string table as we write out the symbols. */
3934 aout_info.strtab = _bfd_stringtab_init ();
3935 if (aout_info.strtab == NULL)
3936 goto error_return;
3937
3938 /* Allocate buffers to hold section contents and relocs. */
3939 aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
3940 aout_info.relocs = (PTR) bfd_malloc (max_relocs_size);
3941 aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int *));
3942 aout_info.output_syms = ((struct external_nlist *)
3943 bfd_malloc ((max_sym_count + 1)
3944 * sizeof (struct external_nlist)));
3945 if ((aout_info.contents == NULL && max_contents_size != 0)
3946 || (aout_info.relocs == NULL && max_relocs_size != 0)
3947 || (aout_info.symbol_map == NULL && max_sym_count != 0)
3948 || aout_info.output_syms == NULL)
3949 goto error_return;
3950
3951 /* If we have a symbol named __DYNAMIC, force it out now. This is
3952 required by SunOS. Doing this here rather than in sunos.c is a
3953 hack, but it's easier than exporting everything which would be
3954 needed. */
3955 {
3956 struct aout_link_hash_entry *h;
3957
3958 h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
3959 FALSE, FALSE, FALSE);
3960 if (h != NULL)
3961 aout_link_write_other_symbol (h, &aout_info);
3962 }
3963
3964 /* The most time efficient way to do the link would be to read all
3965 the input object files into memory and then sort out the
3966 information into the output file. Unfortunately, that will
3967 probably use too much memory. Another method would be to step
3968 through everything that composes the text section and write it
3969 out, and then everything that composes the data section and write
3970 it out, and then write out the relocs, and then write out the
3971 symbols. Unfortunately, that requires reading stuff from each
3972 input file several times, and we will not be able to keep all the
3973 input files open simultaneously, and reopening them will be slow.
3974
3975 What we do is basically process one input file at a time. We do
3976 everything we need to do with an input file once--copy over the
3977 section contents, handle the relocation information, and write
3978 out the symbols--and then we throw away the information we read
3979 from it. This approach requires a lot of lseeks of the output
3980 file, which is unfortunate but still faster than reopening a lot
3981 of files.
3982
3983 We use the output_has_begun field of the input BFDs to see
3984 whether we have already handled it. */
3985 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3986 sub->output_has_begun = FALSE;
3987
3988 /* Mark all sections which are to be included in the link. This
3989 will normally be every section. We need to do this so that we
3990 can identify any sections which the linker has decided to not
3991 include. */
3992 for (o = abfd->sections; o != NULL; o = o->next)
3993 {
3994 for (p = o->link_order_head; p != NULL; p = p->next)
3995 if (p->type == bfd_indirect_link_order)
3996 p->u.indirect.section->linker_mark = TRUE;
3997 }
3998
3999 have_link_order_relocs = FALSE;
4000 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
4001 {
4002 for (p = o->link_order_head;
4003 p != (struct bfd_link_order *) NULL;
4004 p = p->next)
4005 {
4006 if (p->type == bfd_indirect_link_order
4007 && (bfd_get_flavour (p->u.indirect.section->owner)
4008 == bfd_target_aout_flavour))
4009 {
4010 bfd *input_bfd;
4011
4012 input_bfd = p->u.indirect.section->owner;
4013 if (! input_bfd->output_has_begun)
4014 {
4015 if (! aout_link_input_bfd (&aout_info, input_bfd))
4016 goto error_return;
4017 input_bfd->output_has_begun = TRUE;
4018 }
4019 }
4020 else if (p->type == bfd_section_reloc_link_order
4021 || p->type == bfd_symbol_reloc_link_order)
4022 {
4023 /* These are handled below. */
4024 have_link_order_relocs = TRUE;
4025 }
4026 else
4027 {
4028 if (! _bfd_default_link_order (abfd, info, o, p))
4029 goto error_return;
4030 }
4031 }
4032 }
4033
4034 /* Write out any symbols that we have not already written out. */
4035 aout_link_hash_traverse (aout_hash_table (info),
4036 aout_link_write_other_symbol,
4037 (PTR) &aout_info);
4038
4039 /* Now handle any relocs we were asked to create by the linker.
4040 These did not come from any input file. We must do these after
4041 we have written out all the symbols, so that we know the symbol
4042 indices to use. */
4043 if (have_link_order_relocs)
4044 {
4045 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
4046 {
4047 for (p = o->link_order_head;
4048 p != (struct bfd_link_order *) NULL;
4049 p = p->next)
4050 {
4051 if (p->type == bfd_section_reloc_link_order
4052 || p->type == bfd_symbol_reloc_link_order)
4053 {
4054 if (! aout_link_reloc_link_order (&aout_info, o, p))
4055 goto error_return;
4056 }
4057 }
4058 }
4059 }
4060
4061 if (aout_info.contents != NULL)
4062 {
4063 free (aout_info.contents);
4064 aout_info.contents = NULL;
4065 }
4066 if (aout_info.relocs != NULL)
4067 {
4068 free (aout_info.relocs);
4069 aout_info.relocs = NULL;
4070 }
4071 if (aout_info.symbol_map != NULL)
4072 {
4073 free (aout_info.symbol_map);
4074 aout_info.symbol_map = NULL;
4075 }
4076 if (aout_info.output_syms != NULL)
4077 {
4078 free (aout_info.output_syms);
4079 aout_info.output_syms = NULL;
4080 }
4081 if (includes_hash_initialized)
4082 {
4083 bfd_hash_table_free (&aout_info.includes.root);
4084 includes_hash_initialized = FALSE;
4085 }
4086
4087 /* Finish up any dynamic linking we may be doing. */
4088 if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
4089 {
4090 if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
4091 goto error_return;
4092 }
4093
4094 /* Update the header information. */
4095 abfd->symcount = obj_aout_external_sym_count (abfd);
4096 exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
4097 obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
4098 obj_textsec (abfd)->reloc_count =
4099 exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
4100 obj_datasec (abfd)->reloc_count =
4101 exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
4102
4103 /* Write out the string table, unless there are no symbols. */
4104 if (abfd->symcount > 0)
4105 {
4106 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
4107 || ! emit_stringtab (abfd, aout_info.strtab))
4108 goto error_return;
4109 }
4110 else if (obj_textsec (abfd)->reloc_count == 0
4111 && obj_datasec (abfd)->reloc_count == 0)
4112 {
4113 bfd_byte b;
4114 file_ptr pos;
4115
4116 b = 0;
4117 pos = obj_datasec (abfd)->filepos + exec_hdr (abfd)->a_data - 1;
4118 if (bfd_seek (abfd, pos, SEEK_SET) != 0
4119 || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
4120 goto error_return;
4121 }
4122
4123 return TRUE;
4124
4125 error_return:
4126 if (aout_info.contents != NULL)
4127 free (aout_info.contents);
4128 if (aout_info.relocs != NULL)
4129 free (aout_info.relocs);
4130 if (aout_info.symbol_map != NULL)
4131 free (aout_info.symbol_map);
4132 if (aout_info.output_syms != NULL)
4133 free (aout_info.output_syms);
4134 if (includes_hash_initialized)
4135 bfd_hash_table_free (&aout_info.includes.root);
4136 return FALSE;
4137}
4138
4139/* Link an a.out input BFD into the output file. */
4140
4141static bfd_boolean
4142aout_link_input_bfd (finfo, input_bfd)
4143 struct aout_final_link_info *finfo;
4144 bfd *input_bfd;
4145{
4146 bfd_size_type sym_count;
4147
4148 BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
4149
4150 /* If this is a dynamic object, it may need special handling. */
4151 if ((input_bfd->flags & DYNAMIC) != 0
4152 && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
4153 {
4154 return ((*aout_backend_info (input_bfd)->link_dynamic_object)
4155 (finfo->info, input_bfd));
4156 }
4157
4158 /* Get the symbols. We probably have them already, unless
4159 finfo->info->keep_memory is FALSE. */
4160 if (! aout_get_external_symbols (input_bfd))
4161 return FALSE;
4162
4163 sym_count = obj_aout_external_sym_count (input_bfd);
4164
4165 /* Write out the symbols and get a map of the new indices. The map
4166 is placed into finfo->symbol_map. */
4167 if (! aout_link_write_symbols (finfo, input_bfd))
4168 return FALSE;
4169
4170 /* Relocate and write out the sections. These functions use the
4171 symbol map created by aout_link_write_symbols. The linker_mark
4172 field will be set if these sections are to be included in the
4173 link, which will normally be the case. */
4174 if (obj_textsec (input_bfd)->linker_mark)
4175 {
4176 if (! aout_link_input_section (finfo, input_bfd,
4177 obj_textsec (input_bfd),
4178 &finfo->treloff,
4179 exec_hdr (input_bfd)->a_trsize))
4180 return FALSE;
4181 }
4182 if (obj_datasec (input_bfd)->linker_mark)
4183 {
4184 if (! aout_link_input_section (finfo, input_bfd,
4185 obj_datasec (input_bfd),
4186 &finfo->dreloff,
4187 exec_hdr (input_bfd)->a_drsize))
4188 return FALSE;
4189 }
4190
4191 /* If we are not keeping memory, we don't need the symbols any
4192 longer. We still need them if we are keeping memory, because the
4193 strings in the hash table point into them. */
4194 if (! finfo->info->keep_memory)
4195 {
4196 if (! aout_link_free_symbols (input_bfd))
4197 return FALSE;
4198 }
4199
4200 return TRUE;
4201}
4202
4203/* Adjust and write out the symbols for an a.out file. Set the new
4204 symbol indices into a symbol_map. */
4205
4206static bfd_boolean
4207aout_link_write_symbols (finfo, input_bfd)
4208 struct aout_final_link_info *finfo;
4209 bfd *input_bfd;
4210{
4211 bfd *output_bfd;
4212 bfd_size_type sym_count;
4213 char *strings;
4214 enum bfd_link_strip strip;
4215 enum bfd_link_discard discard;
4216 struct external_nlist *outsym;
4217 bfd_size_type strtab_index;
4218 register struct external_nlist *sym;
4219 struct external_nlist *sym_end;
4220 struct aout_link_hash_entry **sym_hash;
4221 int *symbol_map;
4222 bfd_boolean pass;
4223 bfd_boolean skip_next;
4224
4225 output_bfd = finfo->output_bfd;
4226 sym_count = obj_aout_external_sym_count (input_bfd);
4227 strings = obj_aout_external_strings (input_bfd);
4228 strip = finfo->info->strip;
4229 discard = finfo->info->discard;
4230 outsym = finfo->output_syms;
4231
4232 /* First write out a symbol for this object file, unless we are
4233 discarding such symbols. */
4234 if (strip != strip_all
4235 && (strip != strip_some
4236 || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
4237 FALSE, FALSE) != NULL)
4238 && discard != discard_all)
4239 {
4240 H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
4241 H_PUT_8 (output_bfd, 0, outsym->e_other);
4242 H_PUT_16 (output_bfd, 0, outsym->e_desc);
4243 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4244 input_bfd->filename, FALSE);
4245 if (strtab_index == (bfd_size_type) -1)
4246 return FALSE;
4247 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4248 PUT_WORD (output_bfd,
4249 (bfd_get_section_vma (output_bfd,
4250 obj_textsec (input_bfd)->output_section)
4251 + obj_textsec (input_bfd)->output_offset),
4252 outsym->e_value);
4253 ++obj_aout_external_sym_count (output_bfd);
4254 ++outsym;
4255 }
4256
4257 pass = FALSE;
4258 skip_next = FALSE;
4259 sym = obj_aout_external_syms (input_bfd);
4260 sym_end = sym + sym_count;
4261 sym_hash = obj_aout_sym_hashes (input_bfd);
4262 symbol_map = finfo->symbol_map;
4263 memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
4264 for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
4265 {
4266 const char *name;
4267 int type;
4268 struct aout_link_hash_entry *h;
4269 bfd_boolean skip;
4270 asection *symsec;
4271 bfd_vma val = 0;
4272 bfd_boolean copy;
4273
4274 /* We set *symbol_map to 0 above for all symbols. If it has
4275 already been set to -1 for this symbol, it means that we are
4276 discarding it because it appears in a duplicate header file.
4277 See the N_BINCL code below. */
4278 if (*symbol_map == -1)
4279 continue;
4280
4281 /* Initialize *symbol_map to -1, which means that the symbol was
4282 not copied into the output file. We will change it later if
4283 we do copy the symbol over. */
4284 *symbol_map = -1;
4285
4286 type = H_GET_8 (input_bfd, sym->e_type);
4287 name = strings + GET_WORD (input_bfd, sym->e_strx);
4288
4289 h = NULL;
4290
4291 if (pass)
4292 {
4293 /* Pass this symbol through. It is the target of an
4294 indirect or warning symbol. */
4295 val = GET_WORD (input_bfd, sym->e_value);
4296 pass = FALSE;
4297 }
4298 else if (skip_next)
4299 {
4300 /* Skip this symbol, which is the target of an indirect
4301 symbol that we have changed to no longer be an indirect
4302 symbol. */
4303 skip_next = FALSE;
4304 continue;
4305 }
4306 else
4307 {
4308 struct aout_link_hash_entry *hresolve;
4309
4310 /* We have saved the hash table entry for this symbol, if
4311 there is one. Note that we could just look it up again
4312 in the hash table, provided we first check that it is an
4313 external symbol. */
4314 h = *sym_hash;
4315
4316 /* Use the name from the hash table, in case the symbol was
4317 wrapped. */
4318 if (h != NULL
4319 && h->root.type != bfd_link_hash_warning)
4320 name = h->root.root.string;
4321
4322 /* If this is an indirect or warning symbol, then change
4323 hresolve to the base symbol. We also change *sym_hash so
4324 that the relocation routines relocate against the real
4325 symbol. */
4326 hresolve = h;
4327 if (h != (struct aout_link_hash_entry *) NULL
4328 && (h->root.type == bfd_link_hash_indirect
4329 || h->root.type == bfd_link_hash_warning))
4330 {
4331 hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
4332 while (hresolve->root.type == bfd_link_hash_indirect
4333 || hresolve->root.type == bfd_link_hash_warning)
4334 hresolve = ((struct aout_link_hash_entry *)
4335 hresolve->root.u.i.link);
4336 *sym_hash = hresolve;
4337 }
4338
4339 /* If the symbol has already been written out, skip it. */
4340 if (h != (struct aout_link_hash_entry *) NULL
4341 && h->written)
4342 {
4343 if ((type & N_TYPE) == N_INDR
4344 || type == N_WARNING)
4345 skip_next = TRUE;
4346 *symbol_map = h->indx;
4347 continue;
4348 }
4349
4350 /* See if we are stripping this symbol. */
4351 skip = FALSE;
4352 switch (strip)
4353 {
4354 case strip_none:
4355 break;
4356 case strip_debugger:
4357 if (IS_STAB(type))
4358 skip = TRUE;
4359 break;
4360 case strip_some:
4361 if (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE)
4362 == NULL)
4363 skip = TRUE;
4364 break;
4365 case strip_all:
4366 skip = TRUE;
4367 break;
4368 }
4369 if (skip)
4370 {
4371 if (h != (struct aout_link_hash_entry *) NULL)
4372 h->written = TRUE;
4373 continue;
4374 }
4375
4376 /* Get the value of the symbol. */
4377 if ((type & N_TYPE) == N_TEXT
4378 || type == N_WEAKT)
4379 symsec = obj_textsec (input_bfd);
4380 else if ((type & N_TYPE) == N_DATA
4381 || type == N_WEAKD)
4382 symsec = obj_datasec (input_bfd);
4383 else if ((type & N_TYPE) == N_BSS
4384 || type == N_WEAKB)
4385 symsec = obj_bsssec (input_bfd);
4386 else if ((type & N_TYPE) == N_ABS
4387 || type == N_WEAKA)
4388 symsec = bfd_abs_section_ptr;
4389 else if (((type & N_TYPE) == N_INDR
4390 && (hresolve == (struct aout_link_hash_entry *) NULL
4391 || (hresolve->root.type != bfd_link_hash_defined
4392 && hresolve->root.type != bfd_link_hash_defweak
4393 && hresolve->root.type != bfd_link_hash_common)))
4394 || type == N_WARNING)
4395 {
4396 /* Pass the next symbol through unchanged. The
4397 condition above for indirect symbols is so that if
4398 the indirect symbol was defined, we output it with
4399 the correct definition so the debugger will
4400 understand it. */
4401 pass = TRUE;
4402 val = GET_WORD (input_bfd, sym->e_value);
4403 symsec = NULL;
4404 }
4405#if defined(N_IMP1) && defined(N_IMP2)
4406 else if ((type == (N_IMP1 | N_EXT))
4407 || (type == (N_IMP2 | N_EXT)))
4408 symsec = bfd_abs_section_ptr;
4409#endif
4410#if defined(N_EXP)
4411 else if (type == (N_EXP | N_EXT))
4412 symsec = bfd_abs_section_ptr;
4413#endif /* EMX: N_EXP */
4414 else if (IS_STAB(type))
4415 {
4416 val = GET_WORD (input_bfd, sym->e_value);
4417 symsec = NULL;
4418 }
4419 else
4420 {
4421 /* If we get here with an indirect symbol, it means that
4422 we are outputting it with a real definition. In such
4423 a case we do not want to output the next symbol,
4424 which is the target of the indirection. */
4425 if ((type & N_TYPE) == N_INDR)
4426 skip_next = TRUE;
4427
4428 symsec = NULL;
4429
4430 /* We need to get the value from the hash table. We use
4431 hresolve so that if we have defined an indirect
4432 symbol we output the final definition. */
4433 if (h == (struct aout_link_hash_entry *) NULL)
4434 {
4435 switch (type & N_TYPE)
4436 {
4437 case N_SETT:
4438 symsec = obj_textsec (input_bfd);
4439 break;
4440 case N_SETD:
4441 symsec = obj_datasec (input_bfd);
4442 break;
4443 case N_SETB:
4444 symsec = obj_bsssec (input_bfd);
4445 break;
4446 case N_SETA:
4447 symsec = bfd_abs_section_ptr;
4448 break;
4449 default:
4450 val = 0;
4451 break;
4452 }
4453 }
4454 else if (hresolve->root.type == bfd_link_hash_defined
4455 || hresolve->root.type == bfd_link_hash_defweak)
4456 {
4457 asection *input_section;
4458 asection *output_section;
4459
4460 /* This case usually means a common symbol which was
4461 turned into a defined symbol. */
4462 input_section = hresolve->root.u.def.section;
4463 output_section = input_section->output_section;
4464 BFD_ASSERT (bfd_is_abs_section (output_section)
4465 || output_section->owner == output_bfd);
4466 val = (hresolve->root.u.def.value
4467 + bfd_get_section_vma (output_bfd, output_section)
4468 + input_section->output_offset);
4469
4470 /* Get the correct type based on the section. If
4471 this is a constructed set, force it to be
4472 globally visible. */
4473 if (type == N_SETT
4474 || type == N_SETD
4475 || type == N_SETB
4476 || type == N_SETA)
4477 type |= N_EXT;
4478
4479 type &=~ N_TYPE;
4480
4481 if (output_section == obj_textsec (output_bfd))
4482 type |= (hresolve->root.type == bfd_link_hash_defined
4483 ? N_TEXT
4484 : N_WEAKT);
4485 else if (output_section == obj_datasec (output_bfd))
4486 type |= (hresolve->root.type == bfd_link_hash_defined
4487 ? N_DATA
4488 : N_WEAKD);
4489 else if (output_section == obj_bsssec (output_bfd))
4490 type |= (hresolve->root.type == bfd_link_hash_defined
4491 ? N_BSS
4492 : N_WEAKB);
4493#if defined(N_IMP1) && defined(N_IMP2)
4494 else if (hresolve->root.u.def.value == VALUE_N_IMP1)
4495 type |= N_IMP1;
4496#endif
4497 else
4498 type |= (hresolve->root.type == bfd_link_hash_defined
4499 ? N_ABS
4500 : N_WEAKA);
4501 }
4502 else if (hresolve->root.type == bfd_link_hash_common)
4503 val = hresolve->root.u.c.size;
4504 else if (hresolve->root.type == bfd_link_hash_undefweak)
4505 {
4506 val = 0;
4507 type = N_WEAKU;
4508 }
4509 else
4510 val = 0;
4511 }
4512 if (symsec != (asection *) NULL)
4513 val = (symsec->output_section->vma
4514 + symsec->output_offset
4515 + (GET_WORD (input_bfd, sym->e_value)
4516 - symsec->vma));
4517
4518 /* If this is a global symbol set the written flag, and if
4519 it is a local symbol see if we should discard it. */
4520 if (h != (struct aout_link_hash_entry *) NULL)
4521 {
4522 h->written = TRUE;
4523 h->indx = obj_aout_external_sym_count (output_bfd);
4524 }
4525 else if ((type & N_TYPE) != N_SETT
4526 && (type & N_TYPE) != N_SETD
4527 && (type & N_TYPE) != N_SETB
4528 && (type & N_TYPE) != N_SETA)
4529 {
4530 switch (discard)
4531 {
4532 case discard_none:
4533 case discard_sec_merge:
4534 break;
4535 case discard_l:
4536 if (!IS_STAB(type)
4537 && bfd_is_local_label_name (input_bfd, name))
4538 skip = TRUE;
4539 break;
4540 case discard_all:
4541 skip = TRUE;
4542 break;
4543 }
4544 if (skip)
4545 {
4546 pass = FALSE;
4547 continue;
4548 }
4549 }
4550
4551 /* An N_BINCL symbol indicates the start of the stabs
4552 entries for a header file. We need to scan ahead to the
4553 next N_EINCL symbol, ignoring nesting, adding up all the
4554 characters in the symbol names, not including the file
4555 numbers in types (the first number after an open
4556 parenthesis). */
4557 if (type == (int) N_BINCL)
4558 {
4559 struct external_nlist *incl_sym;
4560 int nest;
4561 struct aout_link_includes_entry *incl_entry;
4562 struct aout_link_includes_totals *t;
4563
4564 val = 0;
4565 nest = 0;
4566 for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
4567 {
4568 int incl_type;
4569
4570 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
4571 if (incl_type == (int) N_EINCL)
4572 {
4573 if (nest == 0)
4574 break;
4575 --nest;
4576 }
4577 else if (incl_type == (int) N_BINCL)
4578 ++nest;
4579 else if (nest == 0)
4580 {
4581 const char *s;
4582
4583 s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
4584 for (; *s != '\0'; s++)
4585 {
4586 val += *s;
4587 if (*s == '(')
4588 {
4589 /* Skip the file number. */
4590 ++s;
4591 while (ISDIGIT (*s))
4592 ++s;
4593 --s;
4594 }
4595 }
4596 }
4597 }
4598
4599 /* If we have already included a header file with the
4600 same value, then replace this one with an N_EXCL
4601 symbol. */
4602 copy = (bfd_boolean) (! finfo->info->keep_memory);
4603 incl_entry = aout_link_includes_lookup (&finfo->includes,
4604 name, TRUE, copy);
4605 if (incl_entry == NULL)
4606 return FALSE;
4607 for (t = incl_entry->totals; t != NULL; t = t->next)
4608 if (t->total == val)
4609 break;
4610 if (t == NULL)
4611 {
4612 /* This is the first time we have seen this header
4613 file with this set of stabs strings. */
4614 t = ((struct aout_link_includes_totals *)
4615 bfd_hash_allocate (&finfo->includes.root,
4616 sizeof *t));
4617 if (t == NULL)
4618 return FALSE;
4619 t->total = val;
4620 t->next = incl_entry->totals;
4621 incl_entry->totals = t;
4622 }
4623 else
4624 {
4625 int *incl_map;
4626
4627 /* This is a duplicate header file. We must change
4628 it to be an N_EXCL entry, and mark all the
4629 included symbols to prevent outputting them. */
4630 type = (int) N_EXCL;
4631
4632 nest = 0;
4633 for (incl_sym = sym + 1, incl_map = symbol_map + 1;
4634 incl_sym < sym_end;
4635 incl_sym++, incl_map++)
4636 {
4637 int incl_type;
4638
4639 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
4640 if (incl_type == (int) N_EINCL)
4641 {
4642 if (nest == 0)
4643 {
4644 *incl_map = -1;
4645 break;
4646 }
4647 --nest;
4648 }
4649 else if (incl_type == (int) N_BINCL)
4650 ++nest;
4651 else if (nest == 0)
4652 *incl_map = -1;
4653 }
4654 }
4655 }
4656 }
4657
4658 /* Copy this symbol into the list of symbols we are going to
4659 write out. */
4660 H_PUT_8 (output_bfd, type, outsym->e_type);
4661 H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_other), outsym->e_other);
4662 H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc);
4663 copy = FALSE;
4664 if (! finfo->info->keep_memory)
4665 {
4666 /* name points into a string table which we are going to
4667 free. If there is a hash table entry, use that string.
4668 Otherwise, copy name into memory. */
4669 if (h != (struct aout_link_hash_entry *) NULL)
4670 name = h->root.root.string;
4671 else
4672 copy = TRUE;
4673 }
4674 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4675 name, copy);
4676 if (strtab_index == (bfd_size_type) -1)
4677 return FALSE;
4678 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4679 PUT_WORD (output_bfd, val, outsym->e_value);
4680 *symbol_map = obj_aout_external_sym_count (output_bfd);
4681 ++obj_aout_external_sym_count (output_bfd);
4682 ++outsym;
4683 }
4684
4685 /* Write out the output symbols we have just constructed. */
4686 if (outsym > finfo->output_syms)
4687 {
4688 bfd_size_type outsym_size;
4689
4690 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
4691 return FALSE;
4692 outsym_size = outsym - finfo->output_syms;
4693 outsym_size *= EXTERNAL_NLIST_SIZE;
4694 if (bfd_bwrite ((PTR) finfo->output_syms, outsym_size, output_bfd)
4695 != outsym_size)
4696 return FALSE;
4697 finfo->symoff += outsym_size;
4698 }
4699
4700 return TRUE;
4701}
4702
4703/* Write out a symbol that was not associated with an a.out input
4704 object. */
4705
4706static bfd_boolean
4707aout_link_write_other_symbol (h, data)
4708 struct aout_link_hash_entry *h;
4709 PTR data;
4710{
4711 struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
4712 bfd *output_bfd;
4713 int type;
4714 bfd_vma val;
4715 struct external_nlist outsym;
4716 bfd_size_type indx;
4717 bfd_size_type amt;
4718
4719 if (h->root.type == bfd_link_hash_warning)
4720 {
4721 h = (struct aout_link_hash_entry *) h->root.u.i.link;
4722 if (h->root.type == bfd_link_hash_new)
4723 return TRUE;
4724 }
4725
4726 output_bfd = finfo->output_bfd;
4727
4728 if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
4729 {
4730 if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
4731 (output_bfd, finfo->info, h)))
4732 {
4733 /* FIXME: No way to handle errors. */
4734 abort ();
4735 }
4736 }
4737
4738 if (h->written)
4739 return TRUE;
4740
4741 h->written = TRUE;
4742
4743 /* An indx of -2 means the symbol must be written. */
4744 if (h->indx != -2
4745 && (finfo->info->strip == strip_all
4746 || (finfo->info->strip == strip_some
4747 && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
4748 FALSE, FALSE) == NULL)))
4749 return TRUE;
4750
4751 switch (h->root.type)
4752 {
4753 default:
4754 case bfd_link_hash_warning:
4755 abort ();
4756 /* Avoid variable not initialized warnings. */
4757 return TRUE;
4758 case bfd_link_hash_new:
4759 /* This can happen for set symbols when sets are not being
4760 built. */
4761 return TRUE;
4762 case bfd_link_hash_undefined:
4763 type = N_UNDF | N_EXT;
4764 val = 0;
4765 break;
4766 case bfd_link_hash_defined:
4767 case bfd_link_hash_defweak:
4768 {
4769 asection *sec;
4770
4771 sec = h->root.u.def.section->output_section;
4772 BFD_ASSERT (bfd_is_abs_section (sec)
4773 || sec->owner == output_bfd);
4774 if (sec == obj_textsec (output_bfd))
4775 type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
4776 else if (sec == obj_datasec (output_bfd))
4777 type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
4778 else if (sec == obj_bsssec (output_bfd))
4779 type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
4780#if defined(N_IMP1) && defined(N_IMP2)
4781 else if (h->root.u.def.value == VALUE_N_IMP1)
4782 type = N_IMP1;
4783#endif
4784 else
4785 type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
4786 type |= N_EXT;
4787 val = (h->root.u.def.value
4788 + sec->vma
4789 + h->root.u.def.section->output_offset);
4790 }
4791 break;
4792 case bfd_link_hash_common:
4793 type = N_UNDF | N_EXT;
4794 val = h->root.u.c.size;
4795 break;
4796 case bfd_link_hash_undefweak:
4797 type = N_WEAKU;
4798 val = 0;
4799 case bfd_link_hash_indirect:
4800 /* We ignore these symbols, since the indirected symbol is
4801 already in the hash table. */
4802 return TRUE;
4803 }
4804
4805 H_PUT_8 (output_bfd, type, outsym.e_type);
4806 H_PUT_8 (output_bfd, 0, outsym.e_other);
4807 H_PUT_16 (output_bfd, 0, outsym.e_desc);
4808 indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
4809 FALSE);
4810 if (indx == - (bfd_size_type) 1)
4811 {
4812 /* FIXME: No way to handle errors. */
4813 abort ();
4814 }
4815 PUT_WORD (output_bfd, indx, outsym.e_strx);
4816 PUT_WORD (output_bfd, val, outsym.e_value);
4817
4818 amt = EXTERNAL_NLIST_SIZE;
4819 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
4820 || bfd_bwrite ((PTR) &outsym, amt, output_bfd) != amt)
4821 {
4822 /* FIXME: No way to handle errors. */
4823 abort ();
4824 }
4825
4826 finfo->symoff += EXTERNAL_NLIST_SIZE;
4827 h->indx = obj_aout_external_sym_count (output_bfd);
4828 ++obj_aout_external_sym_count (output_bfd);
4829
4830 return TRUE;
4831}
4832
4833/* Link an a.out section into the output file. */
4834
4835static bfd_boolean
4836aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
4837 rel_size)
4838 struct aout_final_link_info *finfo;
4839 bfd *input_bfd;
4840 asection *input_section;
4841 file_ptr *reloff_ptr;
4842 bfd_size_type rel_size;
4843{
4844 bfd_size_type input_size;
4845 PTR relocs;
4846
4847 /* Get the section contents. */
4848 input_size = bfd_section_size (input_bfd, input_section);
4849 if (! bfd_get_section_contents (input_bfd, input_section,
4850 (PTR) finfo->contents,
4851 (file_ptr) 0, input_size))
4852 return FALSE;
4853
4854 /* Read in the relocs if we haven't already done it. */
4855 if (aout_section_data (input_section) != NULL
4856 && aout_section_data (input_section)->relocs != NULL)
4857 relocs = aout_section_data (input_section)->relocs;
4858 else
4859 {
4860 relocs = finfo->relocs;
4861 if (rel_size > 0)
4862 {
4863 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
4864 || bfd_bread (relocs, rel_size, input_bfd) != rel_size)
4865 return FALSE;
4866 }
4867 }
4868
4869 /* Relocate the section contents. */
4870 if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4871 {
4872 if (! aout_link_input_section_std (finfo, input_bfd, input_section,
4873 (struct reloc_std_external *) relocs,
4874 rel_size, finfo->contents))
4875 return FALSE;
4876 }
4877 else
4878 {
4879 if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
4880 (struct reloc_ext_external *) relocs,
4881 rel_size, finfo->contents))
4882 return FALSE;
4883 }
4884
4885 /* Write out the section contents. */
4886 if (! bfd_set_section_contents (finfo->output_bfd,
4887 input_section->output_section,
4888 (PTR) finfo->contents,
4889 (file_ptr) input_section->output_offset,
4890 input_size))
4891 return FALSE;
4892
4893 /* If we are producing relocateable output, the relocs were
4894 modified, and we now write them out. */
4895 if (finfo->info->relocateable && rel_size > 0)
4896 {
4897 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
4898 return FALSE;
4899 if (bfd_bwrite (relocs, rel_size, finfo->output_bfd) != rel_size)
4900 return FALSE;
4901 *reloff_ptr += rel_size;
4902
4903 /* Assert that the relocs have not run into the symbols, and
4904 that if these are the text relocs they have not run into the
4905 data relocs. */
4906 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
4907 && (reloff_ptr != &finfo->treloff
4908 || (*reloff_ptr
4909 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
4910 }
4911
4912 return TRUE;
4913}
4914
4915/* Get the section corresponding to a reloc index. */
4916
4917static INLINE asection *
4918aout_reloc_index_to_section (abfd, indx)
4919 bfd *abfd;
4920 int indx;
4921{
4922 switch (indx & N_TYPE)
4923 {
4924 case N_TEXT:
4925 return obj_textsec (abfd);
4926 case N_DATA:
4927 return obj_datasec (abfd);
4928 case N_BSS:
4929 return obj_bsssec (abfd);
4930 case N_ABS:
4931 case N_UNDF:
4932 return bfd_abs_section_ptr;
4933 default:
4934 abort ();
4935 }
4936 /*NOTREACHED*/
4937 return NULL;
4938}
4939
4940/* Relocate an a.out section using standard a.out relocs. */
4941
4942static bfd_boolean
4943aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
4944 rel_size, contents)
4945 struct aout_final_link_info *finfo;
4946 bfd *input_bfd;
4947 asection *input_section;
4948 struct reloc_std_external *relocs;
4949 bfd_size_type rel_size;
4950 bfd_byte *contents;
4951{
4952 bfd_boolean (*check_dynamic_reloc)
4953 PARAMS ((struct bfd_link_info *, bfd *, asection *,
4954 struct aout_link_hash_entry *, PTR, bfd_byte *, bfd_boolean *,
4955 bfd_vma *));
4956 bfd *output_bfd;
4957 bfd_boolean relocateable;
4958 struct external_nlist *syms;
4959 char *strings;
4960 struct aout_link_hash_entry **sym_hashes;
4961 int *symbol_map;
4962 bfd_size_type reloc_count;
4963 register struct reloc_std_external *rel;
4964 struct reloc_std_external *rel_end;
4965
4966 output_bfd = finfo->output_bfd;
4967 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4968
4969 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
4970 BFD_ASSERT (input_bfd->xvec->header_byteorder
4971 == output_bfd->xvec->header_byteorder);
4972
4973 relocateable = finfo->info->relocateable;
4974 syms = obj_aout_external_syms (input_bfd);
4975 strings = obj_aout_external_strings (input_bfd);
4976 sym_hashes = obj_aout_sym_hashes (input_bfd);
4977 symbol_map = finfo->symbol_map;
4978
4979 reloc_count = rel_size / RELOC_STD_SIZE;
4980 rel = relocs;
4981 rel_end = rel + reloc_count;
4982 for (; rel < rel_end; rel++)
4983 {
4984 bfd_vma r_addr;
4985 int r_index;
4986 int r_extern;
4987 int r_pcrel;
4988 int r_baserel = 0;
4989 reloc_howto_type *howto;
4990 struct aout_link_hash_entry *h = NULL;
4991 bfd_vma relocation;
4992 bfd_reloc_status_type r;
4993
4994 r_addr = GET_SWORD (input_bfd, rel->r_address);
4995
4996#ifdef MY_reloc_howto
4997 howto = MY_reloc_howto (input_bfd, rel, r_index, r_extern, r_pcrel);
4998#else
4999 {
5000 int r_jmptable;
5001 int r_relative;
5002 int r_length;
5003 unsigned int howto_idx;
5004
5005 if (bfd_header_big_endian (input_bfd))
5006 {
5007 r_index = (((unsigned int) rel->r_index[0] << 16)
5008 | ((unsigned int) rel->r_index[1] << 8)
5009 | rel->r_index[2]);
5010 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
5011 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
5012 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
5013 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
5014 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
5015 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
5016 >> RELOC_STD_BITS_LENGTH_SH_BIG);
5017 }
5018 else
5019 {
5020 r_index = (((unsigned int) rel->r_index[2] << 16)
5021 | ((unsigned int) rel->r_index[1] << 8)
5022 | rel->r_index[0]);
5023 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
5024 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
5025 r_baserel = (0 != (rel->r_type[0]
5026 & RELOC_STD_BITS_BASEREL_LITTLE));
5027 r_jmptable= (0 != (rel->r_type[0]
5028 & RELOC_STD_BITS_JMPTABLE_LITTLE));
5029 r_relative= (0 != (rel->r_type[0]
5030 & RELOC_STD_BITS_RELATIVE_LITTLE));
5031 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
5032 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
5033 }
5034
5035 howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
5036 + 16 * r_jmptable + 32 * r_relative);
5037 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
5038 howto = howto_table_std + howto_idx;
5039 }
5040#endif
5041
5042 if (relocateable)
5043 {
5044 /* We are generating a relocateable output file, and must
5045 modify the reloc accordingly. */
5046 if (r_extern)
5047 {
5048 /* If we know the symbol this relocation is against,
5049 convert it into a relocation against a section. This
5050 is what the native linker does. */
5051 h = sym_hashes[r_index];
5052 if (h != (struct aout_link_hash_entry *) NULL
5053#ifdef EMX
5054 /* Don't touch imported symbols */
5055 && (!bfd_is_abs_section (h->root.u.def.section)
5056 || (h->root.u.def.value != (unsigned)-1))
5057#endif
5058 && (h->root.type == bfd_link_hash_defined
5059 || h->root.type == bfd_link_hash_defweak))
5060 {
5061 asection *output_section;
5062
5063 /* Change the r_extern value. */
5064 if (bfd_header_big_endian (output_bfd))
5065 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
5066 else
5067 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
5068
5069 /* Compute a new r_index. */
5070 output_section = h->root.u.def.section->output_section;
5071 if (output_section == obj_textsec (output_bfd))
5072 r_index = N_TEXT;
5073 else if (output_section == obj_datasec (output_bfd))
5074 r_index = N_DATA;
5075 else if (output_section == obj_bsssec (output_bfd))
5076 r_index = N_BSS;
5077 else
5078 r_index = N_ABS;
5079
5080 /* Add the symbol value and the section VMA to the
5081 addend stored in the contents. */
5082 relocation = (h->root.u.def.value
5083 + output_section->vma
5084 + h->root.u.def.section->output_offset);
5085 }
5086 else
5087 {
5088 /* We must change r_index according to the symbol
5089 map. */
5090 r_index = symbol_map[r_index];
5091
5092 if (r_index == -1)
5093 {
5094 if (h != NULL)
5095 {
5096 /* We decided to strip this symbol, but it
5097 turns out that we can't. Note that we
5098 lose the other and desc information here.
5099 I don't think that will ever matter for a
5100 global symbol. */
5101 if (h->indx < 0)
5102 {
5103 h->indx = -2;
5104 h->written = FALSE;
5105 if (! aout_link_write_other_symbol (h,
5106 (PTR) finfo))
5107 return FALSE;
5108 }
5109 r_index = h->indx;
5110 }
5111 else
5112 {
5113 const char *name;
5114
5115 name = strings + GET_WORD (input_bfd,
5116 syms[r_index].e_strx);
5117 if (! ((*finfo->info->callbacks->unattached_reloc)
5118 (finfo->info, name, input_bfd, input_section,
5119 r_addr)))
5120 return FALSE;
5121 r_index = 0;
5122 }
5123 }
5124
5125 relocation = 0;
5126 }
5127
5128 /* Write out the new r_index value. */
5129 if (bfd_header_big_endian (output_bfd))
5130 {
5131 rel->r_index[0] = r_index >> 16;
5132 rel->r_index[1] = r_index >> 8;
5133 rel->r_index[2] = r_index;
5134 }
5135 else
5136 {
5137 rel->r_index[2] = r_index >> 16;
5138 rel->r_index[1] = r_index >> 8;
5139 rel->r_index[0] = r_index;
5140 }
5141 }
5142 else
5143 {
5144 asection *section;
5145
5146 /* This is a relocation against a section. We must
5147 adjust by the amount that the section moved. */
5148 section = aout_reloc_index_to_section (input_bfd, r_index);
5149 relocation = (section->output_section->vma
5150 + section->output_offset
5151 - section->vma);
5152 }
5153
5154 /* Change the address of the relocation. */
5155 PUT_WORD (output_bfd,
5156 r_addr + input_section->output_offset,
5157 rel->r_address);
5158
5159 /* Adjust a PC relative relocation by removing the reference
5160 to the original address in the section and including the
5161 reference to the new address. */
5162 if (r_pcrel)
5163 relocation -= (input_section->output_section->vma
5164 + input_section->output_offset
5165 - input_section->vma);
5166
5167#ifdef MY_relocatable_reloc
5168 MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
5169#endif
5170
5171 if (relocation == 0)
5172 r = bfd_reloc_ok;
5173 else
5174 r = MY_relocate_contents (howto,
5175 input_bfd, relocation,
5176 contents + r_addr);
5177 }
5178 else
5179 {
5180 bfd_boolean hundef;
5181
5182 /* We are generating an executable, and must do a full
5183 relocation. */
5184 hundef = FALSE;
5185
5186 if (r_extern)
5187 {
5188 h = sym_hashes[r_index];
5189
5190 if (h != (struct aout_link_hash_entry *) NULL
5191 && (h->root.type == bfd_link_hash_defined
5192 || h->root.type == bfd_link_hash_defweak))
5193 {
5194 relocation = (h->root.u.def.value
5195 + h->root.u.def.section->output_section->vma
5196 + h->root.u.def.section->output_offset);
5197 }
5198 else if (h != (struct aout_link_hash_entry *) NULL
5199 && h->root.type == bfd_link_hash_undefweak)
5200 relocation = 0;
5201 else
5202 {
5203 hundef = TRUE;
5204 relocation = 0;
5205 }
5206 }
5207 else
5208 {
5209 asection *section;
5210
5211 section = aout_reloc_index_to_section (input_bfd, r_index);
5212 relocation = (section->output_section->vma
5213 + section->output_offset
5214 - section->vma);
5215 if (r_pcrel)
5216 relocation += input_section->vma;
5217 }
5218
5219 if (check_dynamic_reloc != NULL)
5220 {
5221 bfd_boolean skip;
5222
5223 if (! ((*check_dynamic_reloc)
5224 (finfo->info, input_bfd, input_section, h,
5225 (PTR) rel, contents, &skip, &relocation)))
5226 return FALSE;
5227 if (skip)
5228 continue;
5229 }
5230
5231 /* Now warn if a global symbol is undefined. We could not
5232 do this earlier, because check_dynamic_reloc might want
5233 to skip this reloc. */
5234 if (hundef && ! finfo->info->shared && ! r_baserel)
5235 {
5236 const char *name;
5237
5238 if (h != NULL)
5239 name = h->root.root.string;
5240 else
5241 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5242 if (! ((*finfo->info->callbacks->undefined_symbol)
5243 (finfo->info, name, input_bfd, input_section,
5244 r_addr, TRUE)))
5245 return FALSE;
5246 }
5247
5248 r = MY_final_link_relocate (howto,
5249 input_bfd, input_section,
5250 contents, r_addr, relocation,
5251 (bfd_vma) 0);
5252 }
5253
5254 if (r != bfd_reloc_ok)
5255 {
5256 switch (r)
5257 {
5258 default:
5259 case bfd_reloc_outofrange:
5260 abort ();
5261 case bfd_reloc_overflow:
5262 {
5263 const char *name;
5264
5265 if (h != NULL)
5266 name = h->root.root.string;
5267 else if (r_extern)
5268 name = strings + GET_WORD (input_bfd,
5269 syms[r_index].e_strx);
5270 else
5271 {
5272 asection *s;
5273
5274 s = aout_reloc_index_to_section (input_bfd, r_index);
5275 name = bfd_section_name (input_bfd, s);
5276 }
5277 if (! ((*finfo->info->callbacks->reloc_overflow)
5278 (finfo->info, name, howto->name,
5279 (bfd_vma) 0, input_bfd, input_section, r_addr)))
5280 return FALSE;
5281 }
5282 break;
5283 }
5284 }
5285 }
5286
5287 return TRUE;
5288}
5289
5290/* Relocate an a.out section using extended a.out relocs. */
5291
5292static bfd_boolean
5293aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
5294 rel_size, contents)
5295 struct aout_final_link_info *finfo;
5296 bfd *input_bfd;
5297 asection *input_section;
5298 struct reloc_ext_external *relocs;
5299 bfd_size_type rel_size;
5300 bfd_byte *contents;
5301{
5302 bfd_boolean (*check_dynamic_reloc)
5303 PARAMS ((struct bfd_link_info *, bfd *, asection *,
5304 struct aout_link_hash_entry *, PTR, bfd_byte *, bfd_boolean *,
5305 bfd_vma *));
5306 bfd *output_bfd;
5307 bfd_boolean relocateable;
5308 struct external_nlist *syms;
5309 char *strings;
5310 struct aout_link_hash_entry **sym_hashes;
5311 int *symbol_map;
5312 bfd_size_type reloc_count;
5313 register struct reloc_ext_external *rel;
5314 struct reloc_ext_external *rel_end;
5315
5316 output_bfd = finfo->output_bfd;
5317 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
5318
5319 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
5320 BFD_ASSERT (input_bfd->xvec->header_byteorder
5321 == output_bfd->xvec->header_byteorder);
5322
5323 relocateable = finfo->info->relocateable;
5324 syms = obj_aout_external_syms (input_bfd);
5325 strings = obj_aout_external_strings (input_bfd);
5326 sym_hashes = obj_aout_sym_hashes (input_bfd);
5327 symbol_map = finfo->symbol_map;
5328
5329 reloc_count = rel_size / RELOC_EXT_SIZE;
5330 rel = relocs;
5331 rel_end = rel + reloc_count;
5332 for (; rel < rel_end; rel++)
5333 {
5334 bfd_vma r_addr;
5335 int r_index;
5336 int r_extern;
5337 unsigned int r_type;
5338 bfd_vma r_addend;
5339 struct aout_link_hash_entry *h = NULL;
5340 asection *r_section = NULL;
5341 bfd_vma relocation;
5342
5343 r_addr = GET_SWORD (input_bfd, rel->r_address);
5344
5345 if (bfd_header_big_endian (input_bfd))
5346 {
5347 r_index = (((unsigned int) rel->r_index[0] << 16)
5348 | ((unsigned int) rel->r_index[1] << 8)
5349 | rel->r_index[2]);
5350 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
5351 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
5352 >> RELOC_EXT_BITS_TYPE_SH_BIG);
5353 }
5354 else
5355 {
5356 r_index = (((unsigned int) rel->r_index[2] << 16)
5357 | ((unsigned int) rel->r_index[1] << 8)
5358 | rel->r_index[0]);
5359 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
5360 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
5361 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
5362 }
5363
5364 r_addend = GET_SWORD (input_bfd, rel->r_addend);
5365
5366 BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
5367
5368 if (relocateable)
5369 {
5370 /* We are generating a relocateable output file, and must
5371 modify the reloc accordingly. */
5372 if (r_extern
5373 || r_type == (unsigned int) RELOC_BASE10
5374 || r_type == (unsigned int) RELOC_BASE13
5375 || r_type == (unsigned int) RELOC_BASE22)
5376 {
5377 /* If we know the symbol this relocation is against,
5378 convert it into a relocation against a section. This
5379 is what the native linker does. */
5380 if (r_type == (unsigned int) RELOC_BASE10
5381 || r_type == (unsigned int) RELOC_BASE13
5382 || r_type == (unsigned int) RELOC_BASE22)
5383 h = NULL;
5384 else
5385 h = sym_hashes[r_index];
5386 if (h != (struct aout_link_hash_entry *) NULL
5387 && (h->root.type == bfd_link_hash_defined
5388 || h->root.type == bfd_link_hash_defweak))
5389 {
5390 asection *output_section;
5391
5392 /* Change the r_extern value. */
5393 if (bfd_header_big_endian (output_bfd))
5394 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
5395 else
5396 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
5397
5398 /* Compute a new r_index. */
5399 output_section = h->root.u.def.section->output_section;
5400 if (output_section == obj_textsec (output_bfd))
5401 r_index = N_TEXT;
5402 else if (output_section == obj_datasec (output_bfd))
5403 r_index = N_DATA;
5404 else if (output_section == obj_bsssec (output_bfd))
5405 r_index = N_BSS;
5406 else
5407 r_index = N_ABS;
5408
5409 /* Add the symbol value and the section VMA to the
5410 addend. */
5411 relocation = (h->root.u.def.value
5412 + output_section->vma
5413 + h->root.u.def.section->output_offset);
5414
5415 /* Now RELOCATION is the VMA of the final
5416 destination. If this is a PC relative reloc,
5417 then ADDEND is the negative of the source VMA.
5418 We want to set ADDEND to the difference between
5419 the destination VMA and the source VMA, which
5420 means we must adjust RELOCATION by the change in
5421 the source VMA. This is done below. */
5422 }
5423 else
5424 {
5425 /* We must change r_index according to the symbol
5426 map. */
5427 r_index = symbol_map[r_index];
5428
5429 if (r_index == -1)
5430 {
5431 if (h != NULL)
5432 {
5433 /* We decided to strip this symbol, but it
5434 turns out that we can't. Note that we
5435 lose the other and desc information here.
5436 I don't think that will ever matter for a
5437 global symbol. */
5438 if (h->indx < 0)
5439 {
5440 h->indx = -2;
5441 h->written = FALSE;
5442 if (! aout_link_write_other_symbol (h,
5443 (PTR) finfo))
5444 return FALSE;
5445 }
5446 r_index = h->indx;
5447 }
5448 else
5449 {
5450 const char *name;
5451
5452 name = strings + GET_WORD (input_bfd,
5453 syms[r_index].e_strx);
5454 if (! ((*finfo->info->callbacks->unattached_reloc)
5455 (finfo->info, name, input_bfd, input_section,
5456 r_addr)))
5457 return FALSE;
5458 r_index = 0;
5459 }
5460 }
5461
5462 relocation = 0;
5463
5464 /* If this is a PC relative reloc, then the addend
5465 is the negative of the source VMA. We must
5466 adjust it by the change in the source VMA. This
5467 is done below. */
5468 }
5469
5470 /* Write out the new r_index value. */
5471 if (bfd_header_big_endian (output_bfd))
5472 {
5473 rel->r_index[0] = r_index >> 16;
5474 rel->r_index[1] = r_index >> 8;
5475 rel->r_index[2] = r_index;
5476 }
5477 else
5478 {
5479 rel->r_index[2] = r_index >> 16;
5480 rel->r_index[1] = r_index >> 8;
5481 rel->r_index[0] = r_index;
5482 }
5483 }
5484 else
5485 {
5486 /* This is a relocation against a section. We must
5487 adjust by the amount that the section moved. */
5488 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5489 relocation = (r_section->output_section->vma
5490 + r_section->output_offset
5491 - r_section->vma);
5492
5493 /* If this is a PC relative reloc, then the addend is
5494 the difference in VMA between the destination and the
5495 source. We have just adjusted for the change in VMA
5496 of the destination, so we must also adjust by the
5497 change in VMA of the source. This is done below. */
5498 }
5499
5500 /* As described above, we must always adjust a PC relative
5501 reloc by the change in VMA of the source. However, if
5502 pcrel_offset is set, then the addend does not include the
5503 location within the section, in which case we don't need
5504 to adjust anything. */
5505 if (howto_table_ext[r_type].pc_relative
5506 && ! howto_table_ext[r_type].pcrel_offset)
5507 relocation -= (input_section->output_section->vma
5508 + input_section->output_offset
5509 - input_section->vma);
5510
5511 /* Change the addend if necessary. */
5512 if (relocation != 0)
5513 PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
5514
5515 /* Change the address of the relocation. */
5516 PUT_WORD (output_bfd,
5517 r_addr + input_section->output_offset,
5518 rel->r_address);
5519 }
5520 else
5521 {
5522 bfd_boolean hundef;
5523 bfd_reloc_status_type r;
5524
5525 /* We are generating an executable, and must do a full
5526 relocation. */
5527 hundef = FALSE;
5528
5529 if (r_extern)
5530 {
5531 h = sym_hashes[r_index];
5532
5533 if (h != (struct aout_link_hash_entry *) NULL
5534 && (h->root.type == bfd_link_hash_defined
5535 || h->root.type == bfd_link_hash_defweak))
5536 {
5537 relocation = (h->root.u.def.value
5538 + h->root.u.def.section->output_section->vma
5539 + h->root.u.def.section->output_offset);
5540 }
5541 else if (h != (struct aout_link_hash_entry *) NULL
5542 && h->root.type == bfd_link_hash_undefweak)
5543 relocation = 0;
5544 else
5545 {
5546 hundef = TRUE;
5547 relocation = 0;
5548 }
5549 }
5550 else if (r_type == (unsigned int) RELOC_BASE10
5551 || r_type == (unsigned int) RELOC_BASE13
5552 || r_type == (unsigned int) RELOC_BASE22)
5553 {
5554 struct external_nlist *sym;
5555 int type;
5556
5557 /* For base relative relocs, r_index is always an index
5558 into the symbol table, even if r_extern is 0. */
5559 sym = syms + r_index;
5560 type = H_GET_8 (input_bfd, sym->e_type);
5561 if ((type & N_TYPE) == N_TEXT
5562 || type == N_WEAKT)
5563 r_section = obj_textsec (input_bfd);
5564 else if ((type & N_TYPE) == N_DATA
5565 || type == N_WEAKD)
5566 r_section = obj_datasec (input_bfd);
5567 else if ((type & N_TYPE) == N_BSS
5568 || type == N_WEAKB)
5569 r_section = obj_bsssec (input_bfd);
5570 else if ((type & N_TYPE) == N_ABS
5571 || type == N_WEAKA)
5572 r_section = bfd_abs_section_ptr;
5573 else
5574 abort ();
5575 relocation = (r_section->output_section->vma
5576 + r_section->output_offset
5577 + (GET_WORD (input_bfd, sym->e_value)
5578 - r_section->vma));
5579 }
5580 else
5581 {
5582 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5583
5584 /* If this is a PC relative reloc, then R_ADDEND is the
5585 difference between the two vmas, or
5586 old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
5587 where
5588 old_dest_sec == section->vma
5589 and
5590 old_src_sec == input_section->vma
5591 and
5592 old_src_off == r_addr
5593
5594 _bfd_final_link_relocate expects RELOCATION +
5595 R_ADDEND to be the VMA of the destination minus
5596 r_addr (the minus r_addr is because this relocation
5597 is not pcrel_offset, which is a bit confusing and
5598 should, perhaps, be changed), or
5599 new_dest_sec
5600 where
5601 new_dest_sec == output_section->vma + output_offset
5602 We arrange for this to happen by setting RELOCATION to
5603 new_dest_sec + old_src_sec - old_dest_sec
5604
5605 If this is not a PC relative reloc, then R_ADDEND is
5606 simply the VMA of the destination, so we set
5607 RELOCATION to the change in the destination VMA, or
5608 new_dest_sec - old_dest_sec
5609 */
5610 relocation = (r_section->output_section->vma
5611 + r_section->output_offset
5612 - r_section->vma);
5613 if (howto_table_ext[r_type].pc_relative)
5614 relocation += input_section->vma;
5615 }
5616
5617 if (check_dynamic_reloc != NULL)
5618 {
5619 bfd_boolean skip;
5620
5621 if (! ((*check_dynamic_reloc)
5622 (finfo->info, input_bfd, input_section, h,
5623 (PTR) rel, contents, &skip, &relocation)))
5624 return FALSE;
5625 if (skip)
5626 continue;
5627 }
5628
5629 /* Now warn if a global symbol is undefined. We could not
5630 do this earlier, because check_dynamic_reloc might want
5631 to skip this reloc. */
5632 if (hundef
5633 && ! finfo->info->shared
5634 && r_type != (unsigned int) RELOC_BASE10
5635 && r_type != (unsigned int) RELOC_BASE13
5636 && r_type != (unsigned int) RELOC_BASE22)
5637 {
5638 const char *name;
5639
5640 if (h != NULL)
5641 name = h->root.root.string;
5642 else
5643 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5644 if (! ((*finfo->info->callbacks->undefined_symbol)
5645 (finfo->info, name, input_bfd, input_section,
5646 r_addr, TRUE)))
5647 return FALSE;
5648 }
5649
5650 if (r_type != (unsigned int) RELOC_SPARC_REV32)
5651 r = MY_final_link_relocate (howto_table_ext + r_type,
5652 input_bfd, input_section,
5653 contents, r_addr, relocation,
5654 r_addend);
5655 else
5656 {
5657 bfd_vma x;
5658
5659 x = bfd_get_32 (input_bfd, contents + r_addr);
5660 x = x + relocation + r_addend;
5661 bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
5662 r = bfd_reloc_ok;
5663 }
5664
5665 if (r != bfd_reloc_ok)
5666 {
5667 switch (r)
5668 {
5669 default:
5670 case bfd_reloc_outofrange:
5671 abort ();
5672 case bfd_reloc_overflow:
5673 {
5674 const char *name;
5675
5676 if (h != NULL)
5677 name = h->root.root.string;
5678 else if (r_extern
5679 || r_type == (unsigned int) RELOC_BASE10
5680 || r_type == (unsigned int) RELOC_BASE13
5681 || r_type == (unsigned int) RELOC_BASE22)
5682 name = strings + GET_WORD (input_bfd,
5683 syms[r_index].e_strx);
5684 else
5685 {
5686 asection *s;
5687
5688 s = aout_reloc_index_to_section (input_bfd, r_index);
5689 name = bfd_section_name (input_bfd, s);
5690 }
5691 if (! ((*finfo->info->callbacks->reloc_overflow)
5692 (finfo->info, name, howto_table_ext[r_type].name,
5693 r_addend, input_bfd, input_section, r_addr)))
5694 return FALSE;
5695 }
5696 break;
5697 }
5698 }
5699 }
5700 }
5701
5702 return TRUE;
5703}
5704
5705/* Handle a link order which is supposed to generate a reloc. */
5706
5707static bfd_boolean
5708aout_link_reloc_link_order (finfo, o, p)
5709 struct aout_final_link_info *finfo;
5710 asection *o;
5711 struct bfd_link_order *p;
5712{
5713 struct bfd_link_order_reloc *pr;
5714 int r_index;
5715 int r_extern;
5716 reloc_howto_type *howto;
5717 file_ptr *reloff_ptr = NULL;
5718 struct reloc_std_external srel;
5719 struct reloc_ext_external erel;
5720 PTR rel_ptr;
5721 bfd_size_type amt;
5722
5723 pr = p->u.reloc.p;
5724
5725 if (p->type == bfd_section_reloc_link_order)
5726 {
5727 r_extern = 0;
5728 if (bfd_is_abs_section (pr->u.section))
5729 r_index = N_ABS | N_EXT;
5730 else
5731 {
5732 BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
5733 r_index = pr->u.section->target_index;
5734 }
5735 }
5736 else
5737 {
5738 struct aout_link_hash_entry *h;
5739
5740 BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
5741 r_extern = 1;
5742 h = ((struct aout_link_hash_entry *)
5743 bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
5744 pr->u.name, FALSE, FALSE, TRUE));
5745 if (h != (struct aout_link_hash_entry *) NULL
5746 && h->indx >= 0)
5747 r_index = h->indx;
5748 else if (h != NULL)
5749 {
5750 /* We decided to strip this symbol, but it turns out that we
5751 can't. Note that we lose the other and desc information
5752 here. I don't think that will ever matter for a global
5753 symbol. */
5754 h->indx = -2;
5755 h->written = FALSE;
5756 if (! aout_link_write_other_symbol (h, (PTR) finfo))
5757 return FALSE;
5758 r_index = h->indx;
5759 }
5760 else
5761 {
5762 if (! ((*finfo->info->callbacks->unattached_reloc)
5763 (finfo->info, pr->u.name, (bfd *) NULL,
5764 (asection *) NULL, (bfd_vma) 0)))
5765 return FALSE;
5766 r_index = 0;
5767 }
5768 }
5769
5770 howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
5771 if (howto == 0)
5772 {
5773 bfd_set_error (bfd_error_bad_value);
5774 return FALSE;
5775 }
5776
5777 if (o == obj_textsec (finfo->output_bfd))
5778 reloff_ptr = &finfo->treloff;
5779 else if (o == obj_datasec (finfo->output_bfd))
5780 reloff_ptr = &finfo->dreloff;
5781 else
5782 abort ();
5783
5784 if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
5785 {
5786#ifdef MY_put_reloc
5787 MY_put_reloc (finfo->output_bfd, r_extern, r_index, p->offset, howto,
5788 &srel);
5789#else
5790 {
5791 int r_pcrel;
5792 int r_baserel;
5793 int r_jmptable;
5794 int r_relative;
5795 int r_length;
5796
5797 r_pcrel = (int) howto->pc_relative;
5798 r_baserel = (howto->type & 8) != 0;
5799 r_jmptable = (howto->type & 16) != 0;
5800 r_relative = (howto->type & 32) != 0;
5801 r_length = howto->size;
5802
5803 PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
5804 if (bfd_header_big_endian (finfo->output_bfd))
5805 {
5806 srel.r_index[0] = r_index >> 16;
5807 srel.r_index[1] = r_index >> 8;
5808 srel.r_index[2] = r_index;
5809 srel.r_type[0] =
5810 ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
5811 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
5812 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
5813 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
5814 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
5815 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
5816 }
5817 else
5818 {
5819 srel.r_index[2] = r_index >> 16;
5820 srel.r_index[1] = r_index >> 8;
5821 srel.r_index[0] = r_index;
5822 srel.r_type[0] =
5823 ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
5824 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
5825 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
5826 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
5827 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
5828 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
5829 }
5830 }
5831#endif
5832 rel_ptr = (PTR) &srel;
5833
5834 /* We have to write the addend into the object file, since
5835 standard a.out relocs are in place. It would be more
5836 reliable if we had the current contents of the file here,
5837 rather than assuming zeroes, but we can't read the file since
5838 it was opened using bfd_openw. */
5839 if (pr->addend != 0)
5840 {
5841 bfd_size_type size;
5842 bfd_reloc_status_type r;
5843 bfd_byte *buf;
5844 bfd_boolean ok;
5845
5846 size = bfd_get_reloc_size (howto);
5847 buf = (bfd_byte *) bfd_zmalloc (size);
5848 if (buf == (bfd_byte *) NULL)
5849 return FALSE;
5850 r = MY_relocate_contents (howto, finfo->output_bfd,
5851 (bfd_vma) pr->addend, buf);
5852 switch (r)
5853 {
5854 case bfd_reloc_ok:
5855 break;
5856 default:
5857 case bfd_reloc_outofrange:
5858 abort ();
5859 case bfd_reloc_overflow:
5860 if (! ((*finfo->info->callbacks->reloc_overflow)
5861 (finfo->info,
5862 (p->type == bfd_section_reloc_link_order
5863 ? bfd_section_name (finfo->output_bfd,
5864 pr->u.section)
5865 : pr->u.name),
5866 howto->name, pr->addend, (bfd *) NULL,
5867 (asection *) NULL, (bfd_vma) 0)))
5868 {
5869 free (buf);
5870 return FALSE;
5871 }
5872 break;
5873 }
5874 ok = bfd_set_section_contents (finfo->output_bfd, o, (PTR) buf,
5875 (file_ptr) p->offset, size);
5876 free (buf);
5877 if (! ok)
5878 return FALSE;
5879 }
5880 }
5881 else
5882 {
5883#ifdef MY_put_ext_reloc
5884 MY_put_ext_reloc (finfo->output_bfd, r_extern, r_index, p->offset,
5885 howto, &erel, pr->addend);
5886#else
5887 PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
5888
5889 if (bfd_header_big_endian (finfo->output_bfd))
5890 {
5891 erel.r_index[0] = r_index >> 16;
5892 erel.r_index[1] = r_index >> 8;
5893 erel.r_index[2] = r_index;
5894 erel.r_type[0] =
5895 ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
5896 | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
5897 }
5898 else
5899 {
5900 erel.r_index[2] = r_index >> 16;
5901 erel.r_index[1] = r_index >> 8;
5902 erel.r_index[0] = r_index;
5903 erel.r_type[0] =
5904 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
5905 | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
5906 }
5907
5908 PUT_WORD (finfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend);
5909#endif /* MY_put_ext_reloc */
5910
5911 rel_ptr = (PTR) &erel;
5912 }
5913
5914 amt = obj_reloc_entry_size (finfo->output_bfd);
5915 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
5916 || bfd_bwrite (rel_ptr, amt, finfo->output_bfd) != amt)
5917 return FALSE;
5918
5919 *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
5920
5921 /* Assert that the relocs have not run into the symbols, and that n
5922 the text relocs have not run into the data relocs. */
5923 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
5924 && (reloff_ptr != &finfo->treloff
5925 || (*reloff_ptr
5926 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
5927
5928 return TRUE;
5929}
Note: See TracBrowser for help on using the repository browser.