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