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 */
43 struct som_exec_auxhdr e
;
47 hppa_object_setup (abfd
, file_hdrp
, aux_hdrp
)
49 struct header
*file_hdrp
;
50 struct som_exec_auxhdr
*aux_hdrp
;
52 struct container
*rawptr
;
54 struct hppa_data_struct
*rawptr1
;
55 asection
*text
, *data
, *bss
;
57 rawptr
= (struct container
*) bfd_zalloc (abfd
, sizeof (struct container
));
59 bfd_error
= no_memory
;
63 rawptr1
= (struct hppa_data_struct
*) bfd_zalloc (abfd
, sizeof (struct hppa_data_struct
));
64 if (rawptr1
== NULL
) {
65 bfd_error
= no_memory
;
69 abfd
->tdata
.hppa_data
= rawptr1
;
70 obj_file_hdr (abfd
) = &rawptr
->f
;
71 obj_aux_hdr (abfd
) = &rawptr
->e
;
72 *obj_file_hdr (abfd
) = *file_hdrp
;
73 *obj_aux_hdr (abfd
) = *aux_hdrp
;
75 /* Set the file flags */
76 abfd
->flags
= NO_FLAGS
;
77 if (file_hdrp
->entry_offset
)
78 abfd
->flags
|= HAS_RELOC
;
79 if (file_hdrp
->symbol_total
)
80 abfd
->flags
|= HAS_LINENO
| HAS_DEBUG
| HAS_SYMS
| HAS_LOCALS
;
82 bfd_get_start_address (abfd
) = aux_hdrp
->exec_entry
;
84 obj_pa_symbols (abfd
) = (hppa_symbol_type
*)NULL
;
85 bfd_get_symcount (abfd
) = file_hdrp
->symbol_total
;
87 bfd_default_set_arch_mach(abfd
, bfd_arch_hppa
, 0);
89 /* create the sections. This is raunchy, but bfd_close wants to reclaim
92 text
= bfd_make_section(abfd
, ".text");
93 data
= bfd_make_section(abfd
, ".data");
94 bss
= bfd_make_section(abfd
, ".bss");
96 text
->_raw_size
= aux_hdrp
->exec_tsize
;
97 data
->_raw_size
= aux_hdrp
->exec_dsize
;
98 bss
->_raw_size
= aux_hdrp
->exec_bsize
;
100 text
->flags
= (SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
);
101 data
->flags
= (SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
);
102 bss
->flags
= SEC_ALLOC
;
104 /* The virtual memory addresses of the sections */
105 text
->vma
= aux_hdrp
->exec_tmem
;
106 data
->vma
= aux_hdrp
->exec_dmem
;
107 bss
->vma
= aux_hdrp
->exec_bfill
;
109 /* The file offsets of the sections */
110 text
->filepos
= aux_hdrp
->exec_tfile
;
111 data
->filepos
= aux_hdrp
->exec_dfile
;
113 /* The file offsets of the relocation info */
114 text
->rel_filepos
= 0;
115 data
->rel_filepos
= 0;
117 /* The file offsets of the string table and symbol table. */
118 obj_sym_filepos (abfd
) = file_hdrp
->symbol_location
;
119 bfd_get_symcount (abfd
) = file_hdrp
->symbol_total
;
120 obj_str_filepos (abfd
) = file_hdrp
->symbol_strings_location
;
121 obj_stringtab_size (abfd
) = file_hdrp
->symbol_strings_size
;
126 /* Create a new BFD section for NAME. If NAME already exists, then create a
127 new unique name, with NAME as the prefix. This exists because SOM .o files
128 created by the native compiler can have a $CODE$ section for each
133 make_unique_section (abfd
, name
, num
)
142 sect
= bfd_make_section (abfd
, name
);
145 sprintf(altname
, "%s-%d", name
, num
++);
146 sect
= bfd_make_section (abfd
, altname
);
149 newname
= bfd_alloc (abfd
, strlen(sect
->name
) + 1);
150 strcpy (newname
, sect
->name
);
152 sect
->name
= newname
;
156 /* Convert all of the space and subspace info into BFD sections. Each space
157 contains a number of subspaces, which in turn describe the mapping between
158 regions of the exec file, and the address space that the program runs in.
159 BFD sections which correspond to spaces will overlap the sections for the
160 associated subspaces. */
163 setup_sections (abfd
, file_hdr
)
165 struct header
*file_hdr
;
170 /* First, read in space names */
172 space_strings
= alloca (file_hdr
->space_strings_size
);
176 if (bfd_seek (abfd
, file_hdr
->space_strings_location
, SEEK_SET
) < 0)
178 if (bfd_read (space_strings
, 1, file_hdr
->space_strings_size
, abfd
)
179 != file_hdr
->space_strings_size
)
182 /* Loop over all of the space dictionaries, building up sections */
184 for (space_index
= 0; space_index
< file_hdr
->space_total
; space_index
++)
186 struct space_dictionary_record space
;
187 struct subspace_dictionary_record subspace
;
188 int subspace_index
, tmp
;
189 asection
*space_asect
;
191 /* Read the space dictionary element */
192 if (bfd_seek (abfd
, file_hdr
->space_location
193 + space_index
* sizeof space
, SEEK_SET
) < 0)
195 if (bfd_read (&space
, 1, sizeof space
, abfd
) != sizeof space
)
198 /* Setup the space name string */
199 space
.name
.n_name
= space
.name
.n_strx
+ space_strings
;
201 /* Make a section out of it */
202 space_asect
= make_unique_section (abfd
, space
.name
.n_name
, space_index
);
206 /* Now, read in the first subspace for this space */
207 if (bfd_seek (abfd
, file_hdr
->subspace_location
208 + space
.subspace_index
* sizeof subspace
,
211 if (bfd_read (&subspace
, 1, sizeof subspace
, abfd
) != sizeof subspace
)
213 /* Seek back to the start of the subspaces for loop below */
214 if (bfd_seek (abfd
, file_hdr
->subspace_location
215 + space
.subspace_index
* sizeof subspace
,
219 /* Setup the section flags as appropriate (this is somewhat bogus, as
220 there isn't a clear mapping between what's in the space record, and
221 what BFD can describe here). */
222 if (space
.is_loadable
)
223 space_asect
->flags
|= SEC_ALLOC
;
224 if (space
.is_defined
)
225 space_asect
->flags
|= SEC_LOAD
;
227 /* Setup the start address and file loc from the first subspace record */
228 space_asect
->vma
= subspace
.subspace_start
;
229 space_asect
->filepos
= subspace
.file_loc_init_value
;
230 space_asect
->alignment_power
= subspace
.alignment
;
232 /* Loop over the rest of the subspaces, building up more sections */
233 for (subspace_index
= 0; subspace_index
< space
.subspace_quantity
;
236 asection
*subspace_asect
;
238 /* Read in the next subspace */
239 if (bfd_read (&subspace
, 1, sizeof subspace
, abfd
)
243 /* Setup the subspace name string */
244 subspace
.name
.n_name
= subspace
.name
.n_strx
+ space_strings
;
246 /* Make a section out of this subspace */
247 subspace_asect
= make_unique_section (abfd
, subspace
.name
.n_name
,
248 space
.subspace_index
+ subspace_index
);
253 if (subspace
.is_loadable
)
254 subspace_asect
->flags
|= SEC_ALLOC
| SEC_LOAD
;
255 if (subspace
.code_only
)
256 subspace_asect
->flags
|= SEC_CODE
;
258 subspace_asect
->vma
= subspace
.subspace_start
;
259 subspace_asect
->_cooked_size
= subspace
.subspace_length
;
260 subspace_asect
->_raw_size
= subspace
.initialization_length
;
261 subspace_asect
->alignment_power
= subspace
.alignment
;
262 subspace_asect
->filepos
= subspace
.file_loc_init_value
;
265 /* Setup the sizes for the space section based upon the info in the
266 last subspace of the space. */
267 space_asect
->_cooked_size
= (subspace
.subspace_start
- space_asect
->vma
)
268 + subspace
.subspace_length
;
269 space_asect
->_raw_size
= (subspace
.file_loc_init_value
270 - space_asect
->filepos
)
271 + subspace
.initialization_length
;
279 struct header file_hdr
;
280 struct som_exec_auxhdr aux_hdr
;
282 if (bfd_read ((PTR
) &file_hdr
, 1, FILE_HDR_SIZE
, abfd
) != FILE_HDR_SIZE
)
285 if (!_PA_RISC_ID (file_hdr
.system_id
))
287 bfd_error
= wrong_format
;
291 switch (file_hdr
.a_magic
)
293 case RELOC_MAGIC
: /* I'm not really sure about all of these types... */
301 bfd_error
= wrong_format
;
305 if (file_hdr
.version_id
!= VERSION_ID
306 && file_hdr
.version_id
!= NEW_VERSION_ID
)
308 bfd_error
= wrong_format
;
312 if (bfd_read ((PTR
) &aux_hdr
, 1, AUX_HDR_SIZE
, abfd
) != AUX_HDR_SIZE
)
313 bfd_error
= wrong_format
;
315 if (!setup_sections (abfd
, &file_hdr
))
318 return hppa_object_setup(abfd
, &file_hdr
, &aux_hdr
);
322 DEFUN(hppa_mkobject
,(abfd
),
325 fprintf (stderr
, "hppa_mkobject unimplemented\n");
332 DEFUN(hppa_write_object_contents
,(abfd
),
335 fprintf (stderr
, "hppa_write_object_contents unimplemented\n");
342 hppa_get_symtab_upper_bound (abfd
)
345 fprintf (stderr
, "hppa_get_symtab_upper_bound unimplemented\n");
352 hppa_get_reloc_upper_bound (abfd
, asect
)
356 fprintf (stderr
, "hppa_get_reloc_upper_bound unimplemented\n");
363 hppa_canonicalize_reloc (abfd
, section
, relptr
, symbols
)
369 fprintf (stderr
, "hppa_canonicalize_reloc unimplemented\n");
374 extern bfd_target hppa_vec
;
377 hppa_get_symtab (abfd
, location
)
381 fprintf (stderr
, "hppa_get_symtab unimplemented\n");
388 hppa_make_empty_symbol (abfd
)
391 hppa_symbol_type
*new =
392 (hppa_symbol_type
*)bfd_zalloc (abfd
, sizeof (hppa_symbol_type
));
393 new->symbol
.the_bfd
= abfd
;
399 hppa_print_symbol (ignore_abfd
, afile
, symbol
, how
)
403 bfd_print_symbol_type how
;
405 fprintf (stderr
, "hppa_print_symbol unimplemented\n");
411 hppa_new_section_hook (abfd
, newsect
)
415 newsect
->alignment_power
= 3;
417 /* We allow more than three sections internally */
422 hppa_set_section_contents (abfd
, section
, location
, offset
, count
)
429 fprintf (stderr
, "hppa_set_section_contents unimplimented\n");
436 hppa_set_arch_mach (abfd
, arch
, machine
)
438 enum bfd_architecture arch
;
439 unsigned long machine
;
441 fprintf (stderr
, "hppa_set_arch_mach unimplemented\n");
443 /* Allow any architecture to be supported by the hppa backend */
444 return bfd_default_set_arch_mach(abfd
, arch
, machine
);
448 hppa_find_nearest_line (abfd
, section
, symbols
, offset
, filename_ptr
,
449 functionname_ptr
, line_ptr
)
454 CONST
char **filename_ptr
;
455 CONST
char **functionname_ptr
;
456 unsigned int *line_ptr
;
458 fprintf (stderr
, "hppa_find_nearest_line unimplemented\n");
465 hppa_sizeof_headers (abfd
, reloc
)
469 fprintf (stderr
, "hppa_sizeof_headers unimplemented\n");
476 make_bfd_asection (abfd
, name
, flags
, _raw_size
, vma
, alignment_power
)
480 bfd_size_type _raw_size
;
482 unsigned int alignment_power
;
486 asect
= bfd_make_section (abfd
, name
);
490 asect
->flags
= flags
;
491 asect
->_raw_size
= _raw_size
;
493 asect
->filepos
= bfd_tell (abfd
);
494 asect
->alignment_power
= alignment_power
;
500 hppa_core_file_p (abfd
)
503 core_hdr (abfd
) = bfd_zalloc (abfd
, sizeof (struct hppa_core_struct
));
504 if (!core_hdr (abfd
))
510 struct corehead core_header
;
512 val
= bfd_read ((void *)&core_header
, 1, sizeof core_header
, abfd
);
515 switch (core_header
.type
)
519 bfd_seek (abfd
, core_header
.len
, SEEK_CUR
); /* Just skip this */
523 struct proc_exec proc_exec
;
524 bfd_read ((void *)&proc_exec
, 1, core_header
.len
, abfd
);
525 strncpy (core_command (abfd
), proc_exec
.cmd
, MAXCOMLEN
+ 1);
530 struct proc_info proc_info
;
531 core_regsec (abfd
) = make_bfd_asection (abfd
, ".reg",
532 SEC_ALLOC
+SEC_HAS_CONTENTS
,
534 (int)&proc_info
- (int)&proc_info
.hw_regs
,
536 bfd_read (&proc_info
, 1, core_header
.len
, abfd
);
537 core_signal (abfd
) = proc_info
.sig
;
539 if (!core_regsec (abfd
))
543 core_datasec (abfd
) = make_bfd_asection (abfd
, ".data",
544 SEC_ALLOC
+SEC_LOAD
+SEC_HAS_CONTENTS
,
548 if (!core_datasec (abfd
))
550 bfd_seek (abfd
, core_header
.len
, SEEK_CUR
);
553 core_stacksec (abfd
) = make_bfd_asection (abfd
, ".stack",
554 SEC_ALLOC
+SEC_LOAD
+SEC_HAS_CONTENTS
,
558 if (!core_stacksec (abfd
))
560 bfd_seek (abfd
, core_header
.len
, SEEK_CUR
);
563 fprintf (stderr
, "Unknown HPPA/HPUX core file section type %d\n",
565 bfd_seek (abfd
, core_header
.len
, SEEK_CUR
);
570 /* OK, we believe you. You're a core file (sure, sure). */
576 hppa_core_file_failing_command (abfd
)
579 return core_command (abfd
);
584 hppa_core_file_failing_signal (abfd
)
587 return core_signal (abfd
);
592 hppa_core_file_matches_executable_p (core_bfd
, exec_bfd
)
593 bfd
*core_bfd
, *exec_bfd
;
595 return true; /* FIXME, We have no way of telling at this point */
598 #define hppa_bfd_debug_info_start bfd_void
599 #define hppa_bfd_debug_info_end bfd_void
600 #define hppa_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
604 #define hppa_openr_next_archived_file bfd_generic_openr_next_archived_file
605 #define hppa_generic_stat_arch_elt bfd_generic_stat_arch_elt
606 #define hppa_slurp_armap bfd_false
607 #define hppa_slurp_extended_name_table _bfd_slurp_extended_name_table
608 #define hppa_truncate_arname (void (*)())bfd_nullvoidptr
609 #define hppa_write_armap 0
611 #define hppa_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
612 #define hppa_close_and_cleanup bfd_generic_close_and_cleanup
613 #define hppa_get_section_contents bfd_generic_get_section_contents
615 #define hppa_bfd_get_relocated_section_contents \
616 bfd_generic_get_relocated_section_contents
617 #define hppa_bfd_relax_section bfd_generic_relax_section
618 #define hppa_bfd_seclet_link bfd_generic_seclet_link
620 bfd_target hppa_vec
=
623 bfd_target_hppa_flavour
,
624 true, /* target byte order */
625 true, /* target headers byte order */
626 (HAS_RELOC
| EXEC_P
| /* object flags */
627 HAS_LINENO
| HAS_DEBUG
|
628 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
629 (SEC_CODE
|SEC_DATA
|SEC_ROM
|SEC_HAS_CONTENTS
630 |SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
632 /* leading_symbol_char: is the first char of a user symbol
633 predictable, and if so what is it */
635 ' ', /* ar_pad_char */
636 16, /* ar_max_namelen */
637 3, /* minimum alignment */
638 _do_getb64
, _do_putb64
, _do_getb32
, _do_putb32
, _do_getb16
, _do_putb16
, /* data */
639 _do_getb64
, _do_putb64
, _do_getb32
, _do_putb32
, _do_getb16
, _do_putb16
, /* hdrs */
641 hppa_object_p
, /* bfd_check_format */
642 bfd_generic_archive_p
,
648 _bfd_generic_mkarchive
,
653 hppa_write_object_contents
,
654 _bfd_write_archive_contents
,
661 #endif /* HOST_HPPAHPUX */