1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-26 05:29:30 +00:00

Added a "fillval" attribute to the segment definition. When given, it

overrides the value from the memory area for all space that lies within the
segment itself.


git-svn-id: svn://svn.cc65.org/cc65/trunk@5823 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2012-09-09 19:00:43 +00:00
parent 1c77d3a6f0
commit 574c8fa273
5 changed files with 55 additions and 19 deletions

View File

@ -728,8 +728,11 @@ into a memory area that is marked as readonly.
Unused memory in a memory area may be filled. Use the "<tt/fill = yes/"
attribute to request this. The default value to fill unused space is zero. If
you don't like this, you may specify a byte value that is used to fill these
areas with the "<tt/fillval/" attribute. This value is also used to fill unfilled
areas generated by the assemblers <tt/.ALIGN/ and <tt/.RES/ directives.
areas with the "<tt/fillval/" attribute. If there is no "<tt/fillval/"
attribute for the segment, the "<tt/fillval/" attribute of the memory area (or
its default) is used instead. This means that the value may also be used to
fill unfilled areas generated by the assemblers <tt/.ALIGN/ and <tt/.RES/
directives.
The symbol <tt/%S/ may be used to access the default start address (that is,
the one defined in the <ref id="FEATURES" name="FEATURES"> section, or the
@ -804,6 +807,13 @@ segment in the load memory area, in case different load and run areas have
been specified. There are no special attributes to set start or offset for
just the load memory area.
A "<tt/fillval/" attribute may not only be specified for a memory area, but
also for a segment. The value must be an integer between 0 and 255. It is used
as fill value for space reserved by the assemblers <tt/.ALIGN/ and <tt/.RES/
commands. It is also used as fill value for space between sections (part of a
segment that comes from one object file) caused by alignment, but not for
space that preceeds the first section.
To suppress the warning, the linker issues if it encounters a segment that is
not found in any of the input files, use "<tt/optional=yes/" as additional
segment attribute. Be careful when using this attribute, because a missing

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1999-2011, Ullrich von Bassewitz */
/* (C) 1999-2012, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -142,7 +142,7 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M)
/* Debugging: Check that the file offset is correct */
if (ftell (D->F) != (long)M->FileOffs) {
Internal ("Invalid file offset for memory area %s: %ld/%lu",
GetString (M->Name), ftell (D->F), M->FileOffs);
GetString (M->Name), ftell (D->F), M->FileOffs);
}
/* Walk over all segments in this memory area */
@ -231,11 +231,10 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M)
*/
if (DoWrite) {
unsigned long P = ftell (D->F);
S->Seg->FillVal = M->FillVal;
SegWrite (D->Filename, D->F, S->Seg, BinWriteExpr, D);
PrintNumVal ("Wrote", (unsigned long) (ftell (D->F) - P));
} else if (M->Flags & MF_FILL) {
WriteMult (D->F, M->FillVal, S->Seg->Size);
} else if (M->Flags & MF_FILL) {
WriteMult (D->F, S->Seg->FillVal, S->Seg->Size);
PrintNumVal ("Filled", (unsigned long) S->Seg->Size);
}

View File

@ -118,6 +118,7 @@ static Collection SegDescList = STATIC_COLLECTION_INITIALIZER;
#define SA_OFFSET 0x0040
#define SA_START 0x0080
#define SA_OPTIONAL 0x0100
#define SA_FILLVAL 0x0200
/* Symbol types used in the CfgSymbol structure */
typedef enum {
@ -353,6 +354,7 @@ static SegDesc* NewSegDesc (unsigned Name)
S->Seg = 0;
S->Attr = 0;
S->Flags = 0;
S->FillVal = 0;
S->RunAlignment = 1;
S->LoadAlignment = 1;
@ -637,6 +639,7 @@ static void ParseSegments (void)
{ "ALIGN", CFGTOK_ALIGN },
{ "ALIGN_LOAD", CFGTOK_ALIGN_LOAD },
{ "DEFINE", CFGTOK_DEFINE },
{ "FILLVAL", CFGTOK_FILLVAL },
{ "LOAD", CFGTOK_LOAD },
{ "OFFSET", CFGTOK_OFFSET },
{ "OPTIONAL", CFGTOK_OPTIONAL },
@ -706,6 +709,12 @@ static void ParseSegments (void)
CfgNextTok ();
break;
case CFGTOK_FILLVAL:
FlagAttr (&S->Attr, SA_FILLVAL, "FILLVAL");
S->FillVal = (unsigned char) CfgCheckedConstExpr (0, 0xFF);
S->Flags |= SF_FILLVAL;
break;
case CFGTOK_LOAD:
FlagAttr (&S->Attr, SA_LOAD, "LOAD");
S->Load = CfgGetMemory (GetStrBufId (&CfgSVal));
@ -1561,22 +1570,22 @@ static void ProcessSegments (void)
while (I < CollCount (&SegDescList)) {
/* Get the next segment descriptor */
SegDesc* S = CollAtUnchecked (&SegDescList, I);
SegDesc* S = CollAtUnchecked (&SegDescList, I);
/* Search for the actual segment in the input files. The function may
* return NULL (no such segment), this is checked later.
*/
S->Seg = SegFind (S->Name);
/* If the segment is marked as BSS style, and if the segment exists
/* If the segment is marked as BSS style, and if the segment exists
* in any of the object file, check that there's no initialized data
* in the segment.
*/
if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) {
*/
if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) {
CfgWarning (GetSourcePos (S->LI),
"Segment `%s' with type `bss' contains initialized data",
GetString (S->Name));
}
GetString (S->Name));
}
/* If this segment does exist in any of the object files, insert the
* segment into the load/run memory areas. Otherwise print a warning
@ -1592,6 +1601,9 @@ static void ProcessSegments (void)
MemoryInsert (S->Load, S);
}
/* Use the fill value from the config */
S->Seg->FillVal = S->FillVal;
/* Process the next segment descriptor in the next run */
++I;
@ -1894,6 +1906,13 @@ unsigned CfgProcess (void)
}
/* If this is the load memory area and the segment doesn't have a
* fill value defined, use the one from the memory area.
*/
if (S->Load == M && (S->Flags & SF_FILLVAL) == 0) {
S->Seg->FillVal = M->FillVal;
}
/* Increment the fill level of the memory area and check for an
* overflow.
*/

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1998-2011, Ullrich von Bassewitz */
/* (C) 1998-2012, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -75,6 +75,7 @@ struct SegDesc {
Segment* Seg; /* Pointer to segment structure */
unsigned Attr; /* Attributes for segment */
unsigned Flags; /* Set of bitmapped flags */
unsigned char FillVal; /* Fill value for this segment */
struct MemoryArea* Load; /* Load memory section */
struct MemoryArea* Run; /* Run memory section */
unsigned long Addr; /* Start address or offset into segment */
@ -94,6 +95,7 @@ struct SegDesc {
#define SF_OPTIONAL 0x0100 /* Segment is optional (must not exist) */
#define SF_RUN_DEF 0x0200 /* RUN symbols already defined */
#define SF_LOAD_DEF 0x0400 /* LOAD symbols already defined */
#define SF_FILLVAL 0x0800 /* Segment has separate fill value */

View File

@ -464,16 +464,22 @@ void SegWrite (const char* TgtName, FILE* Tgt, Segment* S, SegWriteFunc F, void*
/* Loop over all sections in this segment */
for (I = 0; I < CollCount (&S->Sections); ++I) {
Section* Sec = CollAtUnchecked (&S->Sections, I);
Fragment* Frag;
Section* Sec = CollAtUnchecked (&S->Sections, I);
Fragment* Frag;
unsigned char FillVal;
/* Output were this section is from */
Print (stdout, 2, " Section from \"%s\"\n", GetObjFileName (Sec->Obj));
/* If we have fill bytes, write them now */
/* If we have fill bytes, write them now. Beware: If this is the
* first section, the fill value is not considered part of the segment
* and therefore taken from the memory area.
*/
FillVal = (I == 0)? S->MemArea->FillVal : S->FillVal;
Print (stdout, 2, " Filling 0x%lx bytes with 0x%02x\n",
Sec->Fill, S->FillVal);
WriteMult (Tgt, S->FillVal, Sec->Fill);
Sec->Fill, FillVal);
WriteMult (Tgt, FillVal, Sec->Fill);
Offs += Sec->Fill;
/* Loop over all fragments in this section */