if (! link_info.relocateable && command_line.force_exe_suffix) { int len = strlen (output_filename); if (len < 4 || (strcasecmp (output_filename + len - 4, ".exe") != 0 && strcasecmp (output_filename + len - 4, ".dll") != 0)) { FILE *src; FILE *dst; const int bsize = 4096; char *buf = xmalloc (bsize); int l; char *dst_name = xmalloc (len + 5); strcpy (dst_name, output_filename); strcat (dst_name, ".exe"); src = fopen (output_filename, FOPEN_RB); dst = fopen (dst_name, FOPEN_WB);  if (!src) einfo ("%X%P: unable to open for source of copy `%s'\n", output_filename); if (!dst) einfo ("%X%P: unable to open for destination of copy `%s'\n", dst_name); while ((l = fread (buf, 1, bsize, src)) > 0) { int done = fwrite (buf, 1, l, dst); if (done != l) { einfo ("%P: Error writing file `%s'\n", dst_name); } } fclose (src); if (!fclose (dst)) { einfo ("%P: Error closing file `%s'\n", dst_name); } free (dst_name); free (buf); } }
main (argc, argv)     int argc;     char **argv;{  char *emulation;  long start_time = get_run_time ();  program_name = argv[0];  xmalloc_set_program_name (program_name);  START_PROGRESS (program_name, 0);  bfd_init ();  xatexit (remove_output);  /* Initialize the data about options.  */  trace_files = trace_file_tries = version_printed = false;  whole_archive = false;  config.traditional_format = false;  config.build_constructors = true;  config.dynamic_link = false;  command_line.force_common_definition = false;  command_line.interpreter = NULL;  command_line.rpath = NULL;  link_info.callbacks = &link_callbacks;  link_info.relocateable = false;  link_info.shared = false;  link_info.symbolic = false;  link_info.static_link = false;  link_info.strip = strip_none;  link_info.discard = discard_none;  link_info.lprefix_len = 1;  link_info.lprefix = "L";  link_info.keep_memory = true;  link_info.input_bfds = NULL;  link_info.create_object_symbols_section = NULL;  link_info.hash = NULL;  link_info.keep_hash = NULL;  link_info.notice_hash = NULL;    ldfile_add_arch ("");  config.make_executable = true;  force_make_executable = false;  config.magic_demand_paged = true;  config.text_read_only = true;  config.make_executable = true;  emulation = get_emulation (argc, argv);  ldemul_choose_mode (emulation);  default_target = ldemul_choose_target ();  lang_init ();  ldemul_before_parse ();  lang_has_input_file = false;  parse_args (argc, argv);  ldemul_set_symbols ();  if (link_info.relocateable)    {      if (command_line.relax)	einfo ("%P%F: -relax and -r may not be used together\n");      if (link_info.shared)	einfo ("%P%F: -r and -shared may not be used together\n");    }  /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols).  I     don't see how else this can be handled, since in this case we     must preserve all externally visible symbols.  */  if (link_info.relocateable && link_info.strip == strip_all)    {      link_info.strip = strip_debugger;      if (link_info.discard == discard_none)	link_info.discard = discard_all;    }  /* This essentially adds another -L directory so this must be done after     the -L's in argv have been processed.  */  set_scripts_dir ();  if (had_script == false)    {      /* Read the emulation's appropriate default script.  */      int isfile;      char *s = ldemul_get_script (&isfile);      if (isfile)	ldfile_open_command_file (s);      else	{	  if (trace_file_tries)	    {	      info_msg ("using internal linker script:\n");	      info_msg ("==================================================\n");	      info_msg (s);	      info_msg ("\n==================================================\n");	    }	  lex_string = s;	  lex_redirect (s);	}      parser_input = input_script;      yyparse ();      lex_string = NULL;    }  lang_final ();  if (lang_has_input_file == false)    {      if (version_printed)	xexit (0);      einfo ("%P%F: no input files\n");    }  if (trace_files)    {      info_msg ("%P: mode %s\n", emulation);    }  ldemul_after_parse ();  if (config.map_filename)    {      if (strcmp (config.map_filename, "-") == 0)	{	  config.map_file = stdout;	}      else	{	  config.map_file = fopen (config.map_filename, FOPEN_WT);	  if (config.map_file == (FILE *) NULL)	    {	      bfd_set_error (bfd_error_system_call);	      einfo ("%P%F: cannot open map file %s: %E\n",		     config.map_filename);	    }	}    }  lang_process ();  /* Print error messages for any missing symbols, for any warning     symbols, and possibly multiple definitions */  if (config.text_read_only)    {      /* Look for a text section and mark the readonly attribute in it */      asection *found = bfd_get_section_by_name (output_bfd, ".text");      if (found != (asection *) NULL)	{	  found->flags |= SEC_READONLY;	}    }  if (link_info.relocateable)    output_bfd->flags &= ~EXEC_P;  else    output_bfd->flags |= EXEC_P;  ldwrite ();  /* Even if we're producing relocateable output, some non-fatal errors should     be reported in the exit status.  (What non-fatal errors, if any, do we     want to ignore for relocateable output?)  */  if (config.make_executable == false && force_make_executable == false)    {      if (trace_files == true)	{	  einfo ("%P: link errors found, deleting executable `%s'\n",		 output_filename);	}      if (output_bfd->iostream)	fclose ((FILE *) (output_bfd->iostream));      unlink (output_filename);      xexit (1);    }  else    {      if (! bfd_close (output_bfd))	einfo ("%F%B: final close failed: %E\n", output_bfd);    }  END_PROGRESS (program_name);  if (config.stats)    {      extern char **environ;#ifdef HAVE_SBRK      char *lim = (char *) sbrk (0);#endif      long run_time = get_run_time () - start_time;      fprintf (stderr, "%s: total time in link: %ld.%06ld\n",	       program_name, run_time / 1000000, run_time % 1000000);#ifdef HAVE_SBRK      fprintf (stderr, "%s: data size %ld\n", program_name,	       (long) (lim - (char *) &environ));#endif    }  /* Prevent remove_output from doing anything, after a successful link.  */  output_filename = NULL;  xexit (0);  return 0;}