OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [bfd/] [nlm32-ppc.c] - Diff between revs 834 and 842

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 834 Rev 842
/* Support for 32-bit PowerPC NLM (NetWare Loadable Module)
/* Support for 32-bit PowerPC NLM (NetWare Loadable Module)
   Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
   Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
   2007 Free Software Foundation, Inc.
   2007 Free Software Foundation, Inc.
 
 
   This file is part of BFD, the Binary File Descriptor library.
   This file is part of BFD, the Binary File Descriptor library.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */
   MA 02110-1301, USA.  */
 
 
#include "bfd.h"
#include "bfd.h"
#include "sysdep.h"
#include "sysdep.h"
#include "libbfd.h"
#include "libbfd.h"
 
 
/* The format of a PowerPC NLM changed.  Define OLDFORMAT to get the
/* The format of a PowerPC NLM changed.  Define OLDFORMAT to get the
   old format.  */
   old format.  */
 
 
#define ARCH_SIZE 32
#define ARCH_SIZE 32
 
 
#include "nlm/ppc-ext.h"
#include "nlm/ppc-ext.h"
#define Nlm_External_Fixed_Header       Nlm32_powerpc_External_Fixed_Header
#define Nlm_External_Fixed_Header       Nlm32_powerpc_External_Fixed_Header
 
 
#include "libnlm.h"
#include "libnlm.h"


#ifdef OLDFORMAT
#ifdef OLDFORMAT
 
 
/* The prefix header is only used in the old format.  */
/* The prefix header is only used in the old format.  */
 
 
/* PowerPC NLM's have a prefix header before the standard NLM.  This
/* PowerPC NLM's have a prefix header before the standard NLM.  This
   function reads it in, verifies the version, and seeks the bfd to
   function reads it in, verifies the version, and seeks the bfd to
   the location before the regular NLM header.  */
   the location before the regular NLM header.  */
 
 
static bfd_boolean
static bfd_boolean
nlm_powerpc_backend_object_p (bfd *abfd)
nlm_powerpc_backend_object_p (bfd *abfd)
{
{
  struct nlm32_powerpc_external_prefix_header s;
  struct nlm32_powerpc_external_prefix_header s;
 
 
  if (bfd_bread (& s, (bfd_size_type) sizeof s, abfd) != sizeof s)
  if (bfd_bread (& s, (bfd_size_type) sizeof s, abfd) != sizeof s)
    return FALSE;
    return FALSE;
 
 
  if (memcmp (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature) != 0
  if (memcmp (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature) != 0
      || H_GET_32 (abfd, s.headerVersion) != NLM32_POWERPC_HEADER_VERSION)
      || H_GET_32 (abfd, s.headerVersion) != NLM32_POWERPC_HEADER_VERSION)
    return FALSE;
    return FALSE;
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* Write out the prefix.  */
/* Write out the prefix.  */
 
 
static bfd_boolean
static bfd_boolean
nlm_powerpc_write_prefix (bfd *abfd)
nlm_powerpc_write_prefix (bfd *abfd)
{
{
  struct nlm32_powerpc_external_prefix_header s;
  struct nlm32_powerpc_external_prefix_header s;
 
 
  memset (&s, 0, sizeof s);
  memset (&s, 0, sizeof s);
  memcpy (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature);
  memcpy (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature);
  H_PUT_32 (abfd, NLM32_POWERPC_HEADER_VERSION, s.headerVersion);
  H_PUT_32 (abfd, NLM32_POWERPC_HEADER_VERSION, s.headerVersion);
  H_PUT_32 (abfd, 0, s.origins);
  H_PUT_32 (abfd, 0, s.origins);
 
 
  /* FIXME: What should we do about the date?  */
  /* FIXME: What should we do about the date?  */
 
 
  if (bfd_bwrite (& s, (bfd_size_type) sizeof s, abfd) != sizeof s)
  if (bfd_bwrite (& s, (bfd_size_type) sizeof s, abfd) != sizeof s)
    return FALSE;
    return FALSE;
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* This reloc handling is only applicable to the old format.  */
/* This reloc handling is only applicable to the old format.  */
 
 
/* How to process the various reloc types.  PowerPC NLMs use XCOFF
/* How to process the various reloc types.  PowerPC NLMs use XCOFF
   reloc types, and I have just copied the XCOFF reloc table here.  */
   reloc types, and I have just copied the XCOFF reloc table here.  */
 
 
static reloc_howto_type nlm_powerpc_howto_table[] =
static reloc_howto_type nlm_powerpc_howto_table[] =
{
{
  /* Standard 32 bit relocation.  */
  /* Standard 32 bit relocation.  */
  HOWTO (0,                      /* Type.  */
  HOWTO (0,                      /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* Bitsize.  */
         32,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_POS",               /* Name.  */
         "R_POS",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Dest mask.  */
         0xffffffff,            /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* 32 bit relocation, but store negative value.  */
  /* 32 bit relocation, but store negative value.  */
  HOWTO (1,                     /* Type.  */
  HOWTO (1,                     /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         -2,                    /* Size (0 = byte, 1 = short, 2 = long).  */
         -2,                    /* Size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* Bitsize.  */
         32,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_NEG",               /* Name.  */
         "R_NEG",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Dest mask.  */
         0xffffffff,            /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* 32 bit PC relative relocation.  */
  /* 32 bit PC relative relocation.  */
  HOWTO (2,                     /* Type.  */
  HOWTO (2,                     /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* Bitsize.  */
         32,                    /* Bitsize.  */
         TRUE,                  /* PC relative.  */
         TRUE,                  /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_REL",               /* Name.  */
         "R_REL",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Dest mask.  */
         0xffffffff,            /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* 16 bit TOC relative relocation.  */
  /* 16 bit TOC relative relocation.  */
  HOWTO (3,                     /* Type.  */
  HOWTO (3,                     /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_TOC",               /* Name.  */
         "R_TOC",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* I don't really know what this is.  */
  /* I don't really know what this is.  */
  HOWTO (4,                     /* Type.  */
  HOWTO (4,                     /* Type.  */
         1,                     /* Rightshift.  */
         1,                     /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* Bitsize.  */
         32,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_RTB",               /* Name.  */
         "R_RTB",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Dest mask.  */
         0xffffffff,            /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* External TOC relative symbol.  */
  /* External TOC relative symbol.  */
  HOWTO (5,                     /* Type.  */
  HOWTO (5,                     /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_GL",                /* Name.  */
         "R_GL",                /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* Local TOC relative symbol.  */
  /* Local TOC relative symbol.  */
  HOWTO (6,                     /* Type.  */
  HOWTO (6,                     /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_TCL",               /* Name.  */
         "R_TCL",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  { 7 },
  { 7 },
 
 
  /* Non modifiable absolute branch.  */
  /* Non modifiable absolute branch.  */
  HOWTO (8,                     /* Type.  */
  HOWTO (8,                     /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         26,                    /* Bitsize.  */
         26,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_BA",                /* Name.  */
         "R_BA",                /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0x3fffffc,             /* Source mask.  */
         0x3fffffc,             /* Source mask.  */
         0x3fffffc,             /* Dest mask.  */
         0x3fffffc,             /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  { 9 },
  { 9 },
 
 
  /* Non modifiable relative branch.  */
  /* Non modifiable relative branch.  */
  HOWTO (0xa,                   /* Type.  */
  HOWTO (0xa,                   /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         26,                    /* Bitsize.  */
         26,                    /* Bitsize.  */
         TRUE,                  /* PC relative.  */
         TRUE,                  /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_BR",                /* Name.  */
         "R_BR",                /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0x3fffffc,             /* Source mask.  */
         0x3fffffc,             /* Source mask.  */
         0x3fffffc,             /* Dest mask.  */
         0x3fffffc,             /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  { 0xb },
  { 0xb },
 
 
  /* Indirect load.  */
  /* Indirect load.  */
  HOWTO (0xc,                   /* Type.  */
  HOWTO (0xc,                   /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_RL",                /* Name.  */
         "R_RL",                /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* Load address.  */
  /* Load address.  */
  HOWTO (0xd,                   /* Type.  */
  HOWTO (0xd,                   /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_RLA",               /* Name.  */
         "R_RLA",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  { 0xe },
  { 0xe },
 
 
  /* Non-relocating reference.  */
  /* Non-relocating reference.  */
  HOWTO (0xf,                   /* Type.  */
  HOWTO (0xf,                   /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* Bitsize.  */
         32,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_REF",               /* Name.  */
         "R_REF",               /* Name.  */
         FALSE,                 /* Partial_inplace.  */
         FALSE,                 /* Partial_inplace.  */
         0,                      /* Source mask.  */
         0,                      /* Source mask.  */
         0,              /* Dest mask.  */
         0,              /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  { 0x10 },
  { 0x10 },
  { 0x11 },
  { 0x11 },
 
 
  /* TOC relative indirect load.  */
  /* TOC relative indirect load.  */
  HOWTO (0x12,                  /* Type.  */
  HOWTO (0x12,                  /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_TRL",               /* Name.  */
         "R_TRL",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* TOC relative load address.  */
  /* TOC relative load address.  */
  HOWTO (0x13,                  /* Type.  */
  HOWTO (0x13,                  /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_TRLA",              /* Name.  */
         "R_TRLA",              /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* Modifiable relative branch.  */
  /* Modifiable relative branch.  */
  HOWTO (0x14,                  /* Type.  */
  HOWTO (0x14,                  /* Type.  */
         1,                     /* Rightshift.  */
         1,                     /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* Bitsize.  */
         32,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_RRTBI",             /* Name.  */
         "R_RRTBI",             /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Dest mask.  */
         0xffffffff,            /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* Modifiable absolute branch.  */
  /* Modifiable absolute branch.  */
  HOWTO (0x15,                  /* Type.  */
  HOWTO (0x15,                  /* Type.  */
         1,                     /* Rightshift.  */
         1,                     /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* Bitsize.  */
         32,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_RRTBA",             /* Name.  */
         "R_RRTBA",             /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Dest mask.  */
         0xffffffff,            /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* Modifiable call absolute indirect.  */
  /* Modifiable call absolute indirect.  */
  HOWTO (0x16,                  /* Type.  */
  HOWTO (0x16,                  /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_CAI",               /* Name.  */
         "R_CAI",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* Modifiable call relative.  */
  /* Modifiable call relative.  */
  HOWTO (0x17,                  /* Type.  */
  HOWTO (0x17,                  /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_REL",               /* Name.  */
         "R_REL",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* Modifiable branch absolute.  */
  /* Modifiable branch absolute.  */
  HOWTO (0x18,                  /* Type.  */
  HOWTO (0x18,                  /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_RBA",               /* Name.  */
         "R_RBA",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* Modifiable branch absolute.  */
  /* Modifiable branch absolute.  */
  HOWTO (0x19,                  /* Type.  */
  HOWTO (0x19,                  /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_RBAC",              /* Name.  */
         "R_RBAC",              /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* Modifiable branch relative.  */
  /* Modifiable branch relative.  */
  HOWTO (0x1a,                  /* Type.  */
  HOWTO (0x1a,                  /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         26,                    /* Bitsize.  */
         26,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_REL",               /* Name.  */
         "R_REL",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE),                /* PC rel offset.  */
         FALSE),                /* PC rel offset.  */
 
 
  /* Modifiable branch absolute.  */
  /* Modifiable branch absolute.  */
  HOWTO (0x1b,                  /* Type.  */
  HOWTO (0x1b,                  /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "R_REL",               /* Name.  */
         "R_REL",               /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Source mask.  */
         0xffff,                /* Dest mask.  */
         0xffff,                /* Dest mask.  */
         FALSE)                 /* PC rel offset.  */
         FALSE)                 /* PC rel offset.  */
};
};
 
 
#define HOWTO_COUNT (sizeof nlm_powerpc_howto_table             \
#define HOWTO_COUNT (sizeof nlm_powerpc_howto_table             \
                     / sizeof nlm_powerpc_howto_table[0])
                     / sizeof nlm_powerpc_howto_table[0])
 
 
/* Read a PowerPC NLM reloc.  */
/* Read a PowerPC NLM reloc.  */
 
 
static bfd_boolean
static bfd_boolean
nlm_powerpc_read_reloc (bfd *abfd,
nlm_powerpc_read_reloc (bfd *abfd,
                        nlmNAME (symbol_type) *sym,
                        nlmNAME (symbol_type) *sym,
                        asection **secp,
                        asection **secp,
                        arelent *rel)
                        arelent *rel)
{
{
  struct nlm32_powerpc_external_reloc ext;
  struct nlm32_powerpc_external_reloc ext;
  bfd_vma l_vaddr;
  bfd_vma l_vaddr;
  unsigned long l_symndx;
  unsigned long l_symndx;
  int l_rtype;
  int l_rtype;
  int l_rsecnm;
  int l_rsecnm;
  asection *code_sec, *data_sec, *bss_sec;
  asection *code_sec, *data_sec, *bss_sec;
 
 
  /* Read the reloc from the file.  */
  /* Read the reloc from the file.  */
  if (bfd_bread (&ext, (bfd_size_type) sizeof ext, abfd) != sizeof ext)
  if (bfd_bread (&ext, (bfd_size_type) sizeof ext, abfd) != sizeof ext)
    return FALSE;
    return FALSE;
 
 
  /* Swap in the fields.  */
  /* Swap in the fields.  */
  l_vaddr = H_GET_32 (abfd, ext.l_vaddr);
  l_vaddr = H_GET_32 (abfd, ext.l_vaddr);
  l_symndx = H_GET_32 (abfd, ext.l_symndx);
  l_symndx = H_GET_32 (abfd, ext.l_symndx);
  l_rtype = H_GET_16 (abfd, ext.l_rtype);
  l_rtype = H_GET_16 (abfd, ext.l_rtype);
  l_rsecnm = H_GET_16 (abfd, ext.l_rsecnm);
  l_rsecnm = H_GET_16 (abfd, ext.l_rsecnm);
 
 
  /* Get the sections now, for convenience.  */
  /* Get the sections now, for convenience.  */
  code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
  code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
  data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
  data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
  bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
  bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
 
 
  /* Work out the arelent fields.  */
  /* Work out the arelent fields.  */
  if (sym != NULL)
  if (sym != NULL)
    /* This is an import.  sym_ptr_ptr is filled in by
    /* This is an import.  sym_ptr_ptr is filled in by
       nlm_canonicalize_reloc.  */
       nlm_canonicalize_reloc.  */
    rel->sym_ptr_ptr = NULL;
    rel->sym_ptr_ptr = NULL;
  else
  else
    {
    {
      asection *sec;
      asection *sec;
 
 
      if (l_symndx == 0)
      if (l_symndx == 0)
        sec = code_sec;
        sec = code_sec;
      else if (l_symndx == 1)
      else if (l_symndx == 1)
        sec = data_sec;
        sec = data_sec;
      else if (l_symndx == 2)
      else if (l_symndx == 2)
        sec = bss_sec;
        sec = bss_sec;
      else
      else
        {
        {
          bfd_set_error (bfd_error_bad_value);
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
          return FALSE;
        }
        }
 
 
      rel->sym_ptr_ptr = sec->symbol_ptr_ptr;
      rel->sym_ptr_ptr = sec->symbol_ptr_ptr;
    }
    }
 
 
  rel->addend = 0;
  rel->addend = 0;
 
 
  BFD_ASSERT ((l_rtype & 0xff) < HOWTO_COUNT);
  BFD_ASSERT ((l_rtype & 0xff) < HOWTO_COUNT);
 
 
  rel->howto = nlm_powerpc_howto_table + (l_rtype & 0xff);
  rel->howto = nlm_powerpc_howto_table + (l_rtype & 0xff);
 
 
  BFD_ASSERT (rel->howto->name != NULL
  BFD_ASSERT (rel->howto->name != NULL
              && ((l_rtype & 0x8000) != 0
              && ((l_rtype & 0x8000) != 0
                  ? (rel->howto->complain_on_overflow
                  ? (rel->howto->complain_on_overflow
                     == complain_overflow_signed)
                     == complain_overflow_signed)
                  : (rel->howto->complain_on_overflow
                  : (rel->howto->complain_on_overflow
                     == complain_overflow_bitfield))
                     == complain_overflow_bitfield))
              && ((l_rtype >> 8) & 0x1f) == rel->howto->bitsize - 1);
              && ((l_rtype >> 8) & 0x1f) == rel->howto->bitsize - 1);
 
 
  if (l_rsecnm == 0)
  if (l_rsecnm == 0)
    *secp = code_sec;
    *secp = code_sec;
  else if (l_rsecnm == 1)
  else if (l_rsecnm == 1)
    {
    {
      *secp = data_sec;
      *secp = data_sec;
      l_vaddr -= code_sec->size;
      l_vaddr -= code_sec->size;
    }
    }
  else
  else
    {
    {
      bfd_set_error (bfd_error_bad_value);
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
      return FALSE;
    }
    }
 
 
  rel->address = l_vaddr;
  rel->address = l_vaddr;
 
 
  return TRUE;
  return TRUE;
}
}
 
 
#else /* not OLDFORMAT */
#else /* not OLDFORMAT */
 
 
/* There is only one type of reloc in a PowerPC NLM.  */
/* There is only one type of reloc in a PowerPC NLM.  */
 
 
static reloc_howto_type nlm_powerpc_howto =
static reloc_howto_type nlm_powerpc_howto =
  HOWTO (0,                      /* Type.  */
  HOWTO (0,                      /* Type.  */
         0,                      /* Rightshift.  */
         0,                      /* Rightshift.  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* Bitsize.  */
         32,                    /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         FALSE,                 /* PC relative.  */
         0,                      /* Bitpos.  */
         0,                      /* Bitpos.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         complain_overflow_bitfield, /* Complain_on_overflow.  */
         0,                      /* Special_function.  */
         0,                      /* Special_function.  */
         "32",                  /* Name.  */
         "32",                  /* Name.  */
         TRUE,                  /* Partial_inplace.  */
         TRUE,                  /* Partial_inplace.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Source mask.  */
         0xffffffff,            /* Dest mask.  */
         0xffffffff,            /* Dest mask.  */
         FALSE);                /* PC rel_offset.  */
         FALSE);                /* PC rel_offset.  */
 
 
/* Read a PowerPC NLM reloc.  */
/* Read a PowerPC NLM reloc.  */
 
 
static bfd_boolean
static bfd_boolean
nlm_powerpc_read_reloc (bfd *abfd,
nlm_powerpc_read_reloc (bfd *abfd,
                        nlmNAME (symbol_type) *sym,
                        nlmNAME (symbol_type) *sym,
                        asection **secp,
                        asection **secp,
                        arelent *rel)
                        arelent *rel)
{
{
  bfd_byte temp[4];
  bfd_byte temp[4];
  bfd_vma val;
  bfd_vma val;
  const char *name;
  const char *name;
 
 
  if (bfd_bread (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
  if (bfd_bread (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
    return FALSE;
    return FALSE;
 
 
  val = bfd_get_32 (abfd, temp);
  val = bfd_get_32 (abfd, temp);
 
 
  /* The value is a word offset into either the code or data segment.
  /* The value is a word offset into either the code or data segment.
     This is the location which needs to be adjusted.
     This is the location which needs to be adjusted.
 
 
     The high bit is 0 if the value is an offset into the data
     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.
     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
     If this is a relocation fixup rather than an imported symbol (the
     sym argument is NULL), then the second most significant bit is 0
     sym argument is NULL), then the second most significant bit is 0
     if the address of the data segment should be added to the
     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
     location addressed by the value, or 1 if the address of the text
     segment should be added.
     segment should be added.
 
 
     If this is an imported symbol, the second most significant bit is
     If this is an imported symbol, the second most significant bit is
     not used and must be 0.  */
     not used and must be 0.  */
 
 
  if ((val & NLM_HIBIT) == 0)
  if ((val & NLM_HIBIT) == 0)
    name = NLM_INITIALIZED_DATA_NAME;
    name = NLM_INITIALIZED_DATA_NAME;
  else
  else
    {
    {
      name = NLM_CODE_NAME;
      name = NLM_CODE_NAME;
      val &=~ NLM_HIBIT;
      val &=~ NLM_HIBIT;
    }
    }
  *secp = bfd_get_section_by_name (abfd, name);
  *secp = bfd_get_section_by_name (abfd, name);
 
 
  if (sym == NULL)
  if (sym == NULL)
    {
    {
      if ((val & (NLM_HIBIT >> 1)) == 0)
      if ((val & (NLM_HIBIT >> 1)) == 0)
        name = NLM_INITIALIZED_DATA_NAME;
        name = NLM_INITIALIZED_DATA_NAME;
      else
      else
        {
        {
          name = NLM_CODE_NAME;
          name = NLM_CODE_NAME;
          val &=~ (NLM_HIBIT >> 1);
          val &=~ (NLM_HIBIT >> 1);
        }
        }
      rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr;
      rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr;
    }
    }
 
 
  rel->howto   = & nlm_powerpc_howto;
  rel->howto   = & nlm_powerpc_howto;
  rel->address = val << 2;
  rel->address = val << 2;
  rel->addend  = 0;
  rel->addend  = 0;
 
 
  return TRUE;
  return TRUE;
}
}
 
 
#endif /* not OLDFORMAT */
#endif /* not OLDFORMAT */
 
 
/* Mangle PowerPC NLM relocs for output.  */
/* Mangle PowerPC NLM relocs for output.  */
 
 
static bfd_boolean
static bfd_boolean
nlm_powerpc_mangle_relocs (bfd *abfd ATTRIBUTE_UNUSED,
nlm_powerpc_mangle_relocs (bfd *abfd ATTRIBUTE_UNUSED,
                           asection *sec ATTRIBUTE_UNUSED,
                           asection *sec ATTRIBUTE_UNUSED,
                           const void * data ATTRIBUTE_UNUSED,
                           const void * data ATTRIBUTE_UNUSED,
                           bfd_vma offset ATTRIBUTE_UNUSED,
                           bfd_vma offset ATTRIBUTE_UNUSED,
                           bfd_size_type count ATTRIBUTE_UNUSED)
                           bfd_size_type count ATTRIBUTE_UNUSED)
{
{
  return TRUE;
  return TRUE;
}
}
 
 
/* Read a PowerPC NLM import record */
/* Read a PowerPC NLM import record */
 
 
static bfd_boolean
static bfd_boolean
nlm_powerpc_read_import (bfd * abfd, nlmNAME (symbol_type) * sym)
nlm_powerpc_read_import (bfd * abfd, nlmNAME (symbol_type) * sym)
{
{
  struct nlm_relent *nlm_relocs;        /* Relocation records for symbol.  */
  struct nlm_relent *nlm_relocs;        /* Relocation records for symbol.  */
  bfd_size_type rcount;                 /* Number of relocs.  */
  bfd_size_type rcount;                 /* Number of relocs.  */
  bfd_byte temp[NLM_TARGET_LONG_SIZE];  /* Temporary 32-bit value.  */
  bfd_byte temp[NLM_TARGET_LONG_SIZE];  /* Temporary 32-bit value.  */
  unsigned char symlength;              /* Length of symbol name.  */
  unsigned char symlength;              /* Length of symbol name.  */
  char *name;
  char *name;
 
 
  if (bfd_bread (& symlength, (bfd_size_type) sizeof (symlength), abfd)
  if (bfd_bread (& symlength, (bfd_size_type) sizeof (symlength), abfd)
      != sizeof (symlength))
      != sizeof (symlength))
    return FALSE;
    return FALSE;
  sym -> symbol.the_bfd = abfd;
  sym -> symbol.the_bfd = abfd;
  name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
  name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
  if (name == NULL)
  if (name == NULL)
    return FALSE;
    return FALSE;
  if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
  if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
    return FALSE;
    return FALSE;
  name[symlength] = '\0';
  name[symlength] = '\0';
  sym -> symbol.name = name;
  sym -> symbol.name = name;
  sym -> symbol.flags = 0;
  sym -> symbol.flags = 0;
  sym -> symbol.value = 0;
  sym -> symbol.value = 0;
  sym -> symbol.section = bfd_und_section_ptr;
  sym -> symbol.section = bfd_und_section_ptr;
  if (bfd_bread (temp, (bfd_size_type) sizeof (temp), abfd)
  if (bfd_bread (temp, (bfd_size_type) sizeof (temp), abfd)
      != sizeof (temp))
      != sizeof (temp))
    return FALSE;
    return FALSE;
  rcount = H_GET_32 (abfd, temp);
  rcount = H_GET_32 (abfd, temp);
  nlm_relocs = bfd_alloc (abfd, rcount * sizeof (struct nlm_relent));
  nlm_relocs = bfd_alloc (abfd, rcount * sizeof (struct nlm_relent));
  if (nlm_relocs == NULL)
  if (nlm_relocs == NULL)
    return FALSE;
    return FALSE;
  sym -> relocs = nlm_relocs;
  sym -> relocs = nlm_relocs;
  sym -> rcnt = 0;
  sym -> rcnt = 0;
  while (sym -> rcnt < rcount)
  while (sym -> rcnt < rcount)
    {
    {
      asection *section;
      asection *section;
 
 
      if (! nlm_powerpc_read_reloc (abfd, sym, &section, &nlm_relocs -> reloc))
      if (! nlm_powerpc_read_reloc (abfd, sym, &section, &nlm_relocs -> reloc))
        return FALSE;
        return FALSE;
      nlm_relocs -> section = section;
      nlm_relocs -> section = section;
      nlm_relocs++;
      nlm_relocs++;
      sym -> rcnt++;
      sym -> rcnt++;
    }
    }
  return TRUE;
  return TRUE;
}
}
 
 
#ifndef OLDFORMAT
#ifndef OLDFORMAT
 
 
/* Write a PowerPC NLM reloc.  */
/* Write a PowerPC NLM reloc.  */
 
 
static bfd_boolean
static bfd_boolean
nlm_powerpc_write_import (bfd * abfd, asection * sec, arelent * rel)
nlm_powerpc_write_import (bfd * abfd, asection * sec, arelent * rel)
{
{
  asymbol *sym;
  asymbol *sym;
  bfd_vma val;
  bfd_vma val;
  bfd_byte temp[4];
  bfd_byte temp[4];
 
 
  /* PowerPC NetWare only supports one kind of reloc.  */
  /* PowerPC NetWare only supports one kind of reloc.  */
  if (rel->addend != 0
  if (rel->addend != 0
      || rel->howto == NULL
      || rel->howto == NULL
      || rel->howto->rightshift != 0
      || rel->howto->rightshift != 0
      || rel->howto->size != 2
      || rel->howto->size != 2
      || rel->howto->bitsize != 32
      || rel->howto->bitsize != 32
      || rel->howto->bitpos != 0
      || rel->howto->bitpos != 0
      || rel->howto->pc_relative
      || rel->howto->pc_relative
      || (rel->howto->src_mask != 0xffffffff && rel->addend != 0)
      || (rel->howto->src_mask != 0xffffffff && rel->addend != 0)
      || rel->howto->dst_mask != 0xffffffff)
      || rel->howto->dst_mask != 0xffffffff)
    {
    {
      bfd_set_error (bfd_error_invalid_operation);
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
      return FALSE;
    }
    }
 
 
  sym = *rel->sym_ptr_ptr;
  sym = *rel->sym_ptr_ptr;
 
 
  /* The value we write out is the offset into the appropriate
  /* The value we write out is the offset into the appropriate
     segment, rightshifted by two.  This offset is the section vma,
     segment, rightshifted by two.  This offset is the section vma,
     adjusted by the vma of the lowest section in that segment, plus
     adjusted by the vma of the lowest section in that segment, plus
     the address of the relocation.  */
     the address of the relocation.  */
  val = bfd_get_section_vma (abfd, sec) + rel->address;
  val = bfd_get_section_vma (abfd, sec) + rel->address;
  if ((val & 3) != 0)
  if ((val & 3) != 0)
    {
    {
      bfd_set_error (bfd_error_bad_value);
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
      return FALSE;
    }
    }
  val >>= 2;
  val >>= 2;
 
 
  /* The high bit is 0 if the reloc is in the data section, or 1 if
  /* The high bit is 0 if the reloc is in the data section, or 1 if
     the reloc is in the code section.  */
     the reloc is in the code section.  */
  if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
  if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
    val -= nlm_get_data_low (abfd);
    val -= nlm_get_data_low (abfd);
  else
  else
    {
    {
      val -= nlm_get_text_low (abfd);
      val -= nlm_get_text_low (abfd);
      val |= NLM_HIBIT;
      val |= NLM_HIBIT;
    }
    }
 
 
  if (! bfd_is_und_section (bfd_get_section (sym)))
  if (! bfd_is_und_section (bfd_get_section (sym)))
    {
    {
      /* This is an internal relocation fixup.  The second most
      /* This is an internal relocation fixup.  The second most
         significant bit is 0 if this is a reloc against the data
         significant bit is 0 if this is a reloc against the data
         segment, or 1 if it is a reloc against the text segment.  */
         segment, or 1 if it is a reloc against the text segment.  */
      if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE)
      if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE)
        val |= NLM_HIBIT >> 1;
        val |= NLM_HIBIT >> 1;
    }
    }
 
 
  bfd_put_32 (abfd, val, temp);
  bfd_put_32 (abfd, val, temp);
  if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
  if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
    return FALSE;
    return FALSE;
 
 
  return TRUE;
  return TRUE;
}
}
 
 
#else /* OLDFORMAT */
#else /* OLDFORMAT */
 
 
/* This is used for the reloc handling in the old format.  */
/* This is used for the reloc handling in the old format.  */
 
 
/* Write a PowerPC NLM reloc.  */
/* Write a PowerPC NLM reloc.  */
 
 
static bfd_boolean
static bfd_boolean
nlm_powerpc_write_reloc (bfd *abfd,
nlm_powerpc_write_reloc (bfd *abfd,
                         asection *sec,
                         asection *sec,
                         arelent *rel,
                         arelent *rel,
                         int indx)
                         int indx)
{
{
  struct nlm32_powerpc_external_reloc ext;
  struct nlm32_powerpc_external_reloc ext;
  asection *code_sec, *data_sec, *bss_sec;
  asection *code_sec, *data_sec, *bss_sec;
  asymbol *sym;
  asymbol *sym;
  asection *symsec;
  asection *symsec;
  unsigned long l_symndx;
  unsigned long l_symndx;
  int l_rtype;
  int l_rtype;
  int l_rsecnm;
  int l_rsecnm;
  reloc_howto_type *howto;
  reloc_howto_type *howto;
  bfd_size_type address;
  bfd_size_type address;
 
 
  /* Get the sections now, for convenience.  */
  /* Get the sections now, for convenience.  */
  code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
  code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
  data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
  data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
  bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
  bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
 
 
  sym = *rel->sym_ptr_ptr;
  sym = *rel->sym_ptr_ptr;
  symsec = bfd_get_section (sym);
  symsec = bfd_get_section (sym);
  if (indx != -1)
  if (indx != -1)
    {
    {
      BFD_ASSERT (bfd_is_und_section (symsec));
      BFD_ASSERT (bfd_is_und_section (symsec));
      l_symndx = indx + 3;
      l_symndx = indx + 3;
    }
    }
  else
  else
    {
    {
      if (symsec == code_sec)
      if (symsec == code_sec)
        l_symndx = 0;
        l_symndx = 0;
      else if (symsec == data_sec)
      else if (symsec == data_sec)
        l_symndx = 1;
        l_symndx = 1;
      else if (symsec == bss_sec)
      else if (symsec == bss_sec)
        l_symndx = 2;
        l_symndx = 2;
      else
      else
        {
        {
          bfd_set_error (bfd_error_bad_value);
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
          return FALSE;
        }
        }
    }
    }
 
 
  H_PUT_32 (abfd, l_symndx, ext.l_symndx);
  H_PUT_32 (abfd, l_symndx, ext.l_symndx);
 
 
  for (howto = nlm_powerpc_howto_table;
  for (howto = nlm_powerpc_howto_table;
       howto < nlm_powerpc_howto_table + HOWTO_COUNT;
       howto < nlm_powerpc_howto_table + HOWTO_COUNT;
       howto++)
       howto++)
    {
    {
      if (howto->rightshift == rel->howto->rightshift
      if (howto->rightshift == rel->howto->rightshift
          && howto->size == rel->howto->size
          && howto->size == rel->howto->size
          && howto->bitsize == rel->howto->bitsize
          && howto->bitsize == rel->howto->bitsize
          && howto->pc_relative == rel->howto->pc_relative
          && howto->pc_relative == rel->howto->pc_relative
          && howto->bitpos == rel->howto->bitpos
          && howto->bitpos == rel->howto->bitpos
          && (howto->partial_inplace == rel->howto->partial_inplace
          && (howto->partial_inplace == rel->howto->partial_inplace
              || (! rel->howto->partial_inplace
              || (! rel->howto->partial_inplace
                  && rel->addend == 0))
                  && rel->addend == 0))
          && (howto->src_mask == rel->howto->src_mask
          && (howto->src_mask == rel->howto->src_mask
              || (rel->howto->src_mask == 0
              || (rel->howto->src_mask == 0
                  && rel->addend == 0))
                  && rel->addend == 0))
          && howto->dst_mask == rel->howto->dst_mask
          && howto->dst_mask == rel->howto->dst_mask
          && howto->pcrel_offset == rel->howto->pcrel_offset)
          && howto->pcrel_offset == rel->howto->pcrel_offset)
        break;
        break;
    }
    }
  if (howto >= nlm_powerpc_howto_table + HOWTO_COUNT)
  if (howto >= nlm_powerpc_howto_table + HOWTO_COUNT)
    {
    {
      bfd_set_error (bfd_error_bad_value);
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
      return FALSE;
    }
    }
 
 
  l_rtype = howto->type;
  l_rtype = howto->type;
  if (howto->complain_on_overflow == complain_overflow_signed)
  if (howto->complain_on_overflow == complain_overflow_signed)
    l_rtype |= 0x8000;
    l_rtype |= 0x8000;
  l_rtype |= (howto->bitsize - 1) << 8;
  l_rtype |= (howto->bitsize - 1) << 8;
  H_PUT_16 (abfd, l_rtype, ext.l_rtype);
  H_PUT_16 (abfd, l_rtype, ext.l_rtype);
 
 
  address = rel->address;
  address = rel->address;
 
 
  if (sec == code_sec)
  if (sec == code_sec)
    l_rsecnm = 0;
    l_rsecnm = 0;
  else if (sec == data_sec)
  else if (sec == data_sec)
    {
    {
      l_rsecnm = 1;
      l_rsecnm = 1;
      address += code_sec->size;
      address += code_sec->size;
    }
    }
  else
  else
    {
    {
      bfd_set_error (bfd_error_bad_value);
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
      return FALSE;
    }
    }
 
 
  H_PUT_16 (abfd, l_rsecnm, ext.l_rsecnm);
  H_PUT_16 (abfd, l_rsecnm, ext.l_rsecnm);
  H_PUT_32 (abfd, address, ext.l_vaddr);
  H_PUT_32 (abfd, address, ext.l_vaddr);
 
 
  if (bfd_bwrite (&ext, (bfd_size_type) sizeof ext, abfd) != sizeof ext)
  if (bfd_bwrite (&ext, (bfd_size_type) sizeof ext, abfd) != sizeof ext)
    return FALSE;
    return FALSE;
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* Write a PowerPC NLM import.  */
/* Write a PowerPC NLM import.  */
 
 
static bfd_boolean
static bfd_boolean
nlm_powerpc_write_import (bfd * abfd, asection * sec, arelent * rel)
nlm_powerpc_write_import (bfd * abfd, asection * sec, arelent * rel)
{
{
  return nlm_powerpc_write_reloc (abfd, sec, rel, -1);
  return nlm_powerpc_write_reloc (abfd, sec, rel, -1);
}
}
 
 
#endif /* OLDFORMAT */
#endif /* OLDFORMAT */
 
 
/* Write a PowerPC NLM external symbol.  This routine keeps a static
/* Write a PowerPC NLM external symbol.  This routine keeps a static
   count of the symbol index.  FIXME: I don't know if this is
   count of the symbol index.  FIXME: I don't know if this is
   necessary, and the index never gets reset.  */
   necessary, and the index never gets reset.  */
 
 
static bfd_boolean
static bfd_boolean
nlm_powerpc_write_external (bfd *abfd,
nlm_powerpc_write_external (bfd *abfd,
                            bfd_size_type count,
                            bfd_size_type count,
                            asymbol *sym,
                            asymbol *sym,
                            struct reloc_and_sec *relocs)
                            struct reloc_and_sec *relocs)
{
{
  unsigned int i;
  unsigned int i;
  bfd_byte len;
  bfd_byte len;
  unsigned char temp[NLM_TARGET_LONG_SIZE];
  unsigned char temp[NLM_TARGET_LONG_SIZE];
#ifdef OLDFORMAT
#ifdef OLDFORMAT
  static int indx;
  static int indx;
#endif
#endif
 
 
  len = strlen (sym->name);
  len = strlen (sym->name);
  if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
  if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
       != sizeof (bfd_byte))
       != sizeof (bfd_byte))
      || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
      || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
    return FALSE;
    return FALSE;
 
 
  bfd_put_32 (abfd, count, temp);
  bfd_put_32 (abfd, count, temp);
  if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
  if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
    return FALSE;
    return FALSE;
 
 
  for (i = 0; i < count; i++)
  for (i = 0; i < count; i++)
    {
    {
#ifndef OLDFORMAT
#ifndef OLDFORMAT
      if (! nlm_powerpc_write_import (abfd, relocs[i].sec, relocs[i].rel))
      if (! nlm_powerpc_write_import (abfd, relocs[i].sec, relocs[i].rel))
        return FALSE;
        return FALSE;
#else
#else
      if (! nlm_powerpc_write_reloc (abfd, relocs[i].sec,
      if (! nlm_powerpc_write_reloc (abfd, relocs[i].sec,
                                     relocs[i].rel, indx))
                                     relocs[i].rel, indx))
        return FALSE;
        return FALSE;
#endif
#endif
    }
    }
 
 
#ifdef OLDFORMAT
#ifdef OLDFORMAT
  ++indx;
  ++indx;
#endif
#endif
 
 
  return TRUE;
  return TRUE;
}
}


#ifndef OLDFORMAT
#ifndef OLDFORMAT
 
 
/* PowerPC Netware uses a word offset, not a byte offset, for public
/* PowerPC Netware uses a word offset, not a byte offset, for public
   symbols.  */
   symbols.  */
 
 
/* Set the section for a public symbol.  */
/* Set the section for a public symbol.  */
 
 
static bfd_boolean
static bfd_boolean
nlm_powerpc_set_public_section (bfd *abfd, nlmNAME (symbol_type) *sym)
nlm_powerpc_set_public_section (bfd *abfd, nlmNAME (symbol_type) *sym)
{
{
  if (sym->symbol.value & NLM_HIBIT)
  if (sym->symbol.value & NLM_HIBIT)
    {
    {
      sym->symbol.value &= ~NLM_HIBIT;
      sym->symbol.value &= ~NLM_HIBIT;
      sym->symbol.flags |= BSF_FUNCTION;
      sym->symbol.flags |= BSF_FUNCTION;
      sym->symbol.section =
      sym->symbol.section =
        bfd_get_section_by_name (abfd, NLM_CODE_NAME);
        bfd_get_section_by_name (abfd, NLM_CODE_NAME);
    }
    }
  else
  else
    sym->symbol.section =
    sym->symbol.section =
      bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
      bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
 
 
  sym->symbol.value <<= 2;
  sym->symbol.value <<= 2;
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* Get the offset to write out for a public symbol.  */
/* Get the offset to write out for a public symbol.  */
 
 
static bfd_vma
static bfd_vma
nlm_powerpc_get_public_offset (bfd *abfd, asymbol *sym)
nlm_powerpc_get_public_offset (bfd *abfd, asymbol *sym)
{
{
  bfd_vma offset;
  bfd_vma offset;
  asection *sec;
  asection *sec;
 
 
  offset = bfd_asymbol_value (sym);
  offset = bfd_asymbol_value (sym);
  sec = bfd_get_section (sym);
  sec = bfd_get_section (sym);
  if (sec->flags & SEC_CODE)
  if (sec->flags & SEC_CODE)
    {
    {
      offset -= nlm_get_text_low (abfd);
      offset -= nlm_get_text_low (abfd);
      offset |= NLM_HIBIT;
      offset |= NLM_HIBIT;
    }
    }
  else if (sec->flags & (SEC_DATA | SEC_ALLOC))
  else if (sec->flags & (SEC_DATA | SEC_ALLOC))
    {
    {
      /* SEC_ALLOC is for the .bss section.  */
      /* SEC_ALLOC is for the .bss section.  */
      offset -= nlm_get_data_low (abfd);
      offset -= nlm_get_data_low (abfd);
    }
    }
  else
  else
    {
    {
      /* We can't handle an exported symbol that is not in the code or
      /* We can't handle an exported symbol that is not in the code or
         data segment.  */
         data segment.  */
      bfd_set_error (bfd_error_invalid_operation);
      bfd_set_error (bfd_error_invalid_operation);
      /* FIXME: No way to return error.  */
      /* FIXME: No way to return error.  */
      abort ();
      abort ();
    }
    }
 
 
  return offset;
  return offset;
}
}
 
 
#endif /* ! defined (OLDFORMAT) */
#endif /* ! defined (OLDFORMAT) */


#include "nlmswap.h"
#include "nlmswap.h"
 
 
static const struct nlm_backend_data nlm32_powerpc_backend =
static const struct nlm_backend_data nlm32_powerpc_backend =
{
{
  "NetWare PowerPC Module \032",
  "NetWare PowerPC Module \032",
  sizeof (Nlm32_powerpc_External_Fixed_Header),
  sizeof (Nlm32_powerpc_External_Fixed_Header),
#ifndef OLDFORMAT
#ifndef OLDFORMAT
  0,     /* Optional_prefix_size.  */
  0,     /* Optional_prefix_size.  */
#else
#else
  sizeof (struct nlm32_powerpc_external_prefix_header),
  sizeof (struct nlm32_powerpc_external_prefix_header),
#endif
#endif
  bfd_arch_powerpc,
  bfd_arch_powerpc,
  0,
  0,
  FALSE,
  FALSE,
#ifndef OLDFORMAT
#ifndef OLDFORMAT
  0,     /* Backend_object_p.  */
  0,     /* Backend_object_p.  */
  0,     /* Write_prefix.  */
  0,     /* Write_prefix.  */
#else
#else
  nlm_powerpc_backend_object_p,
  nlm_powerpc_backend_object_p,
  nlm_powerpc_write_prefix,
  nlm_powerpc_write_prefix,
#endif
#endif
  nlm_powerpc_read_reloc,
  nlm_powerpc_read_reloc,
  nlm_powerpc_mangle_relocs,
  nlm_powerpc_mangle_relocs,
  nlm_powerpc_read_import,
  nlm_powerpc_read_import,
  nlm_powerpc_write_import,
  nlm_powerpc_write_import,
#ifndef OLDFORMAT
#ifndef OLDFORMAT
  nlm_powerpc_set_public_section,
  nlm_powerpc_set_public_section,
  nlm_powerpc_get_public_offset,
  nlm_powerpc_get_public_offset,
#else
#else
  0,     /* Set_public_section.  */
  0,     /* Set_public_section.  */
  0,     /* Get_public_offset.  */
  0,     /* Get_public_offset.  */
#endif
#endif
  nlm_swap_fixed_header_in,
  nlm_swap_fixed_header_in,
  nlm_swap_fixed_header_out,
  nlm_swap_fixed_header_out,
  nlm_powerpc_write_external,
  nlm_powerpc_write_external,
  0,     /* Write_export.  */
  0,     /* Write_export.  */
};
};
 
 
#define TARGET_BIG_NAME                 "nlm32-powerpc"
#define TARGET_BIG_NAME                 "nlm32-powerpc"
#define TARGET_BIG_SYM                  nlmNAME (powerpc_vec)
#define TARGET_BIG_SYM                  nlmNAME (powerpc_vec)
#define TARGET_BACKEND_DATA             & nlm32_powerpc_backend
#define TARGET_BACKEND_DATA             & nlm32_powerpc_backend
 
 
#include "nlm-target.h"
#include "nlm-target.h"
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.