]> git.sur5r.net Git - cc65/blob - src/ld65/main.c
Merge pull request #453 from mrdudz/waitvsync
[cc65] / src / ld65 / main.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                  main.c                                   */
4 /*                                                                           */
5 /*                     Main program for the ld65 linker                      */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998-2013, Ullrich von Bassewitz                                      */
10 /*                Roemerstrasse 52                                           */
11 /*                D-70794 Filderstadt                                        */
12 /* EMail:         uz@cc65.org                                                */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <errno.h>
40
41 /* common */
42 #include "addrsize.h"
43 #include "chartype.h"
44 #include "cmdline.h"
45 #include "filetype.h"
46 #include "libdefs.h"
47 #include "objdefs.h"
48 #include "print.h"
49 #include "target.h"
50 #include "version.h"
51 #include "xmalloc.h"
52
53 /* ld65 */
54 #include "asserts.h"
55 #include "binfmt.h"
56 #include "condes.h"
57 #include "config.h"
58 #include "dbgfile.h"
59 #include "error.h"
60 #include "exports.h"
61 #include "fileio.h"
62 #include "filepath.h"
63 #include "global.h"
64 #include "library.h"
65 #include "mapfile.h"
66 #include "objfile.h"
67 #include "scanner.h"
68 #include "segments.h"
69 #include "spool.h"
70 #include "tpool.h"
71
72
73
74 /*****************************************************************************/
75 /*                                   Data                                    */
76 /*****************************************************************************/
77
78
79
80 static unsigned         ObjFiles   = 0; /* Count of object files linked */
81 static unsigned         LibFiles   = 0; /* Count of library files linked */
82
83 /* struct InputFile.Type definitions */
84 #define INPUT_FILES_FILE       0        /* Entry is a file (unknown type) */
85 #define INPUT_FILES_FILE_OBJ   1        /* Entry is a object file */
86 #define INPUT_FILES_FILE_LIB   2        /* Entry is a library file */
87 #define INPUT_FILES_SGROUP     3        /* Entry is 'StartGroup' */
88 #define INPUT_FILES_EGROUP     4        /* Entry is 'EndGroup' */
89
90 #define MAX_INPUTFILES         256
91
92 /* Array of inputs (libraries and object files) */
93 static struct InputFile {
94     const char *FileName;
95     unsigned Type;
96 }                              *InputFiles;
97 static unsigned                InputFilesCount = 0;
98 static const char              *CmdlineCfgFile = NULL,
99                                *CmdlineTarget = NULL;
100
101
102
103 /*****************************************************************************/
104 /*                                   Code                                    */
105 /*****************************************************************************/
106
107
108
109 static void Usage (void)
110 /* Print usage information and exit */
111 {
112     printf ("Usage: %s [options] module ...\n"
113             "Short options:\n"
114             "  -(\t\t\tStart a library group\n"
115             "  -)\t\t\tEnd a library group\n"
116             "  -C name\t\tUse linker config file\n"
117             "  -D sym=val\t\tDefine a symbol\n"
118             "  -L path\t\tSpecify a library search path\n"
119             "  -Ln name\t\tCreate a VICE label file\n"
120             "  -S addr\t\tSet the default start address\n"
121             "  -V\t\t\tPrint the linker version\n"
122             "  -h\t\t\tHelp (this text)\n"
123             "  -m name\t\tCreate a map file\n"
124             "  -o name\t\tName the default output file\n"
125             "  -t sys\t\tSet the target system\n"
126             "  -u sym\t\tForce an import of symbol `sym'\n"
127             "  -v\t\t\tVerbose mode\n"
128             "  -vm\t\t\tVerbose map file\n"
129             "\n"
130             "Long options:\n"
131             "  --cfg-path path\tSpecify a config file search path\n"
132             "  --config name\t\tUse linker config file\n"
133             "  --dbgfile name\tGenerate debug information\n"
134             "  --define sym=val\tDefine a symbol\n"
135             "  --end-group\t\tEnd a library group\n"
136             "  --force-import sym\tForce an import of symbol `sym'\n"
137             "  --help\t\tHelp (this text)\n"
138             "  --lib file\t\tLink this library\n"
139             "  --lib-path path\tSpecify a library search path\n"
140             "  --mapfile name\tCreate a map file\n"
141             "  --module-id id\tSpecify a module id\n"
142             "  --obj file\t\tLink this object file\n"
143             "  --obj-path path\tSpecify an object file search path\n"
144             "  --start-addr addr\tSet the default start address\n"
145             "  --start-group\t\tStart a library group\n"
146             "  --target sys\t\tSet the target system\n"
147             "  --version\t\tPrint the linker version\n",
148             ProgName);
149 }
150
151
152
153 static unsigned long CvtNumber (const char* Arg, const char* Number)
154 /* Convert a number from a string. Allow '$' and '0x' prefixes for hex
155 ** numbers.
156 */
157 {
158     unsigned long Val;
159     int           Converted;
160
161     /* Convert */
162     if (*Number == '$') {
163         ++Number;
164         Converted = sscanf (Number, "%lx", &Val);
165     } else {
166         Converted = sscanf (Number, "%li", (long*)&Val);
167     }
168
169     /* Check if we do really have a number */
170     if (Converted != 1) {
171         Error ("Invalid number given in argument: %s\n", Arg);
172     }
173
174     /* Return the result */
175     return Val;
176 }
177
178
179
180 static void LinkFile (const char* Name, FILETYPE Type)
181 /* Handle one file */
182 {
183     char*         PathName;
184     FILE*         F;
185     unsigned long Magic;
186
187
188     /* If we don't know the file type, determine it from the extension */
189     if (Type == FILETYPE_UNKNOWN) {
190         Type = GetFileType (Name);
191     }
192
193     /* For known file types, search the file in the directory list */
194     switch (Type) {
195
196         case FILETYPE_LIB:
197             PathName = SearchFile (LibSearchPath, Name);
198             if (PathName == 0) {
199                 PathName = SearchFile (LibDefaultPath, Name);
200             }
201             break;
202
203         case FILETYPE_OBJ:
204             PathName = SearchFile (ObjSearchPath, Name);
205             if (PathName == 0) {
206                 PathName = SearchFile (ObjDefaultPath, Name);
207             }
208             break;
209
210         default:
211             PathName = xstrdup (Name);   /* Use the name as is */
212             break;
213     }
214
215     /* We must have a valid name now */
216     if (PathName == 0) {
217         Error ("Input file `%s' not found", Name);
218     }
219
220     /* Try to open the file */
221     F = fopen (PathName, "rb");
222     if (F == 0) {
223         Error ("Cannot open `%s': %s", PathName, strerror (errno));
224     }
225
226     /* Read the magic word */
227     Magic = Read32 (F);
228
229     /* Check the magic for known file types. The handling is somewhat weird
230     ** since we may have given a file with a ".lib" extension, which was
231     ** searched and found in a directory for library files, but we now find
232     ** out (by looking at the magic) that it's indeed an object file. We just
233     ** ignore the problem and hope no one will notice...
234     */
235     switch (Magic) {
236
237         case OBJ_MAGIC:
238             ObjAdd (F, PathName);
239             ++ObjFiles;
240             break;
241
242         case LIB_MAGIC:
243             LibAdd (F, PathName);
244             ++LibFiles;
245             break;
246
247         default:
248             fclose (F);
249             Error ("File `%s' has unknown type", PathName);
250
251     }
252
253     /* Free allocated memory. */
254     xfree (PathName);
255 }
256
257
258
259 static void DefineSymbol (const char* Def)
260 /* Define a symbol from the command line */
261 {
262     const char* P;
263     long Val;
264     StrBuf SymName = AUTO_STRBUF_INITIALIZER;
265
266
267     /* The symbol must start with a character or underline */
268     if (Def [0] != '_' && !IsAlpha (Def [0])) {
269         InvDef (Def);
270     }
271     P = Def;
272
273     /* Copy the symbol, checking the remainder */
274     while (IsAlNum (*P) || *P == '_') {
275         SB_AppendChar (&SymName, *P++);
276     }
277     SB_Terminate (&SymName);
278
279     /* Do we have a value given? */
280     if (*P != '=') {
281         InvDef (Def);
282     } else {
283         /* We have a value */
284         ++P;
285         if (*P == '$') {
286             ++P;
287             if (sscanf (P, "%lx", &Val) != 1) {
288                 InvDef (Def);
289             }
290         } else {
291             if (sscanf (P, "%li", &Val) != 1) {
292                 InvDef (Def);
293             }
294         }
295     }
296
297     /* Define the new symbol */
298     CreateConstExport (GetStringId (SB_GetConstBuf (&SymName)), Val);
299 }
300
301
302
303 static void OptCfgPath (const char* Opt attribute ((unused)), const char* Arg)
304 /* Specify a config file search path */
305 {
306     AddSearchPath (CfgSearchPath, Arg);
307 }
308
309
310
311 static void OptConfig (const char* Opt attribute ((unused)), const char* Arg)
312 /* Define the config file */
313 {
314     char* PathName;
315
316     if (CfgAvail ()) {
317         Error ("Cannot use -C/-t twice");
318     }
319     /* Search for the file */
320     PathName = SearchFile (CfgSearchPath, Arg);
321     if (PathName == 0) {
322         PathName = SearchFile (CfgDefaultPath, Arg);
323     }
324     if (PathName == 0) {
325         Error ("Cannot find config file `%s'", Arg);
326     }
327
328     /* Read the config */
329     CfgSetName (PathName);
330     CfgRead ();
331 }
332
333
334
335 static void OptDbgFile (const char* Opt attribute ((unused)), const char* Arg)
336 /* Give the name of the debug file */
337 {
338     DbgFileName = Arg;
339 }
340
341
342
343 static void OptDefine (const char* Opt attribute ((unused)), const char* Arg)
344 /* Define a symbol on the command line */
345 {
346     DefineSymbol (Arg);
347 }
348
349
350
351 static void OptEndGroup (const char* Opt attribute ((unused)),
352                          const char* Arg attribute ((unused)))
353 /* End a library group */
354 {
355     LibEndGroup ();
356 }
357
358
359
360 static void OptForceImport (const char* Opt attribute ((unused)), const char* Arg)
361 /* Force an import of a symbol */
362 {
363     /* An optional address size may be specified */
364     const char* ColPos = strchr (Arg, ':');
365     if (ColPos == 0) {
366
367         /* Use default address size (which for now is always absolute
368         ** addressing)
369         */
370         InsertImport (GenImport (GetStringId (Arg), ADDR_SIZE_ABS));
371
372     } else {
373
374         char* A;
375
376         /* Get the address size and check it */
377         unsigned char AddrSize = AddrSizeFromStr (ColPos+1);
378         if (AddrSize == ADDR_SIZE_INVALID) {
379             Error ("Invalid address size `%s'", ColPos+1);
380         }
381
382         /* Create a copy of the argument */
383         A = xstrdup (Arg);
384
385         /* We need just the symbol */
386         A[ColPos - Arg] = '\0';
387
388         /* Generate the import */
389         InsertImport (GenImport (GetStringId (A), AddrSize));
390
391         /* Delete the copy of the argument */
392         xfree (A);
393     }
394 }
395
396
397
398 static void OptHelp (const char* Opt attribute ((unused)),
399                      const char* Arg attribute ((unused)))
400 /* Print usage information and exit */
401 {
402     Usage ();
403     exit (EXIT_SUCCESS);
404 }
405
406
407
408 static void OptLib (const char* Opt attribute ((unused)), const char* Arg)
409 /* Link a library */
410 {
411     InputFiles[InputFilesCount].Type = INPUT_FILES_FILE_LIB;
412     InputFiles[InputFilesCount].FileName = Arg;
413     if (++InputFilesCount >= MAX_INPUTFILES)
414         Error ("Too many input files");
415 }
416
417
418
419 static void OptLibPath (const char* Opt attribute ((unused)), const char* Arg)
420 /* Specify a library file search path */
421 {
422     AddSearchPath (LibSearchPath, Arg);
423 }
424
425
426
427 static void OptMapFile (const char* Opt attribute ((unused)), const char* Arg)
428 /* Give the name of the map file */
429 {
430     if (MapFileName) {
431         Error ("Cannot use -m twice");
432     }
433     MapFileName = Arg;
434 }
435
436
437
438 static void OptModuleId (const char* Opt, const char* Arg)
439 /* Specify a module id */
440 {
441     unsigned long Id = CvtNumber (Opt, Arg);
442     if (Id > 0xFFFFUL) {
443         Error ("Range error in module id");
444     }
445     ModuleId = (unsigned) Id;
446 }
447
448
449
450 static void OptObj (const char* Opt attribute ((unused)), const char* Arg)
451 /* Link an object file */
452 {
453     InputFiles[InputFilesCount].Type = INPUT_FILES_FILE_OBJ;
454     InputFiles[InputFilesCount].FileName = Arg;
455     if (++InputFilesCount >= MAX_INPUTFILES)
456         Error ("Too many input files");
457 }
458
459
460
461 static void OptObjPath (const char* Opt attribute ((unused)), const char* Arg)
462 /* Specify an object file search path */
463 {
464     AddSearchPath (ObjSearchPath, Arg);
465 }
466
467
468
469 static void OptOutputName (const char* Opt attribute ((unused)), const char* Arg)
470 /* Give the name of the output file */
471 {
472     static int OutputNameSeen = 0;
473     if (OutputNameSeen) {
474         Error ("Cannot use -o twice");
475     }
476     OutputNameSeen = 1;
477     OutputName = Arg;
478 }
479
480
481
482 static void OptStartAddr (const char* Opt, const char* Arg)
483 /* Set the default start address */
484 {
485     if (HaveStartAddr) {
486         Error ("Cannot use -S twice");
487     }
488     StartAddr = CvtNumber (Opt, Arg);
489     HaveStartAddr = 1;
490 }
491
492
493
494 static void OptStartGroup (const char* Opt attribute ((unused)),
495                            const char* Arg attribute ((unused)))
496 /* Start a library group */
497 {
498     LibStartGroup ();
499 }
500
501
502
503 static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
504 /* Set the target system */
505 {
506     StrBuf FileName = STATIC_STRBUF_INITIALIZER;
507     char*  PathName;
508
509     /* Map the target name to a target id */
510     Target = FindTarget (Arg);
511     if (Target == TGT_UNKNOWN) {
512         Error ("Invalid target name: `%s'", Arg);
513     }
514
515     /* Set the target binary format */
516     DefaultBinFmt = GetTargetProperties (Target)->BinFmt;
517
518     /* Build config file name from target name */
519     SB_CopyStr (&FileName, GetTargetName (Target));
520     SB_AppendStr (&FileName, ".cfg");
521     SB_Terminate (&FileName);
522
523     /* Search for the file */
524     PathName = SearchFile (CfgSearchPath, SB_GetBuf (&FileName));
525     if (PathName == 0) {
526         PathName = SearchFile (CfgDefaultPath, SB_GetBuf (&FileName));
527     }
528     if (PathName == 0) {
529         Error ("Cannot find config file `%s'", SB_GetBuf (&FileName));
530     }
531
532     /* Free file name memory */
533     SB_Done (&FileName);
534
535     /* Read the file */
536     CfgSetName (PathName);
537     CfgRead ();
538 }
539
540
541
542 static void OptVersion (const char* Opt attribute ((unused)),
543                         const char* Arg attribute ((unused)))
544 /* Print the assembler version */
545 {
546     fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ());
547     exit(EXIT_SUCCESS);
548 }
549
550
551
552 static void CmdlOptStartGroup (const char* Opt attribute ((unused)),
553                                const char* Arg attribute ((unused)))
554 /* Remember 'start group' occurrence in input files array */
555 {
556     InputFiles[InputFilesCount].Type = INPUT_FILES_SGROUP;
557     InputFiles[InputFilesCount].FileName = Arg;  /* Unused */
558     if (++InputFilesCount >= MAX_INPUTFILES)
559         Error ("Too many input files");
560 }
561
562
563
564 static void CmdlOptEndGroup (const char* Opt attribute ((unused)),
565                              const char* Arg attribute ((unused)))
566 /* Remember 'end group' occurrence in input files array */
567 {
568     InputFiles[InputFilesCount].Type = INPUT_FILES_EGROUP;
569     InputFiles[InputFilesCount].FileName = Arg;  /* Unused */
570     if (++InputFilesCount >= MAX_INPUTFILES)
571         Error ("Too many input files");
572 }
573
574
575
576 static void CmdlOptConfig (const char* Opt attribute ((unused)), const char* Arg)
577 /* Set 'config file' command line parameter */
578 {
579     if (CmdlineCfgFile || CmdlineTarget) {
580         Error ("Cannot use -C/-t twice");
581     }
582     CmdlineCfgFile = Arg;
583 }
584
585
586
587 static void CmdlOptTarget (const char* Opt attribute ((unused)), const char* Arg)
588 /* Set 'target' command line parameter */
589 {
590     if (CmdlineCfgFile || CmdlineTarget) {
591         Error ("Cannot use -C/-t twice");
592     }
593     CmdlineTarget = Arg;
594 }
595
596
597
598 static void ParseCommandLine(void)
599 {
600     /* Program long options */
601     static const LongOpt OptTab[] = {
602         { "--cfg-path",         1,      OptCfgPath              },
603         { "--config",           1,      CmdlOptConfig           },
604         { "--dbgfile",          1,      OptDbgFile              },
605         { "--define",           1,      OptDefine               },
606         { "--end-group",        0,      CmdlOptEndGroup         },
607         { "--force-import",     1,      OptForceImport          },
608         { "--help",             0,      OptHelp                 },
609         { "--lib",              1,      OptLib                  },
610         { "--lib-path",         1,      OptLibPath              },
611         { "--mapfile",          1,      OptMapFile              },
612         { "--module-id",        1,      OptModuleId             },
613         { "--obj",              1,      OptObj                  },
614         { "--obj-path",         1,      OptObjPath              },
615         { "--start-addr",       1,      OptStartAddr            },
616         { "--start-group",      0,      CmdlOptStartGroup       },
617         { "--target",           1,      CmdlOptTarget           },
618         { "--version",          0,      OptVersion              },
619     };
620
621     unsigned I;
622     unsigned LabelFileGiven = 0;
623
624     /* Allocate memory for input file array */
625     InputFiles = xmalloc (MAX_INPUTFILES * sizeof (struct InputFile));
626
627     /* Defer setting of config/target and input files until all options are parsed */
628     I = 1;
629     while (I < ArgCount) {
630
631         /* Get the argument */
632         const char* Arg = ArgVec[I];
633
634         /* Check for an option */
635         if (Arg [0] == '-') {
636
637             /* An option */
638             switch (Arg [1]) {
639
640                 case '-':
641                     LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
642                     break;
643
644                 case '(':
645                     CmdlOptStartGroup (Arg, 0);
646                     break;
647
648                 case ')':
649                     CmdlOptEndGroup (Arg, 0);
650                     break;
651
652                 case 'h':
653                 case '?':
654                     OptHelp (Arg, 0);
655                     break;
656
657                 case 'm':
658                     OptMapFile (Arg, GetArg (&I, 2));
659                     break;
660
661                 case 'o':
662                     OptOutputName (NULL, GetArg (&I, 2));
663                     break;
664
665                 case 't':
666                     CmdlOptTarget (Arg, GetArg (&I, 2));
667                     break;
668
669                 case 'u':
670                     OptForceImport (Arg, GetArg (&I, 2));
671                     break;
672
673                 case 'v':
674                     switch (Arg [2]) {
675                         case 'm':   VerboseMap = 1;     break;
676                         case '\0':  ++Verbosity;        break;
677                         default:    UnknownOption (Arg);
678                     }
679                     break;
680
681                 case 'C':
682                     CmdlOptConfig (Arg, GetArg (&I, 2));
683                     break;
684
685                 case 'D':
686                     OptDefine (Arg, GetArg (&I, 2));
687                     break;
688
689                 case 'L':
690                     switch (Arg [2]) {
691                         case 'n':
692                             /* ## This one is obsolete and will go */
693                             if (LabelFileGiven) {
694                                 Error ("Cannot use -Ln twice");
695                             }
696                             LabelFileGiven = 1;
697                             LabelFileName = GetArg (&I, 3);
698                             break;
699                         default:
700                             OptLibPath (Arg, GetArg (&I, 2));
701                             break;
702                     }
703                     break;
704
705                 case 'S':
706                     OptStartAddr (Arg, GetArg (&I, 2));
707                     break;
708
709                 case 'V':
710                     OptVersion (Arg, 0);
711                     break;
712
713                 default:
714                     UnknownOption (Arg);
715                     break;
716             }
717
718         } else {
719
720             /* A filename */
721             InputFiles[InputFilesCount].Type = INPUT_FILES_FILE;
722             InputFiles[InputFilesCount].FileName = Arg;
723             if (++InputFilesCount >= MAX_INPUTFILES)
724                 Error ("Too many input files");
725
726         }
727
728         /* Next argument */
729         ++I;
730     }
731
732     if (CmdlineTarget) {
733         OptTarget (NULL, CmdlineTarget);
734     } else if (CmdlineCfgFile) {
735         OptConfig (NULL, CmdlineCfgFile);
736     }
737
738     /* Process input files */
739     for (I = 0; I < InputFilesCount; ++I) {
740         switch (InputFiles[I].Type) {
741             case INPUT_FILES_FILE:
742                 LinkFile (InputFiles[I].FileName, FILETYPE_UNKNOWN);
743                 break;
744             case INPUT_FILES_FILE_LIB:
745                 LinkFile (InputFiles[I].FileName, FILETYPE_LIB);
746                 break;
747             case INPUT_FILES_FILE_OBJ:
748                 LinkFile (InputFiles[I].FileName, FILETYPE_OBJ);
749                 break;
750             case INPUT_FILES_SGROUP:
751                 OptStartGroup (NULL, 0);
752                 break;
753             case INPUT_FILES_EGROUP:
754                 OptEndGroup (NULL, 0);
755                 break;
756             default:
757                 abort ();
758         }
759     }
760
761     /* Free memory used for input file array */
762     xfree (InputFiles);
763 }
764
765
766
767 int main (int argc, char* argv [])
768 /* Linker main program */
769 {
770     unsigned MemoryAreaOverflows;
771
772     /* Initialize the cmdline module */
773     InitCmdLine (&argc, &argv, "ld65");
774
775     /* Initialize the input file search paths */
776     InitSearchPaths ();
777
778     /* Initialize the string pool */
779     InitStrPool ();
780
781     /* Initialize the type pool */
782     InitTypePool ();
783
784     /* Parse the command line */
785     ParseCommandLine ();
786
787     /* Check if we had any object files */
788     if (ObjFiles == 0) {
789         Error ("No object files to link");
790     }
791
792     /* Check if we have a valid configuration */
793     if (!CfgAvail ()) {
794         Error ("Memory configuration missing");
795     }
796
797     /* Check if we have open library groups */
798     LibCheckGroup ();
799
800     /* Create the condes tables if requested */
801     ConDesCreate ();
802
803     /* Process data from the config file. Assign start addresses for the
804     ** segments, define linker symbols. The function will return the number
805     ** of memory area overflows (zero on success).
806     */
807     MemoryAreaOverflows = CfgProcess ();
808
809     /* Check module assertions */
810     CheckAssertions ();
811
812     /* Check for import/export mismatches */
813     CheckExports ();
814
815     /* If we had a memory area overflow before, we cannot generate the output
816     ** file. However, we will generate a short map file if requested, since
817     ** this will help the user to rearrange segments and fix the overflow.
818     */
819     if (MemoryAreaOverflows) {
820         if (MapFileName) {
821             CreateMapFile (SHORT_MAPFILE);
822         }
823         Error ("Cannot generate most of the files due to memory area overflow%c",
824                (MemoryAreaOverflows > 1) ? 's' : ' ');
825     }
826
827     /* Create the output file */
828     CfgWriteTarget ();
829
830     /* Check for segments not written to the output file */
831     CheckSegments ();
832
833     /* If requested, create a map file and a label file for VICE */
834     if (MapFileName) {
835         CreateMapFile (LONG_MAPFILE);
836     }
837     if (LabelFileName) {
838         CreateLabelFile ();
839     }
840     if (DbgFileName) {
841         CreateDbgFile ();
842     }
843
844     /* Dump the data for debugging */
845     if (Verbosity > 1) {
846         SegDump ();
847         ConDesDump ();
848     }
849
850     /* Return an apropriate exit code */
851     return EXIT_SUCCESS;
852 }