home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / binutils-2.7-src.tgz / tar.out / fsf / binutils / bfd / evax-misc.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  22KB  |  1,066 lines

  1. /* evax-misc.c -- Miscellaneous functions for ALPHA EVAX (openVMS/AXP) files.
  2.    Copyright 1996 Free Software Foundation, Inc.
  3.    Written by Klaus Kämpf (kkaempf@progis.de)
  4.    of proGIS Softwareentwicklung, Aachen, Germany
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  19.  
  20.  
  21. #if __STDC__
  22. #include <stdarg.h>
  23. #endif
  24. #include <stdio.h>
  25.  
  26. #include "bfd.h"
  27. #include "sysdep.h"
  28. #include "bfdlink.h"
  29. #include "libbfd.h"
  30.  
  31. #include "evax.h"
  32.  
  33. /*-----------------------------------------------------------------------------*/
  34. #if EVAX_DEBUG
  35. /* debug functions */
  36.  
  37. /* debug function for all evax extensions
  38.    evaluates environment variable EVAX_DEBUG for a
  39.    numerical value on the first call
  40.    all error levels below this value are printed
  41.   
  42.    levels:
  43.    1    toplevel bfd calls (functions from the bfd vector)
  44.    2    functions called by bfd calls
  45.    ...
  46.    9    almost everything
  47.  
  48.    level is also identation level. Indentation is performed
  49.    if level > 0
  50.     */
  51.  
  52. #if __STDC__
  53. void
  54. _bfd_evax_debug (int level, char *format, ...)
  55. {
  56.   static int min_level = -1;
  57.   static FILE *output = NULL;
  58.   char *eptr;
  59.   va_list args;
  60.   int abslvl = (level > 0)?level:-level;
  61.  
  62.   if (min_level == -1)
  63.     {
  64.       if ((eptr = getenv("EVAX_DEBUG")) != NULL)
  65.     {
  66.       min_level = atoi(eptr);
  67.       output = stderr;
  68.     }
  69.       else
  70.     min_level = 0;
  71.     }
  72.   if (output == NULL)
  73.     return;
  74.   if (abslvl > min_level)
  75.     return;
  76.  
  77.   while(--level>0)
  78.     fprintf(output, " ");
  79.   va_start(args, format);
  80.   vfprintf(output, format, args);
  81.   fflush(output);
  82.   va_end(args);
  83.  
  84.   return;
  85. }
  86.  
  87. #else /* not __STDC__ */
  88.  
  89. void
  90. _bfd_evax_debug (level, format, a1, a2, a3, a4, a5, a6)
  91.      int level;
  92.      char *format;
  93.      long a1; long a2; long a3;
  94.      long a4; long a5; long a6;
  95. {
  96.   static int min_level = -1;
  97.   static FILE *output = NULL;
  98.   char *eptr;
  99.  
  100.   if (min_level == -1)
  101.     {
  102.       if ((eptr = getenv("EVAX_DEBUG")) != NULL)
  103.     {
  104.       min_level = atoi(eptr);
  105.       output = stderr;
  106.     }
  107.       else
  108.     min_level = 0;
  109.     }
  110.   if (output == NULL)
  111.     return;
  112.   if (level > min_level)
  113.     return;
  114.  
  115.   while(--level>0)
  116.     fprintf(output, " ");
  117.   fprintf(output, format, a1, a2, a3, a4, a5, a6);
  118.   fflush(output);
  119.  
  120.   return;
  121. }
  122. #endif /* __STDC__ */
  123.  
  124.  
  125. /* a debug function
  126.    hex dump 'size' bytes starting at 'ptr'  */
  127.  
  128. void
  129. _bfd_hexdump (level, ptr, size, offset)
  130.      int level;
  131.      unsigned char *ptr;
  132.      int size;
  133.      int offset;
  134. {
  135.   unsigned char *lptr = ptr;
  136.   int count = 0;
  137.   long start = offset;
  138.  
  139.   while (size-- > 0)
  140.     {
  141.       if ((count%16) == 0)
  142.     evax_debug (level, "%08lx:", start);
  143.       evax_debug (-level, " %02x", *ptr++);
  144.       count++;
  145.       start++;
  146.       if (size == 0)
  147.     {
  148.       while ((count%16) != 0)
  149.         {
  150.           evax_debug (-level, "   ");
  151.           count++;
  152.         }
  153.     }
  154.       if ((count%16) == 0)
  155.     {
  156.       evax_debug (-level, " ");
  157.       while (lptr < ptr)
  158.         {
  159.           evax_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
  160.           lptr++;
  161.         }
  162.       evax_debug (-level, "\n");
  163.     }
  164.     }
  165.   if ((count%16) != 0)
  166.     evax_debug (-level, "\n");
  167.  
  168.   return;
  169. }
  170. #endif
  171.  
  172.  
  173. /* hash functions
  174.  
  175.    These are needed when reading an object file.  */
  176.  
  177. /* allocate new evax_hash_entry
  178.    keep the symbol name and a pointer to the bfd symbol in the table  */
  179.  
  180. struct bfd_hash_entry *
  181. _bfd_evax_hash_newfunc (entry, table, string)
  182.      struct bfd_hash_entry *entry;
  183.      struct bfd_hash_table *table;
  184.      const char *string;
  185. {
  186.   evax_symbol_entry *ret = (evax_symbol_entry *)entry;
  187.  
  188. #if EVAX_DEBUG
  189.   evax_debug (5, "_bfd_evax_hash_newfunc(%p, %p, %s)\n", entry, table, string);
  190. #endif
  191.  
  192.   if (ret == (evax_symbol_entry *)NULL)
  193.     ret = ((evax_symbol_entry *) bfd_hash_allocate (table, sizeof (evax_symbol_entry)));
  194.   if (ret == (evax_symbol_entry *)NULL)
  195.     {
  196.       bfd_set_error (bfd_error_no_memory);
  197.       return (struct bfd_hash_entry *)NULL;
  198.     }
  199.   ret = (evax_symbol_entry *) bfd_hash_newfunc ((struct bfd_hash_entry *)ret, table, string);
  200.  
  201.   ret->symbol = (asymbol *)NULL;
  202.  
  203.   return (struct bfd_hash_entry *)ret;
  204. }
  205.  
  206.  
  207. /* object file input functions */
  208.  
  209. /* Return type and length from record header (buf)  */
  210.  
  211. void
  212. _bfd_evax_get_header_values (abfd, buf, type, length)
  213.      bfd *abfd;
  214.      unsigned char *buf;
  215.      int *type;
  216.      int *length;
  217. {
  218.   if (type != 0)
  219.     *type = bfd_getl16 (buf);
  220.   buf += 2;
  221.   if (length != 0)
  222.     *length = bfd_getl16 (buf);
  223.  
  224.   return;
  225. }
  226.  
  227.  
  228. /* Get next record from object file to evax_buf
  229.    set PRIV(buf_size) and return it
  230.   
  231.    this is a little tricky since it should be portable.
  232.   
  233.    the openVMS/AXP object file has 'variable length' which means that
  234.    read() returns data in chunks of (hopefully) correct and expected
  235.    size. The linker (and other tools on vms) depend on that. Unix doesn't
  236.    know about 'formatted' files, so reading and writing such an object
  237.    file in a unix environment is not trivial.
  238.   
  239.    With the tool 'file' (available on all vms ftp sites), one
  240.    can view and change the attributes of a file. Changing from
  241.    'variable length' to 'fixed length, 512 bytes' reveals the
  242.    record length at the first 2 bytes of every record. The same
  243.    happens during the transfer of object files from vms to unix,
  244.    at least with ucx, dec's implementation of tcp/ip.
  245.   
  246.    The EVAX format repeats the length at bytes 2 & 3 of every record.
  247.   
  248.    On the first call (file_format == FF_UNKNOWN) we check if
  249.    the first and the third byte pair (!) of the record match.
  250.    If they do it's an object file in an unix environment or with
  251.    wrong attributes (FF_FOREIGN), else we should be in a vms
  252.    environment where read() returns the record size (FF_NATIVE).
  253.   
  254.    reading is always done in 2 steps.
  255.    first just the record header is read and the length extracted
  256.    by get_header_values
  257.    then the read buffer is adjusted and the remaining bytes are
  258.    read in.
  259.   
  260.    all file i/o is always done on even file positions  */
  261.  
  262. int
  263. _bfd_evax_get_record (abfd)
  264.      bfd *abfd;
  265. {
  266.   int test_len, test_start, remaining;
  267.   unsigned char *evax_buf;
  268.  
  269. #if EVAX_DEBUG
  270.   evax_debug (8, "_bfd_evax_get_record\n");
  271. #endif
  272.  
  273.   /* minimum is 6 bytes
  274.      (2 bytes length, 2 bytes record id, 2 bytes length repeated)  */
  275.  
  276.   if (PRIV(buf_size) == 0)
  277.     {
  278.       PRIV(evax_buf) = (unsigned char *) malloc (6);
  279. #if EVAX_DEBUG
  280.       evax_debug (9, "PRIV(evax_buf) %p\n", PRIV(evax_buf));
  281. #endif
  282.     }
  283.  
  284.   evax_buf = PRIV(evax_buf);
  285.  
  286.   if (evax_buf == 0)
  287.     {
  288. #if EVAX_DEBUG
  289.       evax_debug (9, "can't alloc evax_buf\n");
  290. #endif
  291.       bfd_set_error (bfd_error_no_memory);
  292.       return -1;
  293.     }
  294.  
  295.   switch (PRIV(file_format))
  296.     {
  297.       case FF_UNKNOWN:
  298.       case FF_FOREIGN:
  299.     test_len = 6;                /* probe 6 bytes */
  300.     test_start = 2;                /* where the record starts */
  301.       break;
  302.  
  303.       case FF_NATIVE:
  304.     test_len = 4;
  305.     test_start = 0;
  306.       break;
  307.   }
  308.  
  309.   /* skip odd alignment byte  */
  310. #if 0
  311.   if (PRIV(file_format) == FF_FOREIGN)
  312.     {
  313. #endif
  314.       if (bfd_tell (abfd) & 1)
  315.     {
  316. #if EVAX_DEBUG
  317.       evax_debug (10, "skip odd\n");
  318. #endif
  319.       if (bfd_read (PRIV(evax_buf), 1, 1, abfd) != 1)
  320.         {
  321. #if EVAX_DEBUG
  322.           evax_debug (9, "skip odd failed\n");
  323. #endif
  324.           bfd_set_error (bfd_error_file_truncated);
  325.           return 0;
  326.         }
  327.     }
  328. #if 0
  329.     }
  330. #endif
  331.   /* read the record header  */
  332.  
  333.   if (bfd_read (PRIV(evax_buf), 1, test_len, abfd) != test_len)
  334.     {
  335. #if EVAX_DEBUG
  336.       evax_debug (9, "can't bfd_read test %d bytes\n", test_len);
  337. #endif
  338.       bfd_set_error (bfd_error_file_truncated);
  339.       return 0;
  340.     }
  341.  
  342.   /* check file format on first call  */
  343.  
  344.   if (PRIV(file_format) == FF_UNKNOWN)
  345.     {                        /* record length repeats ? */
  346.       if ( (evax_buf[0] == evax_buf[4])
  347.         && (evax_buf[1] == evax_buf[5]))
  348.     {
  349.       PRIV(file_format) = FF_FOREIGN;    /* Y: foreign environment */
  350.       test_start = 2;
  351.     }
  352.       else
  353.     {
  354.       PRIV(file_format) = FF_NATIVE;    /* N: native environment */
  355.       test_start = 0;
  356.     }
  357. #if EVAX_DEBUG
  358.       evax_debug (10, "File format is %s\n", (PRIV(file_format) == FF_FOREIGN)?"foreign":"native");
  359. #endif
  360.     }
  361.  
  362.   /* extract evax record length  */
  363.  
  364.   _bfd_evax_get_header_values (abfd, evax_buf+test_start, NULL,
  365.                    &PRIV(rec_length));
  366.  
  367.   if (PRIV(rec_length) <= 0)
  368.     {
  369.       bfd_set_error (bfd_error_file_truncated);
  370.       return 0;
  371.     }
  372.  
  373.   /* that's what the linker manual says  */
  374.  
  375.   if (PRIV(rec_length) > EOBJ_S_C_MAXRECSIZ)
  376.     {
  377.       bfd_set_error (bfd_error_file_truncated);
  378.       return 0;
  379.     }
  380.  
  381.   /* adjust the buffer  */
  382.  
  383.   if (PRIV(rec_length) > PRIV(buf_size))
  384.     {
  385.       PRIV(evax_buf) = (unsigned char *) realloc (evax_buf, PRIV(rec_length));
  386. #if EVAX_DEBUG
  387.       evax_debug (3, "adjusted the buffer (%p) from %d to %d\n", PRIV(evax_buf), PRIV(buf_size), PRIV(rec_length));
  388. #endif
  389.       evax_buf = PRIV(evax_buf);
  390.       if (evax_buf == 0)
  391.     {
  392. #if EVAX_DEBUG
  393.       evax_debug (9, "can't realloc evax_buf to %d bytes\n", PRIV(rec_length));
  394. #endif
  395.       bfd_set_error (bfd_error_no_memory);
  396.       return -1;
  397.     }
  398.       PRIV(buf_size) = PRIV(rec_length);
  399.     }
  400.  
  401.   /* read the remaining record  */
  402.  
  403.   remaining = PRIV(rec_length) - test_len + test_start;
  404.  
  405.   if (bfd_read (evax_buf + test_len, 1, remaining, abfd) != remaining)
  406.     {
  407. #if EVAX_DEBUG
  408.       evax_debug (9, "can't bfd_read remaining %d bytes\n", remaining);
  409. #endif
  410.       bfd_set_error (bfd_error_file_truncated);
  411.       return 0;
  412.     }
  413.  
  414.   PRIV(evax_rec) = evax_buf + test_start;
  415.  
  416.   return PRIV(rec_length);
  417. }
  418.  
  419.  
  420. /* get next EVAX record from file
  421.    update evax_rec and rec_length to new (remaining) values  */
  422.  
  423. int
  424. _bfd_evax_next_record (abfd)
  425.      bfd *abfd;
  426. {
  427. #if EVAX_DEBUG
  428.   evax_debug (8, "_bfd_evax_next_record (len %d, size %d)\n",
  429.           PRIV(rec_length), PRIV(rec_size));
  430. #endif
  431.  
  432.   if (PRIV(rec_length) > 0)
  433.     {
  434.       PRIV(evax_rec) += PRIV(rec_size);
  435.     }
  436.   else
  437.     {
  438.       if (_bfd_evax_get_record (abfd) <= 0)
  439.     return -1;
  440.     }
  441.   _bfd_evax_get_header_values (abfd, PRIV(evax_rec), &PRIV(rec_type),
  442.                    &PRIV(rec_size));
  443.   PRIV(rec_length) -= PRIV(rec_size);
  444.  
  445. #if EVAX_DEBUG
  446.   evax_debug (8, "_bfd_evax_next_record: rec %p, size %d, length %d, type %d\n",
  447.           PRIV(evax_rec), PRIV(rec_size),    PRIV(rec_length),
  448.           PRIV(rec_type));
  449. #endif
  450.  
  451.   return PRIV(rec_type);
  452. }
  453.  
  454.  
  455.  
  456. /* Copy sized string (string with fixed length) to new allocated area
  457.    size is string length (size of record)  */
  458.  
  459. char *
  460. _bfd_evax_save_sized_string (str, size)
  461.      char *str;
  462.      int size;
  463. {
  464.   char *newstr = bfd_malloc (size + 1);
  465.  
  466.   if (newstr == NULL)
  467.     return 0;
  468.   strncpy (newstr, str, size);
  469.   newstr[size] = 0;
  470.  
  471.   return newstr;
  472. }
  473.  
  474. /* Copy counted string (string with length at first byte) to new allocated area
  475.    ptr points to length byte on entry  */
  476.  
  477. char *
  478. _bfd_evax_save_counted_string (ptr)
  479.      char *ptr;
  480. {
  481.   int len = *ptr++;
  482.  
  483.   return _bfd_evax_save_sized_string (ptr, len);
  484. }
  485.  
  486.  
  487. /* stack routines for EVAX ETIR commands */
  488.  
  489. /* Push value and section index  */
  490.  
  491. void
  492. _bfd_evax_push (abfd, val, psect)
  493.      bfd *abfd;
  494.      uquad val;
  495.      int psect;
  496. {
  497.   static int last_psect;
  498.  
  499. #if EVAX_DEBUG
  500.   evax_debug (4, "<push %016lx(%d) at %d>\n", val, psect, PRIV(stackptr));
  501. #endif
  502.  
  503.   if (psect >= 0)
  504.     last_psect = psect;
  505.  
  506.   PRIV(stack[PRIV(stackptr)]).value = val;
  507.   PRIV(stack[PRIV(stackptr)]).psect = last_psect;
  508.   PRIV(stackptr)++;
  509.   if (PRIV(stackptr) >= STACKSIZE)
  510.     {
  511.       bfd_set_error (bfd_error_bad_value);
  512.       exit(1);
  513.     }
  514.   return;
  515. }
  516.  
  517.  
  518. /* Pop value and section index  */
  519.  
  520. uquad
  521. _bfd_evax_pop (abfd, psect)
  522.      bfd *abfd;
  523.      int *psect;
  524. {
  525.   uquad value;
  526.  
  527.   if (PRIV(stackptr) == 0)
  528.     {
  529.       bfd_set_error (bfd_error_bad_value);
  530.       exit(1);
  531.     }
  532.   PRIV(stackptr)--;
  533.   value = PRIV(stack[PRIV(stackptr)]).value;
  534.   if ((psect != NULL) && (PRIV(stack[PRIV(stackptr)]).psect >= 0))
  535.     *psect = PRIV(stack[PRIV(stackptr)]).psect;
  536.  
  537. #if EVAX_DEBUG
  538.   evax_debug (4, "<pop %016lx(%d)>\n", value, PRIV(stack[PRIV(stackptr)]).psect);
  539. #endif
  540.  
  541.   return value;
  542. }
  543.  
  544.  
  545. /* object file output functions */
  546.  
  547. /* GAS tends to write sections in little chunks (bfd_set_section_contents)
  548.    which we can't use directly. So we save the little chunks in linked
  549.    lists (one per section) and write them later.  */
  550.  
  551. /* Add a new evax_section structure to evax_section_table
  552.    - forward chaining -  */
  553.  
  554. static evax_section *
  555. add_new_contents (abfd, section)
  556.      bfd *abfd;
  557.      sec_ptr section;
  558. {
  559.   evax_section *sptr, *newptr;
  560.  
  561.   newptr = (evax_section *) bfd_zalloc (abfd, sizeof (evax_section));
  562.   if (newptr == (evax_section *)NULL)
  563.     {
  564.       bfd_set_error (bfd_error_no_memory);
  565.       return NULL;
  566.     }
  567.   sptr = PRIV(evax_section_table)[section->index];
  568.   if (sptr == NULL)
  569.     {
  570.       PRIV(evax_section_table)[section->index] = (evax_section *)newptr;
  571.     }
  572.   else
  573.     {
  574.       while (sptr->next != NULL)
  575.     sptr = sptr->next;
  576.       sptr->next = newptr;
  577.     }
  578.   return newptr;
  579. }
  580.  
  581.  
  582. /* Save section data & offset to an evax_section structure
  583.    evax_section_table[] holds the evax_section chain  */
  584.  
  585. boolean
  586. _bfd_save_evax_section (abfd, section, data, offset, count)
  587.      bfd *abfd;
  588.      sec_ptr section;
  589.      PTR data;
  590.      file_ptr offset;
  591.      bfd_size_type count;
  592. {
  593.   evax_section *sptr;
  594.  
  595.   if (section->index >= EVAX_SECTION_COUNT)
  596.     {
  597.       bfd_set_error (bfd_error_nonrepresentable_section);
  598.       return false;
  599.     }
  600.   if (count == (bfd_size_type)0)
  601.     return true;
  602.   sptr = add_new_contents (abfd, section);
  603.   if (sptr == NULL)
  604.     return false;
  605.   sptr->contents = (unsigned char *) bfd_alloc (abfd, (int)count);
  606.   if (sptr->contents == (unsigned char *)NULL)
  607.     {
  608.       bfd_set_error (bfd_error_no_memory);
  609.       return false;
  610.     }
  611.   memcpy (sptr->contents, data, (int)count);
  612.   sptr->offset = (bfd_vma)offset;
  613.   sptr->size = count;
  614.  
  615. #if EVAX_DEBUG
  616.   evax_debug (6, "_bfd_save_evax_section sptr = %08lx\n", sptr);
  617.   _bfd_hexdump (6, data, count, (int)offset);
  618. #endif
  619.  
  620.   return true;
  621. }
  622.  
  623.  
  624. /* Get evax_section pointer to saved contents for section # index  */
  625.  
  626. evax_section *
  627. _bfd_get_evax_section (abfd, index)
  628.      bfd *abfd;
  629.      int index;
  630. {
  631.   if (index >=  EVAX_SECTION_COUNT)
  632.     {
  633.       bfd_set_error (bfd_error_nonrepresentable_section);
  634.       return NULL;
  635.     }
  636.   return PRIV(evax_section_table)[index];
  637. }
  638.  
  639.  
  640. /* Object output routines  */
  641.  
  642. /* Begin new record or record header
  643.    write 2 bytes rectype
  644.    write 2 bytes record length (filled in at flush)
  645.    write 2 bytes header type (ommitted if rechead == -1)  */
  646.  
  647. void
  648. _bfd_evax_output_begin (abfd, rectype, rechead)
  649.      bfd *abfd;
  650.      int rectype;
  651.      int rechead;
  652. {
  653. #if EVAX_DEBUG
  654.   evax_debug (6, "_bfd_evax_output_begin(type %d, head %d)\n", rectype,
  655.           rechead);
  656. #endif
  657.  
  658.   _bfd_evax_output_short (abfd,rectype);
  659.  
  660.   /* save current output position to fill in lenght later  */
  661.  
  662.   if (PRIV(push_level) > 0)
  663.     PRIV(length_pos) = PRIV(output_size);
  664.  
  665. #if EVAX_DEBUG
  666.   evax_debug (6, "_bfd_evax_output_begin: length_pos = %d\n",
  667.           PRIV(length_pos));
  668. #endif
  669.  
  670.   _bfd_evax_output_short (abfd,0);        /* placeholder for length */
  671.  
  672.   if (rechead != -1)
  673.     _bfd_evax_output_short (abfd,rechead);
  674.  
  675.   return;
  676. }
  677.  
  678.  
  679. /* Set record/subrecord alignment  */
  680.  
  681. void
  682. _bfd_evax_output_alignment (abfd, alignto)
  683.      bfd *abfd;
  684.      int alignto;
  685. {
  686. #if EVAX_DEBUG
  687.   evax_debug (6, "_bfd_evax_output_alignment(%d)\n", alignto);
  688. #endif
  689.  
  690.   PRIV(output_alignment) = alignto;
  691.   return;
  692. }
  693.  
  694.  
  695. /* Prepare for subrecord fields  */
  696.  
  697. void
  698. _bfd_evax_output_push (abfd)
  699.      bfd *abfd;
  700. {
  701. #if EVAX_DEBUG
  702.   evax_debug (6, "evax_output_push(pushed_size = %d)\n", PRIV(output_size));
  703. #endif
  704.  
  705.   PRIV(push_level)++;
  706.   PRIV(pushed_size) = PRIV(output_size);
  707.   return;
  708. }
  709.  
  710.  
  711. /* End of subrecord fields  */
  712.  
  713. void
  714. _bfd_evax_output_pop (abfd)
  715.      bfd *abfd;
  716. {
  717. #if EVAX_DEBUG
  718.   evax_debug (6, "evax_output_pop(pushed_size = %d)\n", PRIV(pushed_size));
  719. #endif
  720.  
  721.   _bfd_evax_output_flush (abfd);
  722.   PRIV(length_pos) = 2;
  723.  
  724. #if EVAX_DEBUG
  725.   evax_debug (6, "evax_output_pop: length_pos = %d\n", PRIV(length_pos));
  726. #endif
  727.  
  728.   PRIV(pushed_size) = 0;
  729.   PRIV(push_level)--;
  730.   return;
  731. }
  732.  
  733.  
  734. /* Flush unwritten output, ends current record  */
  735.  
  736. void
  737. _bfd_evax_output_flush (abfd)
  738.      bfd *abfd;
  739. {
  740.   int real_size = PRIV(output_size);
  741.   int aligncount;
  742.   int length;
  743.  
  744. #if EVAX_DEBUG
  745.   evax_debug (6, "_bfd_evax_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n",
  746.           real_size, PRIV(pushed_size), PRIV(length_pos));
  747. #endif
  748.  
  749.   if (PRIV(push_level) > 0)
  750.     length = real_size - PRIV(pushed_size);
  751.   else
  752.     length = real_size;
  753.  
  754.   if (length == 0)
  755.     return;
  756.   aligncount = (PRIV(output_alignment)
  757.         - (length % PRIV(output_alignment))) % PRIV(output_alignment);
  758.  
  759. #if EVAX_DEBUG
  760.   evax_debug (6, "align: adding %d bytes\n", aligncount);
  761. #endif
  762.  
  763.   while(aligncount-- > 0)
  764.     {
  765.       PRIV(output_buf)[real_size++] = 0;
  766. #if 0
  767.       /* this is why I *love* vms: inconsistency :-}
  768.      alignment is added to the subrecord length
  769.      but not to the record length  */
  770.       if (PRIV(push_level) > 0)
  771. #endif
  772.     length++;
  773.     }
  774.  
  775.   /* put length to buffer  */
  776.   PRIV(output_size) = PRIV(length_pos);
  777.   _bfd_evax_output_short (abfd, (unsigned int)length);
  778.  
  779.   if (PRIV(push_level) == 0)
  780.     {
  781. #ifndef VMS
  782.     /* write length first, see FF_FOREIGN in the input routines */
  783.       fwrite (PRIV(output_buf)+2, 2, 1, (FILE *)abfd->iostream);
  784. #endif
  785.       fwrite (PRIV(output_buf), real_size, 1, (FILE *)abfd->iostream);
  786.  
  787.       PRIV(output_size) = 0;
  788.     }
  789.   else
  790.     {
  791.       PRIV(output_size) = real_size;
  792.       PRIV(pushed_size) = PRIV(output_size);
  793.     }
  794.  
  795.   return;
  796. }
  797.  
  798.  
  799. /* End record output  */
  800.  
  801. void
  802. _bfd_evax_output_end (abfd)
  803.      bfd *abfd;
  804. {
  805. #if EVAX_DEBUG
  806.   evax_debug (6, "_bfd_evax_output_end\n");
  807. #endif
  808.  
  809.   _bfd_evax_output_flush (abfd);
  810.  
  811.   return;
  812. }
  813.  
  814.  
  815. /* check remaining buffer size
  816.  
  817.    return what's left.  */
  818.  
  819. int
  820. _bfd_evax_output_check (abfd, size)
  821.     bfd *abfd;
  822.     int size;
  823. {
  824. #if EVAX_DEBUG
  825.   evax_debug (6, "_bfd_evax_output_check(%d)\n", size);
  826. #endif
  827.  
  828.   return (MAX_OUTREC_SIZE - (PRIV(output_size) + size + MIN_OUTREC_LUFT));
  829. }
  830.  
  831.  
  832. /* Output byte (8 bit) value  */
  833.  
  834. void
  835. _bfd_evax_output_byte (abfd, value)
  836.      bfd *abfd;
  837.      unsigned int value;
  838. {
  839. #if EVAX_DEBUG
  840.   evax_debug (6, "_bfd_evax_output_byte(%02x)\n", value);
  841. #endif
  842.  
  843.   bfd_put_8 (abfd, value & 0xff, PRIV(output_buf) + PRIV(output_size));
  844.   PRIV(output_size) += 1;
  845.   return;
  846. }
  847.  
  848.  
  849. /* Output short (16 bit) value  */
  850.  
  851. void
  852. _bfd_evax_output_short (abfd, value)
  853.      bfd *abfd;
  854.      unsigned int value;
  855. {
  856. #if EVAX_DEBUG
  857.   evax_debug (6, "_bfd_evax_output_short (%04x)\n", value);
  858. #endif
  859.  
  860.   bfd_put_16 (abfd, value & 0xffff, PRIV(output_buf) + PRIV(output_size));
  861.   PRIV(output_size) += 2;
  862.   return;
  863. }
  864.  
  865.  
  866. /* Output long (32 bit) value  */
  867.  
  868. void
  869. _bfd_evax_output_long (abfd, value)
  870.      bfd *abfd;
  871.      unsigned long value;
  872. {
  873. #if EVAX_DEBUG
  874.   evax_debug (6, "_bfd_evax_output_long (%08lx)\n", value);
  875. #endif
  876.  
  877.   bfd_put_32 (abfd, value, PRIV(output_buf) + PRIV(output_size));
  878.   PRIV(output_size) += 4;
  879.   return;
  880. }
  881.  
  882.  
  883. /* Output quad (64 bit) value  */
  884.  
  885. void
  886. _bfd_evax_output_quad (abfd, value)
  887.      bfd *abfd;
  888.      uquad value;
  889. {
  890. #if EVAX_DEBUG
  891.   evax_debug (6, "_bfd_evax_output_quad(%016lx)\n", value);
  892. #endif
  893.  
  894.   bfd_put_64(abfd, value, PRIV(output_buf) + PRIV(output_size));
  895.   PRIV(output_size) += 8;
  896.   return;
  897. }
  898.  
  899.  
  900. /* Output c-string as counted string  */
  901.  
  902. void
  903. _bfd_evax_output_counted (abfd, value)
  904.      bfd *abfd;
  905.      char *value;
  906. {
  907. int len;
  908.  
  909. #if EVAX_DEBUG
  910.   evax_debug (6, "_bfd_evax_output_counted(%s)\n", value);
  911. #endif
  912.  
  913.   len = strlen (value);
  914.   if (len == 0)
  915.     {
  916.       (*_bfd_error_handler) ("_bfd_evax_output_counted called with zero bytes");
  917.       return;
  918.     }
  919.   if (len > 255)
  920.     {
  921.       (*_bfd_error_handler) ("_bfd_evax_output_counted called with too many bytes");
  922.       return;
  923.     }
  924.   _bfd_evax_output_byte (abfd, len & 0xff);
  925.   _bfd_evax_output_dump (abfd, (unsigned char *)value, len);
  926. }
  927.  
  928.  
  929. /* Output character area  */
  930.  
  931. void
  932. _bfd_evax_output_dump (abfd, data, length)
  933.      bfd *abfd;
  934.      unsigned char *data;
  935.      int length;
  936. {
  937. #if EVAX_DEBUG
  938.   evax_debug (6, "_bfd_evax_output_dump(%d)\n", length);
  939. #endif
  940.  
  941.   if (length == 0)
  942.     return;
  943.  
  944.   memcpy (PRIV(output_buf) + PRIV(output_size), data, length);
  945.   PRIV(output_size) += length;
  946.  
  947.   return;
  948. }
  949.  
  950.  
  951. /* Output count bytes of value  */
  952.  
  953. void
  954. _bfd_evax_output_fill (abfd, value, count)
  955.      bfd *abfd;
  956.      int value;
  957.      int count;
  958. {
  959. #if EVAX_DEBUG
  960.   evax_debug (6, "_bfd_evax_output_fill(val %02x times %d)\n", value, count);
  961. #endif
  962.  
  963.   if (count == 0)
  964.     return;
  965.   memset (PRIV(output_buf) + PRIV(output_size), value, count);
  966.   PRIV(output_size) += count;
  967.  
  968.   return;
  969. }
  970.  
  971. /*-----------------------------------------------------------------------------*/
  972.  
  973. /* Return basename (stripped of directory information) of filename  */
  974.  
  975. char *
  976. _bfd_evax_basename (name)
  977.      char *name;
  978. {
  979.   char *ptr;
  980.  
  981. #if EVAX_DEBUG
  982.   evax_debug (6, "_bfd_evax_basename %s -> ", name);
  983. #endif
  984.  
  985. #ifndef VMS
  986.   /* assume unix host */
  987.   ptr = strrchr (name, '.');
  988.   if (ptr)
  989.     *ptr = 0;
  990.   ptr = strrchr (name, '/');
  991.   if (ptr)
  992.     *ptr++ = 0;
  993.   else
  994.     ptr = name;
  995. #else
  996.   /* assume vms host */
  997.   ptr = strrchr (name, '.');
  998.   if (ptr)
  999.     {
  1000.       *ptr = 0;
  1001.       ptr = name;
  1002.     }
  1003.   else
  1004.     {
  1005.       ptr = strrchr (name, ']');
  1006.       if (ptr)
  1007.     *ptr++ = 0;
  1008.       else
  1009.     {
  1010.       ptr = strrchr (name, ':');
  1011.       if (ptr)
  1012.         *ptr++ = 0;
  1013.       else
  1014.         ptr = name;
  1015.     }
  1016.     }
  1017. #endif
  1018.  
  1019. #if EVAX_DEBUG
  1020.   evax_debug (6, "%s\n", ptr);
  1021. #endif
  1022.  
  1023.   return ptr;
  1024. }
  1025.  
  1026.  
  1027. /* Manufacure a VMS like time on a unix based system.
  1028.    stolen from obj-vms.c  */
  1029.  
  1030. char *
  1031. _bfd_get_vms_time_string ()
  1032. {
  1033.   static char tbuf[18];
  1034. #ifndef VMS
  1035. #include <sys/types.h>
  1036. #include <time.h>
  1037.  
  1038.   char *pnt;
  1039.   time_t timeb;
  1040.   time (&timeb);
  1041.   pnt = ctime (&timeb);
  1042.   pnt[3] = 0;
  1043.   pnt[7] = 0;
  1044.   pnt[10] = 0;
  1045.   pnt[16] = 0;
  1046.   pnt[24] = 0;
  1047.   sprintf (tbuf, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
  1048. #else
  1049. #include <starlet.h>
  1050.   struct
  1051.   {
  1052.     int Size;
  1053.     char *Ptr;
  1054.   } Descriptor;
  1055.   Descriptor.Size = 17;
  1056.   Descriptor.Ptr = tbuf;
  1057.   sys$asctim (0, &Descriptor, 0, 0);
  1058. #endif /* not VMS */
  1059.  
  1060. #if EVAX_DEBUG
  1061.   evax_debug (6, "vmstimestring:'%s'\n", tbuf);
  1062. #endif
  1063.  
  1064.   return tbuf;
  1065. }
  1066.