/* Remember we had this section */
SectionsEncountered |= SE_FILES;
-}
+}
-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.
* 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
/* Next memory area */
M = M->Next;
}
+
+ /* Return the number of memory area overflows */
+ return Overflows;
}
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 */
#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 */
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) */
};
unsigned I;
+ unsigned MemoryAreaOverflows;
/* Initialize the cmdline module */
InitCmdLine (&argc, &argv, "ld65");
case 'v':
switch (Arg [2]) {
- case 'm': VerboseMap = 1; break;
+ case 'm': VerboseMap = 1; break;
case '\0': ++Verbosity; break;
default: UnknownOption (Arg);
}
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;
/* 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 ();
/* 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 ();
/* If requested, create a map file and a label file for VICE */
if (MapFileName) {
- CreateMapFile ();
+ CreateMapFile (LONG_MAPFILE);
}
if (LabelFileName) {
CreateLabelFile ();
/* */
/* */
/* */
-/* (C) 1998-2003 Ullrich von Bassewitz */
+/* (C) 1998-2005 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
-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;
"-------------\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) {
/* */
/* */
/* */
-/* (C) 1998-2003 Ullrich von Bassewitz */
+/* (C) 1998-2005 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/*****************************************************************************/
-/* 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 */