* hppa.c [HOST_HPPABSD]: Use hpux-style core files.
[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 /* @@FIXME This is not a reasonable set of conditions to permit
27 cross-compilation, obviously. It also isn't enough to support hppa-elf
28 targets either. Can we eliminate the HPUX or BSD dependencies, or
29 at least get the conditionals more localized? */
30 #if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD)
31
32 #include "libbfd.h"
33 #include "libhppa.h"
34
35 #include <stdio.h>
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/dir.h>
39 #include <signal.h>
40 #include <machine/reg.h>
41 #include <sys/user.h> /* After a.out.h */
42 #include <sys/file.h>
43 #include <errno.h>
44
45 /* Magic not defined in standard HP-UX header files until 8.0 */
46
47 #ifndef CPU_PA_RISC1_0
48 #define CPU_PA_RISC1_0 0x20B
49 #endif /* CPU_PA_RISC1_0 */
50
51 #ifndef CPU_PA_RISC1_1
52 #define CPU_PA_RISC1_1 0x210
53 #endif /* CPU_PA_RISC1_1 */
54
55 #ifndef _PA_RISC1_0_ID
56 #define _PA_RISC1_0_ID CPU_PA_RISC1_0
57 #endif /* _PA_RISC1_0_ID */
58
59 #ifndef _PA_RISC1_1_ID
60 #define _PA_RISC1_1_ID CPU_PA_RISC1_1
61 #endif /* _PA_RISC1_1_ID */
62
63 #ifndef _PA_RISC_MAXID
64 #define _PA_RISC_MAXID 0x2FF
65 #endif /* _PA_RISC_MAXID */
66
67 #ifndef _PA_RISC_ID
68 #define _PA_RISC_ID(__m_num) \
69 (((__m_num) == _PA_RISC1_0_ID) || \
70 ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID))
71 #endif /* _PA_RISC_ID */
72
73 struct container
74 {
75 struct header f;
76 struct som_exec_auxhdr e;
77 };
78
79 static bfd_target *
80 hppa_object_setup (abfd, file_hdrp, aux_hdrp)
81 bfd *abfd;
82 struct header *file_hdrp;
83 struct som_exec_auxhdr *aux_hdrp;
84 {
85 struct container *rawptr;
86 struct header *f;
87 struct hppa_data_struct *rawptr1;
88 asection *text, *data, *bss;
89
90 rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
91 if (rawptr == NULL)
92 {
93 bfd_error = no_memory;
94 return 0;
95 }
96
97 rawptr1 = (struct hppa_data_struct *) bfd_zalloc (abfd, sizeof (struct hppa_data_struct));
98 if (rawptr1 == NULL)
99 {
100 bfd_error = no_memory;
101 return 0;
102 }
103
104 abfd->tdata.hppa_data = rawptr1;
105 obj_file_hdr (abfd) = &rawptr->f;
106 obj_aux_hdr (abfd) = &rawptr->e;
107 *obj_file_hdr (abfd) = *file_hdrp;
108 *obj_aux_hdr (abfd) = *aux_hdrp;
109
110 /* Set the file flags */
111 abfd->flags = NO_FLAGS;
112 if (file_hdrp->entry_offset)
113 abfd->flags |= HAS_RELOC;
114 if (file_hdrp->symbol_total)
115 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
116
117 bfd_get_start_address (abfd) = aux_hdrp->exec_entry;
118
119 obj_pa_symbols (abfd) = (hppa_symbol_type *) NULL;
120 bfd_get_symcount (abfd) = file_hdrp->symbol_total;
121
122 bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 0);
123
124 /* create the sections. This is raunchy, but bfd_close wants to reclaim
125 them */
126
127 text = bfd_make_section (abfd, ".text");
128 data = bfd_make_section (abfd, ".data");
129 bss = bfd_make_section (abfd, ".bss");
130
131 text->_raw_size = aux_hdrp->exec_tsize;
132 data->_raw_size = aux_hdrp->exec_dsize;
133 bss->_raw_size = aux_hdrp->exec_bsize;
134
135 text->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS);
136 data->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS);
137 bss->flags = SEC_ALLOC;
138
139 /* The virtual memory addresses of the sections */
140 text->vma = aux_hdrp->exec_tmem;
141 data->vma = aux_hdrp->exec_dmem;
142 bss->vma = aux_hdrp->exec_bfill;
143
144 /* The file offsets of the sections */
145 text->filepos = aux_hdrp->exec_tfile;
146 data->filepos = aux_hdrp->exec_dfile;
147
148 /* The file offsets of the relocation info */
149 text->rel_filepos = 0;
150 data->rel_filepos = 0;
151
152 /* The file offsets of the string table and symbol table. */
153 obj_sym_filepos (abfd) = file_hdrp->symbol_location;
154 bfd_get_symcount (abfd) = file_hdrp->symbol_total;
155 obj_str_filepos (abfd) = file_hdrp->symbol_strings_location;
156 obj_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
157
158 return abfd->xvec;
159 }
160
161 /* Create a new BFD section for NAME. If NAME already exists, then create a
162 new unique name, with NAME as the prefix. This exists because SOM .o files
163 created by the native compiler can have a $CODE$ section for each
164 subroutine.
165 */
166
167 static asection *
168 make_unique_section (abfd, name, num)
169 bfd *abfd;
170 CONST char *name;
171 int num;
172 {
173 asection *sect;
174 char *newname;
175 char altname[100];
176
177 sect = bfd_make_section (abfd, name);
178 while (!sect)
179 {
180 sprintf (altname, "%s-%d", name, num++);
181 sect = bfd_make_section (abfd, altname);
182 }
183
184 newname = bfd_alloc (abfd, strlen (sect->name) + 1);
185 strcpy (newname, sect->name);
186
187 sect->name = newname;
188 return sect;
189 }
190
191 /* Convert all of the space and subspace info into BFD sections. Each space
192 contains a number of subspaces, which in turn describe the mapping between
193 regions of the exec file, and the address space that the program runs in.
194 BFD sections which correspond to spaces will overlap the sections for the
195 associated subspaces. */
196
197 static int
198 setup_sections (abfd, file_hdr)
199 bfd *abfd;
200 struct header *file_hdr;
201 {
202 char *space_strings;
203 int space_index;
204
205 /* First, read in space names */
206
207 space_strings = alloca (file_hdr->space_strings_size);
208 if (!space_strings)
209 return 0;
210
211 if (bfd_seek (abfd, file_hdr->space_strings_location, SEEK_SET) < 0)
212 return 0;
213 if (bfd_read (space_strings, 1, file_hdr->space_strings_size, abfd)
214 != file_hdr->space_strings_size)
215 return 0;
216
217 /* Loop over all of the space dictionaries, building up sections */
218
219 for (space_index = 0; space_index < file_hdr->space_total; space_index++)
220 {
221 struct space_dictionary_record space;
222 struct subspace_dictionary_record subspace;
223 int subspace_index, tmp;
224 asection *space_asect;
225
226 /* Read the space dictionary element */
227 if (bfd_seek (abfd, file_hdr->space_location
228 + space_index * sizeof space, SEEK_SET) < 0)
229 return 0;
230 if (bfd_read (&space, 1, sizeof space, abfd) != sizeof space)
231 return 0;
232
233 /* Setup the space name string */
234 space.name.n_name = space.name.n_strx + space_strings;
235
236 /* Make a section out of it */
237 space_asect = make_unique_section (abfd, space.name.n_name, space_index);
238 if (!space_asect)
239 return 0;
240
241 /* Now, read in the first subspace for this space */
242 if (bfd_seek (abfd, file_hdr->subspace_location
243 + space.subspace_index * sizeof subspace,
244 SEEK_SET) < 0)
245 return 0;
246 if (bfd_read (&subspace, 1, sizeof subspace, abfd) != sizeof subspace)
247 return 0;
248 /* Seek back to the start of the subspaces for loop below */
249 if (bfd_seek (abfd, file_hdr->subspace_location
250 + space.subspace_index * sizeof subspace,
251 SEEK_SET) < 0)
252 return 0;
253
254 /* Setup the section flags as appropriate (this is somewhat bogus, as
255 there isn't a clear mapping between what's in the space record, and
256 what BFD can describe here). */
257 if (space.is_loadable)
258 space_asect->flags |= SEC_ALLOC;
259 if (space.is_defined)
260 space_asect->flags |= SEC_LOAD;
261
262 /* Setup the start address and file loc from the first subspace record */
263 space_asect->vma = subspace.subspace_start;
264 space_asect->filepos = subspace.file_loc_init_value;
265 space_asect->alignment_power = subspace.alignment;
266
267 /* Loop over the rest of the subspaces, building up more sections */
268 for (subspace_index = 0; subspace_index < space.subspace_quantity;
269 subspace_index++)
270 {
271 asection *subspace_asect;
272
273 /* Read in the next subspace */
274 if (bfd_read (&subspace, 1, sizeof subspace, abfd)
275 != sizeof subspace)
276 return 0;
277
278 /* Setup the subspace name string */
279 subspace.name.n_name = subspace.name.n_strx + space_strings;
280
281 /* Make a section out of this subspace */
282 subspace_asect = make_unique_section (abfd, subspace.name.n_name,
283 space.subspace_index + subspace_index);
284
285 if (!subspace_asect)
286 return 0;
287
288 if (subspace.is_loadable)
289 subspace_asect->flags |= SEC_ALLOC | SEC_LOAD;
290 if (subspace.code_only)
291 subspace_asect->flags |= SEC_CODE;
292
293 subspace_asect->vma = subspace.subspace_start;
294 subspace_asect->_cooked_size = subspace.subspace_length;
295 subspace_asect->_raw_size = subspace.initialization_length;
296 subspace_asect->alignment_power = subspace.alignment;
297 subspace_asect->filepos = subspace.file_loc_init_value;
298
299 }
300 /* Setup the sizes for the space section based upon the info in the
301 last subspace of the space. */
302 space_asect->_cooked_size = (subspace.subspace_start - space_asect->vma)
303 + subspace.subspace_length;
304 space_asect->_raw_size = (subspace.file_loc_init_value
305 - space_asect->filepos)
306 + subspace.initialization_length;
307 }
308 }
309
310 static bfd_target *
311 hppa_object_p (abfd)
312 bfd *abfd;
313 {
314 struct header file_hdr;
315 struct som_exec_auxhdr aux_hdr;
316
317 if (bfd_read ((PTR) & file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
318 return 0;
319
320 if (!_PA_RISC_ID (file_hdr.system_id))
321 {
322 bfd_error = wrong_format;
323 return 0;
324 }
325
326 switch (file_hdr.a_magic)
327 {
328 case RELOC_MAGIC: /* I'm not really sure about all of these types... */
329 case EXEC_MAGIC:
330 case SHARE_MAGIC:
331 case DEMAND_MAGIC:
332 #ifdef DL_MAGIC
333 case DL_MAGIC:
334 #endif
335 #ifdef SHL_MAGIC
336 case SHL_MAGIC:
337 #endif
338 break;
339 default:
340 bfd_error = wrong_format;
341 return 0;
342 }
343
344 if (file_hdr.version_id != VERSION_ID
345 && file_hdr.version_id != NEW_VERSION_ID)
346 {
347 bfd_error = wrong_format;
348 return 0;
349 }
350
351 if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
352 bfd_error = wrong_format;
353
354 if (!setup_sections (abfd, &file_hdr))
355 return 0;
356
357 return hppa_object_setup (abfd, &file_hdr, &aux_hdr);
358 }
359
360 static boolean
361 hppa_mkobject (abfd)
362 bfd *abfd;
363 {
364 fprintf (stderr, "hppa_mkobject unimplemented\n");
365 fflush (stderr);
366 abort ();
367 return (false);
368 }
369
370 boolean
371 hppa_write_object_contents(abfd)
372 bfd *abfd;
373 {
374 fprintf (stderr, "hppa_write_object_contents unimplemented\n");
375 fflush (stderr);
376 abort ();
377 return (false);
378 }
379
380 static unsigned int
381 hppa_get_symtab_upper_bound (abfd)
382 bfd *abfd;
383 {
384 fprintf (stderr, "hppa_get_symtab_upper_bound unimplemented\n");
385 fflush (stderr);
386 abort ();
387 return (0);
388 }
389
390 static unsigned int
391 hppa_get_reloc_upper_bound (abfd, asect)
392 bfd *abfd;
393 sec_ptr asect;
394 {
395 fprintf (stderr, "hppa_get_reloc_upper_bound unimplemented\n");
396 fflush (stderr);
397 abort ();
398 return (0);
399 }
400
401 static unsigned int
402 hppa_canonicalize_reloc (abfd, section, relptr, symbols)
403 bfd *abfd;
404 sec_ptr section;
405 arelent **relptr;
406 asymbol **symbols;
407 {
408 fprintf (stderr, "hppa_canonicalize_reloc unimplemented\n");
409 fflush (stderr);
410 abort ();
411 }
412
413 extern bfd_target hppa_vec;
414
415 static unsigned int
416 hppa_get_symtab (abfd, location)
417 bfd *abfd;
418 asymbol **location;
419 {
420 fprintf (stderr, "hppa_get_symtab unimplemented\n");
421 fflush (stderr);
422 abort ();
423 return (0);
424 }
425
426 static asymbol *
427 hppa_make_empty_symbol (abfd)
428 bfd *abfd;
429 {
430 hppa_symbol_type *new =
431 (hppa_symbol_type *) bfd_zalloc (abfd, sizeof (hppa_symbol_type));
432 new->symbol.the_bfd = abfd;
433
434 return &new->symbol;
435 }
436
437 static void
438 hppa_print_symbol (ignore_abfd, afile, symbol, how)
439 bfd *ignore_abfd;
440 PTR afile;
441 asymbol *symbol;
442 bfd_print_symbol_type how;
443 {
444 fprintf (stderr, "hppa_print_symbol unimplemented\n");
445 fflush (stderr);
446 abort ();
447 }
448
449 static boolean
450 hppa_new_section_hook (abfd, newsect)
451 bfd *abfd;
452 asection *newsect;
453 {
454 newsect->alignment_power = 3;
455
456 /* We allow more than three sections internally */
457 return true;
458 }
459
460 static boolean
461 hppa_set_section_contents (abfd, section, location, offset, count)
462 bfd *abfd;
463 sec_ptr section;
464 PTR location;
465 file_ptr offset;
466 bfd_size_type count;
467 {
468 fprintf (stderr, "hppa_set_section_contents unimplimented\n");
469 fflush (stderr);
470 abort ();
471 return false;
472 }
473
474 static boolean
475 hppa_set_arch_mach (abfd, arch, machine)
476 bfd *abfd;
477 enum bfd_architecture arch;
478 unsigned long machine;
479 {
480 fprintf (stderr, "hppa_set_arch_mach unimplemented\n");
481 fflush (stderr);
482 /* Allow any architecture to be supported by the hppa backend */
483 return bfd_default_set_arch_mach (abfd, arch, machine);
484 }
485
486 static boolean
487 hppa_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
488 functionname_ptr, line_ptr)
489 bfd *abfd;
490 asection *section;
491 asymbol **symbols;
492 bfd_vma offset;
493 CONST char **filename_ptr;
494 CONST char **functionname_ptr;
495 unsigned int *line_ptr;
496 {
497 fprintf (stderr, "hppa_find_nearest_line unimplemented\n");
498 fflush (stderr);
499 abort ();
500 return (false);
501 }
502
503 static int
504 hppa_sizeof_headers (abfd, reloc)
505 bfd *abfd;
506 boolean reloc;
507 {
508 fprintf (stderr, "hppa_sizeof_headers unimplemented\n");
509 fflush (stderr);
510 abort ();
511 return (0);
512 }
513
514 static asection *
515 make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power)
516 bfd *abfd;
517 CONST char *name;
518 flagword flags;
519 bfd_size_type _raw_size;
520 bfd_vma vma;
521 unsigned int alignment_power;
522 {
523 asection *asect;
524
525 asect = bfd_make_section (abfd, name);
526 if (!asect)
527 return NULL;
528
529 asect->flags = flags;
530 asect->_raw_size = _raw_size;
531 asect->vma = vma;
532 asect->filepos = bfd_tell (abfd);
533 asect->alignment_power = alignment_power;
534
535 return asect;
536 }
537
538 #if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD)
539 /* This requires system include files. */
540
541 static bfd_target *
542 hppa_core_file_p (abfd)
543 bfd *abfd;
544 {
545 core_hdr (abfd) = bfd_zalloc (abfd, sizeof (struct hppa_core_struct));
546 if (!core_hdr (abfd))
547 return NULL;
548
549 while (1)
550 {
551 int val;
552 struct corehead core_header;
553
554 val = bfd_read ((void *) &core_header, 1, sizeof core_header, abfd);
555 if (val <= 0)
556 break;
557 switch (core_header.type)
558 {
559 case CORE_KERNEL:
560 case CORE_FORMAT:
561 bfd_seek (abfd, core_header.len, SEEK_CUR); /* Just skip this */
562 break;
563 case CORE_EXEC:
564 {
565 struct proc_exec proc_exec;
566 bfd_read ((void *) &proc_exec, 1, core_header.len, abfd);
567 strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1);
568 }
569 break;
570 case CORE_PROC:
571 {
572 struct proc_info proc_info;
573 core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
574 SEC_ALLOC + SEC_HAS_CONTENTS,
575 core_header.len,
576 (int) &proc_info - (int) &proc_info.hw_regs,
577 2);
578 bfd_read (&proc_info, 1, core_header.len, abfd);
579 core_signal (abfd) = proc_info.sig;
580 }
581 if (!core_regsec (abfd))
582 return NULL;
583 break;
584 case CORE_DATA:
585 core_datasec (abfd) = make_bfd_asection (abfd, ".data",
586 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
587 core_header.len,
588 core_header.addr,
589 2);
590 if (!core_datasec (abfd))
591 return NULL;
592 bfd_seek (abfd, core_header.len, SEEK_CUR);
593 break;
594 case CORE_STACK:
595 core_stacksec (abfd) = make_bfd_asection (abfd, ".stack",
596 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
597 core_header.len,
598 core_header.addr,
599 2);
600 if (!core_stacksec (abfd))
601 return NULL;
602 bfd_seek (abfd, core_header.len, SEEK_CUR);
603 break;
604 default:
605 fprintf (stderr, "Unknown HPPA/HPUX core file section type %d\n",
606 core_header.type);
607 bfd_seek (abfd, core_header.len, SEEK_CUR);
608 break;
609 }
610 }
611
612 /* OK, we believe you. You're a core file (sure, sure). */
613
614 return abfd->xvec;
615 }
616
617 static char *
618 hppa_core_file_failing_command (abfd)
619 bfd *abfd;
620 {
621 return core_command (abfd);
622 }
623
624 /* ARGSUSED */
625 static int
626 hppa_core_file_failing_signal (abfd)
627 bfd *abfd;
628 {
629 return core_signal (abfd);
630 }
631
632 /* ARGSUSED */
633 static boolean
634 hppa_core_file_matches_executable_p (core_bfd, exec_bfd)
635 bfd *core_bfd, *exec_bfd;
636 {
637 return true; /* FIXME, We have no way of telling at this point */
638 }
639
640 #endif /* HPUX or BSD. */
641
642 /* Miscellaneous Support Functions -- Control Structures and Functions
643 for the PA. */
644
645 unsigned int
646 assemble_3 (x)
647 unsigned int x;
648 {
649 return (((x & 1) << 2) | ((x & 6) >> 1)) & 7;
650 }
651
652 void
653 dis_assemble_3 (x, r)
654 unsigned int x;
655 unsigned int *r;
656 {
657 *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7;
658 }
659
660 unsigned int
661 assemble_12 (x, y)
662 unsigned int x, y;
663 {
664 return (((y & 1) << 11) | ((x & 1) << 10) | ((x & 0x7fe) >> 1)) & 0xfff;
665 }
666
667 void
668 dis_assemble_12 (as12, x, y)
669 unsigned int as12;
670 unsigned int *x, *y;
671 {
672 *y = (as12 & 0x800) >> 11;
673 *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10);
674 }
675
676 unsigned long
677 assemble_17 (x, y, z)
678 unsigned int x, y, z;
679 {
680 unsigned long temp;
681
682 temp = ((z & 1) << 16) |
683 ((x & 0x1f) << 11) |
684 ((y & 1) << 10) |
685 ((y & 0x7fe) >> 1);
686 return temp & 0x1ffff;
687 }
688
689 void
690 dis_assemble_17 (as17, x, y, z)
691 unsigned int as17;
692 unsigned int *x, *y, *z;
693 {
694
695 *z = (as17 & 0x10000) >> 16;
696 *x = (as17 & 0x0f800) >> 11;
697 *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff;
698 }
699
700 unsigned long
701 assemble_21 (x)
702 unsigned int x;
703 {
704 unsigned long temp;
705
706 temp = ((x & 1) << 20) |
707 ((x & 0xffe) << 8) |
708 ((x & 0xc000) >> 7) |
709 ((x & 0x1f0000) >> 14) |
710 ((x & 0x003000) >> 12);
711 return temp & 0x1fffff;
712 }
713
714 void
715 dis_assemble_21 (as21, x)
716 unsigned int as21, *x;
717 {
718 unsigned long temp;
719
720
721 temp = (as21 & 0x100000) >> 20;
722 temp |= (as21 & 0x0ffe00) >> 8;
723 temp |= (as21 & 0x000180) << 7;
724 temp |= (as21 & 0x00007c) << 14;
725 temp |= (as21 & 0x000003) << 12;
726 *x = temp;
727 }
728
729 #if 0
730 unsigned long
731 sign_ext (x, len)
732 unsigned int x, len;
733 {
734 unsigned int sign;
735 unsigned int result;
736 unsigned int len_ones;
737 int i;
738
739 i = 0;
740 len_ones = 0;
741 while (i < len)
742 {
743 len_ones = (len_ones << 1) | 1;
744 i++;
745 }
746
747 sign = (x >> (len - 1)) & 1;
748
749 if (sign)
750 result = (~0 ^ len_ones) | (len_ones & x);
751 else
752 result = len_ones & x;
753
754 return result;
755 }
756
757 #endif
758 static unsigned long
759 sign_ext (x, len)
760 unsigned int x, len;
761 {
762 return (x << (32 - len)) >> (32 - len);
763 }
764
765 static unsigned int
766 ones (n)
767 int n;
768 {
769 unsigned int len_ones;
770 int i;
771
772 i = 0;
773 len_ones = 0;
774 while (i < n)
775 {
776 len_ones = (len_ones << 1) | 1;
777 i++;
778 }
779
780 return len_ones;
781 }
782
783 void
784 sign_unext (x, len, result)
785 unsigned int x, len;
786 unsigned int *result;
787 {
788 unsigned int len_ones;
789
790 len_ones = ones (len);
791
792 *result = x & len_ones;
793 }
794
795 unsigned long
796 low_sign_ext (x, len)
797 unsigned int x, len;
798 {
799 unsigned int temp1, temp2;
800 unsigned int len_ones;
801
802 len_ones = ones (len);
803
804 temp1 = (x & 1) << (len - 1);
805 temp2 = ((x & 0xfffffffe) & len_ones) >> 1;
806 return sign_ext ((temp1 | temp2), len);
807 }
808
809 void
810 low_sign_unext (x, len, result)
811 unsigned int x, len;
812 unsigned int *result;
813 {
814 unsigned int temp;
815 unsigned int sign;
816 unsigned int rest;
817 unsigned int one_bit_at_len;
818 unsigned int len_ones;
819
820 len_ones = ones (len);
821 one_bit_at_len = 1 << (len - 1);
822
823 sign_unext (x, len, &temp);
824 sign = temp & one_bit_at_len;
825 sign >>= (len - 1);
826
827 rest = temp & (len_ones ^ one_bit_at_len);
828 rest <<= 1;
829
830 *result = rest | sign;
831 }
832
833 /* These work when 'y' is a power of two only. */
834
835 static long
836 round_down (x, y)
837 long x, y;
838 {
839 return x & ~(y - 1);
840 }
841
842 static long
843 round (x, y)
844 long x, y;
845 {
846 return (x + y / 2) & ~(y - 1);
847 }
848
849 static long
850 round_up (x, y)
851 long x, y;
852 {
853 return x - (x | ~(y - 1));
854 }
855
856 /* L(Symbol, Addend): */
857 /* round_down (Symbol + Addend, 2048) */
858
859 static long
860 L (Symbol, Addend)
861 {
862 return (round_down (Symbol + Addend, 2048)) >> 11;
863 }
864
865 /* R(Symbol, Addend): */
866 /* Symbol + Addend - round_down (Symbol + Addend, 2048) */
867
868 static long
869 R (Symbol, Addend)
870 {
871 return Symbol + Addend - round_down (Symbol + Addend, 2048);
872 }
873
874 /* LS(Symbol, Addend): */
875 /* round (Symbol + Addend, 2048) */
876
877 static long
878 LS (Symbol, Addend)
879 {
880 return round (Symbol + Addend, 2048);
881 }
882
883 /* RS(Symbol, Addend): */
884 /* Symbol + Addend - round (Symbol + Addend, 2048) */
885
886 static long
887 RS (Symbol, Addend)
888 {
889 return Symbol + Addend - round (Symbol + Addend, 2048);
890 }
891
892 /* LD(Symbol, Addend): */
893 /* round_up (Symbol + Addend, 2048) */
894
895 static long
896 LD (Symbol, Addend)
897 {
898 return (round_up (Symbol + Addend, 2048)) >> 11;
899 }
900
901 /* RD(Symbol, Addend): */
902 /* Symbol + Addend - round_up (Symbol + Addend, 2048) */
903
904 static long
905 RD (Symbol, Addend)
906 {
907 return Symbol + Addend - round_up (Symbol + Addend, 2048);
908 }
909
910 /* LR(Symbol, Addend): */
911 /* round_down (Symbol, 2048) + round (Addend, 8192) */
912
913 static long
914 LR (Symbol, Addend)
915 {
916 return (round_down (Symbol, 2048) + round (Addend, 8192)) >> 11;
917 }
918
919 /* RR(Symbol, Addend): */
920 /* Symbol - round_down (Symbol, 2048) + */
921 /* Addend - round (Addend, 8192) */
922
923 static long
924 RR (Symbol, Addend)
925 {
926 return Symbol
927 - round_down (Symbol, 2048)
928 + Addend - round (Addend, 8192);
929 }
930
931 unsigned long
932 hppa_field_adjust (value, constant_value, r_field)
933 unsigned long value;
934 unsigned long constant_value;
935 unsigned short r_field;
936 {
937 unsigned long init_value = value;
938 value += constant_value;
939 switch (r_field)
940 {
941 case e_fsel: /* F : no change */
942 break;
943
944 case e_lssel: /* LS : if (bit 21) then add 0x800
945 arithmetic shift right 11 bits */
946 if (value & 0x00000400)
947 value += 0x800;
948 value = (value & 0xfffff800) >> 11;
949 BFD_ASSERT (value == LS (init_value, constant_value));
950 break;
951
952 case e_rssel: /* RS : Sign extend from bit 21 */
953 if (value & 0x00000400)
954 value |= 0xfffff800;
955 else
956 value &= 0x7ff;
957 BFD_ASSERT (value == RS (init_value, constant_value));
958 break;
959
960 case e_lsel: /* L : Arithmetic shift right 11 bits */
961 value = (value & 0xfffff800) >> 11;
962 BFD_ASSERT (value == L (init_value, constant_value));
963 break;
964
965 case e_rsel: /* R : Set bits 0-20 to zero */
966 value = value & 0x7ff;
967 BFD_ASSERT (value == R (init_value, constant_value));
968 break;
969
970 case e_ldsel: /* LD : Add 0x800, arithmetic shift
971 right 11 bits */
972 value += 0x800;
973 value = (value & 0xfffff800) >> 11;
974 BFD_ASSERT (value == LD (init_value, constant_value));
975 break;
976
977 case e_rdsel: /* RD : Set bits 0-20 to one */
978 value |= 0xfffff800;
979 BFD_ASSERT (value == RD (init_value, constant_value));
980 break;
981
982 case e_lrsel: /* LR : L with "rounded" constant */
983 value = value + ((constant_value + 0x1000) & 0xffffe000);
984 value = (value & 0xfffff800) >> 11;
985 BFD_ASSERT (value == LR (init_value, constant_value));
986 break;
987
988 case e_rrsel: /* RR : R with "rounded" constant */
989 value = value + ((constant_value + 0x1000) & 0xffffe000);
990 value = (value & 0x7ff) + constant_value - ((constant_value + 0x1000) & 0xffffe000);
991 BFD_ASSERT (value == RR (init_value, constant_value));
992 break;
993
994 default:
995 fprintf (stderr, "Unrecognized field_selector 0x%02x\n", r_field);
996 break;
997 }
998 return value;
999
1000 }
1001
1002 /* Return information about SOM symbol SYMBOL in RET. */
1003
1004 static void
1005 hppa_get_symbol_info (ignore_abfd, symbol, ret)
1006 bfd *ignore_abfd; /* Ignored. */
1007 asymbol *symbol;
1008 symbol_info *ret;
1009 {
1010 bfd_symbol_info (symbol, ret);
1011 }
1012
1013 /* End of miscellaneous support functions. */
1014
1015 #define hppa_bfd_debug_info_start bfd_void
1016 #define hppa_bfd_debug_info_end bfd_void
1017 #define hppa_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
1018
1019 #define hppa_openr_next_archived_file bfd_generic_openr_next_archived_file
1020 #define hppa_generic_stat_arch_elt bfd_generic_stat_arch_elt
1021 #define hppa_slurp_armap bfd_false
1022 #define hppa_slurp_extended_name_table _bfd_slurp_extended_name_table
1023 #define hppa_truncate_arname (void (*)())bfd_nullvoidptr
1024 #define hppa_write_armap 0
1025
1026 #define hppa_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
1027 #define hppa_close_and_cleanup bfd_generic_close_and_cleanup
1028 #define hppa_get_section_contents bfd_generic_get_section_contents
1029
1030 #define hppa_bfd_get_relocated_section_contents \
1031 bfd_generic_get_relocated_section_contents
1032 #define hppa_bfd_relax_section bfd_generic_relax_section
1033 #define hppa_bfd_seclet_link bfd_generic_seclet_link
1034 #define hppa_bfd_reloc_type_lookup \
1035 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
1036 #define hppa_bfd_make_debug_symbol \
1037 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
1038
1039 bfd_target hppa_vec =
1040 {
1041 "hppa", /* name */
1042 bfd_target_hppa_flavour,
1043 true, /* target byte order */
1044 true, /* target headers byte order */
1045 (HAS_RELOC | EXEC_P | /* object flags */
1046 HAS_LINENO | HAS_DEBUG |
1047 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1048 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1049 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1050
1051 /* leading_symbol_char: is the first char of a user symbol
1052 predictable, and if so what is it */
1053 0,
1054 ' ', /* ar_pad_char */
1055 16, /* ar_max_namelen */
1056 3, /* minimum alignment */
1057 _do_getb64, _do_getb_signed_64, _do_putb64,
1058 _do_getb32, _do_getb_signed_32, _do_putb32,
1059 _do_getb16, _do_getb_signed_16, _do_putb16, /* data */
1060 _do_getb64, _do_getb_signed_64, _do_putb64,
1061 _do_getb32, _do_getb_signed_32, _do_putb32,
1062 _do_getb16, _do_getb_signed_16, _do_putb16, /* hdrs */
1063 {_bfd_dummy_target,
1064 hppa_object_p, /* bfd_check_format */
1065 bfd_generic_archive_p,
1066 hppa_core_file_p,
1067 },
1068 {
1069 bfd_false,
1070 hppa_mkobject,
1071 _bfd_generic_mkarchive,
1072 bfd_false
1073 },
1074 {
1075 bfd_false,
1076 hppa_write_object_contents,
1077 _bfd_write_archive_contents,
1078 bfd_false,
1079 },
1080 #undef hppa
1081 JUMP_TABLE (hppa),
1082 (PTR) 0
1083 };
1084
1085 #endif /* HOST_HPPAHPUX || HOST_HPPABSD */
This page took 0.05052 seconds and 4 git commands to generate.