mirror of
https://github.com/cc65/cc65.git
synced 2025-01-14 00:32:08 +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:
parent
3c20c4c3e1
commit
e8abdea87c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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) */
|
||||||
|
@ -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 ();
|
||||||
|
@ -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) {
|
||||||
|
@ -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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user