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

binutils/2.18/bfd/coff-i960.c

    1: /* BFD back-end for Intel 960 COFF files.
    2:    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1999, 2000, 2001,
    3:    2002, 2003, 2004, 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 I960 1
   24: #define BADMAG(x) I960BADMAG(x)
   25: 
   26: #include "sysdep.h"
   27: #include "bfd.h"
   28: #include "libbfd.h"
   29: #include "coff/i960.h"
   30: #include "coff/internal.h"
   31: #include "libcoff.h"            /* to allow easier abstraction-breaking */
   32: 
   33: static bfd_boolean coff_i960_is_local_label_name
   34:   PARAMS ((bfd *, const char *));
   35: static bfd_reloc_status_type optcall_callback
   36:   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
   37: static bfd_reloc_status_type coff_i960_relocate
   38:   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
   39: static reloc_howto_type *coff_i960_reloc_type_lookup
   40:   PARAMS ((bfd *, bfd_reloc_code_real_type));
   41: static bfd_boolean coff_i960_start_final_link
   42:   PARAMS ((bfd *, struct bfd_link_info *));
   43: static bfd_boolean coff_i960_relocate_section
   44:   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
   45:            struct internal_reloc *, struct internal_syment *, asection **));
   46: static bfd_boolean coff_i960_adjust_symndx
   47:   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
   48:            struct internal_reloc *, bfd_boolean *));
   49: 
   50: #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
   51: #define COFF_ALIGN_IN_SECTION_HEADER 1
   52: 
   53: #define GET_SCNHDR_ALIGN H_GET_32
   54: #define PUT_SCNHDR_ALIGN H_PUT_32
   55: 
   56: /* The i960 does not support an MMU, so COFF_PAGE_SIZE can be
   57:    arbitrarily small.  */
   58: #define COFF_PAGE_SIZE 1
   59: 
   60: #define COFF_LONG_FILENAMES
   61: 
   62: /* This set of local label names is taken from gas.  */
   63: 
   64: static bfd_boolean
   65: coff_i960_is_local_label_name (abfd, name)
   66:      bfd *abfd ATTRIBUTE_UNUSED;
   67:      const char *name;
   68: {
   69:   return (name[0] == 'L'
   70:           || (name[0] == '.'
   71:               && (name[1] == 'C'
   72:                   || name[1] == 'I'
   73:                   || name[1] == '.')));
   74: }
   75: 
   76: /* This is just like the usual CALC_ADDEND, but it includes the
   77:    section VMA for PC relative relocs.  */
   78: #ifndef CALC_ADDEND
   79: #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)                \
   80:   {                                                             \
   81:     coff_symbol_type *coffsym = (coff_symbol_type *) NULL;      \
   82:     if (ptr && bfd_asymbol_bfd (ptr) != abfd)                   \
   83:       coffsym = (obj_symbols (abfd)                             \
   84:                  + (cache_ptr->sym_ptr_ptr - symbols));         \
   85:     else if (ptr)                                               \
   86:       coffsym = coff_symbol_from (abfd, ptr);                   \
   87:     if (coffsym != (coff_symbol_type *) NULL                    \
   88:         && coffsym->native->u.syment.n_scnum == 0)              \
   89:       cache_ptr->addend = 0;                                    \
   90:     else if (ptr && bfd_asymbol_bfd (ptr) == abfd               \
   91:              && ptr->section != (asection *) NULL)              \
   92:       cache_ptr->addend = - (ptr->section->vma + ptr->value);   \
   93:     else                                                        \
   94:       cache_ptr->addend = 0;                                    \
   95:     if (ptr && (reloc.r_type == 25 || reloc.r_type == 27))      \
   96:       cache_ptr->addend += asect->vma;                          \
   97:   }
   98: #endif
   99: 
  100: #define CALLS    0x66003800       /* Template for 'calls' instruction   */
  101: #define BAL      0x0b000000 /* Template for 'bal' instruction       */
  102: #define BAL_MASK 0x00ffffff
  103: 
  104: static bfd_reloc_status_type
  105: optcall_callback (abfd, reloc_entry, symbol_in, data,
  106:                   input_section, ignore_bfd, error_message)
  107:      bfd *abfd;
  108:      arelent *reloc_entry;
  109:      asymbol *symbol_in;
  110:      PTR data;
  111:      asection *input_section;
  112:      bfd *ignore_bfd ATTRIBUTE_UNUSED;
  113:      char **error_message;
  114: {
  115:   /* This item has already been relocated correctly, but we may be
  116:    * able to patch in yet better code - done by digging out the
  117:    * correct info on this symbol */
  118:   bfd_reloc_status_type result;
  119:   coff_symbol_type *cs = coffsymbol(symbol_in);
  120: 
  121:   /* Don't do anything with symbols which aren't tied up yet,
  122:      except move the reloc.  */
  123:   if (bfd_is_und_section (cs->symbol.section)) {
  124:     reloc_entry->address += input_section->output_offset;
  125:     return bfd_reloc_ok;
  126:   }
  127: 
  128:   /* So the target symbol has to be of coff type, and the symbol
  129:      has to have the correct native information within it */
  130:   if ((bfd_asymbol_flavour(&cs->symbol) != bfd_target_coff_flavour)
  131:       || (cs->native == (combined_entry_type *)NULL))
  132:     {
  133:       /* This is interesting, consider the case where we're outputting coff
  134:          from a mix n match input, linking from coff to a symbol defined in a
  135:          bout file will cause this match to be true. Should I complain?  This
  136:          will only work if the bout symbol is non leaf.  */
  137:       *error_message =
  138:         (char *) _("uncertain calling convention for non-COFF symbol");
  139:       result = bfd_reloc_dangerous;
  140:     }
  141:   else
  142:     {
  143:     switch (cs->native->u.syment.n_sclass)
  144:       {
  145:       case C_LEAFSTAT:
  146:       case C_LEAFEXT:
  147:         /* This is a call to a leaf procedure, replace instruction with a bal
  148:            to the correct location.  */
  149:         {
  150:           union internal_auxent *aux = &((cs->native+2)->u.auxent);
  151:           int word = bfd_get_32 (abfd, (bfd_byte *)data + reloc_entry->address);
  152:           int olf = (aux->x_bal.x_balntry - cs->native->u.syment.n_value);
  153:           BFD_ASSERT(cs->native->u.syment.n_numaux==2);
  154: 
  155:           /* We replace the original call instruction with a bal to
  156:              the bal entry point - the offset of which is described in
  157:              the 2nd auxent of the original symbol. We keep the native
  158:              sym and auxents untouched, so the delta between the two
  159:              is the offset of the bal entry point.  */
  160:           word = ((word +  olf)  & BAL_MASK) | BAL;
  161:           bfd_put_32 (abfd, (bfd_vma) word,
  162:                       (bfd_byte *) data + reloc_entry->address);
  163:         }
  164:         result = bfd_reloc_ok;
  165:         break;
  166:       case C_SCALL:
  167:         /* This is a call to a system call, replace with a calls to # */
  168:         BFD_ASSERT(0);
  169:         result = bfd_reloc_ok;
  170:         break;
  171:       default:
  172:         result = bfd_reloc_ok;
  173:         break;
  174:       }
  175:   }
  176:   return result;
  177: }
  178: 
  179: /* i960 COFF is used by VxWorks 5.1.  However, VxWorks 5.1 does not
  180:    appear to correctly handle a reloc against a symbol defined in the
  181:    same object file.  It appears to simply discard such relocs, rather
  182:    than adding their values into the object file.  We handle this here
  183:    by converting all relocs against defined symbols into relocs
  184:    against the section symbol, when generating a relocatable output
  185:    file.
  186: 
  187:    Note that this function is only called if we are not using the COFF
  188:    specific backend linker.  It only does something when doing a
  189:    relocatable link, which will almost certainly fail when not
  190:    generating COFF i960 output, so this function is actually no longer
  191:    useful.  It was used before this target was converted to use the
  192:    COFF specific backend linker.  */
  193: 
  194: static bfd_reloc_status_type
  195: coff_i960_relocate (abfd, reloc_entry, symbol, data, input_section,
  196:                     output_bfd, error_message)
  197:      bfd *abfd;
  198:      arelent *reloc_entry;
  199:      asymbol *symbol;
  200:      PTR data ATTRIBUTE_UNUSED;
  201:      asection *input_section ATTRIBUTE_UNUSED;
  202:      bfd *output_bfd;
  203:      char **error_message ATTRIBUTE_UNUSED;
  204: {
  205:   asection *osec;
  206: 
  207:   if (output_bfd == NULL)
  208:     {
  209:       /* Not generating relocatable output file.  */
  210:       return bfd_reloc_continue;
  211:     }
  212: 
  213:   if (bfd_is_und_section (bfd_get_section (symbol)))
  214:     {
  215:       /* Symbol is not defined, so no need to worry about it.  */
  216:       return bfd_reloc_continue;
  217:     }
  218: 
  219:   if (bfd_is_com_section (bfd_get_section (symbol)))
  220:     {
  221:       /* I don't really know what the right action is for a common
  222:          symbol.  */
  223:       return bfd_reloc_continue;
  224:     }
  225: 
  226:   /* Convert the reloc to use the section symbol.  FIXME: This method
  227:      is ridiculous.  */
  228:   osec = bfd_get_section (symbol)->output_section;
  229:   if (coff_section_data (output_bfd, osec) != NULL
  230:       && coff_section_data (output_bfd, osec)->tdata != NULL)
  231:     reloc_entry->sym_ptr_ptr =
  232:       (asymbol **) coff_section_data (output_bfd, osec)->tdata;
  233:   else
  234:     {
  235:       const char *sec_name;
  236:       asymbol **syms, **sym_end;
  237: 
  238:       sec_name = bfd_get_section_name (output_bfd, osec);
  239:       syms = bfd_get_outsymbols (output_bfd);
  240:       sym_end = syms + bfd_get_symcount (output_bfd);
  241:       for (; syms < sym_end; syms++)
  242:         {
  243:           if (bfd_asymbol_name (*syms) != NULL
  244:               && (*syms)->value == 0
  245:               && strcmp ((*syms)->section->output_section->name,
  246:                          sec_name) == 0)
  247:             break;
  248:         }
  249: 
  250:       if (syms >= sym_end)
  251:         abort ();
  252: 
  253:       reloc_entry->sym_ptr_ptr = syms;
  254: 
  255:       if (coff_section_data (output_bfd, osec) == NULL)
  256:         {
  257:           bfd_size_type amt = sizeof (struct coff_section_tdata);
  258:           osec->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
  259:           if (osec->used_by_bfd == NULL)
  260:             return bfd_reloc_overflow;
  261:         }
  262:       coff_section_data (output_bfd, osec)->tdata = (PTR) syms;
  263:     }
  264: 
  265:   /* Let bfd_perform_relocation do its thing, which will include
  266:      stuffing the symbol addend into the object file.  */
  267:   return bfd_reloc_continue;
  268: }
  269: 
  270: static reloc_howto_type howto_rellong =
  271:   HOWTO ((unsigned int) R_RELLONG, 0, 2, 32,FALSE, 0,
  272:          complain_overflow_bitfield, coff_i960_relocate,"rellong", TRUE,
  273:          0xffffffff, 0xffffffff, 0);
  274: static reloc_howto_type howto_iprmed =
  275:   HOWTO (R_IPRMED, 0, 2, 24,TRUE,0, complain_overflow_signed,
  276:          coff_i960_relocate, "iprmed ", TRUE, 0x00ffffff, 0x00ffffff, 0);
  277: static reloc_howto_type howto_optcall =
  278:   HOWTO (R_OPTCALL, 0,2,24,TRUE,0, complain_overflow_signed,
  279:          optcall_callback, "optcall", TRUE, 0x00ffffff, 0x00ffffff, 0);
  280: 
  281: static reloc_howto_type *
  282: coff_i960_reloc_type_lookup (abfd, code)
  283:      bfd *abfd ATTRIBUTE_UNUSED;
  284:      bfd_reloc_code_real_type code;
  285: {
  286:   switch (code)
  287:     {
  288:     default:
  289:       return 0;
  290:     case BFD_RELOC_I960_CALLJ:
  291:       return &howto_optcall;
  292:     case BFD_RELOC_32:
  293:     case BFD_RELOC_CTOR:
  294:       return &howto_rellong;
  295:     case BFD_RELOC_24_PCREL:
  296:       return &howto_iprmed;
  297:     }
  298: }
  299: 
  300: static reloc_howto_type *
  301: coff_i960_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
  302:                              const char *r_name)
  303: {
  304:   if (strcasecmp (howto_optcall.name, r_name) == 0)
  305:     return &howto_optcall;
  306:   if (strcasecmp (howto_rellong.name, r_name) == 0)
  307:     return &howto_rellong;
  308:   if (strcasecmp (howto_iprmed.name, r_name) == 0)
  309:     return &howto_iprmed;
  310: 
  311:   return NULL;
  312: }
  313: 
  314: /* The real code is in coffcode.h */
  315: 
  316: #define RTYPE2HOWTO(cache_ptr, dst) \
  317: {                                                       \
  318:    reloc_howto_type *howto_ptr;                         \
  319:    switch ((dst)->r_type) {                             \
  320:      case 17: howto_ptr = &howto_rellong; break;        \
  321:      case 25: howto_ptr = &howto_iprmed; break;         \
  322:      case 27: howto_ptr = &howto_optcall; break;        \
  323:      default: howto_ptr = 0; break;                     \
  324:      }                                                  \
  325:    (cache_ptr)->howto = howto_ptr;                      \
  326:  }
  327: 
  328: /* i960 COFF is used by VxWorks 5.1.  However, VxWorks 5.1 does not
  329:    appear to correctly handle a reloc against a symbol defined in the
  330:    same object file.  It appears to simply discard such relocs, rather
  331:    than adding their values into the object file.  We handle this by
  332:    converting all relocs against global symbols into relocs against
  333:    internal symbols at the start of the section.  This routine is
  334:    called at the start of the linking process, and it creates the
  335:    necessary symbols.  */
  336: 
  337: static bfd_boolean
  338: coff_i960_start_final_link (abfd, info)
  339:      bfd *abfd;
  340:      struct bfd_link_info *info;
  341: {
  342:   bfd_size_type symesz = bfd_coff_symesz (abfd);
  343:   asection *o;
  344:   bfd_byte *esym;
  345: 
  346:   if (! info->relocatable)
  347:     return TRUE;
  348: 
  349:   esym = (bfd_byte *) bfd_malloc (symesz);
  350:   if (esym == NULL)
  351:     return FALSE;
  352: 
  353:   if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
  354:     return FALSE;
  355: 
  356:   for (o = abfd->sections; o != NULL; o = o->next)
  357:     {
  358:       struct internal_syment isym;
  359: 
  360:       strncpy (isym._n._n_name, o->name, SYMNMLEN);
  361:       isym.n_value = 0;
  362:       isym.n_scnum = o->target_index;
  363:       isym.n_type = T_NULL;
  364:       isym.n_sclass = C_STAT;
  365:       isym.n_numaux = 0;
  366: 
  367:       bfd_coff_swap_sym_out (abfd, (PTR) &isym, (PTR) esym);
  368: 
  369:       if (bfd_bwrite (esym, symesz, abfd) != symesz)
  370:         {
  371:           free (esym);
  372:           return FALSE;
  373:         }
  374: 
  375:       obj_raw_syment_count (abfd) += 1;
  376:     }
  377: 
  378:   free (esym);
  379: 
  380:   return TRUE;
  381: }
  382: 
  383: /* The reloc processing routine for the optimized COFF linker.  */
  384: 
  385: static bfd_boolean
  386: coff_i960_relocate_section (output_bfd, info, input_bfd, input_section,
  387:                             contents, relocs, syms, sections)
  388:      bfd *output_bfd ATTRIBUTE_UNUSED;
  389:      struct bfd_link_info *info;
  390:      bfd *input_bfd;
  391:      asection *input_section;
  392:      bfd_byte *contents;
  393:      struct internal_reloc *relocs;
  394:      struct internal_syment *syms;
  395:      asection **sections;
  396: {
  397:   struct internal_reloc *rel;
  398:   struct internal_reloc *relend;
  399: 
  400:   rel = relocs;
  401:   relend = rel + input_section->reloc_count;
  402:   for (; rel < relend; rel++)
  403:     {
  404:       long symndx;
  405:       struct coff_link_hash_entry *h;
  406:       struct internal_syment *sym;
  407:       bfd_vma addend;
  408:       bfd_vma val;
  409:       reloc_howto_type *howto;
  410:       bfd_reloc_status_type rstat = bfd_reloc_ok;
  411:       bfd_boolean done;
  412: 
  413:       symndx = rel->r_symndx;
  414: 
  415:       if (symndx == -1)
  416:         {
  417:           h = NULL;
  418:           sym = NULL;
  419:         }
  420:       else
  421:         {
  422:           h = obj_coff_sym_hashes (input_bfd)[symndx];
  423:           sym = syms + symndx;
  424:         }
  425: 
  426:       if (sym != NULL && sym->n_scnum != 0)
  427:         addend = - sym->n_value;
  428:       else
  429:         addend = 0;
  430: 
  431:       switch (rel->r_type)
  432:         {
  433:         case 17: howto = &howto_rellong; break;
  434:         case 25: howto = &howto_iprmed; break;
  435:         case 27: howto = &howto_optcall; break;
  436:         default:
  437:           bfd_set_error (bfd_error_bad_value);
  438:           return FALSE;
  439:         }
  440: 
  441:       val = 0;
  442: 
  443:       if (h == NULL)
  444:         {
  445:           asection *sec;
  446: 
  447:           if (symndx == -1)
  448:             {
  449:               sec = bfd_abs_section_ptr;
  450:               val = 0;
  451:             }
  452:           else
  453:             {
  454:               sec = sections[symndx];
  455:               val = (sec->output_section->vma
  456:                      + sec->output_offset
  457:                      + sym->n_value
  458:                      - sec->vma);
  459:             }
  460:         }
  461:       else
  462:         {
  463:           if (h->root.type == bfd_link_hash_defined
  464:               || h->root.type == bfd_link_hash_defweak)
  465:             {
  466:               asection *sec;
  467: 
  468:               sec = h->root.u.def.section;
  469:               val = (h->root.u.def.value
  470:                      + sec->output_section->vma
  471:                      + sec->output_offset);
  472:             }
  473:           else if (! info->relocatable)
  474:             {
  475:               if (! ((*info->callbacks->undefined_symbol)
  476:                      (info, h->root.root.string, input_bfd, input_section,
  477:                       rel->r_vaddr - input_section->vma, TRUE)))
  478:                 return FALSE;
  479:             }
  480:         }
  481: 
  482:       done = FALSE;
  483: 
  484:       if (howto->type == R_OPTCALL && ! info->relocatable && symndx != -1)
  485:         {
  486:           int class;
  487: 
  488:           if (h != NULL)
  489:             class = h->class;
  490:           else
  491:             class = sym->n_sclass;
  492: 
  493:           switch (class)
  494:             {
  495:             case C_NULL:
  496:               /* This symbol is apparently not from a COFF input file.
  497:                  We warn, and then assume that it is not a leaf
  498:                  function.  */
  499:               if (! ((*info->callbacks->reloc_dangerous)
  500:                      (info,
  501:                       _("uncertain calling convention for non-COFF symbol"),
  502:                       input_bfd, input_section,
  503:                       rel->r_vaddr - input_section->vma)))
  504:                 return FALSE;
  505:               break;
  506:             case C_LEAFSTAT:
  507:             case C_LEAFEXT:
  508:               /* This is a call to a leaf procedure; use the bal
  509:                  instruction.  */
  510:               {
  511:                 long olf;
  512:                 unsigned long word;
  513: 
  514:                 if (h != NULL)
  515:                   {
  516:                     BFD_ASSERT (h->numaux == 2);
  517:                     olf = h->aux[1].x_bal.x_balntry;
  518:                   }
  519:                 else
  520:                   {
  521:                     bfd_byte *esyms;
  522:                     union internal_auxent aux;
  523: 
  524:                     BFD_ASSERT (sym->n_numaux == 2);
  525:                     esyms = (bfd_byte *) obj_coff_external_syms (input_bfd);
  526:                     esyms += (symndx + 2) * bfd_coff_symesz (input_bfd);
  527:                     bfd_coff_swap_aux_in (input_bfd, (PTR) esyms, sym->n_type,
  528:                                           sym->n_sclass, 1, sym->n_numaux,
  529:                                           (PTR) &aux);
  530:                     olf = aux.x_bal.x_balntry;
  531:                   }
  532: 
  533:                 word = bfd_get_32 (input_bfd,
  534:                                    (contents
  535:                                     + (rel->r_vaddr - input_section->vma)));
  536:                 word = ((word + olf - val) & BAL_MASK) | BAL;
  537:                 bfd_put_32 (input_bfd,
  538:                             (bfd_vma) word,
  539:                             contents + (rel->r_vaddr - input_section->vma));
  540:                 done = TRUE;
  541:               }
  542:               break;
  543:             case C_SCALL:
  544:               BFD_ASSERT (0);
  545:               break;
  546:             }
  547:         }
  548: 
  549:       if (! done)
  550:         {
  551:           if (howto->pc_relative)
  552:             addend += input_section->vma;
  553:           rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
  554:                                             contents,
  555:                                             rel->r_vaddr - input_section->vma,
  556:                                             val, addend);
  557:         }
  558: 
  559:       switch (rstat)
  560:         {
  561:         default:
  562:           abort ();
  563:         case bfd_reloc_ok:
  564:           break;
  565:         case