bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

patch for HPUX SOM on non-HPUX systems


From: David Leonard
Subject: patch for HPUX SOM on non-HPUX systems
Date: Wed, 12 Dec 2007 11:23:10 +1000
User-agent: Thunderbird 1.5.0.14pre (X11/20071023)

Here is a patch to allow hpux's som target to build on non-hpux hosts. I have been using it in a linux x86_64 environment which has a different long size and endianness. Also tested on hpux11.00.
Enjoy!

notes:
The patch applies to binutils-2.18, and is licensed under gpl v2.
I was careful to make only minimal changes to som.c.
The header files were re-written by hand, mainly to use preprocessor hex constants instead of bit fields. They were cribbed from online documentation by hp, and the few missing constants were extracted from hpux header files. The bulk of the patch was generated by a perl script to perform reliable byte swapping of the structures. This work is part of a cross compiler effort here at Quest, So, I anticipate some more stress testing soon.

Jeff Law wrote:

The SOM code has never been designed to be cross-compilation safe,
particularly in terms of endianness and datatype size issues.
http://sources.redhat.com/ml/binutils/2002-01/msg00168.html
Index: include/som/spacehdr.h
===================================================================
--- include/som/spacehdr.h      (revision 0)
+++ include/som/spacehdr.h      (revision 12)
@@ -0,0 +1,71 @@
+/* Declaration of data structures for the PA-SOM object format.
+   (c) 2007, Quest Software, Inc. All rights reserved.
+   Written by David Leonard based on information published by Hewlett-Packard.
+
+   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 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.,
+   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _bfd_som_spacehdr_h
+#define _bfd_som_spacehdr_h
+
+#include "aouttypes.h"
+
+struct space_dictionary_record {
+    union name_pt   name;
+    uint32_t        flags;
+#define SPA_IS_LOADABLE                 0x80000000
+#define SPA_IS_DEFINED                  0x40000000
+#define SPA_IS_PRIVATE                  0x20000000
+#define SPA_HAS_INTERMEDIATE_CODE       0x10000000
+#define SPA_IS_TSPECIFIC                0x08000000
+#define SPA_IS_IGNORE_DBG               0x04000000
+#define SPA_RESERVED_MASK               0x03ff0000
+#define SPA_RESERVED_SHIFT              16
+#define SPA_SORT_KEY_MASK               0x0000ff00
+#define SPA_SORT_KEY_SHIFT              8
+#define SPA_RESERVED2_MASK              0x000000ff
+#define SPA_RESERVED2_SHIFT             0
+    int32_t         space_number;
+    int32_t         subspace_index;
+    uint32_t        subspace_quantity;
+    int32_t         loader_fix_index;
+    uint32_t        loader_fix_quantity;
+    int32_t         init_pointer_index;
+    uint32_t        init_pointer_quantity;
+};
+
+struct internal_space_dictionary_record {
+    union internal_name_pt name;
+    bfd_boolean     is_loadable;
+    bfd_boolean     is_defined;
+    bfd_boolean     is_private;
+    bfd_boolean     has_intermediate_code;
+    bfd_boolean     is_tspecific;
+    bfd_boolean     is_ignore_dbg;
+    uint8_t         sort_key;
+    int32_t         space_number;
+    int32_t         subspace_index;
+    uint32_t        subspace_quantity;
+    int32_t         loader_fix_index;
+    uint32_t        loader_fix_quantity;
+    int32_t         init_pointer_index;
+    uint32_t        init_pointer_quantity;
+};
+
+#define SPAHDR  struct space_dictionary_record
+#define SPAHSZ  sizeof(SPAHDR)
+
+#endif /* _bfd_som_spacehdr_h */
Index: include/som/somswap.h
===================================================================
--- include/som/somswap.h       (revision 0)
+++ include/som/somswap.h       (revision 12)
@@ -0,0 +1,587 @@
+/* Structure swapping functions for accessing the PA-SOM object format.
+   (c) 2007, Quest Software, Inc. All rights reserved.
+   Written by David Leonard based on information published by Hewlett-Packard.
+
+   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 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.,
+   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _bfd_som_somswap_h
+#define _bfd_som_somswap_h
+
+/*
+ * Structure swapping.
+ *
+ * SOM structures are 32-bit big-endian. 
+ * 'Internal' structure equivalents are used to hold host
+ * pointers and host-endian integers. In many cases, an 'internal'
+ * structure is not required, because simple byte swapping is sufficient.
+ * However, if the structure contains a pointer, or bit fields, then
+ * an internal structure is provided.
+ * (Bit fields need separate representation because byte swapping doesn't 
+ * work with them.)
+ */
+
+#include "a.out.h"
+#include "lst.h"
+
+static void
+som_bfd_get_sys_clock (bfd * abfd, const struct sys_clock * src, 
+    struct sys_clock * dst)
+{
+    dst->secs     = H_GET_32 (abfd, &src->secs);
+    dst->nanosecs = H_GET_32 (abfd, &src->nanosecs);
+}
+
+static void
+som_bfd_put_sys_clock (bfd * abfd, const struct sys_clock * src, 
+    struct sys_clock * dst)
+{
+    H_PUT_32 (abfd, src->secs, &dst->secs);
+    H_PUT_32 (abfd, src->nanosecs, &dst->nanosecs);
+}
+
+static void
+som_bfd_get_name_pt (bfd * abfd, const union name_pt * src,
+    union internal_name_pt * dst )
+{
+    dst->n_strx = H_GET_32 (abfd, &src->n_strx);
+}
+
+static void
+som_bfd_put_name_pt (bfd * abfd, const union internal_name_pt * src,
+    union name_pt * dst )
+{
+    H_PUT_32 (abfd, src->n_strx, &dst->n_strx);
+}
+
+static void
+som_bfd_get_space_dictionary_record (bfd * abfd, 
+    const struct space_dictionary_record * src,
+    struct internal_space_dictionary_record * dst)
+{
+    uint32_t flags;
+
+    som_bfd_get_name_pt (abfd, &src->name, &dst->name);
+    flags = H_GET_32 (abfd, &src->flags);
+    dst->is_loadable = flags & SPA_IS_LOADABLE;
+    dst->is_defined = flags & SPA_IS_DEFINED;
+    dst->is_private = flags & SPA_IS_PRIVATE;
+    dst->has_intermediate_code = flags & SPA_HAS_INTERMEDIATE_CODE;
+    dst->is_tspecific = flags & SPA_IS_TSPECIFIC;
+    dst->is_ignore_dbg = flags & SPA_IS_IGNORE_DBG;
+    dst->sort_key = (flags & SPA_SORT_KEY_MASK) >> SPA_SORT_KEY_SHIFT;
+    dst->space_number          = H_GET_32 (abfd, &src->init_pointer_quantity);
+    dst->subspace_index        = H_GET_32 (abfd, &src->subspace_index);
+    dst->subspace_quantity     = H_GET_32 (abfd, &src->subspace_quantity);
+    dst->loader_fix_index      = H_GET_32 (abfd, &src->loader_fix_index);
+    dst->loader_fix_quantity   = H_GET_32 (abfd, &src->loader_fix_quantity);
+    dst->init_pointer_index    = H_GET_32 (abfd, &src->init_pointer_index);
+    dst->init_pointer_quantity = H_GET_32 (abfd, &src->init_pointer_quantity);
+}
+
+static void
+som_bfd_put_space_dictionary_record (bfd * abfd, 
+    const struct internal_space_dictionary_record * src,
+    struct space_dictionary_record * dst)
+{
+    uint32_t flags;
+
+    memset (dst, 0, sizeof *dst);
+    som_bfd_put_name_pt (abfd, &src->name, &dst->name);
+    flags = 0;
+    flags |= src->is_loadable ? SPA_IS_LOADABLE : 0;
+    flags |= src->is_defined ? SPA_IS_DEFINED : 0;
+    flags |= src->is_private ? SPA_IS_PRIVATE : 0;
+    flags |= src->has_intermediate_code ? SPA_HAS_INTERMEDIATE_CODE : 0;
+    flags |= src->is_tspecific ? SPA_IS_TSPECIFIC : 0;
+    flags |= src->is_ignore_dbg ? SPA_IS_IGNORE_DBG : 0;
+    flags |= (src->sort_key << SPA_SORT_KEY_SHIFT) & SPA_SORT_KEY_MASK;
+    H_PUT_32 (abfd, flags, &dst->flags);
+    H_PUT_32 (abfd, src->space_number, &dst->space_number);
+    H_PUT_32 (abfd, src->subspace_index, &dst->subspace_index);
+    H_PUT_32 (abfd, src->subspace_quantity, &dst->subspace_quantity);
+    H_PUT_32 (abfd, src->loader_fix_index, &dst->loader_fix_index);
+    H_PUT_32 (abfd, src->loader_fix_quantity, &dst->loader_fix_quantity);
+    H_PUT_32 (abfd, src->init_pointer_index, &dst->init_pointer_index);
+    H_PUT_32 (abfd, src->init_pointer_quantity, &dst->init_pointer_quantity);
+}
+
+static void
+som_bfd_get_subspace_dictionary_record (bfd * abfd, 
+    const struct subspace_dictionary_record * src,
+    struct internal_subspace_dictionary_record * dst)
+{
+    uint32_t flags;
+
+    dst->space_index           = H_GET_32 (abfd, &src->space_index);
+    flags = H_GET_32 (abfd, &src->flags);
+    dst->access_control_bits = (flags & SCN_ACCESS_CONTROL_BITS_MASK) >> 
SCN_ACCESS_CONTROL_BITS_SHIFT;
+    dst->memory_resident = flags & SCN_MEMORY_RESIDENT;
+    dst->dup_common = flags & SCN_DUP_COMMON;
+    dst->is_common = flags & SCN_IS_COMMON;
+    dst->is_loadable = flags & SCN_IS_LOADABLE;
+    dst->quadrant = (flags & SCN_QUADRANT_MASK) >> SCN_QUADRANT_SHIFT;
+    dst->initially_frozen = flags & SCN_INITIALLY_FROZEN;
+    dst->is_first = flags & SCN_IS_FIRST;
+    dst->code_only = flags & SCN_CODE_ONLY;
+    dst->sort_key  = (flags & SCN_SORT_KEY_MASK) >> SCN_SORT_KEY_SHIFT;
+    dst->replicate_init = flags & SCN_REPLICATE_INIT;
+    dst->continuation = flags & SCN_CONTINUATION;
+    dst->is_tspecific = flags & SCN_IS_TSPECIFIC;
+    dst->is_comdat = flags & SCN_IS_COMDAT;
+    dst->file_loc_init_value   = H_GET_32 (abfd, &src->file_loc_init_value);
+    dst->initialization_length = H_GET_32 (abfd, &src->initialization_length);
+    dst->subspace_start        = H_GET_32 (abfd, &src->subspace_start);
+    dst->subspace_length       = H_GET_32 (abfd, &src->subspace_length);
+    dst->alignment = (H_GET_32 (abfd, &src->flags2) & SCN_ALIGNMENT_MASK)
+                       >> SCN_ALIGNMENT_SHIFT;
+    som_bfd_get_name_pt (abfd, &src->name, &dst->name);
+    dst->fixup_request_index   = H_GET_32 (abfd, &src->fixup_request_index);
+    dst->fixup_request_quantity= H_GET_32 (abfd, &src->fixup_request_quantity);
+}
+
+static void
+som_bfd_put_subspace_dictionary_record (bfd * abfd, 
+    const struct internal_subspace_dictionary_record * src,
+    struct subspace_dictionary_record * dst)
+{
+    uint32_t flags;
+
+    memset (dst, 0, sizeof *dst);
+    H_PUT_32 (abfd, src->space_index, &dst->space_index);
+    flags = 0;
+    flags |= (src->access_control_bits << SCN_ACCESS_CONTROL_BITS_SHIFT) & 
SCN_ACCESS_CONTROL_BITS_MASK;
+    flags |= src->memory_resident ? SCN_MEMORY_RESIDENT : 0;
+    flags |= src->dup_common ? SCN_DUP_COMMON : 0;
+    flags |= src->is_common ? SCN_IS_COMMON : 0;
+    flags |= src->is_loadable ? SCN_IS_LOADABLE : 0;
+    flags |= (src->quadrant << SCN_QUADRANT_SHIFT) & SCN_QUADRANT_MASK;
+    flags |= src->initially_frozen ? SCN_INITIALLY_FROZEN : 0;
+    flags |= src->is_first ? SCN_IS_FIRST : 0;
+    flags |= src->code_only ? SCN_CODE_ONLY : 0;
+    flags |= (src->sort_key << SCN_SORT_KEY_SHIFT) & SCN_SORT_KEY_MASK;
+    flags |= src->replicate_init ? SCN_REPLICATE_INIT : 0;
+    flags |= src->continuation ? SCN_CONTINUATION : 0;
+    flags |= src->is_tspecific ? SCN_IS_TSPECIFIC : 0;
+    flags |= src->is_comdat ? SCN_IS_COMDAT : 0;
+    H_PUT_32 (abfd, flags, &dst->flags);
+    H_PUT_32 (abfd, src->file_loc_init_value, &dst->file_loc_init_value);
+    H_PUT_32 (abfd, src->initialization_length, &dst->initialization_length);
+    H_PUT_32 (abfd, src->subspace_start, &dst->subspace_start);
+    H_PUT_32 (abfd, src->subspace_length, &dst->subspace_length);
+    flags = 0;
+    flags |= (src->alignment << SCN_ALIGNMENT_SHIFT) & SCN_ALIGNMENT_MASK;
+    H_PUT_32 (abfd, flags, &dst->flags2);
+    som_bfd_put_name_pt (abfd, &src->name, &dst->name);
+    H_PUT_32 (abfd, src->fixup_request_index, &dst->fixup_request_index);
+    H_PUT_32 (abfd, src->fixup_request_quantity, &dst->fixup_request_quantity);
+}
+
+static void
+som_bfd_get_header (bfd * abfd, const struct header * src, struct header * dst)
+{
+    dst->system_id = H_GET_16 (abfd, &src->system_id);
+    dst->a_magic = H_GET_16 (abfd, &src->a_magic);
+    dst->version_id = H_GET_32 (abfd, &src->version_id);
+    som_bfd_get_sys_clock (abfd, &src->file_time, &dst->file_time);
+    dst->entry_space = H_GET_32 (abfd, &src->entry_space);
+    dst->entry_subspace = H_GET_32 (abfd, &src->entry_subspace);
+    dst->entry_offset = H_GET_32 (abfd, &src->entry_offset);
+    dst->aux_header_location = H_GET_32 (abfd, &src->aux_header_location);
+    dst->aux_header_size = H_GET_32 (abfd, &src->aux_header_size);
+    dst->som_length = H_GET_32 (abfd, &src->som_length);
+    dst->presumed_dp = H_GET_32 (abfd, &src->presumed_dp);
+    dst->space_location = H_GET_32 (abfd, &src->space_location);
+    dst->space_total = H_GET_32 (abfd, &src->space_total);
+    dst->subspace_location = H_GET_32 (abfd, &src->subspace_location);
+    dst->subspace_total = H_GET_32 (abfd, &src->subspace_total);
+    dst->loader_fixup_location = H_GET_32 (abfd, &src->loader_fixup_location);
+    dst->loader_fixup_total = H_GET_32 (abfd, &src->loader_fixup_total);
+    dst->space_strings_location = H_GET_32 (abfd, 
&src->space_strings_location);
+    dst->space_strings_size = H_GET_32 (abfd, &src->space_strings_size);
+    dst->init_array_location = H_GET_32 (abfd, &src->init_array_location);
+    dst->init_array_total = H_GET_32 (abfd, &src->init_array_total);
+    dst->compiler_location = H_GET_32 (abfd, &src->compiler_location);
+    dst->compiler_total = H_GET_32 (abfd, &src->compiler_total);
+    dst->symbol_location = H_GET_32 (abfd, &src->symbol_location);
+    dst->symbol_total = H_GET_32 (abfd, &src->symbol_total);
+    dst->fixup_request_location = H_GET_32 (abfd, 
&src->fixup_request_location);
+    dst->fixup_request_total = H_GET_32 (abfd, &src->fixup_request_total);
+    dst->symbol_strings_location = H_GET_32 (abfd, 
&src->symbol_strings_location);
+    dst->symbol_strings_size = H_GET_32 (abfd, &src->symbol_strings_size);
+    dst->unloadable_sp_location = H_GET_32 (abfd, 
&src->unloadable_sp_location);
+    dst->unloadable_sp_size = H_GET_32 (abfd, &src->unloadable_sp_size);
+    dst->checksum = H_GET_32 (abfd, &src->checksum);
+}
+
+static void
+som_bfd_put_header (bfd * abfd, const struct header * src, struct header * dst)
+{
+    H_PUT_16 (abfd, src->system_id, &dst->system_id);
+    H_PUT_16 (abfd, src->a_magic, &dst->a_magic);
+    H_PUT_32 (abfd, src->version_id, &dst->version_id);
+    som_bfd_put_sys_clock (abfd, &src->file_time, &dst->file_time);
+    H_PUT_32 (abfd, src->entry_space, &dst->entry_space);
+    H_PUT_32 (abfd, src->entry_subspace, &dst->entry_subspace);
+    H_PUT_32 (abfd, src->entry_offset, &dst->entry_offset);
+    H_PUT_32 (abfd, src->aux_header_location, &dst->aux_header_location);
+    H_PUT_32 (abfd, src->aux_header_size, &dst->aux_header_size);
+    H_PUT_32 (abfd, src->som_length, &dst->som_length);
+    H_PUT_32 (abfd, src->presumed_dp, &dst->presumed_dp);
+    H_PUT_32 (abfd, src->space_location, &dst->space_location);
+    H_PUT_32 (abfd, src->space_total, &dst->space_total);
+    H_PUT_32 (abfd, src->subspace_location, &dst->subspace_location);
+    H_PUT_32 (abfd, src->subspace_total, &dst->subspace_total);
+    H_PUT_32 (abfd, src->loader_fixup_location, &dst->loader_fixup_location);
+    H_PUT_32 (abfd, src->loader_fixup_total, &dst->loader_fixup_total);
+    H_PUT_32 (abfd, src->space_strings_location, &dst->space_strings_location);
+    H_PUT_32 (abfd, src->space_strings_size, &dst->space_strings_size);
+    H_PUT_32 (abfd, src->init_array_location, &dst->init_array_location);
+    H_PUT_32 (abfd, src->init_array_total, &dst->init_array_total);
+    H_PUT_32 (abfd, src->compiler_location, &dst->compiler_location);
+    H_PUT_32 (abfd, src->compiler_total, &dst->compiler_total);
+    H_PUT_32 (abfd, src->symbol_location, &dst->symbol_location);
+    H_PUT_32 (abfd, src->symbol_total, &dst->symbol_total);
+    H_PUT_32 (abfd, src->fixup_request_location, &dst->fixup_request_location);
+    H_PUT_32 (abfd, src->fixup_request_total, &dst->fixup_request_total);
+    H_PUT_32 (abfd, src->symbol_strings_location, 
&dst->symbol_strings_location);
+    H_PUT_32 (abfd, src->symbol_strings_size, &dst->symbol_strings_size);
+    H_PUT_32 (abfd, src->unloadable_sp_location, &dst->unloadable_sp_location);
+    H_PUT_32 (abfd, src->unloadable_sp_size, &dst->unloadable_sp_size);
+    H_PUT_32 (abfd, src->checksum, &dst->checksum);
+}
+
+static void
+som_bfd_get_som_entry (bfd * abfd, const struct som_entry * src,
+    struct som_entry * dst)
+{
+    dst->location = H_GET_32 (abfd, &src->location);
+    dst->length = H_GET_32 (abfd, &src->length);
+}
+
+static void
+som_bfd_put_som_entry (bfd * abfd, const struct som_entry * src,
+    struct som_entry * dst)
+{
+    H_PUT_32 (abfd, src->location, &dst->location);
+    H_PUT_32 (abfd, src->length, &dst->length);
+}
+
+static void
+som_bfd_get_aux_id (bfd * abfd,
+    const struct aux_id * src,
+    struct internal_aux_id * dst)
+{
+    uint32_t flags;
+    
+    flags = H_GET_32 (abfd, &src->flags);
+    dst->mandatory = flags & AUX_MANDATORY;
+    dst->copy = flags & AUX_COPY;
+    dst->append = flags & AUX_APPEND;
+    dst->ignore = flags & AUX_IGNORE;
+    dst->type = (flags & AUX_TYPE_MASK) >> AUX_TYPE_SHIFT;
+    dst->length = H_GET_32 (abfd, &src->length);
+}
+
+static void
+som_bfd_put_aux_id (bfd * abfd,
+    const struct internal_aux_id * src,
+    struct aux_id * dst)
+{
+    uint32_t flags;
+
+    memset (dst, 0, sizeof *dst);
+    flags = 0;
+    flags |= src->mandatory ? AUX_MANDATORY : 0;
+    flags |= src->copy ? AUX_COPY : 0;
+    flags |= src->append ? AUX_APPEND : 0;
+    flags |= src->ignore ? AUX_IGNORE : 0;
+    flags |= (src->type << AUX_TYPE_SHIFT) & AUX_TYPE_MASK;
+    H_PUT_32 (abfd, flags, &dst->flags);
+    H_PUT_32 (abfd, src->length, &dst->length);
+}
+
+static void
+som_bfd_get_som_exec_auxhdr (bfd * abfd,
+    const struct som_exec_auxhdr * src,
+    struct internal_som_exec_auxhdr * dst)
+{
+    som_bfd_get_aux_id (abfd, &src->som_auxhdr, &dst->som_auxhdr);
+    dst->exec_tsize = H_GET_32 (abfd, &src->exec_tsize);
+    dst->exec_tmem = H_GET_32 (abfd, &src->exec_tmem);
+    dst->exec_tfile = H_GET_32 (abfd, &src->exec_tfile);
+    dst->exec_dsize = H_GET_32 (abfd, &src->exec_dsize);
+    dst->exec_dmem = H_GET_32 (abfd, &src->exec_dmem);
+    dst->exec_dfile = H_GET_32 (abfd, &src->exec_dfile);
+    dst->exec_bsize = H_GET_32 (abfd, &src->exec_bsize);
+    dst->exec_entry = H_GET_32 (abfd, &src->exec_entry);
+    dst->exec_flags = H_GET_32 (abfd, &src->exec_flags);
+    dst->exec_bfill = H_GET_32 (abfd, &src->exec_bfill);
+}
+
+static void
+som_bfd_put_som_exec_auxhdr (bfd * abfd,
+    const struct internal_som_exec_auxhdr * src,
+    struct som_exec_auxhdr * dst)
+{
+    som_bfd_put_aux_id (abfd, &src->som_auxhdr, &dst->som_auxhdr);
+    H_PUT_32 (abfd, src->exec_tsize, &dst->exec_tsize);
+    H_PUT_32 (abfd, src->exec_tmem, &dst->exec_tmem);
+    H_PUT_32 (abfd, src->exec_tfile, &dst->exec_tfile);
+    H_PUT_32 (abfd, src->exec_dsize, &dst->exec_dsize);
+    H_PUT_32 (abfd, src->exec_dmem, &dst->exec_dmem);
+    H_PUT_32 (abfd, src->exec_dfile, &dst->exec_dfile);
+    H_PUT_32 (abfd, src->exec_bsize, &dst->exec_bsize);
+    H_PUT_32 (abfd, src->exec_entry, &dst->exec_entry);
+    H_PUT_32 (abfd, src->exec_flags, &dst->exec_flags);
+    H_PUT_32 (abfd, src->exec_bfill, &dst->exec_bfill);
+}
+
+
+static void
+som_bfd_get_lst_header (bfd * abfd,
+    const struct lst_header * src,
+    struct lst_header * dst)
+{
+    dst->system_id = H_GET_16 (abfd, &src->system_id);
+    dst->a_magic = H_GET_16 (abfd, &src->a_magic);
+    dst->version_id = H_GET_32 (abfd, &src->version_id);
+    som_bfd_get_sys_clock (abfd, &src->file_time, &dst->file_time);
+    dst->hash_loc = H_GET_32 (abfd, &src->hash_loc);
+    dst->hash_size = H_GET_32 (abfd, &src->hash_size);
+    dst->module_count = H_GET_32 (abfd, &src->module_count);
+    dst->module_limit = H_GET_32 (abfd, &src->module_limit);
+    dst->dir_loc = H_GET_32 (abfd, &src->dir_loc);
+    dst->export_loc = H_GET_32 (abfd, &src->export_loc);
+    dst->export_count = H_GET_32 (abfd, &src->export_count);
+    dst->import_loc = H_GET_32 (abfd, &src->import_loc);
+    dst->aux_loc = H_GET_32 (abfd, &src->aux_loc);
+    dst->aux_size = H_GET_32 (abfd, &src->aux_size);
+    dst->string_loc = H_GET_32 (abfd, &src->string_loc);
+    dst->string_size = H_GET_32 (abfd, &src->string_size);
+    dst->free_list = H_GET_32 (abfd, &src->free_list);
+    dst->file_end = H_GET_32 (abfd, &src->file_end);
+    dst->checksum = H_GET_32 (abfd, &src->checksum);
+}
+
+static void
+som_bfd_put_lst_header (bfd * abfd,
+    const struct lst_header * src,
+    struct lst_header * dst)
+{
+    H_PUT_16 (abfd, src->system_id, &dst->system_id);
+    H_PUT_16 (abfd, src->a_magic, &dst->a_magic);
+    H_PUT_32 (abfd, src->version_id, &dst->version_id);
+    som_bfd_put_sys_clock (abfd, &src->file_time, &dst->file_time);
+    H_PUT_32 (abfd, src->hash_loc, &dst->hash_loc);
+    H_PUT_32 (abfd, src->hash_size, &dst->hash_size);
+    H_PUT_32 (abfd, src->module_count, &dst->module_count);
+    H_PUT_32 (abfd, src->module_limit, &dst->module_limit);
+    H_PUT_32 (abfd, src->dir_loc, &dst->dir_loc);
+    H_PUT_32 (abfd, src->export_loc, &dst->export_loc);
+    H_PUT_32 (abfd, src->export_count, &dst->export_count);
+    H_PUT_32 (abfd, src->import_loc, &dst->import_loc);
+    H_PUT_32 (abfd, src->aux_loc, &dst->aux_loc);
+    H_PUT_32 (abfd, src->aux_size, &dst->aux_size);
+    H_PUT_32 (abfd, src->string_loc, &dst->string_loc);
+    H_PUT_32 (abfd, src->string_size, &dst->string_size);
+    H_PUT_32 (abfd, src->free_list, &dst->free_list);
+    H_PUT_32 (abfd, src->file_end, &dst->file_end);
+    H_PUT_32 (abfd, src->checksum, &dst->checksum);
+}
+
+static void
+som_bfd_get_lst_symbol_record (bfd * abfd,
+    const struct lst_symbol_record * src,
+    struct internal_lst_symbol_record * dst)
+{
+    u_int32_t flags;
+    
+    flags = H_GET_32 (abfd, &src->flags);
+    dst->hidden = flags & LST_HIDDEN;
+    dst->secondary_def = flags & LST_SECONDARY_DEF;
+    dst->symbol_type = (flags & LST_SYMBOL_TYPE_MASK) >> LST_SYMBOL_TYPE_SHIFT;
+    dst->symbol_scope = (flags & LST_SYMBOL_SCOPE_MASK) >> 
LST_SYMBOL_SCOPE_SHIFT;
+    dst->check_level = (flags & LST_CHECK_LEVEL_MASK) >> LST_CHECK_LEVEL_SHIFT;
+    dst->must_qualify = flags & LST_MUST_QUALIFY;
+    dst->initially_frozen = flags & LST_INITIALLY_FROZEN;
+    dst->memory_resident = flags & LST_MEMORY_RESIDENT;
+    dst->is_common = flags & LST_IS_COMMON;
+    dst->dup_common = flags & LST_DUP_COMMON;
+    dst->xleast = (flags & LST_XLEAST_MASK) >> LST_XLEAST_SHIFT;
+    dst->arg_reloc = (flags & LST_ARG_RELOC_MASK) >> LST_ARG_RELOC_SHIFT;
+    som_bfd_get_name_pt (abfd, &src->name, &dst->name);
+    som_bfd_get_name_pt (abfd, &src->qualifier_name, &dst->qualifier_name);
+    dst->symbol_info = H_GET_32 (abfd, &src->symbol_info);
+    dst->symbol_value = H_GET_32 (abfd, &src->symbol_value);
+    dst->symbol_descriptor = H_GET_32 (abfd, &src->symbol_descriptor);
+    flags = H_GET_32 (abfd, &src->flags2);
+    dst->reserved = (flags & LST_RESERVED_MASK) >> LST_RESERVED_SHIFT;
+    dst->max_num_args = (flags & LST_MAX_NUM_ARGS_MASK) >> 
LST_MAX_NUM_ARGS_SHIFT;
+    dst->min_num_args = (flags & LST_MIN_NUM_ARGS_MASK) >> 
LST_MIN_NUM_ARGS_SHIFT;
+    dst->num_args = (flags & LST_NUM_ARGS_MASK) >> LST_NUM_ARGS_SHIFT;
+    dst->som_index = H_GET_32 (abfd, &src->som_index);
+    dst->symbol_key = H_GET_32 (abfd, &src->symbol_key);
+    dst->next_entry = H_GET_32 (abfd, &src->next_entry);
+}
+
+static void
+som_bfd_put_lst_symbol_record (bfd * abfd,
+    const struct internal_lst_symbol_record * src,
+    struct lst_symbol_record * dst)
+{
+    u_int32_t flags;
+
+    memset (dst, 0, sizeof *dst);
+    flags = 0;
+    flags |= src->hidden ? LST_HIDDEN : 0;
+    flags |= src->secondary_def ? LST_SECONDARY_DEF : 0;
+    flags |= (src->symbol_type << LST_SYMBOL_TYPE_SHIFT) & 
LST_SYMBOL_TYPE_MASK;
+    flags |= (src->symbol_scope << LST_SYMBOL_SCOPE_SHIFT) & 
LST_SYMBOL_SCOPE_MASK;
+    flags |= (src->check_level << LST_CHECK_LEVEL_SHIFT) & 
LST_CHECK_LEVEL_MASK;
+    flags |= src->must_qualify ? LST_MUST_QUALIFY : 0;
+    flags |= src->initially_frozen ? LST_INITIALLY_FROZEN : 0;
+    flags |= src->memory_resident ? LST_MEMORY_RESIDENT : 0;
+    flags |= src->is_common ? LST_IS_COMMON : 0;
+    flags |= src->dup_common ? LST_DUP_COMMON : 0;
+    flags |= (src->xleast << LST_XLEAST_SHIFT) & LST_XLEAST_MASK;
+    flags |= (src->arg_reloc << LST_ARG_RELOC_SHIFT) & LST_ARG_RELOC_MASK;
+    H_PUT_32 (abfd, flags, &dst->flags);
+    som_bfd_put_name_pt (abfd, &src->name, &dst->name);
+    som_bfd_put_name_pt (abfd, &src->qualifier_name, &dst->qualifier_name);
+    H_PUT_32 (abfd, src->symbol_info, &dst->symbol_info);
+    H_PUT_32 (abfd, src->symbol_value, &dst->symbol_value);
+    H_PUT_32 (abfd, src->symbol_descriptor, &dst->symbol_descriptor);
+    flags = 0;
+    flags |= (src->reserved << LST_RESERVED_SHIFT) & LST_RESERVED_MASK;
+    flags |= (src->max_num_args << LST_MAX_NUM_ARGS_SHIFT) & 
LST_MAX_NUM_ARGS_MASK;
+    flags |= (src->min_num_args << LST_MIN_NUM_ARGS_SHIFT) & 
LST_MIN_NUM_ARGS_MASK;
+    flags |= (src->num_args << LST_NUM_ARGS_SHIFT) & LST_NUM_ARGS_MASK;
+    H_PUT_32 (abfd, flags, &dst->flags2);
+    H_PUT_32 (abfd, src->som_index, &dst->som_index);
+    H_PUT_32 (abfd, src->symbol_key, &dst->symbol_key);
+    H_PUT_32 (abfd, src->next_entry, &dst->next_entry);
+}
+
+static void
+som_bfd_get_symbol_dictionary_record (bfd * abfd,
+    const struct symbol_dictionary_record * src,
+    struct internal_symbol_dictionary_record * dst)
+{
+    uint32_t flags;
+
+    flags = H_GET_32 (abfd, &src->flags);
+    dst->hidden = flags & SDR_HIDDEN;
+    dst->secondary_def = flags & SDR_SECONDARY_DEF;
+    dst->symbol_type = (flags & SDR_SYMBOL_TYPE_MASK) >> SDR_SYMBOL_TYPE_SHIFT;
+    dst->symbol_scope = (flags & SDR_SYMBOL_SCOPE_MASK) >> 
SDR_SYMBOL_SCOPE_SHIFT;
+    dst->check_level = (flags & SDR_CHECK_LEVEL_MASK) >> SDR_CHECK_LEVEL_SHIFT;
+    dst->must_qualify = flags & SDR_MUST_QUALIFY;
+    dst->initially_frozen = flags & SDR_INITIALLY_FROZEN;
+    dst->memory_resident = flags & SDR_MEMORY_RESIDENT;
+    dst->is_common = flags & SDR_IS_COMMON;
+    dst->dup_common = flags & SDR_DUP_COMMON;
+    dst->xleast = (flags & SDR_XLEAST_MASK) >> SDR_XLEAST_SHIFT;
+    dst->arg_reloc = (flags & SDR_ARG_RELOC_MASK) >> SDR_ARG_RELOC_SHIFT;
+    som_bfd_get_name_pt (abfd, &src->name, &dst->name);
+    som_bfd_get_name_pt (abfd, &src->qualifier_name, &dst->qualifier_name);
+    flags = H_GET_32 (abfd, &src->flags2);
+    dst->has_long_return = flags & SDR_HAS_LONG_RETURN;
+    dst->no_relocation = flags & SDR_NO_RELOCATION;
+    dst->is_comdat = flags & SDR_IS_COMDAT;
+    dst->is_protected = flags & SDR_IS_PROTECTED;
+    dst->reserved = (flags & SDR_RESERVED_MASK) >> SDR_RESERVED_SHIFT;
+    dst->symbol_info = (flags & SDR_SYMBOL_INFO_MASK) >> SDR_SYMBOL_INFO_SHIFT;
+    dst->symbol_value = H_GET_32 (abfd, &src->symbol_value);
+}
+
+static void
+som_bfd_put_symbol_dictionary_record (bfd * abfd,
+    const struct internal_symbol_dictionary_record * src,
+    struct symbol_dictionary_record * dst)
+{
+    uint32_t flags;
+
+    memset (dst, 0, sizeof *dst);
+    flags = 0;
+    flags |= src->hidden ? SDR_HIDDEN : 0;
+    flags |= src->secondary_def ? SDR_SECONDARY_DEF : 0;
+    flags |= (src->symbol_type << SDR_SYMBOL_TYPE_SHIFT) & 
SDR_SYMBOL_TYPE_MASK;
+    flags |= (src->symbol_scope << SDR_SYMBOL_SCOPE_SHIFT) & 
SDR_SYMBOL_SCOPE_MASK;
+    flags |= (src->check_level << SDR_CHECK_LEVEL_SHIFT) & 
SDR_CHECK_LEVEL_MASK;
+    flags |= src->must_qualify ? SDR_MUST_QUALIFY : 0;
+    flags |= src->initially_frozen ? SDR_INITIALLY_FROZEN : 0;
+    flags |= src->memory_resident ? SDR_MEMORY_RESIDENT : 0;
+    flags |= src->is_common ? SDR_IS_COMMON : 0;
+    flags |= src->dup_common ? SDR_DUP_COMMON : 0;
+    flags |= (src->xleast << SDR_XLEAST_SHIFT) & SDR_XLEAST_MASK;
+    flags |= (src->arg_reloc << SDR_ARG_RELOC_SHIFT) & SDR_ARG_RELOC_MASK;
+    som_bfd_put_name_pt (abfd, &src->name, &dst->name);
+    som_bfd_put_name_pt (abfd, &src->qualifier_name, &dst->qualifier_name);
+    H_PUT_32 (abfd, flags, &dst->flags);
+    flags = 0;
+    flags |= src->has_long_return ? SDR_HAS_LONG_RETURN : 0;
+    flags |= src->no_relocation ? SDR_NO_RELOCATION : 0;
+    flags |= src->is_comdat ? SDR_IS_COMDAT : 0;
+    flags |= src->is_protected ? SDR_IS_PROTECTED : 0;
+    flags |= (src->reserved << SDR_RESERVED_SHIFT) & SDR_RESERVED_MASK;
+    flags |= (src->symbol_info << SDR_SYMBOL_INFO_SHIFT) & 
SDR_SYMBOL_INFO_MASK;
+    H_PUT_32 (abfd, flags, &dst->flags2);
+    H_PUT_32 (abfd, src->symbol_value, &dst->symbol_value);
+}
+
+#if 0
+static void
+som_bfd_get_compilation_unit (bfd * abfd,
+    const struct compilation_unit * src,
+    struct internal_compilation_unit * dst)
+{
+    uint32_t flags;
+
+    som_bfd_get_name_pt (abfd, &src->name, &dst->name);
+    som_bfd_get_name_pt (abfd, &src->language_name, &dst->language_name);
+    som_bfd_get_name_pt (abfd, &src->product_id, &dst->product_id);
+    som_bfd_get_name_pt (abfd, &src->version_id, &dst->version_id);
+    flags = H_GET_32 (abfd, &src->flags);
+    dst->reserved = (flags & CU_RESERVED_MASK) >> CU_RESERVED_SHIFT;
+    dst->chunk_flag = flags & CU_CHUNK_FLAG;
+    som_bfd_get_sys_clock (abfd, &src->compile_time, &dst->compile_time);
+    som_bfd_get_sys_clock (abfd, &src->source_time, &dst->source_time);
+}
+#endif
+
+static void
+som_bfd_put_compilation_unit (bfd * abfd,
+    const struct internal_compilation_unit * src,
+    struct compilation_unit * dst)
+{
+    uint32_t flags;
+
+    memset (dst, 0, sizeof *dst);
+    som_bfd_put_name_pt (abfd, &src->name, &dst->name);
+    som_bfd_put_name_pt (abfd, &src->language_name, &dst->language_name);
+    som_bfd_put_name_pt (abfd, &src->product_id, &dst->product_id);
+    som_bfd_put_name_pt (abfd, &src->version_id, &dst->version_id);
+    flags = 0;
+    flags |= (src->reserved << CU_RESERVED_SHIFT) & CU_RESERVED_MASK;
+    flags |= src->chunk_flag ? CU_CHUNK_FLAG : 0;
+    H_PUT_32 (abfd, flags, &dst->flags);
+    som_bfd_put_sys_clock (abfd, &src->compile_time, &dst->compile_time);
+    som_bfd_put_sys_clock (abfd, &src->source_time, &dst->source_time);
+}
+
+
+#endif /* _bfd_som_somswap_h */
Index: include/som/syms.h
===================================================================
--- include/som/syms.h  (revision 0)
+++ include/som/syms.h  (revision 12)
@@ -0,0 +1,104 @@
+/* Declaration of data structures for symbol dicts in PA-SOM object files.
+   (c) 2007, Quest Software, Inc. All rights reserved.
+   Written by David Leonard based on information published by Hewlett-Packard.
+
+   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 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.,
+   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _bfd_som_syms_h
+#define _bfd_som_syms_h
+
+#include "aouttypes.h"
+
+struct symbol_dictionary_record {
+    uint32_t       flags;
+#define SDR_HIDDEN                      0x80000000
+#define SDR_SECONDARY_DEF               0x40000000
+#define SDR_SYMBOL_TYPE_MASK            0x3f000000
+#define SDR_SYMBOL_TYPE_SHIFT           24
+#define SDR_SYMBOL_SCOPE_MASK           0x00f00000
+#define SDR_SYMBOL_SCOPE_SHIFT          20
+#define SDR_CHECK_LEVEL_MASK            0x000e0000
+#define SDR_CHECK_LEVEL_SHIFT           17
+#define SDR_MUST_QUALIFY                0x00010000
+#define SDR_INITIALLY_FROZEN            0x00008000
+#define SDR_MEMORY_RESIDENT             0x00004000
+#define SDR_IS_COMMON                   0x00002000
+#define SDR_DUP_COMMON                  0x00001000
+#define SDR_XLEAST_MASK                 0x00000c00
+#define SDR_XLEAST_SHIFT                10
+#define SDR_ARG_RELOC_MASK              0x000003ff
+#define SDR_ARG_RELOC_SHIFT             0
+    union name_pt   name;
+    union name_pt   qualifier_name;
+    uint32_t        flags2;
+#define SDR_HAS_LONG_RETURN             0x80000000
+#define SDR_NO_RELOCATION               0x40000000
+#define SDR_IS_COMDAT                   0x20000000
+#define SDR_IS_PROTECTED                0x10000000
+#define SDR_RESERVED_MASK               0x0f000000
+#define SDR_RESERVED_SHIFT              24
+#define SDR_SYMBOL_INFO_MASK            0x00ffffff
+#define SDR_SYMBOL_INFO_SHIFT           0
+    uint32_t        symbol_value;
+};
+
+struct internal_symbol_dictionary_record {
+    bfd_boolean     hidden;
+    bfd_boolean     secondary_def;
+    unsigned int    symbol_type : 6;
+#define ST_NULL             0
+#define ST_ABSOLUTE         1
+#define ST_DATA             2
+#define ST_CODE             3
+#define ST_PRI_PROG         4
+#define ST_SEC_PROG         5
+#define ST_ENTRY            6
+#define ST_STORAGE          7
+#define ST_STUB             8
+#define ST_SYM_EXT          10
+#define ST_ARG_EXT          11
+#define ST_MILLICODE        12
+#define ST_PLABEL           13
+    unsigned int    symbol_scope : 4;
+#define SS_UNSAT            0
+#define SS_EXTERNAL         1
+#define SS_LOCAL            2
+#define SS_UNIVERSAL        3
+    unsigned int    check_level : 3;
+    bfd_boolean     must_qualify;
+    bfd_boolean     initially_frozen;
+    bfd_boolean     memory_resident;
+    bfd_boolean     is_common;
+    bfd_boolean     dup_common;
+    unsigned int    xleast : 2;
+    unsigned int    arg_reloc : 10;
+    union internal_name_pt name;
+#define n_nptr              name.n_name
+#define n_offset            name.n_strx
+    union internal_name_pt qualifier_name;
+#define q_nptr              qualifier_name.n_name
+#define q_offset            qualifier_name.n_strx
+    bfd_boolean     has_long_return;
+    bfd_boolean     no_relocation;
+    bfd_boolean     is_comdat;
+    bfd_boolean     is_protected;
+    unsigned int    reserved : 4;
+    uint32_t        symbol_info : 24;
+    uint32_t        symbol_value;
+};
+
+#endif /* _bfd_som_syms_h */
Index: include/som/aouttypes.h
===================================================================
--- include/som/aouttypes.h     (revision 0)
+++ include/som/aouttypes.h     (revision 12)
@@ -0,0 +1,43 @@
+/* Declaration of data structures for the PA-SOM object format.
+   (c) 2007, Quest Software, Inc. All rights reserved.
+   Written by David Leonard based on information published by Hewlett-Packard.
+
+   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 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.,
+   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _bfd_som_aouttypes_h
+#define _bfd_som_aouttypes_h
+
+#include "bfd_stdint.h"
+
+struct sys_clock {
+    uint32_t        secs;
+    uint32_t        nanosecs;
+};
+
+union name_pt {
+    uint32_t        n_name;
+    uint32_t        n_strx;
+};
+
+union internal_name_pt {
+    char *          n_name;
+    uint32_t        n_strx;
+};
+#define NAME_PT             name.n_name
+#define STR_INDEX           name.n_strx
+
+#endif /* _bfd_som_aouttypes_h */
Index: include/som/filehdr.h
===================================================================
--- include/som/filehdr.h       (revision 0)
+++ include/som/filehdr.h       (revision 12)
@@ -0,0 +1,81 @@
+/* Declaration of data structures for the PA-SOM object format.
+   (c) 2007, Quest Software, Inc. All rights reserved.
+   Written by David Leonard based on information published by Hewlett-Packard.
+
+   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 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.,
+   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _bfd_som_filehdr_h
+#define _bfd_som_filehdr_h
+
+#include "aouttypes.h"
+
+struct header {
+    uint16_t        system_id;
+#define CPU_PA_RISC1_0      0x20B
+#define CPU_PA_RISC1_1      0x210
+#define CPU_PA_RISC2_0      0x214
+    uint16_t        a_magic;
+#define EXECLIBMAGIC        0x104
+#define RELOC_MAGIC         0x106
+#define EXEC_MAGIC          0x107
+#define SHARE_MAGIC         0x108
+#define DEMAND_MAGIC        0x10b
+#define DL_MAGIC            0x10d
+#define SHL_MAGIC           0x10e
+    uint32_t        version_id;
+#define VERSION_ID          85082112
+#define NEW_VERSION_ID      87102412
+    struct sys_clock file_time;
+    uint32_t        entry_space;
+    uint32_t        entry_subspace;
+    uint32_t        entry_offset;
+    uint32_t        aux_header_location;
+    uint32_t        aux_header_size;
+    uint32_t        som_length;
+    uint32_t        presumed_dp;
+    uint32_t        space_location;
+    uint32_t        space_total;
+    uint32_t        subspace_location;
+    uint32_t        subspace_total;
+    uint32_t        loader_fixup_location;
+    uint32_t        loader_fixup_total;
+    uint32_t        space_strings_location;
+    uint32_t        space_strings_size;
+    uint32_t        init_array_location;
+    uint32_t        init_array_total;
+    uint32_t        compiler_location;
+    uint32_t        compiler_total;
+    uint32_t        symbol_location;
+    uint32_t        symbol_total;
+    uint32_t        fixup_request_location;
+    uint32_t        fixup_request_total;
+    uint32_t        symbol_strings_location;
+    uint32_t        symbol_strings_size;
+    uint32_t        unloadable_sp_location;
+    uint32_t        unloadable_sp_size;
+    uint32_t        checksum;
+};
+
+#define _PA_RISC1_0_ID      CPU_PA_RISC1_0
+#define _PA_RISC1_1_ID      CPU_PA_RISC1_1
+#define _PA_RISC2_0_ID      CPU_PA_RISC2_0
+#define _PA_RISC_MAXID      0x2FF
+#define _PA_RISC_ID(__m_num)            \
+    (((__m_num) == _PA_RISC1_0_ID) ||   \
+         ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID))
+
+#endif /* _bfd_som_filehdr_h */
Index: include/som/compunit.h
===================================================================
--- include/som/compunit.h      (revision 0)
+++ include/som/compunit.h      (revision 12)
@@ -0,0 +1,54 @@
+/* Declaration of data structures for the PA-SOM object format.
+   (c) 2007, Quest Software, Inc. All rights reserved.
+   Written by David Leonard based on information published by Hewlett-Packard.
+
+   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 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.,
+   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _bfd_som_compunit_h
+#define _bfd_som_compunit_h
+
+#include "aouttypes.h"
+
+struct compilation_unit {
+    union name_pt    name;
+    union name_pt    language_name;
+    union name_pt    product_id;
+    union name_pt    version_id;
+    uint32_t flags;
+#define CU_RESERVED_MASK                0xfffffffe
+#define CU_RESERVED_SHIFT               1
+#define CU_CHUNK_FLAG                   0x00000001
+    struct sys_clock compile_time;
+    struct sys_clock source_time;
+};
+#define COMPUNIT            struct compilation_unit
+#define COMPUNITSZ          sizeof(COMPUNIT)
+
+struct internal_compilation_unit {
+    union internal_name_pt    name;
+    union internal_name_pt    language_name;
+    union internal_name_pt    product_id;
+    union internal_name_pt    version_id;
+    uint32_t         reserved   : 31;
+    uint32_t         chunk_flag :  1;
+    struct sys_clock compile_time;
+    struct sys_clock source_time;
+};
+#define internal_COMPUNIT            struct internal_compilation_unit
+#define internal_COMPUNITSZ          sizeof(internal_COMPUNIT)
+
+#endif /* _bfd_som_compunit_h */
Index: include/som/scnhdr.h
===================================================================
--- include/som/scnhdr.h        (revision 0)
+++ include/som/scnhdr.h        (revision 12)
@@ -0,0 +1,91 @@
+/* Declaration of data structures for the PA-SOM object format.
+   (c) 2007, Quest Software, Inc. All rights reserved.
+   Written by David Leonard based on information published by Hewlett-Packard.
+
+   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 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.,
+   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _bfd_som_scnhdr_h
+#define _bfd_som_scnhdr_h
+
+#include "aouttypes.h"
+
+struct subspace_dictionary_record {
+       int32_t         space_index;
+        uint32_t        flags;
+#define SCN_ACCESS_CONTROL_BITS_MASK    0xfe000000
+#define SCN_ACCESS_CONTROL_BITS_SHIFT   25
+#define SCN_MEMORY_RESIDENT             0x01000000
+#define SCN_DUP_COMMON                  0x00800000
+#define SCN_IS_COMMON                   0x00400000
+#define SCN_IS_LOADABLE                 0x00200000
+#define SCN_QUADRANT_MASK               0x00180000
+#define SCN_QUADRANT_SHIFT              19
+#define SCN_INITIALLY_FROZEN            0x00040000
+#define SCN_IS_FIRST                    0x00020000
+#define SCN_CODE_ONLY                   0x00010000
+#define SCN_SORT_KEY_MASK               0x0000ff00
+#define SCN_SORT_KEY_SHIFT              8
+#define SCN_REPLICATE_INIT              0x00000080
+#define SCN_CONTINUATION                0x00000040
+#define SCN_IS_TSPECIFIC                0x00000020
+#define SCN_IS_COMDAT                   0x00000010
+#define SCN_RESERVED_MASK               0x0000000f
+#define SCN_RESERVED_SHIFT              0
+        int32_t         file_loc_init_value;
+        uint32_t        initialization_length;
+        uint32_t        subspace_start;
+        uint32_t        subspace_length;
+        uint32_t        flags2;
+#define SCN_RESERVED2_MASK              0xf8000000
+#define SCN_RESERVED2_SHIFT             27
+#define SCN_ALIGNMENT_MASK              0x07ffffff
+#define SCN_ALIGNMENT_SHIFT             0
+        union name_pt   name;
+        int32_t         fixup_request_index;
+        uint32_t        fixup_request_quantity;
+};
+
+struct internal_subspace_dictionary_record {
+        int32_t         space_index;
+        uint8_t         access_control_bits: 7;
+        bfd_boolean     memory_resident;
+        bfd_boolean     dup_common;
+        bfd_boolean     is_common;
+        bfd_boolean     is_loadable;
+        uint8_t         quadrant: 2;
+        bfd_boolean     initially_frozen;
+        bfd_boolean     is_first;
+        bfd_boolean     code_only;
+        uint8_t         sort_key;
+        bfd_boolean     replicate_init;
+        bfd_boolean     continuation;
+        bfd_boolean     is_tspecific;
+        bfd_boolean     is_comdat;
+        int32_t         file_loc_init_value;
+        uint32_t        initialization_length;
+        uint32_t        subspace_start;
+        uint32_t        subspace_length;
+        uint32_t        alignment: 27;
+        union internal_name_pt name;
+        int32_t         fixup_request_index;
+        uint32_t        fixup_request_quantity;
+};
+
+#define SCNHDR  struct subspace_dictionary_record
+#define SCNHSZ  sizeof(SCNHDR)
+
+#endif /* _bfd_som_scnhdr_h */
Index: include/som/lst.h
===================================================================
--- include/som/lst.h   (revision 0)
+++ include/som/lst.h   (revision 12)
@@ -0,0 +1,123 @@
+/* Declaration of data structures for the PA-SOM object format.
+   (c) 2007, Quest Software, Inc. All rights reserved.
+   Written by David Leonard based on information published by Hewlett-Packard.
+
+   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 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.,
+   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _bfd_som_lst_h
+#define _bfd_som_lst_h
+
+#include "aouttypes.h"
+
+#define LIBMAGIC            0x0619
+
+struct lst_header {
+    uint16_t            system_id;
+    uint16_t            a_magic;
+    uint32_t            version_id;
+    struct sys_clock    file_time;
+    uint32_t            hash_loc;
+    uint32_t            hash_size;
+    uint32_t            module_count;
+    uint32_t            module_limit;
+    uint32_t            dir_loc;
+    uint32_t            export_loc;
+    uint32_t            export_count;
+    uint32_t            import_loc;
+    uint32_t            aux_loc;
+    uint32_t            aux_size;
+    uint32_t            string_loc;
+    uint32_t            string_size;
+    uint32_t            free_list;
+    uint32_t            file_end;
+    uint32_t            checksum;
+};
+
+struct som_entry {
+    uint32_t            location;
+    uint32_t            length;
+};
+
+struct lst_symbol_record {
+    uint32_t            flags;
+#define LST_HIDDEN                      0x80000000
+#define LST_SECONDARY_DEF               0x40000000
+#define LST_SYMBOL_TYPE_MASK            0x3f000000
+#define LST_SYMBOL_TYPE_SHIFT           24
+#define LST_SYMBOL_SCOPE_MASK           0x00f00000
+#define LST_SYMBOL_SCOPE_SHIFT          20
+#define LST_CHECK_LEVEL_MASK            0x000e0000
+#define LST_CHECK_LEVEL_SHIFT           17
+#define LST_MUST_QUALIFY                0x00010000
+#define LST_INITIALLY_FROZEN            0x00008000
+#define LST_MEMORY_RESIDENT             0x00004000
+#define LST_IS_COMMON                   0x00002000
+#define LST_DUP_COMMON                  0x00001000
+#define LST_XLEAST_MASK                 0x00000c00
+#define LST_XLEAST_SHIFT                10
+#define LST_ARG_RELOC_MASK              0x000003ff
+#define LST_ARG_RELOC_SHIFT             0
+    union name_pt       name;
+    union name_pt       qualifier_name;
+    uint32_t            symbol_info;
+    uint32_t            symbol_value;
+    uint32_t            symbol_descriptor;
+    uint32_t            flags2;
+#define LST_RESERVED_MASK               0xff000000
+#define LST_RESERVED_SHIFT              24
+#define LST_MAX_NUM_ARGS_MASK           0x00ff0000
+#define LST_MAX_NUM_ARGS_SHIFT          16
+#define LST_MIN_NUM_ARGS_MASK           0x0000ff00
+#define LST_MIN_NUM_ARGS_SHIFT          8
+#define LST_NUM_ARGS_MASK               0x000000ff
+#define LST_NUM_ARGS_SHIFT              0
+    uint32_t            som_index;
+    uint32_t            symbol_key;
+    uint32_t            next_entry;
+};
+
+struct internal_lst_symbol_record {
+    bfd_boolean         hidden;
+    bfd_boolean         secondary_def;
+    uint8_t             symbol_type      : 6;
+    uint8_t             symbol_scope     : 4;
+    uint8_t             check_level      : 3;
+    bfd_boolean         must_qualify;
+    bfd_boolean         initially_frozen;
+    bfd_boolean         memory_resident;
+    bfd_boolean         is_common;
+    bfd_boolean         dup_common;
+    uint8_t             xleast           : 2;
+    uint16_t            arg_reloc        :10;
+    union internal_name_pt name;
+    union internal_name_pt qualifier_name;
+    uint32_t            symbol_info;
+    uint32_t            symbol_value;
+    uint32_t            symbol_descriptor;
+    uint8_t             reserved;
+    uint8_t             max_num_args;
+    uint8_t             min_num_args;
+    uint8_t             num_args;
+    uint32_t            som_index;
+    uint32_t            symbol_key;
+    uint32_t            next_entry;
+};
+
+#define LSTSYMESZ           sizeof(struct lst_symbol_record)
+#define SLSTHDR             sizeof(struct lst_header)
+
+#endif /* _bfd_som_lst_h */
Index: include/som/reloc.h
===================================================================
--- include/som/reloc.h (revision 0)
+++ include/som/reloc.h (revision 12)
@@ -0,0 +1,75 @@
+/* Declaration of relocation operators for the PA-SOM object format.
+   (c) 2007, Quest Software, Inc. All rights reserved.
+   Written by David Leonard based on information published by Hewlett-Packard.
+
+   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 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.,
+   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _bfd_som_reloc_h
+#define _bfd_som_reloc_h
+
+#define R_NO_RELOCATION     0x00
+#define R_ZEROES            0x20
+#define R_UNINIT            0x22
+#define R_RELOCATION        0x24
+#define R_DATA_ONE_SYMBOL   0x25
+#define R_DATA_PLABEL       0x27
+#define R_SPACE_REF         0x29
+#define R_REPEATED_INIT     0x2a
+#define R_PCREL_CALL        0x30
+#define R_SHORT_PCREL_MODE  0x3e
+#define R_LONG_PCREL_MODE   0x3f
+#define R_ABS_CALL          0x40
+#define R_DP_RELATIVE       0x50
+#define R_DLT_REL           0x78
+#define R_CODE_ONE_SYMBOL   0x80
+#define R_MILLI_REL         0xae
+#define R_CODE_PLABEL       0xb0
+#define R_BREAKPOINT        0xb2
+#define R_ENTRY             0xb3
+#define R_ALT_ENTRY         0xb5
+#define R_EXIT              0xb6
+#define R_BEGIN_TRY         0xb7
+#define R_END_TRY           0xb8
+#define R_BEGIN_BRTAB       0xbb
+#define R_END_BRTAB         0xbc
+#define R_STATEMENT         0xbd
+#define R_DATA_EXPR         0xc0
+#define R_CODE_EXPR         0xc1
+#define R_FSEL              0xc2
+#define R_LSEL              0xc3
+#define R_RSEL              0xc4
+#define R_N_MODE            0xc5
+#define R_S_MODE            0xc6
+#define R_D_MODE            0xc7
+#define R_R_MODE            0xc8
+#define R_DATA_OVERRIDE     0xc9
+#define R_TRANSLATED        0xce
+#define R_AUX_UNWIND        0xcf
+#define R_COMP1             0xd0
+#define R_COMP2             0xd1
+#define R_COMP3             0xd2
+#define R_PREV_FIXUP        0xd3
+#define R_SEC_STMT          0xd7
+#define R_N0SEL             0xd8
+#define R_N1SEL             0xd9
+#define R_LINETAB           0xda
+#define R_LINETAB_ESC       0xdb
+#define R_LTP_OVERRIDE      0xdc
+#define R_COMMENT           0xdd
+#define R_RESERVED          0xe0
+
+#endif /* _bfd_som_reloc_h */
Index: include/som/a.out.h
===================================================================
--- include/som/a.out.h (revision 0)
+++ include/som/a.out.h (revision 12)
@@ -0,0 +1,32 @@
+/* Declaration of data structures for the PA-SOM object format.
+   (c) 2007, Quest Software, Inc. All rights reserved.
+   Written by David Leonard based on information published by Hewlett-Packard.
+
+   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 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.,
+   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _bfd_som_a_out_h
+#define _bfd_som_a_out_h
+
+#include "filehdr.h"
+#include "aouthdr.h"
+#include "scnhdr.h"
+#include "spacehdr.h"
+#include "compunit.h"
+#include "reloc.h"
+#include "syms.h"
+
+#endif /* _bfd_som_a_out_h */
Index: include/som/aouthdr.h
===================================================================
--- include/som/aouthdr.h       (revision 0)
+++ include/som/aouthdr.h       (revision 12)
@@ -0,0 +1,107 @@
+/* Declaration of data structures for the PA-SOM object format.
+   (c) 2007, Quest Software, Inc. All rights reserved.
+   Written by David Leonard based on information published by Hewlett-Packard.
+
+   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 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.,
+   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+#ifndef _bfd_som_aouthdr_h
+#define _bfd_som_aouthdr_h
+
+#include "aouttypes.h"
+
+struct aux_id {
+    uint32_t       flags;
+#define AUX_MANDATORY                   0x80000000
+#define AUX_COPY                        0x40000000
+#define AUX_APPEND                      0x20000000
+#define AUX_IGNORE                      0x10000000
+#define AUX_RESERVED_MASK               0x0fff0000
+#define AUX_RESERVED_SHIFT              16
+#define AUX_TYPE_MASK                   0x0000ffff
+#define AUX_TYPE_SHIFT                  0
+    uint32_t        length;
+};
+
+struct som_exec_auxhdr {
+    struct aux_id   som_auxhdr;
+    int32_t         exec_tsize;
+    int32_t         exec_tmem;
+    int32_t         exec_tfile;
+    int32_t         exec_dsize;
+    int32_t         exec_dmem;
+    int32_t         exec_dfile;
+    int32_t         exec_bsize;
+    int32_t         exec_entry;
+    int32_t         exec_flags;
+    int32_t         exec_bfill;
+};
+
+struct copyright_aux_hdr {
+    struct aux_id   header_id;
+    uint32_t        string_length;
+    char            copyright[1];  
+    /* Pad to next 32-bit boundary */
+};
+
+struct user_string_aux_hdr {
+    struct aux_id   header_id;
+    uint32_t        string_length;
+    char            user_string[1]; 
+    /* Pad to next 32-bit boundary */
+};
+
+#define AUX_HDR_SIZE sizeof (struct som_exec_auxhdr)
+
+struct internal_aux_id {
+    bfd_boolean     mandatory;
+    bfd_boolean     copy;
+    bfd_boolean     append;
+    bfd_boolean     ignore;
+    uint16_t        type;
+#define   HPUX_AUX_ID         4
+#define   VERSION_AUX_ID      6
+#define   COPYRIGHT_AUX_ID    9
+    uint32_t        length;
+};
+
+struct internal_som_exec_auxhdr {
+    struct internal_aux_id   som_auxhdr;
+    int32_t         exec_tsize;
+    int32_t         exec_tmem;
+    int32_t         exec_tfile;
+    int32_t         exec_dsize;
+    int32_t         exec_dmem;
+    int32_t         exec_dfile;
+    int32_t         exec_bsize;
+    int32_t         exec_entry;
+    int32_t         exec_flags;
+    int32_t         exec_bfill;
+};
+
+struct internal_copyright_aux_hdr {
+    struct internal_aux_id   header_id;
+    uint32_t        string_length;
+    char *          copyright;
+};
+
+struct internal_user_string_aux_hdr {
+    struct internal_aux_id   header_id;
+    uint32_t        string_length;
+    char *          user_string;
+};
+
+
+#endif /* _bfd_som_aouthdr_h */
Index: bfd/som.c
===================================================================
--- bfd/som.c   (revision 6)
+++ bfd/som.c   (working copy)
@@ -5,6 +5,7 @@
 
    Contributed by the Center for Software Science at the
    University of Utah.
+   Made portable by David Leonard of Quest Software, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -27,16 +28,14 @@
 #include "sysdep.h"
 #include "bfd.h"
 
-#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined 
(HOST_HPPAOSF) || defined(HOST_HPPAMPEIX)
-
 #include "libbfd.h"
-#include "som.h"
 #include "safe-ctype.h"
+#include "som.h"
+#include "som/somswap.h"
 
-#include <sys/param.h>
-#include <signal.h>
-#include <machine/reg.h>
-#include <sys/file.h>
+#ifndef MAX
+#define MAX(a,b)    ((a) > (b) ? (a) : (b))
+#endif
 
 static bfd_reloc_status_type hppa_som_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
@@ -44,61 +43,98 @@
 static bfd_boolean som_is_space (asection *);
 static bfd_boolean som_is_subspace (asection *);
 static int compare_subspaces (const void *, const void *);
-static unsigned long som_compute_checksum (bfd *);
+static uint32_t xor_checksum (void *data, size_t size);
 static bfd_boolean som_build_and_write_symbol_table (bfd *);
-static unsigned int som_slurp_symbol_table (bfd *);
+static bfd_boolean som_slurp_symbol_table (bfd *);
 
-/* Magic not defined in standard HP-UX header files until 8.0.  */
+static int som_bfd_write_aux_id_and_string(bfd * abfd, 
+    struct internal_aux_id * aux_id, uint32_t string_length, char *string);
 
-#ifndef CPU_PA_RISC1_0
-#define CPU_PA_RISC1_0 0x20B
-#endif /* CPU_PA_RISC1_0 */
+#define SOM_DECLARE_READ(tag, internal_tag)                            \
+static bfd_boolean som_bfd_read_##tag (bfd *, struct internal_tag *);  \
+static bfd_boolean                                                     \
+som_bfd_read_##tag (bfd * abfd, struct internal_tag * dst)             \
+{                                                                      \
+  struct tag buf;                                                      \
+  if (bfd_bread ((void *) &buf, sizeof buf, abfd) != sizeof buf)       \
+    return FALSE;                                                      \
+  som_bfd_get_##tag (abfd, &buf, dst);                                 \
+  return TRUE;                                                         \
+}
 
-#ifndef CPU_PA_RISC1_1
-#define CPU_PA_RISC1_1 0x210
-#endif /* CPU_PA_RISC1_1 */
+#define SOM_DECLARE_WRITE(tag, internal_tag)                           \
+static bfd_boolean som_bfd_write_##tag (bfd *, const struct internal_tag *); \
+static bfd_boolean                                                     \
+som_bfd_write_##tag (bfd * abfd, const struct internal_tag * src)      \
+{                                                                      \
+  struct tag buf;                                                      \
+  som_bfd_put_##tag (abfd, src, &buf);                                 \
+  return bfd_bwrite ((void *) &buf, sizeof buf, abfd) == sizeof buf;   \
+}                                                                      \
 
-#ifndef CPU_PA_RISC2_0
-#define CPU_PA_RISC2_0 0x214
-#endif /* CPU_PA_RISC2_0 */
+SOM_DECLARE_READ(lst_header, lst_header)
+SOM_DECLARE_READ(header, header)
+SOM_DECLARE_READ(som_entry, som_entry)
+SOM_DECLARE_READ(som_exec_auxhdr, internal_som_exec_auxhdr)
+SOM_DECLARE_READ(space_dictionary_record, internal_space_dictionary_record)
+SOM_DECLARE_READ(subspace_dictionary_record, 
internal_subspace_dictionary_record)
+SOM_DECLARE_READ(lst_symbol_record, internal_lst_symbol_record)
+SOM_DECLARE_WRITE(aux_id, internal_aux_id)
+SOM_DECLARE_WRITE(symbol_dictionary_record, internal_symbol_dictionary_record)
+SOM_DECLARE_WRITE(space_dictionary_record, internal_space_dictionary_record)
+SOM_DECLARE_WRITE(subspace_dictionary_record, 
internal_subspace_dictionary_record)
+SOM_DECLARE_WRITE(compilation_unit, internal_compilation_unit)
+SOM_DECLARE_WRITE(som_exec_auxhdr, internal_som_exec_auxhdr)
+SOM_DECLARE_WRITE(som_entry, som_entry)
+SOM_DECLARE_WRITE(lst_symbol_record, internal_lst_symbol_record)
 
-#ifndef _PA_RISC1_0_ID
-#define _PA_RISC1_0_ID CPU_PA_RISC1_0
-#endif /* _PA_RISC1_0_ID */
+/* Writes an aux_id + string. Returns bytes written, or 0 on error */
+static int 
+som_bfd_write_aux_id_and_string(bfd * abfd, 
+      struct internal_aux_id * aux_id,
+      uint32_t string_length,
+      char *string)
+{
+  uint32_t len;
+  static char zeroes[4] = {0,0,0,0};
+  unsigned int pad;
 
-#ifndef _PA_RISC1_1_ID
-#define _PA_RISC1_1_ID CPU_PA_RISC1_1
-#endif /* _PA_RISC1_1_ID */
+  BFD_ASSERT (aux_id->length % 4 == 0);
+  BFD_ASSERT (aux_id->length >= string_length + sizeof len);
+  BFD_ASSERT (aux_id->length < string_length + sizeof len + 4); /* minimal */
 
-#ifndef _PA_RISC2_0_ID
-#define _PA_RISC2_0_ID CPU_PA_RISC2_0
-#endif /* _PA_RISC2_0_ID */
+  if (! som_bfd_write_aux_id (abfd, aux_id))
+    return 0;
 
-#ifndef _PA_RISC_MAXID
-#define _PA_RISC_MAXID 0x2FF
-#endif /* _PA_RISC_MAXID */
+  H_PUT_32 (abfd, string_length, &len);
+  if (bfd_bwrite (&len, sizeof len, abfd) != sizeof len)
+    return 0;
 
-#ifndef _PA_RISC_ID
-#define _PA_RISC_ID(__m_num)           \
-    (((__m_num) == _PA_RISC1_0_ID) ||  \
-     ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID))
-#endif /* _PA_RISC_ID */
+  if (bfd_bwrite (string, string_length, abfd) != string_length)
+    return 0;
 
-/* HIUX in it's infinite stupidity changed the names for several "well
-   known" constants.  Work around such braindamage.  Try the HPUX version
-   first, then the HIUX version, and finally provide a default.  */
-#ifdef HPUX_AUX_ID
-#define EXEC_AUX_ID HPUX_AUX_ID
-#endif
+  pad = aux_id->length - string_length - sizeof len;
+  if (pad && bfd_bwrite (zeroes, pad, abfd) != pad)
+    return 0;
 
-#if !defined (EXEC_AUX_ID) && defined (HIUX_AUX_ID)
-#define EXEC_AUX_ID HIUX_AUX_ID
-#endif
+  return sizeof (struct aux_id) + sizeof len + string_length + pad;
+}
 
-#ifndef EXEC_AUX_ID
-#define EXEC_AUX_ID 0
-#endif
+/* Computes the 32bit XOR checksum of a buffer */
+static uint32_t
+xor_checksum (void *data, size_t size)
+{
+  uint32_t checksum;
+  uint32_t *p = (uint32_t *) data;
+  uint32_t *end = (uint32_t *) ((char *) data + size);
 
+  BFD_ASSERT (size % sizeof (uint32_t) == 0);
+  checksum = 0;
+  while (p < end)
+    checksum ^= *p++;
+  return checksum;
+}
+
 /* Size (in chars) of the temporary buffers used during fixup and string
    table writes.   */
 
@@ -634,53 +670,8 @@
   -1
 };
 
-/* These apparently are not in older versions of hpux reloc.h (hpux7).  */
-#ifndef R_DLT_REL
-#define R_DLT_REL 0x78
-#endif
+/* #define NO_PCREL_MODES - only for < PA_2_0 */
 
-#ifndef R_AUX_UNWIND
-#define R_AUX_UNWIND 0xcf
-#endif
-
-#ifndef R_SEC_STMT
-#define R_SEC_STMT 0xd7
-#endif
-
-/* And these first appeared in hpux10.  */
-#ifndef R_SHORT_PCREL_MODE
-#define NO_PCREL_MODES
-#define R_SHORT_PCREL_MODE 0x3e
-#endif
-
-#ifndef R_LONG_PCREL_MODE
-#define R_LONG_PCREL_MODE 0x3f
-#endif
-
-#ifndef R_N0SEL
-#define R_N0SEL 0xd8
-#endif
-
-#ifndef R_N1SEL
-#define R_N1SEL 0xd9
-#endif
-
-#ifndef R_LINETAB
-#define R_LINETAB 0xda
-#endif
-
-#ifndef R_LINETAB_ESC
-#define R_LINETAB_ESC 0xdb
-#endif
-
-#ifndef R_LTP_OVERRIDE
-#define R_LTP_OVERRIDE 0xdc
-#endif
-
-#ifndef R_COMMENT
-#define R_COMMENT 0xdd
-#endif
-
 #define SOM_HOWTO(TYPE, NAME)  \
   HOWTO(TYPE, 0, 0, 32, FALSE, 0, 0, hppa_som_reloc, NAME, FALSE, 0, 0, FALSE)
 
@@ -1648,7 +1639,7 @@
 static const bfd_target *
 som_object_setup (bfd *abfd,
                  struct header *file_hdrp,
-                 struct som_exec_auxhdr *aux_hdrp,
+                 struct internal_som_exec_auxhdr *aux_hdrp,
                  unsigned long current_offset)
 {
   asection *section;
@@ -1796,8 +1787,8 @@
   /* 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 som_subspace_dictionary_record subspace, save_subspace;
+      struct internal_space_dictionary_record space;
+      struct internal_subspace_dictionary_record subspace, save_subspace;
       unsigned int subspace_index;
       asection *space_asect;
       bfd_size_type space_size = 0;
@@ -1806,11 +1797,11 @@
       /* Read the space dictionary element.  */
       if (bfd_seek (abfd,
                    (current_offset + file_hdr->space_location
-                    + space_index * sizeof space),
+                    + space_index * sizeof (struct space_dictionary_record)),
                    SEEK_SET) != 0)
        goto error_return;
-      amt = sizeof space;
-      if (bfd_bread (&space, amt, abfd) != amt)
+
+      if (! som_bfd_read_space_dictionary_record (abfd, &space))
        goto error_return;
 
       /* Setup the space name string.  */
@@ -1843,16 +1834,17 @@
       /* Now, read in the first subspace for this space.  */
       if (bfd_seek (abfd,
                    (current_offset + file_hdr->subspace_location
-                    + space.subspace_index * sizeof subspace),
+                    + space.subspace_index 
+                      * sizeof (struct subspace_dictionary_record)),
                    SEEK_SET) != 0)
        goto error_return;
-      amt = sizeof subspace;
-      if (bfd_bread (&subspace, amt, abfd) != amt)
+      if (! som_bfd_read_subspace_dictionary_record(abfd, &subspace))
        goto error_return;
       /* Seek back to the start of the subspaces for loop below.  */
       if (bfd_seek (abfd,
                    (current_offset + file_hdr->subspace_location
-                    + space.subspace_index * sizeof subspace),
+                    + space.subspace_index 
+                      * sizeof (struct subspace_dictionary_record)),
                    SEEK_SET) != 0)
        goto error_return;
 
@@ -1875,8 +1867,7 @@
          asection *subspace_asect;
 
          /* Read in the next subspace.  */
-         amt = sizeof subspace;
-         if (bfd_bread (&subspace, amt, abfd) != amt)
+         if (! som_bfd_read_subspace_dictionary_record(abfd, &subspace))
            goto error_return;
 
          /* Setup the subspace name string.  */
@@ -1913,7 +1904,7 @@
             header as the key.  Then we can assign correct
             subspace indices.  */
          total_subspaces++;
-         subspace_asect->target_index = bfd_tell (abfd) - sizeof (subspace);
+         subspace_asect->target_index = bfd_tell (abfd) - sizeof (struct 
subspace_dictionary_record);
 
          /* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified
             by the access_control_bits in the subspace header.  */
@@ -2069,15 +2060,13 @@
 som_object_p (bfd *abfd)
 {
   struct header file_hdr;
-  struct som_exec_auxhdr *aux_hdr_ptr = NULL;
+  struct internal_som_exec_auxhdr *aux_hdr_ptr = NULL;
   unsigned long current_offset = 0;
   struct lst_header lst_header;
   struct som_entry som_entry;
-  bfd_size_type amt;
 #define ENTRY_SIZE sizeof (struct som_entry)
 
-  amt = FILE_HDR_SIZE;
-  if (bfd_bread ((void *) &file_hdr, amt, abfd) != amt)
+  if (! som_bfd_read_header (abfd, &file_hdr))
     {
       if (bfd_get_error () != bfd_error_system_call)
        bfd_set_error (bfd_error_wrong_format);
@@ -2118,8 +2107,7 @@
          return NULL;
        }
 
-      amt = SLSTHDR;
-      if (bfd_bread ((void *) &lst_header, amt, abfd) != amt)
+      if (! som_bfd_read_lst_header(abfd, &lst_header))
        {
          if (bfd_get_error () != bfd_error_system_call)
            bfd_set_error (bfd_error_wrong_format);
@@ -2135,8 +2123,7 @@
          return NULL;
        }
 
-      amt = ENTRY_SIZE;
-      if (bfd_bread ((void *) &som_entry, amt, abfd) != amt)
+      if (! som_bfd_read_som_entry(abfd, &som_entry))
        {
          if (bfd_get_error () != bfd_error_system_call)
            bfd_set_error (bfd_error_wrong_format);
@@ -2155,8 +2142,7 @@
       current_offset = som_entry.location;
 
       /* And finally, re-read the som header.  */
-      amt = FILE_HDR_SIZE;
-      if (bfd_bread ((void *) &file_hdr, amt, abfd) != amt)
+      if (! som_bfd_read_header (abfd, &file_hdr))
        {
          if (bfd_get_error () != bfd_error_system_call)
            bfd_set_error (bfd_error_wrong_format);
@@ -2187,8 +2173,7 @@
                                (bfd_size_type) sizeof (*aux_hdr_ptr));
       if (aux_hdr_ptr == NULL)
        return NULL;
-      amt = AUX_HDR_SIZE;
-      if (bfd_bread ((void *) aux_hdr_ptr, amt, abfd) != amt)
+      if (! som_bfd_read_som_exec_auxhdr (abfd, aux_hdr_ptr))
        {
          if (bfd_get_error () != bfd_error_system_call)
            bfd_set_error (bfd_error_wrong_format);
@@ -2239,7 +2224,7 @@
   if (abfd->flags & (EXEC_P | DYNAMIC))
     {
       /* Make and attach an exec header to the BFD.  */
-      amt = sizeof (struct som_exec_auxhdr);
+      amt = sizeof (struct internal_som_exec_auxhdr);
       obj_som_exec_hdr (abfd) = bfd_zalloc (abfd, amt);
       if (obj_som_exec_hdr (abfd) == NULL)
        return FALSE;
@@ -2281,7 +2266,7 @@
       if (som_is_space (section))
        {
          /* Allocate space for the space dictionary.  */
-         amt = sizeof (struct space_dictionary_record);
+         amt = sizeof (struct internal_space_dictionary_record);
          som_section_data (section)->space_dict = bfd_zalloc (abfd, amt);
          if (som_section_data (section)->space_dict == NULL)
            return FALSE;
@@ -2303,7 +2288,7 @@
       else
        {
          /* Allocate space for the subspace dictionary.  */
-         amt = sizeof (struct som_subspace_dictionary_record);
+         amt = sizeof (struct internal_subspace_dictionary_record);
          som_section_data (section)->subspace_dict = bfd_zalloc (abfd, amt);
          if (som_section_data (section)->subspace_dict == NULL)
            return FALSE;
@@ -3003,7 +2988,8 @@
         current buffer contents now and maybe allocate a larger
         buffer.  Each entry will take 4 bytes to hold the string
         length + the string itself + null terminator.  */
-      if (p - tmp_space + 5 + length > tmp_space_size)
+      /* Plus another at most 3 bytes for padding */
+      if (p - tmp_space + 5 + length + 3 > tmp_space_size)
        {
          /* Flush buffer before refilling or reallocating.  */
          amt = p - tmp_space;
@@ -3021,6 +3007,7 @@
                 returning from this function.)  The same technique is
                 used a few more times below when a buffer is
                 reallocated.  */
+             /* XXX: Perhaps replace this scheme with bfd_realloc2()? */
              tmp_space_size = MAX (2 * tmp_space_size, 5 + length);
              tmp_space = alloca (tmp_space_size);
            }
@@ -3072,7 +3059,7 @@
                          asymbol **syms,
                          unsigned int num_syms,
                          unsigned int *string_sizep,
-                         COMPUNIT *compilation_unit)
+                         internal_COMPUNIT *compilation_unit)
 {
   unsigned int i;
 
@@ -3114,7 +3101,7 @@
          /* If there is not enough room for the next entry, then dump
             the current buffer contents now and maybe allocate a
             larger buffer.  */
-         if (p - tmp_space + 5 + length > tmp_space_size)
+         if (p - tmp_space + 5 + length + 3 > tmp_space_size)
            {
              /* Flush buffer before refilling or reallocating.  */
              amt = p - tmp_space;
@@ -3183,7 +3170,7 @@
 
       /* If there is not enough room for the next entry, then dump the
         current buffer contents now and maybe allocate a larger buffer.  */
-     if (p - tmp_space + 5 + length > tmp_space_size)
+     if (p - tmp_space + 5 + length + 3 > tmp_space_size)
        {
          /* Flush buffer before refilling or reallocating.  */
          amt = p - tmp_space;
@@ -3247,7 +3234,7 @@
   unsigned long num_spaces, num_subspaces, i;
   asection *section;
   unsigned int total_subspaces = 0;
-  struct som_exec_auxhdr *exec_header = NULL;
+  struct internal_som_exec_auxhdr *exec_header = NULL;
 
   /* The file header will always be first in an object file,
      everything else can be in random locations.  To keep things
@@ -3276,7 +3263,7 @@
       obj_som_file_hdr (abfd)->aux_header_size
        += sizeof (struct som_exec_auxhdr);
       exec_header = obj_som_exec_hdr (abfd);
-      exec_header->som_auxhdr.type = EXEC_AUX_ID;
+      exec_header->som_auxhdr.type = HPUX_AUX_ID;
       exec_header->som_auxhdr.length = 40;
     }
   if (obj_som_version_hdr (abfd) != NULL)
@@ -3287,19 +3274,14 @@
        return FALSE;
 
       /* Write the aux_id structure and the string length.  */
-      len = sizeof (struct aux_id) + sizeof (unsigned int);
-      obj_som_file_hdr (abfd)->aux_header_size += len;
-      current_offset += len;
-      if (bfd_bwrite ((void *) obj_som_version_hdr (abfd), len, abfd) != len)
+      len = som_bfd_write_aux_id_and_string (abfd, 
+           &obj_som_version_hdr (abfd)->header_id,
+           obj_som_version_hdr (abfd)->string_length,
+           obj_som_version_hdr (abfd)->user_string);
+      if (!len)
        return FALSE;
-
-      /* Write the version string.  */
-      len = obj_som_version_hdr (abfd)->header_id.length - sizeof (int);
-      obj_som_file_hdr (abfd)->aux_header_size += len;
       current_offset += len;
-      if (bfd_bwrite ((void *) obj_som_version_hdr (abfd)->user_string, len, 
abfd)
-         != len)
-       return FALSE;
+      obj_som_file_hdr (abfd)->aux_header_size += len;
     }
 
   if (obj_som_copyright_hdr (abfd) != NULL)
@@ -3310,19 +3292,14 @@
        return FALSE;
 
       /* Write the aux_id structure and the string length.  */
-      len = sizeof (struct aux_id) + sizeof (unsigned int);
-      obj_som_file_hdr (abfd)->aux_header_size += len;
-      current_offset += len;
-      if (bfd_bwrite ((void *) obj_som_copyright_hdr (abfd), len, abfd) != len)
+      len = som_bfd_write_aux_id_and_string (abfd, 
+           &obj_som_copyright_hdr (abfd)->header_id,
+           obj_som_copyright_hdr (abfd)->string_length,
+           obj_som_copyright_hdr (abfd)->copyright);
+      if (!len)
        return FALSE;
-
-      /* Write the copyright string.  */
-      len = obj_som_copyright_hdr (abfd)->header_id.length - sizeof (int);
-      obj_som_file_hdr (abfd)->aux_header_size += len;
       current_offset += len;
-      if (bfd_bwrite ((void *) obj_som_copyright_hdr (abfd)->copyright, len, 
abfd)
-         != len)
-       return FALSE;
+      obj_som_file_hdr (abfd)->aux_header_size += len;
     }
 
   /* Next comes the initialization pointers; we have no initialization
@@ -3355,13 +3332,14 @@
   obj_som_file_hdr (abfd)->subspace_location = current_offset;
   obj_som_file_hdr (abfd)->subspace_total = num_subspaces;
   current_offset
-    += num_subspaces * sizeof (struct som_subspace_dictionary_record);
+    += num_subspaces * sizeof (struct subspace_dictionary_record);
 
   /* Next is the string table for the space/subspace names.  We will
      build and write the string table on the fly.  At the same time
      we will fill in the space/subspace name index fields.  */
 
   /* The string table needs to be aligned on a word boundary.  */
+  /* XXX: Unnecessary? all prior structures written are word aligned */
   if (current_offset % 4)
     current_offset += (4 - (current_offset % 4));
 
@@ -3599,6 +3577,7 @@
   unsigned long current_offset;
   unsigned int strings_size, total_reloc_size;
   bfd_size_type amt;
+  struct header header_target;
 
   /* We must set up the version identifier here as objcopy/strip copy
      private BFD data too late for us to handle this in som_begin_writing.  */
@@ -3729,9 +3708,8 @@
          som_section_data (subsection)->subspace_dict->space_index = i;
 
          /* Dump the current subspace header.  */
-         amt = sizeof (struct som_subspace_dictionary_record);
-         if (bfd_bwrite ((void *) som_section_data (subsection)->subspace_dict,
-                        amt, abfd) != amt)
+         if (! som_bfd_write_subspace_dictionary_record (abfd, 
+                     som_section_data (subsection)->subspace_dict))
            return FALSE;
        }
       /* Goto the next section.  */
@@ -3785,9 +3763,8 @@
          som_section_data (subsection)->subspace_dict->space_index = i;
 
          /* Dump this subspace header.  */
-         amt = sizeof (struct som_subspace_dictionary_record);
-         if (bfd_bwrite ((void *) som_section_data (subsection)->subspace_dict,
-                        amt, abfd) != amt)
+         if (! som_bfd_write_subspace_dictionary_record (abfd,
+                   som_section_data (subsection)->subspace_dict))
            return FALSE;
        }
       /* Goto the next section.  */
@@ -3811,9 +3788,8 @@
        section = section->next;
 
       /* Dump its header.  */
-      amt = sizeof (struct space_dictionary_record);
-      if (bfd_bwrite ((void *) som_section_data (section)->space_dict,
-                    amt, abfd) != amt)
+      if (! som_bfd_write_space_dictionary_record (abfd,
+               som_section_data (section)->space_dict))
        return FALSE;
 
       /* Goto the next section.  */
@@ -3827,8 +3803,8 @@
       if (bfd_seek (abfd, location, SEEK_SET) != 0)
        return FALSE;
 
-      amt = COMPUNITSZ;
-      if (bfd_bwrite ((void *) obj_som_compilation_unit (abfd), amt, abfd) != 
amt)
+      if (! som_bfd_write_compilation_unit (abfd,
+               obj_som_compilation_unit (abfd)))
        return FALSE;
     }
 
@@ -3843,23 +3819,28 @@
   else
     obj_som_file_hdr (abfd)->system_id = CPU_PA_RISC1_0;
 
+  /* Convert the working header structure into target endianness */
+  obj_som_file_hdr (abfd)->checksum = 0;
+  som_bfd_put_header (abfd, obj_som_file_hdr (abfd), &header_target);
+
   /* Compute the checksum for the file header just before writing
      the header to disk.  */
-  obj_som_file_hdr (abfd)->checksum = som_compute_checksum (abfd);
+  /* XOR checksums will be correct regardless of host endianness */
+  header_target.checksum = xor_checksum (&header_target, sizeof header_target);
 
   /* Only thing left to do is write out the file header.  It is always
      at location zero.  Seek there and write it.  */
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
     return FALSE;
   amt = sizeof (struct header);
-  if (bfd_bwrite ((void *) obj_som_file_hdr (abfd), amt, abfd) != amt)
+  if (bfd_bwrite ((void *) &header_target, amt, abfd) != amt)
     return FALSE;
 
   /* Now write the exec header.  */
   if (abfd->flags & (EXEC_P | DYNAMIC))
     {
       long tmp, som_length;
-      struct som_exec_auxhdr *exec_header;
+      struct internal_som_exec_auxhdr *exec_header;
 
       exec_header = obj_som_exec_hdr (abfd);
       exec_header->exec_entry = bfd_get_start_address (abfd);
@@ -3889,29 +3870,12 @@
                    SEEK_SET) != 0)
        return FALSE;
 
-      amt = AUX_HDR_SIZE;
-      if (bfd_bwrite ((void *) exec_header, amt, abfd) != amt)
+      if (! som_bfd_write_som_exec_auxhdr (abfd, exec_header))
        return FALSE;
     }
   return TRUE;
 }
 
-/* Compute and return the checksum for a SOM file header.  */
-
-static unsigned long
-som_compute_checksum (bfd *abfd)
-{
-  unsigned long checksum, count, i;
-  unsigned long *buffer = (unsigned long *) obj_som_file_hdr (abfd);
-
-  checksum = 0;
-  count = sizeof (struct header) / sizeof (unsigned long);
-  for (i = 0; i < count; i++)
-    checksum ^= *(buffer + i);
-
-  return checksum;
-}
-
 static void
 som_bfd_derive_misc_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
                                 asymbol *sym,
@@ -4076,14 +4040,14 @@
   unsigned int num_syms = bfd_get_symcount (abfd);
   file_ptr symtab_location = obj_som_file_hdr (abfd)->symbol_location;
   asymbol **bfd_syms = obj_som_sorted_syms (abfd);
-  struct symbol_dictionary_record *som_symtab = NULL;
+  struct internal_symbol_dictionary_record *som_symtab = NULL;
   unsigned int i;
   bfd_size_type symtab_size;
 
   /* Compute total symbol table size and allocate a chunk of memory
      to hold the symbol table as we build it.  */
   symtab_size = num_syms;
-  symtab_size *= sizeof (struct symbol_dictionary_record);
+  symtab_size *= sizeof (struct internal_symbol_dictionary_record);
   som_symtab = bfd_zmalloc (symtab_size);
   if (som_symtab == NULL && symtab_size != 0)
     goto error_return;
@@ -4119,8 +4083,11 @@
   if (bfd_seek (abfd, symtab_location, SEEK_SET) != 0)
     return FALSE;
 
-  if (bfd_bwrite ((void *) som_symtab, symtab_size, abfd) != symtab_size)
-    goto error_return;
+  for (i = 0; i < num_syms; i++)
+    {
+      if (! som_bfd_write_symbol_dictionary_record (abfd, &som_symtab[i]))
+        goto error_return;
+    }
 
   if (som_symtab != NULL)
     free (som_symtab);
@@ -4203,7 +4170,8 @@
 /* Convert from a SOM subspace index to a BFD section.  */
 
 static asection *
-bfd_section_from_som_symbol (bfd *abfd, struct symbol_dictionary_record 
*symbol)
+bfd_section_from_som_symbol (bfd *abfd, 
+    struct internal_symbol_dictionary_record *symbol)
 {
   asection *section;
 
@@ -4242,13 +4210,13 @@
 
 /* Read and save the symbol table associated with the given BFD.  */
 
-static unsigned int
+static bfd_boolean
 som_slurp_symbol_table (bfd *abfd)
 {
   int symbol_count = bfd_get_symcount (abfd);
   int symsize = sizeof (struct symbol_dictionary_record);
   char *stringtab;
-  struct symbol_dictionary_record *buf = NULL, *bufp, *endbufp;
+  struct symbol_dictionary_record *buf = NULL, *ibufp, *endbufp;
   som_symbol_type *sym, *symbase;
   bfd_size_type amt;
 
@@ -4284,8 +4252,13 @@
 
   /* Iterate over all the symbols and internalize them.  */
   endbufp = buf + symbol_count;
-  for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp)
+  for (ibufp = buf, sym = symbase; ibufp < endbufp; ++ibufp)
     {
+      struct internal_symbol_dictionary_record tmp_sdrec, *bufp = &tmp_sdrec;
+
+      /* Convert from target format to an internal format */
+      som_bfd_get_symbol_dictionary_record (abfd, ibufp, bufp);
+       
       /* I don't think we care about these.  */
       if (bufp->symbol_type == ST_SYM_EXT
          || bufp->symbol_type == ST_ARG_EXT)
@@ -5076,8 +5049,8 @@
 static bfd_boolean
 som_bfd_print_private_bfd_data (bfd *abfd, void *farg)
 {
-  struct som_exec_auxhdr *exec_header;
-  struct aux_id* auxhdr;
+  struct internal_som_exec_auxhdr *exec_header;
+  struct internal_aux_id* auxhdr;
   FILE *f;
 
   f = (FILE *) farg;
@@ -5204,15 +5177,15 @@
 
       if (len % 4)
        pad = (4 - (len % 4));
-      amt = sizeof (struct aux_id) + sizeof (unsigned int) + len + pad;
+      amt = sizeof *obj_som_version_hdr (abfd);
       obj_som_version_hdr (abfd) = bfd_zalloc (abfd, amt);
       if (!obj_som_version_hdr (abfd))
        return FALSE;
       obj_som_version_hdr (abfd)->header_id.type = VERSION_AUX_ID;
       obj_som_version_hdr (abfd)->header_id.length = len + pad;
-      obj_som_version_hdr (abfd)->header_id.length += sizeof (int);
+      obj_som_version_hdr (abfd)->header_id.length += sizeof (uint32_t);
       obj_som_version_hdr (abfd)->string_length = len;
-      strncpy (obj_som_version_hdr (abfd)->user_string, string, len);
+      obj_som_version_hdr (abfd)->user_string = strdup(string);
     }
   else if (type == COPYRIGHT_AUX_ID)
     {
@@ -5221,15 +5194,15 @@
 
       if (len % 4)
        pad = (4 - (len % 4));
-      amt = sizeof (struct aux_id) + sizeof (unsigned int) + len + pad;
+      amt = sizeof *obj_som_copyright_hdr (abfd);
       obj_som_copyright_hdr (abfd) = bfd_zalloc (abfd, amt);
       if (!obj_som_copyright_hdr (abfd))
        return FALSE;
       obj_som_copyright_hdr (abfd)->header_id.type = COPYRIGHT_AUX_ID;
       obj_som_copyright_hdr (abfd)->header_id.length = len + pad;
-      obj_som_copyright_hdr (abfd)->header_id.length += sizeof (int);
+      obj_som_copyright_hdr (abfd)->header_id.length += sizeof (uint32_t);
       obj_som_copyright_hdr (abfd)->string_length = len;
-      strcpy (obj_som_copyright_hdr (abfd)->copyright, string);
+      obj_som_copyright_hdr (abfd)->copyright = strdup(string);
     }
   return TRUE;
 }
@@ -5244,7 +5217,8 @@
                                 const char *product_id,
                                 const char *version_id)
 {
-  COMPUNIT *n = (COMPUNIT *) bfd_zalloc (abfd, (bfd_size_type) COMPUNITSZ);
+  internal_COMPUNIT *n = (internal_COMPUNIT *) bfd_zalloc (abfd, 
+    (bfd_size_type) internal_COMPUNITSZ);
 
   if (n == NULL)
     return FALSE;
@@ -5438,12 +5412,12 @@
                          symindex *count)
 {
   unsigned int i;
-  unsigned int *hash_table = NULL;
+  uint32_t *hash_table = NULL;
   bfd_size_type amt;
   file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
 
   amt = lst_header->hash_size;
-  amt *= sizeof (unsigned int);
+  amt *= sizeof (uint32_t);
   hash_table = bfd_malloc (amt);
   if (hash_table == NULL && lst_header->hash_size != 0)
     goto error_return;
@@ -5460,19 +5434,20 @@
      chain.  */
   for (i = 0; i < lst_header->hash_size; i++)
     {
-      struct lst_symbol_record lst_symbol;
+      struct internal_lst_symbol_record lst_symbol;
+      uint32_t index;
 
       /* An empty chain has zero as it's file offset.  */
-      if (hash_table[i] == 0)
+      index = H_GET_32 (abfd, &hash_table[i]);
+      if (index == 0)
        continue;
 
       /* Seek to the first symbol in this hash chain.  */
-      if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) != 0)
+      if (bfd_seek (abfd, lst_filepos + index, SEEK_SET) != 0)
        goto error_return;
 
       /* Read in this symbol and update the counter.  */
-      amt = sizeof (lst_symbol);
-      if (bfd_bread ((void *) &lst_symbol, amt, abfd) != amt)
+      if (! som_bfd_read_lst_symbol_record (abfd, &lst_symbol))
        goto error_return;
 
       (*count)++;
@@ -5487,8 +5462,7 @@
            goto error_return;
 
          /* Read the symbol in and update the counter.  */
-         amt = sizeof (lst_symbol);
-         if (bfd_bread ((void *) &lst_symbol, amt, abfd) != amt)
+         if (! som_bfd_read_lst_symbol_record (abfd, &lst_symbol))
            goto error_return;
 
          (*count)++;
@@ -5514,13 +5488,13 @@
 {
   unsigned int i, len;
   carsym *set = syms[0];
-  unsigned int *hash_table = NULL;
+  uint32_t *hash_table = NULL;
   struct som_entry *som_dict = NULL;
   bfd_size_type amt;
   file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
 
   amt = lst_header->hash_size;
-  amt *= sizeof (unsigned int);
+  amt *= sizeof (uint32_t);
   hash_table = bfd_malloc (amt);
   if (hash_table == NULL && lst_header->hash_size != 0)
     goto error_return;
@@ -5548,13 +5522,14 @@
   for (i = 0; i < lst_header->hash_size; i++)
     {
       struct lst_symbol_record lst_symbol;
+      uint32_t index = bfd_get_32 (abfd, &hash_table[i]);
 
       /* An empty chain has zero as it's file offset.  */
-      if (hash_table[i] == 0)
+      if (index == 0)
        continue;
 
       /* Seek to and read the first symbol on the chain.  */
-      if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) != 0)
+      if (bfd_seek (abfd, lst_filepos + index, SEEK_SET) != 0)
        goto error_return;
 
       amt = sizeof (lst_symbol);
@@ -5586,7 +5561,8 @@
 
       /* Fill in the file offset.  Note that the "location" field points
         to the SOM itself, not the ar_hdr in front of it.  */
-      set->file_offset = som_dict[lst_symbol.som_index].location
+      set->file_offset = bfd_get_32 (abfd,
+                                    &som_dict[lst_symbol.som_index].location)
                          - sizeof (struct ar_hdr);
 
       /* Go to the next symbol.  */
@@ -5623,7 +5599,8 @@
 
          /* Fill in the file offset.  Note that the "location" field points
             to the SOM itself, not the ar_hdr in front of it.  */
-         set->file_offset = som_dict[lst_symbol.som_index].location
+         set->file_offset = bfd_get_32 (abfd,
+                                    &som_dict[lst_symbol.som_index].location)
                               - sizeof (struct ar_hdr);
 
          /* Go on to the next symbol.  */
@@ -5700,8 +5677,7 @@
 
   /* Read in the library symbol table.  We'll make heavy use of this
      in just a minute.  */
-  amt = sizeof (struct lst_header);
-  if (bfd_bread ((void *) &lst_header, amt, abfd) != amt)
+  if (! som_bfd_read_lst_header (abfd, &lst_header))
     return FALSE;
 
   /* Sanity check.  */
@@ -5846,16 +5822,17 @@
 {
   file_ptr lst_filepos;
   char *strings = NULL, *p;
-  struct lst_symbol_record *lst_syms = NULL, *curr_lst_sym;
+  struct internal_lst_symbol_record *lst_syms = NULL, *curr_lst_sym;
   bfd *curr_bfd;
-  unsigned int *hash_table = NULL;
+  uint32_t *hash_table = NULL;
   struct som_entry *som_dict = NULL;
-  struct lst_symbol_record **last_hash_entry = NULL;
+  struct internal_lst_symbol_record **last_hash_entry = NULL;
   unsigned int curr_som_offset, som_index = 0;
   bfd_size_type amt;
+  unsigned int i;
 
   amt = lst.hash_size;
-  amt *= sizeof (unsigned int);
+  amt *= sizeof (uint32_t);
   hash_table = bfd_zmalloc (amt);
   if (hash_table == NULL && lst.hash_size != 0)
     goto error_return;
@@ -5901,7 +5878,7 @@
 
   /* FIXME should be done with buffers just like everything else...  */
   amt = nsyms;
-  amt *= sizeof (struct lst_symbol_record);
+  amt *= sizeof (struct internal_lst_symbol_record);
   lst_syms = bfd_malloc (amt);
   if (lst_syms == NULL && nsyms != 0)
     goto error_return;
@@ -5991,7 +5968,7 @@
          /* Insert into the hash table.  */
          if (hash_table[curr_lst_sym->symbol_key % lst.hash_size])
            {
-             struct lst_symbol_record *tmp;
+             struct internal_lst_symbol_record *tmp;
 
              /* There is already something at the head of this hash chain,
                 so tack this symbol onto the end of the chain.  */
@@ -6020,7 +5997,7 @@
          p += 4;
          strcpy (p, sym->symbol.name);
          p += strlen (sym->symbol.name) + 1;
-         while ((int) p % 4)
+         while ((p - strings) % 4)
            {
              bfd_put_8 (abfd, 0, p);
              p++;
@@ -6043,19 +6020,24 @@
     }
 
   /* Now scribble out the hash table.  */
+  for (i = 0; i < lst.hash_size; i++)
+    {
+      uint32_t hash = hash_table[i];
+      bfd_put_32 (abfd, hash, &hash_table[i]);
+    }
   amt = lst.hash_size * 4;
   if (bfd_bwrite ((void *) hash_table, amt, abfd) != amt)
     goto error_return;
 
   /* Then the SOM dictionary.  */
-  amt = lst.module_count * sizeof (struct som_entry);
-  if (bfd_bwrite ((void *) som_dict, amt, abfd) != amt)
-    goto error_return;
+  for (i = 0; i < lst.module_count; i++)
+    if (!som_bfd_write_som_entry (abfd, &som_dict[i]))
+      goto error_return;
 
   /* The library symbols.  */
-  amt = nsyms * sizeof (struct lst_symbol_record);
-  if (bfd_bwrite ((void *) lst_syms, amt, abfd) != amt)
-    goto error_return;
+  for (i = 0; i < nsyms; i++)
+    if (!som_bfd_write_lst_symbol_record (abfd, &lst_syms[i]))
+      goto error_return;
 
   /* And finally the strings.  */
   amt = string_size;
@@ -6105,7 +6087,7 @@
   unsigned int i, lst_size, nsyms, stringsize;
   struct ar_hdr hdr;
   struct lst_header lst;
-  int *p;
+  struct lst_header lst_target;
   bfd_size_type amt;
 
   /* We'll use this for the archive's date and mode later.  */
@@ -6179,10 +6161,10 @@
 
   /* Compute the checksum.  Must happen after the entire lst header
      has filled in.  */
-  p = (int *) &lst;
   lst.checksum = 0;
-  for (i = 0; i < sizeof (struct lst_header) / sizeof (int) - 1; i++)
-    lst.checksum ^= *p++;
+  som_bfd_put_lst_header (abfd, &lst, &lst_target);
+  /* Note: XOR checksum is valid regardless of host endianness */
+  lst_target.checksum = xor_checksum (&lst_target, sizeof lst_target);
 
   sprintf (hdr.ar_name, "/               ");
   sprintf (hdr.ar_date, "%ld", bfd_ardata (abfd)->armap_timestamp);
@@ -6205,7 +6187,7 @@
 
   /* Now scribble out the lst header.  */
   amt = sizeof (struct lst_header);
-  if (bfd_bwrite ((void *) &lst, amt, abfd) != amt)
+  if (bfd_bwrite ((void *) &lst_target, amt, abfd) != amt)
     return FALSE;
 
   /* Build and write the armap.  */
@@ -6343,4 +6325,3 @@
   NULL
 };
 
-#endif /* HOST_HPPAHPUX || HOST_HPPABSD || HOST_HPPAOSF */
Index: bfd/som.h
===================================================================
--- bfd/som.h   (revision 6)
+++ bfd/som.h   (working copy)
@@ -4,6 +4,7 @@
 
    Contributed by the Center for Software Science at the
    University of Utah (address@hidden).
+   Made portable by David Leonard of Quest Software, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -27,31 +28,11 @@
 
 #include "libhppa.h"
 
-/* We want reloc.h to provide PA 2.0 defines.  */
 #define PA_2_0
+#include "som/a.out.h"
+#include "som/lst.h"
+#include "aout/ar.h"
 
-#include <a.out.h>
-#include <lst.h>
-#include <ar.h>
-
-/* The SOM BFD backend doesn't currently use anything from these
-   two include files, but it's likely to need them in the future.  */
-#ifdef R_DLT_REL
-#include <shl.h>
-#include <dl.h>
-#endif
-
-#if defined(HOST_HPPABSD) || defined (HOST_HPPAOSF)
-/* BSD uses a completely different scheme for object file identification.
-   so for now, define _PA_RISC_ID to accept any random value for a model
-   number.  */
-#undef _PA_RISC_ID
-#define _PA_RISC_ID(__m_num) 1
-#endif /* HOST_HPPABSD */
-
-#define FILE_HDR_SIZE sizeof (struct header)
-#define AUX_HDR_SIZE sizeof (struct som_exec_auxhdr)
-
 typedef struct som_symbol
 {
   asymbol symbol;
@@ -117,10 +98,10 @@
      generated from scratch.  They need not be copied for objcopy
      or strip to work.  */
   struct header *file_hdr;
-  struct copyright_aux_hdr *copyright_aux_hdr;
-  struct user_string_aux_hdr *version_aux_hdr;
-  struct som_exec_auxhdr *exec_hdr;
-  COMPUNIT *comp_unit;
+  struct internal_copyright_aux_hdr *copyright_aux_hdr;
+  struct internal_user_string_aux_hdr *version_aux_hdr;
+  struct internal_som_exec_auxhdr *exec_hdr;
+  internal_COMPUNIT *comp_unit;
 
   /* Pointers to a saved copy of the symbol and string tables.  These
      need not be copied for objcopy or strip to work.  */
@@ -143,35 +124,6 @@
   struct somdata a;
 };
 
-struct som_subspace_dictionary_record
-{
-  int space_index;
-  unsigned int access_control_bits : 7;
-  unsigned int memory_resident : 1;
-  unsigned int dup_common : 1;
-  unsigned int is_common : 1;
-  unsigned int is_loadable : 1;
-  unsigned int quadrant : 2;
-  unsigned int initially_frozen : 1;
-  unsigned int is_first : 1;
-  unsigned int code_only : 1;
-  unsigned int sort_key : 8;
-  unsigned int replicate_init  : 1;
-  unsigned int continuation : 1;
-  unsigned int is_tspecific : 1;
-  unsigned int is_comdat : 1;
-  unsigned int reserved : 4;
-  int file_loc_init_value;
-  unsigned int initialization_length;
-  unsigned int subspace_start;
-  unsigned int subspace_length;
-  unsigned int reserved2 : 5;   
-  unsigned int alignment :27;
-  union name_pt name;
-  int fixup_request_index;
-  unsigned int fixup_request_quantity;
-};
-
 /* Substructure of som_section_data_struct used to hold information
    which can't be represented by the generic BFD section structure,
    but which must be copied during objcopy or strip.  */
@@ -215,8 +167,8 @@
   struct som_copyable_section_data_struct *copy_data;
   unsigned int reloc_size;
   unsigned char *reloc_stream;
-  struct space_dictionary_record *space_dict;
-  struct som_subspace_dictionary_record *subspace_dict;
+  struct internal_space_dictionary_record *space_dict;
+  struct internal_subspace_dictionary_record *subspace_dict;
 };
 
 #define somdata(bfd)                   ((bfd)->tdata.som_data->a)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]