Changeset 914


Ignore:
Timestamp:
Dec 28, 2003, 5:44:43 AM (22 years ago)
Author:
bird
Message:

Added feature for automatic a.out to omf conversion.

File:
1 edited

Legend:

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

    • Property cvs2svn:cvs-rev changed from 1.30 to 1.31
    r913 r914  
    11/* emxomfld.c --  Provide an ld-like interface to the IBM and M$ linkers
    22   Copyright (c) 1992-1998 Eberhard Mattes
     3   Copyright (c) 2003 InnoTek Systemberatung GmbH
     4   Copyright (c) 2003-2004 Knut St. Osmundsen
    35
    46This file is part of emxomld.
     
    122124static char weakdef_fname[_MAX_PATH + 1];
    123125
     126/* list of converted libraries and objects which must be removed upon exit. */
     127static name_list *conv_list = NULL;
     128
    124129/* Non-zero if debugging information is to be omitted.  Set by the -s
    125130   and -S options. */
     
    146151   var. using any of the value VAC365, VAC308 and LINK386. */
    147152static const char *linker_type = "VAC365";
     153
     154/* Non-zero if emxomfld should automatically convert a.out objects and
     155   archives to the OMF equivalents during linking. */
     156static int autoconvert_flag = 1;
     157
    148158
    149159/* Prototypes. */
     
    180190           "Usage: emxomfld -o <file> [-l <lib>] [-L <libdir>] [-T <base>] [-igtsS]\n"
    181191           "                [-Zexe] [-Zdll] [-Zstack <size>] [-Zmap[=<map_file>]]\n"
    182            "                [-O <option>] <file>...\n"
     192           "                [-Z[no-]autoconv] [-O <option>] <file>...\n"
     193           "\n"
     194           "Options:\n"
     195           " -Zno-autoconv / -Zautoconv:\n"
     196           "    Turns off/on the automatic conversion of a.out libs and objs.\n"
     197           "    default: -Zautoconv\n"
    183198           "\n"
    184199           "Environment variables:\n"
     
    502517
    503518  if (fread (&libhdr, 1, sizeof(libhdr), f) == sizeof (libhdr)
     519   && !fseek (f, 0, SEEK_SET)
    504520   && libhdr.rec_type == LIBHDR
    505521   && libhdr.flags <= 1 /* ASSUME only first bit is used... */
    506    && !fseek (f, 0, SEEK_SET))
     522      )
    507523    {
    508524      int page_size = libhdr.rec_len + 3;
     
    516532}
    517533
    518 /* Finds the full path of a library or object file.
     534
     535/* Checks if the file handle is to an omf object or library file. */
     536
     537static int check_omf (FILE *f)
     538{
     539#pragma pack(1)
     540  struct
     541  {
     542    byte rec_type;
     543    word rec_len;
     544  } omfhdr;
     545#pragma pack()
     546  if (fread (&omfhdr, 1, sizeof(omfhdr), f) == sizeof (omfhdr)
     547   && omfhdr.rec_type == THEADR
     548   && omfhdr.rec_len >= sizeof(omfhdr)
     549   && !fseek (f, 0, SEEK_SET)
     550      )
     551    {
     552      return 1;
     553    }
     554
     555  return !fseek (f, 0, SEEK_SET) && check_omf_library (f);
     556}
     557
     558
     559/**
     560 * Generates an unique temporary file.
     561 *
     562 * @returns 0 on success.
     563 * @returns -1 on failure.
     564 * @param   pszFile     Where to put the filename.
     565 * @param   pszPrefix   Prefix.
     566 * @param   pszSuffix   Suffix.
     567 * @remark  The code is nicked from the weak linker.
     568 */
     569static int      make_tempfile(char *pszFile, const char *pszPrefix, const char *pszSuffix)
     570{
     571    struct stat     s;
     572    unsigned        c = 0;
     573    pid_t           pid = getpid();
     574    const char *    pszTmp = getenv("TMP");
     575    if (!pszTmp)    pszTmp = getenv("TMPDIR");
     576    if (!pszTmp)    pszTmp = getenv("TEMP");
     577    if (!pszTmp)    pszTmp = ".";
     578
     579    do
     580    {
     581        struct timeval  tv = {0,0};
     582        if (c++ >= 200)
     583            return -1;
     584        gettimeofday(&tv, NULL);
     585        sprintf(pszFile, "%s\\%s%x%lx%d%lx%s", pszTmp, pszPrefix, pid, tv.tv_sec, c, tv.tv_usec, pszSuffix);
     586    } while (!stat(pszFile, &s));
     587
     588    return 0;
     589}
     590
     591
     592/* Converts the file indicated by pf & pszFilename to omf closing f and
     593   updating filename with the new (temporary filename). A successful
     594   return from the function returns a pointe to the filestream for the
     595   converted file. On failure NULL is returned, f is closed adn filename
     596   is undefined. */
     597
     598static FILE *aout_to_omf (FILE *pf, char *pszFilename, int fLibrary)
     599{
     600    int         rc;
     601    char *      pszNewFile;
     602    name_list  *pName;
     603
     604    fclose(pf);                         /* don't need this! */
     605
     606    if (opt_t)
     607      fprintf(stderr, "emxomfld: info: converting %s %s to OMF.\n",
     608              fLibrary ? "lib" : "obj", pszFilename);
     609
     610    /*
     611     * Make temporary file.
     612     */
     613    pName = xmalloc(sizeof(name_list));
     614    pName->name = pszNewFile = xmalloc(_MAX_PATH);
     615    if (make_tempfile(pszNewFile, "ldconv", fLibrary ? ".lib" : ".obj"))
     616    {
     617        free(pszNewFile);
     618        return NULL;
     619    }
     620
     621    /*
     622     * Do the conversion.
     623     */
     624    rc = spawnlp(P_WAIT, "emxomf.exe", "emxomf.exe",
     625                 "-o", pszNewFile, pszFilename, NULL);
     626    if (!rc)
     627    {
     628        /* open the file */
     629        pf = fopen(pszNewFile, "rb");
     630        if (pf)
     631        {
     632            /* add to auto delete list for removal on exit(). */
     633            pName->next = conv_list;
     634            conv_list = pName;
     635
     636            strcpy(pszFilename, pszNewFile);
     637
     638            if (opt_t)
     639              fprintf(stderr, "emxomfld: info: convert result '%s'.\n",
     640                      pszFilename);
     641            return pf;
     642        }
     643        remove(pszNewFile);
     644    }
     645    free(pszNewFile);
     646    free(pName);
     647
     648    fprintf (stderr, "emxomfld: a.out to omf conversion failed for '%s'.\n",
     649             pszFilename);
     650    exit (2);
     651    return NULL;
     652}
     653
     654
     655/* Finds the full path of a OMF library or object file.
     656
     657   This function may perform conversion from a.out to omf if that feature
     658   is enabled.
    519659
    520660   Object files and libraries will be searched for using the LIB env.var
     
    537677static FILE *find_objlib (char *fullname, const char *name, int is_library)
    538678{
    539   const char *exts [2][2] = { { ".obj", ".o" }, { ".lib", ".a" } };
     679  static const char *exts [2][2] = { { ".obj", ".o" }, { ".lib", ".a" } };
    540680  FILE *f;
    541681  size_t pathlen, namelen = strlen (name);
     
    605745          if (f)
    606746            {
    607               if (is_library && !check_omf_library (f))
     747              if (autoconvert_flag && !check_omf (f))
     748                f = aout_to_omf (f, fullname, is_library);
     749
     750              if (is_library && !check_omf_library (f) /* not sure if this makes sense */)
    608751                fclose (f);
    609752              else
     
    9031046      weakdef_fname[0] = '\0';
    9041047    }
     1048  for (; conv_list; conv_list = conv_list->next)
     1049      remove (conv_list->name);
    9051050}
    9061051
     
    10041149            ++optind;
    10051150          }
     1151        else if (strcmp (optarg, "autoconv") == 0)
     1152          autoconvert_flag = 1;
     1153        else if (strcmp (optarg, "no-autoconv") == 0)
     1154          autoconvert_flag = 0;
    10061155        else
    10071156          {
     
    11371286                    "*** Linker type: %s\n", linker_name, linker_type);
    11381287
    1139   /* apply library hacks */
     1288  /* apply object & library hacks */
     1289  for (pcur = obj_fnames, rc = 0; !rc && pcur; pcur = pcur->next)
     1290    {
     1291      char szname[_MAX_PATH + 1];
     1292      FILE *phfile = find_objlib (szname, pcur->name, FALSE);
     1293      if (!phfile)
     1294        continue;
     1295      free (pcur->name);
     1296      pcur->name = xstrdup(szname);
     1297      fclose(phfile);
     1298    }
     1299
    11401300  for (pcur = lib_fnames, rc = 0; !rc && pcur; pcur = pcur->next)
    11411301    {
     
    11481308      fclose(phfile);
    11491309    }
     1310
    11501311
    11511312  /* Do the weak prelinking unless GCC_WEAKSYMS are set.
Note: See TracChangeset for help on using the changeset viewer.