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