]> git.sur5r.net Git - cc65/commitdiff
Added a new "--force-import" command line option to the linker.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 27 Aug 2009 14:43:44 +0000 (14:43 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 27 Aug 2009 14:43:44 +0000 (14:43 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@4052 b7a2c559-68d2-44c3-8de9-860c34a00d81

doc/ld65.sgml
src/ld65/exports.c
src/ld65/exports.h
src/ld65/main.c

index ca431ff6e613a1c15efd3f3e69aeb68b7bbee2cb..27723cd592e8604897a176b2e7bd2a0b0d220776 100644 (file)
@@ -77,6 +77,7 @@ Long options:
   --define sym=val      Define a symbol
   --dump-config name    Dump a builtin configuration
   --end-group           End a library group
+  --force-import sym    Force an import of symbol `sym'
   --help                Help (this text)
   --lib file            Link this library
   --lib-path path       Specify a library search path
@@ -263,6 +264,22 @@ Here is a description of all the command line options:
   file and it's contents are subject to change without further notice.
 
 
+  <tag><tt>--force-import sym[:addrsize]</tt></tag>
+
+  Force an import of a symbol. While object files are always linked to the
+  output file, regardless if there are any references, object modules from
+  libraries get only linked in if an import can be satisfied by this module.
+  The <tt/--fore-import/ option may be used to add a reference to a symbol and
+  as a result force linkage of the module that exports the identifier.
+
+  The name of the symbol may be followed by a colon and an address size
+  specifier. If no address size is specified, the default address size
+  for the target machine is used.
+
+  Please note that the symbol name needs to have the internal representation,
+  meaning you have to prepend an underline for C identifiers.
+
+
   <tag><tt>--lib file</tt></tag>
 
   Links a library to the output. Use this command line option instead of just
index 7a3c120e930002588db631f61531f0cd7086b152..a5415bf8276950f95d348386b2138301384146c1 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2008 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -106,6 +106,7 @@ static Import* NewImport (unsigned char AddrSize, ObjData* Obj)
     /* Initialize the fields */
     I->Next    = 0;
     I->Obj     = Obj;
+    InitFilePos (&I->Pos);
     I->Exp      = 0;
     I->Name     = INVALID_STRING_ID;
     I->Flags    = 0;
@@ -117,60 +118,6 @@ static Import* NewImport (unsigned char AddrSize, ObjData* Obj)
 
 
 
-void InsertImport (Import* I)
-/* Insert an import into the table */
-{
-    Export* E;
-
-    /* As long as the import is not inserted, V.Name is valid */
-    unsigned Name = I->Name;
-
-    /* Create a hash value for the given name */
-    unsigned Hash = (Name & HASHTAB_MASK);
-
-    /* Search through the list in that slot and print matching duplicates */
-    if (HashTab[Hash] == 0) {
-       /* The slot is empty, we need to insert a dummy export */
-               E = HashTab[Hash] = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
-       ++ExpCount;
-    } else {
-       E = HashTab [Hash];
-       while (1) {
-           if (E->Name == Name) {
-               /* We have an entry, L points to it */
-                       break;
-           }
-           if (E->Next == 0) {
-               /* End of list an entry not found, insert a dummy */
-               E->Next = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
-               E = E->Next;            /* Point to dummy */
-               ++ExpCount;             /* One export more */
-                       break;
-           } else {
-               E = E->Next;
-           }
-       }
-    }
-
-    /* Ok, E now points to a valid exports entry for the given import. Insert
-     * the import into the imports list and update the counters.
-     */
-    I->Exp     = E;
-    I->Next    = E->ImpList;
-    E->ImpList = I;
-    E->ImpCount++;
-    ++ImpCount;                        /* Total import count */
-    if (E->Expr == 0) {
-               /* This is a dummy export */
-       ++ImpOpen;
-    }
-
-    /* Mark the import so we know it's in the list */
-    I->Flags |= IMP_INLIST;
-}
-
-
-
 void FreeImport (Import* I)
 /* Free an import. NOTE: This won't remove the import from the exports table,
  * so it may only be called for unused imports (imports from modules that
@@ -229,6 +176,95 @@ Import* ReadImport (FILE* F, ObjData* Obj)
 
 
 
+Import* GenImport (const char* Name, unsigned char AddrSize)
+/* Generate a new import with the given name and address size and return it */
+{
+    /* Create a new import */
+    Import* I = NewImport (AddrSize, 0);
+
+    /* Read the name */
+    I->Name = GetStringId (Name);
+
+    /* Check the address size */
+    if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) {
+        /* Beware: This function may be called in cases where the object file
+         * is not read completely into memory. In this case, the file list is
+         * invalid. Be sure not to access it in this case.
+         */
+        if (ObjHasFiles (I->Obj)) {
+            Error ("Invalid import size in for `%s', imported from %s(%lu): 0x%02X",
+                   GetString (I->Name),
+                   GetSourceFileName (I->Obj, I->Pos.Name),
+                   I->Pos.Line,
+                   I->AddrSize);
+        } else {
+            Error ("Invalid import size in for `%s', imported from %s: 0x%02X",
+                   GetString (I->Name),
+                   GetObjFileName (I->Obj),
+                   I->AddrSize);
+        }
+    }
+
+    /* Return the new import */
+    return I;
+}
+
+
+
+void InsertImport (Import* I)
+/* Insert an import into the table */
+{
+    Export* E;
+
+    /* As long as the import is not inserted, V.Name is valid */
+    unsigned Name = I->Name;
+
+    /* Create a hash value for the given name */
+    unsigned Hash = (Name & HASHTAB_MASK);
+
+    /* Search through the list in that slot and print matching duplicates */
+    if (HashTab[Hash] == 0) {
+       /* The slot is empty, we need to insert a dummy export */
+               E = HashTab[Hash] = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
+       ++ExpCount;
+    } else {
+       E = HashTab [Hash];
+       while (1) {
+           if (E->Name == Name) {
+               /* We have an entry, L points to it */
+                       break;
+           }
+           if (E->Next == 0) {
+               /* End of list an entry not found, insert a dummy */
+               E->Next = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
+               E = E->Next;            /* Point to dummy */
+               ++ExpCount;             /* One export more */
+                       break;
+           } else {
+               E = E->Next;
+           }
+       }
+    }
+
+    /* Ok, E now points to a valid exports entry for the given import. Insert
+     * the import into the imports list and update the counters.
+     */
+    I->Exp     = E;
+    I->Next    = E->ImpList;
+    E->ImpList = I;
+    E->ImpCount++;
+    ++ImpCount;                        /* Total import count */
+    if (E->Expr == 0) {
+               /* This is a dummy export */
+       ++ImpOpen;
+    }
+
+    /* Mark the import so we know it's in the list */
+    I->Flags |= IMP_INLIST;
+}
+
+
+
 /*****************************************************************************/
 /*                                          Code                                    */
 /*****************************************************************************/
index 6247691d0ddffda0216205302daebeff3d5104d3..e3c3d89a1081e84d4dbc7b48add5259ea797965c 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -114,6 +114,9 @@ void FreeImport (Import* I);
 Import* ReadImport (FILE* F, ObjData* Obj);
 /* Read an import from a file and insert it into the table */
 
+Import* GenImport (const char* Name, unsigned char AddrSize);
+/* Generate a new import with the given name and address size and return it */
+
 void InsertImport (Import* I);
 /* Insert an import into the table */
 
index b51acefcadc804c2a657ce9e6a55122e82676140..7821cdd7b8b1f1b7aec4f11c7350d059b3a6a06f 100644 (file)
@@ -1,15 +1,15 @@
 /*****************************************************************************/
-/*                                                                          */
-/*                                 main.c                                   */
-/*                                                                          */
+/*                                                                          */
+/*                                 main.c                                   */
+/*                                                                          */
 /*                    Main program for the ld65 linker                      */
-/*                                                                          */
-/*                                                                          */
-/*                                                                          */
-/* (C) 1998-2005 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/*                                                                          */
+/*                                                                          */
+/*                                                                          */
+/* (C) 1998-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                          */
 /*                                                                          */
 /* This software is provided 'as-is', without any expressed or implied      */
@@ -39,6 +39,7 @@
 #include <errno.h>
 
 /* common */
+#include "addrsize.h"
 #include "chartype.h"
 #include "cmdline.h"
 #include "filetype.h"
@@ -114,6 +115,7 @@ static void Usage (void)
             "  --define sym=val\tDefine a symbol\n"
             "  --dump-config name\tDump a builtin configuration\n"
             "  --end-group\t\tEnd a library group\n"
+            "  --force-import sym\tForce an import of symbol `sym'\n"
             "  --help\t\tHelp (this text)\n"
             "  --lib file\t\tLink this library\n"
             "  --lib-path path\tSpecify a library search path\n"
@@ -335,7 +337,7 @@ static void OptDumpConfig (const char* Opt attribute ((unused)), const char* Arg
 
 
 static void OptEndGroup (const char* Opt attribute ((unused)),
-                        const char* Arg attribute ((unused)))
+                        const char* Arg attribute ((unused)))
 /* End a library group */
 {
     LibEndGroup ();
@@ -343,6 +345,44 @@ static void OptEndGroup (const char* Opt attribute ((unused)),
 
 
 
+static void OptForceImport (const char* Opt attribute ((unused)), const char* Arg)
+/* Force an import of a symbol */
+{
+    /* An optional address size may be specified */
+    const char* ColPos = strchr (Arg, ':');
+    if (ColPos == 0) {
+
+        /* Use default address size (which for now is always absolute
+         * addressing) 
+         */
+        InsertImport (GenImport (Arg, ADDR_SIZE_ABS));
+
+    } else {
+
+        char* A;
+
+        /* Get the address size and check it */
+        unsigned char AddrSize = AddrSizeFromStr (ColPos+1);
+        if (AddrSize == ADDR_SIZE_INVALID) {
+            Error ("Invalid address size `%s'", ColPos+1);
+        }
+
+        /* Create a copy of the argument */
+        A = xstrdup (Arg);
+
+        /* We need just the symbol */
+        A[ColPos - Arg] = '\0';
+
+        /* Generate the import */
+        InsertImport (GenImport (A, AddrSize));
+
+        /* Delete the copy of the argument */
+        xfree (A);
+    }
+}
+
+
+
 static void OptHelp (const char* Opt attribute ((unused)),
                     const char* Arg attribute ((unused)))
 /* Print usage information and exit */
@@ -466,6 +506,7 @@ int main (int argc, char* argv [])
         { "--define",           1,      OptDefine               },
                { "--dump-config",      1,      OptDumpConfig           },
         { "--end-group",        0,      OptEndGroup             },
+        { "--force-import",     1,      OptForceImport          },
        { "--help",             0,      OptHelp                 },
         { "--lib",              1,      OptLib                  },
                { "--lib-path",         1,      OptLibPath              },