X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fld65%2Fmain.c;h=10fff402e6c05a0d484397405ca2996453822e1f;hb=0807da74bd7c3ebe3e6e75129a07a810b17174b2;hp=41246a296cad5532a7c3319406d3078143cd7950;hpb=fe2d8f26edca851894694fd836b9c0f280fe82c1;p=cc65 diff --git a/src/ld65/main.c b/src/ld65/main.c index 41246a296..10fff402e 100644 --- a/src/ld65/main.c +++ b/src/ld65/main.c @@ -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-2010, 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,8 @@ #include /* common */ +#include "addrsize.h" +#include "chartype.h" #include "cmdline.h" #include "filetype.h" #include "libdefs.h" @@ -94,6 +96,7 @@ static void Usage (void) " -(\t\t\tStart a library group\n" " -)\t\t\tEnd a library group\n" " -C name\t\tUse linker config file\n" + " -D sym=val\t\tDefine a symbol\n" " -L path\t\tSpecify a library search path\n" " -Ln name\t\tCreate a VICE label file\n" " -S addr\t\tSet the default start address\n" @@ -102,6 +105,7 @@ static void Usage (void) " -m name\t\tCreate a map file\n" " -o name\t\tName the default output file\n" " -t sys\t\tSet the target system\n" + " -u sym\t\tForce an import of symbol `sym'\n" " -v\t\t\tVerbose mode\n" " -vm\t\t\tVerbose map file\n" "\n" @@ -109,8 +113,10 @@ static void Usage (void) " --cfg-path path\tSpecify a config file search path\n" " --config name\t\tUse linker config file\n" " --dbgfile name\tGenerate debug information\n" + " --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" @@ -171,11 +177,11 @@ static void LinkFile (const char* Name, FILETYPE Type) switch (Type) { case FILETYPE_LIB: - PathName = SearchFile (Name, SEARCH_LIB); + PathName = SearchFile (LibSearchPath, Name); break; case FILETYPE_OBJ: - PathName = SearchFile (Name, SEARCH_OBJ); + PathName = SearchFile (ObjSearchPath, Name); break; default: @@ -227,10 +233,56 @@ static void LinkFile (const char* Name, FILETYPE Type) +static void DefineSymbol (const char* Def) +/* Define a symbol from the command line */ +{ + const char* P; + unsigned I; + long Val; + StrBuf SymName = AUTO_STRBUF_INITIALIZER; + + + /* The symbol must start with a character or underline */ + if (Def [0] != '_' && !IsAlpha (Def [0])) { + InvDef (Def); + } + P = Def; + + /* Copy the symbol, checking the remainder */ + I = 0; + while (IsAlNum (*P) || *P == '_') { + SB_AppendChar (&SymName, *P++); + } + SB_Terminate (&SymName); + + /* Do we have a value given? */ + if (*P != '=') { + InvDef (Def); + } else { + /* We have a value */ + ++P; + if (*P == '$') { + ++P; + if (sscanf (P, "%lx", &Val) != 1) { + InvDef (Def); + } + } else { + if (sscanf (P, "%li", &Val) != 1) { + InvDef (Def); + } + } + } + + /* Define the new symbol */ + CreateConstExport (GetStringId (SB_GetConstBuf (&SymName)), Val); +} + + + static void OptCfgPath (const char* Opt attribute ((unused)), const char* Arg) /* Specify a config file search path */ { - AddSearchPath (Arg, SEARCH_CFG); + AddSearchPath (CfgSearchPath, Arg); } @@ -244,7 +296,7 @@ static void OptConfig (const char* Opt attribute ((unused)), const char* Arg) Error ("Cannot use -C/-t twice"); } /* Search for the file */ - PathName = SearchFile (Arg, SEARCH_CFG); + PathName = SearchFile (CfgSearchPath, Arg); if (PathName == 0) { Error ("Cannot find config file `%s'", Arg); } else { @@ -262,6 +314,14 @@ static void OptDbgFile (const char* Opt attribute ((unused)), const char* Arg) +static void OptDefine (const char* Opt attribute ((unused)), const char* Arg) +/* Define a symbol on the command line */ +{ + DefineSymbol (Arg); +} + + + static void OptDumpConfig (const char* Opt attribute ((unused)), const char* Arg) /* Dump a builtin linker configuration */ { @@ -278,7 +338,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 (); @@ -286,6 +346,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 */ @@ -307,7 +405,7 @@ static void OptLib (const char* Opt attribute ((unused)), const char* Arg) static void OptLibPath (const char* Opt attribute ((unused)), const char* Arg) /* Specify a library file search path */ { - AddSearchPath (Arg, SEARCH_LIB); + AddSearchPath (LibSearchPath, Arg); } @@ -343,7 +441,7 @@ static void OptObj (const char* Opt attribute ((unused)), const char* Arg) static void OptObjPath (const char* Opt attribute ((unused)), const char* Arg) /* Specify an object file search path */ { - AddSearchPath (Arg, SEARCH_OBJ); + AddSearchPath (ObjSearchPath, Arg); } @@ -392,8 +490,8 @@ static void OptVersion (const char* Opt attribute ((unused)), /* Print the assembler version */ { fprintf (stderr, - "ld65 V%u.%u.%u - (C) Copyright 1998-2002 Ullrich von Bassewitz\n", - VER_MAJOR, VER_MINOR, VER_PATCH); + "ld65 V%s - (C) Copyright 1998-2009, Ullrich von Bassewitz\n", + GetVersionAsString ()); } @@ -406,8 +504,10 @@ int main (int argc, char* argv []) { "--cfg-path", 1, OptCfgPath }, { "--config", 1, OptConfig }, { "--dbgfile", 1, OptDbgFile }, + { "--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 }, @@ -473,16 +573,20 @@ int main (int argc, char* argv []) case 't': if (CfgAvail ()) { - Error ("Cannot use -C/-t twice"); + Error ("Cannot use -C/-t twice"); } OptTarget (Arg, GetArg (&I, 2)); break; + case 'u': + OptForceImport (Arg, GetArg (&I, 2)); + break; + case 'v': switch (Arg [2]) { case 'm': VerboseMap = 1; break; - case '\0': ++Verbosity; break; - default: UnknownOption (Arg); + case '\0': ++Verbosity; break; + default: UnknownOption (Arg); } break; @@ -490,11 +594,15 @@ int main (int argc, char* argv []) OptConfig (Arg, GetArg (&I, 2)); break; + case 'D': + OptDefine (Arg, GetArg (&I, 2)); + break; + case 'L': switch (Arg [2]) { /* ## The first one is obsolete and will go */ - case 'n': LabelFileName = GetArg (&I, 3); break; - default: OptLibPath (Arg, GetArg (&I, 2)); break; + case 'n': LabelFileName = GetArg (&I, 3); break; + default: OptLibPath (Arg, GetArg (&I, 2)); break; } break;