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