1
0
mirror of https://github.com/cc65/cc65.git synced 2024-07-04 13:29:35 +00:00

In case of memory area overflows, generate a short mapfile if one was

requested. This eases the task of rearranging segments when such an
overflow occurs.


git-svn-id: svn://svn.cc65.org/cc65/trunk@3373 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2005-01-23 11:19:26 +00:00
parent 3c20c4c3e1
commit e8abdea87c
5 changed files with 86 additions and 32 deletions

View File

@ -615,7 +615,7 @@ static void ParseFiles (void)
/* Remember we had this section */ /* Remember we had this section */
SectionsEncountered |= SE_FILES; SectionsEncountered |= SE_FILES;
} }
@ -1481,9 +1481,15 @@ static void CreateLoadDefines (SegDesc* S, unsigned long SegAddr)
void CfgAssignSegments (void) unsigned CfgAssignSegments (void)
/* Assign segments, define linker symbols where requested */ /* 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 /* 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 * for an overflow of the section. Assign the start addresses of the
* segments while doing this. * segments while doing this.
@ -1563,10 +1569,12 @@ void CfgAssignSegments (void)
* overflow. * overflow.
*/ */
M->FillLevel = Addr + S->Seg->Size - M->Start; M->FillLevel = Addr + S->Seg->Size - M->Start;
if (M->FillLevel > M->Size) { if (M->FillLevel > M->Size && (M->Flags & MF_OVERFLOW) == 0) {
Error ("Memory area overflow in `%s', segment `%s' (%lu bytes)", ++Overflows;
GetString (M->Name), GetString (S->Name), M->Flags |= MF_OVERFLOW;
M->FillLevel - M->Size); 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 /* If requested, define symbols for the start and size of the
@ -1602,6 +1610,9 @@ void CfgAssignSegments (void)
/* Next memory area */ /* Next memory area */
M = M->Next; M = M->Next;
} }
/* Return the number of memory area overflows */
return Overflows;
} }

View File

@ -79,7 +79,7 @@ struct Memory {
unsigned long Size; /* Length of memory section */ unsigned long Size; /* Length of memory section */
unsigned long FillLevel; /* Actual fill level of segment */ unsigned long FillLevel; /* Actual fill level of segment */
unsigned char FillVal; /* Value used to fill rest of seg */ 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* SegList; /* List of segments for this section */
MemListNode* SegLast; /* Last segment in this section */ MemListNode* SegLast; /* Last segment in this section */
File* F; /* File that contains the entry */ 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_DEFINE 0x0001 /* Define start and size */
#define MF_FILL 0x0002 /* Fill segment */ #define MF_FILL 0x0002 /* Fill segment */
#define MF_RO 0x0004 /* Read only memory area */ #define MF_RO 0x0004 /* Read only memory area */
#define MF_OVERFLOW 0x0008 /* Memory area overflow */
/* Segment flags */ /* Segment flags */
#define SF_RO 0x0001 /* Read only segment */ #define SF_RO 0x0001 /* Read only segment */
@ -133,8 +134,12 @@ extern unsigned SegDescCount; /* Number of entries in list */
void CfgRead (void); void CfgRead (void);
/* Read the configuration */ /* Read the configuration */
void CfgAssignSegments (void); unsigned CfgAssignSegments (void);
/* Assign segments, define linker symbols where requested */ /* 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); void CfgWriteTarget (void);
/* Write the target file(s) */ /* Write the target file(s) */

View File

@ -399,6 +399,7 @@ int main (int argc, char* argv [])
}; };
unsigned I; unsigned I;
unsigned MemoryAreaOverflows;
/* Initialize the cmdline module */ /* Initialize the cmdline module */
InitCmdLine (&argc, &argv, "ld65"); InitCmdLine (&argc, &argv, "ld65");
@ -448,7 +449,7 @@ int main (int argc, char* argv [])
case 'v': case 'v':
switch (Arg [2]) { switch (Arg [2]) {
case 'm': VerboseMap = 1; break; case 'm': VerboseMap = 1; break;
case '\0': ++Verbosity; break; case '\0': ++Verbosity; break;
default: UnknownOption (Arg); default: UnknownOption (Arg);
} }
@ -458,7 +459,7 @@ int main (int argc, char* argv [])
OptConfig (Arg, GetArg (&I, 2)); OptConfig (Arg, GetArg (&I, 2));
break; break;
case 'L': case 'L':
switch (Arg [2]) { switch (Arg [2]) {
/* ## The first one is obsolete and will go */ /* ## The first one is obsolete and will go */
case 'n': LabelFileName = GetArg (&I, 3); break; case 'n': LabelFileName = GetArg (&I, 3); break;
@ -506,8 +507,11 @@ int main (int argc, char* argv [])
/* Create the condes tables if requested */ /* Create the condes tables if requested */
ConDesCreate (); ConDesCreate ();
/* Assign start addresses for the segments, define linker symbols */ /* Assign start addresses for the segments, define linker symbols. The
CfgAssignSegments (); * function will return the number of memory area overflows (zero on
* success).
*/
MemoryAreaOverflows = CfgAssignSegments ();
/* Check module assertions */ /* Check module assertions */
CheckAssertions (); CheckAssertions ();
@ -515,6 +519,18 @@ int main (int argc, char* argv [])
/* Check for import/export mismatches */ /* Check for import/export mismatches */
CheckExports (); 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 */ /* Create the output file */
CfgWriteTarget (); CfgWriteTarget ();
@ -523,7 +539,7 @@ int main (int argc, char* argv [])
/* If requested, create a map file and a label file for VICE */ /* If requested, create a map file and a label file for VICE */
if (MapFileName) { if (MapFileName) {
CreateMapFile (); CreateMapFile (LONG_MAPFILE);
} }
if (LabelFileName) { if (LabelFileName) {
CreateLabelFile (); CreateLabelFile ();

View File

@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2005 Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Römerstraße 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@ -56,8 +56,10 @@
void CreateMapFile (void) void CreateMapFile (int ShortMap)
/* Create a map file */ /* Create a map file. If ShortMap is true, only the segment lists are
* generated, not the import/export lists.
*/
{ {
unsigned I; unsigned I;
@ -102,17 +104,21 @@ void CreateMapFile (void)
"-------------\n"); "-------------\n");
PrintSegmentMap (F); PrintSegmentMap (F);
/* Write the exports list */ /* The remainder is not written for short map files */
fprintf (F, "\n\n" if (!ShortMap) {
"Exports list:\n"
"-------------\n");
PrintExportMap (F);
/* Write the imports list */ /* Write the exports list */
fprintf (F, "\n\n" fprintf (F, "\n\n"
"Imports list:\n" "Exports list:\n"
"-------------\n"); "-------------\n");
PrintImportMap (F); PrintExportMap (F);
/* Write the imports list */
fprintf (F, "\n\n"
"Imports list:\n"
"-------------\n");
PrintImportMap (F);
}
/* Close the file */ /* Close the file */
if (fclose (F) != 0) { if (fclose (F) != 0) {

View File

@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2005 Ullrich von Bassewitz */
/* Römerstrasse 52 */ /* Römerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@ -39,13 +39,29 @@
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Data */
/*****************************************************************************/ /*****************************************************************************/
void CreateMapFile (void); /* Constants that may be used as arguments for CreateMapFile */
/* Create a map file */ 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); void CreateLabelFile (void);
/* Create a label file */ /* Create a label file */