1 /*** bfd backend for sunos binaries */
4 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
6 This file is part of BFD, the Binary File Diddler.
8 BFD is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
13 BFD is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with BFD; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
29 #include "a.out.sun4.h"
30 #include "a.out.gnu.h"
33 #include "liba.out.h" /* BFD a.out internal data structures */
35 void (*bfd_error_trap)();
40 #define CTOR_TABLE_RELOC_IDX 2
41 static reloc_howto_type howto_table_ext[] =
43 HOWTO(RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false),
44 HOWTO(RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false),
45 HOWTO(RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff, false),
46 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, false, true,0,"DISP8", false, 0,0x000000ff, false),
47 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, false, true,0,"DISP16", false, 0,0x0000ffff, false),
48 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, false, true,0,"DISP32", false, 0,0xffffffff, false),
49 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, false, true,0,"WDISP30", false, 0,0x3fffffff, false),
50 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, false, true,0,"WDISP22", false, 0,0x003fffff, false),
51 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, false, true,0,"HI22", false, 0,0x003fffff, false),
52 HOWTO(RELOC_22, 0, 2, 22, false, 0, false, true,0,"22", false, 0,0x003fffff, false),
53 HOWTO(RELOC_13, 0, 2, 13, false, 0, false, true,0,"13", false, 0,0x00001fff, false),
54 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, false, true,0,"LO10", false, 0,0x000003ff, false),
55 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
56 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
57 HOWTO(RELOC_BASE10, 0, 2, 16, false, 0, false, true,0,"BASE10", false, 0,0x0000ffff, false),
58 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, false, true,0,"BASE13", false, 0,0x00001fff, false),
59 HOWTO(RELOC_BASE22, 0, 2, 0, false, 0, false, true,0,"BASE22", false, 0,0x00000000, false),
60 HOWTO(RELOC_PC10, 0, 2, 10, false, 0, false, true,0,"PC10", false, 0,0x000003ff, false),
61 HOWTO(RELOC_PC22, 0, 2, 22, false, 0, false, true,0,"PC22", false, 0,0x003fffff, false),
62 HOWTO(RELOC_JMP_TBL,0, 2, 32, false, 0, false, true,0,"JMP_TBL", false, 0,0xffffffff, false),
63 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
64 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
65 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
66 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, false, true,0,"RELATIVE", false, 0,0x00000000, false),
67 HOWTO(RELOC_JUMPTARG,2, 13, 16, true, 0, false, true,0,"JUMPTARG", false, 0,0x0000ffff, false),
68 HOWTO(RELOC_CONST, 0, 13, 16, false, 0, false, true,0,"CONST", false, 0,0x0000ffff, false),
69 HOWTO(RELOC_CONSTH, 16, 13, 16, false, 0, false, true,0,"CONSTH", false, 0,0x0000ffff, false),
72 /* Convert standard reloc records to "arelent" format (incl byte swap). */
74 static reloc_howto_type howto_table_std[] = {
75 /* type rs size bsz pcrel bitpos abs ovrf sf name part_inpl readmask setmask pcdone */
76 HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),
77 HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),
78 HOWTO( 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff, false),
79 HOWTO( 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead, false),
80 HOWTO( 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff, false),
81 HOWTO( 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
82 HOWTO( 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff, false),
83 HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface, false),
87 bfd_error_vector_type bfd_error_vector;
89 PROTO (void , sunos4_write_syms, ());
90 PROTO (static boolean,sunos4_squirt_out_relocs,(bfd *abfd, asection *section));
97 switch (bfd_get_architecture (abfd)) {
100 return RELOC_EXT_SIZE;
102 return RELOC_STD_SIZE;
107 DEFUN(bfd_aout_swap_exec_header_in,(abfd, raw_bytes, execp),
109 unsigned char *raw_bytes AND
112 struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
114 /* Now fill in fields in the execp, from the bytes in the raw data. */
115 execp->a_info = bfd_h_getlong (abfd, bytes->a_info);
116 execp->a_text = bfd_h_getlong (abfd, bytes->a_text);
117 execp->a_data = bfd_h_getlong (abfd, bytes->a_data);
118 execp->a_bss = bfd_h_getlong (abfd, bytes->a_bss);
119 execp->a_syms = bfd_h_getlong (abfd, bytes->a_syms);
120 execp->a_entry = bfd_h_getlong (abfd, bytes->a_entry);
121 execp->a_trsize = bfd_h_getlong (abfd, bytes->a_trsize);
122 execp->a_drsize = bfd_h_getlong (abfd, bytes->a_drsize);
126 DEFUN(bfd_aout_swap_exec_header_out,(abfd, execp, raw_bytes),
128 struct exec *execp AND
129 unsigned char *raw_bytes)
131 struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
133 /* Now fill in fields in the raw data, from the fields in the exec struct. */
134 bfd_h_putlong (abfd, execp->a_info , bytes->a_info);
135 bfd_h_putlong (abfd, execp->a_text , bytes->a_text);
136 bfd_h_putlong (abfd, execp->a_data , bytes->a_data);
137 bfd_h_putlong (abfd, execp->a_bss , bytes->a_bss);
138 bfd_h_putlong (abfd, execp->a_syms , bytes->a_syms);
139 bfd_h_putlong (abfd, execp->a_entry , bytes->a_entry);
140 bfd_h_putlong (abfd, execp->a_trsize, bytes->a_trsize);
141 bfd_h_putlong (abfd, execp->a_drsize, bytes->a_drsize);
145 sunos4_object_p (abfd)
148 unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
149 unsigned long magic; /* Swapped magic number */
150 unsigned char exec_bytes[EXEC_BYTES_SIZE]; /* Raw bytes of exec hdr */
154 bfd_error = system_call_error;
156 if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
159 magic = bfd_h_getlong (abfd, magicbuf);
161 if (N_BADMAG (*((struct exec *) &magic))) return 0;
163 if (bfd_seek (abfd, 0L, false) < 0) return 0;
165 if (bfd_read ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
166 != EXEC_BYTES_SIZE) {
167 bfd_error = wrong_format;
171 /* Use an intermediate variable for clarity */
172 rawptr = (PTR) bfd_zalloc (abfd, sizeof (struct sunexdata) + sizeof (struct exec));
174 if (rawptr == NULL) {
175 bfd_error = no_memory;
179 set_tdata (abfd, ((struct sunexdata *) rawptr));
180 exec_hdr (abfd) = execp =
181 (struct exec *) ((char *)rawptr + sizeof (struct sunexdata));
183 bfd_aout_swap_exec_header_in (abfd, exec_bytes, execp);
185 /* Set the file flags */
186 abfd->flags = NO_FLAGS;
187 if (execp->a_drsize || execp->a_trsize)
188 abfd->flags |= HAS_RELOC;
190 abfd->flags |= EXEC_P;
192 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
195 if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
196 if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
198 /* Determine the architecture and machine type of the object file. */
199 abfd->obj_arch = bfd_arch_unknown; /* Default values */
200 abfd->obj_machine = 0;
201 switch (N_MACHTYPE (*execp)) {
207 abfd->obj_arch = bfd_arch_m68k;
208 abfd->obj_machine = 68010;
212 abfd->obj_arch = bfd_arch_m68k;
213 abfd->obj_machine = 68020;
217 abfd->obj_arch = bfd_arch_sparc;
221 abfd->obj_arch = bfd_arch_i386;
225 abfd->obj_arch = bfd_arch_a29k;
229 abfd->obj_arch = bfd_arch_obscure;
233 bfd_get_start_address (abfd) = execp->a_entry;
235 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct nlist);
237 /* Remember the positions of the string table and symbol table. */
238 obj_str_filepos (abfd) = N_STROFF (*execp);
239 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
241 /* create the sections. This is raunchy, but bfd_close wants to reclaim
243 obj_textsec (abfd) = (asection *)NULL;
244 obj_datasec (abfd) = (asection *)NULL;
245 obj_bsssec (abfd) = (asection *)NULL;
246 obj_aout_symbols(abfd) = (aout_symbol_type *)NULL;
247 (void)bfd_make_section(abfd, ".text");
248 (void)bfd_make_section(abfd, ".data");
249 (void)bfd_make_section(abfd, ".bss");
251 obj_datasec (abfd)->size = execp->a_data;
252 obj_bsssec (abfd)->size = execp->a_bss;
253 obj_textsec (abfd)->size = execp->a_text;
254 obj_datasec (abfd)->vma = N_DATADDR(*execp);
255 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
256 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
258 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
259 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
261 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
262 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
264 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
265 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
266 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
267 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
268 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
269 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
270 obj_bsssec (abfd)->flags = SEC_ALLOC;
272 abfd->sections = obj_textsec (abfd);
273 obj_textsec (abfd)->next = obj_datasec (abfd);
274 obj_datasec (abfd)->next = obj_bsssec (abfd);
280 sunos4_mkobject (abfd)
285 bfd_error = system_call_error;
287 /* Use an intermediate variable for clarity */
288 rawptr = bfd_zalloc (abfd, sizeof (struct sunexdata) + sizeof (struct exec));
290 if (rawptr == NULL) {
291 bfd_error = no_memory;
295 set_tdata (abfd, (struct sunexdata *) rawptr);
296 exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct sunexdata));
298 /* For simplicity's sake we just make all the sections right here. */
300 obj_textsec (abfd) = (asection *)NULL;
301 obj_datasec (abfd) = (asection *)NULL;
302 obj_bsssec (abfd) = (asection *)NULL;
303 bfd_make_section (abfd, ".text");
304 bfd_make_section (abfd, ".data");
305 bfd_make_section (abfd, ".bss");
310 /* Keep track of machine architecture and machine type for a.out's.
311 Return the machine_type for a particular arch&machine, or M_UNKNOWN
312 if that exact arch&machine can't be represented in a.out format.
314 If the architecture is understood, machine type 0 (default) should
315 always be understood. */
317 static enum machine_type
318 aout_machine_type (arch, machine)
319 enum bfd_architecture arch;
320 unsigned long machine;
322 enum machine_type arch_flags;
324 arch_flags = M_UNKNOWN;
328 if (machine == 0) arch_flags = M_SPARC;
333 case 0: arch_flags = M_68010; break;
334 case 68000: arch_flags = M_UNKNOWN; break;
335 case 68010: arch_flags = M_68010; break;
336 case 68020: arch_flags = M_68020; break;
337 default: arch_flags = M_UNKNOWN; break;
342 if (machine == 0) arch_flags = M_386;
346 if (machine == 0) arch_flags = M_29K;
350 arch_flags = M_UNKNOWN;
357 sunos4_set_arch_mach (abfd, arch, machine)
359 enum bfd_architecture arch;
360 unsigned long machine;
362 abfd->obj_arch = arch;
363 abfd->obj_machine = machine;
364 if (arch != bfd_arch_unknown &&
365 aout_machine_type (arch, machine) == M_UNKNOWN)
366 return false; /* We can't represent this type */
367 return true; /* We're easy ... */
371 sunos4_write_object_contents (abfd)
375 unsigned char exec_bytes[EXEC_BYTES_SIZE];
376 struct exec *execp = exec_hdr (abfd);
378 execp->a_text = obj_textsec (abfd)->size;
380 /* Magic number, maestro, please! */
381 switch (bfd_get_architecture(abfd)) {
383 switch (bfd_get_machine(abfd)) {
385 N_SET_MACHTYPE(*execp, M_68010);
389 N_SET_MACHTYPE(*execp, M_68020);
394 N_SET_MACHTYPE(*execp, M_SPARC);
397 N_SET_MACHTYPE(*execp, M_386);
400 N_SET_MACHTYPE(*execp, M_29K);
403 N_SET_MACHTYPE(*execp, M_UNKNOWN);
406 N_SET_MAGIC (*execp, OMAGIC);
407 if (abfd->flags & D_PAGED) {
408 /* This is not strictly true, but will probably do for the default
410 execp->a_text = obj_textsec (abfd)->size + sizeof(struct exec);
411 N_SET_MAGIC (*execp, ZMAGIC);
412 } else if (abfd->flags & WP_TEXT) {
413 N_SET_MAGIC (*execp, NMAGIC);
415 N_SET_FLAGS (*execp, 0x1); /* copied from ld.c; who the hell knows? */
417 if (abfd->flags & D_PAGED)
419 data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
420 & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
422 if (data_pad > obj_bsssec(abfd)->size)
425 execp->a_bss = obj_bsssec(abfd)->size - data_pad;
426 execp->a_data = obj_datasec(abfd)->size + data_pad;
430 execp->a_data = obj_datasec (abfd)->size;
431 execp->a_bss = obj_bsssec (abfd)->size;
434 execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
435 execp->a_entry = bfd_get_start_address (abfd);
437 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
438 reloc_size_func(abfd));
440 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
441 reloc_size_func(abfd));
443 bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
445 bfd_seek (abfd, 0L, false);
446 bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
448 /* Now write out reloc info, followed by syms and strings */
450 if (bfd_get_symcount (abfd) != 0)
453 (long)(N_SYMOFF(*execp)), false);
455 sunos4_write_syms (abfd);
457 bfd_seek (abfd, (long)(N_TRELOFF(*execp)), false);
459 if (!sunos4_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
460 bfd_seek (abfd, (long)(N_DRELOFF(*execp)), false);
462 if (!sunos4_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
469 #define CORE_MAGIC 0x080456
470 #define CORE_NAMELEN 16
472 /* The core structure is taken from the Sun documentation.
473 Unfortunately, they don't document the FPA structure, or at least I
474 can't find it easily. Fortunately the core header contains its own
475 length. So this shouldn't cause problems, except for c_ucode, which
476 so far we don't use but is easy to find with a little arithmetic. */
478 /* But the reg structure can be gotten from the SPARC processor handbook.
479 This really should be in a GNU include file though so that gdb can use
503 /* Taken from Sun documentation: */
505 /* FIXME: It's worse than we expect. This struct contains TWO substructs
506 neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't
507 even portably access the stuff in between! */
510 int c_magic; /* Corefile magic number */
511 int c_len; /* Sizeof (struct core) */
512 struct regs c_regs; /* General purpose registers */
513 struct exec c_aouthdr; /* A.out header */
514 int c_signo; /* Killing signal, if any */
515 int c_tsize; /* Text size (bytes) */
516 int c_dsize; /* Data size (bytes) */
517 int c_ssize; /* Stack size (bytes) */
518 char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
519 double fp_stuff[1]; /* external FPU state (size unknown by us) */
520 /* The type "double" is critical here, for alignment.
521 SunOS declares a struct here, but the struct's alignment
522 is double since it contains doubles. */
523 int c_ucode; /* Exception no. from u_code */
524 /* (this member is not accessible by name since we don't
525 portably know the size of fp_stuff.) */
528 /* Supposedly the user stack grows downward from the bottom of kernel memory.
529 Presuming that this remains true, this definition will work. */
530 #define USRSTACK (-(128*1024*1024))
532 PROTO (static void, swapcore, (bfd *abfd, struct core *core));
534 /* need this cast b/c ptr is really void * */
535 #define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
536 #define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
537 #define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
538 #define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
539 #define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
541 /* These are stored in the bfd's tdata */
543 struct core *hdr; /* core file header */
544 asection *data_section;
545 asection *stack_section;
546 asection *reg_section;
547 asection *reg2_section;
551 sunos4_core_file_p (abfd)
554 unsigned char longbuf[4]; /* Raw bytes of various header fields */
560 bfd_error = system_call_error;
562 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
565 core_mag = bfd_h_getlong (abfd, longbuf);
567 if (core_mag != CORE_MAGIC) return 0;
569 /* SunOS core headers can vary in length; second word is size; */
570 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
573 core_size = bfd_h_getlong (abfd, longbuf);
575 if (core_size > 20000)
578 if (bfd_seek (abfd, 0L, false) < 0) return 0;
580 rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
581 if (rawptr == NULL) {
582 bfd_error = no_memory;
586 core = (struct core *) (rawptr + sizeof (struct suncordata));
588 if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
589 bfd_error = system_call_error;
590 bfd_release (abfd, rawptr);
594 swapcore (abfd, core);
595 set_tdata (abfd, ((struct suncordata *) rawptr));
596 core_hdr (abfd) = core;
598 /* create the sections. This is raunchy, but bfd_close wants to reclaim
600 core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
601 if (core_stacksec (abfd) == NULL) {
603 bfd_error = no_memory;
604 bfd_release (abfd, rawptr);
607 core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
608 if (core_datasec (abfd) == NULL) {
610 bfd_release (abfd, core_stacksec (abfd));
613 core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
614 if (core_regsec (abfd) == NULL) {
616 bfd_release (abfd, core_datasec (abfd));
619 core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
620 if (core_reg2sec (abfd) == NULL) {
621 bfd_release (abfd, core_regsec (abfd));
625 core_stacksec (abfd)->name = ".stack";
626 core_datasec (abfd)->name = ".data";
627 core_regsec (abfd)->name = ".reg";
628 core_reg2sec (abfd)->name = ".reg2";
630 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
631 core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
632 core_regsec (abfd)->flags = SEC_ALLOC;
633 core_reg2sec (abfd)->flags = SEC_ALLOC;
635 core_stacksec (abfd)->size = core->c_ssize;
636 core_datasec (abfd)->size = core->c_dsize;
637 core_regsec (abfd)->size = (sizeof core->c_regs);
638 /* Float regs take up end of struct, except c_ucode. */
639 core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) -
640 (file_ptr)(((struct core *)0)->fp_stuff);
642 core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize);
643 core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr);
644 core_regsec (abfd)->vma = -1;
645 core_reg2sec (abfd)->vma = -1;
647 core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
648 core_datasec (abfd)->filepos = core->c_len;
649 /* In file header: */
650 core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs);
651 core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
653 /* Align to word at least */
654 core_stacksec (abfd)->alignment_power = 2;
655 core_datasec (abfd)->alignment_power = 2;
656 core_regsec (abfd)->alignment_power = 2;
657 core_reg2sec (abfd)->alignment_power = 2;
659 abfd->sections = core_stacksec (abfd);
660 core_stacksec (abfd)->next = core_datasec (abfd);
661 core_datasec (abfd)->next = core_regsec (abfd);
662 core_regsec (abfd)->next = core_reg2sec (abfd);
664 abfd->section_count = 4;
670 sunos4_core_file_failing_command (abfd)
673 return core_hdr (abfd)->c_cmdname;
677 sunos4_core_file_failing_signal (abfd)
680 return core_hdr (abfd)->c_signo;
684 sunos4_core_file_matches_executable_p (core_bfd, exec_bfd)
685 bfd *core_bfd, *exec_bfd;
687 if (core_bfd->xvec != exec_bfd->xvec) {
688 bfd_error = system_call_error;
692 return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
693 sizeof (struct exec)) == 0) ? true : false;
696 /* byte-swap core structure */
697 /* FIXME, this needs more work to swap IN a core struct from raw bytes */
699 swapcore (abfd, core)
703 unsigned char exec_bytes[EXEC_BYTES_SIZE];
705 core->c_magic = bfd_h_getlong (abfd, (unsigned char *)&core->c_magic);
706 core->c_len = bfd_h_getlong (abfd, (unsigned char *)&core->c_len );
707 /* Leave integer registers in target byte order. */
708 bcopy ((char *)&(core->c_aouthdr), (char *)exec_bytes, EXEC_BYTES_SIZE);
709 bfd_aout_swap_exec_header_in (abfd, exec_bytes, &core->c_aouthdr);
710 core->c_signo = bfd_h_getlong (abfd, (unsigned char *)&core->c_signo);
711 core->c_tsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_tsize);
712 core->c_dsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_dsize);
713 core->c_ssize = bfd_h_getlong (abfd, (unsigned char *)&core->c_ssize);
714 /* Leave FP registers in target byte order. */
715 /* Leave "c_ucode" unswapped for now, since we can't find it easily. */
718 /** exec and core file sections */
721 sunos4_new_section_hook (abfd, newsect)
725 /* align to double at least */
726 newsect->alignment_power = 3;
728 if (bfd_get_format (abfd) == bfd_object) {
729 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
730 obj_textsec(abfd)= newsect;
734 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
735 obj_datasec(abfd) = newsect;
739 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
740 obj_bsssec(abfd) = newsect;
745 /* We allow more than three sections internally */
750 sunos4_set_section_contents (abfd, section, location, offset, count)
753 unsigned char *location;
757 if (abfd->output_has_begun == false)
758 { /* set by bfd.c handler */
759 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
761 bfd_error = invalid_operation;
765 obj_textsec (abfd)->filepos = sizeof(struct exec);
766 obj_datasec(abfd)->filepos = obj_textsec (abfd)->filepos
767 + obj_textsec (abfd)->size;
769 /* regardless, once we know what we're doing, we might as well get going */
770 if (section != obj_bsssec(abfd)) {
771 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
774 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
783 sunos4_get_section_contents (abfd, section, location, offset, count)
791 if (offset >= section->size) return false;
793 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
795 return (bfd_read (location, 1, count, abfd) == count) ? true:false;
801 /* Classify stabs symbols */
804 #define sym_in_text_section(sym) \
805 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
807 #define sym_in_data_section(sym) \
808 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
810 #define sym_in_bss_section(sym) \
811 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
813 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
814 zero in the "value" field. Nonzeroes there are fortrancommon
816 #define sym_is_undefined(sym) \
817 ((sym)->n_type == (N_UNDF | N_EXT) && (sym)->n_value == 0)
819 /* Symbol is a global definition if N_EXT is on and if it has
820 a nonzero type field. */
821 #define sym_is_global_defn(sym) \
822 (((sym)->n_type & N_EXT) && (sym)->n_type & N_TYPE)
824 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
826 #define sym_is_debugger_info(sym) \
827 ((sym)->n_type & ~(N_EXT | N_TYPE))
829 #define sym_is_fortrancommon(sym) \
830 (((sym)->n_type == (N_EXT)) && (sym)->n_value != 0)
832 /* Symbol is absolute if it has N_ABS set */
833 #define sym_is_absolute(sym) \
834 (((sym)->n_type & N_TYPE)== N_ABS)
837 #define sym_is_indirect(sym) \
838 (((sym)->n_type & N_ABS)== N_ABS)
840 /* Only in their own functions for ease of debugging; when sym flags have
841 stabilised these should be inlined into their (single) caller */
844 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd)
845 struct nlist *sym_pointer;
846 aout_symbol_type *cache_ptr;
849 switch (cache_ptr->type & N_TYPE) {
855 asection *section = bfd_make_section(abfd,
856 cache_ptr->symbol.name);
857 arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
859 switch ( (cache_ptr->type & N_TYPE) ) {
861 reloc->relent.section = (asection *)NULL;
862 cache_ptr->symbol.section = (asection *)NULL;
865 reloc->relent.section = (asection *)obj_textsec(abfd);
866 cache_ptr->symbol.value -= reloc->relent.section->vma;
869 reloc->relent.section = (asection *)obj_datasec(abfd);
870 cache_ptr->symbol.value -= reloc->relent.section->vma;
873 reloc->relent.section = (asection *)obj_bsssec(abfd);
874 cache_ptr->symbol.value -= reloc->relent.section->vma;
877 cache_ptr->symbol.section = reloc->relent.section;
878 reloc->relent.addend = cache_ptr->symbol.value ;
880 /* We modify the symbol to belong to a section depending upon the
881 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
882 really care, and add to the size of the section to contain a
883 pointer to the symbol. Build a reloc entry to relocate to this
884 symbol attached to this section. */
886 section->flags = SEC_CONSTRUCTOR;
887 section->reloc_count++;
888 section->alignment_power = 2;
889 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
890 reloc->next = section->constructor_chain;
891 section->constructor_chain = reloc;
892 reloc->relent.address = section->size;
893 section->size += sizeof(int *);
895 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
896 cache_ptr->symbol.flags |= BSF_DEBUGGING ;
901 if (sym_is_debugger_info (sym_pointer)) {
902 cache_ptr->symbol.flags = BSF_DEBUGGING ;
903 /* Work out the section correct for this symbol */
904 switch (sym_pointer->n_type & N_TYPE)
908 cache_ptr->symbol.section = obj_textsec (abfd);
909 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
912 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
913 cache_ptr->symbol.section = obj_datasec (abfd);
916 cache_ptr->symbol.section = obj_bsssec (abfd);
917 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
921 cache_ptr->symbol.section = 0;
926 if (sym_is_fortrancommon (sym_pointer))
928 cache_ptr->symbol.flags = BSF_FORT_COMM;
929 cache_ptr->symbol.section = (asection *)NULL;
932 if (sym_is_undefined (sym_pointer)) {
933 cache_ptr->symbol.flags = BSF_UNDEFINED;
935 else if (sym_is_global_defn (sym_pointer)) {
936 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
939 else if (sym_is_absolute (sym_pointer)) {
940 cache_ptr->symbol.flags = BSF_ABSOLUTE;
943 cache_ptr->symbol.flags = BSF_LOCAL;
946 /* In a.out, the value of a symbol is always relative to the
947 * start of the file, if this is a data symbol we'll subtract
948 * the size of the text section to get the section relative
949 * value. If this is a bss symbol (which would be strange)
950 * we'll subtract the size of the previous two sections
951 * to find the section relative address.
954 if (sym_in_text_section (sym_pointer)) {
955 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
956 cache_ptr->symbol.section = obj_textsec (abfd);
958 else if (sym_in_data_section (sym_pointer)){
959 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
960 cache_ptr->symbol.section = obj_datasec (abfd);
962 else if (sym_in_bss_section(sym_pointer)) {
963 cache_ptr->symbol.section = obj_bsssec (abfd);
964 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
967 cache_ptr->symbol.section = (asection *)NULL;
968 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
976 translate_to_native_sym_flags (sym_pointer, cache_ptr_g, abfd)
977 struct nlist *sym_pointer;
981 asymbol *cache_ptr = (asymbol *)cache_ptr_g;
983 /* FIXME check for writing bss */
984 if (bfd_get_section(cache_ptr)) {
985 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
986 sym_pointer->n_type |= N_BSS;
988 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
989 sym_pointer->n_type |= N_DATA;
991 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
992 sym_pointer->n_type |= N_TEXT;
995 bfd_error_vector.nonrepresentable_section(abfd,
996 bfd_get_output_section(cache_ptr)->name);
998 /* Turn the symbol from section relative to absolute again */
999 sym_pointer->n_value +=
1000 cache_ptr->section->output_section->vma
1001 + cache_ptr->section->output_offset ;
1004 sym_pointer->n_type |= N_ABS;
1007 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
1008 sym_pointer->n_type = (N_UNDF | N_EXT);
1012 if (cache_ptr->flags & BSF_ABSOLUTE) {
1013 sym_pointer->n_type |= N_ABS;
1016 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1017 sym_pointer->n_type |= N_EXT;
1019 if (cache_ptr->flags & BSF_DEBUGGING) {
1020 sym_pointer->n_type = ((aout_symbol_type *)cache_ptr)->type;
1024 /* Native-level interface to symbols. */
1026 /* We read the symbols into a buffer, which is discarded when this
1027 function exits. We read the strings into a buffer large enough to
1028 hold them all plus all the cached symbol entries. */
1031 sunos4_make_empty_symbol (abfd)
1034 aout_symbol_type *new =
1035 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1036 new->symbol.the_bfd = abfd;
1038 return &new->symbol;
1042 DEFUN(sunos4_slurp_symbol_table, (abfd),
1047 unsigned char string_chars[LONG_SIZE];
1050 aout_symbol_type *cached;
1052 /* If there's no work to be done, don't do any */
1053 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1054 symbol_size = exec_hdr(abfd)->a_syms;
1055 if (symbol_size == 0) {
1056 bfd_error = no_symbols;
1060 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1061 if (bfd_read ((PTR)string_chars, LONG_SIZE, 1, abfd) != LONG_SIZE)
1063 string_size = bfd_h_getlong (abfd, string_chars);
1065 strings = bfd_alloc(abfd, string_size + 1);
1066 cached = (aout_symbol_type *)
1067 bfd_zalloc(abfd, bfd_get_symcount (abfd) * sizeof(aout_symbol_type));
1068 /* Alloc this last, so we can free it if obstack is in use. */
1069 syms = (struct nlist *) bfd_alloc(abfd, symbol_size);
1071 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1072 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
1074 if (syms) bfd_release (abfd, syms);
1075 if (cached) bfd_release (abfd, cached);
1076 if (strings)bfd_release (abfd, strings);
1080 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1081 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
1085 /* OK, now walk the new symtable, cacheing symbol properties */
1087 register struct nlist *sym_pointer;
1088 register struct nlist *sym_end = syms + bfd_get_symcount (abfd);
1089 register aout_symbol_type *cache_ptr = cached;
1091 /* run through the table and byte swap if needed */
1092 for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++) {
1093 sym_pointer->n_un.n_strx =
1094 bfd_h_get_x (abfd, &sym_pointer->n_un.n_strx);
1095 sym_pointer->n_desc =
1096 bfd_h_get_x (abfd, &sym_pointer->n_desc);
1097 sym_pointer->n_value =
1098 bfd_h_get_x (abfd, &sym_pointer->n_value);
1099 sym_pointer->n_other = (char)
1100 bfd_h_get_x(abfd, &sym_pointer->n_other);
1101 sym_pointer->n_type = (char)
1102 bfd_h_get_x(abfd, &sym_pointer->n_type);
1105 /* Run through table and copy values */
1106 for (sym_pointer = syms, cache_ptr = cached;
1107 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
1109 cache_ptr->symbol.the_bfd = abfd;
1110 if (sym_pointer->n_un.n_strx)
1111 cache_ptr->symbol.name = sym_pointer->n_un.n_strx + strings;
1113 cache_ptr->symbol.name = (char *)NULL;
1114 cache_ptr->symbol.value = sym_pointer->n_value;
1115 cache_ptr->desc = sym_pointer->n_desc;
1116 cache_ptr->other = sym_pointer->n_other;
1117 cache_ptr->type = sym_pointer->n_type;
1118 cache_ptr->symbol.udata = 0;
1119 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1124 obj_aout_symbols (abfd) = cached;
1125 bfd_release (abfd, (PTR)syms);
1132 DEFUN(sunos4_write_syms,(abfd),
1135 unsigned int count ;
1136 asymbol **generic = bfd_get_outsymbols (abfd);
1138 unsigned int stindex = sizeof(stindex); /* initial string length */
1140 for (count = 0; count < bfd_get_symcount (abfd); count++) {
1141 asymbol *g = generic[count];
1145 unsigned int length = strlen(g->name) +1;
1146 bfd_h_putlong (abfd, stindex, (unsigned char *)&nsp.n_un.n_strx);
1150 bfd_h_putlong (abfd, 0, (unsigned char *)&nsp.n_un.n_strx);
1153 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
1155 nsp.n_desc = aout_symbol( g)->desc;
1156 nsp.n_other = aout_symbol(g)->other;
1157 nsp.n_type = aout_symbol(g)->type;
1167 nsp.n_value = g->value;
1168 translate_to_native_sym_flags (&nsp, (PTR)g, abfd);
1171 bfd_h_putshort (abfd, nsp.n_desc, (unsigned char *)&nsp.n_desc);
1172 bfd_h_putlong (abfd, nsp.n_value, (unsigned char *)&nsp.n_value);
1173 bfd_write((PTR)&nsp,1, sizeof(nsp), abfd);
1177 /* Now output the strings. Be sure to put string length into correct
1178 * byte ordering before writing it.
1180 bfd_h_putlong (abfd, stindex, (unsigned char *)&stindex);
1182 bfd_write((PTR)&stindex, 1, sizeof(stindex), abfd);
1184 generic = bfd_get_outsymbols(abfd);
1185 for (count = 0; count < bfd_get_symcount(abfd); count++)
1187 asymbol *g = *(generic++);
1191 size_t length = strlen(g->name)+1;
1192 bfd_write((PTR)g->name, 1, length, abfd);
1194 if ((g->flags & BSF_FAKE)==0) {
1195 g->name = itos(count); /* smash the generic symbol */
1202 DEFUN(sunos4_reclaim_symbol_table,(abfd),
1209 sunos4_get_symtab_upper_bound (abfd)
1212 if (!sunos4_slurp_symbol_table (abfd)) return 0;
1214 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1218 sunos4_get_symtab (abfd, location)
1222 unsigned int counter = 0;
1223 aout_symbol_type *symbase;
1225 if (!sunos4_slurp_symbol_table (abfd)) return 0;
1227 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1228 *(location++) = (asymbol *)( symbase++);
1230 return bfd_get_symcount(abfd);
1234 /* Standard reloc stuff */
1235 /* Output standard relocation information to a file in target byte order. */
1238 swap_std_reloc_out (abfd, g, natptr)
1240 arelent *g; /* Generic relocation struct */
1241 struct reloc_std_bytes *natptr;
1245 unsigned int r_length;
1247 int r_baserel, r_jmptable, r_relative;
1248 unsigned int r_addend;
1250 bfd_h_putlong (abfd, g->address, natptr->r_address);
1252 r_length = g->howto->size; /* Size as a power of two */
1253 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1254 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1259 r_addend = g->addend; /* Start here, see how it goes */
1261 /* name was clobbered by sunos4_write_syms to be symbol index */
1263 if (g->sym_ptr_ptr != NULL)
1265 if ((*(g->sym_ptr_ptr))->section) {
1266 /* put the section offset into the addend for output */
1267 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1270 r_index = stoi((*(g->sym_ptr_ptr))->name);
1275 if (g->section == NULL) {
1277 r_index = N_ABS | N_EXT;
1279 else if(g->section->output_section == obj_textsec(abfd)) {
1280 r_index = N_TEXT | N_EXT;
1281 r_addend += g->section->output_section->vma;
1283 else if (g->section->output_section == obj_datasec(abfd)) {
1284 r_index = N_DATA | N_EXT;
1285 r_addend += g->section->output_section->vma;
1287 else if (g->section->output_section == obj_bsssec(abfd)) {
1288 r_index = N_BSS | N_EXT ;
1289 r_addend += g->section->output_section->vma;
1296 /* now the fun stuff */
1297 if (abfd->xvec->header_byteorder_big_p != false) {
1298 natptr->r_index[0] = r_index >> 16;
1299 natptr->r_index[1] = r_index >> 8;
1300 natptr->r_index[2] = r_index;
1302 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1303 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1304 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1305 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1306 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1307 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1309 natptr->r_index[2] = r_index >> 16;
1310 natptr->r_index[1] = r_index >> 8;
1311 natptr->r_index[0] = r_index;
1313 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1314 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1315 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1316 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1317 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1318 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1323 /* Extended stuff */
1324 /* Output extended relocation information to a file in target byte order. */
1327 swap_ext_reloc_out (abfd, g, natptr)
1329 arelent *g; /* Generic relocation struct */
1330 register struct reloc_ext_bytes *natptr;
1334 unsigned int r_type;
1335 unsigned int r_addend;
1337 bfd_h_putlong (abfd, g->address, natptr->r_address);
1339 /* Find a type in the output format which matches the input howto -
1340 at the moment we assume input format == output format FIXME!! */
1341 r_type = (enum reloc_type) g->howto->type;
1343 r_addend = g->addend; /* Start here, see how it goes */
1345 /* name was clobbered by sunos4_write_syms to be symbol index*/
1347 if (g->sym_ptr_ptr != NULL)
1349 if ((*(g->sym_ptr_ptr))->section) {
1350 /* put the section offset into the addend for output */
1351 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1354 r_index = stoi((*(g->sym_ptr_ptr))->name);
1359 if (g->section == NULL) {
1361 r_index = N_ABS | N_EXT;
1363 else if(g->section->output_section == obj_textsec(abfd)) {
1364 r_index = N_TEXT | N_EXT;
1365 r_addend += g->section->output_section->vma;
1367 else if (g->section->output_section == obj_datasec(abfd)) {
1368 r_index = N_DATA | N_EXT;
1369 r_addend += g->section->output_section->vma;
1371 else if (g->section->output_section == obj_bsssec(abfd)) {
1372 r_index = N_BSS | N_EXT ;
1373 r_addend += g->section->output_section->vma;
1380 /* now the fun stuff */
1381 if (abfd->xvec->header_byteorder_big_p != false) {
1382 natptr->r_index[0] = r_index >> 16;
1383 natptr->r_index[1] = r_index >> 8;
1384 natptr->r_index[2] = r_index;
1386 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1387 || (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1389 natptr->r_index[2] = r_index >> 16;
1390 natptr->r_index[1] = r_index >> 8;
1391 natptr->r_index[0] = r_index;
1393 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1394 || (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1397 bfd_h_putlong (abfd, r_addend, natptr->r_addend);
1400 #define MOVE_ADDRESS(ad) \
1402 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1403 cache_ptr->section = (asection *)NULL; \
1404 cache_ptr->addend = ad; \
1406 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1407 switch (r_index) { \
1409 case N_TEXT | N_EXT: \
1410 cache_ptr->section = obj_textsec(abfd); \
1411 cache_ptr->addend = ad - su->textsec->vma; \
1414 case N_DATA | N_EXT: \
1415 cache_ptr->section = obj_datasec(abfd); \
1416 cache_ptr->addend = ad - su->datasec->vma; \
1419 case N_BSS | N_EXT: \
1420 cache_ptr->section = obj_bsssec(abfd); \
1421 cache_ptr->addend = ad - su->bsssec->vma; \
1424 case N_ABS | N_EXT: \
1425 cache_ptr->section = NULL; /* No section */ \
1426 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1430 cache_ptr->section = NULL; /* No section */ \
1431 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1438 swap_ext_reloc_in (abfd, bytes, cache_ptr, symbols)
1440 struct reloc_ext_bytes *bytes;
1446 unsigned int r_type;
1447 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1449 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1451 /* now the fun stuff */
1452 if (abfd->xvec->header_byteorder_big_p != false) {
1453 r_index = (bytes->r_index[0] << 16)
1454 | (bytes->r_index[1] << 8)
1455 | bytes->r_index[2];
1456 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_BIG));
1457 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_BIG)
1458 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1460 r_index = (bytes->r_index[2] << 16)
1461 | (bytes->r_index[1] << 8)
1462 | bytes->r_index[0];
1463 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1464 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1465 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1468 cache_ptr->howto = howto_table_ext + r_type;
1469 MOVE_ADDRESS(bfd_h_getlong(abfd,bytes->r_addend));
1473 swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
1475 struct reloc_std_bytes *bytes;
1481 unsigned int r_length;
1483 int r_baserel, r_jmptable, r_relative;
1484 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1486 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1488 /* now the fun stuff */
1489 if (abfd->xvec->header_byteorder_big_p != false) {
1490 r_index = (bytes->r_index[0] << 16)
1491 | (bytes->r_index[1] << 8)
1492 | bytes->r_index[2];
1493 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_BIG));
1494 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_BIG));
1495 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_BIG));
1496 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1497 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_BIG));
1498 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_BIG)
1499 >> RELOC_STD_BITS_LENGTH_SH_BIG;
1501 r_index = (bytes->r_index[2] << 16)
1502 | (bytes->r_index[1] << 8)
1503 | bytes->r_index[0];
1504 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1505 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_LITTLE));
1506 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1507 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1508 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1509 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1510 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1513 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1514 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1522 sunos4_slurp_reloc_table (abfd, asect, symbols)
1530 arelent *reloc_cache;
1533 if (asect->relocation) return true;
1535 if (asect->flags & SEC_CONSTRUCTOR) return true;
1537 if (asect == obj_datasec (abfd)) {
1538 reloc_size = exec_hdr(abfd)->a_drsize;
1542 if (asect == obj_textsec (abfd)) {
1543 reloc_size = exec_hdr(abfd)->a_trsize;
1547 bfd_error = invalid_operation;
1551 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1552 each_size = reloc_size_func(abfd);
1554 count = reloc_size / each_size;
1557 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1561 bfd_error = no_memory;
1565 relocs = bfd_alloc (abfd, reloc_size);
1567 bfd_release (abfd, reloc_cache);
1571 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1572 bfd_release (abfd, relocs);
1573 bfd_release (abfd, reloc_cache);
1574 bfd_error = system_call_error;
1578 if (each_size == RELOC_EXT_SIZE) {
1579 register struct reloc_ext_bytes *rptr = (struct reloc_ext_bytes *) relocs;
1580 unsigned int counter = 0;
1581 arelent *cache_ptr = reloc_cache;
1583 for (; counter < count; counter++, rptr++, cache_ptr++) {
1584 swap_ext_reloc_in(abfd, rptr, cache_ptr, symbols);
1587 register struct reloc_std_bytes *rptr = (struct reloc_std_bytes *) relocs;
1588 unsigned int counter = 0;
1589 arelent *cache_ptr = reloc_cache;
1591 for (; counter < count; counter++, rptr++, cache_ptr++) {
1592 swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
1597 bfd_release (abfd,relocs);
1598 asect->relocation = reloc_cache;
1599 asect->reloc_count = count;
1605 /* Write out a relocation section into an object file. */
1608 sunos4_squirt_out_relocs (abfd, section)
1613 unsigned char *native, *natptr;
1616 unsigned int count = section->reloc_count;
1619 if (count == 0) return true;
1621 each_size = reloc_size_func(abfd);
1622 natsize = each_size * count;
1623 native = (unsigned char *) bfd_zalloc (abfd, natsize);
1625 bfd_error = no_memory;
1629 generic = section->orelocation;
1631 if (each_size == RELOC_EXT_SIZE)
1633 for (natptr = native;
1635 --count, natptr += each_size, ++generic)
1636 swap_ext_reloc_out (abfd, generic, (struct reloc_ext_bytes *)native);
1640 for (natptr = native;
1642 --count, natptr += each_size, ++generic)
1643 swap_std_reloc_out(abfd, generic, (struct reloc_std_bytes *)native);
1646 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1647 bfd_release(abfd, native);
1650 bfd_release (abfd, native);
1655 /* This is stupid. This function should be a boolean predicate */
1657 sunos4_canonicalize_reloc (abfd, section, relptr, symbols)
1663 arelent *tblptr = section->relocation;
1666 if (!(tblptr || sunos4_slurp_reloc_table (abfd, section, symbols)))
1669 if (section->flags & SEC_CONSTRUCTOR) {
1670 arelent_chain *chain = section->constructor_chain;
1671 for (count = 0; count < section->reloc_count; count ++) {
1672 *relptr ++ = &chain->relent;
1673 chain = chain->next;
1677 tblptr = section->relocation;
1678 if (!tblptr) return 0;
1680 for (count = 0; count++ < section->reloc_count;)
1682 *relptr++ = tblptr++;
1687 return section->reloc_count;
1691 sunos4_get_reloc_upper_bound (abfd, asect)
1695 if (bfd_get_format (abfd) != bfd_object) {
1696 bfd_error = invalid_operation;
1699 if (asect->flags & SEC_CONSTRUCTOR) {
1700 return (sizeof (arelent *) * (asect->reloc_count+1));
1704 if (asect == obj_datasec (abfd))
1705 return (sizeof (arelent *) *
1706 ((exec_hdr(abfd)->a_drsize / reloc_size_func(abfd))
1709 if (asect == obj_textsec (abfd))
1710 return (sizeof (arelent *) *
1711 ((exec_hdr(abfd)->a_trsize / reloc_size_func(abfd))
1714 bfd_error = invalid_operation;
1719 sunos4_reclaim_reloc (ignore_abfd, section)
1728 sunos4_get_lineno(ignore_abfd, ignore_symbol)
1732 return (alent *)NULL;
1736 sunos4_print_symbol(ignore_abfd, file, symbol, how)
1740 bfd_print_symbol_enum_type how;
1743 case bfd_print_symbol_name_enum:
1744 fprintf(file,"%s", symbol->name);
1746 case bfd_print_symbol_type_enum:
1747 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1748 (unsigned)(aout_symbol(symbol)->other & 0xff),
1749 (unsigned)(aout_symbol(symbol)->type));
1751 case bfd_print_symbol_all_enum:
1753 CONST char *section_name = symbol->section == (asection *)NULL ?
1754 "*abs" : symbol->section->name;
1756 bfd_print_symbol_vandf((PTR)file,symbol);
1758 fprintf(file," %-5s %04x %02x %02x %s",
1760 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1761 (unsigned)(aout_symbol(symbol)->other & 0xff),
1762 (unsigned)(aout_symbol(symbol)->type & 0xff),
1768 /* Once we know all the stuff that could be consed, we know how to clean
1769 it up. So why don't we? */
1772 sunos4_close_and_cleanup (abfd)
1775 if (!bfd_read_p (abfd))
1776 switch (abfd->format) {
1778 if (!_bfd_write_archive_contents (abfd)) return false; break;
1780 if (!sunos4_write_object_contents (abfd)) return false; break;
1781 default: bfd_error = invalid_operation; return false;
1788 provided a bfd, a section and an offset into the section, calculate
1789 and return the name of the source file and the line nearest to the
1794 DEFUN(sunos4_find_nearest_line,(abfd,
1802 asection *section AND
1803 asymbol **symbols AND
1805 CONST char **filename_ptr AND
1806 CONST char **functionname_ptr AND
1807 unsigned int *line_ptr)
1809 /* Run down the file looking for the filename, function and linenumber */
1811 static char buffer[100];
1812 bfd_vma high_line_vma = ~0;
1813 bfd_vma low_func_vma = 0;
1815 *filename_ptr = abfd->filename;
1816 *functionname_ptr = 0;
1818 if (symbols != (asymbol **)NULL) {
1819 for (p = symbols; *p; p++) {
1820 aout_symbol_type *q = (aout_symbol_type *)(*p);
1823 *filename_ptr = q->symbol.name;
1824 if (obj_textsec(abfd) != section) {
1832 /* We'll keep this if it resolves nearer than the one we have already */
1833 if (q->symbol.value >= offset &&
1834 q->symbol.value < high_line_vma) {
1835 *line_ptr = q->desc;
1836 high_line_vma = q->symbol.value;
1841 /* We'll keep this if it is nearer than the one we have already */
1842 if (q->symbol.value >= low_func_vma &&
1843 q->symbol.value <= offset) {
1844 low_func_vma = q->symbol.value;
1845 func = (asymbol *)q;
1847 if (*line_ptr && func) {
1848 CONST char *function = func->name;
1850 strncpy(buffer, function, sizeof(buffer)-1);
1851 buffer[sizeof(buffer)-1] = 0;
1852 /* Have to remove : stuff */
1853 p = strchr(buffer,':');
1854 if (p != NULL) {*p = NULL; }
1855 *functionname_ptr = buffer;
1870 DEFUN(sunos4_sizeof_headers,(abfd),
1876 #define sunos4_openr_next_archived_file bfd_generic_openr_next_archived_file
1877 #define sunos4_generic_stat_arch_elt bfd_generic_stat_arch_elt
1878 #define sunos4_slurp_armap bfd_slurp_bsd_armap
1879 #define sunos4_slurp_extended_name_table bfd_true
1880 #define sunos4_write_armap bsd_write_armap
1881 #define sunos4_truncate_arname bfd_bsd_truncate_arname
1882 bfd_target aout_big_vec =
1884 "a.out-generic-big", /* name */
1885 bfd_target_aout_flavour_enum,
1886 true, /* target byte order */
1887 true, /* target headers byte order */
1888 (HAS_RELOC | EXEC_P | /* object flags */
1889 HAS_LINENO | HAS_DEBUG |
1890 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1891 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1892 ' ', /* ar_pad_char */
1893 16, /* ar_max_namelen */
1894 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1895 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1897 {_bfd_dummy_target, sunos4_object_p,
1898 bfd_generic_archive_p, sunos4_core_file_p},
1899 {bfd_false, sunos4_mkobject,
1900 _bfd_generic_mkarchive, bfd_false},
1906 bfd_target aout_little_vec =
1908 "a.out-generic-little", /* name */
1909 bfd_target_aout_flavour_enum,
1910 false, /* target byte order */
1911 false, /* target headers byte order */
1912 (HAS_RELOC | EXEC_P | /* object flags */
1913 HAS_LINENO | HAS_DEBUG |
1914 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1915 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1916 ' ', /* ar_pad_char */
1917 16, /* ar_max_namelen */
1918 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* data */
1919 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* hdrs */
1922 {_bfd_dummy_target, sunos4_object_p,
1923 bfd_generic_archive_p, sunos4_core_file_p},
1924 {bfd_false, sunos4_mkobject,
1925 _bfd_generic_mkarchive, bfd_false},