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