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