aboutsummaryrefslogtreecommitdiff
path: root/bfd/som.c
diff options
context:
space:
mode:
authorStu Grossman <grossman@cygnus>1993-10-26 09:42:15 +0000
committerStu Grossman <grossman@cygnus>1993-10-26 09:42:15 +0000
commit9e16fcf1246cc8d4615568e7724c2d39e753a143 (patch)
treeb174430357e8778a27a5f4452042f4b389c624f4 /bfd/som.c
parent2cdce841c4988c4ad0b45e33fab3c773992f62a3 (diff)
downloadgdb-9e16fcf1246cc8d4615568e7724c2d39e753a143.zip
gdb-9e16fcf1246cc8d4615568e7724c2d39e753a143.tar.gz
gdb-9e16fcf1246cc8d4615568e7724c2d39e753a143.tar.bz2
* som.c (hppa_object_setup): Set SEC_CODE for .text section so
that GDB can figure out text_start and text_end.
Diffstat (limited to 'bfd/som.c')
-rw-r--r--bfd/som.c754
1 files changed, 563 insertions, 191 deletions
diff --git a/bfd/som.c b/bfd/som.c
index 8fd1324..8d6d14d 100644
--- a/bfd/som.c
+++ b/bfd/som.c
@@ -4,29 +4,25 @@
Contributed by the Center for Software Science at the
University of Utah (pa-gdb-bugs@cs.utah.edu).
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "bfd.h"
#include "sysdep.h"
-/* @@FIXME This is not a reasonable set of conditions to permit
- cross-compilation, obviously. It also isn't enough to support hppa-elf
- targets either. Can we eliminate the HPUX or BSD dependencies, or
- at least get the conditionals more localized? */
#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD)
#include "libbfd.h"
@@ -70,59 +66,81 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID))
#endif /* _PA_RISC_ID */
-struct container
- {
- struct header f;
- struct som_exec_auxhdr e;
- };
+/* Forward declarations */
+
+static boolean som_mkobject PARAMS ((bfd *));
+static bfd_target * som_object_setup PARAMS ((bfd *,
+ struct header *,
+ struct som_exec_auxhdr *));
+static asection * make_unique_section PARAMS ((bfd *, CONST char *, int));
+static boolean setup_sections PARAMS ((bfd *, struct header *));
+static bfd_target * som_object_p PARAMS ((bfd *));
+static boolean som_write_object_contents PARAMS ((bfd *));
+static boolean som_slurp_string_table PARAMS ((bfd *));
+static unsigned int som_slurp_symbol_table PARAMS ((bfd *));
+static unsigned int som_get_symtab_upper_bound PARAMS ((bfd *));
+static unsigned int som_canonicalize_reloc PARAMS ((bfd *, sec_ptr,
+ arelent **, asymbol **));
+static unsigned int som_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
+static unsigned int som_get_symtab PARAMS ((bfd *, asymbol **));
+static asymbol * som_make_empty_symbol PARAMS ((bfd *));
+static void som_print_symbol PARAMS ((bfd *, PTR,
+ asymbol *, bfd_print_symbol_type));
+static boolean som_new_section_hook PARAMS ((bfd *, asection *));
+static boolean som_set_section_contents PARAMS ((bfd *, sec_ptr, PTR,
+ file_ptr, bfd_size_type));
+static boolean som_set_arch_mach PARAMS ((bfd *, enum bfd_architecture,
+ unsigned long));
+static boolean som_find_nearest_line PARAMS ((bfd *, asection *,
+ asymbol **, bfd_vma,
+ CONST char **,
+ CONST char **,
+ unsigned int *));
+static void som_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
+static asection * som_section_from_subspace_index PARAMS ((bfd *,
+ unsigned int));
+static int log2 PARAMS ((unsigned int));
+
+
+/* Return the logarithm of X, base 2, considering X unsigned.
+ Abort if X is not a power of two -- this should never happen. */
+
+static int
+log2 (x)
+ unsigned int x;
+{
+ int log = 0;
+
+ /* Test for 0 or a power of 2. */
+ if (x == 0 || x != (x & -x))
+ abort();
+
+ while ((x >>= 1) != 0)
+ log++;
+ return log;
+}
+
+/* Perform some initialization for an object. Save results of this
+ initialization in the BFD. */
static bfd_target *
-hppa_object_setup (abfd, file_hdrp, aux_hdrp)
+som_object_setup (abfd, file_hdrp, aux_hdrp)
bfd *abfd;
struct header *file_hdrp;
struct som_exec_auxhdr *aux_hdrp;
{
- struct container *rawptr;
- struct header *f;
- struct hppa_data_struct *rawptr1;
asection *text, *data, *bss;
- rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
- if (rawptr == NULL)
- {
- bfd_error = no_memory;
- return 0;
- }
-
- rawptr1 = (struct hppa_data_struct *) bfd_zalloc (abfd, sizeof (struct hppa_data_struct));
- if (rawptr1 == NULL)
- {
- bfd_error = no_memory;
- return 0;
- }
-
- abfd->tdata.hppa_data = rawptr1;
- obj_file_hdr (abfd) = &rawptr->f;
- obj_aux_hdr (abfd) = &rawptr->e;
- *obj_file_hdr (abfd) = *file_hdrp;
- *obj_aux_hdr (abfd) = *aux_hdrp;
-
- /* Set the file flags */
- abfd->flags = NO_FLAGS;
- if (file_hdrp->entry_offset)
- abfd->flags |= HAS_RELOC;
- if (file_hdrp->symbol_total)
- abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
-
- bfd_get_start_address (abfd) = aux_hdrp->exec_entry;
-
- obj_pa_symbols (abfd) = (hppa_symbol_type *) NULL;
- bfd_get_symcount (abfd) = file_hdrp->symbol_total;
+ /* som_mkobject will set bfd_error if som_mkobject fails. */
+ if (som_mkobject (abfd) != true)
+ return 0;
- bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 0);
+ /* Make the standard .text, .data, and .bss sections so that tools
+ which assume those names work (size for example). They will have
+ no contents, but the sizes and such will reflect those of the
+ $CODE$, $DATA$, and $BSS$ subspaces respectively.
- /* create the sections. This is raunchy, but bfd_close wants to reclaim
- them */
+ FIXME: Should check return status from bfd_make_section calls below. */
text = bfd_make_section (abfd, ".text");
data = bfd_make_section (abfd, ".data");
@@ -132,7 +150,7 @@ hppa_object_setup (abfd, file_hdrp, aux_hdrp)
data->_raw_size = aux_hdrp->exec_dsize;
bss->_raw_size = aux_hdrp->exec_bsize;
- text->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS);
+ text->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_CODE);
data->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS);
bss->flags = (SEC_ALLOC | SEC_IS_COMMON);
@@ -149,20 +167,35 @@ hppa_object_setup (abfd, file_hdrp, aux_hdrp)
text->rel_filepos = 0;
data->rel_filepos = 0;
- /* The file offsets of the string table and symbol table. */
- obj_sym_filepos (abfd) = file_hdrp->symbol_location;
+ /* Set BFD flags based on what information is available in the SOM. */
+ abfd->flags = NO_FLAGS;
+ if (! file_hdrp->entry_offset)
+ abfd->flags |= HAS_RELOC;
+ else
+ abfd->flags |= EXEC_P;
+ if (file_hdrp->symbol_total)
+ abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
+
+ bfd_get_start_address (abfd) = aux_hdrp->exec_entry;
+ bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 0);
bfd_get_symcount (abfd) = file_hdrp->symbol_total;
- obj_str_filepos (abfd) = file_hdrp->symbol_strings_location;
- obj_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
+
+ /* Initialize the saved symbol table and string table to NULL.
+ Save important offsets and sizes from the SOM header into
+ the BFD. */
+ obj_som_stringtab (abfd) = (char *) NULL;
+ obj_som_symtab (abfd) = (som_symbol_type *) NULL;
+ obj_som_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
+ obj_som_sym_filepos (abfd) = file_hdrp->symbol_location;
+ obj_som_str_filepos (abfd) = file_hdrp->symbol_strings_location;
+ obj_som_reloc_filepos (abfd) = file_hdrp->fixup_request_location;
return abfd->xvec;
}
/* Create a new BFD section for NAME. If NAME already exists, then create a
new unique name, with NAME as the prefix. This exists because SOM .o files
- created by the native compiler can have a $CODE$ section for each
- subroutine.
- */
+ may have more than one $CODE$ subspace. */
static asection *
make_unique_section (abfd, name, num)
@@ -194,41 +227,41 @@ make_unique_section (abfd, name, num)
BFD sections which correspond to spaces will overlap the sections for the
associated subspaces. */
-static int
+static boolean
setup_sections (abfd, file_hdr)
bfd *abfd;
struct header *file_hdr;
{
char *space_strings;
int space_index;
+ unsigned int total_subspaces = 0;
/* First, read in space names */
space_strings = alloca (file_hdr->space_strings_size);
if (!space_strings)
- return 0;
+ return false;
if (bfd_seek (abfd, file_hdr->space_strings_location, SEEK_SET) < 0)
- return 0;
+ return false;
if (bfd_read (space_strings, 1, file_hdr->space_strings_size, abfd)
!= file_hdr->space_strings_size)
- return 0;
+ return false;
/* Loop over all of the space dictionaries, building up sections */
-
for (space_index = 0; space_index < file_hdr->space_total; space_index++)
{
struct space_dictionary_record space;
- struct subspace_dictionary_record subspace;
- int subspace_index, tmp;
+ struct subspace_dictionary_record subspace, save_subspace;
+ int subspace_index;
asection *space_asect;
/* Read the space dictionary element */
if (bfd_seek (abfd, file_hdr->space_location
+ space_index * sizeof space, SEEK_SET) < 0)
- return 0;
+ return false;
if (bfd_read (&space, 1, sizeof space, abfd) != sizeof space)
- return 0;
+ return false;
/* Setup the space name string */
space.name.n_name = space.name.n_strx + space_strings;
@@ -236,33 +269,29 @@ setup_sections (abfd, file_hdr)
/* Make a section out of it */
space_asect = make_unique_section (abfd, space.name.n_name, space_index);
if (!space_asect)
- return 0;
+ return false;
/* Now, read in the first subspace for this space */
if (bfd_seek (abfd, file_hdr->subspace_location
+ space.subspace_index * sizeof subspace,
SEEK_SET) < 0)
- return 0;
+ return false;
if (bfd_read (&subspace, 1, sizeof subspace, abfd) != sizeof subspace)
- return 0;
+ return false;
/* Seek back to the start of the subspaces for loop below */
if (bfd_seek (abfd, file_hdr->subspace_location
+ space.subspace_index * sizeof subspace,
SEEK_SET) < 0)
- return 0;
-
- /* Setup the section flags as appropriate (this is somewhat bogus, as
- there isn't a clear mapping between what's in the space record, and
- what BFD can describe here). */
- if (space.is_loadable)
- space_asect->flags |= SEC_ALLOC;
- if (space.is_defined)
- space_asect->flags |= SEC_LOAD;
+ return false;
/* Setup the start address and file loc from the first subspace record */
space_asect->vma = subspace.subspace_start;
space_asect->filepos = subspace.file_loc_init_value;
- space_asect->alignment_power = subspace.alignment;
+ space_asect->alignment_power = log2 (subspace.alignment);
+
+ /* Initialize save_subspace so we can reliably determine if this
+ loop placed any useful values into it. */
+ bzero (&save_subspace, sizeof (struct subspace_dictionary_record));
/* Loop over the rest of the subspaces, building up more sections */
for (subspace_index = 0; subspace_index < space.subspace_quantity;
@@ -273,7 +302,7 @@ setup_sections (abfd, file_hdr)
/* Read in the next subspace */
if (bfd_read (&subspace, 1, sizeof subspace, abfd)
!= sizeof subspace)
- return 0;
+ return false;
/* Setup the subspace name string */
subspace.name.n_name = subspace.name.n_strx + space_strings;
@@ -283,39 +312,108 @@ setup_sections (abfd, file_hdr)
space.subspace_index + subspace_index);
if (!subspace_asect)
- return 0;
-
+ return false;
+
+ /* Keep an easy mapping between subspaces and sections. */
+ som_section_data (subspace_asect)->subspace_index
+ = total_subspaces++;
+
+ /* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified
+ by the access_control_bits in the subspace header. */
+ switch (subspace.access_control_bits >> 4)
+ {
+ /* Readonly data. */
+ case 0x0:
+ subspace_asect->flags |= SEC_DATA | SEC_READONLY;
+ break;
+
+ /* Normal data. */
+ case 0x1:
+ subspace_asect->flags |= SEC_DATA;
+ break;
+
+ /* Readonly code and the gateways.
+ Gateways have other attributes which do not map
+ into anything BFD knows about. */
+ case 0x2:
+ case 0x4:
+ case 0x5:
+ case 0x6:
+ case 0x7:
+ subspace_asect->flags |= SEC_CODE | SEC_READONLY;
+ break;
+
+ /* dynamic (writable) code. */
+ case 0x3:
+ subspace_asect->flags |= SEC_CODE;
+ break;
+ }
+
+ if (subspace.dup_common || subspace.is_common)
+ subspace_asect->flags |= SEC_IS_COMMON;
+ else
+ subspace_asect->flags |= SEC_HAS_CONTENTS;
if (subspace.is_loadable)
subspace_asect->flags |= SEC_ALLOC | SEC_LOAD;
if (subspace.code_only)
subspace_asect->flags |= SEC_CODE;
+ /* This subspace has relocations.
+ The fixup_request_quantity is a byte count for the number of
+ entries in the relocation stream; it is not the actual number
+ of relocations in the subspace. */
+ if (subspace.fixup_request_quantity != 0)
+ {
+ subspace_asect->flags |= SEC_RELOC;
+ subspace_asect->rel_filepos = subspace.fixup_request_index;
+ som_section_data (subspace_asect)->reloc_size
+ = subspace.fixup_request_quantity;
+ /* We can not determine this yet. When we read in the
+ relocation table the correct value will be filled in. */
+ subspace_asect->reloc_count = -1;
+ }
+
+ /* Update save_subspace if appropriate. */
+ if (subspace.file_loc_init_value > save_subspace.file_loc_init_value)
+ save_subspace = subspace;
+
subspace_asect->vma = subspace.subspace_start;
subspace_asect->_cooked_size = subspace.subspace_length;
subspace_asect->_raw_size = subspace.initialization_length;
- subspace_asect->alignment_power = subspace.alignment;
+ subspace_asect->alignment_power = log2 (subspace.alignment);
subspace_asect->filepos = subspace.file_loc_init_value;
-
}
+
+ /* Yow! there is no subspace within the space which actually
+ has initialized information in it; this should never happen
+ as far as I know. */
+ if (!save_subspace.file_loc_init_value)
+ abort ();
+
/* Setup the sizes for the space section based upon the info in the
- last subspace of the space. */
- space_asect->_cooked_size = (subspace.subspace_start - space_asect->vma)
- + subspace.subspace_length;
- space_asect->_raw_size = (subspace.file_loc_init_value
- - space_asect->filepos)
- + subspace.initialization_length;
+ last subspace of the space. */
+ space_asect->_cooked_size = save_subspace.subspace_start
+ - space_asect->vma + save_subspace.subspace_length;
+ space_asect->_raw_size = save_subspace.file_loc_init_value
+ - space_asect->filepos + save_subspace.initialization_length;
}
+ return true;
}
+/* Read in a SOM object and make it into a BFD. */
+
static bfd_target *
-hppa_object_p (abfd)
+som_object_p (abfd)
bfd *abfd;
{
struct header file_hdr;
struct som_exec_auxhdr aux_hdr;
if (bfd_read ((PTR) & file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
- return 0;
+ {
+ bfd_error = system_call_error;
+ return 0;
+ }
if (!_PA_RISC_ID (file_hdr.system_id))
{
@@ -325,7 +423,7 @@ hppa_object_p (abfd)
switch (file_hdr.a_magic)
{
- case RELOC_MAGIC: /* I'm not really sure about all of these types... */
+ case RELOC_MAGIC:
case EXEC_MAGIC:
case SHARE_MAGIC:
case DEMAND_MAGIC:
@@ -335,6 +433,9 @@ hppa_object_p (abfd)
#ifdef SHL_MAGIC
case SHL_MAGIC:
#endif
+#ifdef EXECLIBMAGIC
+ case EXECLIBMAGIC:
+#endif
break;
default:
bfd_error = wrong_format;
@@ -348,143 +449,414 @@ hppa_object_p (abfd)
return 0;
}
- if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
- bfd_error = wrong_format;
+ /* If the aux_header_size field in the file header is zero, then this
+ object is an incomplete executable (a .o file). Do not try to read
+ a non-existant auxiliary header. */
+ bzero (&aux_hdr, sizeof (struct som_exec_auxhdr));
+ if (file_hdr.aux_header_size != 0)
+ {
+ if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
+ {
+ bfd_error = wrong_format;
+ return 0;
+ }
+ }
if (!setup_sections (abfd, &file_hdr))
- return 0;
+ {
+ /* setup_sections does not bubble up a bfd error code. */
+ bfd_error = bad_value;
+ return 0;
+ }
- return hppa_object_setup (abfd, &file_hdr, &aux_hdr);
+ /* This appears to be a valid SOM object. Do some initialization. */
+ return som_object_setup (abfd, &file_hdr, &aux_hdr);
}
+/* Create a SOM object. */
+
static boolean
-hppa_mkobject (abfd)
+som_mkobject (abfd)
bfd *abfd;
{
- fprintf (stderr, "hppa_mkobject unimplemented\n");
- fflush (stderr);
- abort ();
- return (false);
+ /* Allocate memory to hold backend information. */
+ abfd->tdata.som_data = (struct som_data_struct *)
+ bfd_zalloc (abfd, sizeof (struct som_data_struct));
+ if (abfd->tdata.som_data == NULL)
+ {
+ bfd_error = no_memory;
+ return false;
+ }
+ obj_som_file_hdr (abfd) = bfd_zalloc (abfd, sizeof (struct header));
+ if (obj_som_file_hdr (abfd) == NULL)
+
+ {
+ bfd_error = no_memory;
+ return false;
+ }
+ return true;
}
boolean
-hppa_write_object_contents(abfd)
+som_write_object_contents (abfd)
bfd *abfd;
{
- fprintf (stderr, "hppa_write_object_contents unimplemented\n");
+ fprintf (stderr, "som_write_object_contents unimplemented\n");
fflush (stderr);
abort ();
return (false);
}
+/* Read and save the string table associated with the given BFD. */
-static unsigned int
-hppa_get_symtab_upper_bound (abfd)
+static boolean
+som_slurp_string_table (abfd)
bfd *abfd;
{
- fprintf (stderr, "hppa_get_symtab_upper_bound unimplemented\n");
- fflush (stderr);
- abort ();
- return (0);
+ char *stringtab;
+
+ /* Use the saved version if its available. */
+ if (obj_som_stringtab (abfd) != NULL)
+ return true;
+
+ /* Allocate and read in the string table. */
+ stringtab = bfd_zalloc (abfd, obj_som_stringtab_size (abfd));
+ if (stringtab == NULL)
+ {
+ bfd_error = no_memory;
+ return false;
+ }
+
+ if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) < 0)
+ {
+ bfd_error = system_call_error;
+ return false;
+ }
+
+ if (bfd_read (stringtab, obj_som_stringtab_size (abfd), 1, abfd)
+ != obj_som_stringtab_size (abfd))
+ {
+ bfd_error = system_call_error;
+ return false;
+ }
+
+ /* Save our results and return success. */
+ obj_som_stringtab (abfd) = stringtab;
+ return true;
}
+/* Return the amount of data (in bytes) required to hold the symbol
+ table for this object. */
+
static unsigned int
-hppa_get_reloc_upper_bound (abfd, asect)
+som_get_symtab_upper_bound (abfd)
bfd *abfd;
- sec_ptr asect;
{
- fprintf (stderr, "hppa_get_reloc_upper_bound unimplemented\n");
- fflush (stderr);
- abort ();
- return (0);
+ if (!som_slurp_symbol_table (abfd))
+ return 0;
+
+ return (bfd_get_symcount (abfd) + 1) * (sizeof (som_symbol_type *));
}
+/* Convert from a SOM subspace index to a BFD section. */
+
+static asection *
+som_section_from_subspace_index (abfd, index)
+ bfd *abfd;
+ unsigned int index;
+{
+ asection *section;
+
+ for (section = abfd->sections; section != NULL; section = section->next)
+ if (som_section_data (section)->subspace_index == index)
+ return section;
+
+ /* Should never happen. */
+ abort();
+}
+
+/* Read and save the symbol table associated with the given BFD. */
+
static unsigned int
-hppa_canonicalize_reloc (abfd, section, relptr, symbols)
+som_slurp_symbol_table (abfd)
bfd *abfd;
- sec_ptr section;
- arelent **relptr;
- asymbol **symbols;
{
- fprintf (stderr, "hppa_canonicalize_reloc unimplemented\n");
- fflush (stderr);
- abort ();
+ int symbol_count = bfd_get_symcount (abfd);
+ int symsize = sizeof (struct symbol_dictionary_record);
+ char *stringtab;
+ struct symbol_dictionary_record *buf, *bufp, *endbufp;
+ som_symbol_type *sym, *symbase;
+
+ /* Return saved value if it exists. */
+ if (obj_som_symtab (abfd) != NULL)
+ return true;
+
+ /* Sanity checking. Make sure there are some symbols and that
+ we can read the string table too. */
+ if (symbol_count == 0)
+ {
+ bfd_error = no_symbols;
+ return false;
+ }
+
+ if (!som_slurp_string_table (abfd))
+ return false;
+
+ stringtab = obj_som_stringtab (abfd);
+
+ symbase = (som_symbol_type *)
+ bfd_zalloc (abfd, symbol_count * sizeof (som_symbol_type));
+ if (symbase == NULL)
+ {
+ bfd_error = no_memory;
+ return false;
+ }
+
+ /* Read in the external SOM representation. */
+ buf = alloca (symbol_count * symsize);
+ if (buf == NULL)
+ {
+ bfd_error = no_memory;
+ return false;
+ }
+ if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) < 0)
+ {
+ bfd_error = system_call_error;
+ return false;
+ }
+ if (bfd_read (buf, symbol_count * symsize, 1, abfd)
+ != symbol_count * symsize)
+ {
+ bfd_error = no_symbols;
+ return (false);
+ }
+
+ /* Iterate over all the symbols and internalize them. */
+ endbufp = buf + symbol_count;
+ for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp)
+ {
+
+ /* I don't think we care about these. */
+ if (bufp->symbol_type == ST_SYM_EXT
+ || bufp->symbol_type == ST_ARG_EXT)
+ continue;
+
+ /* Some reasonable defaults. */
+ sym->symbol.the_bfd = abfd;
+ sym->symbol.name = bufp->name.n_strx + stringtab;
+ sym->symbol.value = bufp->symbol_value;
+ sym->symbol.section = 0;
+ sym->symbol.flags = 0;
+
+ switch (bufp->symbol_type)
+ {
+ case ST_ENTRY:
+ sym->symbol.flags |= BSF_FUNCTION;
+ sym->symbol.value &= ~0x3;
+ break;
+
+ case ST_PRI_PROG:
+ case ST_SEC_PROG:
+ case ST_STUB:
+ case ST_MILLICODE:
+ case ST_CODE:
+ sym->symbol.value &= ~0x3;
+
+ default:
+ break;
+ }
+
+ /* Handle scoping and section information. */
+ switch (bufp->symbol_scope)
+ {
+ /* symbol_info field is undefined for SS_EXTERNAL and SS_UNSAT symbols,
+ so the section associated with this symbol can't be known. */
+ case SS_EXTERNAL:
+ case SS_UNSAT:
+ sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
+ break;
+
+ case SS_UNIVERSAL:
+ sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
+ sym->symbol.section
+ = som_section_from_subspace_index (abfd, bufp->symbol_info);
+ sym->symbol.value -= sym->symbol.section->vma;
+ break;
+
+#if 0
+ /* SS_GLOBAL and SS_LOCAL are two names for the same thing.
+ Sound dumb? It is. */
+ case SS_GLOBAL:
+#endif
+ case SS_LOCAL:
+ sym->symbol.flags |= BSF_LOCAL;
+ sym->symbol.section
+ = som_section_from_subspace_index (abfd, bufp->symbol_info);
+ sym->symbol.value -= sym->symbol.section->vma;
+ break;
+ }
+
+ /* Mark symbols left around by the debugger. */
+ if (strlen (sym->symbol.name) >= 3
+ && sym->symbol.name[0] == 'L'
+ && (sym->symbol.name[2] == '$' || sym->symbol.name[3] == '$'))
+ sym->symbol.flags |= BSF_DEBUGGING;
+
+ /* Note increment at bottom of loop, since we skip some symbols
+ we can not include it as part of the for statement. */
+ sym++;
+ }
+
+ /* Save our results and return success. */
+ obj_som_symtab (abfd) = symbase;
+ return (true);
}
-extern bfd_target hppa_vec;
+/* Canonicalize a SOM symbol table. Return the number of entries
+ in the symbol table. */
static unsigned int
-hppa_get_symtab (abfd, location)
+som_get_symtab (abfd, location)
bfd *abfd;
asymbol **location;
{
- fprintf (stderr, "hppa_get_symtab unimplemented\n");
- fflush (stderr);
- abort ();
- return (0);
+ int i;
+ som_symbol_type *symbase;
+
+ if (!som_slurp_symbol_table (abfd))
+ return 0;
+
+ i = bfd_get_symcount (abfd);
+ symbase = obj_som_symtab (abfd);
+
+ for (; i > 0; i--, location++, symbase++)
+ *location = &symbase->symbol;
+
+ /* Final null pointer. */
+ *location = 0;
+ return (bfd_get_symcount (abfd));
}
+/* Make a SOM symbol. There is nothing special to do here. */
+
static asymbol *
-hppa_make_empty_symbol (abfd)
+som_make_empty_symbol (abfd)
bfd *abfd;
{
- hppa_symbol_type *new =
- (hppa_symbol_type *) bfd_zalloc (abfd, sizeof (hppa_symbol_type));
+ som_symbol_type *new =
+ (som_symbol_type *) bfd_zalloc (abfd, sizeof (som_symbol_type));
+ if (new == NULL)
+ {
+ bfd_error = no_memory;
+ return 0;
+ }
new->symbol.the_bfd = abfd;
return &new->symbol;
}
+/* Print symbol information. */
+
static void
-hppa_print_symbol (ignore_abfd, afile, symbol, how)
+som_print_symbol (ignore_abfd, afile, symbol, how)
bfd *ignore_abfd;
PTR afile;
asymbol *symbol;
bfd_print_symbol_type how;
{
- fprintf (stderr, "hppa_print_symbol unimplemented\n");
+ FILE *file = (FILE *) afile;
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ case bfd_print_symbol_more:
+ fprintf (file, "som ");
+ fprintf_vma (file, symbol->value);
+ fprintf (file, " %lx", (long) symbol->flags);
+ break;
+ case bfd_print_symbol_all:
+ {
+ CONST char *section_name;
+ section_name = symbol->section ? symbol->section->name : "(*none*)";
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+ fprintf (file, " %s\t%s", section_name, symbol->name);
+ break;
+ }
+ }
+}
+
+static unsigned int
+som_get_reloc_upper_bound (abfd, asect)
+ bfd *abfd;
+ sec_ptr asect;
+{
+ fprintf (stderr, "som_get_reloc_upper_bound unimplemented\n");
fflush (stderr);
abort ();
+ return (0);
}
+static unsigned int
+som_canonicalize_reloc (abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ fprintf (stderr, "som_canonicalize_reloc unimplemented\n");
+ fflush (stderr);
+ abort ();
+}
+
+extern bfd_target som_vec;
+
+/* A hook to set up object file dependent section information. */
+
static boolean
-hppa_new_section_hook (abfd, newsect)
+som_new_section_hook (abfd, newsect)
bfd *abfd;
asection *newsect;
{
+ newsect->used_by_bfd = (struct som_section_data_struct *)
+ bfd_zalloc (abfd, sizeof (struct som_section_data_struct));
newsect->alignment_power = 3;
+ /* Initialize the subspace_index field to -1 so that it does
+ not match a subspace with an index of 0. */
+ som_section_data (newsect)->subspace_index = -1;
+
/* We allow more than three sections internally */
return true;
}
static boolean
-hppa_set_section_contents (abfd, section, location, offset, count)
+som_set_section_contents (abfd, section, location, offset, count)
bfd *abfd;
sec_ptr section;
PTR location;
file_ptr offset;
bfd_size_type count;
{
- fprintf (stderr, "hppa_set_section_contents unimplimented\n");
+ fprintf (stderr, "som_set_section_contents unimplimented\n");
fflush (stderr);
abort ();
return false;
}
static boolean
-hppa_set_arch_mach (abfd, arch, machine)
+som_set_arch_mach (abfd, arch, machine)
bfd *abfd;
enum bfd_architecture arch;
unsigned long machine;
{
- fprintf (stderr, "hppa_set_arch_mach unimplemented\n");
+ fprintf (stderr, "som_set_arch_mach unimplemented\n");
fflush (stderr);
- /* Allow any architecture to be supported by the hppa backend */
+ /* Allow any architecture to be supported by the som backend */
return bfd_default_set_arch_mach (abfd, arch, machine);
}
static boolean
-hppa_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
+som_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
functionname_ptr, line_ptr)
bfd *abfd;
asection *section;
@@ -494,18 +866,18 @@ hppa_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
CONST char **functionname_ptr;
unsigned int *line_ptr;
{
- fprintf (stderr, "hppa_find_nearest_line unimplemented\n");
+ fprintf (stderr, "som_find_nearest_line unimplemented\n");
fflush (stderr);
abort ();
return (false);
}
static int
-hppa_sizeof_headers (abfd, reloc)
+som_sizeof_headers (abfd, reloc)
bfd *abfd;
boolean reloc;
{
- fprintf (stderr, "hppa_sizeof_headers unimplemented\n");
+ fprintf (stderr, "som_sizeof_headers unimplemented\n");
fflush (stderr);
abort ();
return (0);
@@ -514,7 +886,7 @@ hppa_sizeof_headers (abfd, reloc)
/* Return information about SOM symbol SYMBOL in RET. */
static void
-hppa_get_symbol_info (ignore_abfd, symbol, ret)
+som_get_symbol_info (ignore_abfd, symbol, ret)
bfd *ignore_abfd; /* Ignored. */
asymbol *symbol;
symbol_info *ret;
@@ -524,78 +896,78 @@ hppa_get_symbol_info (ignore_abfd, symbol, ret)
/* End of miscellaneous support functions. */
-#define hppa_bfd_debug_info_start bfd_void
-#define hppa_bfd_debug_info_end bfd_void
-#define hppa_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
+#define som_bfd_debug_info_start bfd_void
+#define som_bfd_debug_info_end bfd_void
+#define som_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
-#define hppa_openr_next_archived_file bfd_generic_openr_next_archived_file
-#define hppa_generic_stat_arch_elt bfd_generic_stat_arch_elt
-#define hppa_slurp_armap bfd_false
-#define hppa_slurp_extended_name_table _bfd_slurp_extended_name_table
-#define hppa_truncate_arname (void (*)())bfd_nullvoidptr
-#define hppa_write_armap 0
+#define som_openr_next_archived_file bfd_generic_openr_next_archived_file
+#define som_generic_stat_arch_elt bfd_generic_stat_arch_elt
+#define som_slurp_armap bfd_false
+#define som_slurp_extended_name_table _bfd_slurp_extended_name_table
+#define som_truncate_arname (void (*)())bfd_nullvoidptr
+#define som_write_armap 0
-#define hppa_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
-#define hppa_close_and_cleanup bfd_generic_close_and_cleanup
-#define hppa_get_section_contents bfd_generic_get_section_contents
+#define som_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
+#define som_close_and_cleanup bfd_generic_close_and_cleanup
+#define som_get_section_contents bfd_generic_get_section_contents
-#define hppa_bfd_get_relocated_section_contents \
+#define som_bfd_get_relocated_section_contents \
bfd_generic_get_relocated_section_contents
-#define hppa_bfd_relax_section bfd_generic_relax_section
-#define hppa_bfd_seclet_link bfd_generic_seclet_link
-#define hppa_bfd_reloc_type_lookup \
+#define som_bfd_relax_section bfd_generic_relax_section
+#define som_bfd_seclet_link bfd_generic_seclet_link
+#define som_bfd_reloc_type_lookup \
((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
-#define hppa_bfd_make_debug_symbol \
+#define som_bfd_make_debug_symbol \
((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
/* Core file support is in the hpux-core backend. */
-#define hppa_core_file_failing_command _bfd_dummy_core_file_failing_command
-#define hppa_core_file_failing_signal _bfd_dummy_core_file_failing_signal
-#define hppa_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
+#define som_core_file_failing_command _bfd_dummy_core_file_failing_command
+#define som_core_file_failing_signal _bfd_dummy_core_file_failing_signal
+#define som_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
-bfd_target hppa_vec =
+bfd_target som_vec =
{
- "hppa", /* name */
- bfd_target_hppa_flavour,
+ "som", /* name */
+ bfd_target_som_flavour,
true, /* target byte order */
true, /* target headers byte order */
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
(SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
- | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
/* leading_symbol_char: is the first char of a user symbol
- predictable, and if so what is it */
+ predictable, and if so what is it */
0,
' ', /* ar_pad_char */
16, /* ar_max_namelen */
3, /* minimum alignment */
- _do_getb64, _do_getb_signed_64, _do_putb64,
- _do_getb32, _do_getb_signed_32, _do_putb32,
- _do_getb16, _do_getb_signed_16, _do_putb16, /* data */
- _do_getb64, _do_getb_signed_64, _do_putb64,
- _do_getb32, _do_getb_signed_32, _do_putb32,
- _do_getb16, _do_getb_signed_16, _do_putb16, /* hdrs */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
{_bfd_dummy_target,
- hppa_object_p, /* bfd_check_format */
+ som_object_p, /* bfd_check_format */
bfd_generic_archive_p,
_bfd_dummy_target
},
{
bfd_false,
- hppa_mkobject,
+ som_mkobject,
_bfd_generic_mkarchive,
bfd_false
},
{
bfd_false,
- hppa_write_object_contents,
+ som_write_object_contents,
_bfd_write_archive_contents,
bfd_false,
},
-#undef hppa
- JUMP_TABLE (hppa),
+#undef som
+ JUMP_TABLE (som),
(PTR) 0
};