21504697dccc06b524bf7d66bd7f1fd62ef6089f
[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 DEFUN (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 DEFUN (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_get_symbol_info (ignore_abfd, symbol, ret)
439 bfd *ignore_abfd;
440 asymbol *symbol;
441 symbol_info ret;
442 {
443 bfd_symbol_info (symbol, ret);
444 }
445
446 static void
447 hppa_print_symbol (ignore_abfd, afile, symbol, how)
448 bfd *ignore_abfd;
449 PTR afile;
450 asymbol *symbol;
451 bfd_print_symbol_type how;
452 {
453 fprintf (stderr, "hppa_print_symbol unimplemented\n");
454 fflush (stderr);
455 abort ();
456 }
457
458 static boolean
459 hppa_new_section_hook (abfd, newsect)
460 bfd *abfd;
461 asection *newsect;
462 {
463 newsect->alignment_power = 3;
464
465 /* We allow more than three sections internally */
466 return true;
467 }
468
469 static boolean
470 hppa_set_section_contents (abfd, section, location, offset, count)
471 bfd *abfd;
472 sec_ptr section;
473 PTR location;
474 file_ptr offset;
475 bfd_size_type count;
476 {
477 fprintf (stderr, "hppa_set_section_contents unimplimented\n");
478 fflush (stderr);
479 abort ();
480 return false;
481 }
482
483 static boolean
484 hppa_set_arch_mach (abfd, arch, machine)
485 bfd *abfd;
486 enum bfd_architecture arch;
487 unsigned long machine;
488 {
489 fprintf (stderr, "hppa_set_arch_mach unimplemented\n");
490 fflush (stderr);
491 /* Allow any architecture to be supported by the hppa backend */
492 return bfd_default_set_arch_mach (abfd, arch, machine);
493 }
494
495 static boolean
496 hppa_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
497 functionname_ptr, line_ptr)
498 bfd *abfd;
499 asection *section;
500 asymbol **symbols;
501 bfd_vma offset;
502 CONST char **filename_ptr;
503 CONST char **functionname_ptr;
504 unsigned int *line_ptr;
505 {
506 fprintf (stderr, "hppa_find_nearest_line unimplemented\n");
507 fflush (stderr);
508 abort ();
509 return (false);
510 }
511
512 static int
513 hppa_sizeof_headers (abfd, reloc)
514 bfd *abfd;
515 boolean reloc;
516 {
517 fprintf (stderr, "hppa_sizeof_headers unimplemented\n");
518 fflush (stderr);
519 abort ();
520 return (0);
521 }
522
523 static asection *
524 make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power)
525 bfd *abfd;
526 CONST char *name;
527 flagword flags;
528 bfd_size_type _raw_size;
529 bfd_vma vma;
530 unsigned int alignment_power;
531 {
532 asection *asect;
533
534 asect = bfd_make_section (abfd, name);
535 if (!asect)
536 return NULL;
537
538 asect->flags = flags;
539 asect->_raw_size = _raw_size;
540 asect->vma = vma;
541 asect->filepos = bfd_tell (abfd);
542 asect->alignment_power = alignment_power;
543
544 return asect;
545 }
546
547 #ifdef HOST_HPPAHPUX
548 static bfd_target *
549 hppa_core_file_p (abfd)
550 bfd *abfd;
551 {
552 core_hdr (abfd) = bfd_zalloc (abfd, sizeof (struct hppa_core_struct));
553 if (!core_hdr (abfd))
554 return NULL;
555
556 while (1)
557 {
558 int val;
559 struct corehead core_header;
560
561 val = bfd_read ((void *) &core_header, 1, sizeof core_header, abfd);
562 if (val <= 0)
563 break;
564 switch (core_header.type)
565 {
566 case CORE_KERNEL:
567 case CORE_FORMAT:
568 bfd_seek (abfd, core_header.len, SEEK_CUR); /* Just skip this */
569 break;
570 case CORE_EXEC:
571 {
572 struct proc_exec proc_exec;
573 bfd_read ((void *) &proc_exec, 1, core_header.len, abfd);
574 strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1);
575 }
576 break;
577 case CORE_PROC:
578 {
579 struct proc_info proc_info;
580 core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
581 SEC_ALLOC + SEC_HAS_CONTENTS,
582 core_header.len,
583 (int) &proc_info - (int) &proc_info.hw_regs,
584 2);
585 bfd_read (&proc_info, 1, core_header.len, abfd);
586 core_signal (abfd) = proc_info.sig;
587 }
588 if (!core_regsec (abfd))
589 return NULL;
590 break;
591 case CORE_DATA:
592 core_datasec (abfd) = make_bfd_asection (abfd, ".data",
593 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
594 core_header.len,
595 core_header.addr,
596 2);
597 if (!core_datasec (abfd))
598 return NULL;
599 bfd_seek (abfd, core_header.len, SEEK_CUR);
600 break;
601 case CORE_STACK:
602 core_stacksec (abfd) = make_bfd_asection (abfd, ".stack",
603 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
604 core_header.len,
605 core_header.addr,
606 2);
607 if (!core_stacksec (abfd))
608 return NULL;
609 bfd_seek (abfd, core_header.len, SEEK_CUR);
610 break;
611 default:
612 fprintf (stderr, "Unknown HPPA/HPUX core file section type %d\n",
613 core_header.type);
614 bfd_seek (abfd, core_header.len, SEEK_CUR);
615 break;
616 }
617 }
618
619 /* OK, we believe you. You're a core file (sure, sure). */
620
621 return abfd->xvec;
622 }
623
624 static char *
625 hppa_core_file_failing_command (abfd)
626 bfd *abfd;
627 {
628 return core_command (abfd);
629 }
630
631 /* ARGSUSED */
632 static int
633 hppa_core_file_failing_signal (abfd)
634 bfd *abfd;
635 {
636 return core_signal (abfd);
637 }
638
639 /* ARGSUSED */
640 static boolean
641 hppa_core_file_matches_executable_p (core_bfd, exec_bfd)
642 bfd *core_bfd, *exec_bfd;
643 {
644 return true; /* FIXME, We have no way of telling at this point */
645 }
646
647 #endif /* HOST_HPPAHPUX */
648
649 /* Miscellaneous Support Functions -- Control Structures and Functions
650 for the PA. */
651
652 unsigned int
653 assemble_3 (x)
654 unsigned int x;
655 {
656 return (((x & 1) << 2) | ((x & 6) >> 1)) & 7;
657 }
658
659 void
660 dis_assemble_3 (x, r)
661 unsigned int x;
662 unsigned int *r;
663 {
664 *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7;
665 }
666
667 unsigned int
668 assemble_12 (x, y)
669 unsigned int x, y;
670 {
671 return (((y & 1) << 11) | ((x & 1) << 10) | ((x & 0x7fe) >> 1)) & 0xfff;
672 }
673
674 void
675 dis_assemble_12 (as12, x, y)
676 unsigned int as12;
677 unsigned int *x, *y;
678 {
679 *y = (as12 & 0x800) >> 11;
680 *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10);
681 }
682
683 unsigned long
684 assemble_17 (x, y, z)
685 unsigned int x, y, z;
686 {
687 unsigned long temp;
688
689 temp = ((z & 1) << 16) |
690 ((x & 0x1f) << 11) |
691 ((y & 1) << 10) |
692 ((y & 0x7fe) >> 1);
693 return temp & 0x1ffff;
694 }
695
696 void
697 dis_assemble_17 (as17, x, y, z)
698 unsigned int as17;
699 unsigned int *x, *y, *z;
700 {
701
702 *z = (as17 & 0x10000) >> 16;
703 *x = (as17 & 0x0f800) >> 11;
704 *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff;
705 }
706
707 unsigned long
708 assemble_21 (x)
709 unsigned int x;
710 {
711 unsigned long temp;
712
713 temp = ((x & 1) << 20) |
714 ((x & 0xffe) << 8) |
715 ((x & 0xc000) >> 7) |
716 ((x & 0x1f0000) >> 14) |
717 ((x & 0x003000) >> 12);
718 return temp & 0x1fffff;
719 }
720
721 void
722 dis_assemble_21 (as21, x)
723 unsigned int as21, *x;
724 {
725 unsigned long temp;
726
727
728 temp = (as21 & 0x100000) >> 20;
729 temp |= (as21 & 0x0ffe00) >> 8;
730 temp |= (as21 & 0x000180) << 7;
731 temp |= (as21 & 0x00007c) << 14;
732 temp |= (as21 & 0x000003) << 12;
733 *x = temp;
734 }
735
736 #if 0
737 unsigned long
738 sign_ext (x, len)
739 unsigned int x, len;
740 {
741 unsigned int sign;
742 unsigned int result;
743 unsigned int len_ones;
744 int i;
745
746 i = 0;
747 len_ones = 0;
748 while (i < len)
749 {
750 len_ones = (len_ones << 1) | 1;
751 i++;
752 }
753
754 sign = (x >> (len - 1)) & 1;
755
756 if (sign)
757 result = (~0 ^ len_ones) | (len_ones & x);
758 else
759 result = len_ones & x;
760
761 return result;
762 }
763
764 #endif
765 static unsigned long
766 sign_ext (x, len)
767 unsigned int x, len;
768 {
769 return (x << (32 - len)) >> (32 - len);
770 }
771
772 static unsigned int
773 ones (n)
774 int n;
775 {
776 unsigned int len_ones;
777 int i;
778
779 i = 0;
780 len_ones = 0;
781 while (i < n)
782 {
783 len_ones = (len_ones << 1) | 1;
784 i++;
785 }
786
787 return len_ones;
788 }
789
790 void
791 sign_unext (x, len, result)
792 unsigned int x, len;
793 unsigned int *result;
794 {
795 unsigned int len_ones;
796
797 len_ones = ones (len);
798
799 *result = x & len_ones;
800 }
801
802 unsigned long
803 low_sign_ext (x, len)
804 unsigned int x, len;
805 {
806 unsigned int temp1, temp2;
807 unsigned int len_ones;
808
809 len_ones = ones (len);
810
811 temp1 = (x & 1) << (len - 1);
812 temp2 = ((x & 0xfffffffe) & len_ones) >> 1;
813 return sign_ext ((temp1 | temp2), len);
814 }
815
816 void
817 low_sign_unext (x, len, result)
818 unsigned int x, len;
819 unsigned int *result;
820 {
821 unsigned int temp;
822 unsigned int sign;
823 unsigned int rest;
824 unsigned int one_bit_at_len;
825 unsigned int len_ones;
826
827 len_ones = ones (len);
828 one_bit_at_len = 1 << (len - 1);
829
830 sign_unext (x, len, &temp);
831 sign = temp & one_bit_at_len;
832 sign >>= (len - 1);
833
834 rest = temp & (len_ones ^ one_bit_at_len);
835 rest <<= 1;
836
837 *result = rest | sign;
838 }
839
840 /* These work when 'y' is a power of two only. */
841
842 static long
843 round_down (x, y)
844 long x, y;
845 {
846 return x & ~(y - 1);
847 }
848
849 static long
850 round (x, y)
851 long x, y;
852 {
853 return (x + y / 2) & ~(y - 1);
854 }
855
856 static long
857 round_up (x, y)
858 long x, y;
859 {
860 return x - (x | ~(y - 1));
861 }
862
863 /* L(Symbol, Addend): */
864 /* round_down (Symbol + Addend, 2048) */
865
866 static long
867 L (Symbol, Addend)
868 {
869 return (round_down (Symbol + Addend, 2048)) >> 11;
870 }
871
872 /* R(Symbol, Addend): */
873 /* Symbol + Addend - round_down (Symbol + Addend, 2048) */
874
875 static long
876 R (Symbol, Addend)
877 {
878 return Symbol + Addend - round_down (Symbol + Addend, 2048);
879 }
880
881 /* LS(Symbol, Addend): */
882 /* round (Symbol + Addend, 2048) */
883
884 static long
885 LS (Symbol, Addend)
886 {
887 return round (Symbol + Addend, 2048);
888 }
889
890 /* RS(Symbol, Addend): */
891 /* Symbol + Addend - round (Symbol + Addend, 2048) */
892
893 static long
894 RS (Symbol, Addend)
895 {
896 return Symbol + Addend - round (Symbol + Addend, 2048);
897 }
898
899 /* LD(Symbol, Addend): */
900 /* round_up (Symbol + Addend, 2048) */
901
902 static long
903 LD (Symbol, Addend)
904 {
905 return (round_up (Symbol + Addend, 2048)) >> 11;
906 }
907
908 /* RD(Symbol, Addend): */
909 /* Symbol + Addend - round_up (Symbol + Addend, 2048) */
910
911 static long
912 RD (Symbol, Addend)
913 {
914 return Symbol + Addend - round_up (Symbol + Addend, 2048);
915 }
916
917 /* LR(Symbol, Addend): */
918 /* round_down (Symbol, 2048) + round (Addend, 8192) */
919
920 static long
921 LR (Symbol, Addend)
922 {
923 return (round_down (Symbol, 2048) + round (Addend, 8192)) >> 11;
924 }
925
926 /* RR(Symbol, Addend): */
927 /* Symbol - round_down (Symbol, 2048) + */
928 /* Addend - round (Addend, 8192) */
929
930 static long
931 RR (Symbol, Addend)
932 {
933 return Symbol
934 - round_down (Symbol, 2048)
935 + Addend - round (Addend, 8192);
936 }
937
938 unsigned long
939 DEFUN (hppa_field_adjust, (value, constant_value, r_field),
940 unsigned long value AND
941 unsigned long constant_value AND
942 unsigned short r_field)
943 {
944 unsigned long init_value = value;
945 value += constant_value;
946 switch (r_field)
947 {
948 case e_fsel: /* F : no change */
949 break;
950
951 case e_lssel: /* LS : if (bit 21) then add 0x800
952 arithmetic shift right 11 bits */
953 if (value & 0x00000400)
954 value += 0x800;
955 value = (value & 0xfffff800) >> 11;
956 BFD_ASSERT (value == LS (init_value, constant_value));
957 break;
958
959 case e_rssel: /* RS : Sign extend from bit 21 */
960 if (value & 0x00000400)
961 value |= 0xfffff800;
962 else
963 value &= 0x7ff;
964 BFD_ASSERT (value == RS (init_value, constant_value));
965 break;
966
967 case e_lsel: /* L : Arithmetic shift right 11 bits */
968 value = (value & 0xfffff800) >> 11;
969 BFD_ASSERT (value == L (init_value, constant_value));
970 break;
971
972 case e_rsel: /* R : Set bits 0-20 to zero */
973 value = value & 0x7ff;
974 BFD_ASSERT (value == R (init_value, constant_value));
975 break;
976
977 case e_ldsel: /* LD : Add 0x800, arithmetic shift
978 right 11 bits */
979 value += 0x800;
980 value = (value & 0xfffff800) >> 11;
981 BFD_ASSERT (value == LD (init_value, constant_value));
982 break;
983
984 case e_rdsel: /* RD : Set bits 0-20 to one */
985 value |= 0xfffff800;
986 BFD_ASSERT (value == RD (init_value, constant_value));
987 break;
988
989 case e_lrsel: /* LR : L with "rounded" constant */
990 value = value + ((constant_value + 0x1000) & 0xffffe000);
991 value = (value & 0xfffff800) >> 11;
992 BFD_ASSERT (value == LR (init_value, constant_value));
993 break;
994
995 case e_rrsel: /* RR : R with "rounded" constant */
996 value = value + ((constant_value + 0x1000) & 0xffffe000);
997 value = (value & 0x7ff) + constant_value - ((constant_value + 0x1000) & 0xffffe000);
998 BFD_ASSERT (value == RR (init_value, constant_value));
999 break;
1000
1001 default:
1002 fprintf (stderr, "Unrecognized field_selector 0x%02x\n", r_field);
1003 break;
1004 }
1005 return value;
1006
1007 }
1008
1009 /* Return information about SOM symbol SYMBOL in RET. */
1010
1011 static void
1012 hppa_get_symbol_info (ignore_abfd, symbol, ret)
1013 bfd *ignore_abfd; /* Ignored. */
1014 asymbol *symbol;
1015 symbol_info *ret;
1016 {
1017 bfd_symbol_info (symbol, ret);
1018 }
1019
1020 /* End of miscellaneous support functions. */
1021
1022 #ifdef HOST_HPPABSD
1023 /* All the core file code for BSD needs to be rewritten cleanly. For
1024 now we do not support core files under BSD. */
1025
1026 #define hppa_core_file_p _bfd_dummy_target
1027 #define hppa_core_file_failing_command _bfd_dummy_core_file_failing_command
1028 #define hppa_core_file_failing_signal _bfd_dummy_core_file_failing_signal
1029 #define hppa_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
1030 #endif /* HOST_HPPABSD */
1031
1032 #define hppa_bfd_debug_info_start bfd_void
1033 #define hppa_bfd_debug_info_end bfd_void
1034 #define hppa_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
1035
1036 #define hppa_openr_next_archived_file bfd_generic_openr_next_archived_file
1037 #define hppa_generic_stat_arch_elt bfd_generic_stat_arch_elt
1038 #define hppa_slurp_armap bfd_false
1039 #define hppa_slurp_extended_name_table _bfd_slurp_extended_name_table
1040 #define hppa_truncate_arname (void (*)())bfd_nullvoidptr
1041 #define hppa_write_armap 0
1042
1043 #define hppa_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
1044 #define hppa_close_and_cleanup bfd_generic_close_and_cleanup
1045 #define hppa_get_section_contents bfd_generic_get_section_contents
1046
1047 #define hppa_bfd_get_relocated_section_contents \
1048 bfd_generic_get_relocated_section_contents
1049 #define hppa_bfd_relax_section bfd_generic_relax_section
1050 #define hppa_bfd_seclet_link bfd_generic_seclet_link
1051 #define hppa_bfd_reloc_type_lookup \
1052 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
1053 #define hppa_bfd_make_debug_symbol \
1054 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
1055
1056 bfd_target hppa_vec =
1057 {
1058 "hppa", /* name */
1059 bfd_target_hppa_flavour,
1060 true, /* target byte order */
1061 true, /* target headers byte order */
1062 (HAS_RELOC | EXEC_P | /* object flags */
1063 HAS_LINENO | HAS_DEBUG |
1064 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1065 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1066 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1067
1068 /* leading_symbol_char: is the first char of a user symbol
1069 predictable, and if so what is it */
1070 0,
1071 ' ', /* ar_pad_char */
1072 16, /* ar_max_namelen */
1073 3, /* minimum alignment */
1074 _do_getb64, _do_getb_signed_64, _do_putb64,
1075 _do_getb32, _do_getb_signed_32, _do_putb32,
1076 _do_getb16, _do_getb_signed_16, _do_putb16, /* data */
1077 _do_getb64, _do_getb_signed_64, _do_putb64,
1078 _do_getb32, _do_getb_signed_32, _do_putb32,
1079 _do_getb16, _do_getb_signed_16, _do_putb16, /* hdrs */
1080 {_bfd_dummy_target,
1081 hppa_object_p, /* bfd_check_format */
1082 bfd_generic_archive_p,
1083 hppa_core_file_p,
1084 },
1085 {
1086 bfd_false,
1087 hppa_mkobject,
1088 _bfd_generic_mkarchive,
1089 bfd_false
1090 },
1091 {
1092 bfd_false,
1093 hppa_write_object_contents,
1094 _bfd_write_archive_contents,
1095 bfd_false,
1096 },
1097 #undef hppa
1098 JUMP_TABLE (hppa),
1099 (PTR) 0
1100 };
1101
1102 #endif /* HOST_HPPAHPUX || HOST_HPPABSD */
This page took 0.051589 seconds and 3 git commands to generate.