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