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

binutils/2.18/bfd/aout-tic30.c

    1: /* BFD back-end for TMS320C30 a.out binaries.
    2:    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
    3:    Free Software Foundation, Inc.
    4:    Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
    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, MA
   21:    02110-1301, USA.  */
   22: 
   23: #define TARGET_IS_BIG_ENDIAN_P
   24: #define N_HEADER_IN_TEXT(x)     1
   25: #define TEXT_START_ADDR         1024
   26: #define TARGET_PAGE_SIZE        128
   27: #define SEGMENT_SIZE            TARGET_PAGE_SIZE
   28: #define DEFAULT_ARCH            bfd_arch_tic30
   29: #define ARCH_SIZE 32
   30: 
   31: /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
   32:    remove whitespace added here, and thus will fail to concatenate
   33:    the tokens.  */
   34: #define MY(OP) CONCAT2 (tic30_aout_,OP)
   35: #define TARGETNAME "a.out-tic30"
   36: #define NAME(x,y) CONCAT3 (tic30_aout,_32_,y)
   37: 
   38: #include "sysdep.h"
   39: #include "bfd.h"
   40: #include "libaout.h"
   41: #include "aout/aout64.h"
   42: #include "aout/stab_gnu.h"
   43: #include "aout/ar.h"
   44: 
   45: #define MY_reloc_howto(BFD, REL, IN, EX, PC)   tic30_aout_reloc_howto (BFD, REL, & IN, & EX, & PC)
   46: 
   47: #define MY_final_link_relocate    tic30_aout_final_link_relocate
   48: #define MY_object_p               tic30_aout_object_p
   49: #define MY_mkobject               NAME (aout,mkobject)
   50: #define MY_write_object_contents  tic30_aout_write_object_contents
   51: #define MY_set_sizes              tic30_aout_set_sizes
   52: 
   53: #ifndef MY_exec_hdr_flags
   54: #define MY_exec_hdr_flags 1
   55: #endif
   56: 
   57: #ifndef MY_backend_data
   58: 
   59: #ifndef MY_zmagic_contiguous
   60: #define MY_zmagic_contiguous 0
   61: #endif
   62: #ifndef MY_text_includes_header
   63: #define MY_text_includes_header 0
   64: #endif
   65: #ifndef MY_entry_is_text_address
   66: #define MY_entry_is_text_address 0
   67: #endif
   68: #ifndef MY_exec_header_not_counted
   69: #define MY_exec_header_not_counted 1
   70: #endif
   71: #ifndef MY_add_dynamic_symbols
   72: #define MY_add_dynamic_symbols 0
   73: #endif
   74: #ifndef MY_add_one_symbol
   75: #define MY_add_one_symbol 0
   76: #endif
   77: #ifndef MY_link_dynamic_object
   78: #define MY_link_dynamic_object 0
   79: #endif
   80: #ifndef MY_write_dynamic_symbol
   81: #define MY_write_dynamic_symbol 0
   82: #endif
   83: #ifndef MY_check_dynamic_reloc
   84: #define MY_check_dynamic_reloc 0
   85: #endif
   86: #ifndef MY_finish_dynamic_link
   87: #define MY_finish_dynamic_link 0
   88: #endif
   89: 
   90: static bfd_boolean
   91: tic30_aout_set_sizes (bfd *abfd)
   92: {
   93:   adata (abfd).page_size = TARGET_PAGE_SIZE;
   94: 
   95: #ifdef SEGMENT_SIZE
   96:   adata (abfd).segment_size = SEGMENT_SIZE;
   97: #else
   98:   adata (abfd).segment_size = TARGET_PAGE_SIZE;
   99: #endif
  100: 
  101: #ifdef ZMAGIC_DISK_BLOCK_SIZE
  102:   adata (abfd).zmagic_disk_block_size = ZMAGIC_DISK_BLOCK_SIZE;
  103: #else
  104:   adata (abfd).zmagic_disk_block_size = TARGET_PAGE_SIZE;
  105: #endif
  106: 
  107:   adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
  108: 
  109:   return TRUE;
  110: }
  111: 
  112: static const struct aout_backend_data tic30_aout_backend_data =
  113: {
  114:   MY_zmagic_contiguous,
  115:   MY_text_includes_header,
  116:   MY_entry_is_text_address,
  117:   MY_exec_hdr_flags,
  118:   0,                            /* Text vma?  */
  119:   MY_set_sizes,
  120:   MY_exec_header_not_counted,
  121:   MY_add_dynamic_symbols,
  122:   MY_add_one_symbol,
  123:   MY_link_dynamic_object,
  124:   MY_write_dynamic_symbol,
  125:   MY_check_dynamic_reloc,
  126:   MY_finish_dynamic_link
  127: };
  128: #define MY_backend_data &tic30_aout_backend_data
  129: #endif
  130: 
  131: static reloc_howto_type *
  132:   tic30_aout_reloc_howto (bfd *, struct reloc_std_external *, int *, int *, int *);
  133: static bfd_reloc_status_type
  134:   tic30_aout_final_link_relocate
  135:     (reloc_howto_type *, bfd *, asection *, bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
  136: 
  137: /* FIXME: This is wrong.  aoutx.h should really only be included by
  138:    aout32.c.  */
  139: 
  140: #include "aoutx.h"
  141: 
  142: /* This function is used to work out pc-relative offsets for the
  143:    TMS320C30.  The data already placed by md_pcrel_from within gas is
  144:    useless for a relocation, so we just get the offset value and place
  145:    a version of this within the object code.
  146:    tic30_aout_final_link_relocate will then calculate the required
  147:    relocation to add on to the value in the object code.  */
  148: 
  149: static bfd_reloc_status_type
  150: tic30_aout_fix_pcrel_16 (bfd *abfd,
  151:                          arelent *reloc_entry,
  152:                          asymbol *symbol ATTRIBUTE_UNUSED,
  153:                          void * data,
  154:                          asection *input_section ATTRIBUTE_UNUSED,
  155:                          bfd *output_bfd ATTRIBUTE_UNUSED,
  156:                          char **error_message ATTRIBUTE_UNUSED)
  157: {
  158:   bfd_vma relocation = 1;
  159:   bfd_byte offset_data = bfd_get_8 (abfd, (bfd_byte *) data + reloc_entry->address - 1);
  160: 
  161:   /* The byte before the location of the fix contains bits 23-16 of
  162:      the pcrel instruction.  Bit 21 is set for a delayed instruction
  163:      which requires on offset of 3 instead of 1.  */
  164:   if (offset_data & 0x20)
  165:     relocation -= 3;
  166:   else
  167:     relocation -= 1;
  168:   bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
  169:   return bfd_reloc_ok;
  170: }
  171: 
  172: /* This function is used as a callback for 16-bit relocs.  This is
  173:    required for relocations between segments.  A line in aoutx.h
  174:    requires that any relocations for the data section should point to
  175:    the end of the aligned text section, plus an offset.  By default,
  176:    this does not happen, therefore this function takes care of
  177:    that.  */
  178: 
  179: static bfd_reloc_status_type
  180: tic30_aout_fix_16 (bfd *abfd,
  181:                    arelent *reloc_entry,
  182:                    asymbol *symbol,
  183:                    void * data,
  184:                    asection *input_section ATTRIBUTE_UNUSED,
  185:                    bfd *output_bfd,
  186:                    char **error_message ATTRIBUTE_UNUSED)
  187: {
  188:   bfd_vma relocation;
  189: 
  190:   /* Make sure that the symbol's section is defined.  */
  191:   if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0)
  192:     return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined;
  193:   /* Get the size of the input section and turn it into the TMS320C30
  194:      32-bit address format.  */
  195:   relocation = (symbol->section->vma >> 2);
  196:   relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
  197:   bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
  198:   return bfd_reloc_ok;
  199: }
  200: 
  201: /* This function does the same thing as tic30_aout_fix_16 except for 32
  202:    bit relocations.  */
  203: 
  204: static bfd_reloc_status_type
  205: tic30_aout_fix_32 (bfd *abfd,
  206:                    arelent *reloc_entry,
  207:                    asymbol *symbol,
  208:                    void * data,
  209:                    asection *input_section ATTRIBUTE_UNUSED,
  210:                    bfd *output_bfd,
  211:                    char **error_message ATTRIBUTE_UNUSED)
  212: {
  213:   bfd_vma relocation;
  214: 
  215:   /* Make sure that the symbol's section is defined.  */
  216:   if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0)
  217:     return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined;
  218:   /* Get the size of the input section and turn it into the TMS320C30
  219:      32-bit address format.  */
  220:   relocation = (symbol->section->vma >> 2);
  221:   relocation += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
  222:   bfd_put_32 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
  223:   return bfd_reloc_ok;
  224: }
  225: 
  226: /* This table lists the relocation types for the TMS320C30.  There are
  227:    only a few relocations required, and all must be divided by 4 (>>
  228:    2) to get the 32-bit addresses in the format the TMS320C30 likes
  229:    it.  */
  230: reloc_howto_type tic30_aout_howto_table[] =
  231: {
  232:   EMPTY_HOWTO (-1),
  233:   HOWTO (1, 2, 1, 16, FALSE, 0, 0, tic30_aout_fix_16,
  234:          "16", FALSE, 0x0000FFFF, 0x0000FFFF, FALSE),
  235:   HOWTO (2, 2, 2, 24, FALSE, 0, complain_overflow_bitfield, NULL,
  236:          "24", FALSE, 0x00FFFFFF, 0x00FFFFFF, FALSE),
  237:   HOWTO (3, 18, 3, 24, FALSE, 0, complain_overflow_bitfield, NULL,
  238:          "LDP", FALSE, 0x00FF0000, 0x000000FF, FALSE),
  239:   HOWTO (4, 2, 4, 32, FALSE, 0, complain_overflow_bitfield, tic30_aout_fix_32,
  240:          "32", FALSE, 0xFFFFFFFF, 0xFFFFFFFF, FALSE),
  241:   HOWTO (5, 2, 1, 16, TRUE, 0, complain_overflow_signed,
  242:          tic30_aout_fix_pcrel_16, "PCREL", TRUE, 0x0000FFFF, 0x0000FFFF, TRUE),
  243:   EMPTY_HOWTO (-1),
  244:   EMPTY_HOWTO (-1),
  245:   EMPTY_HOWTO (-1),
  246:   EMPTY_HOWTO (-1),
  247:   EMPTY_HOWTO (-1)
  248: };
  249: 
  250: 
  251: static reloc_howto_type *
  252: tic30_aout_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
  253:                               bfd_reloc_code_real_type code)
  254: {
  255:   switch (code)
  256:     {
  257:     case BFD_RELOC_8:
  258:     case BFD_RELOC_TIC30_LDP:
  259:       return &tic30_aout_howto_table[3];
  260:     case BFD_RELOC_16:
  261:       return &tic30_aout_howto_table[1];
  262:     case BFD_RELOC_24:
  263:       return &tic30_aout_howto_table[2];
  264:     case BFD_RELOC_16_PCREL:
  265:       return &tic30_aout_howto_table[5];
  266:     case BFD_RELOC_32:
  267:       return &tic30_aout_howto_table[4];
  268:     default:
  269:       return NULL;
  270:     }
  271: }
  272: 
  273: static reloc_howto_type *
  274: tic30_aout_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
  275:                               const char *r_name)
  276: {
  277:   unsigned int i;
  278: 
  279:   for (i = 0;
  280:        i < (sizeof (tic30_aout_howto_table)
  281:             / sizeof (tic30_aout_howto_table[0]));
  282:        i++)
  283:     if (tic30_aout_howto_table[i].name != NULL
  284:         && strcasecmp (tic30_aout_howto_table[i].name, r_name) == 0)
  285:       return &tic30_aout_howto_table[i];
  286: 
  287:   return NULL;
  288: }
  289: 
  290: static reloc_howto_type *
  291: tic30_aout_reloc_howto (bfd *abfd,
  292:                         struct reloc_std_external *relocs,
  293:                         int *r_index,
  294:                         int *r_extern,
  295:                         int *r_pcrel)
  296: {
  297:   unsigned int r_length;
  298:   unsigned int r_pcrel_done;
  299:   int index;
  300: 
  301:   *r_pcrel = 0;
  302:   if (bfd_header_big_endian (abfd))
  303:     {
  304:       *r_index = ((relocs->r_index[0] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[2]);
  305:       *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
  306:       r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
  307:       r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) >> RELOC_STD_BITS_LENGTH_SH_BIG);
  308:     }
  309:   else
  310:     {
  311:       *r_index = ((relocs->r_index[2] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[0]);
  312:       *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
  313:       r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
  314:       r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
  315:     }
  316:   index = r_length + 4 * r_pcrel_done;
  317:   return tic30_aout_howto_table + index;
  318: }
  319: 
  320: /* These macros will get 24-bit values from the bfd definition.
  321:    Big-endian only.  */
  322: #define bfd_getb_24(BFD,ADDR)                   \
  323:  (bfd_get_8 (BFD, ADDR    ) << 16) |            \
  324:  (bfd_get_8 (BFD, ADDR + 1) <<  8) |            \
  325:  (bfd_get_8 (BFD, ADDR + 2)      )
  326: 
  327: #define bfd_putb_24(BFD,DATA,ADDR)                              \
  328:  bfd_put_8 (BFD, (bfd_byte) ((DATA >> 16) & 0xFF), ADDR    );   \
  329:  bfd_put_8 (BFD, (bfd_byte) ((DATA >>  8) & 0xFF), ADDR + 1);   \
  330:  bfd_put_8 (BFD, (bfd_byte) ( DATA        & 0xFF), ADDR + 2)
  331: 
  332: /* Set parameters about this a.out file that are machine-dependent.
  333:    This routine is called from some_aout_object_p just before it returns.  */
  334: 
  335: static const bfd_target *
  336: tic30_aout_callback (bfd *abfd)
  337: {
  338:   struct internal_exec *execp = exec_hdr (abfd);
  339:   unsigned int arch_align_power;
  340:   unsigned long arch_align;
  341: 
  342:   /* Calculate the file positions of the parts of a newly read aout header.  */
  343:   obj_textsec (abfd)->size = N_TXTSIZE (*execp);
  344: 
  345:   /* The virtual memory addresses of the sections.  */
  346:   obj_textsec (abfd)->vma = N_TXTADDR (*execp);
  347:   obj_datasec (abfd)->vma = N_DATADDR (*execp);
  348:   obj_bsssec (abfd)->vma = N_BSSADDR (*execp);
  349: 
  350:   obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
  351:   obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
  352:   obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
  353: 
  354:   /* The file offsets of the sections.  */
  355:   obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
  356:   obj_datasec (abfd)->filepos = N_DATOFF (*execp);
  357: 
  358:   /* The file offsets of the relocation info.  */
  359:   obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
  360:   obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
  361: 
  362:   /* The file offsets of the string table and symbol table.  */
  363:   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
  364:   obj_str_filepos (abfd) = N_STROFF (*execp);
  365: 
  366:   /* Determine the architecture and machine type of the object file.  */
  367: #ifdef SET_ARCH_MACH
  368:   SET_ARCH_MACH (abfd, *execp);
  369: #else
  370:   bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0L);
  371: #endif
  372: 
  373:   /* Now that we know the architecture, set the alignments of the
  374:      sections.  This is normally done by NAME (aout,new_section_hook),
  375:      but when the initial sections were created the architecture had
  376:      not yet been set.  However, for backward compatibility, we don't
  377:      set the alignment power any higher than as required by the size
  378:      of the section.  */
  379:   arch_align_power = bfd_get_arch_info (abfd)->section_align_power;
  380:   arch_align = 1 << arch_align_power;
  381:   if ((BFD_ALIGN (obj_textsec (abfd)->size, arch_align)
  382:        == obj_textsec (abfd)->size)
  383:       && (BFD_ALIGN (obj_datasec (abfd)->size, arch_align)
  384:           == obj_datasec (abfd)->size)
  385:       && (BFD_ALIGN (obj_bsssec (abfd)->size, arch_align)
  386:           == obj_bsssec (abfd)->size))
  387:     {
  388:       obj_textsec (abfd)->alignment_power = arch_align_power;
  389:       obj_datasec (abfd)->alignment_power = arch_align_power;
  390:       obj_bsssec (abfd)->alignment_power = arch_align_power;
  391:     }
  392:   return abfd->xvec;
  393: }
  394: 
  395: static bfd_reloc_status_type
  396: tic30_aout_relocate_contents (reloc_howto_type *howto,
  397:                               bfd *input_bfd,
  398:                               bfd_vma relocation,
  399:                               bfd_byte *location)
  400: {
  401:   bfd_vma x;
  402:   bfd_boolean overflow;
  403: 
  404:   if (howto->size < 0)
  405:     relocation = -relocation;
  406: 
  407:   switch (howto->size)
  408:     {
  409:     default:
  410:     case 0:
  411:       abort ();
  412:       break;
  413:     case 1:
  414:       x = bfd_get_16 (input_bfd, location);
  415:       break;
  416:     case 2:
  417:       x = bfd_getb_24 (input_bfd, location);
  418:       break;
  419:     case 3:
  420:       x = bfd_get_8 (input_bfd, location);
  421:       break;
  422:     case 4:
  423:       x = bfd_get_32 (input_bfd, location);
  424:       break;
  425:     }
  426: 
  427:   overflow = FALSE;
  428: 
  429:   if (howto->complain_on_overflow != complain_overflow_dont)
  430:     {
  431:       bfd_vma check;
  432:       bfd_signed_vma signed_check;
  433:       bfd_vma add;
  434:       bfd_signed_vma signed_add;
  435: 
  436:       if (howto->rightshift == 0)
  437:         {
  438:           check = relocation;
  439:           signed_check = (bfd_signed_vma) relocation;
  440:         }
  441:       else
  442:         {
  443:           check = relocation >> howto->rightshift;
  444:           if ((bfd_signed_vma) relocation >= 0)
  445:             signed_check = check;
  446:           else
  447:             signed_check = (check | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->rightshift)));
  448:         }
  449:       add = x & howto->src_mask;
  450:       signed_add = add;
  451:       if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
  452:         signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
  453:       if (howto->bitpos == 0)
  454:         {
  455:           check += add;
  456:           signed_check += signed_add;
  457:         }
  458:       else
  459:         {
  460:           check += add >> howto->bitpos;
  461:           if (signed_add >= 0)
  462:             signed_check += add >> howto->bitpos;
  463:           else
  464:             signed_check += ((add >> howto->bitpos) | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->bitpos)));
  465:         }
  466:       switch (howto->complain_on_overflow)
  467:         {
  468:         case complain_overflow_signed:
  469:           {
  470:             bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
  471:             bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
  472: 
  473:             if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
  474:               overflow = TRUE;
  475:           }
  476:           break;
  477:         case complain_overflow_unsigned:
  478:           {
  479:             bfd_vma reloc_unsigned_max = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
  480: 
  481:             if (check > reloc_unsigned_max)
  482:               overflow = TRUE;
  483:           }
  484:           break;
  485:         case complain_overflow_bitfield:
  486:           {
  487:             bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
  488: 
  489:             if ((check & ~reloc_bits) != 0
  490:                 && (((bfd_vma) signed_check & ~reloc_bits)
  491:                     != ((bfd_vma) -1 & ~reloc_bits)))
  492:               overflow = TRUE;
  493:           }
  494:           break;
  495:         default:
  496:           abort ();
  497:         }
  498:     }
  499:   relocation >>= (bfd_vma) howto->rightshift;
  500:   relocation <<= (bfd_vma) howto->bitpos;
  501:   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask));
  502:   switch (howto->size)
  503:     {
  504:     default:
  505:     case 0:
  506:       abort ();
  507:       break;
  508:     case 1:
  509:       bfd_put_16 (input_bfd, x, location);
  510:       break;
  511:     case 2:
  512:       bfd_putb_24 (input_bfd, x, location);
  513:       break;
  514:     case 3:
  515:       bfd_put_8 (input_bfd, x, location);
  516:       break;
  517:     case 4:
  518:       bfd_put_32 (input_bfd, x, location);
  519:       break;
  520:     }
  521:   return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
  522: }
  523: 
  524: static bfd_reloc_status_type
  525: tic30_aout_final_link_relocate (reloc_howto_type *howto,
  526:                                 bfd *input_bfd,
  527:                                 asection *input_section,
  528:                                 bfd_byte *contents,
  529:                                 bfd_vma address,
  530:                                 bfd_vma value,
  531:                                 bfd_vma addend)
  532: {
  533:   bfd_vma relocation;
  534: 
  535:   if (address > bfd_get_section_limit (input_bfd, input_section))
  536:     return bfd_reloc_outofrange;
  537: 
  538:   relocation = value + addend;