Fix extracting from AIX big archives.
[deliverable/binutils-gdb.git] / bfd / nlm32-ppc.c
index c46f94b5422921d01b89425a4cf9735f84d2b6d1..98410a8d50a578177f39124070f6b757f539273e 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for 32-bit PowerPC NLM (NetWare Loadable Module)
-   Copyright (C) 1994 Free Software Foundation, Inc.
+   Copyright 1994, 1995, 2000, 2001 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -15,12 +15,15 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
 #include "libbfd.h"
 
+/* The format of a PowerPC NLM changed.  Define OLDFORMAT to get the
+   old format.  */
+
 #define ARCH_SIZE 32
 
 #include "nlm/ppc-ext.h"
@@ -28,23 +31,41 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "libnlm.h"
 
+#ifdef OLDFORMAT
 static boolean nlm_powerpc_backend_object_p
   PARAMS ((bfd *));
 static boolean nlm_powerpc_write_prefix
   PARAMS ((bfd *));
+#endif
+
 static boolean nlm_powerpc_read_reloc
   PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
 static boolean nlm_powerpc_mangle_relocs
   PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
 static boolean nlm_powerpc_read_import
   PARAMS ((bfd *, nlmNAME(symbol_type) *));
+
+#ifdef OLDFORMAT
 static boolean nlm_powerpc_write_reloc
   PARAMS ((bfd *, asection *, arelent *, int));
+#endif
+
 static boolean nlm_powerpc_write_import
   PARAMS ((bfd *, asection *, arelent *));
 static boolean nlm_powerpc_write_external
   PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
+
+#ifndef OLDFORMAT
+static boolean nlm_powerpc_set_public_section
+  PARAMS ((bfd *, nlmNAME(symbol_type) *));
+static bfd_vma nlm_powerpc_get_public_offset
+  PARAMS ((bfd *, asymbol *));
+#endif
 \f
+#ifdef OLDFORMAT
+
+/* The prefix header is only used in the old format.  */
+
 /* PowerPC NLM's have a prefix header before the standard NLM.  This
    function reads it in, verifies the version, and seeks the bfd to
    the location before the regular NLM header.  */
@@ -55,11 +76,11 @@ nlm_powerpc_backend_object_p (abfd)
 {
   struct nlm32_powerpc_external_prefix_header s;
 
-  if (bfd_read ((PTR) &s, sizeof s, 1, abfd) != sizeof s)
+  if (bfd_bread ((PTR) &s, (bfd_size_type) sizeof s, abfd) != sizeof s)
     return false;
 
   if (memcmp (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature) != 0
-      || bfd_h_get_32 (abfd, s.headerVersion) != NLM32_POWERPC_HEADER_VERSION)
+      || H_GET_32 (abfd, s.headerVersion) != NLM32_POWERPC_HEADER_VERSION)
     return false;
 
   return true;
@@ -75,361 +96,448 @@ nlm_powerpc_write_prefix (abfd)
 
   memset (&s, 0, sizeof s);
   memcpy (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature);
-  bfd_h_put_32 (abfd, (bfd_vma) NLM32_POWERPC_HEADER_VERSION, s.headerVersion);
-  bfd_h_put_32 (abfd, (bfd_vma) 0, s.origins);
+  H_PUT_32 (abfd, NLM32_POWERPC_HEADER_VERSION, s.headerVersion);
+  H_PUT_32 (abfd, 0, s.origins);
 
   /* FIXME: What should we do about the date?  */
 
-  if (bfd_write ((PTR) &s, sizeof s, 1, abfd) != sizeof s)
+  if (bfd_bwrite ((PTR) &s, (bfd_size_type) sizeof s, abfd) != sizeof s)
     return false;
 
   return true;
 }
+
+#endif /* OLDFORMAT */
 \f
+#ifndef OLDFORMAT
+
+/* There is only one type of reloc in a PowerPC NLM.  */
+
+static reloc_howto_type nlm_powerpc_howto =
+  HOWTO (0,                    /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        0,                     /* special_function */
+        "32",                  /* name */
+        true,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false);                /* pcrel_offset */
+
+/* Read a PowerPC NLM reloc.  */
+
+static boolean
+nlm_powerpc_read_reloc (abfd, sym, secp, rel)
+     bfd *abfd;
+     nlmNAME(symbol_type) *sym;
+     asection **secp;
+     arelent *rel;
+{
+  bfd_byte temp[4];
+  bfd_vma val;
+  const char *name;
+
+  if (bfd_bread (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
+    return false;
+
+  val = bfd_get_32 (abfd, temp);
+
+  /* The value is a word offset into either the code or data segment.
+     This is the location which needs to be adjusted.
+
+     The high bit is 0 if the value is an offset into the data
+     segment, or 1 if the value is an offset into the text segment.
+
+     If this is a relocation fixup rather than an imported symbol (the
+     sym argument is NULL), then the second most significant bit is 0
+     if the address of the data segment should be added to the
+     location addressed by the value, or 1 if the address of the text
+     segment should be added.
+
+     If this is an imported symbol, the second most significant bit is
+     not used and must be 0.  */
+
+  if ((val & NLM_HIBIT) == 0)
+    name = NLM_INITIALIZED_DATA_NAME;
+  else
+    {
+      name = NLM_CODE_NAME;
+      val &=~ NLM_HIBIT;
+    }
+  *secp = bfd_get_section_by_name (abfd, name);
+
+  if (sym == NULL)
+    {
+      if ((val & (NLM_HIBIT >> 1)) == 0)
+       name = NLM_INITIALIZED_DATA_NAME;
+      else
+       {
+         name = NLM_CODE_NAME;
+         val &=~ (NLM_HIBIT >> 1);
+       }
+      rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr;
+    }
+
+  rel->howto = &nlm_powerpc_howto;
+
+  rel->address = val << 2;
+  rel->addend = 0;
+
+  return true;
+}
+
+#else /* OLDFORMAT */
+
+/* This reloc handling is only applicable to the old format.  */
+
 /* How to process the various reloc types.  PowerPC NLMs use XCOFF
    reloc types, and I have just copied the XCOFF reloc table here.  */
 
 static reloc_howto_type nlm_powerpc_howto_table[] =
 {
   /* Standard 32 bit relocation.  */
-  HOWTO (0,                    /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        32,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0,                    /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_POS",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffffffff,            /* src_mask */                             
-        0xffffffff,            /* dst_mask */                             
+        0,                     /* special_function */
+        "R_POS",               /* name */
+        true,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* 32 bit relocation, but store negative value.  */
-  HOWTO (1,                    /* type */                                 
-        0,                     /* rightshift */                           
-        -2,                    /* size (0 = byte, 1 = short, 2 = long) */ 
-        32,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (1,                    /* type */
+        0,                     /* rightshift */
+        -2,                    /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_NEG",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffffffff,            /* src_mask */                             
-        0xffffffff,            /* dst_mask */                             
+        0,                     /* special_function */
+        "R_NEG",               /* name */
+        true,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* 32 bit PC relative relocation.  */
-  HOWTO (2,                    /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        32,                    /* bitsize */                   
-        true,                  /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (2,                    /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_REL",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffffffff,            /* src_mask */                             
-        0xffffffff,            /* dst_mask */                             
+        0,                     /* special_function */
+        "R_REL",               /* name */
+        true,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* 16 bit TOC relative relocation.  */
-  HOWTO (3,                    /* type */                                 
-        0,                     /* rightshift */                           
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        16,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (3,                    /* type */
+        0,                     /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_TOC",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_TOC",               /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* I don't really know what this is.  */
-  HOWTO (4,                    /* type */                                 
-        1,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        32,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (4,                    /* type */
+        1,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_RTB",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffffffff,            /* src_mask */                             
-        0xffffffff,            /* dst_mask */                             
+        0,                     /* special_function */
+        "R_RTB",               /* name */
+        true,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* External TOC relative symbol.  */
-  HOWTO (5,                    /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        16,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (5,                    /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_GL",                /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_GL",                /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* Local TOC relative symbol.  */
-  HOWTO (6,                    /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        16,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (6,                    /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_TCL",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_TCL",               /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   { 7 },
-  
+
   /* Non modifiable absolute branch.  */
-  HOWTO (8,                    /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        26,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (8,                    /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        26,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_BA",                /* name */                                 
-        true,                  /* partial_inplace */                      
-        0x3fffffc,             /* src_mask */                             
-        0x3fffffc,             /* dst_mask */                             
+        0,                     /* special_function */
+        "R_BA",                /* name */
+        true,                  /* partial_inplace */
+        0x3fffffc,             /* src_mask */
+        0x3fffffc,             /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   { 9 },
 
   /* Non modifiable relative branch.  */
-  HOWTO (0xa,                  /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        26,                    /* bitsize */                   
-        true,                  /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0xa,                  /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        26,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_BR",                /* name */                                 
-        true,                  /* partial_inplace */                      
-        0x3fffffc,             /* src_mask */                             
-        0x3fffffc,             /* dst_mask */                             
+        0,                     /* special_function */
+        "R_BR",                /* name */
+        true,                  /* partial_inplace */
+        0x3fffffc,             /* src_mask */
+        0x3fffffc,             /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   { 0xb },
 
   /* Indirect load.  */
-  HOWTO (0xc,                  /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        16,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0xc,                  /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_RL",                /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_RL",                /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* Load address.  */
-  HOWTO (0xd,                  /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        16,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0xd,                  /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_RLA",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_RLA",               /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   { 0xe },
-  
+
   /* Non-relocating reference.  */
-  HOWTO (0xf,                  /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        32,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0xf,                  /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_REF",               /* name */                                 
-        false,                 /* partial_inplace */                      
-        0,                     /* src_mask */                             
-        0,                     /* dst_mask */                             
+        0,                     /* special_function */
+        "R_REF",               /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   { 0x10 },
   { 0x11 },
-  
+
   /* TOC relative indirect load.  */
-  HOWTO (0x12,                 /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        16,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0x12,                 /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_TRL",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_TRL",               /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* TOC relative load address.  */
-  HOWTO (0x13,                 /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        16,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0x13,                 /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_TRLA",              /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_TRLA",              /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* Modifiable relative branch.  */
-  HOWTO (0x14,                 /* type */                                 
-        1,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        32,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0x14,                 /* type */
+        1,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_RRTBI",             /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffffffff,            /* src_mask */                             
-        0xffffffff,            /* dst_mask */                             
+        0,                     /* special_function */
+        "R_RRTBI",             /* name */
+        true,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* Modifiable absolute branch.  */
-  HOWTO (0x15,                 /* type */                                 
-        1,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        32,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0x15,                 /* type */
+        1,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_RRTBA",             /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffffffff,            /* src_mask */                             
-        0xffffffff,            /* dst_mask */                             
+        0,                     /* special_function */
+        "R_RRTBA",             /* name */
+        true,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* Modifiable call absolute indirect.  */
-  HOWTO (0x16,                 /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        16,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0x16,                 /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_CAI",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_CAI",               /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* Modifiable call relative.  */
-  HOWTO (0x17,                 /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        16,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0x17,                 /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_REL",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_REL",               /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* Modifiable branch absolute.  */
-  HOWTO (0x18,                 /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        16,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0x18,                 /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_RBA",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_RBA",               /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* Modifiable branch absolute.  */
-  HOWTO (0x19,                 /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        16,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0x19,                 /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_RBAC",              /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_RBAC",              /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* Modifiable branch relative.  */
-  HOWTO (0x1a,                 /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        26,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0x1a,                 /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        26,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_REL",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_REL",               /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false),                /* pcrel_offset */
-  
+
   /* Modifiable branch absolute.  */
-  HOWTO (0x1b,                 /* type */                                 
-        0,                     /* rightshift */                           
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
-        16,                    /* bitsize */                   
-        false,                 /* pc_relative */                          
-        0,                     /* bitpos */                               
+  HOWTO (0x1b,                 /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        0,                     /* special_function */                     
-        "R_REL",               /* name */                                 
-        true,                  /* partial_inplace */                      
-        0xffff,                /* src_mask */                             
-        0xffff,                /* dst_mask */                             
+        0,                     /* special_function */
+        "R_REL",               /* name */
+        true,                  /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         false)                 /* pcrel_offset */
 };
 
@@ -453,14 +561,14 @@ nlm_powerpc_read_reloc (abfd, sym, secp, rel)
   asection *code_sec, *data_sec, *bss_sec;
 
   /* Read the reloc from the file.  */
-  if (bfd_read (&ext, sizeof ext, 1, abfd) != sizeof ext)
+  if (bfd_bread (&ext, (bfd_size_type) sizeof ext, abfd) != sizeof ext)
     return false;
 
   /* Swap in the fields.  */
-  l_vaddr = bfd_h_get_32 (abfd, ext.l_vaddr);
-  l_symndx = bfd_h_get_32 (abfd, ext.l_symndx);
-  l_rtype = bfd_h_get_16 (abfd, ext.l_rtype);
-  l_rsecnm = bfd_h_get_16 (abfd, ext.l_rsecnm);
+  l_vaddr = H_GET_32 (abfd, ext.l_vaddr);
+  l_symndx = H_GET_32 (abfd, ext.l_symndx);
+  l_rtype = H_GET_16 (abfd, ext.l_rtype);
+  l_rsecnm = H_GET_16 (abfd, ext.l_rsecnm);
 
   /* Get the sections now, for convenience.  */
   code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
@@ -525,15 +633,17 @@ nlm_powerpc_read_reloc (abfd, sym, secp, rel)
   return true;
 }
 
+#endif /* OLDFORMAT */
+
 /* Mangle PowerPC NLM relocs for output.  */
 
 static boolean
 nlm_powerpc_mangle_relocs (abfd, sec, data, offset, count)
-     bfd *abfd;
-     asection *sec;
-     PTR data;
-     bfd_vma offset;
-     bfd_size_type count;
+     bfd *abfd ATTRIBUTE_UNUSED;
+     asection *sec ATTRIBUTE_UNUSED;
+     PTR data ATTRIBUTE_UNUSED;
+     bfd_vma offset ATTRIBUTE_UNUSED;
+     bfd_size_type count ATTRIBUTE_UNUSED;
 {
   return true;
 }
@@ -551,39 +661,34 @@ nlm_powerpc_read_import (abfd, sym)
   unsigned char symlength;             /* length of symbol name */
   char *name;
 
-  if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
+  if (bfd_bread ((PTR) &symlength, (bfd_size_type) sizeof (symlength), abfd)
       != sizeof (symlength))
     return (false);
   sym -> symbol.the_bfd = abfd;
-  name = bfd_alloc (abfd, symlength + 1);
+  name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
   if (name == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
-  if (bfd_read (name, symlength, 1, abfd) != symlength)
+    return false;
+  if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
     return (false);
   name[symlength] = '\0';
   sym -> symbol.name = name;
   sym -> symbol.flags = 0;
   sym -> symbol.value = 0;
-  sym -> symbol.section = &bfd_und_section;
-  if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
+  sym -> symbol.section = bfd_und_section_ptr;
+  if (bfd_bread ((PTR) temp, (bfd_size_type) sizeof (temp), abfd)
+      != sizeof (temp))
     return (false);
-  rcount = bfd_h_get_32 (abfd, temp);
+  rcount = H_GET_32 (abfd, temp);
   nlm_relocs = ((struct nlm_relent *)
                bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
   if (nlm_relocs == (struct nlm_relent *) NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
   sym -> relocs = nlm_relocs;
   sym -> rcnt = 0;
   while (sym -> rcnt < rcount)
     {
       asection *section;
-      
+
       if (nlm_powerpc_read_reloc (abfd, sym, &section,
                                  &nlm_relocs -> reloc)
          == false)
@@ -595,6 +700,79 @@ nlm_powerpc_read_import (abfd, sym)
   return true;
 }
 
+#ifndef OLDFORMAT
+
+/* Write a PowerPC NLM reloc.  */
+
+static boolean
+nlm_powerpc_write_import (abfd, sec, rel)
+     bfd *abfd;
+     asection *sec;
+     arelent *rel;
+{
+  asymbol *sym;
+  bfd_vma val;
+  bfd_byte temp[4];
+
+  /* PowerPC NetWare only supports one kind of reloc.  */
+  if (rel->addend != 0
+      || rel->howto == NULL
+      || rel->howto->rightshift != 0
+      || rel->howto->size != 2
+      || rel->howto->bitsize != 32
+      || rel->howto->bitpos != 0
+      || rel->howto->pc_relative
+      || (rel->howto->src_mask != 0xffffffff && rel->addend != 0)
+      || rel->howto->dst_mask != 0xffffffff)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return false;
+    }
+
+  sym = *rel->sym_ptr_ptr;
+
+  /* The value we write out is the offset into the appropriate
+     segment, rightshifted by two.  This offset is the section vma,
+     adjusted by the vma of the lowest section in that segment, plus
+     the address of the relocation.  */
+  val = bfd_get_section_vma (abfd, sec) + rel->address;
+  if ((val & 3) != 0)
+    {
+      bfd_set_error (bfd_error_bad_value);
+      return false;
+    }
+  val >>= 2;
+
+  /* The high bit is 0 if the reloc is in the data section, or 1 if
+     the reloc is in the code section.  */
+  if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
+    val -= nlm_get_data_low (abfd);
+  else
+    {
+      val -= nlm_get_text_low (abfd);
+      val |= NLM_HIBIT;
+    }
+
+  if (! bfd_is_und_section (bfd_get_section (sym)))
+    {
+      /* This is an internal relocation fixup.  The second most
+        significant bit is 0 if this is a reloc against the data
+        segment, or 1 if it is a reloc against the text segment.  */
+      if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE)
+       val |= NLM_HIBIT >> 1;
+    }
+
+  bfd_put_32 (abfd, val, temp);
+  if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
+    return false;
+
+  return true;
+}
+
+#else /* OLDFORMAT */
+
+/* This is used for the reloc handling in the old format.  */
+
 /* Write a PowerPC NLM reloc.  */
 
 static boolean
@@ -611,7 +789,7 @@ nlm_powerpc_write_reloc (abfd, sec, rel, indx)
   unsigned long l_symndx;
   int l_rtype;
   int l_rsecnm;
-  const reloc_howto_type *howto;
+  reloc_howto_type *howto;
   bfd_size_type address;
 
   /* Get the sections now, for convenience.  */
@@ -623,7 +801,7 @@ nlm_powerpc_write_reloc (abfd, sec, rel, indx)
   symsec = bfd_get_section (sym);
   if (indx != -1)
     {
-      BFD_ASSERT (symsec == &bfd_und_section);
+      BFD_ASSERT (bfd_is_und_section (symsec));
       l_symndx = indx + 3;
     }
   else
@@ -641,7 +819,7 @@ nlm_powerpc_write_reloc (abfd, sec, rel, indx)
        }
     }
 
-  bfd_h_put_32 (abfd, (bfd_vma) l_symndx, ext.l_symndx);
+  H_PUT_32 (abfd, l_symndx, ext.l_symndx);
 
   for (howto = nlm_powerpc_howto_table;
        howto < nlm_powerpc_howto_table + HOWTO_COUNT;
@@ -672,7 +850,7 @@ nlm_powerpc_write_reloc (abfd, sec, rel, indx)
   if (howto->complain_on_overflow == complain_overflow_signed)
     l_rtype |= 0x8000;
   l_rtype |= (howto->bitsize - 1) << 8;
-  bfd_h_put_16 (abfd, (bfd_vma) l_rtype, ext.l_rtype);
+  H_PUT_16 (abfd, l_rtype, ext.l_rtype);
 
   address = rel->address;
 
@@ -689,10 +867,10 @@ nlm_powerpc_write_reloc (abfd, sec, rel, indx)
       return false;
     }
 
-  bfd_h_put_16 (abfd, (bfd_vma) l_rsecnm, ext.l_rsecnm);
-  bfd_h_put_32 (abfd, (bfd_vma) address, ext.l_vaddr);
+  H_PUT_16 (abfd, l_rsecnm, ext.l_rsecnm);
+  H_PUT_32 (abfd, address, ext.l_vaddr);
 
-  if (bfd_write (&ext, sizeof ext, 1, abfd) != sizeof ext)
+  if (bfd_bwrite (&ext, (bfd_size_type) sizeof ext, abfd) != sizeof ext)
     return false;
 
   return true;
@@ -709,6 +887,8 @@ nlm_powerpc_write_import (abfd, sec, rel)
   return nlm_powerpc_write_reloc (abfd, sec, rel, -1);
 }
 
+#endif /* OLDFORMAT */
+
 /* Write a PowerPC NLM external symbol.  This routine keeps a static
    count of the symbol index.  FIXME: I don't know if this is
    necessary, and the index never gets reset.  */
@@ -720,50 +900,140 @@ nlm_powerpc_write_external (abfd, count, sym, relocs)
      asymbol *sym;
      struct reloc_and_sec *relocs;
 {
-  int i;
+  unsigned int i;
   bfd_byte len;
   unsigned char temp[NLM_TARGET_LONG_SIZE];
+#ifdef OLDFORMAT
   static int indx;
+#endif
 
   len = strlen (sym->name);
-  if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
-      || bfd_write (sym->name, len, 1, abfd) != len)
+  if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
+       != sizeof (bfd_byte))
+      || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
     return false;
 
   bfd_put_32 (abfd, count, temp);
-  if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
+  if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
     return false;
 
   for (i = 0; i < count; i++)
     {
-      if (nlm_powerpc_write_reloc (abfd, relocs[i].sec,
-                                  relocs[i].rel, indx) == false)
+#ifndef OLDFORMAT
+      if (! nlm_powerpc_write_import (abfd, relocs[i].sec, relocs[i].rel))
+       return false;
+#else
+      if (! nlm_powerpc_write_reloc (abfd, relocs[i].sec,
+                                    relocs[i].rel, indx))
        return false;
+#endif
     }
 
+#ifdef OLDFORMAT
   ++indx;
+#endif
+
+  return true;
+}
+\f
+#ifndef OLDFORMAT
+
+/* PowerPC Netware uses a word offset, not a byte offset, for public
+   symbols.  */
+
+/* Set the section for a public symbol.  */
+
+static boolean
+nlm_powerpc_set_public_section (abfd, sym)
+     bfd *abfd;
+     nlmNAME(symbol_type) *sym;
+{
+  if (sym->symbol.value & NLM_HIBIT)
+    {
+      sym->symbol.value &= ~NLM_HIBIT;
+      sym->symbol.flags |= BSF_FUNCTION;
+      sym->symbol.section =
+       bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+    }
+  else
+    {
+      sym->symbol.section =
+       bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+    }
+
+  sym->symbol.value <<= 2;
 
   return true;
 }
 
+/* Get the offset to write out for a public symbol.  */
+
+static bfd_vma
+nlm_powerpc_get_public_offset (abfd, sym)
+     bfd *abfd;
+     asymbol *sym;
+{
+  bfd_vma offset;
+  asection *sec;
+
+  offset = bfd_asymbol_value (sym);
+  sec = bfd_get_section (sym);
+  if (sec->flags & SEC_CODE)
+    {
+      offset -= nlm_get_text_low (abfd);
+      offset |= NLM_HIBIT;
+    }
+  else if (sec->flags & (SEC_DATA | SEC_ALLOC))
+    {
+      /* SEC_ALLOC is for the .bss section.  */
+      offset -= nlm_get_data_low (abfd);
+    }
+  else
+    {
+      /* We can't handle an exported symbol that is not in the code or
+        data segment.  */
+      bfd_set_error (bfd_error_invalid_operation);
+      /* FIXME: No way to return error.  */
+      abort ();
+    }
+
+  return offset;
+}
+
+#endif /* ! defined (OLDFORMAT) */
+\f
 #include "nlmswap.h"
 
 static const struct nlm_backend_data nlm32_powerpc_backend =
 {
   "NetWare PowerPC Module \032",
   sizeof (Nlm32_powerpc_External_Fixed_Header),
+#ifndef OLDFORMAT
+  0,   /* optional_prefix_size */
+#else
   sizeof (struct nlm32_powerpc_external_prefix_header),
+#endif
   bfd_arch_powerpc,
   0,
   false,
+#ifndef OLDFORMAT
+  0,   /* backend_object_p */
+  0,   /* write_prefix */
+#else
   nlm_powerpc_backend_object_p,
   nlm_powerpc_write_prefix,
+#endif
   nlm_powerpc_read_reloc,
   nlm_powerpc_mangle_relocs,
   nlm_powerpc_read_import,
   nlm_powerpc_write_import,
+#ifndef OLDFORMAT
+  nlm_powerpc_set_public_section,
+  nlm_powerpc_get_public_offset,
+#else
   0,   /* set_public_section */
   0,   /* get_public_offset */
+#endif
   nlm_swap_fixed_header_in,
   nlm_swap_fixed_header_out,
   nlm_powerpc_write_external,
This page took 0.043497 seconds and 4 git commands to generate.