inbfd->xvec->byteorder_big_p);
bfd_big_endian (inbfd));
main (argc, argv)     int argc;     char **argv;{  int opt;  char *input_file = NULL;  const char *input_format = NULL;  const char *output_format = NULL;  const char *header_file = NULL;  char *ld_arg = NULL;  Nlm_Internal_Fixed_Header fixed_hdr_struct;  Nlm_Internal_Variable_Header var_hdr_struct;  Nlm_Internal_Version_Header version_hdr_struct;  Nlm_Internal_Copyright_Header copyright_hdr_struct;  Nlm_Internal_Extended_Header extended_hdr_struct;  bfd *inbfd;  bfd *outbfd;  asymbol **newsyms, **outsyms;  long symcount, newsymalloc, newsymcount;  long symsize;  asection *text_sec, *bss_sec, *data_sec;  bfd_vma vma;  bfd_size_type align;  asymbol *endsym;  long i;  char inlead, outlead;  boolean gotstart, gotexit, gotcheck;  struct stat st;  FILE *custom_data, *help_data, *message_data, *rpc_data, *shared_data;  size_t custom_size, help_size, message_size, module_size, rpc_size;  asection *custom_section, *help_section, *message_section, *module_section;  asection *rpc_section, *shared_section;  bfd *sharedbfd;  size_t shared_offset, shared_size;  Nlm_Internal_Fixed_Header sharedhdr;  int len;  char *modname;  char **matching;  program_name = argv[0];  xmalloc_set_program_name (program_name);  bfd_init ();  while ((opt = getopt_long (argc, argv, "dhI:l:O:T:V", long_options,			     (int *) NULL))	 != EOF)    {      switch (opt)	{	case 'd':	  debug = 1;	  break;	case 'h':	  show_help ();	  /*NOTREACHED*/	case 'I':	  input_format = optarg;	  break;	case 'l':	  ld_arg = optarg;	  break;	case 'O':	  output_format = optarg;	  break;	case 'T':	  header_file = optarg;	  break;	case 'V':	  printf ("GNU %s version %s\n", program_name, program_version);	  exit (0);	  /*NOTREACHED*/	case 0:	  break;	default:	  show_usage (stderr, 1);	  /*NOTREACHED*/	}    }  /* The input and output files may be named on the command line.  */  output_file = NULL;  if (optind < argc)    {      input_file = argv[optind];      ++optind;      if (optind < argc)	{	  output_file = argv[optind];	  ++optind;	  if (optind < argc)	    show_usage (stderr, 1);	  if (strcmp (input_file, output_file) == 0)	    {	      fprintf (stderr,		       "%s: input and output files must be different\n",		       program_name);	      exit (1);	    }	}    }  /* Initialize the header information to default values.  */  fixed_hdr = &fixed_hdr_struct;  memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);  var_hdr = &var_hdr_struct;  memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);  version_hdr = &version_hdr_struct;  memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);  copyright_hdr = &copyright_hdr_struct;  memset ((PTR) &copyright_hdr_struct, 0, sizeof copyright_hdr_struct);  extended_hdr = &extended_hdr_struct;  memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);  check_procedure = NULL;  custom_file = NULL;  debug_info = false;  exit_procedure = "_Stop";  export_symbols = NULL;  map_file = NULL;  full_map = false;  help_file = NULL;  import_symbols = NULL;  message_file = NULL;  modules = NULL;  sharelib_file = NULL;  start_procedure = "_Prelude";  verbose = false;  rpc_file = NULL;  parse_errors = 0;  /* Parse the header file (if there is one).  */  if (header_file != NULL)    {      if (! nlmlex_file (header_file)	  || yyparse () != 0	  || parse_errors != 0)	exit (1);    }  if (input_files != NULL)    {      if (input_file != NULL)	{	  fprintf (stderr,		   "%s: input file named both on command line and with INPUT\n",		   program_name);	  exit (1);	}      if (input_files->next == NULL)	input_file = input_files->string;      else	input_file = link_inputs (input_files, ld_arg);    }  else if (input_file == NULL)    {      fprintf (stderr, "%s: no input file\n", program_name);      show_usage (stderr, 1);    }  inbfd = bfd_openr (input_file, input_format);  if (inbfd == NULL)    bfd_fatal (input_file);  if (! bfd_check_format_matches (inbfd, bfd_object, &matching))    {      bfd_nonfatal (input_file);      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)	{	  list_matching_formats (matching);	  free (matching);	}      exit (1);    }  if (output_format == NULL)    output_format = select_output_format (bfd_get_arch (inbfd),					  bfd_get_mach (inbfd),					  inbfd->xvec->byteorder_big_p);  assert (output_format != NULL);  /* Use the output file named on the command line if it exists.     Otherwise use the file named in the OUTPUT statement.  */  if (output_file == NULL)    {      fprintf (stderr, "%s: no name for output file\n",	       program_name);      show_usage (stderr, 1);    }  outbfd = bfd_openw (output_file, output_format);  if (outbfd == NULL)    bfd_fatal (output_file);  if (! bfd_set_format (outbfd, bfd_object))    bfd_fatal (output_file);  assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);  if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)    fprintf (stderr,	     "%s: warning:input and output formats are not compatible\n",	     program_name);  /* Move the values read from the command file into outbfd.  */  *nlm_fixed_header (outbfd) = fixed_hdr_struct;  *nlm_variable_header (outbfd) = var_hdr_struct;  *nlm_version_header (outbfd) = version_hdr_struct;  *nlm_copyright_header (outbfd) = copyright_hdr_struct;  *nlm_extended_header (outbfd) = extended_hdr_struct;  /* Start copying the input BFD to the output BFD.  */  if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))    bfd_fatal (bfd_get_filename (outbfd));  symsize = bfd_get_symtab_upper_bound (inbfd);  if (symsize < 0)    bfd_fatal (input_file);  symbols = (asymbol **) xmalloc (symsize);  symcount = bfd_canonicalize_symtab (inbfd, symbols);  if (symcount < 0)    bfd_fatal (input_file);  /* Make sure we have a .bss section.  */  bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);  if (bss_sec == NULL)    {      bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);      if (bss_sec == NULL	  || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)	  || ! bfd_set_section_alignment (outbfd, bss_sec, 1))	bfd_fatal ("make .bss section");    }  /* We store the original section names in the .nlmsections section,     so that programs which understand it can resurrect the original     sections from the NLM.  We will put a pointer to .nlmsections in     the NLM header area.  */  secsec = bfd_make_section (outbfd, ".nlmsections");  if (secsec == NULL)    bfd_fatal ("make .nlmsections section");  if (! bfd_set_section_flags (outbfd, secsec, SEC_HAS_CONTENTS))    bfd_fatal ("set .nlmsections flags");#ifdef NLMCONV_POWERPC  /* For PowerPC NetWare we need to build stubs for calls to undefined     symbols.  Because each stub requires an entry in the TOC section     which must be at the same location as other entries in the TOC     section, we must do this before determining where the TOC section     goes in setup_sections.  */  if (bfd_get_arch (inbfd) == bfd_arch_powerpc)    powerpc_build_stubs (inbfd, outbfd, &symbols, &symcount);#endif  /* Set up the sections.  */  bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);  text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);  /* The .bss section immediately follows the .data section.  */  data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);  if (data_sec != NULL)    {      bfd_size_type add;      vma = bfd_get_section_size_before_reloc (data_sec);      align = 1 << bss_sec->alignment_power;      add = ((vma + align - 1) &~ (align - 1)) - vma;      vma += add;      if (! bfd_set_section_vma (outbfd, bss_sec, vma))	bfd_fatal ("set .bss vma");      if (add != 0)	{	  bfd_size_type data_size;	  data_size = bfd_get_section_size_before_reloc (data_sec);	  if (! bfd_set_section_size (outbfd, data_sec, data_size + add))	    bfd_fatal ("set .data size");	}    }  /* Adjust symbol information.  */  inlead = bfd_get_symbol_leading_char (inbfd);  outlead = bfd_get_symbol_leading_char (outbfd);  gotstart = false;  gotexit = false;  gotcheck = false;  newsymalloc = 10;  newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));  newsymcount = 0;  endsym = NULL;  for (i = 0; i < symcount; i++)    {      register asymbol *sym;      sym = symbols[i];      /* Add or remove a leading underscore.  */      if (inlead != outlead)	{	  if (inlead != '\0')	    {	      if (bfd_asymbol_name (sym)[0] == inlead)		{		  if (outlead == '\0')		    ++sym->name;		  else		    {		      char *new;		      new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);		      new[0] = outlead;		      strcpy (new + 1, bfd_asymbol_name (sym) + 1);		      sym->name = new;		    }		}	    }	  else	    {	      char *new;	      new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);	      new[0] = outlead;	      strcpy (new + 1, bfd_asymbol_name (sym));	      sym->name = new;	    }	}      /* NLM's have an uninitialized data section, but they do not	 have a common section in the Unix sense.  Move all common	 symbols into the .bss section, and mark them as exported.  */      if (bfd_is_com_section (bfd_get_section (sym)))	{	  bfd_vma size;	  sym->section = bss_sec;	  size = sym->value;	  sym->value = bss_sec->_raw_size;	  bss_sec->_raw_size += size;	  align = 1 << bss_sec->alignment_power;	  bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);	  sym->flags |= BSF_EXPORT | BSF_GLOBAL;	}      else if (bfd_get_section (sym)->output_section != NULL)	{	  /* Move the symbol into the output section.  */	  sym->value += bfd_get_section (sym)->output_offset;	  sym->section = bfd_get_section (sym)->output_section;	  /* This is no longer a section symbol.  */	  sym->flags &=~ BSF_SECTION_SYM;	}      /* Force _edata and _end to be defined.  This would normally be	 done by the linker, but the manipulation of the common	 symbols will confuse it.  */      if ((sym->flags & BSF_DEBUGGING) == 0	  && bfd_asymbol_name (sym)[0] == '_'	  && bfd_is_und_section (bfd_get_section (sym)))	{	  if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)	    {	      sym->section = bss_sec;	      sym->value = 0;	    }	  if (strcmp (bfd_asymbol_name (sym), "_end") == 0)	    {	      sym->section = bss_sec;	      endsym = sym;	    }#ifdef NLMCONV_POWERPC	  /* For PowerPC NetWare, we define __GOT0.  This is the start	     of the .got section.  */	  if (bfd_get_arch (inbfd) == bfd_arch_powerpc	      && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)	    {	      asection *got_sec;	      got_sec = bfd_get_section_by_name (inbfd, ".got");	      assert (got_sec != (asection *) NULL);	      sym->value = got_sec->output_offset;	      sym->section = got_sec->output_section;	    }#endif 	}      /* If this is a global symbol, check the export list.  */      if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)	{	  register struct string_list *l;	  int found_simple;	  /* Unfortunately, a symbol can appear multiple times on the	     export list, with and without prefixes.  */	  found_simple = 0;	  for (l = export_symbols; l != NULL; l = l->next)	    {	      if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)		found_simple = 1;	      else		{		  char *zbase;		  zbase = strchr (l->string, '@');		  if (zbase != NULL		      && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)		    {		      /* We must add a symbol with this prefix.  */		      if (newsymcount >= newsymalloc)			{			  newsymalloc += 10;			  newsyms = ((asymbol **)				     xrealloc ((PTR) newsyms,					       (newsymalloc						* sizeof (asymbol *))));			}		      newsyms[newsymcount] =			(asymbol *) xmalloc (sizeof (asymbol));		      *newsyms[newsymcount] = *sym;		      newsyms[newsymcount]->name = l->string;		      ++newsymcount;		    }		}	    }	  if (! found_simple)	    {	      /* The unmodified symbol is actually not exported at		 all.  */	      sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);	      sym->flags |= BSF_LOCAL;	    }	}      /* If it's an undefined symbol, see if it's on the import list.	 Change the prefix if necessary.  */      if (bfd_is_und_section (bfd_get_section (sym)))	{	  register struct string_list *l;	  for (l = import_symbols; l != NULL; l = l->next)	    {	      if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)		break;	      else		{		  char *zbase;		  zbase = strchr (l->string, '@');		  if (zbase != NULL		      && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)		    {		      sym->name = l->string;		      break;		    }		}	    }	  if (l == NULL)	    fprintf (stderr,		     "%s: warning: symbol %s imported but not in import list\n",		     program_name, bfd_asymbol_name (sym));	}	      /* See if it's one of the special named symbols.  */      if ((sym->flags & BSF_DEBUGGING) == 0)	{	  bfd_vma val;	  /* FIXME: If these symbols are not in the .text section, we	     add the .text section size to the value.  This may not be	     correct for all targets.  I'm not sure how this should	     really be handled.  */	  if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)	    {	      val = bfd_asymbol_value (sym);	      if (bfd_get_section (sym) == data_sec		  && text_sec != (asection *) NULL)		val += bfd_section_size (outbfd, text_sec);	      if (! bfd_set_start_address (outbfd, val))		bfd_fatal ("set start address");	      gotstart = true;	    }	  if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)	    {	      val = bfd_asymbol_value (sym);	      if (bfd_get_section (sym) == data_sec		  && text_sec != (asection *) NULL)		val += bfd_section_size (outbfd, text_sec);	      nlm_fixed_header (outbfd)->exitProcedureOffset = val;	      gotexit = true;	    }	  if (check_procedure != NULL	      && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)	    {	      val = bfd_asymbol_value (sym);	      if (bfd_get_section (sym) == data_sec		  && text_sec != (asection *) NULL)		val += bfd_section_size (outbfd, text_sec);	      nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;	      gotcheck = true;	    }	}    }  if (endsym != NULL)    {      endsym->value = bfd_get_section_size_before_reloc (bss_sec);      /* FIXME: If any relocs referring to _end use inplace addends,	 then I think they need to be updated.  This is handled by	 i386_mangle_relocs.  Is it needed for any other object	 formats?  */    }  if (newsymcount == 0)    outsyms = symbols;  else    {      outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)				      * sizeof (asymbol *));      memcpy (outsyms, symbols, symcount * sizeof (asymbol *));      memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));      outsyms[symcount + newsymcount] = NULL;    }  bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);      if (! gotstart)    fprintf (stderr, "%s: warning: START procedure %s not defined\n",	     program_name, start_procedure);  if (! gotexit)    fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",	     program_name, exit_procedure);  if (check_procedure != NULL      && ! gotcheck)    fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",	     program_name, check_procedure);  /* Add additional sections required for the header information.  */  if (custom_file != NULL)    {      custom_data = fopen (custom_file, "r");      if (custom_data == NULL	  || fstat (fileno (custom_data), &st) < 0)	{	  fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,		   strerror (errno));	  custom_file = NULL;	}      else	{	  custom_size = st.st_size;	  custom_section = bfd_make_section (outbfd, ".nlmcustom");	  if (custom_section == NULL	      || ! bfd_set_section_size (outbfd, custom_section, custom_size)	      || ! bfd_set_section_flags (outbfd, custom_section,					  SEC_HAS_CONTENTS))	    bfd_fatal ("custom section");	}    }  if (help_file != NULL)    {      help_data = fopen (help_file, "r");      if (help_data == NULL	  || fstat (fileno (help_data), &st) < 0)	{	  fprintf (stderr, "%s:%s: %s\n", program_name, help_file,		   strerror (errno));	  help_file = NULL;	}      else	{	  help_size = st.st_size;	  help_section = bfd_make_section (outbfd, ".nlmhelp");	  if (help_section == NULL	      || ! bfd_set_section_size (outbfd, help_section, help_size)	      || ! bfd_set_section_flags (outbfd, help_section,					  SEC_HAS_CONTENTS))	    bfd_fatal ("help section");	  strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);	}    }  if (message_file != NULL)    {      message_data = fopen (message_file, "r");      if (message_data == NULL	  || fstat (fileno (message_data), &st) < 0)	{	  fprintf (stderr, "%s:%s: %s\n", program_name, message_file,		   strerror (errno));	  message_file = NULL;	}      else	{	  message_size = st.st_size;	  message_section = bfd_make_section (outbfd, ".nlmmessages");	  if (message_section == NULL	      || ! bfd_set_section_size (outbfd, message_section, message_size)	      || ! bfd_set_section_flags (outbfd, message_section,					  SEC_HAS_CONTENTS))	    bfd_fatal ("message section");	  strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);	}    }  if (modules != NULL)    {      struct string_list *l;      module_size = 0;      for (l = modules; l != NULL; l = l->next)	module_size += strlen (l->string) + 1;      module_section = bfd_make_section (outbfd, ".nlmmodules");      if (module_section == NULL	  || ! bfd_set_section_size (outbfd, module_section, module_size)	  || ! bfd_set_section_flags (outbfd, module_section,				      SEC_HAS_CONTENTS))	bfd_fatal ("module section");    }  if (rpc_file != NULL)    {      rpc_data = fopen (rpc_file, "r");      if (rpc_data == NULL	  || fstat (fileno (rpc_data), &st) < 0)	{	  fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,		   strerror (errno));	  rpc_file = NULL;	}      else	{	  rpc_size = st.st_size;	  rpc_section = bfd_make_section (outbfd, ".nlmrpc");	  if (rpc_section == NULL	      || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)	      || ! bfd_set_section_flags (outbfd, rpc_section,					  SEC_HAS_CONTENTS))	    bfd_fatal ("rpc section");	  strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);	}    }  if (sharelib_file != NULL)    {      sharedbfd = bfd_openr (sharelib_file, output_format);      if (sharedbfd == NULL	  || ! bfd_check_format (sharedbfd, bfd_object))	{	  fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,		   bfd_errmsg (bfd_get_error ()));	  sharelib_file = NULL;	}      else	{	  sharedhdr = *nlm_fixed_header (sharedbfd);	  bfd_close (sharedbfd);	  shared_data = fopen (sharelib_file, "r");	  if (shared_data == NULL	      || (fstat (fileno (shared_data), &st) < 0))	    {	      fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,		       strerror (errno));	      sharelib_file = NULL;	    }	  else	    {	      /* If we were clever, we could just copy out the		 sections of the shared library which we actually		 need.  However, we would have to figure out the sizes		 of the external and public information, and that can		 not be done without reading through them.  */	      if (sharedhdr.uninitializedDataSize > 0)		{		  /* There is no place to record this information.  */		  fprintf (stderr,			   "%s:%s: warning: shared libraries can not have uninitialized data\n",			   program_name, sharelib_file);		}	      shared_offset = st.st_size;	      if (shared_offset > sharedhdr.codeImageOffset)		shared_offset = sharedhdr.codeImageOffset;	      if (shared_offset > sharedhdr.dataImageOffset)		shared_offset = sharedhdr.dataImageOffset;	      if (shared_offset > sharedhdr.relocationFixupOffset)		shared_offset = sharedhdr.relocationFixupOffset;	      if (shared_offset > sharedhdr.externalReferencesOffset)		shared_offset = sharedhdr.externalReferencesOffset;	      if (shared_offset > sharedhdr.publicsOffset)		shared_offset = sharedhdr.publicsOffset;	      shared_size = st.st_size - shared_offset;	      shared_section = bfd_make_section (outbfd, ".nlmshared");	      if (shared_section == NULL		  || ! bfd_set_section_size (outbfd, shared_section,					     shared_size)		  || ! bfd_set_section_flags (outbfd, shared_section,					      SEC_HAS_CONTENTS))		bfd_fatal ("shared section");	      strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);	    }	}    }  /* Check whether a version was given.  */  if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)    fprintf (stderr, "%s: warning: No version number given\n",	     program_name);  /* At least for now, always create an extended header, because that     is what NLMLINK does.  */  strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);  strncpy (nlm_cygnus_ext_header (outbfd)->stamp, "CyGnUsEx", 8);  /* If the date was not given, force it in.  */  if (nlm_version_header (outbfd)->month == 0      && nlm_version_header (outbfd)->day == 0      && nlm_version_header (outbfd)->year == 0)    {      time_t now;      struct tm *ptm;      time (&now);      ptm = localtime (&now);      nlm_version_header (outbfd)->month = ptm->tm_mon + 1;      nlm_version_header (outbfd)->day = ptm->tm_mday;      nlm_version_header (outbfd)->year = ptm->tm_year + 1900;      strncpy (version_hdr->stamp, "VeRsIoN#", 8);    }#ifdef NLMCONV_POWERPC  /* Resolve the stubs we build for PowerPC NetWare.  */  if (bfd_get_arch (inbfd) == bfd_arch_powerpc)    powerpc_resolve_stubs (inbfd, outbfd);#endif  /* Copy over the sections.  */  bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);  /* Finish up the header information.  */  if (custom_file != NULL)    {      PTR data;      data = xmalloc (custom_size);      if (fread (data, 1, custom_size, custom_data) != custom_size)	fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,		 strerror (errno));      else	{	  if (! bfd_set_section_contents (outbfd, custom_section, data,					  (file_ptr) 0, custom_size))	    bfd_fatal ("custom section");	  nlm_fixed_header (outbfd)->customDataOffset =	    custom_section->filepos;	  nlm_fixed_header (outbfd)->customDataSize = custom_size;	}      free (data);    }  if (! debug_info)    {      /* As a special hack, the backend recognizes a debugInfoOffset	 of -1 to mean that it should not output any debugging	 information.  This can not be handling by fiddling with the	 symbol table because exported symbols appear in both the	 export information and the debugging information.  */      nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;    }  if (map_file != NULL)    fprintf (stderr,	     "%s: warning: MAP and FULLMAP are not supported; try ld -M\n",	     program_name);  if (help_file != NULL)    {      PTR data;      data = xmalloc (help_size);      if (fread (data, 1, help_size, help_data) != help_size)	fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,		 strerror (errno));      else	{	  if (! bfd_set_section_contents (outbfd, help_section, data,					  (file_ptr) 0, help_size))	    bfd_fatal ("help section");	  nlm_extended_header (outbfd)->helpFileOffset =	    help_section->filepos;	  nlm_extended_header (outbfd)->helpFileLength = help_size;	}      free (data);    }  if (message_file != NULL)    {      PTR data;      data = xmalloc (message_size);      if (fread (data, 1, message_size, message_data) != message_size)	fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,		 strerror (errno));      else	{	  if (! bfd_set_section_contents (outbfd, message_section, data,					  (file_ptr) 0, message_size))	    bfd_fatal ("message section");	  nlm_extended_header (outbfd)->messageFileOffset =	    message_section->filepos;	  nlm_extended_header (outbfd)->messageFileLength = message_size;	  /* FIXME: Are these offsets correct on all platforms?  Are	     they 32 bits on all platforms?  What endianness?  */	  nlm_extended_header (outbfd)->languageID =	    bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);	  nlm_extended_header (outbfd)->messageCount =	    bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);	}      free (data);    }  if (modules != NULL)    {      PTR data;      unsigned char *set;      struct string_list *l;      bfd_size_type c;      data = xmalloc (module_size);      c = 0;      set = (unsigned char *) data;      for (l = modules; l != NULL; l = l->next)	{	  *set = strlen (l->string);	  strncpy (set + 1, l->string, *set);	  set += *set + 1;	  ++c;	}      if (! bfd_set_section_contents (outbfd, module_section, data,				      (file_ptr) 0, module_size))	bfd_fatal ("module section");      nlm_fixed_header (outbfd)->moduleDependencyOffset =	module_section->filepos;      nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;    }  if (rpc_file != NULL)    {      PTR data;      data = xmalloc (rpc_size);      if (fread (data, 1, rpc_size, rpc_data) != rpc_size)	fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,		 strerror (errno));      else	{	  if (! bfd_set_section_contents (outbfd, rpc_section, data,					  (file_ptr) 0, rpc_size))	    bfd_fatal ("rpc section");	  nlm_extended_header (outbfd)->RPCDataOffset =	    rpc_section->filepos;	  nlm_extended_header (outbfd)->RPCDataLength = rpc_size;	}      free (data);    }  if (sharelib_file != NULL)    {      PTR data;      data = xmalloc (shared_size);      if (fseek (shared_data, shared_offset, SEEK_SET) != 0	  || fread (data, 1, shared_size, shared_data) != shared_size)	fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,		 strerror (errno));      else	{	  if (! bfd_set_section_contents (outbfd, shared_section, data,					  (file_ptr) 0, shared_size))	    bfd_fatal ("shared section");	}      nlm_extended_header (outbfd)->sharedCodeOffset =	sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;      nlm_extended_header (outbfd)->sharedCodeLength =	sharedhdr.codeImageSize;      nlm_extended_header (outbfd)->sharedDataOffset =	sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;      nlm_extended_header (outbfd)->sharedDataLength =	sharedhdr.dataImageSize;      nlm_extended_header (outbfd)->sharedRelocationFixupOffset =	(sharedhdr.relocationFixupOffset	 - shared_offset	 + shared_section->filepos);      nlm_extended_header (outbfd)->sharedRelocationFixupCount =	sharedhdr.numberOfRelocationFixups;      nlm_extended_header (outbfd)->sharedExternalReferenceOffset =	(sharedhdr.externalReferencesOffset	 - shared_offset	 + shared_section->filepos);      nlm_extended_header (outbfd)->sharedExternalReferenceCount =	sharedhdr.numberOfExternalReferences;      nlm_extended_header (outbfd)->sharedPublicsOffset =	sharedhdr.publicsOffset - shared_offset + shared_section->filepos;      nlm_extended_header (outbfd)->sharedPublicsCount =	sharedhdr.numberOfPublics;      nlm_extended_header (outbfd)->sharedDebugRecordOffset =	sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;      nlm_extended_header (outbfd)->sharedDebugRecordCount =	sharedhdr.numberOfDebugRecords;      nlm_extended_header (outbfd)->SharedInitializationOffset =	sharedhdr.codeStartOffset;      nlm_extended_header (outbfd)->SharedExitProcedureOffset =	sharedhdr.exitProcedureOffset;      free (data);    }  len = strlen (output_file);  if (len > NLM_MODULE_NAME_SIZE - 2)    len = NLM_MODULE_NAME_SIZE - 2;  nlm_fixed_header (outbfd)->moduleName[0] = len;  strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,	   NLM_MODULE_NAME_SIZE - 2);  nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';  for (modname = nlm_fixed_header (outbfd)->moduleName;       *modname != '\0';       modname++)    if (islower (*modname))      *modname = toupper (*modname);  strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",	   NLM_OLD_THREAD_NAME_LENGTH);  nlm_cygnus_ext_header (outbfd)->offset = secsec->filepos;  nlm_cygnus_ext_header (outbfd)->length = bfd_section_size (outbfd, secsec);  if (! bfd_close (outbfd))    bfd_fatal (output_file);  if (! bfd_close (inbfd))    bfd_fatal (input_file);  if (unlink_on_exit != NULL)    unlink (unlink_on_exit);  return 0;}