mirror of
https://github.com/cc65/cc65.git
synced 2024-09-28 10:55:43 +00:00
Let the linker generate a new symbol __NAME_FILEOFFS__ that contains the
offset of a memory area in the output file. Partially based on a contribution by David M. Lloyd, david.lloyd@redhat.com. git-svn-id: svn://svn.cc65.org/cc65/trunk@5351 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
45f7cc1403
commit
081308942c
@ -699,18 +699,21 @@ useful for things like a software stack, or an i/o area.
|
|||||||
}
|
}
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
This will define three external symbols that may be used in your code:
|
This will define some external symbols that may be used in your code:
|
||||||
|
|
||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
__STACK_START__ This is set to the start of the memory
|
__STACK_START__ This is set to the start of the memory
|
||||||
area, $C000 in this example.
|
area, $C000 in this example.
|
||||||
__STACK_SIZE__ The size of the area, here $1000.
|
__STACK_SIZE__ The size of the area, here $1000.
|
||||||
__STACK_LAST__ This is NOT the same as START+SIZE.
|
__STACK_LAST__ This is NOT the same as START+SIZE.
|
||||||
Instead, it it defined as the first
|
Instead, it it defined as the first
|
||||||
address that is not used by data. If we
|
address that is not used by data. If we
|
||||||
don't define any segments for this area,
|
don't define any segments for this area,
|
||||||
the value will be the same as START.
|
the value will be the same as START.
|
||||||
</verb></tscreen>
|
__STACK_FILEOFFS__ The binary offset in the output file. This
|
||||||
|
is not defined for relocatable output file
|
||||||
|
formats (o65).
|
||||||
|
</verb></tscreen>
|
||||||
|
|
||||||
A memory section may also have a type. Valid types are
|
A memory section may also have a type. Valid types are
|
||||||
|
|
||||||
|
@ -134,11 +134,18 @@ static void PrintNumVal (const char* Name, unsigned long V)
|
|||||||
static void BinWriteMem (BinDesc* D, MemoryArea* M)
|
static void BinWriteMem (BinDesc* D, MemoryArea* M)
|
||||||
/* Write the segments of one memory area to a file */
|
/* Write the segments of one memory area to a file */
|
||||||
{
|
{
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
/* Get the start address of this memory area */
|
/* Get the start address of this memory area */
|
||||||
unsigned long Addr = M->Start;
|
unsigned long Addr = M->Start;
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
/* Walk over all segments in this memory area */
|
/* Walk over all segments in this memory area */
|
||||||
unsigned I;
|
|
||||||
for (I = 0; I < CollCount (&M->SegList); ++I) {
|
for (I = 0; I < CollCount (&M->SegList); ++I) {
|
||||||
|
|
||||||
int DoWrite;
|
int DoWrite;
|
||||||
@ -171,7 +178,7 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M)
|
|||||||
*/
|
*/
|
||||||
Warning ("Segment `%s' is not aligned properly. Resulting "
|
Warning ("Segment `%s' is not aligned properly. Resulting "
|
||||||
"executable may not be functional.",
|
"executable may not be functional.",
|
||||||
GetString (S->Name));
|
GetString (S->Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is the run memory area, we must apply run alignment. If
|
/* If this is the run memory area, we must apply run alignment. If
|
||||||
|
@ -11,6 +11,10 @@
|
|||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
|
/* With contributions from: */
|
||||||
|
/* */
|
||||||
|
/* - "David M. Lloyd" <david.lloyd@redhat.com> */
|
||||||
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
/* warranty. In no event will the authors be held liable for any damages */
|
/* warranty. In no event will the authors be held liable for any damages */
|
||||||
@ -293,6 +297,7 @@ static File* NewFile (unsigned Name)
|
|||||||
F->Name = Name;
|
F->Name = Name;
|
||||||
F->Flags = 0;
|
F->Flags = 0;
|
||||||
F->Format = BINFMT_DEFAULT;
|
F->Format = BINFMT_DEFAULT;
|
||||||
|
F->Size = 0;
|
||||||
InitCollection (&F->MemoryAreas);
|
InitCollection (&F->MemoryAreas);
|
||||||
|
|
||||||
/* Insert the struct into the list */
|
/* Insert the struct into the list */
|
||||||
@ -1757,6 +1762,9 @@ unsigned CfgProcess (void)
|
|||||||
/* Get the next memory area */
|
/* Get the next memory area */
|
||||||
MemoryArea* M = CollAtUnchecked (&MemoryAreas, I);
|
MemoryArea* M = CollAtUnchecked (&MemoryAreas, I);
|
||||||
|
|
||||||
|
/* Remember the offset in the output file */
|
||||||
|
M->FileOffs = M->F->Size;
|
||||||
|
|
||||||
/* Remember if this is a relocatable memory area */
|
/* Remember if this is a relocatable memory area */
|
||||||
M->Relocatable = RelocatableBinFmt (M->F->Format);
|
M->Relocatable = RelocatableBinFmt (M->F->Format);
|
||||||
|
|
||||||
@ -1904,7 +1912,9 @@ unsigned CfgProcess (void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If requested, define symbols for start and size of the memory area */
|
/* If requested, define symbols for start, size and offset of the
|
||||||
|
* memory area
|
||||||
|
*/
|
||||||
if (M->Flags & MF_DEFINE) {
|
if (M->Flags & MF_DEFINE) {
|
||||||
Export* E;
|
Export* E;
|
||||||
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||||
@ -1918,10 +1928,26 @@ unsigned CfgProcess (void)
|
|||||||
SB_Printf (&Buf, "__%s_LAST__", GetString (M->Name));
|
SB_Printf (&Buf, "__%s_LAST__", GetString (M->Name));
|
||||||
E = CreateMemoryExport (GetStrBufId (&Buf), M, M->FillLevel);
|
E = CreateMemoryExport (GetStrBufId (&Buf), M, M->FillLevel);
|
||||||
CollAppend (&E->DefLines, M->LI);
|
CollAppend (&E->DefLines, M->LI);
|
||||||
|
|
||||||
|
/* Define the file offset of the memory area. This isn't of much
|
||||||
|
* use for relocatable output files.
|
||||||
|
*/
|
||||||
|
if (!M->Relocatable) {
|
||||||
|
SB_Printf (&Buf, "__%s_FILEOFFS__", GetString (M->Name));
|
||||||
|
E = CreateConstExport (GetStrBufId (&Buf), M->FileOffs);
|
||||||
|
CollAppend (&E->DefLines, M->LI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Throw away the string buffer */
|
||||||
SB_Done (&Buf);
|
SB_Done (&Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Grow the file by the size of the memory area */
|
||||||
|
if (M->Flags & MF_FILL) {
|
||||||
|
M->F->Size += M->Size;
|
||||||
|
} else {
|
||||||
|
M->F->Size += M->FillLevel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the number of memory area overflows */
|
/* Return the number of memory area overflows */
|
||||||
|
@ -63,6 +63,7 @@ struct File {
|
|||||||
unsigned Name; /* Name index of the file */
|
unsigned Name; /* Name index of the file */
|
||||||
unsigned Flags;
|
unsigned Flags;
|
||||||
unsigned Format; /* Output format */
|
unsigned Format; /* Output format */
|
||||||
|
unsigned long Size; /* Size of the generated file */
|
||||||
Collection MemoryAreas; /* List of memory areas in this file */
|
Collection MemoryAreas; /* List of memory areas in this file */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ MemoryArea* NewMemoryArea (const FilePos* Pos, unsigned Name)
|
|||||||
M->Name = Name;
|
M->Name = Name;
|
||||||
M->Attr = 0;
|
M->Attr = 0;
|
||||||
M->Flags = 0;
|
M->Flags = 0;
|
||||||
|
M->FileOffs = ~0UL;
|
||||||
M->StartExpr = 0;
|
M->StartExpr = 0;
|
||||||
M->Start = 0;
|
M->Start = 0;
|
||||||
M->SizeExpr = 0;
|
M->SizeExpr = 0;
|
||||||
|
@ -63,6 +63,7 @@ struct MemoryArea {
|
|||||||
unsigned Name; /* Name index of the memory area */
|
unsigned Name; /* Name index of the memory area */
|
||||||
unsigned Attr; /* Which values are valid? */
|
unsigned Attr; /* Which values are valid? */
|
||||||
unsigned Flags; /* Set of bitmapped flags */
|
unsigned Flags; /* Set of bitmapped flags */
|
||||||
|
unsigned long FileOffs; /* Offset in output file */
|
||||||
struct ExprNode* StartExpr; /* Expression for start address */
|
struct ExprNode* StartExpr; /* Expression for start address */
|
||||||
unsigned long Start; /* Start address */
|
unsigned long Start; /* Start address */
|
||||||
struct ExprNode* SizeExpr; /* Expression for size */
|
struct ExprNode* SizeExpr; /* Expression for size */
|
||||||
|
Loading…
Reference in New Issue
Block a user