home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / gnu / gdb-4.12.tar.gz / gdb-4.12.tar / gdb-4.12 / bfd / coff-h8300.c < prev    next >
C/C++ Source or Header  |  1994-02-03  |  16KB  |  573 lines

  1. /* BFD back-end for Hitachi H8/300 COFF binaries.
  2.    Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
  3.    Written by Steve Chamberlain, <sac@cygnus.com>.
  4.  
  5. This file is part of BFD, the Binary File Descriptor library.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #include "bfd.h"
  22. #include "sysdep.h"
  23. #include "obstack.h"
  24. #include "libbfd.h"
  25. #include "bfdlink.h"
  26. #include "coff/h8300.h"
  27. #include "coff/internal.h"
  28. #include "libcoff.h"
  29.  
  30. static reloc_howto_type howto_table[] =
  31. {
  32.   HOWTO (R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "8", true, 0x000000ff, 0x000000ff, false),
  33.   HOWTO (R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16", true, 0x0000ffff, 0x0000ffff, false),
  34.   HOWTO (R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "32", true, 0xffffffff, 0xffffffff, false),
  35.   HOWTO (R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, 0, "DISP8", true, 0x000000ff, 0x000000ff, true),
  36.   HOWTO (R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, 0, "DISP16", true, 0x0000ffff, 0x0000ffff, true),
  37.   HOWTO (R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, 0, "DISP32", true, 0xffffffff, 0xffffffff, true),
  38.   HOWTO (R_MOVB1, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16/8", true, 0x0000ffff, 0x0000ffff, false),
  39.   HOWTO (R_MOVB2, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "8/16", true, 0x0000ffff, 0x0000ffff, false),
  40.   HOWTO (R_JMP1, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16/pcrel", true, 0x0000ffff, 0x0000ffff, false),
  41.   HOWTO (R_JMP2, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "pcrecl/16", true, 0x000000ff, 0x000000ff, false),
  42.  
  43.  
  44.   HOWTO (R_JMPL1, 0, 1, 32, false, 0, complain_overflow_bitfield, 0, "24/pcrell", true, 0x0000ffff, 0x0000ffff, false),
  45.   HOWTO (R_JMPL_B8, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "pc8/24", true, 0x000000ff, 0x000000ff, false),
  46.  
  47.   HOWTO (R_MOVLB1, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "24/8", true, 0x0000ffff, 0x0000ffff, false),
  48.   HOWTO (R_MOVLB2, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "8/24", true, 0x0000ffff, 0x0000ffff, false),
  49.  
  50. };
  51.  
  52.  
  53. /* Turn a howto into a reloc number */
  54.  
  55. #define SELECT_RELOC(x,howto) \
  56.   { x = select_reloc(howto); }
  57.  
  58. #define BADMAG(x) (H8300BADMAG(x)&& H8300HBADMAG(x))
  59. #define H8300 1            /* Customize coffcode.h */
  60. #define __A_MAGIC_SET__
  61.  
  62.  
  63.  
  64. /* Code to swap in the reloc */
  65. #define SWAP_IN_RELOC_OFFSET   bfd_h_get_32
  66. #define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
  67. #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
  68.   dst->r_stuff[0] = 'S'; \
  69.   dst->r_stuff[1] = 'C';
  70.  
  71.  
  72. static int
  73. select_reloc (howto)
  74.      reloc_howto_type *howto;
  75. {
  76.   return howto->type;
  77. }
  78.  
  79. /* Code to turn a r_type into a howto ptr, uses the above howto table
  80.    */
  81.  
  82. static void
  83. rtype2howto (internal, dst)
  84.      arelent *internal;
  85.      struct internal_reloc *dst;
  86. {
  87.   switch (dst->r_type)
  88.     {
  89.     case R_RELBYTE:
  90.       internal->howto = howto_table + 0;
  91.       break;
  92.     case R_RELWORD:
  93.       internal->howto = howto_table + 1;
  94.       break;
  95.     case R_RELLONG:
  96.       internal->howto = howto_table + 2;
  97.       break;
  98.     case R_PCRBYTE:
  99.       internal->howto = howto_table + 3;
  100.       break;
  101.     case R_PCRWORD:
  102.       internal->howto = howto_table + 4;
  103.       break;
  104.     case R_PCRLONG:
  105.       internal->howto = howto_table + 5;
  106.       break;
  107.     case R_MOVB1:
  108.       internal->howto = howto_table + 6;
  109.       break;
  110.     case R_MOVB2:
  111.       internal->howto = howto_table + 7;
  112.       break;
  113.     case R_JMP1:
  114.       internal->howto = howto_table + 8;
  115.       break;
  116.     case R_JMP2:
  117.       internal->howto = howto_table + 9;
  118.       break;
  119.     case R_JMPL1:
  120.       internal->howto = howto_table + 10;
  121.       break;
  122.     case R_JMPL_B8:
  123.       internal->howto = howto_table + 11;
  124.       break;
  125.     case R_MOVLB1:
  126.       internal->howto = howto_table + 12;
  127.       break;
  128.     case R_MOVLB2:
  129.       internal->howto = howto_table + 13;
  130.       break;
  131.     default:
  132.       fprintf (stderr, "Bad reloc\n");
  133.       break;
  134.     }
  135. }
  136.  
  137. #define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
  138.  
  139.  
  140. /* Perform any necessaru magic to the addend in a reloc entry */
  141.  
  142.  
  143. #define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
  144.  cache_ptr->addend =  ext_reloc.r_offset;
  145.  
  146.  
  147. #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
  148.  reloc_processing(relent, reloc, symbols, abfd, section)
  149.  
  150. static void
  151. DEFUN (reloc_processing, (relent, reloc, symbols, abfd, section),
  152.        arelent * relent AND
  153.        struct internal_reloc *reloc AND
  154.        asymbol ** symbols AND
  155.        bfd * abfd AND
  156.        asection * section)
  157. {
  158.   relent->address = reloc->r_vaddr;
  159.   rtype2howto (relent, reloc);
  160.  
  161.   if (((int) reloc->r_symndx) > 0)
  162.     {
  163.       relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
  164.     }
  165.   else
  166.     {
  167.       relent->sym_ptr_ptr = &(bfd_abs_symbol);
  168.     }
  169.  
  170.  
  171.  
  172.   relent->addend = reloc->r_offset;
  173.  
  174.   relent->address -= section->vma;
  175.   /*  relent->section = 0;*/
  176. }
  177.  
  178.  
  179. static int
  180. h8300_reloc16_estimate(input_section, symbols, reloc, shrink, link_info)
  181.      asection *input_section;
  182.      asymbol **symbols;
  183.      arelent *reloc;
  184.      unsigned int shrink;
  185.      struct bfd_link_info *link_info;
  186. {
  187.   bfd_vma value;  
  188.   bfd_vma dot;
  189.   bfd_vma gap;
  190.  
  191.   /* The address of the thing to be relocated will have moved back by 
  192.    the size of the shrink  - but we don't change reloc->address here,
  193.    since we need it to know where the relocation lives in the source
  194.    uncooked section */
  195.  
  196.   /*  reloc->address -= shrink;   conceptual */
  197.  
  198.   bfd_vma address = reloc->address - shrink;
  199.   
  200.  
  201.   switch (reloc->howto->type)
  202.     {     
  203.     case R_MOVB2:
  204.     case R_JMP2:
  205.       shrink+=2;
  206.       break;
  207.  
  208.       /* Thing is a move one byte */
  209.     case R_MOVB1:
  210.       value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
  211.  
  212.       if (value >= 0xff00)
  213.     { 
  214.  
  215.       /* Change the reloc type from 16bit, possible 8 to 8bit
  216.          possible 16 */
  217.       reloc->howto = reloc->howto + 1;      
  218.       /* The place to relc moves back by one */
  219.       /* This will be two bytes smaller in the long run */
  220.       shrink +=2 ;
  221.       bfd_perform_slip(symbols, 2, input_section, address);
  222.     }      
  223.  
  224.       break;
  225.       /* This is the 24 bit branch which could become an 8 bitter, 
  226.        the relocation points to the first byte of the insn, not the
  227.        actual data */
  228.  
  229.     case R_JMPL1:
  230.       value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
  231.     
  232.       dot = input_section->output_section->vma +
  233.     input_section->output_offset + address;
  234.   
  235.       /* See if the address we're looking at within 127 bytes of where
  236.      we are, if so then we can use a small branch rather than the
  237.      jump we were going to */
  238.  
  239.       gap = value - dot ;
  240.   
  241.       if (-120 < (long)gap && (long)gap < 120 )
  242.     { 
  243.  
  244.       /* Change the reloc type from 24bit, possible 8 to 8bit
  245.          possible 32 */
  246.       reloc->howto = reloc->howto + 1;      
  247.       /* This will be two bytes smaller in the long run */
  248.       shrink +=2 ;
  249.       bfd_perform_slip(symbols, 2, input_section, address);
  250.     }
  251.       break;
  252.  
  253.     case R_JMP1:
  254.  
  255.       value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
  256.     
  257.       dot = input_section->output_section->vma +
  258.     input_section->output_offset + address;
  259.   
  260.       /* See if the address we're looking at within 127 bytes of where
  261.      we are, if so then we can use a small branch rather than the
  262.      jump we were going to */
  263.  
  264.       gap = value - (dot - shrink);
  265.   
  266.  
  267.       if (-120 < (long)gap && (long)gap < 120 )
  268.     { 
  269.  
  270.       /* Change the reloc type from 16bit, possible 8 to 8bit
  271.          possible 16 */
  272.       reloc->howto = reloc->howto + 1;      
  273.       /* The place to relc moves back by one */
  274.  
  275.       /* This will be two bytes smaller in the long run */
  276.       shrink +=2 ;
  277.       bfd_perform_slip(symbols, 2, input_section, address);
  278.     }
  279.       break;
  280.     }
  281.  
  282.   
  283.   return shrink;
  284. }
  285.  
  286.  
  287. /* First phase of a relaxing link */
  288.  
  289. /* Reloc types
  290.    large        small
  291.    R_MOVB1        R_MOVB2        mov.b with 16bit or 8 bit address
  292.    R_JMP1        R_JMP2        jmp or pcrel branch
  293.    R_JMPL1        R_JMPL_B8    24jmp or pcrel branch
  294.    R_MOVLB1        R_MOVLB2    24 or 8 bit reloc for mov.b
  295.  
  296. */
  297.  
  298. static void
  299. h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
  300.                dst_ptr)
  301.      bfd *abfd;
  302.      struct bfd_link_info *link_info;
  303.      struct bfd_link_order *link_order;
  304.      arelent *reloc;
  305.      bfd_byte *data;
  306.      unsigned int *src_ptr;
  307.      unsigned int *dst_ptr;
  308. {
  309.   unsigned int src_address = *src_ptr;
  310.   unsigned int dst_address = *dst_ptr;
  311.   asection *input_section = link_order->u.indirect.section;
  312.  
  313.   switch (reloc->howto->type)
  314.     {
  315.       /* A 24 bit branch which could be a 8 bit pcrel, really pointing to
  316.      the byte before the 24bit hole, so we can treat it as a 32bit pointer */
  317.     case R_PCRBYTE:
  318.       {
  319.     bfd_vma dot = link_order->offset 
  320.       + dst_address 
  321.         + link_order->u.indirect.section->output_section->vma;
  322.     int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
  323.            - dot);
  324.     if (gap > 127 || gap < -128)
  325.       {
  326.         if (! ((*link_info->callbacks->reloc_overflow)
  327.            (link_info, input_section->owner, input_section,
  328.             reloc->address)))
  329.           abort ();
  330.       }
  331.  
  332.     bfd_put_8 (abfd, gap, data + dst_address);
  333.     dst_address++;
  334.     src_address++;
  335.  
  336.     break;
  337.       }
  338.  
  339.     case R_RELBYTE:
  340.       {
  341.     unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
  342.                                input_section);
  343.     if (gap > 0xff && gap < ~0xff)
  344.       {
  345.         if (! ((*link_info->callbacks->reloc_overflow)
  346.            (link_info, input_section->owner, input_section,
  347.             reloc->address)))
  348.           abort ();
  349.       }
  350.  
  351.     bfd_put_8 (abfd, gap, data + dst_address);
  352.     dst_address += 1;
  353.     src_address += 1;
  354.  
  355.  
  356.       }
  357.       break;
  358.     case R_JMP1:
  359.       /* A relword which would have like to have been a pcrel */
  360.     case R_MOVB1:
  361.       /* A relword which would like to have been modified but
  362.          didn't make it */
  363.     case R_RELWORD:
  364.       bfd_put_16 (abfd,
  365.           bfd_coff_reloc16_get_value (reloc, link_info, input_section),
  366.           data + dst_address);
  367.       dst_address += 2;
  368.       src_address += 2;
  369.       break;
  370.     case R_RELLONG:
  371.       bfd_put_32 (abfd,
  372.           bfd_coff_reloc16_get_value (reloc, link_info, input_section),
  373.           data + dst_address);
  374.       dst_address += 4;
  375.       src_address += 4;
  376.       break;
  377.  
  378.     case R_MOVB2:
  379.       /* Special relaxed type, there will be a gap between where we
  380.          get stuff from and where we put stuff to now
  381.     
  382.          for a mov.b @aa:16 -> mov.b @aa:8
  383.          opcode 0x6a 0x0y offset
  384.          ->     0x2y off
  385.          */
  386.       if (data[dst_address - 1] != 0x6a)
  387.     abort ();
  388.       switch (data[src_address] & 0xf0)
  389.     {
  390.     case 0x00:
  391.       /* Src is memory */
  392.       data[dst_address - 1] = (data[src_address] & 0xf) | 0x20;
  393.       break;
  394.     case 0x80:
  395.       /* Src is reg */
  396.       data[dst_address - 1] = (data[src_address] & 0xf) | 0x30;
  397.       break;
  398.     default:
  399.       abort ();
  400.     }
  401.  
  402.       /* the offset must fit ! after all, what was all the relaxing
  403.          about ? */
  404.  
  405.       bfd_put_8 (abfd,
  406.          bfd_coff_reloc16_get_value (reloc, link_info, input_section),
  407.          data + dst_address);
  408.  
  409.       /* Note the magic - src goes up by two bytes, but dst by only
  410.          one */
  411.       dst_address += 1;
  412.       src_address += 3;
  413.  
  414.       break;
  415.  
  416.     case R_JMP2:
  417.       
  418.       /* Speciial relaxed type */
  419.       {
  420.     bfd_vma dot = link_order->offset
  421.     + dst_address
  422.     + link_order->u.indirect.section->output_section->vma;
  423.  
  424.     int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
  425.            - dot - 1);
  426.  
  427.     if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00))
  428.       abort ();
  429.  
  430.     bfd_put_8 (abfd, gap, data + dst_address);
  431.  
  432.     switch (data[dst_address - 1])
  433.       {
  434.       case 0x5e:
  435.         /* jsr -> bsr */
  436.         bfd_put_8 (abfd, 0x55, data + dst_address - 1);
  437.         break;
  438.       case 0x5a:
  439.         /* jmp ->bra */
  440.         bfd_put_8 (abfd, 0x40, data + dst_address - 1);
  441.         break;
  442.  
  443.       default:
  444.         abort ();
  445.       }
  446.     dst_address++;
  447.     src_address += 3;
  448.  
  449.     break;
  450.       }
  451.       break;
  452.       
  453.     case R_JMPL_B8: /* 24 bit branch which is now 8 bits */
  454.       
  455.       /* Speciial relaxed type */
  456.       {
  457.     bfd_vma dot = link_order->offset
  458.     + dst_address
  459.     + link_order->u.indirect.section->output_section->vma;
  460.  
  461.     int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
  462.            - dot - 2);
  463.  
  464.     if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00))
  465.       abort ();
  466.  
  467.     switch (data[src_address])
  468.       {
  469.       case 0x5e:
  470.         /* jsr -> bsr */
  471.         bfd_put_8 (abfd, 0x55, data + dst_address);
  472.         break;
  473.       case 0x5a:
  474.         /* jmp ->bra */
  475.         bfd_put_8 (abfd, 0x40, data + dst_address);
  476.         break;
  477.  
  478.       default:
  479.         bfd_put_8 (abfd, 0xde, data + dst_address);
  480.         break;
  481.       }
  482.  
  483.     bfd_put_8 (abfd, gap, data + dst_address + 1);
  484.     dst_address += 2;
  485.     src_address += 4;
  486.  
  487.     break;
  488.       }
  489.  
  490.     case R_JMPL1:
  491.       {
  492.     int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
  493.     int o = bfd_get_32 (abfd, data + src_address);
  494.     v = (v & 0x00ffffff) | (o & 0xff000000);
  495.     bfd_put_32 (abfd, v, data + dst_address);
  496.     dst_address += 4;
  497.     src_address += 4;
  498.       }
  499.  
  500.       break;
  501.  
  502.  
  503.       /* A 24 bit mov  which could be an 8 bit move, really pointing to
  504.      the byte before the 24bit hole, so we can treat it as a 32bit pointer */
  505.     case R_MOVLB1:
  506.       {
  507.     int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
  508.     int o = bfd_get_32 (abfd, data + dst_address);
  509.     v = (v & 0x00ffffff) | (o & 0xff000000);
  510.     bfd_put_32 (abfd, v, data + dst_address);
  511.     dst_address += 4;
  512.     src_address += 4;
  513.       }
  514.  
  515.       break;
  516.     default:
  517.  
  518.       abort ();
  519.       break;
  520.  
  521.     }
  522.   *src_ptr = src_address;
  523.   *dst_ptr = dst_address;
  524.  
  525. }
  526.  
  527. #define coff_reloc16_extra_cases h8300_reloc16_extra_cases
  528. #define coff_reloc16_estimate h8300_reloc16_estimate
  529.  
  530. #include "coffcode.h"
  531.  
  532.  
  533. #undef coff_bfd_get_relocated_section_contents
  534. #undef coff_bfd_relax_section
  535. #define coff_bfd_get_relocated_section_contents \
  536.   bfd_coff_reloc16_get_relocated_section_contents
  537. #define coff_bfd_relax_section bfd_coff_reloc16_relax_section
  538.  
  539.  
  540.  
  541. bfd_target h8300coff_vec =
  542. {
  543.   "coff-h8300",            /* name */
  544.   bfd_target_coff_flavour,
  545.   true,                /* data byte order is big */
  546.   true,                /* header byte order is big */
  547.  
  548.   (HAS_RELOC | EXEC_P |        /* object flags */
  549.    HAS_LINENO | HAS_DEBUG |
  550.    HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
  551.   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),    /* section flags */
  552.   '_',                /* leading char */
  553.   '/',                /* ar_pad_char */
  554.   15,                /* ar_max_namelen */
  555.   1,                /* minimum section alignment */
  556.   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  557.   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  558.   bfd_getb16, bfd_getb_signed_16, bfd_putb16,    /* data */
  559.   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  560.   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  561.   bfd_getb16, bfd_getb_signed_16, bfd_putb16,    /* hdrs */
  562.  
  563.   {_bfd_dummy_target, coff_object_p,    /* bfd_check_format */
  564.    bfd_generic_archive_p, _bfd_dummy_target},
  565.   {bfd_false, coff_mkobject, _bfd_generic_mkarchive,    /* bfd_set_format */
  566.    bfd_false},
  567.   {bfd_false, coff_write_object_contents,    /* bfd_write_contents */
  568.    _bfd_write_archive_contents, bfd_false},
  569.  
  570.   JUMP_TABLE (coff),
  571.   COFF_SWAP_TABLE,
  572. };
  573.