Merged in changes from Jeff Law and Pete Hoogenboom at Utah for PA ELF
[deliverable/binutils-gdb.git] / bfd / hppa.c
CommitLineData
e3c01e92 1/* bfd back-end for HP PA-RISC SOM objects.
0dc1bc8b 2 Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
e3c01e92
SG
3
4 Contributed by the Center for Software Science at the
5 University of Utah (pa-gdb-bugs@cs.utah.edu).
6
7This file is part of BFD, the Binary File Descriptor library.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22
e3c01e92 23#include "bfd.h"
76c7e44d 24#include "sysdep.h"
205d660d 25
09f080a5
KR
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? */
9a5e3a9a 30#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD)
205d660d 31
e3c01e92
SG
32#include "libbfd.h"
33#include "libhppa.h"
34
e3c01e92
SG
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>
7050286d 41#include <sys/user.h> /* After a.out.h */
e3c01e92
SG
42#include <sys/file.h>
43#include <errno.h>
0093d9e6 44
155171de
KR
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 */
d325e28c 50
155171de
KR
51#ifndef CPU_PA_RISC1_1
52#define CPU_PA_RISC1_1 0x210
53#endif /* CPU_PA_RISC1_1 */
d325e28c 54
155171de
KR
55#ifndef _PA_RISC1_0_ID
56#define _PA_RISC1_0_ID CPU_PA_RISC1_0
57#endif /* _PA_RISC1_0_ID */
d325e28c 58
155171de
KR
59#ifndef _PA_RISC1_1_ID
60#define _PA_RISC1_1_ID CPU_PA_RISC1_1
61#endif /* _PA_RISC1_1_ID */
d325e28c 62
155171de
KR
63#ifndef _PA_RISC_MAXID
64#define _PA_RISC_MAXID 0x2FF
65#endif /* _PA_RISC_MAXID */
d325e28c 66
155171de
KR
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
7050286d
KR
73struct container
74 {
75 struct header f;
76 struct som_exec_auxhdr e;
77 };
e3c01e92 78
edff0587
SG
79static bfd_target *
80hppa_object_setup (abfd, file_hdrp, aux_hdrp)
e3c01e92 81 bfd *abfd;
edff0587
SG
82 struct header *file_hdrp;
83 struct som_exec_auxhdr *aux_hdrp;
e3c01e92
SG
84{
85 struct container *rawptr;
86 struct header *f;
87 struct hppa_data_struct *rawptr1;
d0a650a4 88 asection *text, *data, *bss;
e3c01e92
SG
89
90 rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
7050286d
KR
91 if (rawptr == NULL)
92 {
93 bfd_error = no_memory;
94 return 0;
95 }
e3c01e92
SG
96
97 rawptr1 = (struct hppa_data_struct *) bfd_zalloc (abfd, sizeof (struct hppa_data_struct));
7050286d
KR
98 if (rawptr1 == NULL)
99 {
100 bfd_error = no_memory;
101 return 0;
102 }
103
e3c01e92
SG
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
7050286d 119 obj_pa_symbols (abfd) = (hppa_symbol_type *) NULL;
d0a650a4 120 bfd_get_symcount (abfd) = file_hdrp->symbol_total;
e3c01e92 121
7050286d 122 bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 0);
e3c01e92
SG
123
124 /* create the sections. This is raunchy, but bfd_close wants to reclaim
125 them */
d0a650a4 126
7050286d
KR
127 text = bfd_make_section (abfd, ".text");
128 data = bfd_make_section (abfd, ".data");
129 bss = bfd_make_section (abfd, ".bss");
d0a650a4
SG
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;
e3c01e92 138
7050286d
KR
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;
d0a650a4 154 bfd_get_symcount (abfd) = file_hdrp->symbol_total;
7050286d 155 obj_str_filepos (abfd) = file_hdrp->symbol_strings_location;
d0a650a4 156 obj_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
e3c01e92
SG
157
158 return abfd->xvec;
159}
160
edff0587
SG
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
167static asection *
168make_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 {
7050286d 180 sprintf (altname, "%s-%d", name, num++);
edff0587
SG
181 sect = bfd_make_section (abfd, altname);
182 }
183
7050286d 184 newname = bfd_alloc (abfd, strlen (sect->name) + 1);
edff0587
SG
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
197static int
198setup_sections (abfd, file_hdr)
199 bfd *abfd;
200 struct header *file_hdr;
201{
202 char *space_strings;
203 int space_index;
204
7050286d 205 /* First, read in space names */
edff0587
SG
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
7050286d 228 + space_index * sizeof space, SEEK_SET) < 0)
edff0587
SG
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
7050286d
KR
243 + space.subspace_index * sizeof subspace,
244 SEEK_SET) < 0)
edff0587
SG
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
7050286d
KR
250 + space.subspace_index * sizeof subspace,
251 SEEK_SET) < 0)
edff0587
SG
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,
7050286d 283 space.subspace_index + subspace_index);
edff0587
SG
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)
7050286d 303 + subspace.subspace_length;
edff0587
SG
304 space_asect->_raw_size = (subspace.file_loc_init_value
305 - space_asect->filepos)
7050286d 306 + subspace.initialization_length;
edff0587
SG
307 }
308}
309
310static bfd_target *
311hppa_object_p (abfd)
312 bfd *abfd;
e3c01e92
SG
313{
314 struct header file_hdr;
315 struct som_exec_auxhdr aux_hdr;
e3c01e92 316
7050286d 317 if (bfd_read ((PTR) & file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
edff0587
SG
318 return 0;
319
320 if (!_PA_RISC_ID (file_hdr.system_id))
e3c01e92
SG
321 {
322 bfd_error = wrong_format;
323 return 0;
324 }
205d660d 325
205d660d
SG
326 switch (file_hdr.a_magic)
327 {
7050286d 328 case RELOC_MAGIC: /* I'm not really sure about all of these types... */
205d660d
SG
329 case EXEC_MAGIC:
330 case SHARE_MAGIC:
331 case DEMAND_MAGIC:
0093d9e6 332#ifdef DL_MAGIC
205d660d 333 case DL_MAGIC:
0093d9e6
KR
334#endif
335#ifdef SHL_MAGIC
205d660d 336 case SHL_MAGIC:
0093d9e6 337#endif
205d660d
SG
338 break;
339 default:
edff0587 340 bfd_error = wrong_format;
205d660d
SG
341 return 0;
342 }
343
edff0587
SG
344 if (file_hdr.version_id != VERSION_ID
345 && file_hdr.version_id != NEW_VERSION_ID)
e3c01e92
SG
346 {
347 bfd_error = wrong_format;
348 return 0;
349 }
e3c01e92 350
7050286d 351 if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
edff0587 352 bfd_error = wrong_format;
e3c01e92 353
edff0587
SG
354 if (!setup_sections (abfd, &file_hdr))
355 return 0;
356
7050286d 357 return hppa_object_setup (abfd, &file_hdr, &aux_hdr);
edff0587 358}
e3c01e92
SG
359
360static boolean
77478127
SG
361hppa_mkobject (abfd)
362 bfd *abfd;
7050286d 363{
e3c01e92
SG
364 fprintf (stderr, "hppa_mkobject unimplemented\n");
365 fflush (stderr);
366 abort ();
367 return (false);
368}
369
370boolean
77478127
SG
371hppa_write_object_contents(abfd)
372 bfd *abfd;
e3c01e92
SG
373{
374 fprintf (stderr, "hppa_write_object_contents unimplemented\n");
375 fflush (stderr);
376 abort ();
377 return (false);
378}
379
edff0587
SG
380static unsigned int
381hppa_get_symtab_upper_bound (abfd)
382 bfd *abfd;
e3c01e92
SG
383{
384 fprintf (stderr, "hppa_get_symtab_upper_bound unimplemented\n");
385 fflush (stderr);
386 abort ();
387 return (0);
388}
389
edff0587
SG
390static unsigned int
391hppa_get_reloc_upper_bound (abfd, asect)
392 bfd *abfd;
393 sec_ptr asect;
e3c01e92
SG
394{
395 fprintf (stderr, "hppa_get_reloc_upper_bound unimplemented\n");
396 fflush (stderr);
397 abort ();
398 return (0);
399}
400
edff0587
SG
401static unsigned int
402hppa_canonicalize_reloc (abfd, section, relptr, symbols)
403 bfd *abfd;
404 sec_ptr section;
405 arelent **relptr;
406 asymbol **symbols;
e3c01e92
SG
407{
408 fprintf (stderr, "hppa_canonicalize_reloc unimplemented\n");
409 fflush (stderr);
410 abort ();
411}
412
413extern bfd_target hppa_vec;
edff0587
SG
414
415static unsigned int
416hppa_get_symtab (abfd, location)
417 bfd *abfd;
418 asymbol **location;
e3c01e92
SG
419{
420 fprintf (stderr, "hppa_get_symtab unimplemented\n");
421 fflush (stderr);
422 abort ();
423 return (0);
424}
425
edff0587
SG
426static asymbol *
427hppa_make_empty_symbol (abfd)
428 bfd *abfd;
e3c01e92 429{
7050286d
KR
430 hppa_symbol_type *new =
431 (hppa_symbol_type *) bfd_zalloc (abfd, sizeof (hppa_symbol_type));
e3c01e92
SG
432 new->symbol.the_bfd = abfd;
433
434 return &new->symbol;
435}
436
7050286d
KR
437static void
438hppa_print_symbol (ignore_abfd, afile, symbol, how)
edff0587
SG
439 bfd *ignore_abfd;
440 PTR afile;
441 asymbol *symbol;
442 bfd_print_symbol_type how;
e3c01e92
SG
443{
444 fprintf (stderr, "hppa_print_symbol unimplemented\n");
445 fflush (stderr);
446 abort ();
447}
448
edff0587
SG
449static boolean
450hppa_new_section_hook (abfd, newsect)
451 bfd *abfd;
452 asection *newsect;
e3c01e92 453{
e3c01e92
SG
454 newsect->alignment_power = 3;
455
e3c01e92
SG
456 /* We allow more than three sections internally */
457 return true;
458}
459
edff0587
SG
460static boolean
461hppa_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;
e3c01e92
SG
467{
468 fprintf (stderr, "hppa_set_section_contents unimplimented\n");
469 fflush (stderr);
7050286d 470 abort ();
e3c01e92
SG
471 return false;
472}
473
edff0587
SG
474static boolean
475hppa_set_arch_mach (abfd, arch, machine)
476 bfd *abfd;
477 enum bfd_architecture arch;
478 unsigned long machine;
e3c01e92
SG
479{
480 fprintf (stderr, "hppa_set_arch_mach unimplemented\n");
481 fflush (stderr);
482 /* Allow any architecture to be supported by the hppa backend */
7050286d 483 return bfd_default_set_arch_mach (abfd, arch, machine);
e3c01e92
SG
484}
485
e3c01e92 486static boolean
edff0587
SG
487hppa_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;
e3c01e92
SG
496{
497 fprintf (stderr, "hppa_find_nearest_line unimplemented\n");
498 fflush (stderr);
499 abort ();
500 return (false);
501}
502
503static int
edff0587 504hppa_sizeof_headers (abfd, reloc)
7050286d
KR
505 bfd *abfd;
506 boolean reloc;
e3c01e92
SG
507{
508 fprintf (stderr, "hppa_sizeof_headers unimplemented\n");
509 fflush (stderr);
510 abort ();
511 return (0);
512}
513
09f080a5
KR
514/* Miscellaneous Support Functions -- Control Structures and Functions
515 for the PA. */
516
7050286d
KR
517unsigned int
518assemble_3 (x)
09f080a5
KR
519 unsigned int x;
520{
7050286d 521 return (((x & 1) << 2) | ((x & 6) >> 1)) & 7;
09f080a5
KR
522}
523
7050286d
KR
524void
525dis_assemble_3 (x, r)
09f080a5
KR
526 unsigned int x;
527 unsigned int *r;
528{
7050286d 529 *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7;
09f080a5
KR
530}
531
7050286d
KR
532unsigned int
533assemble_12 (x, y)
534 unsigned int x, y;
09f080a5 535{
7050286d 536 return (((y & 1) << 11) | ((x & 1) << 10) | ((x & 0x7fe) >> 1)) & 0xfff;
09f080a5
KR
537}
538
7050286d
KR
539void
540dis_assemble_12 (as12, x, y)
09f080a5 541 unsigned int as12;
7050286d 542 unsigned int *x, *y;
09f080a5 543{
7050286d
KR
544 *y = (as12 & 0x800) >> 11;
545 *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10);
09f080a5
KR
546}
547
7050286d
KR
548unsigned long
549assemble_17 (x, y, z)
550 unsigned int x, y, z;
09f080a5
KR
551{
552 unsigned long temp;
553
7050286d
KR
554 temp = ((z & 1) << 16) |
555 ((x & 0x1f) << 11) |
556 ((y & 1) << 10) |
557 ((y & 0x7fe) >> 1);
09f080a5
KR
558 return temp & 0x1ffff;
559}
560
7050286d
KR
561void
562dis_assemble_17 (as17, x, y, z)
09f080a5 563 unsigned int as17;
7050286d 564 unsigned int *x, *y, *z;
09f080a5
KR
565{
566
7050286d
KR
567 *z = (as17 & 0x10000) >> 16;
568 *x = (as17 & 0x0f800) >> 11;
569 *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff;
09f080a5
KR
570}
571
7050286d
KR
572unsigned long
573assemble_21 (x)
09f080a5
KR
574 unsigned int x;
575{
576 unsigned long temp;
577
7050286d
KR
578 temp = ((x & 1) << 20) |
579 ((x & 0xffe) << 8) |
580 ((x & 0xc000) >> 7) |
581 ((x & 0x1f0000) >> 14) |
582 ((x & 0x003000) >> 12);
09f080a5
KR
583 return temp & 0x1fffff;
584}
585
7050286d
KR
586void
587dis_assemble_21 (as21, x)
588 unsigned int as21, *x;
09f080a5
KR
589{
590 unsigned long temp;
591
592
7050286d
KR
593 temp = (as21 & 0x100000) >> 20;
594 temp |= (as21 & 0x0ffe00) >> 8;
595 temp |= (as21 & 0x000180) << 7;
596 temp |= (as21 & 0x00007c) << 14;
597 temp |= (as21 & 0x000003) << 12;
09f080a5
KR
598 *x = temp;
599}
600
7050286d
KR
601#if 0
602unsigned long
603sign_ext (x, len)
604 unsigned int x, len;
09f080a5
KR
605{
606 unsigned int sign;
607 unsigned int result;
608 unsigned int len_ones;
609 int i;
610
611 i = 0;
612 len_ones = 0;
7050286d
KR
613 while (i < len)
614 {
615 len_ones = (len_ones << 1) | 1;
616 i++;
617 }
09f080a5 618
7050286d 619 sign = (x >> (len - 1)) & 1;
09f080a5 620
7050286d
KR
621 if (sign)
622 result = (~0 ^ len_ones) | (len_ones & x);
09f080a5
KR
623 else
624 result = len_ones & x;
625
626 return result;
627}
628
7050286d
KR
629#endif
630static unsigned long
631sign_ext (x, len)
632 unsigned int x, len;
633{
634 return (x << (32 - len)) >> (32 - len);
635}
636
637static unsigned int
638ones (n)
09f080a5
KR
639 int n;
640{
641 unsigned int len_ones;
642 int i;
643
644 i = 0;
645 len_ones = 0;
7050286d
KR
646 while (i < n)
647 {
648 len_ones = (len_ones << 1) | 1;
649 i++;
650 }
09f080a5
KR
651
652 return len_ones;
653}
654
7050286d
KR
655void
656sign_unext (x, len, result)
657 unsigned int x, len;
09f080a5
KR
658 unsigned int *result;
659{
660 unsigned int len_ones;
661
7050286d 662 len_ones = ones (len);
09f080a5
KR
663
664 *result = x & len_ones;
665}
666
7050286d
KR
667unsigned long
668low_sign_ext (x, len)
669 unsigned int x, len;
09f080a5 670{
7050286d 671 unsigned int temp1, temp2;
09f080a5
KR
672 unsigned int len_ones;
673
7050286d 674 len_ones = ones (len);
09f080a5 675
7050286d
KR
676 temp1 = (x & 1) << (len - 1);
677 temp2 = ((x & 0xfffffffe) & len_ones) >> 1;
678 return sign_ext ((temp1 | temp2), len);
09f080a5
KR
679}
680
7050286d
KR
681void
682low_sign_unext (x, len, result)
683 unsigned int x, len;
09f080a5
KR
684 unsigned int *result;
685{
686 unsigned int temp;
687 unsigned int sign;
688 unsigned int rest;
689 unsigned int one_bit_at_len;
690 unsigned int len_ones;
691
7050286d
KR
692 len_ones = ones (len);
693 one_bit_at_len = 1 << (len - 1);
09f080a5 694
7050286d 695 sign_unext (x, len, &temp);
09f080a5 696 sign = temp & one_bit_at_len;
7050286d 697 sign >>= (len - 1);
09f080a5 698
7050286d 699 rest = temp & (len_ones ^ one_bit_at_len);
09f080a5
KR
700 rest <<= 1;
701
702 *result = rest | sign;
703}
704
705/* These work when 'y' is a power of two only. */
706
7050286d
KR
707static long
708round_down (x, y)
709 long x, y;
09f080a5 710{
7050286d 711 return x & ~(y - 1);
09f080a5
KR
712}
713
7050286d
KR
714static long
715round (x, y)
716 long x, y;
09f080a5 717{
7050286d 718 return (x + y / 2) & ~(y - 1);
09f080a5
KR
719}
720
7050286d
KR
721static long
722round_up (x, y)
723 long x, y;
09f080a5 724{
7050286d 725 return x - (x | ~(y - 1));
09f080a5
KR
726}
727
728/* L(Symbol, Addend): */
729/* round_down (Symbol + Addend, 2048) */
730
7050286d
KR
731static long
732L (Symbol, Addend)
09f080a5 733{
7050286d 734 return (round_down (Symbol + Addend, 2048)) >> 11;
09f080a5
KR
735}
736
737/* R(Symbol, Addend): */
738/* Symbol + Addend - round_down (Symbol + Addend, 2048) */
739
7050286d
KR
740static long
741R (Symbol, Addend)
09f080a5 742{
7050286d 743 return Symbol + Addend - round_down (Symbol + Addend, 2048);
09f080a5
KR
744}
745
746/* LS(Symbol, Addend): */
747/* round (Symbol + Addend, 2048) */
748
7050286d
KR
749static long
750LS (Symbol, Addend)
09f080a5 751{
7050286d 752 return round (Symbol + Addend, 2048);
09f080a5
KR
753}
754
755/* RS(Symbol, Addend): */
756/* Symbol + Addend - round (Symbol + Addend, 2048) */
757
7050286d
KR
758static long
759RS (Symbol, Addend)
09f080a5 760{
7050286d 761 return Symbol + Addend - round (Symbol + Addend, 2048);
09f080a5
KR
762}
763
764/* LD(Symbol, Addend): */
765/* round_up (Symbol + Addend, 2048) */
766
7050286d
KR
767static long
768LD (Symbol, Addend)
09f080a5 769{
7050286d 770 return (round_up (Symbol + Addend, 2048)) >> 11;
09f080a5
KR
771}
772
773/* RD(Symbol, Addend): */
774/* Symbol + Addend - round_up (Symbol + Addend, 2048) */
775
7050286d
KR
776static long
777RD (Symbol, Addend)
09f080a5 778{
7050286d 779 return Symbol + Addend - round_up (Symbol + Addend, 2048);
09f080a5
KR
780}
781
782/* LR(Symbol, Addend): */
783/* round_down (Symbol, 2048) + round (Addend, 8192) */
784
7050286d
KR
785static long
786LR (Symbol, Addend)
09f080a5 787{
7050286d 788 return (round_down (Symbol, 2048) + round (Addend, 8192)) >> 11;
09f080a5
KR
789}
790
791/* RR(Symbol, Addend): */
792/* Symbol - round_down (Symbol, 2048) + */
793/* Addend - round (Addend, 8192) */
794
7050286d
KR
795static long
796RR (Symbol, Addend)
09f080a5 797{
7050286d
KR
798 return Symbol
799 - round_down (Symbol, 2048)
800 + Addend - round (Addend, 8192);
09f080a5
KR
801}
802
803unsigned long
77478127
SG
804hppa_field_adjust (value, constant_value, r_field)
805 unsigned long value;
806 unsigned long constant_value;
807 unsigned short r_field;
09f080a5 808{
7050286d
KR
809 unsigned long init_value = value;
810 value += constant_value;
811 switch (r_field)
812 {
813 case e_fsel: /* F : no change */
814 break;
09f080a5 815
7050286d 816 case e_lssel: /* LS : if (bit 21) then add 0x800
09f080a5 817 arithmetic shift right 11 bits */
7050286d
KR
818 if (value & 0x00000400)
819 value += 0x800;
820 value = (value & 0xfffff800) >> 11;
821 BFD_ASSERT (value == LS (init_value, constant_value));
822 break;
823
824 case e_rssel: /* RS : Sign extend from bit 21 */
825 if (value & 0x00000400)
826 value |= 0xfffff800;
827 else
828 value &= 0x7ff;
829 BFD_ASSERT (value == RS (init_value, constant_value));
830 break;
831
832 case e_lsel: /* L : Arithmetic shift right 11 bits */
833 value = (value & 0xfffff800) >> 11;
834 BFD_ASSERT (value == L (init_value, constant_value));
835 break;
836
837 case e_rsel: /* R : Set bits 0-20 to zero */
838 value = value & 0x7ff;
839 BFD_ASSERT (value == R (init_value, constant_value));
840 break;
841
842 case e_ldsel: /* LD : Add 0x800, arithmetic shift
09f080a5 843 right 11 bits */
7050286d
KR
844 value += 0x800;
845 value = (value & 0xfffff800) >> 11;
846 BFD_ASSERT (value == LD (init_value, constant_value));
847 break;
09f080a5 848
7050286d
KR
849 case e_rdsel: /* RD : Set bits 0-20 to one */
850 value |= 0xfffff800;
851 BFD_ASSERT (value == RD (init_value, constant_value));
852 break;
853
854 case e_lrsel: /* LR : L with "rounded" constant */
855 value = value + ((constant_value + 0x1000) & 0xffffe000);
856 value = (value & 0xfffff800) >> 11;
857 BFD_ASSERT (value == LR (init_value, constant_value));
858 break;
859
860 case e_rrsel: /* RR : R with "rounded" constant */
861 value = value + ((constant_value + 0x1000) & 0xffffe000);
862 value = (value & 0x7ff) + constant_value - ((constant_value + 0x1000) & 0xffffe000);
863 BFD_ASSERT (value == RR (init_value, constant_value));
864 break;
865
866 default:
867 fprintf (stderr, "Unrecognized field_selector 0x%02x\n", r_field);
868 break;
869 }
09f080a5 870 return value;
7050286d 871
09f080a5
KR
872}
873
42d83993
SG
874/* Return information about SOM symbol SYMBOL in RET. */
875
876static void
877hppa_get_symbol_info (ignore_abfd, symbol, ret)
878 bfd *ignore_abfd; /* Ignored. */
879 asymbol *symbol;
880 symbol_info *ret;
881{
882 bfd_symbol_info (symbol, ret);
883}
884
09f080a5 885/* End of miscellaneous support functions. */
d325e28c 886
e3c01e92
SG
887#define hppa_bfd_debug_info_start bfd_void
888#define hppa_bfd_debug_info_end bfd_void
889#define hppa_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
890
e3c01e92
SG
891#define hppa_openr_next_archived_file bfd_generic_openr_next_archived_file
892#define hppa_generic_stat_arch_elt bfd_generic_stat_arch_elt
893#define hppa_slurp_armap bfd_false
894#define hppa_slurp_extended_name_table _bfd_slurp_extended_name_table
895#define hppa_truncate_arname (void (*)())bfd_nullvoidptr
896#define hppa_write_armap 0
897
898#define hppa_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
899#define hppa_close_and_cleanup bfd_generic_close_and_cleanup
900#define hppa_get_section_contents bfd_generic_get_section_contents
901
902#define hppa_bfd_get_relocated_section_contents \
903 bfd_generic_get_relocated_section_contents
904#define hppa_bfd_relax_section bfd_generic_relax_section
0c2fae09 905#define hppa_bfd_seclet_link bfd_generic_seclet_link
8feff717
ILT
906#define hppa_bfd_reloc_type_lookup \
907 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
908#define hppa_bfd_make_debug_symbol \
909 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
e3c01e92 910
a643e626
ILT
911/* Core file support is in the hpux-core backend. */
912#define hppa_core_file_failing_command _bfd_dummy_core_file_failing_command
913#define hppa_core_file_failing_signal _bfd_dummy_core_file_failing_signal
914#define hppa_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
915
e3c01e92
SG
916bfd_target hppa_vec =
917{
918 "hppa", /* name */
919 bfd_target_hppa_flavour,
920 true, /* target byte order */
921 true, /* target headers byte order */
922 (HAS_RELOC | EXEC_P | /* object flags */
923 HAS_LINENO | HAS_DEBUG |
924 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
7050286d
KR
925 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
926 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
4e98653c 927
7050286d 928/* leading_symbol_char: is the first char of a user symbol
4e98653c 929 predictable, and if so what is it */
7050286d 930 0,
e3c01e92
SG
931 ' ', /* ar_pad_char */
932 16, /* ar_max_namelen */
7050286d
KR
933 3, /* minimum alignment */
934 _do_getb64, _do_getb_signed_64, _do_putb64,
935 _do_getb32, _do_getb_signed_32, _do_putb32,
936 _do_getb16, _do_getb_signed_16, _do_putb16, /* data */
937 _do_getb64, _do_getb_signed_64, _do_putb64,
938 _do_getb32, _do_getb_signed_32, _do_putb32,
939 _do_getb16, _do_getb_signed_16, _do_putb16, /* hdrs */
940 {_bfd_dummy_target,
941 hppa_object_p, /* bfd_check_format */
942 bfd_generic_archive_p,
e2a422b8 943 _bfd_dummy_target
7050286d 944 },
e3c01e92
SG
945 {
946 bfd_false,
7050286d 947 hppa_mkobject,
e3c01e92
SG
948 _bfd_generic_mkarchive,
949 bfd_false
7050286d 950 },
e3c01e92
SG
951 {
952 bfd_false,
953 hppa_write_object_contents,
954 _bfd_write_archive_contents,
955 bfd_false,
956 },
acc7c493 957#undef hppa
7050286d 958 JUMP_TABLE (hppa),
8feff717 959 (PTR) 0
e3c01e92
SG
960};
961
9a5e3a9a 962#endif /* HOST_HPPAHPUX || HOST_HPPABSD */
This page took 0.100328 seconds and 4 git commands to generate.