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