]> git.sur5r.net Git - cc65/commitdiff
Reworked and improved the SYMBOLS section. The old syntax (using symbol =
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 12 Nov 2010 14:17:35 +0000 (14:17 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 12 Nov 2010 14:17:35 +0000 (14:17 +0000)
value) is now gone, attributes are used instead. The SYMBOLS section does now
support imports, so the linker config can be used to force symbols (and
therefore module) imports. Evaluation of start address and size for memory
areas has been delayed even further, so it is now possible to use the values
from one memory area in the definition of the next one.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4851 b7a2c559-68d2-44c3-8de9-860c34a00d81

38 files changed:
doc/ld65.sgml
src/ld65/cfg/apple2-dos33.cfg
src/ld65/cfg/apple2-loader.cfg
src/ld65/cfg/apple2-reboot.cfg
src/ld65/cfg/apple2-system.cfg
src/ld65/cfg/apple2.cfg
src/ld65/cfg/apple2enh-dos33.cfg
src/ld65/cfg/apple2enh-loader.cfg
src/ld65/cfg/apple2enh-reboot.cfg
src/ld65/cfg/apple2enh-system.cfg
src/ld65/cfg/apple2enh.cfg
src/ld65/cfg/atari.cfg
src/ld65/cfg/atmos.cfg
src/ld65/cfg/bbc.cfg
src/ld65/cfg/c128.cfg
src/ld65/cfg/c16.cfg
src/ld65/cfg/c64.cfg
src/ld65/cfg/cbm510.cfg
src/ld65/cfg/cbm610.cfg
src/ld65/cfg/geos.cfg
src/ld65/cfg/lunix.cfg
src/ld65/cfg/lynx.cfg
src/ld65/cfg/nes.cfg
src/ld65/cfg/none.cfg
src/ld65/cfg/pet.cfg
src/ld65/cfg/plus4.cfg
src/ld65/cfg/supervision-128k.cfg
src/ld65/cfg/supervision-16k.cfg
src/ld65/cfg/supervision-64k.cfg
src/ld65/cfg/vic20-32k.cfg
src/ld65/cfg/vic20.cfg
src/ld65/cfgexpr.c
src/ld65/config.c
src/ld65/config.h
src/ld65/exports.c
src/ld65/exports.h
src/ld65/objdata.c
src/ld65/scanner.h

index d37beced749309c3cc5a50e03fe4cea46e77651d..2c2b2d599cad90237f0d654530dfa5806b734eae 100644 (file)
@@ -832,8 +832,8 @@ The necessary o65 attributes are defined in a special section labeled
 
 The <tt/FORMAT/ section is used to describe file formats. The default (binary)
 format has currently no attributes, so, while it may be listed in this
-section, the attribute list is empty. The second supported format, 
-<htmlurl url="http://www.6502.org/users/andre/o65/fileformat.html" name="o65">, 
+section, the attribute list is empty. The second supported format,
+<htmlurl url="http://www.6502.org/users/andre/o65/fileformat.html" name="o65">,
 has several attributes that may be defined here.
 
 <tscreen><verb>
@@ -942,12 +942,41 @@ mean, that the <tt/FEATURES/ section has to go to the top of the config file.
 <sect1>The SYMBOLS section<label id="SYMBOLS"><p>
 
 The configuration file may also be used to define symbols used in the link
-stage. The mandatory attribute for a symbol is its value. A second, boolean
-attribute named <tt/weak/ is available. If a symbol is marked as weak, it may
-be overridden by defining a symbol of the same name from the command line. The
-default for symbols is that they're strong, which means that an attempt to
-define a symbol with the same name from the command line will lead to an
-error.
+stage or to force symbols imports. This is done in the SYMBOLS section. The
+symbol name is followed by a colon and symbol attributes.
+
+The following symbol attributes are supported:
+
+<descrip>
+
+  <tag><tt>addrsize</tt></tag>
+
+  The <tt/addrsize/ attribute specifies the address size of the symbol and
+  may be one of
+<itemize>
+    <item><tt/zp/, <tt/zeropage/ or <tt/direct/
+    <item><tt/abs/, <tt/absolute/ or <tt/near/
+    <item><tt/far/
+    <item><tt/long/ or <tt/dword/.
+</itemize>
+
+Without this attribute, the default address size is <tt/abs/.
+
+  <tag><tt>type</tt></tag>
+
+  This attribute is mandatory. Its value is one of <tt/export/, <tt/import/ or
+  <tt/weak/. <tt/export/ means that the symbol is defined and exported from
+  the linker config. <tt/import/ means that an import is generated for this
+  symbol, eventually forcing a module that exports this symbol to be included
+  in the output. <tt/weak/ is similar as <tt/export/. However, the symbol is
+  only defined if it is not defined elsewhere.
+
+  <tag><tt>value</tt></tag>
+
+  This must only be given for symbols of type <tt/export/ or <tt/weak/. It
+  defines the value of the symbol and may be an expression.
+
+</descrip>
 
 The following example defines the stack size for an application, but allows
 the programmer to override the value by specifying <tt/--define
@@ -956,7 +985,7 @@ __STACKSIZE__=xxx/ on the command line.
 <tscreen><verb>
                SYMBOLS {
             # Define the stack size for the application
-                   __STACKSIZE__:      value = $800, weak = yes;
+                   __STACKSIZE__:  type = weak, value = $800;
                }
 </verb></tscreen>
 
index 8e532b2b75f549d42a49be9bd0aa91f0560b587a..3e9234afc63629860bfce47750c07179fba31ee9 100644 (file)
@@ -1,10 +1,10 @@
 # Configuration optimized for DOS 3.3 by allowing for 12KB of HIGHCODE
+
 FEATURES {
     STARTADDRESS: default = $0803;
 }
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0080, size = $001A;
index 51db3f7ad5b53070ca7d34841bb5b521e50532a9..3dd3ecbbab180596c0d7068e88039cf1c73557cc 100644 (file)
@@ -4,7 +4,7 @@ FEATURES {
     STARTADDRESS: default = $0800;
 }
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0080, size = $001A;
index 824ef264b08b406f041dc0c61b166ae9f0805be8..9e1e835cf04582ec6c44c4750a9ec59c64efb5d6 100644 (file)
@@ -5,7 +5,7 @@ FEATURES {
     STARTADDRESS: default = $0800;
 }
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0080, size = $001A;
index 7bf2f39b6ab7c9e41430f6318043bd18fb981101..0a4bcf70563873779583cb93270651d78095aad1 100644 (file)
@@ -1,7 +1,7 @@
 # Configuration for ProDOS 8 system programs (without the header)
 
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0080, size = $001A;
index 68c76502e80f9356cdd2c64c437e238c857ab574..fc96da9af7007469a6572f4213a6c8c60e1d00aa 100644 (file)
@@ -1,10 +1,10 @@
 # Default configuration built into ld65 (allowing for 3KB of HIGHCODE)
+
 FEATURES {
     STARTADDRESS: default = $0803;
 }
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0080, size = $001A;
index 8e532b2b75f549d42a49be9bd0aa91f0560b587a..3e9234afc63629860bfce47750c07179fba31ee9 100644 (file)
@@ -1,10 +1,10 @@
 # Configuration optimized for DOS 3.3 by allowing for 12KB of HIGHCODE
+
 FEATURES {
     STARTADDRESS: default = $0803;
 }
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0080, size = $001A;
index 51db3f7ad5b53070ca7d34841bb5b521e50532a9..3dd3ecbbab180596c0d7068e88039cf1c73557cc 100644 (file)
@@ -4,7 +4,7 @@ FEATURES {
     STARTADDRESS: default = $0800;
 }
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0080, size = $001A;
index 824ef264b08b406f041dc0c61b166ae9f0805be8..9e1e835cf04582ec6c44c4750a9ec59c64efb5d6 100644 (file)
@@ -5,7 +5,7 @@ FEATURES {
     STARTADDRESS: default = $0800;
 }
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0080, size = $001A;
index 7bf2f39b6ab7c9e41430f6318043bd18fb981101..0a4bcf70563873779583cb93270651d78095aad1 100644 (file)
@@ -1,7 +1,7 @@
 # Configuration for ProDOS 8 system programs (without the header)
 
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0080, size = $001A;
index 68c76502e80f9356cdd2c64c437e238c857ab574..fc96da9af7007469a6572f4213a6c8c60e1d00aa 100644 (file)
@@ -1,10 +1,10 @@
 # Default configuration built into ld65 (allowing for 3KB of HIGHCODE)
+
 FEATURES {
     STARTADDRESS: default = $0803;
 }
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0080, size = $001A;
index 88757512c16db3555a35f9b3f3653cd23313bd8a..437ce16819b49ec50fdbd5116dd7c55940044a62 100644 (file)
@@ -2,8 +2,8 @@ FEATURES {
     STARTADDRESS: default = $2E00;
 }
 SYMBOLS {
-    __STACKSIZE__:       value = $0800, weak = yes; # 2k stack
-    __RESERVED_MEMORY__: value = $0000, weak = yes;
+    __STACKSIZE__:       type = weak, value = $0800; # 2k stack
+    __RESERVED_MEMORY__: type = weak, value = $0000;
 }
 MEMORY {
     ZP:      define = yes, start = $0082, size = $007E;
index a71fca5a2294248f0768ccd459049e3f28a857e0..1ea3b76ffc158afd830bbe013e92bcde88b403e6 100644 (file)
@@ -1,5 +1,5 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                 define = yes, start = $00E2, size = $001A;
index f0d608f24a8da08fd13300d3f81012b113095429..d614bc46b0524a2ee3fce46d5d5a0ceaf0572f8b 100644 (file)
@@ -1,5 +1,5 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:  define = yes, start = $0070, size = $0020;
index 9b0e7c7541d26b6052cb1d70b059248e04e87f17..e5e14fc94e63d7bc45b6a848a7fdebb8c8591b27 100644 (file)
@@ -1,6 +1,6 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
-}
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
+}                                            
 MEMORY {
     ZP:                define = yes, start = $0002, size = $001A;
     HEADER: file = %O,               start = $1BFF, size = $000E;
index 7386b34cc4d57ef0eb801e6c696523339df79e82..112ccdd9c8c7239a136f6e14631bb7f21bcb74d8 100644 (file)
@@ -1,5 +1,5 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:     define = yes, start = $0002, size = $001A;
index f7a126e08bdcddc900300cc0ed27728eda6f4094..a232d479c76025ec06955449aac123933a97decb 100644 (file)
@@ -1,5 +1,5 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0002, size = $001A;
index 3a0dbe1eddcc362e0bf7f27db06b233ee989c0b2..9bac135bf40e9244bcb80e316a89fcf0b0072492 100644 (file)
@@ -1,6 +1,6 @@
 SYMBOLS {
     # The stack starts from $FEC3 and grows towards the video ram
-    __STACKSIZE__: value = $06C3, weak = yes; # ~1.5k stack
+    __STACKSIZE__: type = weak, value = $06C3; # ~1.5k stack
 }
 MEMORY {
     HEADER:   file = %O,               start = $0001, size = $0050, fill = yes;
index 177e7ccbed1de6e5a17628b986e357905a6a9271..f9d02ba643502e31c34b32d40da4d6691d9fbfed 100644 (file)
@@ -1,5 +1,5 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     HEADER:   file = %O,               start = $0001, size = $0050, fill = yes;
index d38153b8fb221c98d0a4764d40ff0c16bf7e3dd1..b6e94e144a90ea5ee4c500ff2cf810ecdfd512bf 100644 (file)
@@ -1,5 +1,5 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0400, weak = yes; # 1k stack
+    __STACKSIZE__: type = weak, value = $0400; # 1k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0058, size = $0028;
index 8e29d634d01320ff093e4a34b6aea0bd3ba53a0f..37b485e362dfd20a086042b3e3445b6750dec9f8 100644 (file)
@@ -1,8 +1,8 @@
 # ld65 Linker-configuration for LUnix, Next Generation.
 
 SYMBOLS {
-    __HEAPSIZE__:  value = $2000, weak = yes; # 8k heap [temporary, until LUnix malloc() exists]
-    __STACKSIZE__: value = $0400, weak = yes; # 1k stack (do typical LUnix apps. need 2k?)
+    __HEAPSIZE__:  type = weak, value = $2000; # 8k heap [temporary, until LUnix malloc() exists]
+    __STACKSIZE__: type = weak, value = $0400; # 1k stack (do typical LUnix apps. need 2k?)
 }
 MEMORY {
     ZP:         start = $0080, size = $0040;
@@ -28,7 +28,7 @@ FEATURES {
            label   = __DESTRUCTOR_TABLE__,
            count   = __DESTRUCTOR_COUNT__;
     CONDES: segment = RODATA,
-            type    = interruptor,         
+            type    = interruptor,
            label   = __INTERRUPTOR_TABLE__,
            count   = __INTERRUPTOR_COUNT__;
 }
index c6048247292818a50680c0b0ab38807910025341..819487a515d07304c54b93a61732a83988e1a647 100644 (file)
@@ -1,5 +1,5 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0000, size = $0100;
index be9ee94b52b97e1776bb0fc51975329447f49cdd..42d703e75fbb476669dec49abf4e62b9e1ab3448 100644 (file)
@@ -1,5 +1,5 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0300, weak = yes; # 3 pages stack
+    __STACKSIZE__: type = weak, value = $0300; # 3 pages stack
 }
 MEMORY {
     ZP:     start = $0002, size = $001A, type = rw, define = yes;
index 3cbc2d700e96c20c61b6fdbbf980c3501bf74b7f..54997d823f83119d8e1dfb2681c0c71684cebc61 100644 (file)
@@ -1,5 +1,5 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:  define = yes, start = $0000, size = $0001F;
index 6d224604e754ee8048c5d0be0cb3acfa9ef34497..2cbd7e66dc307b369e914713175793017d4db9a8 100644 (file)
@@ -1,5 +1,5 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:     define = yes, start = $0055, size = $001A;
index 903a9debbd149188aee762995bb1eac0e08a5bed..f9f8b22e1f69cb0ba683665cfd42213ea2989f2d 100644 (file)
@@ -1,5 +1,5 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
+    __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
     ZP:     define = yes, start = $0002, size = $001A;
index 0c2d1b36bd7638a05a5c7498cfd4230948818c26..0d241f450a0d0c3b96ff04581c2327c461995718 100644 (file)
@@ -5,7 +5,7 @@
 # ld65 --config supervision.cfg -o <prog>.bin <prog>.o
 
 SYMBOLS {
-    __STACKSIZE__: value = $0100, weak = yes; # 1 page stack
+    __STACKSIZE__: type = weak, value = $0100; # 1 page stack
 }
 MEMORY {
     RAM:      start = $0000, size = $2000 - __STACKSIZE__;
index 791133e7b2cff287d7f6a2b19e4d951ccc420d8e..3a2a487baf1af7b9d06772d19e3b63f824fccdf5 100644 (file)
@@ -4,7 +4,7 @@
 # ld65 --config supervision16.cfg -o <prog>.bin <prog>.o
 
 SYMBOLS {
-    __STACKSIZE__: value = $0100, weak = yes; # 1 page stack
+    __STACKSIZE__: type = weak, value = $0100; # 1 page stack
 }
 MEMORY {
     ZP:       start = $0000, size = $0100;
index 6ae5872966f3b2e32a3e405be3e2243313b85a86..400c9c3859c7e83e45659380f47f2615a475a2ac 100644 (file)
@@ -5,7 +5,7 @@
 # ld65 --config supervision.cfg -o <prog>.bin <prog>.o
 
 SYMBOLS {
-    __STACKSIZE__: value = $0100, weak = yes; # 1 page stack
+    __STACKSIZE__: type = weak, value = $0100; # 1 page stack
 }
 MEMORY {
     RAM:      start = $0000, size = $2000 - __STACKSIZE__;
index 1aeffcc88ef1137d3a99d381e1b9f6fbb100fd91..c84c03bfd69d7d88435ea4d375f3dd42f6ce4cca 100644 (file)
@@ -2,7 +2,7 @@
 # Contributed by Stefan Haubenthal
 
 SYMBOLS {
-    __STACKSIZE__: value = $0400, weak = yes; # 1k stack
+    __STACKSIZE__: type = weak, value = $0400; # 1k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0002, size = $001A;
index e4afc6fab6a09cd7fea8075e929d4174b5afec89..1d104443da7cdb0be2c2ed091b83acea2d25e56a 100644 (file)
@@ -1,5 +1,5 @@
 SYMBOLS {
-    __STACKSIZE__: value = $0400, weak = yes; # 1k stack
+    __STACKSIZE__: type = weak, value = $0400; # 1k stack
 }
 MEMORY {
     ZP:                define = yes, start = $0002, size = $001A;
index add151b73860bbd38db872adf8ddbf8dd37fbbdd..668d0443b727bbc371a5e916dbac4383ce49e5a2 100644 (file)
@@ -74,6 +74,7 @@ static ExprNode* Factor (void)
             } else {
                 N = NewExprNode (0, EXPR_SYMBOL);
                 N->V.Imp = InsertImport (GenImport (Name, ADDR_SIZE_ABS));
+                N->V.Imp->Pos = CfgErrorPos;
             }
 
             /* Skip the symbol name */
index 1ae73abcfce1c250a4b41d61cbcf5fbe7d12c51d..623264358f09abc2a092b4655aa45b5d0cc4fa32 100644 (file)
@@ -39,6 +39,7 @@
 #include <errno.h>
 
 /* common */
+#include "addrsize.h"
 #include "bitops.h"
 #include "check.h"
 #include "print.h"
@@ -111,28 +112,30 @@ static Collection       SegDescList = STATIC_COLLECTION_INITIALIZER;
 #define SA_START       0x0080
 #define SA_OPTIONAL     0x0100
 
+/* Symbol types used in the CfgSymbol structure */
+typedef enum {
+    CfgSymExport,               /* Not really used in struct CfgSymbol */
+    CfgSymImport,               /* Dito */
+    CfgSymWeak,                 /* Like export but weak */
+    CfgSymO65Export,            /* An o65 export */
+    CfgSymO65Import,            /* An o65 import */
+} CfgSymType;
+
 /* Symbol structure. It is used for o65 imports and exports, but also for
  * symbols from the SYMBOLS sections (symbols defined in the config file or
  * forced imports).
  */
-typedef struct Symbol Symbol;
-struct Symbol {
+typedef struct CfgSymbol CfgSymbol;
+struct CfgSymbol {
+    CfgSymType  Type;           /* Type of symbol */
     FilePos     Pos;            /* Config file position */
     unsigned    Name;           /* Symbol name */
-    unsigned    Flags;          /* Symbol flags */
-    long        Val;            /* Symbol value if any */
+    ExprNode*   Value;          /* Symbol value if any */
+    unsigned    AddrSize;       /* Address size of symbol */
 };
 
 /* Collections with symbols */
-static Collection       O65Imports = STATIC_COLLECTION_INITIALIZER;
-static Collection       O65Exports = STATIC_COLLECTION_INITIALIZER;
-static Collection       Symbols    = STATIC_COLLECTION_INITIALIZER;
-
-/* Symbol flags */
-#define SYM_NONE        0x00    /* No special meaning */
-#define SYM_DEF         0x01    /* Symbol defined in the config file */
-#define SYM_WEAK        0x02    /* Defined symbol is weak */
-#define SYM_IMPORT      0x04    /* A forced import */
+static Collection       CfgSymbols = STATIC_COLLECTION_INITIALIZER;
 
 /* Descriptor holding information about the binary formats */
 static BinDesc*        BinFmtDesc      = 0;
@@ -254,19 +257,24 @@ static void MemoryInsert (MemoryArea* M, SegDesc* S)
 
 
 
-static Symbol* NewSymbol (unsigned Name, unsigned Flags, long Val)
-/* Create a new Symbol structure with the given name name and flags. The
- * current config file position is recorded in the returned struct.
+static CfgSymbol* NewCfgSymbol (CfgSymType Type, unsigned Name)
+/* Create a new CfgSymbol structure with the given type and name. The
+ * current config file position is recorded in the returned struct. The
+ * created struct is inserted into the CfgSymbols collection and returned.
  */
 {
     /* Allocate memory */
-    Symbol* Sym = xmalloc (sizeof (Symbol));
+    CfgSymbol* Sym = xmalloc (sizeof (CfgSymbol));
 
     /* Initialize the fields */
-    Sym->Pos    = CfgErrorPos;
-    Sym->Name   = Name;
-    Sym->Flags  = Flags;
-    Sym->Val    = Val;
+    Sym->Type     = Type;
+    Sym->Pos      = CfgErrorPos;
+    Sym->Name     = Name;
+    Sym->Value    = 0;
+    Sym->AddrSize = ADDR_SIZE_INVALID;
+
+    /* Insert the symbol into the collection */
+    CollAppend (&CfgSymbols, Sym);
 
     /* Return the initialized struct */
     return Sym;
@@ -274,17 +282,6 @@ static Symbol* NewSymbol (unsigned Name, unsigned Flags, long Val)
 
 
 
-static Symbol* NewO65Symbol (void)
-/* Create a new Symbol structure with the name in the current CfgSVal variable
- * ready for use as an o65 symbol. The current config file position is recorded
- * in the returned struct.
- */
-{
-    return NewSymbol (GetStrBufId (&CfgSVal), SYM_NONE, 0);
-}
-
-
-
 static File* NewFile (unsigned Name)
 /* Create a new file descriptor and insert it into the list */
 {
@@ -344,6 +341,7 @@ static SegDesc* NewSegDesc (unsigned Name)
 
     /* Initialize the fields */
     S->Name    = Name;
+    S->Pos     = CfgErrorPos;
     S->Seg     = 0;
     S->Attr    = 0;
     S->Flags   = 0;
@@ -872,7 +870,7 @@ static void ParseO65 (void)
                /* We expect an identifier */
                CfgAssureIdent ();
                 /* Remember it as an export for later */
-                CollAppend (&O65Exports, NewO65Symbol ());
+                NewCfgSymbol (CfgSymO65Export, GetStrBufId (&CfgSVal));
                 /* Eat the identifier token */
                 CfgNextTok ();
                break;
@@ -883,7 +881,7 @@ static void ParseO65 (void)
                /* We expect an identifier */
                CfgAssureIdent ();
                 /* Remember it as an import for later */
-                CollAppend (&O65Imports, NewO65Symbol ());
+                NewCfgSymbol (CfgSymO65Import, GetStrBufId (&CfgSVal));
                 /* Eat the identifier token */
                 CfgNextTok ();
                break;
@@ -1291,107 +1289,159 @@ static void ParseSymbols (void)
 /* Parse a symbols section */
 {
     static const IdentTok Attributes[] = {
+        {   "ADDRSIZE", CFGTOK_ADDRSIZE },
+        {   "TYPE",     CFGTOK_TYPE     },
                {   "VALUE",    CFGTOK_VALUE    },
-        {   "WEAK",     CFGTOK_WEAK     },
+    };
+
+    static const IdentTok AddrSizes [] = {
+               {   "ABS",      CFGTOK_ABS      },
+               {   "ABSOLUTE", CFGTOK_ABS      },
+               {   "DIRECT",   CFGTOK_ZP       },
+               {   "DWORD",    CFGTOK_LONG     },
+               {   "FAR",      CFGTOK_FAR      },
+               {   "LONG",     CFGTOK_LONG     },
+               {   "NEAR",     CFGTOK_ABS      },
+               {   "ZEROPAGE", CFGTOK_ZP       },
+               {   "ZP",       CFGTOK_ZP       },
+    };
+
+    static const IdentTok Types [] = {
+               {   "EXPORT",   CFGTOK_EXPORT   },
+               {   "IMPORT",   CFGTOK_IMPORT   },
+               {   "WEAK",     CFGTOK_WEAK     },
     };
 
     while (CfgTok == CFGTOK_IDENT) {
 
-       long Val = 0L;
-        unsigned Flags = SYM_NONE;
+        /* Bitmask to remember the attributes we got already */
+        enum {
+            atNone             = 0x0000,
+            atAddrSize  = 0x0001,
+            atType      = 0x0002,
+            atValue     = 0x0004,
+        };
+        unsigned AttrFlags = atNone;
+
+               ExprNode* Value = 0;
+        CfgSymType Type = CfgSymExport;
+        unsigned char AddrSize = ADDR_SIZE_ABS;
+        Import* Imp;
+        Export* Exp;
+        CfgSymbol* Sym;
 
        /* Remember the name */
        unsigned Name = GetStrBufId (&CfgSVal);
        CfgNextTok ();
 
-        /* Support both, old and new syntax here. New syntax is a colon
-         * followed by an attribute list, old syntax is an optional equal
-         * sign plus a value.
-         */
-        if (CfgTok != CFGTOK_COLON) {
+        /* New syntax - skip the colon */
+        CfgNextTok ();
 
-            /* Old syntax */
+        /* Parse the attributes */
+        while (1) {
 
-            /* Allow an optional assignment */
-            CfgOptionalAssign ();
+            /* Map the identifier to a token */
+            cfgtok_t AttrTok;
+            CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
+            AttrTok = CfgTok;
 
-            /* Make sure the next token is an integer expression, read and
-             * skip it.
-             */
-            Val = CfgConstExpr ();
+            /* Skip the attribute name */
+            CfgNextTok ();
 
-            /* This is a defined symbol */
-            Flags = SYM_DEF;
+            /* An optional assignment follows */
+            CfgOptionalAssign ();
 
-        } else {
+            /* Check which attribute was given */
+            switch (AttrTok) {
 
-            /* Bitmask to remember the attributes we got already */
-            enum {
-                atNone         = 0x0000,
-                atValue         = 0x0001,
-                atWeak          = 0x0002
-            };
-            unsigned AttrFlags = atNone;
+               case CFGTOK_ADDRSIZE:
+                    /* Don't allow this twice */
+                    FlagAttr (&AttrFlags, atAddrSize, "ADDRSIZE");
+                    /* Map the type to a token */
+                   CfgSpecialToken (AddrSizes, ENTRY_COUNT (AddrSizes), "AddrSize");
+                    switch (CfgTok) {
+                        case CFGTOK_ABS:    AddrSize = ADDR_SIZE_ABS;   break;
+                        case CFGTOK_FAR:    AddrSize = ADDR_SIZE_FAR;   break;
+                        case CFGTOK_LONG:   AddrSize = ADDR_SIZE_LONG;  break;
+                        case CFGTOK_ZP:     AddrSize = ADDR_SIZE_ZP;    break;
+                               default:
+                            Internal ("Unexpected token: %d", CfgTok);
+                    }
+                    CfgNextTok ();
+                   break;
 
+               case CFGTOK_TYPE:
+                    /* Don't allow this twice */
+                    FlagAttr (&AttrFlags, atType, "TYPE");
+                    /* Map the type to a token */
+                   CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
+                    switch (CfgTok) {
+                        case CFGTOK_EXPORT:     Type = CfgSymExport;    break;
+                        case CFGTOK_IMPORT:     Type = CfgSymImport;    break;
+                        case CFGTOK_WEAK:       Type = CfgSymWeak;      break;
+                               default:
+                            Internal ("Unexpected token: %d", CfgTok);
+                    }
+                    CfgNextTok ();
+                   break;
 
-            /* New syntax - skip the colon */
-            CfgNextTok ();
+                case CFGTOK_VALUE:
+                    /* Don't allow this twice */
+                    FlagAttr (&AttrFlags, atValue, "VALUE");
+                    /* Value is an expression */
+                    Value = CfgExpr ();
+                    break;
 
-            /* Parse the attributes */
-            while (1) {
+                default:
+                    FAIL ("Unexpected attribute token");
 
-                /* Map the identifier to a token */
-                cfgtok_t AttrTok;
-                CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
-                AttrTok = CfgTok;
+            }
 
-                /* Skip the attribute name */
+            /* Semicolon ends the decl, otherwise accept an optional comma */
+            if (CfgTok == CFGTOK_SEMI) {
+                break;
+            } else if (CfgTok == CFGTOK_COMMA) {
                 CfgNextTok ();
+            }
+        }
 
-                /* An optional assignment follows */
-                CfgOptionalAssign ();
-
-                /* Check which attribute was given */
-                switch (AttrTok) {
-
-                    case CFGTOK_VALUE:
-                        /* Don't allow this twice */
-                        FlagAttr (&AttrFlags, atValue, "VALUE");
-                        /* We expect a numeric expression */
-                        Val = CfgConstExpr ();
-                        /* Symbol is defined */
-                        Flags |= SYM_DEF;
-                        break;
-
-                    case CFGTOK_WEAK:
-                        /* Don't allow this twice */
-                        FlagAttr (&AttrFlags, atWeak, "WEAK");
-                        CfgBoolToken ();
-                        if (CfgTok == CFGTOK_TRUE) {
-                            Flags |= SYM_WEAK;
-                        }
-                        CfgNextTok ();
-                        break;
+        /* We must have a type */
+        AttrCheck (AttrFlags, atType, "TYPE");
 
-                    default:
-                        FAIL ("Unexpected attribute token");
+        /* Further actions depend on the type */
+        switch (Type) {
 
-                }
+            case CfgSymExport:
+                /* We must have a value */
+                AttrCheck (AttrFlags, atType, "TYPE");
+                /* Create the export */
+                Exp = CreateExprExport (Name, Value, AddrSize);
+                Exp->Pos = CfgErrorPos;
+                break;
 
-                /* Semicolon ends the decl, otherwise accept an optional comma */
-                if (CfgTok == CFGTOK_SEMI) {
-                    break;
-                } else if (CfgTok == CFGTOK_COMMA) {
-                    CfgNextTok ();
+            case CfgSymImport:
+                /* An import must not have a value */
+                if (AttrFlags & atValue) {
+                    CfgError (&CfgErrorPos, "Imports must not have a value");
                 }
-            }
+                /* Generate the import */
+                Imp = InsertImport (GenImport (Name, AddrSize));
+                /* Remember the file position */
+                Imp->Pos = CfgErrorPos;
+                break;
 
-            /* Check if we have all mandatory attributes */
-            AttrCheck (AttrFlags, atValue, "VALUE");
-        }
+            case CfgSymWeak:
+                /* We must have a value */
+                AttrCheck (AttrFlags, atType, "TYPE");
+                /* Remember the symbol for later */
+                Sym = NewCfgSymbol (CfgSymWeak, Name);
+                Sym->Value = Value;
+                Sym->AddrSize = AddrSize;
+                break;
 
-        /* Remember the symbol for later */
-        CollAppend (&Symbols, NewSymbol (Name, Flags, Val));
+            default:
+                Internal ("Unexpected symbol type %d", Type);
+        }
 
        /* Skip the semicolon */
        CfgConsumeSemi ();
@@ -1493,41 +1543,6 @@ void CfgRead (void)
 
 
 
-static void ProcessMemory (void)
-/* Process the MEMORY section */
-{
-    /* Walk over the list with the memory areas */
-    unsigned I;
-    for (I = 0; I < CollCount (&MemoryAreas); ++I) {
-
-        /* Get the next memory area */
-        MemoryArea* M = CollAtUnchecked (&MemoryAreas, I);
-
-        /* Remember if this is a relocatable memory area */
-        M->Relocatable = RelocatableBinFmt (M->F->Format);
-
-        /* Resolve the expressions */
-        if (!IsConstExpr (M->StartExpr)) {
-            CfgError (&M->Pos,
-                      "Start address of memory area `%s' is not constant",
-                      GetString (M->Name));
-        }
-        M->Start = GetExprVal (M->StartExpr);
-
-        if (!IsConstExpr (M->SizeExpr)) {
-            CfgError (&M->Pos,
-                      "Size of memory area `%s' is not constant",
-                      GetString (M->Name));
-        }
-        M->Size = GetExprVal (M->SizeExpr);
-
-        /* Mark the memory area as placed */
-        M->Flags |= MF_PLACED;
-    }
-}
-
-
-
 static void ProcessSegments (void)
 /* Process the SEGMENTS section */
 {
@@ -1589,77 +1604,6 @@ static void ProcessSegments (void)
 
 
 
-static void ProcessO65 (void)
-/* Process the o65 format section */
-{
-    unsigned I;
-
-    /* Walk over the imports, check and add them to the o65 data */
-    for (I = 0; I < CollCount (&O65Imports); ++I) {
-
-        /* Get the import */
-        Symbol* Sym = CollAtUnchecked (&O65Imports, I);
-
-        /* Check if we have this symbol defined already. The entry
-         * routine will check this also, but we get a more verbose
-         * error message when checking it here.
-         */
-        if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
-            CfgError (&Sym->Pos,
-                      "Duplicate imported o65 symbol: `%s'",
-                      GetString (Sym->Name));
-        }
-
-        /* Insert the symbol into the table */
-        O65SetImport (O65FmtDesc, Sym->Name);
-    }
-
-    /* Walk over the exports, check and add them to the o65 data */
-    for (I = 0; I < CollCount (&O65Exports); ++I) {
-
-        /* Get the export */
-        Symbol* Sym = CollAtUnchecked (&O65Exports, I);
-
-        /* Check if the export symbol is also defined as an import. */
-        if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
-            CfgError (&Sym->Pos,
-                      "Exported o65 symbol `%s' cannot also be an o65 import",
-                      GetString (Sym->Name));
-        }
-
-        /* Check if we have this symbol defined already. The entry
-         * routine will check this also, but we get a more verbose
-         * error message when checking it here.
-         */
-        if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
-            CfgError (&Sym->Pos,
-                      "Duplicate exported o65 symbol: `%s'",
-                      GetString (Sym->Name));
-        }
-
-        /* Insert the symbol into the table */
-        O65SetExport (O65FmtDesc, Sym->Name);
-    }
-}
-
-
-
-static void ProcessBin (void)
-/* Process the bin format section */
-{
-}
-
-
-
-static void ProcessFormats (void)
-/* Process the target format section */
-{
-    ProcessO65 ();
-    ProcessBin ();
-}
-
-
-
 static void ProcessSymbols (void)
 /* Process the SYMBOLS section */
 {
@@ -1667,33 +1611,81 @@ static void ProcessSymbols (void)
 
     /* Walk over all symbols */
     unsigned I;
-    for (I = 0; I < CollCount (&Symbols); ++I) {
+    for (I = 0; I < CollCount (&CfgSymbols); ++I) {
 
         /* Get the next symbol */
-        Symbol* Sym = CollAtUnchecked (&Symbols, I);
-
-        /* Do we define this symbol? */
-        if ((Sym->Flags & SYM_DEF) != 0) {
-            /* Check if the symbol is already defined somewhere else */
-            if ((E = FindExport (Sym->Name)) != 0 && !IsUnresolvedExport (E)) {
-                /* If the symbol is not marked as weak, this is an error.
-                 * Otherwise ignore the symbol from the config.
+        CfgSymbol* Sym = CollAtUnchecked (&CfgSymbols, I);
+
+        /* Check what it is. */
+        switch (Sym->Type) {
+
+            case CfgSymO65Export:
+                /* Check if the export symbol is also defined as an import. */
+                if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
+                    CfgError (
+                        &Sym->Pos,
+                        "Exported o65 symbol `%s' cannot also be an o65 import",
+                        GetString (Sym->Name)
+                    );
+                }
+
+                /* Check if we have this symbol defined already. The entry
+                 * routine will check this also, but we get a more verbose
+                 * error message when checking it here.
                  */
-                if ((Sym->Flags & SYM_WEAK) == 0) {
-                    CfgError (&CfgErrorPos,
-                              "Symbol `%s' is already defined",
-                              GetString (Sym->Name));
+                if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
+                    CfgError (
+                        &Sym->Pos,
+                        "Duplicate exported o65 symbol: `%s'",
+                        GetString (Sym->Name)
+                    );
+                }
+
+                /* Insert the symbol into the table */
+                O65SetExport (O65FmtDesc, Sym->Name);
+                break;
+
+            case CfgSymO65Import:
+                /* Check if the import symbol is also defined as an export. */
+                if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
+                    CfgError (
+                        &Sym->Pos,
+                        "Imported o65 symbol `%s' cannot also be an o65 export",
+                        GetString (Sym->Name)
+                    );
+                }
+
+                /* Check if we have this symbol defined already. The entry
+                 * routine will check this also, but we get a more verbose
+                 * error message when checking it here.
+                 */
+                if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
+                    CfgError (
+                        &Sym->Pos,
+                        "Duplicate imported o65 symbol: `%s'",
+                        GetString (Sym->Name)
+                    );
                 }
-            } else {
-                /* The symbol is undefined, generate an export */
-                CreateConstExport (Sym->Name, Sym->Val);
-            }
 
-        } else {
+                /* Insert the symbol into the table */
+                O65SetImport (O65FmtDesc, Sym->Name);
+                break;
 
+            case CfgSymWeak:
+                /* If the symbol is not defined until now, define it */
+                if ((E = FindExport (Sym->Name)) == 0 || IsUnresolvedExport (E)) {
+                    /* The symbol is undefined, generate an export */
+                    E = CreateExprExport (Sym->Name, Sym->Value, Sym->AddrSize);
+                    E->Pos = Sym->Pos;
+                }
+                break;
 
+            default:
+                Internal ("Unexpected symbol type %d", Sym->Type);
+                break;
         }
     }
+
 }
 
 
@@ -1701,12 +1693,19 @@ static void ProcessSymbols (void)
 static void CreateRunDefines (SegDesc* S, unsigned long SegAddr)
 /* Create the defines for a RUN segment */
 {
+    Export* E;
     StrBuf Buf = STATIC_STRBUF_INITIALIZER;
 
+    /* Define the run address of the segment */
     SB_Printf (&Buf, "__%s_RUN__", GetString (S->Name));
-    CreateMemoryExport (GetStrBufId (&Buf), S->Run, SegAddr - S->Run->Start);
+    E = CreateMemoryExport (GetStrBufId (&Buf), S->Run, SegAddr - S->Run->Start);
+    E->Pos = S->Pos;
+
+    /* Define the size of the segment */
     SB_Printf (&Buf, "__%s_SIZE__", GetString (S->Name));
-    CreateConstExport (GetStrBufId (&Buf), S->Seg->Size);
+    E = CreateConstExport (GetStrBufId (&Buf), S->Seg->Size);
+    E->Pos = S->Pos;
+
     S->Flags |= SF_RUN_DEF;
     SB_Done (&Buf);
 }
@@ -1716,10 +1715,14 @@ static void CreateRunDefines (SegDesc* S, unsigned long SegAddr)
 static void CreateLoadDefines (SegDesc* S, unsigned long SegAddr)
 /* Create the defines for a LOAD segment */
 {
+    Export* E;
     StrBuf Buf = STATIC_STRBUF_INITIALIZER;
 
+    /* Define the load address of the segment */
     SB_Printf (&Buf, "__%s_LOAD__", GetString (S->Name));
-    CreateMemoryExport (GetStrBufId (&Buf), S->Load, SegAddr - S->Load->Start);
+    E = CreateMemoryExport (GetStrBufId (&Buf), S->Load, SegAddr - S->Load->Start);
+    E->Pos = S->Pos;
+
     S->Flags |= SF_LOAD_DEF;
     SB_Done (&Buf);
 }
@@ -1738,11 +1741,13 @@ unsigned CfgProcess (void)
     unsigned Overflows = 0;
     unsigned I;
 
-    /* Do postprocessing of the config file data */
-    ProcessSymbols (); /* ######## */
-    ProcessMemory ();
+    /* Postprocess symbols. We must do that first, since weak symbols are
+     * defined here, which may be needed later.
+     */
+    ProcessSymbols ();
+
+    /* Postprocess segments */
     ProcessSegments ();
-    ProcessFormats ();
 
     /* Walk through each of the memory sections. Add up the sizes and check
      * for an overflow of the section. Assign the start addresses of the
@@ -1751,12 +1756,35 @@ unsigned CfgProcess (void)
     for (I = 0; I < CollCount (&MemoryAreas); ++I) {
 
         unsigned J;
+        unsigned long Addr;
 
-        /* Get this entry */
+        /* Get the next memory area */
         MemoryArea* M = CollAtUnchecked (&MemoryAreas, I);
 
+        /* Remember if this is a relocatable memory area */
+        M->Relocatable = RelocatableBinFmt (M->F->Format);
+
+        /* Resolve the start address expression */
+        if (!IsConstExpr (M->StartExpr)) {
+            CfgError (&M->Pos,
+                      "Start address of memory area `%s' is not constant",
+                      GetString (M->Name));
+        }
+        M->Start = GetExprVal (M->StartExpr);
+
+        /* Resolve the size expression */
+        if (!IsConstExpr (M->SizeExpr)) {
+            CfgError (&M->Pos,
+                      "Size of memory area `%s' is not constant",
+                      GetString (M->Name));
+        }
+        M->Size = GetExprVal (M->SizeExpr);
+
+        /* Mark the memory area as placed */
+        M->Flags |= MF_PLACED;
+
        /* Get the start address of this memory area */
-       unsigned long Addr = M->Start;
+       Addr = M->Start;
 
        /* Walk through the segments in this memory area */
         for (J = 0; J < CollCount (&M->SegList); ++J) {
@@ -1855,13 +1883,24 @@ unsigned CfgProcess (void)
 
        /* If requested, define symbols for start and size of the memory area */
        if (M->Flags & MF_DEFINE) {
+            Export* E;
            StrBuf Buf = STATIC_STRBUF_INITIALIZER;
+
+            /* Define the start of the memory area */
            SB_Printf (&Buf, "__%s_START__", GetString (M->Name));
-           CreateMemoryExport (GetStrBufId (&Buf), M, 0);
+           E = CreateMemoryExport (GetStrBufId (&Buf), M, 0);
+            E->Pos = M->Pos;
+
+            /* Define the size of the memory area */
            SB_Printf (&Buf, "__%s_SIZE__", GetString (M->Name));
-           CreateConstExport (GetStrBufId (&Buf), M->Size);
+           E = CreateConstExport (GetStrBufId (&Buf), M->Size);
+            E->Pos = M->Pos;
+
+            /* Define the fill level of the memory area */
            SB_Printf (&Buf, "__%s_LAST__", GetString (M->Name));
-           CreateMemoryExport (GetStrBufId (&Buf), M, M->FillLevel);
+           E = CreateMemoryExport (GetStrBufId (&Buf), M, M->FillLevel);
+            E->Pos = M->Pos;
+
             SB_Done (&Buf);
        }
 
index af752ae8dadd061ffe9201fc77538cb4859dfe0d..3a4cbc852804586535c00d5bd95cd8ee26d589b2 100644 (file)
@@ -40,6 +40,7 @@
 
 /* common */
 #include "coll.h"
+#include "filepos.h"
 
 /* ld65 */
 #include "segments.h"
@@ -68,6 +69,7 @@ struct File {
 typedef struct SegDesc SegDesc;
 struct SegDesc {
     unsigned            Name;           /* Index of the name */
+    FilePos             Pos;            /* Position of definition */
     Segment*                   Seg;            /* Pointer to segment structure */
     unsigned                   Attr;           /* Attributes for segment */
     unsigned                   Flags;          /* Set of bitmapped flags */
index ca44892af9d100ada8775c9dea240f23acca79c2..3d76b73a3184cff02a532f4f040ae950ebf422e7 100644 (file)
@@ -105,8 +105,8 @@ static Import* NewImport (unsigned char AddrSize, ObjData* Obj)
     Import* I = xmalloc (sizeof (Import));
 
     /* Initialize the fields */
-    I->Next    = 0;
-    I->Obj     = Obj;
+    I->Next            = 0;
+    I->Obj             = Obj;
     InitFilePos (&I->Pos);
     I->Exp      = 0;
     I->Name     = INVALID_STRING_ID;
@@ -290,6 +290,7 @@ static Export* NewExport (unsigned char Type, unsigned char AddrSize,
     E->ImpCount = 0;
     E->ImpList  = 0;
     E->Expr            = 0;
+    InitFilePos (&E->Pos);
     E->Type            = Type;
     E->AddrSize = AddrSize;
     memset (E->ConDes, 0, sizeof (E->ConDes));
@@ -467,6 +468,24 @@ Export* CreateConstExport (unsigned Name, long Value)
 
 
 
+Export* CreateExprExport (unsigned Name, ExprNode* Expr, unsigned char AddrSize)
+/* Create an export for an expression */
+{
+    /* Create a new export */
+    Export* E = NewExport (SYM_EXPR | SYM_EQUATE, AddrSize, Name, 0);
+
+    /* Assign the value expression */
+    E->Expr = Expr;
+
+    /* Insert the export */
+    InsertExport (E);
+
+    /* Return the new export */
+    return E;
+}
+
+
+
 Export* CreateMemoryExport (unsigned Name, MemoryArea* Mem, unsigned long Offs)
 /* Create an relative export for a memory area offset */
 {
@@ -590,40 +609,57 @@ static void CheckSymType (const Export* E)
 /* Check the types for one export */
 {
     /* External with matching imports */
-    Import* Imp = E->ImpList;
-    while (Imp) {
-               if (E->AddrSize != Imp->AddrSize) {
-           /* Export is ZP, import is abs or the other way round */
+    Import* I = E->ImpList;
+    while (I) {
+               if (E->AddrSize != I->AddrSize) {
+                   /* Export and import address sizes do not match */
+            StrBuf ExportLoc = STATIC_STRBUF_INITIALIZER;
+            StrBuf ImportLoc = STATIC_STRBUF_INITIALIZER;
             const char* ExpAddrSize = AddrSizeToStr (E->AddrSize);
-            const char* ImpAddrSize = AddrSizeToStr (Imp->AddrSize);
-            const char* ExpObjName  = GetObjFileName (E->Obj);
-            const char* ImpObjName  = GetObjFileName (Imp->Obj);
-           if (E->Obj) {
-               /* User defined export */
-                       Warning ("Address size mismatch for `%s': Exported from %s, "
-                        "%s(%lu) as `%s', import in %s, %s(%lu) as `%s'",
-                        GetString (E->Name),
-                         ExpObjName,
-                         GetSourceFileName (E->Obj, E->Pos.Name),
-                        E->Pos.Line,
-                         ExpAddrSize,
-                         ImpObjName,
-                         GetSourceFileName (Imp->Obj, Imp->Pos.Name),
-                        Imp->Pos.Line,
-                         ImpAddrSize);
-           } else {
-               /* Export created by the linker */
-               Warning ("Address size mismatch for `%s': Symbol is `%s'"
-                         ", but imported from %s, %s(%lu) as `%s'",
-                        GetString (E->Name),
-                         ExpAddrSize,
-                         ImpObjName,
-                         GetSourceFileName (Imp->Obj, Imp->Pos.Name),
-                        Imp->Pos.Line,
-                         ImpAddrSize);
-           }
+            const char* ImpAddrSize = AddrSizeToStr (I->AddrSize);
+
+            /* Generate strings that describe the location of the im- and
+             * exports. This depends on the place from where they come:
+             * Object file or linker config.
+             */
+            if (E->Obj) {
+                /* The export comes from an object file */
+                SB_Printf (&ExportLoc, "%s, %s(%lu)",
+                           GetString (E->Obj->Name),
+                           GetSourceFileName (E->Obj, E->Pos.Name),
+                           E->Pos.Line);
+            } else {
+                SB_Printf (&ExportLoc, "%s(%lu)",
+                           GetSourceFileName (E->Obj, E->Pos.Name),
+                           E->Pos.Line);
+            }
+            if (I->Obj) {
+                /* The import comes from an object file */
+                SB_Printf (&ImportLoc, "%s, %s(%lu)",
+                           GetString (I->Obj->Name),
+                           GetSourceFileName (I->Obj, I->Pos.Name),
+                           I->Pos.Line);
+            } else {
+                SB_Printf (&ImportLoc, "%s(%lu)",
+                           GetSourceFileName (I->Obj, I->Pos.Name),
+                           I->Pos.Line);
+            }
+
+            /* Output the diagnostic */
+            Warning ("Address size mismatch for `%s': "
+                     "Exported from %s as `%s', "
+                     "import in %s as `%s'",
+                     GetString (E->Name),
+                     SB_GetConstBuf (&ExportLoc),
+                     ExpAddrSize,
+                     SB_GetConstBuf (&ImportLoc),
+                     ImpAddrSize);
+
+            /* Free the temporary strings */
+            SB_Done (&ExportLoc);
+            SB_Done (&ImportLoc);
        }
-       Imp = Imp->Next;
+               I = I->Next;
     }
 }
 
index 170f80978fa7b57cffdc9512f520f90d68733432..281b248058038e1756e7b0e4a9b9b36737d93b7e 100644 (file)
@@ -81,8 +81,8 @@ struct Export {
     ObjData*           Obj;            /* Object file that exports the name */
     unsigned           ImpCount;       /* How many imports for this symbol? */
     Import*            ImpList;        /* List of imports for this symbol */
-    FilePos            Pos;            /* File position of definition */
     ExprNode*                  Expr;           /* Expression (0 if not def'd) */
+    FilePos            Pos;            /* File position of definition */
     unsigned char      Type;           /* Type of export */
     unsigned char       AddrSize;       /* Address size of export */
     unsigned char      ConDes[CD_TYPE_COUNT];  /* Constructor/destructor decls */
@@ -136,6 +136,9 @@ void InsertExport (Export* E);
 Export* CreateConstExport (unsigned Name, long Value);
 /* Create an export for a literal date */
 
+Export* CreateExprExport (unsigned Name, ExprNode* Expr, unsigned char AddrSize);
+/* Create an export for an expression */
+
 Export* CreateMemoryExport (unsigned Name, MemoryArea* Mem, unsigned long Offs);
 /* Create an relative export for a memory area offset */
 
index 89f8f8cd5130e4058d36bbe0e0b5ca53efb8bf4a..03eb86043ff1f09db2a23ffce702f3d9070e13ae 100644 (file)
@@ -81,7 +81,7 @@ ObjData* NewObjData (void)
     O->FileCount        = 0;
     O->Files            = EmptyCollection;
     O->SectionCount     = 0;
-    O->Sections         = EmptyCollection;                
+    O->Sections         = EmptyCollection;
     O->ExportCount     = 0;
     O->Exports         = EmptyCollection;
     O->ImportCount     = 0;
@@ -198,7 +198,11 @@ const char* GetSourceFileName (const ObjData* O, unsigned Index)
     if (O == 0) {
 
        /* No object file */
-       return "[linker generated]";
+        if (Index == INVALID_STRING_ID) {
+            return "[linker generated]";
+        } else {
+            return GetString (Index);
+        }
 
     } else {
 
index 92c3f2863dbec44fb2d4d2a5a9887ae74acd61e1..8b90aab800c7249aefe9b55bb55d74266b524bf7 100644 (file)
@@ -122,9 +122,15 @@ typedef enum {
     CFGTOK_CONDES,
     CFGTOK_STARTADDRESS,
 
+    CFGTOK_ADDRSIZE,
     CFGTOK_VALUE,
+
     CFGTOK_WEAK,
 
+    CFGTOK_ABS,
+    CFGTOK_FAR,
+    CFGTOK_LONG,
+
     CFGTOK_SEGMENT,
     CFGTOK_LABEL,
     CFGTOK_COUNT,
@@ -158,7 +164,13 @@ extern cfgtok_t            CfgTok;
 extern StrBuf           CfgSVal;
 extern unsigned long   CfgIVal;
 
-/* Error location */
+/* Error location. PLEASE NOTE: I'm abusing the FilePos structure to some
+ * degree. It is used mostly to hold a file position, where the Name member 
+ * is an index into the source file table of an object file. As used in config
+ * file processing, the Name member is a string pool index instead. This is
+ * distinguished by the object file pointer being NULL or not in the structs 
+ * where this is relevant.
+ */
 extern FilePos          CfgErrorPos;