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