59137a00f6c1ea68f184dae5fbe063cf7075f64b
[deliverable/binutils-gdb.git] / bfd / aoutx.h
1 /* BFD semi-generic back-end for a.out binaries.
2 Copyright 1990, 1991, 1992, 1993 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 ARCH 32
69 | #define TARGET_NAME "a.out-sunos-big"
70 | #define VECNAME sunos_big_vec
71 | #include "aoutf1.h"
72
73 requires all the names from @file{aout32.c}, and produces the jump vector
74
75 | sunos_big_vec
76
77 The file @file{host-aout.c} is a special case. It is for a large set
78 of hosts that use ``more or less standard'' a.out files, and
79 for which cross-debugging is not interesting. It uses the
80 standard 32-bit a.out support routines, but determines the
81 file offsets and addresses of the text, data, and BSS
82 sections, the machine architecture and machine type, and the
83 entry point address, in a host-dependent manner. Once these
84 values have been determined, generic code is used to handle
85 the object file.
86
87 When porting it to run on a new system, you must supply:
88
89 | HOST_PAGE_SIZE
90 | HOST_SEGMENT_SIZE
91 | HOST_MACHINE_ARCH (optional)
92 | HOST_MACHINE_MACHINE (optional)
93 | HOST_TEXT_START_ADDR
94 | HOST_STACK_END_ADDR
95
96 in the file @file{../include/sys/h-@var{XXX}.h} (for your host). These
97 values, plus the structures and macros defined in @file{a.out.h} on
98 your host system, will produce a BFD target that will access
99 ordinary a.out files on your host. To configure a new machine
100 to use @file{host-aout.c}, specify:
101
102 | TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
103 | TDEPFILES= host-aout.o trad-core.o
104
105 in the @file{config/@var{XXX}.mt} file, and modify @file{configure.in}
106 to use the
107 @file{@var{XXX}.mt} file (by setting "<<bfd_target=XXX>>") when your
108 configuration is selected.
109
110 */
111
112 /* Some assumptions:
113 * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
114 Doesn't matter what the setting of WP_TEXT is on output, but it'll
115 get set on input.
116 * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
117 * Any BFD with both flags clear is OMAGIC.
118 (Just want to make these explicit, so the conditions tested in this
119 file make sense if you're more familiar with a.out than with BFD.) */
120
121 #define KEEPIT flags
122 #define KEEPITTYPE int
123
124 #include <assert.h>
125 #include <string.h> /* For strchr and friends */
126 #include "bfd.h"
127 #include <sysdep.h>
128 #include <ansidecl.h>
129 #include "bfdlink.h"
130
131 #include "libaout.h"
132 #include "libbfd.h"
133 #include "aout/aout64.h"
134 #include "aout/stab_gnu.h"
135 #include "aout/ar.h"
136
137 /*
138 SUBSECTION
139 Relocations
140
141 DESCRIPTION
142 The file @file{aoutx.h} provides for both the @emph{standard}
143 and @emph{extended} forms of a.out relocation records.
144
145 The standard records contain only an
146 address, a symbol index, and a type field. The extended records
147 (used on 29ks and sparcs) also have a full integer for an
148 addend.
149
150 */
151 #define CTOR_TABLE_RELOC_IDX 2
152
153 #define howto_table_ext NAME(aout,ext_howto_table)
154 #define howto_table_std NAME(aout,std_howto_table)
155
156 reloc_howto_type howto_table_ext[] =
157 {
158 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
159 HOWTO(RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", false, 0,0x000000ff, false),
160 HOWTO(RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", false, 0,0x0000ffff, false),
161 HOWTO(RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", false, 0,0xffffffff, false),
162 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, complain_overflow_signed,0,"DISP8", false, 0,0x000000ff, false),
163 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, complain_overflow_signed,0,"DISP16", false, 0,0x0000ffff, false),
164 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, complain_overflow_signed,0,"DISP32", false, 0,0xffffffff, false),
165 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, complain_overflow_signed,0,"WDISP30", false, 0,0x3fffffff, false),
166 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, complain_overflow_signed,0,"WDISP22", false, 0,0x003fffff, false),
167 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"HI22", false, 0,0x003fffff, false),
168 HOWTO(RELOC_22, 0, 2, 22, false, 0, complain_overflow_bitfield,0,"22", false, 0,0x003fffff, false),
169 HOWTO(RELOC_13, 0, 2, 13, false, 0, complain_overflow_bitfield,0,"13", false, 0,0x00001fff, false),
170 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, complain_overflow_dont,0,"LO10", false, 0,0x000003ff, false),
171 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, complain_overflow_bitfield,0,"SFA_BASE", false, 0,0xffffffff, false),
172 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, complain_overflow_bitfield,0,"SFA_OFF13",false, 0,0xffffffff, false),
173 HOWTO(RELOC_BASE10, 0, 2, 16, false, 0, complain_overflow_bitfield,0,"BASE10", false, 0,0x0000ffff, false),
174 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, complain_overflow_bitfield,0,"BASE13", false, 0,0x00001fff, false),
175 HOWTO(RELOC_BASE22, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"BASE22", false, 0,0x00000000, false),
176 HOWTO(RELOC_PC10, 0, 2, 10, false, 0, complain_overflow_bitfield,0,"PC10", false, 0,0x000003ff, false),
177 HOWTO(RELOC_PC22, 0, 2, 22, false, 0, complain_overflow_bitfield,0,"PC22", false, 0,0x003fffff, false),
178 HOWTO(RELOC_JMP_TBL,0, 2, 32, false, 0, complain_overflow_bitfield,0,"JMP_TBL", false, 0,0xffffffff, false),
179 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, complain_overflow_bitfield,0,"SEGOFF16", false, 0,0x00000000, false),
180 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"GLOB_DAT", false, 0,0x00000000, false),
181 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_SLOT", false, 0,0x00000000, false),
182 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false),
183 };
184
185 /* Convert standard reloc records to "arelent" format (incl byte swap). */
186
187 reloc_howto_type howto_table_std[] = {
188 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
189 HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false),
190 HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false),
191 HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false),
192 HOWTO( 3, 0, 4, 64, false, 0, complain_overflow_bitfield,0,"64", true, 0xdeaddead,0xdeaddead, false),
193 HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, false),
194 HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
195 HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, false),
196 HOWTO( 7, 0, 4, 64, true, 0, complain_overflow_signed, 0,"DISP64", true, 0xfeedface,0xfeedface, false),
197 { -1 },
198 HOWTO( 9, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"BASE16", false,0xffffffff,0xffffffff, false),
199 HOWTO(10, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"BASE32", false,0xffffffff,0xffffffff, false),
200 };
201
202 #define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0]))
203
204 CONST struct reloc_howto_struct *
205 DEFUN(NAME(aout,reloc_type_lookup),(abfd,code),
206 bfd *abfd AND
207 bfd_reloc_code_real_type code)
208 {
209 #define EXT(i,j) case i: return &howto_table_ext[j]
210 #define STD(i,j) case i: return &howto_table_std[j]
211 int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
212 if (code == BFD_RELOC_CTOR)
213 switch (bfd_get_arch_info (abfd)->bits_per_address)
214 {
215 case 32:
216 code = BFD_RELOC_32;
217 break;
218 }
219 if (ext)
220 switch (code)
221 {
222 EXT (BFD_RELOC_32, 2);
223 EXT (BFD_RELOC_HI22, 8);
224 EXT (BFD_RELOC_LO10, 11);
225 EXT (BFD_RELOC_32_PCREL_S2, 6);
226 EXT (BFD_RELOC_SPARC_WDISP22, 7);
227 default: return (CONST struct reloc_howto_struct *) 0;
228 }
229 else
230 /* std relocs */
231 switch (code)
232 {
233 STD (BFD_RELOC_16, 1);
234 STD (BFD_RELOC_32, 2);
235 STD (BFD_RELOC_8_PCREL, 4);
236 STD (BFD_RELOC_16_PCREL, 5);
237 STD (BFD_RELOC_32_PCREL, 6);
238 STD (BFD_RELOC_16_BASEREL, 9);
239 STD (BFD_RELOC_32_BASEREL, 10);
240 default: return (CONST struct reloc_howto_struct *) 0;
241 }
242 }
243
244 /*
245 SUBSECTION
246 Internal entry points
247
248 DESCRIPTION
249 @file{aoutx.h} exports several routines for accessing the
250 contents of an a.out file, which are gathered and exported in
251 turn by various format specific files (eg sunos.c).
252
253 */
254
255 /*
256 FUNCTION
257 aout_@var{size}_swap_exec_header_in
258
259 SYNOPSIS
260 void aout_@var{size}_swap_exec_header_in,
261 (bfd *abfd,
262 struct external_exec *raw_bytes,
263 struct internal_exec *execp);
264
265 DESCRIPTION
266 Swap the information in an executable header @var{raw_bytes} taken
267 from a raw byte stream memory image into the internal exec header
268 structure @var{execp}.
269 */
270
271 #ifndef NAME_swap_exec_header_in
272 void
273 DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
274 bfd *abfd AND
275 struct external_exec *raw_bytes AND
276 struct internal_exec *execp)
277 {
278 struct external_exec *bytes = (struct external_exec *)raw_bytes;
279
280 /* The internal_exec structure has some fields that are unused in this
281 configuration (IE for i960), so ensure that all such uninitialized
282 fields are zero'd out. There are places where two of these structs
283 are memcmp'd, and thus the contents do matter. */
284 memset (execp, 0, sizeof (struct internal_exec));
285 /* Now fill in fields in the execp, from the bytes in the raw data. */
286 execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
287 execp->a_text = GET_WORD (abfd, bytes->e_text);
288 execp->a_data = GET_WORD (abfd, bytes->e_data);
289 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
290 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
291 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
292 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
293 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
294 }
295 #define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
296 #endif
297
298 /*
299 FUNCTION
300 aout_@var{size}_swap_exec_header_out
301
302 SYNOPSIS
303 void aout_@var{size}_swap_exec_header_out
304 (bfd *abfd,
305 struct internal_exec *execp,
306 struct external_exec *raw_bytes);
307
308 DESCRIPTION
309 Swap the information in an internal exec header structure
310 @var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
311 */
312 void
313 DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
314 bfd *abfd AND
315 struct internal_exec *execp AND
316 struct external_exec *raw_bytes)
317 {
318 struct external_exec *bytes = (struct external_exec *)raw_bytes;
319
320 /* Now fill in fields in the raw data, from the fields in the exec struct. */
321 bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
322 PUT_WORD (abfd, execp->a_text , bytes->e_text);
323 PUT_WORD (abfd, execp->a_data , bytes->e_data);
324 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
325 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
326 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
327 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
328 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
329 }
330
331
332
333 /*
334 FUNCTION
335 aout_@var{size}_some_aout_object_p
336
337 SYNOPSIS
338 bfd_target *aout_@var{size}_some_aout_object_p
339 (bfd *abfd,
340 bfd_target *(*callback_to_real_object_p)());
341
342 DESCRIPTION
343 Some a.out variant thinks that the file open in @var{abfd}
344 checking is an a.out file. Do some more checking, and set up
345 for access if it really is. Call back to the calling
346 environment's "finish up" function just before returning, to
347 handle any last-minute setup.
348 */
349
350 bfd_target *
351 DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
352 bfd *abfd AND
353 struct internal_exec *execp AND
354 bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *)))
355 {
356 struct aout_data_struct *rawptr, *oldrawptr;
357 bfd_target *result;
358
359 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
360 if (rawptr == NULL) {
361 bfd_error = no_memory;
362 return 0;
363 }
364
365 oldrawptr = abfd->tdata.aout_data;
366 abfd->tdata.aout_data = rawptr;
367
368 /* Copy the contents of the old tdata struct.
369 In particular, we want the subformat, since for hpux it was set in
370 hp300hpux.c:swap_exec_header_in and will be used in
371 hp300hpux.c:callback. */
372 if (oldrawptr != NULL)
373 *abfd->tdata.aout_data = *oldrawptr;
374
375 abfd->tdata.aout_data->a.hdr = &rawptr->e;
376 *(abfd->tdata.aout_data->a.hdr) = *execp; /* Copy in the internal_exec struct */
377 execp = abfd->tdata.aout_data->a.hdr;
378
379 /* Set the file flags */
380 abfd->flags = NO_FLAGS;
381 if (execp->a_drsize || execp->a_trsize)
382 abfd->flags |= HAS_RELOC;
383 /* Setting of EXEC_P has been deferred to the bottom of this function */
384 if (execp->a_syms)
385 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
386 if (N_DYNAMIC(*execp))
387 abfd->flags |= DYNAMIC;
388
389 if (N_MAGIC (*execp) == ZMAGIC)
390 {
391 abfd->flags |= D_PAGED|WP_TEXT;
392 adata(abfd).magic = z_magic;
393 }
394 else if (N_MAGIC (*execp) == NMAGIC)
395 {
396 abfd->flags |= WP_TEXT;
397 adata(abfd).magic = n_magic;
398 }
399 else
400 adata(abfd).magic = o_magic;
401
402 bfd_get_start_address (abfd) = execp->a_entry;
403
404 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
405 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
406
407 /* The default relocation entry size is that of traditional V7 Unix. */
408 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
409
410 /* The default symbol entry size is that of traditional Unix. */
411 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
412
413 obj_aout_external_syms (abfd) = NULL;
414 obj_aout_external_strings (abfd) = NULL;
415 obj_aout_sym_hashes (abfd) = NULL;
416
417 /* Create the sections. This is raunchy, but bfd_close wants to reclaim
418 them. */
419
420 obj_textsec (abfd) = bfd_make_section_old_way (abfd, ".text");
421 obj_datasec (abfd) = bfd_make_section_old_way (abfd, ".data");
422 obj_bsssec (abfd) = bfd_make_section_old_way (abfd, ".bss");
423
424 #if 0
425 (void)bfd_make_section (abfd, ".text");
426 (void)bfd_make_section (abfd, ".data");
427 (void)bfd_make_section (abfd, ".bss");
428 #endif
429
430 obj_datasec (abfd)->_raw_size = execp->a_data;
431 obj_bsssec (abfd)->_raw_size = execp->a_bss;
432
433 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
434 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) :
435 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
436 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
437 (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) :
438 (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
439 obj_bsssec (abfd)->flags = SEC_ALLOC;
440
441 #ifdef THIS_IS_ONLY_DOCUMENTATION
442 /* The common code can't fill in these things because they depend
443 on either the start address of the text segment, the rounding
444 up of virtual addersses between segments, or the starting file
445 position of the text segment -- all of which varies among different
446 versions of a.out. */
447
448 /* Call back to the format-dependent code to fill in the rest of the
449 fields and do any further cleanup. Things that should be filled
450 in by the callback: */
451
452 struct exec *execp = exec_hdr (abfd);
453
454 obj_textsec (abfd)->size = N_TXTSIZE(*execp);
455 obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp);
456 /* data and bss are already filled in since they're so standard */
457
458 /* The virtual memory addresses of the sections */
459 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
460 obj_datasec (abfd)->vma = N_DATADDR(*execp);
461 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
462
463 /* The file offsets of the sections */
464 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
465 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
466
467 /* The file offsets of the relocation info */
468 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
469 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
470
471 /* The file offsets of the string table and symbol table. */
472 obj_str_filepos (abfd) = N_STROFF (*execp);
473 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
474
475 /* Determine the architecture and machine type of the object file. */
476 switch (N_MACHTYPE (*exec_hdr (abfd))) {
477 default:
478 abfd->obj_arch = bfd_arch_obscure;
479 break;
480 }
481
482 adata(abfd)->page_size = PAGE_SIZE;
483 adata(abfd)->segment_size = SEGMENT_SIZE;
484 adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
485
486 return abfd->xvec;
487
488 /* The architecture is encoded in various ways in various a.out variants,
489 or is not encoded at all in some of them. The relocation size depends
490 on the architecture and the a.out variant. Finally, the return value
491 is the bfd_target vector in use. If an error occurs, return zero and
492 set bfd_error to the appropriate error code.
493
494 Formats such as b.out, which have additional fields in the a.out
495 header, should cope with them in this callback as well. */
496 #endif /* DOCUMENTATION */
497
498 result = (*callback_to_real_object_p)(abfd);
499
500 /* Now that the segment addresses have been worked out, take a better
501 guess at whether the file is executable. If the entry point
502 is within the text segment, assume it is. (This makes files
503 executable even if their entry point address is 0, as long as
504 their text starts at zero.)
505
506 At some point we should probably break down and stat the file and
507 declare it executable if (one of) its 'x' bits are on... */
508 if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
509 (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
510 abfd->flags |= EXEC_P;
511 if (result)
512 {
513 #if 0 /* These should be set correctly anyways. */
514 abfd->sections = obj_textsec (abfd);
515 obj_textsec (abfd)->next = obj_datasec (abfd);
516 obj_datasec (abfd)->next = obj_bsssec (abfd);
517 #endif
518 }
519 else
520 {
521 free (rawptr);
522 abfd->tdata.aout_data = oldrawptr;
523 }
524 return result;
525 }
526
527 /*
528 FUNCTION
529 aout_@var{size}_mkobject
530
531 SYNOPSIS
532 boolean aout_@var{size}_mkobject, (bfd *abfd);
533
534 DESCRIPTION
535 Initialize BFD @var{abfd} for use with a.out files.
536 */
537
538 boolean
539 DEFUN(NAME(aout,mkobject),(abfd),
540 bfd *abfd)
541 {
542 struct aout_data_struct *rawptr;
543
544 bfd_error = system_call_error;
545
546 /* Use an intermediate variable for clarity */
547 rawptr = (struct aout_data_struct *)bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
548
549 if (rawptr == NULL) {
550 bfd_error = no_memory;
551 return false;
552 }
553
554 abfd->tdata.aout_data = rawptr;
555 exec_hdr (abfd) = &(rawptr->e);
556
557 /* For simplicity's sake we just make all the sections right here. */
558
559 obj_textsec (abfd) = (asection *)NULL;
560 obj_datasec (abfd) = (asection *)NULL;
561 obj_bsssec (abfd) = (asection *)NULL;
562 bfd_make_section (abfd, ".text");
563 bfd_make_section (abfd, ".data");
564 bfd_make_section (abfd, ".bss");
565 bfd_make_section (abfd, BFD_ABS_SECTION_NAME);
566 bfd_make_section (abfd, BFD_UND_SECTION_NAME);
567 bfd_make_section (abfd, BFD_COM_SECTION_NAME);
568
569 return true;
570 }
571
572
573 /*
574 FUNCTION
575 aout_@var{size}_machine_type
576
577 SYNOPSIS
578 enum machine_type aout_@var{size}_machine_type
579 (enum bfd_architecture arch,
580 unsigned long machine));
581
582 DESCRIPTION
583 Keep track of machine architecture and machine type for
584 a.out's. Return the <<machine_type>> for a particular
585 architecture and machine, or <<M_UNKNOWN>> if that exact architecture
586 and machine can't be represented in a.out format.
587
588 If the architecture is understood, machine type 0 (default)
589 is always understood.
590 */
591
592 enum machine_type
593 DEFUN(NAME(aout,machine_type),(arch, machine),
594 enum bfd_architecture arch AND
595 unsigned long machine)
596 {
597 enum machine_type arch_flags;
598
599 arch_flags = M_UNKNOWN;
600
601 switch (arch) {
602 case bfd_arch_sparc:
603 if (machine == 0) arch_flags = M_SPARC;
604 break;
605
606 case bfd_arch_m68k:
607 switch (machine) {
608 case 0: arch_flags = M_68010; break;
609 case 68000: arch_flags = M_UNKNOWN; break;
610 case 68010: arch_flags = M_68010; break;
611 case 68020: arch_flags = M_68020; break;
612 default: arch_flags = M_UNKNOWN; break;
613 }
614 break;
615
616 case bfd_arch_i386:
617 if (machine == 0) arch_flags = M_386;
618 break;
619
620 case bfd_arch_a29k:
621 if (machine == 0) arch_flags = M_29K;
622 break;
623
624 case bfd_arch_mips:
625 switch (machine) {
626 case 0:
627 case 2000:
628 case 3000: arch_flags = M_MIPS1; break;
629 case 4000:
630 case 4400:
631 case 6000: arch_flags = M_MIPS2; break;
632 default: arch_flags = M_UNKNOWN; break;
633 }
634 break;
635
636 default:
637 arch_flags = M_UNKNOWN;
638 }
639 return arch_flags;
640 }
641
642
643 /*
644 FUNCTION
645 aout_@var{size}_set_arch_mach
646
647 SYNOPSIS
648 boolean aout_@var{size}_set_arch_mach,
649 (bfd *,
650 enum bfd_architecture arch,
651 unsigned long machine));
652
653 DESCRIPTION
654 Set the architecture and the machine of the BFD @var{abfd} to the
655 values @var{arch} and @var{machine}. Verify that @var{abfd}'s format
656 can support the architecture required.
657 */
658
659 boolean
660 DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
661 bfd *abfd AND
662 enum bfd_architecture arch AND
663 unsigned long machine)
664 {
665 if (! bfd_default_set_arch_mach (abfd, arch, machine))
666 return false;
667
668 if (arch != bfd_arch_unknown &&
669 NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
670 return false; /* We can't represent this type */
671
672 /* Determine the size of a relocation entry */
673 switch (arch) {
674 case bfd_arch_sparc:
675 case bfd_arch_a29k:
676 case bfd_arch_mips:
677 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
678 break;
679 default:
680 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
681 break;
682 }
683
684 return (*aout_backend_info(abfd)->set_sizes) (abfd);
685 }
686
687 static void
688 adjust_o_magic (abfd, execp)
689 bfd *abfd;
690 struct internal_exec *execp;
691 {
692 file_ptr pos = adata (abfd).exec_bytes_size;
693 bfd_vma vma = 0;
694 int pad = 0;
695
696 /* Text. */
697 obj_textsec(abfd)->filepos = pos;
698 pos += obj_textsec(abfd)->_raw_size;
699 vma += obj_textsec(abfd)->_raw_size;
700
701 /* Data. */
702 if (!obj_datasec(abfd)->user_set_vma)
703 {
704 #if 0 /* ?? Does alignment in the file image really matter? */
705 pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
706 #endif
707 obj_textsec(abfd)->_raw_size += pad;
708 pos += pad;
709 vma += pad;
710 obj_datasec(abfd)->vma = vma;
711 }
712 obj_datasec(abfd)->filepos = pos;
713 pos += obj_datasec(abfd)->_raw_size;
714 vma += obj_datasec(abfd)->_raw_size;
715
716 /* BSS. */
717 if (!obj_bsssec(abfd)->user_set_vma)
718 {
719 #if 0
720 pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
721 #endif
722 obj_datasec(abfd)->_raw_size += pad;
723 pos += pad;
724 vma += pad;
725 obj_bsssec(abfd)->vma = vma;
726 }
727 obj_bsssec(abfd)->filepos = pos;
728
729 /* Fix up the exec header. */
730 execp->a_text = obj_textsec(abfd)->_raw_size;
731 execp->a_data = obj_datasec(abfd)->_raw_size;
732 execp->a_bss = obj_bsssec(abfd)->_raw_size;
733 N_SET_MAGIC (*execp, OMAGIC);
734 }
735
736 static void
737 adjust_z_magic (abfd, execp)
738 bfd *abfd;
739 struct internal_exec *execp;
740 {
741 bfd_size_type data_pad, text_pad;
742 file_ptr text_end;
743 CONST struct aout_backend_data *abdp;
744 int ztih; /* Nonzero if text includes exec header. */
745
746 abdp = aout_backend_info (abfd);
747
748 /* Text. */
749 ztih = abdp && abdp->text_includes_header;
750 obj_textsec(abfd)->filepos = (ztih
751 ? adata(abfd).exec_bytes_size
752 : adata(abfd).page_size);
753 if (! obj_textsec(abfd)->user_set_vma)
754 /* ?? Do we really need to check for relocs here? */
755 obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
756 ? 0
757 : (ztih
758 ? (abdp->default_text_vma
759 + adata(abfd).exec_bytes_size)
760 : abdp->default_text_vma));
761 /* Could take strange alignment of text section into account here? */
762
763 /* Find start of data. */
764 text_end = obj_textsec(abfd)->filepos + obj_textsec(abfd)->_raw_size;
765 text_pad = BFD_ALIGN (text_end, adata(abfd).page_size) - text_end;
766 obj_textsec(abfd)->_raw_size += text_pad;
767 text_end += text_pad;
768
769 /* Data. */
770 if (!obj_datasec(abfd)->user_set_vma)
771 {
772 bfd_vma vma;
773 vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size;
774 obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
775 }
776 if (abdp && abdp->zmagic_mapped_contiguous)
777 {
778 text_pad = (obj_datasec(abfd)->vma
779 - obj_textsec(abfd)->vma
780 - obj_textsec(abfd)->_raw_size);
781 obj_textsec(abfd)->_raw_size += text_pad;
782 }
783 obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos
784 + obj_textsec(abfd)->_raw_size);
785
786 /* Fix up exec header while we're at it. */
787 execp->a_text = obj_textsec(abfd)->_raw_size;
788 if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
789 execp->a_text += adata(abfd).exec_bytes_size;
790 N_SET_MAGIC (*execp, ZMAGIC);
791
792 /* Spec says data section should be rounded up to page boundary. */
793 obj_datasec(abfd)->_raw_size
794 = align_power (obj_datasec(abfd)->_raw_size,
795 obj_bsssec(abfd)->alignment_power);
796 execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size,
797 adata(abfd).page_size);
798 data_pad = execp->a_data - obj_datasec(abfd)->_raw_size;
799
800 /* BSS. */
801 if (!obj_bsssec(abfd)->user_set_vma)
802 obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
803 + obj_datasec(abfd)->_raw_size);
804 /* If the BSS immediately follows the data section and extra space
805 in the page is left after the data section, fudge data
806 in the header so that the bss section looks smaller by that
807 amount. We'll start the bss section there, and lie to the OS.
808 (Note that a linker script, as well as the above assignment,
809 could have explicitly set the BSS vma to immediately follow
810 the data section.) */
811 if (align_power (obj_bsssec(abfd)->vma, obj_bsssec(abfd)->alignment_power)
812 == obj_datasec(abfd)->vma + obj_datasec(abfd)->_raw_size)
813 execp->a_bss = (data_pad > obj_bsssec(abfd)->_raw_size) ? 0 :
814 obj_bsssec(abfd)->_raw_size - data_pad;
815 else
816 execp->a_bss = obj_bsssec(abfd)->_raw_size;
817 }
818
819 static void
820 adjust_n_magic (abfd, execp)
821 bfd *abfd;
822 struct internal_exec *execp;
823 {
824 file_ptr pos = adata(abfd).exec_bytes_size;
825 bfd_vma vma = 0;
826 int pad;
827
828 /* Text. */
829 obj_textsec(abfd)->filepos = pos;
830 if (!obj_textsec(abfd)->user_set_vma)
831 obj_textsec(abfd)->vma = vma;
832 else
833 vma = obj_textsec(abfd)->vma;
834 pos += obj_textsec(abfd)->_raw_size;
835 vma += obj_textsec(abfd)->_raw_size;
836
837 /* Data. */
838 obj_datasec(abfd)->filepos = pos;
839 if (!obj_datasec(abfd)->user_set_vma)
840 obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
841 vma = obj_datasec(abfd)->vma;
842
843 /* Since BSS follows data immediately, see if it needs alignment. */
844 vma += obj_datasec(abfd)->_raw_size;
845 pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
846 obj_datasec(abfd)->_raw_size += pad;
847 pos += obj_datasec(abfd)->_raw_size;
848
849 /* BSS. */
850 if (!obj_bsssec(abfd)->user_set_vma)
851 obj_bsssec(abfd)->vma = vma;
852 else
853 vma = obj_bsssec(abfd)->vma;
854
855 /* Fix up 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, NMAGIC);
860 }
861
862 boolean
863 DEFUN (NAME(aout,adjust_sizes_and_vmas), (abfd, text_size, text_end),
864 bfd *abfd AND bfd_size_type *text_size AND file_ptr *text_end)
865 {
866 struct internal_exec *execp = exec_hdr (abfd);
867
868 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
869 {
870 bfd_error = invalid_operation;
871 return false;
872 }
873 if (adata(abfd).magic != undecided_magic) return true;
874
875 obj_textsec(abfd)->_raw_size =
876 align_power(obj_textsec(abfd)->_raw_size,
877 obj_textsec(abfd)->alignment_power);
878
879 *text_size = obj_textsec (abfd)->_raw_size;
880 /* Rule (heuristic) for when to pad to a new page. Note that there
881 are (at least) two ways demand-paged (ZMAGIC) files have been
882 handled. Most Berkeley-based systems start the text segment at
883 (PAGE_SIZE). However, newer versions of SUNOS start the text
884 segment right after the exec header; the latter is counted in the
885 text segment size, and is paged in by the kernel with the rest of
886 the text. */
887
888 /* This perhaps isn't the right way to do this, but made it simpler for me
889 to understand enough to implement it. Better would probably be to go
890 right from BFD flags to alignment/positioning characteristics. But the
891 old code was sloppy enough about handling the flags, and had enough
892 other magic, that it was a little hard for me to understand. I think
893 I understand it better now, but I haven't time to do the cleanup this
894 minute. */
895
896 if (abfd->flags & D_PAGED)
897 /* Whether or not WP_TEXT is set -- let D_PAGED override. */
898 /* @@ What about QMAGIC? */
899 adata(abfd).magic = z_magic;
900 else if (abfd->flags & WP_TEXT)
901 adata(abfd).magic = n_magic;
902 else
903 adata(abfd).magic = o_magic;
904
905 #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
906 #if __GNUC__ >= 2
907 fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
908 ({ char *str;
909 switch (adata(abfd).magic) {
910 case n_magic: str = "NMAGIC"; break;
911 case o_magic: str = "OMAGIC"; break;
912 case z_magic: str = "ZMAGIC"; break;
913 default: abort ();
914 }
915 str;
916 }),
917 obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size,
918 obj_textsec(abfd)->alignment_power,
919 obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size,
920 obj_datasec(abfd)->alignment_power,
921 obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size,
922 obj_bsssec(abfd)->alignment_power);
923 #endif
924 #endif
925
926 switch (adata(abfd).magic)
927 {
928 case o_magic:
929 adjust_o_magic (abfd, execp);
930 break;
931 case z_magic:
932 adjust_z_magic (abfd, execp);
933 break;
934 case n_magic:
935 adjust_n_magic (abfd, execp);
936 break;
937 default:
938 abort ();
939 }
940
941 #ifdef BFD_AOUT_DEBUG
942 fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
943 obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size,
944 obj_textsec(abfd)->filepos,
945 obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size,
946 obj_datasec(abfd)->filepos,
947 obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size);
948 #endif
949
950 return true;
951 }
952
953 /*
954 FUNCTION
955 aout_@var{size}_new_section_hook
956
957 SYNOPSIS
958 boolean aout_@var{size}_new_section_hook,
959 (bfd *abfd,
960 asection *newsect));
961
962 DESCRIPTION
963 Called by the BFD in response to a @code{bfd_make_section}
964 request.
965 */
966 boolean
967 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
968 bfd *abfd AND
969 asection *newsect)
970 {
971 /* align to double at least */
972 newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
973
974
975 if (bfd_get_format (abfd) == bfd_object)
976 {
977 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
978 obj_textsec(abfd)= newsect;
979 newsect->target_index = N_TEXT | N_EXT;
980 return true;
981 }
982
983 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
984 obj_datasec(abfd) = newsect;
985 newsect->target_index = N_DATA | N_EXT;
986 return true;
987 }
988
989 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
990 obj_bsssec(abfd) = newsect;
991 newsect->target_index = N_BSS | N_EXT;
992 return true;
993 }
994
995 }
996
997 /* We allow more than three sections internally */
998 return true;
999 }
1000
1001 boolean
1002 DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
1003 bfd *abfd AND
1004 sec_ptr section AND
1005 PTR location AND
1006 file_ptr offset AND
1007 bfd_size_type count)
1008 {
1009 file_ptr text_end;
1010 bfd_size_type text_size;
1011
1012 if (abfd->output_has_begun == false)
1013 {
1014 if (NAME(aout,adjust_sizes_and_vmas) (abfd,
1015 &text_size,
1016 &text_end) == false)
1017 return false;
1018 }
1019
1020 /* regardless, once we know what we're doing, we might as well get going */
1021 if (section != obj_bsssec(abfd))
1022 {
1023 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
1024
1025 if (count) {
1026 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
1027 true : false;
1028 }
1029 return true;
1030 }
1031 return true;
1032 }
1033 \f
1034 /* Classify stabs symbols */
1035
1036 #define sym_in_text_section(sym) \
1037 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
1038
1039 #define sym_in_data_section(sym) \
1040 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
1041
1042 #define sym_in_bss_section(sym) \
1043 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
1044
1045 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
1046 zero in the "value" field. Nonzeroes there are fortrancommon
1047 symbols. */
1048 #define sym_is_undefined(sym) \
1049 ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
1050
1051 /* Symbol is a global definition if N_EXT is on and if it has
1052 a nonzero type field. */
1053 #define sym_is_global_defn(sym) \
1054 (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
1055
1056 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
1057 are on. */
1058 #define sym_is_debugger_info(sym) \
1059 (((sym)->type & ~(N_EXT | N_TYPE)) || (sym)->type == N_FN)
1060
1061 #define sym_is_fortrancommon(sym) \
1062 (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
1063
1064 /* Symbol is absolute if it has N_ABS set */
1065 #define sym_is_absolute(sym) \
1066 (((sym)->type & N_TYPE)== N_ABS)
1067
1068
1069 #define sym_is_indirect(sym) \
1070 (((sym)->type & N_ABS)== N_ABS)
1071
1072 /* Only in their own functions for ease of debugging; when sym flags have
1073 stabilised these should be inlined into their (single) caller */
1074
1075 static void
1076 DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
1077 struct external_nlist *sym_pointer AND
1078 aout_symbol_type * cache_ptr AND
1079 bfd * abfd)
1080 {
1081 cache_ptr->symbol.section = 0;
1082 switch (cache_ptr->type & N_TYPE)
1083 {
1084 case N_SETA: case N_SETA | N_EXT:
1085 case N_SETT: case N_SETT | N_EXT:
1086 case N_SETD: case N_SETD | N_EXT:
1087 case N_SETB: case N_SETB | N_EXT:
1088 {
1089 char *copy = bfd_alloc (abfd, strlen (cache_ptr->symbol.name) + 1);
1090 asection *section;
1091 asection *into_section;
1092
1093 arelent_chain *reloc = (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain));
1094 strcpy (copy, cache_ptr->symbol.name);
1095
1096 /* Make sure that this bfd has a section with the right contructor
1097 name */
1098 section = bfd_get_section_by_name (abfd, copy);
1099 if (!section)
1100 section = bfd_make_section (abfd, copy);
1101
1102 /* Build a relocation entry for the constructor */
1103 switch ((cache_ptr->type & N_TYPE))
1104 {
1105 case N_SETA: case N_SETA | N_EXT:
1106 into_section = &bfd_abs_section;
1107 cache_ptr->type = N_ABS;
1108 break;
1109 case N_SETT: case N_SETT | N_EXT:
1110 into_section = (asection *) obj_textsec (abfd);
1111 cache_ptr->type = N_TEXT;
1112 break;
1113 case N_SETD: case N_SETD | N_EXT:
1114 into_section = (asection *) obj_datasec (abfd);
1115 cache_ptr->type = N_DATA;
1116 break;
1117 case N_SETB: case N_SETB | N_EXT:
1118 into_section = (asection *) obj_bsssec (abfd);
1119 cache_ptr->type = N_BSS;
1120 break;
1121 default:
1122 abort ();
1123 }
1124
1125 /* Build a relocation pointing into the constuctor section
1126 pointing at the symbol in the set vector specified */
1127
1128 reloc->relent.addend = cache_ptr->symbol.value;
1129 cache_ptr->symbol.section = into_section->symbol->section;
1130 reloc->relent.sym_ptr_ptr = into_section->symbol_ptr_ptr;
1131
1132
1133 /* We modify the symbol to belong to a section depending upon the
1134 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
1135 really care, and add to the size of the section to contain a
1136 pointer to the symbol. Build a reloc entry to relocate to this
1137 symbol attached to this section. */
1138
1139 section->flags = SEC_CONSTRUCTOR;
1140
1141
1142 section->reloc_count++;
1143 section->alignment_power = 2;
1144
1145 reloc->next = section->constructor_chain;
1146 section->constructor_chain = reloc;
1147 reloc->relent.address = section->_raw_size;
1148 section->_raw_size += sizeof (int *);
1149
1150 reloc->relent.howto
1151 = (obj_reloc_entry_size(abfd) == RELOC_EXT_SIZE
1152 ? howto_table_ext : howto_table_std)
1153 + CTOR_TABLE_RELOC_IDX;
1154 cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
1155 }
1156 break;
1157 default:
1158 if (cache_ptr->type == N_WARNING)
1159 {
1160 /* This symbol is the text of a warning message, the next symbol
1161 is the symbol to associate the warning with */
1162 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
1163
1164 /* @@ Stuffing pointers into integers is a no-no.
1165 We can usually get away with it if the integer is
1166 large enough though. */
1167 if (sizeof (cache_ptr + 1) > sizeof (bfd_vma))
1168 abort ();
1169 cache_ptr->symbol.value = (bfd_vma) ((cache_ptr + 1));
1170
1171 /* We don't use a warning symbol's section, but we need
1172 it to be nonzero for the sanity check below, so
1173 pick one arbitrarily. */
1174 cache_ptr->symbol.section = &bfd_abs_section;
1175
1176 /* We furgle with the next symbol in place.
1177 We don't want it to be undefined, we'll trample the type */
1178 (sym_pointer + 1)->e_type[0] = 0xff;
1179 break;
1180 }
1181 if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT))
1182 {
1183 /* Two symbols in a row for an INDR message. The first symbol
1184 contains the name we will match, the second symbol contains
1185 the name the first name is translated into. It is supplied to
1186 us undefined. This is good, since we want to pull in any files
1187 which define it */
1188 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
1189
1190 /* @@ Stuffing pointers into integers is a no-no.
1191 We can usually get away with it if the integer is
1192 large enough though. */
1193 if (sizeof (cache_ptr + 1) > sizeof (bfd_vma))
1194 abort ();
1195
1196 cache_ptr->symbol.value = (bfd_vma) ((cache_ptr + 1));
1197 cache_ptr->symbol.section = &bfd_ind_section;
1198 }
1199
1200 else if (sym_is_debugger_info (cache_ptr))
1201 {
1202 cache_ptr->symbol.flags = BSF_DEBUGGING;
1203 /* Work out the section correct for this symbol */
1204 switch (cache_ptr->type & N_TYPE)
1205 {
1206 case N_TEXT:
1207 case N_FN:
1208 cache_ptr->symbol.section = obj_textsec (abfd);
1209 cache_ptr->symbol.value -= obj_textsec (abfd)->vma;
1210 break;
1211 case N_DATA:
1212 cache_ptr->symbol.value -= obj_datasec (abfd)->vma;
1213 cache_ptr->symbol.section = obj_datasec (abfd);
1214 break;
1215 case N_BSS:
1216 cache_ptr->symbol.section = obj_bsssec (abfd);
1217 cache_ptr->symbol.value -= obj_bsssec (abfd)->vma;
1218 break;
1219 default:
1220 case N_ABS:
1221 cache_ptr->symbol.section = &bfd_abs_section;
1222 break;
1223 }
1224 }
1225 else
1226 {
1227
1228 if (sym_is_fortrancommon (cache_ptr))
1229 {
1230 cache_ptr->symbol.flags = 0;
1231 cache_ptr->symbol.section = &bfd_com_section;
1232 }
1233 else
1234 {
1235
1236
1237 }
1238
1239 /* In a.out, the value of a symbol is always relative to the
1240 * start of the file, if this is a data symbol we'll subtract
1241 * the size of the text section to get the section relative
1242 * value. If this is a bss symbol (which would be strange)
1243 * we'll subtract the size of the previous two sections
1244 * to find the section relative address.
1245 */
1246
1247 if (sym_in_text_section (cache_ptr))
1248 {
1249 cache_ptr->symbol.value -= obj_textsec (abfd)->vma;
1250 cache_ptr->symbol.section = obj_textsec (abfd);
1251 }
1252 else if (sym_in_data_section (cache_ptr))
1253 {
1254 cache_ptr->symbol.value -= obj_datasec (abfd)->vma;
1255 cache_ptr->symbol.section = obj_datasec (abfd);
1256 }
1257 else if (sym_in_bss_section (cache_ptr))
1258 {
1259 cache_ptr->symbol.section = obj_bsssec (abfd);
1260 cache_ptr->symbol.value -= obj_bsssec (abfd)->vma;
1261 }
1262 else if (sym_is_undefined (cache_ptr))
1263 {
1264 cache_ptr->symbol.flags = 0;
1265 cache_ptr->symbol.section = &bfd_und_section;
1266 }
1267 else if (sym_is_absolute (cache_ptr))
1268 {
1269 cache_ptr->symbol.section = &bfd_abs_section;
1270 }
1271
1272 if (sym_is_global_defn (cache_ptr))
1273 {
1274 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1275 }
1276 else
1277 {
1278 cache_ptr->symbol.flags = BSF_LOCAL;
1279 }
1280 }
1281 }
1282 if (cache_ptr->symbol.section == 0)
1283 abort ();
1284 }
1285
1286
1287
1288 static boolean
1289 DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
1290 struct external_nlist *sym_pointer AND
1291 asymbol *cache_ptr AND
1292 bfd *abfd)
1293 {
1294 bfd_vma value = cache_ptr->value;
1295
1296 /* mask out any existing type bits in case copying from one section
1297 to another */
1298 sym_pointer->e_type[0] &= ~N_TYPE;
1299
1300 /* We attempt to order these tests by decreasing frequency of success,
1301 according to tcov when linking the linker. */
1302 if (bfd_get_output_section(cache_ptr) == &bfd_abs_section) {
1303 sym_pointer->e_type[0] |= N_ABS;
1304 }
1305 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
1306 sym_pointer->e_type[0] |= N_TEXT;
1307 }
1308 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
1309 sym_pointer->e_type[0] |= N_DATA;
1310 }
1311 else if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
1312 sym_pointer->e_type[0] |= N_BSS;
1313 }
1314 else if (bfd_get_output_section(cache_ptr) == &bfd_und_section) {
1315 sym_pointer->e_type[0] = (N_UNDF | N_EXT);
1316 }
1317 else if (bfd_get_output_section(cache_ptr) == &bfd_ind_section) {
1318 sym_pointer->e_type[0] = N_INDR;
1319 }
1320 else if (bfd_get_output_section(cache_ptr) == NULL) {
1321 /* Protect the bfd_is_com_section call.
1322 This case occurs, e.g., for the *DEBUG* section of a COFF file. */
1323 bfd_error = bfd_error_nonrepresentable_section;
1324 return false;
1325 }
1326 else if (bfd_is_com_section (bfd_get_output_section (cache_ptr))) {
1327 sym_pointer->e_type[0] = (N_UNDF | N_EXT);
1328 }
1329 else {
1330 bfd_error = bfd_error_nonrepresentable_section;
1331 return false;
1332 }
1333
1334 /* Turn the symbol from section relative to absolute again */
1335
1336 value += cache_ptr->section->output_section->vma + cache_ptr->section->output_offset ;
1337
1338
1339 if (cache_ptr->flags & (BSF_WARNING)) {
1340 (sym_pointer+1)->e_type[0] = 1;
1341 }
1342
1343 if (cache_ptr->flags & BSF_DEBUGGING) {
1344 sym_pointer->e_type[0] = ((aout_symbol_type *)cache_ptr)->type;
1345 }
1346 else if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1347 sym_pointer->e_type[0] |= N_EXT;
1348 }
1349 if (cache_ptr->flags & BSF_CONSTRUCTOR) {
1350 int type = ((aout_symbol_type *)cache_ptr)->type;
1351 switch (type)
1352 {
1353 case N_ABS: type = N_SETA; break;
1354 case N_TEXT: type = N_SETT; break;
1355 case N_DATA: type = N_SETD; break;
1356 case N_BSS: type = N_SETB; break;
1357 }
1358 sym_pointer->e_type[0] = type;
1359 }
1360
1361 PUT_WORD(abfd, value, sym_pointer->e_value);
1362
1363 return true;
1364 }
1365 \f
1366 /* Native-level interface to symbols. */
1367
1368 /* We read the symbols into a buffer, which is discarded when this
1369 function exits. We read the strings into a buffer large enough to
1370 hold them all plus all the cached symbol entries. */
1371
1372 asymbol *
1373 DEFUN(NAME(aout,make_empty_symbol),(abfd),
1374 bfd *abfd)
1375 {
1376 aout_symbol_type *new =
1377 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1378 new->symbol.the_bfd = abfd;
1379
1380 return &new->symbol;
1381 }
1382
1383 boolean
1384 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
1385 bfd *abfd)
1386 {
1387 bfd_size_type symbol_size;
1388 bfd_size_type string_size;
1389 unsigned char string_chars[BYTES_IN_WORD];
1390 struct external_nlist *syms;
1391 char *strings;
1392 aout_symbol_type *cached;
1393
1394 /* If there's no work to be done, don't do any */
1395 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1396 symbol_size = exec_hdr(abfd)->a_syms;
1397 if (symbol_size == 0)
1398 {
1399 bfd_error = no_symbols;
1400 return false;
1401 }
1402
1403 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1404 if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
1405 return false;
1406 string_size = GET_WORD (abfd, string_chars);
1407
1408 strings =(char *) bfd_alloc(abfd, string_size + 1);
1409 cached = (aout_symbol_type *)
1410 bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
1411
1412 /* malloc this, so we can free it if simply. The symbol caching
1413 might want to allocate onto the bfd's obstack */
1414 syms = (struct external_nlist *) bfd_xmalloc(symbol_size);
1415 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1416 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size)
1417 {
1418 bailout:
1419 if (syms)
1420 free (syms);
1421 if (cached)
1422 bfd_release (abfd, cached);
1423 if (strings)
1424 bfd_release (abfd, strings);
1425 return false;
1426 }
1427
1428 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1429 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size)
1430 {
1431 goto bailout;
1432 }
1433 strings[string_size] = 0; /* Just in case. */
1434
1435 /* OK, now walk the new symtable, cacheing symbol properties */
1436 {
1437 register struct external_nlist *sym_pointer;
1438 register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
1439 register aout_symbol_type *cache_ptr = cached;
1440
1441 /* Run through table and copy values */
1442 for (sym_pointer = syms, cache_ptr = cached;
1443 sym_pointer < sym_end; sym_pointer ++, cache_ptr++)
1444 {
1445 long x = GET_WORD(abfd, sym_pointer->e_strx);
1446 cache_ptr->symbol.the_bfd = abfd;
1447 if (x == 0)
1448 cache_ptr->symbol.name = "";
1449 else if (x >= 0 && x < string_size)
1450 cache_ptr->symbol.name = x + strings;
1451 else
1452 goto bailout;
1453
1454 cache_ptr->symbol.value = GET_SWORD(abfd, sym_pointer->e_value);
1455 cache_ptr->desc = bfd_h_get_16(abfd, sym_pointer->e_desc);
1456 cache_ptr->other = bfd_h_get_8(abfd, sym_pointer->e_other);
1457 cache_ptr->type = bfd_h_get_8(abfd, sym_pointer->e_type);
1458 cache_ptr->symbol.udata = 0;
1459 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1460 }
1461 }
1462
1463 obj_aout_symbols (abfd) = cached;
1464 free((PTR)syms);
1465
1466 return true;
1467 }
1468
1469 \f
1470 /* Possible improvements:
1471 + look for strings matching trailing substrings of other strings
1472 + better data structures? balanced trees?
1473 + smaller per-string or per-symbol data? re-use some of the symbol's
1474 data fields?
1475 + also look at reducing memory use elsewhere -- maybe if we didn't have to
1476 construct the entire symbol table at once, we could get by with smaller
1477 amounts of VM? (What effect does that have on the string table
1478 reductions?)
1479 + rip this out of here, put it into its own file in bfd or libiberty, so
1480 coff and elf can use it too. I'll work on this soon, but have more
1481 pressing tasks right now.
1482
1483 A hash table might(?) be more efficient for handling exactly the cases that
1484 are handled now, but for trailing substring matches, I think we want to
1485 examine the `nearest' values (reverse-)lexically, not merely impose a strict
1486 order, nor look only for exact-match or not-match. I don't think a hash
1487 table would be very useful for that, and I don't feel like fleshing out two
1488 completely different implementations. [raeburn:930419.0331EDT] */
1489
1490 struct stringtab_entry {
1491 /* Hash value for this string. Only useful so long as we aren't doing
1492 substring matches. */
1493 unsigned int hash;
1494
1495 /* Next node to look at, depending on whether the hash value of the string
1496 being searched for is less than or greater than the hash value of the
1497 current node. For now, `equal to' is lumped in with `greater than', for
1498 space efficiency. It's not a common enough case to warrant another field
1499 to be used for all nodes. */
1500 struct stringtab_entry *less;
1501 struct stringtab_entry *greater;
1502
1503 /* The string itself. */
1504 CONST char *string;
1505
1506 /* The index allocated for this string. */
1507 bfd_size_type index;
1508
1509 #ifdef GATHER_STATISTICS
1510 /* How many references have there been to this string? (Not currently used;
1511 could be dumped out for anaylsis, if anyone's interested.) */
1512 unsigned long count;
1513 #endif
1514
1515 /* Next node in linked list, in suggested output order. */
1516 struct stringtab_entry *next_to_output;
1517 };
1518
1519 struct stringtab_data {
1520 /* Tree of string table entries. */
1521 struct stringtab_entry *strings;
1522
1523 /* Fudge factor used to center top node of tree. */
1524 int hash_zero;
1525
1526 /* Next index value to issue. */
1527 bfd_size_type index;
1528
1529 /* Index used for empty strings. Cached here because checking for them
1530 is really easy, and we can avoid searching the tree. */
1531 bfd_size_type empty_string_index;
1532
1533 /* These fields indicate the two ends of a singly-linked list that indicates
1534 the order strings should be written out in. Use this order, and no
1535 seeking will need to be done, so output efficiency should be maximized. */
1536 struct stringtab_entry **end;
1537 struct stringtab_entry *output_order;
1538
1539 #ifdef GATHER_STATISTICS
1540 /* Number of strings which duplicate strings already in the table. */
1541 unsigned long duplicates;
1542
1543 /* Number of bytes saved by not having to write all the duplicate strings. */
1544 unsigned long bytes_saved;
1545
1546 /* Number of zero-length strings. Currently, these all turn into
1547 references to the null byte at the end of the first string. In some
1548 cases (possibly not all? explore this...), it should be possible to
1549 simply write out a zero index value. */
1550 unsigned long empty_strings;
1551
1552 /* Number of times the hash values matched but the strings were different.
1553 Note that this includes the number of times the other string(s) occurs, so
1554 there may only be two strings hashing to the same value, even if this
1555 number is very large. */
1556 unsigned long bad_hash_matches;
1557
1558 /* Null strings aren't counted in this one.
1559 This will probably only be nonzero if we've got an input file
1560 which was produced by `ld -r' (i.e., it's already been processed
1561 through this code). Under some operating systems, native tools
1562 may make all empty strings have the same index; but the pointer
1563 check won't catch those, because to get to that stage we'd already
1564 have to compute the checksum, which requires reading the string,
1565 so we short-circuit that case with empty_string_index above. */
1566 unsigned long pointer_matches;
1567
1568 /* Number of comparisons done. I figure with the algorithms in use below,
1569 the average number of comparisons done (per symbol) should be roughly
1570 log-base-2 of the number of unique strings. */
1571 unsigned long n_compares;
1572 #endif
1573 };
1574
1575 /* Some utility functions for the string table code. */
1576
1577 /* For speed, only hash on the first this many bytes of strings.
1578 This number was chosen by profiling ld linking itself, with -g. */
1579 #define HASHMAXLEN 25
1580
1581 #define HASH_CHAR(c) (sum ^= sum >> 20, sum ^= sum << 7, sum += (c))
1582
1583 static INLINE unsigned int
1584 hash (string, len)
1585 unsigned char *string;
1586 register unsigned int len;
1587 {
1588 register unsigned int sum = 0;
1589
1590 if (len > HASHMAXLEN)
1591 {
1592 HASH_CHAR (len);
1593 len = HASHMAXLEN;
1594 }
1595
1596 while (len--)
1597 {
1598 HASH_CHAR (*string++);
1599 }
1600 return sum;
1601 }
1602
1603 static INLINE void
1604 stringtab_init (tab)
1605 struct stringtab_data *tab;
1606 {
1607 tab->strings = 0;
1608 tab->output_order = 0;
1609 tab->hash_zero = 0;
1610 tab->end = &tab->output_order;
1611
1612 /* Initial string table length includes size of length field. */
1613 tab->index = BYTES_IN_WORD;
1614 tab->empty_string_index = -1;
1615 #ifdef GATHER_STATISTICS
1616 tab->duplicates = 0;
1617 tab->empty_strings = 0;
1618 tab->bad_hash_matches = 0;
1619 tab->pointer_matches = 0;
1620 tab->bytes_saved = 0;
1621 tab->n_compares = 0;
1622 #endif
1623 }
1624
1625 static INLINE int
1626 compare (entry, str, hash)
1627 struct stringtab_entry *entry;
1628 CONST char *str;
1629 unsigned int hash;
1630 {
1631 return hash - entry->hash;
1632 }
1633
1634 #ifdef GATHER_STATISTICS
1635 /* Don't want to have to link in math library with all bfd applications... */
1636 static INLINE double
1637 log2 (num)
1638 int num;
1639 {
1640 double d = num;
1641 int n = 0;
1642 while (d >= 2.0)
1643 n++, d /= 2.0;
1644 return ((d > 1.41) ? 0.5 : 0) + n;
1645 }
1646 #endif
1647
1648 /* Main string table routines. */
1649 /* Returns index in string table. Whether or not this actually adds an
1650 entry into the string table should be irrelevant -- it just has to
1651 return a valid index. */
1652 static bfd_size_type
1653 add_to_stringtab (abfd, str, tab)
1654 bfd *abfd;
1655 CONST char *str;
1656 struct stringtab_data *tab;
1657 {
1658 struct stringtab_entry **ep;
1659 register struct stringtab_entry *entry;
1660 unsigned int hashval, len;
1661
1662 if (str[0] == 0)
1663 {
1664 bfd_size_type index;
1665 CONST bfd_size_type minus_one = -1;
1666
1667 #ifdef GATHER_STATISTICS
1668 tab->empty_strings++;
1669 #endif
1670 index = tab->empty_string_index;
1671 if (index != minus_one)
1672 {
1673 got_empty:
1674 #ifdef GATHER_STATISTICS
1675 tab->bytes_saved++;
1676 tab->duplicates++;
1677 #endif
1678 return index;
1679 }
1680
1681 /* Need to find it. */
1682 entry = tab->strings;
1683 if (entry)
1684 {
1685 index = entry->index + strlen (entry->string);
1686 tab->empty_string_index = index;
1687 goto got_empty;
1688 }
1689 len = 0;
1690 }
1691 else
1692 len = strlen (str);
1693
1694 /* The hash_zero value is chosen such that the first symbol gets a value of
1695 zero. With a balanced tree, this wouldn't be very useful, but without it,
1696 we might get a more even split at the top level, instead of skewing it
1697 badly should hash("/usr/lib/crt0.o") (or whatever) be far from zero. */
1698 hashval = hash (str, len) ^ tab->hash_zero;
1699 ep = &tab->strings;
1700 if (!*ep)
1701 {
1702 tab->hash_zero = hashval;
1703 hashval = 0;
1704 goto add_it;
1705 }
1706
1707 while (*ep)
1708 {
1709 register int cmp;
1710
1711 entry = *ep;
1712 #ifdef GATHER_STATISTICS
1713 tab->n_compares++;
1714 #endif
1715 cmp = compare (entry, str, hashval);
1716 /* The not-equal cases are more frequent, so check them first. */
1717 if (cmp > 0)
1718 ep = &entry->greater;
1719 else if (cmp < 0)
1720 ep = &entry->less;
1721 else
1722 {
1723 if (entry->string == str)
1724 {
1725 #ifdef GATHER_STATISTICS
1726 tab->pointer_matches++;
1727 #endif
1728 goto match;
1729 }
1730 /* Compare the first bytes to save a function call if they
1731 don't match. */
1732 if (entry->string[0] == str[0] && !strcmp (entry->string, str))
1733 {
1734 match:
1735 #ifdef GATHER_STATISTICS
1736 entry->count++;
1737 tab->bytes_saved += len + 1;
1738 tab->duplicates++;
1739 #endif
1740 /* If we're in the linker, and the new string is from a new
1741 input file which might have already had these reductions
1742 run over it, we want to keep the new string pointer. I
1743 don't think we're likely to see any (or nearly as many,
1744 at least) cases where a later string is in the same location
1745 as an earlier one rather than this one. */
1746 entry->string = str;
1747 return entry->index;
1748 }
1749 #ifdef GATHER_STATISTICS
1750 tab->bad_hash_matches++;
1751 #endif
1752 ep = &entry->greater;
1753 }
1754 }
1755
1756 /* If we get here, nothing that's in the table already matched.
1757 EP points to the `next' field at the end of the chain; stick a
1758 new entry on here. */
1759 add_it:
1760 entry = (struct stringtab_entry *)
1761 bfd_alloc_by_size_t (abfd, sizeof (struct stringtab_entry));
1762
1763 entry->less = entry->greater = 0;
1764 entry->hash = hashval;
1765 entry->index = tab->index;
1766 entry->string = str;
1767 entry->next_to_output = 0;
1768 #ifdef GATHER_STATISTICS
1769 entry->count = 1;
1770 #endif
1771
1772 assert (*tab->end == 0);
1773 *(tab->end) = entry;
1774 tab->end = &entry->next_to_output;
1775 assert (*tab->end == 0);
1776
1777 {
1778 tab->index += len + 1;
1779 if (len == 0)
1780 tab->empty_string_index = entry->index;
1781 }
1782 assert (*ep == 0);
1783 *ep = entry;
1784 return entry->index;
1785 }
1786
1787 static void
1788 emit_strtab (abfd, tab)
1789 bfd *abfd;
1790 struct stringtab_data *tab;
1791 {
1792 struct stringtab_entry *entry;
1793 #ifdef GATHER_STATISTICS
1794 int count = 0;
1795 #endif
1796
1797 /* Be sure to put string length into correct byte ordering before writing
1798 it out. */
1799 char buffer[BYTES_IN_WORD];
1800
1801 PUT_WORD (abfd, tab->index, (unsigned char *) buffer);
1802 bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd);
1803
1804 for (entry = tab->output_order; entry; entry = entry->next_to_output)
1805 {
1806 bfd_write ((PTR) entry->string, 1, strlen (entry->string) + 1, abfd);
1807 #ifdef GATHER_STATISTICS
1808 count++;
1809 #endif
1810 }
1811
1812 #ifdef GATHER_STATISTICS
1813 /* Short form only, for now.
1814 To do: Specify output file. Conditionalize on environment? Detailed
1815 analysis if desired. */
1816 {
1817 int n_syms = bfd_get_symcount (abfd);
1818
1819 fprintf (stderr, "String table data for output file:\n");
1820 fprintf (stderr, " %8d symbols output\n", n_syms);
1821 fprintf (stderr, " %8d duplicate strings\n", tab->duplicates);
1822 fprintf (stderr, " %8d empty strings\n", tab->empty_strings);
1823 fprintf (stderr, " %8d unique strings output\n", count);
1824 fprintf (stderr, " %8d pointer matches\n", tab->pointer_matches);
1825 fprintf (stderr, " %8d bytes saved\n", tab->bytes_saved);
1826 fprintf (stderr, " %8d bad hash matches\n", tab->bad_hash_matches);
1827 fprintf (stderr, " %8d hash-val comparisons\n", tab->n_compares);
1828 if (n_syms)
1829 {
1830 double n_compares = tab->n_compares;
1831 double avg_compares = n_compares / n_syms;
1832 /* The second value here should usually be near one. */
1833 fprintf (stderr,
1834 "\t average %f comparisons per symbol (%f * log2 nstrings)\n",
1835 avg_compares, avg_compares / log2 (count));
1836 }
1837 }
1838 #endif
1839
1840 /* Old code:
1841 unsigned int count;
1842 generic = bfd_get_outsymbols(abfd);
1843 for (count = 0; count < bfd_get_symcount(abfd); count++)
1844 {
1845 asymbol *g = *(generic++);
1846
1847 if (g->name)
1848 {
1849 size_t length = strlen(g->name)+1;
1850 bfd_write((PTR)g->name, 1, length, abfd);
1851 }
1852 g->KEEPIT = (KEEPITTYPE) count;
1853 } */
1854 }
1855
1856 boolean
1857 DEFUN(NAME(aout,write_syms),(abfd),
1858 bfd *abfd)
1859 {
1860 unsigned int count ;
1861 asymbol **generic = bfd_get_outsymbols (abfd);
1862 struct stringtab_data strtab;
1863
1864 stringtab_init (&strtab);
1865
1866 for (count = 0; count < bfd_get_symcount (abfd); count++)
1867 {
1868 asymbol *g = generic[count];
1869 struct external_nlist nsp;
1870
1871 if (g->name)
1872 PUT_WORD (abfd, add_to_stringtab (abfd, g->name, &strtab),
1873 (unsigned char *) nsp.e_strx);
1874 else
1875 PUT_WORD (abfd, 0, (unsigned char *)nsp.e_strx);
1876
1877 if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
1878 {
1879 bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc);
1880 bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other);
1881 bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type);
1882 }
1883 else
1884 {
1885 bfd_h_put_16(abfd,0, nsp.e_desc);
1886 bfd_h_put_8(abfd, 0, nsp.e_other);
1887 bfd_h_put_8(abfd, 0, nsp.e_type);
1888 }
1889
1890 if (! translate_to_native_sym_flags (&nsp, g, abfd))
1891 return false;
1892
1893 if (bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd)
1894 != EXTERNAL_NLIST_SIZE)
1895 return false;
1896
1897 /* NB: `KEEPIT' currently overlays `flags', so set this only
1898 here, at the end. */
1899 g->KEEPIT = count;
1900 }
1901
1902 emit_strtab (abfd, &strtab);
1903
1904 return true;
1905 }
1906
1907 \f
1908 unsigned int
1909 DEFUN(NAME(aout,get_symtab),(abfd, location),
1910 bfd *abfd AND
1911 asymbol **location)
1912 {
1913 unsigned int counter = 0;
1914 aout_symbol_type *symbase;
1915
1916 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1917
1918 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1919 *(location++) = (asymbol *)( symbase++);
1920 *location++ =0;
1921 return bfd_get_symcount (abfd);
1922 }
1923
1924 \f
1925 /* Standard reloc stuff */
1926 /* Output standard relocation information to a file in target byte order. */
1927
1928 void
1929 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1930 bfd *abfd AND
1931 arelent *g AND
1932 struct reloc_std_external *natptr)
1933 {
1934 int r_index;
1935 asymbol *sym = *(g->sym_ptr_ptr);
1936 int r_extern;
1937 unsigned int r_length;
1938 int r_pcrel;
1939 int r_baserel, r_jmptable, r_relative;
1940 asection *output_section = sym->section->output_section;
1941
1942 PUT_WORD(abfd, g->address, natptr->r_address);
1943
1944 r_length = g->howto->size ; /* Size as a power of two */
1945 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1946 /* XXX This relies on relocs coming from a.out files. */
1947 r_baserel = (g->howto->type & 8) != 0;
1948 /* r_jmptable, r_relative??? FIXME-soon */
1949 r_jmptable = 0;
1950 r_relative = 0;
1951
1952 #if 0
1953 /* For a standard reloc, the addend is in the object file. */
1954 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1955 #endif
1956
1957 /* name was clobbered by aout_write_syms to be symbol index */
1958
1959 /* If this relocation is relative to a symbol then set the
1960 r_index to the symbols index, and the r_extern bit.
1961
1962 Absolute symbols can come in in two ways, either as an offset
1963 from the abs section, or as a symbol which has an abs value.
1964 check for that here
1965 */
1966
1967
1968 if (bfd_is_com_section (output_section)
1969 || output_section == &bfd_abs_section
1970 || output_section == &bfd_und_section)
1971 {
1972 if (bfd_abs_section.symbol == sym)
1973 {
1974 /* Whoops, looked like an abs symbol, but is really an offset
1975 from the abs section */
1976 r_index = 0;
1977 r_extern = 0;
1978 }
1979 else
1980 {
1981 /* Fill in symbol */
1982 r_extern = 1;
1983 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
1984
1985 }
1986 }
1987 else
1988 {
1989 /* Just an ordinary section */
1990 r_extern = 0;
1991 r_index = output_section->target_index;
1992 }
1993
1994 /* now the fun stuff */
1995 if (abfd->xvec->header_byteorder_big_p != false) {
1996 natptr->r_index[0] = r_index >> 16;
1997 natptr->r_index[1] = r_index >> 8;
1998 natptr->r_index[2] = r_index;
1999 natptr->r_type[0] =
2000 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
2001 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
2002 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
2003 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
2004 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
2005 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
2006 } else {
2007 natptr->r_index[2] = r_index >> 16;
2008 natptr->r_index[1] = r_index >> 8;
2009 natptr->r_index[0] = r_index;
2010 natptr->r_type[0] =
2011 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
2012 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
2013 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
2014 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
2015 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
2016 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
2017 }
2018 }
2019
2020
2021 /* Extended stuff */
2022 /* Output extended relocation information to a file in target byte order. */
2023
2024 void
2025 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
2026 bfd *abfd AND
2027 arelent *g AND
2028 register struct reloc_ext_external *natptr)
2029 {
2030 int r_index;
2031 int r_extern;
2032 unsigned int r_type;
2033 unsigned int r_addend;
2034 asymbol *sym = *(g->sym_ptr_ptr);
2035 asection *output_section = sym->section->output_section;
2036
2037 PUT_WORD (abfd, g->address, natptr->r_address);
2038
2039 r_type = (unsigned int) g->howto->type;
2040
2041 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
2042
2043 /* If this relocation is relative to a symbol then set the
2044 r_index to the symbols index, and the r_extern bit.
2045
2046 Absolute symbols can come in in two ways, either as an offset
2047 from the abs section, or as a symbol which has an abs value.
2048 check for that here. */
2049
2050 if (bfd_is_com_section (output_section)
2051 || output_section == &bfd_abs_section
2052 || output_section == &bfd_und_section)
2053 {
2054 if (bfd_abs_section.symbol == sym)
2055 {
2056 /* Whoops, looked like an abs symbol, but is really an offset
2057 from the abs section */
2058 r_index = 0;
2059 r_extern = 0;
2060 }
2061 else
2062 {
2063 r_extern = 1;
2064 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
2065 }
2066 }
2067 else
2068 {
2069 /* Just an ordinary section */
2070 r_extern = 0;
2071 r_index = output_section->target_index;
2072 }
2073
2074 /* now the fun stuff */
2075 if (abfd->xvec->header_byteorder_big_p != false) {
2076 natptr->r_index[0] = r_index >> 16;
2077 natptr->r_index[1] = r_index >> 8;
2078 natptr->r_index[2] = r_index;
2079 natptr->r_type[0] =
2080 ((r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
2081 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
2082 } else {
2083 natptr->r_index[2] = r_index >> 16;
2084 natptr->r_index[1] = r_index >> 8;
2085 natptr->r_index[0] = r_index;
2086 natptr->r_type[0] =
2087 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
2088 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
2089 }
2090
2091 PUT_WORD (abfd, r_addend, natptr->r_addend);
2092 }
2093
2094 /* BFD deals internally with all things based from the section they're
2095 in. so, something in 10 bytes into a text section with a base of
2096 50 would have a symbol (.text+10) and know .text vma was 50.
2097
2098 Aout keeps all it's symbols based from zero, so the symbol would
2099 contain 60. This macro subs the base of each section from the value
2100 to give the true offset from the section */
2101
2102
2103 #define MOVE_ADDRESS(ad) \
2104 if (r_extern) { \
2105 /* undefined symbol */ \
2106 cache_ptr->sym_ptr_ptr = symbols + r_index; \
2107 cache_ptr->addend = ad; \
2108 } else { \
2109 /* defined, section relative. replace symbol with pointer to \
2110 symbol which points to section */ \
2111 switch (r_index) { \
2112 case N_TEXT: \
2113 case N_TEXT | N_EXT: \
2114 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
2115 cache_ptr->addend = ad - su->textsec->vma; \
2116 break; \
2117 case N_DATA: \
2118 case N_DATA | N_EXT: \
2119 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
2120 cache_ptr->addend = ad - su->datasec->vma; \
2121 break; \
2122 case N_BSS: \
2123 case N_BSS | N_EXT: \
2124 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
2125 cache_ptr->addend = ad - su->bsssec->vma; \
2126 break; \
2127 default: \
2128 case N_ABS: \
2129 case N_ABS | N_EXT: \
2130 cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; \
2131 cache_ptr->addend = ad; \
2132 break; \
2133 } \
2134 } \
2135
2136 void
2137 DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
2138 bfd *abfd AND
2139 struct reloc_ext_external *bytes AND
2140 arelent *cache_ptr AND
2141 asymbol **symbols)
2142 {
2143 int r_index;
2144 int r_extern;
2145 unsigned int r_type;
2146 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2147
2148 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2149
2150 /* now the fun stuff */
2151 if (abfd->xvec->header_byteorder_big_p != false) {
2152 r_index = (bytes->r_index[0] << 16)
2153 | (bytes->r_index[1] << 8)
2154 | bytes->r_index[2];
2155 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2156 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2157 >> RELOC_EXT_BITS_TYPE_SH_BIG;
2158 } else {
2159 r_index = (bytes->r_index[2] << 16)
2160 | (bytes->r_index[1] << 8)
2161 | bytes->r_index[0];
2162 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2163 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2164 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
2165 }
2166
2167 cache_ptr->howto = howto_table_ext + r_type;
2168 MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
2169 }
2170
2171 void
2172 DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
2173 bfd *abfd AND
2174 struct reloc_std_external *bytes AND
2175 arelent *cache_ptr AND
2176 asymbol **symbols)
2177 {
2178 int r_index;
2179 int r_extern;
2180 unsigned int r_length;
2181 int r_pcrel;
2182 int r_baserel, r_jmptable, r_relative;
2183 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2184 int howto_idx;
2185
2186 cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
2187
2188 /* now the fun stuff */
2189 if (abfd->xvec->header_byteorder_big_p != false) {
2190 r_index = (bytes->r_index[0] << 16)
2191 | (bytes->r_index[1] << 8)
2192 | bytes->r_index[2];
2193 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2194 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2195 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2196 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2197 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2198 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2199 >> RELOC_STD_BITS_LENGTH_SH_BIG;
2200 } else {
2201 r_index = (bytes->r_index[2] << 16)
2202 | (bytes->r_index[1] << 8)
2203 | bytes->r_index[0];
2204 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2205 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2206 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2207 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2208 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2209 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2210 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
2211 }
2212
2213 howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel;
2214 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
2215 cache_ptr->howto = howto_table_std + howto_idx;
2216 BFD_ASSERT (cache_ptr->howto->type != -1);
2217 BFD_ASSERT (r_jmptable == 0);
2218 BFD_ASSERT (r_relative == 0);
2219 /* FIXME-soon: Roll jmptable, relative bits into howto setting */
2220
2221 MOVE_ADDRESS(0);
2222 }
2223
2224 /* Reloc hackery */
2225
2226 boolean
2227 DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
2228 bfd *abfd AND
2229 sec_ptr asect AND
2230 asymbol **symbols)
2231 {
2232 unsigned int count;
2233 bfd_size_type reloc_size;
2234 PTR relocs;
2235 arelent *reloc_cache;
2236 size_t each_size;
2237
2238 if (asect->relocation) return true;
2239
2240 if (asect->flags & SEC_CONSTRUCTOR) 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 {
2247 bfd_error = invalid_operation;
2248 return false;
2249 }
2250
2251 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
2252 each_size = obj_reloc_entry_size (abfd);
2253
2254 count = reloc_size / each_size;
2255
2256
2257 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
2258 (arelent)));
2259 if (!reloc_cache) {
2260 nomem:
2261 bfd_error = no_memory;
2262 return false;
2263 }
2264
2265 relocs = (PTR) bfd_alloc (abfd, reloc_size);
2266 if (!relocs) {
2267 bfd_release (abfd, reloc_cache);
2268 goto nomem;
2269 }
2270
2271 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
2272 bfd_release (abfd, relocs);
2273 bfd_release (abfd, reloc_cache);
2274 bfd_error = system_call_error;
2275 return false;
2276 }
2277
2278 if (each_size == RELOC_EXT_SIZE) {
2279 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
2280 unsigned int counter = 0;
2281 arelent *cache_ptr = reloc_cache;
2282
2283 for (; counter < count; counter++, rptr++, cache_ptr++) {
2284 NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
2285 }
2286 } else {
2287 register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
2288 unsigned int counter = 0;
2289 arelent *cache_ptr = reloc_cache;
2290
2291 for (; counter < count; counter++, rptr++, cache_ptr++) {
2292 NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
2293 }
2294
2295 }
2296
2297 bfd_release (abfd,relocs);
2298 asect->relocation = reloc_cache;
2299 asect->reloc_count = count;
2300 return true;
2301 }
2302
2303
2304
2305 /* Write out a relocation section into an object file. */
2306
2307 boolean
2308 DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
2309 bfd *abfd AND
2310 asection *section)
2311 {
2312 arelent **generic;
2313 unsigned char *native, *natptr;
2314 size_t each_size;
2315
2316 unsigned int count = section->reloc_count;
2317 size_t natsize;
2318
2319 if (count == 0) return true;
2320
2321 each_size = obj_reloc_entry_size (abfd);
2322 natsize = each_size * count;
2323 native = (unsigned char *) bfd_zalloc (abfd, natsize);
2324 if (!native) {
2325 bfd_error = no_memory;
2326 return false;
2327 }
2328
2329 generic = section->orelocation;
2330
2331 if (each_size == RELOC_EXT_SIZE)
2332 {
2333 for (natptr = native;
2334 count != 0;
2335 --count, natptr += each_size, ++generic)
2336 NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
2337 }
2338 else
2339 {
2340 for (natptr = native;
2341 count != 0;
2342 --count, natptr += each_size, ++generic)
2343 NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
2344 }
2345
2346 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
2347 bfd_release(abfd, native);
2348 return false;
2349 }
2350 bfd_release (abfd, native);
2351
2352 return true;
2353 }
2354
2355 /* This is stupid. This function should be a boolean predicate */
2356 unsigned int
2357 DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
2358 bfd *abfd AND
2359 sec_ptr section AND
2360 arelent **relptr AND
2361 asymbol **symbols)
2362 {
2363 arelent *tblptr = section->relocation;
2364 unsigned int count;
2365
2366 if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
2367 return 0;
2368
2369 if (section->flags & SEC_CONSTRUCTOR) {
2370 arelent_chain *chain = section->constructor_chain;
2371 for (count = 0; count < section->reloc_count; count ++) {
2372 *relptr ++ = &chain->relent;
2373 chain = chain->next;
2374 }
2375 }
2376 else {
2377 tblptr = section->relocation;
2378 if (!tblptr) return 0;
2379
2380 for (count = 0; count++ < section->reloc_count;)
2381 {
2382 *relptr++ = tblptr++;
2383 }
2384 }
2385 *relptr = 0;
2386
2387 return section->reloc_count;
2388 }
2389
2390 unsigned int
2391 DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
2392 bfd *abfd AND
2393 sec_ptr asect)
2394 {
2395 if (bfd_get_format (abfd) != bfd_object) {
2396 bfd_error = invalid_operation;
2397 return 0;
2398 }
2399 if (asect->flags & SEC_CONSTRUCTOR) {
2400 return (sizeof (arelent *) * (asect->reloc_count+1));
2401 }
2402
2403
2404 if (asect == obj_datasec (abfd))
2405 return (sizeof (arelent *) *
2406 ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
2407 +1));
2408
2409 if (asect == obj_textsec (abfd))
2410 return (sizeof (arelent *) *
2411 ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
2412 +1));
2413
2414 bfd_error = invalid_operation;
2415 return 0;
2416 }
2417
2418 \f
2419 unsigned int
2420 DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
2421 bfd *abfd)
2422 {
2423 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
2424
2425 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2426 }
2427
2428 /*ARGSUSED*/
2429 alent *
2430 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
2431 bfd *ignore_abfd AND
2432 asymbol *ignore_symbol)
2433 {
2434 return (alent *)NULL;
2435 }
2436
2437 /*ARGSUSED*/
2438 void
2439 DEFUN(NAME(aout,get_symbol_info),(ignore_abfd, symbol, ret),
2440 bfd *ignore_abfd AND
2441 asymbol *symbol AND
2442 symbol_info *ret)
2443 {
2444 bfd_symbol_info (symbol, ret);
2445
2446 if (ret->type == '?')
2447 {
2448 int type_code = aout_symbol(symbol)->type & 0xff;
2449 CONST char *stab_name = aout_stab_name(type_code);
2450 static char buf[10];
2451
2452 if (stab_name == NULL)
2453 {
2454 sprintf(buf, "(%d)", type_code);
2455 stab_name = buf;
2456 }
2457 ret->type = '-';
2458 ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
2459 ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
2460 ret->stab_name = stab_name;
2461 }
2462 }
2463
2464 /*ARGSUSED*/
2465 void
2466 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
2467 bfd *ignore_abfd AND
2468 PTR afile AND
2469 asymbol *symbol AND
2470 bfd_print_symbol_type how)
2471 {
2472 FILE *file = (FILE *)afile;
2473
2474 switch (how) {
2475 case bfd_print_symbol_name:
2476 if (symbol->name)
2477 fprintf(file,"%s", symbol->name);
2478 break;
2479 case bfd_print_symbol_more:
2480 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
2481 (unsigned)(aout_symbol(symbol)->other & 0xff),
2482 (unsigned)(aout_symbol(symbol)->type));
2483 break;
2484 case bfd_print_symbol_all:
2485 {
2486 CONST char *section_name = symbol->section->name;
2487
2488
2489 bfd_print_symbol_vandf((PTR)file,symbol);
2490
2491 fprintf(file," %-5s %04x %02x %02x",
2492 section_name,
2493 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
2494 (unsigned)(aout_symbol(symbol)->other & 0xff),
2495 (unsigned)(aout_symbol(symbol)->type & 0xff));
2496 if (symbol->name)
2497 fprintf(file," %s", symbol->name);
2498 }
2499 break;
2500 }
2501 }
2502
2503 /*
2504 provided a BFD, a section and an offset into the section, calculate
2505 and return the name of the source file and the line nearest to the
2506 wanted location.
2507 */
2508
2509 boolean
2510 DEFUN(NAME(aout,find_nearest_line),(abfd,
2511 section,
2512 symbols,
2513 offset,
2514 filename_ptr,
2515 functionname_ptr,
2516 line_ptr),
2517 bfd *abfd AND
2518 asection *section AND
2519 asymbol **symbols AND
2520 bfd_vma offset AND
2521 CONST char **filename_ptr AND
2522 CONST char **functionname_ptr AND
2523 unsigned int *line_ptr)
2524 {
2525 /* Run down the file looking for the filename, function and linenumber */
2526 asymbol **p;
2527 static char buffer[100];
2528 static char filename_buffer[200];
2529 CONST char *directory_name = NULL;
2530 CONST char *main_file_name = NULL;
2531 CONST char *current_file_name = NULL;
2532 CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
2533 bfd_vma high_line_vma = ~0;
2534 bfd_vma low_func_vma = 0;
2535 asymbol *func = 0;
2536 *filename_ptr = abfd->filename;
2537 *functionname_ptr = 0;
2538 *line_ptr = 0;
2539 if (symbols != (asymbol **)NULL) {
2540 for (p = symbols; *p; p++) {
2541 aout_symbol_type *q = (aout_symbol_type *)(*p);
2542 next:
2543 switch (q->type){
2544 case N_SO:
2545 main_file_name = current_file_name = q->symbol.name;
2546 /* Look ahead to next symbol to check if that too is an N_SO. */
2547 p++;
2548 if (*p == NULL)
2549 break;
2550 q = (aout_symbol_type *)(*p);
2551 if (q->type != (int)N_SO)
2552 goto next;
2553
2554 /* Found a second N_SO First is directory; second is filename. */
2555 directory_name = current_file_name;
2556 main_file_name = current_file_name = q->symbol.name;
2557 if (obj_textsec(abfd) != section)
2558 goto done;
2559 break;
2560 case N_SOL:
2561 current_file_name = q->symbol.name;
2562 break;
2563
2564 case N_SLINE:
2565
2566 case N_DSLINE:
2567 case N_BSLINE:
2568 /* We'll keep this if it resolves nearer than the one we have already */
2569 if (q->symbol.value >= offset &&
2570 q->symbol.value < high_line_vma) {
2571 *line_ptr = q->desc;
2572 high_line_vma = q->symbol.value;
2573 line_file_name = current_file_name;
2574 }
2575 break;
2576 case N_FUN:
2577 {
2578 /* We'll keep this if it is nearer than the one we have already */
2579 if (q->symbol.value >= low_func_vma &&
2580 q->symbol.value <= offset) {
2581 low_func_vma = q->symbol.value;
2582 func = (asymbol *)q;
2583 }
2584 if (*line_ptr && func) {
2585 CONST char *function = func->name;
2586 char *p;
2587 strncpy(buffer, function, sizeof(buffer)-1);
2588 buffer[sizeof(buffer)-1] = 0;
2589 /* Have to remove : stuff */
2590 p = strchr(buffer,':');
2591 if (p != NULL) { *p = '\0'; }
2592 *functionname_ptr = buffer;
2593 goto done;
2594
2595 }
2596 }
2597 break;
2598 }
2599 }
2600 }
2601
2602 done:
2603 if (*line_ptr)
2604 main_file_name = line_file_name;
2605 if (main_file_name) {
2606 if (main_file_name[0] == '/' || directory_name == NULL)
2607 *filename_ptr = main_file_name;
2608 else {
2609 sprintf(filename_buffer, "%.140s%.50s",
2610 directory_name, main_file_name);
2611 *filename_ptr = filename_buffer;
2612 }
2613 }
2614 return true;
2615
2616 }
2617
2618 /*ARGSUSED*/
2619 int
2620 DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
2621 bfd *abfd AND
2622 boolean execable)
2623 {
2624 return adata(abfd).exec_bytes_size;
2625 }
2626 \f
2627 /* a.out link code. */
2628
2629 /* a.out linker hash table entries. */
2630
2631 struct aout_link_hash_entry
2632 {
2633 struct bfd_link_hash_entry root;
2634 /* Symbol index in output file. */
2635 int indx;
2636 };
2637
2638 /* a.out linker hash table. */
2639
2640 struct aout_link_hash_table
2641 {
2642 struct bfd_link_hash_table root;
2643 };
2644
2645 static struct bfd_hash_entry *aout_link_hash_newfunc
2646 PARAMS ((struct bfd_hash_entry *entry,
2647 struct bfd_hash_table *table,
2648 const char *string));
2649 static boolean aout_link_add_object_symbols
2650 PARAMS ((bfd *, struct bfd_link_info *));
2651 static boolean aout_link_check_archive_element
2652 PARAMS ((bfd *, struct bfd_link_info *, boolean *));
2653 static boolean aout_link_get_symbols PARAMS ((bfd *));
2654 static boolean aout_link_free_symbols PARAMS ((bfd *));
2655 static boolean aout_link_check_ar_symbols
2656 PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
2657 static boolean aout_link_add_symbols
2658 PARAMS ((bfd *, struct bfd_link_info *));
2659
2660 /* Routine to create an entry in an a.out link hash table. */
2661
2662 static struct bfd_hash_entry *
2663 aout_link_hash_newfunc (entry, table, string)
2664 struct bfd_hash_entry *entry;
2665 struct bfd_hash_table *table;
2666 const char *string;
2667 {
2668 struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
2669
2670 /* Allocate the structure if it has not already been allocated by a
2671 subclass. */
2672 if (ret == (struct aout_link_hash_entry *) NULL)
2673 ret = ((struct aout_link_hash_entry *)
2674 bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
2675
2676 /* Call the allocation method of the superclass. */
2677 ret = ((struct aout_link_hash_entry *)
2678 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2679 table, string));
2680
2681 /* Set local fields. */
2682 ret->indx = -1;
2683
2684 return (struct bfd_hash_entry *) ret;
2685 }
2686
2687 /* Create an a.out link hash table. */
2688
2689 struct bfd_link_hash_table *
2690 NAME(aout,link_hash_table_create) (abfd)
2691 bfd *abfd;
2692 {
2693 struct aout_link_hash_table *ret;
2694
2695 ret = ((struct aout_link_hash_table *)
2696 bfd_xmalloc (sizeof (struct aout_link_hash_table)));
2697 if (! _bfd_link_hash_table_init (&ret->root, abfd,
2698 aout_link_hash_newfunc))
2699 {
2700 free (ret);
2701 return (struct bfd_link_hash_table *) NULL;
2702 }
2703 return &ret->root;
2704 }
2705
2706 /* Look up an entry in an a.out link hash table. */
2707
2708 #define aout_link_hash_lookup(table, string, create, copy, follow) \
2709 ((struct aout_link_hash_entry *) \
2710 bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
2711
2712 /* Traverse an a.out link hash table. */
2713
2714 #define aout_link_hash_traverse(table, func, info) \
2715 (bfd_link_hash_traverse \
2716 (&(table)->root, \
2717 (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
2718 (info)))
2719
2720 /* Get the a.out link hash table from the info structure. This is
2721 just a cast. */
2722
2723 #define aout_hash_table(p) ((struct aout_link_hash_table *) ((p)->hash))
2724
2725 /* Given an a.out BFD, add symbols to the global hash table as
2726 appropriate. */
2727
2728 boolean
2729 NAME(aout,link_add_symbols) (abfd, info)
2730 bfd *abfd;
2731 struct bfd_link_info *info;
2732 {
2733 switch (bfd_get_format (abfd))
2734 {
2735 case bfd_object:
2736 return aout_link_add_object_symbols (abfd, info);
2737 case bfd_archive:
2738 return _bfd_generic_link_add_archive_symbols
2739 (abfd, info, aout_link_check_archive_element);
2740 default:
2741 bfd_error = wrong_format;
2742 return false;
2743 }
2744 }
2745
2746 /* Add symbols from an a.out object file. */
2747
2748 static boolean
2749 aout_link_add_object_symbols (abfd, info)
2750 bfd *abfd;
2751 struct bfd_link_info *info;
2752 {
2753 if (! aout_link_get_symbols (abfd))
2754 return false;
2755 if (! aout_link_add_symbols (abfd, info))
2756 return false;
2757 if (! info->keep_memory)
2758 {
2759 if (! aout_link_free_symbols (abfd))
2760 return false;
2761 }
2762 return true;
2763 }
2764
2765 /* Check a single archive element to see if we need to include it in
2766 the link. *PNEEDED is set according to whether this element is
2767 needed in the link or not. This is called from
2768 _bfd_generic_link_add_archive_symbols. */
2769
2770 static boolean
2771 aout_link_check_archive_element (abfd, info, pneeded)
2772 bfd *abfd;
2773 struct bfd_link_info *info;
2774 boolean *pneeded;
2775 {
2776 if (! aout_link_get_symbols (abfd))
2777 return false;
2778
2779 if (! aout_link_check_ar_symbols (abfd, info, pneeded))
2780 return false;
2781
2782 if (*pneeded)
2783 {
2784 if (! aout_link_add_symbols (abfd, info))
2785 return false;
2786 }
2787
2788 /* We keep around the symbols even if we aren't going to use this
2789 object file, because we may want to reread it. This doesn't
2790 waste too much memory, because it isn't all that common to read
2791 an archive element but not need it. */
2792 if (! info->keep_memory)
2793 {
2794 if (! aout_link_free_symbols (abfd))
2795 return false;
2796 }
2797
2798 return true;
2799 }
2800
2801 /* Read the internal symbols from an a.out file. */
2802
2803 static boolean
2804 aout_link_get_symbols (abfd)
2805 bfd *abfd;
2806 {
2807 bfd_size_type count;
2808 struct external_nlist *syms;
2809 unsigned char string_chars[BYTES_IN_WORD];
2810 bfd_size_type stringsize;
2811 char *strings;
2812
2813 if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
2814 {
2815 /* We already have them. */
2816 return true;
2817 }
2818
2819 count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
2820
2821 /* We allocate using bfd_xmalloc to make the values easy to free
2822 later on. If we put them on the obstack it might not be possible
2823 to free them. */
2824 syms = ((struct external_nlist *)
2825 bfd_xmalloc ((size_t) count * EXTERNAL_NLIST_SIZE));
2826
2827 if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
2828 || (bfd_read ((PTR) syms, 1, exec_hdr (abfd)->a_syms, abfd)
2829 != exec_hdr (abfd)->a_syms))
2830 return false;
2831
2832 /* Get the size of the strings. */
2833 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
2834 || (bfd_read ((PTR) string_chars, BYTES_IN_WORD, 1, abfd)
2835 != BYTES_IN_WORD))
2836 return false;
2837 stringsize = GET_WORD (abfd, string_chars);
2838 strings = (char *) bfd_xmalloc ((size_t) stringsize);
2839
2840 /* Skip space for the string count in the buffer for convenience
2841 when using indexes. */
2842 if (bfd_read (strings + BYTES_IN_WORD, 1, stringsize - BYTES_IN_WORD, abfd)
2843 != stringsize - BYTES_IN_WORD)
2844 return false;
2845
2846 /* Save the data. */
2847 obj_aout_external_syms (abfd) = syms;
2848 obj_aout_external_sym_count (abfd) = count;
2849 obj_aout_external_strings (abfd) = strings;
2850
2851 return true;
2852 }
2853
2854 /* Free up the internal symbols read from an a.out file. */
2855
2856 static boolean
2857 aout_link_free_symbols (abfd)
2858 bfd *abfd;
2859 {
2860 if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
2861 {
2862 free ((PTR) obj_aout_external_syms (abfd));
2863 obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
2864 }
2865 if (obj_aout_external_strings (abfd) != (char *) NULL)
2866 {
2867 free ((PTR) obj_aout_external_strings (abfd));
2868 obj_aout_external_strings (abfd) = (char *) NULL;
2869 }
2870 return true;
2871 }
2872
2873 /* Look through the internal symbols to see if this object file should
2874 be included in the link. We should include this object file if it
2875 defines any symbols which are currently undefined. If this object
2876 file defines a common symbol, then we may adjust the size of the
2877 known symbol but we do not include the object file in the link
2878 (unless there is some other reason to include it). */
2879
2880 static boolean
2881 aout_link_check_ar_symbols (abfd, info, pneeded)
2882 bfd *abfd;
2883 struct bfd_link_info *info;
2884 boolean *pneeded;
2885 {
2886 register struct external_nlist *p;
2887 struct external_nlist *pend;
2888 char *strings;
2889
2890 *pneeded = false;
2891
2892 /* Look through all the symbols. */
2893 p = obj_aout_external_syms (abfd);
2894 pend = p + obj_aout_external_sym_count (abfd);
2895 strings = obj_aout_external_strings (abfd);
2896 for (; p < pend; p++)
2897 {
2898 int type = bfd_h_get_8 (abfd, p->e_type);
2899 const char *name;
2900 struct bfd_link_hash_entry *h;
2901
2902 /* Ignore symbols that are not externally visible. */
2903 if ((type & N_EXT) == 0)
2904 continue;
2905
2906 name = strings + GET_WORD (abfd, p->e_strx);
2907 h = bfd_link_hash_lookup (info->hash, name, false, false, true);
2908
2909 /* We are only interested in symbols that are currently
2910 undefined or common. */
2911 if (h == (struct bfd_link_hash_entry *) NULL
2912 || (h->type != bfd_link_hash_undefined
2913 && h->type != bfd_link_hash_common))
2914 continue;
2915
2916 if ((type & (N_TEXT | N_DATA | N_BSS)) != 0)
2917 {
2918 /* This object file defines this symbol. We must link it
2919 in. This is true regardless of whether the current
2920 definition of the symbol is undefined or common. If the
2921 current definition is common, we have a case in which we
2922 have already seen an object file including
2923 int a;
2924 and this object file from the archive includes
2925 int a = 5;
2926 In such a case we must include this object file. */
2927 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
2928 return false;
2929 *pneeded = true;
2930 return true;
2931 }
2932
2933 if (type == (N_EXT | N_UNDF))
2934 {
2935 bfd_vma value;
2936
2937 value = GET_WORD (abfd, p->e_value);
2938 if (value != 0)
2939 {
2940 /* This symbol is common in the object from the archive
2941 file. */
2942 if (h->type == bfd_link_hash_undefined)
2943 {
2944 bfd *symbfd;
2945
2946 symbfd = h->u.undef.abfd;
2947 if (symbfd == (bfd *) NULL)
2948 {
2949 /* This symbol was created as undefined from
2950 outside BFD. We assume that we should link
2951 in the object file. This is done for the -u
2952 option in the linker. */
2953 if (! (*info->callbacks->add_archive_element) (info,
2954 abfd,
2955 name))
2956 return false;
2957 *pneeded = true;
2958 return true;
2959 }
2960 /* Turn the current link symbol into a common
2961 symbol. It is already on the undefs list. */
2962 h->type = bfd_link_hash_common;
2963 h->u.c.size = value;
2964 h->u.c.section = bfd_make_section_old_way (symbfd,
2965 "COMMON");
2966 }
2967 else
2968 {
2969 /* Adjust the size of the common symbol if
2970 necessary. */
2971 if (value > h->u.c.size)
2972 h->u.c.size = value;
2973 }
2974 }
2975 }
2976 }
2977
2978 /* We do not need this object file. */
2979 return true;
2980 }
2981
2982 /* Add all symbols from an object file to the hash table. */
2983
2984 static boolean
2985 aout_link_add_symbols (abfd, info)
2986 bfd *abfd;
2987 struct bfd_link_info *info;
2988 {
2989 bfd_size_type sym_count;
2990 char *strings;
2991 boolean copy;
2992 struct aout_link_hash_entry **sym_hash;
2993 register struct external_nlist *p;
2994 struct external_nlist *pend;
2995
2996 sym_count = obj_aout_external_sym_count (abfd);
2997 strings = obj_aout_external_strings (abfd);
2998 if (info->keep_memory)
2999 copy = false;
3000 else
3001 copy = true;
3002
3003 /* We keep a list of the linker hash table entries that correspond
3004 to particular symbols. We could just look them up in the hash
3005 table, but keeping the list is more efficient. Perhaps this
3006 should be conditional on info->keep_memory. */
3007 sym_hash = ((struct aout_link_hash_entry **)
3008 bfd_alloc (abfd,
3009 ((size_t) sym_count
3010 * sizeof (struct aout_link_hash_entry *))));
3011 obj_aout_sym_hashes (abfd) = sym_hash;
3012
3013 p = obj_aout_external_syms (abfd);
3014 pend = p + sym_count;
3015 for (; p < pend; p++, sym_hash++)
3016 {
3017 int type;
3018 const char *name;
3019 bfd_vma value;
3020 asection *section;
3021 flagword flags;
3022 const char *string;
3023
3024 *sym_hash = NULL;
3025
3026 type = bfd_h_get_8 (abfd, p->e_type);
3027
3028 /* Ignore debugging symbols. */
3029 if ((type & N_STAB) != 0)
3030 continue;
3031
3032 /* Ignore symbols that are not external. */
3033 if ((type & N_EXT) == 0
3034 && type != N_WARNING
3035 && type != N_SETA
3036 && type != N_SETT
3037 && type != N_SETD
3038 && type != N_SETB)
3039 {
3040 /* If this is an N_INDR symbol we must skip the next entry,
3041 which is the symbol to indirect to (actually, an N_INDR
3042 symbol without N_EXT set is pretty useless). */
3043 if (type == N_INDR)
3044 ++p;
3045 continue;
3046 }
3047
3048 /* Ignore N_FN symbols (these appear to have N_EXT set). */
3049 if (type == N_FN)
3050 continue;
3051
3052 name = strings + GET_WORD (abfd, p->e_strx);
3053 value = GET_WORD (abfd, p->e_value);
3054 flags = BSF_GLOBAL;
3055 string = NULL;
3056 switch (type)
3057 {
3058 default:
3059 abort ();
3060 case N_UNDF | N_EXT:
3061 if (value != 0)
3062 section = &bfd_com_section;
3063 else
3064 section = &bfd_und_section;
3065 break;
3066 case N_ABS | N_EXT:
3067 section = &bfd_abs_section;
3068 break;
3069 case N_TEXT | N_EXT:
3070 section = obj_textsec (abfd);
3071 value -= bfd_get_section_vma (abfd, section);
3072 break;
3073 case N_DATA | N_EXT:
3074 section = obj_datasec (abfd);
3075 value -= bfd_get_section_vma (abfd, section);
3076 break;
3077 case N_BSS | N_EXT:
3078 section = obj_bsssec (abfd);
3079 value -= bfd_get_section_vma (abfd, section);
3080 break;
3081 case N_INDR | N_EXT:
3082 /* An indirect symbol. The next symbol is the symbol
3083 which this one really is. */
3084 BFD_ASSERT (p + 1 < pend);
3085 ++p;
3086 string = strings + GET_WORD (abfd, p->e_strx);
3087 section = &bfd_ind_section;
3088 flags |= BSF_INDIRECT;
3089 break;
3090 case N_COMM | N_EXT:
3091 section = &bfd_com_section;
3092 break;
3093 case N_SETA: case N_SETA | N_EXT:
3094 section = &bfd_abs_section;
3095 flags |= BSF_CONSTRUCTOR;
3096 break;
3097 case N_SETT: case N_SETT | N_EXT:
3098 section = obj_textsec (abfd);
3099 flags |= BSF_CONSTRUCTOR;
3100 value -= bfd_get_section_vma (abfd, section);
3101 break;
3102 case N_SETD: case N_SETD | N_EXT:
3103 section = obj_datasec (abfd);
3104 flags |= BSF_CONSTRUCTOR;
3105 value -= bfd_get_section_vma (abfd, section);
3106 break;
3107 case N_SETB: case N_SETB | N_EXT:
3108 section = obj_bsssec (abfd);
3109 flags |= BSF_CONSTRUCTOR;
3110 value -= bfd_get_section_vma (abfd, section);
3111 break;
3112 case N_WARNING:
3113 /* A warning symbol. The next symbol is the one to warn
3114 about. */
3115 BFD_ASSERT (p + 1 < pend);
3116 ++p;
3117 string = name;
3118 name = strings + GET_WORD (abfd, p->e_strx);
3119 section = &bfd_und_section;
3120 flags |= BSF_WARNING;
3121 break;
3122 }
3123
3124 if (! (_bfd_generic_link_add_one_symbol
3125 (info, abfd, name, flags, section, value, string, copy, false,
3126 ARCH_SIZE, (struct bfd_link_hash_entry **) sym_hash)))
3127 return false;
3128 }
3129
3130 return true;
3131 }
3132
3133 /* During the final link step we need to pass around a bunch of
3134 information, so we do it in an instance of this structure. */
3135
3136 struct aout_final_link_info
3137 {
3138 /* General link information. */
3139 struct bfd_link_info *info;
3140 /* Output bfd. */
3141 bfd *output_bfd;
3142 /* Reloc file positions. */
3143 file_ptr treloff, dreloff;
3144 /* File position of symbols. */
3145 file_ptr symoff;
3146 /* String table. */
3147 struct stringtab_data strtab;
3148 };
3149
3150 static boolean aout_link_input_bfd
3151 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3152 static boolean aout_link_write_symbols
3153 PARAMS ((struct aout_final_link_info *, bfd *input_bfd, int *symbol_map));
3154 static boolean aout_link_write_other_symbol
3155 PARAMS ((struct aout_link_hash_entry *, PTR));
3156 static boolean aout_link_input_section
3157 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3158 asection *input_section, file_ptr *reloff_ptr,
3159 bfd_size_type rel_size, int *symbol_map));
3160 static boolean aout_link_input_section_std
3161 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3162 asection *input_section, struct reloc_std_external *,
3163 bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
3164 static boolean aout_link_input_section_ext
3165 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3166 asection *input_section, struct reloc_ext_external *,
3167 bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
3168 static INLINE asection *aout_reloc_index_to_section
3169 PARAMS ((bfd *, int));
3170
3171 /* Do the final link step. This is called on the output BFD. The
3172 INFO structure should point to a list of BFDs linked through the
3173 link_next field which can be used to find each BFD which takes part
3174 in the output. Also, each section in ABFD should point to a list
3175 of bfd_link_order structures which list all the input sections for
3176 the output section. */
3177
3178 boolean
3179 NAME(aout,final_link) (abfd, info, callback)
3180 bfd *abfd;
3181 struct bfd_link_info *info;
3182 void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
3183 {
3184 struct aout_final_link_info aout_info;
3185 register bfd *sub;
3186 bfd_size_type text_size;
3187 file_ptr text_end;
3188 register struct bfd_link_order *p;
3189 asection *o;
3190
3191 aout_info.info = info;
3192 aout_info.output_bfd = abfd;
3193
3194 if (! info->relocateable)
3195 {
3196 exec_hdr (abfd)->a_trsize = 0;
3197 exec_hdr (abfd)->a_drsize = 0;
3198 }
3199 else
3200 {
3201 bfd_size_type trsize, drsize;
3202
3203 /* Count up the relocation sizes. */
3204 trsize = 0;
3205 drsize = 0;
3206 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3207 {
3208 if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
3209 {
3210 trsize += exec_hdr (sub)->a_trsize;
3211 drsize += exec_hdr (sub)->a_drsize;
3212 }
3213 else
3214 {
3215 /* FIXME: We need to identify the .text and .data sections
3216 and call get_reloc_upper_bound and canonicalize_reloc to
3217 work out the number of relocs needed, and then multiply
3218 by the reloc size. */
3219 abort ();
3220 }
3221 }
3222 exec_hdr (abfd)->a_trsize = trsize;
3223 exec_hdr (abfd)->a_drsize = drsize;
3224 }
3225
3226 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
3227
3228 /* Adjust the section sizes and vmas according to the magic number.
3229 This sets a_text, a_data and a_bss in the exec_hdr and sets the
3230 filepos for each section. */
3231 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3232 return false;
3233
3234 /* The relocation and symbol file positions differ among a.out
3235 targets. We are passed a callback routine from the backend
3236 specific code to handle this.
3237 FIXME: At this point we do not know how much space the symbol
3238 table will require. This will not work for any (nonstandard)
3239 a.out target that needs to know the symbol table size before it
3240 can compute the relocation file positions. This may or may not
3241 be the case for the hp300hpux target, for example. */
3242 (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3243 &aout_info.symoff);
3244 obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3245 obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3246 obj_sym_filepos (abfd) = aout_info.symoff;
3247
3248 /* We keep a count of the symbols as we output them. */
3249 obj_aout_external_sym_count (abfd) = 0;
3250
3251 /* We accumulate the string table as we write out the symbols. */
3252 stringtab_init (&aout_info.strtab);
3253
3254 /* The most time efficient way to do the link would be to read all
3255 the input object files into memory and then sort out the
3256 information into the output file. Unfortunately, that will
3257 probably use too much memory. Another method would be to step
3258 through everything that composes the text section and write it
3259 out, and then everything that composes the data section and write
3260 it out, and then write out the relocs, and then write out the
3261 symbols. Unfortunately, that requires reading stuff from each
3262 input file several times, and we will not be able to keep all the
3263 input files open simultaneously, and reopening them will be slow.
3264
3265 What we do is basically process one input file at a time. We do
3266 everything we need to do with an input file once--copy over the
3267 section contents, handle the relocation information, and write
3268 out the symbols--and then we throw away the information we read
3269 from it. This approach requires a lot of lseeks of the output
3270 file, which is unfortunate but still faster than reopening a lot
3271 of files.
3272
3273 We use the output_has_begun field of the input BFDs to see
3274 whether we have already handled it. */
3275 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3276 sub->output_has_begun = false;
3277
3278 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3279 {
3280 for (p = o->link_order_head;
3281 p != (struct bfd_link_order *) NULL;
3282 p = p->next)
3283 {
3284 /* If we might be using the C based alloca function, we need
3285 to dump the memory allocated by aout_link_input_bfd. */
3286 #ifndef __GNUC__
3287 #ifndef alloca
3288 (void) alloca (0);
3289 #endif
3290 #endif
3291 if (p->type == bfd_indirect_link_order
3292 && (bfd_get_flavour (p->u.indirect.section->owner)
3293 == bfd_target_aout_flavour))
3294 {
3295 bfd *input_bfd;
3296
3297 input_bfd = p->u.indirect.section->owner;
3298 if (! input_bfd->output_has_begun)
3299 {
3300 if (! aout_link_input_bfd (&aout_info, input_bfd))
3301 return false;
3302 input_bfd->output_has_begun = true;
3303 }
3304 }
3305 else
3306 {
3307 if (! _bfd_default_link_order (abfd, info, o, p))
3308 return false;
3309 }
3310 }
3311 }
3312
3313 /* Write out any symbols that we have not already written out. */
3314 aout_link_hash_traverse (aout_hash_table (info),
3315 aout_link_write_other_symbol,
3316 (PTR) &aout_info);
3317
3318 /* Update the header information. */
3319 abfd->symcount = obj_aout_external_sym_count (abfd);
3320 exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
3321 obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
3322 obj_textsec (abfd)->reloc_count =
3323 exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
3324 obj_datasec (abfd)->reloc_count =
3325 exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
3326
3327 /* Write out the string table. */
3328 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
3329 return false;
3330 emit_strtab (abfd, &aout_info.strtab);
3331
3332 return true;
3333 }
3334
3335 /* Link an a.out input BFD into the output file. */
3336
3337 static boolean
3338 aout_link_input_bfd (finfo, input_bfd)
3339 struct aout_final_link_info *finfo;
3340 bfd *input_bfd;
3341 {
3342 bfd_size_type sym_count;
3343 int *symbol_map;
3344
3345 BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
3346
3347 /* Get the symbols. We probably have them already, unless
3348 finfo->info->keep_memory is false. */
3349 if (! aout_link_get_symbols (input_bfd))
3350 return false;
3351
3352 sym_count = obj_aout_external_sym_count (input_bfd);
3353 symbol_map = (int *) alloca ((size_t) sym_count * sizeof (int));
3354
3355 /* Write out the symbols and get a map of the new indices. */
3356 if (! aout_link_write_symbols (finfo, input_bfd, symbol_map))
3357 return false;
3358
3359 /* Relocate and write out the sections. */
3360 if (! aout_link_input_section (finfo, input_bfd,
3361 obj_textsec (input_bfd),
3362 &finfo->treloff,
3363 exec_hdr (input_bfd)->a_trsize,
3364 symbol_map)
3365 || ! aout_link_input_section (finfo, input_bfd,
3366 obj_datasec (input_bfd),
3367 &finfo->dreloff,
3368 exec_hdr (input_bfd)->a_drsize,
3369 symbol_map))
3370 return false;
3371
3372 /* If we are not keeping memory, we don't need the symbols any
3373 longer. We still need them if we are keeping memory, because the
3374 strings in the hash table point into them. */
3375 if (! finfo->info->keep_memory)
3376 {
3377 if (! aout_link_free_symbols (input_bfd))
3378 return false;
3379 }
3380
3381 return true;
3382 }
3383
3384 /* Adjust and write out the symbols for an a.out file. Set the new
3385 symbol indices into a symbol_map. */
3386
3387 static boolean
3388 aout_link_write_symbols (finfo, input_bfd, symbol_map)
3389 struct aout_final_link_info *finfo;
3390 bfd *input_bfd;
3391 int *symbol_map;
3392 {
3393 bfd *output_bfd;
3394 bfd_size_type sym_count;
3395 char *strings;
3396 enum bfd_link_strip strip;
3397 enum bfd_link_discard discard;
3398 struct external_nlist *output_syms;
3399 struct external_nlist *outsym;
3400 register struct external_nlist *sym;
3401 struct external_nlist *sym_end;
3402 struct aout_link_hash_entry **sym_hash;
3403 boolean pass;
3404
3405 output_bfd = finfo->output_bfd;
3406 sym_count = obj_aout_external_sym_count (input_bfd);
3407 strings = obj_aout_external_strings (input_bfd);
3408 strip = finfo->info->strip;
3409 discard = finfo->info->discard;
3410 output_syms = ((struct external_nlist *)
3411 alloca ((size_t) (sym_count + 1) * EXTERNAL_NLIST_SIZE));
3412 outsym = output_syms;
3413
3414 /* First write out a symbol for this object file, unless we are
3415 discarding such symbols. */
3416 if (strip != strip_all
3417 && (strip != strip_some
3418 || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
3419 false, false) != NULL)
3420 && discard != discard_all)
3421 {
3422 bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type);
3423 bfd_h_put_8 (output_bfd, 0, outsym->e_other);
3424 bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc);
3425 PUT_WORD (output_bfd,
3426 add_to_stringtab (output_bfd, input_bfd->filename,
3427 &finfo->strtab),
3428 outsym->e_strx);
3429 PUT_WORD (output_bfd,
3430 bfd_get_section_vma (input_bfd, obj_textsec (input_bfd)),
3431 outsym->e_value);
3432 ++obj_aout_external_sym_count (output_bfd);
3433 ++outsym;
3434 }
3435
3436 pass = false;
3437 sym = obj_aout_external_syms (input_bfd);
3438 sym_end = sym + sym_count;
3439 sym_hash = obj_aout_sym_hashes (input_bfd);
3440 for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
3441 {
3442 const char *name;
3443 int type;
3444 boolean skip;
3445 asection *symsec;
3446 bfd_vma val = 0;
3447
3448 *symbol_map = -1;
3449
3450 type = bfd_h_get_8 (input_bfd, sym->e_type);
3451 name = strings + GET_WORD (input_bfd, sym->e_strx);
3452
3453 if (pass)
3454 {
3455 /* Pass this symbol through. */
3456 val = GET_WORD (input_bfd, sym->e_value);
3457 pass = false;
3458 }
3459 else
3460 {
3461 struct aout_link_hash_entry *h;
3462
3463 /* We have saved the hash table entry for this symbol, if
3464 there is one. Note that we could just look it up again
3465 in the hash table, provided we first check that it is an
3466 external symbol. */
3467 h = *sym_hash;
3468
3469 /* If the symbol has already been written out, skip it. */
3470 if (h != (struct aout_link_hash_entry *) NULL
3471 && h->root.written)
3472 {
3473 *symbol_map = h->indx;
3474 continue;
3475 }
3476
3477 /* See if we are stripping this symbol. */
3478 skip = false;
3479 switch (strip)
3480 {
3481 case strip_none:
3482 break;
3483 case strip_debugger:
3484 if ((type & N_STAB) != 0)
3485 skip = true;
3486 break;
3487 case strip_some:
3488 if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
3489 == NULL)
3490 skip = true;
3491 break;
3492 case strip_all:
3493 skip = true;
3494 break;
3495 }
3496 if (skip)
3497 {
3498 if (h != (struct aout_link_hash_entry *) NULL)
3499 h->root.written = true;
3500 continue;
3501 }
3502
3503 /* Get the value of the symbol. */
3504 if ((type & N_TYPE) == N_TEXT)
3505 symsec = obj_textsec (input_bfd);
3506 else if ((type & N_TYPE) == N_DATA)
3507 symsec = obj_datasec (input_bfd);
3508 else if ((type & N_TYPE) == N_BSS)
3509 symsec = obj_bsssec (input_bfd);
3510 else if ((type & N_TYPE) == N_ABS)
3511 symsec = &bfd_abs_section;
3512 else if ((type & N_TYPE) == N_INDR
3513 || type == N_WARNING)
3514 {
3515 /* Pass the next symbol through unchanged. */
3516 pass = true;
3517 val = GET_WORD (input_bfd, sym->e_value);
3518 symsec = NULL;
3519 }
3520 else if ((type & N_STAB) != 0)
3521 {
3522 val = GET_WORD (input_bfd, sym->e_value);
3523 symsec = NULL;
3524 }
3525 else
3526 {
3527 if (h == (struct aout_link_hash_entry *) NULL)
3528 val = 0;
3529 else if (h->root.type == bfd_link_hash_defined)
3530 {
3531 asection *output_section;
3532
3533 /* This case means a common symbol which was turned
3534 into a defined symbol. */
3535 output_section = h->root.u.def.section->output_section;
3536 BFD_ASSERT (output_section == &bfd_abs_section
3537 || output_section->owner == output_bfd);
3538 val = (h->root.u.def.value
3539 + bfd_get_section_vma (output_bfd, output_section)
3540 + h->root.u.def.section->output_offset);
3541
3542 /* Get the correct type based on the section. If
3543 this is a constructed set, force it to be
3544 globally visible. */
3545 if (type == N_SETT
3546 || type == N_SETD
3547 || type == N_SETB
3548 || type == N_SETA)
3549 type |= N_EXT;
3550
3551 type &=~ N_TYPE;
3552
3553 if (output_section == obj_textsec (output_bfd))
3554 type |= N_TEXT;
3555 else if (output_section == obj_datasec (output_bfd))
3556 type |= N_DATA;
3557 else if (output_section == obj_bsssec (output_bfd))
3558 type |= N_BSS;
3559 else
3560 type |= N_ABS;
3561 }
3562 else if (h->root.type == bfd_link_hash_common)
3563 val = h->root.u.c.size;
3564 else
3565 val = 0;
3566
3567 symsec = NULL;
3568 }
3569 if (symsec != (asection *) NULL)
3570 val = (symsec->output_section->vma
3571 + symsec->output_offset
3572 + (GET_WORD (input_bfd, sym->e_value)
3573 - symsec->vma));
3574
3575 /* If this is a global symbol set the written flag, and if
3576 it is a local symbol see if we should discard it. */
3577 if (h != (struct aout_link_hash_entry *) NULL)
3578 {
3579 h->root.written = true;
3580 h->indx = obj_aout_external_sym_count (output_bfd);
3581 }
3582 else
3583 {
3584 switch (discard)
3585 {
3586 case discard_none:
3587 break;
3588 case discard_l:
3589 if (*name == *finfo->info->lprefix
3590 && (finfo->info->lprefix_len == 1
3591 || strncmp (name, finfo->info->lprefix,
3592 finfo->info->lprefix_len) == 0))
3593 skip = true;
3594 break;
3595 case discard_all:
3596 skip = true;
3597 break;
3598 }
3599 if (skip)
3600 {
3601 pass = false;
3602 continue;
3603 }
3604 }
3605 }
3606
3607 /* Copy this symbol into the list of symbols we are going to
3608 write out. */
3609 bfd_h_put_8 (output_bfd, type, outsym->e_type);
3610 bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other),
3611 outsym->e_other);
3612 bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc),
3613 outsym->e_desc);
3614 PUT_WORD (output_bfd,
3615 add_to_stringtab (output_bfd, name, &finfo->strtab),
3616 outsym->e_strx);
3617 PUT_WORD (output_bfd, val, outsym->e_value);
3618 *symbol_map = obj_aout_external_sym_count (output_bfd);
3619 ++obj_aout_external_sym_count (output_bfd);
3620 ++outsym;
3621 }
3622
3623 /* Write out the output symbols we have just constructed. */
3624 if (outsym > output_syms)
3625 {
3626 bfd_size_type outsym_count;
3627
3628 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
3629 return false;
3630 outsym_count = outsym - output_syms;
3631 if (bfd_write ((PTR) output_syms, (bfd_size_type) EXTERNAL_NLIST_SIZE,
3632 (bfd_size_type) outsym_count, output_bfd)
3633 != outsym_count * EXTERNAL_NLIST_SIZE)
3634 return false;
3635 finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
3636 }
3637
3638 return true;
3639 }
3640
3641 /* Write out a symbol that was not associated with an a.out input
3642 object. */
3643
3644 static boolean
3645 aout_link_write_other_symbol (h, data)
3646 struct aout_link_hash_entry *h;
3647 PTR data;
3648 {
3649 struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
3650 bfd *output_bfd;
3651 int type;
3652 bfd_vma val;
3653 struct external_nlist outsym;
3654
3655 if (h->root.written)
3656 return true;
3657
3658 output_bfd = finfo->output_bfd;
3659
3660 switch (h->root.type)
3661 {
3662 default:
3663 case bfd_link_hash_new:
3664 abort ();
3665 /* Avoid variable not initialized warnings. */
3666 return true;
3667 case bfd_link_hash_undefined:
3668 type = N_UNDF | N_EXT;
3669 val = 0;
3670 break;
3671 case bfd_link_hash_defined:
3672 {
3673 asection *sec;
3674
3675 sec = h->root.u.def.section;
3676 BFD_ASSERT (sec == &bfd_abs_section
3677 || sec->owner == output_bfd);
3678 if (sec == obj_textsec (output_bfd))
3679 type = N_TEXT | N_EXT;
3680 else if (sec == obj_datasec (output_bfd))
3681 type = N_DATA | N_EXT;
3682 else if (sec == obj_bsssec (output_bfd))
3683 type = N_BSS | N_EXT;
3684 else
3685 type = N_ABS | N_EXT;
3686 val = (h->root.u.def.value
3687 + sec->output_section->vma
3688 + sec->output_offset);
3689 }
3690 break;
3691 case bfd_link_hash_common:
3692 type = N_UNDF | N_EXT;
3693 val = h->root.u.c.size;
3694 break;
3695 case bfd_link_hash_indirect:
3696 case bfd_link_hash_warning:
3697 /* FIXME: Ignore these for now. The circumstances under which
3698 they should be written out are not clear to me. */
3699 return true;
3700 }
3701
3702 bfd_h_put_8 (output_bfd, type, outsym.e_type);
3703 bfd_h_put_8 (output_bfd, 0, outsym.e_other);
3704 bfd_h_put_16 (output_bfd, 0, outsym.e_desc);
3705 PUT_WORD (output_bfd,
3706 add_to_stringtab (output_bfd, h->root.root.string, &finfo->strtab),
3707 outsym.e_strx);
3708 PUT_WORD (output_bfd, val, outsym.e_value);
3709
3710 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
3711 || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE,
3712 (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE)
3713 {
3714 /* FIXME: No way to handle errors. */
3715 abort ();
3716 }
3717
3718 finfo->symoff += EXTERNAL_NLIST_SIZE;
3719 h->indx = obj_aout_external_sym_count (output_bfd);
3720 ++obj_aout_external_sym_count (output_bfd);
3721
3722 return true;
3723 }
3724
3725 /* Link an a.out section into the output file. */
3726
3727 static boolean
3728 aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
3729 rel_size, symbol_map)
3730 struct aout_final_link_info *finfo;
3731 bfd *input_bfd;
3732 asection *input_section;
3733 file_ptr *reloff_ptr;
3734 bfd_size_type rel_size;
3735 int *symbol_map;
3736 {
3737 bfd_size_type input_size;
3738 bfd_byte *contents;
3739 PTR relocs;
3740
3741 /* Get the section contents. */
3742 input_size = bfd_section_size (input_bfd, input_section);
3743 contents = (bfd_byte *) alloca (input_size);
3744 if (! bfd_get_section_contents (input_bfd, input_section, (PTR) contents,
3745 (file_ptr) 0, input_size))
3746 return false;
3747
3748 /* Read in the relocs. */
3749 relocs = (PTR) alloca (rel_size);
3750 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
3751 || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
3752 return false;
3753
3754 /* Relocate the section contents. */
3755 if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
3756 {
3757 if (! aout_link_input_section_std (finfo, input_bfd, input_section,
3758 (struct reloc_std_external *) relocs,
3759 rel_size, contents, symbol_map))
3760 return false;
3761 }
3762 else
3763 {
3764 if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
3765 (struct reloc_ext_external *) relocs,
3766 rel_size, contents, symbol_map))
3767 return false;
3768 }
3769
3770 /* Write out the section contents. */
3771 if (! bfd_set_section_contents (finfo->output_bfd,
3772 input_section->output_section,
3773 (PTR) contents,
3774 input_section->output_offset,
3775 input_size))
3776 return false;
3777
3778 /* If we are producing relocateable output, the relocs were
3779 modified, and we now write them out. */
3780 if (finfo->info->relocateable)
3781 {
3782 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
3783 return false;
3784 if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
3785 != rel_size)
3786 return false;
3787 *reloff_ptr += rel_size;
3788
3789 /* Assert that the relocs have not run into the symbols, and
3790 that if these are the text relocs they have not run into the
3791 data relocs. */
3792 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
3793 && (reloff_ptr != &finfo->treloff
3794 || (*reloff_ptr
3795 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
3796 }
3797
3798 return true;
3799 }
3800
3801 /* Get the section corresponding to a reloc index. */
3802
3803 static INLINE asection *
3804 aout_reloc_index_to_section (abfd, indx)
3805 bfd *abfd;
3806 int indx;
3807 {
3808 switch (indx & N_TYPE)
3809 {
3810 case N_TEXT:
3811 return obj_textsec (abfd);
3812 case N_DATA:
3813 return obj_datasec (abfd);
3814 case N_BSS:
3815 return obj_bsssec (abfd);
3816 case N_ABS:
3817 return &bfd_abs_section;
3818 default:
3819 abort ();
3820 }
3821 }
3822
3823 /* Relocate an a.out section using standard a.out relocs. */
3824
3825 static boolean
3826 aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
3827 rel_size, contents, symbol_map)
3828 struct aout_final_link_info *finfo;
3829 bfd *input_bfd;
3830 asection *input_section;
3831 struct reloc_std_external *relocs;
3832 bfd_size_type rel_size;
3833 bfd_byte *contents;
3834 int *symbol_map;
3835 {
3836 bfd *output_bfd;
3837 boolean relocateable;
3838 struct external_nlist *syms;
3839 char *strings;
3840 struct aout_link_hash_entry **sym_hashes;
3841 bfd_size_type reloc_count;
3842 register struct reloc_std_external *rel;
3843 struct reloc_std_external *rel_end;
3844
3845 output_bfd = finfo->output_bfd;
3846
3847 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
3848 BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
3849 == output_bfd->xvec->header_byteorder_big_p);
3850
3851 relocateable = finfo->info->relocateable;
3852 syms = obj_aout_external_syms (input_bfd);
3853 strings = obj_aout_external_strings (input_bfd);
3854 sym_hashes = obj_aout_sym_hashes (input_bfd);
3855
3856 reloc_count = rel_size / RELOC_STD_SIZE;
3857 rel = relocs;
3858 rel_end = rel + reloc_count;
3859 for (; rel < rel_end; rel++)
3860 {
3861 bfd_vma r_addr;
3862 int r_index;
3863 int r_extern;
3864 int r_pcrel;
3865 int r_baserel;
3866 int r_jmptable;
3867 int r_relative;
3868 int r_length;
3869 int howto_idx;
3870 bfd_vma relocation;
3871 bfd_reloc_status_type r;
3872
3873 r_addr = GET_SWORD (input_bfd, rel->r_address);
3874
3875 if (input_bfd->xvec->header_byteorder_big_p)
3876 {
3877 r_index = ((rel->r_index[0] << 16)
3878 | (rel->r_index[1] << 8)
3879 | rel->r_index[2]);
3880 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
3881 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
3882 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
3883 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
3884 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
3885 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
3886 >> RELOC_STD_BITS_LENGTH_SH_BIG);
3887 }
3888 else
3889 {
3890 r_index = ((rel->r_index[2] << 16)
3891 | (rel->r_index[1] << 8)
3892 | rel->r_index[0]);
3893 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
3894 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
3895 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
3896 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
3897 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
3898 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
3899 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
3900 }
3901
3902 howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel;
3903 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
3904 BFD_ASSERT (r_jmptable == 0);
3905 BFD_ASSERT (r_relative == 0);
3906
3907 if (relocateable)
3908 {
3909 /* We are generating a relocateable output file, and must
3910 modify the reloc accordingly. */
3911 if (r_extern)
3912 {
3913 struct aout_link_hash_entry *h;
3914
3915 /* If we know the symbol this relocation is against,
3916 convert it into a relocation against a section. This
3917 is what the native linker does. */
3918 h = sym_hashes[r_index];
3919 if (h != (struct aout_link_hash_entry *) NULL
3920 && h->root.type == bfd_link_hash_defined)
3921 {
3922 asection *output_section;
3923
3924 /* Change the r_extern value. */
3925 if (output_bfd->xvec->header_byteorder_big_p)
3926 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
3927 else
3928 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
3929
3930 /* Compute a new r_index. */
3931 output_section = h->root.u.def.section->output_section;
3932 if (output_section == obj_textsec (output_bfd))
3933 r_index = N_TEXT;
3934 else if (output_section == obj_datasec (output_bfd))
3935 r_index = N_DATA;
3936 else if (output_section == obj_bsssec (output_bfd))
3937 r_index = N_BSS;
3938 else
3939 r_index = N_ABS;
3940
3941 /* Add the symbol value and the section VMA to the
3942 addend stored in the contents. */
3943 relocation = (h->root.u.def.value
3944 + output_section->vma
3945 + h->root.u.def.section->output_offset);
3946 }
3947 else
3948 {
3949 /* We must change r_index according to the symbol
3950 map. */
3951 r_index = symbol_map[r_index];
3952
3953 if (r_index == -1)
3954 {
3955 const char *name;
3956
3957 name = strings + GET_WORD (input_bfd,
3958 syms[r_index].e_strx);
3959 if (! ((*finfo->info->callbacks->unattached_reloc)
3960 (finfo->info, name, input_bfd, input_section,
3961 r_addr)))
3962 return false;
3963 r_index = 0;
3964 }
3965
3966 relocation = 0;
3967 }
3968
3969 /* Write out the new r_index value. */
3970 if (output_bfd->xvec->header_byteorder_big_p)
3971 {
3972 rel->r_index[0] = r_index >> 16;
3973 rel->r_index[1] = r_index >> 8;
3974 rel->r_index[2] = r_index;
3975 }
3976 else
3977 {
3978 rel->r_index[2] = r_index >> 16;
3979 rel->r_index[1] = r_index >> 8;
3980 rel->r_index[0] = r_index;
3981 }
3982 }
3983 else
3984 {
3985 asection *section;
3986
3987 /* This is a relocation against a section. We must
3988 adjust by the amount that the section moved. */
3989 section = aout_reloc_index_to_section (input_bfd, r_index);
3990 relocation = (section->output_section->vma
3991 + section->output_offset
3992 - section->vma);
3993 }
3994
3995 /* Change the address of the relocation. */
3996 PUT_WORD (output_bfd,
3997 r_addr + input_section->output_offset,
3998 rel->r_address);
3999
4000 /* Adjust a PC relative relocation by removing the reference
4001 to the original address in the section and including the
4002 reference to the new address. */
4003 if (r_pcrel)
4004 relocation -= (input_section->output_section->vma
4005 + input_section->output_offset
4006 - input_section->vma);
4007
4008 if (relocation == 0)
4009 r = bfd_reloc_ok;
4010 else
4011 r = _bfd_relocate_contents (howto_table_std + howto_idx,
4012 input_bfd, relocation,
4013 contents + r_addr);
4014 }
4015 else
4016 {
4017 /* We are generating an executable, and must do a full
4018 relocation. */
4019 if (r_extern)
4020 {
4021 struct aout_link_hash_entry *h;
4022
4023 h = sym_hashes[r_index];
4024 if (h != (struct aout_link_hash_entry *) NULL
4025 && h->root.type == bfd_link_hash_defined)
4026 {
4027 relocation = (h->root.u.def.value
4028 + h->root.u.def.section->output_section->vma
4029 + h->root.u.def.section->output_offset);
4030 }
4031 else
4032 {
4033 const char *name;
4034
4035 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4036 if (! ((*finfo->info->callbacks->undefined_symbol)
4037 (finfo->info, name, input_bfd, input_section,
4038 r_addr)))
4039 return false;
4040 relocation = 0;
4041 }
4042 }
4043 else
4044 {
4045 asection *section;
4046
4047 section = aout_reloc_index_to_section (input_bfd, r_index);
4048 relocation = (section->output_section->vma
4049 + section->output_offset
4050 - section->vma);
4051 if (r_pcrel)
4052 relocation += input_section->vma;
4053 }
4054
4055 r = _bfd_final_link_relocate (howto_table_std + howto_idx,
4056 input_bfd, input_section,
4057 contents, r_addr, relocation,
4058 (bfd_vma) 0);
4059 }
4060
4061 if (r != bfd_reloc_ok)
4062 {
4063 switch (r)
4064 {
4065 default:
4066 case bfd_reloc_outofrange:
4067 abort ();
4068 case bfd_reloc_overflow:
4069 if (! ((*finfo->info->callbacks->reloc_overflow)
4070 (finfo->info, input_bfd, input_section, r_addr)))
4071 return false;
4072 break;
4073 }
4074 }
4075 }
4076
4077 return true;
4078 }
4079
4080 /* Relocate an a.out section using extended a.out relocs. */
4081
4082 static boolean
4083 aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
4084 rel_size, contents, symbol_map)
4085 struct aout_final_link_info *finfo;
4086 bfd *input_bfd;
4087 asection *input_section;
4088 struct reloc_ext_external *relocs;
4089 bfd_size_type rel_size;
4090 bfd_byte *contents;
4091 int *symbol_map;
4092 {
4093 bfd *output_bfd;
4094 boolean relocateable;
4095 struct external_nlist *syms;
4096 char *strings;
4097 struct aout_link_hash_entry **sym_hashes;
4098 bfd_size_type reloc_count;
4099 register struct reloc_ext_external *rel;
4100 struct reloc_ext_external *rel_end;
4101
4102 output_bfd = finfo->output_bfd;
4103
4104 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
4105 BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
4106 == output_bfd->xvec->header_byteorder_big_p);
4107
4108 relocateable = finfo->info->relocateable;
4109 syms = obj_aout_external_syms (input_bfd);
4110 strings = obj_aout_external_strings (input_bfd);
4111 sym_hashes = obj_aout_sym_hashes (input_bfd);
4112
4113 reloc_count = rel_size / RELOC_EXT_SIZE;
4114 rel = relocs;
4115 rel_end = rel + reloc_count;
4116 for (; rel < rel_end; rel++)
4117 {
4118 bfd_vma r_addr;
4119 int r_index;
4120 int r_extern;
4121 int r_type;
4122 bfd_vma r_addend;
4123 bfd_vma relocation;
4124
4125 r_addr = GET_SWORD (input_bfd, rel->r_address);
4126
4127 if (input_bfd->xvec->header_byteorder_big_p)
4128 {
4129 r_index = ((rel->r_index[0] << 16)
4130 | (rel->r_index[1] << 8)
4131 | rel->r_index[2]);
4132 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
4133 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
4134 >> RELOC_EXT_BITS_TYPE_SH_BIG);
4135 }
4136 else
4137 {
4138 r_index = ((rel->r_index[2] << 16)
4139 | (rel->r_index[1] << 8)
4140 | rel->r_index[0]);
4141 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
4142 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
4143 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
4144 }
4145
4146 r_addend = GET_SWORD (input_bfd, rel->r_addend);
4147
4148 BFD_ASSERT (r_type >= 0
4149 && r_type < TABLE_SIZE (howto_table_ext));
4150
4151 if (relocateable)
4152 {
4153 /* We are generating a relocateable output file, and must
4154 modify the reloc accordingly. */
4155 if (r_extern)
4156 {
4157 struct aout_link_hash_entry *h;
4158
4159 /* If we know the symbol this relocation is against,
4160 convert it into a relocation against a section. This
4161 is what the native linker does. */
4162 h = sym_hashes[r_index];
4163 if (h != (struct aout_link_hash_entry *) NULL
4164 && h->root.type == bfd_link_hash_defined)
4165 {
4166 asection *output_section;
4167
4168 /* Change the r_extern value. */
4169 if (output_bfd->xvec->header_byteorder_big_p)
4170 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
4171 else
4172 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
4173
4174 /* Compute a new r_index. */
4175 output_section = h->root.u.def.section->output_section;
4176 if (output_section == obj_textsec (output_bfd))
4177 r_index = N_TEXT;
4178 else if (output_section == obj_datasec (output_bfd))
4179 r_index = N_DATA;
4180 else if (output_section == obj_bsssec (output_bfd))
4181 r_index = N_BSS;
4182 else
4183 r_index = N_ABS;
4184
4185 /* Add the symbol value and the section VMA to the
4186 addend. */
4187 relocation = (h->root.u.def.value
4188 + output_section->vma
4189 + h->root.u.def.section->output_offset);
4190
4191 /* Now RELOCATION is the VMA of the final
4192 destination. If this is a PC relative reloc,
4193 then ADDEND is the negative of the source VMA.
4194 We want to set ADDEND to the difference between
4195 the destination VMA and the source VMA, which
4196 means we must adjust RELOCATION by the change in
4197 the source VMA. This is done below. */
4198 }
4199 else
4200 {
4201 /* We must change r_index according to the symbol
4202 map. */
4203 r_index = symbol_map[r_index];
4204
4205 if (r_index == -1)
4206 {
4207 const char *name;
4208
4209 name = (strings
4210 + GET_WORD (input_bfd, syms[r_index].e_strx));
4211 if (! ((*finfo->info->callbacks->unattached_reloc)
4212 (finfo->info, name, input_bfd, input_section,
4213 r_addr)))
4214 return false;
4215 r_index = 0;
4216 }
4217
4218 relocation = 0;
4219
4220 /* If this is a PC relative reloc, then the addend
4221 is the negative of the source VMA. We must
4222 adjust it by the change in the source VMA. This
4223 is done below. */
4224 }
4225
4226 /* Write out the new r_index value. */
4227 if (output_bfd->xvec->header_byteorder_big_p)
4228 {
4229 rel->r_index[0] = r_index >> 16;
4230 rel->r_index[1] = r_index >> 8;
4231 rel->r_index[2] = r_index;
4232 }
4233 else
4234 {
4235 rel->r_index[2] = r_index >> 16;
4236 rel->r_index[1] = r_index >> 8;
4237 rel->r_index[0] = r_index;
4238 }
4239 }
4240 else
4241 {
4242 asection *section;
4243
4244 /* This is a relocation against a section. We must
4245 adjust by the amount that the section moved. */
4246 section = aout_reloc_index_to_section (input_bfd, r_index);
4247 relocation = (section->output_section->vma
4248 + section->output_offset
4249 - section->vma);
4250
4251 /* If this is a PC relative reloc, then the addend is
4252 the difference in VMA between the destination and the
4253 source. We have just adjusted for the change in VMA
4254 of the destination, so we must also adjust by the
4255 change in VMA of the source. This is done below. */
4256 }
4257
4258 /* As described above, we must always adjust a PC relative
4259 reloc by the change in VMA of the source. */
4260 if (howto_table_ext[r_type].pc_relative)
4261 relocation -= (input_section->output_section->vma
4262 + input_section->output_offset
4263 - input_section->vma);
4264
4265 /* Change the addend if necessary. */
4266 if (relocation != 0)
4267 PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
4268
4269 /* Change the address of the relocation. */
4270 PUT_WORD (output_bfd,
4271 r_addr + input_section->output_offset,
4272 rel->r_address);
4273 }
4274 else
4275 {
4276 bfd_reloc_status_type r;
4277
4278 /* We are generating an executable, and must do a full
4279 relocation. */
4280 if (r_extern)
4281 {
4282 struct aout_link_hash_entry *h;
4283
4284 h = sym_hashes[r_index];
4285 if (h != (struct aout_link_hash_entry *) NULL
4286 && h->root.type == bfd_link_hash_defined)
4287 {
4288 relocation = (h->root.u.def.value
4289 + h->root.u.def.section->output_section->vma
4290 + h->root.u.def.section->output_offset);
4291 }
4292 else
4293 {
4294 const char *name;
4295
4296 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4297 if (! ((*finfo->info->callbacks->undefined_symbol)
4298 (finfo->info, name, input_bfd, input_section,
4299 r_addr)))
4300 return false;
4301 relocation = 0;
4302 }
4303 }
4304 else
4305 {
4306 asection *section;
4307
4308 section = aout_reloc_index_to_section (input_bfd, r_index);
4309
4310 /* If this is a PC relative reloc, then R_ADDEND is the
4311 difference between the two vmas, or
4312 old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
4313 where
4314 old_dest_sec == section->vma
4315 and
4316 old_src_sec == input_section->vma
4317 and
4318 old_src_off == r_addr
4319
4320 _bfd_final_link_relocate expects RELOCATION +
4321 R_ADDEND to be the VMA of the destination minus
4322 r_addr (the minus r_addr is because this relocation
4323 is not pcrel_offset, which is a bit confusing and
4324 should, perhaps, be changed), or
4325 new_dest_sec
4326 where
4327 new_dest_sec == output_section->vma + output_offset
4328 We arrange for this to happen by setting RELOCATION to
4329 new_dest_sec + old_src_sec - old_dest_sec
4330
4331 If this is not a PC relative reloc, then R_ADDEND is
4332 simply the VMA of the destination, so we set
4333 RELOCATION to the change in the destination VMA, or
4334 new_dest_sec - old_dest_sec
4335 */
4336 relocation = (section->output_section->vma
4337 + section->output_offset
4338 - section->vma);
4339 if (howto_table_ext[r_type].pc_relative)
4340 relocation += input_section->vma;
4341 }
4342
4343 r = _bfd_final_link_relocate (howto_table_ext + r_type,
4344 input_bfd, input_section,
4345 contents, r_addr, relocation,
4346 r_addend);
4347 if (r != bfd_reloc_ok)
4348 {
4349 switch (r)
4350 {
4351 default:
4352 case bfd_reloc_outofrange:
4353 abort ();
4354 case bfd_reloc_overflow:
4355 if (! ((*finfo->info->callbacks->reloc_overflow)
4356 (finfo->info, input_bfd, input_section, r_addr)))
4357 return false;
4358 break;
4359 }
4360 }
4361 }
4362 }
4363
4364 return true;
4365 }
This page took 0.121895 seconds and 4 git commands to generate.