*** empty log message ***
[external/binutils.git] / bfd / aoutx.h
1 /* BFD semi-generic back-end for a.out binaries
2    Copyright (C) 1990-1991 Free Software Foundation, Inc.
3    Written by Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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.  */
20
21 /*doc*
22 @section a.out backends
23
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. 
27
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.
33
34 This information is further split out into more specific files for each
35 machine, including @code{sunos.c} - for sun3 and sun4 and
36 @code{demo64} for a demonstration of a 64 bit a.out format.
37
38 The base file @code{aoutx.h} defines general mechanisms for reading
39 and writing records to and from disk, and various other methods which
40 BFD requires. It is included by @code{aout32.c} and @code{aout64.c} to
41 form the names aout_32_swap_exec_header_in,
42 aout_64_swap_exec_header_in, etc.
43
44 As an example, this is what goes on to make the back end for a sun4, from aout32.c
45
46 @example
47    #define ARCH_SIZE 32
48    #include "aoutx.h"
49 @end example
50
51 Which exports names:
52 @example
53     ...
54    aout_32_canonicalize_reloc
55    aout_32_find_nearest_line
56    aout_32_get_lineno
57    aout_32_get_reloc_upper_bound
58      ...
59 @end example
60
61 from sunos.c
62
63 @example   
64     #define ARCH 32
65     #define TARGET_NAME "a.out-sunos-big"
66     #define VECNAME    sunos_big_vec
67     #include "aoutf1.h"
68 @end example
69 requires all the names from aout32.c, and produces the jump vector
70
71 @example
72     sunos_big_vec
73 @end example
74
75 The file host-aout.c is a special case.  It is for a large set of hosts
76 that use ``more or less standard'' a.out files, and for which cross-debugging
77 is not interesting.  It uses the standard 32-bit a.out support routines,
78 but determines the file offsets and addresses of the text, data,
79 and BSS sections, the machine architecture and machine type,
80 and the entry point address, in a host-dependent manner.  Once these
81 values have been determined, generic code is used to handle the 
82 object file.
83
84 When porting it to run on a new system, you must supply:
85
86         HOST_PAGE_SIZE
87         HOST_SEGMENT_SIZE
88         HOST_MACHINE_ARCH       (optional)
89         HOST_MACHINE_MACHINE    (optional)
90         HOST_TEXT_START_ADDR
91         HOST_STACK_END_ADDR
92
93 in the file ../include/sys/h-XXX.h (for your host).  These values, plus
94 the structures and macros defined in <a.out.h> on your host system, will
95 produce a BFD target that will access ordinary a.out files on your host.
96
97 To configure a new machine to use host-aout.c, specify:
98
99 TDEFINES = -DDEFAULT_VECTOR=host_aout_big_vec
100 TDEPFILES= host-aout.o trad-core.o
101
102 in the config/t-XXX file, and modify configure.in to use the
103 t-XXX file (by setting "bfd_target=XXX") when your configuration is
104 selected.
105
106 */
107
108 #define KEEPIT flags
109 #define KEEPITTYPE int
110
111 #include "bfd.h"
112 #include <sysdep.h>
113 #include <ansidecl.h>
114
115 struct external_exec;
116 #include "libaout.h"
117 #include "libbfd.h"
118 #include "aout64.h"
119 #include "stab.gnu.h"
120 #include "ar.h"
121
122 void (*bfd_error_trap)();
123
124 /*doc*
125 @subsection relocations
126 The file @code{aoutx.h} caters for both the @emph{standard} and
127 @emph{extended} forms of a.out relocation records.
128
129 The standard records are characterised by containing only an address,
130 a symbol index and a type field. The extended records (used on 29ks
131 and sparcs) also have a full integer for an addend. 
132 */
133 #define CTOR_TABLE_RELOC_IDX 2
134
135 /* start-sanitize-v9 */
136 /* Provided the symbol, returns the value reffed */
137 static  bfd_vma
138 DEFUN(get_symbol_value,(symbol, input_section),
139       asymbol *symbol AND
140       asection *input_section)
141 {                                             
142   bfd_vma relocation = 0;
143
144   if (symbol != (asymbol *)NULL) {              
145     if (symbol->flags & BSF_FORT_COMM) {        
146       relocation = 0;                           
147     } else {                                      
148       relocation = symbol->value;               
149     }                                           
150     if (symbol->section != (asection *)NULL) {    
151       relocation += symbol->section->output_section->vma +
152         symbol->section->output_offset;           
153     }                                             
154   }
155   else {
156     /* No symbol, so use the input section value */
157     relocation = input_section->output_section->vma + input_section->output_offset;
158   }
159   return relocation;
160 }
161
162 static bfd_reloc_status_enum_type
163 DEFUN(reloc64,(abfd, reloc_entry, symbol_in, data, input_section),
164       bfd *abfd AND
165       arelent *reloc_entry AND
166       asymbol *symbol_in AND
167       unsigned char *data AND
168       asection *input_section)
169 {
170   bfd_vma sym_value = get_symbol_value(symbol_in, input_section);
171   bfd_vma value = bfd_get_64(abfd, (bfd_byte *)data + reloc_entry->address);
172   value += sym_value + reloc_entry->addend;
173   bfd_put_64(abfd, value, (bfd_byte *)data+reloc_entry->address);
174   return bfd_reloc_ok;
175 }
176
177 static bfd_reloc_status_enum_type
178 DEFUN(disp64,(abfd, reloc_entry, symbol_in, data, input_section),
179       bfd *abfd AND
180       arelent *reloc_entry AND
181       asymbol *symbol_in AND
182       unsigned char *data AND
183       asection *input_section)
184 {
185   bfd_vma sym_value = get_symbol_value(symbol_in, input_section);
186
187 /* bfd_get_64(abfd, (bfd_byte *)data + reloc_entry->address);*/
188   bfd_vma value = 0;
189   value += sym_value + reloc_entry->addend;
190
191   /* Subtract from the calculated value the pc */
192   value -= reloc_entry->address + input_section->output_section->vma;
193   bfd_put_64(abfd, value, (bfd_byte *)data+reloc_entry->address);
194   return bfd_reloc_ok;
195 }
196
197 static bfd_reloc_status_enum_type
198 DEFUN(hhi22,(abfd, reloc_entry, symbol_in, data, input_section),
199       bfd *abfd AND
200       arelent *reloc_entry AND
201       asymbol *symbol_in AND
202       unsigned char *data AND
203       asection *input_section)
204 {
205   bfd_vma sym_value = get_symbol_value(symbol_in, input_section);
206
207   bfd_vma value =   bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address);
208
209   value = (value & ~0x3fffff) | ( ((sym_value + reloc_entry->addend) >> 32+10) & 0x3fffff);
210
211   bfd_put_32(abfd, value, (bfd_byte *)data+reloc_entry->address);
212   return bfd_reloc_ok;
213 }
214
215 static bfd_reloc_status_enum_type
216 DEFUN(hlo10,(abfd, reloc_entry, symbol_in, data, input_section),
217       bfd *abfd AND
218       arelent *reloc_entry AND
219       asymbol *symbol_in AND
220       unsigned char *data AND
221       asection *input_section)
222 {
223   bfd_vma sym_value = get_symbol_value(symbol_in, input_section);
224
225   bfd_vma value =   bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address);
226
227   value = (value & ~0x3ff) | (((sym_value + reloc_entry->addend) >> 32) & 0x3ff);
228
229   bfd_put_32(abfd, value, (bfd_byte *)data+reloc_entry->address);
230   return bfd_reloc_ok;
231 }
232
233 static bfd_reloc_status_enum_type
234 r64() 
235 {
236   abort();
237 }
238
239 /* end-sanitize-v9 */
240
241 static  reloc_howto_type howto_table_ext[] = 
242 {
243   HOWTO(RELOC_8,      0,  0,    8,  false, 0, true,  true,0,"8",      false, 0,0x000000ff, false),
244   HOWTO(RELOC_16,     0,  1,    16, false, 0, true,  true,0,"16",      false, 0,0x0000ffff, false),
245   HOWTO(RELOC_32,     0,  2,    32, false, 0, true,  true,0,"32",      false, 0,0xffffffff, false),
246   HOWTO(RELOC_DISP8,  0,  0,    8,  true,  0, false, true,0,"DISP8",    false, 0,0x000000ff, false),
247   HOWTO(RELOC_DISP16, 0,  1,    16, true,  0, false, true,0,"DISP16",   false, 0,0x0000ffff, false),
248   HOWTO(RELOC_DISP32, 0,  2,    32, true,  0, false, true,0,"DISP32",   false, 0,0xffffffff, false),
249   HOWTO(RELOC_WDISP30,2,  2,    30, true,  0, false, true,0,"WDISP30",  false, 0,0x3fffffff, false),
250   HOWTO(RELOC_WDISP22,2,  2,    22, true,  0, false, true,0,"WDISP22",  false, 0,0x003fffff, false),
251   HOWTO(RELOC_HI22,   10, 2,    22, false, 0, false, true,0,"HI22",     false, 0,0x003fffff, false),
252   HOWTO(RELOC_22,      0, 2,    22, false, 0, false, true,0,"22",       false, 0,0x003fffff, false),
253   HOWTO(RELOC_13,       0, 2,   13, false, 0, false, true,0,"13",       false, 0,0x00001fff, false),
254   HOWTO(RELOC_LO10,     0, 2,   10, false, 0, false, true,0,"LO10",     false, 0,0x000003ff, false),
255   HOWTO(RELOC_SFA_BASE,0, 2,    32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
256   HOWTO(RELOC_SFA_OFF13,0,2,    32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
257   HOWTO(RELOC_BASE10, 0,  2,    16, false, 0, false, true,0,"BASE10",   false, 0,0x0000ffff, false),
258   HOWTO(RELOC_BASE13, 0,  2,    13, false, 0, false, true,0,"BASE13",   false, 0,0x00001fff, false),
259   HOWTO(RELOC_BASE22, 0,  2,    0,  false, 0, false, true,0,"BASE22",   false, 0,0x00000000, false),
260   HOWTO(RELOC_PC10,   0,  2,    10, false, 0, false, true,0,"PC10",     false, 0,0x000003ff, false),
261   HOWTO(RELOC_PC22,   0,  2,    22, false, 0, false, true,0,"PC22",     false, 0,0x003fffff, false),
262   HOWTO(RELOC_JMP_TBL,0,  2,    32, false, 0, false, true,0,"JMP_TBL",  false, 0,0xffffffff, false),
263   HOWTO(RELOC_SEGOFF16,0, 2,    0,  false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
264   HOWTO(RELOC_GLOB_DAT,0, 2,    0,  false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
265   HOWTO(RELOC_JMP_SLOT,0, 2,    0,  false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
266   HOWTO(RELOC_RELATIVE,0, 2,    0,  false, 0, false,    true,0,"RELATIVE",      false, 0,0x00000000, false),
267
268 /* start-sanitize-v9 */
269
270   HOWTO(RELOC_11, 0,  2,        21, true,  0, false, true,r64,"11",     false, 0,/*0x00000000001fffff*/0, false),
271   HOWTO(RELOC_WDISP2_14, 0, 2,  21, true,  0, false, true,r64,"DISP2_14",false, 0,/*0x00000000001fffff*/0, false),
272   HOWTO(RELOC_WDISP19, 0,  3,   64, true,  0, false, true,r64,"DISP19", false, 0,/*0xffffffffffffffff*/0, false),  
273   HOWTO(RELOC_HHI22,  42, 3,    22, false, 0, false, true,hhi22,"HHI22",false, 0,/*0x003fffff00000000*/0, false),
274   HOWTO(RELOC_HLO10,  32, 3,    10, false, 0, false, true,hlo10,"HLO10", false, 0,/*0x000003ff00000000*/0, false),
275
276   HOWTO(RELOC_JUMPTARG,2, 13,   16, true,  0, false, true,0,"JUMPTARG", false, 0,0x0000ffff, false),
277   HOWTO(RELOC_CONST,    0, 13,  16, false, 0, false, true,0,"CONST",    false, 0,0x0000ffff, false),
278   HOWTO(RELOC_CONSTH, 16, 13,   16, false, 0, false, true,0,"CONSTH",   false, 0,0x0000ffff, false),
279
280
281   HOWTO(RELOC_64,     0,  3,    64, false, 0, true,  true,reloc64,"64",     false, 0,/*0xffffffffffffffff*/0, false),
282   HOWTO(RELOC_DISP64, 0,  3,    64, true,  0, false, true,disp64,"DISP64", false, 0,/*0xffffffffffffffff*/0, false),  
283   HOWTO(RELOC_WDISP21,2,  2,    21, true,  0, false, true,r64,"WDISP21",false, 0,/*0x00000000001fffff*/0, false),
284   HOWTO(RELOC_DISP21, 0,  2,    21, true,  0, false, true,r64,"DISP21", false, 0,/*0x00000000001fffff*/0, false),
285   HOWTO(RELOC_DISP14, 0,  2,    14, true,  0, false, true,r64,"DISP21", false, 0,/*0x0000000000003fff*/0, false),
286
287 /* end-sanitize-v9 */
288 };
289
290 /* Convert standard reloc records to "arelent" format (incl byte swap).  */
291
292 static  reloc_howto_type howto_table_std[] = {
293   /* type           rs   size bsz  pcrel bitpos  abs ovrf sf name    part_inpl   readmask  setmask  pcdone */
294 HOWTO( 0,              0,  0,   8,  false, 0, true,  true,0,"8",        true, 0x000000ff,0x000000ff, false),
295 HOWTO( 1,              0,  1,   16, false, 0, true,  true,0,"16",       true, 0x0000ffff,0x0000ffff, false),
296 HOWTO( 2,              0,  2,   32, false, 0, true,  true,0,"32",       true, 0xffffffff,0xffffffff, false),
297 HOWTO( 3,              0,  3,   64, false, 0, true,  true,0,"64",       true, 0xdeaddead,0xdeaddead, false),
298 HOWTO( 4,              0,  0,   8,  true,  0, false, true,0,"DISP8",    true, 0x000000ff,0x000000ff, false),
299 HOWTO( 5,              0,  1,   16, true,  0, false, true,0,"DISP16",   true, 0x0000ffff,0x0000ffff, false),
300 HOWTO( 6,              0,  2,   32, true,  0, false, true,0,"DISP32",   true, 0xffffffff,0xffffffff, false),
301 HOWTO( 7,              0,  3,   64, true,  0, false, true,0,"DISP64",   true, 0xfeedface,0xfeedface, false),
302 };
303
304
305 bfd_error_vector_type bfd_error_vector;
306
307 /*doc*
308 @subsection Internal Entry Points
309 @code{aoutx.h} exports several routines for accessing the contents of
310 an a.out file, which are gathered and exported in turn by various
311 format specific files (eg sunos.c).
312 */
313
314 /*doc*
315 *i aout_<size>_swap_exec_header_in
316 Swaps the information in an executable header taken from a raw byte stream memory image,
317 into the internal exec_header structure.
318 *; PROTO(void, aout_<size>_swap_exec_header_in,
319       (bfd *abfd,
320       struct external_exec *raw_bytes,
321       struct internal_exec *execp));
322 */
323          
324 void
325 DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
326       bfd *abfd AND
327       struct external_exec *raw_bytes AND
328       struct internal_exec *execp)
329 {
330   struct external_exec *bytes = (struct external_exec *)raw_bytes;
331
332   /* Now fill in fields in the execp, from the bytes in the raw data.  */
333   execp->a_info   = bfd_h_get_32 (abfd, bytes->e_info);
334   execp->a_text   = GET_WORD (abfd, bytes->e_text);
335   execp->a_data   = GET_WORD (abfd, bytes->e_data);
336   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
337   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
338   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
339   execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
340   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
341 }
342
343 /*doc*
344 *i aout_<size>_swap_exec_header_out
345 Swaps the information in an internal exec header structure into the
346 supplied buffer ready for writing to disk.
347 *; PROTO(void, aout_<size>_swap_exec_header_out,
348           (bfd *abfd,
349            struct internal_exec *execp,
350            struct external_exec *raw_bytes));
351 */
352 void
353 DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
354      bfd *abfd AND
355      struct internal_exec *execp AND 
356      struct external_exec *raw_bytes)
357 {
358   struct external_exec *bytes = (struct external_exec *)raw_bytes;
359
360   /* Now fill in fields in the raw data, from the fields in the exec struct. */
361   bfd_h_put_32 (abfd, execp->a_info  , bytes->e_info);
362   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
363   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
364   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
365   PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
366   PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
367   PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
368   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
369 }
370
371 struct container {
372     struct aoutdata a;
373     struct internal_exec e;
374 };
375
376
377 /*doc*
378 *i aout_<size>_some_aout_object_p
379
380 Some A.OUT variant thinks that the file whose format we're checking
381 is an a.out file.  Do some more checking, and set up for access if
382 it really is.  Call back to the calling environments "finish up"
383 function just before returning, to handle any last-minute setup.  
384
385 *; PROTO(bfd_target *, aout_<size>_some_aout_object_p,
386          (bfd *abfd,
387           bfd_target *(*callback_to_real_object_p)()));
388 */
389  
390 bfd_target *
391 DEFUN(NAME(aout,some_aout_object_p),(abfd, callback_to_real_object_p),
392       bfd *abfd AND
393       bfd_target *(*callback_to_real_object_p) ())
394 {
395   struct external_exec exec_bytes;
396   struct internal_exec *execp;
397   struct container *rawptr;
398
399   if (bfd_seek (abfd, 0L, false) < 0) {
400     bfd_error = system_call_error;
401     return 0;
402   }
403
404   if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
405       != EXEC_BYTES_SIZE) {
406     bfd_error = wrong_format;
407     return 0;
408   }
409
410   /* Use an intermediate variable for clarity */
411   rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
412
413   if (rawptr == NULL) {
414     bfd_error = no_memory;
415     return 0;
416   }
417
418   set_tdata (abfd, rawptr);
419   exec_hdr (abfd) = execp = &(rawptr->e);
420   NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, execp);
421
422   /* Set the file flags */
423   abfd->flags = NO_FLAGS;
424   if (execp->a_drsize || execp->a_trsize)
425     abfd->flags |= HAS_RELOC;
426   if (execp->a_entry) 
427     abfd->flags |= EXEC_P;
428   if (execp->a_syms) 
429     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
430
431   if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
432   if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
433
434   bfd_get_start_address (abfd) = execp->a_entry;
435
436   obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
437   bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
438
439   /* Set the default architecture and machine type.  These can be
440      overridden in the callback routine.  */
441   abfd->obj_arch = bfd_arch_unknown;
442   abfd->obj_machine = 0;
443
444   /* The default relocation entry size is that of traditional V7 Unix.  */
445   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
446
447   /* create the sections.  This is raunchy, but bfd_close wants to reclaim
448      them */
449   obj_textsec (abfd) = (asection *)NULL;
450   obj_datasec (abfd) = (asection *)NULL;
451   obj_bsssec (abfd) = (asection *)NULL;
452   (void)bfd_make_section(abfd, ".text");
453   (void)bfd_make_section(abfd, ".data");
454   (void)bfd_make_section(abfd, ".bss");
455
456   abfd->sections = obj_textsec (abfd);
457   obj_textsec (abfd)->next = obj_datasec (abfd);
458   obj_datasec (abfd)->next = obj_bsssec (abfd);
459
460   obj_datasec (abfd)->size = execp->a_data;
461   obj_bsssec (abfd)->size = execp->a_bss;
462   obj_textsec (abfd)->size = execp->a_text;
463
464   if (abfd->flags & D_PAGED) {
465     obj_textsec (abfd)->size -=  EXEC_BYTES_SIZE;
466   }
467     
468
469   obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
470                                (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
471                                (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
472   obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
473                                (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
474                                (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
475   obj_bsssec (abfd)->flags = SEC_ALLOC;
476
477 #ifdef THIS_IS_ONLY_DOCUMENTATION
478   /* Call back to the format-dependent code to fill in the rest of the 
479      fields and do any further cleanup.  Things that should be filled
480      in by the callback:  */
481
482   struct exec *execp = exec_hdr (abfd);
483
484   /* The virtual memory addresses of the sections */
485   obj_datasec (abfd)->vma = N_DATADDR(*execp);
486   obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
487   obj_textsec (abfd)->vma = N_TXTADDR(*execp);
488
489   /* The file offsets of the sections */
490   obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
491   obj_datasec (abfd)->filepos = N_DATOFF(*execp);
492
493   /* The file offsets of the relocation info */
494   obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
495   obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
496
497   /* The file offsets of the string table and symbol table.  */
498   obj_str_filepos (abfd) = N_STROFF (*execp);
499   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
500
501   /* This common code can't fill in those things because they depend
502      on either the start address of the text segment, the rounding
503      up of virtual addersses between segments, or the starting file 
504      position of the text segment -- all of which varies among different
505      versions of a.out.  */
506
507   /* Determine the architecture and machine type of the object file.  */
508   switch (N_MACHTYPE (*exec_hdr (abfd))) {
509   default:
510     abfd->obj_arch = bfd_arch_obscure;
511     break;
512   }
513
514   /* Determine the size of a relocation entry */
515   switch (abfd->obj_arch) {
516   case bfd_arch_sparc:
517   case bfd_arch_a29k:
518     obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
519   default:
520     obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
521   }
522
523   return abfd->xvec;
524
525   /* The architecture is encoded in various ways in various a.out variants,
526      or is not encoded at all in some of them.  The relocation size depends
527      on the architecture and the a.out variant.  Finally, the return value
528      is the bfd_target vector in use.  If an error occurs, return zero and
529      set bfd_error to the appropriate error code.
530      
531      Formats such as b.out, which have additional fields in the a.out
532      header, should cope with them in this callback as well.  */
533 #endif                          /* DOCUMENTATION */
534
535
536   return (*callback_to_real_object_p)(abfd);
537 }
538
539 /*doc*
540 *i aout_<size>_mkobject
541
542 This routine initializes a BFD for use with a.out files.
543
544 *; PROTO(boolean, aout_<size>_mkobject, (bfd *));
545 */
546
547 boolean
548 DEFUN(NAME(aout,mkobject),(abfd),
549      bfd *abfd)
550 {
551   struct container *rawptr;
552
553   bfd_error = system_call_error;
554
555   /* Use an intermediate variable for clarity */
556   rawptr = (struct container *)bfd_zalloc (abfd, sizeof (struct container));
557   
558   if (rawptr == NULL) {
559     bfd_error = no_memory;
560     return false;
561   }
562   
563   set_tdata (abfd, rawptr);
564   exec_hdr (abfd) = &(rawptr->e);
565   
566   /* For simplicity's sake we just make all the sections right here. */
567   
568   obj_textsec (abfd) = (asection *)NULL;
569   obj_datasec (abfd) = (asection *)NULL;
570   obj_bsssec (abfd) = (asection *)NULL;
571   bfd_make_section (abfd, ".text");
572   bfd_make_section (abfd, ".data");
573   bfd_make_section (abfd, ".bss");
574   
575   return true;
576 }
577
578
579 /*doc*
580 *i aout_<size>_machine_type
581
582 Keep track of machine architecture and machine type for a.out's.
583 Return the machine_type for a particular arch&machine, or M_UNKNOWN
584 if that exact arch&machine can't be represented in a.out format.
585
586 If the architecture is understood, machine type 0 (default) should
587 always be understood.  
588
589 *; PROTO(enum machine_type, aout_<size>_machine_type,
590          (enum bfd_architecture arch,
591           unsigned long machine));
592 */
593
594 enum machine_type
595 DEFUN(NAME(aout,machine_type),(arch, machine),
596       enum bfd_architecture arch AND
597       unsigned long machine)
598 {
599   enum machine_type arch_flags;
600     
601   arch_flags = M_UNKNOWN;
602     
603   switch (arch) {
604   case bfd_arch_sparc:
605     if (machine == 0)   arch_flags = M_SPARC;
606     break;
607       
608   case bfd_arch_m68k:
609     switch (machine) {
610     case 0:             arch_flags = M_68010; break;
611     case 68000:         arch_flags = M_UNKNOWN; break;
612     case 68010:         arch_flags = M_68010; break;
613     case 68020:         arch_flags = M_68020; break;
614     default:            arch_flags = M_UNKNOWN; break;
615     }
616     break;
617       
618   case bfd_arch_i386:
619     if (machine == 0)   arch_flags = M_386;
620     break;
621       
622   case bfd_arch_a29k:
623     if (machine == 0)   arch_flags = M_29K;
624     break;
625       
626   default:
627     arch_flags = M_UNKNOWN;
628     break;
629   }
630   return arch_flags;
631 }
632
633 /*doc*
634 *i aout_<size>_set_arch_mach
635
636 Sets the architecture and the machine of the BFD to those values
637 supplied. Verifies that the format can support the architecture
638 required.
639
640 *; PROTO(boolean, aout_<size>_set_arch_mach,
641          (bfd *,
642           enum bfd_architecture,
643           unsigned long machine));
644 */
645
646 boolean
647 DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
648       bfd *abfd AND
649       enum bfd_architecture arch AND
650       unsigned long machine)
651 {
652   abfd->obj_arch = arch;
653   abfd->obj_machine = machine;
654   if (arch != bfd_arch_unknown &&
655       NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
656     return false;               /* We can't represent this type */
657   return true;                  /* We're easy ... */
658 }
659
660 /*doc*
661 *i aout_<size>new_section_hook
662
663 Called by the BFD in response to a @code{bfd_make_section} request.
664 *; PROTO(boolean, aout_<size>_new_section_hook,
665          (bfd *abfd,
666           asection *newsect));
667 */
668 boolean
669 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
670       bfd *abfd AND
671       asection *newsect)
672 {
673   /* align to double at least */
674   newsect->alignment_power = 3;
675     
676   if (bfd_get_format (abfd) == bfd_object) {
677     if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
678       obj_textsec(abfd)= newsect;
679       return true;
680     }
681       
682     if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
683       obj_datasec(abfd) = newsect;
684       return true;
685     }
686       
687     if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
688       obj_bsssec(abfd) = newsect;
689       return true;
690     }
691   }
692     
693   /* We allow more than three sections internally */
694   return true;
695 }
696
697 boolean
698 DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
699       bfd *abfd AND
700       sec_ptr section AND
701       PTR location AND
702       file_ptr offset AND
703       bfd_size_type count)
704 {
705   if (abfd->output_has_begun == false)
706       {                         /* set by bfd.c handler */
707         if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL)) 
708             {
709               bfd_error = invalid_operation;
710               return false;
711             }
712 /*      if (abfd->flags & D_PAGED) {      
713           obj_textsec(abfd)->filepos = 0;
714         }
715         else*/ {
716           obj_textsec(abfd)->filepos = EXEC_BYTES_SIZE;
717         }
718         obj_textsec(abfd)->size = align_power(obj_textsec(abfd)->size,
719                                               obj_textsec(abfd)->alignment_power);
720         obj_datasec(abfd)->filepos =  obj_textsec (abfd)->size + EXEC_BYTES_SIZE;
721         obj_datasec(abfd)->size = align_power(obj_datasec(abfd)->size,
722                                               obj_datasec(abfd)->alignment_power);
723           
724           
725       }
726   /* regardless, once we know what we're doing, we might as well get going */
727   if (section != obj_bsssec(abfd)) 
728       {
729         bfd_seek (abfd, section->filepos + offset, SEEK_SET);
730           
731         if (count) {
732           return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
733             true : false;
734         }
735         return false;
736       }
737   return true;
738 }
739 \f
740 /* Classify stabs symbols */
741
742 #define sym_in_text_section(sym) \
743 (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
744
745 #define sym_in_data_section(sym) \
746 (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
747
748 #define sym_in_bss_section(sym) \
749 (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
750
751 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
752 zero in the "value" field.  Nonzeroes there are fortrancommon
753 symbols.  */
754 #define sym_is_undefined(sym) \
755 ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
756
757 /* Symbol is a global definition if N_EXT is on and if it has
758 a nonzero type field.  */
759 #define sym_is_global_defn(sym) \
760 (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
761
762 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
763 are on.  */
764 #define sym_is_debugger_info(sym) \
765 ((sym)->type & ~(N_EXT | N_TYPE))
766
767 #define sym_is_fortrancommon(sym)       \
768 (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
769
770 /* Symbol is absolute if it has N_ABS set */
771 #define sym_is_absolute(sym) \
772 (((sym)->type  & N_TYPE)== N_ABS)
773
774
775 #define sym_is_indirect(sym) \
776 (((sym)->type & N_ABS)== N_ABS)
777
778 /* Only in their own functions for ease of debugging; when sym flags have
779 stabilised these should be inlined into their (single) caller */
780
781 static void
782 DEFUN(translate_from_native_sym_flags,(sym_pointer, cache_ptr, abfd),
783       struct external_nlist *sym_pointer AND
784       aout_symbol_type *cache_ptr AND
785       bfd *abfd)
786   {
787     switch (cache_ptr->type & N_TYPE) {
788     case N_SETA:
789     case N_SETT:
790     case N_SETD:
791     case N_SETB:
792         {
793           char *copy = bfd_alloc(abfd, strlen(cache_ptr->symbol.name)+1);
794           asection *section ;
795           arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
796           strcpy(copy, cache_ptr->symbol.name);
797           section = bfd_make_section(abfd,copy);
798           switch ( (cache_ptr->type  & N_TYPE) ) {
799           case N_SETA:
800             section->flags = SEC_CONSTRUCTOR;
801             reloc->relent.section =  (asection *)NULL;
802             cache_ptr->symbol.section = (asection *)NULL;
803             break;
804           case N_SETT:
805             section->flags = SEC_CONSTRUCTOR_TEXT;
806             reloc->relent.section = (asection *)obj_textsec(abfd);
807             cache_ptr->symbol.value -= reloc->relent.section->vma;
808             break;
809           case N_SETD:
810             section->flags = SEC_CONSTRUCTOR_DATA;
811             reloc->relent.section = (asection *)obj_datasec(abfd);
812             cache_ptr->symbol.value -= reloc->relent.section->vma;
813             break;
814           case N_SETB:
815             section->flags = SEC_CONSTRUCTOR_BSS;
816             reloc->relent.section = (asection *)obj_bsssec(abfd);
817             cache_ptr->symbol.value -= reloc->relent.section->vma;
818             break;
819           }
820           cache_ptr->symbol.section = reloc->relent.section;
821           reloc->relent.addend = cache_ptr->symbol.value ;
822           
823           /* We modify the symbol to belong to a section depending upon the
824             name of the symbol - probably __CTOR__ or __DTOR__ but we don't
825               really care, and add to the size of the section to contain a
826                 pointer to the symbol. Build a reloc entry to relocate to this
827                   symbol attached to this section.  */
828           
829           
830           section->reloc_count++;
831           section->alignment_power = 2;
832           reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
833           reloc->next = section->constructor_chain;
834           section->constructor_chain = reloc;
835           reloc->relent.address = section->size;
836           section->size += sizeof(int *);
837           
838           reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
839           cache_ptr->symbol.flags |=  BSF_DEBUGGING  | BSF_CONSTRUCTOR;
840         }
841         break;
842   default:
843     if (cache_ptr->type ==  N_WARNING) 
844         {
845       /* This symbol is the text of a warning message, the next symbol
846          is the symbol to associate the warning with */
847       cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
848       cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
849       /* We furgle with the next symbol in place. We don't want it to be undefined, we'll trample the type */
850       (sym_pointer+1)->e_type[0] = 0xff;
851       break;
852     }
853     if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT)) {
854       /* Two symbols in a row for an INDR message. The first symbol
855          contains the name we will match, the second symbol contains the
856          name the first name is translated into. It is supplied to us
857          undefined. This is good, since we want to pull in any files which
858          define it */
859       cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
860       cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
861       break;
862     }
863
864       
865     if (sym_is_debugger_info (cache_ptr)) {
866       cache_ptr->symbol.flags = BSF_DEBUGGING ;
867       /* Work out the section correct for this symbol */
868       switch (cache_ptr->type & N_TYPE) 
869           {
870           case N_TEXT:
871           case N_FN:
872             cache_ptr->symbol.section = obj_textsec (abfd);
873             cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
874             break;
875           case N_DATA:
876             cache_ptr->symbol.value  -= obj_datasec(abfd)->vma;
877             cache_ptr->symbol.section = obj_datasec (abfd);
878             break;
879           case N_BSS :
880             cache_ptr->symbol.section = obj_bsssec (abfd);
881             cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
882             break;
883           case N_ABS:
884           default:
885             cache_ptr->symbol.section = 0;
886             break;
887           }
888     }
889     else {
890
891       if (sym_is_fortrancommon (cache_ptr))
892           {
893             cache_ptr->symbol.flags = BSF_FORT_COMM;
894             cache_ptr->symbol.section = (asection *)NULL;
895           }
896       else {
897         if (sym_is_undefined (cache_ptr)) {
898           cache_ptr->symbol.flags = BSF_UNDEFINED;
899         }
900         else if (sym_is_global_defn (cache_ptr)) {
901           cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
902         }
903           
904         else if (sym_is_absolute (cache_ptr)) {
905           cache_ptr->symbol.flags = BSF_ABSOLUTE;
906         }
907         else {
908           cache_ptr->symbol.flags = BSF_LOCAL;
909         }
910           
911         /* In a.out, the value of a symbol is always relative to the 
912          * start of the file, if this is a data symbol we'll subtract
913          * the size of the text section to get the section relative
914          * value. If this is a bss symbol (which would be strange)
915          * we'll subtract the size of the previous two sections
916          * to find the section relative address.
917          */
918           
919         if (sym_in_text_section (cache_ptr))   {
920           cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
921           cache_ptr->symbol.section = obj_textsec (abfd);
922         }
923         else if (sym_in_data_section (cache_ptr)){
924           cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
925           cache_ptr->symbol.section = obj_datasec (abfd);
926         }
927         else if (sym_in_bss_section(cache_ptr)) {
928           cache_ptr->symbol.section = obj_bsssec (abfd);
929           cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
930         }
931         else {
932           cache_ptr->symbol.section = (asection *)NULL;
933           cache_ptr->symbol.flags |= BSF_ABSOLUTE;
934         }
935       }
936     }
937   }
938 }
939
940 static void
941 DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
942      struct external_nlist *sym_pointer AND
943      asymbol *cache_ptr AND
944      bfd *abfd)
945 {
946   bfd_vma value = cache_ptr->value;
947
948   if (bfd_get_section(cache_ptr)) {
949     if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
950       sym_pointer->e_type[0] |= N_BSS;
951     }
952     else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
953       sym_pointer->e_type[0] |= N_DATA;
954     }
955     else  if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
956       sym_pointer->e_type[0] |= N_TEXT;
957     }
958     else {
959       bfd_error_vector.nonrepresentable_section(abfd,
960                                                 bfd_get_output_section(cache_ptr)->name);
961     }
962     /* Turn the symbol from section relative to absolute again */
963     
964     value +=
965       cache_ptr->section->output_section->vma 
966         + cache_ptr->section->output_offset ;
967   }
968   else {
969     sym_pointer->e_type[0] |= N_ABS;
970   }
971   if (cache_ptr->flags & (BSF_WARNING)) {
972     (sym_pointer+1)->e_type[0] = 1;
973   }  
974   if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
975     sym_pointer->e_type[0] = (N_UNDF | N_EXT);
976   }
977   else {
978     if (cache_ptr->flags & BSF_ABSOLUTE) {
979       sym_pointer->e_type[0] |= N_ABS;
980     }
981     
982     if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
983       sym_pointer->e_type[0] |= N_EXT;
984     }
985     if (cache_ptr->flags & BSF_DEBUGGING) {
986       sym_pointer->e_type [0]= ((aout_symbol_type *)cache_ptr)->type;
987     }
988   }
989   PUT_WORD(abfd, value, sym_pointer->e_value);
990 }
991 \f
992 /* Native-level interface to symbols. */
993
994 /* We read the symbols into a buffer, which is discarded when this
995 function exits.  We read the strings into a buffer large enough to
996 hold them all plus all the cached symbol entries. */
997
998 asymbol *
999 DEFUN(NAME(aout,make_empty_symbol),(abfd),
1000       bfd *abfd)
1001   {
1002     aout_symbol_type  *new =
1003       (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1004     new->symbol.the_bfd = abfd;
1005     
1006     return &new->symbol;
1007   }
1008
1009 boolean
1010 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
1011       bfd *abfd)
1012   {
1013     bfd_size_type symbol_size;
1014     bfd_size_type string_size;
1015     unsigned char string_chars[BYTES_IN_WORD];
1016     struct external_nlist *syms;
1017     char *strings;
1018     aout_symbol_type *cached;
1019     
1020     /* If there's no work to be done, don't do any */
1021     if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1022     symbol_size = exec_hdr(abfd)->a_syms;
1023     if (symbol_size == 0) {
1024       bfd_error = no_symbols;
1025       return false;
1026     }
1027     
1028     bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1029     if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
1030       return false;
1031     string_size = GET_WORD (abfd, string_chars);
1032     
1033     strings =(char *) bfd_alloc(abfd, string_size + 1);
1034     cached = (aout_symbol_type *)
1035       bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
1036
1037     /* malloc this, so we can free it if simply. The symbol caching
1038        might want to allocate onto the bfd's obstack  */
1039     syms = (struct external_nlist *) malloc(symbol_size);
1040     bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1041     if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
1042     bailout:
1043       if (syms)         free (syms);
1044       if (cached)       bfd_release (abfd, cached);
1045       if (strings)bfd_release (abfd, strings);
1046       return false;
1047     }
1048     
1049     bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1050     if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
1051       goto bailout;
1052     }
1053     
1054     /* OK, now walk the new symtable, cacheing symbol properties */
1055       {
1056         register struct external_nlist *sym_pointer;
1057         register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
1058         register aout_symbol_type *cache_ptr = cached;
1059         
1060         /* Run through table and copy values */
1061         for (sym_pointer = syms, cache_ptr = cached;
1062              sym_pointer < sym_end; sym_pointer++, cache_ptr++) 
1063             {
1064               bfd_vma x = GET_WORD(abfd, sym_pointer->e_strx);
1065               cache_ptr->symbol.the_bfd = abfd;
1066               if (x)
1067                 cache_ptr->symbol.name = x + strings;
1068               else
1069                 cache_ptr->symbol.name = (char *)NULL;
1070               
1071               cache_ptr->symbol.value = GET_SWORD(abfd,  sym_pointer->e_value);
1072               cache_ptr->desc = bfd_get_16(abfd, sym_pointer->e_desc);
1073               cache_ptr->other =bfd_get_8(abfd, sym_pointer->e_other);
1074               cache_ptr->type = bfd_get_8(abfd,  sym_pointer->e_type);
1075               cache_ptr->symbol.udata = 0;
1076               translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1077             }
1078       }
1079     
1080     obj_aout_symbols (abfd) =  cached;
1081     free((PTR)syms);
1082     
1083     return true;
1084   }
1085
1086
1087 void
1088 DEFUN(NAME(aout,write_syms),(abfd),
1089       bfd *abfd)
1090   {
1091     unsigned int count ;
1092     asymbol **generic = bfd_get_outsymbols (abfd);
1093     
1094     bfd_size_type stindex = BYTES_IN_WORD; /* initial string length */
1095     
1096     for (count = 0; count < bfd_get_symcount (abfd); count++) {
1097       asymbol *g = generic[count];
1098       struct external_nlist nsp;
1099       
1100       
1101       if (g->name) {
1102         unsigned int length = strlen(g->name) +1;
1103         PUT_WORD  (abfd, stindex, (unsigned char *)nsp.e_strx);
1104         stindex += length;
1105       }
1106       else {
1107         PUT_WORD  (abfd, 0, (unsigned char *)nsp.e_strx);
1108       }
1109       
1110       if (g->the_bfd->xvec->flavour == abfd->xvec->flavour) 
1111           {
1112             bfd_h_put_16(abfd, aout_symbol(g)->desc,  nsp.e_desc);
1113             bfd_h_put_8(abfd, aout_symbol(g)->other,  nsp.e_other);
1114             bfd_h_put_8(abfd, aout_symbol(g)->type,  nsp.e_type);
1115           }
1116       else
1117           {
1118             bfd_h_put_16(abfd,0, nsp.e_desc);
1119             bfd_h_put_8(abfd, 0,  nsp.e_other);
1120             bfd_h_put_8(abfd, 0,  nsp.e_type);
1121           }
1122       
1123       
1124       
1125       translate_to_native_sym_flags (&nsp, g, abfd);
1126       
1127       bfd_write((PTR)&nsp,1,EXTERNAL_LIST_SIZE, abfd);
1128     }
1129     
1130     
1131     /* Now output the strings.  Be sure to put string length into correct
1132       * byte ordering before writing it.
1133         */
1134       {
1135         char buffer[BYTES_IN_WORD];
1136         PUT_WORD  (abfd, stindex, (unsigned char *)buffer);
1137     
1138         bfd_write((PTR)buffer, 1, BYTES_IN_WORD, abfd);
1139       }
1140     generic = bfd_get_outsymbols(abfd);
1141     for (count = 0; count < bfd_get_symcount(abfd); count++) 
1142         {
1143           asymbol *g = *(generic++);
1144           
1145           if (g->name)
1146               {
1147                 size_t length = strlen(g->name)+1;
1148                 bfd_write((PTR)g->name, 1, length, abfd);
1149               }
1150           if ((g->flags & BSF_FAKE)==0) {
1151             g->KEEPIT = (KEEPITTYPE) count;
1152           }
1153         }
1154   }
1155
1156
1157
1158 unsigned int
1159 DEFUN(NAME(aout,get_symtab),(abfd, location),
1160       bfd *abfd AND
1161       asymbol **location)
1162   {
1163     unsigned int counter = 0;
1164     aout_symbol_type *symbase;
1165     
1166     if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1167     
1168     for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1169       *(location++) = (asymbol *)( symbase++);
1170     *location++ =0;
1171     return bfd_get_symcount(abfd);
1172   }
1173
1174 \f
1175 /* Standard reloc stuff */
1176 /* Output standard relocation information to a file in target byte order. */
1177
1178 void
1179 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1180       bfd *abfd AND
1181       arelent *g AND
1182       struct reloc_std_external *natptr)
1183   {
1184     int r_index;
1185     int r_extern;
1186     unsigned int r_length;
1187     int r_pcrel;
1188     int r_baserel, r_jmptable, r_relative;
1189     unsigned int r_addend;
1190     
1191     PUT_WORD(abfd, g->address, natptr->r_address);
1192     
1193     r_length = g->howto->size ; /* Size as a power of two */
1194     r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC? */
1195     /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
1196     r_baserel = 0;
1197     r_jmptable = 0;
1198     r_relative = 0;
1199     
1200     r_addend = g->addend;       /* Start here, see how it goes */
1201     
1202     /* name was clobbered by aout_write_syms to be symbol index */
1203     
1204     if (g->sym_ptr_ptr != NULL) 
1205         {
1206           if ((*(g->sym_ptr_ptr))->section) {
1207             /* put the section offset into the addend for output */
1208             r_addend += (*(g->sym_ptr_ptr))->section->vma;
1209           }
1210           
1211           r_index = ((*(g->sym_ptr_ptr))->KEEPIT);
1212           r_extern = 1;
1213         }
1214     else {
1215       r_extern = 0;
1216       if (g->section == NULL) {
1217         /* It is possible to have a reloc with nothing, we generate an
1218           abs + 0 */
1219         r_addend = 0;
1220         r_index = N_ABS | N_EXT;
1221       }
1222       else  if(g->section->output_section == obj_textsec(abfd)) {
1223         r_index = N_TEXT | N_EXT;
1224         r_addend += g->section->output_section->vma;
1225       }
1226       else if (g->section->output_section == obj_datasec(abfd)) {
1227         r_index = N_DATA | N_EXT;
1228         r_addend += g->section->output_section->vma;
1229       }
1230       else if (g->section->output_section == obj_bsssec(abfd)) {
1231         r_index = N_BSS | N_EXT ;
1232         r_addend += g->section->output_section->vma;
1233       }
1234       else {
1235         BFD_ASSERT(0);
1236       }
1237     }
1238     
1239     /* now the fun stuff */
1240     if (abfd->xvec->header_byteorder_big_p != false) {
1241       natptr->r_index[0] = r_index >> 16;
1242       natptr->r_index[1] = r_index >> 8;
1243       natptr->r_index[2] = r_index;
1244       natptr->r_type[0] =
1245         (r_extern?    RELOC_STD_BITS_EXTERN_BIG: 0)
1246           | (r_pcrel?     RELOC_STD_BITS_PCREL_BIG: 0)
1247             | (r_baserel?   RELOC_STD_BITS_BASEREL_BIG: 0)
1248               | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_BIG: 0)
1249                 | (r_relative?  RELOC_STD_BITS_RELATIVE_BIG: 0)
1250                   | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG);
1251     } else {
1252       natptr->r_index[2] = r_index >> 16;
1253       natptr->r_index[1] = r_index >> 8;
1254       natptr->r_index[0] = r_index;
1255       natptr->r_type[0] =
1256         (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
1257           | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
1258             | (r_baserel?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
1259               | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1260                 | (r_relative?  RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1261                   | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE);
1262     }
1263   }
1264
1265
1266 /* Extended stuff */
1267 /* Output extended relocation information to a file in target byte order. */
1268
1269 void
1270 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1271       bfd *abfd AND
1272       arelent *g AND
1273       register struct reloc_ext_external *natptr)
1274   {
1275     int r_index;
1276     int r_extern;
1277     unsigned int r_type;
1278     unsigned int r_addend;
1279     
1280     PUT_WORD (abfd, g->address, natptr->r_address);
1281     
1282     /* Find a type in the output format which matches the input howto - 
1283       at the moment we assume input format == output format FIXME!! */
1284     r_type = (enum reloc_type) g->howto->type;
1285     
1286     r_addend = g->addend;       /* Start here, see how it goes */
1287
1288   /* name was clobbered by aout_write_syms to be symbol index*/
1289
1290   if (g->sym_ptr_ptr != NULL) 
1291     {
1292       if ((*(g->sym_ptr_ptr))->section) {
1293         /* put the section offset into the addend for output */
1294         r_addend += (*(g->sym_ptr_ptr))->section->vma;
1295       }
1296
1297       r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
1298       r_extern = 1;
1299     }
1300   else {
1301     r_extern = 0;
1302     if (g->section == NULL) {
1303       BFD_ASSERT(0);
1304       r_index = N_ABS | N_EXT;
1305     }
1306     else  if(g->section->output_section == obj_textsec(abfd)) {
1307       r_index = N_TEXT | N_EXT;
1308       r_addend += g->section->output_section->vma;
1309     }
1310     else if (g->section->output_section == obj_datasec(abfd)) {
1311       r_index = N_DATA | N_EXT;
1312       r_addend += g->section->output_section->vma;
1313     }
1314     else if (g->section->output_section == obj_bsssec(abfd)) {
1315       r_index = N_BSS | N_EXT ;
1316       r_addend += g->section->output_section->vma;
1317     }
1318     else {
1319       BFD_ASSERT(0);
1320     }
1321   }
1322
1323   /* now the fun stuff */
1324   if (abfd->xvec->header_byteorder_big_p != false) {
1325     natptr->r_index[0] = r_index >> 16;
1326     natptr->r_index[1] = r_index >> 8;
1327     natptr->r_index[2] = r_index;
1328     natptr->r_type[0] =
1329       (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1330         | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1331   } else {
1332     natptr->r_index[2] = r_index >> 16;
1333     natptr->r_index[1] = r_index >> 8;
1334     natptr->r_index[0] = r_index;
1335     natptr->r_type[0] =
1336       (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1337         | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1338   }
1339
1340   PUT_WORD (abfd, r_addend, natptr->r_addend);
1341 }
1342
1343 #define MOVE_ADDRESS(ad)                                                \
1344   if (r_extern) {                                                       \
1345     cache_ptr->sym_ptr_ptr = symbols + r_index;                         \
1346     cache_ptr->section = (asection *)NULL;                              \
1347       cache_ptr->addend = ad;                                           \
1348   } else {                                                              \
1349     cache_ptr->sym_ptr_ptr = (asymbol **)NULL;                          \
1350     switch (r_index) {                                                  \
1351     case N_TEXT:                                                        \
1352     case N_TEXT | N_EXT:                                                \
1353       cache_ptr->section = obj_textsec(abfd);                           \
1354       cache_ptr->addend = ad  - su->textsec->vma;                       \
1355       break;                                                            \
1356     case N_DATA:                                                        \
1357     case N_DATA | N_EXT:                                                \
1358       cache_ptr->section = obj_datasec(abfd);                           \
1359       cache_ptr->addend = ad - su->datasec->vma;                        \
1360       break;                                                            \
1361     case N_BSS:                                                         \
1362     case N_BSS | N_EXT:                                                 \
1363       cache_ptr->section = obj_bsssec(abfd);                            \
1364       cache_ptr->addend = ad - su->bsssec->vma;                         \
1365       break;                                                            \
1366     case N_ABS:                                                         \
1367     case N_ABS | N_EXT:                                                 \
1368       cache_ptr->section = NULL;        /* No section */                \
1369       cache_ptr->addend = ad;           /* FIXME, is this right? */     \
1370       BFD_ASSERT(1);                                                    \
1371       break;                                                            \
1372     default:                                                            \
1373       cache_ptr->section = NULL;        /* No section */                \
1374       cache_ptr->addend = ad;           /* FIXME, is this right? */     \
1375       BFD_ASSERT(1);                                                    \
1376       break;                                                            \
1377     }                                                                   \
1378   }                                                                     \
1379
1380 void
1381 DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
1382       bfd *abfd AND
1383       struct reloc_ext_external *bytes AND
1384       arelent *cache_ptr AND
1385       asymbol **symbols)
1386 {
1387   int r_index;
1388   int r_extern;
1389   unsigned int r_type;
1390   struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1391
1392   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
1393
1394   /* now the fun stuff */
1395   if (abfd->xvec->header_byteorder_big_p != false) {
1396     r_index =  (bytes->r_index[0] << 16)
1397              | (bytes->r_index[1] << 8)
1398              |  bytes->r_index[2];
1399     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
1400     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
1401                                       >> RELOC_EXT_BITS_TYPE_SH_BIG;
1402   } else {
1403     r_index =  (bytes->r_index[2] << 16)
1404              | (bytes->r_index[1] << 8)
1405              |  bytes->r_index[0];
1406     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1407     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1408                                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1409   }
1410
1411   cache_ptr->howto =  howto_table_ext + r_type;
1412   MOVE_ADDRESS(GET_SWORD(abfd,bytes->r_addend));
1413 }
1414
1415 void
1416 DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
1417   bfd *abfd AND
1418   struct reloc_std_external *bytes AND
1419   arelent *cache_ptr AND
1420   asymbol **symbols)
1421 {
1422   int r_index;
1423   int r_extern;
1424   unsigned int r_length;
1425   int r_pcrel;
1426   int r_baserel, r_jmptable, r_relative;
1427   struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1428
1429   cache_ptr->address = (int32_type)(bfd_h_get_32 (abfd, bytes->r_address));
1430
1431   /* now the fun stuff */
1432   if (abfd->xvec->header_byteorder_big_p != false) {
1433     r_index =  (bytes->r_index[0] << 16)
1434       | (bytes->r_index[1] << 8)
1435         |  bytes->r_index[2];
1436     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
1437     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
1438     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
1439     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1440     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
1441     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) 
1442                         >> RELOC_STD_BITS_LENGTH_SH_BIG;
1443   } else {
1444     r_index =  (bytes->r_index[2] << 16)
1445       | (bytes->r_index[1] << 8)
1446         |  bytes->r_index[0];
1447     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1448     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
1449     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1450     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1451     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1452     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) 
1453                         >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1454   }
1455
1456   cache_ptr->howto =  howto_table_std + r_length + 4 * r_pcrel;
1457   /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
1458
1459   MOVE_ADDRESS(0);
1460 }
1461
1462 /* Reloc hackery */
1463
1464 boolean
1465 DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
1466       bfd *abfd AND
1467       sec_ptr asect AND
1468       asymbol **symbols)
1469 {
1470   unsigned int count;
1471   bfd_size_type reloc_size;
1472   PTR relocs;
1473   arelent *reloc_cache;
1474   size_t each_size;
1475
1476   if (asect->relocation) return true;
1477
1478   if (asect->flags & SEC_CONSTRUCTOR) return true;
1479
1480   if (asect == obj_datasec (abfd)) {
1481     reloc_size = exec_hdr(abfd)->a_drsize;
1482     goto doit;
1483   }
1484
1485   if (asect == obj_textsec (abfd)) {
1486     reloc_size = exec_hdr(abfd)->a_trsize;
1487     goto doit;
1488   }
1489
1490   bfd_error = invalid_operation;
1491   return false;
1492
1493  doit:
1494   bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1495   each_size = obj_reloc_entry_size (abfd);
1496
1497   count = reloc_size / each_size;
1498
1499
1500   reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1501                                                        (arelent)));
1502   if (!reloc_cache) {
1503 nomem:
1504     bfd_error = no_memory;
1505     return false;
1506   }
1507
1508   relocs = (PTR) bfd_alloc (abfd, reloc_size);
1509   if (!relocs) {
1510     bfd_release (abfd, reloc_cache);
1511     goto nomem;
1512   }
1513
1514   if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1515     bfd_release (abfd, relocs);
1516     bfd_release (abfd, reloc_cache);
1517     bfd_error = system_call_error;
1518     return false;
1519   }
1520
1521   if (each_size == RELOC_EXT_SIZE) {
1522     register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
1523     unsigned int counter = 0;
1524     arelent *cache_ptr = reloc_cache;
1525
1526     for (; counter < count; counter++, rptr++, cache_ptr++) {
1527       NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
1528     }
1529   } else {
1530     register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
1531     unsigned int counter = 0;
1532     arelent *cache_ptr = reloc_cache;
1533
1534     for (; counter < count; counter++, rptr++, cache_ptr++) {
1535         NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
1536     }
1537
1538   }
1539
1540   bfd_release (abfd,relocs);
1541   asect->relocation = reloc_cache;
1542   asect->reloc_count = count;
1543   return true;
1544 }
1545
1546
1547
1548 /* Write out a relocation section into an object file.  */
1549
1550 boolean
1551 DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
1552       bfd *abfd AND
1553       asection *section)
1554 {
1555   arelent **generic;
1556   unsigned char *native, *natptr;
1557   size_t each_size;
1558
1559   unsigned int count = section->reloc_count;
1560   size_t natsize;
1561
1562   if (count == 0) return true;
1563
1564   each_size = obj_reloc_entry_size (abfd);
1565   natsize = each_size * count;
1566   native = (unsigned char *) bfd_zalloc (abfd, natsize);
1567   if (!native) {
1568     bfd_error = no_memory;
1569     return false;
1570   }
1571
1572   generic = section->orelocation;
1573
1574   if (each_size == RELOC_EXT_SIZE) 
1575     {
1576       for (natptr = native;
1577            count != 0;
1578            --count, natptr += each_size, ++generic)
1579         NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
1580     }
1581   else 
1582     {
1583       for (natptr = native;
1584            count != 0;
1585            --count, natptr += each_size, ++generic)
1586         NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
1587     }
1588
1589   if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1590     bfd_release(abfd, native);
1591     return false;
1592   }
1593   bfd_release (abfd, native);
1594
1595   return true;
1596 }
1597
1598 /* This is stupid.  This function should be a boolean predicate */
1599 unsigned int
1600 DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
1601       bfd *abfd AND
1602       sec_ptr section AND
1603       arelent **relptr AND
1604       asymbol **symbols)
1605 {
1606   arelent *tblptr = section->relocation;
1607   unsigned int count;
1608
1609   if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
1610     return 0;
1611
1612   if (section->flags & SEC_CONSTRUCTOR) {
1613     arelent_chain *chain = section->constructor_chain;
1614     for (count = 0; count < section->reloc_count; count ++) {
1615       *relptr ++ = &chain->relent;
1616       chain = chain->next;
1617     }
1618   }
1619   else {
1620     tblptr = section->relocation;
1621     if (!tblptr) return 0;
1622
1623     for (count = 0; count++ < section->reloc_count;) 
1624       {
1625         *relptr++ = tblptr++;
1626       }
1627   }
1628   *relptr = 0;
1629
1630   return section->reloc_count;
1631 }
1632
1633 unsigned int
1634 DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
1635      bfd *abfd AND
1636      sec_ptr asect)
1637 {
1638   if (bfd_get_format (abfd) != bfd_object) {
1639     bfd_error = invalid_operation;
1640     return 0;
1641   }
1642   if (asect->flags & SEC_CONSTRUCTOR) {
1643     return (sizeof (arelent *) * (asect->reloc_count+1));
1644   }
1645
1646
1647   if (asect == obj_datasec (abfd))
1648     return (sizeof (arelent *) *
1649             ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
1650              +1));
1651
1652   if (asect == obj_textsec (abfd))
1653     return (sizeof (arelent *) *
1654             ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
1655              +1));
1656
1657   bfd_error = invalid_operation;
1658   return 0;
1659 }
1660
1661 \f
1662  unsigned int
1663 DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
1664      bfd *abfd)
1665 {
1666   if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1667
1668   return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1669 }
1670  alent *
1671 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
1672       bfd *ignore_abfd AND
1673       asymbol *ignore_symbol)
1674 {
1675 return (alent *)NULL;
1676 }
1677
1678
1679 void 
1680 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
1681       bfd *ignore_abfd AND
1682       PTR afile AND
1683       asymbol *symbol AND
1684       bfd_print_symbol_enum_type how)
1685 {
1686   FILE *file = (FILE *)afile;
1687
1688   switch (how) {
1689   case bfd_print_symbol_name_enum:
1690     fprintf(file,"%s", symbol->name);
1691     break;
1692   case bfd_print_symbol_type_enum:
1693     fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1694             (unsigned)(aout_symbol(symbol)->other & 0xff),
1695             (unsigned)(aout_symbol(symbol)->type));
1696     break;
1697   case bfd_print_symbol_all_enum:
1698     {
1699    CONST char *section_name = symbol->section == (asection *)NULL ?
1700         "*abs" : symbol->section->name;
1701
1702       bfd_print_symbol_vandf((PTR)file,symbol);
1703
1704       fprintf(file," %-5s %04x %02x %02x %s",
1705               section_name,
1706               (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1707               (unsigned)(aout_symbol(symbol)->other & 0xff),
1708               (unsigned)(aout_symbol(symbol)->type  & 0xff),
1709               symbol->name);
1710     }
1711     break;
1712   }
1713 }
1714
1715 /* 
1716  provided a BFD, a section and an offset into the section, calculate
1717  and return the name of the source file and the line nearest to the
1718  wanted location.
1719 */
1720  
1721 boolean
1722 DEFUN(NAME(aout,find_nearest_line),(abfd,
1723                                      section,
1724                                      symbols,
1725                                      offset,
1726                                      filename_ptr,
1727                                      functionname_ptr,
1728                                      line_ptr),
1729       bfd *abfd AND
1730       asection *section AND
1731       asymbol **symbols AND
1732       bfd_vma offset AND
1733       CONST char **filename_ptr AND
1734       CONST char **functionname_ptr AND
1735       unsigned int *line_ptr)
1736 {
1737   /* Run down the file looking for the filename, function and linenumber */
1738   asymbol **p;
1739   static  char buffer[100];
1740   bfd_vma high_line_vma = ~0;
1741   bfd_vma low_func_vma = 0;
1742   asymbol *func = 0;
1743   *filename_ptr = abfd->filename;
1744   *functionname_ptr = 0;
1745   *line_ptr = 0;
1746   if (symbols != (asymbol **)NULL) {
1747     for (p = symbols; *p; p++) {
1748       aout_symbol_type  *q = (aout_symbol_type *)(*p);
1749       switch (q->type){
1750       case N_SO:
1751         *filename_ptr = q->symbol.name;
1752         if (obj_textsec(abfd) != section) {
1753           return true;
1754         }
1755         break;
1756       case N_SLINE:
1757
1758       case N_DSLINE:
1759       case N_BSLINE:
1760         /* We'll keep this if it resolves nearer than the one we have already */
1761         if (q->symbol.value >= offset &&
1762             q->symbol.value < high_line_vma) {
1763           *line_ptr = q->desc;
1764           high_line_vma = q->symbol.value;
1765         }
1766         break;
1767       case N_FUN:
1768         {
1769           /* We'll keep this if it is nearer than the one we have already */
1770           if (q->symbol.value >= low_func_vma &&
1771               q->symbol.value <= offset) {
1772             low_func_vma = q->symbol.value;
1773             func = (asymbol *)q;
1774           }
1775           if (*line_ptr && func) {
1776             CONST char *function = func->name;
1777             char *p;
1778             strncpy(buffer, function, sizeof(buffer)-1);
1779             buffer[sizeof(buffer)-1] = 0;
1780             /* Have to remove : stuff */
1781             p = strchr(buffer,':');
1782             if (p != NULL) { *p = NULL; }
1783             *functionname_ptr = buffer;
1784             return true;
1785
1786           }
1787         }
1788         break;
1789       }
1790     }
1791   }
1792   
1793   return true;
1794
1795 }
1796
1797 int 
1798 DEFUN(NAME(aout,sizeof_headers),(ignore_abfd, execable),
1799       bfd *ignore_abfd AND
1800       boolean execable)
1801 {
1802   return EXEC_BYTES_SIZE;
1803 }