from Noah Friedman: define some needed macros if hpux version < 8
[deliverable/binutils-gdb.git] / bfd / hppa.c
1 /* bfd back-end for HP PA-RISC SOM objects.
2 Copyright (C) 1990, 1991, 1992, 1993 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 /* Magic not defined in standard HP-UX header files until 8.0 */
42
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 */
58 #ifndef _PA_RISC_ID
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 */
63
64 struct container {
65 struct header f;
66 struct som_exec_auxhdr e;
67 };
68
69 static bfd_target *
70 hppa_object_setup (abfd, file_hdrp, aux_hdrp)
71 bfd *abfd;
72 struct header *file_hdrp;
73 struct som_exec_auxhdr *aux_hdrp;
74 {
75 struct container *rawptr;
76 struct header *f;
77 struct hppa_data_struct *rawptr1;
78 asection *text, *data, *bss;
79
80 rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
81 if (rawptr == NULL) {
82 bfd_error = no_memory;
83 return 0;
84 }
85
86 rawptr1 = (struct hppa_data_struct *) bfd_zalloc (abfd, sizeof (struct hppa_data_struct));
87 if (rawptr1 == NULL) {
88 bfd_error = no_memory;
89 return 0;
90 }
91
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;
97
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;
104
105 bfd_get_start_address (abfd) = aux_hdrp->exec_entry;
106
107 obj_pa_symbols (abfd) = (hppa_symbol_type *)NULL;
108 bfd_get_symcount (abfd) = file_hdrp->symbol_total;
109
110 bfd_default_set_arch_mach(abfd, bfd_arch_hppa, 0);
111
112 /* create the sections. This is raunchy, but bfd_close wants to reclaim
113 them */
114
115 text = bfd_make_section(abfd, ".text");
116 data = bfd_make_section(abfd, ".data");
117 bss = bfd_make_section(abfd, ".bss");
118
119 text->_raw_size = aux_hdrp->exec_tsize;
120 data->_raw_size = aux_hdrp->exec_dsize;
121 bss->_raw_size = aux_hdrp->exec_bsize;
122
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;
126
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;
131
132 /* The file offsets of the sections */
133 text->filepos = aux_hdrp->exec_tfile;
134 data->filepos = aux_hdrp->exec_dfile;
135
136 /* The file offsets of the relocation info */
137 text->rel_filepos = 0;
138 data->rel_filepos = 0;
139
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;
145
146 return abfd->xvec;
147 }
148
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
152 subroutine.
153 */
154
155 static asection *
156 make_unique_section (abfd, name, num)
157 bfd *abfd;
158 CONST char *name;
159 int num;
160 {
161 asection *sect;
162 char *newname;
163 char altname[100];
164
165 sect = bfd_make_section (abfd, name);
166 while (!sect)
167 {
168 sprintf(altname, "%s-%d", name, num++);
169 sect = bfd_make_section (abfd, altname);
170 }
171
172 newname = bfd_alloc (abfd, strlen(sect->name) + 1);
173 strcpy (newname, sect->name);
174
175 sect->name = newname;
176 return sect;
177 }
178
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. */
184
185 static int
186 setup_sections (abfd, file_hdr)
187 bfd *abfd;
188 struct header *file_hdr;
189 {
190 char *space_strings;
191 int space_index;
192
193 /* First, read in space names */
194
195 space_strings = alloca (file_hdr->space_strings_size);
196 if (!space_strings)
197 return 0;
198
199 if (bfd_seek (abfd, file_hdr->space_strings_location, SEEK_SET) < 0)
200 return 0;
201 if (bfd_read (space_strings, 1, file_hdr->space_strings_size, abfd)
202 != file_hdr->space_strings_size)
203 return 0;
204
205 /* Loop over all of the space dictionaries, building up sections */
206
207 for (space_index = 0; space_index < file_hdr->space_total; space_index++)
208 {
209 struct space_dictionary_record space;
210 struct subspace_dictionary_record subspace;
211 int subspace_index, tmp;
212 asection *space_asect;
213
214 /* Read the space dictionary element */
215 if (bfd_seek (abfd, file_hdr->space_location
216 + space_index * sizeof space, SEEK_SET) < 0)
217 return 0;
218 if (bfd_read (&space, 1, sizeof space, abfd) != sizeof space)
219 return 0;
220
221 /* Setup the space name string */
222 space.name.n_name = space.name.n_strx + space_strings;
223
224 /* Make a section out of it */
225 space_asect = make_unique_section (abfd, space.name.n_name, space_index);
226 if (!space_asect)
227 return 0;
228
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,
232 SEEK_SET) < 0)
233 return 0;
234 if (bfd_read (&subspace, 1, sizeof subspace, abfd) != sizeof subspace)
235 return 0;
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,
239 SEEK_SET) < 0)
240 return 0;
241
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;
249
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;
254
255 /* Loop over the rest of the subspaces, building up more sections */
256 for (subspace_index = 0; subspace_index < space.subspace_quantity;
257 subspace_index++)
258 {
259 asection *subspace_asect;
260
261 /* Read in the next subspace */
262 if (bfd_read (&subspace, 1, sizeof subspace, abfd)
263 != sizeof subspace)
264 return 0;
265
266 /* Setup the subspace name string */
267 subspace.name.n_name = subspace.name.n_strx + space_strings;
268
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);
272
273 if (!subspace_asect)
274 return 0;
275
276 if (subspace.is_loadable)
277 subspace_asect->flags |= SEC_ALLOC | SEC_LOAD;
278 if (subspace.code_only)
279 subspace_asect->flags |= SEC_CODE;
280
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;
286
287 }
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;
295 }
296 }
297
298 static bfd_target *
299 hppa_object_p (abfd)
300 bfd *abfd;
301 {
302 struct header file_hdr;
303 struct som_exec_auxhdr aux_hdr;
304
305 if (bfd_read ((PTR) &file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
306 return 0;
307
308 if (!_PA_RISC_ID (file_hdr.system_id))
309 {
310 bfd_error = wrong_format;
311 return 0;
312 }
313
314 switch (file_hdr.a_magic)
315 {
316 case RELOC_MAGIC: /* I'm not really sure about all of these types... */
317 case EXEC_MAGIC:
318 case SHARE_MAGIC:
319 case DEMAND_MAGIC:
320 case DL_MAGIC:
321 case SHL_MAGIC:
322 break;
323 default:
324 bfd_error = wrong_format;
325 return 0;
326 }
327
328 if (file_hdr.version_id != VERSION_ID
329 && file_hdr.version_id != NEW_VERSION_ID)
330 {
331 bfd_error = wrong_format;
332 return 0;
333 }
334
335 if (bfd_read ((PTR) &aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
336 bfd_error = wrong_format;
337
338 if (!setup_sections (abfd, &file_hdr))
339 return 0;
340
341 return hppa_object_setup(abfd, &file_hdr, &aux_hdr);
342 }
343
344 static boolean
345 DEFUN(hppa_mkobject,(abfd),
346 bfd *abfd)
347 {
348 fprintf (stderr, "hppa_mkobject unimplemented\n");
349 fflush (stderr);
350 abort ();
351 return (false);
352 }
353
354 boolean
355 DEFUN(hppa_write_object_contents,(abfd),
356 bfd *abfd)
357 {
358 fprintf (stderr, "hppa_write_object_contents unimplemented\n");
359 fflush (stderr);
360 abort ();
361 return (false);
362 }
363
364 static unsigned int
365 hppa_get_symtab_upper_bound (abfd)
366 bfd *abfd;
367 {
368 fprintf (stderr, "hppa_get_symtab_upper_bound unimplemented\n");
369 fflush (stderr);
370 abort ();
371 return (0);
372 }
373
374 static unsigned int
375 hppa_get_reloc_upper_bound (abfd, asect)
376 bfd *abfd;
377 sec_ptr asect;
378 {
379 fprintf (stderr, "hppa_get_reloc_upper_bound unimplemented\n");
380 fflush (stderr);
381 abort ();
382 return (0);
383 }
384
385 static unsigned int
386 hppa_canonicalize_reloc (abfd, section, relptr, symbols)
387 bfd *abfd;
388 sec_ptr section;
389 arelent **relptr;
390 asymbol **symbols;
391 {
392 fprintf (stderr, "hppa_canonicalize_reloc unimplemented\n");
393 fflush (stderr);
394 abort ();
395 }
396
397 extern bfd_target hppa_vec;
398
399 static unsigned int
400 hppa_get_symtab (abfd, location)
401 bfd *abfd;
402 asymbol **location;
403 {
404 fprintf (stderr, "hppa_get_symtab unimplemented\n");
405 fflush (stderr);
406 abort ();
407 return (0);
408 }
409
410 static asymbol *
411 hppa_make_empty_symbol (abfd)
412 bfd *abfd;
413 {
414 hppa_symbol_type *new =
415 (hppa_symbol_type *)bfd_zalloc (abfd, sizeof (hppa_symbol_type));
416 new->symbol.the_bfd = abfd;
417
418 return &new->symbol;
419 }
420
421 static void
422 hppa_print_symbol (ignore_abfd, afile, symbol, how)
423 bfd *ignore_abfd;
424 PTR afile;
425 asymbol *symbol;
426 bfd_print_symbol_type how;
427 {
428 fprintf (stderr, "hppa_print_symbol unimplemented\n");
429 fflush (stderr);
430 abort ();
431 }
432
433 static boolean
434 hppa_new_section_hook (abfd, newsect)
435 bfd *abfd;
436 asection *newsect;
437 {
438 newsect->alignment_power = 3;
439
440 /* We allow more than three sections internally */
441 return true;
442 }
443
444 static boolean
445 hppa_set_section_contents (abfd, section, location, offset, count)
446 bfd *abfd;
447 sec_ptr section;
448 PTR location;
449 file_ptr offset;
450 bfd_size_type count;
451 {
452 fprintf (stderr, "hppa_set_section_contents unimplimented\n");
453 fflush (stderr);
454 abort();
455 return false;
456 }
457
458 static boolean
459 hppa_set_arch_mach (abfd, arch, machine)
460 bfd *abfd;
461 enum bfd_architecture arch;
462 unsigned long machine;
463 {
464 fprintf (stderr, "hppa_set_arch_mach unimplemented\n");
465 fflush (stderr);
466 /* Allow any architecture to be supported by the hppa backend */
467 return bfd_default_set_arch_mach(abfd, arch, machine);
468 }
469
470 static boolean
471 hppa_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
472 functionname_ptr, line_ptr)
473 bfd *abfd;
474 asection *section;
475 asymbol **symbols;
476 bfd_vma offset;
477 CONST char **filename_ptr;
478 CONST char **functionname_ptr;
479 unsigned int *line_ptr;
480 {
481 fprintf (stderr, "hppa_find_nearest_line unimplemented\n");
482 fflush (stderr);
483 abort ();
484 return (false);
485 }
486
487 static int
488 hppa_sizeof_headers (abfd, reloc)
489 bfd *abfd;
490 boolean reloc;
491 {
492 fprintf (stderr, "hppa_sizeof_headers unimplemented\n");
493 fflush (stderr);
494 abort ();
495 return (0);
496 }
497
498 static asection *
499 make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power)
500 bfd *abfd;
501 CONST char *name;
502 flagword flags;
503 bfd_size_type _raw_size;
504 bfd_vma vma;
505 unsigned int alignment_power;
506 {
507 asection *asect;
508
509 asect = bfd_make_section (abfd, name);
510 if (!asect)
511 return NULL;
512
513 asect->flags = flags;
514 asect->_raw_size = _raw_size;
515 asect->vma = vma;
516 asect->filepos = bfd_tell (abfd);
517 asect->alignment_power = alignment_power;
518
519 return asect;
520 }
521
522 static bfd_target *
523 hppa_core_file_p (abfd)
524 bfd *abfd;
525 {
526 core_hdr (abfd) = bfd_zalloc (abfd, sizeof (struct hppa_core_struct));
527 if (!core_hdr (abfd))
528 return NULL;
529
530 while (1)
531 {
532 int val;
533 struct corehead core_header;
534
535 val = bfd_read ((void *)&core_header, 1, sizeof core_header, abfd);
536 if (val <= 0)
537 break;
538 switch (core_header.type)
539 {
540 case CORE_KERNEL:
541 case CORE_FORMAT:
542 bfd_seek (abfd, core_header.len, SEEK_CUR); /* Just skip this */
543 break;
544 case CORE_EXEC:
545 {
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);
549 }
550 break;
551 case CORE_PROC:
552 {
553 struct proc_info proc_info;
554 core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
555 SEC_ALLOC+SEC_HAS_CONTENTS,
556 core_header.len,
557 (int)&proc_info - (int)&proc_info.hw_regs,
558 2);
559 bfd_read (&proc_info, 1, core_header.len, abfd);
560 core_signal (abfd) = proc_info.sig;
561 }
562 if (!core_regsec (abfd))
563 return NULL;
564 break;
565 case CORE_DATA:
566 core_datasec (abfd) = make_bfd_asection (abfd, ".data",
567 SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
568 core_header.len,
569 core_header.addr,
570 2);
571 if (!core_datasec (abfd))
572 return NULL;
573 bfd_seek (abfd, core_header.len, SEEK_CUR);
574 break;
575 case CORE_STACK:
576 core_stacksec (abfd) = make_bfd_asection (abfd, ".stack",
577 SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
578 core_header.len,
579 core_header.addr,
580 2);
581 if (!core_stacksec (abfd))
582 return NULL;
583 bfd_seek (abfd, core_header.len, SEEK_CUR);
584 break;
585 default:
586 fprintf (stderr, "Unknown HPPA/HPUX core file section type %d\n",
587 core_header.type);
588 bfd_seek (abfd, core_header.len, SEEK_CUR);
589 break;
590 }
591 }
592
593 /* OK, we believe you. You're a core file (sure, sure). */
594
595 return abfd->xvec;
596 }
597
598 static char *
599 hppa_core_file_failing_command (abfd)
600 bfd *abfd;
601 {
602 return core_command (abfd);
603 }
604
605 /* ARGSUSED */
606 static int
607 hppa_core_file_failing_signal (abfd)
608 bfd *abfd;
609 {
610 return core_signal (abfd);
611 }
612
613 /* ARGSUSED */
614 static boolean
615 hppa_core_file_matches_executable_p (core_bfd, exec_bfd)
616 bfd *core_bfd, *exec_bfd;
617 {
618 return true; /* FIXME, We have no way of telling at this point */
619 }
620
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
624
625
626
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
633
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
637
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)
646
647 bfd_target hppa_vec =
648 {
649 "hppa", /* name */
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 */
658
659 /* leading_symbol_char: is the first char of a user symbol
660 predictable, and if so what is it */
661 0,
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 */
667 { _bfd_dummy_target,
668 hppa_object_p, /* bfd_check_format */
669 bfd_generic_archive_p,
670 hppa_core_file_p,
671 },
672 {
673 bfd_false,
674 hppa_mkobject,
675 _bfd_generic_mkarchive,
676 bfd_false
677 },
678 {
679 bfd_false,
680 hppa_write_object_contents,
681 _bfd_write_archive_contents,
682 bfd_false,
683 },
684 #undef hppa
685 JUMP_TABLE(hppa),
686 (PTR) 0
687 };
688
689 #endif /* HOST_HPPAHPUX */
This page took 0.043467 seconds and 5 git commands to generate.