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:
@@ -699,7 +699,7 @@ 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
|
||||||
@@ -710,6 +710,9 @@ This will define three external symbols that may be used in your code:
|
|||||||
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.
|
||||||
|
__STACK_FILEOFFS__ The binary offset in the output file. This
|
||||||
|
is not defined for relocatable output file
|
||||||
|
formats (o65).
|
||||||
</verb></tscreen>
|
</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;
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -1919,9 +1929,25 @@ unsigned CfgProcess (void)
|
|||||||
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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user