+ /* Free allocated memory. */
+ xfree (PathName);
+}
+
+
+
+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 (CfgSearchPath, Arg);
+}
+
+
+
+static void OptConfig (const char* Opt attribute ((unused)), const char* Arg)
+/* Define the config file */
+{
+ char* PathName;
+
+ if (CfgAvail ()) {
+ Error ("Cannot use -C/-t twice");
+ }
+ /* Search for the file */
+ PathName = SearchFile (CfgSearchPath, Arg);
+ if (PathName == 0) {
+ Error ("Cannot find config file `%s'", Arg);
+ } else {
+ CfgSetName (PathName);
+ }
+}
+
+
+
+static void OptDbgFile (const char* Opt attribute ((unused)), const char* Arg)
+/* Give the name of the debug file */
+{
+ DbgFileName = 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 */
+{
+ /* Map the given target name to its id */
+ target_t T = FindTarget (Arg);
+ if (T == TGT_UNKNOWN) {
+ Error ("Target system `%s' is unknown", Arg);
+ }
+
+ /* Dump the builtin configuration */
+ DumpBuiltinConfig (stdout, T);
+}
+
+
+
+static void OptEndGroup (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
+/* End a library group */
+{
+ LibEndGroup ();
+}
+
+
+
+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);
+ }