OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gdb-7.2/] [gdb-7.2-or32-1.0rc1/] [bfd/] [vms-misc.c] - Diff between revs 330 and 341

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 330 Rev 341
/* vms-misc.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
/* vms-misc.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
   EVAX (openVMS/Alpha) files.
   EVAX (openVMS/Alpha) files.
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
   2007, 2008, 2009, 2010  Free Software Foundation, Inc.
   2007, 2008, 2009, 2010  Free Software Foundation, Inc.
 
 
   Miscellaneous functions.
   Miscellaneous functions.
 
 
   Written by Klaus K"ampf (kkaempf@rmi.de)
   Written by Klaus K"ampf (kkaempf@rmi.de)
 
 
   This program is free software; you can redistribute it and/or modify
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */
   MA 02110-1301, USA.  */
 
 
#if __STDC__
#if __STDC__
#include <stdarg.h>
#include <stdarg.h>
#endif
#endif
 
 
#include "sysdep.h"
#include "sysdep.h"
#include "bfd.h"
#include "bfd.h"
#include "bfdlink.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "libbfd.h"
#include "safe-ctype.h"
#include "safe-ctype.h"
 
 
#ifdef VMS
#ifdef VMS
#define __NEW_STARLET
#define __NEW_STARLET
#include <rms.h>
#include <rms.h>
#include <unixlib.h>
#include <unixlib.h>
#include <gen64def.h>
#include <gen64def.h>
#include <starlet.h>
#include <starlet.h>
#define RME$C_SETRFM 0x00000001
#define RME$C_SETRFM 0x00000001
#include <unistd.h>
#include <unistd.h>
#endif
#endif
#include <time.h>
#include <time.h>
 
 
#include "vms.h"
#include "vms.h"
#include "vms/emh.h"
#include "vms/emh.h"
 
 
#if VMS_DEBUG
#if VMS_DEBUG
/* Debug functions.  */
/* Debug functions.  */
 
 
/* Debug function for all vms extensions evaluates environment
/* Debug function for all vms extensions evaluates environment
   variable VMS_DEBUG for a numerical value on the first call all
   variable VMS_DEBUG for a numerical value on the first call all
   error levels below this value are printed:
   error levels below this value are printed:
 
 
   Levels:
   Levels:
   1    toplevel bfd calls (functions from the bfd vector)
   1    toplevel bfd calls (functions from the bfd vector)
   2    functions called by bfd calls
   2    functions called by bfd calls
   ...
   ...
   9    almost everything
   9    almost everything
 
 
   Level is also indentation level. Indentation is performed
   Level is also indentation level. Indentation is performed
   if level > 0.  */
   if level > 0.  */
 
 
void
void
_bfd_vms_debug (int level, char *format, ...)
_bfd_vms_debug (int level, char *format, ...)
{
{
  static int min_level = -1;
  static int min_level = -1;
  static FILE *output = NULL;
  static FILE *output = NULL;
  char *eptr;
  char *eptr;
  va_list args;
  va_list args;
  int abslvl = (level > 0) ? level : - level;
  int abslvl = (level > 0) ? level : - level;
 
 
  if (min_level == -1)
  if (min_level == -1)
    {
    {
      if ((eptr = getenv ("VMS_DEBUG")) != NULL)
      if ((eptr = getenv ("VMS_DEBUG")) != NULL)
        {
        {
          min_level = atoi (eptr);
          min_level = atoi (eptr);
          output = stderr;
          output = stderr;
        }
        }
      else
      else
        min_level = 0;
        min_level = 0;
    }
    }
  if (output == NULL)
  if (output == NULL)
    return;
    return;
  if (abslvl > min_level)
  if (abslvl > min_level)
    return;
    return;
 
 
  while (--level > 0)
  while (--level > 0)
    fprintf (output, " ");
    fprintf (output, " ");
  va_start (args, format);
  va_start (args, format);
  vfprintf (output, format, args);
  vfprintf (output, format, args);
  fflush (output);
  fflush (output);
  va_end (args);
  va_end (args);
}
}
 
 
/* A debug function
/* A debug function
   hex dump 'size' bytes starting at 'ptr'.  */
   hex dump 'size' bytes starting at 'ptr'.  */
 
 
void
void
_bfd_hexdump (int level, unsigned char *ptr, int size, int offset)
_bfd_hexdump (int level, unsigned char *ptr, int size, int offset)
{
{
  unsigned char *lptr = ptr;
  unsigned char *lptr = ptr;
  int count = 0;
  int count = 0;
  long start = offset;
  long start = offset;
 
 
  while (size-- > 0)
  while (size-- > 0)
    {
    {
      if ((count % 16) == 0)
      if ((count % 16) == 0)
        vms_debug (level, "%08lx:", start);
        vms_debug (level, "%08lx:", start);
      vms_debug (-level, " %02x", *ptr++);
      vms_debug (-level, " %02x", *ptr++);
      count++;
      count++;
      start++;
      start++;
      if (size == 0)
      if (size == 0)
        {
        {
          while ((count % 16) != 0)
          while ((count % 16) != 0)
            {
            {
              vms_debug (-level, "   ");
              vms_debug (-level, "   ");
              count++;
              count++;
            }
            }
        }
        }
      if ((count % 16) == 0)
      if ((count % 16) == 0)
        {
        {
          vms_debug (-level, " ");
          vms_debug (-level, " ");
          while (lptr < ptr)
          while (lptr < ptr)
            {
            {
              vms_debug (-level, "%c", (*lptr < 32) ? '.' : *lptr);
              vms_debug (-level, "%c", (*lptr < 32) ? '.' : *lptr);
              lptr++;
              lptr++;
            }
            }
          vms_debug (-level, "\n");
          vms_debug (-level, "\n");
        }
        }
    }
    }
  if ((count % 16) != 0)
  if ((count % 16) != 0)
    vms_debug (-level, "\n");
    vms_debug (-level, "\n");
}
}
#endif
#endif


 
 
/* Copy sized string (string with fixed size) to new allocated area
/* Copy sized string (string with fixed size) to new allocated area
   size is string size (size of record)  */
   size is string size (size of record)  */
 
 
char *
char *
_bfd_vms_save_sized_string (unsigned char *str, int size)
_bfd_vms_save_sized_string (unsigned char *str, int size)
{
{
  char *newstr = bfd_malloc ((bfd_size_type) size + 1);
  char *newstr = bfd_malloc ((bfd_size_type) size + 1);
 
 
  if (newstr == NULL)
  if (newstr == NULL)
    return NULL;
    return NULL;
  memcpy (newstr, (char *) str, (size_t) size);
  memcpy (newstr, (char *) str, (size_t) size);
  newstr[size] = 0;
  newstr[size] = 0;
 
 
  return newstr;
  return newstr;
}
}
 
 
/* Copy counted string (string with size at first byte) to new allocated area
/* Copy counted string (string with size at first byte) to new allocated area
   ptr points to size byte on entry  */
   ptr points to size byte on entry  */
 
 
char *
char *
_bfd_vms_save_counted_string (unsigned char *ptr)
_bfd_vms_save_counted_string (unsigned char *ptr)
{
{
  int len = *ptr++;
  int len = *ptr++;
 
 
  return _bfd_vms_save_sized_string (ptr, len);
  return _bfd_vms_save_sized_string (ptr, len);
}
}


/* Object output routines.   */
/* Object output routines.   */
 
 
/* Begin new record.
/* Begin new record.
   Write 2 bytes rectype and 2 bytes record length.  */
   Write 2 bytes rectype and 2 bytes record length.  */
 
 
void
void
_bfd_vms_output_begin (struct vms_rec_wr *recwr, int rectype)
_bfd_vms_output_begin (struct vms_rec_wr *recwr, int rectype)
{
{
  vms_debug2 ((6, "_bfd_vms_output_begin (type %d)\n", rectype));
  vms_debug2 ((6, "_bfd_vms_output_begin (type %d)\n", rectype));
 
 
  /* Record must have been closed.  */
  /* Record must have been closed.  */
  BFD_ASSERT (recwr->size == 0);
  BFD_ASSERT (recwr->size == 0);
 
 
  _bfd_vms_output_short (recwr, (unsigned int) rectype);
  _bfd_vms_output_short (recwr, (unsigned int) rectype);
 
 
  /* Placeholder for length.  */
  /* Placeholder for length.  */
  _bfd_vms_output_short (recwr, 0);
  _bfd_vms_output_short (recwr, 0);
}
}
 
 
/* Begin new sub-record.
/* Begin new sub-record.
   Write 2 bytes rectype, and 2 bytes record length.  */
   Write 2 bytes rectype, and 2 bytes record length.  */
 
 
void
void
_bfd_vms_output_begin_subrec (struct vms_rec_wr *recwr, int rectype)
_bfd_vms_output_begin_subrec (struct vms_rec_wr *recwr, int rectype)
{
{
  vms_debug2 ((6, "_bfd_vms_output_begin_subrec (type %d)\n", rectype));
  vms_debug2 ((6, "_bfd_vms_output_begin_subrec (type %d)\n", rectype));
 
 
  /* Subrecord must have been closed.  */
  /* Subrecord must have been closed.  */
  BFD_ASSERT (recwr->subrec_offset == 0);
  BFD_ASSERT (recwr->subrec_offset == 0);
 
 
  /* Save start of subrecord offset.  */
  /* Save start of subrecord offset.  */
  recwr->subrec_offset = recwr->size;
  recwr->subrec_offset = recwr->size;
 
 
  /* Subrecord type.  */
  /* Subrecord type.  */
  _bfd_vms_output_short (recwr, (unsigned int) rectype);
  _bfd_vms_output_short (recwr, (unsigned int) rectype);
 
 
  /* Placeholder for length.  */
  /* Placeholder for length.  */
  _bfd_vms_output_short (recwr, 0);
  _bfd_vms_output_short (recwr, 0);
}
}
 
 
/* Set record/subrecord alignment.   */
/* Set record/subrecord alignment.   */
 
 
void
void
_bfd_vms_output_alignment (struct vms_rec_wr *recwr, int alignto)
_bfd_vms_output_alignment (struct vms_rec_wr *recwr, int alignto)
{
{
  vms_debug2 ((6, "_bfd_vms_output_alignment (%d)\n", alignto));
  vms_debug2 ((6, "_bfd_vms_output_alignment (%d)\n", alignto));
  recwr->align = alignto;
  recwr->align = alignto;
}
}
 
 
/* Align the size of the current record (whose length is LENGTH).
/* Align the size of the current record (whose length is LENGTH).
   Warning: this obviously changes the record (and the possible subrecord)
   Warning: this obviously changes the record (and the possible subrecord)
   length.  */
   length.  */
 
 
static void
static void
_bfd_vms_output_align (struct vms_rec_wr *recwr, unsigned int length)
_bfd_vms_output_align (struct vms_rec_wr *recwr, unsigned int length)
{
{
  unsigned int real_size = recwr->size;
  unsigned int real_size = recwr->size;
  unsigned int aligncount;
  unsigned int aligncount;
 
 
  /* Pad with 0 if alignment is required.  */
  /* Pad with 0 if alignment is required.  */
  aligncount = (recwr->align - (length % recwr->align)) % recwr->align;
  aligncount = (recwr->align - (length % recwr->align)) % recwr->align;
  vms_debug2 ((6, "align: adding %d bytes\n", aligncount));
  vms_debug2 ((6, "align: adding %d bytes\n", aligncount));
  while (aligncount-- > 0)
  while (aligncount-- > 0)
    recwr->buf[real_size++] = 0;
    recwr->buf[real_size++] = 0;
 
 
  recwr->size = real_size;
  recwr->size = real_size;
}
}
 
 
/* Ends current sub-record.  Set length field.  */
/* Ends current sub-record.  Set length field.  */
 
 
void
void
_bfd_vms_output_end_subrec (struct vms_rec_wr *recwr)
_bfd_vms_output_end_subrec (struct vms_rec_wr *recwr)
{
{
  int real_size = recwr->size;
  int real_size = recwr->size;
  int length;
  int length;
 
 
  /* Subrecord must be open.  */
  /* Subrecord must be open.  */
  BFD_ASSERT (recwr->subrec_offset != 0);
  BFD_ASSERT (recwr->subrec_offset != 0);
 
 
  length = real_size - recwr->subrec_offset;
  length = real_size - recwr->subrec_offset;
 
 
  if (length == 0)
  if (length == 0)
    return;
    return;
 
 
  _bfd_vms_output_align (recwr, length);
  _bfd_vms_output_align (recwr, length);
 
 
  /* Put length to buffer.  */
  /* Put length to buffer.  */
  bfd_putl16 ((bfd_vma) (recwr->size - recwr->subrec_offset),
  bfd_putl16 ((bfd_vma) (recwr->size - recwr->subrec_offset),
              recwr->buf + recwr->subrec_offset + 2);
              recwr->buf + recwr->subrec_offset + 2);
 
 
  /* Close the subrecord.  */
  /* Close the subrecord.  */
  recwr->subrec_offset = 0;
  recwr->subrec_offset = 0;
}
}
 
 
/* Ends current record (and write it).  */
/* Ends current record (and write it).  */
 
 
void
void
_bfd_vms_output_end (bfd *abfd, struct vms_rec_wr *recwr)
_bfd_vms_output_end (bfd *abfd, struct vms_rec_wr *recwr)
{
{
  vms_debug2 ((6, "_bfd_vms_output_end (size %u)\n", recwr->size));
  vms_debug2 ((6, "_bfd_vms_output_end (size %u)\n", recwr->size));
 
 
  /* Subrecord must have been closed.  */
  /* Subrecord must have been closed.  */
  BFD_ASSERT (recwr->subrec_offset == 0);
  BFD_ASSERT (recwr->subrec_offset == 0);
 
 
  if (recwr->size == 0)
  if (recwr->size == 0)
    return;
    return;
 
 
  _bfd_vms_output_align (recwr, recwr->size);
  _bfd_vms_output_align (recwr, recwr->size);
 
 
  /* Write the length word.  */
  /* Write the length word.  */
  bfd_putl16 ((bfd_vma) recwr->size, recwr->buf + 2);
  bfd_putl16 ((bfd_vma) recwr->size, recwr->buf + 2);
 
 
  /* File is open in undefined (UDF) format on VMS, but ultimately will be
  /* File is open in undefined (UDF) format on VMS, but ultimately will be
     converted to variable length (VAR) format.  VAR format has a length
     converted to variable length (VAR) format.  VAR format has a length
     word first which must be explicitly output in UDF format.  */
     word first which must be explicitly output in UDF format.  */
  /* So, first the length word.  */
  /* So, first the length word.  */
  bfd_bwrite (recwr->buf + 2, 2, abfd);
  bfd_bwrite (recwr->buf + 2, 2, abfd);
 
 
  /* Align.  */
  /* Align.  */
  if (recwr->size & 1)
  if (recwr->size & 1)
    recwr->buf[recwr->size++] = 0;
    recwr->buf[recwr->size++] = 0;
 
 
  /* Then the record.  */
  /* Then the record.  */
  bfd_bwrite (recwr->buf, (size_t) recwr->size, abfd);
  bfd_bwrite (recwr->buf, (size_t) recwr->size, abfd);
 
 
  recwr->size = 0;
  recwr->size = 0;
}
}
 
 
/* Check remaining buffer size.  Return what's left.  */
/* Check remaining buffer size.  Return what's left.  */
 
 
int
int
_bfd_vms_output_check (struct vms_rec_wr *recwr, int size)
_bfd_vms_output_check (struct vms_rec_wr *recwr, int size)
{
{
  vms_debug2 ((6, "_bfd_vms_output_check (%d)\n", size));
  vms_debug2 ((6, "_bfd_vms_output_check (%d)\n", size));
 
 
  return (MAX_OUTREC_SIZE - (recwr->size + size + MIN_OUTREC_LUFT));
  return (MAX_OUTREC_SIZE - (recwr->size + size + MIN_OUTREC_LUFT));
}
}
 
 
/* Output byte (8 bit) value.  */
/* Output byte (8 bit) value.  */
 
 
void
void
_bfd_vms_output_byte (struct vms_rec_wr *recwr, unsigned int value)
_bfd_vms_output_byte (struct vms_rec_wr *recwr, unsigned int value)
{
{
  vms_debug2 ((6, "_bfd_vms_output_byte (%02x)\n", value));
  vms_debug2 ((6, "_bfd_vms_output_byte (%02x)\n", value));
 
 
  *(recwr->buf + recwr->size) = value;
  *(recwr->buf + recwr->size) = value;
  recwr->size += 1;
  recwr->size += 1;
}
}
 
 
/* Output short (16 bit) value.  */
/* Output short (16 bit) value.  */
 
 
void
void
_bfd_vms_output_short (struct vms_rec_wr *recwr, unsigned int value)
_bfd_vms_output_short (struct vms_rec_wr *recwr, unsigned int value)
{
{
  vms_debug2 ((6, "_bfd_vms_output_short (%04x)\n", value));
  vms_debug2 ((6, "_bfd_vms_output_short (%04x)\n", value));
 
 
  bfd_putl16 ((bfd_vma) value & 0xffff, recwr->buf + recwr->size);
  bfd_putl16 ((bfd_vma) value & 0xffff, recwr->buf + recwr->size);
  recwr->size += 2;
  recwr->size += 2;
}
}
 
 
/* Output long (32 bit) value.  */
/* Output long (32 bit) value.  */
 
 
void
void
_bfd_vms_output_long (struct vms_rec_wr *recwr, unsigned long value)
_bfd_vms_output_long (struct vms_rec_wr *recwr, unsigned long value)
{
{
  vms_debug2 ((6, "_bfd_vms_output_long (%08lx)\n", value));
  vms_debug2 ((6, "_bfd_vms_output_long (%08lx)\n", value));
 
 
  bfd_putl32 ((bfd_vma) value, recwr->buf + recwr->size);
  bfd_putl32 ((bfd_vma) value, recwr->buf + recwr->size);
  recwr->size += 4;
  recwr->size += 4;
}
}
 
 
/* Output quad (64 bit) value.  */
/* Output quad (64 bit) value.  */
 
 
void
void
_bfd_vms_output_quad (struct vms_rec_wr *recwr, bfd_vma value)
_bfd_vms_output_quad (struct vms_rec_wr *recwr, bfd_vma value)
{
{
  vms_debug2 ((6, "_bfd_vms_output_quad (%08lx)\n", (unsigned long)value));
  vms_debug2 ((6, "_bfd_vms_output_quad (%08lx)\n", (unsigned long)value));
 
 
  bfd_putl64 (value, recwr->buf + recwr->size);
  bfd_putl64 (value, recwr->buf + recwr->size);
  recwr->size += 8;
  recwr->size += 8;
}
}
 
 
/* Output c-string as counted string.  */
/* Output c-string as counted string.  */
 
 
void
void
_bfd_vms_output_counted (struct vms_rec_wr *recwr, const char *value)
_bfd_vms_output_counted (struct vms_rec_wr *recwr, const char *value)
{
{
  int len;
  int len;
 
 
  vms_debug2 ((6, "_bfd_vms_output_counted (%s)\n", value));
  vms_debug2 ((6, "_bfd_vms_output_counted (%s)\n", value));
 
 
  len = strlen (value);
  len = strlen (value);
  if (len == 0)
  if (len == 0)
    {
    {
      (*_bfd_error_handler) (_("_bfd_vms_output_counted called with zero bytes"));
      (*_bfd_error_handler) (_("_bfd_vms_output_counted called with zero bytes"));
      return;
      return;
    }
    }
  if (len > 255)
  if (len > 255)
    {
    {
      (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes"));
      (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes"));
      return;
      return;
    }
    }
  _bfd_vms_output_byte (recwr, (unsigned int) len & 0xff);
  _bfd_vms_output_byte (recwr, (unsigned int) len & 0xff);
  _bfd_vms_output_dump (recwr, (const unsigned char *)value, len);
  _bfd_vms_output_dump (recwr, (const unsigned char *)value, len);
}
}
 
 
/* Output character area.  */
/* Output character area.  */
 
 
void
void
_bfd_vms_output_dump (struct vms_rec_wr *recwr, const unsigned char *data, int len)
_bfd_vms_output_dump (struct vms_rec_wr *recwr, const unsigned char *data, int len)
{
{
  vms_debug2 ((6, "_bfd_vms_output_dump (%d)\n", len));
  vms_debug2 ((6, "_bfd_vms_output_dump (%d)\n", len));
 
 
  if (len == 0)
  if (len == 0)
    return;
    return;
 
 
  memcpy (recwr->buf + recwr->size, data, (size_t) len);
  memcpy (recwr->buf + recwr->size, data, (size_t) len);
  recwr->size += len;
  recwr->size += len;
}
}
 
 
/* Output count bytes of value.  */
/* Output count bytes of value.  */
 
 
void
void
_bfd_vms_output_fill (struct vms_rec_wr *recwr, int value, int count)
_bfd_vms_output_fill (struct vms_rec_wr *recwr, int value, int count)
{
{
  vms_debug2 ((6, "_bfd_vms_output_fill (val %02x times %d)\n", value, count));
  vms_debug2 ((6, "_bfd_vms_output_fill (val %02x times %d)\n", value, count));
 
 
  if (count == 0)
  if (count == 0)
    return;
    return;
  memset (recwr->buf + recwr->size, value, (size_t) count);
  memset (recwr->buf + recwr->size, value, (size_t) count);
  recwr->size += count;
  recwr->size += count;
}
}
 
 
#ifdef VMS
#ifdef VMS
/* Convert the file to variable record length format. This is done
/* Convert the file to variable record length format. This is done
   using undocumented system call sys$modify().
   using undocumented system call sys$modify().
   Pure VMS version.  */
   Pure VMS version.  */
 
 
void
void
_bfd_vms_convert_to_var (char * vms_filename)
_bfd_vms_convert_to_var (char * vms_filename)
{
{
  struct FAB fab = cc$rms_fab;
  struct FAB fab = cc$rms_fab;
 
 
  fab.fab$l_fna = vms_filename;
  fab.fab$l_fna = vms_filename;
  fab.fab$b_fns = strlen (vms_filename);
  fab.fab$b_fns = strlen (vms_filename);
  fab.fab$b_fac = FAB$M_PUT;
  fab.fab$b_fac = FAB$M_PUT;
  fab.fab$l_fop = FAB$M_ESC;
  fab.fab$l_fop = FAB$M_ESC;
  fab.fab$l_ctx = RME$C_SETRFM;
  fab.fab$l_ctx = RME$C_SETRFM;
 
 
  sys$open (&fab);
  sys$open (&fab);
 
 
  fab.fab$b_rfm = FAB$C_VAR;
  fab.fab$b_rfm = FAB$C_VAR;
 
 
  sys$modify (&fab);
  sys$modify (&fab);
  sys$close (&fab);
  sys$close (&fab);
}
}
 
 
static int
static int
vms_convert_to_var_1 (char *filename, int type)
vms_convert_to_var_1 (char *filename, int type)
{
{
  if (type != DECC$K_FILE)
  if (type != DECC$K_FILE)
    return FALSE;
    return FALSE;
  vms_convert_to_var (filename);
  vms_convert_to_var (filename);
  return TRUE;
  return TRUE;
}
}
 
 
/* Convert the file to variable record length format. This is done
/* Convert the file to variable record length format. This is done
   using undocumented system call sys$modify().
   using undocumented system call sys$modify().
   Unix filename version.  */
   Unix filename version.  */
 
 
static int
static int
vms_convert_to_var_unix_filename (const char *unix_filename)
vms_convert_to_var_unix_filename (const char *unix_filename)
{
{
  if (decc$to_vms (unix_filename, &vms_convert_to_var_1, 0, 1) != 1)
  if (decc$to_vms (unix_filename, &vms_convert_to_var_1, 0, 1) != 1)
    return FALSE;
    return FALSE;
  return TRUE;
  return TRUE;
}
}
#endif /* VMS */
#endif /* VMS */
 
 
/* Manufacture a VMS like time on a unix based system.
/* Manufacture a VMS like time on a unix based system.
   stolen from obj-vms.c.  */
   stolen from obj-vms.c.  */
 
 
unsigned char *
unsigned char *
get_vms_time_string (void)
get_vms_time_string (void)
{
{
  static unsigned char tbuf[18];
  static unsigned char tbuf[18];
#ifndef VMS
#ifndef VMS
  char *pnt;
  char *pnt;
  time_t timeb;
  time_t timeb;
 
 
  time (& timeb);
  time (& timeb);
  pnt = ctime (&timeb);
  pnt = ctime (&timeb);
  pnt[3] = 0;
  pnt[3] = 0;
  pnt[7] = 0;
  pnt[7] = 0;
  pnt[10] = 0;
  pnt[10] = 0;
  pnt[16] = 0;
  pnt[16] = 0;
  pnt[24] = 0;
  pnt[24] = 0;
  sprintf ((char *) tbuf, "%2s-%3s-%s %s",
  sprintf ((char *) tbuf, "%2s-%3s-%s %s",
           pnt + 8, pnt + 4, pnt + 20, pnt + 11);
           pnt + 8, pnt + 4, pnt + 20, pnt + 11);
#else
#else
  struct
  struct
  {
  {
    int Size;
    int Size;
    unsigned char *Ptr;
    unsigned char *Ptr;
  } Descriptor;
  } Descriptor;
  Descriptor.Size = 17;
  Descriptor.Size = 17;
  Descriptor.Ptr = tbuf;
  Descriptor.Ptr = tbuf;
  SYS$ASCTIM (0, &Descriptor, 0, 0);
  SYS$ASCTIM (0, &Descriptor, 0, 0);
#endif /* not VMS */
#endif /* not VMS */
 
 
  vms_debug2 ((6, "vmstimestring:'%s'\n", tbuf));
  vms_debug2 ((6, "vmstimestring:'%s'\n", tbuf));
 
 
  return tbuf;
  return tbuf;
}
}
 
 
/* Create module name from filename (ie, extract the basename and convert it
/* Create module name from filename (ie, extract the basename and convert it
   in upper cases).  Works on both VMS and UNIX pathes.
   in upper cases).  Works on both VMS and UNIX pathes.
   The result has to be free().  */
   The result has to be free().  */
 
 
char *
char *
vms_get_module_name (const char *filename, bfd_boolean upcase)
vms_get_module_name (const char *filename, bfd_boolean upcase)
{
{
  char *fname, *fptr;
  char *fname, *fptr;
  const char *fout;
  const char *fout;
 
 
  /* Strip VMS path.  */
  /* Strip VMS path.  */
  fout = strrchr (filename, ']');
  fout = strrchr (filename, ']');
  if (fout == NULL)
  if (fout == NULL)
    fout = strchr (filename, ':');
    fout = strchr (filename, ':');
  if (fout != NULL)
  if (fout != NULL)
    fout++;
    fout++;
  else
  else
    fout = filename;
    fout = filename;
 
 
  /* Strip UNIX path.  */
  /* Strip UNIX path.  */
  fptr = strrchr (fout, '/');
  fptr = strrchr (fout, '/');
  if (fptr != NULL)
  if (fptr != NULL)
    fout = fptr + 1;
    fout = fptr + 1;
 
 
  fname = strdup (fout);
  fname = strdup (fout);
 
 
  /* Strip suffix.  */
  /* Strip suffix.  */
  fptr = strrchr (fname, '.');
  fptr = strrchr (fname, '.');
  if (fptr != 0)
  if (fptr != 0)
    *fptr = 0;
    *fptr = 0;
 
 
  /* Convert to upper case and truncate at 31 characters.
  /* Convert to upper case and truncate at 31 characters.
     (VMS object file format restricts module name length to 31).  */
     (VMS object file format restricts module name length to 31).  */
  fptr = fname;
  fptr = fname;
  for (fptr = fname; *fptr != 0; fptr++)
  for (fptr = fname; *fptr != 0; fptr++)
    {
    {
      if (*fptr == ';' || (fptr - fname) >= 31)
      if (*fptr == ';' || (fptr - fname) >= 31)
        {
        {
          *fptr = 0;
          *fptr = 0;
          break;
          break;
        }
        }
      if (upcase)
      if (upcase)
        *fptr = TOUPPER (*fptr);
        *fptr = TOUPPER (*fptr);
    }
    }
  return fname;
  return fname;
}
}
 
 
/* Compared to usual UNIX time_t, VMS time has less limits:
/* Compared to usual UNIX time_t, VMS time has less limits:
   -  64 bit (63 bits in fact as the MSB must be 0)
   -  64 bit (63 bits in fact as the MSB must be 0)
   -  100ns granularity
   -  100ns granularity
   -  epoch is Nov 17, 1858.
   -  epoch is Nov 17, 1858.
   Here has the constants and the routines used to convert VMS from/to UNIX time.
   Here has the constants and the routines used to convert VMS from/to UNIX time.
   The conversion routines don't assume 64 bits arithmetic.  */
   The conversion routines don't assume 64 bits arithmetic.  */
 
 
/* UNIX time granularity for VMS, ie 1s / 100ns.  */
/* UNIX time granularity for VMS, ie 1s / 100ns.  */
#define VMS_TIME_FACTOR 10000000
#define VMS_TIME_FACTOR 10000000
 
 
/* Number of seconds since VMS epoch of the UNIX epoch.  */
/* Number of seconds since VMS epoch of the UNIX epoch.  */
#define VMS_TIME_OFFSET 3506716800U
#define VMS_TIME_OFFSET 3506716800U
 
 
/* Convert a VMS time to a unix time.  */
/* Convert a VMS time to a unix time.  */
 
 
time_t
time_t
vms_time_to_time_t (unsigned int hi, unsigned int lo)
vms_time_to_time_t (unsigned int hi, unsigned int lo)
{
{
  unsigned int tmp;
  unsigned int tmp;
  unsigned int rlo;
  unsigned int rlo;
  int i;
  int i;
 
 
  /* First convert to seconds.  */
  /* First convert to seconds.  */
  tmp = hi % VMS_TIME_FACTOR;
  tmp = hi % VMS_TIME_FACTOR;
  hi = hi / VMS_TIME_FACTOR;
  hi = hi / VMS_TIME_FACTOR;
  rlo = 0;
  rlo = 0;
  for (i = 0; i < 4; i++)
  for (i = 0; i < 4; i++)
    {
    {
      tmp = (tmp << 8) | (lo >> 24);
      tmp = (tmp << 8) | (lo >> 24);
      lo <<= 8;
      lo <<= 8;
 
 
      rlo = (rlo << 8) | (tmp / VMS_TIME_FACTOR);
      rlo = (rlo << 8) | (tmp / VMS_TIME_FACTOR);
      tmp %= VMS_TIME_FACTOR;
      tmp %= VMS_TIME_FACTOR;
    }
    }
  lo = rlo;
  lo = rlo;
 
 
  /* Return 0 in case of overflow.  */
  /* Return 0 in case of overflow.  */
  if (lo > VMS_TIME_OFFSET && hi > 1)
  if (lo > VMS_TIME_OFFSET && hi > 1)
    return 0;
    return 0;
 
 
  /* Return 0 in case of underflow.  */
  /* Return 0 in case of underflow.  */
  if (lo < VMS_TIME_OFFSET)
  if (lo < VMS_TIME_OFFSET)
    return 0;
    return 0;
 
 
  return lo - VMS_TIME_OFFSET;
  return lo - VMS_TIME_OFFSET;
}
}
 
 
/* Convert a time_t to a VMS time.  */
/* Convert a time_t to a VMS time.  */
 
 
void
void
vms_time_t_to_vms_time (time_t ut, unsigned int *hi, unsigned int *lo)
vms_time_t_to_vms_time (time_t ut, unsigned int *hi, unsigned int *lo)
{
{
  unsigned short val[4];
  unsigned short val[4];
  unsigned short tmp[4];
  unsigned short tmp[4];
  unsigned int carry;
  unsigned int carry;
  int i;
  int i;
 
 
  /* Put into val.  */
  /* Put into val.  */
  val[0] = ut & 0xffff;
  val[0] = ut & 0xffff;
  val[1] = (ut >> 16) & 0xffff;
  val[1] = (ut >> 16) & 0xffff;
  val[2] = sizeof (ut) > 4 ? (ut >> 32) & 0xffff : 0;
  val[2] = sizeof (ut) > 4 ? (ut >> 32) & 0xffff : 0;
  val[3] = sizeof (ut) > 4 ? (ut >> 48) & 0xffff : 0;
  val[3] = sizeof (ut) > 4 ? (ut >> 48) & 0xffff : 0;
 
 
  /* Add offset.  */
  /* Add offset.  */
  tmp[0] = VMS_TIME_OFFSET & 0xffff;
  tmp[0] = VMS_TIME_OFFSET & 0xffff;
  tmp[1] = VMS_TIME_OFFSET >> 16;
  tmp[1] = VMS_TIME_OFFSET >> 16;
  tmp[2] = 0;
  tmp[2] = 0;
  tmp[3] = 0;
  tmp[3] = 0;
  carry = 0;
  carry = 0;
  for (i = 0; i < 4; i++)
  for (i = 0; i < 4; i++)
    {
    {
      carry += tmp[i] + val[i];
      carry += tmp[i] + val[i];
      val[i] = carry & 0xffff;
      val[i] = carry & 0xffff;
      carry = carry >> 16;
      carry = carry >> 16;
    }
    }
 
 
  /* Multiply by factor, well first by 10000 and then by 1000.  */
  /* Multiply by factor, well first by 10000 and then by 1000.  */
  carry = 0;
  carry = 0;
  for (i = 0; i < 4; i++)
  for (i = 0; i < 4; i++)
    {
    {
      carry += val[i] * 10000;
      carry += val[i] * 10000;
      val[i] = carry & 0xffff;
      val[i] = carry & 0xffff;
      carry = carry >> 16;
      carry = carry >> 16;
    }
    }
  carry = 0;
  carry = 0;
  for (i = 0; i < 4; i++)
  for (i = 0; i < 4; i++)
    {
    {
      carry += val[i] * 1000;
      carry += val[i] * 1000;
      val[i] = carry & 0xffff;
      val[i] = carry & 0xffff;
      carry = carry >> 16;
      carry = carry >> 16;
    }
    }
 
 
  /* Write the result.  */
  /* Write the result.  */
  *lo = val[0] | (val[1] << 16);
  *lo = val[0] | (val[1] << 16);
  *hi = val[2] | (val[3] << 16);
  *hi = val[2] | (val[3] << 16);
}
}
 
 
/* Convert a raw (stored in a buffer) VMS time to a unix time.  */
/* Convert a raw (stored in a buffer) VMS time to a unix time.  */
 
 
time_t
time_t
vms_rawtime_to_time_t (unsigned char *buf)
vms_rawtime_to_time_t (unsigned char *buf)
{
{
  unsigned int hi = bfd_getl32 (buf + 4);
  unsigned int hi = bfd_getl32 (buf + 4);
  unsigned int lo = bfd_getl32 (buf + 0);
  unsigned int lo = bfd_getl32 (buf + 0);
 
 
  return vms_time_to_time_t (hi, lo);
  return vms_time_to_time_t (hi, lo);
}
}
 
 
void
void
vms_get_time (unsigned int *hi, unsigned int *lo)
vms_get_time (unsigned int *hi, unsigned int *lo)
{
{
#ifdef VMS
#ifdef VMS
  struct _generic_64 t;
  struct _generic_64 t;
 
 
  sys$gettim (&t);
  sys$gettim (&t);
  *lo = t.gen64$q_quadword;
  *lo = t.gen64$q_quadword;
  *hi = t.gen64$q_quadword >> 32;
  *hi = t.gen64$q_quadword >> 32;
#else
#else
  time_t t;
  time_t t;
 
 
  time (&t);
  time (&t);
  vms_time_t_to_vms_time (t, hi, lo);
  vms_time_t_to_vms_time (t, hi, lo);
#endif
#endif
}
}
 
 
/* Get the current time into a raw buffer BUF.  */
/* Get the current time into a raw buffer BUF.  */
 
 
void
void
vms_raw_get_time (unsigned char *buf)
vms_raw_get_time (unsigned char *buf)
{
{
  unsigned int hi, lo;
  unsigned int hi, lo;
 
 
  vms_get_time (&hi, &lo);
  vms_get_time (&hi, &lo);
  bfd_putl32 (lo, buf + 0);
  bfd_putl32 (lo, buf + 0);
  bfd_putl32 (hi, buf + 4);
  bfd_putl32 (hi, buf + 4);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.