diff --git a/src/ld65/config.c b/src/ld65/config.c index 5317e7015..670f4dedb 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -615,7 +615,7 @@ static void ParseFiles (void) /* Remember we had this section */ SectionsEncountered |= SE_FILES; -} +} @@ -1481,9 +1481,15 @@ static void CreateLoadDefines (SegDesc* S, unsigned long SegAddr) -void CfgAssignSegments (void) -/* Assign segments, define linker symbols where requested */ +unsigned CfgAssignSegments (void) +/* Assign segments, define linker symbols where requested. The function will + * return the number of memory area overflows (so zero means anything went ok). + * In case of overflows, a short mapfile can be generated later, to ease the + * task of rearranging segments for the user. + */ { + unsigned Overflows = 0; + /* Walk through each of the memory sections. Add up the sizes and check * for an overflow of the section. Assign the start addresses of the * segments while doing this. @@ -1563,10 +1569,12 @@ void CfgAssignSegments (void) * overflow. */ M->FillLevel = Addr + S->Seg->Size - M->Start; - if (M->FillLevel > M->Size) { - Error ("Memory area overflow in `%s', segment `%s' (%lu bytes)", - GetString (M->Name), GetString (S->Name), - M->FillLevel - M->Size); + if (M->FillLevel > M->Size && (M->Flags & MF_OVERFLOW) == 0) { + ++Overflows; + M->Flags |= MF_OVERFLOW; + Warning ("Memory area overflow in `%s', segment `%s' (%lu bytes)", + GetString (M->Name), GetString (S->Name), + M->FillLevel - M->Size); } /* If requested, define symbols for the start and size of the @@ -1602,6 +1610,9 @@ void CfgAssignSegments (void) /* Next memory area */ M = M->Next; } + + /* Return the number of memory area overflows */ + return Overflows; } diff --git a/src/ld65/config.h b/src/ld65/config.h index 88d939eea..05e617c5d 100644 --- a/src/ld65/config.h +++ b/src/ld65/config.h @@ -79,7 +79,7 @@ struct Memory { unsigned long Size; /* Length of memory section */ unsigned long FillLevel; /* Actual fill level of segment */ unsigned char FillVal; /* Value used to fill rest of seg */ - unsigned char Relocatable; /* Memory are is relocatable */ + unsigned char Relocatable; /* Memory area is relocatable */ MemListNode* SegList; /* List of segments for this section */ MemListNode* SegLast; /* Last segment in this section */ File* F; /* File that contains the entry */ @@ -108,6 +108,7 @@ extern unsigned SegDescCount; /* Number of entries in list */ #define MF_DEFINE 0x0001 /* Define start and size */ #define MF_FILL 0x0002 /* Fill segment */ #define MF_RO 0x0004 /* Read only memory area */ +#define MF_OVERFLOW 0x0008 /* Memory area overflow */ /* Segment flags */ #define SF_RO 0x0001 /* Read only segment */ @@ -133,8 +134,12 @@ extern unsigned SegDescCount; /* Number of entries in list */ void CfgRead (void); /* Read the configuration */ -void CfgAssignSegments (void); -/* Assign segments, define linker symbols where requested */ +unsigned CfgAssignSegments (void); +/* Assign segments, define linker symbols where requested. The function will + * return the number of memory area overflows (so zero means anything went ok). + * In case of overflows, a short mapfile can be generated later, to ease the + * task of rearranging segments for the user. + */ void CfgWriteTarget (void); /* Write the target file(s) */ diff --git a/src/ld65/main.c b/src/ld65/main.c index a424d37f1..d549b4693 100644 --- a/src/ld65/main.c +++ b/src/ld65/main.c @@ -399,6 +399,7 @@ int main (int argc, char* argv []) }; unsigned I; + unsigned MemoryAreaOverflows; /* Initialize the cmdline module */ InitCmdLine (&argc, &argv, "ld65"); @@ -448,7 +449,7 @@ int main (int argc, char* argv []) case 'v': switch (Arg [2]) { - case 'm': VerboseMap = 1; break; + case 'm': VerboseMap = 1; break; case '\0': ++Verbosity; break; default: UnknownOption (Arg); } @@ -458,7 +459,7 @@ int main (int argc, char* argv []) OptConfig (Arg, GetArg (&I, 2)); break; - case 'L': + case 'L': switch (Arg [2]) { /* ## The first one is obsolete and will go */ case 'n': LabelFileName = GetArg (&I, 3); break; @@ -506,8 +507,11 @@ int main (int argc, char* argv []) /* Create the condes tables if requested */ ConDesCreate (); - /* Assign start addresses for the segments, define linker symbols */ - CfgAssignSegments (); + /* Assign start addresses for the segments, define linker symbols. The + * function will return the number of memory area overflows (zero on + * success). + */ + MemoryAreaOverflows = CfgAssignSegments (); /* Check module assertions */ CheckAssertions (); @@ -515,6 +519,18 @@ int main (int argc, char* argv []) /* Check for import/export mismatches */ CheckExports (); + /* If we had a memory area overflow before, we cannot generate the output + * file. However, we will generate a short map file if requested, since + * this will help the user to rearrange segments and fix the overflow. + */ + if (MemoryAreaOverflows) { + if (MapFileName) { + CreateMapFile (SHORT_MAPFILE); + } + Error ("Cannot generate output due to memory area overflow%s", + (MemoryAreaOverflows > 1)? "s" : ""); + } + /* Create the output file */ CfgWriteTarget (); @@ -523,7 +539,7 @@ int main (int argc, char* argv []) /* If requested, create a map file and a label file for VICE */ if (MapFileName) { - CreateMapFile (); + CreateMapFile (LONG_MAPFILE); } if (LabelFileName) { CreateLabelFile (); diff --git a/src/ld65/mapfile.c b/src/ld65/mapfile.c index 05328d592..33404e293 100644 --- a/src/ld65/mapfile.c +++ b/src/ld65/mapfile.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ +/* (C) 1998-2005 Ullrich von Bassewitz */ /* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -56,8 +56,10 @@ -void CreateMapFile (void) -/* Create a map file */ +void CreateMapFile (int ShortMap) +/* Create a map file. If ShortMap is true, only the segment lists are + * generated, not the import/export lists. + */ { unsigned I; @@ -102,17 +104,21 @@ void CreateMapFile (void) "-------------\n"); PrintSegmentMap (F); - /* Write the exports list */ - fprintf (F, "\n\n" - "Exports list:\n" - "-------------\n"); - PrintExportMap (F); + /* The remainder is not written for short map files */ + if (!ShortMap) { - /* Write the imports list */ - fprintf (F, "\n\n" - "Imports list:\n" - "-------------\n"); - PrintImportMap (F); + /* Write the exports list */ + fprintf (F, "\n\n" + "Exports list:\n" + "-------------\n"); + PrintExportMap (F); + + /* Write the imports list */ + fprintf (F, "\n\n" + "Imports list:\n" + "-------------\n"); + PrintImportMap (F); + } /* Close the file */ if (fclose (F) != 0) { diff --git a/src/ld65/mapfile.h b/src/ld65/mapfile.h index b4cc31f18..f1016aca7 100644 --- a/src/ld65/mapfile.h +++ b/src/ld65/mapfile.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ +/* (C) 1998-2005 Ullrich von Bassewitz */ /* Römerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -39,13 +39,29 @@ /*****************************************************************************/ -/* Code */ +/* Data */ /*****************************************************************************/ -void CreateMapFile (void); -/* Create a map file */ +/* Constants that may be used as arguments for CreateMapFile */ +enum { + LONG_MAPFILE, + SHORT_MAPFILE +}; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void CreateMapFile (int ShortMap); +/* Create a map file. If ShortMap is true, only the segment lists are + * generated, not the import/export lists. + */ void CreateLabelFile (void); /* Create a label file */