* gas/hppa/reloc/reloc.exp: Minor fixes so that SOM & ELF can
[deliverable/binutils-gdb.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 #include <ansidecl.h>
24 #include "sysdep.h"
25 #include "bfd.h"
26 #include "libbfd.h"
27
28 #include "a.out.sun4.h"
29 #include "a.out.gnu.h"
30 #include "stab.gnu.h"
31 #include "ar.h"
32 #include "liba.out.h" /* BFD a.out internal data structures */
33
34 void (*bfd_error_trap)();
35
36 static bfd_target *sunos4_callback ();
37
38 /*SUPPRESS558*/
39 /*SUPPRESS529*/
40
41 bfd_target *
42 sunos4_object_p (abfd)
43 bfd *abfd;
44 {
45 unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
46 unsigned long magic; /* Swapped magic number */
47
48 bfd_error = system_call_error;
49
50 if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
51 sizeof (magicbuf))
52 return 0;
53 magic = bfd_h_getlong (abfd, magicbuf);
54
55 if (N_BADMAG (*((struct exec *) &magic))) return 0;
56
57 return some_aout_object_p (abfd, sunos4_callback);
58 }
59
60 /* Determine the size of a relocation entry, based on the architecture */
61 static void
62 DEFUN(choose_reloc_size,(abfd),
63 bfd *abfd)
64 {
65 switch (abfd->obj_arch) {
66 case bfd_arch_sparc:
67 case bfd_arch_a29k:
68 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
69 break;
70 default:
71 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
72 break;
73 }
74 }
75
76 /* Set parameters about this a.out file that are machine-dependent.
77 This routine is called from some_aout_object_p just before it returns. */
78
79 static bfd_target *
80 sunos4_callback (abfd)
81 bfd *abfd;
82 {
83 struct exec *execp = exec_hdr (abfd);
84
85 /* The virtual memory addresses of the sections */
86 obj_datasec (abfd)->vma = N_DATADDR(*execp);
87 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
88 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
89
90 /* The file offsets of the sections */
91 obj_textsec (abfd)->filepos = EXEC_BYTES_SIZE; /*N_TXTOFF(*execp);*/
92 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
93
94 /* The file offsets of the relocation info */
95 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
96 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
97
98 /* The file offsets of the string table and symbol table. */
99 obj_str_filepos (abfd) = N_STROFF (*execp);
100 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
101
102
103
104 /* Determine the architecture and machine type of the object file. */
105 switch (N_MACHTYPE (*exec_hdr (abfd))) {
106
107 case M_UNKNOWN:
108 abfd->obj_arch = bfd_arch_unknown;
109 abfd->obj_machine = 0;
110 break;
111
112 case M_68010:
113 abfd->obj_arch = bfd_arch_m68k;
114 abfd->obj_machine = 68010;
115 break;
116
117 case M_68020:
118 abfd->obj_arch = bfd_arch_m68k;
119 abfd->obj_machine = 68020;
120 break;
121
122 case M_SPARC:
123 abfd->obj_arch = bfd_arch_sparc;
124 abfd->obj_machine = 0;
125 break;
126
127 case M_386:
128 abfd->obj_arch = bfd_arch_i386;
129 abfd->obj_machine = 0;
130 break;
131
132 case M_29K:
133 abfd->obj_arch = bfd_arch_a29k;
134 abfd->obj_machine = 0;
135 break;
136
137 default:
138 abfd->obj_arch = bfd_arch_obscure;
139 abfd->obj_machine = 0;
140 break;
141 }
142
143 choose_reloc_size(abfd);
144 return abfd->xvec;
145 }
146
147
148 boolean
149 sunos4_mkobject (abfd)
150 bfd *abfd;
151 {
152 char *rawptr;
153
154 bfd_error = system_call_error;
155
156 /* Use an intermediate variable for clarity */
157 rawptr = bfd_zalloc (abfd, sizeof (struct aoutdata) + sizeof (struct exec));
158
159 if (rawptr == NULL) {
160 bfd_error = no_memory;
161 return false;
162 }
163
164 set_tdata (abfd, (struct aoutdata *) rawptr);
165 exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct aoutdata));
166
167 /* For simplicity's sake we just make all the sections right here. */
168
169 obj_textsec (abfd) = (asection *)NULL;
170 obj_datasec (abfd) = (asection *)NULL;
171 obj_bsssec (abfd) = (asection *)NULL;
172 bfd_make_section (abfd, ".text");
173 bfd_make_section (abfd, ".data");
174 bfd_make_section (abfd, ".bss");
175
176 return true;
177 }
178
179 /* Keep track of machine architecture and machine type for a.out's.
180 Return the machine_type for a particular arch&machine, or M_UNKNOWN
181 if that exact arch&machine can't be represented in a.out format.
182
183 If the architecture is understood, machine type 0 (default) should
184 always be understood. */
185
186 static enum machine_type
187 aout_machine_type (arch, machine)
188 enum bfd_architecture arch;
189 unsigned long machine;
190 {
191 enum machine_type arch_flags;
192
193 arch_flags = M_UNKNOWN;
194
195 switch (arch) {
196 case bfd_arch_sparc:
197 if (machine == 0) arch_flags = M_SPARC;
198 break;
199
200 case bfd_arch_m68k:
201 switch (machine) {
202 case 0: arch_flags = M_68010; break;
203 case 68000: arch_flags = M_UNKNOWN; break;
204 case 68010: arch_flags = M_68010; break;
205 case 68020: arch_flags = M_68020; break;
206 default: arch_flags = M_UNKNOWN; break;
207 }
208 break;
209
210 case bfd_arch_i386:
211 if (machine == 0) arch_flags = M_386;
212 break;
213
214 case bfd_arch_a29k:
215 if (machine == 0) arch_flags = M_29K;
216 break;
217
218 default:
219 arch_flags = M_UNKNOWN;
220 break;
221 }
222 return arch_flags;
223 }
224
225 /* Write an object file in SunOS format.
226 Section contents have already been written. We write the
227 file header, symbols, and relocation. */
228
229 boolean
230 sunos4_write_object_contents (abfd)
231 bfd *abfd;
232 {
233 size_t data_pad = 0;
234 unsigned char exec_bytes[EXEC_BYTES_SIZE];
235 struct exec *execp = exec_hdr (abfd);
236
237
238
239 execp->a_text = obj_textsec (abfd)->size;
240
241 /* Magic number, maestro, please! */
242 switch (bfd_get_architecture(abfd)) {
243 case bfd_arch_m68k:
244 switch (bfd_get_machine(abfd)) {
245 case 68010:
246 N_SET_MACHTYPE(*execp, M_68010);
247 break;
248 default:
249 case 68020:
250 N_SET_MACHTYPE(*execp, M_68020);
251 break;
252 }
253 break;
254 case bfd_arch_sparc:
255 N_SET_MACHTYPE(*execp, M_SPARC);
256 break;
257 case bfd_arch_i386:
258 N_SET_MACHTYPE(*execp, M_386);
259 break;
260 case bfd_arch_a29k:
261 N_SET_MACHTYPE(*execp, M_29K);
262 break;
263 default:
264 N_SET_MACHTYPE(*execp, M_UNKNOWN);
265 }
266
267 choose_reloc_size(abfd);
268
269 N_SET_MAGIC (*execp, OMAGIC);
270 if (abfd->flags & D_PAGED) {
271 /* This is not strictly true, but will probably do for the default
272 case. FIXME.
273 */
274
275 execp->a_text = obj_textsec (abfd)->size + EXEC_BYTES_SIZE;
276 N_SET_MAGIC (*execp, ZMAGIC);
277 } else if (abfd->flags & WP_TEXT) {
278 N_SET_MAGIC (*execp, NMAGIC);
279 }
280 N_SET_FLAGS (*execp, 0x1); /* copied from ld.c; who the hell knows? */
281
282 if (abfd->flags & D_PAGED)
283 {
284 data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
285 & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
286
287 if (data_pad > obj_bsssec(abfd)->size)
288 execp->a_bss = 0;
289 else
290 execp->a_bss = obj_bsssec(abfd)->size - data_pad;
291 execp->a_data = obj_datasec(abfd)->size + data_pad;
292
293 }
294 else {
295 execp->a_data = obj_datasec (abfd)->size;
296 execp->a_bss = obj_bsssec (abfd)->size;
297 }
298
299 execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
300 execp->a_entry = bfd_get_start_address (abfd);
301
302
303
304
305 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
306 obj_reloc_entry_size (abfd));
307
308 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
309 obj_reloc_entry_size (abfd));
310
311 bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
312
313 bfd_seek (abfd, 0L, false);
314 bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
315
316 /* Now write out reloc info, followed by syms and strings */
317
318 if (bfd_get_symcount (abfd) != 0)
319 {
320 bfd_seek (abfd,
321 (long)(N_SYMOFF(*execp)), false);
322
323 aout_write_syms (abfd);
324
325 bfd_seek (abfd, (long)(N_TRELOFF(*execp)), false);
326
327 if (!aout_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
328 bfd_seek (abfd, (long)(N_DRELOFF(*execp)), false);
329
330 if (!aout_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
331 }
332 return true;
333 }
334 \f
335 /* core files */
336
337 #define CORE_MAGIC 0x080456
338 #define CORE_NAMELEN 16
339
340 /* The core structure is taken from the Sun documentation.
341 Unfortunately, they don't document the FPA structure, or at least I
342 can't find it easily. Fortunately the core header contains its own
343 length. So this shouldn't cause problems, except for c_ucode, which
344 so far we don't use but is easy to find with a little arithmetic. */
345
346 /* But the reg structure can be gotten from the SPARC processor handbook.
347 This really should be in a GNU include file though so that gdb can use
348 the same info. */
349 struct regs {
350 int r_psr;
351 int r_pc;
352 int r_npc;
353 int r_y;
354 int r_g1;
355 int r_g2;
356 int r_g3;
357 int r_g4;
358 int r_g5;
359 int r_g6;
360 int r_g7;
361 int r_o0;
362 int r_o1;
363 int r_o2;
364 int r_o3;
365 int r_o4;
366 int r_o5;
367 int r_o6;
368 int r_o7;
369 };
370
371 /* Taken from Sun documentation: */
372
373 /* FIXME: It's worse than we expect. This struct contains TWO substructs
374 neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't
375 even portably access the stuff in between! */
376
377 struct core {
378 int c_magic; /* Corefile magic number */
379 int c_len; /* Sizeof (struct core) */
380 struct regs c_regs; /* General purpose registers -- MACHDEP SIZE */
381 struct exec c_aouthdr; /* A.out header */
382 int c_signo; /* Killing signal, if any */
383 int c_tsize; /* Text size (bytes) */
384 int c_dsize; /* Data size (bytes) */
385 int c_ssize; /* Stack size (bytes) */
386 char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
387 double fp_stuff[1]; /* external FPU state (size unknown by us) */
388 /* The type "double" is critical here, for alignment.
389 SunOS declares a struct here, but the struct's alignment
390 is double since it contains doubles. */
391 int c_ucode; /* Exception no. from u_code */
392 /* (this member is not accessible by name since we don't
393 portably know the size of fp_stuff.) */
394 };
395
396 /* Supposedly the user stack grows downward from the bottom of kernel memory.
397 Presuming that this remains true, this definition will work. */
398 #define USRSTACK (-(128*1024*1024))
399
400 PROTO (static void, swapcore, (bfd *abfd, struct core *core));
401
402 /* need this cast b/c ptr is really void * */
403 #define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
404 #define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
405 #define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
406 #define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
407 #define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
408
409 /* These are stored in the bfd's tdata */
410 struct suncordata {
411 struct core *hdr; /* core file header */
412 asection *data_section;
413 asection *stack_section;
414 asection *reg_section;
415 asection *reg2_section;
416 };
417
418 bfd_target *
419 sunos4_core_file_p (abfd)
420 bfd *abfd;
421 {
422 unsigned char longbuf[4]; /* Raw bytes of various header fields */
423 int core_size;
424 int core_mag;
425 struct core *core;
426 char *rawptr;
427
428 bfd_error = system_call_error;
429
430 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
431 sizeof (longbuf))
432 return 0;
433 core_mag = bfd_h_getlong (abfd, longbuf);
434
435 if (core_mag != CORE_MAGIC) return 0;
436
437 /* SunOS core headers can vary in length; second word is size; */
438 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
439 sizeof (longbuf))
440 return 0;
441 core_size = bfd_h_getlong (abfd, longbuf);
442 /* Sanity check */
443 if (core_size > 20000)
444 return 0;
445
446 if (bfd_seek (abfd, 0L, false) < 0) return 0;
447
448 rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
449 if (rawptr == NULL) {
450 bfd_error = no_memory;
451 return 0;
452 }
453
454 core = (struct core *) (rawptr + sizeof (struct suncordata));
455
456 if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
457 bfd_error = system_call_error;
458 bfd_release (abfd, rawptr);
459 return 0;
460 }
461
462 swapcore (abfd, core);
463 set_tdata (abfd, ((struct suncordata *) rawptr));
464 core_hdr (abfd) = core;
465
466 /* create the sections. This is raunchy, but bfd_close wants to reclaim
467 them */
468 core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
469 if (core_stacksec (abfd) == NULL) {
470 loser:
471 bfd_error = no_memory;
472 bfd_release (abfd, rawptr);
473 return 0;
474 }
475 core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
476 if (core_datasec (abfd) == NULL) {
477 loser1:
478 bfd_release (abfd, core_stacksec (abfd));
479 goto loser;
480 }
481 core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
482 if (core_regsec (abfd) == NULL) {
483 loser2:
484 bfd_release (abfd, core_datasec (abfd));
485 goto loser1;
486 }
487 core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
488 if (core_reg2sec (abfd) == NULL) {
489 bfd_release (abfd, core_regsec (abfd));
490 goto loser2;
491 }
492
493 core_stacksec (abfd)->name = ".stack";
494 core_datasec (abfd)->name = ".data";
495 core_regsec (abfd)->name = ".reg";
496 core_reg2sec (abfd)->name = ".reg2";
497
498 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
499 core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
500 core_regsec (abfd)->flags = SEC_ALLOC;
501 core_reg2sec (abfd)->flags = SEC_ALLOC;
502
503 core_stacksec (abfd)->size = core->c_ssize;
504 core_datasec (abfd)->size = core->c_dsize;
505 core_regsec (abfd)->size = (sizeof core->c_regs);
506 /* Float regs take up end of struct, except c_ucode. */
507 core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) -
508 (file_ptr)(((struct core *)0)->fp_stuff);
509
510 core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize);
511 core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr);
512 core_regsec (abfd)->vma = -1;
513 core_reg2sec (abfd)->vma = -1;
514
515 core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
516 core_datasec (abfd)->filepos = core->c_len;
517 /* In file header: */
518 core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs);
519 core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
520
521 /* Align to word at least */
522 core_stacksec (abfd)->alignment_power = 2;
523 core_datasec (abfd)->alignment_power = 2;
524 core_regsec (abfd)->alignment_power = 2;
525 core_reg2sec (abfd)->alignment_power = 2;
526
527 abfd->sections = core_stacksec (abfd);
528 core_stacksec (abfd)->next = core_datasec (abfd);
529 core_datasec (abfd)->next = core_regsec (abfd);
530 core_regsec (abfd)->next = core_reg2sec (abfd);
531
532 abfd->section_count = 4;
533
534 return abfd->xvec;
535 }
536
537 char *
538 sunos4_core_file_failing_command (abfd)
539 bfd *abfd;
540 {
541 return core_hdr (abfd)->c_cmdname;
542 }
543
544 int
545 sunos4_core_file_failing_signal (abfd)
546 bfd *abfd;
547 {
548 return core_hdr (abfd)->c_signo;
549 }
550
551 boolean
552 sunos4_core_file_matches_executable_p (core_bfd, exec_bfd)
553 bfd *core_bfd, *exec_bfd;
554 {
555 if (core_bfd->xvec != exec_bfd->xvec) {
556 bfd_error = system_call_error;
557 return false;
558 }
559
560 return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
561 sizeof (struct exec)) == 0) ? true : false;
562 }
563
564 /* byte-swap core structure */
565 /* FIXME, this needs more work to swap IN a core struct from raw bytes */
566 static void
567 swapcore (abfd, core)
568 bfd *abfd;
569 struct core *core;
570 {
571 unsigned char exec_bytes[EXEC_BYTES_SIZE];
572
573 core->c_magic = bfd_h_getlong (abfd, (unsigned char *)&core->c_magic);
574 core->c_len = bfd_h_getlong (abfd, (unsigned char *)&core->c_len );
575 /* Leave integer registers in target byte order. */
576 bcopy ((char *)&(core->c_aouthdr), (char *)exec_bytes, EXEC_BYTES_SIZE);
577 bfd_aout_swap_exec_header_in (abfd, exec_bytes, &core->c_aouthdr);
578 core->c_signo = bfd_h_getlong (abfd, (unsigned char *)&core->c_signo);
579 core->c_tsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_tsize);
580 core->c_dsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_dsize);
581 core->c_ssize = bfd_h_getlong (abfd, (unsigned char *)&core->c_ssize);
582 /* Leave FP registers in target byte order. */
583 /* Leave "c_ucode" unswapped for now, since we can't find it easily. */
584 }
585 \f
586 /* We use BFD generic archive files. */
587 #define aout_openr_next_archived_file bfd_generic_openr_next_archived_file
588 #define aout_generic_stat_arch_elt bfd_generic_stat_arch_elt
589 #define aout_slurp_armap bfd_slurp_bsd_armap
590 #define aout_slurp_extended_name_table bfd_true
591 #define aout_write_armap bsd_write_armap
592 #define aout_truncate_arname bfd_bsd_truncate_arname
593
594 /* We use our own core file format. */
595 #define aout_core_file_failing_command sunos4_core_file_failing_command
596 #define aout_core_file_failing_signal sunos4_core_file_failing_signal
597 #define aout_core_file_matches_executable_p \
598 sunos4_core_file_matches_executable_p
599
600 /* We implement these routines ourselves, rather than using the generic
601 a.out versions. */
602 #define aout_write_object_contents sunos4_write_object_contents
603
604 bfd_target sunos_big_vec =
605 {
606 "a.out-sunos-big", /* name */
607 bfd_target_aout_flavour_enum,
608 true, /* target byte order */
609 true, /* target headers byte order */
610 (HAS_RELOC | EXEC_P | /* object flags */
611 HAS_LINENO | HAS_DEBUG |
612 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
613 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
614 ' ', /* ar_pad_char */
615 16, /* ar_max_namelen */
616 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
617 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
618
619 {_bfd_dummy_target, sunos4_object_p,
620 bfd_generic_archive_p, sunos4_core_file_p},
621 {bfd_false, sunos4_mkobject,
622 _bfd_generic_mkarchive, bfd_false},
623 {bfd_false, sunos4_write_object_contents, /* bfd_write_contents */
624 _bfd_write_archive_contents, bfd_false},
625
626 JUMP_TABLE(aout)
627 };
This page took 0.041808 seconds and 4 git commands to generate.