1 /*** bfd backend for sunos binaries */
3 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Diddler.
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)
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.
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. */
25 #define TARGET_BYTE_ORDER_BIG_P 1
33 void (*bfd_error_trap)();
40 typedef void generic_symbol_type;
41 /* These values are correct for the SPARC. I dunno about anything else */
42 #define PAGE_SIZE 0x02000
43 #define SEGMENT_SIZE PAGE_SIZE
44 #define TEXT_START_ADDR PAGE_SIZE
45 #include "a.out.gnu.h"
48 #include "liba.out.h" /* BFD a.out internal data structures */
50 #include "a.out.sun4.h"
52 #define CTOR_TABLE_RELOC_IDX 2
53 static CONST reloc_howto_type howto_table_ext[] =
55 /* type rs size bsz pcrel bitpos abs ovrf sf name partial inplace mask*/
56 { (unsigned int) RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0x000000ff},
57 { (unsigned int) RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0x0000ffff},
58 { (unsigned int) RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0xffffffff},
59 { (unsigned int) RELOC_DISP8, 0, 0, 8, true, 0, false, true,0,"DISP8", false, 0x000000ff},
60 { (unsigned int) RELOC_DISP16, 0, 1, 16, true, 0, false, true,0,"DISP16", false, 0x0000ffff},
61 { (unsigned int) RELOC_DISP32, 0, 2, 32, true, 0, false, true,0,"DISP32", false, 0xffffffff},
62 { (unsigned int) RELOC_WDISP30,2, 2, 30, true, 0, false, true,0,"WDISP30", false, 0x3fffffff},
63 { (unsigned int) RELOC_WDISP22,2, 2, 22, true, 0, false, true,0,"WDISP22", false, 0x003fffff},
64 { (unsigned int) RELOC_HI22, 10, 2, 22, false, 0, false, true,0,"HI22", false, 0x003fffff},
65 { (unsigned int) RELOC_22, 0, 2, 22, false, 0, false, true,0,"22", false, 0x003fffff},
66 { (unsigned int) RELOC_13, 0, 2, 13, false, 0, false, true,0,"13", false, 0x00001fff},
67 { (unsigned int) RELOC_LO10, 0, 2, 10, false, 0, false, true,0,"LO10", false, 0x000003ff},
68 { (unsigned int) RELOC_SFA_BASE,0, 2, 32, false, 0, false, true,0,"SFA_BASE", false, 0xffffffff},
69 { (unsigned int) RELOC_SFA_OFF13,0,2, 32, false, 0, false, true,0,"SFA_OFF13",false, 0xffffffff},
70 { (unsigned int) RELOC_BASE10, 0, 2, 16, false, 0, false, true,0,"BASE10", false, 0x0000ffff},
71 { (unsigned int) RELOC_BASE13, 0, 2, 13, false, 0, false, true,0,"BASE13", false, 0x00001fff},
72 { (unsigned int) RELOC_BASE22, 0, 2, 0, false, 0, false, true,0,"BASE22", false, 0x00000000},
73 { (unsigned int) RELOC_PC10, 0, 2, 10, false, 0, false, true,0,"PC10", false, 0x000003ff},
74 { (unsigned int) RELOC_PC22, 0, 2, 22, false, 0, false, true,0,"PC22", false, 0x003fffff},
75 { (unsigned int) RELOC_JMP_TBL,0, 2, 32, false, 0, false, true,0,"JMP_TBL", false, 0xffffffff},
76 { (unsigned int) RELOC_SEGOFF16,0, 2, 0, false, 0, false, true,0,"SEGOFF16", false, 0x00000000},
77 { (unsigned int) RELOC_GLOB_DAT,0, 2, 0, false, 0, false, true,0,"GLOB_DAT", false, 0x00000000},
78 { (unsigned int) RELOC_JMP_SLOT,0, 2, 0, false, 0, false, true,0,"JMP_SLOT", false, 0x00000000},
79 { (unsigned int) RELOC_RELATIVE,0, 2, 0, false, 0, false, true,0,"RELATIVE", false, 0x00000000},
80 { (unsigned int) RELOC_JUMPTARG,2, 13, 16, true, 0, false, true,0,"JUMPTARG", false, 0x0000ffff},
81 { (unsigned int) RELOC_CONST, 0, 13, 16, false, 0, false, true,0,"CONST", false, 0x0000ffff},
82 { (unsigned int) RELOC_CONSTH, 16, 13, 16, false, 0, false, true,0,"CONSTH", false, 0x0000ffff},
85 /* Convert standard reloc records to "arelent" format (incl byte swap). */
87 static CONST reloc_howto_type howto_table_std[] = {
88 /* type rs size bsz pcrel bitpos abs ovrf sf name*/
89 { (unsigned int) 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff},
90 { (unsigned int) 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff},
91 { (unsigned int) 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff},
92 { (unsigned int) 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead},
93 { (unsigned int) 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff},
94 { (unsigned int) 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff},
95 { (unsigned int) 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff},
96 { (unsigned int) 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface},
102 PROTO (void , sunos4_write_syms, ());
103 PROTO (static boolean,sunos4_squirt_out_relocs,(bfd *abfd, asection *section));
107 reloc_size_func(abfd)
110 switch (bfd_get_architecture (abfd)) {
113 return RELOC_EXT_SIZE;
115 return RELOC_STD_SIZE;
120 bfd_aout_swap_exec_header_in (abfd, raw_bytes, execp)
122 unsigned char *raw_bytes;
125 struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
127 /* Now fill in fields in the execp, from the bytes in the raw data. */
128 execp->a_info = bfd_h_getlong (abfd, bytes->a_info);
129 execp->a_text = bfd_h_getlong (abfd, bytes->a_text);
130 execp->a_data = bfd_h_getlong (abfd, bytes->a_data);
131 execp->a_bss = bfd_h_getlong (abfd, bytes->a_bss);
132 execp->a_syms = bfd_h_getlong (abfd, bytes->a_syms);
133 execp->a_entry = bfd_h_getlong (abfd, bytes->a_entry);
134 execp->a_trsize = bfd_h_getlong (abfd, bytes->a_trsize);
135 execp->a_drsize = bfd_h_getlong (abfd, bytes->a_drsize);
139 bfd_aout_swap_exec_header_out (abfd, execp, raw_bytes)
142 unsigned char *raw_bytes;
144 struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
146 /* Now fill in fields in the raw data, from the fields in the exec struct. */
147 bfd_h_putlong (abfd, execp->a_info , bytes->a_info);
148 bfd_h_putlong (abfd, execp->a_text , bytes->a_text);
149 bfd_h_putlong (abfd, execp->a_data , bytes->a_data);
150 bfd_h_putlong (abfd, execp->a_bss , bytes->a_bss);
151 bfd_h_putlong (abfd, execp->a_syms , bytes->a_syms);
152 bfd_h_putlong (abfd, execp->a_entry , bytes->a_entry);
153 bfd_h_putlong (abfd, execp->a_trsize, bytes->a_trsize);
154 bfd_h_putlong (abfd, execp->a_drsize, bytes->a_drsize);
157 /* Steve wants some way to frob this stuff from Saber while he's debugging
158 ld, so we have these funny shadow functions */
159 /* ZMAGIC's start at 0 (making the exec part of the text section),
160 other formats start after the exec
162 static unsigned int n_txtoff(ptr)
164 {return N_MAGIC(*ptr)== ZMAGIC ? 0: sizeof(struct exec);}
166 static unsigned int n_datoff(ptr)
168 {return n_txtoff(ptr) + ptr->a_text;}
170 static unsigned int n_treloff(ptr)
172 {return n_datoff(ptr) + ptr->a_data;}
174 static unsigned int n_dreloff(ptr)
176 {return n_treloff(ptr) + ptr->a_trsize;}
178 static unsigned int n_symoff(ptr)
180 {return n_dreloff(ptr) + ptr->a_drsize;}
182 static unsigned int n_stroff(ptr)
184 {return n_symoff(ptr) + ptr->a_syms;}
186 unsigned int n_badmag(ptr)
189 switch (N_MAGIC(*ptr)) {
190 case OMAGIC: case NMAGIC: case ZMAGIC: return 0;
196 sunos4_object_p (abfd)
199 unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
200 unsigned long magic; /* Swapped magic number */
201 unsigned char exec_bytes[EXEC_BYTES_SIZE]; /* Raw bytes of exec hdr */
205 bfd_error = system_call_error;
207 if (bfd_read ((void *)magicbuf, 1, sizeof (magicbuf), abfd) !=
210 magic = bfd_h_getlong (abfd, magicbuf);
212 /* Baroque syntax to mask deficiencies of the Sun compiler */
213 /* if (N_BADMAG (*((struct exec *) &magic))) return 0; */
214 if (n_badmag ((struct exec *) &magic)) return 0;
216 if (bfd_seek (abfd, 0L, false) < 0) return 0;
218 if (bfd_read ((void *) exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
219 != EXEC_BYTES_SIZE) {
220 bfd_error = wrong_format;
224 /* Use an intermediate variable for clarity */
225 rawptr = (void *) zalloc (sizeof (struct sunexdata) + sizeof (struct exec));
227 if (rawptr == NULL) {
228 bfd_error = no_memory;
232 set_tdata (abfd, ((struct sunexdata *) rawptr));
233 exec_hdr (abfd) = execp =
234 (struct exec *) ((char *)rawptr + sizeof (struct sunexdata));
236 bfd_aout_swap_exec_header_in (abfd, exec_bytes, execp);
238 /* Set the file flags */
239 abfd->flags = NO_FLAGS;
240 if (execp->a_drsize || execp->a_trsize)
241 abfd->flags |= HAS_RELOC;
243 abfd->flags |= EXEC_P;
245 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
248 if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
249 if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
251 /* Determine the architecture and machine type of the object file. */
252 abfd->obj_arch = bfd_arch_unknown; /* Default values */
253 abfd->obj_machine = 0;
254 switch (N_MACHTYPE (*execp)) {
260 abfd->obj_arch = bfd_arch_m68k;
261 abfd->obj_machine = 68010;
265 abfd->obj_arch = bfd_arch_m68k;
266 abfd->obj_machine = 68020;
270 abfd->obj_arch = bfd_arch_sparc;
274 abfd->obj_arch = bfd_arch_i386;
278 abfd->obj_arch = bfd_arch_a29k;
282 abfd->obj_arch = bfd_arch_obscure;
286 bfd_get_start_address (abfd) = execp->a_entry;
288 /* Remember the positions of the string table and symbol table. */
289 obj_str_filepos (abfd) = n_stroff (execp);
290 obj_sym_filepos (abfd) = n_symoff (execp);
292 /* create the sections. This is raunchy, but bfd_close wants to reclaim
294 obj_textsec (abfd) = (asection *)NULL;
295 obj_datasec (abfd) = (asection *)NULL;
296 obj_bsssec (abfd) = (asection *)NULL;
297 obj_aout_symbols(abfd) = (aout_symbol_type *)NULL;
298 (void)bfd_make_section(abfd, ".text");
299 (void)bfd_make_section(abfd, ".data");
300 (void)bfd_make_section(abfd, ".bss");
302 obj_datasec (abfd)->size = execp->a_data;
303 obj_bsssec (abfd)->size = execp->a_bss;
304 obj_textsec (abfd)->size = execp->a_text;
305 obj_datasec (abfd)->vma = N_DATADDR(*execp);
306 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
307 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
309 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
310 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
312 obj_textsec (abfd)->rel_filepos = N_TROFF(*execp);
313 obj_datasec (abfd)->rel_filepos = N_DROFF(*execp);
315 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
316 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
317 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
318 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
319 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
320 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
321 obj_bsssec (abfd)->flags = SEC_ALLOC;
323 abfd->sections = obj_textsec (abfd);
324 obj_textsec (abfd)->next = obj_datasec (abfd);
325 obj_datasec (abfd)->next = obj_bsssec (abfd);
331 sunos4_mkobject (abfd)
336 bfd_error = system_call_error;
338 /* Use an intermediate variable for clarity */
339 rawptr = zalloc (sizeof (struct sunexdata) + sizeof (struct exec));
341 if (rawptr == NULL) {
342 bfd_error = no_memory;
346 abfd->tdata = (void *)((struct sunexdata *) rawptr);
347 exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct sunexdata));
349 /* For simplicity's sake we just make all the sections right here. */
351 obj_textsec (abfd) = (asection *)NULL;
352 obj_datasec (abfd) = (asection *)NULL;
353 obj_bsssec (abfd) = (asection *)NULL;
354 bfd_make_section (abfd, ".text");
355 bfd_make_section (abfd, ".data");
356 bfd_make_section (abfd, ".bss");
361 /* Keep track of machine architecture and machine type for a.out's.
362 Return the machine_type for a particular arch&machine, or M_UNKNOWN
363 if that exact arch&machine can't be represented in a.out format.
365 If the architecture is understood, machine type 0 (default) should
366 always be understood. */
368 static enum machine_type
369 aout_machine_type (arch, machine)
370 enum bfd_architecture arch;
371 unsigned long machine;
373 enum machine_type arch_flags;
375 arch_flags = M_UNKNOWN;
379 if (machine == 0) arch_flags = M_SPARC;
384 case 0: arch_flags = M_UNKNOWN; break;
385 case 68000: arch_flags = M_UNKNOWN; break;
386 case 68010: arch_flags = M_68010; break;
387 case 68020: arch_flags = M_68020; break;
388 default: arch_flags = M_UNKNOWN; break;
393 if (machine == 0) arch_flags = M_386;
397 if (machine == 0) arch_flags = M_29K;
401 arch_flags = M_UNKNOWN;
408 sunos4_set_arch_mach (abfd, arch, machine)
410 enum bfd_architecture arch;
411 unsigned long machine;
413 abfd->obj_arch = arch;
414 abfd->obj_machine = machine;
415 if (arch != bfd_arch_unknown &&
416 aout_machine_type (arch, machine) == M_UNKNOWN)
417 return false; /* We can't represent this type */
418 return true; /* We're easy ... */
422 sunos4_write_object_contents (abfd)
425 unsigned int data_pad = 0;
426 unsigned char exec_bytes[EXEC_BYTES_SIZE];
427 struct exec *execp = exec_hdr (abfd);
429 execp->a_text = obj_textsec (abfd)->size;
431 /* Magic number, maestro, please! */
432 switch (bfd_get_architecture(abfd)) {
434 switch (bfd_get_machine(abfd)) {
436 N_SET_MACHTYPE(*execp, M_68010);
440 N_SET_MACHTYPE(*execp, M_68020);
445 N_SET_MACHTYPE(*execp, M_SPARC);
448 N_SET_MACHTYPE(*execp, M_386);
451 N_SET_MACHTYPE(*execp, M_29K);
454 N_SET_MACHTYPE(*execp, M_UNKNOWN);
457 N_SET_MAGIC (*execp, OMAGIC);
458 if (abfd->flags & D_PAGED) {
459 execp->a_text = obj_textsec (abfd)->size + sizeof(struct exec);
460 N_SET_MAGIC (*execp, ZMAGIC);
461 } else if (abfd->flags & WP_TEXT) {
462 N_SET_MAGIC (*execp, NMAGIC);
464 N_SET_FLAGS (*execp, 0x1); /* copied from ld.c; who the hell knows? */
466 if (abfd->flags & D_PAGED)
468 data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
469 & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
471 if (data_pad > obj_bsssec(abfd)->size)
474 execp->a_bss = obj_bsssec(abfd)->size - data_pad;
475 execp->a_data = obj_datasec(abfd)->size + data_pad;
479 execp->a_data = obj_datasec (abfd)->size;
480 execp->a_bss = obj_bsssec (abfd)->size;
483 execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
484 execp->a_entry = bfd_get_start_address (abfd);
486 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
487 reloc_size_func(abfd));
489 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
490 reloc_size_func(abfd));
492 bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
494 bfd_seek (abfd, 0L, false);
495 bfd_write ((void *) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
497 /* Now write out reloc info, followed by syms and strings */
499 if (bfd_get_symcount (abfd) != 0)
502 (long)(N_SYMOFF(*execp)), false);
504 sunos4_write_syms (abfd);
506 bfd_seek (abfd, (long)(N_TROFF(*execp)), false);
508 if (!sunos4_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
509 bfd_seek (abfd, (long)(N_DROFF(*execp)), false);
511 if (!sunos4_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
519 #define CORE_MAGIC 0x080456
520 #define CORE_NAMELEN 16
522 /* The core structure is taken from the Sun documentation.
523 Unfortunately, they don't document the FPA structure, or at least I
524 can't find it easily. Fortunately the core header contains its own
525 length. So this shouldn't cause problems, except for c_ucode, which
526 so far we don't use but is easy to find with a little arithmetic. */
528 /* But the reg structure can be gotten from the SPARC processor handbook.
529 This really should be in a GNU include file though so that gdb can use
553 /* Taken from Sun documentation: */
555 /* FIXME: It's worse than we expect. This struct contains TWO substructs
556 neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't
557 even portably access the stuff in between! */
560 int c_magic; /* Corefile magic number */
561 int c_len; /* Sizeof (struct core) */
562 struct regs c_regs; /* General purpose registers */
563 struct exec c_aouthdr; /* A.out header */
564 int c_signo; /* Killing signal, if any */
565 int c_tsize; /* Text size (bytes) */
566 int c_dsize; /* Data size (bytes) */
567 int c_ssize; /* Stack size (bytes) */
568 char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
569 double fp_stuff[1]; /* external FPU state (size unknown by us) */
570 /* The type "double" is critical here, for alignment.
571 SunOS declares a struct here, but the struct's alignment
572 is double since it contains doubles. */
573 int c_ucode; /* Exception no. from u_code */
574 /* (this member is not accessible by name since we don't
575 portably know the size of fp_stuff.) */
578 /* Supposedly the user stack grows downward from the bottom of kernel memory.
579 Presuming that this remains true, this definition will work. */
580 #define USRSTACK (-(128*1024*1024))
582 PROTO (static void, swapcore, (bfd *abfd, struct core *core));
584 /* need this cast b/c ptr is really void * */
585 #define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
586 #define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
587 #define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
588 #define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
589 #define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
591 /* These are stored in the bfd's tdata */
593 struct core *hdr; /* core file header */
594 asection *data_section;
595 asection *stack_section;
596 asection *reg_section;
597 asection *reg2_section;
601 sunos4_core_file_p (abfd)
604 unsigned char longbuf[4]; /* Raw bytes of various header fields */
610 bfd_error = system_call_error;
612 if (bfd_read ((void *)longbuf, 1, sizeof (longbuf), abfd) !=
615 core_mag = bfd_h_getlong (abfd, longbuf);
617 if (core_mag != CORE_MAGIC) return 0;
619 /* SunOS core headers can vary in length; second word is size; */
620 if (bfd_read ((void *)longbuf, 1, sizeof (longbuf), abfd) !=
623 core_size = bfd_h_getlong (abfd, longbuf);
625 if (core_size > 20000)
628 if (bfd_seek (abfd, 0L, false) < 0) return 0;
630 rawptr = zalloc (core_size + sizeof (struct suncordata));
631 if (rawptr == NULL) {
632 bfd_error = no_memory;
636 core = (struct core *) (rawptr + sizeof (struct suncordata));
638 if ((bfd_read ((void *) core, 1, core_size, abfd)) != core_size) {
639 bfd_error = system_call_error;
640 free ((void *)rawptr);
644 swapcore (abfd, core);
645 set_tdata (abfd, ((struct suncordata *) rawptr));
646 core_hdr (abfd) = core;
648 /* create the sections. This is raunchy, but bfd_close wants to reclaim
650 core_stacksec (abfd) = (asection *) zalloc (sizeof (asection));
651 if (core_stacksec (abfd) == NULL) {
653 bfd_error = no_memory;
654 free ((void *)rawptr);
657 core_datasec (abfd) = (asection *) zalloc (sizeof (asection));
658 if (core_datasec (abfd) == NULL) {
660 free ((void *)core_stacksec (abfd));
663 core_regsec (abfd) = (asection *) zalloc (sizeof (asection));
664 if (core_regsec (abfd) == NULL) {
666 free ((void *)core_datasec (abfd));
669 core_reg2sec (abfd) = (asection *) zalloc (sizeof (asection));
670 if (core_reg2sec (abfd) == NULL) {
671 free ((void *)core_regsec (abfd));
675 core_stacksec (abfd)->name = ".stack";
676 core_datasec (abfd)->name = ".data";
677 core_regsec (abfd)->name = ".reg";
678 core_reg2sec (abfd)->name = ".reg2";
680 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
681 core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
682 core_regsec (abfd)->flags = SEC_ALLOC;
683 core_reg2sec (abfd)->flags = SEC_ALLOC;
685 core_stacksec (abfd)->size = core->c_ssize;
686 core_datasec (abfd)->size = core->c_dsize;
687 core_regsec (abfd)->size = (sizeof core->c_regs);
688 /* Float regs take up end of struct, except c_ucode. */
689 core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) -
690 (file_ptr)(((struct core *)0)->fp_stuff);
692 core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize);
693 core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr);
694 core_regsec (abfd)->vma = -1;
695 core_reg2sec (abfd)->vma = -1;
697 core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
698 core_datasec (abfd)->filepos = core->c_len;
699 /* In file header: */
700 core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs);
701 core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
703 /* Align to word at least */
704 core_stacksec (abfd)->alignment_power = 2;
705 core_datasec (abfd)->alignment_power = 2;
706 core_regsec (abfd)->alignment_power = 2;
707 core_reg2sec (abfd)->alignment_power = 2;
709 abfd->sections = core_stacksec (abfd);
710 core_stacksec (abfd)->next = core_datasec (abfd);
711 core_datasec (abfd)->next = core_regsec (abfd);
712 core_regsec (abfd)->next = core_reg2sec (abfd);
714 abfd->section_count = 4;
720 sunos4_core_file_failing_command (abfd)
723 return core_hdr (abfd)->c_cmdname;
727 sunos4_core_file_failing_signal (abfd)
730 return core_hdr (abfd)->c_signo;
734 sunos4_core_file_matches_executable_p (core_bfd, exec_bfd)
735 bfd *core_bfd, *exec_bfd;
737 if (core_bfd->xvec != exec_bfd->xvec) {
738 bfd_error = system_call_error;
742 return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
743 sizeof (struct exec)) == 0) ? true : false;
746 /* byte-swap core structure */
747 /* FIXME, this needs more work to swap IN a core struct from raw bytes */
749 swapcore (abfd, core)
753 unsigned char exec_bytes[EXEC_BYTES_SIZE];
755 core->c_magic = bfd_h_getlong (abfd, (unsigned char *)&core->c_magic);
756 core->c_len = bfd_h_getlong (abfd, (unsigned char *)&core->c_len );
757 /* Leave integer registers in target byte order. */
758 bcopy ((char *)&(core->c_aouthdr), (char *)exec_bytes, EXEC_BYTES_SIZE);
759 bfd_aout_swap_exec_header_in (abfd, exec_bytes, &core->c_aouthdr);
760 core->c_signo = bfd_h_getlong (abfd, (unsigned char *)&core->c_signo);
761 core->c_tsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_tsize);
762 core->c_dsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_dsize);
763 core->c_ssize = bfd_h_getlong (abfd, (unsigned char *)&core->c_ssize);
764 /* Leave FP registers in target byte order. */
765 /* Leave "c_ucode" unswapped for now, since we can't find it easily. */
768 /** exec and core file sections */
771 sunos4_new_section_hook (abfd, newsect)
775 /* align to double at least */
776 newsect->alignment_power = 3;
778 if (bfd_get_format (abfd) == bfd_object) {
779 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
780 obj_textsec(abfd)= newsect;
784 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
785 obj_datasec(abfd) = newsect;
789 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
790 obj_bsssec(abfd) = newsect;
795 /* We allow more than three sections internally */
800 sunos4_set_section_contents (abfd, section, location, offset, count)
803 unsigned char *location;
807 if (abfd->output_has_begun == false)
808 { /* set by bfd.c handler */
809 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL)
812 (obj_textsec (abfd)->size == 0) || (obj_datasec (abfd)->size=
816 bfd_error = invalid_operation;
822 if (abfd->flags & D_PAGED)
824 obj_textsec (abfd)->filepos = sizeof(struct exec);
825 obj_datasec(abfd)->filepos = obj_textsec (abfd)->size;
830 obj_textsec (abfd)->filepos = sizeof(struct exec);
831 obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos + obj_textsec (abfd)->size;
835 /* regardless, once we know what we're doing, we might as well get going */
837 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
840 return (bfd_write ((void *)location, 1, count, abfd) == count) ?
846 sunos4_get_section_contents (abfd, section, location, offset, count)
854 if (offset >= section->size) return false;
856 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
858 return (bfd_read (location, 1, count, abfd) == count) ? true:false;
864 /* Classify stabs symbols */
867 #define sym_in_text_section(sym) \
868 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
870 #define sym_in_data_section(sym) \
871 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
873 #define sym_in_bss_section(sym) \
874 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
876 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
877 zero in the "value" field. Nonzeroes there are fortrancommon
879 #define sym_is_undefined(sym) \
880 ((sym)->n_type == (N_UNDF | N_EXT) && (sym)->n_value == 0)
882 /* Symbol is a global definition if N_EXT is on and if it has
883 a nonzero type field. */
884 #define sym_is_global_defn(sym) \
885 (((sym)->n_type & N_EXT) && (sym)->n_type & N_TYPE)
887 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
889 #define sym_is_debugger_info(sym) \
890 ((sym)->n_type & ~(N_EXT | N_TYPE))
892 #define sym_is_fortrancommon(sym) \
893 (((sym)->n_type == (N_EXT)) && (sym)->n_value != 0)
895 /* Symbol is absolute if it has N_ABS set */
896 #define sym_is_absolute(sym) \
897 (((sym)->n_type & N_TYPE)== N_ABS)
900 #define sym_is_indirect(sym) \
901 (((sym)->n_type & N_ABS)== N_ABS)
903 /* Only in their own functions for ease of debugging; when sym flags have
904 stabilised these should be inlined into their (single) caller */
907 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd)
908 struct nlist *sym_pointer;
909 aout_symbol_type *cache_ptr;
912 switch (cache_ptr->type & N_TYPE) {
918 asection *section = bfd_make_section(abfd,
919 cache_ptr->symbol.name);
920 arelent_chain *reloc = (arelent_chain *)malloc(sizeof(arelent_chain));
922 switch ( (cache_ptr->type & N_TYPE) ) {
924 reloc->relent.section = (asection *)NULL;
925 cache_ptr->symbol.section = (asection *)NULL;
928 reloc->relent.section = (asection *)obj_textsec(abfd);
929 cache_ptr->symbol.value -= reloc->relent.section->vma;
932 reloc->relent.section = (asection *)obj_datasec(abfd);
933 cache_ptr->symbol.value -= reloc->relent.section->vma;
936 reloc->relent.section = (asection *)obj_bsssec(abfd);
937 cache_ptr->symbol.value -= reloc->relent.section->vma;
940 cache_ptr->symbol.section = reloc->relent.section;
941 reloc->relent.addend = cache_ptr->symbol.value ;
943 We modify the symbol to belong to a section depending upon the
944 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
945 really care, and add to the size of the section to contain a
946 pointer to the symbol. Build a reloc entry to relocate to this
947 symbol attached to this section.
951 section->flags = SEC_CONSTRUCTOR;
952 section->reloc_count++;
953 section->alignment_power = 2;
954 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
955 reloc->next = section->constructor_chain;
956 section->constructor_chain = reloc;
957 reloc->relent.address = section->size;
958 section->size += sizeof(int *);
960 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
961 cache_ptr->symbol.flags |= BSF_DEBUGGING ;
966 if (sym_is_debugger_info (sym_pointer)) {
967 cache_ptr->symbol.flags = BSF_DEBUGGING ;
968 /* Work out the section correct for this symbol */
969 switch (sym_pointer->n_type & N_TYPE)
973 cache_ptr->symbol.section = obj_textsec (abfd);
974 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
977 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
978 cache_ptr->symbol.section = obj_datasec (abfd);
981 cache_ptr->symbol.section = obj_bsssec (abfd);
982 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
986 cache_ptr->symbol.section = 0;
991 if (sym_is_fortrancommon (sym_pointer))
993 cache_ptr->symbol.flags = BSF_FORT_COMM;
994 cache_ptr->symbol.section = (asection *)NULL;
997 if (sym_is_undefined (sym_pointer)) {
998 cache_ptr->symbol.flags = BSF_UNDEFINED;
1000 else if (sym_is_global_defn (sym_pointer)) {
1001 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1004 else if (sym_is_absolute (sym_pointer)) {
1005 cache_ptr->symbol.flags = BSF_ABSOLUTE;
1008 cache_ptr->symbol.flags = BSF_LOCAL;
1011 /* In a.out, the value of a symbol is always relative to the
1012 * start of the file, if this is a data symbol we'll subtract
1013 * the size of the text section to get the section relative
1014 * value. If this is a bss symbol (which would be strange)
1015 * we'll subtract the size of the previous two sections
1016 * to find the section relative address.
1019 if (sym_in_text_section (sym_pointer)) {
1020 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
1021 cache_ptr->symbol.section = obj_textsec (abfd);
1023 else if (sym_in_data_section (sym_pointer)){
1024 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
1025 cache_ptr->symbol.section = obj_datasec (abfd);
1027 else if (sym_in_bss_section(sym_pointer)) {
1028 cache_ptr->symbol.section = obj_bsssec (abfd);
1029 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
1032 cache_ptr->symbol.section = (asection *)NULL;
1033 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
1041 translate_to_native_sym_flags (sym_pointer, cache_ptr_g, abfd)
1042 struct nlist *sym_pointer;
1043 generic_symbol_type *cache_ptr_g;
1046 asymbol *cache_ptr = (asymbol *)cache_ptr_g;
1048 /* FIXME check for wrigin bss */
1049 if (bfd_get_section(cache_ptr)) {
1050 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
1051 sym_pointer->n_type |= N_BSS;
1053 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
1054 sym_pointer->n_type |= N_DATA;
1056 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
1057 sym_pointer->n_type |= N_TEXT;
1060 bfd_error_trap(bfd_error_nonrepresentable_section,
1061 bfd_get_output_section(cache_ptr)->name);
1064 /* Turn the symbol from section relative to absolute again */
1065 sym_pointer->n_value +=
1066 cache_ptr->section->output_section->vma
1067 + cache_ptr->section->output_offset ;
1070 sym_pointer->n_type |= N_ABS;
1073 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
1074 sym_pointer->n_type = (N_UNDF | N_EXT);
1078 if (cache_ptr->flags & BSF_ABSOLUTE) {
1079 sym_pointer->n_type |= N_ABS;
1082 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1083 sym_pointer->n_type |= N_EXT;
1085 if (cache_ptr->flags & BSF_DEBUGGING) {
1086 sym_pointer->n_type = ((aout_symbol_type *)cache_ptr)->type;
1091 /* Native-level interface to symbols. */
1093 /* We read the symbols into a buffer, which is discarded when this
1094 function exits. We read the strings into a buffer large enough to
1095 hold them all plus all the cached symbol entries. */
1098 sunos4_make_empty_symbol (abfd)
1101 aout_symbol_type *new =
1102 (aout_symbol_type *)zalloc (sizeof (aout_symbol_type));
1103 new->symbol.the_bfd = abfd;
1105 return &new->symbol;
1109 sunos4_slurp_symbol_table (abfd)
1112 unsigned int symbol_count;
1117 aout_symbol_type *cached;
1119 /* If there's no work to be done, don't do any */
1120 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1121 symbol_size = exec_hdr(abfd)->a_syms;
1122 if (symbol_size == 0) {
1123 bfd_error = no_symbols;
1127 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1128 if (bfd_read ((void *)&string_size, 4, 1, abfd) != 4)
1130 string_size = bfd_h_getlong (abfd, (unsigned char *)&string_size);
1132 symbol_count = symbol_size / sizeof (struct nlist);
1134 /* Malloc (should alloca) space for native symbols, and
1135 malloc space for string table and symbol cache. */
1137 syms = (struct nlist *) zalloc (symbol_size);
1139 bfd_error = no_memory;
1143 cached = (aout_symbol_type *) zalloc ((size_t)(string_size + 1 +
1144 (symbol_count * sizeof (aout_symbol_type))));
1145 if (cached == NULL) {
1146 bfd_error = no_memory;
1147 free ((void *)syms);
1151 strings = ((char *) cached) + (symbol_count * sizeof (aout_symbol_type));
1153 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1154 if (bfd_read ((void *)syms, 1, symbol_size, abfd) != symbol_size) {
1156 free ((void *)cached);
1161 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1162 if (bfd_read ((void *)strings, 1, string_size, abfd) != string_size) {
1166 /* OK, now walk the new symtable, cacheing symbol properties */
1168 register struct nlist *sym_pointer;
1169 register struct nlist *sym_end = syms + symbol_count;
1170 register aout_symbol_type *cache_ptr = cached;
1172 if (bfd_header_twiddle_required (abfd) == true) {
1173 /* run through the table and byte swap if needed */
1174 for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++) {
1175 sym_pointer->n_un.n_strx =
1176 bfd_h_get_x (abfd, &sym_pointer->n_un.n_strx);
1177 sym_pointer->n_desc =
1178 bfd_h_get_x (abfd, &sym_pointer->n_desc);
1179 sym_pointer->n_value =
1180 bfd_h_get_x (abfd, &sym_pointer->n_value);
1181 sym_pointer->n_other = (char)
1182 bfd_h_get_x(abfd, &sym_pointer->n_other);
1183 sym_pointer->n_type = (char)
1184 bfd_h_get_x(abfd, &sym_pointer->n_type);
1188 /* Run through table and copy values */
1189 for (sym_pointer = syms, cache_ptr = cached;
1190 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
1192 cache_ptr->symbol.the_bfd = abfd;
1193 if (sym_pointer->n_un.n_strx)
1194 cache_ptr->symbol.name = sym_pointer->n_un.n_strx + strings;
1196 cache_ptr->symbol.name = (char *)NULL;
1197 cache_ptr->symbol.value = sym_pointer->n_value;
1198 cache_ptr->desc = sym_pointer->n_desc;
1199 cache_ptr->other = sym_pointer->n_other;
1200 cache_ptr->type = sym_pointer->n_type;
1201 cache_ptr->symbol.udata = 0;
1202 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1207 obj_aout_symbols (abfd) = cached;
1208 bfd_get_symcount (abfd) = symbol_count;
1209 free ((void *)syms);
1216 sunos4_write_syms (abfd)
1219 unsigned int count ;
1220 asymbol **generic = bfd_get_outsymbols (abfd);
1222 unsigned int stindex = sizeof(stindex); /* initial string length */
1224 for (count = 0; count < bfd_get_symcount (abfd); count++) {
1225 asymbol *g = generic[count];
1229 unsigned int length = strlen(g->name) +1;
1230 bfd_h_putlong (abfd, stindex, (unsigned char *)&nsp.n_un.n_strx);
1234 bfd_h_putlong (abfd, 0, (unsigned char *)&nsp.n_un.n_strx);
1237 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
1239 nsp.n_desc = aout_symbol( g)->desc;
1240 nsp.n_other = aout_symbol(g)->other;
1241 nsp.n_type = aout_symbol(g)->type;
1251 nsp.n_value = g->value;
1252 translate_to_native_sym_flags (&nsp, (generic_symbol_type *)g, abfd);
1255 bfd_h_putshort (abfd, nsp.n_desc, (unsigned char *)&nsp.n_desc);
1256 bfd_h_putlong (abfd, nsp.n_value, (unsigned char *)&nsp.n_value);
1257 bfd_write((void *)&nsp,1, sizeof(nsp), abfd);
1261 /* Now output the strings. Be sure to put string length into correct
1262 * byte ordering before writing it.
1264 bfd_h_putlong (abfd, stindex, (unsigned char *)&stindex);
1266 bfd_write((void *)&stindex, 1, sizeof(stindex), abfd);
1268 generic = bfd_get_outsymbols(abfd);
1269 for (count = 0; count < bfd_get_symcount(abfd); count++)
1271 asymbol *g = *(generic++);
1273 if (g->name != (char *)NULL)
1275 size_t length = strlen(g->name)+1;
1276 bfd_write((void *)g->name, 1, length, abfd);
1278 if ((g->flags & BSF_FAKE)==0) {
1279 g->name = itos(count); /* smash the generic symbol */
1286 sunos4_reclaim_symbol_table (abfd)
1291 if (!bfd_get_symcount (abfd)) return;
1293 for (section = abfd->sections;
1294 section != (asection *) NULL;
1295 section = section->next)
1296 if (section->relocation) {
1297 free ((void *)section->relocation);
1298 section->relocation = NULL;
1299 section->reloc_count = 0;
1302 bfd_get_symcount (abfd) = 0;
1303 free ((void *)obj_aout_symbols (abfd));
1304 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
1308 sunos4_get_symtab_upper_bound (abfd)
1311 if (!sunos4_slurp_symbol_table (abfd)) return 0;
1313 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1317 sunos4_get_symtab (abfd, location)
1321 unsigned int counter = 0;
1322 aout_symbol_type *symbase;
1324 if (!sunos4_slurp_symbol_table (abfd)) return 0;
1326 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1327 *(location++) = (asymbol *)( symbase++);
1329 return bfd_get_symcount(abfd);
1333 /* Obsolete procedural interface; better to look at the cache directly */
1335 /* User should have checked the file flags; perhaps we should return
1336 BFD_NO_MORE_SYMBOLS if there are none? */
1339 sunos4_get_symcount_upper_bound (abfd)
1342 /* In case we're doing an output file or something...? */
1343 if (bfd_get_symcount (abfd)) return bfd_get_symcount (abfd);
1345 return (exec_hdr (abfd)->a_syms) / (sizeof (struct nlist));
1349 sunos4_get_first_symbol (ignore_abfd)
1356 sunos4_get_next_symbol (abfd, oidx)
1360 if (oidx == BFD_NO_MORE_SYMBOLS) return BFD_NO_MORE_SYMBOLS;
1361 return ++oidx >= bfd_get_symcount (abfd) ? BFD_NO_MORE_SYMBOLS : oidx;
1365 sunos4_symbol_name (abfd, idx)
1369 return (obj_aout_symbols (abfd) + idx)->symbol.name;
1373 sunos4_symbol_value (abfd, idx)
1377 return (obj_aout_symbols (abfd) + idx)->symbol.value;
1381 sunos4_classify_symbol (abfd, idx)
1385 aout_symbol_type *sym = obj_aout_symbols (abfd) + idx;
1387 if ((sym->symbol.flags & BSF_FORT_COMM) != 0) return bfd_symclass_fcommon;
1388 if ((sym->symbol.flags & BSF_GLOBAL) != 0) return bfd_symclass_global;
1389 if ((sym->symbol.flags & BSF_DEBUGGING) != 0) return bfd_symclass_debugger;
1390 if ((sym->symbol.flags & BSF_UNDEFINED) != 0) return bfd_symclass_undefined;
1392 return bfd_symclass_unknown;
1396 sunos4_symbol_hasclass (abfd, idx, class)
1401 aout_symbol_type *sym = obj_aout_symbols (abfd) + idx;
1403 case bfd_symclass_fcommon:
1404 return (sym->symbol.flags & BSF_FORT_COMM) ? true :false;
1405 case bfd_symclass_global:
1406 return (sym->symbol.flags & BSF_GLOBAL) ? true:false;
1407 case bfd_symclass_debugger:
1408 return (sym->symbol.flags & BSF_DEBUGGING) ? true:false;;
1409 case bfd_symclass_undefined:
1410 return (sym->symbol.flags & BSF_UNDEFINED) ? true:false;;
1411 default: return false;
1415 /* Standard reloc stuff */
1416 /* Output standard relocation information to a file in target byte order. */
1419 swap_std_reloc_out (abfd, p, natptr, count)
1421 arelent **p; /* Generic relocation struct */
1422 struct reloc_std_bytes *natptr;
1427 unsigned int r_length;
1429 int r_baserel, r_jmptable, r_relative;
1430 unsigned int r_addend;
1432 for (idx = 0; idx < count; idx++, p++, natptr++)
1435 bfd_h_putlong (abfd, g->address, natptr->r_address);
1437 r_length = g->howto->size; /* Size as a power of two */
1438 r_pcrel = g->howto->pc_relative; /* Relative to PC? */
1439 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1444 r_addend = g->addend; /* Start here, see how it goes */
1446 /* name was clobbered by sunos4_write_syms to be symbol index */
1448 if (g->sym_ptr_ptr != NULL)
1450 if ((*(g->sym_ptr_ptr))->section) {
1451 /* put the section offset into the addend for output */
1452 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1455 r_index = stoi((*(g->sym_ptr_ptr))->name);
1460 if (g->section == NULL) {
1462 r_index = N_ABS | N_EXT;
1464 else if(g->section->output_section == obj_textsec(abfd)) {
1465 r_index = N_TEXT | N_EXT;
1466 r_addend += g->section->output_section->vma;
1468 else if (g->section->output_section == obj_datasec(abfd)) {
1469 r_index = N_DATA | N_EXT;
1470 r_addend += g->section->output_section->vma;
1472 else if (g->section->output_section == obj_bsssec(abfd)) {
1473 r_index = N_BSS | N_EXT ;
1474 r_addend += g->section->output_section->vma;
1481 /* now the fun stuff */
1482 if (abfd->xvec->header_byteorder_big_p != false) {
1483 natptr->r_index[0] = r_index >> 16;
1484 natptr->r_index[1] = r_index >> 8;
1485 natptr->r_index[2] = r_index;
1487 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1488 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1489 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1490 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1491 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1492 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1494 natptr->r_index[2] = r_index >> 16;
1495 natptr->r_index[1] = r_index >> 8;
1496 natptr->r_index[0] = r_index;
1498 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1499 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1500 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1501 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1502 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1503 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1511 /* Extended stuff */
1512 /* Output extended relocation information to a file in target byte order. */
1515 swap_ext_reloc_out (abfd, p, natptr, count)
1517 arelent **p; /* Generic relocation struct */
1518 register struct reloc_ext_bytes *natptr;
1524 unsigned int r_type;
1525 unsigned int r_addend;
1527 for (idx = 0; idx < count; idx++, p++, natptr++) {
1530 bfd_h_putlong (abfd, g->address, natptr->r_address);
1532 /* Find a type in the output format which matches the input howto -
1533 at the moment we assume input format == output format FIXME!! */
1534 r_type = (enum reloc_type) g->howto->type;
1536 r_addend = g->addend; /* Start here, see how it goes */
1538 /* name was clobbered by sunos4_write_syms to be symbol index*/
1540 if (g->sym_ptr_ptr != NULL)
1542 if ((*(g->sym_ptr_ptr))->section) {
1543 /* put the section offset into the addend for output */
1544 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1547 r_index = stoi((*(g->sym_ptr_ptr))->name);
1552 if (g->section == NULL) {
1554 r_index = N_ABS | N_EXT;
1556 else if(g->section->output_section == obj_textsec(abfd)) {
1557 r_index = N_TEXT | N_EXT;
1558 r_addend += g->section->output_section->vma;
1560 else if (g->section->output_section == obj_datasec(abfd)) {
1561 r_index = N_DATA | N_EXT;
1562 r_addend += g->section->output_section->vma;
1564 else if (g->section->output_section == obj_bsssec(abfd)) {
1565 r_index = N_BSS | N_EXT ;
1566 r_addend += g->section->output_section->vma;
1573 /* now the fun stuff */
1574 if (abfd->xvec->header_byteorder_big_p != false) {
1575 natptr->r_index[0] = r_index >> 16;
1576 natptr->r_index[1] = r_index >> 8;
1577 natptr->r_index[2] = r_index;
1579 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1580 || (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1582 natptr->r_index[2] = r_index >> 16;
1583 natptr->r_index[1] = r_index >> 8;
1584 natptr->r_index[0] = r_index;
1586 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1587 || (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1590 bfd_h_putlong (abfd, r_addend, natptr->r_addend);
1593 #define MOVE_ADDRESS(ad) \
1595 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1596 cache_ptr->section = (asection *)NULL; \
1597 cache_ptr->addend = ad; \
1599 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1600 switch (r_index) { \
1602 case N_TEXT | N_EXT: \
1603 cache_ptr->section = obj_textsec(abfd); \
1604 cache_ptr->addend = ad - su->textsec->vma; \
1607 case N_DATA | N_EXT: \
1608 cache_ptr->section = obj_datasec(abfd); \
1609 cache_ptr->addend = ad - su->datasec->vma; \
1612 case N_BSS | N_EXT: \
1613 cache_ptr->section = obj_bsssec(abfd); \
1614 cache_ptr->addend = ad - su->bsssec->vma; \
1617 case N_ABS | N_EXT: \
1627 swap_ext_reloc_in (abfd, bytes, cache_ptr, symbols)
1629 struct reloc_ext_bytes *bytes;
1635 unsigned int r_type;
1636 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1638 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1640 /* now the fun stuff */
1641 if (abfd->xvec->header_byteorder_big_p != false) {
1642 r_index = (bytes->r_index[0] << 16)
1643 | (bytes->r_index[1] << 8)
1644 | bytes->r_index[2];
1645 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_BIG));
1646 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_BIG)
1647 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1649 r_index = (bytes->r_index[2] << 16)
1650 | (bytes->r_index[1] << 8)
1651 | bytes->r_index[0];
1652 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1653 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1654 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1657 cache_ptr->howto = howto_table_ext + r_type;
1658 MOVE_ADDRESS(bfd_h_getlong(abfd,bytes->r_addend));
1663 swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
1665 struct reloc_std_bytes *bytes;
1671 unsigned int r_length;
1673 int r_baserel, r_jmptable, r_relative;
1674 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1675 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1677 /* now the fun stuff */
1678 if (abfd->xvec->header_byteorder_big_p != false) {
1679 r_index = (bytes->r_index[0] << 16)
1680 | (bytes->r_index[1] << 8)
1681 | bytes->r_index[2];
1682 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_BIG));
1683 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_BIG));
1684 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_BIG));
1685 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1686 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_BIG));
1687 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_BIG)
1688 >> RELOC_STD_BITS_LENGTH_SH_BIG;
1690 r_index = (bytes->r_index[2] << 16)
1691 | (bytes->r_index[1] << 8)
1692 | bytes->r_index[0];
1693 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1694 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_LITTLE));
1695 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1696 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1697 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1698 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1699 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1702 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1703 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1711 sunos4_slurp_reloc_table (abfd, asect, symbols)
1719 arelent *reloc_cache;
1722 if (asect->relocation) return true;
1724 if (asect->flags & SEC_CONSTRUCTOR) return true;
1726 if (asect == obj_datasec (abfd)) {
1727 reloc_size = exec_hdr(abfd)->a_drsize;
1731 if (asect == obj_textsec (abfd)) {
1732 reloc_size = exec_hdr(abfd)->a_trsize;
1736 bfd_error = invalid_operation;
1740 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1741 each_size = reloc_size_func(abfd);
1743 count = reloc_size / each_size;
1745 relocs = malloc (reloc_size);
1747 bfd_error = no_memory;
1750 reloc_cache = (arelent *) zalloc ((size_t)(count * sizeof (arelent)));
1751 if (reloc_cache == (arelent *)NULL) {
1753 bfd_error = no_memory;
1757 if (bfd_read ( relocs, 1, reloc_size, abfd) != reloc_size) {
1758 bfd_error = system_call_error;
1764 if (each_size == RELOC_EXT_SIZE)
1766 register struct reloc_ext_bytes *rptr = relocs;
1767 unsigned int counter = 0;
1768 arelent *cache_ptr = reloc_cache;
1770 for (; counter < count; counter++, rptr++, cache_ptr++) {
1771 swap_ext_reloc_in(abfd, rptr, cache_ptr, symbols);
1775 register struct reloc_std_bytes *rptr = relocs;
1776 unsigned int counter = 0;
1777 arelent *cache_ptr = reloc_cache;
1779 for (; counter < count; counter++, rptr++, cache_ptr++) {
1780 swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
1785 asect->relocation = reloc_cache;
1786 asect->reloc_count = count;
1792 /* Write out a relocation section into an object file. */
1795 sunos4_squirt_out_relocs (abfd, section)
1800 unsigned char *native;
1803 unsigned int count = section->reloc_count;
1806 if (count == 0) return true;
1808 each_size = reloc_size_func(abfd);
1809 natsize = each_size * count;
1810 native = (unsigned char *) zalloc (natsize);
1812 bfd_error = no_memory;
1816 generic = section->orelocation;
1818 if (each_size == RELOC_EXT_SIZE)
1820 swap_ext_reloc_out (abfd,
1822 (struct reloc_ext_bytes *)native,
1827 swap_std_reloc_out(abfd, generic, native, count);
1830 if ( bfd_write ((void *) native, 1, natsize, abfd) != natsize) {
1839 /* This is stupid. This function should be a boolean predicate */
1841 sunos4_canonicalize_reloc (abfd, section, relptr, symbols)
1847 arelent *tblptr = section->relocation;
1850 if (!(tblptr || sunos4_slurp_reloc_table (abfd, section, symbols)))
1853 if (section->flags & SEC_CONSTRUCTOR) {
1854 arelent_chain *chain = section->constructor_chain;
1855 for (count = 0; count < section->reloc_count; count ++) {
1856 *relptr ++ = &chain->relent;
1857 chain = chain->next;
1861 tblptr = section->relocation;
1862 if (!tblptr) return 0;
1864 for (count = 0; count++ < section->reloc_count;)
1866 *relptr++ = tblptr++;
1871 return section->reloc_count;
1875 sunos4_get_reloc_upper_bound (abfd, asect)
1879 if (bfd_get_format (abfd) != bfd_object) {
1880 bfd_error = invalid_operation;
1883 if (asect->flags & SEC_CONSTRUCTOR) {
1884 return (sizeof (arelent *) * (asect->reloc_count+1));
1888 if (asect == obj_datasec (abfd))
1889 return (sizeof (arelent *) *
1890 ((exec_hdr(abfd)->a_drsize / reloc_size_func(abfd))
1893 if (asect == obj_textsec (abfd))
1894 return (sizeof (arelent *) *
1895 ((exec_hdr(abfd)->a_trsize / reloc_size_func(abfd))
1898 bfd_error = invalid_operation;
1903 sunos4_reclaim_reloc (ignore_abfd, section)
1907 if (section->relocation) {
1908 free (section->relocation);
1909 section->relocation = NULL;
1910 section->reloc_count = 0;
1916 sunos4_get_lineno(ignore_abfd, ignore_symbol)
1918 generic_symbol_type *ignore_symbol;
1920 return (alent *)NULL;
1924 sunos4_print_symbol(ignore_abfd, file, symbol, how)
1928 bfd_print_symbol_enum_type how;
1931 case bfd_print_symbol_name_enum:
1932 fprintf(file,"%s", symbol->name);
1934 case bfd_print_symbol_type_enum:
1935 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1936 (unsigned)( aout_symbol(symbol)->other & 0xff),
1937 (unsigned)(aout_symbol(symbol)->type));
1939 case bfd_print_symbol_all_enum:
1941 char *section_name = symbol->section == (asection *)NULL ?
1942 "*abs" : symbol->section->name;
1944 bfd_print_symbol_vandf((void *)file,symbol);
1946 fprintf(file," %-5s %04x %02x %02x %s",
1948 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1949 (unsigned)(aout_symbol(symbol)->other & 0xff),
1950 (unsigned)(aout_symbol(symbol)->type & 0xff),
1956 /* Once we know all the stuff that could be consed, we know how to clean
1957 it up. So why don't we? */
1960 sunos4_close_and_cleanup (abfd)
1963 if (!bfd_read_p (abfd))
1964 switch (abfd->format) {
1966 if (!_bfd_write_archive_contents (abfd)) return false; break;
1968 if (!sunos4_write_object_contents (abfd)) return false; break;
1969 default: bfd_error = invalid_operation; return false;
1972 #define cleaner(ptr) if (abfd->ptr) free (abfd->ptr)
1975 if (abfd->my_archive)
1983 provided a bfd, a section and an offset into the section, calculate
1984 and return the name of the source file and the line nearest to the
1989 sunos4_find_nearest_line(abfd,
2000 char **filename_ptr;
2001 char **functionname_ptr;
2002 unsigned int *line_ptr;
2004 /* Run down the file looking for the filename, function and linenumber */
2006 static char buffer[100];
2007 bfd_vma high_line_vma = ~0;
2008 bfd_vma low_func_vma = 0;
2010 *filename_ptr = abfd->filename;
2011 *functionname_ptr = 0;
2013 if (symbols != (asymbol **)NULL) {
2014 for (p = symbols; *p; p++) {
2015 aout_symbol_type *q = (aout_symbol_type *)(*p);
2018 *filename_ptr = q->symbol.name;
2019 if (obj_textsec(abfd) != section) {
2027 /* We'll keep this if it resolves nearer than the one we have already */
2028 if (q->symbol.value >= offset &&
2029 q->symbol.value < high_line_vma) {
2030 *line_ptr = q->desc;
2031 high_line_vma = q->symbol.value;
2036 /* We'll keep this if it is nearer than the one we have already */
2037 if (q->symbol.value >= low_func_vma &&
2038 q->symbol.value <= offset) {
2039 low_func_vma = q->symbol.value;
2040 func = (asymbol *)q;
2042 if (*line_ptr && func) {
2043 char *function = func->name;
2045 strncpy(buffer, function, sizeof(buffer)-1);
2046 buffer[sizeof(buffer)-1] = 0;
2047 /* Have to remove : stuff */
2048 p = strchr(buffer,':');
2049 if (p != NULL) {*p = NULL; }
2050 *functionname_ptr = buffer;
2064 bfd_target aoutvec =
2066 "a.out-generic-big", /* name */
2067 bfd_target_aout_flavour_enum,
2068 true, /* target byte order */
2069 true, /* target headers byte order */
2070 (HAS_RELOC | EXEC_P | /* object flags */
2071 HAS_LINENO | HAS_DEBUG |
2072 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
2073 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2074 0, /* valid reloc types */
2075 ' ', /* ar_pad_char */
2076 16, /* ar_max_namelen */
2077 sunos4_close_and_cleanup, /* _close_and_cleanup */
2078 sunos4_set_section_contents, /* bfd_set_section_contents */
2079 sunos4_get_section_contents, /* bfd_get_section_contents */
2080 sunos4_new_section_hook, /* new_section_hook */
2081 sunos4_core_file_failing_command, /* _core_file_failing_command */
2082 sunos4_core_file_failing_signal, /* _core_file_failing_signal */
2083 sunos4_core_file_matches_executable_p, /* _core_file_matches_ex...p */
2085 bfd_slurp_bsd_armap, /* bfd_slurp_armap */
2086 bfd_true, /* bfd_slurp_extended_name_table */
2087 bfd_bsd_truncate_arname, /* bfd_truncate_arname */
2089 sunos4_get_symtab_upper_bound, /* get_symtab_upper_bound */
2090 sunos4_get_symtab, /* canonicalize_symtab */
2091 sunos4_reclaim_symbol_table, /* bfd_reclaim_symbol_table */
2092 sunos4_get_reloc_upper_bound, /* get_reloc_upper_bound */
2093 sunos4_canonicalize_reloc, /* bfd_canonicalize_reloc */
2094 sunos4_reclaim_reloc, /* bfd_reclaim_reloc */
2095 sunos4_get_symcount_upper_bound, /* bfd_get_symcount_upper_bound */
2096 sunos4_get_first_symbol, /* bfd_get_first_symbol */
2097 sunos4_get_next_symbol, /* bfd_get_next_symbol */
2098 sunos4_classify_symbol, /* bfd_classify_symbol */
2099 sunos4_symbol_hasclass, /* bfd_symbol_hasclass */
2100 sunos4_symbol_name, /* bfd_symbol_name */
2101 sunos4_symbol_value, /* bfd_symbol_value */
2103 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
2104 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
2106 {_bfd_dummy_target, sunos4_object_p, /* bfd_check_format */
2107 bfd_generic_archive_p, sunos4_core_file_p},
2108 {bfd_false, sunos4_mkobject, /* bfd_zxset_format */
2109 _bfd_generic_mkarchive, bfd_false},
2110 sunos4_make_empty_symbol,
2111 sunos4_print_symbol,
2113 sunos4_set_arch_mach,
2115 bfd_generic_openr_next_archived_file,
2116 sunos4_find_nearest_line, /* bfd_find_nearest_line */
2117 bfd_generic_stat_arch_elt /* bfd_stat_arch_elt */