Minor changes to accomodate merging of three include file directories.
[external/binutils.git] / bfd / sunos.c
1 /*** bfd backend for sunos 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 /* $Id$
22  *
23  */
24
25 #define TARGET_BYTE_ORDER_BIG_P 1
26
27 #include <ansidecl.h>
28 #include "sysdep.h"
29 #include "bfd.h"
30 #include "libbfd.h"
31
32
33 void (*bfd_error_trap)();
34
35 /*SUPPRESS558*/
36 /*SUPPRESS529*/
37
38
39
40
41
42 /* These values are correct for the SPARC.  I dunno about anything else */
43 #define PAGE_SIZE 0x02000
44 #define SEGMENT_SIZE PAGE_SIZE
45 #define TEXT_START_ADDR PAGE_SIZE
46 #include "a.out.gnu.h"
47 #include "stab.gnu.h"
48 #include "ar.h"
49 #include "liba.out.h"           /* BFD a.out internal data structures */
50
51 #include "a.out.sun4.h"
52
53 #define CTOR_TABLE_RELOC_IDX 2
54 static  reloc_howto_type howto_table_ext[] = 
55 {
56   HOWTO(RELOC_8,      0,  0,    8,  false, 0, true,  true,0,"8",      false, 0,0x000000ff, false),
57   HOWTO(RELOC_16,     0,  1,    16, false, 0, true,  true,0,"16",      false, 0,0x0000ffff, false),
58   HOWTO(RELOC_32,     0,  2,    32, false, 0, true,  true,0,"32",      false, 0,0xffffffff, false),
59   HOWTO(RELOC_DISP8,  0,  0,    8,  true,  0, false, true,0,"DISP8",    false, 0,0x000000ff, false),
60   HOWTO(RELOC_DISP16, 0,  1,    16, true,  0, false, true,0,"DISP16",   false, 0,0x0000ffff, false),
61   HOWTO(RELOC_DISP32, 0,  2,    32, true,  0, false, true,0,"DISP32",   false, 0,0xffffffff, false),
62   HOWTO(RELOC_WDISP30,2,  2,    30, true,  0, false, true,0,"WDISP30",  false, 0,0x3fffffff, false),
63   HOWTO(RELOC_WDISP22,2,  2,    22, true,  0, false, true,0,"WDISP22",  false, 0,0x003fffff, false),
64   HOWTO(RELOC_HI22,   10, 2,    22, false, 0, false, true,0,"HI22",     false, 0,0x003fffff, false),
65   HOWTO(RELOC_22,      0, 2,    22, false, 0, false, true,0,"22",       false, 0,0x003fffff, false),
66   HOWTO(RELOC_13,       0, 2,   13, false, 0, false, true,0,"13",       false, 0,0x00001fff, false),
67   HOWTO(RELOC_LO10,     0, 2,   10, false, 0, false, true,0,"LO10",     false, 0,0x000003ff, false),
68   HOWTO(RELOC_SFA_BASE,0, 2,    32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
69   HOWTO(RELOC_SFA_OFF13,0,2,    32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
70   HOWTO(RELOC_BASE10, 0,  2,    16, false, 0, false, true,0,"BASE10",   false, 0,0x0000ffff, false),
71   HOWTO(RELOC_BASE13, 0,  2,    13, false, 0, false, true,0,"BASE13",   false, 0,0x00001fff, false),
72   HOWTO(RELOC_BASE22, 0,  2,    0,  false, 0, false, true,0,"BASE22",   false, 0,0x00000000, false),
73   HOWTO(RELOC_PC10,   0,  2,    10, false, 0, false, true,0,"PC10",     false, 0,0x000003ff, false),
74   HOWTO(RELOC_PC22,   0,  2,    22, false, 0, false, true,0,"PC22",     false, 0,0x003fffff, false),
75   HOWTO(RELOC_JMP_TBL,0,  2,    32, false, 0, false, true,0,"JMP_TBL",  false, 0,0xffffffff, false),
76   HOWTO(RELOC_SEGOFF16,0, 2,    0,  false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
77   HOWTO(RELOC_GLOB_DAT,0, 2,    0,  false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
78   HOWTO(RELOC_JMP_SLOT,0, 2,    0,  false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
79   HOWTO(RELOC_RELATIVE,0, 2,    0,  false, 0, false, true,0,"RELATIVE", false, 0,0x00000000, false),
80   HOWTO(RELOC_JUMPTARG,2, 13,   16, true,  0, false, true,0,"JUMPTARG", false, 0,0x0000ffff, false),
81   HOWTO(RELOC_CONST,    0, 13,  16, false, 0, false, true,0,"CONST",    false, 0,0x0000ffff, false),
82   HOWTO(RELOC_CONSTH, 16, 13,   16, false, 0, false, true,0,"CONSTH",   false, 0,0x0000ffff, false),
83 };
84
85 /* Convert standard reloc records to "arelent" format (incl byte swap).  */
86
87 static  reloc_howto_type howto_table_std[] = {
88   /* type                   rs   size bsz  pcrel bitpos  abs ovrf sf name*/
89 HOWTO( 0,              0,  0,   8,  false, 0, true,  true,0,"8",        true, 0x000000ff,0x000000ff, false),
90 HOWTO( 1,              0,  1,   16, false, 0, true,  true,0,"16",       true, 0x0000ffff,0x0000ffff, false),
91 HOWTO( 2,              0,  2,   32, false, 0, true,  true,0,"32",       true, 0xffffffff,0xffffffff, false),
92 HOWTO( 3,              0,  3,   64, false, 0, true,  true,0,"64",       true, 0xdeaddead,0xdeaddead, false),
93 HOWTO( 4,              0,  0,   8,  true,  0, false, true,0,"DISP8",    true, 0x000000ff,0x000000ff, false),
94 HOWTO( 5,              0,  1,   16, true,  0, false, true,0,"DISP16",   true, 0x0000ffff,0x0000ffff, false),
95 HOWTO( 6,              0,  2,   32, true,  0, false, true,0,"DISP32",   true, 0xffffffff,0xffffffff, false),
96 HOWTO( 7,              0,  3,   64, true,  0, false, true,0,"DISP64",   true, 0xfeedface,0xfeedface, false),
97 };
98
99
100 bfd_error_vector_type bfd_error_vector;
101 /** a.out files */
102
103
104 PROTO (void , sunos4_write_syms, ());
105 PROTO (static boolean,sunos4_squirt_out_relocs,(bfd *abfd, asection *section));
106
107
108 static size_t
109 reloc_size_func(abfd)
110 bfd *abfd;
111 {
112   switch (bfd_get_architecture (abfd)) {
113   case bfd_arch_sparc:
114   case bfd_arch_a29k:
115     return  RELOC_EXT_SIZE;
116   default:
117     return  RELOC_STD_SIZE;
118   }
119 }
120
121 static void
122 DEFUN(bfd_aout_swap_exec_header_in,(abfd, raw_bytes, execp),
123       bfd *abfd AND
124       unsigned char *raw_bytes AND
125       struct exec *execp)
126 {
127   struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
128
129   /* Now fill in fields in the execp, from the bytes in the raw data.  */
130   execp->a_info   = bfd_h_getlong (abfd, bytes->a_info);
131   execp->a_text   = bfd_h_getlong (abfd, bytes->a_text);
132   execp->a_data   = bfd_h_getlong (abfd, bytes->a_data);
133   execp->a_bss    = bfd_h_getlong (abfd, bytes->a_bss);
134   execp->a_syms   = bfd_h_getlong (abfd, bytes->a_syms);
135   execp->a_entry  = bfd_h_getlong (abfd, bytes->a_entry);
136   execp->a_trsize = bfd_h_getlong (abfd, bytes->a_trsize);
137   execp->a_drsize = bfd_h_getlong (abfd, bytes->a_drsize);
138 }
139
140 static void
141 DEFUN(bfd_aout_swap_exec_header_out,(abfd, execp, raw_bytes),
142      bfd *abfd AND
143      struct exec *execp AND 
144      unsigned char *raw_bytes)
145 {
146   struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
147
148   /* Now fill in fields in the raw data, from the fields in the exec struct. */
149   bfd_h_putlong (abfd, execp->a_info  , bytes->a_info);
150   bfd_h_putlong (abfd, execp->a_text  , bytes->a_text);
151   bfd_h_putlong (abfd, execp->a_data  , bytes->a_data);
152   bfd_h_putlong (abfd, execp->a_bss   , bytes->a_bss);
153   bfd_h_putlong (abfd, execp->a_syms  , bytes->a_syms);
154   bfd_h_putlong (abfd, execp->a_entry , bytes->a_entry);
155   bfd_h_putlong (abfd, execp->a_trsize, bytes->a_trsize);
156   bfd_h_putlong (abfd, execp->a_drsize, bytes->a_drsize);
157 }
158
159 /* Steve wants some way to frob this stuff from Saber while he's debugging
160    ld, so we have these funny shadow functions */
161 /* ZMAGIC's start at 0 (making the exec part of the text section),
162   other formats start after the exec
163 */
164 static unsigned int n_txtoff(ptr)
165 struct exec *ptr;
166 {return N_MAGIC(*ptr)== ZMAGIC ? 0: sizeof(struct exec);}
167
168 static unsigned int n_datoff(ptr)
169 struct exec *ptr;
170 {return n_txtoff(ptr) + ptr->a_text;}
171
172 static unsigned int n_treloff(ptr)
173 struct exec *ptr;
174 {return n_datoff(ptr) + ptr->a_data;}
175
176 static unsigned int n_dreloff(ptr)
177 struct exec *ptr;
178 {return n_treloff(ptr) + ptr->a_trsize;}
179
180 static unsigned int n_symoff(ptr)
181 struct exec *ptr;
182 {return n_dreloff(ptr) + ptr->a_drsize;}
183
184 static unsigned int n_stroff(ptr)
185 struct exec *ptr;
186 {return n_symoff(ptr) + ptr->a_syms;}
187
188 static
189 unsigned int n_badmag(ptr)
190      struct exec *ptr;
191 {
192   switch (N_MAGIC(*ptr)) {
193   case OMAGIC: case NMAGIC: case ZMAGIC: return 0;
194   default: return 1;
195   }
196 }
197
198 bfd_target *
199 sunos4_object_p (abfd)
200      bfd *abfd;
201 {
202   unsigned char magicbuf[4];    /* Raw bytes of magic number from file */
203   unsigned long magic;          /* Swapped magic number */
204   unsigned char exec_bytes[EXEC_BYTES_SIZE];    /* Raw bytes of exec hdr */
205   struct exec *execp;
206   PTR rawptr;
207
208   bfd_error = system_call_error;
209
210   if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
211       sizeof (magicbuf))
212     return 0;
213   magic = bfd_h_getlong (abfd, magicbuf);
214
215   /* Baroque syntax to mask deficiencies of the Sun compiler */
216   /* if (N_BADMAG (*((struct exec *) &magic))) return 0; */
217   if (n_badmag ((struct exec *) &magic)) return 0;
218
219   if (bfd_seek (abfd, 0L, false) < 0) return 0;
220
221   if (bfd_read ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
222       != EXEC_BYTES_SIZE) {
223     bfd_error = wrong_format;
224     return 0;
225   }
226
227   /* Use an intermediate variable for clarity */
228   rawptr = (PTR) bfd_zalloc (abfd, sizeof (struct sunexdata) + sizeof (struct exec));
229
230   if (rawptr == NULL) {
231     bfd_error = no_memory;
232     return 0;
233   }
234
235   set_tdata (abfd, ((struct sunexdata *) rawptr));
236   exec_hdr (abfd) = execp =
237     (struct exec *) ((char *)rawptr + sizeof (struct sunexdata));
238
239   bfd_aout_swap_exec_header_in (abfd, exec_bytes, execp);
240
241   /* Set the file flags */
242   abfd->flags = NO_FLAGS;
243   if (execp->a_drsize || execp->a_trsize)
244     abfd->flags |= HAS_RELOC;
245   if (execp->a_entry) 
246     abfd->flags |= EXEC_P;
247   if (execp->a_syms) 
248     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
249
250
251   if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
252   if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
253
254   /* Determine the architecture and machine type of the object file.  */
255   abfd->obj_arch = bfd_arch_unknown;    /* Default values */
256   abfd->obj_machine = 0;
257   switch (N_MACHTYPE (*execp)) {
258
259   case M_UNKNOWN:
260         break;
261
262   case M_68010:
263         abfd->obj_arch = bfd_arch_m68k;
264         abfd->obj_machine = 68010;
265         break;
266
267   case M_68020:
268         abfd->obj_arch = bfd_arch_m68k;
269         abfd->obj_machine = 68020;
270         break;
271
272   case M_SPARC:
273         abfd->obj_arch = bfd_arch_sparc;
274         break;
275
276   case M_386:
277         abfd->obj_arch = bfd_arch_i386;
278         break;
279
280   case M_29K:
281         abfd->obj_arch = bfd_arch_a29k;
282         break;
283
284   default:
285         abfd->obj_arch = bfd_arch_obscure;
286         break;
287   }
288
289   bfd_get_start_address (abfd) = execp->a_entry;
290
291   /* Remember the positions of the string table and symbol table.  */
292   obj_str_filepos (abfd) = n_stroff (execp);
293   obj_sym_filepos (abfd) = n_symoff (execp);
294
295   /* create the sections.  This is raunchy, but bfd_close wants to reclaim
296      them */
297   obj_textsec (abfd) = (asection *)NULL;
298   obj_datasec (abfd) = (asection *)NULL;
299   obj_bsssec (abfd) = (asection *)NULL;
300   obj_aout_symbols(abfd) = (aout_symbol_type *)NULL;
301   (void)bfd_make_section(abfd, ".text");
302   (void)bfd_make_section(abfd, ".data");
303   (void)bfd_make_section(abfd, ".bss");
304
305   obj_datasec (abfd)->size = execp->a_data;
306   obj_bsssec (abfd)->size = execp->a_bss;
307   obj_textsec (abfd)->size = execp->a_text;
308   obj_datasec (abfd)->vma = N_DATADDR(*execp);
309   obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
310   obj_textsec (abfd)->vma = N_TXTADDR(*execp);
311
312   obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
313   obj_datasec (abfd)->filepos = N_DATOFF(*execp);
314
315   obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
316   obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
317
318   obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
319                                (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
320                                (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
321   obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
322                                (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
323                                (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
324   obj_bsssec (abfd)->flags = SEC_ALLOC;
325
326   abfd->sections = obj_textsec (abfd);
327   obj_textsec (abfd)->next = obj_datasec (abfd);
328   obj_datasec (abfd)->next = obj_bsssec (abfd);
329   return abfd->xvec;
330 }
331
332
333 boolean
334 sunos4_mkobject (abfd)
335      bfd *abfd;
336 {
337   char *rawptr;
338
339   bfd_error = system_call_error;
340
341   /* Use an intermediate variable for clarity */
342   rawptr =  bfd_zalloc (abfd,sizeof (struct sunexdata) + sizeof (struct exec));
343
344   if (rawptr == NULL) {
345     bfd_error = no_memory;
346     return false;
347   }
348
349   abfd->tdata = (PTR)((struct sunexdata *) rawptr);
350   exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct sunexdata));
351
352   /* For simplicity's sake we just make all the sections right here. */
353
354   obj_textsec (abfd) = (asection *)NULL;
355   obj_datasec (abfd) = (asection *)NULL;
356   obj_bsssec (abfd) = (asection *)NULL;
357   bfd_make_section (abfd, ".text");
358   bfd_make_section (abfd, ".data");
359   bfd_make_section (abfd, ".bss");
360
361   return true;
362 }
363
364 /* Keep track of machine architecture and machine type for a.out's.
365    Return the machine_type for a particular arch&machine, or M_UNKNOWN
366    if that exact arch&machine can't be represented in a.out format.
367
368    If the architecture is understood, machine type 0 (default) should
369    always be understood.  */
370
371 static enum machine_type
372 aout_machine_type (arch, machine)
373      enum bfd_architecture arch;
374      unsigned long machine;
375 {
376   enum machine_type arch_flags;
377
378   arch_flags = M_UNKNOWN;
379
380   switch (arch) {
381   case bfd_arch_sparc:
382     if (machine == 0)   arch_flags = M_SPARC;
383     break;
384
385   case bfd_arch_m68k:
386     switch (machine) {
387     case 0:             arch_flags = M_68010; break;
388     case 68000:         arch_flags = M_UNKNOWN; break;
389     case 68010:         arch_flags = M_68010; break;
390     case 68020:         arch_flags = M_68020; break;
391     default:            arch_flags = M_UNKNOWN; break;
392     }
393     break;
394
395   case bfd_arch_i386:
396     if (machine == 0)   arch_flags = M_386;
397     break;
398
399   case bfd_arch_a29k:
400     if (machine == 0)   arch_flags = M_29K;
401     break;
402
403   default:
404     arch_flags = M_UNKNOWN;
405     break;
406   }
407   return arch_flags;
408 }
409
410 boolean
411 sunos4_set_arch_mach (abfd, arch, machine)
412      bfd *abfd;
413      enum bfd_architecture arch;
414      unsigned long machine;
415 {
416   abfd->obj_arch = arch;
417   abfd->obj_machine = machine;
418   if (arch != bfd_arch_unknown &&
419       aout_machine_type (arch, machine) == M_UNKNOWN)
420     return false;               /* We can't represent this type */
421   return true;                  /* We're easy ... */
422 }
423
424 boolean
425 sunos4_write_object_contents (abfd)
426      bfd *abfd;
427 {
428   size_t data_pad = 0;
429   unsigned char exec_bytes[EXEC_BYTES_SIZE];
430   struct exec *execp = exec_hdr (abfd);
431
432   execp->a_text = obj_textsec (abfd)->size;
433
434   /* Magic number, maestro, please!  */
435   switch (bfd_get_architecture(abfd)) {
436   case bfd_arch_m68k:
437     switch (bfd_get_machine(abfd)) {
438     case 68010:
439       N_SET_MACHTYPE(*execp, M_68010);
440       break;
441     default:
442     case 68020:
443       N_SET_MACHTYPE(*execp, M_68020);
444       break;
445     }
446     break;
447   case bfd_arch_sparc:
448     N_SET_MACHTYPE(*execp, M_SPARC);
449     break;
450   case bfd_arch_i386:
451     N_SET_MACHTYPE(*execp, M_386);
452     break;
453   case bfd_arch_a29k:
454     N_SET_MACHTYPE(*execp, M_29K);
455     break;
456   default:
457     N_SET_MACHTYPE(*execp, M_UNKNOWN);
458   }
459
460   N_SET_MAGIC (*execp, OMAGIC);
461   if (abfd->flags & D_PAGED) {
462     execp->a_text = obj_textsec (abfd)->size + sizeof(struct exec);
463     N_SET_MAGIC (*execp, ZMAGIC);
464   } else if (abfd->flags & WP_TEXT) {
465     N_SET_MAGIC (*execp, NMAGIC);
466   }
467   N_SET_FLAGS (*execp, 0x1);    /* copied from ld.c; who the hell knows? */
468
469   if (abfd->flags & D_PAGED) 
470       {
471         data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
472                     & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
473
474         if (data_pad > obj_bsssec(abfd)->size)
475           execp->a_bss = 0;
476         else 
477           execp->a_bss = obj_bsssec(abfd)->size - data_pad;
478         execp->a_data = obj_datasec(abfd)->size + data_pad;
479
480       }
481   else {
482     execp->a_data = obj_datasec (abfd)->size;
483     execp->a_bss = obj_bsssec (abfd)->size;
484   }
485
486   execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
487   execp->a_entry = bfd_get_start_address (abfd);
488
489   execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
490                      reloc_size_func(abfd));
491                        
492   execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
493                      reloc_size_func(abfd));
494
495   bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
496
497   bfd_seek (abfd, 0L, false);
498   bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
499
500   /* Now write out reloc info, followed by syms and strings */
501
502   if (bfd_get_symcount (abfd) != 0) 
503     {
504       bfd_seek (abfd,
505                 (long)(N_SYMOFF(*execp)), false);
506
507       sunos4_write_syms (abfd);
508
509       bfd_seek (abfd,   (long)(N_TRELOFF(*execp)), false);
510
511       if (!sunos4_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
512       bfd_seek (abfd, (long)(N_DRELOFF(*execp)), false);
513
514       if (!sunos4_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
515     }
516   return true;
517 }
518
519 /** core files */
520 /** core files */
521
522 #define CORE_MAGIC 0x080456
523 #define CORE_NAMELEN 16
524
525 /* The core structure is taken from the Sun documentation.
526    Unfortunately, they don't document the FPA structure, or at least I
527    can't find it easily.  Fortunately the core header contains its own
528    length.  So this shouldn't cause problems, except for c_ucode, which
529    so far we don't use but is easy to find with a little arithmetic. */
530
531 /* But the reg structure can be gotten from the SPARC processor handbook.
532    This really should be in a GNU include file though so that gdb can use
533    the same info. */
534 struct regs {
535   int r_psr;
536   int r_pc;
537   int r_npc;
538   int r_y;
539   int r_g1;
540   int r_g2;
541   int r_g3;
542   int r_g4;
543   int r_g5;
544   int r_g6;
545   int r_g7;
546   int r_o0;
547   int r_o1;
548   int r_o2;
549   int r_o3;
550   int r_o4;
551   int r_o5;
552   int r_o6;
553   int r_o7;
554 };
555
556 /* Taken from Sun documentation: */
557
558 /* FIXME:  It's worse than we expect.  This struct contains TWO substructs
559    neither of whose size we know, WITH STUFF IN BETWEEN THEM!  We can't
560    even portably access the stuff in between!  */
561
562 struct core {
563   int c_magic;                  /* Corefile magic number */
564   int c_len;                    /* Sizeof (struct core) */
565   struct regs c_regs;           /* General purpose registers */
566   struct exec c_aouthdr;        /* A.out header */
567   int c_signo;                  /* Killing signal, if any */
568   int c_tsize;                  /* Text size (bytes) */
569   int c_dsize;                  /* Data size (bytes) */
570   int c_ssize;                  /* Stack size (bytes) */
571   char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
572   double fp_stuff[1];           /* external FPU state (size unknown by us) */
573                 /* The type "double" is critical here, for alignment.
574                    SunOS declares a struct here, but the struct's alignment
575                    is double since it contains doubles.  */
576   int c_ucode;                  /* Exception no. from u_code */
577                 /* (this member is not accessible by name since we don't
578                     portably know the size of fp_stuff.) */
579 };
580
581 /* Supposedly the user stack grows downward from the bottom of kernel memory.
582    Presuming that this remains true, this definition will work. */
583 #define USRSTACK (-(128*1024*1024))
584
585 PROTO (static void, swapcore, (bfd *abfd, struct core *core));
586
587 /* need this cast b/c ptr is really void * */
588 #define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
589 #define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
590 #define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
591 #define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
592 #define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
593
594 /* These are stored in the bfd's tdata */
595 struct suncordata {
596   struct core *hdr;             /* core file header */
597   asection *data_section;
598   asection *stack_section;
599   asection *reg_section;
600   asection *reg2_section;
601 };
602
603 bfd_target *
604 sunos4_core_file_p (abfd)
605      bfd *abfd;
606 {
607   unsigned char longbuf[4];     /* Raw bytes of various header fields */
608   int core_size;
609   int core_mag;
610   struct core *core;
611   char *rawptr;
612
613   bfd_error = system_call_error;
614
615   if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
616          sizeof (longbuf))
617     return 0;
618   core_mag = bfd_h_getlong (abfd, longbuf);
619
620   if (core_mag != CORE_MAGIC) return 0;
621
622   /* SunOS core headers can vary in length; second word is size; */
623   if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
624          sizeof (longbuf))
625     return 0;
626   core_size = bfd_h_getlong (abfd, longbuf);
627   /* Sanity check */
628   if (core_size > 20000)
629     return 0;
630
631   if (bfd_seek (abfd, 0L, false) < 0) return 0;
632
633   rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
634   if (rawptr == NULL) {
635     bfd_error = no_memory;
636     return 0;
637   }
638
639   core = (struct core *) (rawptr + sizeof (struct suncordata));
640
641   if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
642     bfd_error = system_call_error;
643     free ((PTR)rawptr);
644     return 0;
645   }
646
647   swapcore (abfd, core);
648   set_tdata (abfd, ((struct suncordata *) rawptr));
649   core_hdr (abfd) = core;
650
651   /* create the sections.  This is raunchy, but bfd_close wants to reclaim
652      them */
653   core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
654   if (core_stacksec (abfd) == NULL) {
655 loser:
656     bfd_error = no_memory;
657     free ((PTR)rawptr);
658     return 0;
659   }
660   core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
661   if (core_datasec (abfd) == NULL) {
662 loser1:
663     free ((PTR)core_stacksec (abfd));
664     goto loser;
665   }
666   core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
667   if (core_regsec (abfd) == NULL) {
668 loser2:
669     free ((PTR)core_datasec (abfd));
670     goto loser1;
671   }
672   core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
673   if (core_reg2sec (abfd) == NULL) {
674     free ((PTR)core_regsec (abfd));
675     goto loser2;
676   }
677
678   core_stacksec (abfd)->name = ".stack";
679   core_datasec (abfd)->name = ".data";
680   core_regsec (abfd)->name = ".reg";
681   core_reg2sec (abfd)->name = ".reg2";
682
683   core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
684   core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
685   core_regsec (abfd)->flags = SEC_ALLOC;
686   core_reg2sec (abfd)->flags = SEC_ALLOC;
687
688   core_stacksec (abfd)->size = core->c_ssize;
689   core_datasec (abfd)->size = core->c_dsize;
690   core_regsec (abfd)->size = (sizeof core->c_regs);
691   /* Float regs take up end of struct, except c_ucode.  */
692   core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) -
693                               (file_ptr)(((struct core *)0)->fp_stuff);
694
695   core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize);
696   core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr);
697   core_regsec (abfd)->vma = -1;
698   core_reg2sec (abfd)->vma = -1;
699
700   core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
701   core_datasec (abfd)->filepos = core->c_len;
702                         /* In file header: */
703   core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs);
704   core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
705
706   /* Align to word at least */
707   core_stacksec (abfd)->alignment_power = 2;
708   core_datasec (abfd)->alignment_power = 2;
709   core_regsec (abfd)->alignment_power = 2;
710   core_reg2sec (abfd)->alignment_power = 2;
711
712   abfd->sections = core_stacksec (abfd);
713   core_stacksec (abfd)->next = core_datasec (abfd);
714   core_datasec (abfd)->next = core_regsec (abfd);
715   core_regsec (abfd)->next = core_reg2sec (abfd);
716
717   abfd->section_count = 4;
718
719   return abfd->xvec;
720 }
721
722 char *
723 sunos4_core_file_failing_command (abfd)
724      bfd *abfd;
725 {
726   return core_hdr (abfd)->c_cmdname;
727 }
728
729 int
730 sunos4_core_file_failing_signal (abfd)
731      bfd *abfd;
732 {
733   return core_hdr (abfd)->c_signo;
734 }
735
736 boolean
737 sunos4_core_file_matches_executable_p  (core_bfd, exec_bfd)
738      bfd *core_bfd, *exec_bfd;
739 {
740   if (core_bfd->xvec != exec_bfd->xvec) {
741     bfd_error = system_call_error;
742     return false;
743   }
744
745   return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
746                 sizeof (struct exec)) == 0) ? true : false;
747 }
748
749 /* byte-swap core structure */
750 /* FIXME, this needs more work to swap IN a core struct from raw bytes */
751 static void
752 swapcore (abfd, core)
753      bfd *abfd;
754      struct core *core;
755 {
756   unsigned char exec_bytes[EXEC_BYTES_SIZE];
757
758   core->c_magic = bfd_h_getlong (abfd, (unsigned char *)&core->c_magic);
759   core->c_len   = bfd_h_getlong (abfd, (unsigned char *)&core->c_len  );
760   /* Leave integer registers in target byte order.  */
761   bcopy ((char *)&(core->c_aouthdr), (char *)exec_bytes, EXEC_BYTES_SIZE);
762   bfd_aout_swap_exec_header_in (abfd, exec_bytes, &core->c_aouthdr);
763   core->c_signo = bfd_h_getlong (abfd, (unsigned char *)&core->c_signo);
764   core->c_tsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_tsize);
765   core->c_dsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_dsize);
766   core->c_ssize = bfd_h_getlong (abfd, (unsigned char *)&core->c_ssize);
767   /* Leave FP registers in target byte order.  */
768   /* Leave "c_ucode" unswapped for now, since we can't find it easily.  */
769 }
770 \f
771 /** exec and core file sections */
772
773 boolean
774 sunos4_new_section_hook (abfd, newsect)
775      bfd *abfd;
776      asection *newsect;
777 {
778   /* align to double at least */
779   newsect->alignment_power = 3;
780
781   if (bfd_get_format (abfd) == bfd_object) {
782     if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
783       obj_textsec(abfd)= newsect;
784       return true;
785     }
786
787     if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
788       obj_datasec(abfd) = newsect;
789       return true;
790     }
791
792     if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
793       obj_bsssec(abfd) = newsect;
794       return true;
795     }
796   }
797
798   /* We allow more than three sections internally */
799   return true;
800 }
801
802 boolean
803 sunos4_set_section_contents (abfd, section, location, offset, count)
804      bfd *abfd;
805      sec_ptr section;
806      unsigned char *location;
807      file_ptr offset;
808       int count;
809 {
810   if (abfd->output_has_begun == false)
811       {                         /* set by bfd.c handler */
812         if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL)
813           
814             /*||
815               (obj_textsec (abfd)->size == 0) || (obj_datasec (abfd)->size=
816               0)*/
817             ) 
818             {
819               bfd_error = invalid_operation;
820               return false;
821             }
822
823
824 #if 0
825         if (abfd->flags & D_PAGED)
826             {
827               obj_textsec (abfd)->filepos = sizeof(struct exec);
828               obj_datasec(abfd)->filepos =  obj_textsec (abfd)->size;
829             }
830         else 
831 #endif
832             {
833               obj_textsec (abfd)->filepos = sizeof(struct exec);
834               obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos  + obj_textsec (abfd)->size;
835
836             }
837       }
838   /* regardless, once we know what we're doing, we might as well get going */
839   if (section != obj_bsssec(abfd)) {
840     bfd_seek (abfd, section->filepos + offset, SEEK_SET);
841
842     if (count) {
843       return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
844         true : false;
845     }
846     return false;
847   }
848   return true;
849 }
850 boolean
851 sunos4_get_section_contents (abfd, section, location, offset, count)
852      bfd *abfd;
853      sec_ptr section;
854      PTR location;
855      file_ptr offset;
856      int count;
857 {
858   if (count) {
859     if (offset >= section->size) return false;
860
861     bfd_seek (abfd, section->filepos + offset, SEEK_SET);
862
863     return (bfd_read (location, 1, count, abfd) == count) ? true:false;
864   }
865   else return true;
866 }
867
868 \f
869 /* Classify stabs symbols */
870
871
872 #define sym_in_text_section(sym) \
873      (((sym)->n_type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
874
875 #define sym_in_data_section(sym) \
876      (((sym)->n_type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
877
878 #define sym_in_bss_section(sym) \
879      (((sym)->n_type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
880
881 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
882    zero in the "value" field.  Nonzeroes there are fortrancommon
883    symbols.  */
884 #define sym_is_undefined(sym) \
885         ((sym)->n_type == (N_UNDF | N_EXT) && (sym)->n_value == 0)
886
887 /* Symbol is a global definition if N_EXT is on and if it has
888    a nonzero type field.  */
889 #define sym_is_global_defn(sym) \
890         (((sym)->n_type & N_EXT) && (sym)->n_type & N_TYPE)
891
892 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
893    are on.  */
894 #define sym_is_debugger_info(sym) \
895         ((sym)->n_type & ~(N_EXT | N_TYPE))
896
897 #define sym_is_fortrancommon(sym)       \
898         (((sym)->n_type == (N_EXT)) && (sym)->n_value != 0)
899
900 /* Symbol is absolute if it has N_ABS set */
901 #define sym_is_absolute(sym) \
902                (((sym)->n_type  & N_TYPE)== N_ABS)
903
904
905 #define sym_is_indirect(sym) \
906                (((sym)->n_type  & N_ABS)== N_ABS)
907
908 /* Only in their own functions for ease of debugging; when sym flags have
909    stabilised these should be inlined into their (single) caller */
910
911 static void
912 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd)
913      struct nlist *sym_pointer;
914      aout_symbol_type *cache_ptr;
915      bfd *abfd;
916 {
917   switch (cache_ptr->type & N_TYPE) {
918   case N_SETA:
919   case N_SETT:
920   case N_SETD:
921   case N_SETB:
922     {
923       asection *section = bfd_make_section(abfd,
924                                            cache_ptr->symbol.name);
925       arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
926
927       switch ( (cache_ptr->type  & N_TYPE) ) {
928       case N_SETA:
929         reloc->relent.section =  (asection *)NULL;
930         cache_ptr->symbol.section = (asection *)NULL;
931         break;
932       case N_SETT:
933         reloc->relent.section = (asection *)obj_textsec(abfd);
934         cache_ptr->symbol.value -= reloc->relent.section->vma;
935         break;
936       case N_SETD:
937         reloc->relent.section = (asection *)obj_datasec(abfd);
938         cache_ptr->symbol.value -= reloc->relent.section->vma;
939         break;
940       case N_SETB:
941         reloc->relent.section = (asection *)obj_bsssec(abfd);
942         cache_ptr->symbol.value -= reloc->relent.section->vma;
943         break;
944       }
945       cache_ptr->symbol.section = reloc->relent.section;
946       reloc->relent.addend = cache_ptr->symbol.value ;
947       /* 
948          We modify the symbol to belong to a section depending upon the
949          name of the symbol - probably __CTOR__ or __DTOR__ but we don't
950          really care, and add to the size of the section to contain a
951          pointer to the symbol. Build a reloc entry to relocate to this
952          symbol attached to this section.
953          */
954
955
956       section->flags = SEC_CONSTRUCTOR;
957       section->reloc_count++;
958       section->alignment_power = 2;
959       reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
960       reloc->next = section->constructor_chain;
961       section->constructor_chain = reloc;
962       reloc->relent.address = section->size;
963       section->size += sizeof(int *);
964
965       reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
966       cache_ptr->symbol.flags |=  BSF_DEBUGGING ;
967       }
968     break;
969   default:
970
971     if (sym_is_debugger_info (sym_pointer)) {
972       cache_ptr->symbol.flags = BSF_DEBUGGING ;
973       /* Work out the section correct for this symbol */
974       switch (sym_pointer->n_type & N_TYPE) 
975         {
976         case N_TEXT:
977         case N_FN:
978           cache_ptr->symbol.section = obj_textsec (abfd);
979           cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
980           break;
981         case N_DATA:
982           cache_ptr->symbol.value  -= obj_datasec(abfd)->vma;
983           cache_ptr->symbol.section = obj_datasec (abfd);
984           break;
985         case N_BSS :
986           cache_ptr->symbol.section = obj_bsssec (abfd);
987           cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
988           break;
989         case N_ABS:
990         default:
991           cache_ptr->symbol.section = 0;
992           break;
993         }
994     }
995     else {
996       if (sym_is_fortrancommon (sym_pointer))
997         {
998           cache_ptr->symbol.flags = BSF_FORT_COMM;
999           cache_ptr->symbol.section = (asection *)NULL;
1000         }
1001       else {
1002         if (sym_is_undefined (sym_pointer)) {
1003           cache_ptr->symbol.flags = BSF_UNDEFINED;
1004         }
1005         else if (sym_is_global_defn (sym_pointer)) {
1006           cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1007         }
1008
1009         else if (sym_is_absolute (sym_pointer)) {
1010           cache_ptr->symbol.flags = BSF_ABSOLUTE;
1011         }
1012         else {
1013           cache_ptr->symbol.flags = BSF_LOCAL;
1014         }
1015
1016         /* In a.out, the value of a symbol is always relative to the 
1017          * start of the file, if this is a data symbol we'll subtract
1018          * the size of the text section to get the section relative
1019          * value. If this is a bss symbol (which would be strange)
1020          * we'll subtract the size of the previous two sections
1021          * to find the section relative address.
1022          */
1023
1024         if (sym_in_text_section (sym_pointer))   {
1025           cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
1026           cache_ptr->symbol.section = obj_textsec (abfd);
1027         }
1028         else if (sym_in_data_section (sym_pointer)){
1029           cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
1030           cache_ptr->symbol.section = obj_datasec (abfd);
1031         }
1032         else if (sym_in_bss_section(sym_pointer)) {
1033           cache_ptr->symbol.section = obj_bsssec (abfd);
1034           cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
1035         }
1036         else {
1037           cache_ptr->symbol.section = (asection *)NULL;
1038           cache_ptr->symbol.flags |= BSF_ABSOLUTE;
1039         }
1040       }
1041     }
1042   }
1043 }
1044
1045 void
1046 translate_to_native_sym_flags (sym_pointer, cache_ptr_g, abfd)
1047      struct nlist *sym_pointer;
1048      PTR cache_ptr_g;
1049      bfd *abfd;
1050 {
1051   asymbol *cache_ptr = (asymbol *)cache_ptr_g;
1052
1053   /* FIXME check for wrigin bss */
1054   if (bfd_get_section(cache_ptr)) {
1055     if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
1056       sym_pointer->n_type |= N_BSS;
1057     }
1058     else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
1059       sym_pointer->n_type |= N_DATA;
1060     }
1061     else  if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
1062       sym_pointer->n_type |= N_TEXT;
1063     }
1064     else {
1065
1066       bfd_error_vector.nonrepresentable_section(abfd, bfd_get_output_section(cache_ptr)->name);
1067
1068     }
1069     /* Turn the symbol from section relative to absolute again */
1070     sym_pointer->n_value +=
1071       cache_ptr->section->output_section->vma 
1072         + cache_ptr->section->output_offset ;
1073   }
1074   else {
1075     sym_pointer->n_type |= N_ABS;
1076   }
1077
1078   if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
1079     sym_pointer->n_type = (N_UNDF | N_EXT);
1080     return;
1081   }
1082
1083   if (cache_ptr->flags & BSF_ABSOLUTE) {
1084     sym_pointer->n_type |= N_ABS;
1085   }
1086
1087   if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1088     sym_pointer->n_type |= N_EXT;
1089   }
1090   if (cache_ptr->flags & BSF_DEBUGGING) {
1091     sym_pointer->n_type = ((aout_symbol_type *)cache_ptr)->type;
1092   }
1093   
1094 }
1095 \f
1096 /* Native-level interface to symbols. */
1097
1098 /* We read the symbols into a buffer, which is discarded when this
1099    function exits.  We read the strings into a buffer large enough to
1100    hold them all plus all the cached symbol entries. */
1101
1102 asymbol *
1103 sunos4_make_empty_symbol (abfd)
1104 bfd *abfd;
1105 {
1106   aout_symbol_type  *new =
1107     (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1108   new->symbol.the_bfd = abfd;
1109
1110   return &new->symbol;
1111 }
1112
1113 boolean
1114 DEFUN(sunos4_slurp_symbol_table, (abfd),
1115       bfd *abfd)
1116 {
1117   unsigned int symbol_count;
1118   size_t symbol_size;
1119   size_t string_size;
1120   struct nlist *syms;
1121   char *strings;
1122   aout_symbol_type *cached;
1123
1124   /* If there's no work to be done, don't do any */
1125   if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1126   symbol_size = exec_hdr(abfd)->a_syms;
1127   if (symbol_size == 0) {
1128     bfd_error = no_symbols;
1129     return false;
1130   }
1131
1132   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1133   if (bfd_read ((PTR)&string_size, 4, 1, abfd) != 4)
1134     return false;
1135   string_size = bfd_h_getlong (abfd, (unsigned char *)&string_size);
1136
1137   symbol_count = symbol_size / sizeof (struct nlist);
1138
1139   strings = bfd_alloc(abfd, string_size + 1);
1140   cached = (aout_symbol_type *)
1141            bfd_zalloc(abfd, symbol_count * sizeof(aout_symbol_type));
1142   syms = (struct nlist *) bfd_alloc(abfd, symbol_size);
1143
1144   bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1145   if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
1146   bailout:
1147     return false;
1148   }
1149
1150   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1151   if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
1152     goto bailout;
1153   }
1154
1155   /* OK, now walk the new symtable, cacheing symbol properties */
1156     {
1157       register struct nlist *sym_pointer;
1158       register struct nlist *sym_end = syms + symbol_count;
1159       register aout_symbol_type *cache_ptr = cached;
1160
1161       /* run through the table and byte swap if needed */
1162       for (sym_pointer = syms; sym_pointer < sym_end;  sym_pointer++) {
1163         sym_pointer->n_un.n_strx =
1164           bfd_h_get_x (abfd, &sym_pointer->n_un.n_strx);
1165         sym_pointer->n_desc =
1166           bfd_h_get_x (abfd, &sym_pointer->n_desc);
1167         sym_pointer->n_value =
1168           bfd_h_get_x (abfd, &sym_pointer->n_value);
1169         sym_pointer->n_other = (char)
1170           bfd_h_get_x(abfd, &sym_pointer->n_other);
1171         sym_pointer->n_type = (char)
1172           bfd_h_get_x(abfd, &sym_pointer->n_type);
1173
1174       }
1175
1176       /* Run through table and copy values */
1177       for (sym_pointer = syms, cache_ptr = cached;
1178            sym_pointer < sym_end; sym_pointer++, cache_ptr++) 
1179           {
1180             cache_ptr->symbol.the_bfd = abfd;
1181             if (sym_pointer->n_un.n_strx)
1182               cache_ptr->symbol.name = sym_pointer->n_un.n_strx + strings;
1183             else
1184               cache_ptr->symbol.name = (char *)NULL;
1185             cache_ptr->symbol.value = sym_pointer->n_value;
1186             cache_ptr->desc = sym_pointer->n_desc;
1187             cache_ptr->other = sym_pointer->n_other;
1188             cache_ptr->type = sym_pointer->n_type;
1189             cache_ptr->symbol.udata = 0;
1190             translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1191
1192           }
1193     }
1194
1195   obj_aout_symbols (abfd) =  cached;
1196   bfd_get_symcount (abfd) = symbol_count;
1197   bfd_release (abfd, (PTR)syms);
1198
1199   return true;
1200 }
1201
1202
1203 void
1204 DEFUN(sunos4_write_syms,(abfd),
1205      bfd *abfd)
1206 {
1207   unsigned int count ;
1208   asymbol **generic = bfd_get_outsymbols (abfd);
1209
1210   unsigned int stindex = sizeof(stindex); /* initial string length */
1211
1212   for (count = 0; count < bfd_get_symcount (abfd); count++) {
1213     asymbol *g = generic[count];
1214     struct nlist nsp;
1215
1216     if (g->name) {
1217       unsigned int length = strlen(g->name) +1;
1218       bfd_h_putlong  (abfd, stindex, (unsigned char *)&nsp.n_un.n_strx);
1219       stindex += length;
1220     }
1221     else {
1222       bfd_h_putlong  (abfd, 0, (unsigned char *)&nsp.n_un.n_strx);
1223     }
1224
1225     if (g->the_bfd->xvec->flavour == abfd->xvec->flavour) 
1226       {
1227         nsp.n_desc = aout_symbol( g)->desc;
1228         nsp.n_other = aout_symbol(g)->other;
1229         nsp.n_type = aout_symbol(g)->type;
1230       }
1231     else
1232       {
1233         nsp.n_desc = 0;
1234         nsp.n_other = 0;
1235         nsp.n_type = 0;
1236       }
1237
1238
1239     nsp.n_value = g->value;
1240     translate_to_native_sym_flags (&nsp, (PTR)g, abfd);
1241
1242
1243     bfd_h_putshort (abfd, nsp.n_desc, (unsigned char *)&nsp.n_desc);
1244     bfd_h_putlong  (abfd, nsp.n_value, (unsigned char *)&nsp.n_value);
1245     bfd_write((PTR)&nsp,1, sizeof(nsp), abfd);
1246   }
1247
1248
1249   /* Now output the strings.  Be sure to put string length into correct
1250    * byte ordering before writing it.
1251    */
1252   bfd_h_putlong  (abfd, stindex, (unsigned char *)&stindex);
1253
1254   bfd_write((PTR)&stindex, 1, sizeof(stindex), abfd);
1255   
1256   generic = bfd_get_outsymbols(abfd);
1257   for (count = 0; count < bfd_get_symcount(abfd); count++) 
1258     {
1259       asymbol *g = *(generic++);
1260
1261       if (g->name != (char *)NULL) 
1262         {
1263           size_t length = strlen(g->name)+1;
1264           bfd_write((PTR)g->name, 1, length, abfd);
1265         }
1266       if ((g->flags & BSF_FAKE)==0) {
1267         g->name = itos(count);  /* smash the generic symbol */
1268       }
1269     }
1270 }
1271
1272
1273 void
1274 DEFUN(sunos4_reclaim_symbol_table,(abfd),
1275      bfd *abfd)
1276 {
1277
1278 }
1279 \f
1280 unsigned int
1281 sunos4_get_symtab_upper_bound (abfd)
1282      bfd *abfd;
1283 {
1284   if (!sunos4_slurp_symbol_table (abfd)) return 0;
1285
1286   return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1287 }
1288
1289 unsigned int
1290 sunos4_get_symtab (abfd, location)
1291      bfd *abfd;
1292      asymbol **location;
1293 {
1294   unsigned int counter = 0;
1295   aout_symbol_type *symbase;
1296
1297   if (!sunos4_slurp_symbol_table (abfd)) return 0;
1298
1299   for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1300     *(location++) = (asymbol *)( symbase++);
1301   *location++ =0;
1302   return bfd_get_symcount(abfd);
1303 }
1304
1305 \f
1306 /* Standard reloc stuff */
1307 /* Output standard relocation information to a file in target byte order. */
1308
1309 void
1310 swap_std_reloc_out (abfd, p, natptr, count)
1311      bfd *abfd;
1312      arelent **p;               /* Generic relocation struct */
1313      struct reloc_std_bytes *natptr;
1314      unsigned int count;
1315 {
1316   int r_index;
1317   int r_extern;
1318   unsigned int r_length;
1319   int r_pcrel;
1320   int r_baserel, r_jmptable, r_relative;
1321   unsigned int r_addend;
1322   unsigned int idx;
1323   for (idx = 0; idx < count; idx++, p++, natptr++) 
1324     {
1325       arelent *g = *p;
1326       bfd_h_putlong (abfd, g->address, natptr->r_address);
1327
1328       r_length = g->howto->size; /* Size as a power of two */
1329       r_pcrel  = (int) g->howto->pc_relative;   /* Relative to PC? */
1330       /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
1331       r_baserel = 0;
1332       r_jmptable = 0;
1333       r_relative = 0;
1334
1335       r_addend = g->addend;     /* Start here, see how it goes */
1336
1337       /* name was clobbered by sunos4_write_syms to be symbol index */
1338
1339       if (g->sym_ptr_ptr != NULL) 
1340         {
1341           if ((*(g->sym_ptr_ptr))->section) {
1342             /* put the section offset into the addend for output */
1343             r_addend += (*(g->sym_ptr_ptr))->section->vma;
1344           }
1345
1346           r_index = stoi((*(g->sym_ptr_ptr))->name);
1347           r_extern = 1;
1348         }
1349       else {
1350         r_extern = 0;
1351         if (g->section == NULL) {
1352           BFD_ASSERT(0);
1353           r_index = N_ABS | N_EXT;
1354         }
1355         else  if(g->section->output_section == obj_textsec(abfd)) {
1356           r_index = N_TEXT | N_EXT;
1357           r_addend += g->section->output_section->vma;
1358         }
1359         else if (g->section->output_section == obj_datasec(abfd)) {
1360           r_index = N_DATA | N_EXT;
1361           r_addend += g->section->output_section->vma;
1362         }
1363         else if (g->section->output_section == obj_bsssec(abfd)) {
1364           r_index = N_BSS | N_EXT ;
1365           r_addend += g->section->output_section->vma;
1366         }
1367         else {
1368           BFD_ASSERT(0);
1369         }
1370       }
1371
1372       /* now the fun stuff */
1373       if (abfd->xvec->header_byteorder_big_p != false) {
1374         natptr->r_index[0] = r_index >> 16;
1375         natptr->r_index[1] = r_index >> 8;
1376         natptr->r_index[2] = r_index;
1377         natptr->r_bits[0] =
1378           (r_extern?    RELOC_STD_BITS_EXTERN_BIG: 0)
1379             | (r_pcrel?     RELOC_STD_BITS_PCREL_BIG: 0)
1380               | (r_baserel?   RELOC_STD_BITS_BASEREL_BIG: 0)
1381                 | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_BIG: 0)
1382                   | (r_relative?  RELOC_STD_BITS_RELATIVE_BIG: 0)
1383                     | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG);
1384       } else {
1385         natptr->r_index[2] = r_index >> 16;
1386         natptr->r_index[1] = r_index >> 8;
1387         natptr->r_index[0] = r_index;
1388         natptr->r_bits[0] =
1389           (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
1390             | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
1391               | (r_baserel?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
1392                 | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1393                   | (r_relative?  RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1394                     | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE);
1395       }
1396
1397
1398     }
1399 }
1400
1401
1402 /* Extended stuff */
1403 /* Output extended relocation information to a file in target byte order. */
1404
1405 void
1406 swap_ext_reloc_out (abfd, p, natptr, count)
1407      bfd *abfd;
1408      arelent **p;               /* Generic relocation struct */
1409      register struct reloc_ext_bytes *natptr;
1410      unsigned int count;
1411 {
1412
1413   int r_index;
1414   int r_extern;
1415   unsigned int r_type;
1416   unsigned int r_addend;
1417   unsigned int idx;
1418   for (idx = 0; idx < count; idx++, p++, natptr++) {
1419     arelent *g = *p;
1420
1421     bfd_h_putlong (abfd, g->address, natptr->r_address);
1422
1423     /* Find a type in the output format which matches the input howto - 
1424        at the moment we assume input format == output format FIXME!! */
1425     r_type = (enum reloc_type) g->howto->type;
1426
1427     r_addend = g->addend;       /* Start here, see how it goes */
1428
1429     /* name was clobbered by sunos4_write_syms to be symbol index*/
1430
1431     if (g->sym_ptr_ptr != NULL) 
1432       {
1433         if ((*(g->sym_ptr_ptr))->section) {
1434           /* put the section offset into the addend for output */
1435           r_addend += (*(g->sym_ptr_ptr))->section->vma;
1436         }
1437
1438         r_index = stoi((*(g->sym_ptr_ptr))->name);
1439         r_extern = 1;
1440       }
1441     else {
1442       r_extern = 0;
1443       if (g->section == NULL) {
1444         BFD_ASSERT(0);
1445         r_index = N_ABS | N_EXT;
1446       }
1447       else  if(g->section->output_section == obj_textsec(abfd)) {
1448         r_index = N_TEXT | N_EXT;
1449         r_addend += g->section->output_section->vma;
1450       }
1451       else if (g->section->output_section == obj_datasec(abfd)) {
1452         r_index = N_DATA | N_EXT;
1453         r_addend += g->section->output_section->vma;
1454       }
1455       else if (g->section->output_section == obj_bsssec(abfd)) {
1456         r_index = N_BSS | N_EXT ;
1457         r_addend += g->section->output_section->vma;
1458       }
1459       else {
1460         BFD_ASSERT(0);
1461       }
1462     }
1463
1464     /* now the fun stuff */
1465     if (abfd->xvec->header_byteorder_big_p != false) {
1466       natptr->r_index[0] = r_index >> 16;
1467       natptr->r_index[1] = r_index >> 8;
1468       natptr->r_index[2] = r_index;
1469       natptr->r_bits[0] =
1470         (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1471           || (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1472     } else {
1473       natptr->r_index[2] = r_index >> 16;
1474       natptr->r_index[1] = r_index >> 8;
1475       natptr->r_index[0] = r_index;
1476       natptr->r_bits[0] =
1477         (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1478           || (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1479     }
1480
1481     bfd_h_putlong (abfd, r_addend, natptr->r_addend);
1482   }
1483 }
1484 #define MOVE_ADDRESS(ad)                                                \
1485   if (r_extern) {                                                       \
1486     cache_ptr->sym_ptr_ptr = symbols + r_index;                         \
1487     cache_ptr->section = (asection *)NULL;                              \
1488       cache_ptr->addend = ad;                                           \
1489   } else {                                                              \
1490     cache_ptr->sym_ptr_ptr = (asymbol **)NULL;                          \
1491     switch (r_index) {                                                  \
1492     case N_TEXT:                                                        \
1493     case N_TEXT | N_EXT:                                                \
1494       cache_ptr->section = obj_textsec(abfd);                           \
1495       cache_ptr->addend = ad  - su->textsec->vma;                       \
1496       break;                                                            \
1497     case N_DATA:                                                        \
1498     case N_DATA | N_EXT:                                                \
1499       cache_ptr->section = obj_datasec(abfd);                           \
1500       cache_ptr->addend = ad - su->datasec->vma;                        \
1501       break;                                                            \
1502     case N_BSS:                                                         \
1503     case N_BSS | N_EXT:                                                 \
1504       cache_ptr->section = obj_bsssec(abfd);                            \
1505       cache_ptr->addend = ad - su->bsssec->vma;                         \
1506       break;                                                            \
1507     case N_ABS:                                                         \
1508     case N_ABS | N_EXT:                                                 \
1509       BFD_ASSERT(1);                                                    \
1510       break;                                                            \
1511     default:                                                            \
1512       BFD_ASSERT(1);                                                    \
1513       break;                                                            \
1514     }                                                                   \
1515   }                                                                     \
1516
1517 void
1518 swap_ext_reloc_in (abfd, bytes, cache_ptr, symbols)
1519      bfd *abfd;
1520      struct reloc_ext_bytes *bytes;
1521      arelent *cache_ptr;
1522      asymbol **symbols;
1523 {
1524   int r_index;
1525   int r_extern;
1526   unsigned int r_type;
1527   struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1528
1529   cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1530
1531   /* now the fun stuff */
1532   if (abfd->xvec->header_byteorder_big_p != false) {
1533     r_index =  (bytes->r_index[0] << 16)
1534              | (bytes->r_index[1] << 8)
1535              |  bytes->r_index[2];
1536     r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_BIG));
1537     r_type   =       (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_BIG)
1538                                       >> RELOC_EXT_BITS_TYPE_SH_BIG;
1539   } else {
1540     r_index =  (bytes->r_index[2] << 16)
1541              | (bytes->r_index[1] << 8)
1542              |  bytes->r_index[0];
1543     r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1544     r_type   =       (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1545                                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1546   }
1547
1548   cache_ptr->howto =  howto_table_ext + r_type;
1549   MOVE_ADDRESS(bfd_h_getlong(abfd,bytes->r_addend));
1550                                                                          
1551 }
1552
1553 void
1554 swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
1555      bfd *abfd;
1556  struct reloc_std_bytes *bytes;
1557      arelent *cache_ptr;
1558      asymbol **symbols;
1559 {
1560   int r_index;
1561   int r_extern;
1562   unsigned int r_length;
1563   int r_pcrel;
1564   int r_baserel, r_jmptable, r_relative;
1565   struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1566   cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1567
1568   /* now the fun stuff */
1569   if (abfd->xvec->header_byteorder_big_p != false) {
1570     r_index =  (bytes->r_index[0] << 16)
1571       | (bytes->r_index[1] << 8)
1572         |  bytes->r_index[2];
1573     r_extern  = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_BIG));
1574     r_pcrel   = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_BIG));
1575     r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_BIG));
1576     r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1577     r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_BIG));
1578     r_length  =       (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_BIG) 
1579       >> RELOC_STD_BITS_LENGTH_SH_BIG;
1580   } else {
1581     r_index =  (bytes->r_index[2] << 16)
1582       | (bytes->r_index[1] << 8)
1583         |  bytes->r_index[0];
1584     r_extern  = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1585     r_pcrel   = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_LITTLE));
1586     r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1587     r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1588     r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1589     r_length  =       (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_LITTLE) 
1590       >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1591   }
1592
1593   cache_ptr->howto =  howto_table_std + r_length + 4 * r_pcrel;
1594   /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
1595
1596   MOVE_ADDRESS(0);
1597 }
1598
1599 /* Reloc hackery */
1600
1601 boolean
1602 sunos4_slurp_reloc_table (abfd, asect, symbols)
1603      bfd *abfd;
1604      sec_ptr asect;
1605      asymbol **symbols;
1606 {
1607   unsigned int count;
1608   size_t reloc_size;
1609   PTR relocs;
1610   arelent *reloc_cache;
1611   size_t each_size;
1612
1613   if (asect->relocation) return true;
1614
1615   if (asect->flags & SEC_CONSTRUCTOR) return true;
1616
1617   if (asect == obj_datasec (abfd)) {
1618     reloc_size = exec_hdr(abfd)->a_drsize;
1619     goto doit;
1620   }
1621
1622   if (asect == obj_textsec (abfd)) {
1623     reloc_size = exec_hdr(abfd)->a_trsize;
1624     goto doit;
1625   }
1626
1627   bfd_error = invalid_operation;
1628   return false;
1629
1630  doit:
1631   bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1632   each_size = reloc_size_func(abfd);
1633
1634   count = reloc_size / each_size;
1635
1636
1637   reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1638                                                        (arelent)));
1639   relocs =  bfd_alloc (abfd, reloc_size);
1640
1641   if (bfd_read ( relocs, 1, reloc_size, abfd) != reloc_size) {
1642     bfd_error = system_call_error;
1643     return false;
1644   }
1645
1646   if (each_size == RELOC_EXT_SIZE)
1647     {
1648       register struct reloc_ext_bytes *rptr = (struct reloc_ext_bytes *) relocs;
1649       unsigned int counter = 0;
1650       arelent *cache_ptr = reloc_cache;
1651
1652       for (; counter < count; counter++, rptr++, cache_ptr++) {
1653         swap_ext_reloc_in(abfd, rptr, cache_ptr, symbols);
1654       }
1655     }
1656   else {
1657     register struct reloc_std_bytes *rptr = (struct reloc_std_bytes *) relocs;
1658     unsigned int counter = 0;
1659     arelent *cache_ptr = reloc_cache;
1660
1661     for (; counter < count; counter++, rptr++, cache_ptr++) {
1662         swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
1663     }
1664
1665   }
1666 bfd_release (abfd,relocs);
1667   asect->relocation = reloc_cache;
1668   asect->reloc_count = count;
1669   return true;
1670 }
1671
1672
1673
1674 /* Write out a relocation section into an object file.  */
1675
1676 static boolean
1677 sunos4_squirt_out_relocs (abfd, section)
1678      bfd *abfd;
1679      asection *section;
1680 {
1681   arelent **generic;
1682   unsigned char *native;
1683   size_t each_size;
1684
1685   unsigned int count = section->reloc_count;
1686   size_t natsize;
1687
1688   if (count == 0) return true;
1689
1690   each_size = reloc_size_func(abfd);
1691   natsize = each_size * count;
1692   native = (unsigned char *) bfd_zalloc (abfd, natsize);
1693   if (!native) {
1694     bfd_error = no_memory;
1695     return false;
1696   }
1697
1698   generic = section->orelocation;
1699
1700   if (each_size == RELOC_EXT_SIZE) 
1701     {
1702       swap_ext_reloc_out (abfd,
1703                           generic,
1704                           (struct reloc_ext_bytes *)native,
1705                           count);
1706     }
1707   else 
1708     {
1709       swap_std_reloc_out(abfd, generic, native, count);
1710     }
1711
1712   if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1713     bfd_release(abfd, native);
1714     return false;
1715   }
1716   bfd_release (abfd, native);
1717
1718   return true;
1719 }
1720
1721 /* This is stupid.  This function should be a boolean predicate */
1722 unsigned int
1723 sunos4_canonicalize_reloc (abfd, section, relptr, symbols)
1724      bfd *abfd;
1725      sec_ptr section;
1726      arelent **relptr;
1727      asymbol **symbols;
1728 {
1729   arelent *tblptr = section->relocation;
1730   unsigned int count;
1731
1732   if (!(tblptr || sunos4_slurp_reloc_table (abfd, section, symbols)))
1733     return 0;
1734
1735   if (section->flags & SEC_CONSTRUCTOR) {
1736     arelent_chain *chain = section->constructor_chain;
1737     for (count = 0; count < section->reloc_count; count ++) {
1738       *relptr ++ = &chain->relent;
1739       chain = chain->next;
1740     }
1741   }
1742   else {
1743     tblptr = section->relocation;
1744     if (!tblptr) return 0;
1745
1746     for (count = 0; count++ < section->reloc_count;) 
1747       {
1748         *relptr++ = tblptr++;
1749       }
1750   }
1751   *relptr = 0;
1752
1753   return section->reloc_count;
1754 }
1755
1756 unsigned int
1757 sunos4_get_reloc_upper_bound (abfd, asect)
1758      bfd *abfd;
1759      sec_ptr asect;
1760 {
1761   if (bfd_get_format (abfd) != bfd_object) {
1762     bfd_error = invalid_operation;
1763     return 0;
1764   }
1765   if (asect->flags & SEC_CONSTRUCTOR) {
1766     return (sizeof (arelent *) * (asect->reloc_count+1));
1767   }
1768
1769
1770   if (asect == obj_datasec (abfd))
1771     return (sizeof (arelent *) *
1772             ((exec_hdr(abfd)->a_drsize / reloc_size_func(abfd))
1773              +1));
1774
1775   if (asect == obj_textsec (abfd))
1776     return (sizeof (arelent *) *
1777             ((exec_hdr(abfd)->a_trsize / reloc_size_func(abfd))
1778              +1));
1779
1780   bfd_error = invalid_operation;
1781   return 0;
1782 }
1783
1784 void
1785 sunos4_reclaim_reloc (ignore_abfd, section)
1786      bfd *ignore_abfd;
1787      sec_ptr section;
1788 {
1789
1790 }
1791 \f
1792
1793 alent *
1794 sunos4_get_lineno(ignore_abfd, ignore_symbol)
1795 bfd *ignore_abfd;
1796 PTR ignore_symbol;
1797 {
1798 return (alent *)NULL;
1799 }
1800
1801 void 
1802 sunos4_print_symbol(ignore_abfd, file,  symbol, how)
1803 bfd *ignore_abfd;
1804 FILE *file;
1805 asymbol *symbol;
1806 bfd_print_symbol_enum_type how;
1807 {
1808   switch (how) {
1809   case bfd_print_symbol_name_enum:
1810     fprintf(file,"%s", symbol->name);
1811     break;
1812   case bfd_print_symbol_type_enum:
1813     fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1814             (unsigned)(   aout_symbol(symbol)->other  & 0xff),
1815             (unsigned)(aout_symbol(symbol)->type));
1816     break;
1817   case bfd_print_symbol_all_enum:
1818     {
1819    CONST char *section_name = symbol->section == (asection *)NULL ?
1820         "*abs" : symbol->section->name;
1821
1822       bfd_print_symbol_vandf((PTR)file,symbol);
1823
1824       fprintf(file," %-5s %04x %02x %02x %s",
1825               section_name,
1826               (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1827               (unsigned)(aout_symbol(symbol)->other  & 0xff),
1828               (unsigned)(aout_symbol(symbol)->type  & 0xff),
1829               symbol->name);
1830     }
1831     break;
1832   }
1833 }
1834 /* Once we know all the stuff that could be consed, we know how to clean
1835    it up.  So why don't we? */
1836
1837 boolean
1838 sunos4_close_and_cleanup (abfd)
1839      bfd *abfd;
1840 {
1841   if (!bfd_read_p (abfd))
1842     switch (abfd->format) {
1843     case bfd_archive:
1844       if (!_bfd_write_archive_contents (abfd)) return false; break;
1845     case bfd_object:
1846       if (!sunos4_write_object_contents (abfd))  return false; break;
1847     default: bfd_error = invalid_operation; return false;
1848     }
1849
1850   return true;
1851 }
1852
1853 /* 
1854  provided a bfd, a section and an offset into the section, calculate
1855  and return the name of the source file and the line nearest to the
1856  wanted location.
1857 */
1858  
1859 boolean
1860 DEFUN(sunos4_find_nearest_line,(abfd,
1861                                 section,
1862                                 symbols,
1863                                 offset,
1864                                 filename_ptr,
1865                                 functionname_ptr,
1866                                 line_ptr),
1867       bfd *abfd AND
1868       asection *section AND
1869       asymbol **symbols AND
1870       bfd_vma offset AND
1871       CONST char **filename_ptr AND
1872       CONST char **functionname_ptr AND
1873       unsigned int *line_ptr)
1874 {
1875   /* Run down the file looking for the filename, function and linenumber */
1876   asymbol **p;
1877   static  char buffer[100];
1878   bfd_vma high_line_vma = ~0;
1879   bfd_vma low_func_vma = 0;
1880   asymbol *func = 0;
1881   *filename_ptr = abfd->filename;
1882   *functionname_ptr = 0;
1883   *line_ptr = 0;
1884   if (symbols != (asymbol **)NULL) {
1885     for (p = symbols; *p; p++) {
1886       aout_symbol_type  *q = (aout_symbol_type *)(*p);
1887       switch (q->type){
1888       case N_SO:
1889         *filename_ptr = q->symbol.name;
1890         if (obj_textsec(abfd) != section) {
1891           return true;
1892         }
1893         break;
1894       case N_SLINE:
1895
1896       case N_DSLINE:
1897       case N_BSLINE:
1898         /* We'll keep this if it resolves nearer than the one we have already */
1899         if (q->symbol.value >= offset &&
1900             q->symbol.value < high_line_vma) {
1901           *line_ptr = q->desc;
1902           high_line_vma = q->symbol.value;
1903         }
1904         break;
1905       case N_FUN:
1906         {
1907           /* We'll keep this if it is nearer than the one we have already */
1908           if (q->symbol.value >= low_func_vma &&
1909               q->symbol.value <= offset) {
1910             low_func_vma = q->symbol.value;
1911             func = (asymbol *)q;
1912           }
1913           if (*line_ptr && func) {
1914             CONST char *function = func->name;
1915             char *p;
1916             strncpy(buffer, function, sizeof(buffer)-1);
1917             buffer[sizeof(buffer)-1] = 0;
1918             /* Have to remove : stuff */
1919             p = strchr(buffer,':');
1920             if (p != NULL) {*p = NULL; }
1921             *functionname_ptr = buffer;
1922             return true;
1923
1924           }
1925         }
1926         break;
1927       }
1928     }
1929   }
1930   
1931   return true;
1932
1933 }
1934
1935 static int 
1936 DEFUN(sunos4_sizeof_headers,(abfd),
1937       bfd *abfd)
1938 {
1939 return 0;
1940 }
1941
1942 #define sunos4_openr_next_archived_file bfd_generic_openr_next_archived_file
1943 #define sunos4_generic_stat_arch_elt bfd_generic_stat_arch_elt
1944 #define sunos4_slurp_armap bfd_slurp_bsd_armap
1945 #define sunos4_slurp_extended_name_table bfd_true
1946 #define sunos4_write_armap bsd_write_armap
1947 #define sunos4_truncate_arname bfd_bsd_truncate_arname
1948 bfd_target aout_big_vec =
1949 {
1950   "a.out-generic-big",          /* name */
1951   bfd_target_aout_flavour_enum,
1952   true,                         /* target byte order */
1953   true,                         /* target headers byte order */
1954   (HAS_RELOC | EXEC_P |         /* object flags */
1955    HAS_LINENO | HAS_DEBUG |
1956    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1957   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1958   ' ',                          /* ar_pad_char */
1959   16,                           /* ar_max_namelen */
1960   _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1961   _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1962
1963     {_bfd_dummy_target, sunos4_object_p,
1964        bfd_generic_archive_p, sunos4_core_file_p},
1965     {bfd_false, sunos4_mkobject,
1966        _bfd_generic_mkarchive, bfd_false},
1967
1968   JUMP_TABLE(sunos4)
1969   };
1970
1971
1972 bfd_target aout_little_vec =
1973 {
1974   "a.out-generic-little",               /* name */
1975   bfd_target_aout_flavour_enum,
1976   false,                        /* target byte order */
1977   false,                        /* target headers byte order */
1978   (HAS_RELOC | EXEC_P |         /* object flags */
1979    HAS_LINENO | HAS_DEBUG |
1980    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1981   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1982   ' ',                          /* ar_pad_char */
1983   16,                           /* ar_max_namelen */
1984   _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* data */
1985   _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* hdrs */
1986
1987
1988     {_bfd_dummy_target, sunos4_object_p,
1989        bfd_generic_archive_p, sunos4_core_file_p},
1990     {bfd_false, sunos4_mkobject,
1991        _bfd_generic_mkarchive, bfd_false},
1992
1993   JUMP_TABLE(sunos4)
1994   };
1995