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;
328 obj_textsec (abfd)->size = execp->a_text;
330 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
331 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
332 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
333 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
334 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
335 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
336 obj_bsssec (abfd)->flags = SEC_ALLOC;
338 #ifdef THIS_IS_ONLY_DOCUMENTATION
339 /* Call back to the format-dependent code to fill in the rest of the
340 fields and do any further cleanup. Things that should be filled
341 in by the callback: */
343 struct exec *execp = exec_hdr (abfd);
345 /* The virtual memory addresses of the sections */
346 obj_datasec (abfd)->vma = N_DATADDR(*execp);
347 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
348 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
350 /* The file offsets of the sections */
351 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
352 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
354 /* The file offsets of the relocation info */
355 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
356 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
358 /* The file offsets of the string table and symbol table. */
359 obj_str_filepos (abfd) = N_STROFF (*execp);
360 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
362 /* This common code can't fill in those things because they depend
363 on either the start address of the text segment, the rounding
364 up of virtual addersses between segments, or the starting file
365 position of the text segment -- all of which varies among different
366 versions of a.out. */
368 /* Determine the architecture and machine type of the object file. */
369 switch (N_MACHTYPE (*exec_hdr (abfd))) {
371 abfd->obj_arch = bfd_arch_obscure;
375 /* Determine the size of a relocation entry */
376 switch (abfd->obj_arch) {
379 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
381 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
384 adata(abfd)->page_size = PAGE_SIZE;
385 adata(abfd)->segment_size = SEGMENT_SIZE;
386 adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
390 /* The architecture is encoded in various ways in various a.out variants,
391 or is not encoded at all in some of them. The relocation size depends
392 on the architecture and the a.out variant. Finally, the return value
393 is the bfd_target vector in use. If an error occurs, return zero and
394 set bfd_error to the appropriate error code.
396 Formats such as b.out, which have additional fields in the a.out
397 header, should cope with them in this callback as well. */
398 #endif /* DOCUMENTATION */
401 return (*callback_to_real_object_p)(abfd);
405 *i aout_<size>_mkobject
407 This routine initializes a BFD for use with a.out files.
409 *; PROTO(boolean, aout_<size>_mkobject, (bfd *));
413 DEFUN(NAME(aout,mkobject),(abfd),
416 struct container *rawptr;
418 bfd_error = system_call_error;
420 /* Use an intermediate variable for clarity */
421 rawptr = (struct container *)bfd_zalloc (abfd, sizeof (struct container));
423 if (rawptr == NULL) {
424 bfd_error = no_memory;
428 set_tdata (abfd, rawptr);
429 exec_hdr (abfd) = &(rawptr->e);
431 /* For simplicity's sake we just make all the sections right here. */
433 obj_textsec (abfd) = (asection *)NULL;
434 obj_datasec (abfd) = (asection *)NULL;
435 obj_bsssec (abfd) = (asection *)NULL;
436 bfd_make_section (abfd, ".text");
437 bfd_make_section (abfd, ".data");
438 bfd_make_section (abfd, ".bss");
445 *i aout_<size>_machine_type
447 Keep track of machine architecture and machine type for a.out's.
448 Return the machine_type for a particular arch&machine, or M_UNKNOWN
449 if that exact arch&machine can't be represented in a.out format.
451 If the architecture is understood, machine type 0 (default) should
452 always be understood.
454 *; PROTO(enum machine_type, aout_<size>_machine_type,
455 (enum bfd_architecture arch,
456 unsigned long machine));
460 DEFUN(NAME(aout,machine_type),(arch, machine),
461 enum bfd_architecture arch AND
462 unsigned long machine)
464 enum machine_type arch_flags;
466 arch_flags = M_UNKNOWN;
470 if (machine == 0) arch_flags = M_SPARC;
475 case 0: arch_flags = M_68010; break;
476 case 68000: arch_flags = M_UNKNOWN; break;
477 case 68010: arch_flags = M_68010; break;
478 case 68020: arch_flags = M_68020; break;
479 default: arch_flags = M_UNKNOWN; break;
484 if (machine == 0) arch_flags = M_386;
488 if (machine == 0) arch_flags = M_29K;
492 arch_flags = M_UNKNOWN;
500 *i aout_<size>_set_arch_mach
502 Sets the architecture and the machine of the BFD to those values
503 supplied. Verifies that the format can support the architecture
506 *; PROTO(boolean, aout_<size>_set_arch_mach,
508 enum bfd_architecture,
509 unsigned long machine));
513 DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
515 enum bfd_architecture arch AND
516 unsigned long machine)
518 bfd_default_set_arch_mach(abfd, arch, machine);
519 if (arch != bfd_arch_unknown &&
520 NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
521 return false; /* We can't represent this type */
522 return true; /* We're easy ... */
526 *i aout_<size>new_section_hook
528 Called by the BFD in response to a @code{bfd_make_section} request.
529 *; PROTO(boolean, aout_<size>_new_section_hook,
534 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
538 /* align to double at least */
539 newsect->alignment_power = 3;
541 if (bfd_get_format (abfd) == bfd_object) {
542 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
543 obj_textsec(abfd)= newsect;
547 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
548 obj_datasec(abfd) = newsect;
552 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
553 obj_bsssec(abfd) = newsect;
558 /* We allow more than three sections internally */
563 DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
571 bfd_size_type text_header_size; /* exec_bytes_size if if included in
573 bfd_size_type text_size;
574 if (abfd->output_has_begun == false)
575 { /* set by bfd.c handler */
576 switch (abfd->direction)
580 bfd_error = invalid_operation;
586 case write_direction:
587 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
589 bfd_error = invalid_operation;
592 obj_textsec(abfd)->size =
593 align_power(obj_textsec(abfd)->size,
594 obj_textsec(abfd)->alignment_power);
595 text_size = obj_textsec (abfd)->size;
596 /* Rule (heuristic) for when to pad to a new page.
597 * Note that there are (at least) two ways demand-paged
598 * (ZMAGIC) files have been handled. Most Berkeley-based systems
599 * start the text segment at (PAGE_SIZE). However, newer
600 * versions of SUNOS start the text segment right after the
601 * exec header; the latter is counted in the text segment size,
602 * and is paged in by the kernel with the rest of the text. */
603 if (!(abfd->flags & D_PAGED))
604 { /* Not demand-paged. */
605 obj_textsec(abfd)->filepos = adata(abfd)->exec_bytes_size;
607 else if (obj_textsec(abfd)->vma % adata(abfd)->page_size
608 < adata(abfd)->exec_bytes_size)
609 { /* Old-style demand-paged. */
610 obj_textsec(abfd)->filepos = adata(abfd)->page_size;
613 { /* Sunos-style demand-paged. */
614 obj_textsec(abfd)->filepos = adata(abfd)->exec_bytes_size;
615 text_size += adata(abfd)->exec_bytes_size;
617 text_end = obj_textsec(abfd)->size + obj_textsec(abfd)->filepos;
618 if (abfd->flags & (D_PAGED|WP_TEXT))
620 bfd_size_type text_pad =
621 ALIGN(text_size, adata(abfd)->segment_size) - text_size;
622 text_end += text_pad;
623 obj_textsec(abfd)->size += text_pad;
625 obj_datasec(abfd)->filepos = text_end;
626 obj_datasec(abfd)->size =
627 align_power(obj_datasec(abfd)->size,
628 obj_datasec(abfd)->alignment_power);
632 /* regardless, once we know what we're doing, we might as well get going */
633 if (section != obj_bsssec(abfd))
635 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
638 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
646 /* Classify stabs symbols */
648 #define sym_in_text_section(sym) \
649 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
651 #define sym_in_data_section(sym) \
652 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
654 #define sym_in_bss_section(sym) \
655 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
657 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
658 zero in the "value" field. Nonzeroes there are fortrancommon
660 #define sym_is_undefined(sym) \
661 ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
663 /* Symbol is a global definition if N_EXT is on and if it has
664 a nonzero type field. */
665 #define sym_is_global_defn(sym) \
666 (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
668 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
670 #define sym_is_debugger_info(sym) \
671 ((sym)->type & ~(N_EXT | N_TYPE))
673 #define sym_is_fortrancommon(sym) \
674 (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
676 /* Symbol is absolute if it has N_ABS set */
677 #define sym_is_absolute(sym) \
678 (((sym)->type & N_TYPE)== N_ABS)
681 #define sym_is_indirect(sym) \
682 (((sym)->type & N_ABS)== N_ABS)
684 /* Only in their own functions for ease of debugging; when sym flags have
685 stabilised these should be inlined into their (single) caller */
688 DEFUN(translate_from_native_sym_flags,(sym_pointer, cache_ptr, abfd),
689 struct external_nlist *sym_pointer AND
690 aout_symbol_type *cache_ptr AND
693 switch (cache_ptr->type & N_TYPE) {
699 char *copy = bfd_alloc(abfd, strlen(cache_ptr->symbol.name)+1);
701 arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
702 strcpy(copy, cache_ptr->symbol.name);
703 section = bfd_get_section_by_name (abfd, copy);
705 section = bfd_make_section(abfd,copy);
707 switch ( (cache_ptr->type & N_TYPE) ) {
709 section->flags = SEC_CONSTRUCTOR;
710 reloc->relent.section = (asection *)NULL;
711 cache_ptr->symbol.section = (asection *)NULL;
714 section->flags = SEC_CONSTRUCTOR_TEXT;
715 reloc->relent.section = (asection *)obj_textsec(abfd);
716 cache_ptr->symbol.value -= reloc->relent.section->vma;
719 section->flags = SEC_CONSTRUCTOR_DATA;
720 reloc->relent.section = (asection *)obj_datasec(abfd);
721 cache_ptr->symbol.value -= reloc->relent.section->vma;
724 section->flags = SEC_CONSTRUCTOR_BSS;
725 reloc->relent.section = (asection *)obj_bsssec(abfd);
726 cache_ptr->symbol.value -= reloc->relent.section->vma;
729 cache_ptr->symbol.section = reloc->relent.section;
730 reloc->relent.addend = cache_ptr->symbol.value ;
732 /* We modify the symbol to belong to a section depending upon the
733 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
734 really care, and add to the size of the section to contain a
735 pointer to the symbol. Build a reloc entry to relocate to this
736 symbol attached to this section. */
739 section->reloc_count++;
740 section->alignment_power = 2;
741 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
742 reloc->next = section->constructor_chain;
743 section->constructor_chain = reloc;
744 reloc->relent.address = section->size;
745 section->size += sizeof(int *);
747 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
748 cache_ptr->symbol.flags |= BSF_DEBUGGING | BSF_CONSTRUCTOR;
752 if (cache_ptr->type == N_WARNING)
754 /* This symbol is the text of a warning message, the next symbol
755 is the symbol to associate the warning with */
756 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
757 cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
758 /* We furgle with the next symbol in place. We don't want it to be undefined, we'll trample the type */
759 (sym_pointer+1)->e_type[0] = 0xff;
762 if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT)) {
763 /* Two symbols in a row for an INDR message. The first symbol
764 contains the name we will match, the second symbol contains the
765 name the first name is translated into. It is supplied to us
766 undefined. This is good, since we want to pull in any files which
768 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
769 cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
774 if (sym_is_debugger_info (cache_ptr)) {
775 cache_ptr->symbol.flags = BSF_DEBUGGING ;
776 /* Work out the section correct for this symbol */
777 switch (cache_ptr->type & N_TYPE)
781 cache_ptr->symbol.section = obj_textsec (abfd);
782 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
785 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
786 cache_ptr->symbol.section = obj_datasec (abfd);
789 cache_ptr->symbol.section = obj_bsssec (abfd);
790 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
794 cache_ptr->symbol.section = 0;
800 if (sym_is_fortrancommon (cache_ptr))
802 cache_ptr->symbol.flags = BSF_FORT_COMM;
803 cache_ptr->symbol.section = (asection *)NULL;
806 if (sym_is_undefined (cache_ptr)) {
807 cache_ptr->symbol.flags = BSF_UNDEFINED;
809 else if (sym_is_global_defn (cache_ptr)) {
810 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
813 else if (sym_is_absolute (cache_ptr)) {
814 cache_ptr->symbol.flags = BSF_ABSOLUTE;
817 cache_ptr->symbol.flags = BSF_LOCAL;
820 /* In a.out, the value of a symbol is always relative to the
821 * start of the file, if this is a data symbol we'll subtract
822 * the size of the text section to get the section relative
823 * value. If this is a bss symbol (which would be strange)
824 * we'll subtract the size of the previous two sections
825 * to find the section relative address.
828 if (sym_in_text_section (cache_ptr)) {
829 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
830 cache_ptr->symbol.section = obj_textsec (abfd);
832 else if (sym_in_data_section (cache_ptr)){
833 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
834 cache_ptr->symbol.section = obj_datasec (abfd);
836 else if (sym_in_bss_section(cache_ptr)) {
837 cache_ptr->symbol.section = obj_bsssec (abfd);
838 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
841 cache_ptr->symbol.section = (asection *)NULL;
842 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
850 DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
851 struct external_nlist *sym_pointer AND
852 asymbol *cache_ptr AND
855 bfd_vma value = cache_ptr->value;
857 if (bfd_get_section(cache_ptr)) {
858 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
859 sym_pointer->e_type[0] |= N_BSS;
861 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
862 sym_pointer->e_type[0] |= N_DATA;
864 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
865 sym_pointer->e_type[0] |= N_TEXT;
868 bfd_error_vector.nonrepresentable_section(abfd,
869 bfd_get_output_section(cache_ptr)->name);
871 /* Turn the symbol from section relative to absolute again */
874 cache_ptr->section->output_section->vma
875 + cache_ptr->section->output_offset ;
878 sym_pointer->e_type[0] |= N_ABS;
880 if (cache_ptr->flags & (BSF_WARNING)) {
881 (sym_pointer+1)->e_type[0] = 1;
883 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
884 sym_pointer->e_type[0] = (N_UNDF | N_EXT);
887 if (cache_ptr->flags & BSF_ABSOLUTE) {
888 sym_pointer->e_type[0] |= N_ABS;
891 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
892 sym_pointer->e_type[0] |= N_EXT;
894 if (cache_ptr->flags & BSF_DEBUGGING) {
895 sym_pointer->e_type [0]= ((aout_symbol_type *)cache_ptr)->type;
898 PUT_WORD(abfd, value, sym_pointer->e_value);
901 /* Native-level interface to symbols. */
903 /* We read the symbols into a buffer, which is discarded when this
904 function exits. We read the strings into a buffer large enough to
905 hold them all plus all the cached symbol entries. */
908 DEFUN(NAME(aout,make_empty_symbol),(abfd),
911 aout_symbol_type *new =
912 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
913 new->symbol.the_bfd = abfd;
919 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
922 bfd_size_type symbol_size;
923 bfd_size_type string_size;
924 unsigned char string_chars[BYTES_IN_WORD];
925 struct external_nlist *syms;
927 aout_symbol_type *cached;
929 /* If there's no work to be done, don't do any */
930 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
931 symbol_size = exec_hdr(abfd)->a_syms;
932 if (symbol_size == 0) {
933 bfd_error = no_symbols;
937 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
938 if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
940 string_size = GET_WORD (abfd, string_chars);
942 strings =(char *) bfd_alloc(abfd, string_size + 1);
943 cached = (aout_symbol_type *)
944 bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
946 /* malloc this, so we can free it if simply. The symbol caching
947 might want to allocate onto the bfd's obstack */
948 syms = (struct external_nlist *) malloc(symbol_size);
949 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
950 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
952 if (syms) free (syms);
953 if (cached) bfd_release (abfd, cached);
954 if (strings)bfd_release (abfd, strings);
958 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
959 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
963 /* OK, now walk the new symtable, cacheing symbol properties */
965 register struct external_nlist *sym_pointer;
966 register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
967 register aout_symbol_type *cache_ptr = cached;
969 /* Run through table and copy values */
970 for (sym_pointer = syms, cache_ptr = cached;
971 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
973 bfd_vma x = GET_WORD(abfd, sym_pointer->e_strx);
974 cache_ptr->symbol.the_bfd = abfd;
976 cache_ptr->symbol.name = x + strings;
978 cache_ptr->symbol.name = (char *)NULL;
980 cache_ptr->symbol.value = GET_SWORD(abfd, sym_pointer->e_value);
981 cache_ptr->desc = bfd_get_16(abfd, sym_pointer->e_desc);
982 cache_ptr->other =bfd_get_8(abfd, sym_pointer->e_other);
983 cache_ptr->type = bfd_get_8(abfd, sym_pointer->e_type);
984 cache_ptr->symbol.udata = 0;
985 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
989 obj_aout_symbols (abfd) = cached;
997 DEFUN(NAME(aout,write_syms),(abfd),
1000 unsigned int count ;
1001 asymbol **generic = bfd_get_outsymbols (abfd);
1003 bfd_size_type stindex = BYTES_IN_WORD; /* initial string length */
1005 for (count = 0; count < bfd_get_symcount (abfd); count++) {
1006 asymbol *g = generic[count];
1007 struct external_nlist nsp;
1010 unsigned int length = strlen(g->name) +1;
1011 PUT_WORD (abfd, stindex, (unsigned char *)nsp.e_strx);
1015 PUT_WORD (abfd, 0, (unsigned char *)nsp.e_strx);
1018 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
1020 bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc);
1021 bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other);
1022 bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type);
1026 bfd_h_put_16(abfd,0, nsp.e_desc);
1027 bfd_h_put_8(abfd, 0, nsp.e_other);
1028 bfd_h_put_8(abfd, 0, nsp.e_type);
1031 translate_to_native_sym_flags (&nsp, g, abfd);
1033 bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd);
1036 /* Now output the strings. Be sure to put string length into correct
1037 byte ordering before writing it. */
1039 char buffer[BYTES_IN_WORD];
1040 PUT_WORD (abfd, stindex, (unsigned char *)buffer);
1042 bfd_write((PTR)buffer, 1, BYTES_IN_WORD, abfd);
1044 generic = bfd_get_outsymbols(abfd);
1045 for (count = 0; count < bfd_get_symcount(abfd); count++)
1047 asymbol *g = *(generic++);
1051 size_t length = strlen(g->name)+1;
1052 bfd_write((PTR)g->name, 1, length, abfd);
1054 if ((g->flags & BSF_FAKE)==0) {
1055 g->KEEPIT = (KEEPITTYPE) count;
1063 DEFUN(NAME(aout,get_symtab),(abfd, location),
1067 unsigned int counter = 0;
1068 aout_symbol_type *symbase;
1070 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1072 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1073 *(location++) = (asymbol *)( symbase++);
1075 return bfd_get_symcount(abfd);
1079 /* Standard reloc stuff */
1080 /* Output standard relocation information to a file in target byte order. */
1083 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1086 struct reloc_std_external *natptr)
1090 unsigned int r_length;
1092 int r_baserel, r_jmptable, r_relative;
1093 unsigned int r_addend;
1095 PUT_WORD(abfd, g->address, natptr->r_address);
1097 r_length = g->howto->size ; /* Size as a power of two */
1098 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1099 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1104 r_addend = g->addend; /* Start here, see how it goes */
1106 /* name was clobbered by aout_write_syms to be symbol index */
1108 if (g->sym_ptr_ptr != NULL)
1110 if ((*(g->sym_ptr_ptr))->section) {
1111 /* put the section offset into the addend for output */
1112 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1115 r_index = ((*(g->sym_ptr_ptr))->KEEPIT);
1120 if (g->section == NULL) {
1121 /* It is possible to have a reloc with nothing, we generate an
1124 r_index = N_ABS | N_EXT;
1126 else if(g->section->output_section == obj_textsec(abfd)) {
1127 r_index = N_TEXT | N_EXT;
1128 r_addend += g->section->output_section->vma;
1130 else if (g->section->output_section == obj_datasec(abfd)) {
1131 r_index = N_DATA | N_EXT;
1132 r_addend += g->section->output_section->vma;
1134 else if (g->section->output_section == obj_bsssec(abfd)) {
1135 r_index = N_BSS | N_EXT ;
1136 r_addend += g->section->output_section->vma;
1140 r_index = N_ABS | N_EXT;
1144 /* now the fun stuff */
1145 if (abfd->xvec->header_byteorder_big_p != false) {
1146 natptr->r_index[0] = r_index >> 16;
1147 natptr->r_index[1] = r_index >> 8;
1148 natptr->r_index[2] = r_index;
1150 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1151 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1152 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1153 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1154 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1155 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1157 natptr->r_index[2] = r_index >> 16;
1158 natptr->r_index[1] = r_index >> 8;
1159 natptr->r_index[0] = r_index;
1161 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1162 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1163 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1164 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1165 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1166 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1171 /* Extended stuff */
1172 /* Output extended relocation information to a file in target byte order. */
1175 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1178 register struct reloc_ext_external *natptr)
1182 unsigned int r_type;
1183 unsigned int r_addend;
1185 PUT_WORD (abfd, g->address, natptr->r_address);
1187 /* Find a type in the output format which matches the input howto -
1188 at the moment we assume input format == output format FIXME!! */
1189 r_type = (enum reloc_type) g->howto->type;
1191 r_addend = g->addend; /* Start here, see how it goes */
1193 /* name was clobbered by aout_write_syms to be symbol index*/
1195 if (g->sym_ptr_ptr != NULL)
1197 if ((*(g->sym_ptr_ptr))->section) {
1198 /* put the section offset into the addend for output */
1199 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1202 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
1207 if (g->section == NULL) {
1209 r_index = N_ABS | N_EXT;
1211 else if(g->section->output_section == obj_textsec(abfd)) {
1212 r_index = N_TEXT | N_EXT;
1213 r_addend += g->section->output_section->vma;
1215 else if (g->section->output_section == obj_datasec(abfd)) {
1216 r_index = N_DATA | N_EXT;
1217 r_addend += g->section->output_section->vma;
1219 else if (g->section->output_section == obj_bsssec(abfd)) {
1220 r_index = N_BSS | N_EXT ;
1221 r_addend += g->section->output_section->vma;
1225 r_index = N_ABS | N_EXT;
1229 /* now the fun stuff */
1230 if (abfd->xvec->header_byteorder_big_p != false) {
1231 natptr->r_index[0] = r_index >> 16;
1232 natptr->r_index[1] = r_index >> 8;
1233 natptr->r_index[2] = r_index;
1235 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1236 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1238 natptr->r_index[2] = r_index >> 16;
1239 natptr->r_index[1] = r_index >> 8;
1240 natptr->r_index[0] = r_index;
1242 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1243 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1246 PUT_WORD (abfd, r_addend, natptr->r_addend);
1249 #define MOVE_ADDRESS(ad) \
1251 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1252 cache_ptr->section = (asection *)NULL; \
1253 cache_ptr->addend = ad; \
1255 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1256 switch (r_index) { \
1258 case N_TEXT | N_EXT: \
1259 cache_ptr->section = obj_textsec(abfd); \
1260 cache_ptr->addend = ad - su->textsec->vma; \
1263 case N_DATA | N_EXT: \
1264 cache_ptr->section = obj_datasec(abfd); \
1265 cache_ptr->addend = ad - su->datasec->vma; \
1268 case N_BSS | N_EXT: \
1269 cache_ptr->section = obj_bsssec(abfd); \
1270 cache_ptr->addend = ad - su->bsssec->vma; \
1273 case N_ABS | N_EXT: \
1274 cache_ptr->section = NULL; /* No section */ \
1275 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1279 cache_ptr->section = NULL; /* No section */ \
1280 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1287 DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
1289 struct reloc_ext_external *bytes AND
1290 arelent *cache_ptr AND
1295 unsigned int r_type;
1296 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1298 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
1300 /* now the fun stuff */
1301 if (abfd->xvec->header_byteorder_big_p != false) {
1302 r_index = (bytes->r_index[0] << 16)
1303 | (bytes->r_index[1] << 8)
1304 | bytes->r_index[2];
1305 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
1306 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
1307 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1309 r_index = (bytes->r_index[2] << 16)
1310 | (bytes->r_index[1] << 8)
1311 | bytes->r_index[0];
1312 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1313 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1314 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1317 cache_ptr->howto = howto_table_ext + r_type;
1318 MOVE_ADDRESS(GET_SWORD(abfd,bytes->r_addend));
1322 DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
1324 struct reloc_std_external *bytes AND
1325 arelent *cache_ptr AND
1330 unsigned int r_length;
1332 int r_baserel, r_jmptable, r_relative;
1333 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1335 cache_ptr->address = (int32_type)(bfd_h_get_32 (abfd, bytes->r_address));
1337 /* now the fun stuff */
1338 if (abfd->xvec->header_byteorder_big_p != false) {
1339 r_index = (bytes->r_index[0] << 16)
1340 | (bytes->r_index[1] << 8)
1341 | bytes->r_index[2];
1342 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
1343 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
1344 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
1345 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1346 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
1347 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
1348 >> RELOC_STD_BITS_LENGTH_SH_BIG;
1350 r_index = (bytes->r_index[2] << 16)
1351 | (bytes->r_index[1] << 8)
1352 | bytes->r_index[0];
1353 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1354 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
1355 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1356 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1357 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1358 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1359 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1362 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1363 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1371 DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
1377 bfd_size_type reloc_size;
1379 arelent *reloc_cache;
1382 if (asect->relocation) return true;
1384 if (asect->flags & SEC_CONSTRUCTOR) return true;
1386 if (asect == obj_datasec (abfd)) {
1387 reloc_size = exec_hdr(abfd)->a_drsize;
1391 if (asect == obj_textsec (abfd)) {
1392 reloc_size = exec_hdr(abfd)->a_trsize;
1396 bfd_error = invalid_operation;
1400 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1401 each_size = obj_reloc_entry_size (abfd);
1403 count = reloc_size / each_size;
1406 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1410 bfd_error = no_memory;
1414 relocs = (PTR) bfd_alloc (abfd, reloc_size);
1416 bfd_release (abfd, reloc_cache);
1420 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1421 bfd_release (abfd, relocs);
1422 bfd_release (abfd, reloc_cache);
1423 bfd_error = system_call_error;
1427 if (each_size == RELOC_EXT_SIZE) {
1428 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
1429 unsigned int counter = 0;
1430 arelent *cache_ptr = reloc_cache;
1432 for (; counter < count; counter++, rptr++, cache_ptr++) {
1433 NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
1436 register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
1437 unsigned int counter = 0;
1438 arelent *cache_ptr = reloc_cache;
1440 for (; counter < count; counter++, rptr++, cache_ptr++) {
1441 NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
1446 bfd_release (abfd,relocs);
1447 asect->relocation = reloc_cache;
1448 asect->reloc_count = count;
1454 /* Write out a relocation section into an object file. */
1457 DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
1462 unsigned char *native, *natptr;
1465 unsigned int count = section->reloc_count;
1468 if (count == 0) return true;
1470 each_size = obj_reloc_entry_size (abfd);
1471 natsize = each_size * count;
1472 native = (unsigned char *) bfd_zalloc (abfd, natsize);
1474 bfd_error = no_memory;
1478 generic = section->orelocation;
1480 if (each_size == RELOC_EXT_SIZE)
1482 for (natptr = native;
1484 --count, natptr += each_size, ++generic)
1485 NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
1489 for (natptr = native;
1491 --count, natptr += each_size, ++generic)
1492 NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
1495 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1496 bfd_release(abfd, native);
1499 bfd_release (abfd, native);
1504 /* This is stupid. This function should be a boolean predicate */
1506 DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
1509 arelent **relptr AND
1512 arelent *tblptr = section->relocation;
1515 if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
1518 if (section->flags & SEC_CONSTRUCTOR) {
1519 arelent_chain *chain = section->constructor_chain;
1520 for (count = 0; count < section->reloc_count; count ++) {
1521 *relptr ++ = &chain->relent;
1522 chain = chain->next;
1526 tblptr = section->relocation;
1527 if (!tblptr) return 0;
1529 for (count = 0; count++ < section->reloc_count;)
1531 *relptr++ = tblptr++;
1536 return section->reloc_count;
1540 DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
1544 if (bfd_get_format (abfd) != bfd_object) {
1545 bfd_error = invalid_operation;
1548 if (asect->flags & SEC_CONSTRUCTOR) {
1549 return (sizeof (arelent *) * (asect->reloc_count+1));
1553 if (asect == obj_datasec (abfd))
1554 return (sizeof (arelent *) *
1555 ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
1558 if (asect == obj_textsec (abfd))
1559 return (sizeof (arelent *) *
1560 ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
1563 bfd_error = invalid_operation;
1569 DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
1572 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1574 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1577 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
1578 bfd *ignore_abfd AND
1579 asymbol *ignore_symbol)
1581 return (alent *)NULL;
1586 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
1587 bfd *ignore_abfd AND
1590 bfd_print_symbol_type how)
1592 FILE *file = (FILE *)afile;
1595 case bfd_print_symbol_name:
1597 fprintf(file,"%s", symbol->name);
1599 case bfd_print_symbol_more:
1600 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1601 (unsigned)(aout_symbol(symbol)->other & 0xff),
1602 (unsigned)(aout_symbol(symbol)->type));
1604 case bfd_print_symbol_all:
1606 CONST char *section_name = symbol->section == (asection *)NULL ?
1607 "*abs" : symbol->section->name;
1609 bfd_print_symbol_vandf((PTR)file,symbol);
1611 fprintf(file," %-5s %04x %02x %02x",
1613 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1614 (unsigned)(aout_symbol(symbol)->other & 0xff),
1615 (unsigned)(aout_symbol(symbol)->type & 0xff));
1617 fprintf(file," %s", symbol->name);
1624 provided a BFD, a section and an offset into the section, calculate
1625 and return the name of the source file and the line nearest to the
1630 DEFUN(NAME(aout,find_nearest_line),(abfd,
1638 asection *section AND
1639 asymbol **symbols AND
1641 CONST char **filename_ptr AND
1642 CONST char **functionname_ptr AND
1643 unsigned int *line_ptr)
1645 /* Run down the file looking for the filename, function and linenumber */
1647 static char buffer[100];
1648 bfd_vma high_line_vma = ~0;
1649 bfd_vma low_func_vma = 0;
1651 *filename_ptr = abfd->filename;
1652 *functionname_ptr = 0;
1654 if (symbols != (asymbol **)NULL) {
1655 for (p = symbols; *p; p++) {
1656 aout_symbol_type *q = (aout_symbol_type *)(*p);
1659 *filename_ptr = q->symbol.name;
1660 if (obj_textsec(abfd) != section) {
1668 /* We'll keep this if it resolves nearer than the one we have already */
1669 if (q->symbol.value >= offset &&
1670 q->symbol.value < high_line_vma) {
1671 *line_ptr = q->desc;
1672 high_line_vma = q->symbol.value;
1677 /* We'll keep this if it is nearer than the one we have already */
1678 if (q->symbol.value >= low_func_vma &&
1679 q->symbol.value <= offset) {
1680 low_func_vma = q->symbol.value;
1681 func = (asymbol *)q;
1683 if (*line_ptr && func) {
1684 CONST char *function = func->name;
1686 strncpy(buffer, function, sizeof(buffer)-1);
1687 buffer[sizeof(buffer)-1] = 0;
1688 /* Have to remove : stuff */
1689 p = strchr(buffer,':');
1690 if (p != NULL) { *p = '\0'; }
1691 *functionname_ptr = buffer;
1706 DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
1710 return adata(abfd)->exec_bytes_size;