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