* section.c (bfd_set_section_contents): whitespacs
[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 #ifdef DL_MAGIC
321 case DL_MAGIC:
322 #endif
323 #ifdef SHL_MAGIC
324 case SHL_MAGIC:
325 #endif
326 break;
327 default:
328 bfd_error = wrong_format;
329 return 0;
330 }
331
332 if (file_hdr.version_id != VERSION_ID
333 && file_hdr.version_id != NEW_VERSION_ID)
334 {
335 bfd_error = wrong_format;
336 return 0;
337 }
338
339 if (bfd_read ((PTR) &aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
340 bfd_error = wrong_format;
341
342 if (!setup_sections (abfd, &file_hdr))
343 return 0;
344
345 return hppa_object_setup(abfd, &file_hdr, &aux_hdr);
346 }
347
348 static boolean
349 DEFUN(hppa_mkobject,(abfd),
350 bfd *abfd)
351 {
352 fprintf (stderr, "hppa_mkobject unimplemented\n");
353 fflush (stderr);
354 abort ();
355 return (false);
356 }
357
358 boolean
359 DEFUN(hppa_write_object_contents,(abfd),
360 bfd *abfd)
361 {
362 fprintf (stderr, "hppa_write_object_contents unimplemented\n");
363 fflush (stderr);
364 abort ();
365 return (false);
366 }
367
368 static unsigned int
369 hppa_get_symtab_upper_bound (abfd)
370 bfd *abfd;
371 {
372 fprintf (stderr, "hppa_get_symtab_upper_bound unimplemented\n");
373 fflush (stderr);
374 abort ();
375 return (0);
376 }
377
378 static unsigned int
379 hppa_get_reloc_upper_bound (abfd, asect)
380 bfd *abfd;
381 sec_ptr asect;
382 {
383 fprintf (stderr, "hppa_get_reloc_upper_bound unimplemented\n");
384 fflush (stderr);
385 abort ();
386 return (0);
387 }
388
389 static unsigned int
390 hppa_canonicalize_reloc (abfd, section, relptr, symbols)
391 bfd *abfd;
392 sec_ptr section;
393 arelent **relptr;
394 asymbol **symbols;
395 {
396 fprintf (stderr, "hppa_canonicalize_reloc unimplemented\n");
397 fflush (stderr);
398 abort ();
399 }
400
401 extern bfd_target hppa_vec;
402
403 static unsigned int
404 hppa_get_symtab (abfd, location)
405 bfd *abfd;
406 asymbol **location;
407 {
408 fprintf (stderr, "hppa_get_symtab unimplemented\n");
409 fflush (stderr);
410 abort ();
411 return (0);
412 }
413
414 static asymbol *
415 hppa_make_empty_symbol (abfd)
416 bfd *abfd;
417 {
418 hppa_symbol_type *new =
419 (hppa_symbol_type *)bfd_zalloc (abfd, sizeof (hppa_symbol_type));
420 new->symbol.the_bfd = abfd;
421
422 return &new->symbol;
423 }
424
425 static void
426 hppa_print_symbol (ignore_abfd, afile, symbol, how)
427 bfd *ignore_abfd;
428 PTR afile;
429 asymbol *symbol;
430 bfd_print_symbol_type how;
431 {
432 fprintf (stderr, "hppa_print_symbol unimplemented\n");
433 fflush (stderr);
434 abort ();
435 }
436
437 static boolean
438 hppa_new_section_hook (abfd, newsect)
439 bfd *abfd;
440 asection *newsect;
441 {
442 newsect->alignment_power = 3;
443
444 /* We allow more than three sections internally */
445 return true;
446 }
447
448 static boolean
449 hppa_set_section_contents (abfd, section, location, offset, count)
450 bfd *abfd;
451 sec_ptr section;
452 PTR location;
453 file_ptr offset;
454 bfd_size_type count;
455 {
456 fprintf (stderr, "hppa_set_section_contents unimplimented\n");
457 fflush (stderr);
458 abort();
459 return false;
460 }
461
462 static boolean
463 hppa_set_arch_mach (abfd, arch, machine)
464 bfd *abfd;
465 enum bfd_architecture arch;
466 unsigned long machine;
467 {
468 fprintf (stderr, "hppa_set_arch_mach unimplemented\n");
469 fflush (stderr);
470 /* Allow any architecture to be supported by the hppa backend */
471 return bfd_default_set_arch_mach(abfd, arch, machine);
472 }
473
474 static boolean
475 hppa_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
476 functionname_ptr, line_ptr)
477 bfd *abfd;
478 asection *section;
479 asymbol **symbols;
480 bfd_vma offset;
481 CONST char **filename_ptr;
482 CONST char **functionname_ptr;
483 unsigned int *line_ptr;
484 {
485 fprintf (stderr, "hppa_find_nearest_line unimplemented\n");
486 fflush (stderr);
487 abort ();
488 return (false);
489 }
490
491 static int
492 hppa_sizeof_headers (abfd, reloc)
493 bfd *abfd;
494 boolean reloc;
495 {
496 fprintf (stderr, "hppa_sizeof_headers unimplemented\n");
497 fflush (stderr);
498 abort ();
499 return (0);
500 }
501
502 static asection *
503 make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power)
504 bfd *abfd;
505 CONST char *name;
506 flagword flags;
507 bfd_size_type _raw_size;
508 bfd_vma vma;
509 unsigned int alignment_power;
510 {
511 asection *asect;
512
513 asect = bfd_make_section (abfd, name);
514 if (!asect)
515 return NULL;
516
517 asect->flags = flags;
518 asect->_raw_size = _raw_size;
519 asect->vma = vma;
520 asect->filepos = bfd_tell (abfd);
521 asect->alignment_power = alignment_power;
522
523 return asect;
524 }
525
526 static bfd_target *
527 hppa_core_file_p (abfd)
528 bfd *abfd;
529 {
530 core_hdr (abfd) = bfd_zalloc (abfd, sizeof (struct hppa_core_struct));
531 if (!core_hdr (abfd))
532 return NULL;
533
534 while (1)
535 {
536 int val;
537 struct corehead core_header;
538
539 val = bfd_read ((void *)&core_header, 1, sizeof core_header, abfd);
540 if (val <= 0)
541 break;
542 switch (core_header.type)
543 {
544 case CORE_KERNEL:
545 case CORE_FORMAT:
546 bfd_seek (abfd, core_header.len, SEEK_CUR); /* Just skip this */
547 break;
548 case CORE_EXEC:
549 {
550 struct proc_exec proc_exec;
551 bfd_read ((void *)&proc_exec, 1, core_header.len, abfd);
552 strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1);
553 }
554 break;
555 case CORE_PROC:
556 {
557 struct proc_info proc_info;
558 core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
559 SEC_ALLOC+SEC_HAS_CONTENTS,
560 core_header.len,
561 (int)&proc_info - (int)&proc_info.hw_regs,
562 2);
563 bfd_read (&proc_info, 1, core_header.len, abfd);
564 core_signal (abfd) = proc_info.sig;
565 }
566 if (!core_regsec (abfd))
567 return NULL;
568 break;
569 case CORE_DATA:
570 core_datasec (abfd) = make_bfd_asection (abfd, ".data",
571 SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
572 core_header.len,
573 core_header.addr,
574 2);
575 if (!core_datasec (abfd))
576 return NULL;
577 bfd_seek (abfd, core_header.len, SEEK_CUR);
578 break;
579 case CORE_STACK:
580 core_stacksec (abfd) = make_bfd_asection (abfd, ".stack",
581 SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
582 core_header.len,
583 core_header.addr,
584 2);
585 if (!core_stacksec (abfd))
586 return NULL;
587 bfd_seek (abfd, core_header.len, SEEK_CUR);
588 break;
589 default:
590 fprintf (stderr, "Unknown HPPA/HPUX core file section type %d\n",
591 core_header.type);
592 bfd_seek (abfd, core_header.len, SEEK_CUR);
593 break;
594 }
595 }
596
597 /* OK, we believe you. You're a core file (sure, sure). */
598
599 return abfd->xvec;
600 }
601
602 static char *
603 hppa_core_file_failing_command (abfd)
604 bfd *abfd;
605 {
606 return core_command (abfd);
607 }
608
609 /* ARGSUSED */
610 static int
611 hppa_core_file_failing_signal (abfd)
612 bfd *abfd;
613 {
614 return core_signal (abfd);
615 }
616
617 /* ARGSUSED */
618 static boolean
619 hppa_core_file_matches_executable_p (core_bfd, exec_bfd)
620 bfd *core_bfd, *exec_bfd;
621 {
622 return true; /* FIXME, We have no way of telling at this point */
623 }
624
625 #define hppa_bfd_debug_info_start bfd_void
626 #define hppa_bfd_debug_info_end bfd_void
627 #define hppa_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
628
629
630
631 #define hppa_openr_next_archived_file bfd_generic_openr_next_archived_file
632 #define hppa_generic_stat_arch_elt bfd_generic_stat_arch_elt
633 #define hppa_slurp_armap bfd_false
634 #define hppa_slurp_extended_name_table _bfd_slurp_extended_name_table
635 #define hppa_truncate_arname (void (*)())bfd_nullvoidptr
636 #define hppa_write_armap 0
637
638 #define hppa_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
639 #define hppa_close_and_cleanup bfd_generic_close_and_cleanup
640 #define hppa_get_section_contents bfd_generic_get_section_contents
641
642 #define hppa_bfd_get_relocated_section_contents \
643 bfd_generic_get_relocated_section_contents
644 #define hppa_bfd_relax_section bfd_generic_relax_section
645 #define hppa_bfd_seclet_link bfd_generic_seclet_link
646 #define hppa_bfd_reloc_type_lookup \
647 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
648 #define hppa_bfd_make_debug_symbol \
649 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
650
651 bfd_target hppa_vec =
652 {
653 "hppa", /* name */
654 bfd_target_hppa_flavour,
655 true, /* target byte order */
656 true, /* target headers byte order */
657 (HAS_RELOC | EXEC_P | /* object flags */
658 HAS_LINENO | HAS_DEBUG |
659 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
660 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
661 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
662
663 /* leading_symbol_char: is the first char of a user symbol
664 predictable, and if so what is it */
665 0,
666 ' ', /* ar_pad_char */
667 16, /* ar_max_namelen */
668 3, /* minimum alignment */
669 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
670 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
671 { _bfd_dummy_target,
672 hppa_object_p, /* bfd_check_format */
673 bfd_generic_archive_p,
674 hppa_core_file_p,
675 },
676 {
677 bfd_false,
678 hppa_mkobject,
679 _bfd_generic_mkarchive,
680 bfd_false
681 },
682 {
683 bfd_false,
684 hppa_write_object_contents,
685 _bfd_write_archive_contents,
686 bfd_false,
687 },
688 #undef hppa
689 JUMP_TABLE(hppa),
690 (PTR) 0
691 };
692
693 #endif /* HOST_HPPAHPUX */
This page took 0.048088 seconds and 4 git commands to generate.