1 /*** bfd backend for sunos binaries */
4 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
6 This file is part of BFD, the Binary File Diddler.
8 BFD is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
13 BFD is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with BFD; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
29 #include "a.out.sun4.h"
30 #include "a.out.gnu.h"
33 #include "liba.out.h" /* BFD a.out internal data structures */
35 void (*bfd_error_trap
)();
40 #define CTOR_TABLE_RELOC_IDX 2
41 static reloc_howto_type howto_table_ext
[] =
43 HOWTO(RELOC_8
, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false),
44 HOWTO(RELOC_16
, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false),
45 HOWTO(RELOC_32
, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff, false),
46 HOWTO(RELOC_DISP8
, 0, 0, 8, true, 0, false, true,0,"DISP8", false, 0,0x000000ff, false),
47 HOWTO(RELOC_DISP16
, 0, 1, 16, true, 0, false, true,0,"DISP16", false, 0,0x0000ffff, false),
48 HOWTO(RELOC_DISP32
, 0, 2, 32, true, 0, false, true,0,"DISP32", false, 0,0xffffffff, false),
49 HOWTO(RELOC_WDISP30
,2, 2, 30, true, 0, false, true,0,"WDISP30", false, 0,0x3fffffff, false),
50 HOWTO(RELOC_WDISP22
,2, 2, 22, true, 0, false, true,0,"WDISP22", false, 0,0x003fffff, false),
51 HOWTO(RELOC_HI22
, 10, 2, 22, false, 0, false, true,0,"HI22", false, 0,0x003fffff, false),
52 HOWTO(RELOC_22
, 0, 2, 22, false, 0, false, true,0,"22", false, 0,0x003fffff, false),
53 HOWTO(RELOC_13
, 0, 2, 13, false, 0, false, true,0,"13", false, 0,0x00001fff, false),
54 HOWTO(RELOC_LO10
, 0, 2, 10, false, 0, false, true,0,"LO10", false, 0,0x000003ff, false),
55 HOWTO(RELOC_SFA_BASE
,0, 2, 32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
56 HOWTO(RELOC_SFA_OFF13
,0,2, 32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
57 HOWTO(RELOC_BASE10
, 0, 2, 16, false, 0, false, true,0,"BASE10", false, 0,0x0000ffff, false),
58 HOWTO(RELOC_BASE13
, 0, 2, 13, false, 0, false, true,0,"BASE13", false, 0,0x00001fff, false),
59 HOWTO(RELOC_BASE22
, 0, 2, 0, false, 0, false, true,0,"BASE22", false, 0,0x00000000, false),
60 HOWTO(RELOC_PC10
, 0, 2, 10, false, 0, false, true,0,"PC10", false, 0,0x000003ff, false),
61 HOWTO(RELOC_PC22
, 0, 2, 22, false, 0, false, true,0,"PC22", false, 0,0x003fffff, false),
62 HOWTO(RELOC_JMP_TBL
,0, 2, 32, false, 0, false, true,0,"JMP_TBL", false, 0,0xffffffff, false),
63 HOWTO(RELOC_SEGOFF16
,0, 2, 0, false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
64 HOWTO(RELOC_GLOB_DAT
,0, 2, 0, false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
65 HOWTO(RELOC_JMP_SLOT
,0, 2, 0, false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
66 HOWTO(RELOC_RELATIVE
,0, 2, 0, false, 0, false, true,0,"RELATIVE", false, 0,0x00000000, false),
67 HOWTO(RELOC_JUMPTARG
,2, 13, 16, true, 0, false, true,0,"JUMPTARG", false, 0,0x0000ffff, false),
68 HOWTO(RELOC_CONST
, 0, 13, 16, false, 0, false, true,0,"CONST", false, 0,0x0000ffff, false),
69 HOWTO(RELOC_CONSTH
, 16, 13, 16, false, 0, false, true,0,"CONSTH", false, 0,0x0000ffff, false),
72 /* Convert standard reloc records to "arelent" format (incl byte swap). */
74 static reloc_howto_type howto_table_std
[] = {
75 /* type rs size bsz pcrel bitpos abs ovrf sf name part_inpl readmask setmask pcdone */
76 HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),
77 HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),
78 HOWTO( 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff, false),
79 HOWTO( 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead, false),
80 HOWTO( 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff, false),
81 HOWTO( 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
82 HOWTO( 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff, false),
83 HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface, false),
87 bfd_error_vector_type bfd_error_vector
;
89 PROTO (void , sunos4_write_syms
, ());
90 PROTO (static boolean
,sunos4_squirt_out_relocs
,(bfd
*abfd
, asection
*section
));
97 switch (bfd_get_architecture (abfd
)) {
100 return RELOC_EXT_SIZE
;
102 return RELOC_STD_SIZE
;
107 DEFUN(bfd_aout_swap_exec_header_in
,(abfd
, raw_bytes
, execp
),
109 unsigned char *raw_bytes AND
112 struct exec_bytes
*bytes
= (struct exec_bytes
*)raw_bytes
;
114 /* Now fill in fields in the execp, from the bytes in the raw data. */
115 execp
->a_info
= bfd_h_getlong (abfd
, bytes
->a_info
);
116 execp
->a_text
= bfd_h_getlong (abfd
, bytes
->a_text
);
117 execp
->a_data
= bfd_h_getlong (abfd
, bytes
->a_data
);
118 execp
->a_bss
= bfd_h_getlong (abfd
, bytes
->a_bss
);
119 execp
->a_syms
= bfd_h_getlong (abfd
, bytes
->a_syms
);
120 execp
->a_entry
= bfd_h_getlong (abfd
, bytes
->a_entry
);
121 execp
->a_trsize
= bfd_h_getlong (abfd
, bytes
->a_trsize
);
122 execp
->a_drsize
= bfd_h_getlong (abfd
, bytes
->a_drsize
);
126 DEFUN(bfd_aout_swap_exec_header_out
,(abfd
, execp
, raw_bytes
),
128 struct exec
*execp AND
129 unsigned char *raw_bytes
)
131 struct exec_bytes
*bytes
= (struct exec_bytes
*)raw_bytes
;
133 /* Now fill in fields in the raw data, from the fields in the exec struct. */
134 bfd_h_putlong (abfd
, execp
->a_info
, bytes
->a_info
);
135 bfd_h_putlong (abfd
, execp
->a_text
, bytes
->a_text
);
136 bfd_h_putlong (abfd
, execp
->a_data
, bytes
->a_data
);
137 bfd_h_putlong (abfd
, execp
->a_bss
, bytes
->a_bss
);
138 bfd_h_putlong (abfd
, execp
->a_syms
, bytes
->a_syms
);
139 bfd_h_putlong (abfd
, execp
->a_entry
, bytes
->a_entry
);
140 bfd_h_putlong (abfd
, execp
->a_trsize
, bytes
->a_trsize
);
141 bfd_h_putlong (abfd
, execp
->a_drsize
, bytes
->a_drsize
);
145 sunos4_object_p (abfd
)
148 unsigned char magicbuf
[4]; /* Raw bytes of magic number from file */
149 unsigned long magic
; /* Swapped magic number */
150 unsigned char exec_bytes
[EXEC_BYTES_SIZE
]; /* Raw bytes of exec hdr */
154 bfd_error
= system_call_error
;
156 if (bfd_read ((PTR
)magicbuf
, 1, sizeof (magicbuf
), abfd
) !=
159 magic
= bfd_h_getlong (abfd
, magicbuf
);
161 if (N_BADMAG (*((struct exec
*) &magic
))) return 0;
163 if (bfd_seek (abfd
, 0L, false) < 0) return 0;
165 if (bfd_read ((PTR
) exec_bytes
, 1, EXEC_BYTES_SIZE
, abfd
)
166 != EXEC_BYTES_SIZE
) {
167 bfd_error
= wrong_format
;
171 /* Use an intermediate variable for clarity */
172 rawptr
= (PTR
) bfd_zalloc (abfd
, sizeof (struct sunexdata
) + sizeof (struct exec
));
174 if (rawptr
== NULL
) {
175 bfd_error
= no_memory
;
179 set_tdata (abfd
, ((struct sunexdata
*) rawptr
));
180 exec_hdr (abfd
) = execp
=
181 (struct exec
*) ((char *)rawptr
+ sizeof (struct sunexdata
));
183 bfd_aout_swap_exec_header_in (abfd
, exec_bytes
, execp
);
185 /* Set the file flags */
186 abfd
->flags
= NO_FLAGS
;
187 if (execp
->a_drsize
|| execp
->a_trsize
)
188 abfd
->flags
|= HAS_RELOC
;
190 abfd
->flags
|= EXEC_P
;
192 abfd
->flags
|= HAS_LINENO
| HAS_DEBUG
| HAS_SYMS
| HAS_LOCALS
;
195 if (N_MAGIC (*execp
) == ZMAGIC
) abfd
->flags
|= D_PAGED
;
196 if (N_MAGIC (*execp
) == NMAGIC
) abfd
->flags
|= WP_TEXT
;
198 /* Determine the architecture and machine type of the object file. */
199 abfd
->obj_arch
= bfd_arch_unknown
; /* Default values */
200 abfd
->obj_machine
= 0;
201 switch (N_MACHTYPE (*execp
)) {
207 abfd
->obj_arch
= bfd_arch_m68k
;
208 abfd
->obj_machine
= 68010;
212 abfd
->obj_arch
= bfd_arch_m68k
;
213 abfd
->obj_machine
= 68020;
217 abfd
->obj_arch
= bfd_arch_sparc
;
221 abfd
->obj_arch
= bfd_arch_i386
;
225 abfd
->obj_arch
= bfd_arch_a29k
;
229 abfd
->obj_arch
= bfd_arch_obscure
;
233 bfd_get_start_address (abfd
) = execp
->a_entry
;
235 bfd_get_symcount (abfd
) = execp
->a_syms
/ sizeof (struct nlist
);
237 /* Remember the positions of the string table and symbol table. */
238 obj_str_filepos (abfd
) = N_STROFF (*execp
);
239 obj_sym_filepos (abfd
) = N_SYMOFF (*execp
);
241 /* create the sections. This is raunchy, but bfd_close wants to reclaim
243 obj_textsec (abfd
) = (asection
*)NULL
;
244 obj_datasec (abfd
) = (asection
*)NULL
;
245 obj_bsssec (abfd
) = (asection
*)NULL
;
246 obj_aout_symbols(abfd
) = (aout_symbol_type
*)NULL
;
247 (void)bfd_make_section(abfd
, ".text");
248 (void)bfd_make_section(abfd
, ".data");
249 (void)bfd_make_section(abfd
, ".bss");
251 obj_datasec (abfd
)->size
= execp
->a_data
;
252 obj_bsssec (abfd
)->size
= execp
->a_bss
;
253 obj_textsec (abfd
)->size
= execp
->a_text
;
254 obj_datasec (abfd
)->vma
= N_DATADDR(*execp
);
255 obj_bsssec (abfd
)->vma
= N_BSSADDR(*execp
);
256 obj_textsec (abfd
)->vma
= N_TXTADDR(*execp
);
258 obj_textsec (abfd
)->filepos
= N_TXTOFF(*execp
);
259 obj_datasec (abfd
)->filepos
= N_DATOFF(*execp
);
261 obj_textsec (abfd
)->rel_filepos
= N_TRELOFF(*execp
);
262 obj_datasec (abfd
)->rel_filepos
= N_DRELOFF(*execp
);
264 obj_textsec (abfd
)->flags
= (execp
->a_trsize
!= 0 ?
265 (SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_HAS_CONTENTS
) :
266 (SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
));
267 obj_datasec (abfd
)->flags
= (execp
->a_drsize
!= 0 ?
268 (SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_HAS_CONTENTS
) :
269 (SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
));
270 obj_bsssec (abfd
)->flags
= SEC_ALLOC
;
272 abfd
->sections
= obj_textsec (abfd
);
273 obj_textsec (abfd
)->next
= obj_datasec (abfd
);
274 obj_datasec (abfd
)->next
= obj_bsssec (abfd
);
280 sunos4_mkobject (abfd
)
285 bfd_error
= system_call_error
;
287 /* Use an intermediate variable for clarity */
288 rawptr
= bfd_zalloc (abfd
, sizeof (struct sunexdata
) + sizeof (struct exec
));
290 if (rawptr
== NULL
) {
291 bfd_error
= no_memory
;
295 set_tdata (abfd
, (struct sunexdata
*) rawptr
);
296 exec_hdr (abfd
) = (struct exec
*) (rawptr
+ sizeof (struct sunexdata
));
298 /* For simplicity's sake we just make all the sections right here. */
300 obj_textsec (abfd
) = (asection
*)NULL
;
301 obj_datasec (abfd
) = (asection
*)NULL
;
302 obj_bsssec (abfd
) = (asection
*)NULL
;
303 bfd_make_section (abfd
, ".text");
304 bfd_make_section (abfd
, ".data");
305 bfd_make_section (abfd
, ".bss");
310 /* Keep track of machine architecture and machine type for a.out's.
311 Return the machine_type for a particular arch&machine, or M_UNKNOWN
312 if that exact arch&machine can't be represented in a.out format.
314 If the architecture is understood, machine type 0 (default) should
315 always be understood. */
317 static enum machine_type
318 aout_machine_type (arch
, machine
)
319 enum bfd_architecture arch
;
320 unsigned long machine
;
322 enum machine_type arch_flags
;
324 arch_flags
= M_UNKNOWN
;
328 if (machine
== 0) arch_flags
= M_SPARC
;
333 case 0: arch_flags
= M_68010
; break;
334 case 68000: arch_flags
= M_UNKNOWN
; break;
335 case 68010: arch_flags
= M_68010
; break;
336 case 68020: arch_flags
= M_68020
; break;
337 default: arch_flags
= M_UNKNOWN
; break;
342 if (machine
== 0) arch_flags
= M_386
;
346 if (machine
== 0) arch_flags
= M_29K
;
350 arch_flags
= M_UNKNOWN
;
357 sunos4_set_arch_mach (abfd
, arch
, machine
)
359 enum bfd_architecture arch
;
360 unsigned long machine
;
362 abfd
->obj_arch
= arch
;
363 abfd
->obj_machine
= machine
;
364 if (arch
!= bfd_arch_unknown
&&
365 aout_machine_type (arch
, machine
) == M_UNKNOWN
)
366 return false; /* We can't represent this type */
367 return true; /* We're easy ... */
371 sunos4_write_object_contents (abfd
)
375 unsigned char exec_bytes
[EXEC_BYTES_SIZE
];
376 struct exec
*execp
= exec_hdr (abfd
);
378 execp
->a_text
= obj_textsec (abfd
)->size
;
380 /* Magic number, maestro, please! */
381 switch (bfd_get_architecture(abfd
)) {
383 switch (bfd_get_machine(abfd
)) {
385 N_SET_MACHTYPE(*execp
, M_68010
);
389 N_SET_MACHTYPE(*execp
, M_68020
);
394 N_SET_MACHTYPE(*execp
, M_SPARC
);
397 N_SET_MACHTYPE(*execp
, M_386
);
400 N_SET_MACHTYPE(*execp
, M_29K
);
403 N_SET_MACHTYPE(*execp
, M_UNKNOWN
);
406 N_SET_MAGIC (*execp
, OMAGIC
);
407 if (abfd
->flags
& D_PAGED
) {
408 /* This is not strictly true, but will probably do for the default
410 execp
->a_text
= obj_textsec (abfd
)->size
+ sizeof(struct exec
);
411 N_SET_MAGIC (*execp
, ZMAGIC
);
412 } else if (abfd
->flags
& WP_TEXT
) {
413 N_SET_MAGIC (*execp
, NMAGIC
);
415 N_SET_FLAGS (*execp
, 0x1); /* copied from ld.c; who the hell knows? */
417 if (abfd
->flags
& D_PAGED
)
419 data_pad
= ((obj_datasec(abfd
)->size
+ PAGE_SIZE
-1)
420 & (- PAGE_SIZE
)) - obj_datasec(abfd
)->size
;
422 if (data_pad
> obj_bsssec(abfd
)->size
)
425 execp
->a_bss
= obj_bsssec(abfd
)->size
- data_pad
;
426 execp
->a_data
= obj_datasec(abfd
)->size
+ data_pad
;
430 execp
->a_data
= obj_datasec (abfd
)->size
;
431 execp
->a_bss
= obj_bsssec (abfd
)->size
;
434 execp
->a_syms
= bfd_get_symcount (abfd
) * sizeof (struct nlist
);
435 execp
->a_entry
= bfd_get_start_address (abfd
);
437 execp
->a_trsize
= ((obj_textsec (abfd
)->reloc_count
) *
438 reloc_size_func(abfd
));
440 execp
->a_drsize
= ((obj_datasec (abfd
)->reloc_count
) *
441 reloc_size_func(abfd
));
443 bfd_aout_swap_exec_header_out (abfd
, execp
, exec_bytes
);
445 bfd_seek (abfd
, 0L, false);
446 bfd_write ((PTR
) exec_bytes
, 1, EXEC_BYTES_SIZE
, abfd
);
448 /* Now write out reloc info, followed by syms and strings */
450 if (bfd_get_symcount (abfd
) != 0)
453 (long)(N_SYMOFF(*execp
)), false);
455 sunos4_write_syms (abfd
);
457 bfd_seek (abfd
, (long)(N_TRELOFF(*execp
)), false);
459 if (!sunos4_squirt_out_relocs (abfd
, obj_textsec (abfd
))) return false;
460 bfd_seek (abfd
, (long)(N_DRELOFF(*execp
)), false);
462 if (!sunos4_squirt_out_relocs (abfd
, obj_datasec (abfd
))) return false;
469 #define CORE_MAGIC 0x080456
470 #define CORE_NAMELEN 16
472 /* The core structure is taken from the Sun documentation.
473 Unfortunately, they don't document the FPA structure, or at least I
474 can't find it easily. Fortunately the core header contains its own
475 length. So this shouldn't cause problems, except for c_ucode, which
476 so far we don't use but is easy to find with a little arithmetic. */
478 /* But the reg structure can be gotten from the SPARC processor handbook.
479 This really should be in a GNU include file though so that gdb can use
503 /* Taken from Sun documentation: */
505 /* FIXME: It's worse than we expect. This struct contains TWO substructs
506 neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't
507 even portably access the stuff in between! */
510 int c_magic
; /* Corefile magic number */
511 int c_len
; /* Sizeof (struct core) */
512 struct regs c_regs
; /* General purpose registers */
513 struct exec c_aouthdr
; /* A.out header */
514 int c_signo
; /* Killing signal, if any */
515 int c_tsize
; /* Text size (bytes) */
516 int c_dsize
; /* Data size (bytes) */
517 int c_ssize
; /* Stack size (bytes) */
518 char c_cmdname
[CORE_NAMELEN
+ 1]; /* Command name */
519 double fp_stuff
[1]; /* external FPU state (size unknown by us) */
520 /* The type "double" is critical here, for alignment.
521 SunOS declares a struct here, but the struct's alignment
522 is double since it contains doubles. */
523 int c_ucode
; /* Exception no. from u_code */
524 /* (this member is not accessible by name since we don't
525 portably know the size of fp_stuff.) */
528 /* Supposedly the user stack grows downward from the bottom of kernel memory.
529 Presuming that this remains true, this definition will work. */
530 #define USRSTACK (-(128*1024*1024))
532 PROTO (static void, swapcore
, (bfd
*abfd
, struct core
*core
));
534 /* need this cast b/c ptr is really void * */
535 #define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
536 #define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
537 #define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
538 #define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
539 #define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
541 /* These are stored in the bfd's tdata */
543 struct core
*hdr
; /* core file header */
544 asection
*data_section
;
545 asection
*stack_section
;
546 asection
*reg_section
;
547 asection
*reg2_section
;
551 sunos4_core_file_p (abfd
)
554 unsigned char longbuf
[4]; /* Raw bytes of various header fields */
560 bfd_error
= system_call_error
;
562 if (bfd_read ((PTR
)longbuf
, 1, sizeof (longbuf
), abfd
) !=
565 core_mag
= bfd_h_getlong (abfd
, longbuf
);
567 if (core_mag
!= CORE_MAGIC
) return 0;
569 /* SunOS core headers can vary in length; second word is size; */
570 if (bfd_read ((PTR
)longbuf
, 1, sizeof (longbuf
), abfd
) !=
573 core_size
= bfd_h_getlong (abfd
, longbuf
);
575 if (core_size
> 20000)
578 if (bfd_seek (abfd
, 0L, false) < 0) return 0;
580 rawptr
= bfd_zalloc (abfd
, core_size
+ sizeof (struct suncordata
));
581 if (rawptr
== NULL
) {
582 bfd_error
= no_memory
;
586 core
= (struct core
*) (rawptr
+ sizeof (struct suncordata
));
588 if ((bfd_read ((PTR
) core
, 1, core_size
, abfd
)) != core_size
) {
589 bfd_error
= system_call_error
;
590 bfd_release (abfd
, rawptr
);
594 swapcore (abfd
, core
);
595 set_tdata (abfd
, ((struct suncordata
*) rawptr
));
596 core_hdr (abfd
) = core
;
598 /* create the sections. This is raunchy, but bfd_close wants to reclaim
600 core_stacksec (abfd
) = (asection
*) bfd_zalloc (abfd
, sizeof (asection
));
601 if (core_stacksec (abfd
) == NULL
) {
603 bfd_error
= no_memory
;
604 bfd_release (abfd
, rawptr
);
607 core_datasec (abfd
) = (asection
*) bfd_zalloc (abfd
, sizeof (asection
));
608 if (core_datasec (abfd
) == NULL
) {
610 bfd_release (abfd
, core_stacksec (abfd
));
613 core_regsec (abfd
) = (asection
*) bfd_zalloc (abfd
, sizeof (asection
));
614 if (core_regsec (abfd
) == NULL
) {
616 bfd_release (abfd
, core_datasec (abfd
));
619 core_reg2sec (abfd
) = (asection
*) bfd_zalloc (abfd
, sizeof (asection
));
620 if (core_reg2sec (abfd
) == NULL
) {
621 bfd_release (abfd
, core_regsec (abfd
));
625 core_stacksec (abfd
)->name
= ".stack";
626 core_datasec (abfd
)->name
= ".data";
627 core_regsec (abfd
)->name
= ".reg";
628 core_reg2sec (abfd
)->name
= ".reg2";
630 core_stacksec (abfd
)->flags
= SEC_ALLOC
+ SEC_LOAD
;
631 core_datasec (abfd
)->flags
= SEC_ALLOC
+ SEC_LOAD
;
632 core_regsec (abfd
)->flags
= SEC_ALLOC
;
633 core_reg2sec (abfd
)->flags
= SEC_ALLOC
;
635 core_stacksec (abfd
)->size
= core
->c_ssize
;
636 core_datasec (abfd
)->size
= core
->c_dsize
;
637 core_regsec (abfd
)->size
= (sizeof core
->c_regs
);
638 /* Float regs take up end of struct, except c_ucode. */
639 core_reg2sec (abfd
)->size
= core_size
- (sizeof core
->c_ucode
) -
640 (file_ptr
)(((struct core
*)0)->fp_stuff
);
642 core_stacksec (abfd
)->vma
= (USRSTACK
- core
->c_ssize
);
643 core_datasec (abfd
)->vma
= N_DATADDR(core
->c_aouthdr
);
644 core_regsec (abfd
)->vma
= -1;
645 core_reg2sec (abfd
)->vma
= -1;
647 core_stacksec (abfd
)->filepos
= core
->c_len
+ core
->c_dsize
;
648 core_datasec (abfd
)->filepos
= core
->c_len
;
649 /* In file header: */
650 core_regsec (abfd
)->filepos
= (file_ptr
)(&((struct core
*)0)->c_regs
);
651 core_reg2sec (abfd
)->filepos
= (file_ptr
)(((struct core
*)0)->fp_stuff
);
653 /* Align to word at least */
654 core_stacksec (abfd
)->alignment_power
= 2;
655 core_datasec (abfd
)->alignment_power
= 2;
656 core_regsec (abfd
)->alignment_power
= 2;
657 core_reg2sec (abfd
)->alignment_power
= 2;
659 abfd
->sections
= core_stacksec (abfd
);
660 core_stacksec (abfd
)->next
= core_datasec (abfd
);
661 core_datasec (abfd
)->next
= core_regsec (abfd
);
662 core_regsec (abfd
)->next
= core_reg2sec (abfd
);
664 abfd
->section_count
= 4;
670 sunos4_core_file_failing_command (abfd
)
673 return core_hdr (abfd
)->c_cmdname
;
677 sunos4_core_file_failing_signal (abfd
)
680 return core_hdr (abfd
)->c_signo
;
684 sunos4_core_file_matches_executable_p (core_bfd
, exec_bfd
)
685 bfd
*core_bfd
, *exec_bfd
;
687 if (core_bfd
->xvec
!= exec_bfd
->xvec
) {
688 bfd_error
= system_call_error
;
692 return (bcmp ((char *)&core_hdr (core_bfd
), (char*) &exec_hdr (exec_bfd
),
693 sizeof (struct exec
)) == 0) ? true : false;
696 /* byte-swap core structure */
697 /* FIXME, this needs more work to swap IN a core struct from raw bytes */
699 swapcore (abfd
, core
)
703 unsigned char exec_bytes
[EXEC_BYTES_SIZE
];
705 core
->c_magic
= bfd_h_getlong (abfd
, (unsigned char *)&core
->c_magic
);
706 core
->c_len
= bfd_h_getlong (abfd
, (unsigned char *)&core
->c_len
);
707 /* Leave integer registers in target byte order. */
708 bcopy ((char *)&(core
->c_aouthdr
), (char *)exec_bytes
, EXEC_BYTES_SIZE
);
709 bfd_aout_swap_exec_header_in (abfd
, exec_bytes
, &core
->c_aouthdr
);
710 core
->c_signo
= bfd_h_getlong (abfd
, (unsigned char *)&core
->c_signo
);
711 core
->c_tsize
= bfd_h_getlong (abfd
, (unsigned char *)&core
->c_tsize
);
712 core
->c_dsize
= bfd_h_getlong (abfd
, (unsigned char *)&core
->c_dsize
);
713 core
->c_ssize
= bfd_h_getlong (abfd
, (unsigned char *)&core
->c_ssize
);
714 /* Leave FP registers in target byte order. */
715 /* Leave "c_ucode" unswapped for now, since we can't find it easily. */
718 /** exec and core file sections */
721 sunos4_new_section_hook (abfd
, newsect
)
725 /* align to double at least */
726 newsect
->alignment_power
= 3;
728 if (bfd_get_format (abfd
) == bfd_object
) {
729 if (obj_textsec(abfd
) == NULL
&& !strcmp(newsect
->name
, ".text")) {
730 obj_textsec(abfd
)= newsect
;
734 if (obj_datasec(abfd
) == NULL
&& !strcmp(newsect
->name
, ".data")) {
735 obj_datasec(abfd
) = newsect
;
739 if (obj_bsssec(abfd
) == NULL
&& !strcmp(newsect
->name
, ".bss")) {
740 obj_bsssec(abfd
) = newsect
;
745 /* We allow more than three sections internally */
750 sunos4_set_section_contents (abfd
, section
, location
, offset
, count
)
753 unsigned char *location
;
757 if (abfd
->output_has_begun
== false)
758 { /* set by bfd.c handler */
759 if ((obj_textsec (abfd
) == NULL
) || (obj_datasec (abfd
) == NULL
))
761 bfd_error
= invalid_operation
;
765 obj_textsec(abfd
)->filepos
= sizeof(struct exec
);
766 obj_textsec(abfd
)->size
= align_power(obj_textsec(abfd
)->size
,
767 obj_textsec(abfd
)->alignment_power
);
768 obj_datasec(abfd
)->filepos
= obj_textsec (abfd
)->filepos
+ obj_textsec (abfd
)->size
;
769 obj_datasec(abfd
)->size
= align_power(obj_datasec(abfd
)->size
,
770 obj_datasec(abfd
)->alignment_power
);
773 /* regardless, once we know what we're doing, we might as well get going */
774 if (section
!= obj_bsssec(abfd
)) {
775 bfd_seek (abfd
, section
->filepos
+ offset
, SEEK_SET
);
778 return (bfd_write ((PTR
)location
, 1, count
, abfd
) == count
) ?
787 sunos4_get_section_contents (abfd
, section
, location
, offset
, count
)
795 if (offset
>= section
->size
) return false;
797 bfd_seek (abfd
, section
->filepos
+ offset
, SEEK_SET
);
799 return (bfd_read (location
, 1, count
, abfd
) == count
) ? true:false;
805 /* Classify stabs symbols */
808 #define sym_in_text_section(sym) \
809 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
811 #define sym_in_data_section(sym) \
812 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
814 #define sym_in_bss_section(sym) \
815 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
817 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
818 zero in the "value" field. Nonzeroes there are fortrancommon
820 #define sym_is_undefined(sym) \
821 ((sym)->n_type == (N_UNDF | N_EXT) && (sym)->n_value == 0)
823 /* Symbol is a global definition if N_EXT is on and if it has
824 a nonzero type field. */
825 #define sym_is_global_defn(sym) \
826 (((sym)->n_type & N_EXT) && (sym)->n_type & N_TYPE)
828 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
830 #define sym_is_debugger_info(sym) \
831 ((sym)->n_type & ~(N_EXT | N_TYPE))
833 #define sym_is_fortrancommon(sym) \
834 (((sym)->n_type == (N_EXT)) && (sym)->n_value != 0)
836 /* Symbol is absolute if it has N_ABS set */
837 #define sym_is_absolute(sym) \
838 (((sym)->n_type & N_TYPE)== N_ABS)
841 #define sym_is_indirect(sym) \
842 (((sym)->n_type & N_ABS)== N_ABS)
844 /* Only in their own functions for ease of debugging; when sym flags have
845 stabilised these should be inlined into their (single) caller */
848 translate_from_native_sym_flags (sym_pointer
, cache_ptr
, abfd
)
849 struct nlist
*sym_pointer
;
850 aout_symbol_type
*cache_ptr
;
853 switch (cache_ptr
->type
& N_TYPE
) {
859 asection
*section
= bfd_make_section(abfd
,
860 cache_ptr
->symbol
.name
);
861 arelent_chain
*reloc
= (arelent_chain
*)bfd_alloc(abfd
, sizeof(arelent_chain
));
863 switch ( (cache_ptr
->type
& N_TYPE
) ) {
865 reloc
->relent
.section
= (asection
*)NULL
;
866 cache_ptr
->symbol
.section
= (asection
*)NULL
;
869 reloc
->relent
.section
= (asection
*)obj_textsec(abfd
);
870 cache_ptr
->symbol
.value
-= reloc
->relent
.section
->vma
;
873 reloc
->relent
.section
= (asection
*)obj_datasec(abfd
);
874 cache_ptr
->symbol
.value
-= reloc
->relent
.section
->vma
;
877 reloc
->relent
.section
= (asection
*)obj_bsssec(abfd
);
878 cache_ptr
->symbol
.value
-= reloc
->relent
.section
->vma
;
881 cache_ptr
->symbol
.section
= reloc
->relent
.section
;
882 reloc
->relent
.addend
= cache_ptr
->symbol
.value
;
884 /* We modify the symbol to belong to a section depending upon the
885 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
886 really care, and add to the size of the section to contain a
887 pointer to the symbol. Build a reloc entry to relocate to this
888 symbol attached to this section. */
890 section
->flags
= SEC_CONSTRUCTOR
;
891 section
->reloc_count
++;
892 section
->alignment_power
= 2;
893 reloc
->relent
.sym_ptr_ptr
= (asymbol
**)NULL
;
894 reloc
->next
= section
->constructor_chain
;
895 section
->constructor_chain
= reloc
;
896 reloc
->relent
.address
= section
->size
;
897 section
->size
+= sizeof(int *);
899 reloc
->relent
.howto
= howto_table_ext
+CTOR_TABLE_RELOC_IDX
;
900 cache_ptr
->symbol
.flags
|= BSF_DEBUGGING
;
905 if (sym_is_debugger_info (sym_pointer
)) {
906 cache_ptr
->symbol
.flags
= BSF_DEBUGGING
;
907 /* Work out the section correct for this symbol */
908 switch (sym_pointer
->n_type
& N_TYPE
)
912 cache_ptr
->symbol
.section
= obj_textsec (abfd
);
913 cache_ptr
->symbol
.value
-= obj_textsec(abfd
)->vma
;
916 cache_ptr
->symbol
.value
-= obj_datasec(abfd
)->vma
;
917 cache_ptr
->symbol
.section
= obj_datasec (abfd
);
920 cache_ptr
->symbol
.section
= obj_bsssec (abfd
);
921 cache_ptr
->symbol
.value
-= obj_bsssec(abfd
)->vma
;
925 cache_ptr
->symbol
.section
= 0;
930 if (sym_is_fortrancommon (sym_pointer
))
932 cache_ptr
->symbol
.flags
= BSF_FORT_COMM
;
933 cache_ptr
->symbol
.section
= (asection
*)NULL
;
936 if (sym_is_undefined (sym_pointer
)) {
937 cache_ptr
->symbol
.flags
= BSF_UNDEFINED
;
939 else if (sym_is_global_defn (sym_pointer
)) {
940 cache_ptr
->symbol
.flags
= BSF_GLOBAL
| BSF_EXPORT
;
943 else if (sym_is_absolute (sym_pointer
)) {
944 cache_ptr
->symbol
.flags
= BSF_ABSOLUTE
;
947 cache_ptr
->symbol
.flags
= BSF_LOCAL
;
950 /* In a.out, the value of a symbol is always relative to the
951 * start of the file, if this is a data symbol we'll subtract
952 * the size of the text section to get the section relative
953 * value. If this is a bss symbol (which would be strange)
954 * we'll subtract the size of the previous two sections
955 * to find the section relative address.
958 if (sym_in_text_section (sym_pointer
)) {
959 cache_ptr
->symbol
.value
-= obj_textsec(abfd
)->vma
;
960 cache_ptr
->symbol
.section
= obj_textsec (abfd
);
962 else if (sym_in_data_section (sym_pointer
)){
963 cache_ptr
->symbol
.value
-= obj_datasec(abfd
)->vma
;
964 cache_ptr
->symbol
.section
= obj_datasec (abfd
);
966 else if (sym_in_bss_section(sym_pointer
)) {
967 cache_ptr
->symbol
.section
= obj_bsssec (abfd
);
968 cache_ptr
->symbol
.value
-= obj_bsssec(abfd
)->vma
;
971 cache_ptr
->symbol
.section
= (asection
*)NULL
;
972 cache_ptr
->symbol
.flags
|= BSF_ABSOLUTE
;
980 translate_to_native_sym_flags (sym_pointer
, cache_ptr_g
, abfd
)
981 struct nlist
*sym_pointer
;
985 asymbol
*cache_ptr
= (asymbol
*)cache_ptr_g
;
987 /* FIXME check for writing bss */
988 if (bfd_get_section(cache_ptr
)) {
989 if (bfd_get_output_section(cache_ptr
) == obj_bsssec (abfd
)) {
990 sym_pointer
->n_type
|= N_BSS
;
992 else if (bfd_get_output_section(cache_ptr
) == obj_datasec (abfd
)) {
993 sym_pointer
->n_type
|= N_DATA
;
995 else if (bfd_get_output_section(cache_ptr
) == obj_textsec (abfd
)) {
996 sym_pointer
->n_type
|= N_TEXT
;
999 bfd_error_vector
.nonrepresentable_section(abfd
,
1000 bfd_get_output_section(cache_ptr
)->name
);
1002 /* Turn the symbol from section relative to absolute again */
1003 sym_pointer
->n_value
+=
1004 cache_ptr
->section
->output_section
->vma
1005 + cache_ptr
->section
->output_offset
;
1008 sym_pointer
->n_type
|= N_ABS
;
1011 if (cache_ptr
->flags
& (BSF_FORT_COMM
| BSF_UNDEFINED
)) {
1012 sym_pointer
->n_type
= (N_UNDF
| N_EXT
);
1016 if (cache_ptr
->flags
& BSF_ABSOLUTE
) {
1017 sym_pointer
->n_type
|= N_ABS
;
1020 if (cache_ptr
->flags
& (BSF_GLOBAL
| BSF_EXPORT
)) {
1021 sym_pointer
->n_type
|= N_EXT
;
1023 if (cache_ptr
->flags
& BSF_DEBUGGING
) {
1024 sym_pointer
->n_type
= ((aout_symbol_type
*)cache_ptr
)->type
;
1028 /* Native-level interface to symbols. */
1030 /* We read the symbols into a buffer, which is discarded when this
1031 function exits. We read the strings into a buffer large enough to
1032 hold them all plus all the cached symbol entries. */
1035 sunos4_make_empty_symbol (abfd
)
1038 aout_symbol_type
*new =
1039 (aout_symbol_type
*)bfd_zalloc (abfd
, sizeof (aout_symbol_type
));
1040 new->symbol
.the_bfd
= abfd
;
1042 return &new->symbol
;
1046 DEFUN(sunos4_slurp_symbol_table
, (abfd
),
1051 unsigned char string_chars
[LONG_SIZE
];
1054 aout_symbol_type
*cached
;
1056 /* If there's no work to be done, don't do any */
1057 if (obj_aout_symbols (abfd
) != (aout_symbol_type
*)NULL
) return true;
1058 symbol_size
= exec_hdr(abfd
)->a_syms
;
1059 if (symbol_size
== 0) {
1060 bfd_error
= no_symbols
;
1064 bfd_seek (abfd
, obj_str_filepos (abfd
), SEEK_SET
);
1065 if (bfd_read ((PTR
)string_chars
, LONG_SIZE
, 1, abfd
) != LONG_SIZE
)
1067 string_size
= bfd_h_getlong (abfd
, string_chars
);
1069 strings
= bfd_alloc(abfd
, string_size
+ 1);
1070 cached
= (aout_symbol_type
*)
1071 bfd_zalloc(abfd
, bfd_get_symcount (abfd
) * sizeof(aout_symbol_type
));
1072 /* Alloc this last, so we can free it if obstack is in use. */
1073 syms
= (struct nlist
*) bfd_alloc(abfd
, symbol_size
);
1075 bfd_seek (abfd
, obj_sym_filepos (abfd
), SEEK_SET
);
1076 if (bfd_read ((PTR
)syms
, 1, symbol_size
, abfd
) != symbol_size
) {
1078 if (syms
) bfd_release (abfd
, syms
);
1079 if (cached
) bfd_release (abfd
, cached
);
1080 if (strings
)bfd_release (abfd
, strings
);
1084 bfd_seek (abfd
, obj_str_filepos (abfd
), SEEK_SET
);
1085 if (bfd_read ((PTR
)strings
, 1, string_size
, abfd
) != string_size
) {
1089 /* OK, now walk the new symtable, cacheing symbol properties */
1091 register struct nlist
*sym_pointer
;
1092 register struct nlist
*sym_end
= syms
+ bfd_get_symcount (abfd
);
1093 register aout_symbol_type
*cache_ptr
= cached
;
1095 /* run through the table and byte swap if needed */
1096 for (sym_pointer
= syms
; sym_pointer
< sym_end
; sym_pointer
++) {
1097 sym_pointer
->n_un
.n_strx
=
1098 bfd_h_get_x (abfd
, &sym_pointer
->n_un
.n_strx
);
1099 sym_pointer
->n_desc
=
1100 bfd_h_get_x (abfd
, &sym_pointer
->n_desc
);
1101 sym_pointer
->n_value
=
1102 bfd_h_get_x (abfd
, &sym_pointer
->n_value
);
1103 sym_pointer
->n_other
= (char)
1104 bfd_h_get_x(abfd
, &sym_pointer
->n_other
);
1105 sym_pointer
->n_type
= (char)
1106 bfd_h_get_x(abfd
, &sym_pointer
->n_type
);
1109 /* Run through table and copy values */
1110 for (sym_pointer
= syms
, cache_ptr
= cached
;
1111 sym_pointer
< sym_end
; sym_pointer
++, cache_ptr
++)
1113 cache_ptr
->symbol
.the_bfd
= abfd
;
1114 if (sym_pointer
->n_un
.n_strx
)
1115 cache_ptr
->symbol
.name
= sym_pointer
->n_un
.n_strx
+ strings
;
1117 cache_ptr
->symbol
.name
= (char *)NULL
;
1118 cache_ptr
->symbol
.value
= sym_pointer
->n_value
;
1119 cache_ptr
->desc
= sym_pointer
->n_desc
;
1120 cache_ptr
->other
= sym_pointer
->n_other
;
1121 cache_ptr
->type
= sym_pointer
->n_type
;
1122 cache_ptr
->symbol
.udata
= 0;
1123 translate_from_native_sym_flags (sym_pointer
, cache_ptr
, abfd
);
1128 obj_aout_symbols (abfd
) = cached
;
1129 bfd_release (abfd
, (PTR
)syms
);
1136 DEFUN(sunos4_write_syms
,(abfd
),
1139 unsigned int count
;
1140 asymbol
**generic
= bfd_get_outsymbols (abfd
);
1142 unsigned int stindex
= sizeof(stindex
); /* initial string length */
1144 for (count
= 0; count
< bfd_get_symcount (abfd
); count
++) {
1145 asymbol
*g
= generic
[count
];
1149 unsigned int length
= strlen(g
->name
) +1;
1150 bfd_h_putlong (abfd
, stindex
, (unsigned char *)&nsp
.n_un
.n_strx
);
1154 bfd_h_putlong (abfd
, 0, (unsigned char *)&nsp
.n_un
.n_strx
);
1157 if (g
->the_bfd
->xvec
->flavour
== abfd
->xvec
->flavour
)
1159 nsp
.n_desc
= aout_symbol( g
)->desc
;
1160 nsp
.n_other
= aout_symbol(g
)->other
;
1161 nsp
.n_type
= aout_symbol(g
)->type
;
1171 nsp
.n_value
= g
->value
;
1172 translate_to_native_sym_flags (&nsp
, (PTR
)g
, abfd
);
1175 bfd_h_putshort (abfd
, nsp
.n_desc
, (unsigned char *)&nsp
.n_desc
);
1176 bfd_h_putlong (abfd
, nsp
.n_value
, (unsigned char *)&nsp
.n_value
);
1177 bfd_write((PTR
)&nsp
,1, sizeof(nsp
), abfd
);
1181 /* Now output the strings. Be sure to put string length into correct
1182 * byte ordering before writing it.
1184 bfd_h_putlong (abfd
, stindex
, (unsigned char *)&stindex
);
1186 bfd_write((PTR
)&stindex
, 1, sizeof(stindex
), abfd
);
1188 generic
= bfd_get_outsymbols(abfd
);
1189 for (count
= 0; count
< bfd_get_symcount(abfd
); count
++)
1191 asymbol
*g
= *(generic
++);
1195 size_t length
= strlen(g
->name
)+1;
1196 bfd_write((PTR
)g
->name
, 1, length
, abfd
);
1198 if ((g
->flags
& BSF_FAKE
)==0) {
1199 g
->name
= itos(count
); /* smash the generic symbol */
1206 DEFUN(sunos4_reclaim_symbol_table
,(abfd
),
1213 sunos4_get_symtab_upper_bound (abfd
)
1216 if (!sunos4_slurp_symbol_table (abfd
)) return 0;
1218 return (bfd_get_symcount (abfd
)+1) * (sizeof (aout_symbol_type
*));
1222 sunos4_get_symtab (abfd
, location
)
1226 unsigned int counter
= 0;
1227 aout_symbol_type
*symbase
;
1229 if (!sunos4_slurp_symbol_table (abfd
)) return 0;
1231 for (symbase
= obj_aout_symbols(abfd
); counter
++ < bfd_get_symcount (abfd
);)
1232 *(location
++) = (asymbol
*)( symbase
++);
1234 return bfd_get_symcount(abfd
);
1238 /* Standard reloc stuff */
1239 /* Output standard relocation information to a file in target byte order. */
1242 swap_std_reloc_out (abfd
, g
, natptr
)
1244 arelent
*g
; /* Generic relocation struct */
1245 struct reloc_std_bytes
*natptr
;
1249 unsigned int r_length
;
1251 int r_baserel
, r_jmptable
, r_relative
;
1252 unsigned int r_addend
;
1254 bfd_h_putlong (abfd
, g
->address
, natptr
->r_address
);
1256 r_length
= g
->howto
->size
; /* Size as a power of two */
1257 r_pcrel
= (int) g
->howto
->pc_relative
; /* Relative to PC? */
1258 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1263 r_addend
= g
->addend
; /* Start here, see how it goes */
1265 /* name was clobbered by sunos4_write_syms to be symbol index */
1267 if (g
->sym_ptr_ptr
!= NULL
)
1269 if ((*(g
->sym_ptr_ptr
))->section
) {
1270 /* put the section offset into the addend for output */
1271 r_addend
+= (*(g
->sym_ptr_ptr
))->section
->vma
;
1274 r_index
= stoi((*(g
->sym_ptr_ptr
))->name
);
1279 if (g
->section
== NULL
) {
1280 /* It is possible to have a reloc with nothing, we generate an
1283 r_index
= N_ABS
| N_EXT
;
1285 else if(g
->section
->output_section
== obj_textsec(abfd
)) {
1286 r_index
= N_TEXT
| N_EXT
;
1287 r_addend
+= g
->section
->output_section
->vma
;
1289 else if (g
->section
->output_section
== obj_datasec(abfd
)) {
1290 r_index
= N_DATA
| N_EXT
;
1291 r_addend
+= g
->section
->output_section
->vma
;
1293 else if (g
->section
->output_section
== obj_bsssec(abfd
)) {
1294 r_index
= N_BSS
| N_EXT
;
1295 r_addend
+= g
->section
->output_section
->vma
;
1302 /* now the fun stuff */
1303 if (abfd
->xvec
->header_byteorder_big_p
!= false) {
1304 natptr
->r_index
[0] = r_index
>> 16;
1305 natptr
->r_index
[1] = r_index
>> 8;
1306 natptr
->r_index
[2] = r_index
;
1308 (r_extern
? RELOC_STD_BITS_EXTERN_BIG
: 0)
1309 | (r_pcrel
? RELOC_STD_BITS_PCREL_BIG
: 0)
1310 | (r_baserel
? RELOC_STD_BITS_BASEREL_BIG
: 0)
1311 | (r_jmptable
? RELOC_STD_BITS_JMPTABLE_BIG
: 0)
1312 | (r_relative
? RELOC_STD_BITS_RELATIVE_BIG
: 0)
1313 | (r_length
<< RELOC_STD_BITS_LENGTH_SH_BIG
);
1315 natptr
->r_index
[2] = r_index
>> 16;
1316 natptr
->r_index
[1] = r_index
>> 8;
1317 natptr
->r_index
[0] = r_index
;
1319 (r_extern
? RELOC_STD_BITS_EXTERN_LITTLE
: 0)
1320 | (r_pcrel
? RELOC_STD_BITS_PCREL_LITTLE
: 0)
1321 | (r_baserel
? RELOC_STD_BITS_BASEREL_LITTLE
: 0)
1322 | (r_jmptable
? RELOC_STD_BITS_JMPTABLE_LITTLE
: 0)
1323 | (r_relative
? RELOC_STD_BITS_RELATIVE_LITTLE
: 0)
1324 | (r_length
<< RELOC_STD_BITS_LENGTH_SH_LITTLE
);
1329 /* Extended stuff */
1330 /* Output extended relocation information to a file in target byte order. */
1333 swap_ext_reloc_out (abfd
, g
, natptr
)
1335 arelent
*g
; /* Generic relocation struct */
1336 register struct reloc_ext_bytes
*natptr
;
1340 unsigned int r_type
;
1341 unsigned int r_addend
;
1343 bfd_h_putlong (abfd
, g
->address
, natptr
->r_address
);
1345 /* Find a type in the output format which matches the input howto -
1346 at the moment we assume input format == output format FIXME!! */
1347 r_type
= (enum reloc_type
) g
->howto
->type
;
1349 r_addend
= g
->addend
; /* Start here, see how it goes */
1351 /* name was clobbered by sunos4_write_syms to be symbol index*/
1353 if (g
->sym_ptr_ptr
!= NULL
)
1355 if ((*(g
->sym_ptr_ptr
))->section
) {
1356 /* put the section offset into the addend for output */
1357 r_addend
+= (*(g
->sym_ptr_ptr
))->section
->vma
;
1360 r_index
= stoi((*(g
->sym_ptr_ptr
))->name
);
1365 if (g
->section
== NULL
) {
1367 r_index
= N_ABS
| N_EXT
;
1369 else if(g
->section
->output_section
== obj_textsec(abfd
)) {
1370 r_index
= N_TEXT
| N_EXT
;
1371 r_addend
+= g
->section
->output_section
->vma
;
1373 else if (g
->section
->output_section
== obj_datasec(abfd
)) {
1374 r_index
= N_DATA
| N_EXT
;
1375 r_addend
+= g
->section
->output_section
->vma
;
1377 else if (g
->section
->output_section
== obj_bsssec(abfd
)) {
1378 r_index
= N_BSS
| N_EXT
;
1379 r_addend
+= g
->section
->output_section
->vma
;
1386 /* now the fun stuff */
1387 if (abfd
->xvec
->header_byteorder_big_p
!= false) {
1388 natptr
->r_index
[0] = r_index
>> 16;
1389 natptr
->r_index
[1] = r_index
>> 8;
1390 natptr
->r_index
[2] = r_index
;
1392 (r_extern
? RELOC_EXT_BITS_EXTERN_BIG
: 0)
1393 || (r_type
<< RELOC_EXT_BITS_TYPE_SH_BIG
);
1395 natptr
->r_index
[2] = r_index
>> 16;
1396 natptr
->r_index
[1] = r_index
>> 8;
1397 natptr
->r_index
[0] = r_index
;
1399 (r_extern
? RELOC_EXT_BITS_EXTERN_LITTLE
: 0)
1400 || (r_type
<< RELOC_EXT_BITS_TYPE_SH_LITTLE
);
1403 bfd_h_putlong (abfd
, r_addend
, natptr
->r_addend
);
1406 #define MOVE_ADDRESS(ad) \
1408 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1409 cache_ptr->section = (asection *)NULL; \
1410 cache_ptr->addend = ad; \
1412 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1413 switch (r_index) { \
1415 case N_TEXT | N_EXT: \
1416 cache_ptr->section = obj_textsec(abfd); \
1417 cache_ptr->addend = ad - su->textsec->vma; \
1420 case N_DATA | N_EXT: \
1421 cache_ptr->section = obj_datasec(abfd); \
1422 cache_ptr->addend = ad - su->datasec->vma; \
1425 case N_BSS | N_EXT: \
1426 cache_ptr->section = obj_bsssec(abfd); \
1427 cache_ptr->addend = ad - su->bsssec->vma; \
1430 case N_ABS | N_EXT: \
1431 cache_ptr->section = NULL; /* No section */ \
1432 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1436 cache_ptr->section = NULL; /* No section */ \
1437 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1444 swap_ext_reloc_in (abfd
, bytes
, cache_ptr
, symbols
)
1446 struct reloc_ext_bytes
*bytes
;
1452 unsigned int r_type
;
1453 struct sunexdata
*su
= (struct sunexdata
*)(abfd
->tdata
);
1455 cache_ptr
->address
= bfd_h_getlong (abfd
, bytes
->r_address
);
1457 /* now the fun stuff */
1458 if (abfd
->xvec
->header_byteorder_big_p
!= false) {
1459 r_index
= (bytes
->r_index
[0] << 16)
1460 | (bytes
->r_index
[1] << 8)
1461 | bytes
->r_index
[2];
1462 r_extern
= (0 != (bytes
->r_bits
[0] & RELOC_EXT_BITS_EXTERN_BIG
));
1463 r_type
= (bytes
->r_bits
[0] & RELOC_EXT_BITS_TYPE_BIG
)
1464 >> RELOC_EXT_BITS_TYPE_SH_BIG
;
1466 r_index
= (bytes
->r_index
[2] << 16)
1467 | (bytes
->r_index
[1] << 8)
1468 | bytes
->r_index
[0];
1469 r_extern
= (0 != (bytes
->r_bits
[0] & RELOC_EXT_BITS_EXTERN_LITTLE
));
1470 r_type
= (bytes
->r_bits
[0] & RELOC_EXT_BITS_TYPE_LITTLE
)
1471 >> RELOC_EXT_BITS_TYPE_SH_LITTLE
;
1474 cache_ptr
->howto
= howto_table_ext
+ r_type
;
1475 MOVE_ADDRESS(bfd_h_getlong(abfd
,bytes
->r_addend
));
1479 swap_std_reloc_in (abfd
, bytes
, cache_ptr
, symbols
)
1481 struct reloc_std_bytes
*bytes
;
1487 unsigned int r_length
;
1489 int r_baserel
, r_jmptable
, r_relative
;
1490 struct sunexdata
*su
= (struct sunexdata
*)(abfd
->tdata
);
1492 cache_ptr
->address
= bfd_h_getlong (abfd
, bytes
->r_address
);
1494 /* now the fun stuff */
1495 if (abfd
->xvec
->header_byteorder_big_p
!= false) {
1496 r_index
= (bytes
->r_index
[0] << 16)
1497 | (bytes
->r_index
[1] << 8)
1498 | bytes
->r_index
[2];
1499 r_extern
= (0 != (bytes
->r_bits
[0] & RELOC_STD_BITS_EXTERN_BIG
));
1500 r_pcrel
= (0 != (bytes
->r_bits
[0] & RELOC_STD_BITS_PCREL_BIG
));
1501 r_baserel
= (0 != (bytes
->r_bits
[0] & RELOC_STD_BITS_BASEREL_BIG
));
1502 r_jmptable
= (0 != (bytes
->r_bits
[0] & RELOC_STD_BITS_JMPTABLE_BIG
));
1503 r_relative
= (0 != (bytes
->r_bits
[0] & RELOC_STD_BITS_RELATIVE_BIG
));
1504 r_length
= (bytes
->r_bits
[0] & RELOC_STD_BITS_LENGTH_BIG
)
1505 >> RELOC_STD_BITS_LENGTH_SH_BIG
;
1507 r_index
= (bytes
->r_index
[2] << 16)
1508 | (bytes
->r_index
[1] << 8)
1509 | bytes
->r_index
[0];
1510 r_extern
= (0 != (bytes
->r_bits
[0] & RELOC_STD_BITS_EXTERN_LITTLE
));
1511 r_pcrel
= (0 != (bytes
->r_bits
[0] & RELOC_STD_BITS_PCREL_LITTLE
));
1512 r_baserel
= (0 != (bytes
->r_bits
[0] & RELOC_STD_BITS_BASEREL_LITTLE
));
1513 r_jmptable
= (0 != (bytes
->r_bits
[0] & RELOC_STD_BITS_JMPTABLE_LITTLE
));
1514 r_relative
= (0 != (bytes
->r_bits
[0] & RELOC_STD_BITS_RELATIVE_LITTLE
));
1515 r_length
= (bytes
->r_bits
[0] & RELOC_STD_BITS_LENGTH_LITTLE
)
1516 >> RELOC_STD_BITS_LENGTH_SH_LITTLE
;
1519 cache_ptr
->howto
= howto_table_std
+ r_length
+ 4 * r_pcrel
;
1520 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1528 sunos4_slurp_reloc_table (abfd
, asect
, symbols
)
1536 arelent
*reloc_cache
;
1539 if (asect
->relocation
) return true;
1541 if (asect
->flags
& SEC_CONSTRUCTOR
) return true;
1543 if (asect
== obj_datasec (abfd
)) {
1544 reloc_size
= exec_hdr(abfd
)->a_drsize
;
1548 if (asect
== obj_textsec (abfd
)) {
1549 reloc_size
= exec_hdr(abfd
)->a_trsize
;
1553 bfd_error
= invalid_operation
;
1557 bfd_seek (abfd
, asect
->rel_filepos
, SEEK_SET
);
1558 each_size
= reloc_size_func(abfd
);
1560 count
= reloc_size
/ each_size
;
1563 reloc_cache
= (arelent
*) bfd_zalloc (abfd
, (size_t)(count
* sizeof
1567 bfd_error
= no_memory
;
1571 relocs
= bfd_alloc (abfd
, reloc_size
);
1573 bfd_release (abfd
, reloc_cache
);
1577 if (bfd_read (relocs
, 1, reloc_size
, abfd
) != reloc_size
) {
1578 bfd_release (abfd
, relocs
);
1579 bfd_release (abfd
, reloc_cache
);
1580 bfd_error
= system_call_error
;
1584 if (each_size
== RELOC_EXT_SIZE
) {
1585 register struct reloc_ext_bytes
*rptr
= (struct reloc_ext_bytes
*) relocs
;
1586 unsigned int counter
= 0;
1587 arelent
*cache_ptr
= reloc_cache
;
1589 for (; counter
< count
; counter
++, rptr
++, cache_ptr
++) {
1590 swap_ext_reloc_in(abfd
, rptr
, cache_ptr
, symbols
);
1593 register struct reloc_std_bytes
*rptr
= (struct reloc_std_bytes
*) relocs
;
1594 unsigned int counter
= 0;
1595 arelent
*cache_ptr
= reloc_cache
;
1597 for (; counter
< count
; counter
++, rptr
++, cache_ptr
++) {
1598 swap_std_reloc_in(abfd
, rptr
, cache_ptr
, symbols
);
1603 bfd_release (abfd
,relocs
);
1604 asect
->relocation
= reloc_cache
;
1605 asect
->reloc_count
= count
;
1611 /* Write out a relocation section into an object file. */
1614 sunos4_squirt_out_relocs (abfd
, section
)
1619 unsigned char *native
, *natptr
;
1622 unsigned int count
= section
->reloc_count
;
1625 if (count
== 0) return true;
1627 each_size
= reloc_size_func(abfd
);
1628 natsize
= each_size
* count
;
1629 native
= (unsigned char *) bfd_zalloc (abfd
, natsize
);
1631 bfd_error
= no_memory
;
1635 generic
= section
->orelocation
;
1637 if (each_size
== RELOC_EXT_SIZE
)
1639 for (natptr
= native
;
1641 --count
, natptr
+= each_size
, ++generic
)
1642 swap_ext_reloc_out (abfd
, *generic
, (struct reloc_ext_bytes
*)natptr
);
1646 for (natptr
= native
;
1648 --count
, natptr
+= each_size
, ++generic
)
1649 swap_std_reloc_out(abfd
, *generic
, (struct reloc_std_bytes
*)natptr
);
1652 if ( bfd_write ((PTR
) native
, 1, natsize
, abfd
) != natsize
) {
1653 bfd_release(abfd
, native
);
1656 bfd_release (abfd
, native
);
1661 /* This is stupid. This function should be a boolean predicate */
1663 sunos4_canonicalize_reloc (abfd
, section
, relptr
, symbols
)
1669 arelent
*tblptr
= section
->relocation
;
1672 if (!(tblptr
|| sunos4_slurp_reloc_table (abfd
, section
, symbols
)))
1675 if (section
->flags
& SEC_CONSTRUCTOR
) {
1676 arelent_chain
*chain
= section
->constructor_chain
;
1677 for (count
= 0; count
< section
->reloc_count
; count
++) {
1678 *relptr
++ = &chain
->relent
;
1679 chain
= chain
->next
;
1683 tblptr
= section
->relocation
;
1684 if (!tblptr
) return 0;
1686 for (count
= 0; count
++ < section
->reloc_count
;)
1688 *relptr
++ = tblptr
++;
1693 return section
->reloc_count
;
1697 sunos4_get_reloc_upper_bound (abfd
, asect
)
1701 if (bfd_get_format (abfd
) != bfd_object
) {
1702 bfd_error
= invalid_operation
;
1705 if (asect
->flags
& SEC_CONSTRUCTOR
) {
1706 return (sizeof (arelent
*) * (asect
->reloc_count
+1));
1710 if (asect
== obj_datasec (abfd
))
1711 return (sizeof (arelent
*) *
1712 ((exec_hdr(abfd
)->a_drsize
/ reloc_size_func(abfd
))
1715 if (asect
== obj_textsec (abfd
))
1716 return (sizeof (arelent
*) *
1717 ((exec_hdr(abfd
)->a_trsize
/ reloc_size_func(abfd
))
1720 bfd_error
= invalid_operation
;
1725 sunos4_reclaim_reloc (ignore_abfd
, ignore
)
1734 sunos4_get_lineno(ignore_abfd
, ignore_symbol
)
1738 return (alent
*)NULL
;
1742 sunos4_print_symbol(ignore_abfd
, file
, symbol
, how
)
1746 bfd_print_symbol_enum_type how
;
1749 case bfd_print_symbol_name_enum
:
1750 fprintf(file
,"%s", symbol
->name
);
1752 case bfd_print_symbol_type_enum
:
1753 fprintf(file
,"%4x %2x %2x",(unsigned)(aout_symbol(symbol
)->desc
& 0xffff),
1754 (unsigned)(aout_symbol(symbol
)->other
& 0xff),
1755 (unsigned)(aout_symbol(symbol
)->type
));
1757 case bfd_print_symbol_all_enum
:
1759 CONST
char *section_name
= symbol
->section
== (asection
*)NULL
?
1760 "*abs" : symbol
->section
->name
;
1762 bfd_print_symbol_vandf((PTR
)file
,symbol
);
1764 fprintf(file
," %-5s %04x %02x %02x %s",
1766 (unsigned)(aout_symbol(symbol
)->desc
& 0xffff),
1767 (unsigned)(aout_symbol(symbol
)->other
& 0xff),
1768 (unsigned)(aout_symbol(symbol
)->type
& 0xff),
1774 /* Once we know all the stuff that could be consed, we know how to clean
1775 it up. So why don't we? */
1778 sunos4_close_and_cleanup (abfd
)
1781 if (!bfd_read_p (abfd
))
1782 switch (abfd
->format
) {
1784 if (!_bfd_write_archive_contents (abfd
)) return false; break;
1786 if (!sunos4_write_object_contents (abfd
)) return false; break;
1787 default: bfd_error
= invalid_operation
; return false;
1794 provided a bfd, a section and an offset into the section, calculate
1795 and return the name of the source file and the line nearest to the
1800 DEFUN(sunos4_find_nearest_line
,(abfd
,
1808 asection
*section AND
1809 asymbol
**symbols AND
1811 CONST
char **filename_ptr AND
1812 CONST
char **functionname_ptr AND
1813 unsigned int *line_ptr
)
1815 /* Run down the file looking for the filename, function and linenumber */
1817 static char buffer
[100];
1818 bfd_vma high_line_vma
= ~0;
1819 bfd_vma low_func_vma
= 0;
1821 *filename_ptr
= abfd
->filename
;
1822 *functionname_ptr
= 0;
1824 if (symbols
!= (asymbol
**)NULL
) {
1825 for (p
= symbols
; *p
; p
++) {
1826 aout_symbol_type
*q
= (aout_symbol_type
*)(*p
);
1829 *filename_ptr
= q
->symbol
.name
;
1830 if (obj_textsec(abfd
) != section
) {
1838 /* We'll keep this if it resolves nearer than the one we have already */
1839 if (q
->symbol
.value
>= offset
&&
1840 q
->symbol
.value
< high_line_vma
) {
1841 *line_ptr
= q
->desc
;
1842 high_line_vma
= q
->symbol
.value
;
1847 /* We'll keep this if it is nearer than the one we have already */
1848 if (q
->symbol
.value
>= low_func_vma
&&
1849 q
->symbol
.value
<= offset
) {
1850 low_func_vma
= q
->symbol
.value
;
1851 func
= (asymbol
*)q
;
1853 if (*line_ptr
&& func
) {
1854 CONST
char *function
= func
->name
;
1856 strncpy(buffer
, function
, sizeof(buffer
)-1);
1857 buffer
[sizeof(buffer
)-1] = 0;
1858 /* Have to remove : stuff */
1859 p
= strchr(buffer
,':');
1860 if (p
!= NULL
) {*p
= NULL
; }
1861 *functionname_ptr
= buffer
;
1876 DEFUN(sunos4_sizeof_headers
,(ignore_abfd
),
1879 return 0; /* FIXME, this is the wrong value! */
1882 #define sunos4_openr_next_archived_file bfd_generic_openr_next_archived_file
1883 #define sunos4_generic_stat_arch_elt bfd_generic_stat_arch_elt
1884 #define sunos4_slurp_armap bfd_slurp_bsd_armap
1885 #define sunos4_slurp_extended_name_table bfd_true
1886 #define sunos4_write_armap bsd_write_armap
1887 #define sunos4_truncate_arname bfd_bsd_truncate_arname
1888 bfd_target aout_big_vec
=
1890 "a.out-generic-big", /* name */
1891 bfd_target_aout_flavour_enum
,
1892 true, /* target byte order */
1893 true, /* target headers byte order */
1894 (HAS_RELOC
| EXEC_P
| /* object flags */
1895 HAS_LINENO
| HAS_DEBUG
|
1896 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
1897 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
1898 ' ', /* ar_pad_char */
1899 16, /* ar_max_namelen */
1900 _do_getblong
, _do_putblong
, _do_getbshort
, _do_putbshort
, /* data */
1901 _do_getblong
, _do_putblong
, _do_getbshort
, _do_putbshort
, /* hdrs */
1903 {_bfd_dummy_target
, sunos4_object_p
,
1904 bfd_generic_archive_p
, sunos4_core_file_p
},
1905 {bfd_false
, sunos4_mkobject
,
1906 _bfd_generic_mkarchive
, bfd_false
},
1912 bfd_target aout_little_vec
=
1914 "a.out-generic-little", /* name */
1915 bfd_target_aout_flavour_enum
,
1916 false, /* target byte order */
1917 false, /* target headers byte order */
1918 (HAS_RELOC
| EXEC_P
| /* object flags */
1919 HAS_LINENO
| HAS_DEBUG
|
1920 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
1921 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
1922 ' ', /* ar_pad_char */
1923 16, /* ar_max_namelen */
1924 _do_getllong
, _do_putllong
, _do_getlshort
, _do_putlshort
, /* data */
1925 _do_getllong
, _do_putllong
, _do_getlshort
, _do_putlshort
, /* hdrs */
1928 {_bfd_dummy_target
, sunos4_object_p
,
1929 bfd_generic_archive_p
, sunos4_core_file_p
},
1930 {bfd_false
, sunos4_mkobject
,
1931 _bfd_generic_mkarchive
, bfd_false
},