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