00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028 #include "system.h"
00029
00030 typedef struct dsc {unsigned short len, mbz; char *adr; } Descr;
00031
00032 #undef PATH_SEPARATOR
00033 #undef PATH_SEPARATOR_STR
00034 #define PATH_SEPARATOR ','
00035 #define PATH_SEPARATOR_STR ","
00036
00037
00038
00039
00040 static char *vmsdwarf2spec = 0;
00041
00042
00043 static char *vmsdwarf2ehspec = 0;
00044
00045
00046 static int verbose = 0;
00047
00048
00049 static int save_temps = 0;
00050
00051
00052
00053 static int inhibit_exec = 1;
00054
00055
00056 static int debug = 0;
00057
00058
00059
00060 static int staticp = 0;
00061
00062
00063
00064 static int share = 0;
00065
00066
00067 static int ident = 0;
00068
00069
00070 static int link_arg_max = -1;
00071 static const char **link_args = 0;
00072 static int link_arg_index = -1;
00073
00074
00075 static char optfilefullname [267];
00076 static char *sharefilename = 0;
00077 static char *exefilename = 0;
00078
00079
00080
00081 static char *system_search_dirs = "";
00082
00083
00084 static char *search_dirs;
00085
00086
00087
00088
00089
00090 static void addarg PARAMS ((const char *));
00091
00092
00093 static int is_regular_file PARAMS ((char *));
00094
00095
00096
00097 static char *to_host_file_spec PARAMS ((char *));
00098
00099
00100 static char *locate_lib PARAMS ((char *, char *));
00101
00102
00103
00104 static const char *expand_lib PARAMS ((char *));
00105
00106
00107
00108 static void preprocess_args PARAMS ((int *, char **));
00109
00110
00111
00112 static void process_args PARAMS ((int *, char **));
00113
00114
00115
00116 static int translate_unix PARAMS ((char *, int));
00117
00118 int main PARAMS ((int, char **));
00119
00120 static void
00121 addarg (str)
00122 const char *str;
00123 {
00124 int i;
00125
00126 if (++link_arg_index >= link_arg_max)
00127 {
00128 const char **new_link_args
00129 = (const char **) xcalloc (link_arg_max + 1000, sizeof (char *));
00130
00131 for (i = 0; i <= link_arg_max; i++)
00132 new_link_args [i] = link_args [i];
00133
00134 if (link_args)
00135 free (link_args);
00136
00137 link_arg_max += 1000;
00138 link_args = new_link_args;
00139 }
00140
00141 link_args [link_arg_index] = str;
00142 }
00143
00144 static char *
00145 locate_lib (lib_name, path_val)
00146 char *lib_name;
00147 char *path_val;
00148 {
00149 int lib_len = strlen (lib_name);
00150 char *eptr, *sptr;
00151
00152 for (sptr = path_val; *sptr; sptr = eptr)
00153 {
00154 char *buf, *ptr;
00155
00156 while (*sptr == PATH_SEPARATOR)
00157 sptr ++;
00158
00159 eptr = strchr (sptr, PATH_SEPARATOR);
00160 if (eptr == 0)
00161 eptr = strchr (sptr, 0);
00162
00163 buf = alloca ((eptr-sptr) + lib_len + 4 + 2);
00164 strncpy (buf, sptr, eptr-sptr);
00165 buf [eptr-sptr] = 0;
00166 strcat (buf, "/");
00167 strcat (buf, lib_name);
00168 ptr = strchr (buf, 0);
00169
00170 if (debug || staticp)
00171 {
00172
00173
00174 strcpy (ptr, ".a");
00175 if (is_regular_file (buf))
00176 return xstrdup (to_host_file_spec (buf));
00177
00178 strcpy (ptr, ".olb");
00179 if (is_regular_file (buf))
00180 return xstrdup (to_host_file_spec (buf));
00181
00182 strcpy (ptr, ".exe");
00183 if (is_regular_file (buf))
00184 return xstrdup (to_host_file_spec (buf));
00185 }
00186 else
00187 {
00188
00189 strcpy (ptr, ".exe");
00190 if (is_regular_file (buf))
00191 return xstrdup (to_host_file_spec (buf));
00192
00193 strcpy (ptr, ".a");
00194 if (is_regular_file (buf))
00195 return xstrdup (to_host_file_spec (buf));
00196
00197 strcpy (ptr, ".olb");
00198 if (is_regular_file (buf))
00199 return xstrdup (to_host_file_spec (buf));
00200 }
00201 }
00202
00203 return 0;
00204 }
00205
00206 static const char *
00207 expand_lib (name)
00208 char *name;
00209 {
00210 char *lib, *lib_path;
00211
00212 if (strcmp (name, "c") == 0)
00213
00214
00215 return "sys$library:vaxcrtltx.olb";
00216
00217 else if (strcmp (name, "m") == 0)
00218
00219 return "";
00220
00221 else
00222 {
00223 lib = xmalloc (strlen (name) + 14);
00224
00225 strcpy (lib, "lib");
00226 strcat (lib, name);
00227 lib_path = locate_lib (lib, search_dirs);
00228
00229 if (lib_path)
00230 return lib_path;
00231 }
00232
00233 fprintf (stderr,
00234 "Couldn't locate library: lib%s.exe, lib%s.a or lib%s.olb\n",
00235 name, name, name);
00236
00237 exit (1);
00238 }
00239
00240 static int
00241 is_regular_file (name)
00242 char *name;
00243 {
00244 int ret;
00245 struct stat statbuf;
00246
00247 ret = stat (name, &statbuf);
00248 return !ret && S_ISREG (statbuf.st_mode);
00249 }
00250
00251 static void
00252 preprocess_args (p_argc, argv)
00253 int *p_argc;
00254 char **argv;
00255 {
00256 int i;
00257
00258 for (i = 1; i < *p_argc; i++)
00259 if (strlen (argv[i]) >= 6 && strncmp (argv[i], "-shared", 7) == 0)
00260 share = 1;
00261
00262 for (i = 1; i < *p_argc; i++)
00263 if (strcmp (argv[i], "-o") == 0)
00264 {
00265 char *buff, *ptr;
00266 int out_len;
00267 int len;
00268
00269 i++;
00270 ptr = to_host_file_spec (argv[i]);
00271 exefilename = xstrdup (ptr);
00272 out_len = strlen (ptr);
00273 buff = xmalloc (out_len + 18);
00274
00275 if (share)
00276 strcpy (buff, "/share=");
00277 else
00278 strcpy (buff, "/exe=");
00279
00280 strcat (buff, ptr);
00281 addarg (buff);
00282
00283 if (share)
00284 {
00285 sharefilename = xmalloc (out_len+5);
00286 if (ptr == strchr (argv[i], ']'))
00287 strcpy (sharefilename, ++ptr);
00288 else if (ptr == strchr (argv[i], ':'))
00289 strcpy (sharefilename, ++ptr);
00290 else if (ptr == strrchr (argv[i], '/'))
00291 strcpy (sharefilename, ++ptr);
00292 else
00293 strcpy (sharefilename, argv[i]);
00294
00295 len = strlen (sharefilename);
00296 if (strncasecmp (&sharefilename[len-4], ".exe", 4) == 0)
00297 sharefilename[len-4] = 0;
00298
00299 for (ptr = sharefilename; *ptr; ptr++)
00300 *ptr = TOUPPER (*ptr);
00301 }
00302 }
00303 }
00304
00305 static void
00306 process_args (p_argc, argv)
00307 int *p_argc;
00308 char **argv;
00309 {
00310 int i;
00311
00312 for (i = 1; i < *p_argc; i++)
00313 {
00314 if (strlen (argv[i]) < 2)
00315 continue;
00316
00317 if (strncmp (argv[i], "-L", 2) == 0)
00318 {
00319 char *nbuff, *ptr;
00320 int new_len, search_dirs_len;
00321
00322 ptr = &argv[i][2];
00323 new_len = strlen (ptr);
00324 search_dirs_len = strlen (search_dirs);
00325
00326 nbuff = xmalloc (new_len + 1);
00327 strcpy (nbuff, ptr);
00328
00329
00330 while (new_len > 1 && nbuff [new_len - 1] == '/')
00331 {
00332 nbuff [new_len - 1] = 0;
00333 new_len--;
00334 }
00335
00336 search_dirs = xrealloc (search_dirs, search_dirs_len + new_len + 2);
00337 if (search_dirs_len > 0)
00338 strcat (search_dirs, PATH_SEPARATOR_STR);
00339
00340 strcat (search_dirs, nbuff);
00341 free (nbuff);
00342 }
00343
00344
00345 else if (strcmp (argv[i], "-v") == 0)
00346 verbose = 1;
00347 else if (strcmp (argv[i], "-g0") == 0)
00348 addarg ("/notraceback");
00349 else if (strncmp (argv[i], "-g", 2) == 0)
00350 {
00351 addarg ("/debug");
00352 debug = 1;
00353 }
00354 else if (strcmp (argv[i], "-static") == 0)
00355 staticp = 1;
00356 else if (strcmp (argv[i], "-map") == 0)
00357 {
00358 char *buff, *ptr;
00359
00360 buff = xmalloc (strlen (exefilename) + 5);
00361 strcpy (buff, exefilename);
00362 ptr = strchr (buff, '.');
00363 if (ptr)
00364 *ptr = 0;
00365
00366 strcat (buff, ".map");
00367 addarg ("/map=");
00368 addarg (buff);
00369 addarg ("/full");
00370 }
00371 else if (strcmp (argv[i], "-save-temps") == 0)
00372 save_temps = 1;
00373 else if (strcmp (argv[i], "--noinhibit-exec") == 0)
00374 inhibit_exec = 0;
00375 }
00376 }
00377
00378
00379
00380
00381 int
00382 main (argc, argv)
00383 int argc;
00384 char **argv;
00385 {
00386 int i;
00387 char cwdev [128], *devptr;
00388 int devlen;
00389 int optfd;
00390 FILE *optfile;
00391 char *cwd = getcwd (0, 1024);
00392 char *optfilename;
00393
00394 devptr = strchr (cwd, ':');
00395 devlen = (devptr - cwd) + 1;
00396 strncpy (cwdev, cwd, devlen);
00397 cwdev [devlen] = '\0';
00398
00399 search_dirs = xmalloc (strlen (system_search_dirs) + 1);
00400 strcpy (search_dirs, system_search_dirs);
00401
00402 addarg ("link");
00403
00404
00405 preprocess_args (&argc , argv);
00406
00407
00408 process_args (&argc , argv);
00409
00410
00411
00412 optfilename = alloca (strlen ("LDXXXXXX") + 1);
00413 strcpy (optfilename, "LDXXXXXX");
00414 optfd = mkstemp (optfilename);
00415 getcwd (optfilefullname, 256, 1);
00416 strcat (optfilefullname, optfilename);
00417 strcat (optfilefullname, ".");
00418 optfile = fdopen (optfd, "w");
00419
00420
00421
00422 for (i = 1; i < argc; i++)
00423 {
00424 int arg_len = strlen (argv[i]);
00425
00426 if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
00427 {
00428
00429
00430
00431 if (!ident)
00432 ident = 1;
00433 }
00434 else if (arg_len > 15
00435 && strncasecmp (argv[i], "IDENTIFICATION=", 15) == 0)
00436 {
00437
00438
00439 if (!ident)
00440 {
00441 fprintf (optfile, "case_sensitive=yes\n");
00442 fprintf (optfile, "IDENTIFICATION=\"%15.15s\"\n", &argv[i][15]);
00443 fprintf (optfile, "case_sensitive=NO\n");
00444 ident = 1;
00445 }
00446 }
00447 }
00448
00449 for (i = 1; i < argc; i++)
00450 {
00451 int arg_len = strlen (argv[i]);
00452
00453 if (strcmp (argv[i], "-o") == 0)
00454 i++;
00455 else if (arg_len > 2 && strncmp (argv[i], "-l", 2) == 0)
00456 {
00457 const char *libname = expand_lib (&argv[i][2]);
00458 const char *ext;
00459 int len;
00460
00461 if ((len = strlen (libname)) > 0)
00462 {
00463 char buff [256];
00464
00465 if (len > 4 && strcasecmp (&libname [len-4], ".exe") == 0)
00466 ext = "/shareable";
00467 else
00468 ext = "/library";
00469
00470 if (libname[0] == '[')
00471 sprintf (buff, "%s%s", cwdev, libname);
00472 else
00473 sprintf (buff, "%s", libname);
00474
00475 fprintf (optfile, "%s%s\n", buff, ext);
00476 }
00477 }
00478
00479 else if (strcmp (argv[i], "-v" ) == 0
00480 || strncmp (argv[i], "-g", 2 ) == 0
00481 || strcmp (argv[i], "-static" ) == 0
00482 || strcmp (argv[i], "-map" ) == 0
00483 || strcmp (argv[i], "-save-temps") == 0
00484 || strcmp (argv[i], "--noinhibit-exec") == 0
00485 || (arg_len > 2 && strncmp (argv[i], "-L", 2) == 0)
00486 || (arg_len >= 6 && strncmp (argv[i], "-share", 6) == 0))
00487 ;
00488 else if (arg_len > 1 && argv[i][0] == '@')
00489 {
00490 FILE *atfile;
00491 char *ptr, *ptr1;
00492 struct stat statbuf;
00493 char *buff;
00494 int len;
00495
00496 if (stat (&argv[i][1], &statbuf))
00497 {
00498 fprintf (stderr, "Couldn't open linker response file: %s\n",
00499 &argv[i][1]);
00500 exit (1);
00501 }
00502
00503 buff = xmalloc (statbuf.st_size + 1);
00504 atfile = fopen (&argv[i][1], "r");
00505 fgets (buff, statbuf.st_size + 1, atfile);
00506 fclose (atfile);
00507
00508 len = strlen (buff);
00509 if (buff [len - 1] == '\n')
00510 {
00511 buff [len - 1] = 0;
00512 len--;
00513 }
00514
00515 ptr = buff;
00516
00517 do
00518 {
00519 ptr1 = strchr (ptr, ' ');
00520 if (ptr1)
00521 *ptr1 = 0;
00522 ptr = to_host_file_spec (ptr);
00523 if (ptr[0] == '[')
00524 fprintf (optfile, "%s%s\n", cwdev, ptr);
00525 else
00526 fprintf (optfile, "%s\n", ptr);
00527 ptr = ptr1 + 1;
00528 } while (ptr1);
00529 }
00530
00531
00532
00533
00534 else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0))
00535 addarg (argv[i]);
00536 else if (arg_len > 4
00537 && strncasecmp (&argv[i][arg_len-4], ".OPT", 4) == 0)
00538 {
00539 FILE *optfile1;
00540 char buff [256];
00541
00542 optfile1 = fopen (argv[i], "r");
00543 while (fgets (buff, 256, optfile1))
00544 fputs (buff, optfile);
00545
00546 fclose (optfile1);
00547 }
00548 else if (arg_len > 7 && strncasecmp (argv[i], "GSMATCH", 7) == 0)
00549 fprintf (optfile, "%s\n", argv[i]);
00550 else if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
00551 {
00552
00553 fprintf (optfile, "case_sensitive=yes\n");
00554 fprintf (optfile, "IDENT=\"%15.15s\"\n", &argv[i][6]);
00555 fprintf (optfile, "case_sensitive=NO\n");
00556 ident = 1;
00557 }
00558 else if (arg_len > 15
00559 && strncasecmp (argv[i], "IDENTIFICATION=", 15) == 0)
00560 ;
00561 else
00562 {
00563
00564 const char *addswitch = "";
00565 char buff [256];
00566 int buff_len;
00567 int is_cld = 0;
00568
00569 argv[i] = to_host_file_spec (argv[i]);
00570 arg_len = strlen (argv[i]);
00571
00572 if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".exe") == 0)
00573 addswitch = "/shareable";
00574
00575 if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".cld") == 0)
00576 {
00577 addswitch = "/shareable";
00578 is_cld = 1;
00579 }
00580
00581 if (arg_len > 2 && strcasecmp (&argv[i][arg_len-2], ".a") == 0)
00582 addswitch = "/lib";
00583
00584 if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".olb") == 0)
00585 addswitch = "/lib";
00586
00587 if (argv[i][0] == '[')
00588 sprintf (buff, "%s%s%s\n", cwdev, argv[i], addswitch);
00589 else if (strchr (argv[i], ':'))
00590 sprintf (buff, "%s%s\n", argv[i], addswitch);
00591 else
00592 sprintf (buff, "%s%s%s\n", cwd, argv[i], addswitch);
00593
00594 buff_len = strlen (buff);
00595
00596 if (buff_len >= 15
00597 && strcasecmp (&buff[buff_len - 15], "vms-dwarf2eh.o\n") == 0)
00598 vmsdwarf2ehspec = xstrdup (buff);
00599 else if (buff_len >= 13
00600 && strcasecmp (&buff[buff_len - 13],"vms-dwarf2.o\n") == 0)
00601 vmsdwarf2spec = xstrdup (buff);
00602 else if (is_cld)
00603 {
00604 addarg (buff);
00605 addarg (",");
00606 }
00607 else
00608 fprintf (optfile, buff);
00609 }
00610 }
00611
00612 #if 0
00613 if (share)
00614 fprintf (optfile, "symbol_vector=(main=procedure)\n");
00615 #endif
00616
00617 if (vmsdwarf2ehspec)
00618 {
00619 fprintf (optfile, "case_sensitive=yes\n");
00620 fprintf (optfile, "cluster=DWARF2eh,,,%s", vmsdwarf2ehspec);
00621 fprintf (optfile, "collect=DWARF2eh,eh_frame\n");
00622 fprintf (optfile, "case_sensitive=NO\n");
00623 }
00624
00625 if (debug && vmsdwarf2spec)
00626 {
00627 fprintf (optfile, "case_sensitive=yes\n");
00628 fprintf (optfile, "cluster=DWARF2debug,,,%s", vmsdwarf2spec);
00629 fprintf (optfile, "collect=DWARF2debug,debug_abbrev,debug_aranges,-\n");
00630 fprintf (optfile, " debug_frame,debug_info,debug_line,debug_loc,-\n");
00631 fprintf (optfile, " debug_macinfo,debug_pubnames,debug_str,-\n");
00632 fprintf (optfile, " debug_zzzzzz\n");
00633 fprintf (optfile, "case_sensitive=NO\n");
00634 }
00635
00636 if (debug && share)
00637 {
00638 fprintf (optfile, "case_sensitive=yes\n");
00639 fprintf (optfile, "symbol_vector=(-\n");
00640 fprintf (optfile,
00641 "%s$DWARF2.DEBUG_ABBREV/$dwarf2.debug_abbrev=DATA,-\n",
00642 sharefilename);
00643 fprintf (optfile,
00644 "%s$DWARF2.DEBUG_ARANGES/$dwarf2.debug_aranges=DATA,-\n",
00645 sharefilename);
00646 fprintf (optfile, "%s$DWARF2.DEBUG_FRAME/$dwarf2.debug_frame=DATA,-\n",
00647 sharefilename);
00648 fprintf (optfile, "%s$DWARF2.DEBUG_INFO/$dwarf2.debug_info=DATA,-\n",
00649 sharefilename);
00650 fprintf (optfile, "%s$DWARF2.DEBUG_LINE/$dwarf2.debug_line=DATA,-\n",
00651 sharefilename);
00652 fprintf (optfile, "%s$DWARF2.DEBUG_LOC/$dwarf2.debug_loc=DATA,-\n",
00653 sharefilename);
00654 fprintf (optfile,
00655 "%s$DWARF2.DEBUG_MACINFO/$dwarf2.debug_macinfo=DATA,-\n",
00656 sharefilename);
00657 fprintf (optfile,
00658 "%s$DWARF2.DEBUG_PUBNAMES/$dwarf2.debug_pubnames=DATA,-\n",
00659 sharefilename);
00660 fprintf (optfile, "%s$DWARF2.DEBUG_STR/$dwarf2.debug_str=DATA,-\n",
00661 sharefilename);
00662 fprintf (optfile, "%s$DWARF2.DEBUG_ZZZZZZ/$dwarf2.debug_zzzzzz=DATA)\n",
00663 sharefilename);
00664 fprintf (optfile, "case_sensitive=NO\n");
00665 }
00666
00667 fclose (optfile);
00668 addarg (optfilefullname);
00669 addarg ("/opt");
00670
00671 addarg (NULL);
00672
00673 if (verbose)
00674 {
00675 int i;
00676
00677 for (i = 0; i < link_arg_index; i++)
00678 printf ("%s ", link_args [i]);
00679 putchar ('\n');
00680 }
00681
00682 {
00683 int i;
00684 int len = 0;
00685
00686 for (i = 0; link_args[i]; i++)
00687 len = len + strlen (link_args[i]) + 1;
00688
00689 {
00690 char *allargs = (char *) alloca (len + 1);
00691 Descr cmd;
00692 int status;
00693 int status1 = 1;
00694
00695 for (i = 0; i < len + 1; i++)
00696 allargs [i] = 0;
00697
00698 for (i = 0; link_args [i]; i++)
00699 {
00700 strcat (allargs, link_args [i]);
00701 strcat (allargs, " ");
00702 }
00703
00704 cmd.adr = allargs;
00705 cmd.len = len;
00706 cmd.mbz = 0;
00707
00708 i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status);
00709 if ((i & 1) != 1)
00710 {
00711 LIB$SIGNAL (i);
00712 exit (1);
00713 }
00714
00715 if (debug && !share)
00716 {
00717 strcpy (allargs, "@gnu:[bin]set_exe ");
00718 strcat (allargs, exefilename);
00719 strcat (allargs, " /nodebug /silent");
00720 len = strlen (allargs);
00721 cmd.adr = allargs;
00722 cmd.len = len;
00723 cmd.mbz = 0;
00724
00725 if (verbose)
00726 printf (allargs);
00727
00728 i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status1);
00729
00730 if ((i & 1) != 1)
00731 {
00732 LIB$SIGNAL (i);
00733 exit (1);
00734 }
00735 }
00736
00737 if (!save_temps)
00738 remove (optfilefullname);
00739
00740 if ((status & 1) == 1 && (status1 & 1) == 1)
00741 exit (0);
00742
00743 if (exefilename && inhibit_exec == 1)
00744 remove (exefilename);
00745
00746 exit (1);
00747 }
00748 }
00749 }
00750
00751 static char new_host_filespec [255];
00752 static char filename_buff [256];
00753
00754 static int
00755 translate_unix (name, type)
00756 char *name;
00757 int type ATTRIBUTE_UNUSED;
00758 {
00759 strcpy (filename_buff, name);
00760 return 0;
00761 }
00762
00763 static char *
00764 to_host_file_spec (filespec)
00765 char *filespec;
00766 {
00767 strcpy (new_host_filespec, "");
00768 if (strchr (filespec, ']') || strchr (filespec, ':'))
00769 strcpy (new_host_filespec, filespec);
00770 else
00771 {
00772 decc$to_vms (filespec, translate_unix, 1, 1);
00773 strcpy (new_host_filespec, filename_buff);
00774 }
00775
00776 return new_host_filespec;
00777 }