2 /* BFD semi-generic back-end for a.out binaries */
4 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
6 This file is part of BFD, the Binary File Diddler.
8 BFD is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
13 BFD is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with BFD; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 @section a.out backends
26 BFD supports a number of different flavours of a.out format, though
27 the major differences are only the sizes of the structures on disk,
28 and the shape of the relocation information.
30 The support is split into a basic support file @code{aoutx.h} and
31 other files which derive functions from the base. One derivation file
32 is @code{aoutf1.h} (for a.out flavour 1), and adds to the basic a.out
33 functions support for sun3, sun4, 386 and 29k a.out files, to create a
34 target jump vector for a specific target.
36 This information is further split out into more specific files for each
37 machine, including @code{sunos.c} - for sun3 and sun4 and
38 @code{demo64} for a demonstration of a 64 bit a.out format.
40 The base file @code{aoutx.h} defines general mechanisms for reading
41 and writing records to and from disk, and various other methods which
42 bfd requires. It is included by @code{aout32.c} and @code{aout64.c} to
43 form the names aout_32_swap_exec_header_in,
44 aout_64_swap_exec_header_in, etc.
46 As an example, this is what goes on to make the back end for a sun4, from aout32.c
56 aout_32_canonicalize_reloc
57 aout_32_find_nearest_line
59 aout_32_get_reloc_upper_bound
67 #define TARGET_NAME "a.out-sunos-big"
68 #define VECNAME sunos_big_vec
71 requires all the names from aout32.c, and produces the jump vector
91 void (*bfd_error_trap)();
94 @subsection relocations
95 The file @code{aoutx.h} caters for both the @emph{standard} and
96 @emph{extended} forms of a.out relocation records.
98 The standard records are characterised by containing only an address,
99 a symbol index and a type field. The extended records (used on 29ks
100 and sparcs) also have a full integer for an addend.
102 #define CTOR_TABLE_RELOC_IDX 2
103 static reloc_howto_type howto_table_ext[] =
105 HOWTO(RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false),
106 HOWTO(RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false),
107 HOWTO(RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff, false),
108 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, false, true,0,"DISP8", false, 0,0x000000ff, false),
109 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, false, true,0,"DISP16", false, 0,0x0000ffff, false),
110 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, false, true,0,"DISP32", false, 0,0xffffffff, false),
111 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, false, true,0,"WDISP30", false, 0,0x3fffffff, false),
112 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, false, true,0,"WDISP22", false, 0,0x003fffff, false),
113 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, false, true,0,"HI22", false, 0,0x003fffff, false),
114 HOWTO(RELOC_22, 0, 2, 22, false, 0, false, true,0,"22", false, 0,0x003fffff, false),
115 HOWTO(RELOC_13, 0, 2, 13, false, 0, false, true,0,"13", false, 0,0x00001fff, false),
116 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, false, true,0,"LO10", false, 0,0x000003ff, false),
117 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
118 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
119 HOWTO(RELOC_BASE10, 0, 2, 16, false, 0, false, true,0,"BASE10", false, 0,0x0000ffff, false),
120 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, false, true,0,"BASE13", false, 0,0x00001fff, false),
121 HOWTO(RELOC_BASE22, 0, 2, 0, false, 0, false, true,0,"BASE22", false, 0,0x00000000, false),
122 HOWTO(RELOC_PC10, 0, 2, 10, false, 0, false, true,0,"PC10", false, 0,0x000003ff, false),
123 HOWTO(RELOC_PC22, 0, 2, 22, false, 0, false, true,0,"PC22", false, 0,0x003fffff, false),
124 HOWTO(RELOC_JMP_TBL,0, 2, 32, false, 0, false, true,0,"JMP_TBL", false, 0,0xffffffff, false),
125 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
126 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
127 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
128 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, false, true,0,"RELATIVE", false, 0,0x00000000, false),
129 HOWTO(RELOC_JUMPTARG,2, 13, 16, true, 0, false, true,0,"JUMPTARG", false, 0,0x0000ffff, false),
130 HOWTO(RELOC_CONST, 0, 13, 16, false, 0, false, true,0,"CONST", false, 0,0x0000ffff, false),
131 HOWTO(RELOC_CONSTH, 16, 13, 16, false, 0, false, true,0,"CONSTH", false, 0,0x0000ffff, false),
134 /* Convert standard reloc records to "arelent" format (incl byte swap). */
136 static reloc_howto_type howto_table_std[] = {
137 /* type rs size bsz pcrel bitpos abs ovrf sf name part_inpl readmask setmask pcdone */
138 HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),
139 HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),
140 HOWTO( 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff, false),
141 HOWTO( 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead, false),
142 HOWTO( 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff, false),
143 HOWTO( 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
144 HOWTO( 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff, false),
145 HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface, false),
149 bfd_error_vector_type bfd_error_vector;
152 @subsection Internal Entry Points
153 @code{aoutx.h} exports several routines for accessing the contents of
154 an a.out file, which are gathered and exported in turn by various
155 format specific files (eg sunos.c).
159 *i aout_<size>_swap_exec_header_in
160 Swaps the information in an executable header taken from a raw byte stream memory image,
161 into the internal exec_header structure.
162 *; PROTO(void, aout_<size>_swap_exec_header_in,
164 struct external_exec *raw_bytes,
165 struct internal_exec *execp));
169 DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
171 struct external_exec *raw_bytes AND
172 struct internal_exec *execp)
174 struct external_exec *bytes = (struct external_exec *)raw_bytes;
176 /* Now fill in fields in the execp, from the bytes in the raw data. */
177 execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
178 execp->a_text = GET_WORD (abfd, bytes->e_text);
179 execp->a_data = GET_WORD (abfd, bytes->e_data);
180 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
181 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
182 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
183 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
184 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
188 *i aout_<size>_swap_exec_header_out
189 Swaps the information in an internal exec header structure into the
190 supplied buffer ready for writing to disk.
191 *; PROTO(void, aout_<size>_swap_exec_header_out,
193 struct internal_exec *execp,
194 struct external_exec *raw_bytes));
197 DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
199 struct internal_exec *execp AND
200 struct external_exec *raw_bytes)
202 struct external_exec *bytes = (struct external_exec *)raw_bytes;
204 /* Now fill in fields in the raw data, from the fields in the exec struct. */
205 bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
206 PUT_WORD (abfd, execp->a_text , bytes->e_text);
207 PUT_WORD (abfd, execp->a_data , bytes->e_data);
208 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
209 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
210 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
211 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
212 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
217 struct internal_exec e;
222 *i aout_<size>_some_aout_object_p
224 Some A.OUT variant thinks that the file whose format we're checking
225 is an a.out file. Do some more checking, and set up for access if
226 it really is. Call back to the calling environments "finish up"
227 function just before returning, to handle any last-minute setup.
229 *; PROTO(bfd_target *, aout_<size>_some_aout_object_p,
231 bfd_target *(*callback_to_real_object_p)()));
235 DEFUN(NAME(aout,some_aout_object_p),(abfd, callback_to_real_object_p),
237 bfd_target *(*callback_to_real_object_p) ())
239 struct external_exec exec_bytes;
240 struct internal_exec *execp;
241 struct container *rawptr;
243 if (bfd_seek (abfd, 0L, false) < 0) {
244 bfd_error = system_call_error;
248 if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
249 != EXEC_BYTES_SIZE) {
250 bfd_error = wrong_format;
254 /* Use an intermediate variable for clarity */
255 rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
257 if (rawptr == NULL) {
258 bfd_error = no_memory;
262 set_tdata (abfd, rawptr);
263 exec_hdr (abfd) = execp = &(rawptr->e);
264 NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, execp);
266 /* Set the file flags */
267 abfd->flags = NO_FLAGS;
268 if (execp->a_drsize || execp->a_trsize)
269 abfd->flags |= HAS_RELOC;
271 abfd->flags |= EXEC_P;
273 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
275 if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
276 if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
278 bfd_get_start_address (abfd) = execp->a_entry;
280 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
281 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
283 /* Set the default architecture and machine type. These can be
284 overridden in the callback routine. */
285 abfd->obj_arch = bfd_arch_unknown;
286 abfd->obj_machine = 0;
288 /* The default relocation entry size is that of traditional V7 Unix. */
289 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
291 /* create the sections. This is raunchy, but bfd_close wants to reclaim
293 obj_textsec (abfd) = (asection *)NULL;
294 obj_datasec (abfd) = (asection *)NULL;
295 obj_bsssec (abfd) = (asection *)NULL;
296 (void)bfd_make_section(abfd, ".text");
297 (void)bfd_make_section(abfd, ".data");
298 (void)bfd_make_section(abfd, ".bss");
300 abfd->sections = obj_textsec (abfd);
301 obj_textsec (abfd)->next = obj_datasec (abfd);
302 obj_datasec (abfd)->next = obj_bsssec (abfd);
304 obj_datasec (abfd)->size = execp->a_data;
305 obj_bsssec (abfd)->size = execp->a_bss;
306 obj_textsec (abfd)->size = execp->a_text;
308 if (abfd->flags & D_PAGED) {
309 obj_textsec (abfd)->size -= EXEC_BYTES_SIZE;
313 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
314 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
315 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
316 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
317 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
318 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
319 obj_bsssec (abfd)->flags = SEC_ALLOC;
321 #ifdef THIS_IS_ONLY_DOCUMENTATION
322 /* Call back to the format-dependent code to fill in the rest of the
323 fields and do any further cleanup. Things that should be filled
324 in by the callback: */
326 struct exec *execp = exec_hdr (abfd);
328 /* The virtual memory addresses of the sections */
329 obj_datasec (abfd)->vma = N_DATADDR(*execp);
330 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
331 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
333 /* The file offsets of the sections */
334 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
335 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
337 /* The file offsets of the relocation info */
338 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
339 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
341 /* The file offsets of the string table and symbol table. */
342 obj_str_filepos (abfd) = N_STROFF (*execp);
343 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
345 /* This common code can't fill in those things because they depend
346 on either the start address of the text segment, the rounding
347 up of virtual addersses between segments, or the starting file
348 position of the text segment -- all of which varies among different
349 versions of a.out. */
351 /* Determine the architecture and machine type of the object file. */
352 switch (N_MACHTYPE (*exec_hdr (abfd))) {
354 abfd->obj_arch = bfd_arch_obscure;
358 /* Determine the size of a relocation entry */
359 switch (abfd->obj_arch) {
362 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
364 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
369 /* The architecture is encoded in various ways in various a.out variants,
370 or is not encoded at all in some of them. The relocation size depends
371 on the architecture and the a.out variant. Finally, the return value
372 is the bfd_target vector in use. If an error occurs, return zero and
373 set bfd_error to the appropriate error code.
375 Formats such as b.out, which have additional fields in the a.out
376 header, should cope with them in this callback as well. */
377 #endif /* DOCUMENTATION */
380 return (*callback_to_real_object_p)(abfd);
384 *i aout_<size>_mkobject
386 This routine initializes a bfd for use with a.out files.
388 *; PROTO(boolean, aout_<size>_mkobject, (bfd *));
392 DEFUN(NAME(aout,mkobject),(abfd),
395 struct container *rawptr;
397 bfd_error = system_call_error;
399 /* Use an intermediate variable for clarity */
400 rawptr = (struct container *)bfd_zalloc (abfd, sizeof (struct container));
402 if (rawptr == NULL) {
403 bfd_error = no_memory;
407 set_tdata (abfd, rawptr);
408 exec_hdr (abfd) = &(rawptr->e);
410 /* For simplicity's sake we just make all the sections right here. */
412 obj_textsec (abfd) = (asection *)NULL;
413 obj_datasec (abfd) = (asection *)NULL;
414 obj_bsssec (abfd) = (asection *)NULL;
415 bfd_make_section (abfd, ".text");
416 bfd_make_section (abfd, ".data");
417 bfd_make_section (abfd, ".bss");
424 *i aout_<size>_machine_type
426 Keep track of machine architecture and machine type for a.out's.
427 Return the machine_type for a particular arch&machine, or M_UNKNOWN
428 if that exact arch&machine can't be represented in a.out format.
430 If the architecture is understood, machine type 0 (default) should
431 always be understood.
433 *; PROTO(enum machine_type, aout_<size>_machine_type,
434 (enum bfd_architecture arch,
435 unsigned long machine));
439 DEFUN(NAME(aout,machine_type),(arch, machine),
440 enum bfd_architecture arch AND
441 unsigned long machine)
443 enum machine_type arch_flags;
445 arch_flags = M_UNKNOWN;
449 if (machine == 0) arch_flags = M_SPARC;
454 case 0: arch_flags = M_68010; break;
455 case 68000: arch_flags = M_UNKNOWN; break;
456 case 68010: arch_flags = M_68010; break;
457 case 68020: arch_flags = M_68020; break;
458 default: arch_flags = M_UNKNOWN; break;
463 if (machine == 0) arch_flags = M_386;
467 if (machine == 0) arch_flags = M_29K;
471 arch_flags = M_UNKNOWN;
478 *i aout_<size>_set_arch_mach
480 Sets the architecture and the machine of the bfd to those values
481 supplied. Verifies that the format can support the architecture
484 *; PROTO(boolean, aout_<size>_set_arch_mach,
486 enum bfd_architecture,
487 unsigned long machine));
491 DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
493 enum bfd_architecture arch AND
494 unsigned long machine)
496 abfd->obj_arch = arch;
497 abfd->obj_machine = machine;
498 if (arch != bfd_arch_unknown &&
499 NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
500 return false; /* We can't represent this type */
501 return true; /* We're easy ... */
505 *i aout_<size>new_section_hook
507 Called by the bfd in response to a @code{bfd_make_section} request.
508 *; PROTO(boolean, aout_<size>_new_section_hook,
513 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
517 /* align to double at least */
518 newsect->alignment_power = 3;
520 if (bfd_get_format (abfd) == bfd_object) {
521 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
522 obj_textsec(abfd)= newsect;
526 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
527 obj_datasec(abfd) = newsect;
531 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
532 obj_bsssec(abfd) = newsect;
537 /* We allow more than three sections internally */
542 DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
549 if (abfd->output_has_begun == false)
550 { /* set by bfd.c handler */
551 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
553 bfd_error = invalid_operation;
556 /* if (abfd->flags & D_PAGED) {
557 obj_textsec(abfd)->filepos = 0;
560 obj_textsec(abfd)->filepos = EXEC_BYTES_SIZE;
562 obj_textsec(abfd)->size = align_power(obj_textsec(abfd)->size,
563 obj_textsec(abfd)->alignment_power);
564 obj_datasec(abfd)->filepos = obj_textsec (abfd)->size + EXEC_BYTES_SIZE;
565 obj_datasec(abfd)->size = align_power(obj_datasec(abfd)->size,
566 obj_datasec(abfd)->alignment_power);
570 /* regardless, once we know what we're doing, we might as well get going */
571 if (section != obj_bsssec(abfd))
573 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
576 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
584 /* Classify stabs symbols */
586 #define sym_in_text_section(sym) \
587 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
589 #define sym_in_data_section(sym) \
590 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
592 #define sym_in_bss_section(sym) \
593 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
595 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
596 zero in the "value" field. Nonzeroes there are fortrancommon
598 #define sym_is_undefined(sym) \
599 ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
601 /* Symbol is a global definition if N_EXT is on and if it has
602 a nonzero type field. */
603 #define sym_is_global_defn(sym) \
604 (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
606 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
608 #define sym_is_debugger_info(sym) \
609 ((sym)->type & ~(N_EXT | N_TYPE))
611 #define sym_is_fortrancommon(sym) \
612 (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
614 /* Symbol is absolute if it has N_ABS set */
615 #define sym_is_absolute(sym) \
616 (((sym)->type & N_TYPE)== N_ABS)
619 #define sym_is_indirect(sym) \
620 (((sym)->type & N_ABS)== N_ABS)
622 /* Only in their own functions for ease of debugging; when sym flags have
623 stabilised these should be inlined into their (single) caller */
626 DEFUN(translate_from_native_sym_flags,(sym_pointer, cache_ptr, abfd),
627 struct external_nlist *sym_pointer AND
628 aout_symbol_type *cache_ptr AND
631 switch (cache_ptr->type & N_TYPE) {
637 asection *section = bfd_make_section(abfd,
638 cache_ptr->symbol.name);
639 arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
641 switch ( (cache_ptr->type & N_TYPE) ) {
643 reloc->relent.section = (asection *)NULL;
644 cache_ptr->symbol.section = (asection *)NULL;
647 reloc->relent.section = (asection *)obj_textsec(abfd);
648 cache_ptr->symbol.value -= reloc->relent.section->vma;
651 reloc->relent.section = (asection *)obj_datasec(abfd);
652 cache_ptr->symbol.value -= reloc->relent.section->vma;
655 reloc->relent.section = (asection *)obj_bsssec(abfd);
656 cache_ptr->symbol.value -= reloc->relent.section->vma;
659 cache_ptr->symbol.section = reloc->relent.section;
660 reloc->relent.addend = cache_ptr->symbol.value ;
662 /* We modify the symbol to belong to a section depending upon the
663 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
664 really care, and add to the size of the section to contain a
665 pointer to the symbol. Build a reloc entry to relocate to this
666 symbol attached to this section. */
668 section->flags = SEC_CONSTRUCTOR;
669 section->reloc_count++;
670 section->alignment_power = 2;
671 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
672 reloc->next = section->constructor_chain;
673 section->constructor_chain = reloc;
674 reloc->relent.address = section->size;
675 section->size += sizeof(int *);
677 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
678 cache_ptr->symbol.flags |= BSF_DEBUGGING ;
683 if (sym_is_debugger_info (cache_ptr)) {
684 cache_ptr->symbol.flags = BSF_DEBUGGING ;
685 /* Work out the section correct for this symbol */
686 switch (cache_ptr->type & N_TYPE)
690 cache_ptr->symbol.section = obj_textsec (abfd);
691 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
694 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
695 cache_ptr->symbol.section = obj_datasec (abfd);
698 cache_ptr->symbol.section = obj_bsssec (abfd);
699 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
703 cache_ptr->symbol.section = 0;
708 if (sym_is_fortrancommon (cache_ptr))
710 cache_ptr->symbol.flags = BSF_FORT_COMM;
711 cache_ptr->symbol.section = (asection *)NULL;
714 if (sym_is_undefined (cache_ptr)) {
715 cache_ptr->symbol.flags = BSF_UNDEFINED;
717 else if (sym_is_global_defn (cache_ptr)) {
718 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
721 else if (sym_is_absolute (cache_ptr)) {
722 cache_ptr->symbol.flags = BSF_ABSOLUTE;
725 cache_ptr->symbol.flags = BSF_LOCAL;
728 /* In a.out, the value of a symbol is always relative to the
729 * start of the file, if this is a data symbol we'll subtract
730 * the size of the text section to get the section relative
731 * value. If this is a bss symbol (which would be strange)
732 * we'll subtract the size of the previous two sections
733 * to find the section relative address.
736 if (sym_in_text_section (cache_ptr)) {
737 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
738 cache_ptr->symbol.section = obj_textsec (abfd);
740 else if (sym_in_data_section (cache_ptr)){
741 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
742 cache_ptr->symbol.section = obj_datasec (abfd);
744 else if (sym_in_bss_section(cache_ptr)) {
745 cache_ptr->symbol.section = obj_bsssec (abfd);
746 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
749 cache_ptr->symbol.section = (asection *)NULL;
750 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
758 DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
759 struct external_nlist *sym_pointer AND
760 asymbol *cache_ptr AND
763 bfd_vma value = cache_ptr->value;
765 if (bfd_get_section(cache_ptr)) {
766 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
767 sym_pointer->e_type[0] |= N_BSS;
769 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
770 sym_pointer->e_type[0] |= N_DATA;
772 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
773 sym_pointer->e_type[0] |= N_TEXT;
776 bfd_error_vector.nonrepresentable_section(abfd,
777 bfd_get_output_section(cache_ptr)->name);
779 /* Turn the symbol from section relative to absolute again */
782 cache_ptr->section->output_section->vma
783 + cache_ptr->section->output_offset ;
786 sym_pointer->e_type[0] |= N_ABS;
789 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
790 sym_pointer->e_type[0] = (N_UNDF | N_EXT);
793 if (cache_ptr->flags & BSF_ABSOLUTE) {
794 sym_pointer->e_type[0] |= N_ABS;
797 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
798 sym_pointer->e_type[0] |= N_EXT;
800 if (cache_ptr->flags & BSF_DEBUGGING) {
801 sym_pointer->e_type [0]= ((aout_symbol_type *)cache_ptr)->type;
804 PUT_WORD(abfd, value, sym_pointer->e_value);
807 /* Native-level interface to symbols. */
809 /* We read the symbols into a buffer, which is discarded when this
810 function exits. We read the strings into a buffer large enough to
811 hold them all plus all the cached symbol entries. */
814 DEFUN(NAME(aout,make_empty_symbol),(abfd),
817 aout_symbol_type *new =
818 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
819 new->symbol.the_bfd = abfd;
825 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
828 bfd_size_type symbol_size;
829 bfd_size_type string_size;
830 unsigned char string_chars[BYTES_IN_WORD];
831 struct external_nlist *syms;
833 aout_symbol_type *cached;
835 /* If there's no work to be done, don't do any */
836 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
837 symbol_size = exec_hdr(abfd)->a_syms;
838 if (symbol_size == 0) {
839 bfd_error = no_symbols;
843 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
844 if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
846 string_size = GET_WORD (abfd, string_chars);
848 strings =(char *) bfd_alloc(abfd, string_size + 1);
849 cached = (aout_symbol_type *)
850 bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
851 /* Alloc this last, so we can free it if obstack is in use. */
852 syms = (struct external_nlist *) bfd_alloc(abfd, symbol_size);
854 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
855 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
857 if (syms) bfd_release (abfd, syms);
858 if (cached) bfd_release (abfd, cached);
859 if (strings)bfd_release (abfd, strings);
863 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
864 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
868 /* OK, now walk the new symtable, cacheing symbol properties */
870 register struct external_nlist *sym_pointer;
871 register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
872 register aout_symbol_type *cache_ptr = cached;
874 /* Run through table and copy values */
875 for (sym_pointer = syms, cache_ptr = cached;
876 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
878 bfd_vma x = GET_WORD(abfd, sym_pointer->e_strx);
879 cache_ptr->symbol.the_bfd = abfd;
881 cache_ptr->symbol.name = x + strings;
883 cache_ptr->symbol.name = (char *)NULL;
885 cache_ptr->symbol.value = GET_SWORD(abfd, sym_pointer->e_value);
886 cache_ptr->desc = bfd_get_16(abfd, sym_pointer->e_desc);
887 cache_ptr->other =bfd_get_8(abfd, sym_pointer->e_other);
888 cache_ptr->type = bfd_get_8(abfd, sym_pointer->e_type);
889 cache_ptr->symbol.udata = 0;
890 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
894 obj_aout_symbols (abfd) = cached;
895 bfd_release (abfd, (PTR)syms);
902 DEFUN(NAME(aout,write_syms),(abfd),
906 asymbol **generic = bfd_get_outsymbols (abfd);
908 bfd_size_type stindex = BYTES_IN_WORD; /* initial string length */
910 for (count = 0; count < bfd_get_symcount (abfd); count++) {
911 asymbol *g = generic[count];
912 struct external_nlist nsp;
916 unsigned int length = strlen(g->name) +1;
917 PUT_WORD (abfd, stindex, (unsigned char *)nsp.e_strx);
921 PUT_WORD (abfd, 0, (unsigned char *)nsp.e_strx);
924 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
926 bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc);
927 bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other);
928 bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type);
932 bfd_h_put_16(abfd,0, nsp.e_desc);
933 bfd_h_put_8(abfd, 0, nsp.e_other);
934 bfd_h_put_8(abfd, 0, nsp.e_type);
939 translate_to_native_sym_flags (&nsp, (PTR)g, abfd);
941 bfd_write((PTR)&nsp,1,EXTERNAL_LIST_SIZE, abfd);
945 /* Now output the strings. Be sure to put string length into correct
946 * byte ordering before writing it.
949 char buffer[BYTES_IN_WORD];
950 PUT_WORD (abfd, stindex, (unsigned char *)buffer);
952 bfd_write((PTR)buffer, 1, BYTES_IN_WORD, abfd);
954 generic = bfd_get_outsymbols(abfd);
955 for (count = 0; count < bfd_get_symcount(abfd); count++)
957 asymbol *g = *(generic++);
961 size_t length = strlen(g->name)+1;
962 bfd_write((PTR)g->name, 1, length, abfd);
964 if ((g->flags & BSF_FAKE)==0) {
965 g->name = itos(count); /* smash the generic symbol */
973 DEFUN(NAME(aout,get_symtab),(abfd, location),
977 unsigned int counter = 0;
978 aout_symbol_type *symbase;
980 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
982 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
983 *(location++) = (asymbol *)( symbase++);
985 return bfd_get_symcount(abfd);
989 /* Standard reloc stuff */
990 /* Output standard relocation information to a file in target byte order. */
993 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
996 struct reloc_std_external *natptr)
1000 unsigned int r_length;
1002 int r_baserel, r_jmptable, r_relative;
1003 unsigned int r_addend;
1005 PUT_WORD(abfd, g->address, natptr->r_address);
1007 r_length = g->howto->size ; /* Size as a power of two */
1008 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1009 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1014 r_addend = g->addend; /* Start here, see how it goes */
1016 /* name was clobbered by aout_write_syms to be symbol index */
1018 if (g->sym_ptr_ptr != NULL)
1020 if ((*(g->sym_ptr_ptr))->section) {
1021 /* put the section offset into the addend for output */
1022 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1025 r_index = stoi((*(g->sym_ptr_ptr))->name);
1030 if (g->section == NULL) {
1031 /* It is possible to have a reloc with nothing, we generate an
1034 r_index = N_ABS | N_EXT;
1036 else if(g->section->output_section == obj_textsec(abfd)) {
1037 r_index = N_TEXT | N_EXT;
1038 r_addend += g->section->output_section->vma;
1040 else if (g->section->output_section == obj_datasec(abfd)) {
1041 r_index = N_DATA | N_EXT;
1042 r_addend += g->section->output_section->vma;
1044 else if (g->section->output_section == obj_bsssec(abfd)) {
1045 r_index = N_BSS | N_EXT ;
1046 r_addend += g->section->output_section->vma;
1053 /* now the fun stuff */
1054 if (abfd->xvec->header_byteorder_big_p != false) {
1055 natptr->r_index[0] = r_index >> 16;
1056 natptr->r_index[1] = r_index >> 8;
1057 natptr->r_index[2] = r_index;
1059 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1060 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1061 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1062 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1063 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1064 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1066 natptr->r_index[2] = r_index >> 16;
1067 natptr->r_index[1] = r_index >> 8;
1068 natptr->r_index[0] = r_index;
1070 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1071 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1072 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1073 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1074 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1075 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1080 /* Extended stuff */
1081 /* Output extended relocation information to a file in target byte order. */
1084 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1087 register struct reloc_ext_external *natptr)
1091 unsigned int r_type;
1092 unsigned int r_addend;
1094 PUT_WORD (abfd, g->address, natptr->r_address);
1096 /* Find a type in the output format which matches the input howto -
1097 at the moment we assume input format == output format FIXME!! */
1098 r_type = (enum reloc_type) g->howto->type;
1100 r_addend = g->addend; /* Start here, see how it goes */
1102 /* name was clobbered by aout_write_syms to be symbol index*/
1104 if (g->sym_ptr_ptr != NULL)
1106 if ((*(g->sym_ptr_ptr))->section) {
1107 /* put the section offset into the addend for output */
1108 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1111 r_index = stoi((*(g->sym_ptr_ptr))->name);
1116 if (g->section == NULL) {
1118 r_index = N_ABS | N_EXT;
1120 else if(g->section->output_section == obj_textsec(abfd)) {
1121 r_index = N_TEXT | N_EXT;
1122 r_addend += g->section->output_section->vma;
1124 else if (g->section->output_section == obj_datasec(abfd)) {
1125 r_index = N_DATA | N_EXT;
1126 r_addend += g->section->output_section->vma;
1128 else if (g->section->output_section == obj_bsssec(abfd)) {
1129 r_index = N_BSS | N_EXT ;
1130 r_addend += g->section->output_section->vma;
1137 /* now the fun stuff */
1138 if (abfd->xvec->header_byteorder_big_p != false) {
1139 natptr->r_index[0] = r_index >> 16;
1140 natptr->r_index[1] = r_index >> 8;
1141 natptr->r_index[2] = r_index;
1143 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1144 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1146 natptr->r_index[2] = r_index >> 16;
1147 natptr->r_index[1] = r_index >> 8;
1148 natptr->r_index[0] = r_index;
1150 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1151 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1154 PUT_WORD (abfd, r_addend, natptr->r_addend);
1157 #define MOVE_ADDRESS(ad) \
1159 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1160 cache_ptr->section = (asection *)NULL; \
1161 cache_ptr->addend = ad; \
1163 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1164 switch (r_index) { \
1166 case N_TEXT | N_EXT: \
1167 cache_ptr->section = obj_textsec(abfd); \
1168 cache_ptr->addend = ad - su->textsec->vma; \
1171 case N_DATA | N_EXT: \
1172 cache_ptr->section = obj_datasec(abfd); \
1173 cache_ptr->addend = ad - su->datasec->vma; \
1176 case N_BSS | N_EXT: \
1177 cache_ptr->section = obj_bsssec(abfd); \
1178 cache_ptr->addend = ad - su->bsssec->vma; \
1181 case N_ABS | N_EXT: \
1182 cache_ptr->section = NULL; /* No section */ \
1183 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1187 cache_ptr->section = NULL; /* No section */ \
1188 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1195 DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
1197 struct reloc_ext_external *bytes AND
1198 arelent *cache_ptr AND
1203 unsigned int r_type;
1204 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1206 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
1208 /* now the fun stuff */
1209 if (abfd->xvec->header_byteorder_big_p != false) {
1210 r_index = (bytes->r_index[0] << 16)
1211 | (bytes->r_index[1] << 8)
1212 | bytes->r_index[2];
1213 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
1214 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
1215 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1217 r_index = (bytes->r_index[2] << 16)
1218 | (bytes->r_index[1] << 8)
1219 | bytes->r_index[0];
1220 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1221 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1222 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1225 cache_ptr->howto = howto_table_ext + r_type;
1226 MOVE_ADDRESS(GET_SWORD(abfd,bytes->r_addend));
1230 DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
1232 struct reloc_std_external *bytes AND
1233 arelent *cache_ptr AND
1238 unsigned int r_length;
1240 int r_baserel, r_jmptable, r_relative;
1241 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1243 cache_ptr->address = (int32_type)(bfd_h_get_32 (abfd, bytes->r_address));
1245 /* now the fun stuff */
1246 if (abfd->xvec->header_byteorder_big_p != false) {
1247 r_index = (bytes->r_index[0] << 16)
1248 | (bytes->r_index[1] << 8)
1249 | bytes->r_index[2];
1250 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
1251 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
1252 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
1253 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1254 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
1255 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
1256 >> RELOC_STD_BITS_LENGTH_SH_BIG;
1258 r_index = (bytes->r_index[2] << 16)
1259 | (bytes->r_index[1] << 8)
1260 | bytes->r_index[0];
1261 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1262 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
1263 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1264 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1265 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1266 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1267 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1270 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1271 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1279 DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
1285 bfd_size_type reloc_size;
1287 arelent *reloc_cache;
1290 if (asect->relocation) return true;
1292 if (asect->flags & SEC_CONSTRUCTOR) return true;
1294 if (asect == obj_datasec (abfd)) {
1295 reloc_size = exec_hdr(abfd)->a_drsize;
1299 if (asect == obj_textsec (abfd)) {
1300 reloc_size = exec_hdr(abfd)->a_trsize;
1304 bfd_error = invalid_operation;
1308 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1309 each_size = obj_reloc_entry_size (abfd);
1311 count = reloc_size / each_size;
1314 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1318 bfd_error = no_memory;
1322 relocs = (PTR) bfd_alloc (abfd, reloc_size);
1324 bfd_release (abfd, reloc_cache);
1328 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1329 bfd_release (abfd, relocs);
1330 bfd_release (abfd, reloc_cache);
1331 bfd_error = system_call_error;
1335 if (each_size == RELOC_EXT_SIZE) {
1336 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
1337 unsigned int counter = 0;
1338 arelent *cache_ptr = reloc_cache;
1340 for (; counter < count; counter++, rptr++, cache_ptr++) {
1341 NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
1344 register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
1345 unsigned int counter = 0;
1346 arelent *cache_ptr = reloc_cache;
1348 for (; counter < count; counter++, rptr++, cache_ptr++) {
1349 NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
1354 bfd_release (abfd,relocs);
1355 asect->relocation = reloc_cache;
1356 asect->reloc_count = count;
1362 /* Write out a relocation section into an object file. */
1365 DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
1370 unsigned char *native, *natptr;
1373 unsigned int count = section->reloc_count;
1376 if (count == 0) return true;
1378 each_size = obj_reloc_entry_size (abfd);
1379 natsize = each_size * count;
1380 native = (unsigned char *) bfd_zalloc (abfd, natsize);
1382 bfd_error = no_memory;
1386 generic = section->orelocation;
1388 if (each_size == RELOC_EXT_SIZE)
1390 for (natptr = native;
1392 --count, natptr += each_size, ++generic)
1393 NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
1397 for (natptr = native;
1399 --count, natptr += each_size, ++generic)
1400 NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
1403 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1404 bfd_release(abfd, native);
1407 bfd_release (abfd, native);
1412 /* This is stupid. This function should be a boolean predicate */
1414 DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
1417 arelent **relptr AND
1420 arelent *tblptr = section->relocation;
1423 if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
1426 if (section->flags & SEC_CONSTRUCTOR) {
1427 arelent_chain *chain = section->constructor_chain;
1428 for (count = 0; count < section->reloc_count; count ++) {
1429 *relptr ++ = &chain->relent;
1430 chain = chain->next;
1434 tblptr = section->relocation;
1435 if (!tblptr) return 0;
1437 for (count = 0; count++ < section->reloc_count;)
1439 *relptr++ = tblptr++;
1444 return section->reloc_count;
1448 DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
1452 if (bfd_get_format (abfd) != bfd_object) {
1453 bfd_error = invalid_operation;
1456 if (asect->flags & SEC_CONSTRUCTOR) {
1457 return (sizeof (arelent *) * (asect->reloc_count+1));
1461 if (asect == obj_datasec (abfd))
1462 return (sizeof (arelent *) *
1463 ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
1466 if (asect == obj_textsec (abfd))
1467 return (sizeof (arelent *) *
1468 ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
1471 bfd_error = invalid_operation;
1477 DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
1480 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1482 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1485 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
1486 bfd *ignore_abfd AND
1487 asymbol *ignore_symbol)
1489 return (alent *)NULL;
1494 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
1495 bfd *ignore_abfd AND
1498 bfd_print_symbol_enum_type how)
1500 FILE *file = (FILE *)afile;
1503 case bfd_print_symbol_name_enum:
1504 fprintf(file,"%s", symbol->name);
1506 case bfd_print_symbol_type_enum:
1507 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1508 (unsigned)(aout_symbol(symbol)->other & 0xff),
1509 (unsigned)(aout_symbol(symbol)->type));
1511 case bfd_print_symbol_all_enum:
1513 CONST char *section_name = symbol->section == (asection *)NULL ?
1514 "*abs" : symbol->section->name;
1516 bfd_print_symbol_vandf((PTR)file,symbol);
1518 fprintf(file," %-5s %04x %02x %02x %s",
1520 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1521 (unsigned)(aout_symbol(symbol)->other & 0xff),
1522 (unsigned)(aout_symbol(symbol)->type & 0xff),
1530 provided a bfd, a section and an offset into the section, calculate
1531 and return the name of the source file and the line nearest to the
1536 DEFUN(NAME(aout,find_nearest_line),(abfd,
1544 asection *section AND
1545 asymbol **symbols AND
1547 CONST char **filename_ptr AND
1548 CONST char **functionname_ptr AND
1549 unsigned int *line_ptr)
1551 /* Run down the file looking for the filename, function and linenumber */
1553 static char buffer[100];
1554 bfd_vma high_line_vma = ~0;
1555 bfd_vma low_func_vma = 0;
1557 *filename_ptr = abfd->filename;
1558 *functionname_ptr = 0;
1560 if (symbols != (asymbol **)NULL) {
1561 for (p = symbols; *p; p++) {
1562 aout_symbol_type *q = (aout_symbol_type *)(*p);
1565 *filename_ptr = q->symbol.name;
1566 if (obj_textsec(abfd) != section) {
1574 /* We'll keep this if it resolves nearer than the one we have already */
1575 if (q->symbol.value >= offset &&
1576 q->symbol.value < high_line_vma) {
1577 *line_ptr = q->desc;
1578 high_line_vma = q->symbol.value;
1583 /* We'll keep this if it is nearer than the one we have already */
1584 if (q->symbol.value >= low_func_vma &&
1585 q->symbol.value <= offset) {
1586 low_func_vma = q->symbol.value;
1587 func = (asymbol *)q;
1589 if (*line_ptr && func) {
1590 CONST char *function = func->name;
1592 strncpy(buffer, function, sizeof(buffer)-1);
1593 buffer[sizeof(buffer)-1] = 0;
1594 /* Have to remove : stuff */
1595 p = strchr(buffer,':');
1596 if (p != NULL) { *p = NULL; }
1597 *functionname_ptr = buffer;
1612 DEFUN(NAME(aout,sizeof_headers),(ignore_abfd, execable),
1613 bfd *ignore_abfd AND
1616 return EXEC_BYTES_SIZE;