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