Changeset 60


Ignore:
Timestamp:
Apr 29, 2003, 6:13:11 PM (22 years ago)
Author:
bird
Message:

Changes relative to original emxomfld:

  • Resource compiler is run with "-n" so that it won't show its logo. Note that old versions of RC do not understand "-n" - if you receive messages

like "RC: error - invalid switch -n" you will need a newer RC.

  • With -Zexe emxomfld copies ldstub.bin into a file with same name as executable but without ".exe" extenstion. This way you can use Unix

shell scripts and makefiles without modifications.

  • Implemented kludgy weak sypport for emxomf converter. Alas, LINK386 does not support real weak symbols for OMF object files :-( This is

implemented by keeping a list of all weak symbols in a separate text

file, along with the object file name where it has been encountered

for the first time. Then, when this symbol is encountered, if the

output file is the mentioned object file, it is transformed into a

strong external symbol, otherwise it is transformed into a non-exported

local symbol (thus duplicate symbol errors won't occur).

  • Added the `-w' switch to emxomf to suppress reading/writing of the weaksyms.omf file.
    • Disabled several warnings encountered during translation of the newer a.out files generated by latest gcc's. It looks like stabs format has

been improved a little since last update to EMX tools.

  • Added support for variables in the BSS segment. Newer gcc can generate variables directly in .bss, and emxomf used to `forget' such labels,

although did not print any warnings.

  • emxomf won't remove the leading underscore for stdcall names. This is for better compatibility with VACPP.
    • patch to emxomld to not pass the /bat{ch} switch if the EMXOMF_LINKER variable is set to ILINK. Also for ILINK the /NOFREE{FORMAT} switch is

passed, which ensures command-line format compatibility with LINK386.

  • emxomf fixed so that the segdef records are defined as paragraph aligned. This allows to merge data segments from different object files without

breaking alignments less or equal than 16 bytes.

Location:
trunk/src/emx/src/emxomf
Files:
3 edited

Legend:

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

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r59 r60  
    2525#include <stdarg.h>
    2626#include <string.h>
     27#include <alloca.h>
     28#include <ctype.h>
    2729#include <getopt.h>
    2830#include <sys/param.h>
     
    125127};
    126128
     129/* This structure keeps track which weak symbol and where it is defined,
     130   to simulate weak symbols in OMF (which aren't supported in OMF) */
     131
     132struct weaksym
     133{
     134  struct weaksym *next;         /* Next weak symbol in chain */
     135  char *name;                   /* Symbol name */
     136  char *module;                 /* Object file where it should be defined */
     137  int used;                     /* 1 if the symbol has been encountered */
     138};
     139
    127140
    128141/* The number of symbols in the a.out file. */
     
    237250static int opt_x = FALSE;
    238251
     252/* Suppress reading and/or writing of the weaksyms.omf file */
     253static int opt_w = FALSE;
     254
     255/* Remove underscores from all symbol names */
     256static int opt_rmunder = FALSE;
     257
    239258/* This is the page size for OMF libraries.  It is set by the -p
    240259   option. */
     
    258277/* The index of the "WEAK$ZERO" symbol or 0. */
    259278static int weak_zero_index;
     279
     280/* The list of currently known OMF symbols */
     281static struct weaksym *weak_symbol_list;
     282static struct weaksym **weak_symbol_top = &weak_symbol_list;
     283
     284/* 1 whenever the weak symbol list has been altered */
     285static int weak_list_altered;
     286
     287/* The file name of the weak symbol list file */
     288static char *weak_list_filename;
    260289
    261290/* OMF name indices: segments, classes, groups, etc. */
     
    348377/* The name of the identifier manipulation DLL.  If this variable is
    349378   NULL, no IDMDLL record is written. */
    350 static char *idmdll_name = "GPPDEMID";
     379static char *idmdll_name = "GPP3DEM";
    351380
    352381/* If this variable is TRUE (-b option), we always use the 32-bit
     
    499528
    500529
     530/* Check if we should remove the leading underscore from a symbol name */
     531static inline int strip_underscore (const char *name)
     532{
     533  if (!opt_rmunder)
     534    return 0;
     535
     536  return (*name == '_');
     537}
     538
     539
    501540/* Find an a.out symbol.  The underscore character `_' is prepended to
    502541   NAME.  On success, a pointer to the symbol table entry (in the
     
    506545const struct nlist *find_symbol (const char *name)
    507546{
    508   int i, j, n, len, ok, t;
     547  int i, j, n, len, t;
    509548  const byte *s;
    510549 
     
    515554  while (i < str_size)
    516555    {
    517       ok = TRUE; s = name;
    518       if (str_ptr[i] == '_')
     556      int sym_ofs = i;
     557      s = name;
     558      if (strip_underscore (str_ptr + i))
    519559        ++i;
    520       else
    521         ok = FALSE;
    522       if (ok && memcmp (name, str_ptr+i, len+1) == 0)
     560      if (memcmp (name, str_ptr+i, len+1) == 0)
    523561        {
    524562
     
    527565
    528566          n = sym_count;
    529           --i;                  /* Move back to the underscore */
    530567          for (j = 0; j < n; ++j)
    531             if (sym_ptr[j].string == i)
     568            if (sym_ptr[j].string == sym_ofs)
    532569              {
    533570                t = sym_ptr[j].type & ~N_EXT;
     
    540577    }
    541578  return NULL;                  /* Symbol not found */
     579}
     580
     581
     582/* Add a symbol to weak symbol list */
     583
     584static struct weaksym *add_weak (const char *symname, const char *modname)
     585{
     586  struct weaksym *newsym = malloc (sizeof (struct weaksym));
     587  newsym->name = xstrdup (symname);
     588  newsym->module = xstrdup (modname);
     589  newsym->used = 0;
     590  newsym->next = NULL;
     591  *weak_symbol_top = newsym;
     592  weak_symbol_top = &newsym->next;
     593  weak_list_altered = 1;
     594  return newsym;
     595}
     596
     597
     598/* Load the weak symbols table from the weaksyms.omf file.
     599 * We emulate the weak symbol functionality in the following way:
     600 * first time we encounter a weak symbol, we mark it as "strong"
     601 * and remember the first object file where it was encountered.
     602 * Then when another instance of this weak symbol is encountered
     603 * the output file name is checked; if it is a different object file,
     604 * the symbol is marked as local. Otherwise it is marked as strong.
     605 * Finally, when we find any external references to this symbol, they
     606 * are marked as "OMF weak reference", e.g. the N_WEAKU type
     607 * (which is quite different from a.out weaks, thats why we have
     608 * to dig all that mess!). Alas, this mechanism can require multi-pass
     609 * builds for complex cases...
     610 */
     611
     612static void weak_load (void)
     613{
     614  FILE *wf;
     615
     616  if (opt_w)
     617    return;
     618
     619  /* Find and open the weak symbol list file */
     620  weak_list_filename = getenv ("GCC_WEAKSYMS");
     621  if (!weak_list_filename)
     622    weak_list_filename = "weaksyms.omf";
     623  wf = fopen (weak_list_filename, "r");
     624  if (!wf)
     625    return;
     626
     627  /* Every line of the file contains something like:
     628       __symbol:object_file
     629     or just
     630       __symbol
     631  */
     632
     633  char line [1024];
     634  while (fgets (line, sizeof (line), wf))
     635    {
     636      char *eol = strchr (line, 0);
     637      while ((eol > line) && (isspace (eol [-1])))
     638        eol--;
     639      *eol = 0;
     640      char *sep = strchr (line, ':');
     641      if (!sep)
     642        {
     643          fprintf (stderr, "WARNING: bad line `%s' in weak symbol list file `%s'\n",
     644            line, weak_list_filename);
     645          continue;
     646        }
     647
     648      *sep = 0;
     649      add_weak (line, sep + 1);
     650    }
     651
     652  fclose (wf);
     653
     654  /* Mark the list as unmodified */
     655  weak_list_altered = 0;
     656}
     657
     658
     659/* Save the weak symbol list */
     660
     661static void weak_save (void)
     662{
     663  FILE *wf;
     664  struct weaksym *wsym;
     665
     666  if (opt_w)
     667    return;
     668
     669  /* Find and open the weak symbol list file */
     670  wf = fopen (weak_list_filename, "w");
     671  if (!wf)
     672    return;
     673
     674  for (wsym = weak_symbol_list; wsym; wsym = wsym->next)
     675    fprintf (wf, "%s:%s\n", wsym->name, wsym->module);
     676
     677  fclose (wf);
     678}
     679
     680
     681/* Free the weak symbol list */
     682
     683static void weak_free (void)
     684{
     685  struct weaksym *cur = weak_symbol_list;
     686  while (cur)
     687    {
     688      struct weaksym *next = cur->next;
     689      free (cur->name);
     690      free (cur->module);
     691      free (cur);
     692      cur = next;
     693    }
     694  weak_symbol_list = NULL;
     695}
     696
     697
     698/* Find if a symbol is weak */
     699
     700static struct weaksym *is_weak (const char *symname)
     701{
     702  struct weaksym *wsym;
     703  for (wsym = weak_symbol_list; wsym; wsym = wsym->next)
     704    if (!strcmp (symname, wsym->name))
     705      return wsym;
     706  return NULL;
    542707}
    543708
     
    742907static void put_sym (const char *src)
    743908{
    744   if (*src == '_')
     909  if (strip_underscore (src))
    745910    ++src;
    746911  put_str (src);
     
    9651130
    9661131
     1132/* Check all external symbol references for weakness; if a symbol is weak,
     1133   mark it as N_WEAKU so that it is later writen within a WKEXT record.
     1134   Also we convert a.out-style weak symbols here as normal public symbols,
     1135   as the sense of weak is reverse in OMF */
     1136
     1137static void weak_process (void)
     1138{
     1139  int i;
     1140
     1141#define SETTYPE(t) ((struct nlist *)sym_ptr)[i].type = t
     1142
     1143  for (i = 0; i < sym_count; ++i)
     1144    if ((sym_ptr[i].type >= N_WEAKA) && (sym_ptr[i].type <= N_WEAKB))
     1145      {
     1146        const char *name = str_ptr + sym_ptr[i].string;
     1147
     1148        int public = N_EXT;
     1149
     1150        /* Add the symbol to weak list if not already */
     1151        struct weaksym *wsym = is_weak (name);
     1152        if (!wsym)
     1153          wsym = add_weak (name, out_fname);
     1154        else if (strcmp (out_fname, wsym->module) || wsym->used)
     1155          public = 0;
     1156        /* If the symbol is exported more than once (e.g. from an archive),
     1157           export just the first instance... */
     1158        wsym->used = 1;
     1159
     1160        /* Now convert it to a normal public symbol */
     1161        switch (sym_ptr[i].type)
     1162          {
     1163            case N_WEAKA: SETTYPE (N_ABS  | public); break;
     1164            case N_WEAKT: SETTYPE (N_TEXT | public); break;
     1165            case N_WEAKD: SETTYPE (N_DATA | public); break;
     1166            case N_WEAKB: SETTYPE (N_BSS  | public); break;
     1167          }
     1168      }
     1169    else if ((sym_ptr[i].type & N_EXT) && is_weak (str_ptr + sym_ptr[i].string))
     1170      {
     1171         /* Convert a external reference to N_WEAKU */
     1172         /* P.S. As experiments show, WKEXT works somewhat strangely
     1173            with LINK386 (sometimes such external references are left
     1174            unresolved, even that they could be resolved), thus the
     1175            following line is commented out */
     1176         /*SETTYPE (N_WEAKU);*/
     1177      }
     1178
     1179#undef SETTYPE
     1180}
     1181
     1182
    9671183/* Write ALIAS records into the output file for all indirect
    9681184   references. */
     
    9841200          {
    9851201            pub_name = str_ptr + sym_ptr[i].string;
    986             if (*pub_name == '_')
     1202            if (strip_underscore (pub_name))
    9871203              ++pub_name;
    9881204            if (omflib_add_pub (out_lib, pub_name, mod_page, lib_errmsg) != 0)
     
    10341250                  {
    10351251                    pub_name = name;
    1036                     if (*pub_name == '_')
     1252                    if (strip_underscore (pub_name))
    10371253                      ++pub_name;
    10381254                    if (omflib_add_pub (out_lib, pub_name, mod_page,
     
    10761292  write_pubdef1 (N_DATA, udat_index, FALSE, text_size);
    10771293  write_pubdef1 (N_DATA, udat_index, TRUE, text_size);
     1294  write_pubdef1 (N_BSS, bss_index, FALSE, text_size + data_size);
     1295  write_pubdef1 (N_BSS, bss_index, TRUE, text_size + data_size);
    10781296}
    10791297
     
    11711389    The segment attributes byte contains the following fields:
    11721390
    1173     A (bits 5-7)        Alignment (101=relocatable, 32-bit alignment)
     1391    A (bits 5-7)        Alignment (011=relocatable, paragraph (16b) alignment)
     1392                        (before gcc 3.2.2: 101=relocatable, 32-bit alignment)
    11741393    C (bits 2-4)        Combination (010=PUBLIC, 101=STACK)
    11751394    B (bit 1)           Big (segment length is 64KB)
     
    11801399  byte seg_attr;
    11811400
    1182   seg_attr = (stack ? 0xb5 : 0xa9);
     1401  seg_attr = (stack ? 0x75 : 0x69);
    11831402  if (size > 0x10000 || force_big)
    11841403    {
     
    21352354  /* Skip a leading underscore character if present. */
    21362355
    2137   if (*pub_name == '_')
     2356  if (strip_underscore (pub_name))
    21382357    ++pub_name;
    21392358
     
    26292848                    case N_INDR|N_EXT:
    26302849                    case N_WEAKU:
     2850                    case N_WEAKA:
     2851                    case N_WEAKT:
     2852                    case N_WEAKD:
     2853                    case N_WEAKB:
    26312854      case N_SETA:  case N_SETA|N_EXT:
    26322855      case N_SETT:  case N_SETT|N_EXT:
     
    28473070  if (do_set_groups)
    28483071    write_set_groups ();
     3072
     3073  /* Process weak symbols */
     3074  weak_process ();
    28493075
    28503076  /* Define external, communal and public symbols (EXTDEF, WKEXT,
     
    29463172  puts ("  -I <idmdll>        Name the identifier manipulation DLL");
    29473173  puts ("  -O <directory>     Extract files to <directory>");
     3174  puts ("  -w                 Suppress reading/writing of the weaksyms.omf file");
     3175  puts ("  -z                 Remove underscores from all symbol names");
    29483176  exit (1);
    29493177}
     
    33313559  /* Parse the command line options. */
    33323560
    3333   while ((c = getopt (argc, argv, "bdD:gi:I:m:l::o:p:qO:r:R:sux")) != EOF)
     3561  while ((c = getopt (argc, argv, "bdD:gi:I:m:l::o:p:qO:r:R:suxwz")) != EOF)
    33343562    switch (c)
    33353563      {
     
    34083636        opt_x = TRUE;
    34093637        break;
     3638      case 'w':
     3639        opt_w = TRUE;
     3640        break;
     3641      case 'z':
     3642        opt_rmunder = TRUE;
     3643        break;
    34103644      default:
    34113645        usage ();
     
    34173651    usage ();
    34183652
     3653  /* Initialize weak symbol list */
     3654
     3655  weak_symbol_list = NULL;
     3656  weak_load ();
     3657
    34193658  if (opt_o != NULL)
    34203659    {
    3421 
    34223660      /* If the -o option is used, there must be exactly one input
    34233661         file name. */
     
    34493687    }
    34503688
     3689  /* If the weak symbol list has been altered, save it */
     3690
     3691  if (weak_list_altered)
     3692    weak_save ();
     3693
     3694  /* Free the weak symbol list */
     3695
     3696  weak_free ();
     3697
    34513698  /* If a LIB response file has been created, finish and close it. */
    34523699
  • trunk/src/emx/src/emxomf/emxomfld.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r59 r60  
    2828#include <sys/types.h>
    2929#include <sys/stat.h>
    30 #include <getopt.h>
     30#include <emx/getopt.h>
    3131#include <errno.h>
     32#include <sys/utime.h>
    3233#include <sys/moddef.h>
     34#include <alloca.h>
    3335#include "defs.h"
    3436
     
    142144int main (int argc, char *argv[]);
    143145
     146/* To avoid including os2.h... */
     147unsigned DosCopy (char *, char *, unsigned);
     148
    144149
    145150/* Tell the user how to run this program. */
     
    461466  const char *ext;
    462467  char tmp[512], *t;
     468  static char emxshell [200];
     469
     470  /* Drop EMXSHELL since it can point to a Unix shell which is bad for us */
     471  sprintf (emxshell, "EMXSHELL=%s", getenv ("OS2_SHELL"));
     472  putenv (emxshell);
    463473
    464474  /* Close and delete the response file on exit. */
     
    675685                        statement is used for a segment of class
    676686                        'CODE').  Not grouping neighboring code
    677                         segments would break sets */
     687                        segments would break sets
     688
     689     For ILINK the following option is passed:
     690
     691     /NOFR[EEFORMAT]    Use /NOFREEFORMAT to allow a LINK386-compatible
     692                        command line syntax, in which different types of file
     693                        are grouped and separated by commas.
     694  */
    678695
    679696  put_arg (linker_name, TRUE);
     697
     698  /* If the linker is ILINK, don't use the /BAT{CH} option */
     699  t = _getname (linker_name);
     700  if (strnicmp (t, "ILINK", 5))
    680701  put_arg ("/bat", FALSE);
     702  else
     703    put_arg ("/nofree", FALSE);
    681704  put_arg ("/nol", FALSE);
    682705  put_arg ("/noe", FALSE);
     
    772795
    773796  rc = system (command_line);
     797  /* ILINK returns 4 on warnings: consider this as success */
     798  if (rc == 4) rc = 0;
     799
    774800  if (rc < 0)
    775801    {
     
    784810    {
    785811      arg_init (TRUE);
    786       put_arg ("rc", TRUE);
     812      put_arg ("rc -n", TRUE);
    787813      put_arg (res_fname, TRUE);
    788814      put_arg (output_fname, TRUE);
     
    802828  if (rc == 0 && exe_flag)
    803829    {
    804       int h;
    805 
    806       h = open (output_fname,
    807                 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
    808       if (h < 0)
     830      char execname[512];
     831
     832      t = xstrdup (output_fname);
     833      _remext (t);
     834
     835      _execname((char *)&execname, sizeof(execname));
     836      strcpy(_getname((char *)&execname), "ldstub.bin");
     837      /* Copy stub into file */
     838      DosCopy((char *)&execname, t, 4);
     839      /* Now touch it */
     840      if (utime(t, NULL))
    809841        {
    810842          perror ("emxomfld");
    811843          exit (2);
    812844        }
    813       close (h);
     845      free (t);
    814846    }
    815847
  • trunk/src/emx/src/emxomf/stabshll.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r59 r60  
    2525#include <string.h>
    2626#include <time.h>
     27#include <alloca.h>
    2728#include "defs.h"
    2829#include "emxomf.h"
     
    341342static int unnamed_struct_number;
    342343
     344/* Suppress several kinds of warnings since newer gccs generates lots of
     345   warnings... */
     346
     347static void no_warning (char *format, ...)
     348{
     349  (void)format;
     350}
     351
    343352
    344353/* Start a type table record of type TYPE, with type qualifier QUAL.
     
    912921      /* This should not happen. */
    913922
    914       warning ("stabs type %d not defined", tp->d.stabs_ref);
     923      no_warning ("stabs type %d not defined", tp->d.stabs_ref);
    915924      return 4;
    916925
     
    934943      if (tp->d.struc.flags & STRUC_FORWARD)
    935944        {
    936           warning ("size of incomplete structure %s is unknown",
     945          no_warning ("size of incomplete structure %s is unknown",
    937946                   tp->d.struc.name);
    938947          return 0;
     
    11751184  if (*parse_ptr != c)
    11761185    {
    1177       warning ("Invalid symbol data: `%c' expected", c);
     1186      no_warning ("Invalid symbol data: `%c' expected", c);
    11781187      return FALSE;
    11791188    }
     
    12241233    default:
    12251234      ++parse_ptr;
    1226       warning ("Invalid visibility: %c", *parse_ptr);
     1235      no_warning ("Invalid visibility: %c", *parse_ptr);
    12271236      if (*parse_ptr != 0)
    12281237        ++parse_ptr;
     
    13611370      else
    13621371        {
    1363           warning ("Unknown range type: %lld..%lld", range_lo, range_hi);
     1372          no_warning ("Unknown range type: %lld..%lld", range_lo, range_hi);
    13641373          goto syntax;
    13651374        }
     
    16181627                  if (*parse_ptr != ':')
    16191628                    {
    1620                       warning ("Arguments for member function missing");
     1629                      no_warning ("Arguments for member function missing");
    16211630                      goto syntax;
    16221631                    }
     
    16431652                      break;
    16441653                    default:
    1645                       warning ("Unknown member function qualifier: %c",
     1654                      no_warning ("Unknown member function qualifier: %c",
    16461655                               *parse_ptr);
    16471656                      if (*parse_ptr != 0)
     
    16731682                      break;
    16741683                    default:
    1675                       warning ("Unknown member function qualifier: %c",
     1684                      no_warning ("Unknown member function qualifier: %c",
    16761685                               *parse_ptr);
    16771686                      if (*parse_ptr != 0)
     
    19791988
    19801989    default:
    1981       warning ("Unknown type: %c", *parse_ptr);
     1990      no_warning ("Unknown type: %c", *parse_ptr);
    19821991      goto syntax;
    19831992    }
     
    20082017  tp = parse_type (type_name);
    20092018  if (*parse_ptr != 0)
    2010     warning ("unexpected character at end of stabs type: %c", *parse_ptr);
     2019    no_warning ("unexpected character at end of stabs type: %c", *parse_ptr);
    20112020  return tp;
    20122021}
     
    20322041  if (tp->index == -2)
    20332042    {
    2034       warning ("Cycle detected by make_type");
     2043      no_warning ("Cycle detected by make_type");
    20352044      RETURN (0);
    20362045    }
     
    20442053      if (t1 == NULL)
    20452054        {
    2046           warning ("Undefined stabs type %d referenced", tp->d.stabs_ref);
     2055          no_warning ("Undefined stabs type %d referenced", tp->d.stabs_ref);
    20472056          RETURN (0x82);        /* 32 bit signed */
    20482057        }
     
    27242733          if (sym2 == NULL)
    27252734            {
    2726               warning ("Cannot find address of global variable %s", name);
     2735              no_warning ("Cannot find address of global variable %s", name);
    27272736              return;
    27282737            }
Note: See TracChangeset for help on using the changeset viewer.