1 /* BFD semi-generic back-end for a.out binaries
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3 Written by Cygnus Support.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22 @section a.out backends
24 BFD supports a number of different flavours of a.out format, though
25 the major differences are only the sizes of the structures on disk,
26 and the shape of the relocation information.
28 The support is split into a basic support file @code{aoutx.h} and
29 other files which derive functions from the base. One derivation file
30 is @code{aoutf1.h} (for a.out flavour 1), and adds to the basic a.out
31 functions support for sun3, sun4, 386 and 29k a.out files, to create a
32 target jump vector for a specific target.
34 This information is further split out into more specific files for each
35 machine, including @code{sunos.c} for sun3 and sun4, @code{newsos3.c} for
36 the Sony NEWS, and @code{demo64.c} for a demonstration of a 64 bit a.out
39 The base file @code{aoutx.h} defines general mechanisms for reading
40 and writing records to and from disk, and various other methods which
41 BFD requires. It is included by @code{aout32.c} and @code{aout64.c} to
42 form the names aout_32_swap_exec_header_in,
43 aout_64_swap_exec_header_in, etc.
45 As an example, this is what goes on to make the back end for a sun4, from aout32.c
55 aout_32_canonicalize_reloc
56 aout_32_find_nearest_line
58 aout_32_get_reloc_upper_bound
66 #define TARGET_NAME "a.out-sunos-big"
67 #define VECNAME sunos_big_vec
70 requires all the names from aout32.c, and produces the jump vector
76 The file host-aout.c is a special case. It is for a large set of hosts
77 that use ``more or less standard'' a.out files, and for which cross-debugging
78 is not interesting. It uses the standard 32-bit a.out support routines,
79 but determines the file offsets and addresses of the text, data,
80 and BSS sections, the machine architecture and machine type,
81 and the entry point address, in a host-dependent manner. Once these
82 values have been determined, generic code is used to handle the
85 When porting it to run on a new system, you must supply:
89 HOST_MACHINE_ARCH (optional)
90 HOST_MACHINE_MACHINE (optional)
94 in the file ../include/sys/h-XXX.h (for your host). These values, plus
95 the structures and macros defined in <a.out.h> on your host system, will
96 produce a BFD target that will access ordinary a.out files on your host.
98 To configure a new machine to use host-aout.c, specify:
100 TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
101 TDEPFILES= host-aout.o trad-core.o
103 in the config/mt-XXX file, and modify configure.in to use the
104 mt-XXX file (by setting "bfd_target=XXX") when your configuration is
110 #define KEEPITTYPE int
114 #include <ansidecl.h>
116 struct external_exec;
120 #include "stab.gnu.h"
123 void (*bfd_error_trap)();
126 @subsection relocations
127 The file @code{aoutx.h} caters for both the @emph{standard} and
128 @emph{extended} forms of a.out relocation records.
130 The standard records are characterised by containing only an address,
131 a symbol index and a type field. The extended records (used on 29ks
132 and sparcs) also have a full integer for an addend.
134 #define CTOR_TABLE_RELOC_IDX 2
137 static reloc_howto_type howto_table_ext[] =
139 HOWTO(RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false),
140 HOWTO(RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false),
141 HOWTO(RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff, false),
142 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, false, true,0,"DISP8", false, 0,0x000000ff, false),
143 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, false, true,0,"DISP16", false, 0,0x0000ffff, false),
144 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, false, true,0,"DISP32", false, 0,0xffffffff, false),
145 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, false, true,0,"WDISP30", false, 0,0x3fffffff, false),
146 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, false, true,0,"WDISP22", false, 0,0x003fffff, false),
147 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, false, true,0,"HI22", false, 0,0x003fffff, false),
148 HOWTO(RELOC_22, 0, 2, 22, false, 0, false, true,0,"22", false, 0,0x003fffff, false),
149 HOWTO(RELOC_13, 0, 2, 13, false, 0, false, true,0,"13", false, 0,0x00001fff, false),
150 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, false, true,0,"LO10", false, 0,0x000003ff, false),
151 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
152 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
153 HOWTO(RELOC_BASE10, 0, 2, 16, false, 0, false, true,0,"BASE10", false, 0,0x0000ffff, false),
154 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, false, true,0,"BASE13", false, 0,0x00001fff, false),
155 HOWTO(RELOC_BASE22, 0, 2, 0, false, 0, false, true,0,"BASE22", false, 0,0x00000000, false),
156 HOWTO(RELOC_PC10, 0, 2, 10, false, 0, false, true,0,"PC10", false, 0,0x000003ff, false),
157 HOWTO(RELOC_PC22, 0, 2, 22, false, 0, false, true,0,"PC22", false, 0,0x003fffff, false),
158 HOWTO(RELOC_JMP_TBL,0, 2, 32, false, 0, false, true,0,"JMP_TBL", false, 0,0xffffffff, false),
159 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
160 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
161 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
162 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, false, true,0,"RELATIVE", false, 0,0x00000000, false),
166 /* Convert standard reloc records to "arelent" format (incl byte swap). */
168 static reloc_howto_type howto_table_std[] = {
169 /* type rs size bsz pcrel bitpos abs ovrf sf name part_inpl readmask setmask pcdone */
170 HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),
171 HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),
172 HOWTO( 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff, false),
173 HOWTO( 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead, false),
174 HOWTO( 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff, false),
175 HOWTO( 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
176 HOWTO( 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff, false),
177 HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface, false),
181 bfd_error_vector_type bfd_error_vector;
184 @subsection Internal Entry Points
185 @code{aoutx.h} exports several routines for accessing the contents of
186 an a.out file, which are gathered and exported in turn by various
187 format specific files (eg sunos.c).
191 *i aout_<size>_swap_exec_header_in
192 Swaps the information in an executable header taken from a raw byte stream memory image,
193 into the internal exec_header structure.
194 *; PROTO(void, aout_<size>_swap_exec_header_in,
196 struct external_exec *raw_bytes,
197 struct internal_exec *execp));
201 DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
203 struct external_exec *raw_bytes AND
204 struct internal_exec *execp)
206 struct external_exec *bytes = (struct external_exec *)raw_bytes;
208 /* Now fill in fields in the execp, from the bytes in the raw data. */
209 execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
210 execp->a_text = GET_WORD (abfd, bytes->e_text);
211 execp->a_data = GET_WORD (abfd, bytes->e_data);
212 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
213 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
214 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
215 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
216 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
220 *i aout_<size>_swap_exec_header_out
221 Swaps the information in an internal exec header structure into the
222 supplied buffer ready for writing to disk.
223 *; PROTO(void, aout_<size>_swap_exec_header_out,
225 struct internal_exec *execp,
226 struct external_exec *raw_bytes));
229 DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
231 struct internal_exec *execp AND
232 struct external_exec *raw_bytes)
234 struct external_exec *bytes = (struct external_exec *)raw_bytes;
236 /* Now fill in fields in the raw data, from the fields in the exec struct. */
237 bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
238 PUT_WORD (abfd, execp->a_text , bytes->e_text);
239 PUT_WORD (abfd, execp->a_data , bytes->e_data);
240 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
241 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
242 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
243 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
244 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
249 struct internal_exec e;
254 *i aout_<size>_some_aout_object_p
256 Some A.OUT variant thinks that the file whose format we're checking
257 is an a.out file. Do some more checking, and set up for access if
258 it really is. Call back to the calling environments "finish up"
259 function just before returning, to handle any last-minute setup.
261 *; PROTO(bfd_target *, aout_<size>_some_aout_object_p,
263 bfd_target *(*callback_to_real_object_p)()));
267 DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
269 struct internal_exec *execp AND
270 bfd_target *(*callback_to_real_object_p) ())
272 struct container *rawptr;
274 rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
275 if (rawptr == NULL) {
276 bfd_error = no_memory;
280 set_tdata (abfd, &rawptr->a);
281 exec_hdr (abfd) = &rawptr->e;
282 *exec_hdr (abfd) = *execp; /* Copy in the internal_exec struct */
283 execp = exec_hdr (abfd); /* Switch to using the newly malloc'd one */
285 /* Set the file flags */
286 abfd->flags = NO_FLAGS;
287 if (execp->a_drsize || execp->a_trsize)
288 abfd->flags |= HAS_RELOC;
290 abfd->flags |= EXEC_P;
292 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
294 if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
295 if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
297 bfd_get_start_address (abfd) = execp->a_entry;
299 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
300 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
302 /* Set the default architecture and machine type. These can be
303 overridden in the callback routine. */
305 bfd_default_set_arch_mach(abfd, bfd_arch_unknown, 0);
307 /* The default relocation entry size is that of traditional V7 Unix. */
308 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
310 /* The default symbol entry size is that of traditional Unix. */
311 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
313 /* create the sections. This is raunchy, but bfd_close wants to reclaim
315 obj_textsec (abfd) = (asection *)NULL;
316 obj_datasec (abfd) = (asection *)NULL;
317 obj_bsssec (abfd) = (asection *)NULL;
318 (void)bfd_make_section(abfd, ".text");
319 (void)bfd_make_section(abfd, ".data");
320 (void)bfd_make_section(abfd, ".bss");
322 abfd->sections = obj_textsec (abfd);
323 obj_textsec (abfd)->next = obj_datasec (abfd);
324 obj_datasec (abfd)->next = obj_bsssec (abfd);
326 obj_datasec (abfd)->size = execp->a_data;
327 obj_bsssec (abfd)->size = execp->a_bss;
329 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
330 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
331 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
332 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
333 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
334 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
335 obj_bsssec (abfd)->flags = SEC_ALLOC;
337 #ifdef THIS_IS_ONLY_DOCUMENTATION
338 /* The common code can't fill in these things because they depend
339 on either the start address of the text segment, the rounding
340 up of virtual addersses between segments, or the starting file
341 position of the text segment -- all of which varies among different
342 versions of a.out. */
344 /* Call back to the format-dependent code to fill in the rest of the
345 fields and do any further cleanup. Things that should be filled
346 in by the callback: */
348 struct exec *execp = exec_hdr (abfd);
350 obj_textsec (abfd)->size = N_TXTSIZE(*execp);
351 /* data and bss are already filled in since they're so standard */
353 /* The virtual memory addresses of the sections */
354 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
355 obj_datasec (abfd)->vma = N_DATADDR(*execp);
356 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
358 /* The file offsets of the sections */
359 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
360 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
362 /* The file offsets of the relocation info */
363 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
364 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
366 /* The file offsets of the string table and symbol table. */
367 obj_str_filepos (abfd) = N_STROFF (*execp);
368 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
370 /* Determine the architecture and machine type of the object file. */
371 switch (N_MACHTYPE (*exec_hdr (abfd))) {
373 abfd->obj_arch = bfd_arch_obscure;
377 /* Determine the size of a relocation entry */
378 switch (abfd->obj_arch) {
381 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
383 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
386 adata(abfd)->page_size = PAGE_SIZE;
387 adata(abfd)->segment_size = SEGMENT_SIZE;
388 adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
392 /* The architecture is encoded in various ways in various a.out variants,
393 or is not encoded at all in some of them. The relocation size depends
394 on the architecture and the a.out variant. Finally, the return value
395 is the bfd_target vector in use. If an error occurs, return zero and
396 set bfd_error to the appropriate error code.
398 Formats such as b.out, which have additional fields in the a.out
399 header, should cope with them in this callback as well. */
400 #endif /* DOCUMENTATION */
402 return (*callback_to_real_object_p)(abfd);
406 *i aout_<size>_mkobject
408 This routine initializes a BFD for use with a.out files.
410 *; PROTO(boolean, aout_<size>_mkobject, (bfd *));
414 DEFUN(NAME(aout,mkobject),(abfd),
417 struct container *rawptr;
419 bfd_error = system_call_error;
421 /* Use an intermediate variable for clarity */
422 rawptr = (struct container *)bfd_zalloc (abfd, sizeof (struct container));
424 if (rawptr == NULL) {
425 bfd_error = no_memory;
429 set_tdata (abfd, rawptr);
430 exec_hdr (abfd) = &(rawptr->e);
432 /* For simplicity's sake we just make all the sections right here. */
434 obj_textsec (abfd) = (asection *)NULL;
435 obj_datasec (abfd) = (asection *)NULL;
436 obj_bsssec (abfd) = (asection *)NULL;
437 bfd_make_section (abfd, ".text");
438 bfd_make_section (abfd, ".data");
439 bfd_make_section (abfd, ".bss");
446 *i aout_<size>_machine_type
448 Keep track of machine architecture and machine type for a.out's.
449 Return the machine_type for a particular arch&machine, or M_UNKNOWN
450 if that exact arch&machine can't be represented in a.out format.
452 If the architecture is understood, machine type 0 (default) should
453 always be understood.
455 *; PROTO(enum machine_type, aout_<size>_machine_type,
456 (enum bfd_architecture arch,
457 unsigned long machine));
461 DEFUN(NAME(aout,machine_type),(arch, machine),
462 enum bfd_architecture arch AND
463 unsigned long machine)
465 enum machine_type arch_flags;
467 arch_flags = M_UNKNOWN;
471 if (machine == 0) arch_flags = M_SPARC;
476 case 0: arch_flags = M_68010; break;
477 case 68000: arch_flags = M_UNKNOWN; break;
478 case 68010: arch_flags = M_68010; break;
479 case 68020: arch_flags = M_68020; break;
480 default: arch_flags = M_UNKNOWN; break;
485 if (machine == 0) arch_flags = M_386;
489 if (machine == 0) arch_flags = M_29K;
493 arch_flags = M_UNKNOWN;
501 *i aout_<size>_set_arch_mach
503 Sets the architecture and the machine of the BFD to those values
504 supplied. Verifies that the format can support the architecture
507 *; PROTO(boolean, aout_<size>_set_arch_mach,
509 enum bfd_architecture,
510 unsigned long machine));
514 DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
516 enum bfd_architecture arch AND
517 unsigned long machine)
519 bfd_default_set_arch_mach(abfd, arch, machine);
520 if (arch != bfd_arch_unknown &&
521 NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
522 return false; /* We can't represent this type */
523 return true; /* We're easy ... */
527 *i aout_<size>new_section_hook
529 Called by the BFD in response to a @code{bfd_make_section} request.
530 *; PROTO(boolean, aout_<size>_new_section_hook,
535 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
539 /* align to double at least */
540 newsect->alignment_power = 3;
542 if (bfd_get_format (abfd) == bfd_object) {
543 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
544 obj_textsec(abfd)= newsect;
548 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
549 obj_datasec(abfd) = newsect;
553 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
554 obj_bsssec(abfd) = newsect;
559 /* We allow more than three sections internally */
564 DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
572 bfd_size_type text_header_size; /* exec_bytes_size if if included in
574 bfd_size_type text_size;
575 if (abfd->output_has_begun == false)
576 { /* set by bfd.c handler */
577 switch (abfd->direction)
581 bfd_error = invalid_operation;
587 case write_direction:
588 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
590 bfd_error = invalid_operation;
593 obj_textsec(abfd)->size =
594 align_power(obj_textsec(abfd)->size,
595 obj_textsec(abfd)->alignment_power);
596 text_size = obj_textsec (abfd)->size;
597 /* Rule (heuristic) for when to pad to a new page.
598 * Note that there are (at least) two ways demand-paged
599 * (ZMAGIC) files have been handled. Most Berkeley-based systems
600 * start the text segment at (PAGE_SIZE). However, newer
601 * versions of SUNOS start the text segment right after the
602 * exec header; the latter is counted in the text segment size,
603 * and is paged in by the kernel with the rest of the text. */
604 if (!(abfd->flags & D_PAGED))
605 { /* Not demand-paged. */
606 obj_textsec(abfd)->filepos = adata(abfd)->exec_bytes_size;
608 else if (obj_textsec(abfd)->vma % adata(abfd)->page_size
609 < adata(abfd)->exec_bytes_size)
610 { /* Old-style demand-paged. */
611 obj_textsec(abfd)->filepos = adata(abfd)->page_size;
614 { /* Sunos-style demand-paged. */
615 obj_textsec(abfd)->filepos = adata(abfd)->exec_bytes_size;
616 text_size += adata(abfd)->exec_bytes_size;
618 text_end = obj_textsec(abfd)->size + obj_textsec(abfd)->filepos;
619 if (abfd->flags & (D_PAGED|WP_TEXT))
621 bfd_size_type text_pad =
622 BFD_ALIGN(text_size, adata(abfd)->segment_size)
624 text_end += text_pad;
625 obj_textsec(abfd)->size += text_pad;
627 obj_datasec(abfd)->filepos = text_end;
628 obj_datasec(abfd)->size =
629 align_power(obj_datasec(abfd)->size,
630 obj_datasec(abfd)->alignment_power);
634 /* regardless, once we know what we're doing, we might as well get going */
635 if (section != obj_bsssec(abfd))
637 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
640 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
648 /* Classify stabs symbols */
650 #define sym_in_text_section(sym) \
651 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
653 #define sym_in_data_section(sym) \
654 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
656 #define sym_in_bss_section(sym) \
657 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
659 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
660 zero in the "value" field. Nonzeroes there are fortrancommon
662 #define sym_is_undefined(sym) \
663 ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
665 /* Symbol is a global definition if N_EXT is on and if it has
666 a nonzero type field. */
667 #define sym_is_global_defn(sym) \
668 (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
670 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
672 #define sym_is_debugger_info(sym) \
673 ((sym)->type & ~(N_EXT | N_TYPE))
675 #define sym_is_fortrancommon(sym) \
676 (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
678 /* Symbol is absolute if it has N_ABS set */
679 #define sym_is_absolute(sym) \
680 (((sym)->type & N_TYPE)== N_ABS)
683 #define sym_is_indirect(sym) \
684 (((sym)->type & N_ABS)== N_ABS)
686 /* Only in their own functions for ease of debugging; when sym flags have
687 stabilised these should be inlined into their (single) caller */
690 DEFUN(translate_from_native_sym_flags,(sym_pointer, cache_ptr, abfd),
691 struct external_nlist *sym_pointer AND
692 aout_symbol_type *cache_ptr AND
695 switch (cache_ptr->type & N_TYPE) {
701 char *copy = bfd_alloc(abfd, strlen(cache_ptr->symbol.name)+1);
703 arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
704 strcpy(copy, cache_ptr->symbol.name);
705 section = bfd_get_section_by_name (abfd, copy);
707 section = bfd_make_section(abfd,copy);
709 switch ( (cache_ptr->type & N_TYPE) ) {
711 section->flags = SEC_CONSTRUCTOR;
712 reloc->relent.section = (asection *)NULL;
713 cache_ptr->symbol.section = (asection *)NULL;
716 section->flags = SEC_CONSTRUCTOR_TEXT;
717 reloc->relent.section = (asection *)obj_textsec(abfd);
718 cache_ptr->symbol.value -= reloc->relent.section->vma;
721 section->flags = SEC_CONSTRUCTOR_DATA;
722 reloc->relent.section = (asection *)obj_datasec(abfd);
723 cache_ptr->symbol.value -= reloc->relent.section->vma;
726 section->flags = SEC_CONSTRUCTOR_BSS;
727 reloc->relent.section = (asection *)obj_bsssec(abfd);
728 cache_ptr->symbol.value -= reloc->relent.section->vma;
731 cache_ptr->symbol.section = reloc->relent.section;
732 reloc->relent.addend = cache_ptr->symbol.value ;
734 /* We modify the symbol to belong to a section depending upon the
735 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
736 really care, and add to the size of the section to contain a
737 pointer to the symbol. Build a reloc entry to relocate to this
738 symbol attached to this section. */
741 section->reloc_count++;
742 section->alignment_power = 2;
743 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
744 reloc->next = section->constructor_chain;
745 section->constructor_chain = reloc;
746 reloc->relent.address = section->size;
747 section->size += sizeof(int *);
749 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
750 cache_ptr->symbol.flags |= BSF_DEBUGGING | BSF_CONSTRUCTOR;
754 if (cache_ptr->type == N_WARNING)
756 /* This symbol is the text of a warning message, the next symbol
757 is the symbol to associate the warning with */
758 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
759 cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
760 /* We furgle with the next symbol in place. We don't want it to be undefined, we'll trample the type */
761 (sym_pointer+1)->e_type[0] = 0xff;
764 if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT)) {
765 /* Two symbols in a row for an INDR message. The first symbol
766 contains the name we will match, the second symbol contains the
767 name the first name is translated into. It is supplied to us
768 undefined. This is good, since we want to pull in any files which
770 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
771 cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
776 if (sym_is_debugger_info (cache_ptr)) {
777 cache_ptr->symbol.flags = BSF_DEBUGGING ;
778 /* Work out the section correct for this symbol */
779 switch (cache_ptr->type & N_TYPE)
783 cache_ptr->symbol.section = obj_textsec (abfd);
784 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
787 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
788 cache_ptr->symbol.section = obj_datasec (abfd);
791 cache_ptr->symbol.section = obj_bsssec (abfd);
792 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
796 cache_ptr->symbol.section = 0;
802 if (sym_is_fortrancommon (cache_ptr))
804 cache_ptr->symbol.flags = BSF_FORT_COMM;
805 cache_ptr->symbol.section = (asection *)NULL;
808 if (sym_is_undefined (cache_ptr)) {
809 cache_ptr->symbol.flags = BSF_UNDEFINED;
811 else if (sym_is_global_defn (cache_ptr)) {
812 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
815 else if (sym_is_absolute (cache_ptr)) {
816 cache_ptr->symbol.flags = BSF_ABSOLUTE;
819 cache_ptr->symbol.flags = BSF_LOCAL;
822 /* In a.out, the value of a symbol is always relative to the
823 * start of the file, if this is a data symbol we'll subtract
824 * the size of the text section to get the section relative
825 * value. If this is a bss symbol (which would be strange)
826 * we'll subtract the size of the previous two sections
827 * to find the section relative address.
830 if (sym_in_text_section (cache_ptr)) {
831 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
832 cache_ptr->symbol.section = obj_textsec (abfd);
834 else if (sym_in_data_section (cache_ptr)){
835 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
836 cache_ptr->symbol.section = obj_datasec (abfd);
838 else if (sym_in_bss_section(cache_ptr)) {
839 cache_ptr->symbol.section = obj_bsssec (abfd);
840 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
843 cache_ptr->symbol.section = (asection *)NULL;
844 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
852 DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
853 struct external_nlist *sym_pointer AND
854 asymbol *cache_ptr AND
857 bfd_vma value = cache_ptr->value;
859 if (bfd_get_section(cache_ptr)) {
860 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
861 sym_pointer->e_type[0] |= N_BSS;
863 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
864 sym_pointer->e_type[0] |= N_DATA;
866 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
867 sym_pointer->e_type[0] |= N_TEXT;
870 bfd_error_vector.nonrepresentable_section(abfd,
871 bfd_get_output_section(cache_ptr)->name);
873 /* Turn the symbol from section relative to absolute again */
876 cache_ptr->section->output_section->vma
877 + cache_ptr->section->output_offset ;
880 sym_pointer->e_type[0] |= N_ABS;
882 if (cache_ptr->flags & (BSF_WARNING)) {
883 (sym_pointer+1)->e_type[0] = 1;
885 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
886 sym_pointer->e_type[0] = (N_UNDF | N_EXT);
889 if (cache_ptr->flags & BSF_ABSOLUTE) {
890 sym_pointer->e_type[0] |= N_ABS;
893 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
894 sym_pointer->e_type[0] |= N_EXT;
896 if (cache_ptr->flags & BSF_DEBUGGING) {
897 sym_pointer->e_type [0]= ((aout_symbol_type *)cache_ptr)->type;
900 PUT_WORD(abfd, value, sym_pointer->e_value);
903 /* Native-level interface to symbols. */
905 /* We read the symbols into a buffer, which is discarded when this
906 function exits. We read the strings into a buffer large enough to
907 hold them all plus all the cached symbol entries. */
910 DEFUN(NAME(aout,make_empty_symbol),(abfd),
913 aout_symbol_type *new =
914 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
915 new->symbol.the_bfd = abfd;
921 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
924 bfd_size_type symbol_size;
925 bfd_size_type string_size;
926 unsigned char string_chars[BYTES_IN_WORD];
927 struct external_nlist *syms;
929 aout_symbol_type *cached;
931 /* If there's no work to be done, don't do any */
932 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
933 symbol_size = exec_hdr(abfd)->a_syms;
934 if (symbol_size == 0) {
935 bfd_error = no_symbols;
939 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
940 if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
942 string_size = GET_WORD (abfd, string_chars);
944 strings =(char *) bfd_alloc(abfd, string_size + 1);
945 cached = (aout_symbol_type *)
946 bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
948 /* malloc this, so we can free it if simply. The symbol caching
949 might want to allocate onto the bfd's obstack */
950 syms = (struct external_nlist *) bfd_xmalloc(symbol_size);
951 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
952 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
954 if (syms) free (syms);
955 if (cached) bfd_release (abfd, cached);
956 if (strings)bfd_release (abfd, strings);
960 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
961 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
965 /* OK, now walk the new symtable, cacheing symbol properties */
967 register struct external_nlist *sym_pointer;
968 register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
969 register aout_symbol_type *cache_ptr = cached;
971 /* Run through table and copy values */
972 for (sym_pointer = syms, cache_ptr = cached;
973 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
975 bfd_vma x = GET_WORD(abfd, sym_pointer->e_strx);
976 cache_ptr->symbol.the_bfd = abfd;
978 cache_ptr->symbol.name = x + strings;
980 cache_ptr->symbol.name = (char *)NULL;
982 cache_ptr->symbol.value = GET_SWORD(abfd, sym_pointer->e_value);
983 cache_ptr->desc = bfd_get_16(abfd, sym_pointer->e_desc);
984 cache_ptr->other =bfd_get_8(abfd, sym_pointer->e_other);
985 cache_ptr->type = bfd_get_8(abfd, sym_pointer->e_type);
986 cache_ptr->symbol.udata = 0;
987 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
991 obj_aout_symbols (abfd) = cached;
999 DEFUN(NAME(aout,write_syms),(abfd),
1002 unsigned int count ;
1003 asymbol **generic = bfd_get_outsymbols (abfd);
1005 bfd_size_type stindex = BYTES_IN_WORD; /* initial string length */
1007 for (count = 0; count < bfd_get_symcount (abfd); count++) {
1008 asymbol *g = generic[count];
1009 struct external_nlist nsp;
1012 unsigned int length = strlen(g->name) +1;
1013 PUT_WORD (abfd, stindex, (unsigned char *)nsp.e_strx);
1017 PUT_WORD (abfd, 0, (unsigned char *)nsp.e_strx);
1020 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
1022 bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc);
1023 bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other);
1024 bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type);
1028 bfd_h_put_16(abfd,0, nsp.e_desc);
1029 bfd_h_put_8(abfd, 0, nsp.e_other);
1030 bfd_h_put_8(abfd, 0, nsp.e_type);
1033 translate_to_native_sym_flags (&nsp, g, abfd);
1035 bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd);
1038 /* Now output the strings. Be sure to put string length into correct
1039 byte ordering before writing it. */
1041 char buffer[BYTES_IN_WORD];
1042 PUT_WORD (abfd, stindex, (unsigned char *)buffer);
1044 bfd_write((PTR)buffer, 1, BYTES_IN_WORD, abfd);
1046 generic = bfd_get_outsymbols(abfd);
1047 for (count = 0; count < bfd_get_symcount(abfd); count++)
1049 asymbol *g = *(generic++);
1053 size_t length = strlen(g->name)+1;
1054 bfd_write((PTR)g->name, 1, length, abfd);
1056 if ((g->flags & BSF_FAKE)==0) {
1057 g->KEEPIT = (KEEPITTYPE) count;
1065 DEFUN(NAME(aout,get_symtab),(abfd, location),
1069 unsigned int counter = 0;
1070 aout_symbol_type *symbase;
1072 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1074 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1075 *(location++) = (asymbol *)( symbase++);
1077 return bfd_get_symcount(abfd);
1081 /* Standard reloc stuff */
1082 /* Output standard relocation information to a file in target byte order. */
1085 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1088 struct reloc_std_external *natptr)
1092 unsigned int r_length;
1094 int r_baserel, r_jmptable, r_relative;
1095 unsigned int r_addend;
1097 PUT_WORD(abfd, g->address, natptr->r_address);
1099 r_length = g->howto->size ; /* Size as a power of two */
1100 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1101 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1106 r_addend = g->addend; /* Start here, see how it goes */
1108 /* name was clobbered by aout_write_syms to be symbol index */
1110 if (g->sym_ptr_ptr != NULL)
1112 if ((*(g->sym_ptr_ptr))->section) {
1113 /* put the section offset into the addend for output */
1114 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1117 r_index = ((*(g->sym_ptr_ptr))->KEEPIT);
1122 if (g->section == NULL) {
1123 /* It is possible to have a reloc with nothing, we generate an
1126 r_index = N_ABS | N_EXT;
1128 else if(g->section->output_section == obj_textsec(abfd)) {
1129 r_index = N_TEXT | N_EXT;
1130 r_addend += g->section->output_section->vma;
1132 else if (g->section->output_section == obj_datasec(abfd)) {
1133 r_index = N_DATA | N_EXT;
1134 r_addend += g->section->output_section->vma;
1136 else if (g->section->output_section == obj_bsssec(abfd)) {
1137 r_index = N_BSS | N_EXT ;
1138 r_addend += g->section->output_section->vma;
1142 r_index = N_ABS | N_EXT;
1146 /* now the fun stuff */
1147 if (abfd->xvec->header_byteorder_big_p != false) {
1148 natptr->r_index[0] = r_index >> 16;
1149 natptr->r_index[1] = r_index >> 8;
1150 natptr->r_index[2] = r_index;
1152 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1153 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1154 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1155 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1156 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1157 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1159 natptr->r_index[2] = r_index >> 16;
1160 natptr->r_index[1] = r_index >> 8;
1161 natptr->r_index[0] = r_index;
1163 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1164 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1165 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1166 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1167 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1168 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1173 /* Extended stuff */
1174 /* Output extended relocation information to a file in target byte order. */
1177 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1180 register struct reloc_ext_external *natptr)
1184 unsigned int r_type;
1185 unsigned int r_addend;
1187 PUT_WORD (abfd, g->address, natptr->r_address);
1189 /* Find a type in the output format which matches the input howto -
1190 at the moment we assume input format == output format FIXME!! */
1191 r_type = (enum reloc_type) g->howto->type;
1193 r_addend = g->addend; /* Start here, see how it goes */
1195 /* name was clobbered by aout_write_syms to be symbol index*/
1197 if (g->sym_ptr_ptr != NULL)
1199 if ((*(g->sym_ptr_ptr))->section) {
1200 /* put the section offset into the addend for output */
1201 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1204 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
1209 if (g->section == NULL) {
1211 r_index = N_ABS | N_EXT;
1213 else if(g->section->output_section == obj_textsec(abfd)) {
1214 r_index = N_TEXT | N_EXT;
1215 r_addend += g->section->output_section->vma;
1217 else if (g->section->output_section == obj_datasec(abfd)) {
1218 r_index = N_DATA | N_EXT;
1219 r_addend += g->section->output_section->vma;
1221 else if (g->section->output_section == obj_bsssec(abfd)) {
1222 r_index = N_BSS | N_EXT ;
1223 r_addend += g->section->output_section->vma;
1227 r_index = N_ABS | N_EXT;
1231 /* now the fun stuff */
1232 if (abfd->xvec->header_byteorder_big_p != false) {
1233 natptr->r_index[0] = r_index >> 16;
1234 natptr->r_index[1] = r_index >> 8;
1235 natptr->r_index[2] = r_index;
1237 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1238 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1240 natptr->r_index[2] = r_index >> 16;
1241 natptr->r_index[1] = r_index >> 8;
1242 natptr->r_index[0] = r_index;
1244 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1245 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1248 PUT_WORD (abfd, r_addend, natptr->r_addend);
1251 #define MOVE_ADDRESS(ad) \
1253 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1254 cache_ptr->section = (asection *)NULL; \
1255 cache_ptr->addend = ad; \
1257 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1258 switch (r_index) { \
1260 case N_TEXT | N_EXT: \
1261 cache_ptr->section = obj_textsec(abfd); \
1262 cache_ptr->addend = ad - su->textsec->vma; \
1265 case N_DATA | N_EXT: \
1266 cache_ptr->section = obj_datasec(abfd); \
1267 cache_ptr->addend = ad - su->datasec->vma; \
1270 case N_BSS | N_EXT: \
1271 cache_ptr->section = obj_bsssec(abfd); \
1272 cache_ptr->addend = ad - su->bsssec->vma; \
1275 case N_ABS | N_EXT: \
1276 cache_ptr->section = NULL; /* No section */ \
1277 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1281 cache_ptr->section = NULL; /* No section */ \
1282 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1289 DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
1291 struct reloc_ext_external *bytes AND
1292 arelent *cache_ptr AND
1297 unsigned int r_type;
1298 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1300 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
1302 /* now the fun stuff */
1303 if (abfd->xvec->header_byteorder_big_p != false) {
1304 r_index = (bytes->r_index[0] << 16)
1305 | (bytes->r_index[1] << 8)
1306 | bytes->r_index[2];
1307 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
1308 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
1309 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1311 r_index = (bytes->r_index[2] << 16)
1312 | (bytes->r_index[1] << 8)
1313 | bytes->r_index[0];
1314 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1315 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1316 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1319 cache_ptr->howto = howto_table_ext + r_type;
1320 MOVE_ADDRESS(GET_SWORD(abfd,bytes->r_addend));
1324 DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
1326 struct reloc_std_external *bytes AND
1327 arelent *cache_ptr AND
1332 unsigned int r_length;
1334 int r_baserel, r_jmptable, r_relative;
1335 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1337 cache_ptr->address = (int32_type)(bfd_h_get_32 (abfd, bytes->r_address));
1339 /* now the fun stuff */
1340 if (abfd->xvec->header_byteorder_big_p != false) {
1341 r_index = (bytes->r_index[0] << 16)
1342 | (bytes->r_index[1] << 8)
1343 | bytes->r_index[2];
1344 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
1345 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
1346 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
1347 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1348 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
1349 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
1350 >> RELOC_STD_BITS_LENGTH_SH_BIG;
1352 r_index = (bytes->r_index[2] << 16)
1353 | (bytes->r_index[1] << 8)
1354 | bytes->r_index[0];
1355 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1356 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
1357 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1358 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1359 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1360 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1361 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1364 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1365 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1373 DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
1379 bfd_size_type reloc_size;
1381 arelent *reloc_cache;
1384 if (asect->relocation) return true;
1386 if (asect->flags & SEC_CONSTRUCTOR) return true;
1388 if (asect == obj_datasec (abfd)) {
1389 reloc_size = exec_hdr(abfd)->a_drsize;
1393 if (asect == obj_textsec (abfd)) {
1394 reloc_size = exec_hdr(abfd)->a_trsize;
1398 bfd_error = invalid_operation;
1402 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1403 each_size = obj_reloc_entry_size (abfd);
1405 count = reloc_size / each_size;
1408 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1412 bfd_error = no_memory;
1416 relocs = (PTR) bfd_alloc (abfd, reloc_size);
1418 bfd_release (abfd, reloc_cache);
1422 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1423 bfd_release (abfd, relocs);
1424 bfd_release (abfd, reloc_cache);
1425 bfd_error = system_call_error;
1429 if (each_size == RELOC_EXT_SIZE) {
1430 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
1431 unsigned int counter = 0;
1432 arelent *cache_ptr = reloc_cache;
1434 for (; counter < count; counter++, rptr++, cache_ptr++) {
1435 NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
1438 register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
1439 unsigned int counter = 0;
1440 arelent *cache_ptr = reloc_cache;
1442 for (; counter < count; counter++, rptr++, cache_ptr++) {
1443 NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
1448 bfd_release (abfd,relocs);
1449 asect->relocation = reloc_cache;
1450 asect->reloc_count = count;
1456 /* Write out a relocation section into an object file. */
1459 DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
1464 unsigned char *native, *natptr;
1467 unsigned int count = section->reloc_count;
1470 if (count == 0) return true;
1472 each_size = obj_reloc_entry_size (abfd);
1473 natsize = each_size * count;
1474 native = (unsigned char *) bfd_zalloc (abfd, natsize);
1476 bfd_error = no_memory;
1480 generic = section->orelocation;
1482 if (each_size == RELOC_EXT_SIZE)
1484 for (natptr = native;
1486 --count, natptr += each_size, ++generic)
1487 NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
1491 for (natptr = native;
1493 --count, natptr += each_size, ++generic)
1494 NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
1497 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1498 bfd_release(abfd, native);
1501 bfd_release (abfd, native);
1506 /* This is stupid. This function should be a boolean predicate */
1508 DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
1511 arelent **relptr AND
1514 arelent *tblptr = section->relocation;
1517 if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
1520 if (section->flags & SEC_CONSTRUCTOR) {
1521 arelent_chain *chain = section->constructor_chain;
1522 for (count = 0; count < section->reloc_count; count ++) {
1523 *relptr ++ = &chain->relent;
1524 chain = chain->next;
1528 tblptr = section->relocation;
1529 if (!tblptr) return 0;
1531 for (count = 0; count++ < section->reloc_count;)
1533 *relptr++ = tblptr++;
1538 return section->reloc_count;
1542 DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
1546 if (bfd_get_format (abfd) != bfd_object) {
1547 bfd_error = invalid_operation;
1550 if (asect->flags & SEC_CONSTRUCTOR) {
1551 return (sizeof (arelent *) * (asect->reloc_count+1));
1555 if (asect == obj_datasec (abfd))
1556 return (sizeof (arelent *) *
1557 ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
1560 if (asect == obj_textsec (abfd))
1561 return (sizeof (arelent *) *
1562 ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
1565 bfd_error = invalid_operation;
1571 DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
1574 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1576 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1579 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
1580 bfd *ignore_abfd AND
1581 asymbol *ignore_symbol)
1583 return (alent *)NULL;
1588 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
1589 bfd *ignore_abfd AND
1592 bfd_print_symbol_type how)
1594 FILE *file = (FILE *)afile;
1597 case bfd_print_symbol_name:
1599 fprintf(file,"%s", symbol->name);
1601 case bfd_print_symbol_more:
1602 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1603 (unsigned)(aout_symbol(symbol)->other & 0xff),
1604 (unsigned)(aout_symbol(symbol)->type));
1606 case bfd_print_symbol_all:
1608 CONST char *section_name = symbol->section == (asection *)NULL ?
1609 "*abs" : symbol->section->name;
1611 bfd_print_symbol_vandf((PTR)file,symbol);
1613 fprintf(file," %-5s %04x %02x %02x",
1615 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1616 (unsigned)(aout_symbol(symbol)->other & 0xff),
1617 (unsigned)(aout_symbol(symbol)->type & 0xff));
1619 fprintf(file," %s", symbol->name);
1622 case bfd_print_symbol_nm:
1624 int section_code = bfd_decode_symclass (symbol);
1626 if (section_code == 'U')
1628 else if (symbol->section != (asection *)NULL)
1629 fprintf_vma(file, symbol->value+symbol->section->vma);
1631 fprintf_vma(file, symbol->value);
1632 if (section_code == '?')
1634 int type_code = aout_symbol(symbol)->type & 0xff;
1635 char *stab_name = aout_stab_name(type_code);
1637 if (stab_name == NULL)
1639 sprintf(buf, "(%d)", type_code);
1642 fprintf(file," - %02x %04x %5s",
1643 (unsigned)(aout_symbol(symbol)->other & 0xff),
1644 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1648 fprintf(file," %c", section_code);
1650 fprintf(file," %s", symbol->name);
1657 provided a BFD, a section and an offset into the section, calculate
1658 and return the name of the source file and the line nearest to the
1663 DEFUN(NAME(aout,find_nearest_line),(abfd,
1671 asection *section AND
1672 asymbol **symbols AND
1674 CONST char **filename_ptr AND
1675 CONST char **functionname_ptr AND
1676 unsigned int *line_ptr)
1678 /* Run down the file looking for the filename, function and linenumber */
1680 static char buffer[100];
1681 static char filename_buffer[200];
1682 bfd_vma high_line_vma = ~0;
1683 bfd_vma low_func_vma = 0;
1685 *filename_ptr = abfd->filename;
1686 *functionname_ptr = 0;
1688 if (symbols != (asymbol **)NULL) {
1689 for (p = symbols; *p; p++) {
1690 aout_symbol_type *q = (aout_symbol_type *)(*p);
1694 *filename_ptr = q->symbol.name;
1695 /* Look ahead to next symbol to check if that too is an N_SO. */
1699 q = (aout_symbol_type *)(*p);
1700 if (q->type != N_SO)
1703 /* Found a second N_SO First is directory; second is filename. */
1704 if (q->symbol.name[0] == '/')
1705 *filename_ptr = q->symbol.name;
1708 sprintf(filename_buffer, "%.140s%.50s",
1709 *filename_ptr, q->symbol.name);
1710 *filename_ptr = filename_buffer;
1713 if (obj_textsec(abfd) != section) {
1721 /* We'll keep this if it resolves nearer than the one we have already */
1722 if (q->symbol.value >= offset &&
1723 q->symbol.value < high_line_vma) {
1724 *line_ptr = q->desc;
1725 high_line_vma = q->symbol.value;
1730 /* We'll keep this if it is nearer than the one we have already */
1731 if (q->symbol.value >= low_func_vma &&
1732 q->symbol.value <= offset) {
1733 low_func_vma = q->symbol.value;
1734 func = (asymbol *)q;
1736 if (*line_ptr && func) {
1737 CONST char *function = func->name;
1739 strncpy(buffer, function, sizeof(buffer)-1);
1740 buffer[sizeof(buffer)-1] = 0;
1741 /* Have to remove : stuff */
1742 p = strchr(buffer,':');
1743 if (p != NULL) { *p = '\0'; }
1744 *functionname_ptr = buffer;
1759 DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
1763 return adata(abfd)->exec_bytes_size;