summaryrefslogtreecommitdiff
path: root/bfd/vms-misc.c
diff options
context:
space:
mode:
authorTristan Gingold <gingold@adacore.com>2010-04-01 09:47:13 +0000
committerTristan Gingold <gingold@adacore.com>2010-04-01 09:47:13 +0000
commit053dc88b3991f981f5b0611ea2dc1463e4f584fc (patch)
treee24d38ce706abd8ea3b41915e71281630d6627e0 /bfd/vms-misc.c
parent9e6a0106accda9d9485485a9d074eb0ec6230ae7 (diff)
downloadbinutils-redhat-053dc88b3991f981f5b0611ea2dc1463e4f584fc.tar.gz
2010-04-01 Tristan Gingold <gingold@adacore.com>
* vms.h: Include time.h. Add prototypes for vms_get_module_name, vms_time_to_time_t and vms_rawtime_to_time_t. * vms.c (vms_alpha_vec): Add archives support. * vms-misc.c: Include safe-ctype.h (vms_get_module_name): New function. (vms_time_to_time_t, vms_rawtime_to_time_t): Ditto. * vms-hdr.c (_bfd_vms_write_hdr): Put module name creation to the vms_get_module_name function. Use this function. * targets.c: Declare vms_lib_txt_vec. Add it to _bfd_target_vector. * libbfd-in.h: Add prototype for _bfd_append_relative_path. Add prototypes for vms-lib.c * libbfd.h: Regenerate. * configure.in (TDEFINES): Add an entry for vms_lib_txt_vec. Add vms-lib.lo to vms_alpha_vec. * config.bfd (targ_cpu): Add targ_selvecs for alpha*-*-*vms*. * configure: Regenerate. * bfd.c: Add selective_search field. * bfd-in2.h: Regenerate. * archive.c (append_relative_path): Rename to _bfd_append_relative_path and make it public. (_bfd_get_elt_at_filepos): Adjust for above renaming. * Makefile.am (BFD32_BACKENDS): Add vms-lib.lo (BFD32_BACKENDS_CFILES): Add vms-lib.c * Makefile.in: Regenerate.
Diffstat (limited to 'bfd/vms-misc.c')
-rw-r--r--bfd/vms-misc.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/bfd/vms-misc.c b/bfd/vms-misc.c
index 47e598559b..96463243b2 100644
--- a/bfd/vms-misc.c
+++ b/bfd/vms-misc.c
@@ -30,6 +30,7 @@
#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
+#include "safe-ctype.h"
#include "vms.h"
@@ -1045,3 +1046,93 @@ _bfd_vms_enter_symbol (bfd * abfd, char *name)
#endif
return entry;
}
+
+/* Create module name from filename (ie, extract the basename and convert it
+ in upper cases). Works on both VMS and UNIX pathes.
+ The result has to be free(). */
+
+char *
+vms_get_module_name (const char *filename, bfd_boolean upcase)
+{
+ char *fname, *fptr;
+ const char *fout;
+
+ /* Strip VMS path. */
+ fout = strrchr (filename, ']');
+ if (fout == NULL)
+ fout = strchr (filename, ':');
+ if (fout != NULL)
+ fout++;
+ else
+ fout = filename;
+
+ /* Strip UNIX path. */
+ fptr = strrchr (fout, '/');
+ if (fptr != NULL)
+ fout = fptr + 1;
+
+ fname = strdup (fout);
+
+ /* Strip suffix. */
+ fptr = strrchr (fname, '.');
+ if (fptr != 0)
+ *fptr = 0;
+
+ /* Convert to upper case and truncate at 31 characters.
+ (VMS object file format restricts module name length to 31). */
+ fptr = fname;
+ for (fptr = fname; *fptr != 0; fptr++)
+ {
+ if (*fptr == ';' || (fptr - fname) >= 31)
+ {
+ *fptr = 0;
+ break;
+ }
+ if (upcase)
+ *fptr = TOUPPER (*fptr);
+ }
+ return fname;
+}
+
+/* Convert a raw VMS time to a unix time. */
+
+time_t
+vms_time_to_time_t (unsigned int hi, unsigned int lo)
+{
+ const unsigned int off = 3506716800U;
+ const unsigned int factor = 10000000;
+ unsigned int tmp;
+ unsigned int rlo;
+ int i;
+
+ /* First convert to seconds. */
+ tmp = hi % factor;
+ hi = hi / factor;
+ rlo = 0;
+ for (i = 0; i < 4; i++)
+ {
+ tmp = (tmp << 8) | (lo >> 24);
+ lo <<= 8;
+
+ rlo = (rlo << 8) | (tmp / factor);
+ tmp %= factor;
+ }
+ lo = rlo;
+
+ /* Return 0 in case of overflow. */
+ if (lo > off && hi > 1)
+ return 0;
+
+ return lo - off;
+}
+
+/* Convert a raw (stored in a buffer) VMS time to a unix time. */
+
+time_t
+vms_rawtime_to_time_t (unsigned char *buf)
+{
+ unsigned int hi = bfd_getl32 (buf + 4);
+ unsigned int lo = bfd_getl32 (buf + 0);
+
+ return vms_time_to_time_t (hi, lo);
+}