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)();
41 typedef void generic_symbol_type;
42 /* These values are correct for the SPARC. I dunno about anything else */
43 #define PAGE_SIZE 0x02000
44 #define SEGMENT_SIZE PAGE_SIZE
45 #define TEXT_START_ADDR PAGE_SIZE
46 #include "a.out.gnu.h"
49 #include "liba.out.h" /* BFD a.out internal data structures */
51 #include "a.out.sun4.h"
53 #define CTOR_TABLE_RELOC_IDX 2
54 static reloc_howto_type howto_table_ext[] =
56 /* type rs size bsz pcrel bitpos abs ovrf sf name partial inplace mask*/
57 { (unsigned int) RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff},
58 { (unsigned int) RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff},
59 { (unsigned int) RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff},
60 { (unsigned int) RELOC_DISP8, 0, 0, 8, true, 0, false, true,0,"DISP8", false, 0,0x000000ff},
61 { (unsigned int) RELOC_DISP16, 0, 1, 16, true, 0, false, true,0,"DISP16", false, 0,0x0000ffff},
62 { (unsigned int) RELOC_DISP32, 0, 2, 32, true, 0, false, true,0,"DISP32", false, 0,0xffffffff},
63 { (unsigned int) RELOC_WDISP30,2, 2, 30, true, 0, false, true,0,"WDISP30", false, 0,0x3fffffff},
64 { (unsigned int) RELOC_WDISP22,2, 2, 22, true, 0, false, true,0,"WDISP22", false, 0,0x003fffff},
65 { (unsigned int) RELOC_HI22, 10, 2, 22, false, 0, false, true,0,"HI22", false, 0,0x003fffff},
66 { (unsigned int) RELOC_22, 0, 2, 22, false, 0, false, true,0,"22", false, 0,0x003fffff},
67 { (unsigned int) RELOC_13, 0, 2, 13, false, 0, false, true,0,"13", false, 0,0x00001fff},
68 { (unsigned int) RELOC_LO10, 0, 2, 10, false, 0, false, true,0,"LO10", false, 0,0x000003ff},
69 { (unsigned int) RELOC_SFA_BASE,0, 2, 32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff},
70 { (unsigned int) RELOC_SFA_OFF13,0,2, 32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff},
71 { (unsigned int) RELOC_BASE10, 0, 2, 16, false, 0, false, true,0,"BASE10", false, 0,0x0000ffff},
72 { (unsigned int) RELOC_BASE13, 0, 2, 13, false, 0, false, true,0,"BASE13", false, 0,0x00001fff},
73 { (unsigned int) RELOC_BASE22, 0, 2, 0, false, 0, false, true,0,"BASE22", false, 0,0x00000000},
74 { (unsigned int) RELOC_PC10, 0, 2, 10, false, 0, false, true,0,"PC10", false, 0,0x000003ff},
75 { (unsigned int) RELOC_PC22, 0, 2, 22, false, 0, false, true,0,"PC22", false, 0,0x003fffff},
76 { (unsigned int) RELOC_JMP_TBL,0, 2, 32, false, 0, false, true,0,"JMP_TBL", false, 0,0xffffffff},
77 { (unsigned int) RELOC_SEGOFF16,0, 2, 0, false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000},
78 { (unsigned int) RELOC_GLOB_DAT,0, 2, 0, false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000},
79 { (unsigned int) RELOC_JMP_SLOT,0, 2, 0, false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000},
80 { (unsigned int) RELOC_RELATIVE,0, 2, 0, false, 0, false, true,0,"RELATIVE", false, 0,0x00000000},
81 { (unsigned int) RELOC_JUMPTARG,2, 13, 16, true, 0, false, true,0,"JUMPTARG", false, 0,0x0000ffff},
82 { (unsigned int) RELOC_CONST, 0, 13, 16, false, 0, false, true,0,"CONST", false, 0,0x0000ffff},
83 { (unsigned int) RELOC_CONSTH, 16, 13, 16, false, 0, false, true,0,"CONSTH", false, 0,0x0000ffff},
86 /* Convert standard reloc records to "arelent" format (incl byte swap). */
88 static reloc_howto_type howto_table_std[] = {
89 /* type rs size bsz pcrel bitpos abs ovrf sf name*/
90 { (unsigned int) 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff},
91 { (unsigned int) 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff},
92 { (unsigned int) 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff},
93 { (unsigned int) 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead},
94 { (unsigned int) 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff},
95 { (unsigned int) 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff},
96 { (unsigned int) 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff},
97 { (unsigned int) 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface},
101 bfd_error_vector_type bfd_error_vector;
105 PROTO (void , sunos4_write_syms, ());
106 PROTO (static boolean,sunos4_squirt_out_relocs,(bfd *abfd, asection *section));
110 reloc_size_func(abfd)
113 switch (bfd_get_architecture (abfd)) {
116 return RELOC_EXT_SIZE;
118 return RELOC_STD_SIZE;
123 DEFUN(bfd_aout_swap_exec_header_in,(abfd, raw_bytes, execp),
125 unsigned char *raw_bytes AND
128 struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
130 /* Now fill in fields in the execp, from the bytes in the raw data. */
131 execp->a_info = bfd_h_getlong (abfd, bytes->a_info);
132 execp->a_text = bfd_h_getlong (abfd, bytes->a_text);
133 execp->a_data = bfd_h_getlong (abfd, bytes->a_data);
134 execp->a_bss = bfd_h_getlong (abfd, bytes->a_bss);
135 execp->a_syms = bfd_h_getlong (abfd, bytes->a_syms);
136 execp->a_entry = bfd_h_getlong (abfd, bytes->a_entry);
137 execp->a_trsize = bfd_h_getlong (abfd, bytes->a_trsize);
138 execp->a_drsize = bfd_h_getlong (abfd, bytes->a_drsize);
142 DEFUN(bfd_aout_swap_exec_header_out,(abfd, execp, raw_bytes),
144 struct exec *execp AND
145 unsigned char *raw_bytes)
147 struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
149 /* Now fill in fields in the raw data, from the fields in the exec struct. */
150 bfd_h_putlong (abfd, execp->a_info , bytes->a_info);
151 bfd_h_putlong (abfd, execp->a_text , bytes->a_text);
152 bfd_h_putlong (abfd, execp->a_data , bytes->a_data);
153 bfd_h_putlong (abfd, execp->a_bss , bytes->a_bss);
154 bfd_h_putlong (abfd, execp->a_syms , bytes->a_syms);
155 bfd_h_putlong (abfd, execp->a_entry , bytes->a_entry);
156 bfd_h_putlong (abfd, execp->a_trsize, bytes->a_trsize);
157 bfd_h_putlong (abfd, execp->a_drsize, bytes->a_drsize);
160 /* Steve wants some way to frob this stuff from Saber while he's debugging
161 ld, so we have these funny shadow functions */
162 /* ZMAGIC's start at 0 (making the exec part of the text section),
163 other formats start after the exec
165 static unsigned int n_txtoff(ptr)
167 {return N_MAGIC(*ptr)== ZMAGIC ? 0: sizeof(struct exec);}
169 static unsigned int n_datoff(ptr)
171 {return n_txtoff(ptr) + ptr->a_text;}
173 static unsigned int n_treloff(ptr)
175 {return n_datoff(ptr) + ptr->a_data;}
177 static unsigned int n_dreloff(ptr)
179 {return n_treloff(ptr) + ptr->a_trsize;}
181 static unsigned int n_symoff(ptr)
183 {return n_dreloff(ptr) + ptr->a_drsize;}
185 static unsigned int n_stroff(ptr)
187 {return n_symoff(ptr) + ptr->a_syms;}
190 unsigned int n_badmag(ptr)
193 switch (N_MAGIC(*ptr)) {
194 case OMAGIC: case NMAGIC: case ZMAGIC: return 0;
200 sunos4_object_p (abfd)
203 unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
204 unsigned long magic; /* Swapped magic number */
205 unsigned char exec_bytes[EXEC_BYTES_SIZE]; /* Raw bytes of exec hdr */
209 bfd_error = system_call_error;
211 if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
214 magic = bfd_h_getlong (abfd, magicbuf);
216 /* Baroque syntax to mask deficiencies of the Sun compiler */
217 /* if (N_BADMAG (*((struct exec *) &magic))) return 0; */
218 if (n_badmag ((struct exec *) &magic)) return 0;
220 if (bfd_seek (abfd, 0L, false) < 0) return 0;
222 if (bfd_read ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
223 != EXEC_BYTES_SIZE) {
224 bfd_error = wrong_format;
228 /* Use an intermediate variable for clarity */
229 rawptr = (PTR) zalloc (sizeof (struct sunexdata) + sizeof (struct exec));
231 if (rawptr == NULL) {
232 bfd_error = no_memory;
236 set_tdata (abfd, ((struct sunexdata *) rawptr));
237 exec_hdr (abfd) = execp =
238 (struct exec *) ((char *)rawptr + sizeof (struct sunexdata));
240 bfd_aout_swap_exec_header_in (abfd, exec_bytes, execp);
242 /* Set the file flags */
243 abfd->flags = NO_FLAGS;
244 if (execp->a_drsize || execp->a_trsize)
245 abfd->flags |= HAS_RELOC;
247 abfd->flags |= EXEC_P;
249 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
252 if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
253 if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
255 /* Determine the architecture and machine type of the object file. */
256 abfd->obj_arch = bfd_arch_unknown; /* Default values */
257 abfd->obj_machine = 0;
258 switch (N_MACHTYPE (*execp)) {
264 abfd->obj_arch = bfd_arch_m68k;
265 abfd->obj_machine = 68010;
269 abfd->obj_arch = bfd_arch_m68k;
270 abfd->obj_machine = 68020;
274 abfd->obj_arch = bfd_arch_sparc;
278 abfd->obj_arch = bfd_arch_i386;
282 abfd->obj_arch = bfd_arch_a29k;
286 abfd->obj_arch = bfd_arch_obscure;
290 bfd_get_start_address (abfd) = execp->a_entry;
292 /* Remember the positions of the string table and symbol table. */
293 obj_str_filepos (abfd) = n_stroff (execp);
294 obj_sym_filepos (abfd) = n_symoff (execp);
296 /* create the sections. This is raunchy, but bfd_close wants to reclaim
298 obj_textsec (abfd) = (asection *)NULL;
299 obj_datasec (abfd) = (asection *)NULL;
300 obj_bsssec (abfd) = (asection *)NULL;
301 obj_aout_symbols(abfd) = (aout_symbol_type *)NULL;
302 (void)bfd_make_section(abfd, ".text");
303 (void)bfd_make_section(abfd, ".data");
304 (void)bfd_make_section(abfd, ".bss");
306 obj_datasec (abfd)->size = execp->a_data;
307 obj_bsssec (abfd)->size = execp->a_bss;
308 obj_textsec (abfd)->size = execp->a_text;
309 obj_datasec (abfd)->vma = N_DATADDR(*execp);
310 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
311 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
313 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
314 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
316 obj_textsec (abfd)->rel_filepos = N_TROFF(*execp);
317 obj_datasec (abfd)->rel_filepos = N_DROFF(*execp);
319 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
320 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
321 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
322 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
323 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
324 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
325 obj_bsssec (abfd)->flags = SEC_ALLOC;
327 abfd->sections = obj_textsec (abfd);
328 obj_textsec (abfd)->next = obj_datasec (abfd);
329 obj_datasec (abfd)->next = obj_bsssec (abfd);
335 sunos4_mkobject (abfd)
340 bfd_error = system_call_error;
342 /* Use an intermediate variable for clarity */
343 rawptr = zalloc (sizeof (struct sunexdata) + sizeof (struct exec));
345 if (rawptr == NULL) {
346 bfd_error = no_memory;
350 abfd->tdata = (PTR)((struct sunexdata *) rawptr);
351 exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct sunexdata));
353 /* For simplicity's sake we just make all the sections right here. */
355 obj_textsec (abfd) = (asection *)NULL;
356 obj_datasec (abfd) = (asection *)NULL;
357 obj_bsssec (abfd) = (asection *)NULL;
358 bfd_make_section (abfd, ".text");
359 bfd_make_section (abfd, ".data");
360 bfd_make_section (abfd, ".bss");
365 /* Keep track of machine architecture and machine type for a.out's.
366 Return the machine_type for a particular arch&machine, or M_UNKNOWN
367 if that exact arch&machine can't be represented in a.out format.
369 If the architecture is understood, machine type 0 (default) should
370 always be understood. */
372 static enum machine_type
373 aout_machine_type (arch, machine)
374 enum bfd_architecture arch;
375 unsigned long machine;
377 enum machine_type arch_flags;
379 arch_flags = M_UNKNOWN;
383 if (machine == 0) arch_flags = M_SPARC;
388 case 0: arch_flags = M_UNKNOWN; break;
389 case 68000: arch_flags = M_UNKNOWN; break;
390 case 68010: arch_flags = M_68010; break;
391 case 68020: arch_flags = M_68020; break;
392 default: arch_flags = M_UNKNOWN; break;
397 if (machine == 0) arch_flags = M_386;
401 if (machine == 0) arch_flags = M_29K;
405 arch_flags = M_UNKNOWN;
412 sunos4_set_arch_mach (abfd, arch, machine)
414 enum bfd_architecture arch;
415 unsigned long machine;
417 abfd->obj_arch = arch;
418 abfd->obj_machine = machine;
419 if (arch != bfd_arch_unknown &&
420 aout_machine_type (arch, machine) == M_UNKNOWN)
421 return false; /* We can't represent this type */
422 return true; /* We're easy ... */
426 sunos4_write_object_contents (abfd)
430 unsigned char exec_bytes[EXEC_BYTES_SIZE];
431 struct exec *execp = exec_hdr (abfd);
433 execp->a_text = obj_textsec (abfd)->size;
435 /* Magic number, maestro, please! */
436 switch (bfd_get_architecture(abfd)) {
438 switch (bfd_get_machine(abfd)) {
440 N_SET_MACHTYPE(*execp, M_68010);
444 N_SET_MACHTYPE(*execp, M_68020);
449 N_SET_MACHTYPE(*execp, M_SPARC);
452 N_SET_MACHTYPE(*execp, M_386);
455 N_SET_MACHTYPE(*execp, M_29K);
458 N_SET_MACHTYPE(*execp, M_UNKNOWN);
461 N_SET_MAGIC (*execp, OMAGIC);
462 if (abfd->flags & D_PAGED) {
463 execp->a_text = obj_textsec (abfd)->size + sizeof(struct exec);
464 N_SET_MAGIC (*execp, ZMAGIC);
465 } else if (abfd->flags & WP_TEXT) {
466 N_SET_MAGIC (*execp, NMAGIC);
468 N_SET_FLAGS (*execp, 0x1); /* copied from ld.c; who the hell knows? */
470 if (abfd->flags & D_PAGED)
472 data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
473 & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
475 if (data_pad > obj_bsssec(abfd)->size)
478 execp->a_bss = obj_bsssec(abfd)->size - data_pad;
479 execp->a_data = obj_datasec(abfd)->size + data_pad;
483 execp->a_data = obj_datasec (abfd)->size;
484 execp->a_bss = obj_bsssec (abfd)->size;
487 execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
488 execp->a_entry = bfd_get_start_address (abfd);
490 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
491 reloc_size_func(abfd));
493 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
494 reloc_size_func(abfd));
496 bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
498 bfd_seek (abfd, 0L, false);
499 bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
501 /* Now write out reloc info, followed by syms and strings */
503 if (bfd_get_symcount (abfd) != 0)
506 (long)(N_SYMOFF(*execp)), false);
508 sunos4_write_syms (abfd);
510 bfd_seek (abfd, (long)(N_TROFF(*execp)), false);
512 if (!sunos4_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
513 bfd_seek (abfd, (long)(N_DROFF(*execp)), false);
515 if (!sunos4_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
523 #define CORE_MAGIC 0x080456
524 #define CORE_NAMELEN 16
526 /* The core structure is taken from the Sun documentation.
527 Unfortunately, they don't document the FPA structure, or at least I
528 can't find it easily. Fortunately the core header contains its own
529 length. So this shouldn't cause problems, except for c_ucode, which
530 so far we don't use but is easy to find with a little arithmetic. */
532 /* But the reg structure can be gotten from the SPARC processor handbook.
533 This really should be in a GNU include file though so that gdb can use
557 /* Taken from Sun documentation: */
559 /* FIXME: It's worse than we expect. This struct contains TWO substructs
560 neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't
561 even portably access the stuff in between! */
564 int c_magic; /* Corefile magic number */
565 int c_len; /* Sizeof (struct core) */
566 struct regs c_regs; /* General purpose registers */
567 struct exec c_aouthdr; /* A.out header */
568 int c_signo; /* Killing signal, if any */
569 int c_tsize; /* Text size (bytes) */
570 int c_dsize; /* Data size (bytes) */
571 int c_ssize; /* Stack size (bytes) */
572 char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
573 double fp_stuff[1]; /* external FPU state (size unknown by us) */
574 /* The type "double" is critical here, for alignment.
575 SunOS declares a struct here, but the struct's alignment
576 is double since it contains doubles. */
577 int c_ucode; /* Exception no. from u_code */
578 /* (this member is not accessible by name since we don't
579 portably know the size of fp_stuff.) */
582 /* Supposedly the user stack grows downward from the bottom of kernel memory.
583 Presuming that this remains true, this definition will work. */
584 #define USRSTACK (-(128*1024*1024))
586 PROTO (static void, swapcore, (bfd *abfd, struct core *core));
588 /* need this cast b/c ptr is really void * */
589 #define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
590 #define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
591 #define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
592 #define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
593 #define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
595 /* These are stored in the bfd's tdata */
597 struct core *hdr; /* core file header */
598 asection *data_section;
599 asection *stack_section;
600 asection *reg_section;
601 asection *reg2_section;
605 sunos4_core_file_p (abfd)
608 unsigned char longbuf[4]; /* Raw bytes of various header fields */
614 bfd_error = system_call_error;
616 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
619 core_mag = bfd_h_getlong (abfd, longbuf);
621 if (core_mag != CORE_MAGIC) return 0;
623 /* SunOS core headers can vary in length; second word is size; */
624 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
627 core_size = bfd_h_getlong (abfd, longbuf);
629 if (core_size > 20000)
632 if (bfd_seek (abfd, 0L, false) < 0) return 0;
634 rawptr = zalloc (core_size + sizeof (struct suncordata));
635 if (rawptr == NULL) {
636 bfd_error = no_memory;
640 core = (struct core *) (rawptr + sizeof (struct suncordata));
642 if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
643 bfd_error = system_call_error;
648 swapcore (abfd, core);
649 set_tdata (abfd, ((struct suncordata *) rawptr));
650 core_hdr (abfd) = core;
652 /* create the sections. This is raunchy, but bfd_close wants to reclaim
654 core_stacksec (abfd) = (asection *) zalloc (sizeof (asection));
655 if (core_stacksec (abfd) == NULL) {
657 bfd_error = no_memory;
661 core_datasec (abfd) = (asection *) zalloc (sizeof (asection));
662 if (core_datasec (abfd) == NULL) {
664 free ((PTR)core_stacksec (abfd));
667 core_regsec (abfd) = (asection *) zalloc (sizeof (asection));
668 if (core_regsec (abfd) == NULL) {
670 free ((PTR)core_datasec (abfd));
673 core_reg2sec (abfd) = (asection *) zalloc (sizeof (asection));
674 if (core_reg2sec (abfd) == NULL) {
675 free ((PTR)core_regsec (abfd));
679 core_stacksec (abfd)->name = ".stack";
680 core_datasec (abfd)->name = ".data";
681 core_regsec (abfd)->name = ".reg";
682 core_reg2sec (abfd)->name = ".reg2";
684 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
685 core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
686 core_regsec (abfd)->flags = SEC_ALLOC;
687 core_reg2sec (abfd)->flags = SEC_ALLOC;
689 core_stacksec (abfd)->size = core->c_ssize;
690 core_datasec (abfd)->size = core->c_dsize;
691 core_regsec (abfd)->size = (sizeof core->c_regs);
692 /* Float regs take up end of struct, except c_ucode. */
693 core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) -
694 (file_ptr)(((struct core *)0)->fp_stuff);
696 core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize);
697 core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr);
698 core_regsec (abfd)->vma = -1;
699 core_reg2sec (abfd)->vma = -1;
701 core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
702 core_datasec (abfd)->filepos = core->c_len;
703 /* In file header: */
704 core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs);
705 core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
707 /* Align to word at least */
708 core_stacksec (abfd)->alignment_power = 2;
709 core_datasec (abfd)->alignment_power = 2;
710 core_regsec (abfd)->alignment_power = 2;
711 core_reg2sec (abfd)->alignment_power = 2;
713 abfd->sections = core_stacksec (abfd);
714 core_stacksec (abfd)->next = core_datasec (abfd);
715 core_datasec (abfd)->next = core_regsec (abfd);
716 core_regsec (abfd)->next = core_reg2sec (abfd);
718 abfd->section_count = 4;
724 sunos4_core_file_failing_command (abfd)
727 return core_hdr (abfd)->c_cmdname;
731 sunos4_core_file_failing_signal (abfd)
734 return core_hdr (abfd)->c_signo;
738 sunos4_core_file_matches_executable_p (core_bfd, exec_bfd)
739 bfd *core_bfd, *exec_bfd;
741 if (core_bfd->xvec != exec_bfd->xvec) {
742 bfd_error = system_call_error;
746 return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
747 sizeof (struct exec)) == 0) ? true : false;
750 /* byte-swap core structure */
751 /* FIXME, this needs more work to swap IN a core struct from raw bytes */
753 swapcore (abfd, core)
757 unsigned char exec_bytes[EXEC_BYTES_SIZE];
759 core->c_magic = bfd_h_getlong (abfd, (unsigned char *)&core->c_magic);
760 core->c_len = bfd_h_getlong (abfd, (unsigned char *)&core->c_len );
761 /* Leave integer registers in target byte order. */
762 bcopy ((char *)&(core->c_aouthdr), (char *)exec_bytes, EXEC_BYTES_SIZE);
763 bfd_aout_swap_exec_header_in (abfd, exec_bytes, &core->c_aouthdr);
764 core->c_signo = bfd_h_getlong (abfd, (unsigned char *)&core->c_signo);
765 core->c_tsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_tsize);
766 core->c_dsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_dsize);
767 core->c_ssize = bfd_h_getlong (abfd, (unsigned char *)&core->c_ssize);
768 /* Leave FP registers in target byte order. */
769 /* Leave "c_ucode" unswapped for now, since we can't find it easily. */
772 /** exec and core file sections */
775 sunos4_new_section_hook (abfd, newsect)
779 /* align to double at least */
780 newsect->alignment_power = 3;
782 if (bfd_get_format (abfd) == bfd_object) {
783 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
784 obj_textsec(abfd)= newsect;
788 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
789 obj_datasec(abfd) = newsect;
793 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
794 obj_bsssec(abfd) = newsect;
799 /* We allow more than three sections internally */
804 sunos4_set_section_contents (abfd, section, location, offset, count)
807 unsigned char *location;
811 if (abfd->output_has_begun == false)
812 { /* set by bfd.c handler */
813 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL)
816 (obj_textsec (abfd)->size == 0) || (obj_datasec (abfd)->size=
820 bfd_error = invalid_operation;
826 if (abfd->flags & D_PAGED)
828 obj_textsec (abfd)->filepos = sizeof(struct exec);
829 obj_datasec(abfd)->filepos = obj_textsec (abfd)->size;
834 obj_textsec (abfd)->filepos = sizeof(struct exec);
835 obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos + obj_textsec (abfd)->size;
839 /* regardless, once we know what we're doing, we might as well get going */
841 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
844 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
850 sunos4_get_section_contents (abfd, section, location, offset, count)
858 if (offset >= section->size) return false;
860 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
862 return (bfd_read (location, 1, count, abfd) == count) ? true:false;
868 /* Classify stabs symbols */
871 #define sym_in_text_section(sym) \
872 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
874 #define sym_in_data_section(sym) \
875 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
877 #define sym_in_bss_section(sym) \
878 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
880 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
881 zero in the "value" field. Nonzeroes there are fortrancommon
883 #define sym_is_undefined(sym) \
884 ((sym)->n_type == (N_UNDF | N_EXT) && (sym)->n_value == 0)
886 /* Symbol is a global definition if N_EXT is on and if it has
887 a nonzero type field. */
888 #define sym_is_global_defn(sym) \
889 (((sym)->n_type & N_EXT) && (sym)->n_type & N_TYPE)
891 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
893 #define sym_is_debugger_info(sym) \
894 ((sym)->n_type & ~(N_EXT | N_TYPE))
896 #define sym_is_fortrancommon(sym) \
897 (((sym)->n_type == (N_EXT)) && (sym)->n_value != 0)
899 /* Symbol is absolute if it has N_ABS set */
900 #define sym_is_absolute(sym) \
901 (((sym)->n_type & N_TYPE)== N_ABS)
904 #define sym_is_indirect(sym) \
905 (((sym)->n_type & N_ABS)== N_ABS)
907 /* Only in their own functions for ease of debugging; when sym flags have
908 stabilised these should be inlined into their (single) caller */
911 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd)
912 struct nlist *sym_pointer;
913 aout_symbol_type *cache_ptr;
916 switch (cache_ptr->type & N_TYPE) {
922 asection *section = bfd_make_section(abfd,
923 cache_ptr->symbol.name);
924 arelent_chain *reloc = (arelent_chain *)malloc(sizeof(arelent_chain));
926 switch ( (cache_ptr->type & N_TYPE) ) {
928 reloc->relent.section = (asection *)NULL;
929 cache_ptr->symbol.section = (asection *)NULL;
932 reloc->relent.section = (asection *)obj_textsec(abfd);
933 cache_ptr->symbol.value -= reloc->relent.section->vma;
936 reloc->relent.section = (asection *)obj_datasec(abfd);
937 cache_ptr->symbol.value -= reloc->relent.section->vma;
940 reloc->relent.section = (asection *)obj_bsssec(abfd);
941 cache_ptr->symbol.value -= reloc->relent.section->vma;
944 cache_ptr->symbol.section = reloc->relent.section;
945 reloc->relent.addend = cache_ptr->symbol.value ;
947 We modify the symbol to belong to a section depending upon the
948 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
949 really care, and add to the size of the section to contain a
950 pointer to the symbol. Build a reloc entry to relocate to this
951 symbol attached to this section.
955 section->flags = SEC_CONSTRUCTOR;
956 section->reloc_count++;
957 section->alignment_power = 2;
958 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
959 reloc->next = section->constructor_chain;
960 section->constructor_chain = reloc;
961 reloc->relent.address = section->size;
962 section->size += sizeof(int *);
964 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
965 cache_ptr->symbol.flags |= BSF_DEBUGGING ;
970 if (sym_is_debugger_info (sym_pointer)) {
971 cache_ptr->symbol.flags = BSF_DEBUGGING ;
972 /* Work out the section correct for this symbol */
973 switch (sym_pointer->n_type & N_TYPE)
977 cache_ptr->symbol.section = obj_textsec (abfd);
978 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
981 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
982 cache_ptr->symbol.section = obj_datasec (abfd);
985 cache_ptr->symbol.section = obj_bsssec (abfd);
986 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
990 cache_ptr->symbol.section = 0;
995 if (sym_is_fortrancommon (sym_pointer))
997 cache_ptr->symbol.flags = BSF_FORT_COMM;
998 cache_ptr->symbol.section = (asection *)NULL;
1001 if (sym_is_undefined (sym_pointer)) {
1002 cache_ptr->symbol.flags = BSF_UNDEFINED;
1004 else if (sym_is_global_defn (sym_pointer)) {
1005 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1008 else if (sym_is_absolute (sym_pointer)) {
1009 cache_ptr->symbol.flags = BSF_ABSOLUTE;
1012 cache_ptr->symbol.flags = BSF_LOCAL;
1015 /* In a.out, the value of a symbol is always relative to the
1016 * start of the file, if this is a data symbol we'll subtract
1017 * the size of the text section to get the section relative
1018 * value. If this is a bss symbol (which would be strange)
1019 * we'll subtract the size of the previous two sections
1020 * to find the section relative address.
1023 if (sym_in_text_section (sym_pointer)) {
1024 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
1025 cache_ptr->symbol.section = obj_textsec (abfd);
1027 else if (sym_in_data_section (sym_pointer)){
1028 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
1029 cache_ptr->symbol.section = obj_datasec (abfd);
1031 else if (sym_in_bss_section(sym_pointer)) {
1032 cache_ptr->symbol.section = obj_bsssec (abfd);
1033 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
1036 cache_ptr->symbol.section = (asection *)NULL;
1037 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
1045 translate_to_native_sym_flags (sym_pointer, cache_ptr_g, abfd)
1046 struct nlist *sym_pointer;
1047 generic_symbol_type *cache_ptr_g;
1050 asymbol *cache_ptr = (asymbol *)cache_ptr_g;
1052 /* FIXME check for wrigin bss */
1053 if (bfd_get_section(cache_ptr)) {
1054 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
1055 sym_pointer->n_type |= N_BSS;
1057 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
1058 sym_pointer->n_type |= N_DATA;
1060 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
1061 sym_pointer->n_type |= N_TEXT;
1065 bfd_error_vector.nonrepresentable_section(abfd, bfd_get_output_section(cache_ptr)->name);
1068 /* Turn the symbol from section relative to absolute again */
1069 sym_pointer->n_value +=
1070 cache_ptr->section->output_section->vma
1071 + cache_ptr->section->output_offset ;
1074 sym_pointer->n_type |= N_ABS;
1077 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
1078 sym_pointer->n_type = (N_UNDF | N_EXT);
1082 if (cache_ptr->flags & BSF_ABSOLUTE) {
1083 sym_pointer->n_type |= N_ABS;
1086 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1087 sym_pointer->n_type |= N_EXT;
1089 if (cache_ptr->flags & BSF_DEBUGGING) {
1090 sym_pointer->n_type = ((aout_symbol_type *)cache_ptr)->type;
1095 /* Native-level interface to symbols. */
1097 /* We read the symbols into a buffer, which is discarded when this
1098 function exits. We read the strings into a buffer large enough to
1099 hold them all plus all the cached symbol entries. */
1102 sunos4_make_empty_symbol (abfd)
1105 aout_symbol_type *new =
1106 (aout_symbol_type *)zalloc (sizeof (aout_symbol_type));
1107 new->symbol.the_bfd = abfd;
1109 return &new->symbol;
1113 DEFUN(sunos4_slurp_symbol_table, (abfd),
1116 unsigned int symbol_count;
1121 aout_symbol_type *cached;
1123 /* If there's no work to be done, don't do any */
1124 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1125 symbol_size = exec_hdr(abfd)->a_syms;
1126 if (symbol_size == 0) {
1127 bfd_error = no_symbols;
1131 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1132 if (bfd_read ((PTR)&string_size, 4, 1, abfd) != 4)
1134 string_size = bfd_h_getlong (abfd, (unsigned char *)&string_size);
1136 symbol_count = symbol_size / sizeof (struct nlist);
1138 /* Malloc (should alloca) space for native symbols, and
1139 malloc space for string table and symbol cache. */
1141 syms = (struct nlist *) zalloc (symbol_size);
1143 bfd_error = no_memory;
1147 cached = (aout_symbol_type *) zalloc ((size_t)(string_size + 1 +
1148 (symbol_count * sizeof (aout_symbol_type))));
1149 if (cached == NULL) {
1150 bfd_error = no_memory;
1155 strings = ((char *) cached) + (symbol_count * sizeof (aout_symbol_type));
1157 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1158 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
1165 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1166 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
1170 /* OK, now walk the new symtable, cacheing symbol properties */
1172 register struct nlist *sym_pointer;
1173 register struct nlist *sym_end = syms + symbol_count;
1174 register aout_symbol_type *cache_ptr = cached;
1176 /* run through the table and byte swap if needed */
1177 for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++) {
1178 sym_pointer->n_un.n_strx =
1179 bfd_h_get_x (abfd, &sym_pointer->n_un.n_strx);
1180 sym_pointer->n_desc =
1181 bfd_h_get_x (abfd, &sym_pointer->n_desc);
1182 sym_pointer->n_value =
1183 bfd_h_get_x (abfd, &sym_pointer->n_value);
1184 sym_pointer->n_other = (char)
1185 bfd_h_get_x(abfd, &sym_pointer->n_other);
1186 sym_pointer->n_type = (char)
1187 bfd_h_get_x(abfd, &sym_pointer->n_type);
1191 /* Run through table and copy values */
1192 for (sym_pointer = syms, cache_ptr = cached;
1193 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
1195 cache_ptr->symbol.the_bfd = abfd;
1196 if (sym_pointer->n_un.n_strx)
1197 cache_ptr->symbol.name = sym_pointer->n_un.n_strx + strings;
1199 cache_ptr->symbol.name = (char *)NULL;
1200 cache_ptr->symbol.value = sym_pointer->n_value;
1201 cache_ptr->desc = sym_pointer->n_desc;
1202 cache_ptr->other = sym_pointer->n_other;
1203 cache_ptr->type = sym_pointer->n_type;
1204 cache_ptr->symbol.udata = 0;
1205 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1210 obj_aout_symbols (abfd) = cached;
1211 bfd_get_symcount (abfd) = symbol_count;
1219 DEFUN(sunos4_write_syms,(abfd),
1222 unsigned int count ;
1223 asymbol **generic = bfd_get_outsymbols (abfd);
1225 unsigned int stindex = sizeof(stindex); /* initial string length */
1227 for (count = 0; count < bfd_get_symcount (abfd); count++) {
1228 asymbol *g = generic[count];
1232 unsigned int length = strlen(g->name) +1;
1233 bfd_h_putlong (abfd, stindex, (unsigned char *)&nsp.n_un.n_strx);
1237 bfd_h_putlong (abfd, 0, (unsigned char *)&nsp.n_un.n_strx);
1240 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
1242 nsp.n_desc = aout_symbol( g)->desc;
1243 nsp.n_other = aout_symbol(g)->other;
1244 nsp.n_type = aout_symbol(g)->type;
1254 nsp.n_value = g->value;
1255 translate_to_native_sym_flags (&nsp, (generic_symbol_type *)g, abfd);
1258 bfd_h_putshort (abfd, nsp.n_desc, (unsigned char *)&nsp.n_desc);
1259 bfd_h_putlong (abfd, nsp.n_value, (unsigned char *)&nsp.n_value);
1260 bfd_write((PTR)&nsp,1, sizeof(nsp), abfd);
1264 /* Now output the strings. Be sure to put string length into correct
1265 * byte ordering before writing it.
1267 bfd_h_putlong (abfd, stindex, (unsigned char *)&stindex);
1269 bfd_write((PTR)&stindex, 1, sizeof(stindex), abfd);
1271 generic = bfd_get_outsymbols(abfd);
1272 for (count = 0; count < bfd_get_symcount(abfd); count++)
1274 asymbol *g = *(generic++);
1276 if (g->name != (char *)NULL)
1278 size_t length = strlen(g->name)+1;
1279 bfd_write((PTR)g->name, 1, length, abfd);
1281 if ((g->flags & BSF_FAKE)==0) {
1282 g->name = itos(count); /* smash the generic symbol */
1289 DEFUN(sunos4_reclaim_symbol_table,(abfd),
1294 if (!bfd_get_symcount (abfd)) return;
1296 for (section = abfd->sections;
1297 section != (asection *) NULL;
1298 section = section->next)
1299 if (section->relocation) {
1300 free ((PTR)section->relocation);
1301 section->relocation = NULL;
1302 section->reloc_count = 0;
1305 bfd_get_symcount (abfd) = 0;
1306 free ((PTR)obj_aout_symbols (abfd));
1307 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
1311 sunos4_get_symtab_upper_bound (abfd)
1314 if (!sunos4_slurp_symbol_table (abfd)) return 0;
1316 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1320 sunos4_get_symtab (abfd, location)
1324 unsigned int counter = 0;
1325 aout_symbol_type *symbase;
1327 if (!sunos4_slurp_symbol_table (abfd)) return 0;
1329 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1330 *(location++) = (asymbol *)( symbase++);
1332 return bfd_get_symcount(abfd);
1336 /* Obsolete procedural interface; better to look at the cache directly */
1338 /* User should have checked the file flags; perhaps we should return
1339 BFD_NO_MORE_SYMBOLS if there are none? */
1342 sunos4_get_symcount_upper_bound (abfd)
1345 /* In case we're doing an output file or something...? */
1346 if (bfd_get_symcount (abfd)) return bfd_get_symcount (abfd);
1348 return (exec_hdr (abfd)->a_syms) / (sizeof (struct nlist));
1352 sunos4_get_first_symbol (ignore_abfd)
1359 sunos4_get_next_symbol (abfd, oidx)
1363 if (oidx == BFD_NO_MORE_SYMBOLS) return BFD_NO_MORE_SYMBOLS;
1364 return ++oidx >= bfd_get_symcount (abfd) ? BFD_NO_MORE_SYMBOLS : oidx;
1368 sunos4_symbol_name (abfd, idx)
1372 return (obj_aout_symbols (abfd) + idx)->symbol.name;
1376 sunos4_symbol_value (abfd, idx)
1380 return (obj_aout_symbols (abfd) + idx)->symbol.value;
1384 sunos4_classify_symbol (abfd, idx)
1388 aout_symbol_type *sym = obj_aout_symbols (abfd) + idx;
1390 if ((sym->symbol.flags & BSF_FORT_COMM) != 0) return bfd_symclass_fcommon;
1391 if ((sym->symbol.flags & BSF_GLOBAL) != 0) return bfd_symclass_global;
1392 if ((sym->symbol.flags & BSF_DEBUGGING) != 0) return bfd_symclass_debugger;
1393 if ((sym->symbol.flags & BSF_UNDEFINED) != 0) return bfd_symclass_undefined;
1395 return bfd_symclass_unknown;
1399 sunos4_symbol_hasclass (abfd, idx, class)
1404 aout_symbol_type *sym = obj_aout_symbols (abfd) + idx;
1406 case bfd_symclass_fcommon:
1407 return (sym->symbol.flags & BSF_FORT_COMM) ? true :false;
1408 case bfd_symclass_global:
1409 return (sym->symbol.flags & BSF_GLOBAL) ? true:false;
1410 case bfd_symclass_debugger:
1411 return (sym->symbol.flags & BSF_DEBUGGING) ? true:false;;
1412 case bfd_symclass_undefined:
1413 return (sym->symbol.flags & BSF_UNDEFINED) ? true:false;;
1414 default: return false;
1418 /* Standard reloc stuff */
1419 /* Output standard relocation information to a file in target byte order. */
1422 swap_std_reloc_out (abfd, p, natptr, count)
1424 arelent **p; /* Generic relocation struct */
1425 struct reloc_std_bytes *natptr;
1430 unsigned int r_length;
1432 int r_baserel, r_jmptable, r_relative;
1433 unsigned int r_addend;
1435 for (idx = 0; idx < count; idx++, p++, natptr++)
1438 bfd_h_putlong (abfd, g->address, natptr->r_address);
1440 r_length = g->howto->size; /* Size as a power of two */
1441 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1442 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1447 r_addend = g->addend; /* Start here, see how it goes */
1449 /* name was clobbered by sunos4_write_syms to be symbol index */
1451 if (g->sym_ptr_ptr != NULL)
1453 if ((*(g->sym_ptr_ptr))->section) {
1454 /* put the section offset into the addend for output */
1455 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1458 r_index = stoi((*(g->sym_ptr_ptr))->name);
1463 if (g->section == NULL) {
1465 r_index = N_ABS | N_EXT;
1467 else if(g->section->output_section == obj_textsec(abfd)) {
1468 r_index = N_TEXT | N_EXT;
1469 r_addend += g->section->output_section->vma;
1471 else if (g->section->output_section == obj_datasec(abfd)) {
1472 r_index = N_DATA | N_EXT;
1473 r_addend += g->section->output_section->vma;
1475 else if (g->section->output_section == obj_bsssec(abfd)) {
1476 r_index = N_BSS | N_EXT ;
1477 r_addend += g->section->output_section->vma;
1484 /* now the fun stuff */
1485 if (abfd->xvec->header_byteorder_big_p != false) {
1486 natptr->r_index[0] = r_index >> 16;
1487 natptr->r_index[1] = r_index >> 8;
1488 natptr->r_index[2] = r_index;
1490 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1491 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1492 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1493 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1494 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1495 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1497 natptr->r_index[2] = r_index >> 16;
1498 natptr->r_index[1] = r_index >> 8;
1499 natptr->r_index[0] = r_index;
1501 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1502 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1503 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1504 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1505 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1506 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1514 /* Extended stuff */
1515 /* Output extended relocation information to a file in target byte order. */
1518 swap_ext_reloc_out (abfd, p, natptr, count)
1520 arelent **p; /* Generic relocation struct */
1521 register struct reloc_ext_bytes *natptr;
1527 unsigned int r_type;
1528 unsigned int r_addend;
1530 for (idx = 0; idx < count; idx++, p++, natptr++) {
1533 bfd_h_putlong (abfd, g->address, natptr->r_address);
1535 /* Find a type in the output format which matches the input howto -
1536 at the moment we assume input format == output format FIXME!! */
1537 r_type = (enum reloc_type) g->howto->type;
1539 r_addend = g->addend; /* Start here, see how it goes */
1541 /* name was clobbered by sunos4_write_syms to be symbol index*/
1543 if (g->sym_ptr_ptr != NULL)
1545 if ((*(g->sym_ptr_ptr))->section) {
1546 /* put the section offset into the addend for output */
1547 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1550 r_index = stoi((*(g->sym_ptr_ptr))->name);
1555 if (g->section == NULL) {
1557 r_index = N_ABS | N_EXT;
1559 else if(g->section->output_section == obj_textsec(abfd)) {
1560 r_index = N_TEXT | N_EXT;
1561 r_addend += g->section->output_section->vma;
1563 else if (g->section->output_section == obj_datasec(abfd)) {
1564 r_index = N_DATA | N_EXT;
1565 r_addend += g->section->output_section->vma;
1567 else if (g->section->output_section == obj_bsssec(abfd)) {
1568 r_index = N_BSS | N_EXT ;
1569 r_addend += g->section->output_section->vma;
1576 /* now the fun stuff */
1577 if (abfd->xvec->header_byteorder_big_p != false) {
1578 natptr->r_index[0] = r_index >> 16;
1579 natptr->r_index[1] = r_index >> 8;
1580 natptr->r_index[2] = r_index;
1582 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1583 || (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1585 natptr->r_index[2] = r_index >> 16;
1586 natptr->r_index[1] = r_index >> 8;
1587 natptr->r_index[0] = r_index;
1589 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1590 || (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1593 bfd_h_putlong (abfd, r_addend, natptr->r_addend);
1596 #define MOVE_ADDRESS(ad) \
1598 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1599 cache_ptr->section = (asection *)NULL; \
1600 cache_ptr->addend = ad; \
1602 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1603 switch (r_index) { \
1605 case N_TEXT | N_EXT: \
1606 cache_ptr->section = obj_textsec(abfd); \
1607 cache_ptr->addend = ad - su->textsec->vma; \
1610 case N_DATA | N_EXT: \
1611 cache_ptr->section = obj_datasec(abfd); \
1612 cache_ptr->addend = ad - su->datasec->vma; \
1615 case N_BSS | N_EXT: \
1616 cache_ptr->section = obj_bsssec(abfd); \
1617 cache_ptr->addend = ad - su->bsssec->vma; \
1620 case N_ABS | N_EXT: \
1630 swap_ext_reloc_in (abfd, bytes, cache_ptr, symbols)
1632 struct reloc_ext_bytes *bytes;
1638 unsigned int r_type;
1639 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1641 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1643 /* now the fun stuff */
1644 if (abfd->xvec->header_byteorder_big_p != false) {
1645 r_index = (bytes->r_index[0] << 16)
1646 | (bytes->r_index[1] << 8)
1647 | bytes->r_index[2];
1648 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_BIG));
1649 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_BIG)
1650 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1652 r_index = (bytes->r_index[2] << 16)
1653 | (bytes->r_index[1] << 8)
1654 | bytes->r_index[0];
1655 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1656 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1657 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1660 cache_ptr->howto = howto_table_ext + r_type;
1661 MOVE_ADDRESS(bfd_h_getlong(abfd,bytes->r_addend));
1666 swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
1668 struct reloc_std_bytes *bytes;
1674 unsigned int r_length;
1676 int r_baserel, r_jmptable, r_relative;
1677 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1678 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1680 /* now the fun stuff */
1681 if (abfd->xvec->header_byteorder_big_p != false) {
1682 r_index = (bytes->r_index[0] << 16)
1683 | (bytes->r_index[1] << 8)
1684 | bytes->r_index[2];
1685 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_BIG));
1686 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_BIG));
1687 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_BIG));
1688 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1689 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_BIG));
1690 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_BIG)
1691 >> RELOC_STD_BITS_LENGTH_SH_BIG;
1693 r_index = (bytes->r_index[2] << 16)
1694 | (bytes->r_index[1] << 8)
1695 | bytes->r_index[0];
1696 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1697 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_LITTLE));
1698 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1699 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1700 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1701 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1702 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1705 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1706 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1714 sunos4_slurp_reloc_table (abfd, asect, symbols)
1722 arelent *reloc_cache;
1725 if (asect->relocation) return true;
1727 if (asect->flags & SEC_CONSTRUCTOR) return true;
1729 if (asect == obj_datasec (abfd)) {
1730 reloc_size = exec_hdr(abfd)->a_drsize;
1734 if (asect == obj_textsec (abfd)) {
1735 reloc_size = exec_hdr(abfd)->a_trsize;
1739 bfd_error = invalid_operation;
1743 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1744 each_size = reloc_size_func(abfd);
1746 count = reloc_size / each_size;
1748 relocs = (PTR) malloc (reloc_size);
1750 bfd_error = no_memory;
1753 reloc_cache = (arelent *) zalloc ((size_t)(count * sizeof (arelent)));
1754 if (reloc_cache == (arelent *)NULL) {
1756 bfd_error = no_memory;
1760 if (bfd_read ( relocs, 1, reloc_size, abfd) != reloc_size) {
1761 bfd_error = system_call_error;
1767 if (each_size == RELOC_EXT_SIZE)
1769 register struct reloc_ext_bytes *rptr = (struct reloc_ext_bytes *) relocs;
1770 unsigned int counter = 0;
1771 arelent *cache_ptr = reloc_cache;
1773 for (; counter < count; counter++, rptr++, cache_ptr++) {
1774 swap_ext_reloc_in(abfd, rptr, cache_ptr, symbols);
1778 register struct reloc_std_bytes *rptr = (struct reloc_std_bytes *) relocs;
1779 unsigned int counter = 0;
1780 arelent *cache_ptr = reloc_cache;
1782 for (; counter < count; counter++, rptr++, cache_ptr++) {
1783 swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
1788 asect->relocation = reloc_cache;
1789 asect->reloc_count = count;
1795 /* Write out a relocation section into an object file. */
1798 sunos4_squirt_out_relocs (abfd, section)
1803 unsigned char *native;
1806 unsigned int count = section->reloc_count;
1809 if (count == 0) return true;
1811 each_size = reloc_size_func(abfd);
1812 natsize = each_size * count;
1813 native = (unsigned char *) zalloc (natsize);
1815 bfd_error = no_memory;
1819 generic = section->orelocation;
1821 if (each_size == RELOC_EXT_SIZE)
1823 swap_ext_reloc_out (abfd,
1825 (struct reloc_ext_bytes *)native,
1830 swap_std_reloc_out(abfd, generic, native, count);
1833 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1842 /* This is stupid. This function should be a boolean predicate */
1844 sunos4_canonicalize_reloc (abfd, section, relptr, symbols)
1850 arelent *tblptr = section->relocation;
1853 if (!(tblptr || sunos4_slurp_reloc_table (abfd, section, symbols)))
1856 if (section->flags & SEC_CONSTRUCTOR) {
1857 arelent_chain *chain = section->constructor_chain;
1858 for (count = 0; count < section->reloc_count; count ++) {
1859 *relptr ++ = &chain->relent;
1860 chain = chain->next;
1864 tblptr = section->relocation;
1865 if (!tblptr) return 0;
1867 for (count = 0; count++ < section->reloc_count;)
1869 *relptr++ = tblptr++;
1874 return section->reloc_count;
1878 sunos4_get_reloc_upper_bound (abfd, asect)
1882 if (bfd_get_format (abfd) != bfd_object) {
1883 bfd_error = invalid_operation;
1886 if (asect->flags & SEC_CONSTRUCTOR) {
1887 return (sizeof (arelent *) * (asect->reloc_count+1));
1891 if (asect == obj_datasec (abfd))
1892 return (sizeof (arelent *) *
1893 ((exec_hdr(abfd)->a_drsize / reloc_size_func(abfd))
1896 if (asect == obj_textsec (abfd))
1897 return (sizeof (arelent *) *
1898 ((exec_hdr(abfd)->a_trsize / reloc_size_func(abfd))
1901 bfd_error = invalid_operation;
1906 sunos4_reclaim_reloc (ignore_abfd, section)
1910 if (section->relocation) {
1911 free (section->relocation);
1912 section->relocation = NULL;
1913 section->reloc_count = 0;
1919 sunos4_get_lineno(ignore_abfd, ignore_symbol)
1921 generic_symbol_type *ignore_symbol;
1923 return (alent *)NULL;
1927 sunos4_print_symbol(ignore_abfd, file, symbol, how)
1931 bfd_print_symbol_enum_type how;
1934 case bfd_print_symbol_name_enum:
1935 fprintf(file,"%s", symbol->name);
1937 case bfd_print_symbol_type_enum:
1938 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1939 (unsigned)( aout_symbol(symbol)->other & 0xff),
1940 (unsigned)(aout_symbol(symbol)->type));
1942 case bfd_print_symbol_all_enum:
1944 CONST char *section_name = symbol->section == (asection *)NULL ?
1945 "*abs" : symbol->section->name;
1947 bfd_print_symbol_vandf((PTR)file,symbol);
1949 fprintf(file," %-5s %04x %02x %02x %s",
1951 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1952 (unsigned)(aout_symbol(symbol)->other & 0xff),
1953 (unsigned)(aout_symbol(symbol)->type & 0xff),
1959 /* Once we know all the stuff that could be consed, we know how to clean
1960 it up. So why don't we? */
1963 sunos4_close_and_cleanup (abfd)
1966 if (!bfd_read_p (abfd))
1967 switch (abfd->format) {
1969 if (!_bfd_write_archive_contents (abfd)) return false; break;
1971 if (!sunos4_write_object_contents (abfd)) return false; break;
1972 default: bfd_error = invalid_operation; return false;
1975 #define cleaner(ptr) if (abfd->ptr) free (abfd->ptr)
1978 if (abfd->my_archive)
1986 provided a bfd, a section and an offset into the section, calculate
1987 and return the name of the source file and the line nearest to the
1992 DEFUN(sunos4_find_nearest_line,(abfd,
2000 asection *section AND
2001 asymbol **symbols AND
2003 CONST char **filename_ptr AND
2004 CONST char **functionname_ptr AND
2005 unsigned int *line_ptr)
2007 /* Run down the file looking for the filename, function and linenumber */
2009 static char buffer[100];
2010 bfd_vma high_line_vma = ~0;
2011 bfd_vma low_func_vma = 0;
2013 *filename_ptr = abfd->filename;
2014 *functionname_ptr = 0;
2016 if (symbols != (asymbol **)NULL) {
2017 for (p = symbols; *p; p++) {
2018 aout_symbol_type *q = (aout_symbol_type *)(*p);
2021 *filename_ptr = q->symbol.name;
2022 if (obj_textsec(abfd) != section) {
2030 /* We'll keep this if it resolves nearer than the one we have already */
2031 if (q->symbol.value >= offset &&
2032 q->symbol.value < high_line_vma) {
2033 *line_ptr = q->desc;
2034 high_line_vma = q->symbol.value;
2039 /* We'll keep this if it is nearer than the one we have already */
2040 if (q->symbol.value >= low_func_vma &&
2041 q->symbol.value <= offset) {
2042 low_func_vma = q->symbol.value;
2043 func = (asymbol *)q;
2045 if (*line_ptr && func) {
2046 CONST char *function = func->name;
2048 strncpy(buffer, function, sizeof(buffer)-1);
2049 buffer[sizeof(buffer)-1] = 0;
2050 /* Have to remove : stuff */
2051 p = strchr(buffer,':');
2052 if (p != NULL) {*p = NULL; }
2053 *functionname_ptr = buffer;
2067 bfd_target aout_big_vec =
2069 "a.out-generic-big", /* name */
2070 bfd_target_aout_flavour_enum,
2071 true, /* target byte order */
2072 true, /* target headers byte order */
2073 (HAS_RELOC | EXEC_P | /* object flags */
2074 HAS_LINENO | HAS_DEBUG |
2075 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
2076 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2077 0, /* valid reloc types */
2078 ' ', /* ar_pad_char */
2079 16, /* ar_max_namelen */
2080 sunos4_close_and_cleanup, /* _close_and_cleanup */
2081 sunos4_set_section_contents, /* bfd_set_section_contents */
2082 sunos4_get_section_contents, /* bfd_get_section_contents */
2083 sunos4_new_section_hook, /* new_section_hook */
2084 sunos4_core_file_failing_command, /* _core_file_failing_command */
2085 sunos4_core_file_failing_signal, /* _core_file_failing_signal */
2086 sunos4_core_file_matches_executable_p, /* _core_file_matches_ex...p */
2088 bfd_slurp_bsd_armap, /* bfd_slurp_armap */
2089 bfd_true, /* bfd_slurp_extended_name_table */
2090 bfd_bsd_truncate_arname, /* bfd_truncate_arname */
2092 sunos4_get_symtab_upper_bound, /* get_symtab_upper_bound */
2093 sunos4_get_symtab, /* canonicalize_symtab */
2094 sunos4_reclaim_symbol_table, /* bfd_reclaim_symbol_table */
2095 sunos4_get_reloc_upper_bound, /* get_reloc_upper_bound */
2096 sunos4_canonicalize_reloc, /* bfd_canonicalize_reloc */
2097 sunos4_reclaim_reloc, /* bfd_reclaim_reloc */
2098 sunos4_get_symcount_upper_bound, /* bfd_get_symcount_upper_bound */
2099 sunos4_get_first_symbol, /* bfd_get_first_symbol */
2100 sunos4_get_next_symbol, /* bfd_get_next_symbol */
2101 sunos4_classify_symbol, /* bfd_classify_symbol */
2102 sunos4_symbol_hasclass, /* bfd_symbol_hasclass */
2103 sunos4_symbol_name, /* bfd_symbol_name */
2104 sunos4_symbol_value, /* bfd_symbol_value */
2106 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
2107 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
2109 {_bfd_dummy_target, sunos4_object_p, /* bfd_check_format */
2110 bfd_generic_archive_p, sunos4_core_file_p},
2111 {bfd_false, sunos4_mkobject, /* bfd_zxset_format */
2112 _bfd_generic_mkarchive, bfd_false},
2113 sunos4_make_empty_symbol,
2114 sunos4_print_symbol,
2116 sunos4_set_arch_mach,
2118 bfd_generic_openr_next_archived_file,
2119 sunos4_find_nearest_line, /* bfd_find_nearest_line */
2120 bfd_generic_stat_arch_elt /* bfd_stat_arch_elt */
2123 bfd_target aout_little_vec =
2125 "a.out-generic-little", /* name */
2126 bfd_target_aout_flavour_enum,
2127 true, /* target byte order */
2128 true, /* target headers byte order */
2129 (HAS_RELOC | EXEC_P | /* object flags */
2130 HAS_LINENO | HAS_DEBUG |
2131 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
2132 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2133 0, /* valid reloc types */
2134 ' ', /* ar_pad_char */
2135 16, /* ar_max_namelen */
2136 sunos4_close_and_cleanup, /* _close_and_cleanup */
2137 sunos4_set_section_contents, /* bfd_set_section_contents */
2138 sunos4_get_section_contents, /* bfd_get_section_contents */
2139 sunos4_new_section_hook, /* new_section_hook */
2140 sunos4_core_file_failing_command, /* _core_file_failing_command */
2141 sunos4_core_file_failing_signal, /* _core_file_failing_signal */
2142 sunos4_core_file_matches_executable_p, /* _core_file_matches_ex...p */
2144 bfd_slurp_bsd_armap, /* bfd_slurp_armap */
2145 bfd_true, /* bfd_slurp_extended_name_table */
2146 bfd_bsd_truncate_arname, /* bfd_truncate_arname */
2148 sunos4_get_symtab_upper_bound, /* get_symtab_upper_bound */
2149 sunos4_get_symtab, /* canonicalize_symtab */
2150 sunos4_reclaim_symbol_table, /* bfd_reclaim_symbol_table */
2151 sunos4_get_reloc_upper_bound, /* get_reloc_upper_bound */
2152 sunos4_canonicalize_reloc, /* bfd_canonicalize_reloc */
2153 sunos4_reclaim_reloc, /* bfd_reclaim_reloc */
2154 sunos4_get_symcount_upper_bound, /* bfd_get_symcount_upper_bound */
2155 sunos4_get_first_symbol, /* bfd_get_first_symbol */
2156 sunos4_get_next_symbol, /* bfd_get_next_symbol */
2157 sunos4_classify_symbol, /* bfd_classify_symbol */
2158 sunos4_symbol_hasclass, /* bfd_symbol_hasclass */
2159 sunos4_symbol_name, /* bfd_symbol_name */
2160 sunos4_symbol_value, /* bfd_symbol_value */
2162 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* data */
2163 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* hdrs */
2165 {_bfd_dummy_target, sunos4_object_p, /* bfd_check_format */
2166 bfd_generic_archive_p, sunos4_core_file_p},
2167 {bfd_false, sunos4_mkobject, /* bfd_zxset_format */
2168 _bfd_generic_mkarchive, bfd_false},
2169 sunos4_make_empty_symbol,
2170 sunos4_print_symbol,
2172 sunos4_set_arch_mach,
2174 bfd_generic_openr_next_archived_file,
2175 sunos4_find_nearest_line, /* bfd_find_nearest_line */
2176 bfd_generic_stat_arch_elt /* bfd_stat_arch_elt */