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