ld65 fix overwrite segments adding wrong padding or causing internal errors

This commit is contained in:
bbbradsmith
2023-02-19 08:14:04 -05:00
parent c097401f8b
commit 2ac055383f

View File

@@ -1945,6 +1945,10 @@ unsigned CfgProcess (void)
/* Remember the start address before handling this segment */ /* Remember the start address before handling this segment */
unsigned long StartAddr = Addr; unsigned long StartAddr = Addr;
/* For computing FillLevel */
unsigned long FillLevel;
unsigned long FillAdded = 0;
/* Take note of "overwrite" segments and make sure there are no /* Take note of "overwrite" segments and make sure there are no
** other segment types following them in current memory region. ** other segment types following them in current memory region.
*/ */
@@ -2081,14 +2085,19 @@ unsigned CfgProcess (void)
/* Increment the fill level of the memory area; and, check for an /* Increment the fill level of the memory area; and, check for an
** overflow. ** overflow.
*/ */
M->FillLevel = Addr + S->Seg->Size - M->Start; FillLevel = Addr + S->Seg->Size - M->Start;
if (M->FillLevel > M->Size && (M->Flags & MF_OVERFLOW) == 0) { if (FillLevel > M->Size && (M->Flags & MF_OVERFLOW) == 0) {
++Overflows; ++Overflows;
M->Flags |= MF_OVERFLOW; M->Flags |= MF_OVERFLOW;
CfgWarning (GetSourcePos (M->LI), CfgWarning (GetSourcePos (M->LI),
"Segment '%s' overflows memory area '%s' by %lu byte%c", "Segment '%s' overflows memory area '%s' by %lu byte%c",
GetString (S->Name), GetString (M->Name), GetString (S->Name), GetString (M->Name),
M->FillLevel - M->Size, (M->FillLevel - M->Size == 1) ? ' ' : 's'); FillLevel - M->Size, (FillLevel - M->Size == 1) ? ' ' : 's');
}
if (FillLevel > M->FillLevel) {
/* Regular segments increase FillLevel. Overwrite segments may increase but not decrease FillLevel. */
FillAdded = FillLevel - M->FillLevel;
M->FillLevel = FillLevel;
} }
/* If requested, define symbols for the start and size of the /* If requested, define symbols for the start and size of the
@@ -2107,13 +2116,14 @@ unsigned CfgProcess (void)
Addr += S->Seg->Size; Addr += S->Seg->Size;
/* If this segment will go out to the file, or its place /* If this segment will go out to the file, or its place
** in the file will be filled, then increase the file size, ** in the file will be filled, then increase the file size.
** unless it's an OVERWRITE segment. ** An OVERWRITE segment will only increase the size if it overlapped some of the fill area.
*/ */
if (S->Load == M && if (S->Load == M &&
((S->Flags & SF_BSS) == 0 || (M->Flags & MF_FILL) != 0) && ((S->Flags & SF_BSS) == 0 || (M->Flags & MF_FILL) != 0)) {
(S->Flags & SF_OVERWRITE) == 0) { M->F->Size += (!(S->Flags & SF_OVERWRITE)) ?
M->F->Size += Addr - StartAddr; (Addr - StartAddr) :
FillAdded;
} }
} }