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... */
324 bfd_error
= wrong_format
;
328 if (file_hdr
.version_id
!= VERSION_ID
329 && file_hdr
.version_id
!= NEW_VERSION_ID
)
331 bfd_error
= wrong_format
;
335 if (bfd_read ((PTR
) &aux_hdr
, 1, AUX_HDR_SIZE
, abfd
) != AUX_HDR_SIZE
)
336 bfd_error
= wrong_format
;
338 if (!setup_sections (abfd
, &file_hdr
))
341 return hppa_object_setup(abfd
, &file_hdr
, &aux_hdr
);
345 DEFUN(hppa_mkobject
,(abfd
),
348 fprintf (stderr
, "hppa_mkobject unimplemented\n");
355 DEFUN(hppa_write_object_contents
,(abfd
),
358 fprintf (stderr
, "hppa_write_object_contents unimplemented\n");
365 hppa_get_symtab_upper_bound (abfd
)
368 fprintf (stderr
, "hppa_get_symtab_upper_bound unimplemented\n");
375 hppa_get_reloc_upper_bound (abfd
, asect
)
379 fprintf (stderr
, "hppa_get_reloc_upper_bound unimplemented\n");
386 hppa_canonicalize_reloc (abfd
, section
, relptr
, symbols
)
392 fprintf (stderr
, "hppa_canonicalize_reloc unimplemented\n");
397 extern bfd_target hppa_vec
;
400 hppa_get_symtab (abfd
, location
)
404 fprintf (stderr
, "hppa_get_symtab unimplemented\n");
411 hppa_make_empty_symbol (abfd
)
414 hppa_symbol_type
*new =
415 (hppa_symbol_type
*)bfd_zalloc (abfd
, sizeof (hppa_symbol_type
));
416 new->symbol
.the_bfd
= abfd
;
422 hppa_print_symbol (ignore_abfd
, afile
, symbol
, how
)
426 bfd_print_symbol_type how
;
428 fprintf (stderr
, "hppa_print_symbol unimplemented\n");
434 hppa_new_section_hook (abfd
, newsect
)
438 newsect
->alignment_power
= 3;
440 /* We allow more than three sections internally */
445 hppa_set_section_contents (abfd
, section
, location
, offset
, count
)
452 fprintf (stderr
, "hppa_set_section_contents unimplimented\n");
459 hppa_set_arch_mach (abfd
, arch
, machine
)
461 enum bfd_architecture arch
;
462 unsigned long machine
;
464 fprintf (stderr
, "hppa_set_arch_mach unimplemented\n");
466 /* Allow any architecture to be supported by the hppa backend */
467 return bfd_default_set_arch_mach(abfd
, arch
, machine
);
471 hppa_find_nearest_line (abfd
, section
, symbols
, offset
, filename_ptr
,
472 functionname_ptr
, line_ptr
)
477 CONST
char **filename_ptr
;
478 CONST
char **functionname_ptr
;
479 unsigned int *line_ptr
;
481 fprintf (stderr
, "hppa_find_nearest_line unimplemented\n");
488 hppa_sizeof_headers (abfd
, reloc
)
492 fprintf (stderr
, "hppa_sizeof_headers unimplemented\n");
499 make_bfd_asection (abfd
, name
, flags
, _raw_size
, vma
, alignment_power
)
503 bfd_size_type _raw_size
;
505 unsigned int alignment_power
;
509 asect
= bfd_make_section (abfd
, name
);
513 asect
->flags
= flags
;
514 asect
->_raw_size
= _raw_size
;
516 asect
->filepos
= bfd_tell (abfd
);
517 asect
->alignment_power
= alignment_power
;
523 hppa_core_file_p (abfd
)
526 core_hdr (abfd
) = bfd_zalloc (abfd
, sizeof (struct hppa_core_struct
));
527 if (!core_hdr (abfd
))
533 struct corehead core_header
;
535 val
= bfd_read ((void *)&core_header
, 1, sizeof core_header
, abfd
);
538 switch (core_header
.type
)
542 bfd_seek (abfd
, core_header
.len
, SEEK_CUR
); /* Just skip this */
546 struct proc_exec proc_exec
;
547 bfd_read ((void *)&proc_exec
, 1, core_header
.len
, abfd
);
548 strncpy (core_command (abfd
), proc_exec
.cmd
, MAXCOMLEN
+ 1);
553 struct proc_info proc_info
;
554 core_regsec (abfd
) = make_bfd_asection (abfd
, ".reg",
555 SEC_ALLOC
+SEC_HAS_CONTENTS
,
557 (int)&proc_info
- (int)&proc_info
.hw_regs
,
559 bfd_read (&proc_info
, 1, core_header
.len
, abfd
);
560 core_signal (abfd
) = proc_info
.sig
;
562 if (!core_regsec (abfd
))
566 core_datasec (abfd
) = make_bfd_asection (abfd
, ".data",
567 SEC_ALLOC
+SEC_LOAD
+SEC_HAS_CONTENTS
,
571 if (!core_datasec (abfd
))
573 bfd_seek (abfd
, core_header
.len
, SEEK_CUR
);
576 core_stacksec (abfd
) = make_bfd_asection (abfd
, ".stack",
577 SEC_ALLOC
+SEC_LOAD
+SEC_HAS_CONTENTS
,
581 if (!core_stacksec (abfd
))
583 bfd_seek (abfd
, core_header
.len
, SEEK_CUR
);
586 fprintf (stderr
, "Unknown HPPA/HPUX core file section type %d\n",
588 bfd_seek (abfd
, core_header
.len
, SEEK_CUR
);
593 /* OK, we believe you. You're a core file (sure, sure). */
599 hppa_core_file_failing_command (abfd
)
602 return core_command (abfd
);
607 hppa_core_file_failing_signal (abfd
)
610 return core_signal (abfd
);
615 hppa_core_file_matches_executable_p (core_bfd
, exec_bfd
)
616 bfd
*core_bfd
, *exec_bfd
;
618 return true; /* FIXME, We have no way of telling at this point */
621 #define hppa_bfd_debug_info_start bfd_void
622 #define hppa_bfd_debug_info_end bfd_void
623 #define hppa_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
627 #define hppa_openr_next_archived_file bfd_generic_openr_next_archived_file
628 #define hppa_generic_stat_arch_elt bfd_generic_stat_arch_elt
629 #define hppa_slurp_armap bfd_false
630 #define hppa_slurp_extended_name_table _bfd_slurp_extended_name_table
631 #define hppa_truncate_arname (void (*)())bfd_nullvoidptr
632 #define hppa_write_armap 0
634 #define hppa_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
635 #define hppa_close_and_cleanup bfd_generic_close_and_cleanup
636 #define hppa_get_section_contents bfd_generic_get_section_contents
638 #define hppa_bfd_get_relocated_section_contents \
639 bfd_generic_get_relocated_section_contents
640 #define hppa_bfd_relax_section bfd_generic_relax_section
641 #define hppa_bfd_seclet_link bfd_generic_seclet_link
642 #define hppa_bfd_reloc_type_lookup \
643 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
644 #define hppa_bfd_make_debug_symbol \
645 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
647 bfd_target hppa_vec
=
650 bfd_target_hppa_flavour
,
651 true, /* target byte order */
652 true, /* target headers byte order */
653 (HAS_RELOC
| EXEC_P
| /* object flags */
654 HAS_LINENO
| HAS_DEBUG
|
655 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
656 (SEC_CODE
|SEC_DATA
|SEC_ROM
|SEC_HAS_CONTENTS
657 |SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
659 /* leading_symbol_char: is the first char of a user symbol
660 predictable, and if so what is it */
662 ' ', /* ar_pad_char */
663 16, /* ar_max_namelen */
664 3, /* minimum alignment */
665 _do_getb64
, _do_putb64
, _do_getb32
, _do_putb32
, _do_getb16
, _do_putb16
, /* data */
666 _do_getb64
, _do_putb64
, _do_getb32
, _do_putb32
, _do_getb16
, _do_putb16
, /* hdrs */
668 hppa_object_p
, /* bfd_check_format */
669 bfd_generic_archive_p
,
675 _bfd_generic_mkarchive
,
680 hppa_write_object_contents
,
681 _bfd_write_archive_contents
,
689 #endif /* HOST_HPPAHPUX */