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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [vms/] [vms-ld.c] - Blame information for rev 720

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
/* VMS linker wrapper.
2
   Copyright (C) 2011 Free Software Foundation, Inc.
3
   Contributed by AdaCore
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3, or (at your option)
10
any later version.
11
 
12
GCC is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
20
 
21
/* This program is a wrapper around the VMS linker.
22
   It translates Unix style command line options into corresponding
23
   VMS style qualifiers and then spawns the VMS linker.
24
 
25
   It is possible to build this program on UNIX but only for the purpose of
26
   checking for errors.  */
27
 
28
#include <stdlib.h>
29
#include <string.h>
30
#include <unistd.h>
31
#include <stdio.h>
32
 
33
#include "libiberty.h"
34
#include <safe-ctype.h>
35
#include <sys/stat.h>
36
 
37
/* Macro for logicals.  */
38
#define LNM__STRING 2
39
#define LNM_C_NAMLENGTH 255
40
#define PSL_C_SUPER 2
41
#define PSL_C_USER 3
42
 
43
/* Local variable declarations.  */
44
static int ld_nocall_debug = 0;
45
static int ld_mkthreads = 0;
46
static int ld_upcalls = 0;
47
 
48
/* verbose = 1 if -v passed.  */
49
static int verbose = 0;
50
 
51
/* save_temps = 1 if -save-temps passed.  */
52
static int save_temps = 0;
53
 
54
/* By default don't generate executable file if there are errors
55
   in the link.  Override with --noinhibit-exec.  */
56
static int inhibit_exec = 1;
57
 
58
/* debug = 1 if -g passed.  */
59
static int debug = 0;
60
 
61
/* By default prefer to link with static libraries.  */
62
static int staticp = 1;
63
 
64
/* By default generate an executable, not a shareable image library.
65
   Override with -shared.  */
66
static int share = 0;
67
 
68
/* Linker command line.  */
69
static int link_cmd_maxlen = 0;
70
static char *link_cmd = 0;
71
static int link_cmd_len = 0;
72
 
73
/* Keep track of filenames.  */
74
static char *sharebasename;
75
static const char *exefullfilename;
76
static const char *exefilename;
77
 
78
/* Search dir list passed on command line (with -L).  */
79
static const char **search_dirs;
80
static int search_dirs_len;
81
 
82
/* Local function declarations.  */
83
static void addarg (const char *);
84
static int is_regular_file (char *);
85
static char *to_host_file_spec (char *);
86
static char *locate_lib (char *);
87
static const char *expand_lib (char *);
88
static void preprocess_args (int, char **);
89
static void process_args (int, char **);
90
static void maybe_set_link_compat (void);
91
static int set_exe (const char *);
92
#ifdef VMS
93
static int translate_unix (char *, int);
94
#endif
95
 
96
 
97
/* Append STR to the command line to invoke the linker.
98
   Expand the line as necessary to accommodate.  */
99
 
100
static void
101
addarg (const char *str)
102
{
103
  int l = strlen (str);
104
 
105
  /* Extend the line.  */
106
  if (link_cmd_len + l >= link_cmd_maxlen)
107
    {
108
      link_cmd_maxlen = link_cmd_len + l + 1024;
109
      link_cmd = XRESIZEVEC (char, link_cmd, link_cmd_maxlen);
110
    }
111
 
112
  memcpy (link_cmd + link_cmd_len, str, l);
113
  link_cmd_len += l;
114
}
115
 
116
/* Check to see if NAME is a regular file, i.e. not a directory.  */
117
 
118
static int
119
is_regular_file (char *name)
120
{
121
  int ret;
122
  struct stat statbuf;
123
 
124
  ret = stat (name, &statbuf);
125
  return !ret && S_ISREG (statbuf.st_mode);
126
}
127
 
128
#ifdef VMS
129
static char new_host_filespec [255];
130
static char filename_buff [256];
131
 
132
/* Action routine called by decc$to_vms.  NAME is a file name or
133
   directory name.  TYPE is unused.  */
134
 
135
static int
136
translate_unix (char *name, int type ATTRIBUTE_UNUSED)
137
{
138
  strcpy (filename_buff, name);
139
  return 0;
140
}
141
#endif
142
 
143
/* Translate a Unix syntax file specification FILESPEC into VMS syntax.
144
   If indicators of VMS syntax found, return input string.
145
   Return a pointer to a static buffer.  */
146
 
147
static char *
148
to_host_file_spec (char *filespec)
149
{
150
#ifdef VMS
151
  if (strchr (filespec, ']') || strchr (filespec, ':'))
152
    {
153
      /* Looks like a VMS path.  */
154
      return filespec;
155
    }
156
  else
157
    {
158
 
159
      strcpy (filename_buff, filespec);
160
      decc$to_vms (filespec, translate_unix, 1, 1);
161
      strcpy (new_host_filespec, filename_buff);
162
      return new_host_filespec;
163
    }
164
#else
165
  return filespec;
166
#endif
167
}
168
 
169
/* Locate library LIB_NAME on the library path.  */
170
 
171
static char *
172
locate_lib (char *lib_name)
173
{
174
  int lib_len = strlen (lib_name);
175
  const char *exts[3];
176
  int i;
177
 
178
  if (staticp)
179
    {
180
      /* For static links, look for shareable image libraries last.  */
181
      exts[0] = ".a";
182
      exts[1] = ".olb";
183
      exts[2] = ".exe";
184
    }
185
  else
186
    {
187
      exts[0] = ".exe";
188
      exts[1] = ".a";
189
      exts[2] = ".olb";
190
    }
191
 
192
  for (i = 0; i < search_dirs_len; i++)
193
    {
194
      char *buf;
195
      int l;
196
      int j;
197
 
198
      l = strlen (search_dirs[i]);
199
      buf = (char *)alloca (l + 4 + lib_len + 4 + 1);
200
      /* Put PATH/libLIB.  */
201
      memcpy (buf, search_dirs[i], l);
202
      memcpy (buf + l, "/lib", 4);
203
      l += 4;
204
      memcpy (buf + l, lib_name, lib_len);
205
      l += lib_len;
206
 
207
      /* Look for files with the extensions.  */
208
      for (j = 0; j < 3; j++)
209
        {
210
          strcpy (buf + l, exts[j]);
211
          if (is_regular_file (buf))
212
            return xstrdup (to_host_file_spec (buf));
213
        }
214
    }
215
 
216
  return NULL;
217
}
218
 
219
/* Given a library name NAME, i.e. foo,  Look for libfoo.lib and then
220
   libfoo.a in the set of directories we are allowed to search in.
221
   May return NULL if the library can be discarded.  */
222
 
223
static const char *
224
expand_lib (char *name)
225
{
226
  char *lib_path;
227
 
228
  /* Discard libc.  */
229
  if (strcmp (name, "c") == 0)
230
    return NULL;
231
 
232
  /* Discard libm.  No separate library for math functions.  */
233
  if (strcmp (name, "m") == 0)
234
    return NULL;
235
 
236
  /* Search on path.  */
237
  lib_path = locate_lib (name);
238
  if (lib_path)
239
    return lib_path;
240
 
241
  fprintf (stderr,
242
           "Couldn't locate library: lib%s.exe, lib%s.a or lib%s.olb\n",
243
           name, name, name);
244
 
245
  exit (EXIT_FAILURE);
246
}
247
 
248
/* Preprocess the number of args P_ARGC in ARGV.
249
   Look for special flags, etc. that must be handled first.  */
250
 
251
static void
252
preprocess_args (int argc, char **argv)
253
{
254
  int i;
255
 
256
  /* Scan for -shared.  */
257
  for (i = 1; i < argc; i++)
258
    if (strcmp (argv[i], "-shared") == 0)
259
      {
260
        share = 1;
261
        break;
262
      }
263
 
264
  for (i = 1; i < argc; i++)
265
    if (strcmp (argv[i], "-o") == 0)
266
      {
267
        int len;
268
 
269
        i++;
270
        exefilename = lbasename (argv[i]);
271
        exefullfilename = xstrdup (to_host_file_spec (argv[i]));
272
 
273
        if (share)
274
          addarg(" /share=");
275
        else
276
          addarg (" /exe=");
277
        addarg (exefullfilename);
278
 
279
        if (share)
280
          {
281
            char *ptr;
282
 
283
            /* Extract the basename.  */
284
            ptr = strchr (argv[i], ']');
285
            if (ptr == NULL)
286
              ptr = strchr (argv[i], ':');
287
            if (ptr == NULL)
288
              ptr = strchr (argv[i], '/');
289
            if (ptr == NULL)
290
              sharebasename = xstrdup (argv[i]);
291
            else
292
              sharebasename = xstrdup (ptr + 1);
293
 
294
            len = strlen (sharebasename);
295
            if (strncasecmp (&sharebasename[len-4], ".exe", 4) == 0)
296
              sharebasename[len - 4] = 0;
297
 
298
            /* Convert to uppercase.  */
299
            for (ptr = sharebasename; *ptr; ptr++)
300
              *ptr = TOUPPER (*ptr);
301
          }
302
      }
303
 
304
  if (exefullfilename == NULL && !share)
305
    {
306
      exefilename = "a_out.exe";
307
      exefullfilename = "a_out.exe";
308
      addarg (xstrdup (" /exe=a_out.exe"));
309
    }
310
}
311
 
312
/* Preprocess the number of args ARGC in ARGV.  Look for
313
   special flags, etc. that must be handled for the VMS linker.  */
314
 
315
static void
316
process_args (int argc, char **argv)
317
{
318
  int i;
319
 
320
  for (i = 1; i < argc; i++)
321
    {
322
      if (strncmp (argv[i], "-L", 2) == 0)
323
        {
324
          search_dirs = XRESIZEVEC(const char *, search_dirs,
325
                                   search_dirs_len + 1);
326
          search_dirs[search_dirs_len++] = &argv[i][2];
327
        }
328
 
329
      /* -v turns on verbose option here and is passed on to gcc.  */
330
      else if (strcmp (argv[i], "-v") == 0)
331
        verbose++;
332
      else if (strcmp (argv[i], "--version") == 0)
333
        {
334
          fprintf (stdout, "VMS Linker\n");
335
          exit (EXIT_SUCCESS);
336
        }
337
      else if (strcmp (argv[i], "--help") == 0)
338
        {
339
          fprintf (stdout, "VMS Linker\n");
340
          exit (EXIT_SUCCESS);
341
        }
342
      else if (strcmp (argv[i], "-g0") == 0)
343
        addarg ("/notraceback");
344
      else if (strncmp (argv[i], "-g", 2) == 0)
345
        {
346
          addarg ("/debug");
347
          debug = 1;
348
        }
349
      else if (strcmp (argv[i], "-static") == 0)
350
        staticp = 1;
351
      else if (strcmp (argv[i], "-map") == 0)
352
        {
353
          char *buff, *ptr;
354
 
355
          buff = (char *) xstrdup (exefullfilename);
356
          ptr = strrchr (buff, '.');
357
          if (ptr)
358
            *ptr = 0;
359
 
360
          strcat (buff, ".map");
361
          addarg ("/map=");
362
          addarg (buff);
363
          addarg (".map");
364
          addarg ("/full");
365
 
366
          free (buff);
367
        }
368
      else if (strcmp (argv[i], "-save-temps") == 0)
369
        save_temps = 1;
370
      else if (strcmp (argv[i], "--noinhibit-exec") == 0)
371
        inhibit_exec = 0;
372
    }
373
}
374
 
375
#ifdef VMS
376
typedef struct dsc
377
{
378
  unsigned short len, mbz;
379
  const char *adr;
380
} Descriptor;
381
 
382
struct lst
383
{
384
  unsigned short buflen, item_code;
385
  const void *bufaddr;
386
  void *retlenaddr;
387
};
388
 
389
static struct
390
{
391
  struct lst items [1];
392
  unsigned int terminator;
393
} item_lst1;
394
 
395
static struct
396
{
397
  struct lst items [2];
398
  unsigned int terminator;
399
} item_lst2;
400
 
401
/* Checks if logical names are defined for setting system library path and
402
   linker program to enable compatibility with earlier VMS versions.  */
403
 
404
static void
405
maybe_set_link_compat (void)
406
{
407
  char lnm_buff [LNM_C_NAMLENGTH];
408
  unsigned int lnm_buff_len;
409
  int status;
410
  Descriptor tabledsc, linkdsc;
411
 
412
  tabledsc.adr = "LNM$JOB";
413
  tabledsc.len = strlen (tabledsc.adr);
414
  tabledsc.mbz = 0;
415
 
416
  linkdsc.adr = "GCC_LD_SYS$LIBRARY";
417
  linkdsc.len = strlen (linkdsc.adr);
418
  linkdsc.mbz = 0;
419
 
420
  item_lst1.items[0].buflen = LNM_C_NAMLENGTH;
421
  item_lst1.items[0].item_code = LNM__STRING;
422
  item_lst1.items[0].bufaddr = lnm_buff;
423
  item_lst1.items[0].retlenaddr = &lnm_buff_len;
424
  item_lst1.terminator = 0;
425
 
426
  status = SYS$TRNLNM
427
    (0,          /* attr */
428
     &tabledsc,  /* tabnam */
429
     &linkdsc,   /* lognam */
430
     0,          /* acmode */
431
     &item_lst1);
432
 
433
  /* If GCC_LD_SYS$LIBRARY is defined, redefine SYS$LIBRARY to search
434
     the equivalence name first for system libraries, then the default
435
     system library directory */
436
 
437
  if ((status & 1) == 1)
438
    {
439
      unsigned char acmode = PSL_C_USER; /* Don't retain after image exit */
440
      const char *syslib = "SYS$SYSROOT:[SYSLIB]"; /* Default SYS$LIBRARY */
441
 
442
      /* Only visible to current and child processes */
443
      tabledsc.adr = "LNM$PROCESS";
444
      tabledsc.len = strlen (tabledsc.adr);
445
      tabledsc.mbz = 0;
446
 
447
      linkdsc.adr = "SYS$LIBRARY";
448
      linkdsc.len = strlen (linkdsc.adr);
449
      linkdsc.mbz = 0;
450
 
451
      item_lst2.items[0].buflen = lnm_buff_len;
452
      item_lst2.items[0].item_code = LNM__STRING;
453
      item_lst2.items[0].bufaddr = lnm_buff;
454
      item_lst2.items[0].retlenaddr = 0;
455
 
456
      item_lst2.items[1].buflen = strlen (syslib);
457
      item_lst2.items[1].item_code = LNM__STRING;
458
      item_lst2.items[1].bufaddr = syslib;
459
      item_lst2.items[1].retlenaddr = 0;
460
      item_lst2.terminator = 0;
461
 
462
      status = SYS$CRELNM
463
        (0,          /* attr */
464
         &tabledsc,  /* tabnam */
465
         &linkdsc,   /* lognam */
466
         &acmode,    /* acmode */
467
         &item_lst2);
468
 
469
    }
470
 
471
  tabledsc.adr = "LNM$JOB";
472
  tabledsc.len = strlen (tabledsc.adr);
473
  tabledsc.mbz = 0;
474
 
475
  linkdsc.adr = "GCC_LD_LINK";
476
  linkdsc.len = strlen (linkdsc.adr);
477
  linkdsc.mbz = 0;
478
 
479
  item_lst1.items[0].buflen = LNM_C_NAMLENGTH;
480
  item_lst1.items[0].item_code = LNM__STRING;
481
  item_lst1.items[0].bufaddr = lnm_buff;
482
  item_lst1.items[0].retlenaddr = &lnm_buff_len;
483
  item_lst1.terminator = 0;
484
 
485
  status = SYS$TRNLNM
486
    (0,          /* attr */
487
     &tabledsc,  /* tabnam */
488
     &linkdsc,   /* lognam */
489
     0,          /* acmode */
490
     &item_lst1);
491
 
492
  /* If GCC_LD_LINK is defined, redefine LINK to use the equivalence name
493
     (sometimes the LINK program version is used by VMS to determine
494
     compatibility).  */
495
 
496
  if ((status & 1) == 1)
497
    {
498
      unsigned char acmode = PSL_C_USER; /* Don't retain after image exit.  */
499
 
500
      /* Only visible to current and child processes.  */
501
      tabledsc.adr = "LNM$PROCESS";
502
      tabledsc.len = strlen (tabledsc.adr);
503
      tabledsc.mbz = 0;
504
 
505
      linkdsc.adr = "LINK";
506
      linkdsc.len = strlen (linkdsc.adr);
507
      linkdsc.mbz = 0;
508
 
509
      item_lst1.items[0].buflen = lnm_buff_len;
510
      item_lst1.items[0].item_code = LNM__STRING;
511
      item_lst1.items[0].bufaddr = lnm_buff;
512
      item_lst1.items[0].retlenaddr = 0;
513
      item_lst1.terminator = 0;
514
 
515
      status = SYS$CRELNM
516
        (0,          /* attr */
517
         &tabledsc,  /* tabnam */
518
         &linkdsc,   /* lognam */
519
         &acmode,    /* acmode */
520
         &item_lst1);
521
    }
522
}
523
#else
524
static void
525
maybe_set_link_compat (void)
526
{
527
}
528
#endif
529
 
530
/* Set environment defined executable attributes.  */
531
 
532
static int
533
set_exe (const char *arg)
534
{
535
  char allargs [1024];
536
  int res;
537
 
538
  snprintf (allargs, sizeof (allargs),
539
            "$@gnu:[bin]set_exe %s %s", exefullfilename, arg);
540
  if (verbose)
541
    printf ("%s\n", allargs);
542
 
543
  res = system (allargs);
544
  if (verbose > 1)
545
    printf ("$!status = %d\n", res);
546
 
547
  if ((res & 1) != 1)
548
    {
549
      fprintf (stderr, "ld error: popen set_exe\n");
550
      return 1;
551
    }
552
  return 0;
553
}
554
 
555
/* The main program.  Spawn the VMS linker after fixing up the Unix-like flags
556
   and args to be what the VMS linker wants.  */
557
 
558
int
559
main (int argc, char **argv)
560
{
561
  /* File specification for vms-dwarf2.o.  */
562
  char *vmsdwarf2spec = 0;
563
 
564
  /* File specification for vms-dwarf2eh.o.  */
565
  char *vmsdwarf2ehspec = 0;
566
 
567
  int i;
568
  char cwdev[128], *devptr;
569
  int cwdevlen;
570
  FILE *optfile;
571
  char *cwd, *ptr;
572
  char *optfilename;
573
  int status = 0;
574
 
575
  /* Some linker options can be set with logicals.  */
576
  if (getenv ("GNAT$LD_NOCALL_DEBUG"))
577
    ld_nocall_debug = 1;
578
  if (getenv ("GNAT$LD_MKTHREADS"))
579
    ld_mkthreads = 1;
580
  if (getenv ("GNAT$LD_UPCALLS"))
581
    ld_upcalls = 1;
582
  if (getenv ("GNAT$LD_SHARED_LIBS"))
583
    staticp = 0;
584
 
585
  /* Get current dir.  */
586
#ifdef VMS
587
  cwd = getcwd (0, 1024, 1);
588
#else
589
  cwd = getcwd (0, 1024);
590
  strcat (cwd, "/");
591
#endif
592
 
593
  /* Extract device part of the path.  */
594
  devptr = strchr (cwd, ':');
595
  if (devptr)
596
    cwdevlen = (devptr - cwd) + 1;
597
  else
598
    cwdevlen = 0;
599
  memcpy (cwdev, cwd, cwdevlen);
600
  cwdev [cwdevlen] = '\0';
601
 
602
  maybe_set_link_compat ();
603
 
604
  /* Linker command starts with the command name.  */
605
  addarg ("$ link");
606
 
607
  /* Pass to find args that have to be append first.  */
608
  preprocess_args (argc , argv);
609
 
610
  /* Pass to find the rest of the args.  */
611
  process_args (argc , argv);
612
 
613
  if (!verbose)
614
    addarg ("/noinform");
615
 
616
  /* Create a temp file to hold args, otherwise we can easily exceed the VMS
617
     command line length limits.  */
618
  optfilename = (char *) xmalloc (strlen (exefilename) + 13);
619
  strcpy (optfilename, exefilename);
620
  ptr = strrchr (optfilename, '.');
621
  if (ptr)
622
    *ptr = 0;
623
  strcat (optfilename, ".opt_tmpfile");
624
  optfile = fopen (optfilename, "w");
625
 
626
  /* Write out the IDENTIFICATION argument first so that it can be overridden
627
     by an options file.  */
628
  for (i = 1; i < argc; i++)
629
    {
630
      int arg_len = strlen (argv[i]);
631
 
632
      if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
633
        {
634
          /* Comes from command line. If present will always appear before
635
             --identification=... and will override.  */
636
          break;
637
        }
638
      else if (arg_len > 17
639
               && strncasecmp (argv[i], "--identification=", 17) == 0)
640
        {
641
          /* Comes from pragma Ident ().  */
642
          fprintf (optfile, "case_sensitive=yes\n");
643
          fprintf (optfile, "IDENTIFICATION=\"%-.15s\"\n", &argv[i][17]);
644
          fprintf (optfile, "case_sensitive=NO\n");
645
        }
646
    }
647
 
648
  for (i = 1; i < argc; i++)
649
    {
650
      int arg_len = strlen (argv[i]);
651
 
652
      if (strcmp (argv[i], "-o") == 0)
653
        {
654
          /* Already handled.  */
655
          i++;
656
        }
657
      else if (arg_len > 2 && strncmp (argv[i], "-l", 2) == 0)
658
        {
659
          const char *libname;
660
 
661
          libname = expand_lib (&argv[i][2]);
662
          if (libname != NULL)
663
            {
664
              int len = strlen (libname);
665
              const char *ext;
666
 
667
              if (len > 4 && strcasecmp (&libname [len-4], ".exe") == 0)
668
                ext = "/shareable";
669
              else
670
                ext = "/library";
671
 
672
              if (libname[0] == '[')
673
                fprintf (optfile, "%s%s%s\n", cwdev, libname, ext);
674
              else
675
                fprintf (optfile, "%s%s\n", libname, ext);
676
            }
677
        }
678
      else if (strcmp (argv[i], "-v" ) == 0
679
               || strncmp (argv[i], "-g", 2 ) == 0
680
               || strcmp (argv[i], "-static" ) == 0
681
               || strcmp (argv[i], "-map" ) == 0
682
               || strcmp (argv[i], "-save-temps") == 0
683
               || strcmp (argv[i], "--noinhibit-exec") == 0
684
               || (arg_len > 2 && strncmp (argv[i], "-L", 2) == 0)
685
               || (arg_len >= 6 && strncmp (argv[i], "-share", 6) == 0))
686
        {
687
          /* Already handled.  */
688
        }
689
      else if (strncmp (argv[i], "--opt=", 6) == 0)
690
        fprintf (optfile, "%s\n", argv[i] + 6);
691
      else if (arg_len > 1 && argv[i][0] == '@')
692
        {
693
          /* Read response file (in fact a single line of filenames).  */
694
          FILE *atfile;
695
          char *ptr, *ptr1;
696
          struct stat statbuf;
697
          char *buff;
698
          int len;
699
 
700
          if (stat (&argv[i][1], &statbuf))
701
            {
702
              fprintf (stderr, "Couldn't open linker response file: %s\n",
703
                       &argv[i][1]);
704
              exit (EXIT_FAILURE);
705
            }
706
 
707
          /* Read the line.  */
708
          buff = (char *) xmalloc (statbuf.st_size + 1);
709
          atfile = fopen (&argv[i][1], "r");
710
          fgets (buff, statbuf.st_size + 1, atfile);
711
          fclose (atfile);
712
 
713
          /* Remove trailing \n.  */
714
          len = strlen (buff);
715
          if (buff [len - 1] == '\n')
716
            {
717
              buff [len - 1] = 0;
718
              len--;
719
            }
720
 
721
          /* Put the filenames to the opt file.  */
722
          ptr = buff;
723
          do
724
          {
725
             ptr1 = strchr (ptr, ' ');
726
             if (ptr1)
727
               *ptr1 = 0;
728
 
729
             /* Add device name if a path is present.  */
730
             ptr = to_host_file_spec (ptr);
731
             if (ptr[0] == '[')
732
               fprintf (optfile, "%s%s\n", cwdev, ptr);
733
             else
734
               fprintf (optfile, "%s\n", ptr);
735
 
736
             ptr = ptr1 + 1;
737
          }
738
          while (ptr1);
739
        }
740
      else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0))
741
        {
742
          /* Unix style file specs and VMS style switches look alike,
743
             so assume an arg consisting of one and only one slash,
744
             and that being first, is really a switch.  */
745
          addarg (argv[i]);
746
        }
747
      else if (arg_len > 4
748
               && strncasecmp (&argv[i][arg_len-4], ".opt", 4) == 0)
749
        {
750
          /* Read option file.  */
751
          FILE *optfile1;
752
          char buff[256];
753
 
754
          /* Disable __UNIX_FOPEN redefinition in case user supplied .opt
755
             file is not stream oriented. */
756
 
757
          optfile1 = (fopen) (argv[i], "r");
758
          if (optfile1 == 0)
759
            {
760
              perror (argv[i]);
761
              status = 1;
762
              goto cleanup_and_exit;
763
            }
764
 
765
          while (fgets (buff, sizeof (buff), optfile1))
766
            fputs (buff, optfile);
767
 
768
          fclose (optfile1);
769
        }
770
      else if (arg_len > 7 && strncasecmp (argv[i], "GSMATCH", 7) == 0)
771
        fprintf (optfile, "%s\n", argv[i]);
772
      else if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
773
        {
774
          /* Comes from command line and will override pragma.  */
775
          fprintf (optfile, "case_sensitive=yes\n");
776
          fprintf (optfile, "IDENT=\"%15.15s\"\n", &argv[i][6]);
777
          fprintf (optfile, "case_sensitive=NO\n");
778
        }
779
      else if (arg_len > 17
780
               && strncasecmp (argv[i], "--identification=", 17) == 0)
781
        {
782
          /* Already handled.  */
783
        }
784
      else
785
        {
786
          /* Assume filename arg.  */
787
          const char *file;
788
          const char *addswitch = NULL;
789
          char *buff;
790
          int buff_len;
791
          int is_cld = 0;
792
 
793
          file = to_host_file_spec (argv[i]);
794
          arg_len = strlen (file);
795
 
796
          /* Handle shareable image libraries.  */
797
          if (arg_len > 4 && strcasecmp (&file[arg_len - 4], ".exe") == 0)
798
            addswitch = "/shareable";
799
          else if (arg_len > 4 && strcasecmp (&file[arg_len - 4], ".cld") == 0)
800
            {
801
              addswitch = "/shareable";
802
              is_cld = 1;
803
            }
804
 
805
          /* Handle object libraries.  */
806
          else if (arg_len > 2 && strcasecmp (&file[arg_len - 2], ".a") == 0)
807
            addswitch = "/lib";
808
          else if (arg_len > 4 && strcasecmp (&file[arg_len - 4], ".olb") == 0)
809
            addswitch = "/lib";
810
 
811
          /* Absolutize file location.  */
812
          if (file[0] == '[')
813
            {
814
              buff = (char *) xmalloc (cwdevlen + arg_len + 1);
815
              sprintf (buff, "%s%s", cwdev, file);
816
            }
817
          else if (strchr (file, ':'))
818
            {
819
              buff = xstrdup (file);
820
            }
821
          else
822
            {
823
              buff = (char *) xmalloc (strlen (cwd) + arg_len + 1);
824
              sprintf (buff, "%s%s", cwd, file);
825
            }
826
 
827
          buff_len = strlen (buff);
828
 
829
          if (buff_len >= 15
830
              && strcasecmp (&buff[buff_len - 14], "vms-dwarf2eh.o") == 0)
831
            {
832
              /* Remind of it.  */
833
              vmsdwarf2ehspec = xstrdup (buff);
834
            }
835
          else if (buff_len >= 13
836
                   && strcasecmp (&buff[buff_len - 12], "vms-dwarf2.o") == 0)
837
            {
838
              /* Remind of it.  */
839
              vmsdwarf2spec = xstrdup (buff);
840
            }
841
          else if (is_cld)
842
            {
843
              /* Command line definition file.  */
844
              addarg (buff);
845
              addarg (addswitch);
846
              addarg (",");
847
            }
848
          else
849
            {
850
              fprintf (optfile, "%s%s\n",
851
                       buff, addswitch != NULL ? addswitch : "");
852
            }
853
          free (buff);
854
        }
855
    }
856
 
857
  if (vmsdwarf2ehspec)
858
    {
859
      /* Sequentialize exception handling info.  */
860
 
861
      fprintf (optfile, "case_sensitive=yes\n");
862
      fprintf (optfile, "cluster=DWARF2eh,,,%s\n", vmsdwarf2ehspec);
863
      fprintf (optfile, "collect=DWARF2eh,eh_frame\n");
864
      fprintf (optfile, "case_sensitive=NO\n");
865
    }
866
 
867
  if (debug && vmsdwarf2spec)
868
    {
869
      /* Sequentialize the debug info.  */
870
 
871
      fprintf (optfile, "case_sensitive=yes\n");
872
      fprintf (optfile, "cluster=DWARF2debug,,,%s\n", vmsdwarf2spec);
873
      fprintf (optfile, "collect=DWARF2debug,debug_abbrev,debug_aranges,-\n");
874
      fprintf (optfile, " debug_frame,debug_info,debug_line,debug_loc,-\n");
875
      fprintf (optfile, " debug_macinfo,debug_pubnames,debug_str,-\n");
876
      fprintf (optfile, " debug_zzzzzz\n");
877
      fprintf (optfile, "case_sensitive=NO\n");
878
    }
879
 
880
  if (debug && share && vmsdwarf2spec)
881
    {
882
      /* Sequentialize the shared library debug info.  */
883
 
884
      fprintf (optfile, "case_sensitive=yes\n");
885
      fprintf (optfile, "symbol_vector=(-\n");
886
      fprintf (optfile,
887
               "%s$DWARF2.DEBUG_ABBREV/$dwarf2.debug_abbrev=DATA,-\n",
888
               sharebasename);
889
      fprintf (optfile,
890
               "%s$DWARF2.DEBUG_ARANGES/$dwarf2.debug_aranges=DATA,-\n",
891
               sharebasename);
892
      fprintf (optfile, "%s$DWARF2.DEBUG_FRAME/$dwarf2.debug_frame=DATA,-\n",
893
               sharebasename);
894
      fprintf (optfile, "%s$DWARF2.DEBUG_INFO/$dwarf2.debug_info=DATA,-\n",
895
               sharebasename);
896
      fprintf (optfile, "%s$DWARF2.DEBUG_LINE/$dwarf2.debug_line=DATA,-\n",
897
               sharebasename);
898
      fprintf (optfile, "%s$DWARF2.DEBUG_LOC/$dwarf2.debug_loc=DATA,-\n",
899
               sharebasename);
900
      fprintf (optfile,
901
               "%s$DWARF2.DEBUG_MACINFO/$dwarf2.debug_macinfo=DATA,-\n",
902
               sharebasename);
903
      fprintf (optfile,
904
               "%s$DWARF2.DEBUG_PUBNAMES/$dwarf2.debug_pubnames=DATA,-\n",
905
               sharebasename);
906
      fprintf (optfile, "%s$DWARF2.DEBUG_STR/$dwarf2.debug_str=DATA,-\n",
907
               sharebasename);
908
      fprintf (optfile, "%s$DWARF2.DEBUG_ZZZZZZ/$dwarf2.debug_zzzzzz=DATA)\n",
909
               sharebasename);
910
      fprintf (optfile, "case_sensitive=NO\n");
911
    }
912
 
913
  fprintf (optfile, "PSECT_ATTR=LIB$INITIALIZE,GBL\n");
914
  fclose (optfile);
915
 
916
  /* Append opt file.  */
917
  addarg (" ");
918
  addarg (optfilename);
919
  addarg ("/opt");
920
 
921
  if (verbose)
922
    printf ("%s\n", link_cmd);
923
 
924
  status = system (link_cmd);
925
  if (verbose > 1)
926
    printf ("$!status = %d\n", status);
927
 
928
  if ((status & 1) != 1)
929
    {
930
      status = 1;
931
      goto cleanup_and_exit;
932
    }
933
 
934
  if (debug && !share && ld_nocall_debug)
935
    {
936
      status = set_exe ("/flags=nocall_debug");
937
      if (status != 0)
938
        goto cleanup_and_exit;
939
    }
940
 
941
  if (!share && ld_mkthreads)
942
    {
943
      status = set_exe ("/flags=mkthreads");
944
      if (status != 0)
945
        goto cleanup_and_exit;
946
    }
947
 
948
  if (!share && ld_upcalls)
949
    {
950
      status = set_exe ("/flags=upcalls");
951
      if (status != 0)
952
        goto cleanup_and_exit;
953
    }
954
 
955
  status = 0;
956
 
957
 cleanup_and_exit:
958
  if (!save_temps)
959
    remove (optfilename);
960
 
961
  if (status == 0)
962
    exit (EXIT_SUCCESS);
963
 
964
  if (exefullfilename && inhibit_exec == 1)
965
    remove (exefullfilename);
966
 
967
  exit (EXIT_FAILURE);
968
}

powered by: WebSVN 2.1.0

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