⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ld.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
   Return 1 if the argument is a option complete in itself.   Return 2 if the argument is a option which uses an argument.   Thus, the value is the number of consecutive arguments   that are part of options.  */intclassify_arg (arg)     register char *arg;{  if (*arg != '-') return 0;  switch (arg[1])    {    case 'A':    case 'D':    case 'e':    case 'L':    case 'l':    case 'o':    case 'u':    case 'V':    case 'y':      if (arg[2])	return 1;      return 2;    case 'B':      if (! strcmp (&arg[2], "static"))	return 1;    case 'T':      if (arg[2] == 0)	return 2;      if (! strcmp (&arg[2], "text"))	return 2;      if (! strcmp (&arg[2], "data"))	return 2;      return 1;    }  return 1;}/* Process the command arguments,   setting up file_table with an entry for each input file,   and setting variables according to the options.  */voiddecode_command (argc, argv)     char **argv;     int argc;{  register int i;  register struct file_entry *p;  char *cp;  number_of_files = 0;  output_filename = "a.out";  n_search_dirs = 0;  search_dirs = (char **) xmalloc (sizeof (char *));  /* First compute number_of_files so we know how long to make file_table.  */  /* Also process most options completely.  */  for (i = 1; i < argc; i++)    {      register int code = classify_arg (argv[i]);      if (code)	{	  if (i + code > argc)	    fatal ("no argument following %s\n", argv[i]);	  decode_option (argv[i], argv[i+1]);	  if (argv[i][1] == 'l' || argv[i][1] == 'A')	    number_of_files++;	  i += code - 1;	}      else	number_of_files++;    }  if (!number_of_files)    fatal ("no input files", 0);  p = file_table    = (struct file_entry *) xmalloc (number_of_files * sizeof (struct file_entry));  bzero (p, number_of_files * sizeof (struct file_entry));  /* Now scan again and fill in file_table.  */  /* All options except -A and -l are ignored here.  */  for (i = 1; i < argc; i++)    {      register int code = classify_arg (argv[i]);      if (code)	{	  char *string;	  if (code == 2)	    string = argv[i+1];	  else	    string = &argv[i][2];	  if (argv[i][1] == 'A')	    {	      if (p != file_table)		fatal ("-A specified before an input file other than the first");	      p->filename = string;	      p->local_sym_name = string;	      p->just_syms_flag = 1;	      p++;	    }	  if (argv[i][1] == 'l')	    {	      if (cp = rindex(string, '/'))		{		  *cp++ = '\0';		  cp = concat (string, "/lib", cp);		  p->filename = concat (cp, ".a", "");	        }	      else	        p->filename = concat ("lib", string, ".a");	      p->local_sym_name = concat ("-l", string, "");	      p->search_dirs_flag = 1;	      p++;	    }	  i += code - 1;	}      else	{	  p->filename = argv[i];	  p->local_sym_name = argv[i];	  p++;	}    }  /* Now check some option settings for consistency.  */#ifdef NMAGIC  if ((magic == ZMAGIC || magic == NMAGIC)#else  if ((magic == ZMAGIC)#endif      && (text_start - text_start_alignment) & (page_size - 1))    fatal ("-T argument not multiple of page size, with sharable output", 0);  /* Append the standard search directories to the user-specified ones.  */  {    int n = sizeof standard_search_dirs / sizeof standard_search_dirs[0];    n_search_dirs += n;    search_dirs      = (char **) xrealloc (search_dirs, n_search_dirs * sizeof (char *));    bcopy (standard_search_dirs, &search_dirs[n_search_dirs - n],	   n * sizeof (char *));  }}voidadd_cmdline_ref (sp)     struct glosym *sp;{  struct glosym **ptr;  for (ptr = cmdline_references;       ptr < cmdline_references + cl_refs_allocated && *ptr;       ptr++)    ;  if (ptr >= cmdline_references + cl_refs_allocated - 1)    {      int diff = ptr - cmdline_references;      cl_refs_allocated *= 2;      cmdline_references = (struct glosym **)	xrealloc (cmdline_references,		 cl_refs_allocated * sizeof (struct glosym *));      ptr = cmdline_references + diff;    }  *ptr++ = sp;  *ptr = (struct glosym *) 0;}intset_element_prefixed_p (name)     char *name;{  struct string_list_element *p;  int i;  for (p = set_element_prefixes; p; p = p->next)    {      for (i = 0; p->str[i] != '\0' && (p->str[i] == name[i]); i++)	;      if (p->str[i] == '\0')	return 1;    }  return 0;}int parse ();/* Record an option and arrange to act on it later.   ARG should be the following command argument,   which may or may not be used by this option.   The `l' and `A' options are ignored here since they actually   specify input files.  */voiddecode_option (swt, arg)     register char *swt, *arg;{  /* We get Bstatic from gcc on suns.  */  if (! strcmp (swt + 1, "Bstatic"))    return;  if (! strcmp (swt + 1, "Ttext"))    {      text_start = parse (arg, "%x", "invalid argument to -Ttext");      T_flag_specified = 1;      return;    }  if (! strcmp (swt + 1, "Tdata"))    {      data_start = parse (arg, "%x", "invalid argument to -Tdata");      Tdata_flag_specified = 1;      return;    }  if (! strcmp (swt + 1, "noinhibit-exec"))    {      force_executable = 1;      return;    }  if (swt[2] != 0)    arg = &swt[2];  switch (swt[1])    {    case 'A':      return;    case 'D':      specified_data_size = parse (arg, "%x", "invalid argument to -D");      return;    case 'd':      force_common_definition = 1;      return;    case 'e':      entry_symbol = getsym (arg);      if (!entry_symbol->defined && !entry_symbol->referenced)	undefined_global_sym_count++;      entry_symbol->referenced = 1;      add_cmdline_ref (entry_symbol);      return;    case 'l':      /* If linking with libg++, use the C++ demangler. */      if (arg != NULL && strcmp (arg, "g++") == 0)	demangler = cplus_demangle;      return;    case 'L':      n_search_dirs++;      search_dirs	= (char **) xrealloc (search_dirs, n_search_dirs * sizeof (char *));      search_dirs[n_search_dirs - 1] = arg;      return;    case 'M':      write_map = 1;      return;    case 'N':      magic = OMAGIC;      return;#ifdef NMAGIC    case 'n':      magic = NMAGIC;      return;#endif    case 'o':      output_filename = arg;      return;    case 'p':      padtext = 1;      return;    case 'r':      relocatable_output = 1;      magic = OMAGIC;      text_start = 0;      return;    case 'S':      strip_symbols = STRIP_DEBUGGER;      return;    case 's':      strip_symbols = STRIP_ALL;      return;    case 'T':      text_start = parse (arg, "%x", "invalid argument to -T");      T_flag_specified = 1;      return;    case 't':      trace_files = 1;      return;    case 'u':      {	register symbol *sp = getsym (arg);	if (!sp->defined && !sp->referenced)	  undefined_global_sym_count++;	sp->referenced = 1;	add_cmdline_ref (sp);      }      return;    case 'V':      {	struct string_list_element *new	  = (struct string_list_element *)	    xmalloc (sizeof (struct string_list_element));	new->str = arg;	new->next = set_element_prefixes;	set_element_prefixes = new;	return;      }    case 'X':      discard_locals = DISCARD_L;      return;    case 'x':      discard_locals = DISCARD_ALL;      return;    case 'y':      {	register symbol *sp = getsym (&swt[2]);	sp->trace = 1;      }      return;    case 'z':      magic = ZMAGIC;      return;    default:      fatal ("invalid command option `%s'", swt);    }}/** Convenient functions for operating on one or all files being */ /** loaded.  */void print_file_name ();/* Call FUNCTION on each input file entry.   Do not call for entries for libraries;   instead, call once for each library member that is being loaded.   FUNCTION receives two arguments: the entry, and ARG.  */voideach_file (function, arg)     register void (*function)();     register int arg;{  register int i;  for (i = 0; i < number_of_files; i++)    {      register struct file_entry *entry = &file_table[i];      if (entry->library_flag)        {	  register struct file_entry *subentry = entry->subfiles;	  for (; subentry; subentry = subentry->chain)	    (*function) (subentry, arg);	}      else	(*function) (entry, arg);    }}/* Call FUNCTION on each input file entry until it returns a non-zero   value.  Return this value.   Do not call for entries for libraries;   instead, call once for each library member that is being loaded.   FUNCTION receives two arguments: the entry, and ARG.  It must be a   function returning unsigned long (though this can probably be fudged). */unsigned longcheck_each_file (function, arg)     register unsigned long (*function)();     register int arg;{  register int i;  register unsigned long return_val;  for (i = 0; i < number_of_files; i++)    {      register struct file_entry *entry = &file_table[i];      if (entry->library_flag)        {	  register struct file_entry *subentry = entry->subfiles;	  for (; subentry; subentry = subentry->chain)	    if (return_val = (*function) (subentry, arg))	      return return_val;	}      else	if (return_val = (*function) (entry, arg))	  return return_val;    }  return 0;}/* Like `each_file' but ignore files that were just for symbol definitions.  */voideach_full_file (function, arg)     register void (*function)();     register int arg;{  register int i;  for (i = 0; i < number_of_files; i++)    {      register struct file_entry *entry = &file_table[i];      if (entry->just_syms_flag)	continue;      if (entry->library_flag)        {	  register struct file_entry *subentry = entry->subfiles;	  for (; subentry; subentry = subentry->chain)	    (*function) (subentry, arg);	}      else	(*function) (entry, arg);    }}/* Close the input file that is now open.  */voidfile_close (){  close (input_desc);  input_desc = 0;  input_file = 0;}/* Open the input file specified by 'entry', and return a descriptor.   The open file is remembered; if the same file is opened twice in a row,   a new open is not actually done.  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -