1
0
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:
uz 2011-12-31 15:21:33 +00:00
parent 45f7cc1403
commit 081308942c
6 changed files with 49 additions and 10 deletions

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */
}; };

View 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;

View File

@ -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 */