]> git.sur5r.net Git - cc65/commitdiff
Let the linker generate a new symbol __NAME_FILEOFFS__ that contains the
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 31 Dec 2011 15:21:33 +0000 (15:21 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 31 Dec 2011 15:21:33 +0000 (15:21 +0000)
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

doc/ld65.sgml
src/ld65/bin.c
src/ld65/config.c
src/ld65/config.h
src/ld65/memarea.c
src/ld65/memarea.h

index c077d2ee7f2f08efc057d0da635eec1049bc5384..6b6878a48211e70280a34ca5be7f116ff883fa01 100644 (file)
@@ -699,18 +699,21 @@ useful for things like a software stack, or an i/o area.
        }
 </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>
                __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.
-</verb></tscreen>
+                               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).
+</verb></tscreen>                             
 
 A memory section may also have a type. Valid types are
 
index 402cc04438d94f51933e1919fcddf8510f873156..17cb8d56f72313654feef76fbe95fc1b34f4ca5b 100644 (file)
@@ -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
index ebafd0bd3b0996fb227881bf76798f3b43df1d03..d0ad874aeca6d14bf298b65026d19d7ed621bba9 100644 (file)
 /*                D-70794 Filderstadt                                        */
 /* 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       */
 /* 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 */
index 901796196968c46c82b77724aee8ed155de70bea..6dc4a7b6b9f1d2533f3221a9c8373063adda4283 100644 (file)
@@ -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 */
 };
 
index c95fca61b36491bd1ffe5ab1687cf99bce6fb016..3e48ae285ba9ca09d430240431a691383f504e5f 100644 (file)
@@ -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;
index d67b9926b27889aab0eb6946391668afa19fdb7c..4d3135fa36f8d8fd977d9ac2425ab5e7dd3fb31e 100644 (file)
@@ -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 */