1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-02 04:41:35 +00:00

Added a new "--force-import" command line option to the linker.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4052 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2009-08-27 14:43:44 +00:00
parent 2b15f40424
commit ee6028993e
4 changed files with 170 additions and 73 deletions

View 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

View 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 */
/*****************************************************************************/

View 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 */

View 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 },