1 /* bfd back-end for HP PA-RISC SOM objects.
2 Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
4 Contributed by the Center for Software Science at the
5 University of Utah (pa-gdb-bugs@cs.utah.edu).
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
32 #include <sys/types.h>
33 #include <sys/param.h>
36 #include <machine/reg.h>
37 #include <sys/user.h> /* After a.out.h */
41 /* Magic not defined in standard HP-UX header files until 8.0 */
43 #ifndef CPU_PA_RISC1_0
44 #define CPU_PA_RISC1_0 0x20B
45 #endif /* CPU_PA_RISC1_0 */
46 #ifndef CPU_PA_RISC1_1
47 #define CPU_PA_RISC1_1 0x210
48 #endif /* CPU_PA_RISC1_1 */
49 #ifndef _PA_RISC1_0_ID
50 #define _PA_RISC1_0_ID CPU_PA_RISC1_0
51 #endif /* _PA_RISC1_0_ID */
52 #ifndef _PA_RISC1_1_ID
53 #define _PA_RISC1_1_ID CPU_PA_RISC1_1
54 #endif /* _PA_RISC1_1_ID */
55 #ifndef _PA_RISC_MAXID
56 #define _PA_RISC_MAXID 0x2FF
57 #endif /* _PA_RISC_MAXID */
59 #define _PA_RISC_ID(__m_num) \
60 (((__m_num) == _PA_RISC1_0_ID) || \
61 ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID))
62 #endif /* _PA_RISC_ID */
66 struct som_exec_auxhdr e
;
70 hppa_object_setup (abfd
, file_hdrp
, aux_hdrp
)
72 struct header
*file_hdrp
;
73 struct som_exec_auxhdr
*aux_hdrp
;
75 struct container
*rawptr
;
77 struct hppa_data_struct
*rawptr1
;
78 asection
*text
, *data
, *bss
;
80 rawptr
= (struct container
*) bfd_zalloc (abfd
, sizeof (struct container
));
82 bfd_error
= no_memory
;
86 rawptr1
= (struct hppa_data_struct
*) bfd_zalloc (abfd
, sizeof (struct hppa_data_struct
));
87 if (rawptr1
== NULL
) {
88 bfd_error
= no_memory
;
92 abfd
->tdata
.hppa_data
= rawptr1
;
93 obj_file_hdr (abfd
) = &rawptr
->f
;
94 obj_aux_hdr (abfd
) = &rawptr
->e
;
95 *obj_file_hdr (abfd
) = *file_hdrp
;
96 *obj_aux_hdr (abfd
) = *aux_hdrp
;
98 /* Set the file flags */
99 abfd
->flags
= NO_FLAGS
;
100 if (file_hdrp
->entry_offset
)
101 abfd
->flags
|= HAS_RELOC
;
102 if (file_hdrp
->symbol_total
)
103 abfd
->flags
|= HAS_LINENO
| HAS_DEBUG
| HAS_SYMS
| HAS_LOCALS
;
105 bfd_get_start_address (abfd
) = aux_hdrp
->exec_entry
;
107 obj_pa_symbols (abfd
) = (hppa_symbol_type
*)NULL
;
108 bfd_get_symcount (abfd
) = file_hdrp
->symbol_total
;
110 bfd_default_set_arch_mach(abfd
, bfd_arch_hppa
, 0);
112 /* create the sections. This is raunchy, but bfd_close wants to reclaim
115 text
= bfd_make_section(abfd
, ".text");
116 data
= bfd_make_section(abfd
, ".data");
117 bss
= bfd_make_section(abfd
, ".bss");
119 text
->_raw_size
= aux_hdrp
->exec_tsize
;
120 data
->_raw_size
= aux_hdrp
->exec_dsize
;
121 bss
->_raw_size
= aux_hdrp
->exec_bsize
;
123 text
->flags
= (SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
);
124 data
->flags
= (SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
);
125 bss
->flags
= SEC_ALLOC
;
127 /* The virtual memory addresses of the sections */
128 text
->vma
= aux_hdrp
->exec_tmem
;
129 data
->vma
= aux_hdrp
->exec_dmem
;
130 bss
->vma
= aux_hdrp
->exec_bfill
;
132 /* The file offsets of the sections */
133 text
->filepos
= aux_hdrp
->exec_tfile
;
134 data
->filepos
= aux_hdrp
->exec_dfile
;
136 /* The file offsets of the relocation info */
137 text
->rel_filepos
= 0;
138 data
->rel_filepos
= 0;
140 /* The file offsets of the string table and symbol table. */
141 obj_sym_filepos (abfd
) = file_hdrp
->symbol_location
;
142 bfd_get_symcount (abfd
) = file_hdrp
->symbol_total
;
143 obj_str_filepos (abfd
) = file_hdrp
->symbol_strings_location
;
144 obj_stringtab_size (abfd
) = file_hdrp
->symbol_strings_size
;
149 /* Create a new BFD section for NAME. If NAME already exists, then create a
150 new unique name, with NAME as the prefix. This exists because SOM .o files
151 created by the native compiler can have a $CODE$ section for each
156 make_unique_section (abfd
, name
, num
)
165 sect
= bfd_make_section (abfd
, name
);
168 sprintf(altname
, "%s-%d", name
, num
++);
169 sect
= bfd_make_section (abfd
, altname
);
172 newname
= bfd_alloc (abfd
, strlen(sect
->name
) + 1);
173 strcpy (newname
, sect
->name
);
175 sect
->name
= newname
;
179 /* Convert all of the space and subspace info into BFD sections. Each space
180 contains a number of subspaces, which in turn describe the mapping between
181 regions of the exec file, and the address space that the program runs in.
182 BFD sections which correspond to spaces will overlap the sections for the
183 associated subspaces. */
186 setup_sections (abfd
, file_hdr
)
188 struct header
*file_hdr
;
193 /* First, read in space names */
195 space_strings
= alloca (file_hdr
->space_strings_size
);
199 if (bfd_seek (abfd
, file_hdr
->space_strings_location
, SEEK_SET
) < 0)
201 if (bfd_read (space_strings
, 1, file_hdr
->space_strings_size
, abfd
)
202 != file_hdr
->space_strings_size
)
205 /* Loop over all of the space dictionaries, building up sections */
207 for (space_index
= 0; space_index
< file_hdr
->space_total
; space_index
++)
209 struct space_dictionary_record space
;
210 struct subspace_dictionary_record subspace
;
211 int subspace_index
, tmp
;
212 asection
*space_asect
;
214 /* Read the space dictionary element */
215 if (bfd_seek (abfd
, file_hdr
->space_location
216 + space_index
* sizeof space
, SEEK_SET
) < 0)
218 if (bfd_read (&space
, 1, sizeof space
, abfd
) != sizeof space
)
221 /* Setup the space name string */
222 space
.name
.n_name
= space
.name
.n_strx
+ space_strings
;
224 /* Make a section out of it */
225 space_asect
= make_unique_section (abfd
, space
.name
.n_name
, space_index
);
229 /* Now, read in the first subspace for this space */
230 if (bfd_seek (abfd
, file_hdr
->subspace_location
231 + space
.subspace_index
* sizeof subspace
,
234 if (bfd_read (&subspace
, 1, sizeof subspace
, abfd
) != sizeof subspace
)
236 /* Seek back to the start of the subspaces for loop below */
237 if (bfd_seek (abfd
, file_hdr
->subspace_location
238 + space
.subspace_index
* sizeof subspace
,
242 /* Setup the section flags as appropriate (this is somewhat bogus, as
243 there isn't a clear mapping between what's in the space record, and
244 what BFD can describe here). */
245 if (space
.is_loadable
)
246 space_asect
->flags
|= SEC_ALLOC
;
247 if (space
.is_defined
)
248 space_asect
->flags
|= SEC_LOAD
;
250 /* Setup the start address and file loc from the first subspace record */
251 space_asect
->vma
= subspace
.subspace_start
;
252 space_asect
->filepos
= subspace
.file_loc_init_value
;
253 space_asect
->alignment_power
= subspace
.alignment
;
255 /* Loop over the rest of the subspaces, building up more sections */
256 for (subspace_index
= 0; subspace_index
< space
.subspace_quantity
;
259 asection
*subspace_asect
;
261 /* Read in the next subspace */
262 if (bfd_read (&subspace
, 1, sizeof subspace
, abfd
)
266 /* Setup the subspace name string */
267 subspace
.name
.n_name
= subspace
.name
.n_strx
+ space_strings
;
269 /* Make a section out of this subspace */
270 subspace_asect
= make_unique_section (abfd
, subspace
.name
.n_name
,
271 space
.subspace_index
+ subspace_index
);
276 if (subspace
.is_loadable
)
277 subspace_asect
->flags
|= SEC_ALLOC
| SEC_LOAD
;
278 if (subspace
.code_only
)
279 subspace_asect
->flags
|= SEC_CODE
;
281 subspace_asect
->vma
= subspace
.subspace_start
;
282 subspace_asect
->_cooked_size
= subspace
.subspace_length
;
283 subspace_asect
->_raw_size
= subspace
.initialization_length
;
284 subspace_asect
->alignment_power
= subspace
.alignment
;
285 subspace_asect
->filepos
= subspace
.file_loc_init_value
;
288 /* Setup the sizes for the space section based upon the info in the
289 last subspace of the space. */
290 space_asect
->_cooked_size
= (subspace
.subspace_start
- space_asect
->vma
)
291 + subspace
.subspace_length
;
292 space_asect
->_raw_size
= (subspace
.file_loc_init_value
293 - space_asect
->filepos
)
294 + subspace
.initialization_length
;
302 struct header file_hdr
;
303 struct som_exec_auxhdr aux_hdr
;
305 if (bfd_read ((PTR
) &file_hdr
, 1, FILE_HDR_SIZE
, abfd
) != FILE_HDR_SIZE
)
308 if (!_PA_RISC_ID (file_hdr
.system_id
))
310 bfd_error
= wrong_format
;
314 switch (file_hdr
.a_magic
)
316 case RELOC_MAGIC
: /* I'm not really sure about all of these types... */
328 bfd_error
= wrong_format
;
332 if (file_hdr
.version_id
!= VERSION_ID
333 && file_hdr
.version_id
!= NEW_VERSION_ID
)
335 bfd_error
= wrong_format
;
339 if (bfd_read ((PTR
) &aux_hdr
, 1, AUX_HDR_SIZE
, abfd
) != AUX_HDR_SIZE
)
340 bfd_error
= wrong_format
;
342 if (!setup_sections (abfd
, &file_hdr
))
345 return hppa_object_setup(abfd
, &file_hdr
, &aux_hdr
);
349 DEFUN(hppa_mkobject
,(abfd
),
352 fprintf (stderr
, "hppa_mkobject unimplemented\n");
359 DEFUN(hppa_write_object_contents
,(abfd
),
362 fprintf (stderr
, "hppa_write_object_contents unimplemented\n");
369 hppa_get_symtab_upper_bound (abfd
)
372 fprintf (stderr
, "hppa_get_symtab_upper_bound unimplemented\n");
379 hppa_get_reloc_upper_bound (abfd
, asect
)
383 fprintf (stderr
, "hppa_get_reloc_upper_bound unimplemented\n");
390 hppa_canonicalize_reloc (abfd
, section
, relptr
, symbols
)
396 fprintf (stderr
, "hppa_canonicalize_reloc unimplemented\n");
401 extern bfd_target hppa_vec
;
404 hppa_get_symtab (abfd
, location
)
408 fprintf (stderr
, "hppa_get_symtab unimplemented\n");
415 hppa_make_empty_symbol (abfd
)
418 hppa_symbol_type
*new =
419 (hppa_symbol_type
*)bfd_zalloc (abfd
, sizeof (hppa_symbol_type
));
420 new->symbol
.the_bfd
= abfd
;
426 hppa_print_symbol (ignore_abfd
, afile
, symbol
, how
)
430 bfd_print_symbol_type how
;
432 fprintf (stderr
, "hppa_print_symbol unimplemented\n");
438 hppa_new_section_hook (abfd
, newsect
)
442 newsect
->alignment_power
= 3;
444 /* We allow more than three sections internally */
449 hppa_set_section_contents (abfd
, section
, location
, offset
, count
)
456 fprintf (stderr
, "hppa_set_section_contents unimplimented\n");
463 hppa_set_arch_mach (abfd
, arch
, machine
)
465 enum bfd_architecture arch
;
466 unsigned long machine
;
468 fprintf (stderr
, "hppa_set_arch_mach unimplemented\n");
470 /* Allow any architecture to be supported by the hppa backend */
471 return bfd_default_set_arch_mach(abfd
, arch
, machine
);
475 hppa_find_nearest_line (abfd
, section
, symbols
, offset
, filename_ptr
,
476 functionname_ptr
, line_ptr
)
481 CONST
char **filename_ptr
;
482 CONST
char **functionname_ptr
;
483 unsigned int *line_ptr
;
485 fprintf (stderr
, "hppa_find_nearest_line unimplemented\n");
492 hppa_sizeof_headers (abfd
, reloc
)
496 fprintf (stderr
, "hppa_sizeof_headers unimplemented\n");
503 make_bfd_asection (abfd
, name
, flags
, _raw_size
, vma
, alignment_power
)
507 bfd_size_type _raw_size
;
509 unsigned int alignment_power
;
513 asect
= bfd_make_section (abfd
, name
);
517 asect
->flags
= flags
;
518 asect
->_raw_size
= _raw_size
;
520 asect
->filepos
= bfd_tell (abfd
);
521 asect
->alignment_power
= alignment_power
;
527 hppa_core_file_p (abfd
)
530 core_hdr (abfd
) = bfd_zalloc (abfd
, sizeof (struct hppa_core_struct
));
531 if (!core_hdr (abfd
))
537 struct corehead core_header
;
539 val
= bfd_read ((void *)&core_header
, 1, sizeof core_header
, abfd
);
542 switch (core_header
.type
)
546 bfd_seek (abfd
, core_header
.len
, SEEK_CUR
); /* Just skip this */
550 struct proc_exec proc_exec
;
551 bfd_read ((void *)&proc_exec
, 1, core_header
.len
, abfd
);
552 strncpy (core_command (abfd
), proc_exec
.cmd
, MAXCOMLEN
+ 1);
557 struct proc_info proc_info
;
558 core_regsec (abfd
) = make_bfd_asection (abfd
, ".reg",
559 SEC_ALLOC
+SEC_HAS_CONTENTS
,
561 (int)&proc_info
- (int)&proc_info
.hw_regs
,
563 bfd_read (&proc_info
, 1, core_header
.len
, abfd
);
564 core_signal (abfd
) = proc_info
.sig
;
566 if (!core_regsec (abfd
))
570 core_datasec (abfd
) = make_bfd_asection (abfd
, ".data",
571 SEC_ALLOC
+SEC_LOAD
+SEC_HAS_CONTENTS
,
575 if (!core_datasec (abfd
))
577 bfd_seek (abfd
, core_header
.len
, SEEK_CUR
);
580 core_stacksec (abfd
) = make_bfd_asection (abfd
, ".stack",
581 SEC_ALLOC
+SEC_LOAD
+SEC_HAS_CONTENTS
,
585 if (!core_stacksec (abfd
))
587 bfd_seek (abfd
, core_header
.len
, SEEK_CUR
);
590 fprintf (stderr
, "Unknown HPPA/HPUX core file section type %d\n",
592 bfd_seek (abfd
, core_header
.len
, SEEK_CUR
);
597 /* OK, we believe you. You're a core file (sure, sure). */
603 hppa_core_file_failing_command (abfd
)
606 return core_command (abfd
);
611 hppa_core_file_failing_signal (abfd
)
614 return core_signal (abfd
);
619 hppa_core_file_matches_executable_p (core_bfd
, exec_bfd
)
620 bfd
*core_bfd
, *exec_bfd
;
622 return true; /* FIXME, We have no way of telling at this point */
625 #define hppa_bfd_debug_info_start bfd_void
626 #define hppa_bfd_debug_info_end bfd_void
627 #define hppa_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
631 #define hppa_openr_next_archived_file bfd_generic_openr_next_archived_file
632 #define hppa_generic_stat_arch_elt bfd_generic_stat_arch_elt
633 #define hppa_slurp_armap bfd_false
634 #define hppa_slurp_extended_name_table _bfd_slurp_extended_name_table
635 #define hppa_truncate_arname (void (*)())bfd_nullvoidptr
636 #define hppa_write_armap 0
638 #define hppa_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
639 #define hppa_close_and_cleanup bfd_generic_close_and_cleanup
640 #define hppa_get_section_contents bfd_generic_get_section_contents
642 #define hppa_bfd_get_relocated_section_contents \
643 bfd_generic_get_relocated_section_contents
644 #define hppa_bfd_relax_section bfd_generic_relax_section
645 #define hppa_bfd_seclet_link bfd_generic_seclet_link
646 #define hppa_bfd_reloc_type_lookup \
647 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
648 #define hppa_bfd_make_debug_symbol \
649 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
651 bfd_target hppa_vec
=
654 bfd_target_hppa_flavour
,
655 true, /* target byte order */
656 true, /* target headers byte order */
657 (HAS_RELOC
| EXEC_P
| /* object flags */
658 HAS_LINENO
| HAS_DEBUG
|
659 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
660 (SEC_CODE
|SEC_DATA
|SEC_ROM
|SEC_HAS_CONTENTS
661 |SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
663 /* leading_symbol_char: is the first char of a user symbol
664 predictable, and if so what is it */
666 ' ', /* ar_pad_char */
667 16, /* ar_max_namelen */
668 3, /* minimum alignment */
669 _do_getb64
, _do_getb_signed_64
, _do_putb64
,
670 _do_getb32
, _do_getb_signed_32
, _do_putb32
,
671 _do_getb16
, _do_getb_signed_16
, _do_putb16
, /* data */
672 _do_getb64
, _do_getb_signed_64
, _do_putb64
,
673 _do_getb32
, _do_getb_signed_32
, _do_putb32
,
674 _do_getb16
, _do_getb_signed_16
, _do_putb16
, /* hdrs */
676 hppa_object_p
, /* bfd_check_format */
677 bfd_generic_archive_p
,
683 _bfd_generic_mkarchive
,
688 hppa_write_object_contents
,
689 _bfd_write_archive_contents
,
697 #endif /* HOST_HPPAHPUX */