Changed the shape of the howto type yet again.
[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_TROFF(*execp);
316   obj_datasec (abfd)->rel_filepos = N_DROFF(*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_TROFF(*execp)), false);
510
511       if (!sunos4_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
512       bfd_seek (abfd, (long)(N_DROFF(*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 = bfd_zalloc(abfd, symbol_count * sizeof(aout_symbol_type));
1141   syms = bfd_alloc(abfd, symbol_size);
1142
1143   bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1144   if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
1145   bailout:
1146     return false;
1147   }
1148
1149   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1150   if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
1151     goto bailout;
1152   }
1153
1154   /* OK, now walk the new symtable, cacheing symbol properties */
1155     {
1156       register struct nlist *sym_pointer;
1157       register struct nlist *sym_end = syms + symbol_count;
1158       register aout_symbol_type *cache_ptr = cached;
1159
1160       /* run through the table and byte swap if needed */
1161       for (sym_pointer = syms; sym_pointer < sym_end;  sym_pointer++) {
1162         sym_pointer->n_un.n_strx =
1163           bfd_h_get_x (abfd, &sym_pointer->n_un.n_strx);
1164         sym_pointer->n_desc =
1165           bfd_h_get_x (abfd, &sym_pointer->n_desc);
1166         sym_pointer->n_value =
1167           bfd_h_get_x (abfd, &sym_pointer->n_value);
1168         sym_pointer->n_other = (char)
1169           bfd_h_get_x(abfd, &sym_pointer->n_other);
1170         sym_pointer->n_type = (char)
1171           bfd_h_get_x(abfd, &sym_pointer->n_type);
1172
1173       }
1174
1175       /* Run through table and copy values */
1176       for (sym_pointer = syms, cache_ptr = cached;
1177            sym_pointer < sym_end; sym_pointer++, cache_ptr++) 
1178           {
1179             cache_ptr->symbol.the_bfd = abfd;
1180             if (sym_pointer->n_un.n_strx)
1181               cache_ptr->symbol.name = sym_pointer->n_un.n_strx + strings;
1182             else
1183               cache_ptr->symbol.name = (char *)NULL;
1184             cache_ptr->symbol.value = sym_pointer->n_value;
1185             cache_ptr->desc = sym_pointer->n_desc;
1186             cache_ptr->other = sym_pointer->n_other;
1187             cache_ptr->type = sym_pointer->n_type;
1188             cache_ptr->symbol.udata = 0;
1189             translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1190
1191           }
1192     }
1193
1194   obj_aout_symbols (abfd) =  cached;
1195   bfd_get_symcount (abfd) = symbol_count;
1196   bfd_release (abfd, (PTR)syms);
1197
1198   return true;
1199 }
1200
1201
1202 void
1203 DEFUN(sunos4_write_syms,(abfd),
1204      bfd *abfd)
1205 {
1206   unsigned int count ;
1207   asymbol **generic = bfd_get_outsymbols (abfd);
1208
1209   unsigned int stindex = sizeof(stindex); /* initial string length */
1210
1211   for (count = 0; count < bfd_get_symcount (abfd); count++) {
1212     asymbol *g = generic[count];
1213     struct nlist nsp;
1214
1215     if (g->name) {
1216       unsigned int length = strlen(g->name) +1;
1217       bfd_h_putlong  (abfd, stindex, (unsigned char *)&nsp.n_un.n_strx);
1218       stindex += length;
1219     }
1220     else {
1221       bfd_h_putlong  (abfd, 0, (unsigned char *)&nsp.n_un.n_strx);
1222     }
1223
1224     if (g->the_bfd->xvec->flavour == abfd->xvec->flavour) 
1225       {
1226         nsp.n_desc = aout_symbol( g)->desc;
1227         nsp.n_other = aout_symbol(g)->other;
1228         nsp.n_type = aout_symbol(g)->type;
1229       }
1230     else
1231       {
1232         nsp.n_desc = 0;
1233         nsp.n_other = 0;
1234         nsp.n_type = 0;
1235       }
1236
1237
1238     nsp.n_value = g->value;
1239     translate_to_native_sym_flags (&nsp, (PTR)g, abfd);
1240
1241
1242     bfd_h_putshort (abfd, nsp.n_desc, (unsigned char *)&nsp.n_desc);
1243     bfd_h_putlong  (abfd, nsp.n_value, (unsigned char *)&nsp.n_value);
1244     bfd_write((PTR)&nsp,1, sizeof(nsp), abfd);
1245   }
1246
1247
1248   /* Now output the strings.  Be sure to put string length into correct
1249    * byte ordering before writing it.
1250    */
1251   bfd_h_putlong  (abfd, stindex, (unsigned char *)&stindex);
1252
1253   bfd_write((PTR)&stindex, 1, sizeof(stindex), abfd);
1254   
1255   generic = bfd_get_outsymbols(abfd);
1256   for (count = 0; count < bfd_get_symcount(abfd); count++) 
1257     {
1258       asymbol *g = *(generic++);
1259
1260       if (g->name != (char *)NULL) 
1261         {
1262           size_t length = strlen(g->name)+1;
1263           bfd_write((PTR)g->name, 1, length, abfd);
1264         }
1265       if ((g->flags & BSF_FAKE)==0) {
1266         g->name = itos(count);  /* smash the generic symbol */
1267       }
1268     }
1269 }
1270
1271
1272 void
1273 DEFUN(sunos4_reclaim_symbol_table,(abfd),
1274      bfd *abfd)
1275 {
1276
1277 }
1278 \f
1279 unsigned int
1280 sunos4_get_symtab_upper_bound (abfd)
1281      bfd *abfd;
1282 {
1283   if (!sunos4_slurp_symbol_table (abfd)) return 0;
1284
1285   return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1286 }
1287
1288 unsigned int
1289 sunos4_get_symtab (abfd, location)
1290      bfd *abfd;
1291      asymbol **location;
1292 {
1293   unsigned int counter = 0;
1294   aout_symbol_type *symbase;
1295
1296   if (!sunos4_slurp_symbol_table (abfd)) return 0;
1297
1298   for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1299     *(location++) = (asymbol *)( symbase++);
1300   *location++ =0;
1301   return bfd_get_symcount(abfd);
1302 }
1303
1304 \f
1305 /* Standard reloc stuff */
1306 /* Output standard relocation information to a file in target byte order. */
1307
1308 void
1309 swap_std_reloc_out (abfd, p, natptr, count)
1310      bfd *abfd;
1311      arelent **p;               /* Generic relocation struct */
1312      struct reloc_std_bytes *natptr;
1313      unsigned int count;
1314 {
1315   int r_index;
1316   int r_extern;
1317   unsigned int r_length;
1318   int r_pcrel;
1319   int r_baserel, r_jmptable, r_relative;
1320   unsigned int r_addend;
1321   unsigned int idx;
1322   for (idx = 0; idx < count; idx++, p++, natptr++) 
1323     {
1324       arelent *g = *p;
1325       bfd_h_putlong (abfd, g->address, natptr->r_address);
1326
1327       r_length = g->howto->size; /* Size as a power of two */
1328       r_pcrel  = (int) g->howto->pc_relative;   /* Relative to PC? */
1329       /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
1330       r_baserel = 0;
1331       r_jmptable = 0;
1332       r_relative = 0;
1333
1334       r_addend = g->addend;     /* Start here, see how it goes */
1335
1336       /* name was clobbered by sunos4_write_syms to be symbol index */
1337
1338       if (g->sym_ptr_ptr != NULL) 
1339         {
1340           if ((*(g->sym_ptr_ptr))->section) {
1341             /* put the section offset into the addend for output */
1342             r_addend += (*(g->sym_ptr_ptr))->section->vma;
1343           }
1344
1345           r_index = stoi((*(g->sym_ptr_ptr))->name);
1346           r_extern = 1;
1347         }
1348       else {
1349         r_extern = 0;
1350         if (g->section == NULL) {
1351           BFD_ASSERT(0);
1352           r_index = N_ABS | N_EXT;
1353         }
1354         else  if(g->section->output_section == obj_textsec(abfd)) {
1355           r_index = N_TEXT | N_EXT;
1356           r_addend += g->section->output_section->vma;
1357         }
1358         else if (g->section->output_section == obj_datasec(abfd)) {
1359           r_index = N_DATA | N_EXT;
1360           r_addend += g->section->output_section->vma;
1361         }
1362         else if (g->section->output_section == obj_bsssec(abfd)) {
1363           r_index = N_BSS | N_EXT ;
1364           r_addend += g->section->output_section->vma;
1365         }
1366         else {
1367           BFD_ASSERT(0);
1368         }
1369       }
1370
1371       /* now the fun stuff */
1372       if (abfd->xvec->header_byteorder_big_p != false) {
1373         natptr->r_index[0] = r_index >> 16;
1374         natptr->r_index[1] = r_index >> 8;
1375         natptr->r_index[2] = r_index;
1376         natptr->r_bits[0] =
1377           (r_extern?    RELOC_STD_BITS_EXTERN_BIG: 0)
1378             | (r_pcrel?     RELOC_STD_BITS_PCREL_BIG: 0)
1379               | (r_baserel?   RELOC_STD_BITS_BASEREL_BIG: 0)
1380                 | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_BIG: 0)
1381                   | (r_relative?  RELOC_STD_BITS_RELATIVE_BIG: 0)
1382                     | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG);
1383       } else {
1384         natptr->r_index[2] = r_index >> 16;
1385         natptr->r_index[1] = r_index >> 8;
1386         natptr->r_index[0] = r_index;
1387         natptr->r_bits[0] =
1388           (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
1389             | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
1390               | (r_baserel?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
1391                 | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1392                   | (r_relative?  RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1393                     | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE);
1394       }
1395
1396
1397     }
1398 }
1399
1400
1401 /* Extended stuff */
1402 /* Output extended relocation information to a file in target byte order. */
1403
1404 void
1405 swap_ext_reloc_out (abfd, p, natptr, count)
1406      bfd *abfd;
1407      arelent **p;               /* Generic relocation struct */
1408      register struct reloc_ext_bytes *natptr;
1409      unsigned int count;
1410 {
1411
1412   int r_index;
1413   int r_extern;
1414   unsigned int r_type;
1415   unsigned int r_addend;
1416   unsigned int idx;
1417   for (idx = 0; idx < count; idx++, p++, natptr++) {
1418     arelent *g = *p;
1419
1420     bfd_h_putlong (abfd, g->address, natptr->r_address);
1421
1422     /* Find a type in the output format which matches the input howto - 
1423        at the moment we assume input format == output format FIXME!! */
1424     r_type = (enum reloc_type) g->howto->type;
1425
1426     r_addend = g->addend;       /* Start here, see how it goes */
1427
1428     /* name was clobbered by sunos4_write_syms to be symbol index*/
1429
1430     if (g->sym_ptr_ptr != NULL) 
1431       {
1432         if ((*(g->sym_ptr_ptr))->section) {
1433           /* put the section offset into the addend for output */
1434           r_addend += (*(g->sym_ptr_ptr))->section->vma;
1435         }
1436
1437         r_index = stoi((*(g->sym_ptr_ptr))->name);
1438         r_extern = 1;
1439       }
1440     else {
1441       r_extern = 0;
1442       if (g->section == NULL) {
1443         BFD_ASSERT(0);
1444         r_index = N_ABS | N_EXT;
1445       }
1446       else  if(g->section->output_section == obj_textsec(abfd)) {
1447         r_index = N_TEXT | N_EXT;
1448         r_addend += g->section->output_section->vma;
1449       }
1450       else if (g->section->output_section == obj_datasec(abfd)) {
1451         r_index = N_DATA | N_EXT;
1452         r_addend += g->section->output_section->vma;
1453       }
1454       else if (g->section->output_section == obj_bsssec(abfd)) {
1455         r_index = N_BSS | N_EXT ;
1456         r_addend += g->section->output_section->vma;
1457       }
1458       else {
1459         BFD_ASSERT(0);
1460       }
1461     }
1462
1463     /* now the fun stuff */
1464     if (abfd->xvec->header_byteorder_big_p != false) {
1465       natptr->r_index[0] = r_index >> 16;
1466       natptr->r_index[1] = r_index >> 8;
1467       natptr->r_index[2] = r_index;
1468       natptr->r_bits[0] =
1469         (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1470           || (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1471     } else {
1472       natptr->r_index[2] = r_index >> 16;
1473       natptr->r_index[1] = r_index >> 8;
1474       natptr->r_index[0] = r_index;
1475       natptr->r_bits[0] =
1476         (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1477           || (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1478     }
1479
1480     bfd_h_putlong (abfd, r_addend, natptr->r_addend);
1481   }
1482 }
1483 #define MOVE_ADDRESS(ad)                                                \
1484   if (r_extern) {                                                       \
1485     cache_ptr->sym_ptr_ptr = symbols + r_index;                         \
1486     cache_ptr->section = (asection *)NULL;                              \
1487       cache_ptr->addend = ad;                                           \
1488   } else {                                                              \
1489     cache_ptr->sym_ptr_ptr = (asymbol **)NULL;                          \
1490     switch (r_index) {                                                  \
1491     case N_TEXT:                                                        \
1492     case N_TEXT | N_EXT:                                                \
1493       cache_ptr->section = obj_textsec(abfd);                           \
1494       cache_ptr->addend = ad  - su->textsec->vma;                       \
1495       break;                                                            \
1496     case N_DATA:                                                        \
1497     case N_DATA | N_EXT:                                                \
1498       cache_ptr->section = obj_datasec(abfd);                           \
1499       cache_ptr->addend = ad - su->datasec->vma;                        \
1500       break;                                                            \
1501     case N_BSS:                                                         \
1502     case N_BSS | N_EXT:                                                 \
1503       cache_ptr->section = obj_bsssec(abfd);                            \
1504       cache_ptr->addend = ad - su->bsssec->vma;                         \
1505       break;                                                            \
1506     case N_ABS:                                                         \
1507     case N_ABS | N_EXT:                                                 \
1508       BFD_ASSERT(1);                                                    \
1509       break;                                                            \
1510     default:                                                            \
1511       BFD_ASSERT(1);                                                    \
1512       break;                                                            \
1513     }                                                                   \
1514   }                                                                     \
1515
1516 void
1517 swap_ext_reloc_in (abfd, bytes, cache_ptr, symbols)
1518      bfd *abfd;
1519      struct reloc_ext_bytes *bytes;
1520      arelent *cache_ptr;
1521      asymbol **symbols;
1522 {
1523   int r_index;
1524   int r_extern;
1525   unsigned int r_type;
1526   struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1527
1528   cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1529
1530   /* now the fun stuff */
1531   if (abfd->xvec->header_byteorder_big_p != false) {
1532     r_index =  (bytes->r_index[0] << 16)
1533              | (bytes->r_index[1] << 8)
1534              |  bytes->r_index[2];
1535     r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_BIG));
1536     r_type   =       (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_BIG)
1537                                       >> RELOC_EXT_BITS_TYPE_SH_BIG;
1538   } else {
1539     r_index =  (bytes->r_index[2] << 16)
1540              | (bytes->r_index[1] << 8)
1541              |  bytes->r_index[0];
1542     r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1543     r_type   =       (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1544                                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1545   }
1546
1547   cache_ptr->howto =  howto_table_ext + r_type;
1548   MOVE_ADDRESS(bfd_h_getlong(abfd,bytes->r_addend));
1549                                                                          
1550 }
1551
1552 void
1553 swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
1554      bfd *abfd;
1555  struct reloc_std_bytes *bytes;
1556      arelent *cache_ptr;
1557      asymbol **symbols;
1558 {
1559   int r_index;
1560   int r_extern;
1561   unsigned int r_length;
1562   int r_pcrel;
1563   int r_baserel, r_jmptable, r_relative;
1564   struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1565   cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1566
1567   /* now the fun stuff */
1568   if (abfd->xvec->header_byteorder_big_p != false) {
1569     r_index =  (bytes->r_index[0] << 16)
1570       | (bytes->r_index[1] << 8)
1571         |  bytes->r_index[2];
1572     r_extern  = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_BIG));
1573     r_pcrel   = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_BIG));
1574     r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_BIG));
1575     r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1576     r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_BIG));
1577     r_length  =       (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_BIG) 
1578       >> RELOC_STD_BITS_LENGTH_SH_BIG;
1579   } else {
1580     r_index =  (bytes->r_index[2] << 16)
1581       | (bytes->r_index[1] << 8)
1582         |  bytes->r_index[0];
1583     r_extern  = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1584     r_pcrel   = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_LITTLE));
1585     r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1586     r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1587     r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1588     r_length  =       (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_LITTLE) 
1589       >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1590   }
1591
1592   cache_ptr->howto =  howto_table_std + r_length + 4 * r_pcrel;
1593   /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
1594
1595   MOVE_ADDRESS(0);
1596 }
1597
1598 /* Reloc hackery */
1599
1600 boolean
1601 sunos4_slurp_reloc_table (abfd, asect, symbols)
1602      bfd *abfd;
1603      sec_ptr asect;
1604      asymbol **symbols;
1605 {
1606   unsigned int count;
1607   size_t reloc_size;
1608   PTR relocs;
1609   arelent *reloc_cache;
1610   size_t each_size;
1611
1612   if (asect->relocation) return true;
1613
1614   if (asect->flags & SEC_CONSTRUCTOR) return true;
1615
1616   if (asect == obj_datasec (abfd)) {
1617     reloc_size = exec_hdr(abfd)->a_drsize;
1618     goto doit;
1619   }
1620
1621   if (asect == obj_textsec (abfd)) {
1622     reloc_size = exec_hdr(abfd)->a_trsize;
1623     goto doit;
1624   }
1625
1626   bfd_error = invalid_operation;
1627   return false;
1628
1629  doit:
1630   bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1631   each_size = reloc_size_func(abfd);
1632
1633   count = reloc_size / each_size;
1634
1635
1636   reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1637                                                        (arelent)));
1638   relocs =  bfd_alloc (abfd, reloc_size);
1639
1640   if (bfd_read ( relocs, 1, reloc_size, abfd) != reloc_size) {
1641     bfd_error = system_call_error;
1642     return false;
1643   }
1644
1645   if (each_size == RELOC_EXT_SIZE)
1646     {
1647       register struct reloc_ext_bytes *rptr = (struct reloc_ext_bytes *) relocs;
1648       unsigned int counter = 0;
1649       arelent *cache_ptr = reloc_cache;
1650
1651       for (; counter < count; counter++, rptr++, cache_ptr++) {
1652         swap_ext_reloc_in(abfd, rptr, cache_ptr, symbols);
1653       }
1654     }
1655   else {
1656     register struct reloc_std_bytes *rptr = (struct reloc_std_bytes *) relocs;
1657     unsigned int counter = 0;
1658     arelent *cache_ptr = reloc_cache;
1659
1660     for (; counter < count; counter++, rptr++, cache_ptr++) {
1661         swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
1662     }
1663
1664   }
1665 bfd_release (abfd,relocs);
1666   asect->relocation = reloc_cache;
1667   asect->reloc_count = count;
1668   return true;
1669 }
1670
1671
1672
1673 /* Write out a relocation section into an object file.  */
1674
1675 static boolean
1676 sunos4_squirt_out_relocs (abfd, section)
1677      bfd *abfd;
1678      asection *section;
1679 {
1680   arelent **generic;
1681   unsigned char *native;
1682   size_t each_size;
1683
1684   unsigned int count = section->reloc_count;
1685   size_t natsize;
1686
1687   if (count == 0) return true;
1688
1689   each_size = reloc_size_func(abfd);
1690   natsize = each_size * count;
1691   native = (unsigned char *) bfd_zalloc (abfd, natsize);
1692   if (!native) {
1693     bfd_error = no_memory;
1694     return false;
1695   }
1696
1697   generic = section->orelocation;
1698
1699   if (each_size == RELOC_EXT_SIZE) 
1700     {
1701       swap_ext_reloc_out (abfd,
1702                           generic,
1703                           (struct reloc_ext_bytes *)native,
1704                           count);
1705     }
1706   else 
1707     {
1708       swap_std_reloc_out(abfd, generic, native, count);
1709     }
1710
1711   if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1712     bfd_release(abfd, native);
1713     return false;
1714   }
1715   bfd_release (abfd, native);
1716
1717   return true;
1718 }
1719
1720 /* This is stupid.  This function should be a boolean predicate */
1721 unsigned int
1722 sunos4_canonicalize_reloc (abfd, section, relptr, symbols)
1723      bfd *abfd;
1724      sec_ptr section;
1725      arelent **relptr;
1726      asymbol **symbols;
1727 {
1728   arelent *tblptr = section->relocation;
1729   unsigned int count;
1730
1731   if (!(tblptr || sunos4_slurp_reloc_table (abfd, section, symbols)))
1732     return 0;
1733
1734   if (section->flags & SEC_CONSTRUCTOR) {
1735     arelent_chain *chain = section->constructor_chain;
1736     for (count = 0; count < section->reloc_count; count ++) {
1737       *relptr ++ = &chain->relent;
1738       chain = chain->next;
1739     }
1740   }
1741   else {
1742     tblptr = section->relocation;
1743     if (!tblptr) return 0;
1744
1745     for (count = 0; count++ < section->reloc_count;) 
1746       {
1747         *relptr++ = tblptr++;
1748       }
1749   }
1750   *relptr = 0;
1751
1752   return section->reloc_count;
1753 }
1754
1755 unsigned int
1756 sunos4_get_reloc_upper_bound (abfd, asect)
1757      bfd *abfd;
1758      sec_ptr asect;
1759 {
1760   if (bfd_get_format (abfd) != bfd_object) {
1761     bfd_error = invalid_operation;
1762     return 0;
1763   }
1764   if (asect->flags & SEC_CONSTRUCTOR) {
1765     return (sizeof (arelent *) * (asect->reloc_count+1));
1766   }
1767
1768
1769   if (asect == obj_datasec (abfd))
1770     return (sizeof (arelent *) *
1771             ((exec_hdr(abfd)->a_drsize / reloc_size_func(abfd))
1772              +1));
1773
1774   if (asect == obj_textsec (abfd))
1775     return (sizeof (arelent *) *
1776             ((exec_hdr(abfd)->a_trsize / reloc_size_func(abfd))
1777              +1));
1778
1779   bfd_error = invalid_operation;
1780   return 0;
1781 }
1782
1783 void
1784 sunos4_reclaim_reloc (ignore_abfd, section)
1785      bfd *ignore_abfd;
1786      sec_ptr section;
1787 {
1788
1789 }
1790 \f
1791
1792 alent *
1793 sunos4_get_lineno(ignore_abfd, ignore_symbol)
1794 bfd *ignore_abfd;
1795 PTR ignore_symbol;
1796 {
1797 return (alent *)NULL;
1798 }
1799
1800 void 
1801 sunos4_print_symbol(ignore_abfd, file,  symbol, how)
1802 bfd *ignore_abfd;
1803 FILE *file;
1804 asymbol *symbol;
1805 bfd_print_symbol_enum_type how;
1806 {
1807   switch (how) {
1808   case bfd_print_symbol_name_enum:
1809     fprintf(file,"%s", symbol->name);
1810     break;
1811   case bfd_print_symbol_type_enum:
1812     fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1813             (unsigned)(   aout_symbol(symbol)->other  & 0xff),
1814             (unsigned)(aout_symbol(symbol)->type));
1815     break;
1816   case bfd_print_symbol_all_enum:
1817     {
1818    CONST char *section_name = symbol->section == (asection *)NULL ?
1819         "*abs" : symbol->section->name;
1820
1821       bfd_print_symbol_vandf((PTR)file,symbol);
1822
1823       fprintf(file," %-5s %04x %02x %02x %s",
1824               section_name,
1825               (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1826               (unsigned)(aout_symbol(symbol)->other  & 0xff),
1827               (unsigned)(aout_symbol(symbol)->type  & 0xff),
1828               symbol->name);
1829     }
1830     break;
1831   }
1832 }
1833 /* Once we know all the stuff that could be consed, we know how to clean
1834    it up.  So why don't we? */
1835
1836 boolean
1837 sunos4_close_and_cleanup (abfd)
1838      bfd *abfd;
1839 {
1840   if (!bfd_read_p (abfd))
1841     switch (abfd->format) {
1842     case bfd_archive:
1843       if (!_bfd_write_archive_contents (abfd)) return false; break;
1844     case bfd_object:
1845       if (!sunos4_write_object_contents (abfd))  return false; break;
1846     default: bfd_error = invalid_operation; return false;
1847     }
1848
1849   return true;
1850 }
1851
1852 /* 
1853  provided a bfd, a section and an offset into the section, calculate
1854  and return the name of the source file and the line nearest to the
1855  wanted location.
1856 */
1857  
1858 boolean
1859 DEFUN(sunos4_find_nearest_line,(abfd,
1860                                 section,
1861                                 symbols,
1862                                 offset,
1863                                 filename_ptr,
1864                                 functionname_ptr,
1865                                 line_ptr),
1866       bfd *abfd AND
1867       asection *section AND
1868       asymbol **symbols AND
1869       bfd_vma offset AND
1870       CONST char **filename_ptr AND
1871       CONST char **functionname_ptr AND
1872       unsigned int *line_ptr)
1873 {
1874   /* Run down the file looking for the filename, function and linenumber */
1875   asymbol **p;
1876   static  char buffer[100];
1877   bfd_vma high_line_vma = ~0;
1878   bfd_vma low_func_vma = 0;
1879   asymbol *func = 0;
1880   *filename_ptr = abfd->filename;
1881   *functionname_ptr = 0;
1882   *line_ptr = 0;
1883   if (symbols != (asymbol **)NULL) {
1884     for (p = symbols; *p; p++) {
1885       aout_symbol_type  *q = (aout_symbol_type *)(*p);
1886       switch (q->type){
1887       case N_SO:
1888         *filename_ptr = q->symbol.name;
1889         if (obj_textsec(abfd) != section) {
1890           return true;
1891         }
1892         break;
1893       case N_SLINE:
1894
1895       case N_DSLINE:
1896       case N_BSLINE:
1897         /* We'll keep this if it resolves nearer than the one we have already */
1898         if (q->symbol.value >= offset &&
1899             q->symbol.value < high_line_vma) {
1900           *line_ptr = q->desc;
1901           high_line_vma = q->symbol.value;
1902         }
1903         break;
1904       case N_FUN:
1905         {
1906           /* We'll keep this if it is nearer than the one we have already */
1907           if (q->symbol.value >= low_func_vma &&
1908               q->symbol.value <= offset) {
1909             low_func_vma = q->symbol.value;
1910             func = (asymbol *)q;
1911           }
1912           if (*line_ptr && func) {
1913             CONST char *function = func->name;
1914             char *p;
1915             strncpy(buffer, function, sizeof(buffer)-1);
1916             buffer[sizeof(buffer)-1] = 0;
1917             /* Have to remove : stuff */
1918             p = strchr(buffer,':');
1919             if (p != NULL) {*p = NULL; }
1920             *functionname_ptr = buffer;
1921             return true;
1922
1923           }
1924         }
1925         break;
1926       }
1927     }
1928   }
1929   
1930   return true;
1931
1932 }
1933
1934 static int 
1935 DEFUN(sunos4_sizeof_headers,(abfd),
1936       bfd *abfd)
1937 {
1938 return 0;
1939 }
1940
1941 #define sunos4_openr_next_archived_file bfd_generic_openr_next_archived_file
1942 #define sunos4_generic_stat_arch_elt bfd_generic_stat_arch_elt
1943 #define sunos4_slurp_armap bfd_slurp_bsd_armap
1944 #define sunos4_slurp_extended_name_table bfd_true
1945 #define sunos4_write_armap bsd_write_armap
1946 #define sunos4_truncate_arname bfd_bsd_truncate_arname
1947 bfd_target aout_big_vec =
1948 {
1949   "a.out-generic-big",          /* name */
1950   bfd_target_aout_flavour_enum,
1951   true,                         /* target byte order */
1952   true,                         /* target headers byte order */
1953   (HAS_RELOC | EXEC_P |         /* object flags */
1954    HAS_LINENO | HAS_DEBUG |
1955    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1956   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1957   ' ',                          /* ar_pad_char */
1958   16,                           /* ar_max_namelen */
1959   _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1960   _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1961
1962     {_bfd_dummy_target, sunos4_object_p,
1963        bfd_generic_archive_p, sunos4_core_file_p},
1964     {bfd_false, sunos4_mkobject,
1965        _bfd_generic_mkarchive, bfd_false},
1966
1967   JUMP_TABLE(sunos4)
1968   };
1969
1970
1971 bfd_target aout_little_vec =
1972 {
1973   "a.out-generic-little",               /* name */
1974   bfd_target_aout_flavour_enum,
1975   false,                        /* target byte order */
1976   false,                        /* target headers byte order */
1977   (HAS_RELOC | EXEC_P |         /* object flags */
1978    HAS_LINENO | HAS_DEBUG |
1979    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1980   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1981   ' ',                          /* ar_pad_char */
1982   16,                           /* ar_max_namelen */
1983   _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* data */
1984   _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* hdrs */
1985
1986
1987     {_bfd_dummy_target, sunos4_object_p,
1988        bfd_generic_archive_p, sunos4_core_file_p},
1989     {bfd_false, sunos4_mkobject,
1990        _bfd_generic_mkarchive, bfd_false},
1991
1992   JUMP_TABLE(sunos4)
1993   };
1994