home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / GDB / GDB-4.13 / GDB-4 / gdb-4.13 / bfd / coff-h8300.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-21  |  16.2 KB  |  606 lines

  1. /* BFD back-end for Hitachi H8/300 COFF binaries.
  2.    Copyright 1990, 1991, 1992, 1993, 1994 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, 2, 32, false, 0, complain_overflow_bitfield, 0, "24/pcrell", true, 0x00ffffff, 0x00ffffff, 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.r_type = 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. reloc_processing (relent, reloc, symbols, abfd, section)
  152.      arelent * relent;
  153.      struct internal_reloc *reloc;
  154.      asymbol ** symbols;
  155.      bfd * abfd;
  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_section_ptr->symbol_ptr_ptr;
  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(abfd, input_section, reloc, shrink, link_info)
  181.      bfd *abfd;
  182.      asection *input_section;
  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(abfd, 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(abfd, 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(abfd, 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, bfd_asymbol_name (*reloc->sym_ptr_ptr),
  328.             reloc->howto->name, reloc->addend, input_section->owner,
  329.             input_section, reloc->address)))
  330.           abort ();
  331.       }
  332.  
  333.     bfd_put_8 (abfd, gap, data + dst_address);
  334.     dst_address++;
  335.     src_address++;
  336.  
  337.     break;
  338.       }
  339.     case R_PCRWORD:
  340.       {
  341.     bfd_vma dot = link_order->offset 
  342.       + dst_address 
  343.         + link_order->u.indirect.section->output_section->vma;
  344.     int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
  345.            - dot) - 1;
  346.     if (gap > 32767 || gap < -32768)
  347.       {
  348.         if (! ((*link_info->callbacks->reloc_overflow)
  349.            (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
  350.             reloc->howto->name, reloc->addend, input_section->owner,
  351.             input_section, reloc->address)))
  352.           abort ();
  353.       }
  354.  
  355.     bfd_put_16 (abfd, gap, data + dst_address);
  356.     dst_address+=2;
  357.     src_address+=2;
  358.  
  359.     break;
  360.       }
  361.  
  362.     case R_RELBYTE:
  363.       {
  364.     unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
  365.                                input_section);
  366.     if (gap > 0xff && gap < ~0xff)
  367.       {
  368.         if (! ((*link_info->callbacks->reloc_overflow)
  369.            (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
  370.             reloc->howto->name, reloc->addend, input_section->owner,
  371.             input_section, reloc->address)))
  372.           abort ();
  373.       }
  374.  
  375.     bfd_put_8 (abfd, gap, data + dst_address);
  376.     dst_address += 1;
  377.     src_address += 1;
  378.  
  379.  
  380.       }
  381.       break;
  382.     case R_JMP1:
  383.       /* A relword which would have like to have been a pcrel */
  384.     case R_MOVB1:
  385.       /* A relword which would like to have been modified but
  386.          didn't make it */
  387.     case R_RELWORD:
  388.       bfd_put_16 (abfd,
  389.           bfd_coff_reloc16_get_value (reloc, link_info, input_section),
  390.           data + dst_address);
  391.       dst_address += 2;
  392.       src_address += 2;
  393.       break;
  394.     case R_RELLONG:
  395.       bfd_put_32 (abfd,
  396.           bfd_coff_reloc16_get_value (reloc, link_info, input_section),
  397.           data + dst_address);
  398.       dst_address += 4;
  399.       src_address += 4;
  400.       break;
  401.  
  402.     case R_MOVB2:
  403.       /* Special relaxed type, there will be a gap between where we
  404.          get stuff from and where we put stuff to now
  405.     
  406.          for a mov.b @aa:16 -> mov.b @aa:8
  407.          opcode 0x6a 0x0y offset
  408.          ->     0x2y off
  409.          */
  410.       if (data[dst_address - 1] != 0x6a)
  411.     abort ();
  412.       switch (data[src_address] & 0xf0)
  413.     {
  414.     case 0x00:
  415.       /* Src is memory */
  416.       data[dst_address - 1] = (data[src_address] & 0xf) | 0x20;
  417.       break;
  418.     case 0x80:
  419.       /* Src is reg */
  420.       data[dst_address - 1] = (data[src_address] & 0xf) | 0x30;
  421.       break;
  422.     default:
  423.       abort ();
  424.     }
  425.  
  426.       /* the offset must fit ! after all, what was all the relaxing
  427.          about ? */
  428.  
  429.       bfd_put_8 (abfd,
  430.          bfd_coff_reloc16_get_value (reloc, link_info, input_section),
  431.          data + dst_address);
  432.  
  433.       /* Note the magic - src goes up by two bytes, but dst by only
  434.          one */
  435.       dst_address += 1;
  436.       src_address += 3;
  437.  
  438.       break;
  439.  
  440.     case R_JMP2:
  441.       
  442.       /* Speciial relaxed type */
  443.       {
  444.     bfd_vma dot = link_order->offset
  445.     + dst_address
  446.     + link_order->u.indirect.section->output_section->vma;
  447.  
  448.     int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
  449.            - dot - 1);
  450.  
  451.     if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00))
  452.       abort ();
  453.  
  454.     bfd_put_8 (abfd, gap, data + dst_address);
  455.  
  456.     switch (data[dst_address - 1])
  457.       {
  458.       case 0x5e:
  459.         /* jsr -> bsr */
  460.         bfd_put_8 (abfd, 0x55, data + dst_address - 1);
  461.         break;
  462.       case 0x5a:
  463.         /* jmp ->bra */
  464.         bfd_put_8 (abfd, 0x40, data + dst_address - 1);
  465.         break;
  466.  
  467.       default:
  468.         abort ();
  469.       }
  470.     dst_address++;
  471.     src_address += 3;
  472.  
  473.     break;
  474.       }
  475.       break;
  476.       
  477.     case R_JMPL_B8: /* 24 bit branch which is now 8 bits */
  478.       
  479.       /* Speciial relaxed type */
  480.       {
  481.     bfd_vma dot = link_order->offset
  482.     + dst_address
  483.     + link_order->u.indirect.section->output_section->vma;
  484.  
  485.     int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
  486.            - dot - 2);
  487.  
  488.     if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00))
  489.       abort ();
  490.  
  491.     switch (data[src_address])
  492.       {
  493.       case 0x5e:
  494.         /* jsr -> bsr */
  495.         bfd_put_8 (abfd, 0x55, data + dst_address);
  496.         break;
  497.       case 0x5a:
  498.         /* jmp ->bra */
  499.         bfd_put_8 (abfd, 0x40, data + dst_address);
  500.         break;
  501.  
  502.       default:
  503.         bfd_put_8 (abfd, 0xde, data + dst_address);
  504.         break;
  505.       }
  506.  
  507.     bfd_put_8 (abfd, gap, data + dst_address + 1);
  508.     dst_address += 2;
  509.     src_address += 4;
  510.  
  511.     break;
  512.       }
  513.  
  514.     case R_JMPL1:
  515.       {
  516.     int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
  517.     int o = bfd_get_32 (abfd, data + src_address);
  518.     v = (v & 0x00ffffff) | (o & 0xff000000);
  519.     bfd_put_32 (abfd, v, data + dst_address);
  520.     dst_address += 4;
  521.     src_address += 4;
  522.       }
  523.  
  524.       break;
  525.  
  526.  
  527.       /* A 24 bit mov  which could be an 8 bit move, really pointing to
  528.      the byte before the 24bit hole, so we can treat it as a 32bit pointer */
  529.     case R_MOVLB1:
  530.       {
  531.     int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
  532.     int o = bfd_get_32 (abfd, data + dst_address);
  533.     v = (v & 0x00ffffff) | (o & 0xff000000);
  534.     bfd_put_32 (abfd, v, data + dst_address);
  535.     dst_address += 4;
  536.     src_address += 4;
  537.       }
  538.  
  539.       break;
  540.     default:
  541.  
  542.       abort ();
  543.       break;
  544.  
  545.     }
  546.   *src_ptr = src_address;
  547.   *dst_ptr = dst_address;
  548.  
  549. }
  550.  
  551. #define coff_reloc16_extra_cases h8300_reloc16_extra_cases
  552. #define coff_reloc16_estimate h8300_reloc16_estimate
  553.  
  554. #include "coffcode.h"
  555.  
  556.  
  557. #undef coff_bfd_get_relocated_section_contents
  558. #undef coff_bfd_relax_section
  559. #define coff_bfd_get_relocated_section_contents \
  560.   bfd_coff_reloc16_get_relocated_section_contents
  561. #define coff_bfd_relax_section bfd_coff_reloc16_relax_section
  562.  
  563.  
  564.  
  565. const bfd_target h8300coff_vec =
  566. {
  567.   "coff-h8300",            /* name */
  568.   bfd_target_coff_flavour,
  569.   true,                /* data byte order is big */
  570.   true,                /* header byte order is big */
  571.  
  572.   (HAS_RELOC | EXEC_P |        /* object flags */
  573.    HAS_LINENO | HAS_DEBUG |
  574.    HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
  575.   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),    /* section flags */
  576.   '_',                /* leading char */
  577.   '/',                /* ar_pad_char */
  578.   15,                /* ar_max_namelen */
  579.   1,                /* minimum section alignment */
  580.   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  581.   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  582.   bfd_getb16, bfd_getb_signed_16, bfd_putb16,    /* data */
  583.   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  584.   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  585.   bfd_getb16, bfd_getb_signed_16, bfd_putb16,    /* hdrs */
  586.  
  587.   {_bfd_dummy_target, coff_object_p,    /* bfd_check_format */
  588.    bfd_generic_archive_p, _bfd_dummy_target},
  589.   {bfd_false, coff_mkobject, _bfd_generic_mkarchive,    /* bfd_set_format */
  590.    bfd_false},
  591.   {bfd_false, coff_write_object_contents,    /* bfd_write_contents */
  592.    _bfd_write_archive_contents, bfd_false},
  593.  
  594.      BFD_JUMP_TABLE_GENERIC (coff),
  595.      BFD_JUMP_TABLE_COPY (coff),
  596.      BFD_JUMP_TABLE_CORE (_bfd_nocore),
  597.      BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
  598.      BFD_JUMP_TABLE_SYMBOLS (coff),
  599.      BFD_JUMP_TABLE_RELOCS (coff),
  600.      BFD_JUMP_TABLE_WRITE (coff),
  601.      BFD_JUMP_TABLE_LINK (coff),
  602.      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
  603.  
  604.   COFF_SWAP_TABLE,
  605. };
  606.