* src/SDCCmain.c (linkEdit): fixed bug 1609279
[fw/sdcc] / src / SDCCmain.c
index 2c89171d08991fec84f611091526c23200b3b55c..ac9385656809bc1652edb44083c02b23afe3bf5f 100644 (file)
@@ -91,10 +91,9 @@ int ds390_jammed = 0;
 char scratchFileName[PATH_MAX];
 char buffer[PATH_MAX * 2];
 
-#define OPTION_HELP     "-help"
-
 #define LENGTH(_a)      (sizeof(_a)/sizeof(*(_a)))
 
+#define OPTION_HELP             "--help"
 #define OPTION_STACK_8BIT       "--stack-8bit"
 #define OPTION_OUT_FMT_IHX      "--out-fmt-ihx"
 #define OPTION_OUT_FMT_S19      "--out-fmt-s19"
@@ -146,7 +145,7 @@ char buffer[PATH_MAX * 2];
 static const OPTION
 optionsTable[] = {
     { 0,    NULL,                   NULL, "General options" },
-    { 0,    "--help",               NULL, "Display this help" },
+    { 0,    OPTION_HELP,            NULL, "Display this help" },
     { 'v',  OPTION_VERSION,         NULL, "Display sdcc's version" },
     { 0,    "--verbose",            &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
     { 'V',  NULL,                   &options.verboseExec, "Execute verbosely.  Show sub commands as they are run" },
@@ -165,7 +164,7 @@ optionsTable[] = {
     { 'o',  NULL,                   NULL, "Place the output into the given path resp. file" },
     { 0,    OPTION_PRINT_SEARCH_DIRS, &options.printSearchDirs, "display the directories in the compiler's search path"},
     { 0,    OPTION_MSVC_ERROR_STYLE, &options.vc_err_style, "messages are compatible with Micro$oft visual studio"},
-    { 0,    OPTION_USE_STDOUT, &options.use_stdout, "send errors to stdout instead of stderr"},
+    { 0,    OPTION_USE_STDOUT,      NULL, "send errors to stdout instead of stderr"},
     { 0,    "--nostdlib",           &options.nostdlib, "Do not include the standard library directory in the search path" },
     { 0,    "--nostdinc",           &options.nostdinc, "Do not include the standard include directory in the search path" },
     { 0,    OPTION_LESS_PEDANTIC,   NULL, "Disable some of the more pedantic warnings" },
@@ -181,7 +180,7 @@ optionsTable[] = {
     { 'm',  NULL,                   NULL, "Set the port to use e.g. -mz80." },
     { 'p',  NULL,                   NULL, "Select port specific processor e.g. -mpic14 -p16f84" },
     { 0,    OPTION_LARGE_MODEL,     NULL, "external data space is used" },
-    { 0,    OPTION_MEDIUM_MODEL,    NULL, "not supported" },
+    { 0,    OPTION_MEDIUM_MODEL,    NULL, "external paged data space is used" },
     { 0,    OPTION_SMALL_MODEL,     NULL, "internal data space is used (default)" },
 #if !OPT_DISABLE_DS390
     { 0,    OPTION_FLAT24_MODEL,    NULL, "use the flat24 model for the ds390 (default)" },
@@ -263,8 +262,10 @@ optionsTable[] = {
     { 0,    OPTION_STACK_LOC,       NULL, "<nnnn> Stack pointer initial value" },
     { 0,    OPTION_DATA_LOC,        NULL, "<nnnn> Direct data start location" },
     { 0,    OPTION_IDATA_LOC,       NULL, NULL },
+#if !OPT_DISABLE_DS390 || !OPT_DISABLE_MCS51 || !OPT_DISABLE_PIC
+    { 0,    OPTION_STACK_SIZE,      NULL,"MCS51/DS390/PIC - Tells the linker to allocate this space for stack"},
+#endif
 #if !OPT_DISABLE_DS390 || !OPT_DISABLE_MCS51
-    { 0,    OPTION_STACK_SIZE,      NULL,"MCS51/DS390 - Tells the linker to allocate this space for stack"},
     { 0,    OPTION_PACK_IRAM,       NULL,"MCS51/DS390 - Tells the linker to pack variables in internal ram (default)"},
     { 0,    OPTION_NO_PACK_IRAM,    &options.no_pack_iram,"MCS51/DS390 - Tells the linker not to pack variables in internal ram"},
 #endif
@@ -306,7 +307,7 @@ static const char *_baseValues[] = {
   NULL
 };
 
-static const char *_preCmd = "{cpp} -nostdinc -Wall -std=c99 -DSDCC=1 {cppextraopts} \"{fullsrcfilename}\" \"{cppoutfilename}\"";
+static const char *_preCmd = "{cpp} -nostdinc -Wall -std=c99 {cppextraopts} \"{fullsrcfilename}\" \"{cppoutfilename}\"";
 
 PORT *port;
 
@@ -376,7 +377,6 @@ static void
 _setProcessor (char *_processor)
 {
   port->processor = _processor;
-  fprintf(stderr,"Processor: %s\n",_processor);
 }
 
 static void
@@ -413,7 +413,7 @@ _findPort (int argc, char **argv)
     }
 
   /* Use the first in the list */
-        port = _ports[0];
+  port = _ports[0];
 }
 
 /* search through the command line options for the processor */
@@ -437,16 +437,16 @@ _findProcessor (int argc, char **argv)
 /* printVersionInfo - prints the version info        */
 /*-----------------------------------------------------------------*/
 void
-printVersionInfo (void)
+printVersionInfo (FILE *stream)
 {
   int i;
 
-  fprintf (stderr,
+  fprintf (stream,
            "SDCC : ");
   for (i = 0; i < NUM_PORTS; i++)
-    fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
+    fprintf (stream, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
 
-  fprintf (stderr, " " SDCC_VERSION_STR
+  fprintf (stream, " " SDCC_VERSION_STR
 #ifdef SDCC_SUB_VERSION_STR
            "/" SDCC_SUB_VERSION_STR
 #endif
@@ -468,7 +468,7 @@ printVersionInfo (void)
 }
 
 static void
-printOptions(const OPTION *optionsTable)
+printOptions(const OPTION *optionsTable, FILE *stream)
 {
   int i;
   for (i = 0;
@@ -479,11 +479,11 @@ printOptions(const OPTION *optionsTable)
       if (!optionsTable[i].shortOpt && !optionsTable[i].longOpt
           && optionsTable[i].help)
         {
-          fprintf (stdout, "\n%s:\n", optionsTable[i].help);
+          fprintf (stream, "\n%s:\n", optionsTable[i].help);
         }
       else
         {
-          fprintf(stdout, "  %c%c  %-20s  %s\n",
+          fprintf(stream, "  %c%c  %-20s  %s\n",
                   optionsTable[i].shortOpt !=0 ? '-' : ' ',
                   optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
                   optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
@@ -496,28 +496,28 @@ printOptions(const OPTION *optionsTable)
 /*-----------------------------------------------------------------*/
 /* printUsage - prints command line syntax         */
 /*-----------------------------------------------------------------*/
-void
+static void
 printUsage (void)
 {
     int i;
-    printVersionInfo();
-    fprintf (stdout,
+    FILE *stream = stderr;
+
+    printVersionInfo (stream);
+    fprintf (stream,
              "Usage : sdcc [options] filename\n"
              "Options :-\n"
              );
 
-    printOptions(optionsTable);
+    printOptions (optionsTable, stream);
 
     for (i = 0; i < NUM_PORTS; i++)
       {
         if (_ports[i]->poptions != NULL)
           {
-            fprintf (stdout, "\nSpecial options for the %s port:\n", _ports[i]->target);
-            printOptions (_ports[i]->poptions);
+            fprintf (stream, "\nSpecial options for the %s port:\n", _ports[i]->target);
+            printOptions (_ports[i]->poptions, stream);
           }
       }
-
-    exit (0);
 }
 
 /*-----------------------------------------------------------------*/
@@ -712,7 +712,7 @@ getStringArg(const char *szStart, char **argv, int *pi, int argc)
         {
           werror (E_ARGUMENT_MISSING, szStart);
           /* Die here rather than checking for errors later. */
-          exit(-1);
+          exit(EXIT_FAILURE);
         }
       else
         {
@@ -882,10 +882,19 @@ parseCmdLine (int argc, char **argv)
       /* options */
       if (argv[i][0] == '-' && argv[i][1] == '-')
         {
+          if (strcmp (argv[i], OPTION_USE_STDOUT) == 0)
+            {
+              if (options.use_stdout == 0)
+                {
+                  options.use_stdout = 1;
+                  dup2(STDOUT_FILENO, STDERR_FILENO);
+                }
+              continue;
+            }
           if (strcmp (argv[i], OPTION_HELP) == 0)
             {
               printUsage ();
-              exit (0);
+              exit (EXIT_SUCCESS);
             }
 
           if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
@@ -956,8 +965,8 @@ parseCmdLine (int argc, char **argv)
 
           if (strcmp (argv[i], OPTION_VERSION) == 0)
             {
-              printVersionInfo ();
-              exit (0);
+              printVersionInfo (stdout);
+              exit (EXIT_SUCCESS);
               continue;
             }
 
@@ -999,14 +1008,14 @@ parseCmdLine (int argc, char **argv)
 
           if (strcmp (argv[i], OPTION_XRAM_SIZE) == 0)
             {
-              options.xram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
+              options.xram_size = getIntArg(OPTION_XRAM_SIZE, argv, &i, argc);
               options.xram_size_set = TRUE;
               continue;
             }
 
           if (strcmp (argv[i], OPTION_CODE_SIZE) == 0)
             {
-              options.code_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
+              options.code_size = getIntArg(OPTION_CODE_SIZE, argv, &i, argc);
               continue;
             }
 
@@ -1155,7 +1164,7 @@ parseCmdLine (int argc, char **argv)
               verifyShortOption(argv[i]);
 
               printUsage ();
-              exit (0);
+              exit (EXIT_SUCCESS);
               break;
 
             case 'm':
@@ -1247,7 +1256,7 @@ parseCmdLine (int argc, char **argv)
             case 'v':
               verifyShortOption(argv[i]);
 
-              printVersionInfo ();
+              printVersionInfo (stdout);
               exit (0);
               break;
 
@@ -1429,7 +1438,6 @@ parseCmdLine (int argc, char **argv)
         werror (E_FILE_OPEN_ERR, scratchFileName);
     }
   MSVC_style(options.vc_err_style);
-  if(options.use_stdout) dup2(STDOUT_FILENO, STDERR_FILENO);
 
   return 0;
 }
@@ -1524,14 +1532,14 @@ linkEdit (char **envp)
 
           /* data segment start. If zero, the linker chooses
              the best place for data */
-          if(options.data_loc)
+          if (options.data_loc)
             {
               WRITE_SEG_LOC (DATA_NAME, options.data_loc);
             }
 
           /* xdata segment start. If zero, the linker chooses
              the best place for xdata */
-          if(options.xdata_loc)
+          if (options.xdata_loc)
             {
               WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
             }
@@ -1579,10 +1587,22 @@ linkEdit (char **envp)
               switch (options.model)
                 {
                 case MODEL_SMALL:
-                  c = "small";
+                  if (options.stackAuto)
+                    c = "small-stack-auto";
+                  else
+                    c = "small";
+                  break;
+                case MODEL_MEDIUM:
+                  if (options.stackAuto)
+                    c = "medium-stack-auto";
+                  else
+                    c = "medium";
                   break;
                 case MODEL_LARGE:
-                  c = "large";
+                  if (options.stackAuto)
+                    c = "large-stack-auto";
+                  else
+                    c = "large";
                   break;
                 case MODEL_FLAT24:
                   /* c = "flat24"; */
@@ -1599,7 +1619,7 @@ linkEdit (char **envp)
                       fprintf(stderr,
                         "Add support for your FLAT24 target in %s @ line %d\n",
                         __FILE__, __LINE__);
-                      exit(-1);
+                      exit(EXIT_FAILURE);
                     }
                   break;
                 case MODEL_PAGE0:
@@ -1647,7 +1667,7 @@ linkEdit (char **envp)
                   fprintf(stderr,
                     "Add support for your FLAT24 target in %s @ line %d\n",
                     __FILE__, __LINE__);
-                  exit(-1);
+                  exit(EXIT_FAILURE);
                 }
               }
 #endif
@@ -1775,7 +1795,7 @@ linkEdit (char **envp)
       set *tempSet=NULL, *libSet=NULL;
 
       strcpy(buffer3, linkerScriptFileName);
-      if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
+      if(/*TARGET_IS_PIC16 ||*/ TARGET_IS_PIC) {
 
          /* use $l to set the linker include directories */
          tempSet = appendStrSet(libDirsSet, "-I\"", "\"");
@@ -1812,6 +1832,13 @@ linkEdit (char **envp)
   /*  if (options.verbose)fprintf(stderr, "linker command line: %s\n", buffer); */
 
   system_ret = my_system (buffer);
+
+#ifdef _WIN32
+  #define STRCMP stricmp
+#else
+  #define STRCMP strcmp
+#endif
+
   /* TODO: most linker don't have a -o parameter */
   /* -o option overrides default name? */
   if (fullDstFileName)
@@ -1840,8 +1867,8 @@ linkEdit (char **envp)
       strncatz (scratchFileName,
         options.out_fmt ? ".S19" : ".ihx",
         sizeof(scratchFileName));
-      if (strcmp (fullDstFileName, scratchFileName))
-        unlink (fullDstFileName);
+      if (STRCMP (fullDstFileName, scratchFileName))
+        remove (fullDstFileName);
       rename (scratchFileName, fullDstFileName);
 
       strncpyz (buffer, fullDstFileName, sizeof(buffer));
@@ -1856,15 +1883,15 @@ linkEdit (char **envp)
       strncatz (scratchFileName, ".map", sizeof(scratchFileName));
       *q = 0;
       strncatz(buffer, ".map", sizeof(buffer));
-      if (strcmp (scratchFileName, buffer))
-        unlink (buffer);
+      if (STRCMP (scratchFileName, buffer))
+        remove (buffer);
       rename (scratchFileName, buffer);
       *p = 0;
       strncatz (scratchFileName, ".mem", sizeof(scratchFileName));
       *q = 0;
       strncatz(buffer, ".mem", sizeof(buffer));
-      if (strcmp (scratchFileName, buffer))
-        unlink (buffer);
+      if (STRCMP (scratchFileName, buffer))
+        remove (buffer);
       rename (scratchFileName, buffer);
       if (options.debug)
         {
@@ -1872,14 +1899,14 @@ linkEdit (char **envp)
           strncatz (scratchFileName, ".cdb", sizeof(scratchFileName));
           *q = 0;
           strncatz(buffer, ".cdb", sizeof(buffer));
-          if (strcmp (scratchFileName, buffer))
-            unlink (buffer);
+          if (STRCMP (scratchFileName, buffer))
+            remove (buffer);
           rename (scratchFileName, buffer);
           /* and the OMF file without extension: */
           *p = 0;
           *q = 0;
-          if (strcmp (scratchFileName, buffer))
-            unlink (buffer);
+          if (STRCMP (scratchFileName, buffer))
+            remove (buffer);
           rename (scratchFileName, buffer);
         }
     }
@@ -1932,7 +1959,7 @@ assemble (char **envp)
                   port->linker.rel_ext,
                   sizeof(scratchFileName));
         if (strcmp (scratchFileName, fullDstFileName))
-          unlink (fullDstFileName);
+          remove (fullDstFileName);
         rename (scratchFileName, fullDstFileName);
     }
 }
@@ -1952,6 +1979,16 @@ preProcess (char **envp)
       const char *s;
       set *inclList = NULL;
 
+      if (NULL != port->linker.rel_ext)
+        {
+#define OBJ_EXT_STR     "-obj-ext="
+#define OBJ_EXT_LEN     ((sizeof OBJ_EXT_STR) - 1)
+          char *buf = Safe_alloc(strlen(port->linker.rel_ext) + (OBJ_EXT_LEN + 1));
+          strcpy(buf, OBJ_EXT_STR);
+          strcpy(&buf[OBJ_EXT_LEN], port->linker.rel_ext);
+          addSet(&preArgvSet, buf);
+        }
+
       /* if using external stack define the macro */
       if (options.useXstack)
         addSet(&preArgvSet, Safe_strdup("-DSDCC_USE_XSTACK"));
@@ -1994,10 +2031,24 @@ preProcess (char **envp)
           break;
         }
 
+      /* add SDCC version number */
+      {
+        char buf[20];
+        SNPRINTF(buf, sizeof(buf), "-DSDCC=%d%d%d",
+                 SDCC_VERSION_HI, SDCC_VERSION_LO, SDCC_VERSION_P);
+        addSet(&preArgvSet, Safe_strdup(buf));
+      }
+
       /* add port (processor information to processor */
       addSet(&preArgvSet, Safe_strdup("-DSDCC_{port}"));
       addSet(&preArgvSet, Safe_strdup("-D__{port}"));
 
+      if (port && port->processor && TARGET_IS_PIC) {
+        char proc[512];
+       SNPRINTF(&proc[0], 512, "-DSDCC_PROCESSOR=\"%s\"", port->processor);
+       addSet(&preArgvSet, Safe_strdup(proc));
+      }
+
       /* standard include path */
       if (!options.nostdinc) {
         inclList = appendStrSet(includeDirsSet, "-I\"", "\"");
@@ -2022,7 +2073,6 @@ preProcess (char **envp)
 
       if (options.verbose)
         printf ("sdcc: Calling preprocessor...\n");
-
       buildCmdLine2 (buffer, sizeof(buffer), _preCmd);
 
       if (preProcOnly) {
@@ -2069,13 +2119,6 @@ setBinPaths(const char *argv0)
     SNPRINTF(buf, sizeof buf, "%s" PREFIX2BIN_DIR, p);
     addSetHead(&binPathSet, Safe_strdup(buf));
   }
-
-#if 0
-  if (options.printSearchDirs) {
-    printf("programs:\n");
-    fputStrSet(stdout, binPathSet);
-  }
-#endif
 }
 
 /* Set system include path */
@@ -2119,13 +2162,6 @@ setIncludePath(void)
         addSetHead(&includeDirsSet, p2);
     }
   }
-
-#if 0
-  if (options.printSearchDirs) {
-    printf("includedir:\n");
-    fputStrSet(stdout, includeDirsSet);
-  }
-#endif
 }
 
 /* Set system lib path */
@@ -2150,13 +2186,6 @@ setLibPath(void)
 
   if ((p = getenv(SDCC_LIB_NAME)) != NULL)
     addSetHead(&libDirsSet, p);
-
-#if 0
-  if (options.printSearchDirs) {
-    printf("libdir:\n");
-    fputStrSet(stdout, libDirsSet);
-  }
-#endif
 }
 
 /* Set data path */
@@ -2193,13 +2222,6 @@ setDataPaths(const char *argv0)
   addSet(&dataDirsSet, Safe_strdup(DATADIR));
 #endif
 
-#if 0
-  if (options.printSearchDirs) {
-    printf("datadir:\n");
-    fputStrSet(stdout, dataDirsSet);
-  }
-#endif
-
   setIncludePath();
   setLibPath();
 }
@@ -2291,8 +2313,6 @@ main (int argc, char **argv, char **envp)
   /* turn all optimizations off by default */
   memset (&optimize, 0, sizeof (struct optimize));
 
-  /*printVersionInfo (); */
-
   if (NUM_PORTS==0) {
     fprintf (stderr, "Build error: no ports are enabled.\n");
     exit (1);
@@ -2302,7 +2322,7 @@ main (int argc, char **argv, char **envp)
   atexit(rm_tmpfiles);
 
   /* install signal handler;
-     it's only purpuse is to call exit() to remove temp files */
+     it's only purpose is to call exit() to remove temp files */
   if (!getenv("SDCC_LEAVE_SIGNALS"))
     {
       signal (SIGABRT, sig_handler);
@@ -2322,7 +2342,7 @@ main (int argc, char **argv, char **envp)
 #ifdef JAMIN_DS390
   if (strcmp(port->target, "mcs51") == 0) {
     printf("DS390 jammed in A\n");
-          _setPort ("ds390");
+    _setPort ("ds390");
     ds390_jammed = 1;
   }
 #endif
@@ -2340,8 +2360,12 @@ main (int argc, char **argv, char **envp)
     options.stack10bit=0;
   }
 #endif
+
   parseCmdLine (argc, argv);
 
+  if (options.verbose && NULL != port->processor)
+    printf("Processor: %s\n", port->processor);
+
   initValues ();
 
   setBinPaths(argv[0]);
@@ -2354,12 +2378,13 @@ main (int argc, char **argv, char **envp)
         doPrintSearchDirs();
 
   /* if no input then printUsage & exit */
-  if (!options.c1mode && !fullSrcFileName && peekSet(relFilesSet) == NULL) {
-    if (!options.printSearchDirs)
+  if (!options.c1mode && !fullSrcFileName && peekSet(relFilesSet) == NULL)
+    {
+      if (options.printSearchDirs)
+        exit (EXIT_SUCCESS);
       printUsage();
-
-    exit(0);
-  }
+      exit (EXIT_FAILURE);
+    }
 
   /* initMem() is expensive, but
      initMem() must called before port->finaliseOptions ().
@@ -2423,6 +2448,9 @@ main (int argc, char **argv, char **envp)
       !options.c1mode &&
       (fullSrcFileName || peekSet(relFilesSet) != NULL))
     {
+      if (options.verbose)
+        printf ("sdcc: Calling linker...\n");
+
       if (port->linker.do_link)
         port->linker.do_link ();
       else