b8040cbc06db28703bf51824a9bc52470e0f512e
[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->e_type[0] = N_WARNING;
1341 (sym_pointer+1)->e_type[0] = 1;
1342 }
1343
1344 if (cache_ptr->flags & BSF_DEBUGGING) {
1345 sym_pointer->e_type[0] = ((aout_symbol_type *)cache_ptr)->type;
1346 }
1347 else if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1348 sym_pointer->e_type[0] |= N_EXT;
1349 }
1350 if (cache_ptr->flags & BSF_CONSTRUCTOR) {
1351 int type = ((aout_symbol_type *)cache_ptr)->type;
1352 switch (type)
1353 {
1354 case N_ABS: type = N_SETA; break;
1355 case N_TEXT: type = N_SETT; break;
1356 case N_DATA: type = N_SETD; break;
1357 case N_BSS: type = N_SETB; break;
1358 }
1359 sym_pointer->e_type[0] = type;
1360 }
1361
1362 PUT_WORD(abfd, value, sym_pointer->e_value);
1363
1364 return true;
1365 }
1366 \f
1367 /* Native-level interface to symbols. */
1368
1369 /* We read the symbols into a buffer, which is discarded when this
1370 function exits. We read the strings into a buffer large enough to
1371 hold them all plus all the cached symbol entries. */
1372
1373 asymbol *
1374 DEFUN(NAME(aout,make_empty_symbol),(abfd),
1375 bfd *abfd)
1376 {
1377 aout_symbol_type *new =
1378 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1379 new->symbol.the_bfd = abfd;
1380
1381 return &new->symbol;
1382 }
1383
1384 boolean
1385 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
1386 bfd *abfd)
1387 {
1388 bfd_size_type symbol_size;
1389 bfd_size_type string_size;
1390 unsigned char string_chars[BYTES_IN_WORD];
1391 struct external_nlist *syms;
1392 char *strings;
1393 aout_symbol_type *cached;
1394
1395 /* If there's no work to be done, don't do any */
1396 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1397 symbol_size = exec_hdr(abfd)->a_syms;
1398 if (symbol_size == 0)
1399 {
1400 bfd_error = no_symbols;
1401 return false;
1402 }
1403
1404 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1405 if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
1406 return false;
1407 string_size = GET_WORD (abfd, string_chars);
1408
1409 strings =(char *) bfd_alloc(abfd, string_size + 1);
1410 cached = (aout_symbol_type *)
1411 bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
1412
1413 /* malloc this, so we can free it if simply. The symbol caching
1414 might want to allocate onto the bfd's obstack */
1415 syms = (struct external_nlist *) bfd_xmalloc(symbol_size);
1416 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1417 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size)
1418 {
1419 bailout:
1420 if (syms)
1421 free (syms);
1422 if (cached)
1423 bfd_release (abfd, cached);
1424 if (strings)
1425 bfd_release (abfd, strings);
1426 return false;
1427 }
1428
1429 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1430 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size)
1431 {
1432 goto bailout;
1433 }
1434 strings[string_size] = 0; /* Just in case. */
1435
1436 /* OK, now walk the new symtable, cacheing symbol properties */
1437 {
1438 register struct external_nlist *sym_pointer;
1439 register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
1440 register aout_symbol_type *cache_ptr = cached;
1441
1442 /* Run through table and copy values */
1443 for (sym_pointer = syms, cache_ptr = cached;
1444 sym_pointer < sym_end; sym_pointer ++, cache_ptr++)
1445 {
1446 long x = GET_WORD(abfd, sym_pointer->e_strx);
1447 cache_ptr->symbol.the_bfd = abfd;
1448 if (x == 0)
1449 cache_ptr->symbol.name = "";
1450 else if (x >= 0 && x < string_size)
1451 cache_ptr->symbol.name = x + strings;
1452 else
1453 goto bailout;
1454
1455 cache_ptr->symbol.value = GET_SWORD(abfd, sym_pointer->e_value);
1456 cache_ptr->desc = bfd_h_get_16(abfd, sym_pointer->e_desc);
1457 cache_ptr->other = bfd_h_get_8(abfd, sym_pointer->e_other);
1458 cache_ptr->type = bfd_h_get_8(abfd, sym_pointer->e_type);
1459 cache_ptr->symbol.udata = 0;
1460 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1461 }
1462 }
1463
1464 obj_aout_symbols (abfd) = cached;
1465 free((PTR)syms);
1466
1467 return true;
1468 }
1469
1470 \f
1471 /* Possible improvements:
1472 + look for strings matching trailing substrings of other strings
1473 + better data structures? balanced trees?
1474 + smaller per-string or per-symbol data? re-use some of the symbol's
1475 data fields?
1476 + also look at reducing memory use elsewhere -- maybe if we didn't have to
1477 construct the entire symbol table at once, we could get by with smaller
1478 amounts of VM? (What effect does that have on the string table
1479 reductions?)
1480 + rip this out of here, put it into its own file in bfd or libiberty, so
1481 coff and elf can use it too. I'll work on this soon, but have more
1482 pressing tasks right now.
1483
1484 A hash table might(?) be more efficient for handling exactly the cases that
1485 are handled now, but for trailing substring matches, I think we want to
1486 examine the `nearest' values (reverse-)lexically, not merely impose a strict
1487 order, nor look only for exact-match or not-match. I don't think a hash
1488 table would be very useful for that, and I don't feel like fleshing out two
1489 completely different implementations. [raeburn:930419.0331EDT] */
1490
1491 struct stringtab_entry {
1492 /* Hash value for this string. Only useful so long as we aren't doing
1493 substring matches. */
1494 unsigned int hash;
1495
1496 /* Next node to look at, depending on whether the hash value of the string
1497 being searched for is less than or greater than the hash value of the
1498 current node. For now, `equal to' is lumped in with `greater than', for
1499 space efficiency. It's not a common enough case to warrant another field
1500 to be used for all nodes. */
1501 struct stringtab_entry *less;
1502 struct stringtab_entry *greater;
1503
1504 /* The string itself. */
1505 CONST char *string;
1506
1507 /* The index allocated for this string. */
1508 bfd_size_type index;
1509
1510 #ifdef GATHER_STATISTICS
1511 /* How many references have there been to this string? (Not currently used;
1512 could be dumped out for anaylsis, if anyone's interested.) */
1513 unsigned long count;
1514 #endif
1515
1516 /* Next node in linked list, in suggested output order. */
1517 struct stringtab_entry *next_to_output;
1518 };
1519
1520 struct stringtab_data {
1521 /* Tree of string table entries. */
1522 struct stringtab_entry *strings;
1523
1524 /* Fudge factor used to center top node of tree. */
1525 int hash_zero;
1526
1527 /* Next index value to issue. */
1528 bfd_size_type index;
1529
1530 /* Index used for empty strings. Cached here because checking for them
1531 is really easy, and we can avoid searching the tree. */
1532 bfd_size_type empty_string_index;
1533
1534 /* These fields indicate the two ends of a singly-linked list that indicates
1535 the order strings should be written out in. Use this order, and no
1536 seeking will need to be done, so output efficiency should be maximized. */
1537 struct stringtab_entry **end;
1538 struct stringtab_entry *output_order;
1539
1540 #ifdef GATHER_STATISTICS
1541 /* Number of strings which duplicate strings already in the table. */
1542 unsigned long duplicates;
1543
1544 /* Number of bytes saved by not having to write all the duplicate strings. */
1545 unsigned long bytes_saved;
1546
1547 /* Number of zero-length strings. Currently, these all turn into
1548 references to the null byte at the end of the first string. In some
1549 cases (possibly not all? explore this...), it should be possible to
1550 simply write out a zero index value. */
1551 unsigned long empty_strings;
1552
1553 /* Number of times the hash values matched but the strings were different.
1554 Note that this includes the number of times the other string(s) occurs, so
1555 there may only be two strings hashing to the same value, even if this
1556 number is very large. */
1557 unsigned long bad_hash_matches;
1558
1559 /* Null strings aren't counted in this one.
1560 This will probably only be nonzero if we've got an input file
1561 which was produced by `ld -r' (i.e., it's already been processed
1562 through this code). Under some operating systems, native tools
1563 may make all empty strings have the same index; but the pointer
1564 check won't catch those, because to get to that stage we'd already
1565 have to compute the checksum, which requires reading the string,
1566 so we short-circuit that case with empty_string_index above. */
1567 unsigned long pointer_matches;
1568
1569 /* Number of comparisons done. I figure with the algorithms in use below,
1570 the average number of comparisons done (per symbol) should be roughly
1571 log-base-2 of the number of unique strings. */
1572 unsigned long n_compares;
1573 #endif
1574 };
1575
1576 /* Some utility functions for the string table code. */
1577
1578 /* For speed, only hash on the first this many bytes of strings.
1579 This number was chosen by profiling ld linking itself, with -g. */
1580 #define HASHMAXLEN 25
1581
1582 #define HASH_CHAR(c) (sum ^= sum >> 20, sum ^= sum << 7, sum += (c))
1583
1584 static INLINE unsigned int
1585 hash (string, len)
1586 unsigned char *string;
1587 register unsigned int len;
1588 {
1589 register unsigned int sum = 0;
1590
1591 if (len > HASHMAXLEN)
1592 {
1593 HASH_CHAR (len);
1594 len = HASHMAXLEN;
1595 }
1596
1597 while (len--)
1598 {
1599 HASH_CHAR (*string++);
1600 }
1601 return sum;
1602 }
1603
1604 static INLINE void
1605 stringtab_init (tab)
1606 struct stringtab_data *tab;
1607 {
1608 tab->strings = 0;
1609 tab->output_order = 0;
1610 tab->hash_zero = 0;
1611 tab->end = &tab->output_order;
1612
1613 /* Initial string table length includes size of length field. */
1614 tab->index = BYTES_IN_WORD;
1615 tab->empty_string_index = -1;
1616 #ifdef GATHER_STATISTICS
1617 tab->duplicates = 0;
1618 tab->empty_strings = 0;
1619 tab->bad_hash_matches = 0;
1620 tab->pointer_matches = 0;
1621 tab->bytes_saved = 0;
1622 tab->n_compares = 0;
1623 #endif
1624 }
1625
1626 static INLINE int
1627 compare (entry, str, hash)
1628 struct stringtab_entry *entry;
1629 CONST char *str;
1630 unsigned int hash;
1631 {
1632 return hash - entry->hash;
1633 }
1634
1635 #ifdef GATHER_STATISTICS
1636 /* Don't want to have to link in math library with all bfd applications... */
1637 static INLINE double
1638 log2 (num)
1639 int num;
1640 {
1641 double d = num;
1642 int n = 0;
1643 while (d >= 2.0)
1644 n++, d /= 2.0;
1645 return ((d > 1.41) ? 0.5 : 0) + n;
1646 }
1647 #endif
1648
1649 /* Main string table routines. */
1650 /* Returns index in string table. Whether or not this actually adds an
1651 entry into the string table should be irrelevant -- it just has to
1652 return a valid index. */
1653 static bfd_size_type
1654 add_to_stringtab (abfd, str, tab)
1655 bfd *abfd;
1656 CONST char *str;
1657 struct stringtab_data *tab;
1658 {
1659 struct stringtab_entry **ep;
1660 register struct stringtab_entry *entry;
1661 unsigned int hashval, len;
1662
1663 if (str[0] == 0)
1664 {
1665 bfd_size_type index;
1666 CONST bfd_size_type minus_one = -1;
1667
1668 #ifdef GATHER_STATISTICS
1669 tab->empty_strings++;
1670 #endif
1671 index = tab->empty_string_index;
1672 if (index != minus_one)
1673 {
1674 got_empty:
1675 #ifdef GATHER_STATISTICS
1676 tab->bytes_saved++;
1677 tab->duplicates++;
1678 #endif
1679 return index;
1680 }
1681
1682 /* Need to find it. */
1683 entry = tab->strings;
1684 if (entry)
1685 {
1686 index = entry->index + strlen (entry->string);
1687 tab->empty_string_index = index;
1688 goto got_empty;
1689 }
1690 len = 0;
1691 }
1692 else
1693 len = strlen (str);
1694
1695 /* The hash_zero value is chosen such that the first symbol gets a value of
1696 zero. With a balanced tree, this wouldn't be very useful, but without it,
1697 we might get a more even split at the top level, instead of skewing it
1698 badly should hash("/usr/lib/crt0.o") (or whatever) be far from zero. */
1699 hashval = hash (str, len) ^ tab->hash_zero;
1700 ep = &tab->strings;
1701 if (!*ep)
1702 {
1703 tab->hash_zero = hashval;
1704 hashval = 0;
1705 goto add_it;
1706 }
1707
1708 while (*ep)
1709 {
1710 register int cmp;
1711
1712 entry = *ep;
1713 #ifdef GATHER_STATISTICS
1714 tab->n_compares++;
1715 #endif
1716 cmp = compare (entry, str, hashval);
1717 /* The not-equal cases are more frequent, so check them first. */
1718 if (cmp > 0)
1719 ep = &entry->greater;
1720 else if (cmp < 0)
1721 ep = &entry->less;
1722 else
1723 {
1724 if (entry->string == str)
1725 {
1726 #ifdef GATHER_STATISTICS
1727 tab->pointer_matches++;
1728 #endif
1729 goto match;
1730 }
1731 /* Compare the first bytes to save a function call if they
1732 don't match. */
1733 if (entry->string[0] == str[0] && !strcmp (entry->string, str))
1734 {
1735 match:
1736 #ifdef GATHER_STATISTICS
1737 entry->count++;
1738 tab->bytes_saved += len + 1;
1739 tab->duplicates++;
1740 #endif
1741 /* If we're in the linker, and the new string is from a new
1742 input file which might have already had these reductions
1743 run over it, we want to keep the new string pointer. I
1744 don't think we're likely to see any (or nearly as many,
1745 at least) cases where a later string is in the same location
1746 as an earlier one rather than this one. */
1747 entry->string = str;
1748 return entry->index;
1749 }
1750 #ifdef GATHER_STATISTICS
1751 tab->bad_hash_matches++;
1752 #endif
1753 ep = &entry->greater;
1754 }
1755 }
1756
1757 /* If we get here, nothing that's in the table already matched.
1758 EP points to the `next' field at the end of the chain; stick a
1759 new entry on here. */
1760 add_it:
1761 entry = (struct stringtab_entry *)
1762 bfd_alloc_by_size_t (abfd, sizeof (struct stringtab_entry));
1763
1764 entry->less = entry->greater = 0;
1765 entry->hash = hashval;
1766 entry->index = tab->index;
1767 entry->string = str;
1768 entry->next_to_output = 0;
1769 #ifdef GATHER_STATISTICS
1770 entry->count = 1;
1771 #endif
1772
1773 assert (*tab->end == 0);
1774 *(tab->end) = entry;
1775 tab->end = &entry->next_to_output;
1776 assert (*tab->end == 0);
1777
1778 {
1779 tab->index += len + 1;
1780 if (len == 0)
1781 tab->empty_string_index = entry->index;
1782 }
1783 assert (*ep == 0);
1784 *ep = entry;
1785 return entry->index;
1786 }
1787
1788 static void
1789 emit_strtab (abfd, tab)
1790 bfd *abfd;
1791 struct stringtab_data *tab;
1792 {
1793 struct stringtab_entry *entry;
1794 #ifdef GATHER_STATISTICS
1795 int count = 0;
1796 #endif
1797
1798 /* Be sure to put string length into correct byte ordering before writing
1799 it out. */
1800 char buffer[BYTES_IN_WORD];
1801
1802 PUT_WORD (abfd, tab->index, (unsigned char *) buffer);
1803 bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd);
1804
1805 for (entry = tab->output_order; entry; entry = entry->next_to_output)
1806 {
1807 bfd_write ((PTR) entry->string, 1, strlen (entry->string) + 1, abfd);
1808 #ifdef GATHER_STATISTICS
1809 count++;
1810 #endif
1811 }
1812
1813 #ifdef GATHER_STATISTICS
1814 /* Short form only, for now.
1815 To do: Specify output file. Conditionalize on environment? Detailed
1816 analysis if desired. */
1817 {
1818 int n_syms = bfd_get_symcount (abfd);
1819
1820 fprintf (stderr, "String table data for output file:\n");
1821 fprintf (stderr, " %8d symbols output\n", n_syms);
1822 fprintf (stderr, " %8d duplicate strings\n", tab->duplicates);
1823 fprintf (stderr, " %8d empty strings\n", tab->empty_strings);
1824 fprintf (stderr, " %8d unique strings output\n", count);
1825 fprintf (stderr, " %8d pointer matches\n", tab->pointer_matches);
1826 fprintf (stderr, " %8d bytes saved\n", tab->bytes_saved);
1827 fprintf (stderr, " %8d bad hash matches\n", tab->bad_hash_matches);
1828 fprintf (stderr, " %8d hash-val comparisons\n", tab->n_compares);
1829 if (n_syms)
1830 {
1831 double n_compares = tab->n_compares;
1832 double avg_compares = n_compares / n_syms;
1833 /* The second value here should usually be near one. */
1834 fprintf (stderr,
1835 "\t average %f comparisons per symbol (%f * log2 nstrings)\n",
1836 avg_compares, avg_compares / log2 (count));
1837 }
1838 }
1839 #endif
1840
1841 /* Old code:
1842 unsigned int count;
1843 generic = bfd_get_outsymbols(abfd);
1844 for (count = 0; count < bfd_get_symcount(abfd); count++)
1845 {
1846 asymbol *g = *(generic++);
1847
1848 if (g->name)
1849 {
1850 size_t length = strlen(g->name)+1;
1851 bfd_write((PTR)g->name, 1, length, abfd);
1852 }
1853 g->KEEPIT = (KEEPITTYPE) count;
1854 } */
1855 }
1856
1857 boolean
1858 DEFUN(NAME(aout,write_syms),(abfd),
1859 bfd *abfd)
1860 {
1861 unsigned int count ;
1862 asymbol **generic = bfd_get_outsymbols (abfd);
1863 struct stringtab_data strtab;
1864
1865 stringtab_init (&strtab);
1866
1867 for (count = 0; count < bfd_get_symcount (abfd); count++)
1868 {
1869 asymbol *g = generic[count];
1870 struct external_nlist nsp;
1871
1872 if (g->name)
1873 PUT_WORD (abfd, add_to_stringtab (abfd, g->name, &strtab),
1874 (unsigned char *) nsp.e_strx);
1875 else
1876 PUT_WORD (abfd, 0, (unsigned char *)nsp.e_strx);
1877
1878 if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
1879 {
1880 bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc);
1881 bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other);
1882 bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type);
1883 }
1884 else
1885 {
1886 bfd_h_put_16(abfd,0, nsp.e_desc);
1887 bfd_h_put_8(abfd, 0, nsp.e_other);
1888 bfd_h_put_8(abfd, 0, nsp.e_type);
1889 }
1890
1891 if (! translate_to_native_sym_flags (&nsp, g, abfd))
1892 return false;
1893
1894 if (bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd)
1895 != EXTERNAL_NLIST_SIZE)
1896 return false;
1897
1898 /* NB: `KEEPIT' currently overlays `flags', so set this only
1899 here, at the end. */
1900 g->KEEPIT = count;
1901 }
1902
1903 emit_strtab (abfd, &strtab);
1904
1905 return true;
1906 }
1907
1908 \f
1909 unsigned int
1910 DEFUN(NAME(aout,get_symtab),(abfd, location),
1911 bfd *abfd AND
1912 asymbol **location)
1913 {
1914 unsigned int counter = 0;
1915 aout_symbol_type *symbase;
1916
1917 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1918
1919 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1920 *(location++) = (asymbol *)( symbase++);
1921 *location++ =0;
1922 return bfd_get_symcount (abfd);
1923 }
1924
1925 \f
1926 /* Standard reloc stuff */
1927 /* Output standard relocation information to a file in target byte order. */
1928
1929 void
1930 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1931 bfd *abfd AND
1932 arelent *g AND
1933 struct reloc_std_external *natptr)
1934 {
1935 int r_index;
1936 asymbol *sym = *(g->sym_ptr_ptr);
1937 int r_extern;
1938 unsigned int r_length;
1939 int r_pcrel;
1940 int r_baserel, r_jmptable, r_relative;
1941 asection *output_section = sym->section->output_section;
1942
1943 PUT_WORD(abfd, g->address, natptr->r_address);
1944
1945 r_length = g->howto->size ; /* Size as a power of two */
1946 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1947 /* XXX This relies on relocs coming from a.out files. */
1948 r_baserel = (g->howto->type & 8) != 0;
1949 /* r_jmptable, r_relative??? FIXME-soon */
1950 r_jmptable = 0;
1951 r_relative = 0;
1952
1953 #if 0
1954 /* For a standard reloc, the addend is in the object file. */
1955 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1956 #endif
1957
1958 /* name was clobbered by aout_write_syms to be symbol index */
1959
1960 /* If this relocation is relative to a symbol then set the
1961 r_index to the symbols index, and the r_extern bit.
1962
1963 Absolute symbols can come in in two ways, either as an offset
1964 from the abs section, or as a symbol which has an abs value.
1965 check for that here
1966 */
1967
1968
1969 if (bfd_is_com_section (output_section)
1970 || output_section == &bfd_abs_section
1971 || output_section == &bfd_und_section)
1972 {
1973 if (bfd_abs_section.symbol == sym)
1974 {
1975 /* Whoops, looked like an abs symbol, but is really an offset
1976 from the abs section */
1977 r_index = 0;
1978 r_extern = 0;
1979 }
1980 else
1981 {
1982 /* Fill in symbol */
1983 r_extern = 1;
1984 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
1985
1986 }
1987 }
1988 else
1989 {
1990 /* Just an ordinary section */
1991 r_extern = 0;
1992 r_index = output_section->target_index;
1993 }
1994
1995 /* now the fun stuff */
1996 if (abfd->xvec->header_byteorder_big_p != false) {
1997 natptr->r_index[0] = r_index >> 16;
1998 natptr->r_index[1] = r_index >> 8;
1999 natptr->r_index[2] = r_index;
2000 natptr->r_type[0] =
2001 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
2002 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
2003 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
2004 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
2005 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
2006 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
2007 } else {
2008 natptr->r_index[2] = r_index >> 16;
2009 natptr->r_index[1] = r_index >> 8;
2010 natptr->r_index[0] = r_index;
2011 natptr->r_type[0] =
2012 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
2013 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
2014 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
2015 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
2016 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
2017 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
2018 }
2019 }
2020
2021
2022 /* Extended stuff */
2023 /* Output extended relocation information to a file in target byte order. */
2024
2025 void
2026 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
2027 bfd *abfd AND
2028 arelent *g AND
2029 register struct reloc_ext_external *natptr)
2030 {
2031 int r_index;
2032 int r_extern;
2033 unsigned int r_type;
2034 unsigned int r_addend;
2035 asymbol *sym = *(g->sym_ptr_ptr);
2036 asection *output_section = sym->section->output_section;
2037
2038 PUT_WORD (abfd, g->address, natptr->r_address);
2039
2040 r_type = (unsigned int) g->howto->type;
2041
2042 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
2043
2044 /* If this relocation is relative to a symbol then set the
2045 r_index to the symbols index, and the r_extern bit.
2046
2047 Absolute symbols can come in in two ways, either as an offset
2048 from the abs section, or as a symbol which has an abs value.
2049 check for that here. */
2050
2051 if (bfd_is_com_section (output_section)
2052 || output_section == &bfd_abs_section
2053 || output_section == &bfd_und_section)
2054 {
2055 if (bfd_abs_section.symbol == sym)
2056 {
2057 /* Whoops, looked like an abs symbol, but is really an offset
2058 from the abs section */
2059 r_index = 0;
2060 r_extern = 0;
2061 }
2062 else
2063 {
2064 r_extern = 1;
2065 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
2066 }
2067 }
2068 else
2069 {
2070 /* Just an ordinary section */
2071 r_extern = 0;
2072 r_index = output_section->target_index;
2073 }
2074
2075 /* now the fun stuff */
2076 if (abfd->xvec->header_byteorder_big_p != false) {
2077 natptr->r_index[0] = r_index >> 16;
2078 natptr->r_index[1] = r_index >> 8;
2079 natptr->r_index[2] = r_index;
2080 natptr->r_type[0] =
2081 ((r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
2082 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
2083 } else {
2084 natptr->r_index[2] = r_index >> 16;
2085 natptr->r_index[1] = r_index >> 8;
2086 natptr->r_index[0] = r_index;
2087 natptr->r_type[0] =
2088 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
2089 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
2090 }
2091
2092 PUT_WORD (abfd, r_addend, natptr->r_addend);
2093 }
2094
2095 /* BFD deals internally with all things based from the section they're
2096 in. so, something in 10 bytes into a text section with a base of
2097 50 would have a symbol (.text+10) and know .text vma was 50.
2098
2099 Aout keeps all it's symbols based from zero, so the symbol would
2100 contain 60. This macro subs the base of each section from the value
2101 to give the true offset from the section */
2102
2103
2104 #define MOVE_ADDRESS(ad) \
2105 if (r_extern) { \
2106 /* undefined symbol */ \
2107 cache_ptr->sym_ptr_ptr = symbols + r_index; \
2108 cache_ptr->addend = ad; \
2109 } else { \
2110 /* defined, section relative. replace symbol with pointer to \
2111 symbol which points to section */ \
2112 switch (r_index) { \
2113 case N_TEXT: \
2114 case N_TEXT | N_EXT: \
2115 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
2116 cache_ptr->addend = ad - su->textsec->vma; \
2117 break; \
2118 case N_DATA: \
2119 case N_DATA | N_EXT: \
2120 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
2121 cache_ptr->addend = ad - su->datasec->vma; \
2122 break; \
2123 case N_BSS: \
2124 case N_BSS | N_EXT: \
2125 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
2126 cache_ptr->addend = ad - su->bsssec->vma; \
2127 break; \
2128 default: \
2129 case N_ABS: \
2130 case N_ABS | N_EXT: \
2131 cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; \
2132 cache_ptr->addend = ad; \
2133 break; \
2134 } \
2135 } \
2136
2137 void
2138 DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
2139 bfd *abfd AND
2140 struct reloc_ext_external *bytes AND
2141 arelent *cache_ptr AND
2142 asymbol **symbols)
2143 {
2144 int r_index;
2145 int r_extern;
2146 unsigned int r_type;
2147 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2148
2149 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2150
2151 /* now the fun stuff */
2152 if (abfd->xvec->header_byteorder_big_p != false) {
2153 r_index = (bytes->r_index[0] << 16)
2154 | (bytes->r_index[1] << 8)
2155 | bytes->r_index[2];
2156 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2157 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2158 >> RELOC_EXT_BITS_TYPE_SH_BIG;
2159 } else {
2160 r_index = (bytes->r_index[2] << 16)
2161 | (bytes->r_index[1] << 8)
2162 | bytes->r_index[0];
2163 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2164 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2165 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
2166 }
2167
2168 cache_ptr->howto = howto_table_ext + r_type;
2169 MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
2170 }
2171
2172 void
2173 DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
2174 bfd *abfd AND
2175 struct reloc_std_external *bytes AND
2176 arelent *cache_ptr AND
2177 asymbol **symbols)
2178 {
2179 int r_index;
2180 int r_extern;
2181 unsigned int r_length;
2182 int r_pcrel;
2183 int r_baserel, r_jmptable, r_relative;
2184 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2185 int howto_idx;
2186
2187 cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
2188
2189 /* now the fun stuff */
2190 if (abfd->xvec->header_byteorder_big_p != false) {
2191 r_index = (bytes->r_index[0] << 16)
2192 | (bytes->r_index[1] << 8)
2193 | bytes->r_index[2];
2194 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2195 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2196 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2197 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2198 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2199 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2200 >> RELOC_STD_BITS_LENGTH_SH_BIG;
2201 } else {
2202 r_index = (bytes->r_index[2] << 16)
2203 | (bytes->r_index[1] << 8)
2204 | bytes->r_index[0];
2205 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2206 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2207 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2208 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2209 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2210 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2211 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
2212 }
2213
2214 howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel;
2215 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
2216 cache_ptr->howto = howto_table_std + howto_idx;
2217 BFD_ASSERT (cache_ptr->howto->type != -1);
2218 BFD_ASSERT (r_jmptable == 0);
2219 BFD_ASSERT (r_relative == 0);
2220 /* FIXME-soon: Roll jmptable, relative bits into howto setting */
2221
2222 MOVE_ADDRESS(0);
2223 }
2224
2225 /* Reloc hackery */
2226
2227 boolean
2228 DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
2229 bfd *abfd AND
2230 sec_ptr asect AND
2231 asymbol **symbols)
2232 {
2233 unsigned int count;
2234 bfd_size_type reloc_size;
2235 PTR relocs;
2236 arelent *reloc_cache;
2237 size_t each_size;
2238
2239 if (asect->relocation) return true;
2240
2241 if (asect->flags & SEC_CONSTRUCTOR) return true;
2242
2243 if (asect == obj_datasec (abfd)) {
2244 reloc_size = exec_hdr(abfd)->a_drsize;
2245 } else if (asect == obj_textsec (abfd)) {
2246 reloc_size = exec_hdr(abfd)->a_trsize;
2247 } else {
2248 bfd_error = invalid_operation;
2249 return false;
2250 }
2251
2252 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
2253 each_size = obj_reloc_entry_size (abfd);
2254
2255 count = reloc_size / each_size;
2256
2257
2258 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
2259 (arelent)));
2260 if (!reloc_cache) {
2261 nomem:
2262 bfd_error = no_memory;
2263 return false;
2264 }
2265
2266 relocs = (PTR) bfd_alloc (abfd, reloc_size);
2267 if (!relocs) {
2268 bfd_release (abfd, reloc_cache);
2269 goto nomem;
2270 }
2271
2272 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
2273 bfd_release (abfd, relocs);
2274 bfd_release (abfd, reloc_cache);
2275 bfd_error = system_call_error;
2276 return false;
2277 }
2278
2279 if (each_size == RELOC_EXT_SIZE) {
2280 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
2281 unsigned int counter = 0;
2282 arelent *cache_ptr = reloc_cache;
2283
2284 for (; counter < count; counter++, rptr++, cache_ptr++) {
2285 NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
2286 }
2287 } else {
2288 register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
2289 unsigned int counter = 0;
2290 arelent *cache_ptr = reloc_cache;
2291
2292 for (; counter < count; counter++, rptr++, cache_ptr++) {
2293 NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
2294 }
2295
2296 }
2297
2298 bfd_release (abfd,relocs);
2299 asect->relocation = reloc_cache;
2300 asect->reloc_count = count;
2301 return true;
2302 }
2303
2304
2305
2306 /* Write out a relocation section into an object file. */
2307
2308 boolean
2309 DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
2310 bfd *abfd AND
2311 asection *section)
2312 {
2313 arelent **generic;
2314 unsigned char *native, *natptr;
2315 size_t each_size;
2316
2317 unsigned int count = section->reloc_count;
2318 size_t natsize;
2319
2320 if (count == 0) return true;
2321
2322 each_size = obj_reloc_entry_size (abfd);
2323 natsize = each_size * count;
2324 native = (unsigned char *) bfd_zalloc (abfd, natsize);
2325 if (!native) {
2326 bfd_error = no_memory;
2327 return false;
2328 }
2329
2330 generic = section->orelocation;
2331
2332 if (each_size == RELOC_EXT_SIZE)
2333 {
2334 for (natptr = native;
2335 count != 0;
2336 --count, natptr += each_size, ++generic)
2337 NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
2338 }
2339 else
2340 {
2341 for (natptr = native;
2342 count != 0;
2343 --count, natptr += each_size, ++generic)
2344 NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
2345 }
2346
2347 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
2348 bfd_release(abfd, native);
2349 return false;
2350 }
2351 bfd_release (abfd, native);
2352
2353 return true;
2354 }
2355
2356 /* This is stupid. This function should be a boolean predicate */
2357 unsigned int
2358 DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
2359 bfd *abfd AND
2360 sec_ptr section AND
2361 arelent **relptr AND
2362 asymbol **symbols)
2363 {
2364 arelent *tblptr = section->relocation;
2365 unsigned int count;
2366
2367 if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
2368 return 0;
2369
2370 if (section->flags & SEC_CONSTRUCTOR) {
2371 arelent_chain *chain = section->constructor_chain;
2372 for (count = 0; count < section->reloc_count; count ++) {
2373 *relptr ++ = &chain->relent;
2374 chain = chain->next;
2375 }
2376 }
2377 else {
2378 tblptr = section->relocation;
2379 if (!tblptr) return 0;
2380
2381 for (count = 0; count++ < section->reloc_count;)
2382 {
2383 *relptr++ = tblptr++;
2384 }
2385 }
2386 *relptr = 0;
2387
2388 return section->reloc_count;
2389 }
2390
2391 unsigned int
2392 DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
2393 bfd *abfd AND
2394 sec_ptr asect)
2395 {
2396 if (bfd_get_format (abfd) != bfd_object) {
2397 bfd_error = invalid_operation;
2398 return 0;
2399 }
2400 if (asect->flags & SEC_CONSTRUCTOR) {
2401 return (sizeof (arelent *) * (asect->reloc_count+1));
2402 }
2403
2404
2405 if (asect == obj_datasec (abfd))
2406 return (sizeof (arelent *) *
2407 ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
2408 +1));
2409
2410 if (asect == obj_textsec (abfd))
2411 return (sizeof (arelent *) *
2412 ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
2413 +1));
2414
2415 bfd_error = invalid_operation;
2416 return 0;
2417 }
2418
2419 \f
2420 unsigned int
2421 DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
2422 bfd *abfd)
2423 {
2424 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
2425
2426 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2427 }
2428
2429 /*ARGSUSED*/
2430 alent *
2431 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
2432 bfd *ignore_abfd AND
2433 asymbol *ignore_symbol)
2434 {
2435 return (alent *)NULL;
2436 }
2437
2438 /*ARGSUSED*/
2439 void
2440 DEFUN(NAME(aout,get_symbol_info),(ignore_abfd, symbol, ret),
2441 bfd *ignore_abfd AND
2442 asymbol *symbol AND
2443 symbol_info *ret)
2444 {
2445 bfd_symbol_info (symbol, ret);
2446
2447 if (ret->type == '?')
2448 {
2449 int type_code = aout_symbol(symbol)->type & 0xff;
2450 CONST char *stab_name = aout_stab_name(type_code);
2451 static char buf[10];
2452
2453 if (stab_name == NULL)
2454 {
2455 sprintf(buf, "(%d)", type_code);
2456 stab_name = buf;
2457 }
2458 ret->type = '-';
2459 ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
2460 ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
2461 ret->stab_name = stab_name;
2462 }
2463 }
2464
2465 /*ARGSUSED*/
2466 void
2467 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
2468 bfd *ignore_abfd AND
2469 PTR afile AND
2470 asymbol *symbol AND
2471 bfd_print_symbol_type how)
2472 {
2473 FILE *file = (FILE *)afile;
2474
2475 switch (how) {
2476 case bfd_print_symbol_name:
2477 if (symbol->name)
2478 fprintf(file,"%s", symbol->name);
2479 break;
2480 case bfd_print_symbol_more:
2481 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
2482 (unsigned)(aout_symbol(symbol)->other & 0xff),
2483 (unsigned)(aout_symbol(symbol)->type));
2484 break;
2485 case bfd_print_symbol_all:
2486 {
2487 CONST char *section_name = symbol->section->name;
2488
2489
2490 bfd_print_symbol_vandf((PTR)file,symbol);
2491
2492 fprintf(file," %-5s %04x %02x %02x",
2493 section_name,
2494 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
2495 (unsigned)(aout_symbol(symbol)->other & 0xff),
2496 (unsigned)(aout_symbol(symbol)->type & 0xff));
2497 if (symbol->name)
2498 fprintf(file," %s", symbol->name);
2499 }
2500 break;
2501 }
2502 }
2503
2504 /*
2505 provided a BFD, a section and an offset into the section, calculate
2506 and return the name of the source file and the line nearest to the
2507 wanted location.
2508 */
2509
2510 boolean
2511 DEFUN(NAME(aout,find_nearest_line),(abfd,
2512 section,
2513 symbols,
2514 offset,
2515 filename_ptr,
2516 functionname_ptr,
2517 line_ptr),
2518 bfd *abfd AND
2519 asection *section AND
2520 asymbol **symbols AND
2521 bfd_vma offset AND
2522 CONST char **filename_ptr AND
2523 CONST char **functionname_ptr AND
2524 unsigned int *line_ptr)
2525 {
2526 /* Run down the file looking for the filename, function and linenumber */
2527 asymbol **p;
2528 static char buffer[100];
2529 static char filename_buffer[200];
2530 CONST char *directory_name = NULL;
2531 CONST char *main_file_name = NULL;
2532 CONST char *current_file_name = NULL;
2533 CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
2534 bfd_vma high_line_vma = ~0;
2535 bfd_vma low_func_vma = 0;
2536 asymbol *func = 0;
2537 *filename_ptr = abfd->filename;
2538 *functionname_ptr = 0;
2539 *line_ptr = 0;
2540 if (symbols != (asymbol **)NULL) {
2541 for (p = symbols; *p; p++) {
2542 aout_symbol_type *q = (aout_symbol_type *)(*p);
2543 next:
2544 switch (q->type){
2545 case N_SO:
2546 main_file_name = current_file_name = q->symbol.name;
2547 /* Look ahead to next symbol to check if that too is an N_SO. */
2548 p++;
2549 if (*p == NULL)
2550 break;
2551 q = (aout_symbol_type *)(*p);
2552 if (q->type != (int)N_SO)
2553 goto next;
2554
2555 /* Found a second N_SO First is directory; second is filename. */
2556 directory_name = current_file_name;
2557 main_file_name = current_file_name = q->symbol.name;
2558 if (obj_textsec(abfd) != section)
2559 goto done;
2560 break;
2561 case N_SOL:
2562 current_file_name = q->symbol.name;
2563 break;
2564
2565 case N_SLINE:
2566
2567 case N_DSLINE:
2568 case N_BSLINE:
2569 /* We'll keep this if it resolves nearer than the one we have already */
2570 if (q->symbol.value >= offset &&
2571 q->symbol.value < high_line_vma) {
2572 *line_ptr = q->desc;
2573 high_line_vma = q->symbol.value;
2574 line_file_name = current_file_name;
2575 }
2576 break;
2577 case N_FUN:
2578 {
2579 /* We'll keep this if it is nearer than the one we have already */
2580 if (q->symbol.value >= low_func_vma &&
2581 q->symbol.value <= offset) {
2582 low_func_vma = q->symbol.value;
2583 func = (asymbol *)q;
2584 }
2585 if (*line_ptr && func) {
2586 CONST char *function = func->name;
2587 char *p;
2588 strncpy(buffer, function, sizeof(buffer)-1);
2589 buffer[sizeof(buffer)-1] = 0;
2590 /* Have to remove : stuff */
2591 p = strchr(buffer,':');
2592 if (p != NULL) { *p = '\0'; }
2593 *functionname_ptr = buffer;
2594 goto done;
2595
2596 }
2597 }
2598 break;
2599 }
2600 }
2601 }
2602
2603 done:
2604 if (*line_ptr)
2605 main_file_name = line_file_name;
2606 if (main_file_name) {
2607 if (main_file_name[0] == '/' || directory_name == NULL)
2608 *filename_ptr = main_file_name;
2609 else {
2610 sprintf(filename_buffer, "%.140s%.50s",
2611 directory_name, main_file_name);
2612 *filename_ptr = filename_buffer;
2613 }
2614 }
2615 return true;
2616
2617 }
2618
2619 /*ARGSUSED*/
2620 int
2621 DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
2622 bfd *abfd AND
2623 boolean execable)
2624 {
2625 return adata(abfd).exec_bytes_size;
2626 }
2627 \f
2628 /* a.out link code. */
2629
2630 /* a.out linker hash table entries. */
2631
2632 struct aout_link_hash_entry
2633 {
2634 struct bfd_link_hash_entry root;
2635 /* Symbol index in output file. */
2636 int indx;
2637 };
2638
2639 /* a.out linker hash table. */
2640
2641 struct aout_link_hash_table
2642 {
2643 struct bfd_link_hash_table root;
2644 };
2645
2646 static struct bfd_hash_entry *aout_link_hash_newfunc
2647 PARAMS ((struct bfd_hash_entry *entry,
2648 struct bfd_hash_table *table,
2649 const char *string));
2650 static boolean aout_link_add_object_symbols
2651 PARAMS ((bfd *, struct bfd_link_info *));
2652 static boolean aout_link_check_archive_element
2653 PARAMS ((bfd *, struct bfd_link_info *, boolean *));
2654 static boolean aout_link_get_symbols PARAMS ((bfd *));
2655 static boolean aout_link_free_symbols PARAMS ((bfd *));
2656 static boolean aout_link_check_ar_symbols
2657 PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
2658 static boolean aout_link_add_symbols
2659 PARAMS ((bfd *, struct bfd_link_info *));
2660
2661 /* Routine to create an entry in an a.out link hash table. */
2662
2663 static struct bfd_hash_entry *
2664 aout_link_hash_newfunc (entry, table, string)
2665 struct bfd_hash_entry *entry;
2666 struct bfd_hash_table *table;
2667 const char *string;
2668 {
2669 struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
2670
2671 /* Allocate the structure if it has not already been allocated by a
2672 subclass. */
2673 if (ret == (struct aout_link_hash_entry *) NULL)
2674 ret = ((struct aout_link_hash_entry *)
2675 bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
2676
2677 /* Call the allocation method of the superclass. */
2678 ret = ((struct aout_link_hash_entry *)
2679 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2680 table, string));
2681
2682 /* Set local fields. */
2683 ret->indx = -1;
2684
2685 return (struct bfd_hash_entry *) ret;
2686 }
2687
2688 /* Create an a.out link hash table. */
2689
2690 struct bfd_link_hash_table *
2691 NAME(aout,link_hash_table_create) (abfd)
2692 bfd *abfd;
2693 {
2694 struct aout_link_hash_table *ret;
2695
2696 ret = ((struct aout_link_hash_table *)
2697 bfd_xmalloc (sizeof (struct aout_link_hash_table)));
2698 if (! _bfd_link_hash_table_init (&ret->root, abfd,
2699 aout_link_hash_newfunc))
2700 {
2701 free (ret);
2702 return (struct bfd_link_hash_table *) NULL;
2703 }
2704 return &ret->root;
2705 }
2706
2707 /* Look up an entry in an a.out link hash table. */
2708
2709 #define aout_link_hash_lookup(table, string, create, copy, follow) \
2710 ((struct aout_link_hash_entry *) \
2711 bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
2712
2713 /* Traverse an a.out link hash table. */
2714
2715 #define aout_link_hash_traverse(table, func, info) \
2716 (bfd_link_hash_traverse \
2717 (&(table)->root, \
2718 (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
2719 (info)))
2720
2721 /* Get the a.out link hash table from the info structure. This is
2722 just a cast. */
2723
2724 #define aout_hash_table(p) ((struct aout_link_hash_table *) ((p)->hash))
2725
2726 /* Given an a.out BFD, add symbols to the global hash table as
2727 appropriate. */
2728
2729 boolean
2730 NAME(aout,link_add_symbols) (abfd, info)
2731 bfd *abfd;
2732 struct bfd_link_info *info;
2733 {
2734 switch (bfd_get_format (abfd))
2735 {
2736 case bfd_object:
2737 return aout_link_add_object_symbols (abfd, info);
2738 case bfd_archive:
2739 return _bfd_generic_link_add_archive_symbols
2740 (abfd, info, aout_link_check_archive_element);
2741 default:
2742 bfd_error = wrong_format;
2743 return false;
2744 }
2745 }
2746
2747 /* Add symbols from an a.out object file. */
2748
2749 static boolean
2750 aout_link_add_object_symbols (abfd, info)
2751 bfd *abfd;
2752 struct bfd_link_info *info;
2753 {
2754 if (! aout_link_get_symbols (abfd))
2755 return false;
2756 if (! aout_link_add_symbols (abfd, info))
2757 return false;
2758 if (! info->keep_memory)
2759 {
2760 if (! aout_link_free_symbols (abfd))
2761 return false;
2762 }
2763 return true;
2764 }
2765
2766 /* Check a single archive element to see if we need to include it in
2767 the link. *PNEEDED is set according to whether this element is
2768 needed in the link or not. This is called from
2769 _bfd_generic_link_add_archive_symbols. */
2770
2771 static boolean
2772 aout_link_check_archive_element (abfd, info, pneeded)
2773 bfd *abfd;
2774 struct bfd_link_info *info;
2775 boolean *pneeded;
2776 {
2777 if (! aout_link_get_symbols (abfd))
2778 return false;
2779
2780 if (! aout_link_check_ar_symbols (abfd, info, pneeded))
2781 return false;
2782
2783 if (*pneeded)
2784 {
2785 if (! aout_link_add_symbols (abfd, info))
2786 return false;
2787 }
2788
2789 /* We keep around the symbols even if we aren't going to use this
2790 object file, because we may want to reread it. This doesn't
2791 waste too much memory, because it isn't all that common to read
2792 an archive element but not need it. */
2793 if (! info->keep_memory)
2794 {
2795 if (! aout_link_free_symbols (abfd))
2796 return false;
2797 }
2798
2799 return true;
2800 }
2801
2802 /* Read the internal symbols from an a.out file. */
2803
2804 static boolean
2805 aout_link_get_symbols (abfd)
2806 bfd *abfd;
2807 {
2808 bfd_size_type count;
2809 struct external_nlist *syms;
2810 unsigned char string_chars[BYTES_IN_WORD];
2811 bfd_size_type stringsize;
2812 char *strings;
2813
2814 if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
2815 {
2816 /* We already have them. */
2817 return true;
2818 }
2819
2820 count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
2821
2822 /* We allocate using bfd_xmalloc to make the values easy to free
2823 later on. If we put them on the obstack it might not be possible
2824 to free them. */
2825 syms = ((struct external_nlist *)
2826 bfd_xmalloc ((size_t) count * EXTERNAL_NLIST_SIZE));
2827
2828 if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
2829 || (bfd_read ((PTR) syms, 1, exec_hdr (abfd)->a_syms, abfd)
2830 != exec_hdr (abfd)->a_syms))
2831 return false;
2832
2833 /* Get the size of the strings. */
2834 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
2835 || (bfd_read ((PTR) string_chars, BYTES_IN_WORD, 1, abfd)
2836 != BYTES_IN_WORD))
2837 return false;
2838 stringsize = GET_WORD (abfd, string_chars);
2839 strings = (char *) bfd_xmalloc ((size_t) stringsize);
2840
2841 /* Skip space for the string count in the buffer for convenience
2842 when using indexes. */
2843 if (bfd_read (strings + BYTES_IN_WORD, 1, stringsize - BYTES_IN_WORD, abfd)
2844 != stringsize - BYTES_IN_WORD)
2845 return false;
2846
2847 /* Save the data. */
2848 obj_aout_external_syms (abfd) = syms;
2849 obj_aout_external_sym_count (abfd) = count;
2850 obj_aout_external_strings (abfd) = strings;
2851
2852 return true;
2853 }
2854
2855 /* Free up the internal symbols read from an a.out file. */
2856
2857 static boolean
2858 aout_link_free_symbols (abfd)
2859 bfd *abfd;
2860 {
2861 if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
2862 {
2863 free ((PTR) obj_aout_external_syms (abfd));
2864 obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
2865 }
2866 if (obj_aout_external_strings (abfd) != (char *) NULL)
2867 {
2868 free ((PTR) obj_aout_external_strings (abfd));
2869 obj_aout_external_strings (abfd) = (char *) NULL;
2870 }
2871 return true;
2872 }
2873
2874 /* Look through the internal symbols to see if this object file should
2875 be included in the link. We should include this object file if it
2876 defines any symbols which are currently undefined. If this object
2877 file defines a common symbol, then we may adjust the size of the
2878 known symbol but we do not include the object file in the link
2879 (unless there is some other reason to include it). */
2880
2881 static boolean
2882 aout_link_check_ar_symbols (abfd, info, pneeded)
2883 bfd *abfd;
2884 struct bfd_link_info *info;
2885 boolean *pneeded;
2886 {
2887 register struct external_nlist *p;
2888 struct external_nlist *pend;
2889 char *strings;
2890
2891 *pneeded = false;
2892
2893 /* Look through all the symbols. */
2894 p = obj_aout_external_syms (abfd);
2895 pend = p + obj_aout_external_sym_count (abfd);
2896 strings = obj_aout_external_strings (abfd);
2897 for (; p < pend; p++)
2898 {
2899 int type = bfd_h_get_8 (abfd, p->e_type);
2900 const char *name;
2901 struct bfd_link_hash_entry *h;
2902
2903 /* Ignore symbols that are not externally visible. */
2904 if ((type & N_EXT) == 0)
2905 continue;
2906
2907 name = strings + GET_WORD (abfd, p->e_strx);
2908 h = bfd_link_hash_lookup (info->hash, name, false, false, true);
2909
2910 /* We are only interested in symbols that are currently
2911 undefined or common. */
2912 if (h == (struct bfd_link_hash_entry *) NULL
2913 || (h->type != bfd_link_hash_undefined
2914 && h->type != bfd_link_hash_common))
2915 continue;
2916
2917 if ((type & (N_TEXT | N_DATA | N_BSS)) != 0)
2918 {
2919 /* This object file defines this symbol. We must link it
2920 in. This is true regardless of whether the current
2921 definition of the symbol is undefined or common. If the
2922 current definition is common, we have a case in which we
2923 have already seen an object file including
2924 int a;
2925 and this object file from the archive includes
2926 int a = 5;
2927 In such a case we must include this object file. */
2928 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
2929 return false;
2930 *pneeded = true;
2931 return true;
2932 }
2933
2934 if (type == (N_EXT | N_UNDF))
2935 {
2936 bfd_vma value;
2937
2938 value = GET_WORD (abfd, p->e_value);
2939 if (value != 0)
2940 {
2941 /* This symbol is common in the object from the archive
2942 file. */
2943 if (h->type == bfd_link_hash_undefined)
2944 {
2945 bfd *symbfd;
2946
2947 symbfd = h->u.undef.abfd;
2948 if (symbfd == (bfd *) NULL)
2949 {
2950 /* This symbol was created as undefined from
2951 outside BFD. We assume that we should link
2952 in the object file. This is done for the -u
2953 option in the linker. */
2954 if (! (*info->callbacks->add_archive_element) (info,
2955 abfd,
2956 name))
2957 return false;
2958 *pneeded = true;
2959 return true;
2960 }
2961 /* Turn the current link symbol into a common
2962 symbol. It is already on the undefs list. */
2963 h->type = bfd_link_hash_common;
2964 h->u.c.size = value;
2965 h->u.c.section = bfd_make_section_old_way (symbfd,
2966 "COMMON");
2967 }
2968 else
2969 {
2970 /* Adjust the size of the common symbol if
2971 necessary. */
2972 if (value > h->u.c.size)
2973 h->u.c.size = value;
2974 }
2975 }
2976 }
2977 }
2978
2979 /* We do not need this object file. */
2980 return true;
2981 }
2982
2983 /* Add all symbols from an object file to the hash table. */
2984
2985 static boolean
2986 aout_link_add_symbols (abfd, info)
2987 bfd *abfd;
2988 struct bfd_link_info *info;
2989 {
2990 bfd_size_type sym_count;
2991 char *strings;
2992 boolean copy;
2993 struct aout_link_hash_entry **sym_hash;
2994 register struct external_nlist *p;
2995 struct external_nlist *pend;
2996
2997 sym_count = obj_aout_external_sym_count (abfd);
2998 strings = obj_aout_external_strings (abfd);
2999 if (info->keep_memory)
3000 copy = false;
3001 else
3002 copy = true;
3003
3004 /* We keep a list of the linker hash table entries that correspond
3005 to particular symbols. We could just look them up in the hash
3006 table, but keeping the list is more efficient. Perhaps this
3007 should be conditional on info->keep_memory. */
3008 sym_hash = ((struct aout_link_hash_entry **)
3009 bfd_alloc (abfd,
3010 ((size_t) sym_count
3011 * sizeof (struct aout_link_hash_entry *))));
3012 obj_aout_sym_hashes (abfd) = sym_hash;
3013
3014 p = obj_aout_external_syms (abfd);
3015 pend = p + sym_count;
3016 for (; p < pend; p++, sym_hash++)
3017 {
3018 int type;
3019 const char *name;
3020 bfd_vma value;
3021 asection *section;
3022 flagword flags;
3023 const char *string;
3024
3025 *sym_hash = NULL;
3026
3027 type = bfd_h_get_8 (abfd, p->e_type);
3028
3029 /* Ignore debugging symbols. */
3030 if ((type & N_STAB) != 0)
3031 continue;
3032
3033 /* Ignore symbols that are not external. */
3034 if ((type & N_EXT) == 0
3035 && type != N_WARNING
3036 && type != N_SETA
3037 && type != N_SETT
3038 && type != N_SETD
3039 && type != N_SETB)
3040 {
3041 /* If this is an N_INDR symbol we must skip the next entry,
3042 which is the symbol to indirect to (actually, an N_INDR
3043 symbol without N_EXT set is pretty useless). */
3044 if (type == N_INDR)
3045 {
3046 ++p;
3047 ++sym_hash;
3048 }
3049 continue;
3050 }
3051
3052 /* Ignore N_FN symbols (these appear to have N_EXT set). */
3053 if (type == N_FN)
3054 continue;
3055
3056 name = strings + GET_WORD (abfd, p->e_strx);
3057 value = GET_WORD (abfd, p->e_value);
3058 flags = BSF_GLOBAL;
3059 string = NULL;
3060 switch (type)
3061 {
3062 default:
3063 abort ();
3064 case N_UNDF | N_EXT:
3065 if (value != 0)
3066 section = &bfd_com_section;
3067 else
3068 section = &bfd_und_section;
3069 break;
3070 case N_ABS | N_EXT:
3071 section = &bfd_abs_section;
3072 break;
3073 case N_TEXT | N_EXT:
3074 section = obj_textsec (abfd);
3075 value -= bfd_get_section_vma (abfd, section);
3076 break;
3077 case N_DATA | N_EXT:
3078 section = obj_datasec (abfd);
3079 value -= bfd_get_section_vma (abfd, section);
3080 break;
3081 case N_BSS | N_EXT:
3082 section = obj_bsssec (abfd);
3083 value -= bfd_get_section_vma (abfd, section);
3084 break;
3085 case N_INDR | N_EXT:
3086 /* An indirect symbol. The next symbol is the symbol
3087 which this one really is. */
3088 BFD_ASSERT (p + 1 < pend);
3089 ++p;
3090 string = strings + GET_WORD (abfd, p->e_strx);
3091 section = &bfd_ind_section;
3092 flags |= BSF_INDIRECT;
3093 break;
3094 case N_COMM | N_EXT:
3095 section = &bfd_com_section;
3096 break;
3097 case N_SETA: case N_SETA | N_EXT:
3098 section = &bfd_abs_section;
3099 flags |= BSF_CONSTRUCTOR;
3100 break;
3101 case N_SETT: case N_SETT | N_EXT:
3102 section = obj_textsec (abfd);
3103 flags |= BSF_CONSTRUCTOR;
3104 value -= bfd_get_section_vma (abfd, section);
3105 break;
3106 case N_SETD: case N_SETD | N_EXT:
3107 section = obj_datasec (abfd);
3108 flags |= BSF_CONSTRUCTOR;
3109 value -= bfd_get_section_vma (abfd, section);
3110 break;
3111 case N_SETB: case N_SETB | N_EXT:
3112 section = obj_bsssec (abfd);
3113 flags |= BSF_CONSTRUCTOR;
3114 value -= bfd_get_section_vma (abfd, section);
3115 break;
3116 case N_WARNING:
3117 /* A warning symbol. The next symbol is the one to warn
3118 about. */
3119 BFD_ASSERT (p + 1 < pend);
3120 ++p;
3121 string = name;
3122 name = strings + GET_WORD (abfd, p->e_strx);
3123 section = &bfd_und_section;
3124 flags |= BSF_WARNING;
3125 break;
3126 }
3127
3128 if (! (_bfd_generic_link_add_one_symbol
3129 (info, abfd, name, flags, section, value, string, copy, false,
3130 ARCH_SIZE, (struct bfd_link_hash_entry **) sym_hash)))
3131 return false;
3132
3133 if (type == (N_INDR | N_EXT) || type == N_WARNING)
3134 ++sym_hash;
3135 }
3136
3137 return true;
3138 }
3139
3140 /* During the final link step we need to pass around a bunch of
3141 information, so we do it in an instance of this structure. */
3142
3143 struct aout_final_link_info
3144 {
3145 /* General link information. */
3146 struct bfd_link_info *info;
3147 /* Output bfd. */
3148 bfd *output_bfd;
3149 /* Reloc file positions. */
3150 file_ptr treloff, dreloff;
3151 /* File position of symbols. */
3152 file_ptr symoff;
3153 /* String table. */
3154 struct stringtab_data strtab;
3155 };
3156
3157 static boolean aout_link_input_bfd
3158 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3159 static boolean aout_link_write_symbols
3160 PARAMS ((struct aout_final_link_info *, bfd *input_bfd, int *symbol_map));
3161 static boolean aout_link_write_other_symbol
3162 PARAMS ((struct aout_link_hash_entry *, PTR));
3163 static boolean aout_link_input_section
3164 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3165 asection *input_section, file_ptr *reloff_ptr,
3166 bfd_size_type rel_size, int *symbol_map));
3167 static boolean aout_link_input_section_std
3168 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3169 asection *input_section, struct reloc_std_external *,
3170 bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
3171 static boolean aout_link_input_section_ext
3172 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3173 asection *input_section, struct reloc_ext_external *,
3174 bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
3175 static INLINE asection *aout_reloc_index_to_section
3176 PARAMS ((bfd *, int));
3177
3178 /* Do the final link step. This is called on the output BFD. The
3179 INFO structure should point to a list of BFDs linked through the
3180 link_next field which can be used to find each BFD which takes part
3181 in the output. Also, each section in ABFD should point to a list
3182 of bfd_link_order structures which list all the input sections for
3183 the output section. */
3184
3185 boolean
3186 NAME(aout,final_link) (abfd, info, callback)
3187 bfd *abfd;
3188 struct bfd_link_info *info;
3189 void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
3190 {
3191 struct aout_final_link_info aout_info;
3192 register bfd *sub;
3193 bfd_size_type text_size;
3194 file_ptr text_end;
3195 register struct bfd_link_order *p;
3196 asection *o;
3197
3198 aout_info.info = info;
3199 aout_info.output_bfd = abfd;
3200
3201 if (! info->relocateable)
3202 {
3203 exec_hdr (abfd)->a_trsize = 0;
3204 exec_hdr (abfd)->a_drsize = 0;
3205 }
3206 else
3207 {
3208 bfd_size_type trsize, drsize;
3209
3210 /* Count up the relocation sizes. */
3211 trsize = 0;
3212 drsize = 0;
3213 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3214 {
3215 if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
3216 {
3217 trsize += exec_hdr (sub)->a_trsize;
3218 drsize += exec_hdr (sub)->a_drsize;
3219 }
3220 else
3221 {
3222 /* FIXME: We need to identify the .text and .data sections
3223 and call get_reloc_upper_bound and canonicalize_reloc to
3224 work out the number of relocs needed, and then multiply
3225 by the reloc size. */
3226 abort ();
3227 }
3228 }
3229 exec_hdr (abfd)->a_trsize = trsize;
3230 exec_hdr (abfd)->a_drsize = drsize;
3231 }
3232
3233 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
3234
3235 /* Adjust the section sizes and vmas according to the magic number.
3236 This sets a_text, a_data and a_bss in the exec_hdr and sets the
3237 filepos for each section. */
3238 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3239 return false;
3240
3241 /* The relocation and symbol file positions differ among a.out
3242 targets. We are passed a callback routine from the backend
3243 specific code to handle this.
3244 FIXME: At this point we do not know how much space the symbol
3245 table will require. This will not work for any (nonstandard)
3246 a.out target that needs to know the symbol table size before it
3247 can compute the relocation file positions. This may or may not
3248 be the case for the hp300hpux target, for example. */
3249 (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3250 &aout_info.symoff);
3251 obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3252 obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3253 obj_sym_filepos (abfd) = aout_info.symoff;
3254
3255 /* We keep a count of the symbols as we output them. */
3256 obj_aout_external_sym_count (abfd) = 0;
3257
3258 /* We accumulate the string table as we write out the symbols. */
3259 stringtab_init (&aout_info.strtab);
3260
3261 /* The most time efficient way to do the link would be to read all
3262 the input object files into memory and then sort out the
3263 information into the output file. Unfortunately, that will
3264 probably use too much memory. Another method would be to step
3265 through everything that composes the text section and write it
3266 out, and then everything that composes the data section and write
3267 it out, and then write out the relocs, and then write out the
3268 symbols. Unfortunately, that requires reading stuff from each
3269 input file several times, and we will not be able to keep all the
3270 input files open simultaneously, and reopening them will be slow.
3271
3272 What we do is basically process one input file at a time. We do
3273 everything we need to do with an input file once--copy over the
3274 section contents, handle the relocation information, and write
3275 out the symbols--and then we throw away the information we read
3276 from it. This approach requires a lot of lseeks of the output
3277 file, which is unfortunate but still faster than reopening a lot
3278 of files.
3279
3280 We use the output_has_begun field of the input BFDs to see
3281 whether we have already handled it. */
3282 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3283 sub->output_has_begun = false;
3284
3285 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3286 {
3287 for (p = o->link_order_head;
3288 p != (struct bfd_link_order *) NULL;
3289 p = p->next)
3290 {
3291 /* If we might be using the C based alloca function, we need
3292 to dump the memory allocated by aout_link_input_bfd. */
3293 #ifndef __GNUC__
3294 #ifndef alloca
3295 (void) alloca (0);
3296 #endif
3297 #endif
3298 if (p->type == bfd_indirect_link_order
3299 && (bfd_get_flavour (p->u.indirect.section->owner)
3300 == bfd_target_aout_flavour))
3301 {
3302 bfd *input_bfd;
3303
3304 input_bfd = p->u.indirect.section->owner;
3305 if (! input_bfd->output_has_begun)
3306 {
3307 if (! aout_link_input_bfd (&aout_info, input_bfd))
3308 return false;
3309 input_bfd->output_has_begun = true;
3310 }
3311 }
3312 else
3313 {
3314 if (! _bfd_default_link_order (abfd, info, o, p))
3315 return false;
3316 }
3317 }
3318 }
3319
3320 /* Write out any symbols that we have not already written out. */
3321 aout_link_hash_traverse (aout_hash_table (info),
3322 aout_link_write_other_symbol,
3323 (PTR) &aout_info);
3324
3325 /* Update the header information. */
3326 abfd->symcount = obj_aout_external_sym_count (abfd);
3327 exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
3328 obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
3329 obj_textsec (abfd)->reloc_count =
3330 exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
3331 obj_datasec (abfd)->reloc_count =
3332 exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
3333
3334 /* Write out the string table. */
3335 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
3336 return false;
3337 emit_strtab (abfd, &aout_info.strtab);
3338
3339 return true;
3340 }
3341
3342 /* Link an a.out input BFD into the output file. */
3343
3344 static boolean
3345 aout_link_input_bfd (finfo, input_bfd)
3346 struct aout_final_link_info *finfo;
3347 bfd *input_bfd;
3348 {
3349 bfd_size_type sym_count;
3350 int *symbol_map;
3351
3352 BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
3353
3354 /* Get the symbols. We probably have them already, unless
3355 finfo->info->keep_memory is false. */
3356 if (! aout_link_get_symbols (input_bfd))
3357 return false;
3358
3359 sym_count = obj_aout_external_sym_count (input_bfd);
3360 symbol_map = (int *) alloca ((size_t) sym_count * sizeof (int));
3361
3362 /* Write out the symbols and get a map of the new indices. */
3363 if (! aout_link_write_symbols (finfo, input_bfd, symbol_map))
3364 return false;
3365
3366 /* Relocate and write out the sections. */
3367 if (! aout_link_input_section (finfo, input_bfd,
3368 obj_textsec (input_bfd),
3369 &finfo->treloff,
3370 exec_hdr (input_bfd)->a_trsize,
3371 symbol_map)
3372 || ! aout_link_input_section (finfo, input_bfd,
3373 obj_datasec (input_bfd),
3374 &finfo->dreloff,
3375 exec_hdr (input_bfd)->a_drsize,
3376 symbol_map))
3377 return false;
3378
3379 /* If we are not keeping memory, we don't need the symbols any
3380 longer. We still need them if we are keeping memory, because the
3381 strings in the hash table point into them. */
3382 if (! finfo->info->keep_memory)
3383 {
3384 if (! aout_link_free_symbols (input_bfd))
3385 return false;
3386 }
3387
3388 return true;
3389 }
3390
3391 /* Adjust and write out the symbols for an a.out file. Set the new
3392 symbol indices into a symbol_map. */
3393
3394 static boolean
3395 aout_link_write_symbols (finfo, input_bfd, symbol_map)
3396 struct aout_final_link_info *finfo;
3397 bfd *input_bfd;
3398 int *symbol_map;
3399 {
3400 bfd *output_bfd;
3401 bfd_size_type sym_count;
3402 char *strings;
3403 enum bfd_link_strip strip;
3404 enum bfd_link_discard discard;
3405 struct external_nlist *output_syms;
3406 struct external_nlist *outsym;
3407 register struct external_nlist *sym;
3408 struct external_nlist *sym_end;
3409 struct aout_link_hash_entry **sym_hash;
3410 boolean pass;
3411 boolean skip_indirect;
3412
3413 output_bfd = finfo->output_bfd;
3414 sym_count = obj_aout_external_sym_count (input_bfd);
3415 strings = obj_aout_external_strings (input_bfd);
3416 strip = finfo->info->strip;
3417 discard = finfo->info->discard;
3418 output_syms = ((struct external_nlist *)
3419 alloca ((size_t) (sym_count + 1) * EXTERNAL_NLIST_SIZE));
3420 outsym = output_syms;
3421
3422 /* First write out a symbol for this object file, unless we are
3423 discarding such symbols. */
3424 if (strip != strip_all
3425 && (strip != strip_some
3426 || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
3427 false, false) != NULL)
3428 && discard != discard_all)
3429 {
3430 bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type);
3431 bfd_h_put_8 (output_bfd, 0, outsym->e_other);
3432 bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc);
3433 PUT_WORD (output_bfd,
3434 add_to_stringtab (output_bfd, input_bfd->filename,
3435 &finfo->strtab),
3436 outsym->e_strx);
3437 PUT_WORD (output_bfd,
3438 bfd_get_section_vma (input_bfd, obj_textsec (input_bfd)),
3439 outsym->e_value);
3440 ++obj_aout_external_sym_count (output_bfd);
3441 ++outsym;
3442 }
3443
3444 pass = false;
3445 skip_indirect = false;
3446 sym = obj_aout_external_syms (input_bfd);
3447 sym_end = sym + sym_count;
3448 sym_hash = obj_aout_sym_hashes (input_bfd);
3449 for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
3450 {
3451 const char *name;
3452 int type;
3453 boolean skip;
3454 asection *symsec;
3455 bfd_vma val = 0;
3456
3457 *symbol_map = -1;
3458
3459 type = bfd_h_get_8 (input_bfd, sym->e_type);
3460 name = strings + GET_WORD (input_bfd, sym->e_strx);
3461
3462 if (pass)
3463 {
3464 /* Pass this symbol through. It is the target of an
3465 indirect or warning symbol. */
3466 val = GET_WORD (input_bfd, sym->e_value);
3467 pass = false;
3468 }
3469 else if (skip_indirect)
3470 {
3471 /* Skip this symbol, which is the target of an indirect
3472 symbol that we have changed to no longer be an indirect
3473 symbol. */
3474 skip_indirect = false;
3475 continue;
3476 }
3477 else
3478 {
3479 struct aout_link_hash_entry *h;
3480 struct aout_link_hash_entry *hresolve;
3481
3482 /* We have saved the hash table entry for this symbol, if
3483 there is one. Note that we could just look it up again
3484 in the hash table, provided we first check that it is an
3485 external symbol. */
3486 h = *sym_hash;
3487
3488 /* If this is an indirect or warning symbol, then change
3489 hresolve to the base symbol. We also change *sym_hash so
3490 that the relocation routines relocate against the real
3491 symbol. */
3492 hresolve = h;
3493 if (h != (struct aout_link_hash_entry *) NULL
3494 && (h->root.type == bfd_link_hash_indirect
3495 || h->root.type == bfd_link_hash_warning))
3496 {
3497 hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
3498 while (hresolve->root.type == bfd_link_hash_indirect)
3499 hresolve = ((struct aout_link_hash_entry *)
3500 hresolve->root.u.i.link);
3501 *sym_hash = hresolve;
3502 }
3503
3504 /* If the symbol has already been written out, skip it. */
3505 if (h != (struct aout_link_hash_entry *) NULL
3506 && h->root.written)
3507 {
3508 *symbol_map = h->indx;
3509 continue;
3510 }
3511
3512 /* See if we are stripping this symbol. */
3513 skip = false;
3514 switch (strip)
3515 {
3516 case strip_none:
3517 break;
3518 case strip_debugger:
3519 if ((type & N_STAB) != 0)
3520 skip = true;
3521 break;
3522 case strip_some:
3523 if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
3524 == NULL)
3525 skip = true;
3526 break;
3527 case strip_all:
3528 skip = true;
3529 break;
3530 }
3531 if (skip)
3532 {
3533 if (h != (struct aout_link_hash_entry *) NULL)
3534 h->root.written = true;
3535 continue;
3536 }
3537
3538 /* Get the value of the symbol. */
3539 if ((type & N_TYPE) == N_TEXT)
3540 symsec = obj_textsec (input_bfd);
3541 else if ((type & N_TYPE) == N_DATA)
3542 symsec = obj_datasec (input_bfd);
3543 else if ((type & N_TYPE) == N_BSS)
3544 symsec = obj_bsssec (input_bfd);
3545 else if ((type & N_TYPE) == N_ABS)
3546 symsec = &bfd_abs_section;
3547 else if (((type & N_TYPE) == N_INDR
3548 && (hresolve == (struct aout_link_hash_entry *) NULL
3549 || (hresolve->root.type != bfd_link_hash_defined
3550 && hresolve->root.type != bfd_link_hash_common)))
3551 || type == N_WARNING)
3552 {
3553 /* Pass the next symbol through unchanged. The
3554 condition above for indirect symbols is so that if
3555 the indirect symbol was defined, we output it with
3556 the correct definition so the debugger will
3557 understand it. */
3558 pass = true;
3559 val = GET_WORD (input_bfd, sym->e_value);
3560 symsec = NULL;
3561 }
3562 else if ((type & N_STAB) != 0)
3563 {
3564 val = GET_WORD (input_bfd, sym->e_value);
3565 symsec = NULL;
3566 }
3567 else
3568 {
3569 /* If we get here with an indirect symbol, it means that
3570 we are outputting it with a real definition. In such
3571 a case we do not want to output the next symbol,
3572 which is the target of the indirection. */
3573 if ((type & N_TYPE) == N_INDR)
3574 skip_indirect = true;
3575
3576 /* We need to get the value from the hash table. We use
3577 hresolve so that if we have defined an indirect
3578 symbol we output the final definition. */
3579 if (h == (struct aout_link_hash_entry *) NULL)
3580 val = 0;
3581 else if (hresolve->root.type == bfd_link_hash_defined)
3582 {
3583 asection *input_section;
3584 asection *output_section;
3585
3586 /* This case means a common symbol which was turned
3587 into a defined symbol. */
3588 input_section = hresolve->root.u.def.section;
3589 output_section = input_section->output_section;
3590 BFD_ASSERT (output_section == &bfd_abs_section
3591 || output_section->owner == output_bfd);
3592 val = (hresolve->root.u.def.value
3593 + bfd_get_section_vma (output_bfd, output_section)
3594 + input_section->output_offset);
3595
3596 /* Get the correct type based on the section. If
3597 this is a constructed set, force it to be
3598 globally visible. */
3599 if (type == N_SETT
3600 || type == N_SETD
3601 || type == N_SETB
3602 || type == N_SETA)
3603 type |= N_EXT;
3604
3605 type &=~ N_TYPE;
3606
3607 if (output_section == obj_textsec (output_bfd))
3608 type |= N_TEXT;
3609 else if (output_section == obj_datasec (output_bfd))
3610 type |= N_DATA;
3611 else if (output_section == obj_bsssec (output_bfd))
3612 type |= N_BSS;
3613 else
3614 type |= N_ABS;
3615 }
3616 else if (hresolve->root.type == bfd_link_hash_common)
3617 val = hresolve->root.u.c.size;
3618 else
3619 val = 0;
3620
3621 symsec = NULL;
3622 }
3623 if (symsec != (asection *) NULL)
3624 val = (symsec->output_section->vma
3625 + symsec->output_offset
3626 + (GET_WORD (input_bfd, sym->e_value)
3627 - symsec->vma));
3628
3629 /* If this is a global symbol set the written flag, and if
3630 it is a local symbol see if we should discard it. */
3631 if (h != (struct aout_link_hash_entry *) NULL)
3632 {
3633 h->root.written = true;
3634 h->indx = obj_aout_external_sym_count (output_bfd);
3635 }
3636 else
3637 {
3638 switch (discard)
3639 {
3640 case discard_none:
3641 break;
3642 case discard_l:
3643 if (*name == *finfo->info->lprefix
3644 && (finfo->info->lprefix_len == 1
3645 || strncmp (name, finfo->info->lprefix,
3646 finfo->info->lprefix_len) == 0))
3647 skip = true;
3648 break;
3649 case discard_all:
3650 skip = true;
3651 break;
3652 }
3653 if (skip)
3654 {
3655 pass = false;
3656 continue;
3657 }
3658 }
3659 }
3660
3661 /* Copy this symbol into the list of symbols we are going to
3662 write out. */
3663 bfd_h_put_8 (output_bfd, type, outsym->e_type);
3664 bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other),
3665 outsym->e_other);
3666 bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc),
3667 outsym->e_desc);
3668 PUT_WORD (output_bfd,
3669 add_to_stringtab (output_bfd, name, &finfo->strtab),
3670 outsym->e_strx);
3671 PUT_WORD (output_bfd, val, outsym->e_value);
3672 *symbol_map = obj_aout_external_sym_count (output_bfd);
3673 ++obj_aout_external_sym_count (output_bfd);
3674 ++outsym;
3675 }
3676
3677 /* Write out the output symbols we have just constructed. */
3678 if (outsym > output_syms)
3679 {
3680 bfd_size_type outsym_count;
3681
3682 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
3683 return false;
3684 outsym_count = outsym - output_syms;
3685 if (bfd_write ((PTR) output_syms, (bfd_size_type) EXTERNAL_NLIST_SIZE,
3686 (bfd_size_type) outsym_count, output_bfd)
3687 != outsym_count * EXTERNAL_NLIST_SIZE)
3688 return false;
3689 finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
3690 }
3691
3692 return true;
3693 }
3694
3695 /* Write out a symbol that was not associated with an a.out input
3696 object. */
3697
3698 static boolean
3699 aout_link_write_other_symbol (h, data)
3700 struct aout_link_hash_entry *h;
3701 PTR data;
3702 {
3703 struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
3704 bfd *output_bfd;
3705 int type;
3706 bfd_vma val;
3707 struct external_nlist outsym;
3708
3709 if (h->root.written)
3710 return true;
3711
3712 output_bfd = finfo->output_bfd;
3713
3714 switch (h->root.type)
3715 {
3716 default:
3717 case bfd_link_hash_new:
3718 abort ();
3719 /* Avoid variable not initialized warnings. */
3720 return true;
3721 case bfd_link_hash_undefined:
3722 type = N_UNDF | N_EXT;
3723 val = 0;
3724 break;
3725 case bfd_link_hash_defined:
3726 {
3727 asection *sec;
3728
3729 sec = h->root.u.def.section;
3730 BFD_ASSERT (sec == &bfd_abs_section
3731 || sec->owner == output_bfd);
3732 if (sec == obj_textsec (output_bfd))
3733 type = N_TEXT | N_EXT;
3734 else if (sec == obj_datasec (output_bfd))
3735 type = N_DATA | N_EXT;
3736 else if (sec == obj_bsssec (output_bfd))
3737 type = N_BSS | N_EXT;
3738 else
3739 type = N_ABS | N_EXT;
3740 val = (h->root.u.def.value
3741 + sec->output_section->vma
3742 + sec->output_offset);
3743 }
3744 break;
3745 case bfd_link_hash_common:
3746 type = N_UNDF | N_EXT;
3747 val = h->root.u.c.size;
3748 break;
3749 case bfd_link_hash_indirect:
3750 case bfd_link_hash_warning:
3751 /* FIXME: Ignore these for now. The circumstances under which
3752 they should be written out are not clear to me. */
3753 return true;
3754 }
3755
3756 bfd_h_put_8 (output_bfd, type, outsym.e_type);
3757 bfd_h_put_8 (output_bfd, 0, outsym.e_other);
3758 bfd_h_put_16 (output_bfd, 0, outsym.e_desc);
3759 PUT_WORD (output_bfd,
3760 add_to_stringtab (output_bfd, h->root.root.string, &finfo->strtab),
3761 outsym.e_strx);
3762 PUT_WORD (output_bfd, val, outsym.e_value);
3763
3764 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
3765 || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE,
3766 (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE)
3767 {
3768 /* FIXME: No way to handle errors. */
3769 abort ();
3770 }
3771
3772 finfo->symoff += EXTERNAL_NLIST_SIZE;
3773 h->indx = obj_aout_external_sym_count (output_bfd);
3774 ++obj_aout_external_sym_count (output_bfd);
3775
3776 return true;
3777 }
3778
3779 /* Link an a.out section into the output file. */
3780
3781 static boolean
3782 aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
3783 rel_size, symbol_map)
3784 struct aout_final_link_info *finfo;
3785 bfd *input_bfd;
3786 asection *input_section;
3787 file_ptr *reloff_ptr;
3788 bfd_size_type rel_size;
3789 int *symbol_map;
3790 {
3791 bfd_size_type input_size;
3792 bfd_byte *contents;
3793 PTR relocs;
3794
3795 /* Get the section contents. */
3796 input_size = bfd_section_size (input_bfd, input_section);
3797 contents = (bfd_byte *) alloca (input_size);
3798 if (! bfd_get_section_contents (input_bfd, input_section, (PTR) contents,
3799 (file_ptr) 0, input_size))
3800 return false;
3801
3802 /* Read in the relocs. */
3803 relocs = (PTR) alloca (rel_size);
3804 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
3805 || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
3806 return false;
3807
3808 /* Relocate the section contents. */
3809 if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
3810 {
3811 if (! aout_link_input_section_std (finfo, input_bfd, input_section,
3812 (struct reloc_std_external *) relocs,
3813 rel_size, contents, symbol_map))
3814 return false;
3815 }
3816 else
3817 {
3818 if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
3819 (struct reloc_ext_external *) relocs,
3820 rel_size, contents, symbol_map))
3821 return false;
3822 }
3823
3824 /* Write out the section contents. */
3825 if (! bfd_set_section_contents (finfo->output_bfd,
3826 input_section->output_section,
3827 (PTR) contents,
3828 input_section->output_offset,
3829 input_size))
3830 return false;
3831
3832 /* If we are producing relocateable output, the relocs were
3833 modified, and we now write them out. */
3834 if (finfo->info->relocateable)
3835 {
3836 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
3837 return false;
3838 if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
3839 != rel_size)
3840 return false;
3841 *reloff_ptr += rel_size;
3842
3843 /* Assert that the relocs have not run into the symbols, and
3844 that if these are the text relocs they have not run into the
3845 data relocs. */
3846 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
3847 && (reloff_ptr != &finfo->treloff
3848 || (*reloff_ptr
3849 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
3850 }
3851
3852 return true;
3853 }
3854
3855 /* Get the section corresponding to a reloc index. */
3856
3857 static INLINE asection *
3858 aout_reloc_index_to_section (abfd, indx)
3859 bfd *abfd;
3860 int indx;
3861 {
3862 switch (indx & N_TYPE)
3863 {
3864 case N_TEXT:
3865 return obj_textsec (abfd);
3866 case N_DATA:
3867 return obj_datasec (abfd);
3868 case N_BSS:
3869 return obj_bsssec (abfd);
3870 case N_ABS:
3871 return &bfd_abs_section;
3872 default:
3873 abort ();
3874 }
3875 }
3876
3877 /* Relocate an a.out section using standard a.out relocs. */
3878
3879 static boolean
3880 aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
3881 rel_size, contents, symbol_map)
3882 struct aout_final_link_info *finfo;
3883 bfd *input_bfd;
3884 asection *input_section;
3885 struct reloc_std_external *relocs;
3886 bfd_size_type rel_size;
3887 bfd_byte *contents;
3888 int *symbol_map;
3889 {
3890 bfd *output_bfd;
3891 boolean relocateable;
3892 struct external_nlist *syms;
3893 char *strings;
3894 struct aout_link_hash_entry **sym_hashes;
3895 bfd_size_type reloc_count;
3896 register struct reloc_std_external *rel;
3897 struct reloc_std_external *rel_end;
3898
3899 output_bfd = finfo->output_bfd;
3900
3901 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
3902 BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
3903 == output_bfd->xvec->header_byteorder_big_p);
3904
3905 relocateable = finfo->info->relocateable;
3906 syms = obj_aout_external_syms (input_bfd);
3907 strings = obj_aout_external_strings (input_bfd);
3908 sym_hashes = obj_aout_sym_hashes (input_bfd);
3909
3910 reloc_count = rel_size / RELOC_STD_SIZE;
3911 rel = relocs;
3912 rel_end = rel + reloc_count;
3913 for (; rel < rel_end; rel++)
3914 {
3915 bfd_vma r_addr;
3916 int r_index;
3917 int r_extern;
3918 int r_pcrel;
3919 int r_baserel;
3920 int r_jmptable;
3921 int r_relative;
3922 int r_length;
3923 int howto_idx;
3924 bfd_vma relocation;
3925 bfd_reloc_status_type r;
3926
3927 r_addr = GET_SWORD (input_bfd, rel->r_address);
3928
3929 if (input_bfd->xvec->header_byteorder_big_p)
3930 {
3931 r_index = ((rel->r_index[0] << 16)
3932 | (rel->r_index[1] << 8)
3933 | rel->r_index[2]);
3934 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
3935 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
3936 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
3937 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
3938 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
3939 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
3940 >> RELOC_STD_BITS_LENGTH_SH_BIG);
3941 }
3942 else
3943 {
3944 r_index = ((rel->r_index[2] << 16)
3945 | (rel->r_index[1] << 8)
3946 | rel->r_index[0]);
3947 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
3948 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
3949 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
3950 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
3951 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
3952 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
3953 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
3954 }
3955
3956 howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel;
3957 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
3958 BFD_ASSERT (r_jmptable == 0);
3959 BFD_ASSERT (r_relative == 0);
3960
3961 if (relocateable)
3962 {
3963 /* We are generating a relocateable output file, and must
3964 modify the reloc accordingly. */
3965 if (r_extern)
3966 {
3967 struct aout_link_hash_entry *h;
3968
3969 /* If we know the symbol this relocation is against,
3970 convert it into a relocation against a section. This
3971 is what the native linker does. */
3972 h = sym_hashes[r_index];
3973 if (h != (struct aout_link_hash_entry *) NULL
3974 && h->root.type == bfd_link_hash_defined)
3975 {
3976 asection *output_section;
3977
3978 /* Change the r_extern value. */
3979 if (output_bfd->xvec->header_byteorder_big_p)
3980 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
3981 else
3982 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
3983
3984 /* Compute a new r_index. */
3985 output_section = h->root.u.def.section->output_section;
3986 if (output_section == obj_textsec (output_bfd))
3987 r_index = N_TEXT;
3988 else if (output_section == obj_datasec (output_bfd))
3989 r_index = N_DATA;
3990 else if (output_section == obj_bsssec (output_bfd))
3991 r_index = N_BSS;
3992 else
3993 r_index = N_ABS;
3994
3995 /* Add the symbol value and the section VMA to the
3996 addend stored in the contents. */
3997 relocation = (h->root.u.def.value
3998 + output_section->vma
3999 + h->root.u.def.section->output_offset);
4000 }
4001 else
4002 {
4003 /* We must change r_index according to the symbol
4004 map. */
4005 r_index = symbol_map[r_index];
4006
4007 if (r_index == -1)
4008 {
4009 const char *name;
4010
4011 name = strings + GET_WORD (input_bfd,
4012 syms[r_index].e_strx);
4013 if (! ((*finfo->info->callbacks->unattached_reloc)
4014 (finfo->info, name, input_bfd, input_section,
4015 r_addr)))
4016 return false;
4017 r_index = 0;
4018 }
4019
4020 relocation = 0;
4021 }
4022
4023 /* Write out the new r_index value. */
4024 if (output_bfd->xvec->header_byteorder_big_p)
4025 {
4026 rel->r_index[0] = r_index >> 16;
4027 rel->r_index[1] = r_index >> 8;
4028 rel->r_index[2] = r_index;
4029 }
4030 else
4031 {
4032 rel->r_index[2] = r_index >> 16;
4033 rel->r_index[1] = r_index >> 8;
4034 rel->r_index[0] = r_index;
4035 }
4036 }
4037 else
4038 {
4039 asection *section;
4040
4041 /* This is a relocation against a section. We must
4042 adjust by the amount that the section moved. */
4043 section = aout_reloc_index_to_section (input_bfd, r_index);
4044 relocation = (section->output_section->vma
4045 + section->output_offset
4046 - section->vma);
4047 }
4048
4049 /* Change the address of the relocation. */
4050 PUT_WORD (output_bfd,
4051 r_addr + input_section->output_offset,
4052 rel->r_address);
4053
4054 /* Adjust a PC relative relocation by removing the reference
4055 to the original address in the section and including the
4056 reference to the new address. */
4057 if (r_pcrel)
4058 relocation -= (input_section->output_section->vma
4059 + input_section->output_offset
4060 - input_section->vma);
4061
4062 if (relocation == 0)
4063 r = bfd_reloc_ok;
4064 else
4065 r = _bfd_relocate_contents (howto_table_std + howto_idx,
4066 input_bfd, relocation,
4067 contents + r_addr);
4068 }
4069 else
4070 {
4071 /* We are generating an executable, and must do a full
4072 relocation. */
4073 if (r_extern)
4074 {
4075 struct aout_link_hash_entry *h;
4076
4077 h = sym_hashes[r_index];
4078 if (h != (struct aout_link_hash_entry *) NULL
4079 && h->root.type == bfd_link_hash_defined)
4080 {
4081 relocation = (h->root.u.def.value
4082 + h->root.u.def.section->output_section->vma
4083 + h->root.u.def.section->output_offset);
4084 }
4085 else
4086 {
4087 const char *name;
4088
4089 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4090 if (! ((*finfo->info->callbacks->undefined_symbol)
4091 (finfo->info, name, input_bfd, input_section,
4092 r_addr)))
4093 return false;
4094 relocation = 0;
4095 }
4096 }
4097 else
4098 {
4099 asection *section;
4100
4101 section = aout_reloc_index_to_section (input_bfd, r_index);
4102 relocation = (section->output_section->vma
4103 + section->output_offset
4104 - section->vma);
4105 if (r_pcrel)
4106 relocation += input_section->vma;
4107 }
4108
4109 r = _bfd_final_link_relocate (howto_table_std + howto_idx,
4110 input_bfd, input_section,
4111 contents, r_addr, relocation,
4112 (bfd_vma) 0);
4113 }
4114
4115 if (r != bfd_reloc_ok)
4116 {
4117 switch (r)
4118 {
4119 default:
4120 case bfd_reloc_outofrange:
4121 abort ();
4122 case bfd_reloc_overflow:
4123 if (! ((*finfo->info->callbacks->reloc_overflow)
4124 (finfo->info, input_bfd, input_section, r_addr)))
4125 return false;
4126 break;
4127 }
4128 }
4129 }
4130
4131 return true;
4132 }
4133
4134 /* Relocate an a.out section using extended a.out relocs. */
4135
4136 static boolean
4137 aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
4138 rel_size, contents, symbol_map)
4139 struct aout_final_link_info *finfo;
4140 bfd *input_bfd;
4141 asection *input_section;
4142 struct reloc_ext_external *relocs;
4143 bfd_size_type rel_size;
4144 bfd_byte *contents;
4145 int *symbol_map;
4146 {
4147 bfd *output_bfd;
4148 boolean relocateable;
4149 struct external_nlist *syms;
4150 char *strings;
4151 struct aout_link_hash_entry **sym_hashes;
4152 bfd_size_type reloc_count;
4153 register struct reloc_ext_external *rel;
4154 struct reloc_ext_external *rel_end;
4155
4156 output_bfd = finfo->output_bfd;
4157
4158 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
4159 BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
4160 == output_bfd->xvec->header_byteorder_big_p);
4161
4162 relocateable = finfo->info->relocateable;
4163 syms = obj_aout_external_syms (input_bfd);
4164 strings = obj_aout_external_strings (input_bfd);
4165 sym_hashes = obj_aout_sym_hashes (input_bfd);
4166
4167 reloc_count = rel_size / RELOC_EXT_SIZE;
4168 rel = relocs;
4169 rel_end = rel + reloc_count;
4170 for (; rel < rel_end; rel++)
4171 {
4172 bfd_vma r_addr;
4173 int r_index;
4174 int r_extern;
4175 int r_type;
4176 bfd_vma r_addend;
4177 bfd_vma relocation;
4178
4179 r_addr = GET_SWORD (input_bfd, rel->r_address);
4180
4181 if (input_bfd->xvec->header_byteorder_big_p)
4182 {
4183 r_index = ((rel->r_index[0] << 16)
4184 | (rel->r_index[1] << 8)
4185 | rel->r_index[2]);
4186 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
4187 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
4188 >> RELOC_EXT_BITS_TYPE_SH_BIG);
4189 }
4190 else
4191 {
4192 r_index = ((rel->r_index[2] << 16)
4193 | (rel->r_index[1] << 8)
4194 | rel->r_index[0]);
4195 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
4196 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
4197 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
4198 }
4199
4200 r_addend = GET_SWORD (input_bfd, rel->r_addend);
4201
4202 BFD_ASSERT (r_type >= 0
4203 && r_type < TABLE_SIZE (howto_table_ext));
4204
4205 if (relocateable)
4206 {
4207 /* We are generating a relocateable output file, and must
4208 modify the reloc accordingly. */
4209 if (r_extern)
4210 {
4211 struct aout_link_hash_entry *h;
4212
4213 /* If we know the symbol this relocation is against,
4214 convert it into a relocation against a section. This
4215 is what the native linker does. */
4216 h = sym_hashes[r_index];
4217 if (h != (struct aout_link_hash_entry *) NULL
4218 && h->root.type == bfd_link_hash_defined)
4219 {
4220 asection *output_section;
4221
4222 /* Change the r_extern value. */
4223 if (output_bfd->xvec->header_byteorder_big_p)
4224 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
4225 else
4226 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
4227
4228 /* Compute a new r_index. */
4229 output_section = h->root.u.def.section->output_section;
4230 if (output_section == obj_textsec (output_bfd))
4231 r_index = N_TEXT;
4232 else if (output_section == obj_datasec (output_bfd))
4233 r_index = N_DATA;
4234 else if (output_section == obj_bsssec (output_bfd))
4235 r_index = N_BSS;
4236 else
4237 r_index = N_ABS;
4238
4239 /* Add the symbol value and the section VMA to the
4240 addend. */
4241 relocation = (h->root.u.def.value
4242 + output_section->vma
4243 + h->root.u.def.section->output_offset);
4244
4245 /* Now RELOCATION is the VMA of the final
4246 destination. If this is a PC relative reloc,
4247 then ADDEND is the negative of the source VMA.
4248 We want to set ADDEND to the difference between
4249 the destination VMA and the source VMA, which
4250 means we must adjust RELOCATION by the change in
4251 the source VMA. This is done below. */
4252 }
4253 else
4254 {
4255 /* We must change r_index according to the symbol
4256 map. */
4257 r_index = symbol_map[r_index];
4258
4259 if (r_index == -1)
4260 {
4261 const char *name;
4262
4263 name = (strings
4264 + GET_WORD (input_bfd, syms[r_index].e_strx));
4265 if (! ((*finfo->info->callbacks->unattached_reloc)
4266 (finfo->info, name, input_bfd, input_section,
4267 r_addr)))
4268 return false;
4269 r_index = 0;
4270 }
4271
4272 relocation = 0;
4273
4274 /* If this is a PC relative reloc, then the addend
4275 is the negative of the source VMA. We must
4276 adjust it by the change in the source VMA. This
4277 is done below. */
4278 }
4279
4280 /* Write out the new r_index value. */
4281 if (output_bfd->xvec->header_byteorder_big_p)
4282 {
4283 rel->r_index[0] = r_index >> 16;
4284 rel->r_index[1] = r_index >> 8;
4285 rel->r_index[2] = r_index;
4286 }
4287 else
4288 {
4289 rel->r_index[2] = r_index >> 16;
4290 rel->r_index[1] = r_index >> 8;
4291 rel->r_index[0] = r_index;
4292 }
4293 }
4294 else
4295 {
4296 asection *section;
4297
4298 /* This is a relocation against a section. We must
4299 adjust by the amount that the section moved. */
4300 section = aout_reloc_index_to_section (input_bfd, r_index);
4301 relocation = (section->output_section->vma
4302 + section->output_offset
4303 - section->vma);
4304
4305 /* If this is a PC relative reloc, then the addend is
4306 the difference in VMA between the destination and the
4307 source. We have just adjusted for the change in VMA
4308 of the destination, so we must also adjust by the
4309 change in VMA of the source. This is done below. */
4310 }
4311
4312 /* As described above, we must always adjust a PC relative
4313 reloc by the change in VMA of the source. */
4314 if (howto_table_ext[r_type].pc_relative)
4315 relocation -= (input_section->output_section->vma
4316 + input_section->output_offset
4317 - input_section->vma);
4318
4319 /* Change the addend if necessary. */
4320 if (relocation != 0)
4321 PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
4322
4323 /* Change the address of the relocation. */
4324 PUT_WORD (output_bfd,
4325 r_addr + input_section->output_offset,
4326 rel->r_address);
4327 }
4328 else
4329 {
4330 bfd_reloc_status_type r;
4331
4332 /* We are generating an executable, and must do a full
4333 relocation. */
4334 if (r_extern)
4335 {
4336 struct aout_link_hash_entry *h;
4337
4338 h = sym_hashes[r_index];
4339 if (h != (struct aout_link_hash_entry *) NULL
4340 && h->root.type == bfd_link_hash_defined)
4341 {
4342 relocation = (h->root.u.def.value
4343 + h->root.u.def.section->output_section->vma
4344 + h->root.u.def.section->output_offset);
4345 }
4346 else
4347 {
4348 const char *name;
4349
4350 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4351 if (! ((*finfo->info->callbacks->undefined_symbol)
4352 (finfo->info, name, input_bfd, input_section,
4353 r_addr)))
4354 return false;
4355 relocation = 0;
4356 }
4357 }
4358 else
4359 {
4360 asection *section;
4361
4362 section = aout_reloc_index_to_section (input_bfd, r_index);
4363
4364 /* If this is a PC relative reloc, then R_ADDEND is the
4365 difference between the two vmas, or
4366 old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
4367 where
4368 old_dest_sec == section->vma
4369 and
4370 old_src_sec == input_section->vma
4371 and
4372 old_src_off == r_addr
4373
4374 _bfd_final_link_relocate expects RELOCATION +
4375 R_ADDEND to be the VMA of the destination minus
4376 r_addr (the minus r_addr is because this relocation
4377 is not pcrel_offset, which is a bit confusing and
4378 should, perhaps, be changed), or
4379 new_dest_sec
4380 where
4381 new_dest_sec == output_section->vma + output_offset
4382 We arrange for this to happen by setting RELOCATION to
4383 new_dest_sec + old_src_sec - old_dest_sec
4384
4385 If this is not a PC relative reloc, then R_ADDEND is
4386 simply the VMA of the destination, so we set
4387 RELOCATION to the change in the destination VMA, or
4388 new_dest_sec - old_dest_sec
4389 */
4390 relocation = (section->output_section->vma
4391 + section->output_offset
4392 - section->vma);
4393 if (howto_table_ext[r_type].pc_relative)
4394 relocation += input_section->vma;
4395 }
4396
4397 r = _bfd_final_link_relocate (howto_table_ext + r_type,
4398 input_bfd, input_section,
4399 contents, r_addr, relocation,
4400 r_addend);
4401 if (r != bfd_reloc_ok)
4402 {
4403 switch (r)
4404 {
4405 default:
4406 case bfd_reloc_outofrange:
4407 abort ();
4408 case bfd_reloc_overflow:
4409 if (! ((*finfo->info->callbacks->reloc_overflow)
4410 (finfo->info, input_bfd, input_section, r_addr)))
4411 return false;
4412 break;
4413 }
4414 }
4415 }
4416 }
4417
4418 return true;
4419 }
This page took 0.144863 seconds and 4 git commands to generate.