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 TDEFINES = -DDEFAULT_VECTOR=host_aout_big_vec
101 TDEPFILES= host-aout.o trad-core.o
103 in the config/t-XXX file, and modify configure.in to use the
104 t-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_make_section(abfd,copy);
704 switch ( (cache_ptr->type & N_TYPE) ) {
706 section->flags = SEC_CONSTRUCTOR;
707 reloc->relent.section = (asection *)NULL;
708 cache_ptr->symbol.section = (asection *)NULL;
711 section->flags = SEC_CONSTRUCTOR_TEXT;
712 reloc->relent.section = (asection *)obj_textsec(abfd);
713 cache_ptr->symbol.value -= reloc->relent.section->vma;
716 section->flags = SEC_CONSTRUCTOR_DATA;
717 reloc->relent.section = (asection *)obj_datasec(abfd);
718 cache_ptr->symbol.value -= reloc->relent.section->vma;
721 section->flags = SEC_CONSTRUCTOR_BSS;
722 reloc->relent.section = (asection *)obj_bsssec(abfd);
723 cache_ptr->symbol.value -= reloc->relent.section->vma;
726 cache_ptr->symbol.section = reloc->relent.section;
727 reloc->relent.addend = cache_ptr->symbol.value ;
729 /* We modify the symbol to belong to a section depending upon the
730 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
731 really care, and add to the size of the section to contain a
732 pointer to the symbol. Build a reloc entry to relocate to this
733 symbol attached to this section. */
736 section->reloc_count++;
737 section->alignment_power = 2;
738 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
739 reloc->next = section->constructor_chain;
740 section->constructor_chain = reloc;
741 reloc->relent.address = section->size;
742 section->size += sizeof(int *);
744 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
745 cache_ptr->symbol.flags |= BSF_DEBUGGING | BSF_CONSTRUCTOR;
749 if (cache_ptr->type == N_WARNING)
751 /* This symbol is the text of a warning message, the next symbol
752 is the symbol to associate the warning with */
753 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
754 cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
755 /* We furgle with the next symbol in place. We don't want it to be undefined, we'll trample the type */
756 (sym_pointer+1)->e_type[0] = 0xff;
759 if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT)) {
760 /* Two symbols in a row for an INDR message. The first symbol
761 contains the name we will match, the second symbol contains the
762 name the first name is translated into. It is supplied to us
763 undefined. This is good, since we want to pull in any files which
765 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
766 cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
771 if (sym_is_debugger_info (cache_ptr)) {
772 cache_ptr->symbol.flags = BSF_DEBUGGING ;
773 /* Work out the section correct for this symbol */
774 switch (cache_ptr->type & N_TYPE)
778 cache_ptr->symbol.section = obj_textsec (abfd);
779 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
782 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
783 cache_ptr->symbol.section = obj_datasec (abfd);
786 cache_ptr->symbol.section = obj_bsssec (abfd);
787 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
791 cache_ptr->symbol.section = 0;
797 if (sym_is_fortrancommon (cache_ptr))
799 cache_ptr->symbol.flags = BSF_FORT_COMM;
800 cache_ptr->symbol.section = (asection *)NULL;
803 if (sym_is_undefined (cache_ptr)) {
804 cache_ptr->symbol.flags = BSF_UNDEFINED;
806 else if (sym_is_global_defn (cache_ptr)) {
807 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
810 else if (sym_is_absolute (cache_ptr)) {
811 cache_ptr->symbol.flags = BSF_ABSOLUTE;
814 cache_ptr->symbol.flags = BSF_LOCAL;
817 /* In a.out, the value of a symbol is always relative to the
818 * start of the file, if this is a data symbol we'll subtract
819 * the size of the text section to get the section relative
820 * value. If this is a bss symbol (which would be strange)
821 * we'll subtract the size of the previous two sections
822 * to find the section relative address.
825 if (sym_in_text_section (cache_ptr)) {
826 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
827 cache_ptr->symbol.section = obj_textsec (abfd);
829 else if (sym_in_data_section (cache_ptr)){
830 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
831 cache_ptr->symbol.section = obj_datasec (abfd);
833 else if (sym_in_bss_section(cache_ptr)) {
834 cache_ptr->symbol.section = obj_bsssec (abfd);
835 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
838 cache_ptr->symbol.section = (asection *)NULL;
839 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
847 DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
848 struct external_nlist *sym_pointer AND
849 asymbol *cache_ptr AND
852 bfd_vma value = cache_ptr->value;
854 if (bfd_get_section(cache_ptr)) {
855 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
856 sym_pointer->e_type[0] |= N_BSS;
858 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
859 sym_pointer->e_type[0] |= N_DATA;
861 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
862 sym_pointer->e_type[0] |= N_TEXT;
865 bfd_error_vector.nonrepresentable_section(abfd,
866 bfd_get_output_section(cache_ptr)->name);
868 /* Turn the symbol from section relative to absolute again */
871 cache_ptr->section->output_section->vma
872 + cache_ptr->section->output_offset ;
875 sym_pointer->e_type[0] |= N_ABS;
877 if (cache_ptr->flags & (BSF_WARNING)) {
878 (sym_pointer+1)->e_type[0] = 1;
880 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
881 sym_pointer->e_type[0] = (N_UNDF | N_EXT);
884 if (cache_ptr->flags & BSF_ABSOLUTE) {
885 sym_pointer->e_type[0] |= N_ABS;
888 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
889 sym_pointer->e_type[0] |= N_EXT;
891 if (cache_ptr->flags & BSF_DEBUGGING) {
892 sym_pointer->e_type [0]= ((aout_symbol_type *)cache_ptr)->type;
895 PUT_WORD(abfd, value, sym_pointer->e_value);
898 /* Native-level interface to symbols. */
900 /* We read the symbols into a buffer, which is discarded when this
901 function exits. We read the strings into a buffer large enough to
902 hold them all plus all the cached symbol entries. */
905 DEFUN(NAME(aout,make_empty_symbol),(abfd),
908 aout_symbol_type *new =
909 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
910 new->symbol.the_bfd = abfd;
916 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
919 bfd_size_type symbol_size;
920 bfd_size_type string_size;
921 unsigned char string_chars[BYTES_IN_WORD];
922 struct external_nlist *syms;
924 aout_symbol_type *cached;
926 /* If there's no work to be done, don't do any */
927 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
928 symbol_size = exec_hdr(abfd)->a_syms;
929 if (symbol_size == 0) {
930 bfd_error = no_symbols;
934 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
935 if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
937 string_size = GET_WORD (abfd, string_chars);
939 strings =(char *) bfd_alloc(abfd, string_size + 1);
940 cached = (aout_symbol_type *)
941 bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
943 /* malloc this, so we can free it if simply. The symbol caching
944 might want to allocate onto the bfd's obstack */
945 syms = (struct external_nlist *) malloc(symbol_size);
946 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
947 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
949 if (syms) free (syms);
950 if (cached) bfd_release (abfd, cached);
951 if (strings)bfd_release (abfd, strings);
955 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
956 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
960 /* OK, now walk the new symtable, cacheing symbol properties */
962 register struct external_nlist *sym_pointer;
963 register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
964 register aout_symbol_type *cache_ptr = cached;
966 /* Run through table and copy values */
967 for (sym_pointer = syms, cache_ptr = cached;
968 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
970 bfd_vma x = GET_WORD(abfd, sym_pointer->e_strx);
971 cache_ptr->symbol.the_bfd = abfd;
973 cache_ptr->symbol.name = x + strings;
975 cache_ptr->symbol.name = (char *)NULL;
977 cache_ptr->symbol.value = GET_SWORD(abfd, sym_pointer->e_value);
978 cache_ptr->desc = bfd_get_16(abfd, sym_pointer->e_desc);
979 cache_ptr->other =bfd_get_8(abfd, sym_pointer->e_other);
980 cache_ptr->type = bfd_get_8(abfd, sym_pointer->e_type);
981 cache_ptr->symbol.udata = 0;
982 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
986 obj_aout_symbols (abfd) = cached;
994 DEFUN(NAME(aout,write_syms),(abfd),
998 asymbol **generic = bfd_get_outsymbols (abfd);
1000 bfd_size_type stindex = BYTES_IN_WORD; /* initial string length */
1002 for (count = 0; count < bfd_get_symcount (abfd); count++) {
1003 asymbol *g = generic[count];
1004 struct external_nlist nsp;
1007 unsigned int length = strlen(g->name) +1;
1008 PUT_WORD (abfd, stindex, (unsigned char *)nsp.e_strx);
1012 PUT_WORD (abfd, 0, (unsigned char *)nsp.e_strx);
1015 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
1017 bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc);
1018 bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other);
1019 bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type);
1023 bfd_h_put_16(abfd,0, nsp.e_desc);
1024 bfd_h_put_8(abfd, 0, nsp.e_other);
1025 bfd_h_put_8(abfd, 0, nsp.e_type);
1028 translate_to_native_sym_flags (&nsp, g, abfd);
1030 bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd);
1033 /* Now output the strings. Be sure to put string length into correct
1034 byte ordering before writing it. */
1036 char buffer[BYTES_IN_WORD];
1037 PUT_WORD (abfd, stindex, (unsigned char *)buffer);
1039 bfd_write((PTR)buffer, 1, BYTES_IN_WORD, abfd);
1041 generic = bfd_get_outsymbols(abfd);
1042 for (count = 0; count < bfd_get_symcount(abfd); count++)
1044 asymbol *g = *(generic++);
1048 size_t length = strlen(g->name)+1;
1049 bfd_write((PTR)g->name, 1, length, abfd);
1051 if ((g->flags & BSF_FAKE)==0) {
1052 g->KEEPIT = (KEEPITTYPE) count;
1060 DEFUN(NAME(aout,get_symtab),(abfd, location),
1064 unsigned int counter = 0;
1065 aout_symbol_type *symbase;
1067 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1069 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1070 *(location++) = (asymbol *)( symbase++);
1072 return bfd_get_symcount(abfd);
1076 /* Standard reloc stuff */
1077 /* Output standard relocation information to a file in target byte order. */
1080 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1083 struct reloc_std_external *natptr)
1087 unsigned int r_length;
1089 int r_baserel, r_jmptable, r_relative;
1090 unsigned int r_addend;
1092 PUT_WORD(abfd, g->address, natptr->r_address);
1094 r_length = g->howto->size ; /* Size as a power of two */
1095 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1096 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1101 r_addend = g->addend; /* Start here, see how it goes */
1103 /* name was clobbered by aout_write_syms to be symbol index */
1105 if (g->sym_ptr_ptr != NULL)
1107 if ((*(g->sym_ptr_ptr))->section) {
1108 /* put the section offset into the addend for output */
1109 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1112 r_index = ((*(g->sym_ptr_ptr))->KEEPIT);
1117 if (g->section == NULL) {
1118 /* It is possible to have a reloc with nothing, we generate an
1121 r_index = N_ABS | N_EXT;
1123 else if(g->section->output_section == obj_textsec(abfd)) {
1124 r_index = N_TEXT | N_EXT;
1125 r_addend += g->section->output_section->vma;
1127 else if (g->section->output_section == obj_datasec(abfd)) {
1128 r_index = N_DATA | N_EXT;
1129 r_addend += g->section->output_section->vma;
1131 else if (g->section->output_section == obj_bsssec(abfd)) {
1132 r_index = N_BSS | N_EXT ;
1133 r_addend += g->section->output_section->vma;
1137 r_index = N_ABS | N_EXT;
1141 /* now the fun stuff */
1142 if (abfd->xvec->header_byteorder_big_p != false) {
1143 natptr->r_index[0] = r_index >> 16;
1144 natptr->r_index[1] = r_index >> 8;
1145 natptr->r_index[2] = r_index;
1147 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1148 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1149 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1150 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1151 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1152 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1154 natptr->r_index[2] = r_index >> 16;
1155 natptr->r_index[1] = r_index >> 8;
1156 natptr->r_index[0] = r_index;
1158 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1159 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1160 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1161 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1162 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1163 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1168 /* Extended stuff */
1169 /* Output extended relocation information to a file in target byte order. */
1172 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1175 register struct reloc_ext_external *natptr)
1179 unsigned int r_type;
1180 unsigned int r_addend;
1182 PUT_WORD (abfd, g->address, natptr->r_address);
1184 /* Find a type in the output format which matches the input howto -
1185 at the moment we assume input format == output format FIXME!! */
1186 r_type = (enum reloc_type) g->howto->type;
1188 r_addend = g->addend; /* Start here, see how it goes */
1190 /* name was clobbered by aout_write_syms to be symbol index*/
1192 if (g->sym_ptr_ptr != NULL)
1194 if ((*(g->sym_ptr_ptr))->section) {
1195 /* put the section offset into the addend for output */
1196 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1199 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
1204 if (g->section == NULL) {
1206 r_index = N_ABS | N_EXT;
1208 else if(g->section->output_section == obj_textsec(abfd)) {
1209 r_index = N_TEXT | N_EXT;
1210 r_addend += g->section->output_section->vma;
1212 else if (g->section->output_section == obj_datasec(abfd)) {
1213 r_index = N_DATA | N_EXT;
1214 r_addend += g->section->output_section->vma;
1216 else if (g->section->output_section == obj_bsssec(abfd)) {
1217 r_index = N_BSS | N_EXT ;
1218 r_addend += g->section->output_section->vma;
1222 r_index = N_ABS | N_EXT;
1226 /* now the fun stuff */
1227 if (abfd->xvec->header_byteorder_big_p != false) {
1228 natptr->r_index[0] = r_index >> 16;
1229 natptr->r_index[1] = r_index >> 8;
1230 natptr->r_index[2] = r_index;
1232 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1233 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1235 natptr->r_index[2] = r_index >> 16;
1236 natptr->r_index[1] = r_index >> 8;
1237 natptr->r_index[0] = r_index;
1239 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1240 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1243 PUT_WORD (abfd, r_addend, natptr->r_addend);
1246 #define MOVE_ADDRESS(ad) \
1248 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1249 cache_ptr->section = (asection *)NULL; \
1250 cache_ptr->addend = ad; \
1252 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1253 switch (r_index) { \
1255 case N_TEXT | N_EXT: \
1256 cache_ptr->section = obj_textsec(abfd); \
1257 cache_ptr->addend = ad - su->textsec->vma; \
1260 case N_DATA | N_EXT: \
1261 cache_ptr->section = obj_datasec(abfd); \
1262 cache_ptr->addend = ad - su->datasec->vma; \
1265 case N_BSS | N_EXT: \
1266 cache_ptr->section = obj_bsssec(abfd); \
1267 cache_ptr->addend = ad - su->bsssec->vma; \
1270 case N_ABS | N_EXT: \
1271 cache_ptr->section = NULL; /* No section */ \
1272 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1276 cache_ptr->section = NULL; /* No section */ \
1277 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1284 DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
1286 struct reloc_ext_external *bytes AND
1287 arelent *cache_ptr AND
1292 unsigned int r_type;
1293 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1295 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
1297 /* now the fun stuff */
1298 if (abfd->xvec->header_byteorder_big_p != false) {
1299 r_index = (bytes->r_index[0] << 16)
1300 | (bytes->r_index[1] << 8)
1301 | bytes->r_index[2];
1302 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
1303 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
1304 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1306 r_index = (bytes->r_index[2] << 16)
1307 | (bytes->r_index[1] << 8)
1308 | bytes->r_index[0];
1309 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1310 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1311 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1314 cache_ptr->howto = howto_table_ext + r_type;
1315 MOVE_ADDRESS(GET_SWORD(abfd,bytes->r_addend));
1319 DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
1321 struct reloc_std_external *bytes AND
1322 arelent *cache_ptr AND
1327 unsigned int r_length;
1329 int r_baserel, r_jmptable, r_relative;
1330 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1332 cache_ptr->address = (int32_type)(bfd_h_get_32 (abfd, bytes->r_address));
1334 /* now the fun stuff */
1335 if (abfd->xvec->header_byteorder_big_p != false) {
1336 r_index = (bytes->r_index[0] << 16)
1337 | (bytes->r_index[1] << 8)
1338 | bytes->r_index[2];
1339 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
1340 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
1341 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
1342 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1343 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
1344 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
1345 >> RELOC_STD_BITS_LENGTH_SH_BIG;
1347 r_index = (bytes->r_index[2] << 16)
1348 | (bytes->r_index[1] << 8)
1349 | bytes->r_index[0];
1350 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1351 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
1352 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1353 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1354 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1355 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1356 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1359 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1360 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1368 DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
1374 bfd_size_type reloc_size;
1376 arelent *reloc_cache;
1379 if (asect->relocation) return true;
1381 if (asect->flags & SEC_CONSTRUCTOR) return true;
1383 if (asect == obj_datasec (abfd)) {
1384 reloc_size = exec_hdr(abfd)->a_drsize;
1388 if (asect == obj_textsec (abfd)) {
1389 reloc_size = exec_hdr(abfd)->a_trsize;
1393 bfd_error = invalid_operation;
1397 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1398 each_size = obj_reloc_entry_size (abfd);
1400 count = reloc_size / each_size;
1403 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1407 bfd_error = no_memory;
1411 relocs = (PTR) bfd_alloc (abfd, reloc_size);
1413 bfd_release (abfd, reloc_cache);
1417 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1418 bfd_release (abfd, relocs);
1419 bfd_release (abfd, reloc_cache);
1420 bfd_error = system_call_error;
1424 if (each_size == RELOC_EXT_SIZE) {
1425 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
1426 unsigned int counter = 0;
1427 arelent *cache_ptr = reloc_cache;
1429 for (; counter < count; counter++, rptr++, cache_ptr++) {
1430 NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
1433 register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
1434 unsigned int counter = 0;
1435 arelent *cache_ptr = reloc_cache;
1437 for (; counter < count; counter++, rptr++, cache_ptr++) {
1438 NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
1443 bfd_release (abfd,relocs);
1444 asect->relocation = reloc_cache;
1445 asect->reloc_count = count;
1451 /* Write out a relocation section into an object file. */
1454 DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
1459 unsigned char *native, *natptr;
1462 unsigned int count = section->reloc_count;
1465 if (count == 0) return true;
1467 each_size = obj_reloc_entry_size (abfd);
1468 natsize = each_size * count;
1469 native = (unsigned char *) bfd_zalloc (abfd, natsize);
1471 bfd_error = no_memory;
1475 generic = section->orelocation;
1477 if (each_size == RELOC_EXT_SIZE)
1479 for (natptr = native;
1481 --count, natptr += each_size, ++generic)
1482 NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
1486 for (natptr = native;
1488 --count, natptr += each_size, ++generic)
1489 NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
1492 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1493 bfd_release(abfd, native);
1496 bfd_release (abfd, native);
1501 /* This is stupid. This function should be a boolean predicate */
1503 DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
1506 arelent **relptr AND
1509 arelent *tblptr = section->relocation;
1512 if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
1515 if (section->flags & SEC_CONSTRUCTOR) {
1516 arelent_chain *chain = section->constructor_chain;
1517 for (count = 0; count < section->reloc_count; count ++) {
1518 *relptr ++ = &chain->relent;
1519 chain = chain->next;
1523 tblptr = section->relocation;
1524 if (!tblptr) return 0;
1526 for (count = 0; count++ < section->reloc_count;)
1528 *relptr++ = tblptr++;
1533 return section->reloc_count;
1537 DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
1541 if (bfd_get_format (abfd) != bfd_object) {
1542 bfd_error = invalid_operation;
1545 if (asect->flags & SEC_CONSTRUCTOR) {
1546 return (sizeof (arelent *) * (asect->reloc_count+1));
1550 if (asect == obj_datasec (abfd))
1551 return (sizeof (arelent *) *
1552 ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
1555 if (asect == obj_textsec (abfd))
1556 return (sizeof (arelent *) *
1557 ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
1560 bfd_error = invalid_operation;
1566 DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
1569 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1571 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1574 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
1575 bfd *ignore_abfd AND
1576 asymbol *ignore_symbol)
1578 return (alent *)NULL;
1583 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
1584 bfd *ignore_abfd AND
1587 bfd_print_symbol_type how)
1589 FILE *file = (FILE *)afile;
1592 case bfd_print_symbol_name:
1594 fprintf(file,"%s", symbol->name);
1596 case bfd_print_symbol_more:
1597 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1598 (unsigned)(aout_symbol(symbol)->other & 0xff),
1599 (unsigned)(aout_symbol(symbol)->type));
1601 case bfd_print_symbol_all:
1603 CONST char *section_name = symbol->section == (asection *)NULL ?
1604 "*abs" : symbol->section->name;
1606 bfd_print_symbol_vandf((PTR)file,symbol);
1608 fprintf(file," %-5s %04x %02x %02x",
1610 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1611 (unsigned)(aout_symbol(symbol)->other & 0xff),
1612 (unsigned)(aout_symbol(symbol)->type & 0xff));
1614 fprintf(file," %s", symbol->name);
1621 provided a BFD, a section and an offset into the section, calculate
1622 and return the name of the source file and the line nearest to the
1627 DEFUN(NAME(aout,find_nearest_line),(abfd,
1635 asection *section AND
1636 asymbol **symbols AND
1638 CONST char **filename_ptr AND
1639 CONST char **functionname_ptr AND
1640 unsigned int *line_ptr)
1642 /* Run down the file looking for the filename, function and linenumber */
1644 static char buffer[100];
1645 bfd_vma high_line_vma = ~0;
1646 bfd_vma low_func_vma = 0;
1648 *filename_ptr = abfd->filename;
1649 *functionname_ptr = 0;
1651 if (symbols != (asymbol **)NULL) {
1652 for (p = symbols; *p; p++) {
1653 aout_symbol_type *q = (aout_symbol_type *)(*p);
1656 *filename_ptr = q->symbol.name;
1657 if (obj_textsec(abfd) != section) {
1665 /* We'll keep this if it resolves nearer than the one we have already */
1666 if (q->symbol.value >= offset &&
1667 q->symbol.value < high_line_vma) {
1668 *line_ptr = q->desc;
1669 high_line_vma = q->symbol.value;
1674 /* We'll keep this if it is nearer than the one we have already */
1675 if (q->symbol.value >= low_func_vma &&
1676 q->symbol.value <= offset) {
1677 low_func_vma = q->symbol.value;
1678 func = (asymbol *)q;
1680 if (*line_ptr && func) {
1681 CONST char *function = func->name;
1683 strncpy(buffer, function, sizeof(buffer)-1);
1684 buffer[sizeof(buffer)-1] = 0;
1685 /* Have to remove : stuff */
1686 p = strchr(buffer,':');
1687 if (p != NULL) { *p = '\0'; }
1688 *functionname_ptr = buffer;
1703 DEFUN(NAME(aout,sizeof_headers),(ignore_abfd, execable),
1704 bfd *ignore_abfd AND
1707 return EXEC_BYTES_SIZE;