(linenum→info "unix/slp.c:2238")

binutils/2.18/bfd/coff-m88k.c

    1: /* BFD back-end for Motorola 88000 COFF "Binary Compatibility Standard" files.
    2:    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
    3:    2001, 2002, 2003, 2007  Free Software Foundation, Inc.
    4:    Written by Cygnus Support.
    5: 
    6:    This file is part of BFD, the Binary File Descriptor library.
    7: 
    8:    This program is free software; you can redistribute it and/or modify
    9:    it under the terms of the GNU General Public License as published by
   10:    the Free Software Foundation; either version 3 of the License, or
   11:    (at your option) any later version.
   12: 
   13:    This program is distributed in the hope that it will be useful,
   14:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16:    GNU General Public License for more details.
   17: 
   18:    You should have received a copy of the GNU General Public License
   19:    along with this program; if not, write to the Free Software
   20:    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   21:    MA 02110-1301, USA.  */
   22: 
   23: #define M88 1           /* Customize various include files */
   24: #include "sysdep.h"
   25: #include "bfd.h"
   26: #include "libbfd.h"
   27: #include "coff/m88k.h"
   28: #include "coff/internal.h"
   29: #include "libcoff.h"
   30: 
   31: static bfd_boolean m88k_is_local_label_name PARAMS ((bfd *, const char *));
   32: static bfd_reloc_status_type m88k_special_reloc
   33:   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
   34: static void rtype2howto PARAMS ((arelent *, struct internal_reloc *));
   35: static void reloc_processing
   36:   PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
   37: 
   38: #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
   39: 
   40: #define GET_SCNHDR_NRELOC H_GET_32
   41: #define GET_SCNHDR_NLNNO  H_GET_32
   42: 
   43: /* On coff-m88k, local labels start with '@'.  */
   44: 
   45: #define coff_bfd_is_local_label_name m88k_is_local_label_name
   46: 
   47: static bfd_boolean
   48: m88k_is_local_label_name (abfd, name)
   49:      bfd *abfd ATTRIBUTE_UNUSED;
   50:      const char *name;
   51: {
   52:   return name[0] == '@';
   53: }
   54: 
   55: static bfd_reloc_status_type
   56: m88k_special_reloc (abfd, reloc_entry, symbol, data,
   57:                     input_section, output_bfd, error_message)
   58:      bfd *abfd;
   59:      arelent *reloc_entry;
   60:      asymbol *symbol;
   61:      PTR data;
   62:      asection *input_section;
   63:      bfd *output_bfd;
   64:      char **error_message ATTRIBUTE_UNUSED;
   65: {
   66:   reloc_howto_type *howto = reloc_entry->howto;
   67: 
   68:   switch (howto->type)
   69:     {
   70:     case R_HVRT16:
   71:     case R_LVRT16:
   72:       if (output_bfd != (bfd *) NULL)
   73:         {
   74:           /* This is a partial relocation, and we want to apply the
   75:              relocation to the reloc entry rather than the raw data.
   76:              Modify the reloc inplace to reflect what we now know.  */
   77: 
   78:           reloc_entry->address += input_section->output_offset;
   79:         }
   80:       else
   81:         {
   82:           bfd_vma output_base = 0;
   83:           bfd_vma addr = reloc_entry->address;
   84:           bfd_vma x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
   85:           asection *reloc_target_output_section;
   86:           long relocation = 0;
   87: 
   88:           /* Work out which section the relocation is targeted at and the
   89:              initial relocation command value.  */
   90: 
   91:           /* Get symbol value.  (Common symbols are special.)  */
   92:           if (bfd_is_com_section (symbol->section))
   93:             relocation = 0;
   94:           else
   95:             relocation = symbol->value;
   96: 
   97:           reloc_target_output_section = symbol->section->output_section;
   98: 
   99:           /* Convert input-section-relative symbol value to absolute.  */
  100:           if (output_bfd)
  101:             output_base = 0;
  102:           else
  103:             output_base = reloc_target_output_section->vma;
  104: 
  105:           relocation += output_base + symbol->section->output_offset;
  106: 
  107:           /* Add in supplied addend.  */
  108:           relocation += ((reloc_entry->addend << howto->bitsize) + x);
  109: 
  110:           reloc_entry->addend = 0;
  111: 
  112:           relocation >>= (bfd_vma) howto->rightshift;
  113: 
  114:           /* Shift everything up to where it's going to be used */
  115: 
  116:           relocation <<= (bfd_vma) howto->bitpos;
  117: 
  118:           if (relocation)
  119:             bfd_put_16 (abfd, (bfd_vma) relocation,
  120:                         (unsigned char *) data + addr);
  121:         }
  122: 
  123:       /* If we are not producing relocatable output, return an error if
  124:          the symbol is not defined.  */
  125:       if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL)
  126:         return bfd_reloc_undefined;
  127: 
  128:       return bfd_reloc_ok;
  129: 
  130:     default:
  131:       if (output_bfd != (bfd *) NULL)
  132:         {
  133:           /* This is a partial relocation, and we want to apply the
  134:              relocation to the reloc entry rather than the raw data.
  135:              Modify the reloc inplace to reflect what we now know.  */
  136: 
  137:           reloc_entry->address += input_section->output_offset;
  138:           return bfd_reloc_ok;
  139:         }
  140:       break;
  141:     }
  142: 
  143:   if (output_bfd == (bfd *) NULL)
  144:     return bfd_reloc_continue;
  145: 
  146:   return bfd_reloc_ok;
  147: }
  148: 
  149: static reloc_howto_type howto_table[] =
  150: {
  151:   HOWTO (R_PCR16L,                      /* type */
  152:          02,                           /* rightshift */
  153:          1,                            /* size (0 = byte, 1 = short, 2 = long) */
  154:          16,                           /* bitsize */
  155:          TRUE,                         /* pc_relative */
  156:          0,                            /* bitpos */
  157:          complain_overflow_signed,     /* complain_on_overflow */
  158:          m88k_special_reloc,           /* special_function */
  159:          "PCR16L",                     /* name */
  160:          FALSE,                                /* partial_inplace */
  161:          0x0000ffff,                   /* src_mask */
  162:          0x0000ffff,                   /* dst_mask */
  163:          TRUE),                                /* pcrel_offset */
  164: 
  165:   HOWTO (R_PCR26L,                      /* type */
  166:          02,                           /* rightshift */
  167:          2,                            /* size (0 = byte, 1 = short, 2 = long) */
  168:          26,                           /* bitsize */
  169:          TRUE,                         /* pc_relative */
  170:          0,                            /* bitpos */
  171:          complain_overflow_signed,     /* complain_on_overflow */
  172:          m88k_special_reloc,           /* special_function */
  173:          "PCR26L",                     /* name */
  174:          FALSE,                                /* partial_inplace */
  175:          0x03ffffff,                   /* src_mask */
  176:          0x03ffffff,                   /* dst_mask */
  177:          TRUE),                                /* pcrel_offset */
  178: 
  179:   HOWTO (R_VRT16,                       /* type */
  180:          00,                           /* rightshift */
  181:          1,                            /* size (0 = byte, 1 = short, 2 = long) */
  182:          16,                           /* bitsize */
  183:          FALSE,                                /* pc_relative */
  184:          0,                            /* bitpos */
  185:          complain_overflow_bitfield,   /* complain_on_overflow */
  186:          m88k_special_reloc,           /* special_function */
  187:          "VRT16",                      /* name */
  188:          FALSE,                                /* partial_inplace */
  189:          0x0000ffff,                   /* src_mask */
  190:          0x0000ffff,                   /* dst_mask */
  191:          TRUE),                                /* pcrel_offset */
  192: 
  193:   HOWTO (R_HVRT16,                      /* type */
  194:          16,                           /* rightshift */
  195:          1,                            /* size (0 = byte, 1 = short, 2 = long) */
  196:          16,                           /* bitsize */
  197:          FALSE,                                /* pc_relative */
  198:          0,                            /* bitpos */
  199:          complain_overflow_dont,       /* complain_on_overflow */
  200:          m88k_special_reloc,           /* special_function */
  201:          "HVRT16",                     /* name */
  202:          FALSE,                                /* partial_inplace */
  203:          0x0000ffff,                   /* src_mask */
  204:          0x0000ffff,                   /* dst_mask */
  205:          TRUE),                                /* pcrel_offset */
  206: 
  207:   HOWTO (R_LVRT16,                      /* type */
  208:          00,                           /* rightshift */
  209:          1,                            /* size (0 = byte, 1 = short, 2 = long) */
  210:          16,                           /* bitsize */
  211:          FALSE,                                /* pc_relative */
  212:          0,                            /* bitpos */
  213:          complain_overflow_dont,       /* complain_on_overflow */
  214:          m88k_special_reloc,           /* special_function */
  215:          "LVRT16",                     /* name */
  216:          FALSE,                                /* partial_inplace */
  217:          0x0000ffff,                   /* src_mask */
  218:          0x0000ffff,                   /* dst_mask */
  219:          TRUE),                                /* pcrel_offset */
  220: 
  221:   HOWTO (R_VRT32,                       /* type */
  222:          00,                           /* rightshift */
  223:          2,                            /* size (0 = byte, 1 = short, 2 = long) */
  224:          32,                           /* bitsize */
  225:          FALSE,                                /* pc_relative */
  226:          0,                            /* bitpos */
  227:          complain_overflow_bitfield,   /* complain_on_overflow */
  228:          m88k_special_reloc,           /* special_function */
  229:          "VRT32",                      /* name */
  230:          FALSE,                                /* partial_inplace */
  231:          0xffffffff,                   /* src_mask */
  232:          0xffffffff,                   /* dst_mask */
  233:          TRUE),                                /* pcrel_offset */
  234: };
  235: 
  236: /* Code to turn an external r_type into a pointer to an entry in the
  237:    above howto table.  */
  238: static void
  239: rtype2howto (cache_ptr, dst)
  240:      arelent *cache_ptr;
  241:      struct internal_reloc *dst;
  242: {
  243:   if (dst->r_type >= R_PCR16L && dst->r_type <= R_VRT32)
  244:     {
  245:       cache_ptr->howto = howto_table + dst->r_type - R_PCR16L;
  246:     }
  247:   else
  248:     {
  249:       BFD_ASSERT (0);
  250:     }
  251: }
  252: 
  253: #define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst)
  254: 
  255: /* Code to swap in the reloc offset */
  256: #define SWAP_IN_RELOC_OFFSET  H_GET_16
  257: #define SWAP_OUT_RELOC_OFFSET H_PUT_16
  258: 
  259: #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section)     \
  260:   reloc_processing(relent, reloc, symbols, abfd, section)
  261: 
  262: static void
  263: reloc_processing (relent, reloc, symbols, abfd, section)
  264:      arelent *relent;
  265:      struct internal_reloc *reloc;
  266:      asymbol **symbols;
  267:      bfd *abfd;
  268:      asection *section;
  269: {
  270:   relent->address = reloc->r_vaddr;
  271:   rtype2howto (relent, reloc);
  272: 
  273:   if (((int) reloc->r_symndx) > 0)
  274:     {
  275:       relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
  276:     }
  277:   else
  278:     {
  279:       relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
  280:     }
  281: 
  282:   relent->addend = reloc->r_offset;
  283:   relent->address -= section->vma;
  284: }
  285: 
  286: #define BADMAG(x) MC88BADMAG(x)
  287: #include "coffcode.h"
  288: 
  289: #undef coff_write_armap
  290: 
  291: CREATE_BIG_COFF_TARGET_VEC (m88kbcs_vec, "coff-m88kbcs", 0, 0, '_', NULL, COFF_SWAP_TABLE)
Syntax (Markdown)