Back to index

cell-binutils  2.17cvs20070401
coff-m88k.c
Go to the documentation of this file.
00001 /* BFD back-end for Motorola 88000 COFF "Binary Compatibility Standard" files.
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
00003    2001, 2002, 2003
00004    Free Software Foundation, Inc.
00005    Written by Cygnus Support.
00006 
00007 This file is part of BFD, the Binary File Descriptor library.
00008 
00009 This program is free software; you can redistribute it and/or modify
00010 it under the terms of the GNU General Public License as published by
00011 the Free Software Foundation; either version 2 of the License, or
00012 (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00022 
00023 #define M88 1        /* Customize various include files */
00024 #include "bfd.h"
00025 #include "sysdep.h"
00026 #include "libbfd.h"
00027 #include "coff/m88k.h"
00028 #include "coff/internal.h"
00029 #include "libcoff.h"
00030 
00031 static bfd_boolean m88k_is_local_label_name PARAMS ((bfd *, const char *));
00032 static bfd_reloc_status_type m88k_special_reloc
00033   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00034 static void rtype2howto PARAMS ((arelent *, struct internal_reloc *));
00035 static void reloc_processing
00036   PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
00037 
00038 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
00039 
00040 #define GET_SCNHDR_NRELOC H_GET_32
00041 #define GET_SCNHDR_NLNNO  H_GET_32
00042 
00043 /* On coff-m88k, local labels start with '@'.  */
00044 
00045 #define coff_bfd_is_local_label_name m88k_is_local_label_name
00046 
00047 static bfd_boolean
00048 m88k_is_local_label_name (abfd, name)
00049      bfd *abfd ATTRIBUTE_UNUSED;
00050      const char *name;
00051 {
00052   return name[0] == '@';
00053 }
00054 
00055 static bfd_reloc_status_type
00056 m88k_special_reloc (abfd, reloc_entry, symbol, data,
00057                   input_section, output_bfd, error_message)
00058      bfd *abfd;
00059      arelent *reloc_entry;
00060      asymbol *symbol;
00061      PTR data;
00062      asection *input_section;
00063      bfd *output_bfd;
00064      char **error_message ATTRIBUTE_UNUSED;
00065 {
00066   reloc_howto_type *howto = reloc_entry->howto;
00067 
00068   switch (howto->type)
00069     {
00070     case R_HVRT16:
00071     case R_LVRT16:
00072       if (output_bfd != (bfd *) NULL)
00073        {
00074          /* This is a partial relocation, and we want to apply the
00075             relocation to the reloc entry rather than the raw data.
00076             Modify the reloc inplace to reflect what we now know.  */
00077 
00078          reloc_entry->address += input_section->output_offset;
00079        }
00080       else
00081        {
00082          bfd_vma output_base = 0;
00083          bfd_vma addr = reloc_entry->address;
00084          bfd_vma x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
00085          asection *reloc_target_output_section;
00086          long relocation = 0;
00087 
00088          /* Work out which section the relocation is targeted at and the
00089             initial relocation command value.  */
00090 
00091          /* Get symbol value.  (Common symbols are special.)  */
00092          if (bfd_is_com_section (symbol->section))
00093            relocation = 0;
00094          else
00095            relocation = symbol->value;
00096 
00097          reloc_target_output_section = symbol->section->output_section;
00098 
00099          /* Convert input-section-relative symbol value to absolute.  */
00100          if (output_bfd)
00101            output_base = 0;
00102          else
00103            output_base = reloc_target_output_section->vma;
00104 
00105          relocation += output_base + symbol->section->output_offset;
00106 
00107          /* Add in supplied addend.  */
00108          relocation += ((reloc_entry->addend << howto->bitsize) + x);
00109 
00110          reloc_entry->addend = 0;
00111 
00112          relocation >>= (bfd_vma) howto->rightshift;
00113 
00114          /* Shift everything up to where it's going to be used */
00115 
00116          relocation <<= (bfd_vma) howto->bitpos;
00117 
00118          if (relocation)
00119            bfd_put_16 (abfd, (bfd_vma) relocation,
00120                      (unsigned char *) data + addr);
00121        }
00122 
00123       /* If we are not producing relocatable output, return an error if
00124         the symbol is not defined.  */
00125       if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL)
00126        return bfd_reloc_undefined;
00127 
00128       return bfd_reloc_ok;
00129 
00130     default:
00131       if (output_bfd != (bfd *) NULL)
00132        {
00133          /* This is a partial relocation, and we want to apply the
00134             relocation to the reloc entry rather than the raw data.
00135             Modify the reloc inplace to reflect what we now know.  */
00136 
00137          reloc_entry->address += input_section->output_offset;
00138          return bfd_reloc_ok;
00139        }
00140       break;
00141     }
00142 
00143   if (output_bfd == (bfd *) NULL)
00144     return bfd_reloc_continue;
00145 
00146   return bfd_reloc_ok;
00147 }
00148 
00149 static reloc_howto_type howto_table[] =
00150 {
00151   HOWTO (R_PCR16L,                 /* type */
00152         02,                        /* rightshift */
00153         1,                         /* size (0 = byte, 1 = short, 2 = long) */
00154         16,                        /* bitsize */
00155         TRUE,                      /* pc_relative */
00156         0,                         /* bitpos */
00157         complain_overflow_signed,  /* complain_on_overflow */
00158         m88k_special_reloc,        /* special_function */
00159         "PCR16L",                  /* name */
00160         FALSE,                            /* partial_inplace */
00161         0x0000ffff,                /* src_mask */
00162         0x0000ffff,                /* dst_mask */
00163         TRUE),                            /* pcrel_offset */
00164 
00165   HOWTO (R_PCR26L,                 /* type */
00166         02,                        /* rightshift */
00167         2,                         /* size (0 = byte, 1 = short, 2 = long) */
00168         26,                        /* bitsize */
00169         TRUE,                      /* pc_relative */
00170         0,                         /* bitpos */
00171         complain_overflow_signed,  /* complain_on_overflow */
00172         m88k_special_reloc,        /* special_function */
00173         "PCR26L",                  /* name */
00174         FALSE,                            /* partial_inplace */
00175         0x03ffffff,                /* src_mask */
00176         0x03ffffff,                /* dst_mask */
00177         TRUE),                            /* pcrel_offset */
00178 
00179   HOWTO (R_VRT16,                  /* type */
00180         00,                        /* rightshift */
00181         1,                         /* size (0 = byte, 1 = short, 2 = long) */
00182         16,                        /* bitsize */
00183         FALSE,                            /* pc_relative */
00184         0,                         /* bitpos */
00185         complain_overflow_bitfield,       /* complain_on_overflow */
00186         m88k_special_reloc,        /* special_function */
00187         "VRT16",                   /* name */
00188         FALSE,                            /* partial_inplace */
00189         0x0000ffff,                /* src_mask */
00190         0x0000ffff,                /* dst_mask */
00191         TRUE),                            /* pcrel_offset */
00192 
00193   HOWTO (R_HVRT16,                 /* type */
00194         16,                        /* rightshift */
00195         1,                         /* size (0 = byte, 1 = short, 2 = long) */
00196         16,                        /* bitsize */
00197         FALSE,                            /* pc_relative */
00198         0,                         /* bitpos */
00199         complain_overflow_dont,    /* complain_on_overflow */
00200         m88k_special_reloc,        /* special_function */
00201         "HVRT16",                  /* name */
00202         FALSE,                            /* partial_inplace */
00203         0x0000ffff,                /* src_mask */
00204         0x0000ffff,                /* dst_mask */
00205         TRUE),                            /* pcrel_offset */
00206 
00207   HOWTO (R_LVRT16,                 /* type */
00208         00,                        /* rightshift */
00209         1,                         /* size (0 = byte, 1 = short, 2 = long) */
00210         16,                        /* bitsize */
00211         FALSE,                            /* pc_relative */
00212         0,                         /* bitpos */
00213         complain_overflow_dont,    /* complain_on_overflow */
00214         m88k_special_reloc,        /* special_function */
00215         "LVRT16",                  /* name */
00216         FALSE,                            /* partial_inplace */
00217         0x0000ffff,                /* src_mask */
00218         0x0000ffff,                /* dst_mask */
00219         TRUE),                            /* pcrel_offset */
00220 
00221   HOWTO (R_VRT32,                  /* type */
00222         00,                        /* rightshift */
00223         2,                         /* size (0 = byte, 1 = short, 2 = long) */
00224         32,                        /* bitsize */
00225         FALSE,                            /* pc_relative */
00226         0,                         /* bitpos */
00227         complain_overflow_bitfield,       /* complain_on_overflow */
00228         m88k_special_reloc,        /* special_function */
00229         "VRT32",                   /* name */
00230         FALSE,                            /* partial_inplace */
00231         0xffffffff,                /* src_mask */
00232         0xffffffff,                /* dst_mask */
00233         TRUE),                            /* pcrel_offset */
00234 };
00235 
00236 /* Code to turn an external r_type into a pointer to an entry in the
00237    above howto table.  */
00238 static void
00239 rtype2howto (cache_ptr, dst)
00240      arelent *cache_ptr;
00241      struct internal_reloc *dst;
00242 {
00243   if (dst->r_type >= R_PCR16L && dst->r_type <= R_VRT32)
00244     {
00245       cache_ptr->howto = howto_table + dst->r_type - R_PCR16L;
00246     }
00247   else
00248     {
00249       BFD_ASSERT (0);
00250     }
00251 }
00252 
00253 #define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst)
00254 
00255 /* Code to swap in the reloc offset */
00256 #define SWAP_IN_RELOC_OFFSET  H_GET_16
00257 #define SWAP_OUT_RELOC_OFFSET H_PUT_16
00258 
00259 #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section)    \
00260   reloc_processing(relent, reloc, symbols, abfd, section)
00261 
00262 static void
00263 reloc_processing (relent, reloc, symbols, abfd, section)
00264      arelent *relent;
00265      struct internal_reloc *reloc;
00266      asymbol **symbols;
00267      bfd *abfd;
00268      asection *section;
00269 {
00270   relent->address = reloc->r_vaddr;
00271   rtype2howto (relent, reloc);
00272 
00273   if (((int) reloc->r_symndx) > 0)
00274     {
00275       relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
00276     }
00277   else
00278     {
00279       relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
00280     }
00281 
00282   relent->addend = reloc->r_offset;
00283   relent->address -= section->vma;
00284 }
00285 
00286 #define BADMAG(x) MC88BADMAG(x)
00287 #include "coffcode.h"
00288 
00289 #undef coff_write_armap
00290 
00291 CREATE_BIG_COFF_TARGET_VEC (m88kbcs_vec, "coff-m88kbcs", 0, 0, '_', NULL, COFF_SWAP_TABLE)