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)();
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 HOWTO(RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false),
57 HOWTO(RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false),
58 HOWTO(RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff, false),
59 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, false, true,0,"DISP8", false, 0,0x000000ff, false),
60 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, false, true,0,"DISP16", false, 0,0x0000ffff, false),
61 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, false, true,0,"DISP32", false, 0,0xffffffff, false),
62 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, false, true,0,"WDISP30", false, 0,0x3fffffff, false),
63 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, false, true,0,"WDISP22", false, 0,0x003fffff, false),
64 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, false, true,0,"HI22", false, 0,0x003fffff, false),
65 HOWTO(RELOC_22, 0, 2, 22, false, 0, false, true,0,"22", false, 0,0x003fffff, false),
66 HOWTO(RELOC_13, 0, 2, 13, false, 0, false, true,0,"13", false, 0,0x00001fff, false),
67 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, false, true,0,"LO10", false, 0,0x000003ff, false),
68 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
69 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
70 HOWTO(RELOC_BASE10, 0, 2, 16, false, 0, false, true,0,"BASE10", false, 0,0x0000ffff, false),
71 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, false, true,0,"BASE13", false, 0,0x00001fff, false),
72 HOWTO(RELOC_BASE22, 0, 2, 0, false, 0, false, true,0,"BASE22", false, 0,0x00000000, false),
73 HOWTO(RELOC_PC10, 0, 2, 10, false, 0, false, true,0,"PC10", false, 0,0x000003ff, false),
74 HOWTO(RELOC_PC22, 0, 2, 22, false, 0, false, true,0,"PC22", false, 0,0x003fffff, false),
75 HOWTO(RELOC_JMP_TBL,0, 2, 32, false, 0, false, true,0,"JMP_TBL", false, 0,0xffffffff, false),
76 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
77 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
78 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
79 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, false, true,0,"RELATIVE", false, 0,0x00000000, false),
80 HOWTO(RELOC_JUMPTARG,2, 13, 16, true, 0, false, true,0,"JUMPTARG", false, 0,0x0000ffff, false),
81 HOWTO(RELOC_CONST, 0, 13, 16, false, 0, false, true,0,"CONST", false, 0,0x0000ffff, false),
82 HOWTO(RELOC_CONSTH, 16, 13, 16, false, 0, false, true,0,"CONSTH", false, 0,0x0000ffff, false),
85 /* Convert standard reloc records to "arelent" format (incl byte swap). */
87 static reloc_howto_type howto_table_std[] = {
88 /* type rs size bsz pcrel bitpos abs ovrf sf name*/
89 HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),
90 HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),
91 HOWTO( 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff, false),
92 HOWTO( 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead, false),
93 HOWTO( 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff, false),
94 HOWTO( 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
95 HOWTO( 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff, false),
96 HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface, false),
100 bfd_error_vector_type bfd_error_vector;
104 PROTO (void , sunos4_write_syms, ());
105 PROTO (static boolean,sunos4_squirt_out_relocs,(bfd *abfd, asection *section));
109 reloc_size_func(abfd)
112 switch (bfd_get_architecture (abfd)) {
115 return RELOC_EXT_SIZE;
117 return RELOC_STD_SIZE;
122 DEFUN(bfd_aout_swap_exec_header_in,(abfd, raw_bytes, execp),
124 unsigned char *raw_bytes AND
127 struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
129 /* Now fill in fields in the execp, from the bytes in the raw data. */
130 execp->a_info = bfd_h_getlong (abfd, bytes->a_info);
131 execp->a_text = bfd_h_getlong (abfd, bytes->a_text);
132 execp->a_data = bfd_h_getlong (abfd, bytes->a_data);
133 execp->a_bss = bfd_h_getlong (abfd, bytes->a_bss);
134 execp->a_syms = bfd_h_getlong (abfd, bytes->a_syms);
135 execp->a_entry = bfd_h_getlong (abfd, bytes->a_entry);
136 execp->a_trsize = bfd_h_getlong (abfd, bytes->a_trsize);
137 execp->a_drsize = bfd_h_getlong (abfd, bytes->a_drsize);
141 DEFUN(bfd_aout_swap_exec_header_out,(abfd, execp, raw_bytes),
143 struct exec *execp AND
144 unsigned char *raw_bytes)
146 struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
148 /* Now fill in fields in the raw data, from the fields in the exec struct. */
149 bfd_h_putlong (abfd, execp->a_info , bytes->a_info);
150 bfd_h_putlong (abfd, execp->a_text , bytes->a_text);
151 bfd_h_putlong (abfd, execp->a_data , bytes->a_data);
152 bfd_h_putlong (abfd, execp->a_bss , bytes->a_bss);
153 bfd_h_putlong (abfd, execp->a_syms , bytes->a_syms);
154 bfd_h_putlong (abfd, execp->a_entry , bytes->a_entry);
155 bfd_h_putlong (abfd, execp->a_trsize, bytes->a_trsize);
156 bfd_h_putlong (abfd, execp->a_drsize, bytes->a_drsize);
159 /* Steve wants some way to frob this stuff from Saber while he's debugging
160 ld, so we have these funny shadow functions */
161 /* ZMAGIC's start at 0 (making the exec part of the text section),
162 other formats start after the exec
164 static unsigned int n_txtoff(ptr)
166 {return N_MAGIC(*ptr)== ZMAGIC ? 0: sizeof(struct exec);}
168 static unsigned int n_datoff(ptr)
170 {return n_txtoff(ptr) + ptr->a_text;}
172 static unsigned int n_treloff(ptr)
174 {return n_datoff(ptr) + ptr->a_data;}
176 static unsigned int n_dreloff(ptr)
178 {return n_treloff(ptr) + ptr->a_trsize;}
180 static unsigned int n_symoff(ptr)
182 {return n_dreloff(ptr) + ptr->a_drsize;}
184 static unsigned int n_stroff(ptr)
186 {return n_symoff(ptr) + ptr->a_syms;}
189 unsigned int n_badmag(ptr)
192 switch (N_MAGIC(*ptr)) {
193 case OMAGIC: case NMAGIC: case ZMAGIC: return 0;
199 sunos4_object_p (abfd)
202 unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
203 unsigned long magic; /* Swapped magic number */
204 unsigned char exec_bytes[EXEC_BYTES_SIZE]; /* Raw bytes of exec hdr */
208 bfd_error = system_call_error;
210 if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
213 magic = bfd_h_getlong (abfd, magicbuf);
215 /* Baroque syntax to mask deficiencies of the Sun compiler */
216 /* if (N_BADMAG (*((struct exec *) &magic))) return 0; */
217 if (n_badmag ((struct exec *) &magic)) return 0;
219 if (bfd_seek (abfd, 0L, false) < 0) return 0;
221 if (bfd_read ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
222 != EXEC_BYTES_SIZE) {
223 bfd_error = wrong_format;
227 /* Use an intermediate variable for clarity */
228 rawptr = (PTR) bfd_zalloc (abfd, sizeof (struct sunexdata) + sizeof (struct exec));
230 if (rawptr == NULL) {
231 bfd_error = no_memory;
235 set_tdata (abfd, ((struct sunexdata *) rawptr));
236 exec_hdr (abfd) = execp =
237 (struct exec *) ((char *)rawptr + sizeof (struct sunexdata));
239 bfd_aout_swap_exec_header_in (abfd, exec_bytes, execp);
241 /* Set the file flags */
242 abfd->flags = NO_FLAGS;
243 if (execp->a_drsize || execp->a_trsize)
244 abfd->flags |= HAS_RELOC;
246 abfd->flags |= EXEC_P;
248 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
251 if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
252 if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
254 /* Determine the architecture and machine type of the object file. */
255 abfd->obj_arch = bfd_arch_unknown; /* Default values */
256 abfd->obj_machine = 0;
257 switch (N_MACHTYPE (*execp)) {
263 abfd->obj_arch = bfd_arch_m68k;
264 abfd->obj_machine = 68010;
268 abfd->obj_arch = bfd_arch_m68k;
269 abfd->obj_machine = 68020;
273 abfd->obj_arch = bfd_arch_sparc;
277 abfd->obj_arch = bfd_arch_i386;
281 abfd->obj_arch = bfd_arch_a29k;
285 abfd->obj_arch = bfd_arch_obscure;
289 bfd_get_start_address (abfd) = execp->a_entry;
291 /* Remember the positions of the string table and symbol table. */
292 obj_str_filepos (abfd) = n_stroff (execp);
293 obj_sym_filepos (abfd) = n_symoff (execp);
295 /* create the sections. This is raunchy, but bfd_close wants to reclaim
297 obj_textsec (abfd) = (asection *)NULL;
298 obj_datasec (abfd) = (asection *)NULL;
299 obj_bsssec (abfd) = (asection *)NULL;
300 obj_aout_symbols(abfd) = (aout_symbol_type *)NULL;
301 (void)bfd_make_section(abfd, ".text");
302 (void)bfd_make_section(abfd, ".data");
303 (void)bfd_make_section(abfd, ".bss");
305 obj_datasec (abfd)->size = execp->a_data;
306 obj_bsssec (abfd)->size = execp->a_bss;
307 obj_textsec (abfd)->size = execp->a_text;
308 obj_datasec (abfd)->vma = N_DATADDR(*execp);
309 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
310 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
312 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
313 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
315 obj_textsec (abfd)->rel_filepos = N_TROFF(*execp);
316 obj_datasec (abfd)->rel_filepos = N_DROFF(*execp);
318 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
319 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
320 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
321 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
322 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
323 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
324 obj_bsssec (abfd)->flags = SEC_ALLOC;
326 abfd->sections = obj_textsec (abfd);
327 obj_textsec (abfd)->next = obj_datasec (abfd);
328 obj_datasec (abfd)->next = obj_bsssec (abfd);
334 sunos4_mkobject (abfd)
339 bfd_error = system_call_error;
341 /* Use an intermediate variable for clarity */
342 rawptr = bfd_zalloc (abfd,sizeof (struct sunexdata) + sizeof (struct exec));
344 if (rawptr == NULL) {
345 bfd_error = no_memory;
349 abfd->tdata = (PTR)((struct sunexdata *) rawptr);
350 exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct sunexdata));
352 /* For simplicity's sake we just make all the sections right here. */
354 obj_textsec (abfd) = (asection *)NULL;
355 obj_datasec (abfd) = (asection *)NULL;
356 obj_bsssec (abfd) = (asection *)NULL;
357 bfd_make_section (abfd, ".text");
358 bfd_make_section (abfd, ".data");
359 bfd_make_section (abfd, ".bss");
364 /* Keep track of machine architecture and machine type for a.out's.
365 Return the machine_type for a particular arch&machine, or M_UNKNOWN
366 if that exact arch&machine can't be represented in a.out format.
368 If the architecture is understood, machine type 0 (default) should
369 always be understood. */
371 static enum machine_type
372 aout_machine_type (arch, machine)
373 enum bfd_architecture arch;
374 unsigned long machine;
376 enum machine_type arch_flags;
378 arch_flags = M_UNKNOWN;
382 if (machine == 0) arch_flags = M_SPARC;
387 case 0: arch_flags = M_68010; break;
388 case 68000: arch_flags = M_UNKNOWN; break;
389 case 68010: arch_flags = M_68010; break;
390 case 68020: arch_flags = M_68020; break;
391 default: arch_flags = M_UNKNOWN; break;
396 if (machine == 0) arch_flags = M_386;
400 if (machine == 0) arch_flags = M_29K;
404 arch_flags = M_UNKNOWN;
411 sunos4_set_arch_mach (abfd, arch, machine)
413 enum bfd_architecture arch;
414 unsigned long machine;
416 abfd->obj_arch = arch;
417 abfd->obj_machine = machine;
418 if (arch != bfd_arch_unknown &&
419 aout_machine_type (arch, machine) == M_UNKNOWN)
420 return false; /* We can't represent this type */
421 return true; /* We're easy ... */
425 sunos4_write_object_contents (abfd)
429 unsigned char exec_bytes[EXEC_BYTES_SIZE];
430 struct exec *execp = exec_hdr (abfd);
432 execp->a_text = obj_textsec (abfd)->size;
434 /* Magic number, maestro, please! */
435 switch (bfd_get_architecture(abfd)) {
437 switch (bfd_get_machine(abfd)) {
439 N_SET_MACHTYPE(*execp, M_68010);
443 N_SET_MACHTYPE(*execp, M_68020);
448 N_SET_MACHTYPE(*execp, M_SPARC);
451 N_SET_MACHTYPE(*execp, M_386);
454 N_SET_MACHTYPE(*execp, M_29K);
457 N_SET_MACHTYPE(*execp, M_UNKNOWN);
460 N_SET_MAGIC (*execp, OMAGIC);
461 if (abfd->flags & D_PAGED) {
462 execp->a_text = obj_textsec (abfd)->size + sizeof(struct exec);
463 N_SET_MAGIC (*execp, ZMAGIC);
464 } else if (abfd->flags & WP_TEXT) {
465 N_SET_MAGIC (*execp, NMAGIC);
467 N_SET_FLAGS (*execp, 0x1); /* copied from ld.c; who the hell knows? */
469 if (abfd->flags & D_PAGED)
471 data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
472 & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
474 if (data_pad > obj_bsssec(abfd)->size)
477 execp->a_bss = obj_bsssec(abfd)->size - data_pad;
478 execp->a_data = obj_datasec(abfd)->size + data_pad;
482 execp->a_data = obj_datasec (abfd)->size;
483 execp->a_bss = obj_bsssec (abfd)->size;
486 execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
487 execp->a_entry = bfd_get_start_address (abfd);
489 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
490 reloc_size_func(abfd));
492 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
493 reloc_size_func(abfd));
495 bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
497 bfd_seek (abfd, 0L, false);
498 bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
500 /* Now write out reloc info, followed by syms and strings */
502 if (bfd_get_symcount (abfd) != 0)
505 (long)(N_SYMOFF(*execp)), false);
507 sunos4_write_syms (abfd);
509 bfd_seek (abfd, (long)(N_TROFF(*execp)), false);
511 if (!sunos4_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
512 bfd_seek (abfd, (long)(N_DROFF(*execp)), false);
514 if (!sunos4_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
522 #define CORE_MAGIC 0x080456
523 #define CORE_NAMELEN 16
525 /* The core structure is taken from the Sun documentation.
526 Unfortunately, they don't document the FPA structure, or at least I
527 can't find it easily. Fortunately the core header contains its own
528 length. So this shouldn't cause problems, except for c_ucode, which
529 so far we don't use but is easy to find with a little arithmetic. */
531 /* But the reg structure can be gotten from the SPARC processor handbook.
532 This really should be in a GNU include file though so that gdb can use
556 /* Taken from Sun documentation: */
558 /* FIXME: It's worse than we expect. This struct contains TWO substructs
559 neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't
560 even portably access the stuff in between! */
563 int c_magic; /* Corefile magic number */
564 int c_len; /* Sizeof (struct core) */
565 struct regs c_regs; /* General purpose registers */
566 struct exec c_aouthdr; /* A.out header */
567 int c_signo; /* Killing signal, if any */
568 int c_tsize; /* Text size (bytes) */
569 int c_dsize; /* Data size (bytes) */
570 int c_ssize; /* Stack size (bytes) */
571 char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
572 double fp_stuff[1]; /* external FPU state (size unknown by us) */
573 /* The type "double" is critical here, for alignment.
574 SunOS declares a struct here, but the struct's alignment
575 is double since it contains doubles. */
576 int c_ucode; /* Exception no. from u_code */
577 /* (this member is not accessible by name since we don't
578 portably know the size of fp_stuff.) */
581 /* Supposedly the user stack grows downward from the bottom of kernel memory.
582 Presuming that this remains true, this definition will work. */
583 #define USRSTACK (-(128*1024*1024))
585 PROTO (static void, swapcore, (bfd *abfd, struct core *core));
587 /* need this cast b/c ptr is really void * */
588 #define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
589 #define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
590 #define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
591 #define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
592 #define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
594 /* These are stored in the bfd's tdata */
596 struct core *hdr; /* core file header */
597 asection *data_section;
598 asection *stack_section;
599 asection *reg_section;
600 asection *reg2_section;
604 sunos4_core_file_p (abfd)
607 unsigned char longbuf[4]; /* Raw bytes of various header fields */
613 bfd_error = system_call_error;
615 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
618 core_mag = bfd_h_getlong (abfd, longbuf);
620 if (core_mag != CORE_MAGIC) return 0;
622 /* SunOS core headers can vary in length; second word is size; */
623 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
626 core_size = bfd_h_getlong (abfd, longbuf);
628 if (core_size > 20000)
631 if (bfd_seek (abfd, 0L, false) < 0) return 0;
633 rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
634 if (rawptr == NULL) {
635 bfd_error = no_memory;
639 core = (struct core *) (rawptr + sizeof (struct suncordata));
641 if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
642 bfd_error = system_call_error;
647 swapcore (abfd, core);
648 set_tdata (abfd, ((struct suncordata *) rawptr));
649 core_hdr (abfd) = core;
651 /* create the sections. This is raunchy, but bfd_close wants to reclaim
653 core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
654 if (core_stacksec (abfd) == NULL) {
656 bfd_error = no_memory;
660 core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
661 if (core_datasec (abfd) == NULL) {
663 free ((PTR)core_stacksec (abfd));
666 core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
667 if (core_regsec (abfd) == NULL) {
669 free ((PTR)core_datasec (abfd));
672 core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
673 if (core_reg2sec (abfd) == NULL) {
674 free ((PTR)core_regsec (abfd));
678 core_stacksec (abfd)->name = ".stack";
679 core_datasec (abfd)->name = ".data";
680 core_regsec (abfd)->name = ".reg";
681 core_reg2sec (abfd)->name = ".reg2";
683 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
684 core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
685 core_regsec (abfd)->flags = SEC_ALLOC;
686 core_reg2sec (abfd)->flags = SEC_ALLOC;
688 core_stacksec (abfd)->size = core->c_ssize;
689 core_datasec (abfd)->size = core->c_dsize;
690 core_regsec (abfd)->size = (sizeof core->c_regs);
691 /* Float regs take up end of struct, except c_ucode. */
692 core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) -
693 (file_ptr)(((struct core *)0)->fp_stuff);
695 core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize);
696 core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr);
697 core_regsec (abfd)->vma = -1;
698 core_reg2sec (abfd)->vma = -1;
700 core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
701 core_datasec (abfd)->filepos = core->c_len;
702 /* In file header: */
703 core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs);
704 core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
706 /* Align to word at least */
707 core_stacksec (abfd)->alignment_power = 2;
708 core_datasec (abfd)->alignment_power = 2;
709 core_regsec (abfd)->alignment_power = 2;
710 core_reg2sec (abfd)->alignment_power = 2;
712 abfd->sections = core_stacksec (abfd);
713 core_stacksec (abfd)->next = core_datasec (abfd);
714 core_datasec (abfd)->next = core_regsec (abfd);
715 core_regsec (abfd)->next = core_reg2sec (abfd);
717 abfd->section_count = 4;
723 sunos4_core_file_failing_command (abfd)
726 return core_hdr (abfd)->c_cmdname;
730 sunos4_core_file_failing_signal (abfd)
733 return core_hdr (abfd)->c_signo;
737 sunos4_core_file_matches_executable_p (core_bfd, exec_bfd)
738 bfd *core_bfd, *exec_bfd;
740 if (core_bfd->xvec != exec_bfd->xvec) {
741 bfd_error = system_call_error;
745 return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
746 sizeof (struct exec)) == 0) ? true : false;
749 /* byte-swap core structure */
750 /* FIXME, this needs more work to swap IN a core struct from raw bytes */
752 swapcore (abfd, core)
756 unsigned char exec_bytes[EXEC_BYTES_SIZE];
758 core->c_magic = bfd_h_getlong (abfd, (unsigned char *)&core->c_magic);
759 core->c_len = bfd_h_getlong (abfd, (unsigned char *)&core->c_len );
760 /* Leave integer registers in target byte order. */
761 bcopy ((char *)&(core->c_aouthdr), (char *)exec_bytes, EXEC_BYTES_SIZE);
762 bfd_aout_swap_exec_header_in (abfd, exec_bytes, &core->c_aouthdr);
763 core->c_signo = bfd_h_getlong (abfd, (unsigned char *)&core->c_signo);
764 core->c_tsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_tsize);
765 core->c_dsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_dsize);
766 core->c_ssize = bfd_h_getlong (abfd, (unsigned char *)&core->c_ssize);
767 /* Leave FP registers in target byte order. */
768 /* Leave "c_ucode" unswapped for now, since we can't find it easily. */
771 /** exec and core file sections */
774 sunos4_new_section_hook (abfd, newsect)
778 /* align to double at least */
779 newsect->alignment_power = 3;
781 if (bfd_get_format (abfd) == bfd_object) {
782 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
783 obj_textsec(abfd)= newsect;
787 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
788 obj_datasec(abfd) = newsect;
792 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
793 obj_bsssec(abfd) = newsect;
798 /* We allow more than three sections internally */
803 sunos4_set_section_contents (abfd, section, location, offset, count)
806 unsigned char *location;
810 if (abfd->output_has_begun == false)
811 { /* set by bfd.c handler */
812 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL)
815 (obj_textsec (abfd)->size == 0) || (obj_datasec (abfd)->size=
819 bfd_error = invalid_operation;
825 if (abfd->flags & D_PAGED)
827 obj_textsec (abfd)->filepos = sizeof(struct exec);
828 obj_datasec(abfd)->filepos = obj_textsec (abfd)->size;
833 obj_textsec (abfd)->filepos = sizeof(struct exec);
834 obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos + obj_textsec (abfd)->size;
838 /* regardless, once we know what we're doing, we might as well get going */
839 if (section != obj_bsssec(abfd)) {
840 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
843 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
851 sunos4_get_section_contents (abfd, section, location, offset, count)
859 if (offset >= section->size) return false;
861 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
863 return (bfd_read (location, 1, count, abfd) == count) ? true:false;
869 /* Classify stabs symbols */
872 #define sym_in_text_section(sym) \
873 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
875 #define sym_in_data_section(sym) \
876 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
878 #define sym_in_bss_section(sym) \
879 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
881 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
882 zero in the "value" field. Nonzeroes there are fortrancommon
884 #define sym_is_undefined(sym) \
885 ((sym)->n_type == (N_UNDF | N_EXT) && (sym)->n_value == 0)
887 /* Symbol is a global definition if N_EXT is on and if it has
888 a nonzero type field. */
889 #define sym_is_global_defn(sym) \
890 (((sym)->n_type & N_EXT) && (sym)->n_type & N_TYPE)
892 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
894 #define sym_is_debugger_info(sym) \
895 ((sym)->n_type & ~(N_EXT | N_TYPE))
897 #define sym_is_fortrancommon(sym) \
898 (((sym)->n_type == (N_EXT)) && (sym)->n_value != 0)
900 /* Symbol is absolute if it has N_ABS set */
901 #define sym_is_absolute(sym) \
902 (((sym)->n_type & N_TYPE)== N_ABS)
905 #define sym_is_indirect(sym) \
906 (((sym)->n_type & N_ABS)== N_ABS)
908 /* Only in their own functions for ease of debugging; when sym flags have
909 stabilised these should be inlined into their (single) caller */
912 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd)
913 struct nlist *sym_pointer;
914 aout_symbol_type *cache_ptr;
917 switch (cache_ptr->type & N_TYPE) {
923 asection *section = bfd_make_section(abfd,
924 cache_ptr->symbol.name);
925 arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
927 switch ( (cache_ptr->type & N_TYPE) ) {
929 reloc->relent.section = (asection *)NULL;
930 cache_ptr->symbol.section = (asection *)NULL;
933 reloc->relent.section = (asection *)obj_textsec(abfd);
934 cache_ptr->symbol.value -= reloc->relent.section->vma;
937 reloc->relent.section = (asection *)obj_datasec(abfd);
938 cache_ptr->symbol.value -= reloc->relent.section->vma;
941 reloc->relent.section = (asection *)obj_bsssec(abfd);
942 cache_ptr->symbol.value -= reloc->relent.section->vma;
945 cache_ptr->symbol.section = reloc->relent.section;
946 reloc->relent.addend = cache_ptr->symbol.value ;
948 We modify the symbol to belong to a section depending upon the
949 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
950 really care, and add to the size of the section to contain a
951 pointer to the symbol. Build a reloc entry to relocate to this
952 symbol attached to this section.
956 section->flags = SEC_CONSTRUCTOR;
957 section->reloc_count++;
958 section->alignment_power = 2;
959 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
960 reloc->next = section->constructor_chain;
961 section->constructor_chain = reloc;
962 reloc->relent.address = section->size;
963 section->size += sizeof(int *);
965 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
966 cache_ptr->symbol.flags |= BSF_DEBUGGING ;
971 if (sym_is_debugger_info (sym_pointer)) {
972 cache_ptr->symbol.flags = BSF_DEBUGGING ;
973 /* Work out the section correct for this symbol */
974 switch (sym_pointer->n_type & N_TYPE)
978 cache_ptr->symbol.section = obj_textsec (abfd);
979 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
982 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
983 cache_ptr->symbol.section = obj_datasec (abfd);
986 cache_ptr->symbol.section = obj_bsssec (abfd);
987 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
991 cache_ptr->symbol.section = 0;
996 if (sym_is_fortrancommon (sym_pointer))
998 cache_ptr->symbol.flags = BSF_FORT_COMM;
999 cache_ptr->symbol.section = (asection *)NULL;
1002 if (sym_is_undefined (sym_pointer)) {
1003 cache_ptr->symbol.flags = BSF_UNDEFINED;
1005 else if (sym_is_global_defn (sym_pointer)) {
1006 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1009 else if (sym_is_absolute (sym_pointer)) {
1010 cache_ptr->symbol.flags = BSF_ABSOLUTE;
1013 cache_ptr->symbol.flags = BSF_LOCAL;
1016 /* In a.out, the value of a symbol is always relative to the
1017 * start of the file, if this is a data symbol we'll subtract
1018 * the size of the text section to get the section relative
1019 * value. If this is a bss symbol (which would be strange)
1020 * we'll subtract the size of the previous two sections
1021 * to find the section relative address.
1024 if (sym_in_text_section (sym_pointer)) {
1025 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
1026 cache_ptr->symbol.section = obj_textsec (abfd);
1028 else if (sym_in_data_section (sym_pointer)){
1029 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
1030 cache_ptr->symbol.section = obj_datasec (abfd);
1032 else if (sym_in_bss_section(sym_pointer)) {
1033 cache_ptr->symbol.section = obj_bsssec (abfd);
1034 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
1037 cache_ptr->symbol.section = (asection *)NULL;
1038 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
1046 translate_to_native_sym_flags (sym_pointer, cache_ptr_g, abfd)
1047 struct nlist *sym_pointer;
1051 asymbol *cache_ptr = (asymbol *)cache_ptr_g;
1053 /* FIXME check for wrigin bss */
1054 if (bfd_get_section(cache_ptr)) {
1055 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
1056 sym_pointer->n_type |= N_BSS;
1058 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
1059 sym_pointer->n_type |= N_DATA;
1061 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
1062 sym_pointer->n_type |= N_TEXT;
1066 bfd_error_vector.nonrepresentable_section(abfd, bfd_get_output_section(cache_ptr)->name);
1069 /* Turn the symbol from section relative to absolute again */
1070 sym_pointer->n_value +=
1071 cache_ptr->section->output_section->vma
1072 + cache_ptr->section->output_offset ;
1075 sym_pointer->n_type |= N_ABS;
1078 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
1079 sym_pointer->n_type = (N_UNDF | N_EXT);
1083 if (cache_ptr->flags & BSF_ABSOLUTE) {
1084 sym_pointer->n_type |= N_ABS;
1087 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1088 sym_pointer->n_type |= N_EXT;
1090 if (cache_ptr->flags & BSF_DEBUGGING) {
1091 sym_pointer->n_type = ((aout_symbol_type *)cache_ptr)->type;
1096 /* Native-level interface to symbols. */
1098 /* We read the symbols into a buffer, which is discarded when this
1099 function exits. We read the strings into a buffer large enough to
1100 hold them all plus all the cached symbol entries. */
1103 sunos4_make_empty_symbol (abfd)
1106 aout_symbol_type *new =
1107 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1108 new->symbol.the_bfd = abfd;
1110 return &new->symbol;
1114 DEFUN(sunos4_slurp_symbol_table, (abfd),
1117 unsigned int symbol_count;
1122 aout_symbol_type *cached;
1124 /* If there's no work to be done, don't do any */
1125 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1126 symbol_size = exec_hdr(abfd)->a_syms;
1127 if (symbol_size == 0) {
1128 bfd_error = no_symbols;
1132 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1133 if (bfd_read ((PTR)&string_size, 4, 1, abfd) != 4)
1135 string_size = bfd_h_getlong (abfd, (unsigned char *)&string_size);
1137 symbol_count = symbol_size / sizeof (struct nlist);
1139 strings = bfd_alloc(abfd, string_size + 1);
1140 cached = bfd_zalloc(abfd, symbol_count * sizeof(aout_symbol_type));
1141 syms = bfd_alloc(abfd, symbol_size);
1143 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1144 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
1149 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1150 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
1154 /* OK, now walk the new symtable, cacheing symbol properties */
1156 register struct nlist *sym_pointer;
1157 register struct nlist *sym_end = syms + symbol_count;
1158 register aout_symbol_type *cache_ptr = cached;
1160 /* run through the table and byte swap if needed */
1161 for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++) {
1162 sym_pointer->n_un.n_strx =
1163 bfd_h_get_x (abfd, &sym_pointer->n_un.n_strx);
1164 sym_pointer->n_desc =
1165 bfd_h_get_x (abfd, &sym_pointer->n_desc);
1166 sym_pointer->n_value =
1167 bfd_h_get_x (abfd, &sym_pointer->n_value);
1168 sym_pointer->n_other = (char)
1169 bfd_h_get_x(abfd, &sym_pointer->n_other);
1170 sym_pointer->n_type = (char)
1171 bfd_h_get_x(abfd, &sym_pointer->n_type);
1175 /* Run through table and copy values */
1176 for (sym_pointer = syms, cache_ptr = cached;
1177 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
1179 cache_ptr->symbol.the_bfd = abfd;
1180 if (sym_pointer->n_un.n_strx)
1181 cache_ptr->symbol.name = sym_pointer->n_un.n_strx + strings;
1183 cache_ptr->symbol.name = (char *)NULL;
1184 cache_ptr->symbol.value = sym_pointer->n_value;
1185 cache_ptr->desc = sym_pointer->n_desc;
1186 cache_ptr->other = sym_pointer->n_other;
1187 cache_ptr->type = sym_pointer->n_type;
1188 cache_ptr->symbol.udata = 0;
1189 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1194 obj_aout_symbols (abfd) = cached;
1195 bfd_get_symcount (abfd) = symbol_count;
1196 bfd_release (abfd, (PTR)syms);
1203 DEFUN(sunos4_write_syms,(abfd),
1206 unsigned int count ;
1207 asymbol **generic = bfd_get_outsymbols (abfd);
1209 unsigned int stindex = sizeof(stindex); /* initial string length */
1211 for (count = 0; count < bfd_get_symcount (abfd); count++) {
1212 asymbol *g = generic[count];
1216 unsigned int length = strlen(g->name) +1;
1217 bfd_h_putlong (abfd, stindex, (unsigned char *)&nsp.n_un.n_strx);
1221 bfd_h_putlong (abfd, 0, (unsigned char *)&nsp.n_un.n_strx);
1224 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
1226 nsp.n_desc = aout_symbol( g)->desc;
1227 nsp.n_other = aout_symbol(g)->other;
1228 nsp.n_type = aout_symbol(g)->type;
1238 nsp.n_value = g->value;
1239 translate_to_native_sym_flags (&nsp, (PTR)g, abfd);
1242 bfd_h_putshort (abfd, nsp.n_desc, (unsigned char *)&nsp.n_desc);
1243 bfd_h_putlong (abfd, nsp.n_value, (unsigned char *)&nsp.n_value);
1244 bfd_write((PTR)&nsp,1, sizeof(nsp), abfd);
1248 /* Now output the strings. Be sure to put string length into correct
1249 * byte ordering before writing it.
1251 bfd_h_putlong (abfd, stindex, (unsigned char *)&stindex);
1253 bfd_write((PTR)&stindex, 1, sizeof(stindex), abfd);
1255 generic = bfd_get_outsymbols(abfd);
1256 for (count = 0; count < bfd_get_symcount(abfd); count++)
1258 asymbol *g = *(generic++);
1260 if (g->name != (char *)NULL)
1262 size_t length = strlen(g->name)+1;
1263 bfd_write((PTR)g->name, 1, length, abfd);
1265 if ((g->flags & BSF_FAKE)==0) {
1266 g->name = itos(count); /* smash the generic symbol */
1273 DEFUN(sunos4_reclaim_symbol_table,(abfd),
1280 sunos4_get_symtab_upper_bound (abfd)
1283 if (!sunos4_slurp_symbol_table (abfd)) return 0;
1285 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1289 sunos4_get_symtab (abfd, location)
1293 unsigned int counter = 0;
1294 aout_symbol_type *symbase;
1296 if (!sunos4_slurp_symbol_table (abfd)) return 0;
1298 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1299 *(location++) = (asymbol *)( symbase++);
1301 return bfd_get_symcount(abfd);
1305 /* Standard reloc stuff */
1306 /* Output standard relocation information to a file in target byte order. */
1309 swap_std_reloc_out (abfd, p, natptr, count)
1311 arelent **p; /* Generic relocation struct */
1312 struct reloc_std_bytes *natptr;
1317 unsigned int r_length;
1319 int r_baserel, r_jmptable, r_relative;
1320 unsigned int r_addend;
1322 for (idx = 0; idx < count; idx++, p++, natptr++)
1325 bfd_h_putlong (abfd, g->address, natptr->r_address);
1327 r_length = g->howto->size; /* Size as a power of two */
1328 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1329 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1334 r_addend = g->addend; /* Start here, see how it goes */
1336 /* name was clobbered by sunos4_write_syms to be symbol index */
1338 if (g->sym_ptr_ptr != NULL)
1340 if ((*(g->sym_ptr_ptr))->section) {
1341 /* put the section offset into the addend for output */
1342 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1345 r_index = stoi((*(g->sym_ptr_ptr))->name);
1350 if (g->section == NULL) {
1352 r_index = N_ABS | N_EXT;
1354 else if(g->section->output_section == obj_textsec(abfd)) {
1355 r_index = N_TEXT | N_EXT;
1356 r_addend += g->section->output_section->vma;
1358 else if (g->section->output_section == obj_datasec(abfd)) {
1359 r_index = N_DATA | N_EXT;
1360 r_addend += g->section->output_section->vma;
1362 else if (g->section->output_section == obj_bsssec(abfd)) {
1363 r_index = N_BSS | N_EXT ;
1364 r_addend += g->section->output_section->vma;
1371 /* now the fun stuff */
1372 if (abfd->xvec->header_byteorder_big_p != false) {
1373 natptr->r_index[0] = r_index >> 16;
1374 natptr->r_index[1] = r_index >> 8;
1375 natptr->r_index[2] = r_index;
1377 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1378 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1379 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1380 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1381 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1382 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1384 natptr->r_index[2] = r_index >> 16;
1385 natptr->r_index[1] = r_index >> 8;
1386 natptr->r_index[0] = r_index;
1388 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1389 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1390 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1391 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1392 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1393 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1401 /* Extended stuff */
1402 /* Output extended relocation information to a file in target byte order. */
1405 swap_ext_reloc_out (abfd, p, natptr, count)
1407 arelent **p; /* Generic relocation struct */
1408 register struct reloc_ext_bytes *natptr;
1414 unsigned int r_type;
1415 unsigned int r_addend;
1417 for (idx = 0; idx < count; idx++, p++, natptr++) {
1420 bfd_h_putlong (abfd, g->address, natptr->r_address);
1422 /* Find a type in the output format which matches the input howto -
1423 at the moment we assume input format == output format FIXME!! */
1424 r_type = (enum reloc_type) g->howto->type;
1426 r_addend = g->addend; /* Start here, see how it goes */
1428 /* name was clobbered by sunos4_write_syms to be symbol index*/
1430 if (g->sym_ptr_ptr != NULL)
1432 if ((*(g->sym_ptr_ptr))->section) {
1433 /* put the section offset into the addend for output */
1434 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1437 r_index = stoi((*(g->sym_ptr_ptr))->name);
1442 if (g->section == NULL) {
1444 r_index = N_ABS | N_EXT;
1446 else if(g->section->output_section == obj_textsec(abfd)) {
1447 r_index = N_TEXT | N_EXT;
1448 r_addend += g->section->output_section->vma;
1450 else if (g->section->output_section == obj_datasec(abfd)) {
1451 r_index = N_DATA | N_EXT;
1452 r_addend += g->section->output_section->vma;
1454 else if (g->section->output_section == obj_bsssec(abfd)) {
1455 r_index = N_BSS | N_EXT ;
1456 r_addend += g->section->output_section->vma;
1463 /* now the fun stuff */
1464 if (abfd->xvec->header_byteorder_big_p != false) {
1465 natptr->r_index[0] = r_index >> 16;
1466 natptr->r_index[1] = r_index >> 8;
1467 natptr->r_index[2] = r_index;
1469 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1470 || (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1472 natptr->r_index[2] = r_index >> 16;
1473 natptr->r_index[1] = r_index >> 8;
1474 natptr->r_index[0] = r_index;
1476 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1477 || (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1480 bfd_h_putlong (abfd, r_addend, natptr->r_addend);
1483 #define MOVE_ADDRESS(ad) \
1485 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1486 cache_ptr->section = (asection *)NULL; \
1487 cache_ptr->addend = ad; \
1489 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1490 switch (r_index) { \
1492 case N_TEXT | N_EXT: \
1493 cache_ptr->section = obj_textsec(abfd); \
1494 cache_ptr->addend = ad - su->textsec->vma; \
1497 case N_DATA | N_EXT: \
1498 cache_ptr->section = obj_datasec(abfd); \
1499 cache_ptr->addend = ad - su->datasec->vma; \
1502 case N_BSS | N_EXT: \
1503 cache_ptr->section = obj_bsssec(abfd); \
1504 cache_ptr->addend = ad - su->bsssec->vma; \
1507 case N_ABS | N_EXT: \
1517 swap_ext_reloc_in (abfd, bytes, cache_ptr, symbols)
1519 struct reloc_ext_bytes *bytes;
1525 unsigned int r_type;
1526 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1528 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1530 /* now the fun stuff */
1531 if (abfd->xvec->header_byteorder_big_p != false) {
1532 r_index = (bytes->r_index[0] << 16)
1533 | (bytes->r_index[1] << 8)
1534 | bytes->r_index[2];
1535 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_BIG));
1536 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_BIG)
1537 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1539 r_index = (bytes->r_index[2] << 16)
1540 | (bytes->r_index[1] << 8)
1541 | bytes->r_index[0];
1542 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1543 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1544 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1547 cache_ptr->howto = howto_table_ext + r_type;
1548 MOVE_ADDRESS(bfd_h_getlong(abfd,bytes->r_addend));
1553 swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
1555 struct reloc_std_bytes *bytes;
1561 unsigned int r_length;
1563 int r_baserel, r_jmptable, r_relative;
1564 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1565 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1567 /* now the fun stuff */
1568 if (abfd->xvec->header_byteorder_big_p != false) {
1569 r_index = (bytes->r_index[0] << 16)
1570 | (bytes->r_index[1] << 8)
1571 | bytes->r_index[2];
1572 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_BIG));
1573 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_BIG));
1574 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_BIG));
1575 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1576 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_BIG));
1577 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_BIG)
1578 >> RELOC_STD_BITS_LENGTH_SH_BIG;
1580 r_index = (bytes->r_index[2] << 16)
1581 | (bytes->r_index[1] << 8)
1582 | bytes->r_index[0];
1583 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1584 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_LITTLE));
1585 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1586 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1587 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1588 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1589 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1592 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1593 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1601 sunos4_slurp_reloc_table (abfd, asect, symbols)
1609 arelent *reloc_cache;
1612 if (asect->relocation) return true;
1614 if (asect->flags & SEC_CONSTRUCTOR) return true;
1616 if (asect == obj_datasec (abfd)) {
1617 reloc_size = exec_hdr(abfd)->a_drsize;
1621 if (asect == obj_textsec (abfd)) {
1622 reloc_size = exec_hdr(abfd)->a_trsize;
1626 bfd_error = invalid_operation;
1630 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1631 each_size = reloc_size_func(abfd);
1633 count = reloc_size / each_size;
1636 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1638 relocs = bfd_alloc (abfd, reloc_size);
1640 if (bfd_read ( relocs, 1, reloc_size, abfd) != reloc_size) {
1641 bfd_error = system_call_error;
1645 if (each_size == RELOC_EXT_SIZE)
1647 register struct reloc_ext_bytes *rptr = (struct reloc_ext_bytes *) relocs;
1648 unsigned int counter = 0;
1649 arelent *cache_ptr = reloc_cache;
1651 for (; counter < count; counter++, rptr++, cache_ptr++) {
1652 swap_ext_reloc_in(abfd, rptr, cache_ptr, symbols);
1656 register struct reloc_std_bytes *rptr = (struct reloc_std_bytes *) relocs;
1657 unsigned int counter = 0;
1658 arelent *cache_ptr = reloc_cache;
1660 for (; counter < count; counter++, rptr++, cache_ptr++) {
1661 swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
1665 bfd_release (abfd,relocs);
1666 asect->relocation = reloc_cache;
1667 asect->reloc_count = count;
1673 /* Write out a relocation section into an object file. */
1676 sunos4_squirt_out_relocs (abfd, section)
1681 unsigned char *native;
1684 unsigned int count = section->reloc_count;
1687 if (count == 0) return true;
1689 each_size = reloc_size_func(abfd);
1690 natsize = each_size * count;
1691 native = (unsigned char *) bfd_zalloc (abfd, natsize);
1693 bfd_error = no_memory;
1697 generic = section->orelocation;
1699 if (each_size == RELOC_EXT_SIZE)
1701 swap_ext_reloc_out (abfd,
1703 (struct reloc_ext_bytes *)native,
1708 swap_std_reloc_out(abfd, generic, native, count);
1711 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1712 bfd_release(abfd, native);
1715 bfd_release (abfd, native);
1720 /* This is stupid. This function should be a boolean predicate */
1722 sunos4_canonicalize_reloc (abfd, section, relptr, symbols)
1728 arelent *tblptr = section->relocation;
1731 if (!(tblptr || sunos4_slurp_reloc_table (abfd, section, symbols)))
1734 if (section->flags & SEC_CONSTRUCTOR) {
1735 arelent_chain *chain = section->constructor_chain;
1736 for (count = 0; count < section->reloc_count; count ++) {
1737 *relptr ++ = &chain->relent;
1738 chain = chain->next;
1742 tblptr = section->relocation;
1743 if (!tblptr) return 0;
1745 for (count = 0; count++ < section->reloc_count;)
1747 *relptr++ = tblptr++;
1752 return section->reloc_count;
1756 sunos4_get_reloc_upper_bound (abfd, asect)
1760 if (bfd_get_format (abfd) != bfd_object) {
1761 bfd_error = invalid_operation;
1764 if (asect->flags & SEC_CONSTRUCTOR) {
1765 return (sizeof (arelent *) * (asect->reloc_count+1));
1769 if (asect == obj_datasec (abfd))
1770 return (sizeof (arelent *) *
1771 ((exec_hdr(abfd)->a_drsize / reloc_size_func(abfd))
1774 if (asect == obj_textsec (abfd))
1775 return (sizeof (arelent *) *
1776 ((exec_hdr(abfd)->a_trsize / reloc_size_func(abfd))
1779 bfd_error = invalid_operation;
1784 sunos4_reclaim_reloc (ignore_abfd, section)
1793 sunos4_get_lineno(ignore_abfd, ignore_symbol)
1797 return (alent *)NULL;
1801 sunos4_print_symbol(ignore_abfd, file, symbol, how)
1805 bfd_print_symbol_enum_type how;
1808 case bfd_print_symbol_name_enum:
1809 fprintf(file,"%s", symbol->name);
1811 case bfd_print_symbol_type_enum:
1812 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1813 (unsigned)( aout_symbol(symbol)->other & 0xff),
1814 (unsigned)(aout_symbol(symbol)->type));
1816 case bfd_print_symbol_all_enum:
1818 CONST char *section_name = symbol->section == (asection *)NULL ?
1819 "*abs" : symbol->section->name;
1821 bfd_print_symbol_vandf((PTR)file,symbol);
1823 fprintf(file," %-5s %04x %02x %02x %s",
1825 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1826 (unsigned)(aout_symbol(symbol)->other & 0xff),
1827 (unsigned)(aout_symbol(symbol)->type & 0xff),
1833 /* Once we know all the stuff that could be consed, we know how to clean
1834 it up. So why don't we? */
1837 sunos4_close_and_cleanup (abfd)
1840 if (!bfd_read_p (abfd))
1841 switch (abfd->format) {
1843 if (!_bfd_write_archive_contents (abfd)) return false; break;
1845 if (!sunos4_write_object_contents (abfd)) return false; break;
1846 default: bfd_error = invalid_operation; return false;
1853 provided a bfd, a section and an offset into the section, calculate
1854 and return the name of the source file and the line nearest to the
1859 DEFUN(sunos4_find_nearest_line,(abfd,
1867 asection *section AND
1868 asymbol **symbols AND
1870 CONST char **filename_ptr AND
1871 CONST char **functionname_ptr AND
1872 unsigned int *line_ptr)
1874 /* Run down the file looking for the filename, function and linenumber */
1876 static char buffer[100];
1877 bfd_vma high_line_vma = ~0;
1878 bfd_vma low_func_vma = 0;
1880 *filename_ptr = abfd->filename;
1881 *functionname_ptr = 0;
1883 if (symbols != (asymbol **)NULL) {
1884 for (p = symbols; *p; p++) {
1885 aout_symbol_type *q = (aout_symbol_type *)(*p);
1888 *filename_ptr = q->symbol.name;
1889 if (obj_textsec(abfd) != section) {
1897 /* We'll keep this if it resolves nearer than the one we have already */
1898 if (q->symbol.value >= offset &&
1899 q->symbol.value < high_line_vma) {
1900 *line_ptr = q->desc;
1901 high_line_vma = q->symbol.value;
1906 /* We'll keep this if it is nearer than the one we have already */
1907 if (q->symbol.value >= low_func_vma &&
1908 q->symbol.value <= offset) {
1909 low_func_vma = q->symbol.value;
1910 func = (asymbol *)q;
1912 if (*line_ptr && func) {
1913 CONST char *function = func->name;
1915 strncpy(buffer, function, sizeof(buffer)-1);
1916 buffer[sizeof(buffer)-1] = 0;
1917 /* Have to remove : stuff */
1918 p = strchr(buffer,':');
1919 if (p != NULL) {*p = NULL; }
1920 *functionname_ptr = buffer;
1935 DEFUN(sunos4_sizeof_headers,(abfd),
1941 #define sunos4_openr_next_archived_file bfd_generic_openr_next_archived_file
1942 #define sunos4_generic_stat_arch_elt bfd_generic_stat_arch_elt
1943 #define sunos4_slurp_armap bfd_slurp_bsd_armap
1944 #define sunos4_slurp_extended_name_table bfd_true
1945 #define sunos4_write_armap bsd_write_armap
1946 #define sunos4_truncate_arname bfd_bsd_truncate_arname
1947 bfd_target aout_big_vec =
1949 "a.out-generic-big", /* name */
1950 bfd_target_aout_flavour_enum,
1951 true, /* target byte order */
1952 true, /* target headers byte order */
1953 (HAS_RELOC | EXEC_P | /* object flags */
1954 HAS_LINENO | HAS_DEBUG |
1955 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1956 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1957 ' ', /* ar_pad_char */
1958 16, /* ar_max_namelen */
1959 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1960 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1962 {_bfd_dummy_target, sunos4_object_p,
1963 bfd_generic_archive_p, sunos4_core_file_p},
1964 {bfd_false, sunos4_mkobject,
1965 _bfd_generic_mkarchive, bfd_false},
1971 bfd_target aout_little_vec =
1973 "a.out-generic-little", /* name */
1974 bfd_target_aout_flavour_enum,
1975 false, /* target byte order */
1976 false, /* target headers byte order */
1977 (HAS_RELOC | EXEC_P | /* object flags */
1978 HAS_LINENO | HAS_DEBUG |
1979 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1980 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1981 ' ', /* ar_pad_char */
1982 16, /* ar_max_namelen */
1983 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* data */
1984 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* hdrs */
1987 {_bfd_dummy_target, sunos4_object_p,
1988 bfd_generic_archive_p, sunos4_core_file_p},
1989 {bfd_false, sunos4_mkobject,
1990 _bfd_generic_mkarchive, bfd_false},