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