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