1 /* BFD semi-generic back-end for a.out binaries.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
4 Free Software Foundation, Inc.
5 Written by Cygnus Support.
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
29 BFD supports a number of different flavours of a.out format,
30 though the major differences are only the sizes of the
31 structures on disk, and the shape of the relocation
34 The support is split into a basic support file @file{aoutx.h}
35 and other files which derive functions from the base. One
36 derivation file is @file{aoutf1.h} (for a.out flavour 1), and
37 adds to the basic a.out functions support for sun3, sun4, 386
38 and 29k a.out files, to create a target jump vector for a
41 This information is further split out into more specific files
42 for each machine, including @file{sunos.c} for sun3 and sun4,
43 @file{newsos3.c} for the Sony NEWS, and @file{demo64.c} for a
44 demonstration of a 64 bit a.out format.
46 The base file @file{aoutx.h} defines general mechanisms for
47 reading and writing records to and from disk and various
48 other methods which BFD requires. It is included by
49 @file{aout32.c} and @file{aout64.c} to form the names
50 <<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc.
52 As an example, this is what goes on to make the back end for a
53 sun4, from @file{aout32.c}:
55 | #define ARCH_SIZE 32
61 | aout_32_canonicalize_reloc
62 | aout_32_find_nearest_line
64 | aout_32_get_reloc_upper_bound
69 | #define TARGET_NAME "a.out-sunos-big"
70 | #define VECNAME sunos_big_vec
73 requires all the names from @file{aout32.c}, and produces the jump vector
77 The file @file{host-aout.c} is a special case. It is for a large set
78 of hosts that use ``more or less standard'' a.out files, and
79 for which cross-debugging is not interesting. It uses the
80 standard 32-bit a.out support routines, but determines the
81 file offsets and addresses of the text, data, and BSS
82 sections, the machine architecture and machine type, and the
83 entry point address, in a host-dependent manner. Once these
84 values have been determined, generic code is used to handle
87 When porting it to run on a new system, you must supply:
91 | HOST_MACHINE_ARCH (optional)
92 | HOST_MACHINE_MACHINE (optional)
93 | HOST_TEXT_START_ADDR
96 in the file @file{../include/sys/h-@var{XXX}.h} (for your host). These
97 values, plus the structures and macros defined in @file{a.out.h} on
98 your host system, will produce a BFD target that will access
99 ordinary a.out files on your host. To configure a new machine
100 to use @file{host-aout.c}, specify:
102 | TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
103 | TDEPFILES= host-aout.o trad-core.o
105 in the @file{config/@var{XXX}.mt} file, and modify @file{configure.in}
107 @file{@var{XXX}.mt} file (by setting "<<bfd_target=XXX>>") when your
108 configuration is selected.
113 * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
114 Doesn't matter what the setting of WP_TEXT is on output, but it'll
116 * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
117 * Any BFD with both flags clear is OMAGIC.
118 (Just want to make these explicit, so the conditions tested in this
119 file make sense if you're more familiar with a.out than with BFD.) */
121 #define KEEPIT udata.i
125 #include "safe-ctype.h"
130 #include "aout/aout64.h"
131 #include "aout/stab_gnu.h"
134 static boolean aout_get_external_symbols PARAMS ((bfd *));
135 static boolean translate_from_native_sym_flags
136 PARAMS ((bfd *, aout_symbol_type *));
137 static boolean translate_to_native_sym_flags
138 PARAMS ((bfd *, asymbol *, struct external_nlist *));
139 static void adjust_o_magic PARAMS ((bfd *, struct internal_exec *));
140 static void adjust_z_magic PARAMS ((bfd *, struct internal_exec *));
141 static void adjust_n_magic PARAMS ((bfd *, struct internal_exec *));
142 reloc_howto_type * NAME(aout,reloc_type_lookup)
143 PARAMS ((bfd *, bfd_reloc_code_real_type));
150 The file @file{aoutx.h} provides for both the @emph{standard}
151 and @emph{extended} forms of a.out relocation records.
153 The standard records contain only an
154 address, a symbol index, and a type field. The extended records
155 (used on 29ks and sparcs) also have a full integer for an
159 #ifndef CTOR_TABLE_RELOC_HOWTO
160 #define CTOR_TABLE_RELOC_IDX 2
161 #define CTOR_TABLE_RELOC_HOWTO(BFD) \
162 ((obj_reloc_entry_size (BFD) == RELOC_EXT_SIZE \
163 ? howto_table_ext : howto_table_std) \
164 + CTOR_TABLE_RELOC_IDX)
167 #ifndef MY_swap_std_reloc_in
168 #define MY_swap_std_reloc_in NAME(aout,swap_std_reloc_in)
171 #ifndef MY_swap_ext_reloc_in
172 #define MY_swap_ext_reloc_in NAME(aout,swap_ext_reloc_in)
175 #ifndef MY_swap_std_reloc_out
176 #define MY_swap_std_reloc_out NAME(aout,swap_std_reloc_out)
179 #ifndef MY_swap_ext_reloc_out
180 #define MY_swap_ext_reloc_out NAME(aout,swap_ext_reloc_out)
183 #ifndef MY_final_link_relocate
184 #define MY_final_link_relocate _bfd_final_link_relocate
187 #ifndef MY_relocate_contents
188 #define MY_relocate_contents _bfd_relocate_contents
191 #define howto_table_ext NAME(aout,ext_howto_table)
192 #define howto_table_std NAME(aout,std_howto_table)
194 reloc_howto_type howto_table_ext[] =
196 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone. */
197 HOWTO(RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", false, 0,0x000000ff, false),
198 HOWTO(RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", false, 0,0x0000ffff, false),
199 HOWTO(RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", false, 0,0xffffffff, false),
200 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, complain_overflow_signed,0,"DISP8", false, 0,0x000000ff, false),
201 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, complain_overflow_signed,0,"DISP16", false, 0,0x0000ffff, false),
202 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, complain_overflow_signed,0,"DISP32", false, 0,0xffffffff, false),
203 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, complain_overflow_signed,0,"WDISP30", false, 0,0x3fffffff, false),
204 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, complain_overflow_signed,0,"WDISP22", false, 0,0x003fffff, false),
205 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"HI22", false, 0,0x003fffff, false),
206 HOWTO(RELOC_22, 0, 2, 22, false, 0, complain_overflow_bitfield,0,"22", false, 0,0x003fffff, false),
207 HOWTO(RELOC_13, 0, 2, 13, false, 0, complain_overflow_bitfield,0,"13", false, 0,0x00001fff, false),
208 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, complain_overflow_dont,0,"LO10", false, 0,0x000003ff, false),
209 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, complain_overflow_bitfield,0,"SFA_BASE", false, 0,0xffffffff, false),
210 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, complain_overflow_bitfield,0,"SFA_OFF13",false, 0,0xffffffff, false),
211 HOWTO(RELOC_BASE10, 0, 2, 10, false, 0, complain_overflow_dont,0,"BASE10", false, 0,0x000003ff, false),
212 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, complain_overflow_signed,0,"BASE13", false, 0,0x00001fff, false),
213 HOWTO(RELOC_BASE22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"BASE22", false, 0,0x003fffff, false),
214 HOWTO(RELOC_PC10, 0, 2, 10, true, 0, complain_overflow_dont,0,"PC10", false, 0,0x000003ff, true),
215 HOWTO(RELOC_PC22, 10, 2, 22, true, 0, complain_overflow_signed,0,"PC22", false, 0,0x003fffff, true),
216 HOWTO(RELOC_JMP_TBL,2, 2, 30, true, 0, complain_overflow_signed,0,"JMP_TBL", false, 0,0x3fffffff, false),
217 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, complain_overflow_bitfield,0,"SEGOFF16", false, 0,0x00000000, false),
218 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"GLOB_DAT", false, 0,0x00000000, false),
219 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_SLOT", false, 0,0x00000000, false),
220 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false),
221 HOWTO(0, 0, 0, 0, false, 0, complain_overflow_dont, 0, "R_SPARC_NONE", false,0,0x00000000,true),
222 HOWTO(0, 0, 0, 0, false, 0, complain_overflow_dont, 0, "R_SPARC_NONE", false,0,0x00000000,true),
223 #define RELOC_SPARC_REV32 RELOC_WDISP19
224 HOWTO(RELOC_SPARC_REV32, 0, 2, 32, false, 0, complain_overflow_dont,0,"R_SPARC_REV32", false, 0,0xffffffff, false),
227 /* Convert standard reloc records to "arelent" format (incl byte swap). */
229 reloc_howto_type howto_table_std[] = {
230 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone. */
231 HOWTO ( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false),
232 HOWTO ( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false),
233 HOWTO ( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false),
234 HOWTO ( 3, 0, 4, 64, false, 0, complain_overflow_bitfield,0,"64", true, 0xdeaddead,0xdeaddead, false),
235 HOWTO ( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, false),
236 HOWTO ( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
237 HOWTO ( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, false),
238 HOWTO ( 7, 0, 4, 64, true, 0, complain_overflow_signed, 0,"DISP64", true, 0xfeedface,0xfeedface, false),
239 HOWTO ( 8, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"GOT_REL", false, 0,0x00000000, false),
240 HOWTO ( 9, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"BASE16", false,0xffffffff,0xffffffff, false),
241 HOWTO (10, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"BASE32", false,0xffffffff,0xffffffff, false),
247 HOWTO (16, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_TABLE", false, 0,0x00000000, false),
263 HOWTO (32, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false),
271 HOWTO (40, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"BASEREL", false, 0,0x00000000, false),
274 #define TABLE_SIZE(TABLE) (sizeof (TABLE) / sizeof (TABLE[0]))
277 NAME(aout,reloc_type_lookup) (abfd,code)
279 bfd_reloc_code_real_type code;
281 #define EXT(i, j) case i: return &howto_table_ext[j]
282 #define STD(i, j) case i: return &howto_table_std[j]
283 int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
285 if (code == BFD_RELOC_CTOR)
286 switch (bfd_get_arch_info (abfd)->bits_per_address)
299 EXT (BFD_RELOC_8, 0);
300 EXT (BFD_RELOC_16, 1);
301 EXT (BFD_RELOC_32, 2);
302 EXT (BFD_RELOC_HI22, 8);
303 EXT (BFD_RELOC_LO10, 11);
304 EXT (BFD_RELOC_32_PCREL_S2, 6);
305 EXT (BFD_RELOC_SPARC_WDISP22, 7);
306 EXT (BFD_RELOC_SPARC13, 10);
307 EXT (BFD_RELOC_SPARC_GOT10, 14);
308 EXT (BFD_RELOC_SPARC_BASE13, 15);
309 EXT (BFD_RELOC_SPARC_GOT13, 15);
310 EXT (BFD_RELOC_SPARC_GOT22, 16);
311 EXT (BFD_RELOC_SPARC_PC10, 17);
312 EXT (BFD_RELOC_SPARC_PC22, 18);
313 EXT (BFD_RELOC_SPARC_WPLT30, 19);
314 EXT (BFD_RELOC_SPARC_REV32, 26);
315 default: return (reloc_howto_type *) NULL;
321 STD (BFD_RELOC_16, 1);
322 STD (BFD_RELOC_32, 2);
323 STD (BFD_RELOC_8_PCREL, 4);
324 STD (BFD_RELOC_16_PCREL, 5);
325 STD (BFD_RELOC_32_PCREL, 6);
326 STD (BFD_RELOC_16_BASEREL, 9);
327 STD (BFD_RELOC_32_BASEREL, 10);
328 default: return (reloc_howto_type *) NULL;
334 Internal entry points
337 @file{aoutx.h} exports several routines for accessing the
338 contents of an a.out file, which are gathered and exported in
339 turn by various format specific files (eg sunos.c).
345 aout_@var{size}_swap_exec_header_in
348 void aout_@var{size}_swap_exec_header_in,
350 struct external_exec *raw_bytes,
351 struct internal_exec *execp);
354 Swap the information in an executable header @var{raw_bytes} taken
355 from a raw byte stream memory image into the internal exec header
356 structure @var{execp}.
359 #ifndef NAME_swap_exec_header_in
361 NAME(aout,swap_exec_header_in) (abfd, raw_bytes, execp)
363 struct external_exec *raw_bytes;
364 struct internal_exec *execp;
366 struct external_exec *bytes = (struct external_exec *)raw_bytes;
368 /* The internal_exec structure has some fields that are unused in this
369 configuration (IE for i960), so ensure that all such uninitialized
370 fields are zero'd out. There are places where two of these structs
371 are memcmp'd, and thus the contents do matter. */
372 memset ((PTR) execp, 0, sizeof (struct internal_exec));
373 /* Now fill in fields in the execp, from the bytes in the raw data. */
374 execp->a_info = H_GET_32 (abfd, bytes->e_info);
375 execp->a_text = GET_WORD (abfd, bytes->e_text);
376 execp->a_data = GET_WORD (abfd, bytes->e_data);
377 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
378 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
379 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
380 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
381 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
383 #define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
388 aout_@var{size}_swap_exec_header_out
391 void aout_@var{size}_swap_exec_header_out
393 struct internal_exec *execp,
394 struct external_exec *raw_bytes);
397 Swap the information in an internal exec header structure
398 @var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
401 NAME(aout,swap_exec_header_out) (abfd, execp, raw_bytes)
403 struct internal_exec *execp;
404 struct external_exec *raw_bytes;
406 struct external_exec *bytes = (struct external_exec *)raw_bytes;
408 /* Now fill in fields in the raw data, from the fields in the exec struct. */
409 H_PUT_32 (abfd, execp->a_info , bytes->e_info);
410 PUT_WORD (abfd, execp->a_text , bytes->e_text);
411 PUT_WORD (abfd, execp->a_data , bytes->e_data);
412 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
413 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
414 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
415 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
416 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
419 /* Make all the section for an a.out file. */
422 NAME(aout,make_sections) (abfd)
425 if (obj_textsec (abfd) == (asection *) NULL
426 && bfd_make_section (abfd, ".text") == (asection *) NULL)
428 if (obj_datasec (abfd) == (asection *) NULL
429 && bfd_make_section (abfd, ".data") == (asection *) NULL)
431 if (obj_bsssec (abfd) == (asection *) NULL
432 && bfd_make_section (abfd, ".bss") == (asection *) NULL)
439 aout_@var{size}_some_aout_object_p
442 const bfd_target *aout_@var{size}_some_aout_object_p
444 const bfd_target *(*callback_to_real_object_p) ());
447 Some a.out variant thinks that the file open in @var{abfd}
448 checking is an a.out file. Do some more checking, and set up
449 for access if it really is. Call back to the calling
450 environment's "finish up" function just before returning, to
451 handle any last-minute setup.
455 NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
457 struct internal_exec *execp;
458 const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *));
460 struct aout_data_struct *rawptr, *oldrawptr;
461 const bfd_target *result;
462 bfd_size_type amt = sizeof (struct aout_data_struct);
464 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
468 oldrawptr = abfd->tdata.aout_data;
469 abfd->tdata.aout_data = rawptr;
471 /* Copy the contents of the old tdata struct.
472 In particular, we want the subformat, since for hpux it was set in
473 hp300hpux.c:swap_exec_header_in and will be used in
474 hp300hpux.c:callback. */
475 if (oldrawptr != NULL)
476 *abfd->tdata.aout_data = *oldrawptr;
478 abfd->tdata.aout_data->a.hdr = &rawptr->e;
479 /* Copy in the internal_exec struct. */
480 *(abfd->tdata.aout_data->a.hdr) = *execp;
481 execp = abfd->tdata.aout_data->a.hdr;
483 /* Set the file flags. */
484 abfd->flags = BFD_NO_FLAGS;
485 if (execp->a_drsize || execp->a_trsize)
486 abfd->flags |= HAS_RELOC;
487 /* Setting of EXEC_P has been deferred to the bottom of this function. */
489 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
490 if (N_DYNAMIC (*execp))
491 abfd->flags |= DYNAMIC;
493 if (N_MAGIC (*execp) == ZMAGIC)
495 abfd->flags |= D_PAGED | WP_TEXT;
496 adata (abfd).magic = z_magic;
498 else if (N_MAGIC (*execp) == QMAGIC)
500 abfd->flags |= D_PAGED | WP_TEXT;
501 adata (abfd).magic = z_magic;
502 adata (abfd).subformat = q_magic_format;
504 else if (N_MAGIC (*execp) == NMAGIC)
506 abfd->flags |= WP_TEXT;
507 adata (abfd).magic = n_magic;
509 else if (N_MAGIC (*execp) == OMAGIC
510 || N_MAGIC (*execp) == BMAGIC)
511 adata (abfd).magic = o_magic;
514 /* Should have been checked with N_BADMAG before this routine
519 bfd_get_start_address (abfd) = execp->a_entry;
521 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
522 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
524 /* The default relocation entry size is that of traditional V7 Unix. */
525 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
527 /* The default symbol entry size is that of traditional Unix. */
528 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
531 bfd_init_window (&obj_aout_sym_window (abfd));
532 bfd_init_window (&obj_aout_string_window (abfd));
534 obj_aout_external_syms (abfd) = NULL;
535 obj_aout_external_strings (abfd) = NULL;
536 obj_aout_sym_hashes (abfd) = NULL;
538 if (! NAME(aout,make_sections) (abfd))
541 obj_datasec (abfd)->_raw_size = execp->a_data;
542 obj_bsssec (abfd)->_raw_size = execp->a_bss;
544 obj_textsec (abfd)->flags =
545 (execp->a_trsize != 0
546 ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
547 : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
548 obj_datasec (abfd)->flags =
549 (execp->a_drsize != 0
550 ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
551 : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
552 obj_bsssec (abfd)->flags = SEC_ALLOC;
554 #ifdef THIS_IS_ONLY_DOCUMENTATION
555 /* The common code can't fill in these things because they depend
556 on either the start address of the text segment, the rounding
557 up of virtual addresses between segments, or the starting file
558 position of the text segment -- all of which varies among different
559 versions of a.out. */
561 /* Call back to the format-dependent code to fill in the rest of the
562 fields and do any further cleanup. Things that should be filled
563 in by the callback: */
565 struct exec *execp = exec_hdr (abfd);
567 obj_textsec (abfd)->size = N_TXTSIZE (*execp);
568 obj_textsec (abfd)->raw_size = N_TXTSIZE (*execp);
569 /* Data and bss are already filled in since they're so standard. */
571 /* The virtual memory addresses of the sections. */
572 obj_textsec (abfd)->vma = N_TXTADDR (*execp);
573 obj_datasec (abfd)->vma = N_DATADDR (*execp);
574 obj_bsssec (abfd)->vma = N_BSSADDR (*execp);
576 /* The file offsets of the sections. */
577 obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
578 obj_datasec (abfd)->filepos = N_DATOFF (*execp);
580 /* The file offsets of the relocation info. */
581 obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
582 obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
584 /* The file offsets of the string table and symbol table. */
585 obj_str_filepos (abfd) = N_STROFF (*execp);
586 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
588 /* Determine the architecture and machine type of the object file. */
589 switch (N_MACHTYPE (*exec_hdr (abfd)))
592 abfd->obj_arch = bfd_arch_obscure;
596 adata (abfd)->page_size = TARGET_PAGE_SIZE;
597 adata (abfd)->segment_size = SEGMENT_SIZE;
598 adata (abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
602 /* The architecture is encoded in various ways in various a.out variants,
603 or is not encoded at all in some of them. The relocation size depends
604 on the architecture and the a.out variant. Finally, the return value
605 is the bfd_target vector in use. If an error occurs, return zero and
606 set bfd_error to the appropriate error code.
608 Formats such as b.out, which have additional fields in the a.out
609 header, should cope with them in this callback as well. */
610 #endif /* DOCUMENTATION */
612 result = (*callback_to_real_object_p) (abfd);
614 /* Now that the segment addresses have been worked out, take a better
615 guess at whether the file is executable. If the entry point
616 is within the text segment, assume it is. (This makes files
617 executable even if their entry point address is 0, as long as
618 their text starts at zero.).
620 This test had to be changed to deal with systems where the text segment
621 runs at a different location than the default. The problem is that the
622 entry address can appear to be outside the text segment, thus causing an
623 erroneous conclusion that the file isn't executable.
625 To fix this, we now accept any non-zero entry point as an indication of
626 executability. This will work most of the time, since only the linker
627 sets the entry point, and that is likely to be non-zero for most systems. */
629 if (execp->a_entry != 0
630 || (execp->a_entry >= obj_textsec (abfd)->vma
631 && execp->a_entry < (obj_textsec (abfd)->vma
632 + obj_textsec (abfd)->_raw_size)))
633 abfd->flags |= EXEC_P;
637 struct stat stat_buf;
639 /* The original heuristic doesn't work in some important cases.
640 The a.out file has no information about the text start
641 address. For files (like kernels) linked to non-standard
642 addresses (ld -Ttext nnn) the entry point may not be between
643 the default text start (obj_textsec(abfd)->vma) and
644 (obj_textsec(abfd)->vma) + text size. This is not just a mach
645 issue. Many kernels are loaded at non standard addresses. */
646 if (abfd->iostream != NULL
647 && (abfd->flags & BFD_IN_MEMORY) == 0
648 && (fstat (fileno ((FILE *) (abfd->iostream)), &stat_buf) == 0)
649 && ((stat_buf.st_mode & 0111) != 0))
650 abfd->flags |= EXEC_P;
652 #endif /* STAT_FOR_EXEC */
656 #if 0 /* These should be set correctly anyways. */
657 abfd->sections = obj_textsec (abfd);
658 obj_textsec (abfd)->next = obj_datasec (abfd);
659 obj_datasec (abfd)->next = obj_bsssec (abfd);
665 bfd_release (abfd, rawptr);
666 abfd->tdata.aout_data = oldrawptr;
672 aout_@var{size}_mkobject
675 boolean aout_@var{size}_mkobject, (bfd *abfd);
678 Initialize BFD @var{abfd} for use with a.out files.
682 NAME(aout,mkobject) (abfd)
685 struct aout_data_struct *rawptr;
686 bfd_size_type amt = sizeof (struct aout_data_struct);
688 bfd_set_error (bfd_error_system_call);
690 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
694 abfd->tdata.aout_data = rawptr;
695 exec_hdr (abfd) = &(rawptr->e);
697 obj_textsec (abfd) = (asection *) NULL;
698 obj_datasec (abfd) = (asection *) NULL;
699 obj_bsssec (abfd) = (asection *) NULL;
706 aout_@var{size}_machine_type
709 enum machine_type aout_@var{size}_machine_type
710 (enum bfd_architecture arch,
711 unsigned long machine));
714 Keep track of machine architecture and machine type for
715 a.out's. Return the <<machine_type>> for a particular
716 architecture and machine, or <<M_UNKNOWN>> if that exact architecture
717 and machine can't be represented in a.out format.
719 If the architecture is understood, machine type 0 (default)
720 is always understood.
724 NAME(aout,machine_type) (arch, machine, unknown)
725 enum bfd_architecture arch;
726 unsigned long machine;
729 enum machine_type arch_flags;
731 arch_flags = M_UNKNOWN;
738 || machine == bfd_mach_sparc
739 || machine == bfd_mach_sparc_sparclite
740 || machine == bfd_mach_sparc_sparclite_le
741 || machine == bfd_mach_sparc_v9)
742 arch_flags = M_SPARC;
743 else if (machine == bfd_mach_sparc_sparclet)
744 arch_flags = M_SPARCLET;
750 case 0: arch_flags = M_68010; break;
751 case bfd_mach_m68000: arch_flags = M_UNKNOWN; *unknown = false; break;
752 case bfd_mach_m68010: arch_flags = M_68010; break;
753 case bfd_mach_m68020: arch_flags = M_68020; break;
754 default: arch_flags = M_UNKNOWN; break;
777 case bfd_mach_mips3000:
778 case bfd_mach_mips3900:
779 arch_flags = M_MIPS1;
781 case bfd_mach_mips6000:
782 arch_flags = M_MIPS2;
784 case bfd_mach_mips4000:
785 case bfd_mach_mips4010:
786 case bfd_mach_mips4100:
787 case bfd_mach_mips4300:
788 case bfd_mach_mips4400:
789 case bfd_mach_mips4600:
790 case bfd_mach_mips4650:
791 case bfd_mach_mips8000:
792 case bfd_mach_mips10000:
793 case bfd_mach_mips12000:
794 case bfd_mach_mips16:
795 case bfd_mach_mipsisa32:
797 case bfd_mach_mipsisa64:
798 case bfd_mach_mips_sb1:
799 /* FIXME: These should be MIPS3, MIPS4, MIPS16, MIPS32, etc. */
800 arch_flags = M_MIPS2;
803 arch_flags = M_UNKNOWN;
811 case 0: arch_flags = M_NS32532; break;
812 case 32032: arch_flags = M_NS32032; break;
813 case 32532: arch_flags = M_NS32532; break;
814 default: arch_flags = M_UNKNOWN; break;
823 if (machine == 0 || machine == 255)
828 arch_flags = M_UNKNOWN;
831 if (arch_flags != M_UNKNOWN)
839 aout_@var{size}_set_arch_mach
842 boolean aout_@var{size}_set_arch_mach,
844 enum bfd_architecture arch,
845 unsigned long machine));
848 Set the architecture and the machine of the BFD @var{abfd} to the
849 values @var{arch} and @var{machine}. Verify that @var{abfd}'s format
850 can support the architecture required.
854 NAME(aout,set_arch_mach) (abfd, arch, machine)
856 enum bfd_architecture arch;
857 unsigned long machine;
859 if (! bfd_default_set_arch_mach (abfd, arch, machine))
862 if (arch != bfd_arch_unknown)
866 NAME(aout,machine_type) (arch, machine, &unknown);
871 /* Determine the size of a relocation entry. */
877 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
880 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
884 return (*aout_backend_info (abfd)->set_sizes) (abfd);
888 adjust_o_magic (abfd, execp)
890 struct internal_exec *execp;
892 file_ptr pos = adata (abfd).exec_bytes_size;
897 obj_textsec (abfd)->filepos = pos;
898 if (!obj_textsec (abfd)->user_set_vma)
899 obj_textsec (abfd)->vma = vma;
901 vma = obj_textsec (abfd)->vma;
903 pos += obj_textsec (abfd)->_raw_size;
904 vma += obj_textsec (abfd)->_raw_size;
907 if (!obj_datasec (abfd)->user_set_vma)
909 #if 0 /* ?? Does alignment in the file image really matter? */
910 pad = align_power (vma, obj_datasec (abfd)->alignment_power) - vma;
912 obj_textsec (abfd)->_raw_size += pad;
915 obj_datasec (abfd)->vma = vma;
918 vma = obj_datasec (abfd)->vma;
919 obj_datasec (abfd)->filepos = pos;
920 pos += obj_datasec (abfd)->_raw_size;
921 vma += obj_datasec (abfd)->_raw_size;
924 if (!obj_bsssec (abfd)->user_set_vma)
927 pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
929 obj_datasec (abfd)->_raw_size += pad;
932 obj_bsssec (abfd)->vma = vma;
936 /* The VMA of the .bss section is set by the VMA of the
937 .data section plus the size of the .data section. We may
938 need to add padding bytes to make this true. */
939 pad = obj_bsssec (abfd)->vma - vma;
942 obj_datasec (abfd)->_raw_size += pad;
946 obj_bsssec (abfd)->filepos = pos;
948 /* Fix up the exec header. */
949 execp->a_text = obj_textsec (abfd)->_raw_size;
950 execp->a_data = obj_datasec (abfd)->_raw_size;
951 execp->a_bss = obj_bsssec (abfd)->_raw_size;
952 N_SET_MAGIC (*execp, OMAGIC);
956 adjust_z_magic (abfd, execp)
958 struct internal_exec *execp;
960 bfd_size_type data_pad, text_pad;
962 const struct aout_backend_data *abdp;
963 int ztih; /* Nonzero if text includes exec header. */
965 abdp = aout_backend_info (abfd);
969 && (abdp->text_includes_header
970 || obj_aout_subformat (abfd) == q_magic_format));
971 obj_textsec (abfd)->filepos = (ztih
972 ? adata (abfd).exec_bytes_size
973 : adata (abfd).zmagic_disk_block_size);
974 if (! obj_textsec (abfd)->user_set_vma)
976 /* ?? Do we really need to check for relocs here? */
977 obj_textsec (abfd)->vma = ((abfd->flags & HAS_RELOC)
980 ? (abdp->default_text_vma
981 + adata (abfd).exec_bytes_size)
982 : abdp->default_text_vma));
987 /* The .text section is being loaded at an unusual address. We
988 may need to pad it such that the .data section starts at a page
991 text_pad = ((obj_textsec (abfd)->filepos - obj_textsec (abfd)->vma)
992 & (adata (abfd).page_size - 1));
994 text_pad = ((- obj_textsec (abfd)->vma)
995 & (adata (abfd).page_size - 1));
998 /* Find start of data. */
1001 text_end = obj_textsec (abfd)->filepos + obj_textsec (abfd)->_raw_size;
1002 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
1006 /* Note that if page_size == zmagic_disk_block_size, then
1007 filepos == page_size, and this case is the same as the ztih
1009 text_end = obj_textsec (abfd)->_raw_size;
1010 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
1011 text_end += obj_textsec (abfd)->filepos;
1013 obj_textsec (abfd)->_raw_size += text_pad;
1014 text_end += text_pad;
1017 if (!obj_datasec (abfd)->user_set_vma)
1020 vma = obj_textsec (abfd)->vma + obj_textsec (abfd)->_raw_size;
1021 obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
1023 if (abdp && abdp->zmagic_mapped_contiguous)
1025 asection * text = obj_textsec (abfd);
1026 asection * data = obj_datasec (abfd);
1028 text_pad = data->vma - (text->vma + text->_raw_size);
1029 /* Only pad the text section if the data
1030 section is going to be placed after it. */
1032 text->_raw_size += text_pad;
1034 obj_datasec (abfd)->filepos = (obj_textsec (abfd)->filepos
1035 + obj_textsec (abfd)->_raw_size);
1037 /* Fix up exec header while we're at it. */
1038 execp->a_text = obj_textsec (abfd)->_raw_size;
1039 if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
1040 execp->a_text += adata (abfd).exec_bytes_size;
1041 if (obj_aout_subformat (abfd) == q_magic_format)
1042 N_SET_MAGIC (*execp, QMAGIC);
1044 N_SET_MAGIC (*execp, ZMAGIC);
1046 /* Spec says data section should be rounded up to page boundary. */
1047 obj_datasec (abfd)->_raw_size
1048 = align_power (obj_datasec (abfd)->_raw_size,
1049 obj_bsssec (abfd)->alignment_power);
1050 execp->a_data = BFD_ALIGN (obj_datasec (abfd)->_raw_size,
1051 adata (abfd).page_size);
1052 data_pad = execp->a_data - obj_datasec (abfd)->_raw_size;
1055 if (!obj_bsssec (abfd)->user_set_vma)
1056 obj_bsssec (abfd)->vma = (obj_datasec (abfd)->vma
1057 + obj_datasec (abfd)->_raw_size);
1058 /* If the BSS immediately follows the data section and extra space
1059 in the page is left after the data section, fudge data
1060 in the header so that the bss section looks smaller by that
1061 amount. We'll start the bss section there, and lie to the OS.
1062 (Note that a linker script, as well as the above assignment,
1063 could have explicitly set the BSS vma to immediately follow
1064 the data section.) */
1065 if (align_power (obj_bsssec (abfd)->vma, obj_bsssec (abfd)->alignment_power)
1066 == obj_datasec (abfd)->vma + obj_datasec (abfd)->_raw_size)
1067 execp->a_bss = (data_pad > obj_bsssec (abfd)->_raw_size
1068 ? 0 : obj_bsssec (abfd)->_raw_size - data_pad);
1070 execp->a_bss = obj_bsssec (abfd)->_raw_size;
1074 adjust_n_magic (abfd, execp)
1076 struct internal_exec *execp;
1078 file_ptr pos = adata (abfd).exec_bytes_size;
1083 obj_textsec (abfd)->filepos = pos;
1084 if (!obj_textsec (abfd)->user_set_vma)
1085 obj_textsec (abfd)->vma = vma;
1087 vma = obj_textsec (abfd)->vma;
1088 pos += obj_textsec (abfd)->_raw_size;
1089 vma += obj_textsec (abfd)->_raw_size;
1092 obj_datasec (abfd)->filepos = pos;
1093 if (!obj_datasec (abfd)->user_set_vma)
1094 obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
1095 vma = obj_datasec (abfd)->vma;
1097 /* Since BSS follows data immediately, see if it needs alignment. */
1098 vma += obj_datasec (abfd)->_raw_size;
1099 pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
1100 obj_datasec (abfd)->_raw_size += pad;
1101 pos += obj_datasec (abfd)->_raw_size;
1104 if (!obj_bsssec (abfd)->user_set_vma)
1105 obj_bsssec (abfd)->vma = vma;
1107 vma = obj_bsssec (abfd)->vma;
1109 /* Fix up exec header. */
1110 execp->a_text = obj_textsec (abfd)->_raw_size;
1111 execp->a_data = obj_datasec (abfd)->_raw_size;
1112 execp->a_bss = obj_bsssec (abfd)->_raw_size;
1113 N_SET_MAGIC (*execp, NMAGIC);
1117 NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end)
1119 bfd_size_type *text_size;
1120 file_ptr *text_end ATTRIBUTE_UNUSED;
1122 struct internal_exec *execp = exec_hdr (abfd);
1124 if (! NAME(aout,make_sections) (abfd))
1127 if (adata (abfd).magic != undecided_magic)
1130 obj_textsec (abfd)->_raw_size =
1131 align_power (obj_textsec (abfd)->_raw_size,
1132 obj_textsec (abfd)->alignment_power);
1134 *text_size = obj_textsec (abfd)->_raw_size;
1135 /* Rule (heuristic) for when to pad to a new page. Note that there
1136 are (at least) two ways demand-paged (ZMAGIC) files have been
1137 handled. Most Berkeley-based systems start the text segment at
1138 (TARGET_PAGE_SIZE). However, newer versions of SUNOS start the text
1139 segment right after the exec header; the latter is counted in the
1140 text segment size, and is paged in by the kernel with the rest of
1143 /* This perhaps isn't the right way to do this, but made it simpler for me
1144 to understand enough to implement it. Better would probably be to go
1145 right from BFD flags to alignment/positioning characteristics. But the
1146 old code was sloppy enough about handling the flags, and had enough
1147 other magic, that it was a little hard for me to understand. I think
1148 I understand it better now, but I haven't time to do the cleanup this
1151 if (abfd->flags & D_PAGED)
1152 /* Whether or not WP_TEXT is set -- let D_PAGED override. */
1153 adata (abfd).magic = z_magic;
1154 else if (abfd->flags & WP_TEXT)
1155 adata (abfd).magic = n_magic;
1157 adata (abfd).magic = o_magic;
1159 #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
1161 fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
1163 switch (adata (abfd).magic)
1165 case n_magic: str = "NMAGIC"; break;
1166 case o_magic: str = "OMAGIC"; break;
1167 case z_magic: str = "ZMAGIC"; break;
1172 obj_textsec (abfd)->vma, obj_textsec (abfd)->_raw_size,
1173 obj_textsec (abfd)->alignment_power,
1174 obj_datasec (abfd)->vma, obj_datasec (abfd)->_raw_size,
1175 obj_datasec (abfd)->alignment_power,
1176 obj_bsssec (abfd)->vma, obj_bsssec (abfd)->_raw_size,
1177 obj_bsssec (abfd)->alignment_power);
1181 switch (adata (abfd).magic)
1184 adjust_o_magic (abfd, execp);
1187 adjust_z_magic (abfd, execp);
1190 adjust_n_magic (abfd, execp);
1196 #ifdef BFD_AOUT_DEBUG
1197 fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
1198 obj_textsec (abfd)->vma, obj_textsec (abfd)->_raw_size,
1199 obj_textsec (abfd)->filepos,
1200 obj_datasec (abfd)->vma, obj_datasec (abfd)->_raw_size,
1201 obj_datasec (abfd)->filepos,
1202 obj_bsssec (abfd)->vma, obj_bsssec (abfd)->_raw_size);
1210 aout_@var{size}_new_section_hook
1213 boolean aout_@var{size}_new_section_hook,
1215 asection *newsect));
1218 Called by the BFD in response to a @code{bfd_make_section}
1222 NAME(aout,new_section_hook) (abfd, newsect)
1226 /* Align to double at least. */
1227 newsect->alignment_power = bfd_get_arch_info (abfd)->section_align_power;
1229 if (bfd_get_format (abfd) == bfd_object)
1231 if (obj_textsec (abfd) == NULL && !strcmp (newsect->name, ".text"))
1233 obj_textsec (abfd)= newsect;
1234 newsect->target_index = N_TEXT;
1238 if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data"))
1240 obj_datasec (abfd) = newsect;
1241 newsect->target_index = N_DATA;
1245 if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss"))
1247 obj_bsssec (abfd) = newsect;
1248 newsect->target_index = N_BSS;
1253 /* We allow more than three sections internally. */
1258 NAME(aout,set_section_contents) (abfd, section, location, offset, count)
1263 bfd_size_type count;
1266 bfd_size_type text_size;
1268 if (! abfd->output_has_begun)
1270 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
1274 if (section == obj_bsssec (abfd))
1276 bfd_set_error (bfd_error_no_contents);
1280 if (section != obj_textsec (abfd)
1281 && section != obj_datasec (abfd))
1283 (*_bfd_error_handler)
1284 (_("%s: can not represent section `%s' in a.out object file format"),
1285 bfd_get_filename (abfd), bfd_get_section_name (abfd, section));
1286 bfd_set_error (bfd_error_nonrepresentable_section);
1292 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
1293 || bfd_bwrite (location, count, abfd) != count)
1300 /* Read the external symbols from an a.out file. */
1303 aout_get_external_symbols (abfd)
1306 if (obj_aout_external_syms (abfd) == (struct external_nlist *) NULL)
1308 bfd_size_type count;
1309 struct external_nlist *syms;
1312 count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
1315 if (! bfd_get_file_window (abfd, obj_sym_filepos (abfd),
1316 exec_hdr (abfd)->a_syms,
1317 &obj_aout_sym_window (abfd), true))
1319 syms = (struct external_nlist *) obj_aout_sym_window (abfd).data;
1321 /* We allocate using malloc to make the values easy to free
1322 later on. If we put them on the objalloc it might not be
1323 possible to free them. */
1324 syms = ((struct external_nlist *)
1325 bfd_malloc (count * EXTERNAL_NLIST_SIZE));
1326 if (syms == (struct external_nlist *) NULL && count != 0)
1329 amt = exec_hdr (abfd)->a_syms;
1330 if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
1331 || bfd_bread (syms, amt, abfd) != amt)
1338 obj_aout_external_syms (abfd) = syms;
1339 obj_aout_external_sym_count (abfd) = count;
1342 if (obj_aout_external_strings (abfd) == NULL
1343 && exec_hdr (abfd)->a_syms != 0)
1345 unsigned char string_chars[BYTES_IN_WORD];
1346 bfd_size_type stringsize;
1348 bfd_size_type amt = BYTES_IN_WORD;
1350 /* Get the size of the strings. */
1351 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
1352 || bfd_bread ((PTR) string_chars, amt, abfd) != amt)
1354 stringsize = GET_WORD (abfd, string_chars);
1357 if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
1358 &obj_aout_string_window (abfd), true))
1360 strings = (char *) obj_aout_string_window (abfd).data;
1362 strings = (char *) bfd_malloc (stringsize + 1);
1363 if (strings == NULL)
1366 /* Skip space for the string count in the buffer for convenience
1367 when using indexes. */
1368 amt = stringsize - BYTES_IN_WORD;
1369 if (bfd_bread (strings + BYTES_IN_WORD, amt, abfd) != amt)
1376 /* Ensure that a zero index yields an empty string. */
1379 strings[stringsize - 1] = 0;
1381 obj_aout_external_strings (abfd) = strings;
1382 obj_aout_external_string_size (abfd) = stringsize;
1388 /* Translate an a.out symbol into a BFD symbol. The desc, other, type
1389 and symbol->value fields of CACHE_PTR will be set from the a.out
1390 nlist structure. This function is responsible for setting
1391 symbol->flags and symbol->section, and adjusting symbol->value. */
1394 translate_from_native_sym_flags (abfd, cache_ptr)
1396 aout_symbol_type *cache_ptr;
1400 if ((cache_ptr->type & N_STAB) != 0
1401 || cache_ptr->type == N_FN)
1405 /* This is a debugging symbol. */
1406 cache_ptr->symbol.flags = BSF_DEBUGGING;
1408 /* Work out the symbol section. */
1409 switch (cache_ptr->type & N_TYPE)
1413 sec = obj_textsec (abfd);
1416 sec = obj_datasec (abfd);
1419 sec = obj_bsssec (abfd);
1423 sec = bfd_abs_section_ptr;
1427 cache_ptr->symbol.section = sec;
1428 cache_ptr->symbol.value -= sec->vma;
1433 /* Get the default visibility. This does not apply to all types, so
1434 we just hold it in a local variable to use if wanted. */
1435 if ((cache_ptr->type & N_EXT) == 0)
1436 visible = BSF_LOCAL;
1438 visible = BSF_GLOBAL;
1440 switch (cache_ptr->type)
1443 case N_ABS: case N_ABS | N_EXT:
1444 cache_ptr->symbol.section = bfd_abs_section_ptr;
1445 cache_ptr->symbol.flags = visible;
1448 case N_UNDF | N_EXT:
1449 if (cache_ptr->symbol.value != 0)
1451 /* This is a common symbol. */
1452 cache_ptr->symbol.flags = BSF_GLOBAL;
1453 cache_ptr->symbol.section = bfd_com_section_ptr;
1457 cache_ptr->symbol.flags = 0;
1458 cache_ptr->symbol.section = bfd_und_section_ptr;
1462 case N_TEXT: case N_TEXT | N_EXT:
1463 cache_ptr->symbol.section = obj_textsec (abfd);
1464 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1465 cache_ptr->symbol.flags = visible;
1468 /* N_SETV symbols used to represent set vectors placed in the
1469 data section. They are no longer generated. Theoretically,
1470 it was possible to extract the entries and combine them with
1471 new ones, although I don't know if that was ever actually
1472 done. Unless that feature is restored, treat them as data
1474 case N_SETV: case N_SETV | N_EXT:
1475 case N_DATA: case N_DATA | N_EXT:
1476 cache_ptr->symbol.section = obj_datasec (abfd);
1477 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1478 cache_ptr->symbol.flags = visible;
1481 case N_BSS: case N_BSS | N_EXT:
1482 cache_ptr->symbol.section = obj_bsssec (abfd);
1483 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1484 cache_ptr->symbol.flags = visible;
1487 case N_SETA: case N_SETA | N_EXT:
1488 case N_SETT: case N_SETT | N_EXT:
1489 case N_SETD: case N_SETD | N_EXT:
1490 case N_SETB: case N_SETB | N_EXT:
1492 /* This code is no longer needed. It used to be used to make
1493 the linker handle set symbols, but they are now handled in
1494 the add_symbols routine instead. */
1497 arelent_chain *reloc;
1498 asection *into_section;
1501 /* This is a set symbol. The name of the symbol is the name
1502 of the set (e.g., __CTOR_LIST__). The value of the symbol
1503 is the value to add to the set. We create a section with
1504 the same name as the symbol, and add a reloc to insert the
1505 appropriate value into the section.
1507 This action is actually obsolete; it used to make the
1508 linker do the right thing, but the linker no longer uses
1511 section = bfd_get_section_by_name (abfd, cache_ptr->symbol.name);
1512 if (section == NULL)
1516 amt = strlen (cache_ptr->symbol.name) + 1;
1517 copy = bfd_alloc (abfd, amt);
1521 strcpy (copy, cache_ptr->symbol.name);
1522 section = bfd_make_section (abfd, copy);
1523 if (section == NULL)
1527 amt = sizeof (arelent_chain);
1528 reloc = (arelent_chain *) bfd_alloc (abfd, amt);
1532 /* Build a relocation entry for the constructor. */
1533 switch (cache_ptr->type & N_TYPE)
1536 into_section = bfd_abs_section_ptr;
1537 cache_ptr->type = N_ABS;
1540 into_section = obj_textsec (abfd);
1541 cache_ptr->type = N_TEXT;
1544 into_section = obj_datasec (abfd);
1545 cache_ptr->type = N_DATA;
1548 into_section = obj_bsssec (abfd);
1549 cache_ptr->type = N_BSS;
1553 /* Build a relocation pointing into the constructor section
1554 pointing at the symbol in the set vector specified. */
1555 reloc->relent.addend = cache_ptr->symbol.value;
1556 cache_ptr->symbol.section = into_section;
1557 reloc->relent.sym_ptr_ptr = into_section->symbol_ptr_ptr;
1559 /* We modify the symbol to belong to a section depending upon
1560 the name of the symbol, and add to the size of the section
1561 to contain a pointer to the symbol. Build a reloc entry to
1562 relocate to this symbol attached to this section. */
1563 section->flags = SEC_CONSTRUCTOR | SEC_RELOC;
1565 section->reloc_count++;
1566 section->alignment_power = 2;
1568 reloc->next = section->constructor_chain;
1569 section->constructor_chain = reloc;
1570 reloc->relent.address = section->_raw_size;
1571 section->_raw_size += BYTES_IN_WORD;
1573 reloc->relent.howto = CTOR_TABLE_RELOC_HOWTO (abfd);
1577 switch (cache_ptr->type & N_TYPE)
1580 cache_ptr->symbol.section = bfd_abs_section_ptr;
1583 cache_ptr->symbol.section = obj_textsec (abfd);
1586 cache_ptr->symbol.section = obj_datasec (abfd);
1589 cache_ptr->symbol.section = obj_bsssec (abfd);
1593 cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
1598 /* This symbol is the text of a warning message. The next
1599 symbol is the symbol to associate the warning with. If a
1600 reference is made to that symbol, a warning is issued. */
1601 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
1602 cache_ptr->symbol.section = bfd_abs_section_ptr;
1605 case N_INDR: case N_INDR | N_EXT:
1606 /* An indirect symbol. This consists of two symbols in a row.
1607 The first symbol is the name of the indirection. The second
1608 symbol is the name of the target. A reference to the first
1609 symbol becomes a reference to the second. */
1610 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible;
1611 cache_ptr->symbol.section = bfd_ind_section_ptr;
1615 cache_ptr->symbol.section = bfd_und_section_ptr;
1616 cache_ptr->symbol.flags = BSF_WEAK;
1620 cache_ptr->symbol.section = bfd_abs_section_ptr;
1621 cache_ptr->symbol.flags = BSF_WEAK;
1625 cache_ptr->symbol.section = obj_textsec (abfd);
1626 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1627 cache_ptr->symbol.flags = BSF_WEAK;
1631 cache_ptr->symbol.section = obj_datasec (abfd);
1632 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1633 cache_ptr->symbol.flags = BSF_WEAK;
1637 cache_ptr->symbol.section = obj_bsssec (abfd);
1638 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1639 cache_ptr->symbol.flags = BSF_WEAK;
1646 /* Set the fields of SYM_POINTER according to CACHE_PTR. */
1649 translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
1652 struct external_nlist *sym_pointer;
1654 bfd_vma value = cache_ptr->value;
1658 /* Mask out any existing type bits in case copying from one section
1660 sym_pointer->e_type[0] &= ~N_TYPE;
1662 sec = bfd_get_section (cache_ptr);
1667 /* This case occurs, e.g., for the *DEBUG* section of a COFF
1669 (*_bfd_error_handler)
1670 (_("%s: can not represent section for symbol `%s' in a.out object file format"),
1671 bfd_get_filename (abfd),
1672 cache_ptr->name != NULL ? cache_ptr->name : _("*unknown*"));
1673 bfd_set_error (bfd_error_nonrepresentable_section);
1677 if (sec->output_section != NULL)
1679 off = sec->output_offset;
1680 sec = sec->output_section;
1683 if (bfd_is_abs_section (sec))
1684 sym_pointer->e_type[0] |= N_ABS;
1685 else if (sec == obj_textsec (abfd))
1686 sym_pointer->e_type[0] |= N_TEXT;
1687 else if (sec == obj_datasec (abfd))
1688 sym_pointer->e_type[0] |= N_DATA;
1689 else if (sec == obj_bsssec (abfd))
1690 sym_pointer->e_type[0] |= N_BSS;
1691 else if (bfd_is_und_section (sec))
1692 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1693 else if (bfd_is_ind_section (sec))
1694 sym_pointer->e_type[0] = N_INDR;
1695 else if (bfd_is_com_section (sec))
1696 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1699 (*_bfd_error_handler)
1700 (_("%s: can not represent section `%s' in a.out object file format"),
1701 bfd_get_filename (abfd), bfd_get_section_name (abfd, sec));
1702 bfd_set_error (bfd_error_nonrepresentable_section);
1706 /* Turn the symbol from section relative to absolute again. */
1707 value += sec->vma + off;
1709 if ((cache_ptr->flags & BSF_WARNING) != 0)
1710 sym_pointer->e_type[0] = N_WARNING;
1712 if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
1713 sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
1714 else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
1715 sym_pointer->e_type[0] |= N_EXT;
1716 else if ((cache_ptr->flags & BSF_LOCAL) != 0)
1717 sym_pointer->e_type[0] &= ~N_EXT;
1719 if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0)
1721 int type = ((aout_symbol_type *) cache_ptr)->type;
1725 case N_ABS: type = N_SETA; break;
1726 case N_TEXT: type = N_SETT; break;
1727 case N_DATA: type = N_SETD; break;
1728 case N_BSS: type = N_SETB; break;
1730 sym_pointer->e_type[0] = type;
1733 if ((cache_ptr->flags & BSF_WEAK) != 0)
1737 switch (sym_pointer->e_type[0] & N_TYPE)
1740 case N_ABS: type = N_WEAKA; break;
1741 case N_TEXT: type = N_WEAKT; break;
1742 case N_DATA: type = N_WEAKD; break;
1743 case N_BSS: type = N_WEAKB; break;
1744 case N_UNDF: type = N_WEAKU; break;
1746 sym_pointer->e_type[0] = type;
1749 PUT_WORD (abfd, value, sym_pointer->e_value);
1754 /* Native-level interface to symbols. */
1757 NAME(aout,make_empty_symbol) (abfd)
1760 bfd_size_type amt = sizeof (aout_symbol_type);
1761 aout_symbol_type *new = (aout_symbol_type *) bfd_zalloc (abfd, amt);
1764 new->symbol.the_bfd = abfd;
1766 return &new->symbol;
1769 /* Translate a set of internal symbols into external symbols. */
1772 NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic)
1774 aout_symbol_type *in;
1775 struct external_nlist *ext;
1776 bfd_size_type count;
1778 bfd_size_type strsize;
1781 struct external_nlist *ext_end;
1783 ext_end = ext + count;
1784 for (; ext < ext_end; ext++, in++)
1788 x = GET_WORD (abfd, ext->e_strx);
1789 in->symbol.the_bfd = abfd;
1791 /* For the normal symbols, the zero index points at the number
1792 of bytes in the string table but is to be interpreted as the
1793 null string. For the dynamic symbols, the number of bytes in
1794 the string table is stored in the __DYNAMIC structure and the
1795 zero index points at an actual string. */
1796 if (x == 0 && ! dynamic)
1797 in->symbol.name = "";
1798 else if (x < strsize)
1799 in->symbol.name = str + x;
1803 in->symbol.value = GET_SWORD (abfd, ext->e_value);
1804 in->desc = H_GET_16 (abfd, ext->e_desc);
1805 in->other = H_GET_8 (abfd, ext->e_other);
1806 in->type = H_GET_8 (abfd, ext->e_type);
1807 in->symbol.udata.p = NULL;
1809 if (! translate_from_native_sym_flags (abfd, in))
1813 in->symbol.flags |= BSF_DYNAMIC;
1819 /* We read the symbols into a buffer, which is discarded when this
1820 function exits. We read the strings into a buffer large enough to
1821 hold them all plus all the cached symbol entries. */
1824 NAME(aout,slurp_symbol_table) (abfd)
1827 struct external_nlist *old_external_syms;
1828 aout_symbol_type *cached;
1829 bfd_size_type cached_size;
1831 /* If there's no work to be done, don't do any. */
1832 if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
1835 old_external_syms = obj_aout_external_syms (abfd);
1837 if (! aout_get_external_symbols (abfd))
1840 cached_size = obj_aout_external_sym_count (abfd);
1841 cached_size *= sizeof (aout_symbol_type);
1842 cached = (aout_symbol_type *) bfd_zmalloc (cached_size);
1843 if (cached == NULL && cached_size != 0)
1846 /* Convert from external symbol information to internal. */
1847 if (! (NAME(aout,translate_symbol_table)
1849 obj_aout_external_syms (abfd),
1850 obj_aout_external_sym_count (abfd),
1851 obj_aout_external_strings (abfd),
1852 obj_aout_external_string_size (abfd),
1859 bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
1861 obj_aout_symbols (abfd) = cached;
1863 /* It is very likely that anybody who calls this function will not
1864 want the external symbol information, so if it was allocated
1865 because of our call to aout_get_external_symbols, we free it up
1866 right away to save space. */
1867 if (old_external_syms == (struct external_nlist *) NULL
1868 && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
1871 bfd_free_window (&obj_aout_sym_window (abfd));
1873 free (obj_aout_external_syms (abfd));
1875 obj_aout_external_syms (abfd) = NULL;
1881 /* We use a hash table when writing out symbols so that we only write
1882 out a particular string once. This helps particularly when the
1883 linker writes out stabs debugging entries, because each different
1884 contributing object file tends to have many duplicate stabs
1887 This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
1888 if BFD_TRADITIONAL_FORMAT is set. */
1890 static bfd_size_type add_to_stringtab
1891 PARAMS ((bfd *, struct bfd_strtab_hash *, const char *, boolean));
1892 static boolean emit_stringtab PARAMS ((bfd *, struct bfd_strtab_hash *));
1894 /* Get the index of a string in a strtab, adding it if it is not
1897 static INLINE bfd_size_type
1898 add_to_stringtab (abfd, tab, str, copy)
1900 struct bfd_strtab_hash *tab;
1905 bfd_size_type index;
1907 /* An index of 0 always means the empty string. */
1908 if (str == 0 || *str == '\0')
1911 /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
1912 doesn't understand a hashed string table. */
1914 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
1917 index = _bfd_stringtab_add (tab, str, hash, copy);
1919 if (index != (bfd_size_type) -1)
1921 /* Add BYTES_IN_WORD to the return value to account for the
1922 space taken up by the string table size. */
1923 index += BYTES_IN_WORD;
1929 /* Write out a strtab. ABFD is already at the right location in the
1933 emit_stringtab (abfd, tab)
1935 struct bfd_strtab_hash *tab;
1937 bfd_byte buffer[BYTES_IN_WORD];
1938 bfd_size_type amt = BYTES_IN_WORD;
1940 /* The string table starts with the size. */
1941 PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
1942 if (bfd_bwrite ((PTR) buffer, amt, abfd) != amt)
1945 return _bfd_stringtab_emit (abfd, tab);
1949 NAME(aout,write_syms) (abfd)
1952 unsigned int count ;
1953 asymbol **generic = bfd_get_outsymbols (abfd);
1954 struct bfd_strtab_hash *strtab;
1956 strtab = _bfd_stringtab_init ();
1960 for (count = 0; count < bfd_get_symcount (abfd); count++)
1962 asymbol *g = generic[count];
1964 struct external_nlist nsp;
1967 indx = add_to_stringtab (abfd, strtab, g->name, false);
1968 if (indx == (bfd_size_type) -1)
1970 PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
1972 if (bfd_asymbol_flavour (g) == abfd->xvec->flavour)
1974 H_PUT_16 (abfd, aout_symbol (g)->desc, nsp.e_desc);
1975 H_PUT_8 (abfd, aout_symbol (g)->other, nsp.e_other);
1976 H_PUT_8 (abfd, aout_symbol (g)->type, nsp.e_type);
1980 H_PUT_16 (abfd, 0, nsp.e_desc);
1981 H_PUT_8 (abfd, 0, nsp.e_other);
1982 H_PUT_8 (abfd, 0, nsp.e_type);
1985 if (! translate_to_native_sym_flags (abfd, g, &nsp))
1988 amt = EXTERNAL_NLIST_SIZE;
1989 if (bfd_bwrite ((PTR) &nsp, amt, abfd) != amt)
1992 /* NB: `KEEPIT' currently overlays `udata.p', so set this only
1993 here, at the end. */
1997 if (! emit_stringtab (abfd, strtab))
2000 _bfd_stringtab_free (strtab);
2005 _bfd_stringtab_free (strtab);
2010 NAME(aout,get_symtab) (abfd, location)
2014 unsigned int counter = 0;
2015 aout_symbol_type *symbase;
2017 if (!NAME(aout,slurp_symbol_table) (abfd))
2020 for (symbase = obj_aout_symbols (abfd);
2021 counter++ < bfd_get_symcount (abfd);
2023 *(location++) = (asymbol *) (symbase++);
2025 return bfd_get_symcount (abfd);
2028 /* Standard reloc stuff. */
2029 /* Output standard relocation information to a file in target byte order. */
2031 extern void NAME(aout,swap_std_reloc_out)
2032 PARAMS ((bfd *, arelent *, struct reloc_std_external *));
2035 NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
2038 struct reloc_std_external *natptr;
2041 asymbol *sym = *(g->sym_ptr_ptr);
2043 unsigned int r_length;
2045 int r_baserel, r_jmptable, r_relative;
2046 asection *output_section = sym->section->output_section;
2048 PUT_WORD (abfd, g->address, natptr->r_address);
2050 r_length = g->howto->size ; /* Size as a power of two. */
2051 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
2052 /* XXX This relies on relocs coming from a.out files. */
2053 r_baserel = (g->howto->type & 8) != 0;
2054 r_jmptable = (g->howto->type & 16) != 0;
2055 r_relative = (g->howto->type & 32) != 0;
2058 /* For a standard reloc, the addend is in the object file. */
2059 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
2062 /* Name was clobbered by aout_write_syms to be symbol index. */
2064 /* If this relocation is relative to a symbol then set the
2065 r_index to the symbols index, and the r_extern bit.
2067 Absolute symbols can come in in two ways, either as an offset
2068 from the abs section, or as a symbol which has an abs value.
2069 check for that here. */
2071 if (bfd_is_com_section (output_section)
2072 || bfd_is_abs_section (output_section)
2073 || bfd_is_und_section (output_section))
2075 if (bfd_abs_section_ptr->symbol == sym)
2077 /* Whoops, looked like an abs symbol, but is
2078 really an offset from the abs section. */
2084 /* Fill in symbol. */
2086 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2091 /* Just an ordinary section. */
2093 r_index = output_section->target_index;
2096 /* Now the fun stuff. */
2097 if (bfd_header_big_endian (abfd))
2099 natptr->r_index[0] = r_index >> 16;
2100 natptr->r_index[1] = r_index >> 8;
2101 natptr->r_index[2] = r_index;
2102 natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
2103 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
2104 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
2105 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
2106 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
2107 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
2111 natptr->r_index[2] = r_index >> 16;
2112 natptr->r_index[1] = r_index >> 8;
2113 natptr->r_index[0] = r_index;
2114 natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
2115 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
2116 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
2117 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
2118 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
2119 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
2123 /* Extended stuff. */
2124 /* Output extended relocation information to a file in target byte order. */
2126 extern void NAME(aout,swap_ext_reloc_out)
2127 PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
2130 NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
2133 register struct reloc_ext_external *natptr;
2137 unsigned int r_type;
2139 asymbol *sym = *(g->sym_ptr_ptr);
2140 asection *output_section = sym->section->output_section;
2142 PUT_WORD (abfd, g->address, natptr->r_address);
2144 r_type = (unsigned int) g->howto->type;
2146 r_addend = g->addend;
2147 if ((sym->flags & BSF_SECTION_SYM) != 0)
2148 r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma;
2150 /* If this relocation is relative to a symbol then set the
2151 r_index to the symbols index, and the r_extern bit.
2153 Absolute symbols can come in in two ways, either as an offset
2154 from the abs section, or as a symbol which has an abs value.
2155 check for that here. */
2156 if (bfd_is_abs_section (bfd_get_section (sym)))
2161 else if ((sym->flags & BSF_SECTION_SYM) == 0)
2163 if (bfd_is_und_section (bfd_get_section (sym))
2164 || (sym->flags & BSF_GLOBAL) != 0)
2168 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2172 /* Just an ordinary section. */
2174 r_index = output_section->target_index;
2177 /* Now the fun stuff. */
2178 if (bfd_header_big_endian (abfd))
2180 natptr->r_index[0] = r_index >> 16;
2181 natptr->r_index[1] = r_index >> 8;
2182 natptr->r_index[2] = r_index;
2183 natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
2184 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
2188 natptr->r_index[2] = r_index >> 16;
2189 natptr->r_index[1] = r_index >> 8;
2190 natptr->r_index[0] = r_index;
2191 natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
2192 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE));
2195 PUT_WORD (abfd, r_addend, natptr->r_addend);
2198 /* BFD deals internally with all things based from the section they're
2199 in. so, something in 10 bytes into a text section with a base of
2200 50 would have a symbol (.text+10) and know .text vma was 50.
2202 Aout keeps all it's symbols based from zero, so the symbol would
2203 contain 60. This macro subs the base of each section from the value
2204 to give the true offset from the section. */
2206 #define MOVE_ADDRESS(ad) \
2209 /* Undefined symbol. */ \
2210 cache_ptr->sym_ptr_ptr = symbols + r_index; \
2211 cache_ptr->addend = ad; \
2215 /* Defined, section relative. Replace symbol with pointer to \
2216 symbol which points to section. */ \
2220 case N_TEXT | N_EXT: \
2221 cache_ptr->sym_ptr_ptr = obj_textsec (abfd)->symbol_ptr_ptr; \
2222 cache_ptr->addend = ad - su->textsec->vma; \
2225 case N_DATA | N_EXT: \
2226 cache_ptr->sym_ptr_ptr = obj_datasec (abfd)->symbol_ptr_ptr; \
2227 cache_ptr->addend = ad - su->datasec->vma; \
2230 case N_BSS | N_EXT: \
2231 cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr; \
2232 cache_ptr->addend = ad - su->bsssec->vma; \
2236 case N_ABS | N_EXT: \
2237 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
2238 cache_ptr->addend = ad; \
2244 NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2246 struct reloc_ext_external *bytes;
2249 bfd_size_type symcount;
2251 unsigned int r_index;
2253 unsigned int r_type;
2254 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2256 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2258 /* Now the fun stuff. */
2259 if (bfd_header_big_endian (abfd))
2261 r_index = ((bytes->r_index[0] << 16)
2262 | (bytes->r_index[1] << 8)
2263 | bytes->r_index[2]);
2264 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2265 r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2266 >> RELOC_EXT_BITS_TYPE_SH_BIG);
2270 r_index = ((bytes->r_index[2] << 16)
2271 | (bytes->r_index[1] << 8)
2272 | bytes->r_index[0]);
2273 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2274 r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2275 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
2278 cache_ptr->howto = howto_table_ext + r_type;
2280 /* Base relative relocs are always against the symbol table,
2281 regardless of the setting of r_extern. r_extern just reflects
2282 whether the symbol the reloc is against is local or global. */
2283 if (r_type == RELOC_BASE10
2284 || r_type == RELOC_BASE13
2285 || r_type == RELOC_BASE22)
2288 if (r_extern && r_index > symcount)
2290 /* We could arrange to return an error, but it might be useful
2291 to see the file even if it is bad. */
2296 MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
2300 NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2302 struct reloc_std_external *bytes;
2305 bfd_size_type symcount;
2307 unsigned int r_index;
2309 unsigned int r_length;
2311 int r_baserel, r_jmptable, r_relative;
2312 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2313 unsigned int howto_idx;
2315 cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
2317 /* Now the fun stuff. */
2318 if (bfd_header_big_endian (abfd))
2320 r_index = ((bytes->r_index[0] << 16)
2321 | (bytes->r_index[1] << 8)
2322 | bytes->r_index[2]);
2323 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2324 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2325 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2326 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2327 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2328 r_length = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2329 >> RELOC_STD_BITS_LENGTH_SH_BIG);
2333 r_index = ((bytes->r_index[2] << 16)
2334 | (bytes->r_index[1] << 8)
2335 | bytes->r_index[0]);
2336 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2337 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2338 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2339 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2340 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2341 r_length = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2342 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
2345 howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
2346 + 16 * r_jmptable + 32 * r_relative);
2347 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
2348 cache_ptr->howto = howto_table_std + howto_idx;
2349 BFD_ASSERT (cache_ptr->howto->type != (unsigned int) -1);
2351 /* Base relative relocs are always against the symbol table,
2352 regardless of the setting of r_extern. r_extern just reflects
2353 whether the symbol the reloc is against is local or global. */
2357 if (r_extern && r_index > symcount)
2359 /* We could arrange to return an error, but it might be useful
2360 to see the file even if it is bad. */
2368 /* Read and swap the relocs for a section. */
2371 NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
2376 bfd_size_type count;
2377 bfd_size_type reloc_size;
2379 arelent *reloc_cache;
2381 unsigned int counter = 0;
2385 if (asect->relocation)
2388 if (asect->flags & SEC_CONSTRUCTOR)
2391 if (asect == obj_datasec (abfd))
2392 reloc_size = exec_hdr (abfd)->a_drsize;
2393 else if (asect == obj_textsec (abfd))
2394 reloc_size = exec_hdr (abfd)->a_trsize;
2395 else if (asect == obj_bsssec (abfd))
2399 bfd_set_error (bfd_error_invalid_operation);
2403 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
2406 each_size = obj_reloc_entry_size (abfd);
2408 count = reloc_size / each_size;
2410 amt = count * sizeof (arelent);
2411 reloc_cache = (arelent *) bfd_zmalloc (amt);
2412 if (reloc_cache == NULL && count != 0)
2415 relocs = bfd_malloc (reloc_size);
2416 if (relocs == NULL && reloc_size != 0)
2422 if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
2429 cache_ptr = reloc_cache;
2430 if (each_size == RELOC_EXT_SIZE)
2432 struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
2434 for (; counter < count; counter++, rptr++, cache_ptr++)
2435 MY_swap_ext_reloc_in (abfd, rptr, cache_ptr, symbols,
2436 (bfd_size_type) bfd_get_symcount (abfd));
2440 struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
2442 for (; counter < count; counter++, rptr++, cache_ptr++)
2443 MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
2444 (bfd_size_type) bfd_get_symcount (abfd));
2449 asect->relocation = reloc_cache;
2450 asect->reloc_count = cache_ptr - reloc_cache;
2455 /* Write out a relocation section into an object file. */
2458 NAME(aout,squirt_out_relocs) (abfd, section)
2463 unsigned char *native, *natptr;
2466 unsigned int count = section->reloc_count;
2467 bfd_size_type natsize;
2469 if (count == 0 || section->orelocation == NULL)
2472 each_size = obj_reloc_entry_size (abfd);
2473 natsize = (bfd_size_type) each_size * count;
2474 native = (unsigned char *) bfd_zalloc (abfd, natsize);
2478 generic = section->orelocation;
2480 if (each_size == RELOC_EXT_SIZE)
2482 for (natptr = native;
2484 --count, natptr += each_size, ++generic)
2485 MY_swap_ext_reloc_out (abfd, *generic,
2486 (struct reloc_ext_external *) natptr);
2490 for (natptr = native;
2492 --count, natptr += each_size, ++generic)
2493 MY_swap_std_reloc_out (abfd, *generic,
2494 (struct reloc_std_external *) natptr);
2497 if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
2499 bfd_release (abfd, native);
2502 bfd_release (abfd, native);
2507 /* This is stupid. This function should be a boolean predicate. */
2510 NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols)
2516 arelent *tblptr = section->relocation;
2519 if (section == obj_bsssec (abfd))
2525 if (!(tblptr || NAME(aout,slurp_reloc_table) (abfd, section, symbols)))
2528 if (section->flags & SEC_CONSTRUCTOR)
2530 arelent_chain *chain = section->constructor_chain;
2531 for (count = 0; count < section->reloc_count; count ++)
2533 *relptr ++ = &chain->relent;
2534 chain = chain->next;
2539 tblptr = section->relocation;
2541 for (count = 0; count++ < section->reloc_count; )
2543 *relptr++ = tblptr++;
2548 return section->reloc_count;
2552 NAME(aout,get_reloc_upper_bound) (abfd, asect)
2556 if (bfd_get_format (abfd) != bfd_object)
2558 bfd_set_error (bfd_error_invalid_operation);
2562 if (asect->flags & SEC_CONSTRUCTOR)
2563 return (sizeof (arelent *) * (asect->reloc_count+1));
2565 if (asect == obj_datasec (abfd))
2566 return (sizeof (arelent *)
2567 * ((exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd))
2570 if (asect == obj_textsec (abfd))
2571 return (sizeof (arelent *)
2572 * ((exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd))
2575 if (asect == obj_bsssec (abfd))
2576 return sizeof (arelent *);
2578 if (asect == obj_bsssec (abfd))
2581 bfd_set_error (bfd_error_invalid_operation);
2586 NAME(aout,get_symtab_upper_bound) (abfd)
2589 if (!NAME(aout,slurp_symbol_table) (abfd))
2592 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2596 NAME(aout,get_lineno) (ignore_abfd, ignore_symbol)
2597 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2598 asymbol *ignore_symbol ATTRIBUTE_UNUSED;
2600 return (alent *)NULL;
2604 NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
2605 bfd *ignore_abfd ATTRIBUTE_UNUSED;
2609 bfd_symbol_info (symbol, ret);
2611 if (ret->type == '?')
2613 int type_code = aout_symbol (symbol)->type & 0xff;
2614 const char *stab_name = bfd_get_stab_name (type_code);
2615 static char buf[10];
2617 if (stab_name == NULL)
2619 sprintf (buf, "(%d)", type_code);
2623 ret->stab_type = type_code;
2624 ret->stab_other = (unsigned) (aout_symbol (symbol)->other & 0xff);
2625 ret->stab_desc = (unsigned) (aout_symbol (symbol)->desc & 0xffff);
2626 ret->stab_name = stab_name;
2631 NAME(aout,print_symbol) (abfd, afile, symbol, how)
2635 bfd_print_symbol_type how;
2637 FILE *file = (FILE *)afile;
2641 case bfd_print_symbol_name:
2643 fprintf (file,"%s", symbol->name);
2645 case bfd_print_symbol_more:
2646 fprintf (file,"%4x %2x %2x",
2647 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2648 (unsigned) (aout_symbol (symbol)->other & 0xff),
2649 (unsigned) (aout_symbol (symbol)->type));
2651 case bfd_print_symbol_all:
2653 const char *section_name = symbol->section->name;
2655 bfd_print_symbol_vandf (abfd, (PTR)file, symbol);
2657 fprintf (file," %-5s %04x %02x %02x",
2659 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2660 (unsigned) (aout_symbol (symbol)->other & 0xff),
2661 (unsigned) (aout_symbol (symbol)->type & 0xff));
2663 fprintf (file," %s", symbol->name);
2669 /* If we don't have to allocate more than 1MB to hold the generic
2670 symbols, we use the generic minisymbol methord: it's faster, since
2671 it only translates the symbols once, not multiple times. */
2672 #define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
2674 /* Read minisymbols. For minisymbols, we use the unmodified a.out
2675 symbols. The minisymbol_to_symbol function translates these into
2676 BFD asymbol structures. */
2679 NAME(aout,read_minisymbols) (abfd, dynamic, minisymsp, sizep)
2683 unsigned int *sizep;
2687 /* We could handle the dynamic symbols here as well, but it's
2688 easier to hand them off. */
2689 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2692 if (! aout_get_external_symbols (abfd))
2695 if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2696 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2698 *minisymsp = (PTR) obj_aout_external_syms (abfd);
2700 /* By passing the external symbols back from this routine, we are
2701 giving up control over the memory block. Clear
2702 obj_aout_external_syms, so that we do not try to free it
2704 obj_aout_external_syms (abfd) = NULL;
2706 *sizep = EXTERNAL_NLIST_SIZE;
2707 return obj_aout_external_sym_count (abfd);
2710 /* Convert a minisymbol to a BFD asymbol. A minisymbol is just an
2711 unmodified a.out symbol. The SYM argument is a structure returned
2712 by bfd_make_empty_symbol, which we fill in here. */
2715 NAME(aout,minisymbol_to_symbol) (abfd, dynamic, minisym, sym)
2722 || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2723 return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
2725 memset (sym, 0, sizeof (aout_symbol_type));
2727 /* We call translate_symbol_table to translate a single symbol. */
2728 if (! (NAME(aout,translate_symbol_table)
2730 (aout_symbol_type *) sym,
2731 (struct external_nlist *) minisym,
2733 obj_aout_external_strings (abfd),
2734 obj_aout_external_string_size (abfd),
2741 /* Provided a BFD, a section and an offset into the section, calculate
2742 and return the name of the source file and the line nearest to the
2746 NAME(aout,find_nearest_line)
2747 (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
2752 const char **filename_ptr;
2753 const char **functionname_ptr;
2754 unsigned int *line_ptr;
2756 /* Run down the file looking for the filename, function and linenumber. */
2758 const char *directory_name = NULL;
2759 const char *main_file_name = NULL;
2760 const char *current_file_name = NULL;
2761 const char *line_file_name = NULL; /* Value of current_file_name at line number. */
2762 const char *line_directory_name = NULL; /* Value of directory_name at line number. */
2763 bfd_vma low_line_vma = 0;
2764 bfd_vma low_func_vma = 0;
2766 bfd_size_type filelen, funclen;
2769 *filename_ptr = abfd->filename;
2770 *functionname_ptr = 0;
2773 if (symbols != (asymbol **)NULL)
2775 for (p = symbols; *p; p++)
2777 aout_symbol_type *q = (aout_symbol_type *) (*p);
2782 /* If this looks like a file name symbol, and it comes after
2783 the line number we have found so far, but before the
2784 offset, then we have probably not found the right line
2786 if (q->symbol.value <= offset
2787 && ((q->symbol.value > low_line_vma
2788 && (line_file_name != NULL
2790 || (q->symbol.value > low_func_vma
2793 const char *symname;
2795 symname = q->symbol.name;
2796 if (strcmp (symname + strlen (symname) - 2, ".o") == 0)
2798 if (q->symbol.value > low_line_vma)
2801 line_file_name = NULL;
2803 if (q->symbol.value > low_func_vma)
2810 /* If this symbol is less than the offset, but greater than
2811 the line number we have found so far, then we have not
2812 found the right line number. */
2813 if (q->symbol.value <= offset)
2815 if (q->symbol.value > low_line_vma)
2818 line_file_name = NULL;
2820 if (q->symbol.value > low_func_vma)
2824 main_file_name = current_file_name = q->symbol.name;
2825 /* Look ahead to next symbol to check if that too is an N_SO. */
2829 q = (aout_symbol_type *) (*p);
2830 if (q->type != (int)N_SO)
2833 /* Found a second N_SO First is directory; second is filename. */
2834 directory_name = current_file_name;
2835 main_file_name = current_file_name = q->symbol.name;
2836 if (obj_textsec (abfd) != section)
2840 current_file_name = q->symbol.name;
2847 /* We'll keep this if it resolves nearer than the one we have
2849 if (q->symbol.value >= low_line_vma
2850 && q->symbol.value <= offset)
2852 *line_ptr = q->desc;
2853 low_line_vma = q->symbol.value;
2854 line_file_name = current_file_name;
2855 line_directory_name = directory_name;
2860 /* We'll keep this if it is nearer than the one we have already. */
2861 if (q->symbol.value >= low_func_vma &&
2862 q->symbol.value <= offset)
2864 low_func_vma = q->symbol.value;
2865 func = (asymbol *)q;
2867 else if (q->symbol.value > offset)
2878 main_file_name = line_file_name;
2879 directory_name = line_directory_name;
2882 if (main_file_name == NULL
2883 || IS_ABSOLUTE_PATH (main_file_name)
2884 || directory_name == NULL)
2887 filelen = strlen (directory_name) + strlen (main_file_name);
2892 funclen = strlen (bfd_asymbol_name (func));
2894 if (adata (abfd).line_buf != NULL)
2895 free (adata (abfd).line_buf);
2897 if (filelen + funclen == 0)
2898 adata (abfd).line_buf = buf = NULL;
2901 buf = (char *) bfd_malloc (filelen + funclen + 3);
2902 adata (abfd).line_buf = buf;
2907 if (main_file_name != NULL)
2909 if (IS_ABSOLUTE_PATH (main_file_name) || directory_name == NULL)
2910 *filename_ptr = main_file_name;
2913 sprintf (buf, "%s%s", directory_name, main_file_name);
2914 *filename_ptr = buf;
2921 const char *function = func->name;
2924 /* The caller expects a symbol name. We actually have a
2925 function name, without the leading underscore. Put the
2926 underscore back in, so that the caller gets a symbol name. */
2927 if (bfd_get_symbol_leading_char (abfd) == '\0')
2928 strcpy (buf, function);
2931 buf[0] = bfd_get_symbol_leading_char (abfd);
2932 strcpy (buf + 1, function);
2934 /* Have to remove : stuff. */
2935 colon = strchr (buf, ':');
2938 *functionname_ptr = buf;
2945 NAME(aout,sizeof_headers) (abfd, execable)
2947 boolean execable ATTRIBUTE_UNUSED;
2949 return adata (abfd).exec_bytes_size;
2952 /* Free all information we have cached for this BFD. We can always
2953 read it again later if we need it. */
2956 NAME(aout,bfd_free_cached_info) (abfd)
2961 if (bfd_get_format (abfd) != bfd_object
2962 || abfd->tdata.aout_data == NULL)
2965 #define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
2966 BFCI_FREE (obj_aout_symbols (abfd));
2968 obj_aout_external_syms (abfd) = 0;
2969 bfd_free_window (&obj_aout_sym_window (abfd));
2970 bfd_free_window (&obj_aout_string_window (abfd));
2971 obj_aout_external_strings (abfd) = 0;
2973 BFCI_FREE (obj_aout_external_syms (abfd));
2974 BFCI_FREE (obj_aout_external_strings (abfd));
2976 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
2977 BFCI_FREE (o->relocation);
2983 /* a.out link code. */
2985 static boolean aout_link_add_object_symbols
2986 PARAMS ((bfd *, struct bfd_link_info *));
2987 static boolean aout_link_check_archive_element
2988 PARAMS ((bfd *, struct bfd_link_info *, boolean *));
2989 static boolean aout_link_free_symbols PARAMS ((bfd *));
2990 static boolean aout_link_check_ar_symbols
2991 PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
2992 static boolean aout_link_add_symbols
2993 PARAMS ((bfd *, struct bfd_link_info *));
2995 /* Routine to create an entry in an a.out link hash table. */
2997 struct bfd_hash_entry *
2998 NAME(aout,link_hash_newfunc) (entry, table, string)
2999 struct bfd_hash_entry *entry;
3000 struct bfd_hash_table *table;
3003 struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
3005 /* Allocate the structure if it has not already been allocated by a
3007 if (ret == (struct aout_link_hash_entry *) NULL)
3008 ret = ((struct aout_link_hash_entry *)
3009 bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
3010 if (ret == (struct aout_link_hash_entry *) NULL)
3011 return (struct bfd_hash_entry *) ret;
3013 /* Call the allocation method of the superclass. */
3014 ret = ((struct aout_link_hash_entry *)
3015 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
3019 /* Set local fields. */
3020 ret->written = false;
3024 return (struct bfd_hash_entry *) ret;
3027 /* Initialize an a.out link hash table. */
3030 NAME(aout,link_hash_table_init) (table, abfd, newfunc)
3031 struct aout_link_hash_table *table;
3033 struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
3034 struct bfd_hash_table *,
3037 return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
3040 /* Create an a.out link hash table. */
3042 struct bfd_link_hash_table *
3043 NAME(aout,link_hash_table_create) (abfd)
3046 struct aout_link_hash_table *ret;
3047 bfd_size_type amt = sizeof (struct aout_link_hash_table);
3049 ret = (struct aout_link_hash_table *) bfd_alloc (abfd, amt);
3051 return (struct bfd_link_hash_table *) NULL;
3052 if (! NAME(aout,link_hash_table_init) (ret, abfd,
3053 NAME(aout,link_hash_newfunc)))
3056 return (struct bfd_link_hash_table *) NULL;
3061 /* Given an a.out BFD, add symbols to the global hash table as
3065 NAME(aout,link_add_symbols) (abfd, info)
3067 struct bfd_link_info *info;
3069 switch (bfd_get_format (abfd))
3072 return aout_link_add_object_symbols (abfd, info);
3074 return _bfd_generic_link_add_archive_symbols
3075 (abfd, info, aout_link_check_archive_element);
3077 bfd_set_error (bfd_error_wrong_format);
3082 /* Add symbols from an a.out object file. */
3085 aout_link_add_object_symbols (abfd, info)
3087 struct bfd_link_info *info;
3089 if (! aout_get_external_symbols (abfd))
3091 if (! aout_link_add_symbols (abfd, info))
3093 if (! info->keep_memory)
3095 if (! aout_link_free_symbols (abfd))
3101 /* Check a single archive element to see if we need to include it in
3102 the link. *PNEEDED is set according to whether this element is
3103 needed in the link or not. This is called from
3104 _bfd_generic_link_add_archive_symbols. */
3107 aout_link_check_archive_element (abfd, info, pneeded)
3109 struct bfd_link_info *info;
3112 if (! aout_get_external_symbols (abfd))
3115 if (! aout_link_check_ar_symbols (abfd, info, pneeded))
3120 if (! aout_link_add_symbols (abfd, info))
3124 if (! info->keep_memory || ! *pneeded)
3126 if (! aout_link_free_symbols (abfd))
3133 /* Free up the internal symbols read from an a.out file. */
3136 aout_link_free_symbols (abfd)
3139 if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
3142 bfd_free_window (&obj_aout_sym_window (abfd));
3144 free ((PTR) obj_aout_external_syms (abfd));
3146 obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
3148 if (obj_aout_external_strings (abfd) != (char *) NULL)
3151 bfd_free_window (&obj_aout_string_window (abfd));
3153 free ((PTR) obj_aout_external_strings (abfd));
3155 obj_aout_external_strings (abfd) = (char *) NULL;
3160 /* Look through the internal symbols to see if this object file should
3161 be included in the link. We should include this object file if it
3162 defines any symbols which are currently undefined. If this object
3163 file defines a common symbol, then we may adjust the size of the
3164 known symbol but we do not include the object file in the link
3165 (unless there is some other reason to include it). */
3168 aout_link_check_ar_symbols (abfd, info, pneeded)
3170 struct bfd_link_info *info;
3173 register struct external_nlist *p;
3174 struct external_nlist *pend;
3179 /* Look through all the symbols. */
3180 p = obj_aout_external_syms (abfd);
3181 pend = p + obj_aout_external_sym_count (abfd);
3182 strings = obj_aout_external_strings (abfd);
3183 for (; p < pend; p++)
3185 int type = H_GET_8 (abfd, p->e_type);
3187 struct bfd_link_hash_entry *h;
3189 /* Ignore symbols that are not externally visible. This is an
3190 optimization only, as we check the type more thoroughly
3192 if (((type & N_EXT) == 0
3193 || (type & N_STAB) != 0
3200 if (type == N_WARNING
3206 name = strings + GET_WORD (abfd, p->e_strx);
3207 h = bfd_link_hash_lookup (info->hash, name, false, false, true);
3209 /* We are only interested in symbols that are currently
3210 undefined or common. */
3211 if (h == (struct bfd_link_hash_entry *) NULL
3212 || (h->type != bfd_link_hash_undefined
3213 && h->type != bfd_link_hash_common))
3215 if (type == (N_INDR | N_EXT))
3220 if (type == (N_TEXT | N_EXT)
3221 || type == (N_DATA | N_EXT)
3222 || type == (N_BSS | N_EXT)
3223 || type == (N_ABS | N_EXT)
3224 || type == (N_INDR | N_EXT))
3226 /* This object file defines this symbol. We must link it
3227 in. This is true regardless of whether the current
3228 definition of the symbol is undefined or common.
3230 If the current definition is common, we have a case in
3231 which we have already seen an object file including:
3233 and this object file from the archive includes:
3235 In such a case, whether to include this object is target
3236 dependant for backward compatability.
3238 FIXME: The SunOS 4.1.3 linker will pull in the archive
3239 element if the symbol is defined in the .data section,
3240 but not if it is defined in the .text section. That
3241 seems a bit crazy to me, and it has not been implemented
3242 yet. However, it might be correct. */
3243 if (h->type == bfd_link_hash_common)
3247 switch (info->common_skip_ar_aymbols)
3249 case bfd_link_common_skip_text:
3250 skip = (type == (N_TEXT | N_EXT));
3252 case bfd_link_common_skip_data:
3253 skip = (type == (N_DATA | N_EXT));
3256 case bfd_link_common_skip_all:
3265 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3271 if (type == (N_UNDF | N_EXT))
3275 value = GET_WORD (abfd, p->e_value);
3278 /* This symbol is common in the object from the archive
3280 if (h->type == bfd_link_hash_undefined)
3285 symbfd = h->u.undef.abfd;
3286 if (symbfd == (bfd *) NULL)
3288 /* This symbol was created as undefined from
3289 outside BFD. We assume that we should link
3290 in the object file. This is done for the -u
3291 option in the linker. */
3292 if (! (*info->callbacks->add_archive_element) (info,
3299 /* Turn the current link symbol into a common
3300 symbol. It is already on the undefs list. */
3301 h->type = bfd_link_hash_common;
3302 h->u.c.p = ((struct bfd_link_hash_common_entry *)
3303 bfd_hash_allocate (&info->hash->table,
3304 sizeof (struct bfd_link_hash_common_entry)));
3305 if (h->u.c.p == NULL)
3308 h->u.c.size = value;
3310 /* FIXME: This isn't quite right. The maximum
3311 alignment of a common symbol should be set by the
3312 architecture of the output file, not of the input
3314 power = bfd_log2 (value);
3315 if (power > bfd_get_arch_info (abfd)->section_align_power)
3316 power = bfd_get_arch_info (abfd)->section_align_power;
3317 h->u.c.p->alignment_power = power;
3319 h->u.c.p->section = bfd_make_section_old_way (symbfd,
3324 /* Adjust the size of the common symbol if
3326 if (value > h->u.c.size)
3327 h->u.c.size = value;
3337 /* This symbol is weak but defined. We must pull it in if
3338 the current link symbol is undefined, but we don't want
3339 it if the current link symbol is common. */
3340 if (h->type == bfd_link_hash_undefined)
3342 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3350 /* We do not need this object file. */
3354 /* Add all symbols from an object file to the hash table. */
3357 aout_link_add_symbols (abfd, info)
3359 struct bfd_link_info *info;
3361 boolean (*add_one_symbol) PARAMS ((struct bfd_link_info *, bfd *,
3362 const char *, flagword, asection *,
3363 bfd_vma, const char *, boolean,
3365 struct bfd_link_hash_entry **));
3366 struct external_nlist *syms;
3367 bfd_size_type sym_count;
3370 struct aout_link_hash_entry **sym_hash;
3371 register struct external_nlist *p;
3372 struct external_nlist *pend;
3375 syms = obj_aout_external_syms (abfd);
3376 sym_count = obj_aout_external_sym_count (abfd);
3377 strings = obj_aout_external_strings (abfd);
3378 if (info->keep_memory)
3383 if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
3385 if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
3386 (abfd, info, &syms, &sym_count, &strings)))
3390 /* We keep a list of the linker hash table entries that correspond
3391 to particular symbols. We could just look them up in the hash
3392 table, but keeping the list is more efficient. Perhaps this
3393 should be conditional on info->keep_memory. */
3394 amt = sym_count * sizeof (struct aout_link_hash_entry *);
3395 sym_hash = (struct aout_link_hash_entry **) bfd_alloc (abfd, amt);
3396 if (sym_hash == NULL && sym_count != 0)
3398 obj_aout_sym_hashes (abfd) = sym_hash;
3400 add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
3401 if (add_one_symbol == NULL)
3402 add_one_symbol = _bfd_generic_link_add_one_symbol;
3405 pend = p + sym_count;
3406 for (; p < pend; p++, sym_hash++)
3417 type = H_GET_8 (abfd, p->e_type);
3419 /* Ignore debugging symbols. */
3420 if ((type & N_STAB) != 0)
3423 name = strings + GET_WORD (abfd, p->e_strx);
3424 value = GET_WORD (abfd, p->e_value);
3441 /* Ignore symbols that are not externally visible. */
3444 /* Ignore local indirect symbol. */
3449 case N_UNDF | N_EXT:
3452 section = bfd_und_section_ptr;
3456 section = bfd_com_section_ptr;
3459 section = bfd_abs_section_ptr;
3461 case N_TEXT | N_EXT:
3462 section = obj_textsec (abfd);
3463 value -= bfd_get_section_vma (abfd, section);
3465 case N_DATA | N_EXT:
3466 case N_SETV | N_EXT:
3467 /* Treat N_SETV symbols as N_DATA symbol; see comment in
3468 translate_from_native_sym_flags. */
3469 section = obj_datasec (abfd);
3470 value -= bfd_get_section_vma (abfd, section);
3473 section = obj_bsssec (abfd);
3474 value -= bfd_get_section_vma (abfd, section);
3476 case N_INDR | N_EXT:
3477 /* An indirect symbol. The next symbol is the symbol
3478 which this one really is. */
3479 BFD_ASSERT (p + 1 < pend);
3481 string = strings + GET_WORD (abfd, p->e_strx);
3482 section = bfd_ind_section_ptr;
3483 flags |= BSF_INDIRECT;
3485 case N_COMM | N_EXT:
3486 section = bfd_com_section_ptr;
3488 case N_SETA: case N_SETA | N_EXT:
3489 section = bfd_abs_section_ptr;
3490 flags |= BSF_CONSTRUCTOR;
3492 case N_SETT: case N_SETT | N_EXT:
3493 section = obj_textsec (abfd);
3494 flags |= BSF_CONSTRUCTOR;
3495 value -= bfd_get_section_vma (abfd, section);
3497 case N_SETD: case N_SETD | N_EXT:
3498 section = obj_datasec (abfd);
3499 flags |= BSF_CONSTRUCTOR;
3500 value -= bfd_get_section_vma (abfd, section);
3502 case N_SETB: case N_SETB | N_EXT:
3503 section = obj_bsssec (abfd);
3504 flags |= BSF_CONSTRUCTOR;
3505 value -= bfd_get_section_vma (abfd, section);
3508 /* A warning symbol. The next symbol is the one to warn
3510 BFD_ASSERT (p + 1 < pend);
3513 name = strings + GET_WORD (abfd, p->e_strx);
3514 section = bfd_und_section_ptr;
3515 flags |= BSF_WARNING;
3518 section = bfd_und_section_ptr;
3522 section = bfd_abs_section_ptr;
3526 section = obj_textsec (abfd);
3527 value -= bfd_get_section_vma (abfd, section);
3531 section = obj_datasec (abfd);
3532 value -= bfd_get_section_vma (abfd, section);
3536 section = obj_bsssec (abfd);
3537 value -= bfd_get_section_vma (abfd, section);
3542 if (! ((*add_one_symbol)
3543 (info, abfd, name, flags, section, value, string, copy, false,
3544 (struct bfd_link_hash_entry **) sym_hash)))
3547 /* Restrict the maximum alignment of a common symbol based on
3548 the architecture, since a.out has no way to represent
3549 alignment requirements of a section in a .o file. FIXME:
3550 This isn't quite right: it should use the architecture of the
3551 output file, not the input files. */
3552 if ((*sym_hash)->root.type == bfd_link_hash_common
3553 && ((*sym_hash)->root.u.c.p->alignment_power >
3554 bfd_get_arch_info (abfd)->section_align_power))
3555 (*sym_hash)->root.u.c.p->alignment_power =
3556 bfd_get_arch_info (abfd)->section_align_power;
3558 /* If this is a set symbol, and we are not building sets, then
3559 it is possible for the hash entry to not have been set. In
3560 such a case, treat the symbol as not globally defined. */
3561 if ((*sym_hash)->root.type == bfd_link_hash_new)
3563 BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
3567 if (type == (N_INDR | N_EXT) || type == N_WARNING)
3574 /* A hash table used for header files with N_BINCL entries. */
3576 struct aout_link_includes_table
3578 struct bfd_hash_table root;
3581 /* A linked list of totals that we have found for a particular header
3584 struct aout_link_includes_totals
3586 struct aout_link_includes_totals *next;
3590 /* An entry in the header file hash table. */
3592 struct aout_link_includes_entry
3594 struct bfd_hash_entry root;
3595 /* List of totals we have found for this file. */
3596 struct aout_link_includes_totals *totals;
3599 /* Look up an entry in an the header file hash table. */
3601 #define aout_link_includes_lookup(table, string, create, copy) \
3602 ((struct aout_link_includes_entry *) \
3603 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
3605 /* During the final link step we need to pass around a bunch of
3606 information, so we do it in an instance of this structure. */
3608 struct aout_final_link_info
3610 /* General link information. */
3611 struct bfd_link_info *info;
3614 /* Reloc file positions. */
3615 file_ptr treloff, dreloff;
3616 /* File position of symbols. */
3619 struct bfd_strtab_hash *strtab;
3620 /* Header file hash table. */
3621 struct aout_link_includes_table includes;
3622 /* A buffer large enough to hold the contents of any section. */
3624 /* A buffer large enough to hold the relocs of any section. */
3626 /* A buffer large enough to hold the symbol map of any input BFD. */
3628 /* A buffer large enough to hold output symbols of any input BFD. */
3629 struct external_nlist *output_syms;
3632 static struct bfd_hash_entry *aout_link_includes_newfunc
3633 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
3634 static boolean aout_link_input_bfd
3635 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3636 static boolean aout_link_write_symbols
3637 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3638 static boolean aout_link_write_other_symbol
3639 PARAMS ((struct aout_link_hash_entry *, PTR));
3640 static boolean aout_link_input_section
3641 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3642 asection *input_section, file_ptr *reloff_ptr,
3643 bfd_size_type rel_size));
3644 static boolean aout_link_input_section_std
3645 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3646 asection *input_section, struct reloc_std_external *,
3647 bfd_size_type rel_size, bfd_byte *contents));
3648 static boolean aout_link_input_section_ext
3649 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3650 asection *input_section, struct reloc_ext_external *,
3651 bfd_size_type rel_size, bfd_byte *contents));
3652 static INLINE asection *aout_reloc_index_to_section
3653 PARAMS ((bfd *, int));
3654 static boolean aout_link_reloc_link_order
3655 PARAMS ((struct aout_final_link_info *, asection *,
3656 struct bfd_link_order *));
3658 /* The function to create a new entry in the header file hash table. */
3660 static struct bfd_hash_entry *
3661 aout_link_includes_newfunc (entry, table, string)
3662 struct bfd_hash_entry *entry;
3663 struct bfd_hash_table *table;
3666 struct aout_link_includes_entry *ret =
3667 (struct aout_link_includes_entry *) entry;
3669 /* Allocate the structure if it has not already been allocated by a
3671 if (ret == (struct aout_link_includes_entry *) NULL)
3672 ret = ((struct aout_link_includes_entry *)
3673 bfd_hash_allocate (table,
3674 sizeof (struct aout_link_includes_entry)));
3675 if (ret == (struct aout_link_includes_entry *) NULL)
3676 return (struct bfd_hash_entry *) ret;
3678 /* Call the allocation method of the superclass. */
3679 ret = ((struct aout_link_includes_entry *)
3680 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
3683 /* Set local fields. */
3687 return (struct bfd_hash_entry *) ret;
3690 /* Do the final link step. This is called on the output BFD. The
3691 INFO structure should point to a list of BFDs linked through the
3692 link_next field which can be used to find each BFD which takes part
3693 in the output. Also, each section in ABFD should point to a list
3694 of bfd_link_order structures which list all the input sections for
3695 the output section. */
3698 NAME(aout,final_link) (abfd, info, callback)
3700 struct bfd_link_info *info;
3701 void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
3703 struct aout_final_link_info aout_info;
3704 boolean includes_hash_initialized = false;
3706 bfd_size_type trsize, drsize;
3707 bfd_size_type max_contents_size;
3708 bfd_size_type max_relocs_size;
3709 bfd_size_type max_sym_count;
3710 bfd_size_type text_size;
3712 register struct bfd_link_order *p;
3714 boolean have_link_order_relocs;
3717 abfd->flags |= DYNAMIC;
3719 aout_info.info = info;
3720 aout_info.output_bfd = abfd;
3721 aout_info.contents = NULL;
3722 aout_info.relocs = NULL;
3723 aout_info.symbol_map = NULL;
3724 aout_info.output_syms = NULL;
3726 if (! bfd_hash_table_init_n (&aout_info.includes.root,
3727 aout_link_includes_newfunc,
3730 includes_hash_initialized = true;
3732 /* Figure out the largest section size. Also, if generating
3733 relocateable output, count the relocs. */
3736 max_contents_size = 0;
3737 max_relocs_size = 0;
3739 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
3743 if (info->relocateable)
3745 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3747 trsize += exec_hdr (sub)->a_trsize;
3748 drsize += exec_hdr (sub)->a_drsize;
3752 /* FIXME: We need to identify the .text and .data sections
3753 and call get_reloc_upper_bound and canonicalize_reloc to
3754 work out the number of relocs needed, and then multiply
3755 by the reloc size. */
3756 (*_bfd_error_handler)
3757 (_("%s: relocateable link from %s to %s not supported"),
3758 bfd_get_filename (abfd),
3759 sub->xvec->name, abfd->xvec->name);
3760 bfd_set_error (bfd_error_invalid_operation);
3765 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3767 sz = bfd_section_size (sub, obj_textsec (sub));
3768 if (sz > max_contents_size)
3769 max_contents_size = sz;
3770 sz = bfd_section_size (sub, obj_datasec (sub));
3771 if (sz > max_contents_size)
3772 max_contents_size = sz;
3774 sz = exec_hdr (sub)->a_trsize;
3775 if (sz > max_relocs_size)
3776 max_relocs_size = sz;
3777 sz = exec_hdr (sub)->a_drsize;
3778 if (sz > max_relocs_size)
3779 max_relocs_size = sz;
3781 sz = obj_aout_external_sym_count (sub);
3782 if (sz > max_sym_count)
3787 if (info->relocateable)
3789 if (obj_textsec (abfd) != (asection *) NULL)
3790 trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
3792 * obj_reloc_entry_size (abfd));
3793 if (obj_datasec (abfd) != (asection *) NULL)
3794 drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
3796 * obj_reloc_entry_size (abfd));
3799 exec_hdr (abfd)->a_trsize = trsize;
3800 exec_hdr (abfd)->a_drsize = drsize;
3802 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
3804 /* Adjust the section sizes and vmas according to the magic number.
3805 This sets a_text, a_data and a_bss in the exec_hdr and sets the
3806 filepos for each section. */
3807 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3810 /* The relocation and symbol file positions differ among a.out
3811 targets. We are passed a callback routine from the backend
3812 specific code to handle this.
3813 FIXME: At this point we do not know how much space the symbol
3814 table will require. This will not work for any (nonstandard)
3815 a.out target that needs to know the symbol table size before it
3816 can compute the relocation file positions. This may or may not
3817 be the case for the hp300hpux target, for example. */
3818 (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3820 obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3821 obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3822 obj_sym_filepos (abfd) = aout_info.symoff;
3824 /* We keep a count of the symbols as we output them. */
3825 obj_aout_external_sym_count (abfd) = 0;
3827 /* We accumulate the string table as we write out the symbols. */
3828 aout_info.strtab = _bfd_stringtab_init ();
3829 if (aout_info.strtab == NULL)
3832 /* Allocate buffers to hold section contents and relocs. */
3833 aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
3834 aout_info.relocs = (PTR) bfd_malloc (max_relocs_size);
3835 aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int *));
3836 aout_info.output_syms = ((struct external_nlist *)
3837 bfd_malloc ((max_sym_count + 1)
3838 * sizeof (struct external_nlist)));
3839 if ((aout_info.contents == NULL && max_contents_size != 0)
3840 || (aout_info.relocs == NULL && max_relocs_size != 0)
3841 || (aout_info.symbol_map == NULL && max_sym_count != 0)
3842 || aout_info.output_syms == NULL)
3845 /* If we have a symbol named __DYNAMIC, force it out now. This is
3846 required by SunOS. Doing this here rather than in sunos.c is a
3847 hack, but it's easier than exporting everything which would be
3850 struct aout_link_hash_entry *h;
3852 h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
3853 false, false, false);
3855 aout_link_write_other_symbol (h, &aout_info);
3858 /* The most time efficient way to do the link would be to read all
3859 the input object files into memory and then sort out the
3860 information into the output file. Unfortunately, that will
3861 probably use too much memory. Another method would be to step
3862 through everything that composes the text section and write it
3863 out, and then everything that composes the data section and write
3864 it out, and then write out the relocs, and then write out the
3865 symbols. Unfortunately, that requires reading stuff from each
3866 input file several times, and we will not be able to keep all the
3867 input files open simultaneously, and reopening them will be slow.
3869 What we do is basically process one input file at a time. We do
3870 everything we need to do with an input file once--copy over the
3871 section contents, handle the relocation information, and write
3872 out the symbols--and then we throw away the information we read
3873 from it. This approach requires a lot of lseeks of the output
3874 file, which is unfortunate but still faster than reopening a lot
3877 We use the output_has_begun field of the input BFDs to see
3878 whether we have already handled it. */
3879 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3880 sub->output_has_begun = false;
3882 /* Mark all sections which are to be included in the link. This
3883 will normally be every section. We need to do this so that we
3884 can identify any sections which the linker has decided to not
3886 for (o = abfd->sections; o != NULL; o = o->next)
3888 for (p = o->link_order_head; p != NULL; p = p->next)
3890 if (p->type == bfd_indirect_link_order)
3891 p->u.indirect.section->linker_mark = true;
3895 have_link_order_relocs = false;
3896 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3898 for (p = o->link_order_head;
3899 p != (struct bfd_link_order *) NULL;
3902 if (p->type == bfd_indirect_link_order
3903 && (bfd_get_flavour (p->u.indirect.section->owner)
3904 == bfd_target_aout_flavour))
3908 input_bfd = p->u.indirect.section->owner;
3909 if (! input_bfd->output_has_begun)
3911 if (! aout_link_input_bfd (&aout_info, input_bfd))
3913 input_bfd->output_has_begun = true;
3916 else if (p->type == bfd_section_reloc_link_order
3917 || p->type == bfd_symbol_reloc_link_order)
3919 /* These are handled below. */
3920 have_link_order_relocs = true;
3924 if (! _bfd_default_link_order (abfd, info, o, p))
3930 /* Write out any symbols that we have not already written out. */
3931 aout_link_hash_traverse (aout_hash_table (info),
3932 aout_link_write_other_symbol,
3935 /* Now handle any relocs we were asked to create by the linker.
3936 These did not come from any input file. We must do these after
3937 we have written out all the symbols, so that we know the symbol
3939 if (have_link_order_relocs)
3941 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3943 for (p = o->link_order_head;
3944 p != (struct bfd_link_order *) NULL;
3947 if (p->type == bfd_section_reloc_link_order
3948 || p->type == bfd_symbol_reloc_link_order)
3950 if (! aout_link_reloc_link_order (&aout_info, o, p))
3957 if (aout_info.contents != NULL)
3959 free (aout_info.contents);
3960 aout_info.contents = NULL;
3962 if (aout_info.relocs != NULL)
3964 free (aout_info.relocs);
3965 aout_info.relocs = NULL;
3967 if (aout_info.symbol_map != NULL)
3969 free (aout_info.symbol_map);
3970 aout_info.symbol_map = NULL;
3972 if (aout_info.output_syms != NULL)
3974 free (aout_info.output_syms);
3975 aout_info.output_syms = NULL;
3977 if (includes_hash_initialized)
3979 bfd_hash_table_free (&aout_info.includes.root);
3980 includes_hash_initialized = false;
3983 /* Finish up any dynamic linking we may be doing. */
3984 if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
3986 if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
3990 /* Update the header information. */
3991 abfd->symcount = obj_aout_external_sym_count (abfd);
3992 exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
3993 obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
3994 obj_textsec (abfd)->reloc_count =
3995 exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
3996 obj_datasec (abfd)->reloc_count =
3997 exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
3999 /* Write out the string table, unless there are no symbols. */
4000 if (abfd->symcount > 0)
4002 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
4003 || ! emit_stringtab (abfd, aout_info.strtab))
4006 else if (obj_textsec (abfd)->reloc_count == 0
4007 && obj_datasec (abfd)->reloc_count == 0)
4013 pos = obj_datasec (abfd)->filepos + exec_hdr (abfd)->a_data - 1;
4014 if (bfd_seek (abfd, pos, SEEK_SET) != 0
4015 || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
4022 if (aout_info.contents != NULL)
4023 free (aout_info.contents);
4024 if (aout_info.relocs != NULL)
4025 free (aout_info.relocs);
4026 if (aout_info.symbol_map != NULL)
4027 free (aout_info.symbol_map);
4028 if (aout_info.output_syms != NULL)
4029 free (aout_info.output_syms);
4030 if (includes_hash_initialized)
4031 bfd_hash_table_free (&aout_info.includes.root);
4035 /* Link an a.out input BFD into the output file. */
4038 aout_link_input_bfd (finfo, input_bfd)
4039 struct aout_final_link_info *finfo;
4042 bfd_size_type sym_count;
4044 BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
4046 /* If this is a dynamic object, it may need special handling. */
4047 if ((input_bfd->flags & DYNAMIC) != 0
4048 && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
4050 return ((*aout_backend_info (input_bfd)->link_dynamic_object)
4051 (finfo->info, input_bfd));
4054 /* Get the symbols. We probably have them already, unless
4055 finfo->info->keep_memory is false. */
4056 if (! aout_get_external_symbols (input_bfd))
4059 sym_count = obj_aout_external_sym_count (input_bfd);
4061 /* Write out the symbols and get a map of the new indices. The map
4062 is placed into finfo->symbol_map. */
4063 if (! aout_link_write_symbols (finfo, input_bfd))
4066 /* Relocate and write out the sections. These functions use the
4067 symbol map created by aout_link_write_symbols. The linker_mark
4068 field will be set if these sections are to be included in the
4069 link, which will normally be the case. */
4070 if (obj_textsec (input_bfd)->linker_mark)
4072 if (! aout_link_input_section (finfo, input_bfd,
4073 obj_textsec (input_bfd),
4075 exec_hdr (input_bfd)->a_trsize))
4078 if (obj_datasec (input_bfd)->linker_mark)
4080 if (! aout_link_input_section (finfo, input_bfd,
4081 obj_datasec (input_bfd),
4083 exec_hdr (input_bfd)->a_drsize))
4087 /* If we are not keeping memory, we don't need the symbols any
4088 longer. We still need them if we are keeping memory, because the
4089 strings in the hash table point into them. */
4090 if (! finfo->info->keep_memory)
4092 if (! aout_link_free_symbols (input_bfd))
4099 /* Adjust and write out the symbols for an a.out file. Set the new
4100 symbol indices into a symbol_map. */
4103 aout_link_write_symbols (finfo, input_bfd)
4104 struct aout_final_link_info *finfo;
4108 bfd_size_type sym_count;
4110 enum bfd_link_strip strip;
4111 enum bfd_link_discard discard;
4112 struct external_nlist *outsym;
4113 bfd_size_type strtab_index;
4114 register struct external_nlist *sym;
4115 struct external_nlist *sym_end;
4116 struct aout_link_hash_entry **sym_hash;
4121 output_bfd = finfo->output_bfd;
4122 sym_count = obj_aout_external_sym_count (input_bfd);
4123 strings = obj_aout_external_strings (input_bfd);
4124 strip = finfo->info->strip;
4125 discard = finfo->info->discard;
4126 outsym = finfo->output_syms;
4128 /* First write out a symbol for this object file, unless we are
4129 discarding such symbols. */
4130 if (strip != strip_all
4131 && (strip != strip_some
4132 || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
4133 false, false) != NULL)
4134 && discard != discard_all)
4136 H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
4137 H_PUT_8 (output_bfd, 0, outsym->e_other);
4138 H_PUT_16 (output_bfd, 0, outsym->e_desc);
4139 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4140 input_bfd->filename, false);
4141 if (strtab_index == (bfd_size_type) -1)
4143 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4144 PUT_WORD (output_bfd,
4145 (bfd_get_section_vma (output_bfd,
4146 obj_textsec (input_bfd)->output_section)
4147 + obj_textsec (input_bfd)->output_offset),
4149 ++obj_aout_external_sym_count (output_bfd);
4155 sym = obj_aout_external_syms (input_bfd);
4156 sym_end = sym + sym_count;
4157 sym_hash = obj_aout_sym_hashes (input_bfd);
4158 symbol_map = finfo->symbol_map;
4159 memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
4160 for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
4164 struct aout_link_hash_entry *h;
4170 /* We set *symbol_map to 0 above for all symbols. If it has
4171 already been set to -1 for this symbol, it means that we are
4172 discarding it because it appears in a duplicate header file.
4173 See the N_BINCL code below. */
4174 if (*symbol_map == -1)
4177 /* Initialize *symbol_map to -1, which means that the symbol was
4178 not copied into the output file. We will change it later if
4179 we do copy the symbol over. */
4182 type = H_GET_8 (input_bfd, sym->e_type);
4183 name = strings + GET_WORD (input_bfd, sym->e_strx);
4189 /* Pass this symbol through. It is the target of an
4190 indirect or warning symbol. */
4191 val = GET_WORD (input_bfd, sym->e_value);
4196 /* Skip this symbol, which is the target of an indirect
4197 symbol that we have changed to no longer be an indirect
4204 struct aout_link_hash_entry *hresolve;
4206 /* We have saved the hash table entry for this symbol, if
4207 there is one. Note that we could just look it up again
4208 in the hash table, provided we first check that it is an
4212 /* Use the name from the hash table, in case the symbol was
4215 && h->root.type != bfd_link_hash_warning)
4216 name = h->root.root.string;
4218 /* If this is an indirect or warning symbol, then change
4219 hresolve to the base symbol. We also change *sym_hash so
4220 that the relocation routines relocate against the real
4223 if (h != (struct aout_link_hash_entry *) NULL
4224 && (h->root.type == bfd_link_hash_indirect
4225 || h->root.type == bfd_link_hash_warning))
4227 hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
4228 while (hresolve->root.type == bfd_link_hash_indirect
4229 || hresolve->root.type == bfd_link_hash_warning)
4230 hresolve = ((struct aout_link_hash_entry *)
4231 hresolve->root.u.i.link);
4232 *sym_hash = hresolve;
4235 /* If the symbol has already been written out, skip it. */
4236 if (h != (struct aout_link_hash_entry *) NULL
4239 if ((type & N_TYPE) == N_INDR
4240 || type == N_WARNING)
4242 *symbol_map = h->indx;
4246 /* See if we are stripping this symbol. */
4252 case strip_debugger:
4253 if ((type & N_STAB) != 0)
4257 if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
4267 if (h != (struct aout_link_hash_entry *) NULL)
4272 /* Get the value of the symbol. */
4273 if ((type & N_TYPE) == N_TEXT
4275 symsec = obj_textsec (input_bfd);
4276 else if ((type & N_TYPE) == N_DATA
4278 symsec = obj_datasec (input_bfd);
4279 else if ((type & N_TYPE) == N_BSS
4281 symsec = obj_bsssec (input_bfd);
4282 else if ((type & N_TYPE) == N_ABS
4284 symsec = bfd_abs_section_ptr;
4285 else if (((type & N_TYPE) == N_INDR
4286 && (hresolve == (struct aout_link_hash_entry *) NULL
4287 || (hresolve->root.type != bfd_link_hash_defined
4288 && hresolve->root.type != bfd_link_hash_defweak
4289 && hresolve->root.type != bfd_link_hash_common)))
4290 || type == N_WARNING)
4292 /* Pass the next symbol through unchanged. The
4293 condition above for indirect symbols is so that if
4294 the indirect symbol was defined, we output it with
4295 the correct definition so the debugger will
4298 val = GET_WORD (input_bfd, sym->e_value);
4301 else if ((type & N_STAB) != 0)
4303 val = GET_WORD (input_bfd, sym->e_value);
4308 /* If we get here with an indirect symbol, it means that
4309 we are outputting it with a real definition. In such
4310 a case we do not want to output the next symbol,
4311 which is the target of the indirection. */
4312 if ((type & N_TYPE) == N_INDR)
4317 /* We need to get the value from the hash table. We use
4318 hresolve so that if we have defined an indirect
4319 symbol we output the final definition. */
4320 if (h == (struct aout_link_hash_entry *) NULL)
4322 switch (type & N_TYPE)
4325 symsec = obj_textsec (input_bfd);
4328 symsec = obj_datasec (input_bfd);
4331 symsec = obj_bsssec (input_bfd);
4334 symsec = bfd_abs_section_ptr;
4341 else if (hresolve->root.type == bfd_link_hash_defined
4342 || hresolve->root.type == bfd_link_hash_defweak)
4344 asection *input_section;
4345 asection *output_section;
4347 /* This case usually means a common symbol which was
4348 turned into a defined symbol. */
4349 input_section = hresolve->root.u.def.section;
4350 output_section = input_section->output_section;
4351 BFD_ASSERT (bfd_is_abs_section (output_section)
4352 || output_section->owner == output_bfd);
4353 val = (hresolve->root.u.def.value
4354 + bfd_get_section_vma (output_bfd, output_section)
4355 + input_section->output_offset);
4357 /* Get the correct type based on the section. If
4358 this is a constructed set, force it to be
4359 globally visible. */
4368 if (output_section == obj_textsec (output_bfd))
4369 type |= (hresolve->root.type == bfd_link_hash_defined
4372 else if (output_section == obj_datasec (output_bfd))
4373 type |= (hresolve->root.type == bfd_link_hash_defined
4376 else if (output_section == obj_bsssec (output_bfd))
4377 type |= (hresolve->root.type == bfd_link_hash_defined
4381 type |= (hresolve->root.type == bfd_link_hash_defined
4385 else if (hresolve->root.type == bfd_link_hash_common)
4386 val = hresolve->root.u.c.size;
4387 else if (hresolve->root.type == bfd_link_hash_undefweak)
4395 if (symsec != (asection *) NULL)
4396 val = (symsec->output_section->vma
4397 + symsec->output_offset
4398 + (GET_WORD (input_bfd, sym->e_value)
4401 /* If this is a global symbol set the written flag, and if
4402 it is a local symbol see if we should discard it. */
4403 if (h != (struct aout_link_hash_entry *) NULL)
4406 h->indx = obj_aout_external_sym_count (output_bfd);
4408 else if ((type & N_TYPE) != N_SETT
4409 && (type & N_TYPE) != N_SETD
4410 && (type & N_TYPE) != N_SETB
4411 && (type & N_TYPE) != N_SETA)
4416 case discard_sec_merge:
4419 if ((type & N_STAB) == 0
4420 && bfd_is_local_label_name (input_bfd, name))
4434 /* An N_BINCL symbol indicates the start of the stabs
4435 entries for a header file. We need to scan ahead to the
4436 next N_EINCL symbol, ignoring nesting, adding up all the
4437 characters in the symbol names, not including the file
4438 numbers in types (the first number after an open
4440 if (type == N_BINCL)
4442 struct external_nlist *incl_sym;
4444 struct aout_link_includes_entry *incl_entry;
4445 struct aout_link_includes_totals *t;
4449 for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
4453 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
4454 if (incl_type == N_EINCL)
4460 else if (incl_type == N_BINCL)
4466 s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
4467 for (; *s != '\0'; s++)
4472 /* Skip the file number. */
4474 while (ISDIGIT (*s))
4482 /* If we have already included a header file with the
4483 same value, then replace this one with an N_EXCL
4485 copy = ! finfo->info->keep_memory;
4486 incl_entry = aout_link_includes_lookup (&finfo->includes,
4488 if (incl_entry == NULL)
4490 for (t = incl_entry->totals; t != NULL; t = t->next)
4491 if (t->total == val)
4495 /* This is the first time we have seen this header
4496 file with this set of stabs strings. */
4497 t = ((struct aout_link_includes_totals *)
4498 bfd_hash_allocate (&finfo->includes.root,
4503 t->next = incl_entry->totals;
4504 incl_entry->totals = t;
4510 /* This is a duplicate header file. We must change
4511 it to be an N_EXCL entry, and mark all the
4512 included symbols to prevent outputting them. */
4516 for (incl_sym = sym + 1, incl_map = symbol_map + 1;
4518 incl_sym++, incl_map++)
4522 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
4523 if (incl_type == N_EINCL)
4532 else if (incl_type == N_BINCL)
4541 /* Copy this symbol into the list of symbols we are going to
4543 H_PUT_8 (output_bfd, type, outsym->e_type);
4544 H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_other), outsym->e_other);
4545 H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc);
4547 if (! finfo->info->keep_memory)
4549 /* name points into a string table which we are going to
4550 free. If there is a hash table entry, use that string.
4551 Otherwise, copy name into memory. */
4552 if (h != (struct aout_link_hash_entry *) NULL)
4553 name = h->root.root.string;
4557 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4559 if (strtab_index == (bfd_size_type) -1)
4561 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4562 PUT_WORD (output_bfd, val, outsym->e_value);
4563 *symbol_map = obj_aout_external_sym_count (output_bfd);
4564 ++obj_aout_external_sym_count (output_bfd);
4568 /* Write out the output symbols we have just constructed. */
4569 if (outsym > finfo->output_syms)
4571 bfd_size_type outsym_size;
4573 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
4575 outsym_size = outsym - finfo->output_syms;
4576 outsym_size *= EXTERNAL_NLIST_SIZE;
4577 if (bfd_bwrite ((PTR) finfo->output_syms, outsym_size, output_bfd)
4580 finfo->symoff += outsym_size;
4586 /* Write out a symbol that was not associated with an a.out input
4590 aout_link_write_other_symbol (h, data)
4591 struct aout_link_hash_entry *h;
4594 struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
4598 struct external_nlist outsym;
4602 if (h->root.type == bfd_link_hash_warning)
4604 h = (struct aout_link_hash_entry *) h->root.u.i.link;
4605 if (h->root.type == bfd_link_hash_new)
4609 output_bfd = finfo->output_bfd;
4611 if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
4613 if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
4614 (output_bfd, finfo->info, h)))
4616 /* FIXME: No way to handle errors. */
4626 /* An indx of -2 means the symbol must be written. */
4628 && (finfo->info->strip == strip_all
4629 || (finfo->info->strip == strip_some
4630 && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
4631 false, false) == NULL)))
4634 switch (h->root.type)
4637 case bfd_link_hash_warning:
4639 /* Avoid variable not initialized warnings. */
4641 case bfd_link_hash_new:
4642 /* This can happen for set symbols when sets are not being
4645 case bfd_link_hash_undefined:
4646 type = N_UNDF | N_EXT;
4649 case bfd_link_hash_defined:
4650 case bfd_link_hash_defweak:
4654 sec = h->root.u.def.section->output_section;
4655 BFD_ASSERT (bfd_is_abs_section (sec)
4656 || sec->owner == output_bfd);
4657 if (sec == obj_textsec (output_bfd))
4658 type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
4659 else if (sec == obj_datasec (output_bfd))
4660 type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
4661 else if (sec == obj_bsssec (output_bfd))
4662 type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
4664 type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
4666 val = (h->root.u.def.value
4668 + h->root.u.def.section->output_offset);
4671 case bfd_link_hash_common:
4672 type = N_UNDF | N_EXT;
4673 val = h->root.u.c.size;
4675 case bfd_link_hash_undefweak:
4678 case bfd_link_hash_indirect:
4679 /* We ignore these symbols, since the indirected symbol is
4680 already in the hash table. */
4684 H_PUT_8 (output_bfd, type, outsym.e_type);
4685 H_PUT_8 (output_bfd, 0, outsym.e_other);
4686 H_PUT_16 (output_bfd, 0, outsym.e_desc);
4687 indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
4689 if (indx == - (bfd_size_type) 1)
4691 /* FIXME: No way to handle errors. */
4694 PUT_WORD (output_bfd, indx, outsym.e_strx);
4695 PUT_WORD (output_bfd, val, outsym.e_value);
4697 amt = EXTERNAL_NLIST_SIZE;
4698 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
4699 || bfd_bwrite ((PTR) &outsym, amt, output_bfd) != amt)
4701 /* FIXME: No way to handle errors. */
4705 finfo->symoff += EXTERNAL_NLIST_SIZE;
4706 h->indx = obj_aout_external_sym_count (output_bfd);
4707 ++obj_aout_external_sym_count (output_bfd);
4712 /* Link an a.out section into the output file. */
4715 aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
4717 struct aout_final_link_info *finfo;
4719 asection *input_section;
4720 file_ptr *reloff_ptr;
4721 bfd_size_type rel_size;
4723 bfd_size_type input_size;
4726 /* Get the section contents. */
4727 input_size = bfd_section_size (input_bfd, input_section);
4728 if (! bfd_get_section_contents (input_bfd, input_section,
4729 (PTR) finfo->contents,
4730 (file_ptr) 0, input_size))
4733 /* Read in the relocs if we haven't already done it. */
4734 if (aout_section_data (input_section) != NULL
4735 && aout_section_data (input_section)->relocs != NULL)
4736 relocs = aout_section_data (input_section)->relocs;
4739 relocs = finfo->relocs;
4742 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
4743 || bfd_bread (relocs, rel_size, input_bfd) != rel_size)
4748 /* Relocate the section contents. */
4749 if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4751 if (! aout_link_input_section_std (finfo, input_bfd, input_section,
4752 (struct reloc_std_external *) relocs,
4753 rel_size, finfo->contents))
4758 if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
4759 (struct reloc_ext_external *) relocs,
4760 rel_size, finfo->contents))
4764 /* Write out the section contents. */
4765 if (! bfd_set_section_contents (finfo->output_bfd,
4766 input_section->output_section,
4767 (PTR) finfo->contents,
4768 (file_ptr) input_section->output_offset,
4772 /* If we are producing relocateable output, the relocs were
4773 modified, and we now write them out. */
4774 if (finfo->info->relocateable && rel_size > 0)
4776 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
4778 if (bfd_bwrite (relocs, rel_size, finfo->output_bfd) != rel_size)
4780 *reloff_ptr += rel_size;
4782 /* Assert that the relocs have not run into the symbols, and
4783 that if these are the text relocs they have not run into the
4785 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
4786 && (reloff_ptr != &finfo->treloff
4788 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
4794 /* Get the section corresponding to a reloc index. */
4796 static INLINE asection *
4797 aout_reloc_index_to_section (abfd, indx)
4801 switch (indx & N_TYPE)
4804 return obj_textsec (abfd);
4806 return obj_datasec (abfd);
4808 return obj_bsssec (abfd);
4811 return bfd_abs_section_ptr;
4819 /* Relocate an a.out section using standard a.out relocs. */
4822 aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
4824 struct aout_final_link_info *finfo;
4826 asection *input_section;
4827 struct reloc_std_external *relocs;
4828 bfd_size_type rel_size;
4831 boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
4833 struct aout_link_hash_entry *,
4834 PTR, bfd_byte *, boolean *,
4837 boolean relocateable;
4838 struct external_nlist *syms;
4840 struct aout_link_hash_entry **sym_hashes;
4842 bfd_size_type reloc_count;
4843 register struct reloc_std_external *rel;
4844 struct reloc_std_external *rel_end;
4846 output_bfd = finfo->output_bfd;
4847 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4849 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
4850 BFD_ASSERT (input_bfd->xvec->header_byteorder
4851 == output_bfd->xvec->header_byteorder);
4853 relocateable = finfo->info->relocateable;
4854 syms = obj_aout_external_syms (input_bfd);
4855 strings = obj_aout_external_strings (input_bfd);
4856 sym_hashes = obj_aout_sym_hashes (input_bfd);
4857 symbol_map = finfo->symbol_map;
4859 reloc_count = rel_size / RELOC_STD_SIZE;
4861 rel_end = rel + reloc_count;
4862 for (; rel < rel_end; rel++)
4869 reloc_howto_type *howto;
4870 struct aout_link_hash_entry *h = NULL;
4872 bfd_reloc_status_type r;
4874 r_addr = GET_SWORD (input_bfd, rel->r_address);
4876 #ifdef MY_reloc_howto
4877 howto = MY_reloc_howto (input_bfd, rel, r_index, r_extern, r_pcrel);
4883 unsigned int howto_idx;
4885 if (bfd_header_big_endian (input_bfd))
4887 r_index = ((rel->r_index[0] << 16)
4888 | (rel->r_index[1] << 8)
4890 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
4891 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
4892 r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
4893 r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
4894 r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
4895 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
4896 >> RELOC_STD_BITS_LENGTH_SH_BIG);
4900 r_index = ((rel->r_index[2] << 16)
4901 | (rel->r_index[1] << 8)
4903 r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
4904 r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
4905 r_baserel = (0 != (rel->r_type[0]
4906 & RELOC_STD_BITS_BASEREL_LITTLE));
4907 r_jmptable= (0 != (rel->r_type[0]
4908 & RELOC_STD_BITS_JMPTABLE_LITTLE));
4909 r_relative= (0 != (rel->r_type[0]
4910 & RELOC_STD_BITS_RELATIVE_LITTLE));
4911 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
4912 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
4915 howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
4916 + 16 * r_jmptable + 32 * r_relative);
4917 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
4918 howto = howto_table_std + howto_idx;
4924 /* We are generating a relocateable output file, and must
4925 modify the reloc accordingly. */
4928 /* If we know the symbol this relocation is against,
4929 convert it into a relocation against a section. This
4930 is what the native linker does. */
4931 h = sym_hashes[r_index];
4932 if (h != (struct aout_link_hash_entry *) NULL
4933 && (h->root.type == bfd_link_hash_defined
4934 || h->root.type == bfd_link_hash_defweak))
4936 asection *output_section;
4938 /* Change the r_extern value. */
4939 if (bfd_header_big_endian (output_bfd))
4940 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
4942 rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
4944 /* Compute a new r_index. */
4945 output_section = h->root.u.def.section->output_section;
4946 if (output_section == obj_textsec (output_bfd))
4948 else if (output_section == obj_datasec (output_bfd))
4950 else if (output_section == obj_bsssec (output_bfd))
4955 /* Add the symbol value and the section VMA to the
4956 addend stored in the contents. */
4957 relocation = (h->root.u.def.value
4958 + output_section->vma
4959 + h->root.u.def.section->output_offset);
4963 /* We must change r_index according to the symbol
4965 r_index = symbol_map[r_index];
4971 /* We decided to strip this symbol, but it
4972 turns out that we can't. Note that we
4973 lose the other and desc information here.
4974 I don't think that will ever matter for a
4980 if (! aout_link_write_other_symbol (h,
4990 name = strings + GET_WORD (input_bfd,
4991 syms[r_index].e_strx);
4992 if (! ((*finfo->info->callbacks->unattached_reloc)
4993 (finfo->info, name, input_bfd, input_section,
5003 /* Write out the new r_index value. */
5004 if (bfd_header_big_endian (output_bfd))
5006 rel->r_index[0] = r_index >> 16;
5007 rel->r_index[1] = r_index >> 8;
5008 rel->r_index[2] = r_index;
5012 rel->r_index[2] = r_index >> 16;
5013 rel->r_index[1] = r_index >> 8;
5014 rel->r_index[0] = r_index;
5021 /* This is a relocation against a section. We must
5022 adjust by the amount that the section moved. */
5023 section = aout_reloc_index_to_section (input_bfd, r_index);
5024 relocation = (section->output_section->vma
5025 + section->output_offset
5029 /* Change the address of the relocation. */
5030 PUT_WORD (output_bfd,
5031 r_addr + input_section->output_offset,
5034 /* Adjust a PC relative relocation by removing the reference
5035 to the original address in the section and including the
5036 reference to the new address. */
5038 relocation -= (input_section->output_section->vma
5039 + input_section->output_offset
5040 - input_section->vma);
5042 #ifdef MY_relocatable_reloc
5043 MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
5046 if (relocation == 0)
5049 r = MY_relocate_contents (howto,
5050 input_bfd, relocation,
5057 /* We are generating an executable, and must do a full
5063 h = sym_hashes[r_index];
5065 if (h != (struct aout_link_hash_entry *) NULL
5066 && (h->root.type == bfd_link_hash_defined
5067 || h->root.type == bfd_link_hash_defweak))
5069 relocation = (h->root.u.def.value
5070 + h->root.u.def.section->output_section->vma
5071 + h->root.u.def.section->output_offset);
5073 else if (h != (struct aout_link_hash_entry *) NULL
5074 && h->root.type == bfd_link_hash_undefweak)
5086 section = aout_reloc_index_to_section (input_bfd, r_index);
5087 relocation = (section->output_section->vma
5088 + section->output_offset
5091 relocation += input_section->vma;
5094 if (check_dynamic_reloc != NULL)
5098 if (! ((*check_dynamic_reloc)
5099 (finfo->info, input_bfd, input_section, h,
5100 (PTR) rel, contents, &skip, &relocation)))
5106 /* Now warn if a global symbol is undefined. We could not
5107 do this earlier, because check_dynamic_reloc might want
5108 to skip this reloc. */
5109 if (hundef && ! finfo->info->shared && ! r_baserel)
5114 name = h->root.root.string;
5116 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5117 if (! ((*finfo->info->callbacks->undefined_symbol)
5118 (finfo->info, name, input_bfd, input_section,
5123 r = MY_final_link_relocate (howto,
5124 input_bfd, input_section,
5125 contents, r_addr, relocation,
5129 if (r != bfd_reloc_ok)
5134 case bfd_reloc_outofrange:
5136 case bfd_reloc_overflow:
5141 name = h->root.root.string;
5143 name = strings + GET_WORD (input_bfd,
5144 syms[r_index].e_strx);
5149 s = aout_reloc_index_to_section (input_bfd, r_index);
5150 name = bfd_section_name (input_bfd, s);
5152 if (! ((*finfo->info->callbacks->reloc_overflow)
5153 (finfo->info, name, howto->name,
5154 (bfd_vma) 0, input_bfd, input_section, r_addr)))
5165 /* Relocate an a.out section using extended a.out relocs. */
5168 aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
5170 struct aout_final_link_info *finfo;
5172 asection *input_section;
5173 struct reloc_ext_external *relocs;
5174 bfd_size_type rel_size;
5177 boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
5179 struct aout_link_hash_entry *,
5180 PTR, bfd_byte *, boolean *,
5183 boolean relocateable;
5184 struct external_nlist *syms;
5186 struct aout_link_hash_entry **sym_hashes;
5188 bfd_size_type reloc_count;
5189 register struct reloc_ext_external *rel;
5190 struct reloc_ext_external *rel_end;
5192 output_bfd = finfo->output_bfd;
5193 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
5195 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
5196 BFD_ASSERT (input_bfd->xvec->header_byteorder
5197 == output_bfd->xvec->header_byteorder);
5199 relocateable = finfo->info->relocateable;
5200 syms = obj_aout_external_syms (input_bfd);
5201 strings = obj_aout_external_strings (input_bfd);
5202 sym_hashes = obj_aout_sym_hashes (input_bfd);
5203 symbol_map = finfo->symbol_map;
5205 reloc_count = rel_size / RELOC_EXT_SIZE;
5207 rel_end = rel + reloc_count;
5208 for (; rel < rel_end; rel++)
5213 unsigned int r_type;
5215 struct aout_link_hash_entry *h = NULL;
5216 asection *r_section = NULL;
5219 r_addr = GET_SWORD (input_bfd, rel->r_address);
5221 if (bfd_header_big_endian (input_bfd))
5223 r_index = ((rel->r_index[0] << 16)
5224 | (rel->r_index[1] << 8)
5226 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
5227 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
5228 >> RELOC_EXT_BITS_TYPE_SH_BIG);
5232 r_index = ((rel->r_index[2] << 16)
5233 | (rel->r_index[1] << 8)
5235 r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
5236 r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
5237 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
5240 r_addend = GET_SWORD (input_bfd, rel->r_addend);
5242 BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
5246 /* We are generating a relocateable output file, and must
5247 modify the reloc accordingly. */
5249 || r_type == RELOC_BASE10
5250 || r_type == RELOC_BASE13
5251 || r_type == RELOC_BASE22)
5253 /* If we know the symbol this relocation is against,
5254 convert it into a relocation against a section. This
5255 is what the native linker does. */
5256 if (r_type == RELOC_BASE10
5257 || r_type == RELOC_BASE13
5258 || r_type == RELOC_BASE22)
5261 h = sym_hashes[r_index];
5262 if (h != (struct aout_link_hash_entry *) NULL
5263 && (h->root.type == bfd_link_hash_defined
5264 || h->root.type == bfd_link_hash_defweak))
5266 asection *output_section;
5268 /* Change the r_extern value. */
5269 if (bfd_header_big_endian (output_bfd))
5270 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
5272 rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
5274 /* Compute a new r_index. */
5275 output_section = h->root.u.def.section->output_section;
5276 if (output_section == obj_textsec (output_bfd))
5278 else if (output_section == obj_datasec (output_bfd))
5280 else if (output_section == obj_bsssec (output_bfd))
5285 /* Add the symbol value and the section VMA to the
5287 relocation = (h->root.u.def.value
5288 + output_section->vma
5289 + h->root.u.def.section->output_offset);
5291 /* Now RELOCATION is the VMA of the final
5292 destination. If this is a PC relative reloc,
5293 then ADDEND is the negative of the source VMA.
5294 We want to set ADDEND to the difference between
5295 the destination VMA and the source VMA, which
5296 means we must adjust RELOCATION by the change in
5297 the source VMA. This is done below. */
5301 /* We must change r_index according to the symbol
5303 r_index = symbol_map[r_index];
5309 /* We decided to strip this symbol, but it
5310 turns out that we can't. Note that we
5311 lose the other and desc information here.
5312 I don't think that will ever matter for a
5318 if (! aout_link_write_other_symbol (h,
5328 name = strings + GET_WORD (input_bfd,
5329 syms[r_index].e_strx);
5330 if (! ((*finfo->info->callbacks->unattached_reloc)
5331 (finfo->info, name, input_bfd, input_section,
5340 /* If this is a PC relative reloc, then the addend
5341 is the negative of the source VMA. We must
5342 adjust it by the change in the source VMA. This
5346 /* Write out the new r_index value. */
5347 if (bfd_header_big_endian (output_bfd))
5349 rel->r_index[0] = r_index >> 16;
5350 rel->r_index[1] = r_index >> 8;
5351 rel->r_index[2] = r_index;
5355 rel->r_index[2] = r_index >> 16;
5356 rel->r_index[1] = r_index >> 8;
5357 rel->r_index[0] = r_index;
5362 /* This is a relocation against a section. We must
5363 adjust by the amount that the section moved. */
5364 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5365 relocation = (r_section->output_section->vma
5366 + r_section->output_offset
5369 /* If this is a PC relative reloc, then the addend is
5370 the difference in VMA between the destination and the
5371 source. We have just adjusted for the change in VMA
5372 of the destination, so we must also adjust by the
5373 change in VMA of the source. This is done below. */
5376 /* As described above, we must always adjust a PC relative
5377 reloc by the change in VMA of the source. However, if
5378 pcrel_offset is set, then the addend does not include the
5379 location within the section, in which case we don't need
5380 to adjust anything. */
5381 if (howto_table_ext[r_type].pc_relative
5382 && ! howto_table_ext[r_type].pcrel_offset)
5383 relocation -= (input_section->output_section->vma
5384 + input_section->output_offset
5385 - input_section->vma);
5387 /* Change the addend if necessary. */
5388 if (relocation != 0)
5389 PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
5391 /* Change the address of the relocation. */
5392 PUT_WORD (output_bfd,
5393 r_addr + input_section->output_offset,
5399 bfd_reloc_status_type r;
5401 /* We are generating an executable, and must do a full
5407 h = sym_hashes[r_index];
5409 if (h != (struct aout_link_hash_entry *) NULL
5410 && (h->root.type == bfd_link_hash_defined
5411 || h->root.type == bfd_link_hash_defweak))
5413 relocation = (h->root.u.def.value
5414 + h->root.u.def.section->output_section->vma
5415 + h->root.u.def.section->output_offset);
5417 else if (h != (struct aout_link_hash_entry *) NULL
5418 && h->root.type == bfd_link_hash_undefweak)
5426 else if (r_type == RELOC_BASE10
5427 || r_type == RELOC_BASE13
5428 || r_type == RELOC_BASE22)
5430 struct external_nlist *sym;
5433 /* For base relative relocs, r_index is always an index
5434 into the symbol table, even if r_extern is 0. */
5435 sym = syms + r_index;
5436 type = H_GET_8 (input_bfd, sym->e_type);
5437 if ((type & N_TYPE) == N_TEXT
5439 r_section = obj_textsec (input_bfd);
5440 else if ((type & N_TYPE) == N_DATA
5442 r_section = obj_datasec (input_bfd);
5443 else if ((type & N_TYPE) == N_BSS
5445 r_section = obj_bsssec (input_bfd);
5446 else if ((type & N_TYPE) == N_ABS
5448 r_section = bfd_abs_section_ptr;
5451 relocation = (r_section->output_section->vma
5452 + r_section->output_offset
5453 + (GET_WORD (input_bfd, sym->e_value)
5458 r_section = aout_reloc_index_to_section (input_bfd, r_index);
5460 /* If this is a PC relative reloc, then R_ADDEND is the
5461 difference between the two vmas, or
5462 old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
5464 old_dest_sec == section->vma
5466 old_src_sec == input_section->vma
5468 old_src_off == r_addr
5470 _bfd_final_link_relocate expects RELOCATION +
5471 R_ADDEND to be the VMA of the destination minus
5472 r_addr (the minus r_addr is because this relocation
5473 is not pcrel_offset, which is a bit confusing and
5474 should, perhaps, be changed), or
5477 new_dest_sec == output_section->vma + output_offset
5478 We arrange for this to happen by setting RELOCATION to
5479 new_dest_sec + old_src_sec - old_dest_sec
5481 If this is not a PC relative reloc, then R_ADDEND is
5482 simply the VMA of the destination, so we set
5483 RELOCATION to the change in the destination VMA, or
5484 new_dest_sec - old_dest_sec
5486 relocation = (r_section->output_section->vma
5487 + r_section->output_offset
5489 if (howto_table_ext[r_type].pc_relative)
5490 relocation += input_section->vma;
5493 if (check_dynamic_reloc != NULL)
5497 if (! ((*check_dynamic_reloc)
5498 (finfo->info, input_bfd, input_section, h,
5499 (PTR) rel, contents, &skip, &relocation)))
5505 /* Now warn if a global symbol is undefined. We could not
5506 do this earlier, because check_dynamic_reloc might want
5507 to skip this reloc. */
5509 && ! finfo->info->shared
5510 && r_type != RELOC_BASE10
5511 && r_type != RELOC_BASE13
5512 && r_type != RELOC_BASE22)
5517 name = h->root.root.string;
5519 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5520 if (! ((*finfo->info->callbacks->undefined_symbol)
5521 (finfo->info, name, input_bfd, input_section,
5526 if (r_type != RELOC_SPARC_REV32)
5527 r = MY_final_link_relocate (howto_table_ext + r_type,
5528 input_bfd, input_section,
5529 contents, r_addr, relocation,
5535 x = bfd_get_32 (input_bfd, contents + r_addr);
5536 x = x + relocation + r_addend;
5537 bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
5541 if (r != bfd_reloc_ok)
5546 case bfd_reloc_outofrange:
5548 case bfd_reloc_overflow:
5553 name = h->root.root.string;
5555 || r_type == RELOC_BASE10
5556 || r_type == RELOC_BASE13
5557 || r_type == RELOC_BASE22)
5558 name = strings + GET_WORD (input_bfd,
5559 syms[r_index].e_strx);
5564 s = aout_reloc_index_to_section (input_bfd, r_index);
5565 name = bfd_section_name (input_bfd, s);
5567 if (! ((*finfo->info->callbacks->reloc_overflow)
5568 (finfo->info, name, howto_table_ext[r_type].name,
5569 r_addend, input_bfd, input_section, r_addr)))
5581 /* Handle a link order which is supposed to generate a reloc. */
5584 aout_link_reloc_link_order (finfo, o, p)
5585 struct aout_final_link_info *finfo;
5587 struct bfd_link_order *p;
5589 struct bfd_link_order_reloc *pr;
5592 reloc_howto_type *howto;
5593 file_ptr *reloff_ptr = NULL;
5594 struct reloc_std_external srel;
5595 struct reloc_ext_external erel;
5601 if (p->type == bfd_section_reloc_link_order)
5604 if (bfd_is_abs_section (pr->u.section))
5605 r_index = N_ABS | N_EXT;
5608 BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
5609 r_index = pr->u.section->target_index;
5614 struct aout_link_hash_entry *h;
5616 BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
5618 h = ((struct aout_link_hash_entry *)
5619 bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
5620 pr->u.name, false, false, true));
5621 if (h != (struct aout_link_hash_entry *) NULL
5626 /* We decided to strip this symbol, but it turns out that we
5627 can't. Note that we lose the other and desc information
5628 here. I don't think that will ever matter for a global
5632 if (! aout_link_write_other_symbol (h, (PTR) finfo))
5638 if (! ((*finfo->info->callbacks->unattached_reloc)
5639 (finfo->info, pr->u.name, (bfd *) NULL,
5640 (asection *) NULL, (bfd_vma) 0)))
5646 howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
5649 bfd_set_error (bfd_error_bad_value);
5653 if (o == obj_textsec (finfo->output_bfd))
5654 reloff_ptr = &finfo->treloff;
5655 else if (o == obj_datasec (finfo->output_bfd))
5656 reloff_ptr = &finfo->dreloff;
5660 if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
5663 MY_put_reloc (finfo->output_bfd, r_extern, r_index, p->offset, howto,
5673 r_pcrel = howto->pc_relative;
5674 r_baserel = (howto->type & 8) != 0;
5675 r_jmptable = (howto->type & 16) != 0;
5676 r_relative = (howto->type & 32) != 0;
5677 r_length = howto->size;
5679 PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
5680 if (bfd_header_big_endian (finfo->output_bfd))
5682 srel.r_index[0] = r_index >> 16;
5683 srel.r_index[1] = r_index >> 8;
5684 srel.r_index[2] = r_index;
5686 ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
5687 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
5688 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
5689 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
5690 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
5691 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
5695 srel.r_index[2] = r_index >> 16;
5696 srel.r_index[1] = r_index >> 8;
5697 srel.r_index[0] = r_index;
5699 ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
5700 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
5701 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
5702 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
5703 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
5704 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
5708 rel_ptr = (PTR) &srel;
5710 /* We have to write the addend into the object file, since
5711 standard a.out relocs are in place. It would be more
5712 reliable if we had the current contents of the file here,
5713 rather than assuming zeroes, but we can't read the file since
5714 it was opened using bfd_openw. */
5715 if (pr->addend != 0)
5718 bfd_reloc_status_type r;
5722 size = bfd_get_reloc_size (howto);
5723 buf = (bfd_byte *) bfd_zmalloc (size);
5724 if (buf == (bfd_byte *) NULL)
5726 r = MY_relocate_contents (howto, finfo->output_bfd,
5727 (bfd_vma) pr->addend, buf);
5733 case bfd_reloc_outofrange:
5735 case bfd_reloc_overflow:
5736 if (! ((*finfo->info->callbacks->reloc_overflow)
5738 (p->type == bfd_section_reloc_link_order
5739 ? bfd_section_name (finfo->output_bfd,
5742 howto->name, pr->addend, (bfd *) NULL,
5743 (asection *) NULL, (bfd_vma) 0)))
5750 ok = bfd_set_section_contents (finfo->output_bfd, o, (PTR) buf,
5751 (file_ptr) p->offset, size);
5759 #ifdef MY_put_ext_reloc
5760 MY_put_ext_reloc (finfo->output_bfd, r_extern, r_index, p->offset,
5761 howto, &erel, pr->addend);
5763 PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
5765 if (bfd_header_big_endian (finfo->output_bfd))
5767 erel.r_index[0] = r_index >> 16;
5768 erel.r_index[1] = r_index >> 8;
5769 erel.r_index[2] = r_index;
5771 ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
5772 | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
5776 erel.r_index[2] = r_index >> 16;
5777 erel.r_index[1] = r_index >> 8;
5778 erel.r_index[0] = r_index;
5780 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
5781 | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
5784 PUT_WORD (finfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend);
5785 #endif /* MY_put_ext_reloc */
5787 rel_ptr = (PTR) &erel;
5790 amt = obj_reloc_entry_size (finfo->output_bfd);
5791 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
5792 || bfd_bwrite (rel_ptr, amt, finfo->output_bfd) != amt)
5795 *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
5797 /* Assert that the relocs have not run into the symbols, and that n
5798 the text relocs have not run into the data relocs. */
5799 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
5800 && (reloff_ptr != &finfo->treloff
5802 <= obj_datasec (finfo->output_bfd)->rel_filepos)));