* hppa.c: Conditionalize on HOST_HPPAHPUX instead of hp9000s800.
[deliverable/binutils-gdb.git] / bfd / hppa.c
1 /* bfd back-end for HP PA-RISC SOM objects.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3
4 Contributed by the Center for Software Science at the
5 University of Utah (pa-gdb-bugs@cs.utah.edu).
6
7 This file is part of BFD, the Binary File Descriptor library.
8
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.
13
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.
18
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. */
22
23 #include "bfd.h"
24 #include "sysdep.h"
25
26 #ifdef HOST_HPPAHPUX
27
28 #include "libbfd.h"
29 #include "libhppa.h"
30
31 #include <stdio.h>
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/dir.h>
35 #include <signal.h>
36 #include <machine/reg.h>
37 #include <sys/user.h> /* After a.out.h */
38 #include <sys/file.h>
39 #include <errno.h>
40
41 struct container {
42 struct header f;
43 struct som_exec_auxhdr e;
44 };
45
46 #undef USIZE
47 #undef UPAGES
48
49 #define USIZE 3
50 #define UPAGES 7
51
52 void
53 fill_spaces(abfd, file_hdr, dbx_subspace, dbx_strings_subspace)
54 bfd *abfd;
55 struct header *file_hdr;
56 struct subspace_dictionary_record *dbx_subspace, *dbx_strings_subspace;
57 {
58 char *space_strings = (char *) alloca (file_hdr->space_strings_size);
59 int i;
60 /* for millicode games. */
61 struct space_dictionary_record space;
62 struct subspace_dictionary_record subspace;
63 int index;
64 /* indices of subspace entries for $TEXT$ and $GDB_DEBUG$ */
65 int text_index = 0, gdb_debug_index = 0;
66
67 /* initialize in case we don't find any dbx symbols. */
68 dbx_subspace->subspace_length = dbx_strings_subspace->subspace_length = 0;
69 bfd_seek (abfd, file_hdr->space_strings_location, SEEK_SET);
70 if (bfd_read ((PTR) space_strings, 1, file_hdr->space_strings_size, abfd)
71 != file_hdr->space_strings_size)
72 {
73 bfd_error = wrong_format; /* space strings table corrupted. */
74 return;
75 }
76 bfd_seek (abfd, file_hdr->space_location, SEEK_SET);
77 for (i = 0; i < file_hdr->space_total; i++)
78 {
79 bfd_read ((PTR) &space, 1, sizeof(space), abfd);
80 index = (file_hdr->subspace_location +
81 (space.subspace_index * sizeof(subspace)));
82 if (!strcmp (space_strings + space.name.n_strx, "$TEXT$"))
83 text_index = index;
84 else if (!strcmp (space_strings + space.name.n_strx, "$GDB_DEBUG$"))
85 gdb_debug_index = index;
86 }
87 /* search out the beginning and end if millicode */
88 bfd_seek (abfd, text_index, SEEK_SET);
89 for (i = 0; i < file_hdr->subspace_total; i++)
90 {
91 bfd_read ((PTR) &subspace, 1, sizeof(subspace), abfd);
92 if (!strcmp (space_strings + subspace.name.n_strx, "$MILLICODE$"))
93 {
94 millicode_start = subspace.subspace_start;
95 millicode_end = (millicode_start + subspace.subspace_length);
96 }
97 else if (!strncmp (space_strings + subspace.name.n_strx, "$UNWIND", 7))
98 {
99 int *foo;
100 long s;
101
102 #if 0
103 s = bfd_tell(abfd);
104 printf("Found %s\n", space_strings + subspace.name.n_strx);
105 foo = malloc (subspace.initialization_length);
106 bfd_seek (abfd, subspace.file_loc_init_value, SEEK_SET);
107 bfd_read (foo, 1, subspace.initialization_length, abfd);
108 bfd_seek (abfd, s, SEEK_SET);
109 free (foo);
110 #endif
111 }
112 }
113 /* read symbols subspace and strings subspace in possibly arbitrary
114 order. */
115 bfd_seek (abfd, gdb_debug_index, SEEK_SET);
116 bfd_read ((PTR) &subspace, 1, sizeof(struct subspace_dictionary_record),
117 abfd);
118 if (!strcmp (space_strings + subspace.name.n_strx, "$GDB_STRINGS$"))
119 {
120 *dbx_strings_subspace = subspace;
121 bfd_read ((PTR) dbx_subspace, 1,
122 sizeof(struct subspace_dictionary_record), abfd);
123 }
124 else
125 {
126 *dbx_subspace = subspace;
127 bfd_read ((PTR) dbx_strings_subspace, 1,
128 sizeof(struct subspace_dictionary_record), abfd);
129 }
130 }
131
132 bfd_target *
133 DEFUN(hppa_object_setup,(abfd, file_hdrp, aux_hdrp, dbx_subspace,
134 dbx_strings_subspace),
135 bfd *abfd AND
136 struct header *file_hdrp AND
137 struct som_exec_auxhdr *aux_hdrp AND
138 struct subspace_dictionary_record *dbx_subspace AND
139 struct subspace_dictionary_record *dbx_strings_subspace)
140 {
141 struct container *rawptr;
142 struct header *f;
143 struct hppa_data_struct *rawptr1;
144
145 rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
146 if (rawptr == NULL) {
147 bfd_error = no_memory;
148 return 0;
149 }
150
151 rawptr1 = (struct hppa_data_struct *) bfd_zalloc (abfd, sizeof (struct hppa_data_struct));
152 if (rawptr1 == NULL) {
153 bfd_error = no_memory;
154 return 0;
155 }
156
157 abfd->tdata.hppa_data = rawptr1;
158 obj_file_hdr (abfd) = &rawptr->f;
159 obj_aux_hdr (abfd) = &rawptr->e;
160 *obj_file_hdr (abfd) = *file_hdrp;
161 *obj_aux_hdr (abfd) = *aux_hdrp;
162
163 /* Set the file flags */
164 abfd->flags = NO_FLAGS;
165 if (file_hdrp->entry_offset)
166 abfd->flags |= HAS_RELOC;
167 if (file_hdrp->symbol_total)
168 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
169
170 bfd_get_start_address (abfd) = aux_hdrp->exec_entry;
171
172 obj_hp_symbol_entry_size (abfd) = sizeof(struct symbol_dictionary_record);
173 obj_dbx_symbol_entry_size (abfd) = 12;
174
175 obj_pa_symbols (abfd) = (hppa_symbol_type *)NULL;
176 obj_hp_sym_count (abfd) = file_hdrp->symbol_total;
177 obj_dbx_sym_count (abfd) = dbx_subspace->subspace_length /
178 obj_dbx_symbol_entry_size (abfd);
179 bfd_get_symcount (abfd) = obj_hp_sym_count (abfd) + obj_dbx_sym_count (abfd);
180
181 bfd_default_set_arch_mach(abfd, bfd_arch_hppa, 0);
182
183 /* create the sections. This is raunchy, but bfd_close wants to reclaim
184 them */
185 obj_textsec (abfd) = (asection *)NULL;
186 obj_datasec (abfd) = (asection *)NULL;
187 obj_bsssec (abfd) = (asection *)NULL;
188 (void)bfd_make_section(abfd, ".text");
189 (void)bfd_make_section(abfd, ".data");
190 (void)bfd_make_section(abfd, ".bss");
191
192 abfd->sections = obj_textsec (abfd);
193 obj_textsec (abfd)->next = obj_datasec (abfd);
194 obj_datasec (abfd)->next = obj_bsssec (abfd);
195
196 obj_datasec (abfd)->_raw_size = aux_hdrp->exec_dsize;
197 obj_bsssec (abfd)->_raw_size = aux_hdrp->exec_bsize;
198 obj_textsec (abfd)->_raw_size = aux_hdrp->exec_tsize;
199
200 obj_textsec (abfd)->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS);
201 obj_datasec (abfd)->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS);
202 obj_bsssec (abfd)->flags = SEC_ALLOC;
203
204 /* The virtual memory addresses of the sections */
205 obj_datasec (abfd)->vma = aux_hdrp->exec_dmem;
206 obj_bsssec (abfd)->vma = aux_hdrp->exec_bfill;
207 obj_textsec (abfd)->vma = aux_hdrp->exec_tmem;
208
209 /* The file offsets of the sections */
210 obj_textsec (abfd)->filepos = aux_hdrp->exec_tfile;
211 obj_datasec (abfd)->filepos = aux_hdrp->exec_dfile;
212
213 /* The file offsets of the relocation info */
214 obj_textsec (abfd)->rel_filepos = 0;
215 obj_datasec (abfd)->rel_filepos = 0;
216
217 /* The file offsets of the string table and symbol table. */
218 obj_hp_sym_filepos (abfd) = file_hdrp->symbol_location;
219 obj_hp_str_filepos (abfd) = file_hdrp->symbol_strings_location;
220 obj_dbx_sym_filepos (abfd) = dbx_subspace->file_loc_init_value;
221 obj_dbx_str_filepos (abfd) = dbx_strings_subspace->file_loc_init_value;
222 obj_hp_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
223 obj_dbx_stringtab_size (abfd) = dbx_strings_subspace->subspace_length;
224
225 return abfd->xvec;
226 }
227
228 bfd_target *
229 DEFUN(hppa_object_p,(abfd),
230 bfd *abfd)
231 {
232 struct header file_hdr;
233 struct som_exec_auxhdr aux_hdr;
234 struct subspace_dictionary_record dbx_subspace;
235 struct subspace_dictionary_record dbx_strings_subspace;
236
237 if (bfd_read ((PTR) &file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
238 {
239 bfd_error = wrong_format;
240 return 0;
241 }
242
243 if (!_PA_RISC_ID (file_hdr.system_id))
244 return 0;
245
246 switch (file_hdr.a_magic)
247 {
248 case RELOC_MAGIC: /* I'm not really sure about all of these types... */
249 case EXEC_MAGIC:
250 case SHARE_MAGIC:
251 case DEMAND_MAGIC:
252 case DL_MAGIC:
253 case SHL_MAGIC:
254 break;
255 default:
256 return 0;
257 }
258
259 if (bfd_read ((PTR) &aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
260 {
261 bfd_error = wrong_format;
262 return 0;
263 }
264
265 fill_spaces(abfd, &file_hdr, &dbx_subspace, &dbx_strings_subspace);
266
267 return hppa_object_setup(abfd, &file_hdr, &aux_hdr, &dbx_subspace, &dbx_strings_subspace);
268 }
269
270
271 static boolean
272 DEFUN(hppa_mkobject,(abfd),
273 bfd *abfd)
274 {
275 fprintf (stderr, "hppa_mkobject unimplemented\n");
276 fflush (stderr);
277 abort ();
278 return (false);
279 }
280
281 boolean
282 DEFUN(hppa_write_object_contents,(abfd),
283 bfd *abfd)
284 {
285 fprintf (stderr, "hppa_write_object_contents unimplemented\n");
286 fflush (stderr);
287 abort ();
288 return (false);
289 }
290
291
292
293 unsigned int
294 DEFUN(hppa_get_symtab_upper_bound,(abfd),
295 bfd *abfd)
296 {
297 fprintf (stderr, "hppa_get_symtab_upper_bound unimplemented\n");
298 fflush (stderr);
299 abort ();
300 return (0);
301 }
302
303 unsigned int
304 DEFUN(hppa_get_reloc_upper_bound,(abfd, asect),
305 bfd *abfd AND
306 sec_ptr asect)
307 {
308 fprintf (stderr, "hppa_get_reloc_upper_bound unimplemented\n");
309 fflush (stderr);
310 abort ();
311 return (0);
312 }
313
314 unsigned int
315 DEFUN(hppa_canonicalize_reloc,(abfd, section, relptr, symbols),
316 bfd *abfd AND
317 sec_ptr section AND
318 arelent **relptr AND
319 asymbol **symbols)
320 {
321 fprintf (stderr, "hppa_canonicalize_reloc unimplemented\n");
322 fflush (stderr);
323 abort ();
324 }
325
326 extern bfd_target hppa_vec;
327 unsigned int
328 DEFUN(hppa_get_symtab,(abfd, location),
329 bfd *abfd AND
330 asymbol **location)
331 {
332 fprintf (stderr, "hppa_get_symtab unimplemented\n");
333 fflush (stderr);
334 abort ();
335 return (0);
336 }
337
338 asymbol *
339 DEFUN(hppa_make_empty_symbol,(abfd),
340 bfd *abfd)
341 {
342 hppa_symbol_type *new =
343 (hppa_symbol_type *)bfd_zalloc (abfd, sizeof (hppa_symbol_type));
344 new->symbol.the_bfd = abfd;
345
346 return &new->symbol;
347 }
348
349
350 void
351 DEFUN(hppa_print_symbol,(ignore_abfd, afile, symbol, how),
352 bfd *ignore_abfd AND
353 PTR afile AND
354 asymbol *symbol AND
355 bfd_print_symbol_type how)
356 {
357 fprintf (stderr, "hppa_print_symbol unimplemented\n");
358 fflush (stderr);
359 abort ();
360 }
361
362
363
364 boolean
365 DEFUN(hppa_new_section_hook,(abfd, newsect),
366 bfd *abfd AND
367 asection *newsect)
368 {
369 /* align to double at least */
370 newsect->alignment_power = 3;
371
372 if (bfd_get_format (abfd) == bfd_object) {
373 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
374 obj_textsec(abfd)= newsect;
375 return true;
376 }
377
378 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
379 obj_datasec(abfd) = newsect;
380 return true;
381 }
382
383 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
384 obj_bsssec(abfd) = newsect;
385 return true;
386 }
387 }
388
389 /* We allow more than three sections internally */
390 return true;
391 }
392
393
394
395
396 boolean
397 DEFUN(hppa_set_section_contents,(abfd, section, location, offset, count),
398 bfd *abfd AND
399 sec_ptr section AND
400 PTR location AND
401 file_ptr offset AND
402 bfd_size_type count)
403 {
404 fprintf (stderr, "hppa_set_section_contents unimplimented\n");
405 fflush (stderr);
406 abort();
407 return false;
408 }
409
410
411 boolean
412 DEFUN(hppa_set_arch_mach,(abfd, arch, machine),
413 bfd *abfd AND
414 enum bfd_architecture arch AND
415 unsigned long machine)
416 {
417 fprintf (stderr, "hppa_set_arch_mach unimplemented\n");
418 fflush (stderr);
419 /* Allow any architecture to be supported by the hppa backend */
420 return bfd_default_set_arch_mach(abfd, arch, machine);
421 }
422
423
424 static boolean
425 DEFUN (hppa_find_nearest_line,(abfd,
426 section,
427 symbols,
428 offset,
429 filename_ptr,
430 functionname_ptr,
431 line_ptr),
432 bfd *abfd AND
433 asection *section AND
434 asymbol **symbols AND
435 bfd_vma offset AND
436 CONST char **filename_ptr AND
437 CONST char **functionname_ptr AND
438 unsigned int *line_ptr)
439 {
440 fprintf (stderr, "hppa_find_nearest_line unimplemented\n");
441 fflush (stderr);
442 abort ();
443 return (false);
444 }
445
446 static int
447 DEFUN (hppa_sizeof_headers, (abfd, reloc),
448 bfd *abfd AND
449 boolean reloc)
450 {
451 fprintf (stderr, "hppa_sizeof_headers unimplemented\n");
452 fflush (stderr);
453 abort ();
454 return (0);
455 }
456
457 static asection *
458 make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power)
459 bfd *abfd;
460 const char *name;
461 flagword flags;
462 bfd_size_type _raw_size;
463 bfd_vma vma;
464 unsigned int alignment_power;
465 {
466 asection *asect;
467
468 asect = bfd_zalloc (abfd, sizeof (asection));
469 if (!asect)
470 {
471 bfd_error = no_memory;
472 return NULL;
473 }
474
475 asect->name = name;
476 asect->flags = flags;
477 asect->_raw_size = _raw_size;
478 asect->vma = vma;
479 asect->filepos = bfd_tell (abfd);
480 asect->alignment_power = alignment_power;
481
482 asect->next = abfd->sections;
483 abfd->sections = asect;
484 abfd->section_count++;
485
486 return asect;
487 }
488
489 bfd_target *
490 hppa_core_file_p (abfd)
491 bfd *abfd;
492 {
493 core_hdr (abfd) = bfd_zalloc (abfd, sizeof (struct hppa_core_struct));
494 if (!core_hdr (abfd))
495 return NULL;
496
497 while (1)
498 {
499 int val;
500 struct corehead core_header;
501
502 val = bfd_read ((void *)&core_header, 1, sizeof core_header, abfd);
503 if (val <= 0)
504 break;
505 switch (core_header.type)
506 {
507 case CORE_KERNEL:
508 case CORE_FORMAT:
509 bfd_seek (abfd, core_header.len, SEEK_CUR); /* Just skip this */
510 break;
511 case CORE_EXEC:
512 {
513 struct proc_exec proc_exec;
514 bfd_read ((void *)&proc_exec, 1, core_header.len, abfd);
515 strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1);
516 }
517 break;
518 case CORE_PROC:
519 {
520 struct proc_info proc_info;
521 core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
522 SEC_ALLOC+SEC_HAS_CONTENTS,
523 core_header.len,
524 (int)&proc_info - (int)&proc_info.hw_regs,
525 2);
526 bfd_read (&proc_info, 1, core_header.len, abfd);
527 core_signal (abfd) = proc_info.sig;
528 }
529 if (!core_regsec (abfd))
530 return NULL;
531 break;
532 case CORE_DATA:
533 core_datasec (abfd) = make_bfd_asection (abfd, ".data",
534 SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
535 core_header.len,
536 core_header.addr,
537 2);
538 if (!core_datasec (abfd))
539 return NULL;
540 bfd_seek (abfd, core_header.len, SEEK_CUR);
541 break;
542 case CORE_STACK:
543 core_stacksec (abfd) = make_bfd_asection (abfd, ".data",
544 SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
545 core_header.len,
546 core_header.addr,
547 2);
548 if (!core_stacksec (abfd))
549 return NULL;
550 bfd_seek (abfd, core_header.len, SEEK_CUR);
551 break;
552 default:
553 fprintf (stderr, "Unknown HPPA/HPUX core file section type %d\n",
554 core_header.type);
555 bfd_seek (abfd, core_header.len, SEEK_CUR);
556 break;
557 }
558 }
559
560 /* OK, we believe you. You're a core file (sure, sure). */
561
562 return abfd->xvec;
563 }
564
565 char *
566 hppa_core_file_failing_command (abfd)
567 bfd *abfd;
568 {
569 return core_command (abfd);
570 }
571
572 /* ARGSUSED */
573 int
574 hppa_core_file_failing_signal (abfd)
575 bfd *abfd;
576 {
577 return core_signal (abfd);
578 }
579
580 /* ARGSUSED */
581 boolean
582 hppa_core_file_matches_executable_p (core_bfd, exec_bfd)
583 bfd *core_bfd, *exec_bfd;
584 {
585 return true; /* FIXME, We have no way of telling at this point */
586 }
587
588 #define hppa_bfd_debug_info_start bfd_void
589 #define hppa_bfd_debug_info_end bfd_void
590 #define hppa_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
591
592
593
594 #define hppa_openr_next_archived_file bfd_generic_openr_next_archived_file
595 #define hppa_generic_stat_arch_elt bfd_generic_stat_arch_elt
596 #define hppa_slurp_armap bfd_false
597 #define hppa_slurp_extended_name_table _bfd_slurp_extended_name_table
598 #define hppa_truncate_arname (void (*)())bfd_nullvoidptr
599 #define hppa_write_armap 0
600
601 #define hppa_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
602 #define hppa_close_and_cleanup bfd_generic_close_and_cleanup
603 #define hppa_get_section_contents bfd_generic_get_section_contents
604
605 #define hppa_bfd_get_relocated_section_contents \
606 bfd_generic_get_relocated_section_contents
607 #define hppa_bfd_relax_section bfd_generic_relax_section
608
609 bfd_target hppa_vec =
610 {
611 "hppa", /* name */
612 bfd_target_hppa_flavour,
613 true, /* target byte order */
614 true, /* target headers byte order */
615 (HAS_RELOC | EXEC_P | /* object flags */
616 HAS_LINENO | HAS_DEBUG |
617 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
618 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
619 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
620
621 /* leading_symbol_char: is the first char of a user symbol
622 predictable, and if so what is it */
623 0,
624
625
626 ' ', /* ar_pad_char */
627 16, /* ar_max_namelen */
628 3, /* minimum alignment */
629 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
630 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
631
632 { _bfd_dummy_target,
633 hppa_object_p, /* bfd_check_format */
634 bfd_generic_archive_p,
635 hppa_core_file_p,
636 },
637 {
638 bfd_false,
639 hppa_mkobject,
640 _bfd_generic_mkarchive,
641 bfd_false
642 },
643 {
644 bfd_false,
645 hppa_write_object_contents,
646 _bfd_write_archive_contents,
647 bfd_false,
648 },
649 #undef hppa
650 JUMP_TABLE(hppa)
651 };
652
653 #endif /* HOST_HPPAHPUX */
This page took 0.041498 seconds and 4 git commands to generate.