Back to index

cell-binutils  2.17cvs20070401
vms-tir.c
Go to the documentation of this file.
00001 /* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
00002    EVAX (openVMS/Alpha) files.
00003    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005
00004    Free Software Foundation, Inc.
00005 
00006    TIR record handling functions
00007    ETIR record handling functions
00008 
00009    go and read the openVMS linker manual (esp. appendix B)
00010    if you don't know what's going on here :-)
00011 
00012    Written by Klaus K"ampf (kkaempf@rmi.de)
00013 
00014    This program is free software; you can redistribute it and/or modify
00015    it under the terms of the GNU General Public License as published by
00016    the Free Software Foundation; either version 2 of the License, or
00017    (at your option) any later version.
00018 
00019    This program is distributed in the hope that it will be useful,
00020    but WITHOUT ANY WARRANTY; without even the implied warranty of
00021    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022    GNU General Public License for more details.
00023 
00024    You should have received a copy of the GNU General Public License
00025    along with this program; if not, write to the Free Software
00026    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00027 
00028 /* The following type abbreviations are used:
00029 
00030        cs     counted string (ascii string with length byte)
00031        by     byte (1 byte)
00032        sh     short (2 byte, 16 bit)
00033        lw     longword (4 byte, 32 bit)
00034        qw     quadword (8 byte, 64 bit)
00035        da     data stream  */
00036 
00037 #include "bfd.h"
00038 #include "sysdep.h"
00039 #include "bfdlink.h"
00040 #include "libbfd.h"
00041 #include "vms.h"
00042 
00043 static int
00044 check_section (bfd * abfd, int size)
00045 {
00046   bfd_size_type offset;
00047 
00048   offset = PRIV (image_ptr) - PRIV (image_section)->contents;
00049   if (offset + size > PRIV (image_section)->size)
00050     {
00051       PRIV (image_section)->contents
00052        = bfd_realloc (PRIV (image_section)->contents, offset + size);
00053       if (PRIV (image_section)->contents == 0)
00054        {
00055          (*_bfd_error_handler) (_("No Mem !"));
00056          return -1;
00057        }
00058       PRIV (image_section)->size = offset + size;
00059       PRIV (image_ptr) = PRIV (image_section)->contents + offset;
00060     }
00061 
00062   return 0;
00063 }
00064 
00065 /* Routines to fill sections contents during tir/etir read.  */
00066 
00067 /* Initialize image buffer pointer to be filled.  */
00068 
00069 static void
00070 image_set_ptr (bfd * abfd, int psect, uquad offset)
00071 {
00072 #if VMS_DEBUG
00073   _bfd_vms_debug (4, "image_set_ptr (%d=%s, %d)\n",
00074                 psect, PRIV (sections)[psect]->name, offset);
00075 #endif
00076 
00077   PRIV (image_ptr) = PRIV (sections)[psect]->contents + offset;
00078   PRIV (image_section) = PRIV (sections)[psect];
00079 }
00080 
00081 /* Increment image buffer pointer by offset.  */
00082 
00083 static void
00084 image_inc_ptr (bfd * abfd, uquad offset)
00085 {
00086 #if VMS_DEBUG
00087   _bfd_vms_debug (4, "image_inc_ptr (%d)\n", offset);
00088 #endif
00089 
00090   PRIV (image_ptr) += offset;
00091 }
00092 
00093 /* Dump multiple bytes to section image.  */
00094 
00095 static void
00096 image_dump (bfd * abfd,
00097            unsigned char *ptr,
00098            int size,
00099            int offset ATTRIBUTE_UNUSED)
00100 {
00101 #if VMS_DEBUG
00102   _bfd_vms_debug (8, "image_dump from (%p, %d) to (%p)\n", ptr, size,
00103                 PRIV (image_ptr));
00104   _bfd_hexdump (9, ptr, size, offset);
00105 #endif
00106 
00107   if (PRIV (is_vax) && check_section (abfd, size))
00108     return;
00109 
00110   while (size-- > 0)
00111     *PRIV (image_ptr)++ = *ptr++;
00112 }
00113 
00114 /* Write byte to section image.  */
00115 
00116 static void
00117 image_write_b (bfd * abfd, unsigned int value)
00118 {
00119 #if VMS_DEBUG
00120   _bfd_vms_debug (6, "image_write_b (%02x)\n", (int) value);
00121 #endif
00122 
00123   if (PRIV (is_vax) && check_section (abfd, 1))
00124     return;
00125 
00126   *PRIV (image_ptr)++ = (value & 0xff);
00127 }
00128 
00129 /* Write 2-byte word to image.  */
00130 
00131 static void
00132 image_write_w (bfd * abfd, unsigned int value)
00133 {
00134 #if VMS_DEBUG
00135   _bfd_vms_debug (6, "image_write_w (%04x)\n", (int) value);
00136 #endif
00137 
00138   if (PRIV (is_vax) && check_section (abfd, 2))
00139     return;
00140 
00141   bfd_putl16 ((bfd_vma) value, PRIV (image_ptr));
00142   PRIV (image_ptr) += 2;
00143 }
00144 
00145 /* Write 4-byte long to image.  */
00146 
00147 static void
00148 image_write_l (bfd * abfd, unsigned long value)
00149 {
00150 #if VMS_DEBUG
00151   _bfd_vms_debug (6, "image_write_l (%08lx)\n", value);
00152 #endif
00153 
00154   if (PRIV (is_vax) && check_section (abfd, 4))
00155     return;
00156 
00157   bfd_putl32 ((bfd_vma) value, PRIV (image_ptr));
00158   PRIV (image_ptr) += 4;
00159 }
00160 
00161 /* Write 8-byte quad to image.  */
00162 
00163 static void
00164 image_write_q (bfd * abfd, uquad value)
00165 {
00166 #if VMS_DEBUG
00167   _bfd_vms_debug (6, "image_write_q (%016lx)\n", value);
00168 #endif
00169 
00170   if (PRIV (is_vax) && check_section (abfd, 8))
00171     return;
00172 
00173   bfd_putl64 (value, PRIV (image_ptr));
00174   PRIV (image_ptr) += 8;
00175 }
00176 
00177 static const char *
00178 cmd_name (int cmd)
00179 {
00180   switch (cmd)
00181     {
00182     case ETIR_S_C_STA_GBL: return "ETIR_S_C_STA_GBL";
00183     case ETIR_S_C_STA_PQ: return "ETIR_S_C_STA_PQ";
00184     case ETIR_S_C_STA_LI: return "ETIR_S_C_STA_LI";
00185     case ETIR_S_C_STA_MOD: return "ETIR_S_C_STA_MOD";
00186     case ETIR_S_C_STA_CKARG: return "ETIR_S_C_STA_CKARG";
00187     case ETIR_S_C_STO_B: return "ETIR_S_C_STO_B";
00188     case ETIR_S_C_STO_W: return "ETIR_S_C_STO_W";
00189     case ETIR_S_C_STO_GBL: return "ETIR_S_C_STO_GBL";
00190     case ETIR_S_C_STO_CA: return "ETIR_S_C_STO_CA";
00191     case ETIR_S_C_STO_RB: return "ETIR_S_C_STO_RB";
00192     case ETIR_S_C_STO_AB: return "ETIR_S_C_STO_AB";
00193     case ETIR_S_C_STO_GBL_LW: return "ETIR_S_C_STO_GBL_LW";
00194     case ETIR_S_C_STO_LP_PSB: return "ETIR_S_C_STO_LP_PSB";
00195     case ETIR_S_C_STO_HINT_GBL: return "ETIR_S_C_STO_HINT_GBL";
00196     case ETIR_S_C_STO_HINT_PS: return "ETIR_S_C_STO_HINT_PS";
00197     case ETIR_S_C_OPR_INSV: return "ETIR_S_C_OPR_INSV";
00198     case ETIR_S_C_OPR_USH: return "ETIR_S_C_OPR_USH";
00199     case ETIR_S_C_OPR_ROT: return "ETIR_S_C_OPR_ROT";
00200     case ETIR_S_C_OPR_REDEF: return "ETIR_S_C_OPR_REDEF";
00201     case ETIR_S_C_OPR_DFLIT: return "ETIR_S_C_OPR_DFLIT";
00202     case ETIR_S_C_STC_LP: return "ETIR_S_C_STC_LP";
00203     case ETIR_S_C_STC_GBL: return "ETIR_S_C_STC_GBL";
00204     case ETIR_S_C_STC_GCA: return "ETIR_S_C_STC_GCA";
00205     case ETIR_S_C_STC_PS: return "ETIR_S_C_STC_PS";
00206     case ETIR_S_C_STC_NBH_PS: return "ETIR_S_C_STC_NBH_PS";
00207     case ETIR_S_C_STC_NOP_GBL: return "ETIR_S_C_STC_NOP_GBL";
00208     case ETIR_S_C_STC_NOP_PS: return "ETIR_S_C_STC_NOP_PS";
00209     case ETIR_S_C_STC_BSR_GBL: return "ETIR_S_C_STC_BSR_GBL";
00210     case ETIR_S_C_STC_BSR_PS: return "ETIR_S_C_STC_BSR_PS";
00211     case ETIR_S_C_STC_LDA_GBL: return "ETIR_S_C_STC_LDA_GBL";
00212     case ETIR_S_C_STC_LDA_PS: return "ETIR_S_C_STC_LDA_PS";
00213     case ETIR_S_C_STC_BOH_GBL: return "ETIR_S_C_STC_BOH_GBL";
00214     case ETIR_S_C_STC_BOH_PS: return "ETIR_S_C_STC_BOH_PS";
00215     case ETIR_S_C_STC_NBH_GBL: return "ETIR_S_C_STC_NBH_GBL";
00216 
00217     default:
00218       /* These names have not yet been added to this switch statement.  */
00219       abort ();
00220     }
00221 }
00222 #define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
00223 
00224 /* etir_sta
00225 
00226    vms stack commands
00227 
00228    handle sta_xxx commands in etir section
00229    ptr points to data area in record
00230 
00231    see table B-8 of the openVMS linker manual.  */
00232 
00233 static bfd_boolean
00234 etir_sta (bfd * abfd, int cmd, unsigned char *ptr)
00235 {
00236 #if VMS_DEBUG
00237   _bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd);
00238   _bfd_hexdump (8, ptr, 16, (int) ptr);
00239 #endif
00240 
00241   switch (cmd)
00242     {
00243       /* stack global
00244         arg: cs      symbol name
00245 
00246         stack 32 bit value of symbol (high bits set to 0).  */
00247     case ETIR_S_C_STA_GBL:
00248       {
00249        char *name;
00250        vms_symbol_entry *entry;
00251 
00252        name = _bfd_vms_save_counted_string (ptr);
00253        entry = (vms_symbol_entry *)
00254          bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
00255        if (entry == NULL)
00256          {
00257 #if VMS_DEBUG
00258            _bfd_vms_debug (3, "%s: no symbol \"%s\"\n",
00259                          cmd_name (cmd), name);
00260 #endif
00261            _bfd_vms_push (abfd, (uquad) 0, -1);
00262          }
00263        else
00264          _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
00265       }
00266       break;
00267 
00268       /* stack longword
00269         arg: lw      value
00270 
00271         stack 32 bit value, sign extend to 64 bit.  */
00272     case ETIR_S_C_STA_LW:
00273       _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
00274       break;
00275 
00276       /* stack global
00277         arg: qw      value
00278 
00279         stack 64 bit value of symbol.  */
00280     case ETIR_S_C_STA_QW:
00281       _bfd_vms_push (abfd, (uquad) bfd_getl64 (ptr), -1);
00282       break;
00283 
00284       /* stack psect base plus quadword offset
00285         arg: lw      section index
00286         qw    signed quadword offset (low 32 bits)
00287 
00288         stack qw argument and section index
00289         (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB).  */
00290     case ETIR_S_C_STA_PQ:
00291       {
00292        uquad dummy;
00293        unsigned int psect;
00294 
00295        psect = bfd_getl32 (ptr);
00296        if (psect >= PRIV (section_count))
00297          {
00298            (*_bfd_error_handler) (_("bad section index in %s"),
00299                                cmd_name (cmd));
00300            bfd_set_error (bfd_error_bad_value);
00301            return FALSE;
00302          }
00303        dummy = bfd_getl64 (ptr + 4);
00304        _bfd_vms_push (abfd, dummy, (int) psect);
00305       }
00306       break;
00307 
00308     case ETIR_S_C_STA_LI:
00309     case ETIR_S_C_STA_MOD:
00310     case ETIR_S_C_STA_CKARG:
00311       (*_bfd_error_handler) (_("unsupported STA cmd %s"), cmd_name (cmd));
00312       return FALSE;
00313       break;
00314 
00315     default:
00316       (*_bfd_error_handler) (_("reserved STA cmd %d"), cmd);
00317       return FALSE;
00318       break;
00319     }
00320 #if VMS_DEBUG
00321   _bfd_vms_debug (5, "etir_sta true\n");
00322 #endif
00323   return TRUE;
00324 }
00325 
00326 /* etir_sto
00327 
00328    vms store commands
00329 
00330    handle sto_xxx commands in etir section
00331    ptr points to data area in record
00332 
00333    see table B-9 of the openVMS linker manual.  */
00334 
00335 static bfd_boolean
00336 etir_sto (bfd * abfd, int cmd, unsigned char *ptr)
00337 {
00338   uquad dummy;
00339   int psect;
00340 
00341 #if VMS_DEBUG
00342   _bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd);
00343   _bfd_hexdump (8, ptr, 16, (int) ptr);
00344 #endif
00345 
00346   switch (cmd)
00347     {
00348       /* Store byte: pop stack, write byte
00349         arg: -.  */
00350     case ETIR_S_C_STO_B:
00351       dummy = _bfd_vms_pop (abfd, &psect);
00352       /* FIXME: check top bits.  */
00353       image_write_b (abfd, (unsigned int) dummy & 0xff);
00354       break;
00355 
00356       /* Store word: pop stack, write word
00357         arg: -.  */
00358     case ETIR_S_C_STO_W:
00359       dummy = _bfd_vms_pop (abfd, &psect);
00360       /* FIXME: check top bits */
00361       image_write_w (abfd, (unsigned int) dummy & 0xffff);
00362       break;
00363 
00364       /* Store longword: pop stack, write longword
00365         arg: -.  */
00366     case ETIR_S_C_STO_LW:
00367       dummy = _bfd_vms_pop (abfd, &psect);
00368       dummy += (PRIV (sections)[psect])->vma;
00369       /* FIXME: check top bits.  */
00370       image_write_l (abfd, (unsigned int) dummy & 0xffffffff);
00371       break;
00372 
00373       /* Store quadword: pop stack, write quadword
00374         arg: -.  */
00375     case ETIR_S_C_STO_QW:
00376       dummy = _bfd_vms_pop (abfd, &psect);
00377       dummy += (PRIV (sections)[psect])->vma;
00378       /* FIXME: check top bits.  */
00379       image_write_q (abfd, dummy);
00380       break;
00381 
00382       /* Store immediate repeated: pop stack for repeat count
00383         arg: lw      byte count
00384         da    data.  */
00385     case ETIR_S_C_STO_IMMR:
00386       {
00387        int size;
00388 
00389        size = bfd_getl32 (ptr);
00390        dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
00391        while (dummy-- > 0)
00392          image_dump (abfd, ptr+4, size, 0);
00393       }
00394       break;
00395 
00396       /* Store global: write symbol value
00397         arg: cs      global symbol name.  */
00398     case ETIR_S_C_STO_GBL:
00399       {
00400        vms_symbol_entry *entry;
00401        char *name;
00402 
00403        name = _bfd_vms_save_counted_string (ptr);
00404        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
00405                                                 name, FALSE, FALSE);
00406        if (entry == NULL)
00407          {
00408            (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
00409                                cmd_name (cmd), name);
00410            return FALSE;
00411          }
00412        else
00413          /* FIXME, reloc.  */
00414          image_write_q (abfd, (uquad) (entry->symbol->value));
00415       }
00416       break;
00417 
00418       /* Store code address: write address of entry point
00419         arg: cs      global symbol name (procedure).  */
00420     case ETIR_S_C_STO_CA:
00421       {
00422        vms_symbol_entry *entry;
00423        char *name;
00424 
00425        name = _bfd_vms_save_counted_string (ptr);
00426        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
00427                                                 name, FALSE, FALSE);
00428        if (entry == NULL)
00429          {
00430            (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
00431                                cmd_name (cmd), name);
00432            return FALSE;
00433          }
00434        else
00435          /* FIXME, reloc.  */
00436          image_write_q (abfd, (uquad) (entry->symbol->value));
00437       }
00438       break;
00439 
00440       /* Store offset to psect: pop stack, add low 32 bits to base of psect
00441         arg: none.  */
00442     case ETIR_S_C_STO_OFF:
00443       {
00444        uquad q;
00445        int psect1;
00446 
00447        q = _bfd_vms_pop (abfd, & psect1);
00448        q += (PRIV (sections)[psect1])->vma;
00449        image_write_q (abfd, q);
00450       }
00451       break;
00452 
00453       /* Store immediate
00454         arg: lw      count of bytes
00455              da      data.  */
00456     case ETIR_S_C_STO_IMM:
00457       {
00458        int size;
00459 
00460        size = bfd_getl32 (ptr);
00461        image_dump (abfd, ptr+4, size, 0);
00462       }
00463       break;
00464 
00465       /* This code is 'reserved to digital' according to the openVMS
00466         linker manual, however it is generated by the DEC C compiler
00467         and defined in the include file.
00468         FIXME, since the following is just a guess
00469         store global longword: store 32bit value of symbol
00470         arg: cs      symbol name.  */
00471     case ETIR_S_C_STO_GBL_LW:
00472       {
00473        vms_symbol_entry *entry;
00474        char *name;
00475 
00476        name = _bfd_vms_save_counted_string (ptr);
00477        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
00478                                                 name, FALSE, FALSE);
00479        if (entry == NULL)
00480          {
00481 #if VMS_DEBUG
00482            _bfd_vms_debug (3, "%s: no symbol \"%s\"\n", cmd_name (cmd), name);
00483 #endif
00484            image_write_l (abfd, (unsigned long) 0);     /* FIXME, reloc */
00485          }
00486        else
00487          /* FIXME, reloc.  */
00488          image_write_l (abfd, (unsigned long) (entry->symbol->value));
00489       }
00490       break;
00491 
00492     case ETIR_S_C_STO_RB:
00493     case ETIR_S_C_STO_AB:
00494     case ETIR_S_C_STO_LP_PSB:
00495       (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
00496       break;
00497 
00498     case ETIR_S_C_STO_HINT_GBL:
00499     case ETIR_S_C_STO_HINT_PS:
00500       (*_bfd_error_handler) (_("%s: not implemented"), cmd_name (cmd));
00501       break;
00502 
00503     default:
00504       (*_bfd_error_handler) (_("reserved STO cmd %d"), cmd);
00505       break;
00506     }
00507 
00508   return TRUE;
00509 }
00510 
00511 /* Stack operator commands
00512    all 32 bit signed arithmetic
00513    all word just like a stack calculator
00514    arguments are popped from stack, results are pushed on stack
00515 
00516    see table B-10 of the openVMS linker manual.  */
00517 
00518 static bfd_boolean
00519 etir_opr (bfd * abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED)
00520 {
00521   long op1, op2;
00522 
00523 #if VMS_DEBUG
00524   _bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd);
00525   _bfd_hexdump (8, ptr, 16, (int) ptr);
00526 #endif
00527 
00528   switch (cmd)
00529     {
00530     case ETIR_S_C_OPR_NOP:      /* No-op.  */
00531       break;
00532 
00533     case ETIR_S_C_OPR_ADD:      /* Add.  */
00534       op1 = (long) _bfd_vms_pop (abfd, NULL);
00535       op2 = (long) _bfd_vms_pop (abfd, NULL);
00536       _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
00537       break;
00538 
00539     case ETIR_S_C_OPR_SUB:      /* Subtract.  */
00540       op1 = (long) _bfd_vms_pop (abfd, NULL);
00541       op2 = (long) _bfd_vms_pop (abfd, NULL);
00542       _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
00543       break;
00544 
00545     case ETIR_S_C_OPR_MUL:      /* Multiply.  */
00546       op1 = (long) _bfd_vms_pop (abfd, NULL);
00547       op2 = (long) _bfd_vms_pop (abfd, NULL);
00548       _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
00549       break;
00550 
00551     case ETIR_S_C_OPR_DIV:      /* Divide.  */
00552       op1 = (long) _bfd_vms_pop (abfd, NULL);
00553       op2 = (long) _bfd_vms_pop (abfd, NULL);
00554       if (op2 == 0)
00555        _bfd_vms_push (abfd, (uquad) 0, -1);
00556       else
00557        _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
00558       break;
00559 
00560     case ETIR_S_C_OPR_AND:      /* Logical AND.  */
00561       op1 = (long) _bfd_vms_pop (abfd, NULL);
00562       op2 = (long) _bfd_vms_pop (abfd, NULL);
00563       _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
00564       break;
00565 
00566     case ETIR_S_C_OPR_IOR:      /* Logical inclusive OR.  */
00567       op1 = (long) _bfd_vms_pop (abfd, NULL);
00568       op2 = (long) _bfd_vms_pop (abfd, NULL);
00569       _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
00570       break;
00571 
00572     case ETIR_S_C_OPR_EOR:      /* Logical exclusive OR.  */
00573       op1 = (long) _bfd_vms_pop (abfd, NULL);
00574       op2 = (long) _bfd_vms_pop (abfd, NULL);
00575       _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
00576       break;
00577 
00578     case ETIR_S_C_OPR_NEG:      /* Negate.  */
00579       op1 = (long) _bfd_vms_pop (abfd, NULL);
00580       _bfd_vms_push (abfd, (uquad) (-op1), -1);
00581       break;
00582 
00583     case ETIR_S_C_OPR_COM:      /* Complement.  */
00584       op1 = (long) _bfd_vms_pop (abfd, NULL);
00585       _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
00586       break;
00587 
00588     case ETIR_S_C_OPR_ASH:      /* Arithmetic shift.  */
00589       op1 = (long) _bfd_vms_pop (abfd, NULL);
00590       op2 = (long) _bfd_vms_pop (abfd, NULL);
00591       if (op2 < 0)          /* Shift right.  */
00592        op1 >>= -op2;
00593       else                  /* Shift left.  */
00594        op1 <<= op2;
00595       _bfd_vms_push (abfd, (uquad) op1, -1);
00596       break;
00597 
00598     case ETIR_S_C_OPR_INSV:      /* Insert field.   */
00599       (void) _bfd_vms_pop (abfd, NULL);
00600     case ETIR_S_C_OPR_USH:       /* Unsigned shift.   */
00601     case ETIR_S_C_OPR_ROT:       /* Rotate.  */
00602     case ETIR_S_C_OPR_REDEF:     /* Redefine symbol to current location.  */
00603     case ETIR_S_C_OPR_DFLIT:     /* Define a literal.  */
00604       (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
00605       break;
00606 
00607     case ETIR_S_C_OPR_SEL:      /* Select.  */
00608       if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
00609        (void) _bfd_vms_pop (abfd, NULL);
00610       else
00611        {
00612          op1 = (long) _bfd_vms_pop (abfd, NULL);
00613          (void) _bfd_vms_pop (abfd, NULL);
00614          _bfd_vms_push (abfd, (uquad) op1, -1);
00615        }
00616       break;
00617 
00618     default:
00619       (*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd);
00620       break;
00621     }
00622 
00623   return TRUE;
00624 }
00625 
00626 /* Control commands.
00627 
00628    See table B-11 of the openVMS linker manual.  */
00629 
00630 static bfd_boolean
00631 etir_ctl (bfd * abfd, int cmd, unsigned char *ptr)
00632 {
00633   uquad        dummy;
00634   int psect;
00635 
00636 #if VMS_DEBUG
00637   _bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd);
00638   _bfd_hexdump (8, ptr, 16, (int) ptr);
00639 #endif
00640 
00641   switch (cmd)
00642     {
00643       /* Det relocation base: pop stack, set image location counter
00644         arg: none.  */
00645     case ETIR_S_C_CTL_SETRB:
00646       dummy = _bfd_vms_pop (abfd, &psect);
00647       image_set_ptr (abfd, psect, dummy);
00648       break;
00649 
00650       /* Augment relocation base: increment image location counter by offset
00651         arg: lw      offset value.  */
00652     case ETIR_S_C_CTL_AUGRB:
00653       dummy = bfd_getl32 (ptr);
00654       image_inc_ptr (abfd, dummy);
00655       break;
00656 
00657       /* Define location: pop index, save location counter under index
00658         arg: none.  */
00659     case ETIR_S_C_CTL_DFLOC:
00660       dummy = _bfd_vms_pop (abfd, NULL);
00661       /* FIXME */
00662       break;
00663 
00664       /* Set location: pop index, restore location counter from index
00665         arg: none.  */
00666     case ETIR_S_C_CTL_STLOC:
00667       dummy = _bfd_vms_pop (abfd, &psect);
00668       /* FIXME */
00669       break;
00670 
00671       /* Stack defined location: pop index, push location counter from index
00672         arg: none.  */
00673     case ETIR_S_C_CTL_STKDL:
00674       dummy = _bfd_vms_pop (abfd, &psect);
00675       /* FIXME.  */
00676       break;
00677 
00678     default:
00679       (*_bfd_error_handler) (_("reserved CTL cmd %d"), cmd);
00680       break;
00681     }
00682   return TRUE;
00683 }
00684 
00685 /* Store conditional commands
00686 
00687    See table B-12 and B-13 of the openVMS linker manual.  */
00688 
00689 static bfd_boolean
00690 etir_stc (bfd * abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED)
00691 {
00692 #if VMS_DEBUG
00693   _bfd_vms_debug (5, "etir_stc %d/%x\n", cmd, cmd);
00694   _bfd_hexdump (8, ptr, 16, (int) ptr);
00695 #endif
00696 
00697   switch (cmd)
00698     {
00699       /* 200 Store-conditional Linkage Pair
00700         arg: none.  */
00701     case ETIR_S_C_STC_LP:
00702       (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
00703       break;
00704 
00705       /* 201 Store-conditional Linkage Pair with Procedure Signature
00706         arg:  lw     linkage index
00707               cs     procedure name
00708               by     signature length
00709               da     signature.  */
00710     case ETIR_S_C_STC_LP_PSB:
00711       image_inc_ptr (abfd, (uquad) 16);   /* skip entry,procval */
00712       break;
00713 
00714       /* 202 Store-conditional Address at global address
00715         arg:  lw     linkage index
00716               cs     global name.  */
00717 
00718     case ETIR_S_C_STC_GBL:
00719       (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
00720       break;
00721 
00722       /* 203 Store-conditional Code Address at global address
00723         arg:  lw     linkage index
00724               cs     procedure name.  */
00725     case ETIR_S_C_STC_GCA:
00726       (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
00727       break;
00728 
00729       /* 204 Store-conditional Address at psect + offset
00730         arg:  lw     linkage index
00731               lw     psect index
00732               qw     offset.  */
00733     case ETIR_S_C_STC_PS:
00734       (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
00735       break;
00736 
00737       /* 205 Store-conditional NOP at address of global
00738         arg: none.  */
00739     case ETIR_S_C_STC_NOP_GBL:
00740 
00741       /* 206 Store-conditional NOP at pect + offset
00742         arg: none.  */
00743     case ETIR_S_C_STC_NOP_PS:
00744 
00745       /* 207 Store-conditional BSR at global address
00746         arg: none.  */
00747     case ETIR_S_C_STC_BSR_GBL:
00748 
00749       /* 208 Store-conditional BSR at pect + offset
00750         arg: none.  */
00751     case ETIR_S_C_STC_BSR_PS:
00752 
00753       /* 209 Store-conditional LDA at global address
00754         arg: none.  */
00755     case ETIR_S_C_STC_LDA_GBL:
00756 
00757       /* 210 Store-conditional LDA at psect + offset
00758         arg: none.  */
00759     case ETIR_S_C_STC_LDA_PS:
00760 
00761       /* 211 Store-conditional BSR or Hint at global address
00762         arg: none.  */
00763     case ETIR_S_C_STC_BOH_GBL:
00764 
00765       /* 212 Store-conditional BSR or Hint at pect + offset
00766         arg: none.  */
00767     case ETIR_S_C_STC_BOH_PS:
00768 
00769       /* 213 Store-conditional NOP,BSR or HINT at global address
00770         arg: none.  */
00771     case ETIR_S_C_STC_NBH_GBL:
00772 
00773       /* 214 Store-conditional NOP,BSR or HINT at psect + offset
00774         arg: none.  */
00775     case ETIR_S_C_STC_NBH_PS:
00776       /* FIXME */
00777       break;
00778 
00779     default:
00780 #if VMS_DEBUG
00781       _bfd_vms_debug (3,  "reserved STC cmd %d", cmd);
00782 #endif
00783       break;
00784     }
00785   return TRUE;
00786 }
00787 
00788 static asection *
00789 new_section (bfd * abfd ATTRIBUTE_UNUSED, int idx)
00790 {
00791   asection *section;
00792   char sname[16];
00793   char *name;
00794 
00795 #if VMS_DEBUG
00796   _bfd_vms_debug (5, "new_section %d\n", idx);
00797 #endif
00798   sprintf (sname, SECTION_NAME_TEMPLATE, idx);
00799 
00800   name = bfd_malloc ((bfd_size_type) strlen (sname) + 1);
00801   if (name == 0)
00802     return NULL;
00803   strcpy (name, sname);
00804 
00805   section = bfd_malloc ((bfd_size_type) sizeof (asection));
00806   if (section == 0)
00807     {
00808 #if VMS_DEBUG
00809       _bfd_vms_debug (6,  "bfd_make_section (%s) failed", name);
00810 #endif
00811       return NULL;
00812     }
00813 
00814   section->size = 0;
00815   section->vma = 0;
00816   section->contents = 0;
00817   section->name = name;
00818   section->index = idx;
00819 
00820   return section;
00821 }
00822 
00823 static int
00824 alloc_section (bfd * abfd, unsigned int idx)
00825 {
00826   bfd_size_type amt;
00827 
00828 #if VMS_DEBUG
00829   _bfd_vms_debug (4, "alloc_section %d\n", idx);
00830 #endif
00831 
00832   amt = idx + 1;
00833   amt *= sizeof (asection *);
00834   PRIV (sections) = bfd_realloc (PRIV (sections), amt);
00835   if (PRIV (sections) == 0)
00836     return -1;
00837 
00838   while (PRIV (section_count) <= idx)
00839     {
00840       PRIV (sections)[PRIV (section_count)]
00841        = new_section (abfd, (int) PRIV (section_count));
00842       if (PRIV (sections)[PRIV (section_count)] == 0)
00843        return -1;
00844       PRIV (section_count)++;
00845     }
00846 
00847   return 0;
00848 }
00849 
00850 /* tir_sta
00851 
00852    vax stack commands
00853 
00854    Handle sta_xxx commands in tir section
00855    ptr points to data area in record
00856 
00857    See table 7-3 of the VAX/VMS linker manual.  */
00858 
00859 static unsigned char *
00860 tir_sta (bfd * abfd, unsigned char *ptr)
00861 {
00862   int cmd = *ptr++;
00863 
00864 #if VMS_DEBUG
00865   _bfd_vms_debug (5, "tir_sta %d\n", cmd);
00866 #endif
00867 
00868   switch (cmd)
00869     {
00870       /* stack */
00871     case TIR_S_C_STA_GBL:
00872       /* stack global
00873         arg: cs      symbol name
00874 
00875         stack 32 bit value of symbol (high bits set to 0).  */
00876       {
00877        char *name;
00878        vms_symbol_entry *entry;
00879 
00880        name = _bfd_vms_save_counted_string (ptr);
00881 
00882        entry = _bfd_vms_enter_symbol (abfd, name);
00883        if (entry == NULL)
00884          return NULL;
00885 
00886        _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
00887        ptr += *ptr + 1;
00888       }
00889       break;
00890 
00891     case TIR_S_C_STA_SB:
00892       /* stack signed byte
00893         arg: by      value
00894 
00895         stack byte value, sign extend to 32 bit.  */
00896       _bfd_vms_push (abfd, (uquad) *ptr++, -1);
00897       break;
00898 
00899     case TIR_S_C_STA_SW:
00900       /* stack signed short word
00901         arg: sh      value
00902 
00903         stack 16 bit value, sign extend to 32 bit.  */
00904       _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1);
00905       ptr += 2;
00906       break;
00907 
00908     case TIR_S_C_STA_LW:
00909       /* stack signed longword
00910         arg: lw      value
00911 
00912         stack 32 bit value.  */
00913       _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
00914       ptr += 4;
00915       break;
00916 
00917     case TIR_S_C_STA_PB:
00918     case TIR_S_C_STA_WPB:
00919       /* stack psect base plus byte offset (word index)
00920         arg: by      section index
00921               (sh    section index)
00922               by     signed byte offset.  */
00923       {
00924        unsigned long dummy;
00925        unsigned int psect;
00926 
00927        if (cmd == TIR_S_C_STA_PB)
00928          psect = *ptr++;
00929        else
00930          {
00931            psect = bfd_getl16 (ptr);
00932            ptr += 2;
00933          }
00934 
00935        if (psect >= PRIV (section_count))
00936          alloc_section (abfd, psect);
00937 
00938        dummy = (long) *ptr++;
00939        dummy += (PRIV (sections)[psect])->vma;
00940        _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
00941       }
00942       break;
00943 
00944     case TIR_S_C_STA_PW:
00945     case TIR_S_C_STA_WPW:
00946       /* stack psect base plus word offset (word index)
00947         arg: by      section index
00948               (sh    section index)
00949               sh     signed short offset.  */
00950       {
00951        unsigned long dummy;
00952        unsigned int psect;
00953 
00954        if (cmd == TIR_S_C_STA_PW)
00955          psect = *ptr++;
00956        else
00957          {
00958            psect = bfd_getl16 (ptr);
00959            ptr += 2;
00960          }
00961 
00962        if (psect >= PRIV (section_count))
00963          alloc_section (abfd, psect);
00964 
00965        dummy = bfd_getl16 (ptr); ptr+=2;
00966        dummy += (PRIV (sections)[psect])->vma;
00967        _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
00968       }
00969       break;
00970 
00971     case TIR_S_C_STA_PL:
00972     case TIR_S_C_STA_WPL:
00973       /* stack psect base plus long offset (word index)
00974         arg: by      section index
00975               (sh    section index)
00976               lw     signed longword offset.      */
00977       {
00978        unsigned long dummy;
00979        unsigned int psect;
00980 
00981        if (cmd == TIR_S_C_STA_PL)
00982          psect = *ptr++;
00983        else
00984          {
00985            psect = bfd_getl16 (ptr);
00986            ptr += 2;
00987          }
00988 
00989        if (psect >= PRIV (section_count))
00990          alloc_section (abfd, psect);
00991 
00992        dummy = bfd_getl32 (ptr); ptr += 4;
00993        dummy += (PRIV (sections)[psect])->vma;
00994        _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
00995       }
00996       break;
00997 
00998     case TIR_S_C_STA_UB:
00999       /* stack unsigned byte
01000         arg: by      value
01001 
01002         stack byte value.  */
01003       _bfd_vms_push (abfd, (uquad) *ptr++, -1);
01004       break;
01005 
01006     case TIR_S_C_STA_UW:
01007       /* stack unsigned short word
01008         arg: sh      value
01009 
01010         stack 16 bit value.  */
01011       _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1);
01012       ptr += 2;
01013       break;
01014 
01015     case TIR_S_C_STA_BFI:
01016       /* stack byte from image
01017         arg: none.  */
01018       /* FALLTHRU  */
01019     case TIR_S_C_STA_WFI:
01020       /* stack byte from image
01021         arg: none.  */
01022       /* FALLTHRU */
01023     case TIR_S_C_STA_LFI:
01024       /* stack byte from image
01025         arg: none.  */
01026       (*_bfd_error_handler) (_("stack-from-image not implemented"));
01027       return NULL;
01028 
01029     case TIR_S_C_STA_EPM:
01030       /* stack entry point mask
01031         arg: cs      symbol name
01032 
01033         stack (unsigned) entry point mask of symbol
01034         err if symbol is no entry point.  */
01035       {
01036        char *name;
01037        vms_symbol_entry *entry;
01038 
01039        name = _bfd_vms_save_counted_string (ptr);
01040        entry = _bfd_vms_enter_symbol (abfd, name);
01041        if (entry == NULL)
01042          return NULL;
01043 
01044        (*_bfd_error_handler) (_("stack-entry-mask not fully implemented"));
01045        _bfd_vms_push (abfd, (uquad) 0, -1);
01046        ptr += *ptr + 1;
01047       }
01048       break;
01049 
01050     case TIR_S_C_STA_CKARG:
01051       /* compare procedure argument
01052         arg: cs      symbol name
01053               by     argument index
01054               da     argument descriptor
01055 
01056         compare argument descriptor with symbol argument (ARG$V_PASSMECH)
01057         and stack TRUE (args match) or FALSE (args dont match) value.  */
01058       (*_bfd_error_handler) (_("PASSMECH not fully implemented"));
01059       _bfd_vms_push (abfd, (uquad) 1, -1);
01060       break;
01061 
01062     case TIR_S_C_STA_LSY:
01063       /* stack local symbol value
01064         arg:  sh     environment index
01065               cs     symbol name.  */
01066       {
01067        int envidx;
01068        char *name;
01069        vms_symbol_entry *entry;
01070 
01071        envidx = bfd_getl16 (ptr);
01072        ptr += 2;
01073        name = _bfd_vms_save_counted_string (ptr);
01074        entry = _bfd_vms_enter_symbol (abfd, name);
01075        if (entry == NULL)
01076          return NULL;
01077        (*_bfd_error_handler) (_("stack-local-symbol not fully implemented"));
01078        _bfd_vms_push (abfd, (uquad) 0, -1);
01079        ptr += *ptr + 1;
01080       }
01081       break;
01082 
01083     case TIR_S_C_STA_LIT:
01084       /* stack literal
01085         arg:  by     literal index
01086 
01087         stack literal.  */
01088       ptr++;
01089       _bfd_vms_push (abfd, (uquad) 0, -1);
01090       (*_bfd_error_handler) (_("stack-literal not fully implemented"));
01091       break;
01092 
01093     case TIR_S_C_STA_LEPM:
01094       /* stack local symbol entry point mask
01095         arg:  sh     environment index
01096               cs     symbol name
01097 
01098         stack (unsigned) entry point mask of symbol
01099         err if symbol is no entry point.  */
01100       {
01101        int envidx;
01102        char *name;
01103        vms_symbol_entry *entry;
01104 
01105        envidx = bfd_getl16 (ptr);
01106        ptr += 2;
01107        name = _bfd_vms_save_counted_string (ptr);
01108        entry = _bfd_vms_enter_symbol (abfd, name);
01109        if (entry == NULL)
01110          return NULL;
01111        (*_bfd_error_handler) (_("stack-local-symbol-entry-point-mask not fully implemented"));
01112        _bfd_vms_push (abfd, (uquad) 0, -1);
01113        ptr += *ptr + 1;
01114       }
01115       break;
01116 
01117     default:
01118       (*_bfd_error_handler) (_("reserved STA cmd %d"), ptr[-1]);
01119       return NULL;
01120       break;
01121     }
01122 
01123   return ptr;
01124 }
01125 
01126 static const char *
01127 tir_cmd_name (int cmd)
01128 {
01129   switch (cmd)
01130     {
01131     case TIR_S_C_STO_RSB: return "TIR_S_C_STO_RSB";
01132     case TIR_S_C_STO_RSW: return "TIR_S_C_STO_RSW";
01133     case TIR_S_C_STO_RL: return "TIR_S_C_STO_RL";
01134     case TIR_S_C_STO_VPS: return "TIR_S_C_STO_VPS";
01135     case TIR_S_C_STO_USB: return "TIR_S_C_STO_USB";
01136     case TIR_S_C_STO_USW: return "TIR_S_C_STO_USW";
01137     case TIR_S_C_STO_RUB: return "TIR_S_C_STO_RUB";
01138     case TIR_S_C_STO_RUW: return "TIR_S_C_STO_RUW";
01139     case TIR_S_C_STO_PIRR: return "TIR_S_C_STO_PIRR";
01140     case TIR_S_C_OPR_INSV: return "TIR_S_C_OPR_INSV";
01141     case TIR_S_C_OPR_DFLIT: return "TIR_S_C_OPR_DFLIT";
01142     case TIR_S_C_OPR_REDEF: return "TIR_S_C_OPR_REDEF";
01143     case TIR_S_C_OPR_ROT: return "TIR_S_C_OPR_ROT";
01144     case TIR_S_C_OPR_USH: return "TIR_S_C_OPR_USH";
01145     case TIR_S_C_OPR_ASH: return "TIR_S_C_OPR_ASH";
01146     case TIR_S_C_CTL_DFLOC: return "TIR_S_C_CTL_DFLOC";
01147     case TIR_S_C_CTL_STLOC: return "TIR_S_C_CTL_STLOC";
01148     case TIR_S_C_CTL_STKDL: return "TIR_S_C_CTL_STKDL";
01149 
01150     default:
01151       /* These strings have not been added yet.  */
01152       abort ();
01153     }
01154 }
01155 
01156 /* tir_sto
01157 
01158    vax store commands
01159 
01160    handle sto_xxx commands in tir section
01161    ptr points to data area in record
01162 
01163    See table 7-4 of the VAX/VMS linker manual.  */
01164 
01165 static unsigned char *
01166 tir_sto (bfd * abfd, unsigned char *ptr)
01167 {
01168   unsigned long dummy;
01169   int size;
01170   int psect;
01171 
01172 #if VMS_DEBUG
01173   _bfd_vms_debug (5, "tir_sto %d\n", *ptr);
01174 #endif
01175 
01176   switch (*ptr++)
01177     {
01178     case TIR_S_C_STO_SB:
01179       /* Store signed byte: pop stack, write byte
01180         arg: none.  */
01181       dummy = _bfd_vms_pop (abfd, &psect);
01182       image_write_b (abfd, dummy & 0xff); /* FIXME: check top bits */
01183       break;
01184 
01185     case TIR_S_C_STO_SW:
01186       /* Store signed word: pop stack, write word
01187         arg: none.  */
01188       dummy = _bfd_vms_pop (abfd, &psect);
01189       image_write_w (abfd, dummy & 0xffff);      /* FIXME: check top bits */
01190       break;
01191 
01192     case TIR_S_C_STO_LW:
01193       /* Store longword: pop stack, write longword
01194         arg: none.  */
01195       dummy = _bfd_vms_pop (abfd, &psect);
01196       image_write_l (abfd, dummy & 0xffffffff);  /* FIXME: check top bits */
01197       break;
01198 
01199     case TIR_S_C_STO_BD:
01200       /* Store byte displaced: pop stack, sub lc+1, write byte
01201         arg: none.  */
01202       dummy = _bfd_vms_pop (abfd, &psect);
01203       dummy -= ((PRIV (sections)[psect])->vma + 1);
01204       image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
01205       break;
01206 
01207     case TIR_S_C_STO_WD:
01208       /* Store word displaced: pop stack, sub lc+2, write word
01209         arg: none.  */
01210       dummy = _bfd_vms_pop (abfd, &psect);
01211       dummy -= ((PRIV (sections)[psect])->vma + 2);
01212       image_write_w (abfd, dummy & 0xffff);/* FIXME: check top bits */
01213       break;
01214 
01215     case TIR_S_C_STO_LD:
01216       /* Store long displaced: pop stack, sub lc+4, write long
01217         arg: none.  */
01218       dummy = _bfd_vms_pop (abfd, &psect);
01219       dummy -= ((PRIV (sections)[psect])->vma + 4);
01220       image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */
01221       break;
01222 
01223     case TIR_S_C_STO_LI:
01224       /* Store short literal: pop stack, write byte
01225         arg: none.  */
01226       dummy = _bfd_vms_pop (abfd, &psect);
01227       image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
01228       break;
01229 
01230     case TIR_S_C_STO_PIDR:
01231       /* Store position independent data reference: pop stack, write longword
01232         arg: none.
01233         FIXME: incomplete !  */
01234       dummy = _bfd_vms_pop (abfd, &psect);
01235       image_write_l (abfd, dummy & 0xffffffff);
01236       break;
01237 
01238     case TIR_S_C_STO_PICR:
01239       /* Store position independent code reference: pop stack, write longword
01240         arg: none.
01241         FIXME: incomplete !  */
01242       dummy = _bfd_vms_pop (abfd, &psect);
01243       image_write_b (abfd, 0x9f);
01244       image_write_l (abfd, dummy & 0xffffffff);
01245       break;
01246 
01247     case TIR_S_C_STO_RIVB:
01248       /* Store repeated immediate variable bytes
01249         1-byte count n field followed by n bytes of data
01250         pop stack, write n bytes <stack> times.  */
01251       size = *ptr++;
01252       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
01253       while (dummy-- > 0L)
01254        image_dump (abfd, ptr, size, 0);
01255       ptr += size;
01256       break;
01257 
01258     case TIR_S_C_STO_B:
01259       /* Store byte from top longword.  */
01260       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
01261       image_write_b (abfd, dummy & 0xff);
01262       break;
01263 
01264     case TIR_S_C_STO_W:
01265       /* Store word from top longword.  */
01266       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
01267       image_write_w (abfd, dummy & 0xffff);
01268       break;
01269 
01270     case TIR_S_C_STO_RB:
01271       /* Store repeated byte from top longword.  */
01272       size = (unsigned long) _bfd_vms_pop (abfd, NULL);
01273       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
01274       while (size-- > 0)
01275        image_write_b (abfd, dummy & 0xff);
01276       break;
01277 
01278     case TIR_S_C_STO_RW:
01279       /* Store repeated word from top longword.  */
01280       size = (unsigned long) _bfd_vms_pop (abfd, NULL);
01281       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
01282       while (size-- > 0)
01283        image_write_w (abfd, dummy & 0xffff);
01284       break;
01285 
01286     case TIR_S_C_STO_RSB:
01287     case TIR_S_C_STO_RSW:
01288     case TIR_S_C_STO_RL:
01289     case TIR_S_C_STO_VPS:
01290     case TIR_S_C_STO_USB:
01291     case TIR_S_C_STO_USW:
01292     case TIR_S_C_STO_RUB:
01293     case TIR_S_C_STO_RUW:
01294     case TIR_S_C_STO_PIRR:
01295       (*_bfd_error_handler) (_("%s: not implemented"), tir_cmd_name (ptr[-1]));
01296       break;
01297 
01298     default:
01299       (*_bfd_error_handler) (_("reserved STO cmd %d"), ptr[-1]);
01300       break;
01301     }
01302 
01303   return ptr;
01304 }
01305 
01306 /* Stack operator commands
01307    All 32 bit signed arithmetic
01308    All word just like a stack calculator
01309    Arguments are popped from stack, results are pushed on stack
01310 
01311    See table 7-5 of the VAX/VMS linker manual.  */
01312 
01313 static unsigned char *
01314 tir_opr (bfd * abfd, unsigned char *ptr)
01315 {
01316   long op1, op2;
01317 
01318 #if VMS_DEBUG
01319   _bfd_vms_debug (5, "tir_opr %d\n", *ptr);
01320 #endif
01321 
01322   /* Operation.  */
01323   switch (*ptr++)
01324     {
01325     case TIR_S_C_OPR_NOP: /* No-op.  */
01326       break;
01327 
01328     case TIR_S_C_OPR_ADD: /* Add.  */
01329       op1 = (long) _bfd_vms_pop (abfd, NULL);
01330       op2 = (long) _bfd_vms_pop (abfd, NULL);
01331       _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
01332       break;
01333 
01334     case TIR_S_C_OPR_SUB: /* Subtract.  */
01335       op1 = (long) _bfd_vms_pop (abfd, NULL);
01336       op2 = (long) _bfd_vms_pop (abfd, NULL);
01337       _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
01338       break;
01339 
01340     case TIR_S_C_OPR_MUL: /* Multiply.  */
01341       op1 = (long) _bfd_vms_pop (abfd, NULL);
01342       op2 = (long) _bfd_vms_pop (abfd, NULL);
01343       _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
01344       break;
01345 
01346     case TIR_S_C_OPR_DIV: /* Divide.  */
01347       op1 = (long) _bfd_vms_pop (abfd, NULL);
01348       op2 = (long) _bfd_vms_pop (abfd, NULL);
01349       if (op2 == 0)
01350        _bfd_vms_push (abfd, (uquad) 0, -1);
01351       else
01352        _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
01353       break;
01354 
01355     case TIR_S_C_OPR_AND: /* Logical AND.  */
01356       op1 = (long) _bfd_vms_pop (abfd, NULL);
01357       op2 = (long) _bfd_vms_pop (abfd, NULL);
01358       _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
01359       break;
01360 
01361     case TIR_S_C_OPR_IOR: /* Logical inclusive OR.  */
01362       op1 = (long) _bfd_vms_pop (abfd, NULL);
01363       op2 = (long) _bfd_vms_pop (abfd, NULL);
01364       _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
01365       break;
01366 
01367     case TIR_S_C_OPR_EOR: /* Logical exclusive OR.  */
01368       op1 = (long) _bfd_vms_pop (abfd, NULL);
01369       op2 = (long) _bfd_vms_pop (abfd, NULL);
01370       _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
01371       break;
01372 
01373     case TIR_S_C_OPR_NEG: /* Negate.  */
01374       op1 = (long) _bfd_vms_pop (abfd, NULL);
01375       _bfd_vms_push (abfd, (uquad) (-op1), -1);
01376       break;
01377 
01378     case TIR_S_C_OPR_COM: /* Complement.  */
01379       op1 = (long) _bfd_vms_pop (abfd, NULL);
01380       _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
01381       break;
01382 
01383     case TIR_S_C_OPR_INSV: /* Insert field.  */
01384       (void) _bfd_vms_pop (abfd, NULL);
01385       (*_bfd_error_handler)  (_("%s: not fully implemented"),
01386                            tir_cmd_name (ptr[-1]));
01387       break;
01388 
01389     case TIR_S_C_OPR_ASH: /* Arithmetic shift.  */
01390       op1 = (long) _bfd_vms_pop (abfd, NULL);
01391       op2 = (long) _bfd_vms_pop (abfd, NULL);
01392       if (HIGHBIT (op1))    /* Shift right.  */
01393        op2 >>= op1;
01394       else                  /* Shift left.  */
01395        op2 <<= op1;
01396       _bfd_vms_push (abfd, (uquad) op2, -1);
01397       (*_bfd_error_handler)  (_("%s: not fully implemented"),
01398                            tir_cmd_name (ptr[-1]));
01399       break;
01400 
01401     case TIR_S_C_OPR_USH: /* Unsigned shift.  */
01402       op1 = (long) _bfd_vms_pop (abfd, NULL);
01403       op2 = (long) _bfd_vms_pop (abfd, NULL);
01404       if (HIGHBIT (op1))    /* Shift right.  */
01405        op2 >>= op1;
01406       else                  /* Shift left.  */
01407        op2 <<= op1;
01408       _bfd_vms_push (abfd, (uquad) op2, -1);
01409       (*_bfd_error_handler)  (_("%s: not fully implemented"),
01410                            tir_cmd_name (ptr[-1]));
01411       break;
01412 
01413     case TIR_S_C_OPR_ROT: /* Rotate.  */
01414       op1 = (long) _bfd_vms_pop (abfd, NULL);
01415       op2 = (long) _bfd_vms_pop (abfd, NULL);
01416       if (HIGHBIT (0))      /* Shift right.  */
01417        op2 >>= op1;
01418       else           /* Shift left.  */
01419        op2 <<= op1;
01420       _bfd_vms_push (abfd, (uquad) op2, -1);
01421       (*_bfd_error_handler)  (_("%s: not fully implemented"),
01422                            tir_cmd_name (ptr[-1]));
01423       break;
01424 
01425     case TIR_S_C_OPR_SEL: /* Select.  */
01426       if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
01427        (void) _bfd_vms_pop (abfd, NULL);
01428       else
01429        {
01430          op1 = (long) _bfd_vms_pop (abfd, NULL);
01431          (void) _bfd_vms_pop (abfd, NULL);
01432          _bfd_vms_push (abfd, (uquad) op1, -1);
01433        }
01434       break;
01435 
01436     case TIR_S_C_OPR_REDEF: /* Redefine symbol to current location.  */
01437     case TIR_S_C_OPR_DFLIT: /* Define a literal.  */
01438       (*_bfd_error_handler) (_("%s: not supported"),
01439                           tir_cmd_name (ptr[-1]));
01440       break;
01441 
01442     default:
01443       (*_bfd_error_handler) (_("reserved OPR cmd %d"), ptr[-1]);
01444       break;
01445     }
01446 
01447   return ptr;
01448 }
01449 
01450 /* Control commands
01451 
01452    See table 7-6 of the VAX/VMS linker manual.  */
01453 
01454 static unsigned char *
01455 tir_ctl (bfd * abfd, unsigned char *ptr)
01456 {
01457   unsigned long dummy;
01458   unsigned int psect;
01459 
01460 #if VMS_DEBUG
01461   _bfd_vms_debug (5, "tir_ctl %d\n", *ptr);
01462 #endif
01463 
01464   switch (*ptr++)
01465     {
01466     case TIR_S_C_CTL_SETRB:
01467       /* Set relocation base: pop stack, set image location counter
01468         arg: none.  */
01469       dummy = _bfd_vms_pop (abfd, (int *) &psect);
01470       if (psect >= PRIV (section_count))
01471        alloc_section (abfd, psect);
01472       image_set_ptr (abfd, (int) psect, (uquad) dummy);
01473       break;
01474 
01475     case TIR_S_C_CTL_AUGRB:
01476       /* Augment relocation base: increment image location counter by offset
01477         arg: lw      offset value.  */
01478       dummy = bfd_getl32 (ptr);
01479       image_inc_ptr (abfd, (uquad) dummy);
01480       break;
01481 
01482     case TIR_S_C_CTL_DFLOC:
01483       /* Define location: pop index, save location counter under index
01484         arg: none.  */
01485       dummy = _bfd_vms_pop (abfd, NULL);
01486       (*_bfd_error_handler) (_("%s: not fully implemented"),
01487                           tir_cmd_name (ptr[-1]));
01488       break;
01489 
01490     case TIR_S_C_CTL_STLOC:
01491       /* Set location: pop index, restore location counter from index
01492         arg: none.  */
01493       dummy = _bfd_vms_pop (abfd, (int *) &psect);
01494       (*_bfd_error_handler) (_("%s: not fully implemented"),
01495                           tir_cmd_name (ptr[-1]));
01496       break;
01497 
01498     case TIR_S_C_CTL_STKDL:
01499       /* Stack defined location: pop index, push location counter from index
01500         arg: none.  */
01501       dummy = _bfd_vms_pop (abfd, (int *) &psect);
01502       (*_bfd_error_handler) (_("%s: not fully implemented"),
01503                           tir_cmd_name (ptr[-1]));
01504       break;
01505 
01506     default:
01507       (*_bfd_error_handler) (_("reserved CTL cmd %d"), ptr[-1]);
01508       break;
01509     }
01510   return ptr;
01511 }
01512 
01513 /* Handle command from TIR section.  */
01514 
01515 static unsigned char *
01516 tir_cmd (bfd * abfd, unsigned char *ptr)
01517 {
01518   struct
01519   {
01520     int mincod;
01521     int maxcod;
01522     unsigned char * (*explain) (bfd *, unsigned char *);
01523   }
01524   tir_table[] =
01525   {
01526     { 0,              TIR_S_C_MAXSTACOD, tir_sta },
01527     { TIR_S_C_MINSTOCOD, TIR_S_C_MAXSTOCOD, tir_sto },
01528     { TIR_S_C_MINOPRCOD, TIR_S_C_MAXOPRCOD, tir_opr },
01529     { TIR_S_C_MINCTLCOD, TIR_S_C_MAXCTLCOD, tir_ctl },
01530     { -1, -1, NULL }
01531   };
01532   int i = 0;
01533 
01534 #if VMS_DEBUG
01535   _bfd_vms_debug (4, "tir_cmd %d/%x\n", *ptr, *ptr);
01536   _bfd_hexdump (8, ptr, 16, (int) ptr);
01537 #endif
01538 
01539   if (*ptr & 0x80)
01540     {
01541       /* Store immediate.  */
01542       i = 128 - (*ptr++ & 0x7f);
01543       image_dump (abfd, ptr, i, 0);
01544       ptr += i;
01545     }
01546   else
01547     {
01548       while (tir_table[i].mincod >= 0)
01549        {
01550          if ( (tir_table[i].mincod <= *ptr)
01551               && (*ptr <= tir_table[i].maxcod))
01552            {
01553              ptr = tir_table[i].explain (abfd, ptr);
01554              break;
01555            }
01556          i++;
01557        }
01558       if (tir_table[i].mincod < 0)
01559        {
01560          (*_bfd_error_handler) (_("obj code %d not found"), *ptr);
01561          ptr = 0;
01562        }
01563     }
01564 
01565   return ptr;
01566 }
01567 
01568 /* Handle command from ETIR section.  */
01569 
01570 static int
01571 etir_cmd (bfd * abfd, int cmd, unsigned char *ptr)
01572 {
01573   static struct
01574   {
01575     int mincod;
01576     int maxcod;
01577     bfd_boolean (*explain) (bfd *, int, unsigned char *);
01578   }
01579   etir_table[] =
01580   {
01581     { ETIR_S_C_MINSTACOD, ETIR_S_C_MAXSTACOD, etir_sta },
01582     { ETIR_S_C_MINSTOCOD, ETIR_S_C_MAXSTOCOD, etir_sto },
01583     { ETIR_S_C_MINOPRCOD, ETIR_S_C_MAXOPRCOD, etir_opr },
01584     { ETIR_S_C_MINCTLCOD, ETIR_S_C_MAXCTLCOD, etir_ctl },
01585     { ETIR_S_C_MINSTCCOD, ETIR_S_C_MAXSTCCOD, etir_stc },
01586     { -1, -1, NULL }
01587   };
01588 
01589   int i = 0;
01590 
01591 #if VMS_DEBUG
01592   _bfd_vms_debug (4, "etir_cmd %d/%x\n", cmd, cmd);
01593   _bfd_hexdump (8, ptr, 16, (int) ptr);
01594 #endif
01595 
01596   while (etir_table[i].mincod >= 0)
01597     {
01598       if ( (etir_table[i].mincod <= cmd)
01599           && (cmd <= etir_table[i].maxcod))
01600        {
01601          if (!etir_table[i].explain (abfd, cmd, ptr))
01602            return -1;
01603          break;
01604        }
01605       i++;
01606     }
01607 
01608 #if VMS_DEBUG
01609   _bfd_vms_debug (4, "etir_cmd: = 0\n");
01610 #endif
01611   return 0;
01612 }
01613 
01614 /* Text Information and Relocation Records (OBJ$C_TIR)
01615    handle tir record.  */
01616 
01617 static int
01618 analyze_tir (bfd * abfd, unsigned char *ptr, unsigned int length)
01619 {
01620   unsigned char *maxptr;
01621 
01622 #if VMS_DEBUG
01623   _bfd_vms_debug (3, "analyze_tir: %d bytes\n", length);
01624 #endif
01625 
01626   maxptr = ptr + length;
01627 
01628   while (ptr < maxptr)
01629     {
01630       ptr = tir_cmd (abfd, ptr);
01631       if (ptr == 0)
01632        return -1;
01633     }
01634 
01635   return 0;
01636 }
01637 
01638 /* Text Information and Relocation Records (EOBJ$C_ETIR)
01639    handle etir record.  */
01640 
01641 static int
01642 analyze_etir (bfd * abfd, unsigned char *ptr, unsigned int length)
01643 {
01644   int cmd;
01645   unsigned char *maxptr;
01646   int result = 0;
01647 
01648 #if VMS_DEBUG
01649   _bfd_vms_debug (3, "analyze_etir: %d bytes\n", length);
01650 #endif
01651 
01652   maxptr = ptr + length;
01653 
01654   while (ptr < maxptr)
01655     {
01656       cmd = bfd_getl16 (ptr);
01657       length = bfd_getl16 (ptr + 2);
01658       result = etir_cmd (abfd, cmd, ptr+4);
01659       if (result != 0)
01660        break;
01661       ptr += length;
01662     }
01663 
01664 #if VMS_DEBUG
01665   _bfd_vms_debug (3, "analyze_etir: = %d\n", result);
01666 #endif
01667 
01668   return result;
01669 }
01670 
01671 /* Process ETIR record
01672    Return 0 on success, -1 on error.  */
01673 
01674 int
01675 _bfd_vms_slurp_tir (bfd * abfd, int objtype)
01676 {
01677   int result;
01678 
01679 #if VMS_DEBUG
01680   _bfd_vms_debug (2, "TIR/ETIR\n");
01681 #endif
01682 
01683   switch (objtype)
01684     {
01685     case EOBJ_S_C_ETIR:
01686       PRIV (vms_rec) += 4;  /* Skip type, size.  */
01687       PRIV (rec_size) -= 4;
01688       result = analyze_etir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
01689       break;
01690     case OBJ_S_C_TIR:
01691       PRIV (vms_rec) += 1;  /* Skip type.  */
01692       PRIV (rec_size) -= 1;
01693       result = analyze_tir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
01694       break;
01695     default:
01696       result = -1;
01697       break;
01698     }
01699 
01700   return result;
01701 }
01702 
01703 /* Process EDBG record
01704    Return 0 on success, -1 on error
01705 
01706    Not implemented yet.  */
01707 
01708 int
01709 _bfd_vms_slurp_dbg (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
01710 {
01711 #if VMS_DEBUG
01712   _bfd_vms_debug (2, "DBG/EDBG\n");
01713 #endif
01714 
01715   abfd->flags |= (HAS_DEBUG | HAS_LINENO);
01716   return 0;
01717 }
01718 
01719 /* Process ETBT record
01720    Return 0 on success, -1 on error
01721 
01722    Not implemented yet.  */
01723 
01724 int
01725 _bfd_vms_slurp_tbt (bfd * abfd ATTRIBUTE_UNUSED,
01726                   int objtype ATTRIBUTE_UNUSED)
01727 {
01728 #if VMS_DEBUG
01729   _bfd_vms_debug (2, "TBT/ETBT\n");
01730 #endif
01731 
01732   return 0;
01733 }
01734 
01735 /* Process LNK record
01736    Return 0 on success, -1 on error
01737 
01738    Not implemented yet.  */
01739 
01740 int
01741 _bfd_vms_slurp_lnk (bfd * abfd ATTRIBUTE_UNUSED,
01742                   int objtype ATTRIBUTE_UNUSED)
01743 {
01744 #if VMS_DEBUG
01745   _bfd_vms_debug (2, "LNK\n");
01746 #endif
01747 
01748   return 0;
01749 }
01750 
01751 /* Start ETIR record for section #index at virtual addr offset.  */
01752 
01753 static void
01754 start_etir_record (bfd * abfd, int index, uquad offset, bfd_boolean justoffset)
01755 {
01756   if (!justoffset)
01757     {
01758       /* One ETIR per section.  */
01759       _bfd_vms_output_begin (abfd, EOBJ_S_C_ETIR, -1);
01760       _bfd_vms_output_push (abfd);
01761     }
01762 
01763   /* Push start offset.  */
01764   _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
01765   _bfd_vms_output_long (abfd, (unsigned long) index);
01766   _bfd_vms_output_quad (abfd, (uquad) offset);
01767   _bfd_vms_output_flush (abfd);
01768 
01769   /* Start = pop ().  */
01770   _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1);
01771   _bfd_vms_output_flush (abfd);
01772 }
01773 
01774 static void
01775 end_etir_record (bfd * abfd)
01776 {
01777   _bfd_vms_output_pop (abfd);
01778   _bfd_vms_output_end (abfd);
01779 }
01780 
01781 /* WRITE ETIR SECTION
01782 
01783    This is still under construction and therefore not documented.  */
01784 
01785 static void
01786 sto_imm (bfd * abfd, vms_section *sptr, bfd_vma vaddr, int index)
01787 {
01788   int size;
01789   int ssize;
01790   unsigned char *cptr;
01791 
01792 #if VMS_DEBUG
01793   _bfd_vms_debug (8, "sto_imm %d bytes\n", sptr->size);
01794   _bfd_hexdump (9, sptr->contents, (int) sptr->size, (int) vaddr);
01795 #endif
01796 
01797   ssize = sptr->size;
01798   cptr = sptr->contents;
01799 
01800   while (ssize > 0)
01801     {
01802       /* Try all the rest.  */
01803       size = ssize;
01804 
01805       if (_bfd_vms_output_check (abfd, size) < 0)
01806        {
01807          /* Doesn't fit, split !  */
01808          end_etir_record (abfd);
01809          start_etir_record (abfd, index, vaddr, FALSE);
01810          /* Get max size.  */
01811          size = _bfd_vms_output_check (abfd, 0);
01812          /* More than what's left ?  */
01813          if (size > ssize)
01814            size = ssize;
01815        }
01816 
01817       _bfd_vms_output_begin (abfd, ETIR_S_C_STO_IMM, -1);
01818       _bfd_vms_output_long (abfd, (unsigned long) (size));
01819       _bfd_vms_output_dump (abfd, cptr, size);
01820       _bfd_vms_output_flush (abfd);
01821 
01822 #if VMS_DEBUG
01823       _bfd_vms_debug (10, "dumped %d bytes\n", size);
01824       _bfd_hexdump (10, cptr, (int) size, (int) vaddr);
01825 #endif
01826 
01827       vaddr += size;
01828       ssize -= size;
01829       cptr += size;
01830     }
01831 }
01832 
01833 /* Write section contents for bfd abfd.  */
01834 
01835 int
01836 _bfd_vms_write_tir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
01837 {
01838   asection *section;
01839   vms_section *sptr;
01840   int nextoffset;
01841 
01842 #if VMS_DEBUG
01843   _bfd_vms_debug (2, "vms_write_tir (%p, %d)\n", abfd, objtype);
01844 #endif
01845 
01846   _bfd_vms_output_alignment (abfd, 4);
01847 
01848   nextoffset = 0;
01849   PRIV (vms_linkage_index) = 1;
01850 
01851   /* Dump all other sections.  */
01852   section = abfd->sections;
01853 
01854   while (section != NULL)
01855     {
01856 
01857 #if VMS_DEBUG
01858       _bfd_vms_debug (4, "writing %d. section '%s' (%d bytes)\n",
01859                     section->index, section->name,
01860                     (int) (section->size));
01861 #endif
01862 
01863       if (section->flags & SEC_RELOC)
01864        {
01865          int i;
01866 
01867          if ((i = section->reloc_count) <= 0)
01868            (*_bfd_error_handler) (_("SEC_RELOC with no relocs in section %s"),
01869                                section->name);
01870 #if VMS_DEBUG
01871          else
01872            {
01873              arelent **rptr;
01874              _bfd_vms_debug (4, "%d relocations:\n", i);
01875              rptr = section->orelocation;
01876              while (i-- > 0)
01877               {
01878                 _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, addr %08lx, off %08lx, len %d: %s\n",
01879                               (*(*rptr)->sym_ptr_ptr)->name,
01880                               (*(*rptr)->sym_ptr_ptr)->section->name,
01881                               (long) (*(*rptr)->sym_ptr_ptr)->value,
01882                               (*rptr)->address, (*rptr)->addend,
01883                               bfd_get_reloc_size ((*rptr)->howto),
01884                               (*rptr)->howto->name);
01885                 rptr++;
01886               }
01887            }
01888 #endif
01889        }
01890 
01891       if ((section->flags & SEC_HAS_CONTENTS)
01892          && (! bfd_is_com_section (section)))
01893        {
01894          /* Virtual addr in section.  */
01895          bfd_vma vaddr;
01896 
01897          sptr = _bfd_get_vms_section (abfd, section->index);
01898          if (sptr == NULL)
01899            {
01900              bfd_set_error (bfd_error_no_contents);
01901              return -1;
01902            }
01903 
01904          vaddr = (bfd_vma) (sptr->offset);
01905 
01906          start_etir_record (abfd, section->index, (uquad) sptr->offset,
01907                           FALSE);
01908 
01909          while (sptr != NULL)
01910            {
01911              /* One STA_PQ, CTL_SETRB per vms_section.  */
01912              if (section->flags & SEC_RELOC)
01913               {
01914                 /* Check for relocs.  */
01915                 arelent **rptr = section->orelocation;
01916                 int i = section->reloc_count;
01917 
01918                 for (;;)
01919                   {
01920                     bfd_size_type addr = (*rptr)->address;
01921                     bfd_size_type len = bfd_get_reloc_size ((*rptr)->howto);
01922                     if (sptr->offset < addr)
01923                      {
01924                        /* Sptr starts before reloc.  */
01925                        bfd_size_type before = addr - sptr->offset;
01926                        if (sptr->size <= before)
01927                          {
01928                            /* Complete before.  */
01929                            sto_imm (abfd, sptr, vaddr, section->index);
01930                            vaddr += sptr->size;
01931                            break;
01932                          }
01933                        else
01934                          {
01935                            /* Partly before.  */
01936                            int after = sptr->size - before;
01937 
01938                            sptr->size = before;
01939                            sto_imm (abfd, sptr, vaddr, section->index);
01940                            vaddr += sptr->size;
01941                            sptr->contents += before;
01942                            sptr->offset += before;
01943                            sptr->size = after;
01944                          }
01945                      }
01946                     else if (sptr->offset == addr)
01947                      {
01948                        /* Sptr starts at reloc.  */
01949                        asymbol *sym = *(*rptr)->sym_ptr_ptr;
01950                        asection *sec = sym->section;
01951 
01952                        switch ((*rptr)->howto->type)
01953                          {
01954                          case ALPHA_R_IGNORE:
01955                            break;
01956 
01957                          case ALPHA_R_REFLONG:
01958                            {
01959                             if (bfd_is_und_section (sym->section))
01960                               {
01961                                 int slen = strlen ((char *) sym->name);
01962                                 char *hash;
01963 
01964                                 if (_bfd_vms_output_check (abfd, slen) < 0)
01965                                   {
01966                                    end_etir_record (abfd);
01967                                    start_etir_record (abfd,
01968                                                     section->index,
01969                                                     vaddr, FALSE);
01970                                   }
01971                                 _bfd_vms_output_begin (abfd,
01972                                                     ETIR_S_C_STO_GBL_LW,
01973                                                     -1);
01974                                 hash = (_bfd_vms_length_hash_symbol
01975                                        (abfd, sym->name, EOBJ_S_C_SYMSIZ));
01976                                 _bfd_vms_output_counted (abfd, hash);
01977                                 _bfd_vms_output_flush (abfd);
01978                               }
01979                             else if (bfd_is_abs_section (sym->section))
01980                               {
01981                                 if (_bfd_vms_output_check (abfd, 16) < 0)
01982                                   {
01983                                    end_etir_record (abfd);
01984                                    start_etir_record (abfd,
01985                                                     section->index,
01986                                                     vaddr, FALSE);
01987                                   }
01988                                 _bfd_vms_output_begin (abfd,
01989                                                     ETIR_S_C_STA_LW,
01990                                                     -1);
01991                                 _bfd_vms_output_quad (abfd,
01992                                                    (uquad) sym->value);
01993                                 _bfd_vms_output_flush (abfd);
01994                                 _bfd_vms_output_begin (abfd,
01995                                                     ETIR_S_C_STO_LW,
01996                                                     -1);
01997                                 _bfd_vms_output_flush (abfd);
01998                               }
01999                             else
02000                               {
02001                                 if (_bfd_vms_output_check (abfd, 32) < 0)
02002                                   {
02003                                    end_etir_record (abfd);
02004                                    start_etir_record (abfd,
02005                                                     section->index,
02006                                                     vaddr, FALSE);
02007                                   }
02008                                 _bfd_vms_output_begin (abfd,
02009                                                     ETIR_S_C_STA_PQ,
02010                                                     -1);
02011                                 _bfd_vms_output_long (abfd,
02012                                                    (unsigned long) (sec->index));
02013                                 _bfd_vms_output_quad (abfd,
02014                                                    ((uquad) (*rptr)->addend
02015                                                     + (uquad) sym->value));
02016                                 _bfd_vms_output_flush (abfd);
02017                                 _bfd_vms_output_begin (abfd,
02018                                                     ETIR_S_C_STO_LW,
02019                                                     -1);
02020                                 _bfd_vms_output_flush (abfd);
02021                               }
02022                            }
02023                            break;
02024 
02025                          case ALPHA_R_REFQUAD:
02026                            {
02027                             if (bfd_is_und_section (sym->section))
02028                               {
02029                                 int slen = strlen ((char *) sym->name);
02030                                 char *hash;
02031 
02032                                 if (_bfd_vms_output_check (abfd, slen) < 0)
02033                                   {
02034                                    end_etir_record (abfd);
02035                                    start_etir_record (abfd,
02036                                                     section->index,
02037                                                     vaddr, FALSE);
02038                                   }
02039                                 _bfd_vms_output_begin (abfd,
02040                                                     ETIR_S_C_STO_GBL,
02041                                                     -1);
02042                                 hash = (_bfd_vms_length_hash_symbol
02043                                        (abfd, sym->name, EOBJ_S_C_SYMSIZ));
02044                                 _bfd_vms_output_counted (abfd, hash);
02045                                 _bfd_vms_output_flush (abfd);
02046                               }
02047                             else if (bfd_is_abs_section (sym->section))
02048                               {
02049                                 if (_bfd_vms_output_check (abfd, 16) < 0)
02050                                   {
02051                                    end_etir_record (abfd);
02052                                    start_etir_record (abfd,
02053                                                     section->index,
02054                                                     vaddr, FALSE);
02055                                   }
02056                                 _bfd_vms_output_begin (abfd,
02057                                                     ETIR_S_C_STA_QW,
02058                                                     -1);
02059                                 _bfd_vms_output_quad (abfd,
02060                                                    (uquad) sym->value);
02061                                 _bfd_vms_output_flush (abfd);
02062                                 _bfd_vms_output_begin (abfd,
02063                                                     ETIR_S_C_STO_QW,
02064                                                     -1);
02065                                 _bfd_vms_output_flush (abfd);
02066                               }
02067                             else
02068                               {
02069                                 if (_bfd_vms_output_check (abfd, 32) < 0)
02070                                   {
02071                                    end_etir_record (abfd);
02072                                    start_etir_record (abfd,
02073                                                     section->index,
02074                                                     vaddr, FALSE);
02075                                   }
02076                                 _bfd_vms_output_begin (abfd,
02077                                                     ETIR_S_C_STA_PQ,
02078                                                     -1);
02079                                 _bfd_vms_output_long (abfd,
02080                                                    (unsigned long) (sec->index));
02081                                 _bfd_vms_output_quad (abfd,
02082                                                    ((uquad) (*rptr)->addend
02083                                                     + (uquad) sym->value));
02084                                 _bfd_vms_output_flush (abfd);
02085                                 _bfd_vms_output_begin (abfd,
02086                                                     ETIR_S_C_STO_OFF,
02087                                                     -1);
02088                                 _bfd_vms_output_flush (abfd);
02089                               }
02090                            }
02091                            break;
02092 
02093                          case ALPHA_R_HINT:
02094                            {
02095                             int hint_size;
02096                             char *hash ATTRIBUTE_UNUSED;
02097 
02098                             hint_size = sptr->size;
02099                             sptr->size = len;
02100                             sto_imm (abfd, sptr, vaddr, section->index);
02101                             sptr->size = hint_size;
02102                            }
02103                            break;
02104                          case ALPHA_R_LINKAGE:
02105                            {
02106                             char *hash;
02107 
02108                             if (_bfd_vms_output_check (abfd, 64) < 0)
02109                               {
02110                                 end_etir_record (abfd);
02111                                 start_etir_record (abfd, section->index,
02112                                                  vaddr, FALSE);
02113                               }
02114                             _bfd_vms_output_begin (abfd,
02115                                                  ETIR_S_C_STC_LP_PSB,
02116                                                  -1);
02117                             _bfd_vms_output_long (abfd,
02118                                                 (unsigned long) PRIV (vms_linkage_index));
02119                             PRIV (vms_linkage_index) += 2;
02120                             hash = (_bfd_vms_length_hash_symbol
02121                                    (abfd, sym->name, EOBJ_S_C_SYMSIZ));
02122                             _bfd_vms_output_counted (abfd, hash);
02123                             _bfd_vms_output_byte (abfd, 0);
02124                             _bfd_vms_output_flush (abfd);
02125                            }
02126                            break;
02127 
02128                          case ALPHA_R_CODEADDR:
02129                            {
02130                             int slen = strlen ((char *) sym->name);
02131                             char *hash;
02132                             if (_bfd_vms_output_check (abfd, slen) < 0)
02133                               {
02134                                 end_etir_record (abfd);
02135                                 start_etir_record (abfd,
02136                                                  section->index,
02137                                                  vaddr, FALSE);
02138                               }
02139                             _bfd_vms_output_begin (abfd,
02140                                                  ETIR_S_C_STO_CA,
02141                                                  -1);
02142                             hash = (_bfd_vms_length_hash_symbol
02143                                    (abfd, sym->name, EOBJ_S_C_SYMSIZ));
02144                             _bfd_vms_output_counted (abfd, hash);
02145                             _bfd_vms_output_flush (abfd);
02146                            }
02147                            break;
02148 
02149                          default:
02150                            (*_bfd_error_handler) (_("Unhandled relocation %s"),
02151                                                (*rptr)->howto->name);
02152                            break;
02153                          }
02154 
02155                        vaddr += len;
02156 
02157                        if (len == sptr->size)
02158                          {
02159                            break;
02160                          }
02161                        else
02162                          {
02163                            sptr->contents += len;
02164                            sptr->offset += len;
02165                            sptr->size -= len;
02166                            i--;
02167                            rptr++;
02168                          }
02169                      }
02170                     else
02171                      {
02172                        /* Sptr starts after reloc.  */
02173                        i--;
02174                        /* Check next reloc.  */
02175                        rptr++;
02176                      }
02177 
02178                     if (i == 0)
02179                      {
02180                        /* All reloc checked.  */
02181                        if (sptr->size > 0)
02182                          {
02183                            /* Dump rest.  */
02184                            sto_imm (abfd, sptr, vaddr, section->index);
02185                            vaddr += sptr->size;
02186                          }
02187                        break;
02188                      }
02189                   }
02190               }
02191              else
02192               {
02193                 /* No relocs, just dump.  */
02194                 sto_imm (abfd, sptr, vaddr, section->index);
02195                 vaddr += sptr->size;
02196               }
02197 
02198              sptr = sptr->next;
02199            }
02200 
02201          end_etir_record (abfd);
02202        }
02203 
02204       section = section->next;
02205     }
02206 
02207   _bfd_vms_output_alignment (abfd, 2);
02208   return 0;
02209 }
02210 
02211 /* Write traceback data for bfd abfd.  */
02212 
02213 int
02214 _bfd_vms_write_tbt (bfd * abfd ATTRIBUTE_UNUSED,
02215                   int objtype ATTRIBUTE_UNUSED)
02216 {
02217 #if VMS_DEBUG
02218   _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
02219 #endif
02220 
02221   return 0;
02222 }
02223 
02224 /* Write debug info for bfd abfd.  */
02225 
02226 int
02227 _bfd_vms_write_dbg (bfd * abfd ATTRIBUTE_UNUSED,
02228                   int objtype ATTRIBUTE_UNUSED)
02229 {
02230 #if VMS_DEBUG
02231   _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
02232 #endif
02233 
02234   return 0;
02235 }