]> git.sur5r.net Git - cc65/commitdiff
Added o65 symbol export capability
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 1 Dec 2001 17:14:12 +0000 (17:14 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 1 Dec 2001 17:14:12 +0000 (17:14 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1127 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ld65/cfg/lunix.cfg
src/ld65/config.c
src/ld65/exports.c
src/ld65/exports.h
src/ld65/o65.c

index b66e319880628dee91caed0687293b73a7c893d9..610b16e49ffe8c09bdeb1fa9b6ffa02f08b0b2c5 100644 (file)
@@ -22,7 +22,9 @@ FILES {
     %O: format = o65;
 }
 FORMATS {
-    o65: os = lunix, type = small, import = LUNIXKERNAL, import = LIB6502;
+    o65: os = lunix, type = small, 
+        import = LUNIXKERNAL, import = LIB6502,
+        export = _main;
 }
 SYMBOLS {
     __STACKSIZE__ = $800;      # 2K stack
index c8aa03b4527b9b441acfe46651df58452f1c3834..fc4fc04e7cc1c16be2f22886b9934afdae26c665 100644 (file)
@@ -833,6 +833,10 @@ static void ParseO65 (void)
            case CFGTOK_EXPORT:
                /* We expect an identifier */
                CfgAssureIdent ();
+               /* Check if the export symbol is also defined as an import. */
+               if (O65GetImport (O65FmtDesc, CfgSVal) != 0) {
+                   CfgError ("Exported symbol `%s' cannot be an import", CfgSVal);
+               }
                /* 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.
@@ -847,15 +851,19 @@ static void ParseO65 (void)
            case CFGTOK_IMPORT:
                /* We expect an identifier */
                CfgAssureIdent ();
-               /* 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, CfgSVal) != 0) {
-                   CfgError ("Duplicate imported symbol: `%s'", CfgSVal);
-               }
-               /* Insert the symbol into the table */
-               O65SetImport (O65FmtDesc, CfgSVal);
+               /* Check if the imported symbol is also defined as an export. */
+               if (O65GetExport (O65FmtDesc, CfgSVal) != 0) {
+                   CfgError ("Imported symbol `%s' cannot be an export", CfgSVal);
+               }
+               /* 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, CfgSVal) != 0) {
+                   CfgError ("Duplicate imported symbol: `%s'", CfgSVal);
+               }
+               /* Insert the symbol into the table */
+               O65SetImport (O65FmtDesc, CfgSVal);
                break;
 
            case CFGTOK_TYPE:
index ad426d238b8668e6ce4b28dca8294ebf31d57a68..6518bcaf917ab2a0d67a651fc6f3921544af73fa 100644 (file)
@@ -400,9 +400,9 @@ Export* CreateSegExport (const char* Name, Section* Sec, unsigned long Offs)
 
 
 
-static Export* FindExport (const char* Name)
+Export* FindExport (const char* Name)
 /* Check for an identifier in the list. Return 0 if not found, otherwise
- * return a pointer to the export.                      
+ * return a pointer to the export.
  */
 {
     /* Get a pointer to the list with the symbols hash value */
@@ -426,8 +426,14 @@ int IsUnresolved (const char* Name)
 /* Check if this symbol is an unresolved export */
 {
     /* Find the export */
-    Export* E = FindExport (Name);
+    return IsUnresolvedExport (FindExport (Name));
+}
+
 
+
+int IsUnresolvedExport (const Export* E)
+/* Return true if the given export is unresolved */
+{
     /* Check if it's unresolved */
     return E != 0 && E->Expr == 0;
 }
index 7204f8c8ece86885aa274cb0b5ca7fa4b313a1b2..1a0e1a008f612756f828657fc41aa3458e6441f2 100644 (file)
@@ -126,10 +126,18 @@ Export* CreateMemExport (const char* Name, Memory* Mem, unsigned long Offs);
 Export* CreateSegExport (const char* Name, Section* S, unsigned long Offs);
 /* Create a relative export to a segment (section) */
 
+Export* FindExport (const char* Name);
+/* Check for an identifier in the list. Return 0 if not found, otherwise
+ * return a pointer to the export.
+ */
+
 int IsUnresolved (const char* Name);
 /* Check if this symbol is an unresolved export */
 
-int IsConstExport (const Export* E);
+int IsUnresolvedExport (const Export* E);
+/* Return true if the given export is unresolved */
+
+int IsConstExport (const Export* E);  
 /* Return true if the expression associated with this export is const */
 
 long GetExportVal (const Export* E);
index aadfe2fe3d8d34b12b7580c86f333ccdbf361054..123bad6247d54e0661210280ab2bd356dff545c0 100644 (file)
@@ -130,7 +130,7 @@ struct O65RelocTab {
 
 /* Structure describing the format */
 struct O65Desc {
-    O65Header      Header;             /* File header */
+    O65Header      Header;             /* File header */
     O65Option*     Options;            /* List of file options */
     ExtSymTab*     Exports;            /* Table with exported symbols */
     ExtSymTab*     Imports;            /* Table with imported symbols */
@@ -168,18 +168,31 @@ struct ExprDesc {
 
 
 /*****************************************************************************/
-/*                            Helper functions                              */
+/*                            Helper functions                              */
 /*****************************************************************************/
 
 
 
+static ExprDesc* InitExprDesc (ExprDesc* ED, O65Desc* D)
+/* Initialize an ExprDesc structure for use with O65ParseExpr */
+{
+    ED->D         = D;
+    ED->Val       = 0;
+    ED->TooComplex = 0;
+    ED->SegRef     = 0;
+    ED->ExtRef     = 0;
+    return ED;
+}
+
+
+
 static void WriteSize (const O65Desc* D, unsigned long Val)
 /* Write a "size" word to the file */
 {
-    if (D->Header.Mode & MF_SIZE_32BIT) {
-       Write32 (D->F, Val);
-    } else {
-       Write16 (D->F, (unsigned) Val);
+    switch (D->Header.Mode & MF_SIZE_MASK) {
+       case MF_SIZE_16BIT:     Write16 (D->F, (unsigned) Val); break;
+       case MF_SIZE_32BIT:     Write32 (D->F, Val);            break;
+       default:                Internal ("Invalid size in header: %04X", D->Header.Mode);
     }
 }
 
@@ -297,7 +310,7 @@ static void O65ParseExpr (ExprNode* Expr, ExprDesc* D, int Sign)
                }
            } else {
                MarkExport (E);
-               O65ParseExpr (E->Expr, D, Sign);
+               O65ParseExpr (E->Expr, D, Sign);
                UnmarkExport (E);
            }
            break;
@@ -437,7 +450,7 @@ static void FreeO65Option (O65Option* O)
 
 
 /*****************************************************************************/
-/*                    Subroutines to write o65 sections                     */
+/*                    Subroutines to write o65 sections                     */
 /*****************************************************************************/
 
 
@@ -529,15 +542,8 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
                Expr = E->Left;
     }
 
-    /* Initialize the descriptor for expression parsing */
-    ED.D         = D;
-    ED.Val       = 0;
-    ED.TooComplex = 0;
-    ED.SegRef     = 0;
-    ED.ExtRef     = 0;
-
     /* Recursively collect information about this expression */
-    O65ParseExpr (Expr, &ED, 1);
+    O65ParseExpr (Expr, InitExprDesc (&ED, D), 1);
 
     /* We cannot handle both, an imported symbol and a segment ref */
     if (ED.SegRef != 0 && ED.ExtRef != 0) {
@@ -749,20 +755,20 @@ static void O65WriteZPSeg (O65Desc* D, Memory* M attribute ((unused)))
 static void O65WriteImports (O65Desc* D)
 /* Write the list of imported symbols to the O65 file */
 {
-    const ExtSym* E;
+    const ExtSym* S;
 
-    /* Write the number of external symbols */
+    /* Write the number of imports */
     WriteSize (D, ExtSymCount (D->Imports));
 
     /* Write out the symbol names, zero terminated */
-    E = ExtSymList (D->Imports);
-    while (E) {
-       /* Get the name */
-       const char* Name = ExtSymName (E);
-       /* And write it to the output file */
-       WriteData (D->F, Name, strlen (Name) + 1);
-       /* Next symbol */
-       E = ExtSymNext (E);
+    S = ExtSymList (D->Imports);
+    while (S) {
+       /* Get the name */
+       const char* Name = ExtSymName (S);
+       /* And write it to the output file */
+       WriteData (D->F, Name, strlen (Name) + 1);
+       /* Next symbol */
+       S = ExtSymNext (S);
     }
 }
 
@@ -787,10 +793,75 @@ static void O65WriteDataReloc (O65Desc* D)
 static void O65WriteExports (O65Desc* D)
 /* Write the list of exports */
 {
-    /* Since ld65 creates exectutables, not object files, we do not have
-     * exports. This may change if we support writing shared libraries...
-     */
-    WriteSize (D, 0);
+    const ExtSym* S;
+
+    /* Write the number of exports */
+    WriteSize (D, ExtSymCount (D->Exports));
+
+    /* Write out the symbol information */
+    S = ExtSymList (D->Exports);
+    while (S) {
+
+       ExprNode* Expr;
+       unsigned char SegmentID;
+       ExprDesc ED;
+
+       /* Get the name */
+       const char* Name = ExtSymName (S);
+
+       /* Get the export for this symbol. We've checked before that this
+        * export does really exist, so if it is unresolved, or if we don't
+        * find it, there is an error in the linker code.
+        */
+       Export* E = FindExport (Name);
+       if (E == 0 || IsUnresolvedExport (E)) {
+           Internal ("Unresolved export `%s' found in O65WriteExports", Name);
+       }
+
+       /* Get the expression for the symbol */
+       Expr = E->Expr;
+
+       /* Recursively collect information about this expression */
+       O65ParseExpr (Expr, InitExprDesc (&ED, D), 1);
+
+               /* We cannot handle expressions with imported symbols here */
+       if (ED.ExtRef != 0) {
+           ED.TooComplex = 1;
+       }
+
+       /* Bail out if we cannot handle the expression */
+       if (ED.TooComplex) {
+           Error ("Expression for symbol `%s' is too complex", Name);
+       }
+
+       /* Determine the segment id for the expression */
+       if (ED.SegRef == 0) {
+           /* Absolute value */
+           SegmentID = O65SEG_ABS;
+       } else {
+           /* Segment reference. Search for the segment and map it to it's
+            * o65 segmentID
+            */
+           const SegDesc* Seg = O65FindSeg (D, ED.SegRef->Seg);
+           if (Seg == 0) {
+               /* For some reason, we didn't find this segment in the list of
+                * segments written to the o65 file.
+                */
+               Error ("Segment for symbol `%s' is undefined", Name);
+           }
+           SegmentID = O65SegType (Seg);
+       }
+
+       /* Write the name to the output file */
+       WriteData (D->F, Name, strlen (Name) + 1);
+
+       /* Output the segment id followed by the literal value */
+               Write8 (D->F, SegmentID);
+       WriteSize (D, ED.Val);
+
+       /* Next symbol */
+       S = ExtSymNext (S);
+    }
 }
 
 
@@ -992,6 +1063,14 @@ ExtSym* O65GetExport (O65Desc* D, const char* Ident)
 void O65SetExport (O65Desc* D, const char* Ident)
 /* Set an exported identifier */
 {
+    /* Get the export for this symbol and check if it does exist and is
+     * a resolved symbol.
+     */
+    Export* E = FindExport (Ident);
+    if (E == 0 || IsUnresolvedExport (E)) {
+       Error ("Unresolved export: `%s'", Ident);
+    }
+
     /* Insert the entry into the table */
     NewExtSym (D->Exports, Ident);
 }