version number updated following 2.2 release
[deliverable/binutils-gdb.git] / bfd / som.c
CommitLineData
d9ad93bc
KR
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
9e16fcf1 7 This file is part of BFD, the Binary File Descriptor library.
d9ad93bc 8
9e16fcf1
SG
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.
d9ad93bc 13
9e16fcf1
SG
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.
d9ad93bc 18
9e16fcf1
SG
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. */
d9ad93bc
KR
22
23#include "bfd.h"
24#include "sysdep.h"
25
d9ad93bc
KR
26#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD)
27
28#include "libbfd.h"
29#include "som.h"
70f1d738 30#include "libhppa.h"
d9ad93bc
KR
31
32#include <stdio.h>
33#include <sys/types.h>
34#include <sys/param.h>
35#include <sys/dir.h>
36#include <signal.h>
37#include <machine/reg.h>
38#include <sys/user.h> /* After a.out.h */
39#include <sys/file.h>
40#include <errno.h>
41
42/* Magic not defined in standard HP-UX header files until 8.0 */
43
44#ifndef CPU_PA_RISC1_0
45#define CPU_PA_RISC1_0 0x20B
46#endif /* CPU_PA_RISC1_0 */
47
48#ifndef CPU_PA_RISC1_1
49#define CPU_PA_RISC1_1 0x210
50#endif /* CPU_PA_RISC1_1 */
51
52#ifndef _PA_RISC1_0_ID
53#define _PA_RISC1_0_ID CPU_PA_RISC1_0
54#endif /* _PA_RISC1_0_ID */
55
56#ifndef _PA_RISC1_1_ID
57#define _PA_RISC1_1_ID CPU_PA_RISC1_1
58#endif /* _PA_RISC1_1_ID */
59
60#ifndef _PA_RISC_MAXID
61#define _PA_RISC_MAXID 0x2FF
62#endif /* _PA_RISC_MAXID */
63
64#ifndef _PA_RISC_ID
65#define _PA_RISC_ID(__m_num) \
66 (((__m_num) == _PA_RISC1_0_ID) || \
67 ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID))
68#endif /* _PA_RISC_ID */
69
4fdb66cd
JL
70/* SOM allows any one of the four previous relocations to be reused
71 with a "R_PREV_FIXUP" relocation entry. Since R_PREV_FIXUP
72 relocations are always a single byte, using a R_PREV_FIXUP instead
73 of some multi-byte relocation makes object files smaller.
74
75 Note one side effect of using a R_PREV_FIXUP is the relocation that
76 is being repeated moves to the front of the queue. */
77struct reloc_queue
78 {
79 unsigned char *reloc;
80 unsigned int size;
81 } reloc_queue[4];
82
83/* This fully describes the symbol types which may be attached to
84 an EXPORT or IMPORT directive. Only SOM uses this formation
85 (ELF has no need for it). */
86typedef enum
87{
88 SYMBOL_TYPE_UNKNOWN,
89 SYMBOL_TYPE_ABSOLUTE,
90 SYMBOL_TYPE_CODE,
91 SYMBOL_TYPE_DATA,
92 SYMBOL_TYPE_ENTRY,
93 SYMBOL_TYPE_MILLICODE,
94 SYMBOL_TYPE_PLABEL,
95 SYMBOL_TYPE_PRI_PROG,
96 SYMBOL_TYPE_SEC_PROG,
97} pa_symbol_type;
98
9e16fcf1
SG
99/* Forward declarations */
100
101static boolean som_mkobject PARAMS ((bfd *));
102static bfd_target * som_object_setup PARAMS ((bfd *,
103 struct header *,
104 struct som_exec_auxhdr *));
105static asection * make_unique_section PARAMS ((bfd *, CONST char *, int));
106static boolean setup_sections PARAMS ((bfd *, struct header *));
107static bfd_target * som_object_p PARAMS ((bfd *));
108static boolean som_write_object_contents PARAMS ((bfd *));
109static boolean som_slurp_string_table PARAMS ((bfd *));
110static unsigned int som_slurp_symbol_table PARAMS ((bfd *));
111static unsigned int som_get_symtab_upper_bound PARAMS ((bfd *));
112static unsigned int som_canonicalize_reloc PARAMS ((bfd *, sec_ptr,
113 arelent **, asymbol **));
114static unsigned int som_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
115static unsigned int som_get_symtab PARAMS ((bfd *, asymbol **));
116static asymbol * som_make_empty_symbol PARAMS ((bfd *));
117static void som_print_symbol PARAMS ((bfd *, PTR,
118 asymbol *, bfd_print_symbol_type));
119static boolean som_new_section_hook PARAMS ((bfd *, asection *));
120static boolean som_set_section_contents PARAMS ((bfd *, sec_ptr, PTR,
121 file_ptr, bfd_size_type));
122static boolean som_set_arch_mach PARAMS ((bfd *, enum bfd_architecture,
123 unsigned long));
124static boolean som_find_nearest_line PARAMS ((bfd *, asection *,
125 asymbol **, bfd_vma,
126 CONST char **,
127 CONST char **,
128 unsigned int *));
129static void som_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
130static asection * som_section_from_subspace_index PARAMS ((bfd *,
131 unsigned int));
132static int log2 PARAMS ((unsigned int));
133
134
135/* Return the logarithm of X, base 2, considering X unsigned.
40249bfb
JL
136 Abort if X is not a power of two -- this should never happen (FIXME:
137 It will happen on corrupt executables. GDB should give an error, not
138 a coredump, in that case). */
9e16fcf1
SG
139
140static int
141log2 (x)
142 unsigned int x;
143{
144 int log = 0;
145
146 /* Test for 0 or a power of 2. */
147 if (x == 0 || x != (x & -x))
148 abort();
149
150 while ((x >>= 1) != 0)
151 log++;
152 return log;
153}
154
155/* Perform some initialization for an object. Save results of this
156 initialization in the BFD. */
d9ad93bc
KR
157
158static bfd_target *
9e16fcf1 159som_object_setup (abfd, file_hdrp, aux_hdrp)
d9ad93bc
KR
160 bfd *abfd;
161 struct header *file_hdrp;
162 struct som_exec_auxhdr *aux_hdrp;
163{
d9ad93bc
KR
164 asection *text, *data, *bss;
165
9e16fcf1
SG
166 /* som_mkobject will set bfd_error if som_mkobject fails. */
167 if (som_mkobject (abfd) != true)
168 return 0;
d9ad93bc 169
9e16fcf1
SG
170 /* Make the standard .text, .data, and .bss sections so that tools
171 which assume those names work (size for example). They will have
172 no contents, but the sizes and such will reflect those of the
173 $CODE$, $DATA$, and $BSS$ subspaces respectively.
d9ad93bc 174
9e16fcf1 175 FIXME: Should check return status from bfd_make_section calls below. */
d9ad93bc
KR
176
177 text = bfd_make_section (abfd, ".text");
178 data = bfd_make_section (abfd, ".data");
179 bss = bfd_make_section (abfd, ".bss");
180
181 text->_raw_size = aux_hdrp->exec_tsize;
182 data->_raw_size = aux_hdrp->exec_dsize;
183 bss->_raw_size = aux_hdrp->exec_bsize;
184
9e16fcf1 185 text->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_CODE);
d9ad93bc
KR
186 data->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS);
187 bss->flags = (SEC_ALLOC | SEC_IS_COMMON);
188
189 /* The virtual memory addresses of the sections */
190 text->vma = aux_hdrp->exec_tmem;
191 data->vma = aux_hdrp->exec_dmem;
192 bss->vma = aux_hdrp->exec_bfill;
193
194 /* The file offsets of the sections */
195 text->filepos = aux_hdrp->exec_tfile;
196 data->filepos = aux_hdrp->exec_dfile;
197
198 /* The file offsets of the relocation info */
199 text->rel_filepos = 0;
200 data->rel_filepos = 0;
201
9e16fcf1
SG
202 /* Set BFD flags based on what information is available in the SOM. */
203 abfd->flags = NO_FLAGS;
204 if (! file_hdrp->entry_offset)
205 abfd->flags |= HAS_RELOC;
206 else
207 abfd->flags |= EXEC_P;
208 if (file_hdrp->symbol_total)
209 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
210
211 bfd_get_start_address (abfd) = aux_hdrp->exec_entry;
212 bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 0);
d9ad93bc 213 bfd_get_symcount (abfd) = file_hdrp->symbol_total;
9e16fcf1
SG
214
215 /* Initialize the saved symbol table and string table to NULL.
216 Save important offsets and sizes from the SOM header into
217 the BFD. */
218 obj_som_stringtab (abfd) = (char *) NULL;
219 obj_som_symtab (abfd) = (som_symbol_type *) NULL;
220 obj_som_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
221 obj_som_sym_filepos (abfd) = file_hdrp->symbol_location;
222 obj_som_str_filepos (abfd) = file_hdrp->symbol_strings_location;
223 obj_som_reloc_filepos (abfd) = file_hdrp->fixup_request_location;
d9ad93bc
KR
224
225 return abfd->xvec;
226}
227
228/* Create a new BFD section for NAME. If NAME already exists, then create a
229 new unique name, with NAME as the prefix. This exists because SOM .o files
9e16fcf1 230 may have more than one $CODE$ subspace. */
d9ad93bc
KR
231
232static asection *
233make_unique_section (abfd, name, num)
234 bfd *abfd;
235 CONST char *name;
236 int num;
237{
238 asection *sect;
239 char *newname;
240 char altname[100];
241
242 sect = bfd_make_section (abfd, name);
243 while (!sect)
244 {
245 sprintf (altname, "%s-%d", name, num++);
246 sect = bfd_make_section (abfd, altname);
247 }
248
249 newname = bfd_alloc (abfd, strlen (sect->name) + 1);
250 strcpy (newname, sect->name);
251
252 sect->name = newname;
253 return sect;
254}
255
256/* Convert all of the space and subspace info into BFD sections. Each space
257 contains a number of subspaces, which in turn describe the mapping between
258 regions of the exec file, and the address space that the program runs in.
259 BFD sections which correspond to spaces will overlap the sections for the
260 associated subspaces. */
261
9e16fcf1 262static boolean
d9ad93bc
KR
263setup_sections (abfd, file_hdr)
264 bfd *abfd;
265 struct header *file_hdr;
266{
267 char *space_strings;
268 int space_index;
9e16fcf1 269 unsigned int total_subspaces = 0;
d9ad93bc
KR
270
271 /* First, read in space names */
272
273 space_strings = alloca (file_hdr->space_strings_size);
274 if (!space_strings)
9e16fcf1 275 return false;
d9ad93bc
KR
276
277 if (bfd_seek (abfd, file_hdr->space_strings_location, SEEK_SET) < 0)
9e16fcf1 278 return false;
d9ad93bc
KR
279 if (bfd_read (space_strings, 1, file_hdr->space_strings_size, abfd)
280 != file_hdr->space_strings_size)
9e16fcf1 281 return false;
d9ad93bc
KR
282
283 /* Loop over all of the space dictionaries, building up sections */
d9ad93bc
KR
284 for (space_index = 0; space_index < file_hdr->space_total; space_index++)
285 {
286 struct space_dictionary_record space;
9e16fcf1
SG
287 struct subspace_dictionary_record subspace, save_subspace;
288 int subspace_index;
d9ad93bc
KR
289 asection *space_asect;
290
291 /* Read the space dictionary element */
292 if (bfd_seek (abfd, file_hdr->space_location
293 + space_index * sizeof space, SEEK_SET) < 0)
9e16fcf1 294 return false;
d9ad93bc 295 if (bfd_read (&space, 1, sizeof space, abfd) != sizeof space)
9e16fcf1 296 return false;
d9ad93bc
KR
297
298 /* Setup the space name string */
299 space.name.n_name = space.name.n_strx + space_strings;
300
301 /* Make a section out of it */
302 space_asect = make_unique_section (abfd, space.name.n_name, space_index);
303 if (!space_asect)
9e16fcf1 304 return false;
d9ad93bc
KR
305
306 /* Now, read in the first subspace for this space */
307 if (bfd_seek (abfd, file_hdr->subspace_location
308 + space.subspace_index * sizeof subspace,
309 SEEK_SET) < 0)
9e16fcf1 310 return false;
d9ad93bc 311 if (bfd_read (&subspace, 1, sizeof subspace, abfd) != sizeof subspace)
9e16fcf1 312 return false;
d9ad93bc
KR
313 /* Seek back to the start of the subspaces for loop below */
314 if (bfd_seek (abfd, file_hdr->subspace_location
315 + space.subspace_index * sizeof subspace,
316 SEEK_SET) < 0)
9e16fcf1 317 return false;
d9ad93bc
KR
318
319 /* Setup the start address and file loc from the first subspace record */
320 space_asect->vma = subspace.subspace_start;
321 space_asect->filepos = subspace.file_loc_init_value;
9e16fcf1
SG
322 space_asect->alignment_power = log2 (subspace.alignment);
323
324 /* Initialize save_subspace so we can reliably determine if this
325 loop placed any useful values into it. */
326 bzero (&save_subspace, sizeof (struct subspace_dictionary_record));
d9ad93bc
KR
327
328 /* Loop over the rest of the subspaces, building up more sections */
329 for (subspace_index = 0; subspace_index < space.subspace_quantity;
330 subspace_index++)
331 {
332 asection *subspace_asect;
333
334 /* Read in the next subspace */
335 if (bfd_read (&subspace, 1, sizeof subspace, abfd)
336 != sizeof subspace)
9e16fcf1 337 return false;
d9ad93bc
KR
338
339 /* Setup the subspace name string */
340 subspace.name.n_name = subspace.name.n_strx + space_strings;
341
342 /* Make a section out of this subspace */
343 subspace_asect = make_unique_section (abfd, subspace.name.n_name,
344 space.subspace_index + subspace_index);
345
346 if (!subspace_asect)
9e16fcf1
SG
347 return false;
348
349 /* Keep an easy mapping between subspaces and sections. */
350 som_section_data (subspace_asect)->subspace_index
351 = total_subspaces++;
352
353 /* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified
354 by the access_control_bits in the subspace header. */
355 switch (subspace.access_control_bits >> 4)
356 {
357 /* Readonly data. */
358 case 0x0:
359 subspace_asect->flags |= SEC_DATA | SEC_READONLY;
360 break;
361
362 /* Normal data. */
363 case 0x1:
364 subspace_asect->flags |= SEC_DATA;
365 break;
366
367 /* Readonly code and the gateways.
368 Gateways have other attributes which do not map
369 into anything BFD knows about. */
370 case 0x2:
371 case 0x4:
372 case 0x5:
373 case 0x6:
374 case 0x7:
375 subspace_asect->flags |= SEC_CODE | SEC_READONLY;
376 break;
377
378 /* dynamic (writable) code. */
379 case 0x3:
380 subspace_asect->flags |= SEC_CODE;
381 break;
382 }
383
384 if (subspace.dup_common || subspace.is_common)
385 subspace_asect->flags |= SEC_IS_COMMON;
386 else
387 subspace_asect->flags |= SEC_HAS_CONTENTS;
d9ad93bc
KR
388 if (subspace.is_loadable)
389 subspace_asect->flags |= SEC_ALLOC | SEC_LOAD;
390 if (subspace.code_only)
391 subspace_asect->flags |= SEC_CODE;
392
9e16fcf1
SG
393 /* This subspace has relocations.
394 The fixup_request_quantity is a byte count for the number of
395 entries in the relocation stream; it is not the actual number
396 of relocations in the subspace. */
397 if (subspace.fixup_request_quantity != 0)
398 {
399 subspace_asect->flags |= SEC_RELOC;
400 subspace_asect->rel_filepos = subspace.fixup_request_index;
401 som_section_data (subspace_asect)->reloc_size
402 = subspace.fixup_request_quantity;
403 /* We can not determine this yet. When we read in the
404 relocation table the correct value will be filled in. */
405 subspace_asect->reloc_count = -1;
406 }
407
408 /* Update save_subspace if appropriate. */
409 if (subspace.file_loc_init_value > save_subspace.file_loc_init_value)
410 save_subspace = subspace;
411
d9ad93bc
KR
412 subspace_asect->vma = subspace.subspace_start;
413 subspace_asect->_cooked_size = subspace.subspace_length;
414 subspace_asect->_raw_size = subspace.initialization_length;
9e16fcf1 415 subspace_asect->alignment_power = log2 (subspace.alignment);
d9ad93bc 416 subspace_asect->filepos = subspace.file_loc_init_value;
d9ad93bc 417 }
9e16fcf1
SG
418
419 /* Yow! there is no subspace within the space which actually
420 has initialized information in it; this should never happen
421 as far as I know. */
422 if (!save_subspace.file_loc_init_value)
423 abort ();
424
d9ad93bc 425 /* Setup the sizes for the space section based upon the info in the
9e16fcf1
SG
426 last subspace of the space. */
427 space_asect->_cooked_size = save_subspace.subspace_start
428 - space_asect->vma + save_subspace.subspace_length;
429 space_asect->_raw_size = save_subspace.file_loc_init_value
430 - space_asect->filepos + save_subspace.initialization_length;
d9ad93bc 431 }
9e16fcf1 432 return true;
d9ad93bc
KR
433}
434
9e16fcf1
SG
435/* Read in a SOM object and make it into a BFD. */
436
d9ad93bc 437static bfd_target *
9e16fcf1 438som_object_p (abfd)
d9ad93bc
KR
439 bfd *abfd;
440{
441 struct header file_hdr;
442 struct som_exec_auxhdr aux_hdr;
443
444 if (bfd_read ((PTR) & file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
9e16fcf1
SG
445 {
446 bfd_error = system_call_error;
447 return 0;
448 }
d9ad93bc
KR
449
450 if (!_PA_RISC_ID (file_hdr.system_id))
451 {
452 bfd_error = wrong_format;
453 return 0;
454 }
455
456 switch (file_hdr.a_magic)
457 {
9e16fcf1 458 case RELOC_MAGIC:
d9ad93bc
KR
459 case EXEC_MAGIC:
460 case SHARE_MAGIC:
461 case DEMAND_MAGIC:
462#ifdef DL_MAGIC
463 case DL_MAGIC:
464#endif
465#ifdef SHL_MAGIC
466 case SHL_MAGIC:
9e16fcf1
SG
467#endif
468#ifdef EXECLIBMAGIC
469 case EXECLIBMAGIC:
d9ad93bc
KR
470#endif
471 break;
472 default:
473 bfd_error = wrong_format;
474 return 0;
475 }
476
477 if (file_hdr.version_id != VERSION_ID
478 && file_hdr.version_id != NEW_VERSION_ID)
479 {
480 bfd_error = wrong_format;
481 return 0;
482 }
483
9e16fcf1
SG
484 /* If the aux_header_size field in the file header is zero, then this
485 object is an incomplete executable (a .o file). Do not try to read
486 a non-existant auxiliary header. */
487 bzero (&aux_hdr, sizeof (struct som_exec_auxhdr));
488 if (file_hdr.aux_header_size != 0)
489 {
490 if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
491 {
492 bfd_error = wrong_format;
493 return 0;
494 }
495 }
d9ad93bc
KR
496
497 if (!setup_sections (abfd, &file_hdr))
9e16fcf1
SG
498 {
499 /* setup_sections does not bubble up a bfd error code. */
500 bfd_error = bad_value;
501 return 0;
502 }
d9ad93bc 503
9e16fcf1
SG
504 /* This appears to be a valid SOM object. Do some initialization. */
505 return som_object_setup (abfd, &file_hdr, &aux_hdr);
d9ad93bc
KR
506}
507
9e16fcf1
SG
508/* Create a SOM object. */
509
d9ad93bc 510static boolean
9e16fcf1 511som_mkobject (abfd)
d9ad93bc
KR
512 bfd *abfd;
513{
9e16fcf1
SG
514 /* Allocate memory to hold backend information. */
515 abfd->tdata.som_data = (struct som_data_struct *)
516 bfd_zalloc (abfd, sizeof (struct som_data_struct));
517 if (abfd->tdata.som_data == NULL)
518 {
519 bfd_error = no_memory;
520 return false;
521 }
522 obj_som_file_hdr (abfd) = bfd_zalloc (abfd, sizeof (struct header));
523 if (obj_som_file_hdr (abfd) == NULL)
524
525 {
526 bfd_error = no_memory;
527 return false;
528 }
529 return true;
d9ad93bc
KR
530}
531
532boolean
9e16fcf1 533som_write_object_contents (abfd)
d9ad93bc
KR
534 bfd *abfd;
535{
9e16fcf1 536 fprintf (stderr, "som_write_object_contents unimplemented\n");
d9ad93bc
KR
537 fflush (stderr);
538 abort ();
539 return (false);
540}
9e16fcf1 541/* Read and save the string table associated with the given BFD. */
d9ad93bc 542
9e16fcf1
SG
543static boolean
544som_slurp_string_table (abfd)
d9ad93bc
KR
545 bfd *abfd;
546{
9e16fcf1
SG
547 char *stringtab;
548
549 /* Use the saved version if its available. */
550 if (obj_som_stringtab (abfd) != NULL)
551 return true;
552
553 /* Allocate and read in the string table. */
554 stringtab = bfd_zalloc (abfd, obj_som_stringtab_size (abfd));
555 if (stringtab == NULL)
556 {
557 bfd_error = no_memory;
558 return false;
559 }
560
561 if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) < 0)
562 {
563 bfd_error = system_call_error;
564 return false;
565 }
566
567 if (bfd_read (stringtab, obj_som_stringtab_size (abfd), 1, abfd)
568 != obj_som_stringtab_size (abfd))
569 {
570 bfd_error = system_call_error;
571 return false;
572 }
573
574 /* Save our results and return success. */
575 obj_som_stringtab (abfd) = stringtab;
576 return true;
d9ad93bc
KR
577}
578
9e16fcf1
SG
579/* Return the amount of data (in bytes) required to hold the symbol
580 table for this object. */
581
d9ad93bc 582static unsigned int
9e16fcf1 583som_get_symtab_upper_bound (abfd)
d9ad93bc 584 bfd *abfd;
d9ad93bc 585{
9e16fcf1
SG
586 if (!som_slurp_symbol_table (abfd))
587 return 0;
588
589 return (bfd_get_symcount (abfd) + 1) * (sizeof (som_symbol_type *));
d9ad93bc
KR
590}
591
9e16fcf1
SG
592/* Convert from a SOM subspace index to a BFD section. */
593
594static asection *
595som_section_from_subspace_index (abfd, index)
596 bfd *abfd;
597 unsigned int index;
598{
599 asection *section;
600
601 for (section = abfd->sections; section != NULL; section = section->next)
602 if (som_section_data (section)->subspace_index == index)
603 return section;
604
605 /* Should never happen. */
606 abort();
607}
608
609/* Read and save the symbol table associated with the given BFD. */
610
d9ad93bc 611static unsigned int
9e16fcf1 612som_slurp_symbol_table (abfd)
d9ad93bc 613 bfd *abfd;
d9ad93bc 614{
9e16fcf1
SG
615 int symbol_count = bfd_get_symcount (abfd);
616 int symsize = sizeof (struct symbol_dictionary_record);
617 char *stringtab;
618 struct symbol_dictionary_record *buf, *bufp, *endbufp;
619 som_symbol_type *sym, *symbase;
620
621 /* Return saved value if it exists. */
622 if (obj_som_symtab (abfd) != NULL)
623 return true;
624
625 /* Sanity checking. Make sure there are some symbols and that
626 we can read the string table too. */
627 if (symbol_count == 0)
628 {
629 bfd_error = no_symbols;
630 return false;
631 }
632
633 if (!som_slurp_string_table (abfd))
634 return false;
635
636 stringtab = obj_som_stringtab (abfd);
637
638 symbase = (som_symbol_type *)
639 bfd_zalloc (abfd, symbol_count * sizeof (som_symbol_type));
640 if (symbase == NULL)
641 {
642 bfd_error = no_memory;
643 return false;
644 }
645
646 /* Read in the external SOM representation. */
647 buf = alloca (symbol_count * symsize);
648 if (buf == NULL)
649 {
650 bfd_error = no_memory;
651 return false;
652 }
653 if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) < 0)
654 {
655 bfd_error = system_call_error;
656 return false;
657 }
658 if (bfd_read (buf, symbol_count * symsize, 1, abfd)
659 != symbol_count * symsize)
660 {
661 bfd_error = no_symbols;
662 return (false);
663 }
664
665 /* Iterate over all the symbols and internalize them. */
666 endbufp = buf + symbol_count;
667 for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp)
668 {
669
670 /* I don't think we care about these. */
671 if (bufp->symbol_type == ST_SYM_EXT
672 || bufp->symbol_type == ST_ARG_EXT)
673 continue;
674
675 /* Some reasonable defaults. */
676 sym->symbol.the_bfd = abfd;
677 sym->symbol.name = bufp->name.n_strx + stringtab;
678 sym->symbol.value = bufp->symbol_value;
679 sym->symbol.section = 0;
680 sym->symbol.flags = 0;
681
682 switch (bufp->symbol_type)
683 {
684 case ST_ENTRY:
685 sym->symbol.flags |= BSF_FUNCTION;
686 sym->symbol.value &= ~0x3;
687 break;
688
689 case ST_PRI_PROG:
690 case ST_SEC_PROG:
691 case ST_STUB:
692 case ST_MILLICODE:
693 case ST_CODE:
694 sym->symbol.value &= ~0x3;
695
696 default:
697 break;
698 }
699
700 /* Handle scoping and section information. */
701 switch (bufp->symbol_scope)
702 {
703 /* symbol_info field is undefined for SS_EXTERNAL and SS_UNSAT symbols,
704 so the section associated with this symbol can't be known. */
705 case SS_EXTERNAL:
706 case SS_UNSAT:
707 sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
708 break;
709
710 case SS_UNIVERSAL:
711 sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
712 sym->symbol.section
713 = som_section_from_subspace_index (abfd, bufp->symbol_info);
714 sym->symbol.value -= sym->symbol.section->vma;
715 break;
716
717#if 0
718 /* SS_GLOBAL and SS_LOCAL are two names for the same thing.
719 Sound dumb? It is. */
720 case SS_GLOBAL:
721#endif
722 case SS_LOCAL:
723 sym->symbol.flags |= BSF_LOCAL;
724 sym->symbol.section
725 = som_section_from_subspace_index (abfd, bufp->symbol_info);
726 sym->symbol.value -= sym->symbol.section->vma;
727 break;
728 }
729
730 /* Mark symbols left around by the debugger. */
731 if (strlen (sym->symbol.name) >= 3
732 && sym->symbol.name[0] == 'L'
733 && (sym->symbol.name[2] == '$' || sym->symbol.name[3] == '$'))
734 sym->symbol.flags |= BSF_DEBUGGING;
735
736 /* Note increment at bottom of loop, since we skip some symbols
737 we can not include it as part of the for statement. */
738 sym++;
739 }
740
741 /* Save our results and return success. */
742 obj_som_symtab (abfd) = symbase;
743 return (true);
d9ad93bc
KR
744}
745
9e16fcf1
SG
746/* Canonicalize a SOM symbol table. Return the number of entries
747 in the symbol table. */
d9ad93bc
KR
748
749static unsigned int
9e16fcf1 750som_get_symtab (abfd, location)
d9ad93bc
KR
751 bfd *abfd;
752 asymbol **location;
753{
9e16fcf1
SG
754 int i;
755 som_symbol_type *symbase;
756
757 if (!som_slurp_symbol_table (abfd))
758 return 0;
759
760 i = bfd_get_symcount (abfd);
761 symbase = obj_som_symtab (abfd);
762
763 for (; i > 0; i--, location++, symbase++)
764 *location = &symbase->symbol;
765
766 /* Final null pointer. */
767 *location = 0;
768 return (bfd_get_symcount (abfd));
d9ad93bc
KR
769}
770
9e16fcf1
SG
771/* Make a SOM symbol. There is nothing special to do here. */
772
d9ad93bc 773static asymbol *
9e16fcf1 774som_make_empty_symbol (abfd)
d9ad93bc
KR
775 bfd *abfd;
776{
9e16fcf1
SG
777 som_symbol_type *new =
778 (som_symbol_type *) bfd_zalloc (abfd, sizeof (som_symbol_type));
779 if (new == NULL)
780 {
781 bfd_error = no_memory;
782 return 0;
783 }
d9ad93bc
KR
784 new->symbol.the_bfd = abfd;
785
786 return &new->symbol;
787}
788
9e16fcf1
SG
789/* Print symbol information. */
790
d9ad93bc 791static void
9e16fcf1 792som_print_symbol (ignore_abfd, afile, symbol, how)
d9ad93bc
KR
793 bfd *ignore_abfd;
794 PTR afile;
795 asymbol *symbol;
796 bfd_print_symbol_type how;
797{
9e16fcf1
SG
798 FILE *file = (FILE *) afile;
799 switch (how)
800 {
801 case bfd_print_symbol_name:
802 fprintf (file, "%s", symbol->name);
803 break;
804 case bfd_print_symbol_more:
805 fprintf (file, "som ");
806 fprintf_vma (file, symbol->value);
807 fprintf (file, " %lx", (long) symbol->flags);
808 break;
809 case bfd_print_symbol_all:
810 {
811 CONST char *section_name;
812 section_name = symbol->section ? symbol->section->name : "(*none*)";
813 bfd_print_symbol_vandf ((PTR) file, symbol);
814 fprintf (file, " %s\t%s", section_name, symbol->name);
815 break;
816 }
817 }
818}
819
820static unsigned int
821som_get_reloc_upper_bound (abfd, asect)
822 bfd *abfd;
823 sec_ptr asect;
824{
825 fprintf (stderr, "som_get_reloc_upper_bound unimplemented\n");
d9ad93bc
KR
826 fflush (stderr);
827 abort ();
9e16fcf1 828 return (0);
d9ad93bc
KR
829}
830
9e16fcf1
SG
831static unsigned int
832som_canonicalize_reloc (abfd, section, relptr, symbols)
833 bfd *abfd;
834 sec_ptr section;
835 arelent **relptr;
836 asymbol **symbols;
837{
838 fprintf (stderr, "som_canonicalize_reloc unimplemented\n");
839 fflush (stderr);
840 abort ();
841}
842
843extern bfd_target som_vec;
844
845/* A hook to set up object file dependent section information. */
846
d9ad93bc 847static boolean
9e16fcf1 848som_new_section_hook (abfd, newsect)
d9ad93bc
KR
849 bfd *abfd;
850 asection *newsect;
851{
9e16fcf1
SG
852 newsect->used_by_bfd = (struct som_section_data_struct *)
853 bfd_zalloc (abfd, sizeof (struct som_section_data_struct));
d9ad93bc
KR
854 newsect->alignment_power = 3;
855
9e16fcf1
SG
856 /* Initialize the subspace_index field to -1 so that it does
857 not match a subspace with an index of 0. */
858 som_section_data (newsect)->subspace_index = -1;
859
d9ad93bc
KR
860 /* We allow more than three sections internally */
861 return true;
862}
863
40249bfb
JL
864/* Set backend info for sections which can not be described
865 in the BFD data structures. */
866
867void
868bfd_som_set_section_attributes (section, defined, private, sort_key, spnum)
869 asection *section;
870 char defined;
871 char private;
872 unsigned char sort_key;
873 int spnum;
874{
875 struct space_dictionary_record *space_dict;
876
877 som_section_data (section)->is_space = 1;
878 space_dict = &som_section_data (section)->space_dict;
879 space_dict->is_defined = defined;
880 space_dict->is_private = private;
881 space_dict->sort_key = sort_key;
882 space_dict->space_number = spnum;
883}
884
885/* Set backend info for subsections which can not be described
886 in the BFD data structures. */
887
888void
889bfd_som_set_subsection_attributes (section, container, access,
890 sort_key, quadrant)
891 asection *section;
892 asection *container;
893 int access;
894 unsigned char sort_key;
895 int quadrant;
896{
897 struct subspace_dictionary_record *subspace_dict;
898 som_section_data (section)->is_subspace = 1;
899 subspace_dict = &som_section_data (section)->subspace_dict;
900 subspace_dict->access_control_bits = access;
901 subspace_dict->sort_key = sort_key;
902 subspace_dict->quadrant = quadrant;
903 som_section_data (section)->containing_space = container;
904}
905
906/* Set the full SOM symbol type. SOM needs far more symbol information
907 than any other object file format I'm aware of. It is mandatory
908 to be able to know if a symbol is an entry point, millicode, data,
909 code, absolute, storage request, or procedure label. If you get
910 the symbol type wrong your program will not link. */
911
912void
913bfd_som_set_symbol_type (symbol, type)
914 asymbol *symbol;
915 unsigned int type;
916{
917 (*som_symbol_data (symbol))->som_type = type;
918}
919
920/* Attach 64bits of unwind information to a symbol (which hopefully
921 is a function of some kind!). It would be better to keep this
922 in the R_ENTRY relocation, but there is not enough space. */
923
924void
925bfd_som_attach_unwind_info (symbol, unwind_desc)
926 asymbol *symbol;
927 char *unwind_desc;
928{
929 (*som_symbol_data (symbol))->unwind = unwind_desc;
930}
931
d9ad93bc 932static boolean
9e16fcf1 933som_set_section_contents (abfd, section, location, offset, count)
d9ad93bc
KR
934 bfd *abfd;
935 sec_ptr section;
936 PTR location;
937 file_ptr offset;
938 bfd_size_type count;
939{
9e16fcf1 940 fprintf (stderr, "som_set_section_contents unimplimented\n");
d9ad93bc
KR
941 fflush (stderr);
942 abort ();
943 return false;
944}
945
946static boolean
9e16fcf1 947som_set_arch_mach (abfd, arch, machine)
d9ad93bc
KR
948 bfd *abfd;
949 enum bfd_architecture arch;
950 unsigned long machine;
951{
9e16fcf1 952 fprintf (stderr, "som_set_arch_mach unimplemented\n");
d9ad93bc 953 fflush (stderr);
9e16fcf1 954 /* Allow any architecture to be supported by the som backend */
d9ad93bc
KR
955 return bfd_default_set_arch_mach (abfd, arch, machine);
956}
957
958static boolean
9e16fcf1 959som_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
d9ad93bc
KR
960 functionname_ptr, line_ptr)
961 bfd *abfd;
962 asection *section;
963 asymbol **symbols;
964 bfd_vma offset;
965 CONST char **filename_ptr;
966 CONST char **functionname_ptr;
967 unsigned int *line_ptr;
968{
9e16fcf1 969 fprintf (stderr, "som_find_nearest_line unimplemented\n");
d9ad93bc
KR
970 fflush (stderr);
971 abort ();
972 return (false);
973}
974
975static int
9e16fcf1 976som_sizeof_headers (abfd, reloc)
d9ad93bc
KR
977 bfd *abfd;
978 boolean reloc;
979{
9e16fcf1 980 fprintf (stderr, "som_sizeof_headers unimplemented\n");
d9ad93bc
KR
981 fflush (stderr);
982 abort ();
983 return (0);
984}
985
986/* Return information about SOM symbol SYMBOL in RET. */
987
988static void
9e16fcf1 989som_get_symbol_info (ignore_abfd, symbol, ret)
d9ad93bc
KR
990 bfd *ignore_abfd; /* Ignored. */
991 asymbol *symbol;
992 symbol_info *ret;
993{
994 bfd_symbol_info (symbol, ret);
995}
996
997/* End of miscellaneous support functions. */
998
9e16fcf1
SG
999#define som_bfd_debug_info_start bfd_void
1000#define som_bfd_debug_info_end bfd_void
1001#define som_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
d9ad93bc 1002
9e16fcf1
SG
1003#define som_openr_next_archived_file bfd_generic_openr_next_archived_file
1004#define som_generic_stat_arch_elt bfd_generic_stat_arch_elt
1005#define som_slurp_armap bfd_false
1006#define som_slurp_extended_name_table _bfd_slurp_extended_name_table
1007#define som_truncate_arname (void (*)())bfd_nullvoidptr
1008#define som_write_armap 0
d9ad93bc 1009
9e16fcf1
SG
1010#define som_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
1011#define som_close_and_cleanup bfd_generic_close_and_cleanup
1012#define som_get_section_contents bfd_generic_get_section_contents
d9ad93bc 1013
9e16fcf1 1014#define som_bfd_get_relocated_section_contents \
d9ad93bc 1015 bfd_generic_get_relocated_section_contents
9e16fcf1
SG
1016#define som_bfd_relax_section bfd_generic_relax_section
1017#define som_bfd_seclet_link bfd_generic_seclet_link
1018#define som_bfd_reloc_type_lookup \
d9ad93bc 1019 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
9e16fcf1 1020#define som_bfd_make_debug_symbol \
d9ad93bc
KR
1021 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
1022
1023/* Core file support is in the hpux-core backend. */
9e16fcf1
SG
1024#define som_core_file_failing_command _bfd_dummy_core_file_failing_command
1025#define som_core_file_failing_signal _bfd_dummy_core_file_failing_signal
1026#define som_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
d9ad93bc 1027
9e16fcf1 1028bfd_target som_vec =
d9ad93bc 1029{
9e16fcf1
SG
1030 "som", /* name */
1031 bfd_target_som_flavour,
d9ad93bc
KR
1032 true, /* target byte order */
1033 true, /* target headers byte order */
1034 (HAS_RELOC | EXEC_P | /* object flags */
1035 HAS_LINENO | HAS_DEBUG |
40249bfb 1036 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
d9ad93bc 1037 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
9e16fcf1 1038 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
d9ad93bc
KR
1039
1040/* leading_symbol_char: is the first char of a user symbol
9e16fcf1 1041 predictable, and if so what is it */
d9ad93bc
KR
1042 0,
1043 ' ', /* ar_pad_char */
1044 16, /* ar_max_namelen */
1045 3, /* minimum alignment */
9e16fcf1
SG
1046 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1047 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1048 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1049 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1050 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1051 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
d9ad93bc 1052 {_bfd_dummy_target,
9e16fcf1 1053 som_object_p, /* bfd_check_format */
d9ad93bc
KR
1054 bfd_generic_archive_p,
1055 _bfd_dummy_target
1056 },
1057 {
1058 bfd_false,
9e16fcf1 1059 som_mkobject,
d9ad93bc
KR
1060 _bfd_generic_mkarchive,
1061 bfd_false
1062 },
1063 {
1064 bfd_false,
9e16fcf1 1065 som_write_object_contents,
d9ad93bc
KR
1066 _bfd_write_archive_contents,
1067 bfd_false,
1068 },
9e16fcf1
SG
1069#undef som
1070 JUMP_TABLE (som),
d9ad93bc
KR
1071 (PTR) 0
1072};
1073
1074#endif /* HOST_HPPAHPUX || HOST_HPPABSD */
This page took 0.077834 seconds and 4 git commands to generate.