dllwrap.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,250 行 · 第 1/3 页

C
1,250
字号
  if (! def_file_seen)    {      char *fileprefix = choose_temp_base ();      def_file_name = (char *) xmalloc (strlen (fileprefix) + 5);      sprintf (def_file_name, "%s.def",                (dontdeltemps) ? mybasename (fileprefix) : fileprefix);      delete_def_file = 1;      free (fileprefix);      delete_def_file = 1;      warn (_("no export definition file provided"));      warn (_("creating one, but that may not be what you want"));    }    /* set the target platform. */  if (strstr (target, "cygwin"))    which_target = CYGWIN_TARGET;  else if (strstr (target, "mingw"))    which_target = MINGW_TARGET;  else     which_target = UNKNOWN_TARGET;  /* re-create the command lines as a string, taking care to quote stuff. */  dlltool_cmdline = dyn_string_new (cmdline_len);  if (verbose)    {      dyn_string_append_cstr (dlltool_cmdline, " -v");    }  dyn_string_append_cstr (dlltool_cmdline, " --dllname ");  dyn_string_append_cstr (dlltool_cmdline, dll_name);  for (i = 1; i < argc; ++i)    {      if (dlltool_arg_indices[i])        {	  char *arg = saved_argv[i];          int quote = (strchr (arg, ' ') || strchr (arg, '\t'));	  dyn_string_append_cstr (dlltool_cmdline, 	                     (quote) ? " \"" : " ");	  dyn_string_append_cstr (dlltool_cmdline, arg);	  dyn_string_append_cstr (dlltool_cmdline, 	                     (quote) ? "\"" : "");	}    }  driver_cmdline = dyn_string_new (cmdline_len);  if (! driver_flags || strlen (driver_flags) == 0)    {      switch (which_target)        {	case CYGWIN_TARGET:          driver_flags = cygwin_driver_flags;	  break;		case MINGW_TARGET:          driver_flags = mingw32_driver_flags;	  break;		default:          driver_flags = generic_driver_flags;	  break;	}    }  dyn_string_append_cstr (driver_cmdline, driver_flags);  dyn_string_append_cstr (driver_cmdline, " -o ");  dyn_string_append_cstr (driver_cmdline, dll_file_name);  if (! entry_point || strlen (entry_point) == 0)    {      switch (which_target)        {	case CYGWIN_TARGET:	  entry_point = "__cygwin_dll_entry@12";	  break;		case MINGW_TARGET:	  entry_point = "_DllMainCRTStartup@12";	  break;		default:          entry_point = "_DllMain@12";	  break;	}    }  dyn_string_append_cstr (driver_cmdline, " -Wl,-e,");  dyn_string_append_cstr (driver_cmdline, entry_point);  dyn_string_append_cstr (dlltool_cmdline, " --exclude-symbol=");  dyn_string_append_cstr (dlltool_cmdline,                      (entry_point[0] == '_') ? entry_point+1 : entry_point);  if (! image_base_str || strlen (image_base_str) == 0)    {      char *tmpbuf = (char *) xmalloc (sizeof ("0x12345678") + 1);      unsigned long hash = strhash (dll_file_name);      sprintf (tmpbuf, "0x%.8lX", 0x60000000|((hash<<16)&0xFFC0000));      image_base_str = tmpbuf;    }  dyn_string_append_cstr (driver_cmdline, " -Wl,--image-base,");  dyn_string_append_cstr (driver_cmdline, image_base_str);  if (verbose)    {      dyn_string_append_cstr (driver_cmdline, " -v");    }  for (i = 1; i < argc; ++i)    {      if (driver_arg_indices[i])        {	  char *arg = saved_argv[i];          int quote = (strchr (arg, ' ') || strchr (arg, '\t'));	  dyn_string_append_cstr (driver_cmdline, 	                     (quote) ? " \"" : " ");	  dyn_string_append_cstr (driver_cmdline, arg);	  dyn_string_append_cstr (driver_cmdline, 	                     (quote) ? "\"" : "");	}    }    /*   * Step pre-1. If no --def <EXPORT_DEF> is specified, then create it   * and then pass it on.   */    if (! def_file_seen)     {      int i;      dyn_string_t step_pre1;      step_pre1 = dyn_string_new (1024);      dyn_string_append_cstr (step_pre1, dlltool_cmdline->s);      if (export_all)	{          dyn_string_append_cstr (step_pre1, " --export-all --exclude-symbol=");          dyn_string_append_cstr (step_pre1, 	  "_cygwin_dll_entry@12,DllMainCRTStartup@12,DllMain@12,DllEntryPoint@12");	}      dyn_string_append_cstr (step_pre1, " --output-def ");      dyn_string_append_cstr (step_pre1, def_file_name);      for (i = 1; i < argc; ++i)	{	  if (driver_arg_indices[i])	    {	      char *arg = saved_argv[i];	      size_t len = strlen (arg);	      if (len >= 2 && arg[len-2] == '.' 	          && (arg[len-1] == 'o' || arg[len-1] == 'a'))		{		  int quote = (strchr (arg, ' ') || strchr (arg, '\t'));		  dyn_string_append_cstr (step_pre1,				     (quote) ? " \"" : " ");		  dyn_string_append_cstr (step_pre1, arg);		  dyn_string_append_cstr (step_pre1,				     (quote) ? "\"" : "");		}	    }	}      if (run (dlltool_name, step_pre1->s))	cleanup_and_exit (1);            dyn_string_delete (step_pre1);    }  dyn_string_append_cstr (dlltool_cmdline, " --def ");  dyn_string_append_cstr (dlltool_cmdline, def_file_name);  if (verbose)    {      fprintf (stderr, _("DLLTOOL name    : %s\n"), dlltool_name);      fprintf (stderr, _("DLLTOOL options : %s\n"), dlltool_cmdline->s);      fprintf (stderr, _("DRIVER name     : %s\n"), driver_name);      fprintf (stderr, _("DRIVER options  : %s\n"), driver_cmdline->s);    }   /*   * Step 1. Call GCC/LD to create base relocation file. If using GCC, the   * driver command line will look like the following:   *       *    % gcc -Wl,--dll --Wl,--base-file,foo.base [rest of command line]   *   * If the user does not specify a base name, create temporary one that   * is deleted at exit.   *   */    if (! base_file_name)    {      char *fileprefix = choose_temp_base ();      base_file_name = (char *) xmalloc (strlen (fileprefix) + 6);      sprintf (base_file_name, "%s.base",                (dontdeltemps) ? mybasename (fileprefix) : fileprefix);      delete_base_file = 1;      free (fileprefix);    }    {    int quote;    dyn_string_t step1 = dyn_string_new (driver_cmdline->length                                          + strlen (base_file_name)				         + 20);    dyn_string_append_cstr (step1, "-Wl,--base-file,");    quote = (strchr (base_file_name, ' ')              || strchr (base_file_name, '\t'));    dyn_string_append_cstr (step1, 	               (quote) ? "\"" : "");    dyn_string_append_cstr (step1, base_file_name);    dyn_string_append_cstr (step1, 	               (quote) ? "\"" : "");    if (driver_cmdline->length)      {        dyn_string_append_cstr (step1, " ");        dyn_string_append_cstr (step1, driver_cmdline->s);      }    if (run (driver_name, step1->s))      cleanup_and_exit (1);        dyn_string_delete (step1);  }  /*   * Step 2. generate the exp file by running dlltool.    * dlltool command line will look like the following:   *       *    % dlltool -Wl,--dll --Wl,--base-file,foo.base [rest of command line]   *   * If the user does not specify a base name, create temporary one that   * is deleted at exit.   *   */    if (! exp_file_name)    {      char *p = strrchr (dll_name, '.');      size_t prefix_len = (p) ? p - dll_name : strlen (dll_name);      exp_file_name = (char *) xmalloc (prefix_len + 4 + 1);      strncpy (exp_file_name, dll_name, prefix_len);      exp_file_name[prefix_len] = '\0';      strcat (exp_file_name, ".exp");      delete_exp_file = 1;    }    {    int quote;    dyn_string_t step2 = dyn_string_new (dlltool_cmdline->length                                          + strlen (base_file_name)                                         + strlen (exp_file_name)				         + 20);    dyn_string_append_cstr (step2, "--base-file ");    quote = (strchr (base_file_name, ' ')              || strchr (base_file_name, '\t'));    dyn_string_append_cstr (step2, 	               (quote) ? "\"" : "");    dyn_string_append_cstr (step2, base_file_name);    dyn_string_append_cstr (step2, 	               (quote) ? "\" " : " ");    dyn_string_append_cstr (step2, "--output-exp ");    quote = (strchr (exp_file_name, ' ')              || strchr (exp_file_name, '\t'));    dyn_string_append_cstr (step2, 	               (quote) ? "\"" : "");    dyn_string_append_cstr (step2, exp_file_name);    dyn_string_append_cstr (step2, 	               (quote) ? "\"" : "");    if (dlltool_cmdline->length)      {        dyn_string_append_cstr (step2, " ");        dyn_string_append_cstr (step2, dlltool_cmdline->s);      }    if (run (dlltool_name, step2->s))      cleanup_and_exit (1);        dyn_string_delete (step2);  }  /*   * Step 3. Call GCC/LD to again, adding the exp file this time.   * driver command line will look like the following:   *       *    % gcc -Wl,--dll --Wl,--base-file,foo.base foo.exp [rest ...]   */  {    int quote;    dyn_string_t step3 = dyn_string_new (driver_cmdline->length                                          + strlen (exp_file_name)                                         + strlen (base_file_name)				         + 20);    dyn_string_append_cstr (step3, "-Wl,--base-file,");    quote = (strchr (base_file_name, ' ')              || strchr (base_file_name, '\t'));    dyn_string_append_cstr (step3, 	               (quote) ? "\"" : "");    dyn_string_append_cstr (step3, base_file_name);    dyn_string_append_cstr (step3, 	               (quote) ? "\" " : " ");    quote = (strchr (exp_file_name, ' ')              || strchr (exp_file_name, '\t'));    dyn_string_append_cstr (step3, 	               (quote) ? "\"" : "");    dyn_string_append_cstr (step3, exp_file_name);    dyn_string_append_cstr (step3, 	               (quote) ? "\"" : "");    if (driver_cmdline->length)      {        dyn_string_append_cstr (step3, " ");        dyn_string_append_cstr (step3, driver_cmdline->s);      }    if (run (driver_name, step3->s))      cleanup_and_exit (1);        dyn_string_delete (step3);  }  /*   * Step 4. Run DLLTOOL again using the same command line.   */  {    int quote;    dyn_string_t step4 = dyn_string_new (dlltool_cmdline->length                                          + strlen (base_file_name)                                         + strlen (exp_file_name)				         + 20);    dyn_string_append_cstr (step4, "--base-file ");    quote = (strchr (base_file_name, ' ')              || strchr (base_file_name, '\t'));    dyn_string_append_cstr (step4, 	               (quote) ? "\"" : "");    dyn_string_append_cstr (step4, base_file_name);    dyn_string_append_cstr (step4, 	               (quote) ? "\" " : " ");    dyn_string_append_cstr (step4, "--output-exp ");    quote = (strchr (exp_file_name, ' ')              || strchr (exp_file_name, '\t'));    dyn_string_append_cstr (step4, 	               (quote) ? "\"" : "");    dyn_string_append_cstr (step4, exp_file_name);    dyn_string_append_cstr (step4, 	               (quote) ? "\"" : "");    if (dlltool_cmdline->length)      {        dyn_string_append_cstr (step4, " ");        dyn_string_append_cstr (step4, dlltool_cmdline->s);      }    if (output_lib_file_name)      {        dyn_string_append_cstr (step4, " --output-lib ");        dyn_string_append_cstr (step4, output_lib_file_name);      }    if (run (dlltool_name, step4->s))      cleanup_and_exit (1);        dyn_string_delete (step4);  }    /*   * Step 5. Link it all together and be done with it.   * driver command line will look like the following:   *       *    % gcc -Wl,--dll foo.exp [rest ...]   *   */  {    int quote;    dyn_string_t step5 = dyn_string_new (driver_cmdline->length                                          + strlen (exp_file_name)				         + 20);    quote = (strchr (exp_file_name, ' ')              || strchr (exp_file_name, '\t'));    dyn_string_append_cstr (step5, 	               (quote) ? "\"" : "");    dyn_string_append_cstr (step5, exp_file_name);    dyn_string_append_cstr (step5, 	               (quote) ? "\"" : "");    if (driver_cmdline->length)      {        dyn_string_append_cstr (step5, " ");        dyn_string_append_cstr (step5, driver_cmdline->s);      }    if (run (driver_name, step5->s))      cleanup_and_exit (1);        dyn_string_delete (step5);  }  cleanup_and_exit (0);  return 0;}

⌨️ 快捷键说明

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