Basically a checkpoint for coff-mips.c.
[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 static bfd_target *
47 hppa_object_setup (abfd, file_hdrp, aux_hdrp)
48 bfd *abfd;
49 struct header *file_hdrp;
50 struct som_exec_auxhdr *aux_hdrp;
51 {
52 struct container *rawptr;
53 struct header *f;
54 struct hppa_data_struct *rawptr1;
55 asection *text, *data, *bss;
56
57 rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
58 if (rawptr == NULL) {
59 bfd_error = no_memory;
60 return 0;
61 }
62
63 rawptr1 = (struct hppa_data_struct *) bfd_zalloc (abfd, sizeof (struct hppa_data_struct));
64 if (rawptr1 == NULL) {
65 bfd_error = no_memory;
66 return 0;
67 }
68
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;
74
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;
81
82 bfd_get_start_address (abfd) = aux_hdrp->exec_entry;
83
84 obj_pa_symbols (abfd) = (hppa_symbol_type *)NULL;
85 bfd_get_symcount (abfd) = file_hdrp->symbol_total;
86
87 bfd_default_set_arch_mach(abfd, bfd_arch_hppa, 0);
88
89 /* create the sections. This is raunchy, but bfd_close wants to reclaim
90 them */
91
92 text = bfd_make_section(abfd, ".text");
93 data = bfd_make_section(abfd, ".data");
94 bss = bfd_make_section(abfd, ".bss");
95
96 text->_raw_size = aux_hdrp->exec_tsize;
97 data->_raw_size = aux_hdrp->exec_dsize;
98 bss->_raw_size = aux_hdrp->exec_bsize;
99
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;
103
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;
108
109 /* The file offsets of the sections */
110 text->filepos = aux_hdrp->exec_tfile;
111 data->filepos = aux_hdrp->exec_dfile;
112
113 /* The file offsets of the relocation info */
114 text->rel_filepos = 0;
115 data->rel_filepos = 0;
116
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;
122
123 return abfd->xvec;
124 }
125
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
129 subroutine.
130 */
131
132 static asection *
133 make_unique_section (abfd, name, num)
134 bfd *abfd;
135 CONST char *name;
136 int num;
137 {
138 asection *sect;
139 char *newname;
140 char altname[100];
141
142 sect = bfd_make_section (abfd, name);
143 while (!sect)
144 {
145 sprintf(altname, "%s-%d", name, num++);
146 sect = bfd_make_section (abfd, altname);
147 }
148
149 newname = bfd_alloc (abfd, strlen(sect->name) + 1);
150 strcpy (newname, sect->name);
151
152 sect->name = newname;
153 return sect;
154 }
155
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. */
161
162 static int
163 setup_sections (abfd, file_hdr)
164 bfd *abfd;
165 struct header *file_hdr;
166 {
167 char *space_strings;
168 int space_index;
169
170 /* First, read in space names */
171
172 space_strings = alloca (file_hdr->space_strings_size);
173 if (!space_strings)
174 return 0;
175
176 if (bfd_seek (abfd, file_hdr->space_strings_location, SEEK_SET) < 0)
177 return 0;
178 if (bfd_read (space_strings, 1, file_hdr->space_strings_size, abfd)
179 != file_hdr->space_strings_size)
180 return 0;
181
182 /* Loop over all of the space dictionaries, building up sections */
183
184 for (space_index = 0; space_index < file_hdr->space_total; space_index++)
185 {
186 struct space_dictionary_record space;
187 struct subspace_dictionary_record subspace;
188 int subspace_index, tmp;
189 asection *space_asect;
190
191 /* Read the space dictionary element */
192 if (bfd_seek (abfd, file_hdr->space_location
193 + space_index * sizeof space, SEEK_SET) < 0)
194 return 0;
195 if (bfd_read (&space, 1, sizeof space, abfd) != sizeof space)
196 return 0;
197
198 /* Setup the space name string */
199 space.name.n_name = space.name.n_strx + space_strings;
200
201 /* Make a section out of it */
202 space_asect = make_unique_section (abfd, space.name.n_name, space_index);
203 if (!space_asect)
204 return 0;
205
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,
209 SEEK_SET) < 0)
210 return 0;
211 if (bfd_read (&subspace, 1, sizeof subspace, abfd) != sizeof subspace)
212 return 0;
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,
216 SEEK_SET) < 0)
217 return 0;
218
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;
226
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;
231
232 /* Loop over the rest of the subspaces, building up more sections */
233 for (subspace_index = 0; subspace_index < space.subspace_quantity;
234 subspace_index++)
235 {
236 asection *subspace_asect;
237
238 /* Read in the next subspace */
239 if (bfd_read (&subspace, 1, sizeof subspace, abfd)
240 != sizeof subspace)
241 return 0;
242
243 /* Setup the subspace name string */
244 subspace.name.n_name = subspace.name.n_strx + space_strings;
245
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);
249
250 if (!subspace_asect)
251 return 0;
252
253 if (subspace.is_loadable)
254 subspace_asect->flags |= SEC_ALLOC | SEC_LOAD;
255 if (subspace.code_only)
256 subspace_asect->flags |= SEC_CODE;
257
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;
263
264 }
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;
272 }
273 }
274
275 static bfd_target *
276 hppa_object_p (abfd)
277 bfd *abfd;
278 {
279 struct header file_hdr;
280 struct som_exec_auxhdr aux_hdr;
281
282 if (bfd_read ((PTR) &file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
283 return 0;
284
285 if (!_PA_RISC_ID (file_hdr.system_id))
286 {
287 bfd_error = wrong_format;
288 return 0;
289 }
290
291 switch (file_hdr.a_magic)
292 {
293 case RELOC_MAGIC: /* I'm not really sure about all of these types... */
294 case EXEC_MAGIC:
295 case SHARE_MAGIC:
296 case DEMAND_MAGIC:
297 case DL_MAGIC:
298 case SHL_MAGIC:
299 break;
300 default:
301 bfd_error = wrong_format;
302 return 0;
303 }
304
305 if (file_hdr.version_id != VERSION_ID
306 && file_hdr.version_id != NEW_VERSION_ID)
307 {
308 bfd_error = wrong_format;
309 return 0;
310 }
311
312 if (bfd_read ((PTR) &aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
313 bfd_error = wrong_format;
314
315 if (!setup_sections (abfd, &file_hdr))
316 return 0;
317
318 return hppa_object_setup(abfd, &file_hdr, &aux_hdr);
319 }
320
321 static boolean
322 DEFUN(hppa_mkobject,(abfd),
323 bfd *abfd)
324 {
325 fprintf (stderr, "hppa_mkobject unimplemented\n");
326 fflush (stderr);
327 abort ();
328 return (false);
329 }
330
331 boolean
332 DEFUN(hppa_write_object_contents,(abfd),
333 bfd *abfd)
334 {
335 fprintf (stderr, "hppa_write_object_contents unimplemented\n");
336 fflush (stderr);
337 abort ();
338 return (false);
339 }
340
341 static unsigned int
342 hppa_get_symtab_upper_bound (abfd)
343 bfd *abfd;
344 {
345 fprintf (stderr, "hppa_get_symtab_upper_bound unimplemented\n");
346 fflush (stderr);
347 abort ();
348 return (0);
349 }
350
351 static unsigned int
352 hppa_get_reloc_upper_bound (abfd, asect)
353 bfd *abfd;
354 sec_ptr asect;
355 {
356 fprintf (stderr, "hppa_get_reloc_upper_bound unimplemented\n");
357 fflush (stderr);
358 abort ();
359 return (0);
360 }
361
362 static unsigned int
363 hppa_canonicalize_reloc (abfd, section, relptr, symbols)
364 bfd *abfd;
365 sec_ptr section;
366 arelent **relptr;
367 asymbol **symbols;
368 {
369 fprintf (stderr, "hppa_canonicalize_reloc unimplemented\n");
370 fflush (stderr);
371 abort ();
372 }
373
374 extern bfd_target hppa_vec;
375
376 static unsigned int
377 hppa_get_symtab (abfd, location)
378 bfd *abfd;
379 asymbol **location;
380 {
381 fprintf (stderr, "hppa_get_symtab unimplemented\n");
382 fflush (stderr);
383 abort ();
384 return (0);
385 }
386
387 static asymbol *
388 hppa_make_empty_symbol (abfd)
389 bfd *abfd;
390 {
391 hppa_symbol_type *new =
392 (hppa_symbol_type *)bfd_zalloc (abfd, sizeof (hppa_symbol_type));
393 new->symbol.the_bfd = abfd;
394
395 return &new->symbol;
396 }
397
398 static void
399 hppa_print_symbol (ignore_abfd, afile, symbol, how)
400 bfd *ignore_abfd;
401 PTR afile;
402 asymbol *symbol;
403 bfd_print_symbol_type how;
404 {
405 fprintf (stderr, "hppa_print_symbol unimplemented\n");
406 fflush (stderr);
407 abort ();
408 }
409
410 static boolean
411 hppa_new_section_hook (abfd, newsect)
412 bfd *abfd;
413 asection *newsect;
414 {
415 newsect->alignment_power = 3;
416
417 /* We allow more than three sections internally */
418 return true;
419 }
420
421 static boolean
422 hppa_set_section_contents (abfd, section, location, offset, count)
423 bfd *abfd;
424 sec_ptr section;
425 PTR location;
426 file_ptr offset;
427 bfd_size_type count;
428 {
429 fprintf (stderr, "hppa_set_section_contents unimplimented\n");
430 fflush (stderr);
431 abort();
432 return false;
433 }
434
435 static boolean
436 hppa_set_arch_mach (abfd, arch, machine)
437 bfd *abfd;
438 enum bfd_architecture arch;
439 unsigned long machine;
440 {
441 fprintf (stderr, "hppa_set_arch_mach unimplemented\n");
442 fflush (stderr);
443 /* Allow any architecture to be supported by the hppa backend */
444 return bfd_default_set_arch_mach(abfd, arch, machine);
445 }
446
447 static boolean
448 hppa_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
449 functionname_ptr, line_ptr)
450 bfd *abfd;
451 asection *section;
452 asymbol **symbols;
453 bfd_vma offset;
454 CONST char **filename_ptr;
455 CONST char **functionname_ptr;
456 unsigned int *line_ptr;
457 {
458 fprintf (stderr, "hppa_find_nearest_line unimplemented\n");
459 fflush (stderr);
460 abort ();
461 return (false);
462 }
463
464 static int
465 hppa_sizeof_headers (abfd, reloc)
466 bfd *abfd;
467 boolean reloc;
468 {
469 fprintf (stderr, "hppa_sizeof_headers unimplemented\n");
470 fflush (stderr);
471 abort ();
472 return (0);
473 }
474
475 static asection *
476 make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power)
477 bfd *abfd;
478 CONST char *name;
479 flagword flags;
480 bfd_size_type _raw_size;
481 bfd_vma vma;
482 unsigned int alignment_power;
483 {
484 asection *asect;
485
486 asect = bfd_make_section (abfd, name);
487 if (!asect)
488 return NULL;
489
490 asect->flags = flags;
491 asect->_raw_size = _raw_size;
492 asect->vma = vma;
493 asect->filepos = bfd_tell (abfd);
494 asect->alignment_power = alignment_power;
495
496 return asect;
497 }
498
499 static bfd_target *
500 hppa_core_file_p (abfd)
501 bfd *abfd;
502 {
503 core_hdr (abfd) = bfd_zalloc (abfd, sizeof (struct hppa_core_struct));
504 if (!core_hdr (abfd))
505 return NULL;
506
507 while (1)
508 {
509 int val;
510 struct corehead core_header;
511
512 val = bfd_read ((void *)&core_header, 1, sizeof core_header, abfd);
513 if (val <= 0)
514 break;
515 switch (core_header.type)
516 {
517 case CORE_KERNEL:
518 case CORE_FORMAT:
519 bfd_seek (abfd, core_header.len, SEEK_CUR); /* Just skip this */
520 break;
521 case CORE_EXEC:
522 {
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);
526 }
527 break;
528 case CORE_PROC:
529 {
530 struct proc_info proc_info;
531 core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
532 SEC_ALLOC+SEC_HAS_CONTENTS,
533 core_header.len,
534 (int)&proc_info - (int)&proc_info.hw_regs,
535 2);
536 bfd_read (&proc_info, 1, core_header.len, abfd);
537 core_signal (abfd) = proc_info.sig;
538 }
539 if (!core_regsec (abfd))
540 return NULL;
541 break;
542 case CORE_DATA:
543 core_datasec (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_datasec (abfd))
549 return NULL;
550 bfd_seek (abfd, core_header.len, SEEK_CUR);
551 break;
552 case CORE_STACK:
553 core_stacksec (abfd) = make_bfd_asection (abfd, ".stack",
554 SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
555 core_header.len,
556 core_header.addr,
557 2);
558 if (!core_stacksec (abfd))
559 return NULL;
560 bfd_seek (abfd, core_header.len, SEEK_CUR);
561 break;
562 default:
563 fprintf (stderr, "Unknown HPPA/HPUX core file section type %d\n",
564 core_header.type);
565 bfd_seek (abfd, core_header.len, SEEK_CUR);
566 break;
567 }
568 }
569
570 /* OK, we believe you. You're a core file (sure, sure). */
571
572 return abfd->xvec;
573 }
574
575 static char *
576 hppa_core_file_failing_command (abfd)
577 bfd *abfd;
578 {
579 return core_command (abfd);
580 }
581
582 /* ARGSUSED */
583 static int
584 hppa_core_file_failing_signal (abfd)
585 bfd *abfd;
586 {
587 return core_signal (abfd);
588 }
589
590 /* ARGSUSED */
591 static boolean
592 hppa_core_file_matches_executable_p (core_bfd, exec_bfd)
593 bfd *core_bfd, *exec_bfd;
594 {
595 return true; /* FIXME, We have no way of telling at this point */
596 }
597
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
601
602
603
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
610
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
614
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
619
620 bfd_target hppa_vec =
621 {
622 "hppa", /* name */
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 */
631
632 /* leading_symbol_char: is the first char of a user symbol
633 predictable, and if so what is it */
634 0,
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 */
640 { _bfd_dummy_target,
641 hppa_object_p, /* bfd_check_format */
642 bfd_generic_archive_p,
643 hppa_core_file_p,
644 },
645 {
646 bfd_false,
647 hppa_mkobject,
648 _bfd_generic_mkarchive,
649 bfd_false
650 },
651 {
652 bfd_false,
653 hppa_write_object_contents,
654 _bfd_write_archive_contents,
655 bfd_false,
656 },
657 #undef hppa
658 JUMP_TABLE(hppa)
659 };
660
661 #endif /* HOST_HPPAHPUX */
This page took 0.042768 seconds and 4 git commands to generate.