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