Changeset 523


Ignore:
Timestamp:
Aug 4, 2003, 7:16:27 PM (22 years ago)
Author:
bird
Message:

#582: tracing, linker types.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/src/emxomf/emxomfld.c

    • Property cvs2svn:cvs-rev changed from 1.16 to 1.17
    r522 r523  
    1 /* emxomfld.c --  Provide an ld-like interface to LINK386
     1/* emxomfld.c --  Provide an ld-like interface to the IBM and M$ linkers
    22   Copyright (c) 1992-1998 Eberhard Mattes
    33
     
    4949
    5050
     51/* Whether or not linker tracing is enabled. */
     52static int opt_t;
     53
    5154/* The output file name, specified by the -o option.  */
    5255static const char *output_fname = NULL;
     
    8891static name_list **add_lib_fnames = &lib_fnames;
    8992
    90 /* List of LINK386 options.  LINK386 options can be specified with the
     93/* List of linker options.  Linker options can be specified with the
    9194   -O option.  add_options is used to add another entry at the end of
    9295   the list. */
     
    9497static name_list **add_options = &options;
    9598
    96 /* The command line passed to LINK386. */
     99/* The command line passed to the linker. */
    97100static char command_line[260];
    98101
     
    129132static long stack_size = 0;
    130133
    131 /* The name of the linker to use.  By default, LINK386 is used.  This
    132    can be overriden with the EMXOMFLD_LINKER environment variable. */
    133 static const char *linker_name = "link386";
     134/* The name of the linker to use.  By default, ilink is used.  This
     135   can be overridden with the EMXOMFLD_LINKER environment variable. */
     136static const char *linker_name = "ilink.exe";
     137
     138/* The type of linker to use. By default we assume it's VAC365 or later
     139   version of ilink. This can be overridden with the EMXOMFLD_TYPE env.
     140   var. using any of the value VAC365, VAC308 and LINK386. */
     141static const char *linker_type = "VAC365";
    134142
    135143/* Prototypes. */
     
    166174
    167175  fprintf (stderr,
    168            "Usage: emxomfld -o <file> [-l <lib>] [-L <libdir>] [-T <base>] [-sS]\n"
     176           "Usage: emxomfld -o <file> [-l <lib>] [-L <libdir>] [-T <base>] [-igtsS]\n"
    169177           "                [-Zexe] [-Zdll] [-Zstack <size>] [-Zmap[=<map_file>]]\n"
    170            "                [-O <option>] <file>...\n");
     178           "                [-O <option>] <file>...\n"
     179           "\n"
     180           "Environment variables:\n"
     181           "  EMXOMFLD_TYPE:\n"
     182           "    The type of linker we're using. Values: VAC365, VAC308, LINK386.\n"
     183           "        VAC365   ilink.exe from IBM C and C++ Compilers for OS/2 v3.6 or later.\n"
     184           "        VAC308   ilink.exe from Visual Age for C++ v3.08.\n"
     185           "        LINK386  link386 form OS/2 install or DDK.\n"
     186           "  EMXOMFLD_LINKER:\n"
     187           "    Name of the linker to use and optionally extra parameters. Spaces in the\n"
     188           "    linker name or path is not supported. Quotes are not supported either.\n"
     189           "The default values for these two variables are VAC365 and ilink.exe.\n");
    171190  exit (1);
    172191}
     
    239258
    240259
    241 /* Replace forward slashes `/' in NAME with backslashes `\'.  LINK386
    242    needs backslashes in path names. */
     260/* Replace forward slashes `/' in NAME with backslashes `\'.  The linkers
     261   requires backslashes in path names. */
    243262
    244263static void conv_path (char *name)
     
    312331          /* If SRC is a single comma or a single semicolon, copy it
    313332             to the output, ignoring the maximum line length.  This is
    314              to meet the LINK386 command syntax. The maximum line
     333             to meet the IBM/M$ linker command syntax. The maximum line
    315334             length allows for enough commas and semicolons added this
    316335             way. */
     
    413432
    414433
    415 /* Build the environment for LINK386: define the LIB environment
    416    variable. */
     434/* Build the environment for the IBM/M$ Linkers: define the LIB
     435   environment variable. */
    417436
    418437static void make_env (void)
     
    453472
    454473  putenv (tmp);
     474
     475  if (opt_t)
     476    fprintf(stderr, "*** LIB=%s\n", tmp);
    455477}
    456478
     
    605627
    606628  /* look for ilinker options. */
     629  if (opt_t)
     630      fFlags |= WLDC_VERBOSE;
    607631  for (pOpt = options; pOpt; pOpt = pOpt->next)
    608632    if (    !strnicmp(pOpt->name, "/NOE", 4)
     
    631655
    632656  /* create the linker and to the linking. */
     657  if (opt_t)
     658    fprintf(stderr, "*** Invoking weak prelinker with flags %x.\n", fFlags);
    633659  pwld = wldCreate (fFlags);
    634660  if (pwld)
     
    665691      /* complete pass 1 */
    666692      if (!rc)
    667       {
     693        {
    668694          rc = wldPass1 (pwld);
    669695          /* ignore unresolved externals for now. */
    670696          if (rc == 42)
     697            {
    671698              rc = 0;
    672       }
     699              fprintf(stderr, "Ignoring unresolved externals reported from weak prelinker.");
     700            }
     701        }
    673702
    674703      /* generate weak aliases. */
     
    680709      /* cleanup the linker */
    681710      wldDestroy (pwld);
     711     
     712      /* last words */
     713      if (rc)
     714        fprintf (stderr, "emxomfld: weak prelinker failed. (rc=%d)\n", rc);
    682715    }
    683716  else
    684717    {
    685718      rc = 8;
    686       fprintf (stderr, "emxomfld: failed to create weak linker.\n");
    687     }
    688 
     719      fprintf (stderr, "emxomfld: failed to create weak prelinker.\n");
     720    }
     721
     722  /* die on error. */
    689723  if (rc)
    690724    exit(rc);
     725
     726  /* verbose */
     727  if (opt_t)
     728    fprintf(stderr, "*** Weak prelinker done\n");
    691729}
    692730
     
    697735static void arg_init (int rsp)
    698736{
    699   command_line[0] = 0;
     737  response_fname[0] = '\0';
     738  command_line[0] = '\0';
    700739  line_len = 0;
    701740  response_flag = rsp;
     
    721760
    722761
     762/* -t output. We dump the commandline and responsefile. */
     763static void  show_spawn(const char *pszwhat)
     764{
     765  if (!opt_t)
     766    return;
     767  fprintf(stderr, "*** Invoking %s\n %s\n", pszwhat, command_line);
     768  if (response_fname[0])
     769    { /* display the responsfile content. */
     770      char sz[4096];
     771      FILE *phfile = fopen(response_fname, "r");
     772      fprintf(stderr, "--- Response file %s:\n", response_fname);
     773      sz[0] = '\0';
     774      while (fgets(sz, sizeof(sz), phfile))
     775          fprintf(stderr, "%s", sz);
     776      fclose(phfile);
     777      if (sz[strlen(sz) - 1] != '\n')
     778          fprintf(stderr, "\n");
     779      fprintf(stderr, "--- End of Response File\n");
     780    }
     781}
     782
     783
     784/* Execute commandline and returns the result.
     785   pszwhat is used for opt_t trace information. */
     786
     787static int emxomfld_spawn(char *pszcmd, const char *pszwhat)
     788{
     789  int       argi;
     790  char **   argv;
     791  char *    psz;
     792  int       rc;
     793
     794  if (opt_t)
     795      show_spawn(pszwhat);
     796
     797  /* construct spawnvp() argument array */
     798  argi = 0;
     799  argv = NULL;
     800  psz = pszcmd;
     801  while (psz && *psz)
     802    {
     803      char *psz2 = psz;
     804
     805      /* skip blanks. */
     806      while (*psz2 == '\t' || *psz2 == ' ')
     807          psz2++;
     808
     809      /* find end of argument taking in account in arg quoting. */
     810      while (*psz2 && *psz2 != '\t' && *psz2 != ' ')
     811        {
     812          if (*psz2 == '"' || *psz2 == '\'')
     813            {
     814              char chQuote = *psz2++;
     815              while (*psz2 && *psz2 != chQuote)
     816                psz2++;
     817            }
     818          else
     819            psz2++;
     820        }
     821      /* terminate and set psz2 to point to next */
     822      if (*psz2)
     823        *psz2++ = '\0';
     824     
     825      /* add argument to argument vector. */
     826      if (!(argi % 32))
     827        argv = xrealloc(argv, argi + 32);
     828      argv[argi++] = xstrdup(psz);
     829
     830      /* next */
     831      psz = psz2;                           
     832    }
     833
     834  /* Spawn process. */
     835  rc = spawnvp(P_WAIT, argv[0], argv);
     836  if (opt_t)
     837    fprintf(stderr, "*** Return from %s is %d\n", pszwhat, rc);
     838
     839  return rc;
     840}
     841
     842
    723843/* Cleanup by closing (if open) and deleting (if pressent) the
    724844   response file.  This function is used with atexit(). */
     
    744864
    745865
    746 /* Main function of emxomf.  Parse the command line and call LINK386
    747    (and optionally RC). */
     866/* Main function of emxomf.  Parse the command line and call the IBM/M$
     867   linker (and optionally RC). */
    748868
    749869int main (int argc, char *argv[])
    750870{
    751871  int c, rc, files;
    752   int opt_i;
    753872  const char *ext;
    754873  char tmp[512], *t;
    755   static char emxshell [200];
     874  char execname[512];
    756875
    757876  /* Get options from response files (@filename) and wildcard (*.o) on the command. */
     877 
    758878  _response (&argc, &argv);
    759879  _wildcard (&argc, &argv);
    760880
    761   /* Drop EMXSHELL since it can point to a Unix shell which is bad for us */
    762   sprintf (emxshell, "EMXSHELL=%s", getenv ("OS2_SHELL"));
    763   putenv (emxshell);
    764 
    765881  /* Close and delete the response file on exit. */
    766882
     
    769885  /* Prepare parsing of the command line. */
    770886
    771   opt_i = FALSE; files = 0;
     887  files = 0;
    772888  opterr = FALSE; optmode = GETOPT_KEEP;
    773889  if (argc < 2)
     
    776892  /* Parse the command line options and other arguments. */
    777893
    778   while ((c = getopt (argc, argv, "o:O:il:vL:T:sSxXZ:")) != EOF)
     894  while ((c = getopt (argc, argv, "o:O:itl:vL:T:sSxXZ:")) != EOF)
    779895    switch (c)
    780896      {
    781       case 'i':                 /* Use /INFORMATION option of LINK386 */
    782         opt_i = TRUE;
     897      case 't':
     898      case 'i':                 /* Trace the linking process, sending /INFO to the IBM/M$ linker. */
     899        opt_t = TRUE;
    783900        break;
    784901
     
    811928        break;
    812929
    813       case 'O':                 /* Specify LINK386 option */
     930      case 'O':                 /* Specify Linker option */
    814931        add_name_list (&add_options, optarg);
    815932        break;
     
    846963        else
    847964          {
    848             fprintf (stderr, "emxomfld: invalid option\n");
     965            fprintf (stderr, "emxomfld: invalid option (%s)\n", optarg);
    849966            usage ();
    850967          }
     
    861978          {
    862979            /* GCC's temporary files don't have an extension.  Add a
    863                dot to the end of the name to prevent LINK386 from
     980               dot to the end of the name to prevent the linker from
    864981               adding `.obj'. */
    865982
     
    9111028
    9121029      default:
    913         fprintf (stderr, "emxomfld: invalid option\n");
     1030        fprintf (stderr, "emxomfld: invalid option (%s)\n", argv[optind - 1]);
    9141031        usage ();
    9151032      }
     
    9371054    remove (output_fname);
    9381055
    939   /* If neither -Zmap nor -Zmap=file is used, pass "nul" to LINK386 in
     1056  /* If neither -Zmap nor -Zmap=file is used, pass "nul" to the linker in
    9401057     the map file field.  If -Zmap is used, construct the name of the
    9411058     .map file.  If -Zmap=file is used, use `file' as the name of the
     
    9731090          free(pcur->name);
    9741091          pcur->name = xstrdup(szname);
    975         }
    976 
    977     }
    978 
    979 
    980   /* Start building the LINK386 command line.  We can use a response
     1092          fclose(phfile);
     1093        }
     1094
     1095    }
     1096
     1097  /* EMXOMFLD_TYPE contains VAC365, VAC308 or LINK386 if set. If non of these
     1098     we assume VAC365.
     1099     EMXOMFLD_LINKER contains the linker name and perhaps extra arguments. If
     1100     not set we'll use the default linker, ilink.  */
     1101
     1102  t = getenv ("EMXOMFLD_TYPE");
     1103  if (    t
     1104      &&  stricmp(t, "VAC365")
     1105      &&  stricmp(t, "VAC308")
     1106      &&  stricmp(t, "LINK386")
     1107      )
     1108    fprintf (stderr, "emxomfld: warning: '%s' is an invalid value for EMXOMFLD_TYPE.\n", t);
     1109  else if (t)
     1110    linker_type = t;
     1111
     1112  t = getenv ("EMXOMFLD_LINKER");
     1113  if (t)
     1114    linker_name = t;
     1115  if (opt_t)
     1116    fprintf(stderr, "*** Linker     : %s\n"
     1117                    "*** Linker type: %s\n", linker_name, linker_type);
     1118
     1119
     1120
     1121  /* Start building the linker command line.  We can use a response
    9811122     file if the command line gets too long. */
    9821123
    9831124  arg_init (TRUE);
    9841125
    985   /* Default options are:
    986 
     1126  /*
     1127     For VAC365 and VAC308 the default options is:
     1128
     1129     /NOFR[EEFORMAT]    Use /NOFREEFORMAT to allow a LINK386-compatible
     1130                        command line syntax, in which different types of file
     1131                        are grouped and separated by commas.
     1132
     1133     /DBGPACK           If !strip_symbols then we'll add this option, which
     1134                        will cause type tables to be merged into one global
     1135                        table and so eliminating a lot of duplicate info.
     1136                       
     1137     For VAC365 additional default option is:
     1138     
     1139     /STUB:<emxomfld-path>\os2stub.bin
     1140                        Causes this MZ stub to be used when linking the
     1141                        executables instead of the default on for the linker.
     1142 
     1143     For LINK386 the default options is:
     1144     
    9871145     /BATCH             Run in batch mode (disable prompting, don't
    9881146                        echo response file)
     1147   
     1148     The default options for all linkers are:
    9891149
    9901150     /NOLOGO            Don't display sign-on banner
     
    10001160                        'CODE').  Not grouping neighboring code
    10011161                        segments would break sets
    1002 
    1003      For ILINK the following option is passed:
    1004 
    1005      /NOFR[EEFORMAT]    Use /NOFREEFORMAT to allow a LINK386-compatible
    1006                         command line syntax, in which different types of file
    1007                         are grouped and separated by commas.
     1162                       
     1163     For non DLLs targets:
     1164     
     1165     /BASE:0x10000      Base the executable an so removing extra fixups.
     1166
    10081167  */
    10091168
    1010   t = getenv ("EMXOMFLD_LINKER");
    1011   if (t != NULL)
    1012     linker_name = t;
     1169  /* issue commandline */
    10131170  put_arg (linker_name, TRUE, FALSE);
    10141171
    1015   /* If the linker is ILINK, don't use the /BAT{CH} option */
    1016   t = _getname (linker_name);           /* TODO: this assumes that the env var is a filename only.
    1017                                          * It should be possible to add options as well. Therefore the 2nd check. */
    1018   if (strnicmp (t, "ILINK", 5) && strnicmp(linker_name, "ILINK", 5))
    1019     put_arg ("/bat", FALSE, FALSE);
    1020   else
    1021     put_arg ("/nofree", FALSE, FALSE);
     1172  /* the next part depends on the linker type. */
     1173  if (!stricmp (linker_type, "LINK386"))
     1174      put_arg ("/bat", FALSE, FALSE); 
     1175  else /* vac3xx: */
     1176    {
     1177      put_arg ("/nofree", FALSE, FALSE); 
     1178      if (!strip_symbols)
     1179        put_arg ("/db", FALSE, FALSE); 
     1180      if (map_flag)
     1181        put_arg ("/map", FALSE, FALSE); 
     1182
     1183      /* VAC365: check if we have os2stub.bin. */
     1184      if (!stricmp (linker_type, "VAC365"))
     1185        {
     1186          struct stat s;
     1187          _execname(&execname[0], sizeof(execname));
     1188          strcpy(_getname(&execname[0]), "os2stub.bin");
     1189
     1190          if (!stat (execname, &s))
     1191            {
     1192              sprintf (tmp, "/STUB:%s", &execname[0]);
     1193              put_arg (tmp, FALSE, FALSE);
     1194            }
     1195        }
     1196    }
    10221197  put_arg ("/nol", FALSE, FALSE);
    10231198  put_arg ("/noe", FALSE, FALSE);
     
    10251200  put_arg ("/packc", FALSE, FALSE);
    10261201
    1027   /* Add the /INFORMATION option if the -i option was given.  This is
     1202  /* Add the /INFORMATION option if the -i or -t option was given.  This is
    10281203     for debugging. */
    10291204
    1030   if (opt_i)
     1205  if (opt_t)
    10311206    put_arg ("/i", FALSE, FALSE);
    10321207
    10331208  /* Add the /DEBUG option if the -s option was not given.  Without
    1034      this, LINK386 throws away debugging information. */
     1209     this, the linker throws away debugging information. */
    10351210
    10361211  if (!strip_symbols)
     
    10481223      if (def_fname != NULL)
    10491224        {
     1225          int token;
    10501226          md = _md_open (def_fname);
    10511227          if (md == NULL)
     
    10541230              exit (2);
    10551231            }
    1056           if (_md_next_token (md) == _MD_LIBRARY)
     1232          token = _md_next_token (md);
     1233          if (token == _MD_LIBRARY || token == _MD_PHYSICAL || token == _MD_VIRTUAL)
    10571234            dll_flag = TRUE;
    10581235          _md_close (md);
     
    10611238  if (base == NULL && !dll_flag)
    10621239    base = "0x10000";
    1063   if (base != NULL && strcmp (base, "no") != 0)
     1240  if (base != NULL && stricmp (base, "no") != 0)
    10641241    {
    10651242      sprintf (tmp, "/bas:%s", base);
     
    10691246  /* Add the /STACK:n option if the -Zstack option was given. */
    10701247
    1071   if (stack_size != 0)
     1248  if (stack_size != 0 && !dll_flag)
    10721249    {
    10731250      sprintf (tmp, "/st:0x%lx", stack_size * 1024);
     
    10751252    }
    10761253
    1077   /* Add the LINK386 options specified with -O. */
     1254  /* Add the linker options specified with -O. */
    10781255
    10791256  put_args (options, FALSE);
     
    11051282  arg_end ();
    11061283
    1107   /* Call LINK386 via CMD.EXE (what a waste -- but I'm lazy) and abort
    1108      on failure. */
    1109 
    1110   rc = system (command_line);
    1111   /* ILINK returns 4 on warnings: consider this as success */
    1112   if (rc == 4) rc = 0;
    1113 
     1284  /* Call Linker and abort on failure. */
     1285
     1286  rc = emxomfld_spawn (command_line, "Linker");
     1287  if (rc == 4 && !strnicmp(linker_type, "VAC3", 4)) /* Ignore iLink warnings. */
     1288      rc = 0;                           
    11141289  if (rc < 0)
    11151290    {
     
    11181293    }
    11191294
    1120   /* Run RC if LINK386 completed successfully and a binary resource
     1295  /* Run RC if Linker completed successfully and a binary resource
    11211296     file was given on the command line. */
    11221297
     
    11241299    {
    11251300      arg_init (TRUE);
    1126       put_arg ("rc", TRUE, FALSE);
     1301      put_arg ("rc.exe", TRUE, FALSE);
    11271302      put_arg ("-n", FALSE, FALSE);
    11281303      put_arg (res_fname, TRUE, TRUE);
    11291304      put_arg (output_fname, TRUE, TRUE);
    11301305      arg_end ();
    1131       rc = system (command_line);
     1306      rc = emxomfld_spawn (command_line, "Resource Linker");
    11321307      if (rc < 0)
    11331308        {
     
    11371312    }
    11381313
    1139   /* If both LINK386 and RC competed successfully and the -Zexe option
     1314  /* If both Linker and RC completed successfully and the -Zexe option
    11401315     was given, touch the output file (without .exe) to keep `make'
    11411316     happy. */
     
    11431318  if (rc == 0 && exe_flag)
    11441319    {
    1145       char execname[512];
    1146 
     1320      /* find target and source filenames. */
    11471321      t = xstrdup (output_fname);
    11481322      _remext (t);
    1149 
    1150       _execname((char *)&execname, sizeof(execname));
    1151       strcpy(_getname((char *)&execname), "ldstub.bin");
     1323      _execname(&execname[0], sizeof(execname));
     1324      strcpy(_getname(&execname[0]), "ldstub.bin");
     1325     
    11521326      /* Copy stub into file */
    1153       DosCopy((char *)&execname, t, 4);
     1327      if (opt_t)
     1328          fprintf(stderr, "*** copy %s to %s (-Zexe)", execname, t);
     1329      DosCopy(&execname[0], t, 4);
     1330
    11541331      /* Now touch it */
    11551332      if (utime(t, NULL))
     
    11611338    }
    11621339
    1163   /* Return the return code of LINK386 (or RC). */
     1340  /* Return the return code of Linker or RC. */
    11641341
    11651342  return rc;
Note: See TracChangeset for help on using the changeset viewer.