From: uz Date: Sat, 31 Dec 2011 15:21:33 +0000 (+0000) Subject: Let the linker generate a new symbol __NAME_FILEOFFS__ that contains the X-Git-Tag: V2.13.3~113 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=081308942c2421a8a22fd0fd856e80e066445d77;p=cc65 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 --- diff --git a/doc/ld65.sgml b/doc/ld65.sgml index c077d2ee7..6b6878a48 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -699,18 +699,21 @@ useful for things like a software stack, or an i/o area. } -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: __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_LAST__ This is NOT the same as START+SIZE. - Instead, it it defined as the first - address that is not used by data. If we - don't define any segments for this area, - the value will be the same as START. - + Instead, it it defined as the first + address that is not used by data. If we + don't define any segments for this area, + 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). + A memory section may also have a type. Valid types are diff --git a/src/ld65/bin.c b/src/ld65/bin.c index 402cc0443..17cb8d56f 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -134,11 +134,18 @@ static void PrintNumVal (const char* Name, unsigned long V) static void BinWriteMem (BinDesc* D, MemoryArea* M) /* Write the segments of one memory area to a file */ { + unsigned I; + /* Get the start address of this memory area */ 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 */ - unsigned I; for (I = 0; I < CollCount (&M->SegList); ++I) { int DoWrite; @@ -171,7 +178,7 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) */ Warning ("Segment `%s' is not aligned properly. Resulting " "executable may not be functional.", - GetString (S->Name)); + GetString (S->Name)); } /* If this is the run memory area, we must apply run alignment. If diff --git a/src/ld65/config.c b/src/ld65/config.c index ebafd0bd3..d0ad874ae 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -11,6 +11,10 @@ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ +/* With contributions from: */ +/* */ +/* - "David M. Lloyd" */ +/* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ /* 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->Flags = 0; F->Format = BINFMT_DEFAULT; + F->Size = 0; InitCollection (&F->MemoryAreas); /* Insert the struct into the list */ @@ -1757,6 +1762,9 @@ unsigned CfgProcess (void) /* Get the next memory area */ 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 */ 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) { Export* E; StrBuf Buf = STATIC_STRBUF_INITIALIZER; @@ -1918,10 +1928,26 @@ unsigned CfgProcess (void) SB_Printf (&Buf, "__%s_LAST__", GetString (M->Name)); E = CreateMemoryExport (GetStrBufId (&Buf), M, M->FillLevel); 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); } + /* 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 */ diff --git a/src/ld65/config.h b/src/ld65/config.h index 901796196..6dc4a7b6b 100644 --- a/src/ld65/config.h +++ b/src/ld65/config.h @@ -63,6 +63,7 @@ struct File { unsigned Name; /* Name index of the file */ unsigned Flags; unsigned Format; /* Output format */ + unsigned long Size; /* Size of the generated file */ Collection MemoryAreas; /* List of memory areas in this file */ }; diff --git a/src/ld65/memarea.c b/src/ld65/memarea.c index c95fca61b..3e48ae285 100644 --- a/src/ld65/memarea.c +++ b/src/ld65/memarea.c @@ -58,6 +58,7 @@ MemoryArea* NewMemoryArea (const FilePos* Pos, unsigned Name) M->Name = Name; M->Attr = 0; M->Flags = 0; + M->FileOffs = ~0UL; M->StartExpr = 0; M->Start = 0; M->SizeExpr = 0; diff --git a/src/ld65/memarea.h b/src/ld65/memarea.h index d67b9926b..4d3135fa3 100644 --- a/src/ld65/memarea.h +++ b/src/ld65/memarea.h @@ -63,6 +63,7 @@ struct MemoryArea { unsigned Name; /* Name index of the memory area */ unsigned Attr; /* Which values are valid? */ unsigned Flags; /* Set of bitmapped flags */ + unsigned long FileOffs; /* Offset in output file */ struct ExprNode* StartExpr; /* Expression for start address */ unsigned long Start; /* Start address */ struct ExprNode* SizeExpr; /* Expression for size */