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