Home | History | Annotate | Download | only in bfd
      1 /* NLM (NetWare Loadable Module) executable support for BFD.
      2    Copyright (C) 1993-2014 Free Software Foundation, Inc.
      3 
      4    Written by Fred Fish @ Cygnus Support, using ELF support as the
      5    template.
      6 
      7    This file is part of BFD, the Binary File Descriptor library.
      8 
      9    This program is free software; you can redistribute it and/or modify
     10    it under the terms of the GNU General Public License as published by
     11    the Free Software Foundation; either version 3 of the License, or
     12    (at your option) any later version.
     13 
     14    This program is distributed in the hope that it will be useful,
     15    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17    GNU General Public License for more details.
     18 
     19    You should have received a copy of the GNU General Public License
     20    along with this program; if not, write to the Free Software
     21    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     22    MA 02110-1301, USA.  */
     23 
     24 #include "sysdep.h"
     25 #include "bfd.h"
     26 #include "libbfd.h"
     27 #include "libnlm.h"
     28 
     29 /* The functions in this file do not use the names they appear to use.
     30    This file is actually compiled multiple times, once for each size
     31    of NLM target we are using.  At each size we use a different name,
     32    constructed by the macro nlmNAME.  For example, the function which
     33    is named nlm_symbol_type below is actually named nlm32_symbol_type
     34    in the final executable.  */
     35 
     36 #define Nlm_External_Fixed_Header	NlmNAME (External_Fixed_Header)
     37 #define Nlm_External_Version_Header	NlmNAME (External_Version_Header)
     38 #define Nlm_External_Copyright_Header	NlmNAME (External_Copyright_Header)
     39 #define Nlm_External_Extended_Header	NlmNAME (External_Extended_Header)
     40 #define Nlm_External_Custom_Header	NlmNAME (External_Custom_Header)
     41 #define Nlm_External_Cygnus_Ext_Header	NlmNAME (External_Cygnus_Ext_Header)
     42 
     43 #define nlm_symbol_type			nlmNAME (symbol_type)
     44 #define nlm_get_symtab_upper_bound	nlmNAME (get_symtab_upper_bound)
     45 #define nlm_canonicalize_symtab		nlmNAME (canonicalize_symtab)
     46 #define nlm_make_empty_symbol		nlmNAME (make_empty_symbol)
     47 #define nlm_print_symbol		nlmNAME (print_symbol)
     48 #define nlm_get_symbol_info		nlmNAME (get_symbol_info)
     49 #define nlm_get_reloc_upper_bound	nlmNAME (get_reloc_upper_bound)
     50 #define nlm_canonicalize_reloc		nlmNAME (canonicalize_reloc)
     51 #define nlm_object_p			nlmNAME (object_p)
     52 #define nlm_set_section_contents	nlmNAME (set_section_contents)
     53 #define nlm_write_object_contents	nlmNAME (write_object_contents)
     54 
     55 #define nlm_swap_fixed_header_in(abfd,src,dst) \
     56   (nlm_swap_fixed_header_in_func (abfd)) (abfd, src, dst)
     57 #define nlm_swap_fixed_header_out(abfd,src,dst) \
     58   (nlm_swap_fixed_header_out_func (abfd)) (abfd, src, dst)
     59 
     60 /* Should perhaps use put_offset, put_word, etc.  For now, the two versions
     61    can be handled by explicitly specifying 32 bits or "the long type".  */
     62 #if ARCH_SIZE == 64
     63 #define put_word	H_PUT_64
     64 #define get_word	H_GET_64
     65 #endif
     66 #if ARCH_SIZE == 32
     67 #define put_word	H_PUT_32
     68 #define get_word	H_GET_32
     69 #endif
     70 
     71 /* Read and swap in the variable length header.  All the fields must
     72    exist in the NLM, and must exist in the order they are read here.  */
     73 
     74 static bfd_boolean
     75 nlm_swap_variable_header_in (bfd *abfd)
     76 {
     77   unsigned char temp[NLM_TARGET_LONG_SIZE];
     78   bfd_size_type amt;
     79 
     80   /* Read the description length and text members.  */
     81   amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
     82   if (bfd_bread ((void *) &nlm_variable_header (abfd)->descriptionLength,
     83 		amt, abfd) != amt)
     84     return FALSE;
     85   amt = nlm_variable_header (abfd)->descriptionLength + 1;
     86   if (bfd_bread ((void *) nlm_variable_header (abfd)->descriptionText,
     87 		amt, abfd) != amt)
     88     return FALSE;
     89 
     90   /* Read and convert the stackSize field.  */
     91   amt = sizeof (temp);
     92   if (bfd_bread ((void *) temp, amt, abfd) != amt)
     93     return FALSE;
     94   nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);
     95 
     96   /* Read and convert the reserved field.  */
     97   amt = sizeof (temp);
     98   if (bfd_bread ((void *) temp, amt, abfd) != amt)
     99     return FALSE;
    100   nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);
    101 
    102   /* Read the oldThreadName field.  This field is a fixed length string.  */
    103   amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
    104   if (bfd_bread ((void *) nlm_variable_header (abfd)->oldThreadName,
    105 		amt, abfd) != amt)
    106     return FALSE;
    107 
    108   /* Read the screen name length and text members.  */
    109   amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
    110   if (bfd_bread ((void *) & nlm_variable_header (abfd)->screenNameLength,
    111 		amt, abfd) != amt)
    112     return FALSE;
    113   amt = nlm_variable_header (abfd)->screenNameLength + 1;
    114   if (bfd_bread ((void *) nlm_variable_header (abfd)->screenName,
    115 		amt, abfd) != amt)
    116     return FALSE;
    117 
    118   /* Read the thread name length and text members.  */
    119   amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
    120   if (bfd_bread ((void *) & nlm_variable_header (abfd)->threadNameLength,
    121 		amt, abfd) != amt)
    122     return FALSE;
    123   amt = nlm_variable_header (abfd)->threadNameLength + 1;
    124   if (bfd_bread ((void *) nlm_variable_header (abfd)->threadName,
    125 		amt, abfd) != amt)
    126     return FALSE;
    127   return TRUE;
    128 }
    129 
    130 /* Add a section to the bfd.  */
    131 
    132 static bfd_boolean
    133 add_bfd_section (bfd *abfd,
    134 		 char *name,
    135 		 file_ptr offset,
    136 		 bfd_size_type size,
    137 		 flagword flags)
    138 {
    139   asection *newsect;
    140 
    141   newsect = bfd_make_section_with_flags (abfd, name, flags);
    142   if (newsect == NULL)
    143     return FALSE;
    144 
    145   newsect->vma = 0;		/* NLM's are relocatable.  */
    146   newsect->size = size;
    147   newsect->filepos = offset;
    148   newsect->alignment_power = bfd_log2 ((bfd_vma) 0);	/* FIXME */
    149 
    150   return TRUE;
    151 }
    152 
    153 /* Read and swap in the contents of all the auxiliary headers.  Because of
    154    the braindead design, we have to do strcmps on strings of indeterminate
    155    length to figure out what each auxiliary header is.  Even worse, we have
    156    no way of knowing how many auxiliary headers there are or where the end
    157    of the auxiliary headers are, except by finding something that doesn't
    158    look like a known auxiliary header.  This means that the first new type
    159    of auxiliary header added will break all existing tools that don't
    160    recognize it.  */
    161 
    162 static bfd_boolean
    163 nlm_swap_auxiliary_headers_in (bfd *abfd)
    164 {
    165   char tempstr[16];
    166   file_ptr position;
    167   bfd_size_type amt;
    168 
    169   for (;;)
    170     {
    171       position = bfd_tell (abfd);
    172       amt = sizeof (tempstr);
    173       if (bfd_bread ((void *) tempstr, amt, abfd) != amt)
    174 	return FALSE;
    175       if (bfd_seek (abfd, position, SEEK_SET) != 0)
    176 	return FALSE;
    177       if (CONST_STRNEQ (tempstr, "VeRsIoN#"))
    178 	{
    179 	  Nlm_External_Version_Header thdr;
    180 
    181 	  amt = sizeof (thdr);
    182 	  if (bfd_bread ((void *) &thdr, amt, abfd) != amt)
    183 	    return FALSE;
    184 	  memcpy (nlm_version_header (abfd)->stamp, thdr.stamp,
    185 		  sizeof (thdr.stamp));
    186 	  nlm_version_header (abfd)->majorVersion =
    187 	    get_word (abfd, (bfd_byte *) thdr.majorVersion);
    188 	  nlm_version_header (abfd)->minorVersion =
    189 	    get_word (abfd, (bfd_byte *) thdr.minorVersion);
    190 	  nlm_version_header (abfd)->revision =
    191 	    get_word (abfd, (bfd_byte *) thdr.revision);
    192 	  nlm_version_header (abfd)->year =
    193 	    get_word (abfd, (bfd_byte *) thdr.year);
    194 	  nlm_version_header (abfd)->month =
    195 	    get_word (abfd, (bfd_byte *) thdr.month);
    196 	  nlm_version_header (abfd)->day =
    197 	    get_word (abfd, (bfd_byte *) thdr.day);
    198 	}
    199       else if (CONST_STRNEQ (tempstr, "MeSsAgEs"))
    200 	{
    201 	  Nlm_External_Extended_Header thdr;
    202 
    203 	  amt = sizeof (thdr);
    204 	  if (bfd_bread ((void *) &thdr, amt, abfd) != amt)
    205 	    return FALSE;
    206 	  memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp,
    207 		  sizeof (thdr.stamp));
    208 	  nlm_extended_header (abfd)->languageID =
    209 	    get_word (abfd, (bfd_byte *) thdr.languageID);
    210 	  nlm_extended_header (abfd)->messageFileOffset =
    211 	    get_word (abfd, (bfd_byte *) thdr.messageFileOffset);
    212 	  nlm_extended_header (abfd)->messageFileLength =
    213 	    get_word (abfd, (bfd_byte *) thdr.messageFileLength);
    214 	  nlm_extended_header (abfd)->messageCount =
    215 	    get_word (abfd, (bfd_byte *) thdr.messageCount);
    216 	  nlm_extended_header (abfd)->helpFileOffset =
    217 	    get_word (abfd, (bfd_byte *) thdr.helpFileOffset);
    218 	  nlm_extended_header (abfd)->helpFileLength =
    219 	    get_word (abfd, (bfd_byte *) thdr.helpFileLength);
    220 	  nlm_extended_header (abfd)->RPCDataOffset =
    221 	    get_word (abfd, (bfd_byte *) thdr.RPCDataOffset);
    222 	  nlm_extended_header (abfd)->RPCDataLength =
    223 	    get_word (abfd, (bfd_byte *) thdr.RPCDataLength);
    224 	  nlm_extended_header (abfd)->sharedCodeOffset =
    225 	    get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset);
    226 	  nlm_extended_header (abfd)->sharedCodeLength =
    227 	    get_word (abfd, (bfd_byte *) thdr.sharedCodeLength);
    228 	  nlm_extended_header (abfd)->sharedDataOffset =
    229 	    get_word (abfd, (bfd_byte *) thdr.sharedDataOffset);
    230 	  nlm_extended_header (abfd)->sharedDataLength =
    231 	    get_word (abfd, (bfd_byte *) thdr.sharedDataLength);
    232 	  nlm_extended_header (abfd)->sharedRelocationFixupOffset =
    233 	    get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset);
    234 	  nlm_extended_header (abfd)->sharedRelocationFixupCount =
    235 	    get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount);
    236 	  nlm_extended_header (abfd)->sharedExternalReferenceOffset =
    237 	    get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset);
    238 	  nlm_extended_header (abfd)->sharedExternalReferenceCount =
    239 	    get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount);
    240 	  nlm_extended_header (abfd)->sharedPublicsOffset =
    241 	    get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
    242 	  nlm_extended_header (abfd)->sharedPublicsCount =
    243 	    get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
    244 	  nlm_extended_header (abfd)->sharedDebugRecordOffset =
    245 	    get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordOffset);
    246 	  nlm_extended_header (abfd)->sharedDebugRecordCount =
    247 	    get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordCount);
    248 	  nlm_extended_header (abfd)->SharedInitializationOffset =
    249 	    get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
    250 	  nlm_extended_header (abfd)->SharedExitProcedureOffset =
    251 	    get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset);
    252 	  nlm_extended_header (abfd)->productID =
    253 	    get_word (abfd, (bfd_byte *) thdr.productID);
    254 	  nlm_extended_header (abfd)->reserved0 =
    255 	    get_word (abfd, (bfd_byte *) thdr.reserved0);
    256 	  nlm_extended_header (abfd)->reserved1 =
    257 	    get_word (abfd, (bfd_byte *) thdr.reserved1);
    258 	  nlm_extended_header (abfd)->reserved2 =
    259 	    get_word (abfd, (bfd_byte *) thdr.reserved2);
    260 	  nlm_extended_header (abfd)->reserved3 =
    261 	    get_word (abfd, (bfd_byte *) thdr.reserved3);
    262 	  nlm_extended_header (abfd)->reserved4 =
    263 	    get_word (abfd, (bfd_byte *) thdr.reserved4);
    264 	  nlm_extended_header (abfd)->reserved5 =
    265 	    get_word (abfd, (bfd_byte *) thdr.reserved5);
    266 	}
    267       else if (CONST_STRNEQ (tempstr, "CoPyRiGhT="))
    268 	{
    269 	  amt = sizeof (nlm_copyright_header (abfd)->stamp);
    270 	  if (bfd_bread ((void *) nlm_copyright_header (abfd)->stamp,
    271 			amt, abfd) != amt)
    272 	    return FALSE;
    273 	  if (bfd_bread ((void *) &(nlm_copyright_header (abfd)
    274 				->copyrightMessageLength),
    275 			(bfd_size_type) 1, abfd) != 1)
    276 	    return FALSE;
    277 	  /* The copyright message is a variable length string.  */
    278 	  amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
    279 	  if (bfd_bread ((void *) nlm_copyright_header (abfd)->copyrightMessage,
    280 			amt, abfd) != amt)
    281 	    return FALSE;
    282 	}
    283       else if (CONST_STRNEQ (tempstr, "CuStHeAd"))
    284 	{
    285 	  Nlm_External_Custom_Header thdr;
    286 	  bfd_size_type hdrLength;
    287 	  file_ptr dataOffset;
    288 	  bfd_size_type dataLength;
    289 	  char dataStamp[8];
    290 	  void * hdr;
    291 
    292 	  /* Read the stamp ("CuStHeAd").  */
    293 	  amt = sizeof (thdr.stamp);
    294 	  if (bfd_bread ((void *) thdr.stamp, amt, abfd) != amt)
    295 	    return FALSE;
    296 	  /* Read the length of this custom header.  */
    297 	  amt = sizeof (thdr.length);
    298 	  if (bfd_bread ((void *) thdr.length, amt, abfd) != amt)
    299 	    return FALSE;
    300 	  hdrLength = get_word (abfd, (bfd_byte *) thdr.length);
    301 	  /* Read further fields if we have them.  */
    302 	  if (hdrLength < NLM_TARGET_LONG_SIZE)
    303 	    dataOffset = 0;
    304 	  else
    305 	    {
    306 	      amt = sizeof (thdr.dataOffset);
    307 	      if (bfd_bread ((void *) thdr.dataOffset, amt, abfd) != amt)
    308 		return FALSE;
    309 	      dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset);
    310 	    }
    311 	  if (hdrLength < 2 * NLM_TARGET_LONG_SIZE)
    312 	    dataLength = 0;
    313 	  else
    314 	    {
    315 	      amt = sizeof (thdr.dataLength);
    316 	      if (bfd_bread ((void *) thdr.dataLength, amt, abfd) != amt)
    317 		return FALSE;
    318 	      dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength);
    319 	    }
    320 	  if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8)
    321 	    memset (dataStamp, 0, sizeof (dataStamp));
    322 	  else
    323 	    {
    324 	      amt = sizeof (dataStamp);
    325 	      if (bfd_bread ((void *) dataStamp, amt, abfd) != amt)
    326 		return FALSE;
    327 	    }
    328 
    329 	  /* Read the rest of the header, if any.  */
    330 	  if (hdrLength <= 2 * NLM_TARGET_LONG_SIZE + 8)
    331 	    {
    332 	      hdr = NULL;
    333 	      hdrLength = 0;
    334 	    }
    335 	  else
    336 	    {
    337 	      hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8;
    338 	      hdr = bfd_alloc (abfd, hdrLength);
    339 	      if (hdr == NULL)
    340 		return FALSE;
    341 	      if (bfd_bread (hdr, hdrLength, abfd) != hdrLength)
    342 		return FALSE;
    343 	    }
    344 
    345 	  /* If we have found a Cygnus header, process it.  Otherwise,
    346 	     just save the associated data without trying to interpret
    347 	     it.  */
    348 	  if (CONST_STRNEQ (dataStamp, "CyGnUsEx"))
    349 	    {
    350 	      file_ptr pos;
    351 	      bfd_byte *contents;
    352 	      bfd_byte *p, *pend;
    353 
    354 	      BFD_ASSERT (hdrLength == 0 && hdr == NULL);
    355 
    356 	      pos = bfd_tell (abfd);
    357 	      if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0)
    358 		return FALSE;
    359 	      contents = bfd_alloc (abfd, dataLength);
    360 	      if (contents == NULL)
    361 		return FALSE;
    362 	      if (bfd_bread (contents, dataLength, abfd) != dataLength)
    363 		return FALSE;
    364 	      if (bfd_seek (abfd, pos, SEEK_SET) != 0)
    365 		return FALSE;
    366 
    367 	      LITMEMCPY (nlm_cygnus_ext_header (abfd), "CyGnUsEx");
    368 	      nlm_cygnus_ext_header (abfd)->offset = dataOffset;
    369 	      nlm_cygnus_ext_header (abfd)->length = dataLength;
    370 
    371 	      /* This data this header points to provides a list of
    372 		 the sections which were in the original object file
    373 		 which was converted to become an NLM.  We locate
    374 		 those sections and add them to the BFD.  Note that
    375 		 this is likely to create a second .text, .data and
    376 		 .bss section; retrieving the sections by name will
    377 		 get the actual NLM sections, which is what we want to
    378 		 happen.  The sections from the original file, which
    379 		 may be subsets of the NLM section, can only be found
    380 		 using bfd_map_over_sections.  */
    381 	      p = contents;
    382 	      pend = p + dataLength;
    383 	      while (p < pend)
    384 		{
    385 		  char *name;
    386 		  size_t l;
    387 		  file_ptr filepos;
    388 		  bfd_size_type size;
    389 		  asection *newsec;
    390 
    391 		  /* The format of this information is
    392 		     null terminated section name
    393 		     zeroes to adjust to 4 byte boundary
    394 		     4 byte section data file pointer
    395 		     4 byte section size.  */
    396 
    397 		  name = (char *) p;
    398 		  l = strlen (name) + 1;
    399 		  l = (l + 3) &~ (size_t) 3;
    400 		  p += l;
    401 		  filepos = H_GET_32 (abfd, p);
    402 		  p += 4;
    403 		  size = H_GET_32 (abfd, p);
    404 		  p += 4;
    405 
    406 		  newsec = bfd_make_section_anyway (abfd, name);
    407 		  if (newsec == NULL)
    408 		    return FALSE;
    409 		  newsec->size = size;
    410 		  if (filepos != 0)
    411 		    {
    412 		      newsec->filepos = filepos;
    413 		      newsec->flags |= SEC_HAS_CONTENTS;
    414 		    }
    415 		}
    416 	    }
    417 	  else
    418 	    {
    419 	      memcpy (nlm_custom_header (abfd)->stamp, thdr.stamp,
    420 		      sizeof (thdr.stamp));
    421 	      nlm_custom_header (abfd)->hdrLength = hdrLength;
    422 	      nlm_custom_header (abfd)->dataOffset = dataOffset;
    423 	      nlm_custom_header (abfd)->dataLength = dataLength;
    424 	      memcpy (nlm_custom_header (abfd)->dataStamp, dataStamp,
    425 		      sizeof (dataStamp));
    426 	      nlm_custom_header (abfd)->hdr = hdr;
    427 	    }
    428 	}
    429       else
    430 	break;
    431     }
    432   return TRUE;
    433 }
    434 
    435 const bfd_target *
    436 nlm_object_p (bfd *abfd)
    437 {
    438   struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd);
    439   bfd_boolean (*backend_object_p) (bfd *);
    440   void * x_fxdhdr = NULL;
    441   Nlm_Internal_Fixed_Header *i_fxdhdrp;
    442   struct nlm_obj_tdata *new_tdata = NULL;
    443   const char *signature;
    444   enum bfd_architecture arch;
    445   bfd_size_type amt;
    446 
    447   /* Some NLM formats have a prefix before the standard NLM fixed
    448      header.  */
    449   backend_object_p = nlm_backend_object_p_func (abfd);
    450   if (backend_object_p)
    451     {
    452       if (!(*backend_object_p) (abfd))
    453 	goto got_wrong_format_error;
    454     }
    455 
    456   /* Read in the fixed length portion of the NLM header in external format.  */
    457   amt = nlm_fixed_header_size (abfd);
    458   x_fxdhdr = bfd_malloc (amt);
    459   if (x_fxdhdr == NULL)
    460     goto got_no_match;
    461 
    462   if (bfd_bread ((void *) x_fxdhdr, amt, abfd) != amt)
    463     {
    464       if (bfd_get_error () != bfd_error_system_call)
    465 	goto got_wrong_format_error;
    466       else
    467 	goto got_no_match;
    468     }
    469 
    470   /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
    471      the tdata pointer in the bfd.  */
    472   amt = sizeof (struct nlm_obj_tdata);
    473   new_tdata = bfd_zalloc (abfd, amt);
    474   if (new_tdata == NULL)
    475     goto got_no_match;
    476 
    477   nlm_tdata (abfd) = new_tdata;
    478 
    479   i_fxdhdrp = nlm_fixed_header (abfd);
    480   nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp);
    481   free (x_fxdhdr);
    482   x_fxdhdr = NULL;
    483 
    484   /* Check to see if we have an NLM file for this backend by matching
    485      the NLM signature.  */
    486   signature = nlm_signature (abfd);
    487   if (signature != NULL
    488       && *signature != '\0'
    489       && strncmp ((char *) i_fxdhdrp->signature, signature,
    490 		  NLM_SIGNATURE_SIZE) != 0)
    491     goto got_wrong_format_error;
    492 
    493   /* There's no supported way to discover the endianness of an NLM, so test for
    494      a sane version number after doing byte swapping appropriate for this
    495      XVEC.  (Hack alert!)  */
    496   if (i_fxdhdrp->version > 0xFFFF)
    497     goto got_wrong_format_error;
    498 
    499   /* There's no supported way to check for 32 bit versus 64 bit addresses,
    500      so ignore this distinction for now.  (FIXME) */
    501   /* Swap in the rest of the required header.  */
    502   if (!nlm_swap_variable_header_in (abfd))
    503     {
    504       if (bfd_get_error () != bfd_error_system_call)
    505 	goto got_wrong_format_error;
    506       else
    507 	goto got_no_match;
    508     }
    509 
    510   /* Add the sections supplied by all NLM's, and then read in the
    511      auxiliary headers.  Reading the auxiliary headers may create
    512      additional sections described in the cygnus_ext header.
    513      From this point on we assume that we have an NLM, and do not
    514      treat errors as indicating the wrong format.  */
    515   if (!add_bfd_section (abfd, NLM_CODE_NAME,
    516 			i_fxdhdrp->codeImageOffset,
    517 			i_fxdhdrp->codeImageSize,
    518 			(SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
    519 			 | SEC_RELOC))
    520       || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
    521 			   i_fxdhdrp->dataImageOffset,
    522 			   i_fxdhdrp->dataImageSize,
    523 			   (SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
    524 			    | SEC_RELOC))
    525       || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
    526 			   (file_ptr) 0,
    527 			   i_fxdhdrp->uninitializedDataSize,
    528 			   SEC_ALLOC))
    529     goto got_no_match;
    530 
    531   if (!nlm_swap_auxiliary_headers_in (abfd))
    532     goto got_no_match;
    533 
    534   if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
    535       || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
    536     abfd->flags |= HAS_RELOC;
    537   if (nlm_fixed_header (abfd)->numberOfPublics != 0
    538       || nlm_fixed_header (abfd)->numberOfDebugRecords != 0
    539       || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
    540     abfd->flags |= HAS_SYMS;
    541 
    542   arch = nlm_architecture (abfd);
    543   if (arch != bfd_arch_unknown)
    544     bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
    545 
    546   abfd->flags |= EXEC_P;
    547   bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset;
    548 
    549   return abfd->xvec;
    550 
    551 got_wrong_format_error:
    552   bfd_set_error (bfd_error_wrong_format);
    553 got_no_match:
    554   nlm_tdata (abfd) = preserved_tdata;
    555   if (new_tdata != NULL)
    556     bfd_release (abfd, new_tdata);
    557   if (x_fxdhdr != NULL)
    558     free (x_fxdhdr);
    559 
    560   return NULL;
    561 }
    562 
    563 /* Swap and write out the variable length header.  All the fields must
    564    exist in the NLM, and must exist in this order.  */
    565 
    566 static bfd_boolean
    567 nlm_swap_variable_header_out (bfd *abfd)
    568 {
    569   bfd_byte temp[NLM_TARGET_LONG_SIZE];
    570   bfd_size_type amt;
    571 
    572   /* Write the description length and text members.  */
    573   amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
    574   if (bfd_bwrite (& nlm_variable_header (abfd)->descriptionLength, amt,
    575 		  abfd) != amt)
    576     return FALSE;
    577   amt = nlm_variable_header (abfd)->descriptionLength + 1;
    578   if (bfd_bwrite ((void *) nlm_variable_header (abfd)->descriptionText, amt,
    579 		  abfd) != amt)
    580     return FALSE;
    581 
    582   /* Convert and write the stackSize field.  */
    583   put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize, temp);
    584   amt = sizeof (temp);
    585   if (bfd_bwrite (temp, amt, abfd) != amt)
    586     return FALSE;
    587 
    588   /* Convert and write the reserved field.  */
    589   put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved, temp);
    590   amt = sizeof (temp);
    591   if (bfd_bwrite (temp, amt, abfd) != amt)
    592     return FALSE;
    593 
    594   /* Write the oldThreadName field.  This field is a fixed length string.  */
    595   amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
    596   if (bfd_bwrite (nlm_variable_header (abfd)->oldThreadName, amt,
    597 		  abfd) != amt)
    598     return FALSE;
    599 
    600   /* Write the screen name length and text members.  */
    601   amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
    602   if (bfd_bwrite (& nlm_variable_header (abfd)->screenNameLength, amt,
    603 		 abfd) != amt)
    604     return FALSE;
    605   amt = nlm_variable_header (abfd)->screenNameLength + 1;
    606   if (bfd_bwrite (nlm_variable_header (abfd)->screenName, amt, abfd) != amt)
    607     return FALSE;
    608 
    609   /* Write the thread name length and text members.  */
    610   amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
    611   if (bfd_bwrite (& nlm_variable_header (abfd)->threadNameLength, amt,
    612 		 abfd) != amt)
    613     return FALSE;
    614   amt = nlm_variable_header (abfd)->threadNameLength + 1;
    615   if (bfd_bwrite (nlm_variable_header (abfd)->threadName, amt, abfd) != amt)
    616     return FALSE;
    617   return TRUE;
    618 }
    619 
    620 /* Return whether there is a non-zero byte in a memory block.  */
    621 
    622 static bfd_boolean
    623 find_nonzero (void * buf, size_t size)
    624 {
    625   char *p = (char *) buf;
    626 
    627   while (size-- != 0)
    628     if (*p++ != 0)
    629       return TRUE;
    630   return FALSE;
    631 }
    632 
    633 /* Swap out the contents of the auxiliary headers.  We create those
    634    auxiliary headers which have been set non-zero.  We do not require
    635    the caller to set up the stamp fields.  */
    636 
    637 static bfd_boolean
    638 nlm_swap_auxiliary_headers_out (bfd *abfd)
    639 {
    640   bfd_size_type amt;
    641 
    642   /* Write out the version header if there is one.  */
    643   if (find_nonzero (nlm_version_header (abfd),
    644 		    sizeof (Nlm_Internal_Version_Header)))
    645     {
    646       Nlm_External_Version_Header thdr;
    647 
    648       LITMEMCPY (thdr.stamp, "VeRsIoN#");
    649       put_word (abfd, (bfd_vma) nlm_version_header (abfd)->majorVersion,
    650 		(bfd_byte *) thdr.majorVersion);
    651       put_word (abfd, (bfd_vma) nlm_version_header (abfd)->minorVersion,
    652 		(bfd_byte *) thdr.minorVersion);
    653       put_word (abfd, (bfd_vma) nlm_version_header (abfd)->revision,
    654 		(bfd_byte *) thdr.revision);
    655       put_word (abfd, (bfd_vma) nlm_version_header (abfd)->year,
    656 		(bfd_byte *) thdr.year);
    657       put_word (abfd, (bfd_vma) nlm_version_header (abfd)->month,
    658 		(bfd_byte *) thdr.month);
    659       put_word (abfd, (bfd_vma) nlm_version_header (abfd)->day,
    660 		(bfd_byte *) thdr.day);
    661       if (bfd_bwrite ((void *) &thdr, (bfd_size_type) sizeof (thdr), abfd)
    662 	  != sizeof (thdr))
    663 	return FALSE;
    664     }
    665 
    666   /* Note - the CoPyRiGhT tag is emitted before the MeSsAgEs
    667      tag in order to make the NW4.x and NW5.x loaders happy.  */
    668 
    669   /* Write out the copyright header if there is one.  */
    670   if (find_nonzero (nlm_copyright_header (abfd),
    671 		    sizeof (Nlm_Internal_Copyright_Header)))
    672     {
    673       Nlm_External_Copyright_Header thdr;
    674 
    675       LITMEMCPY (thdr.stamp, "CoPyRiGhT=");
    676       amt = sizeof (thdr.stamp);
    677       if (bfd_bwrite ((void *) thdr.stamp, amt, abfd) != amt)
    678 	return FALSE;
    679       thdr.copyrightMessageLength[0] =
    680 	nlm_copyright_header (abfd)->copyrightMessageLength;
    681       amt = 1;
    682       if (bfd_bwrite ((void *) thdr.copyrightMessageLength, amt, abfd) != amt)
    683 	return FALSE;
    684       /* The copyright message is a variable length string.  */
    685       amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
    686       if (bfd_bwrite ((void *) nlm_copyright_header (abfd)->copyrightMessage,
    687 		     amt, abfd) != amt)
    688 	return FALSE;
    689     }
    690 
    691   /* Write out the extended header if there is one.  */
    692   if (find_nonzero (nlm_extended_header (abfd),
    693 		    sizeof (Nlm_Internal_Extended_Header)))
    694     {
    695       Nlm_External_Extended_Header thdr;
    696 
    697       LITMEMCPY (thdr.stamp, "MeSsAgEs");
    698       put_word (abfd,
    699 		(bfd_vma) nlm_extended_header (abfd)->languageID,
    700 		(bfd_byte *) thdr.languageID);
    701       put_word (abfd,
    702 		(bfd_vma) nlm_extended_header (abfd)->messageFileOffset,
    703 		(bfd_byte *) thdr.messageFileOffset);
    704       put_word (abfd,
    705 		(bfd_vma) nlm_extended_header (abfd)->messageFileLength,
    706 		(bfd_byte *) thdr.messageFileLength);
    707       put_word (abfd,
    708 		(bfd_vma) nlm_extended_header (abfd)->messageCount,
    709 		(bfd_byte *) thdr.messageCount);
    710       put_word (abfd,
    711 		(bfd_vma) nlm_extended_header (abfd)->helpFileOffset,
    712 		(bfd_byte *) thdr.helpFileOffset);
    713       put_word (abfd,
    714 		(bfd_vma) nlm_extended_header (abfd)->helpFileLength,
    715 		(bfd_byte *) thdr.helpFileLength);
    716       put_word (abfd,
    717 		(bfd_vma) nlm_extended_header (abfd)->RPCDataOffset,
    718 		(bfd_byte *) thdr.RPCDataOffset);
    719       put_word (abfd,
    720 		(bfd_vma) nlm_extended_header (abfd)->RPCDataLength,
    721 		(bfd_byte *) thdr.RPCDataLength);
    722       put_word (abfd,
    723 		(bfd_vma) nlm_extended_header (abfd)->sharedCodeOffset,
    724 		(bfd_byte *) thdr.sharedCodeOffset);
    725       put_word (abfd,
    726 		(bfd_vma) nlm_extended_header (abfd)->sharedCodeLength,
    727 		(bfd_byte *) thdr.sharedCodeLength);
    728       put_word (abfd,
    729 		(bfd_vma) nlm_extended_header (abfd)->sharedDataOffset,
    730 		(bfd_byte *) thdr.sharedDataOffset);
    731       put_word (abfd,
    732 		(bfd_vma) nlm_extended_header (abfd)->sharedDataLength,
    733 		(bfd_byte *) thdr.sharedDataLength);
    734       put_word (abfd,
    735 	  (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupOffset,
    736 		(bfd_byte *) thdr.sharedRelocationFixupOffset);
    737       put_word (abfd,
    738 	   (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupCount,
    739 		(bfd_byte *) thdr.sharedRelocationFixupCount);
    740       put_word (abfd,
    741 	(bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceOffset,
    742 		(bfd_byte *) thdr.sharedExternalReferenceOffset);
    743       put_word (abfd,
    744 	 (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceCount,
    745 		(bfd_byte *) thdr.sharedExternalReferenceCount);
    746       put_word (abfd,
    747 		(bfd_vma) nlm_extended_header (abfd)->sharedPublicsOffset,
    748 		(bfd_byte *) thdr.sharedPublicsOffset);
    749       put_word (abfd,
    750 		(bfd_vma) nlm_extended_header (abfd)->sharedPublicsCount,
    751 		(bfd_byte *) thdr.sharedPublicsCount);
    752       put_word (abfd,
    753 	      (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordOffset,
    754 		(bfd_byte *) thdr.sharedDebugRecordOffset);
    755       put_word (abfd,
    756 		(bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordCount,
    757 		(bfd_byte *) thdr.sharedDebugRecordCount);
    758       put_word (abfd,
    759 	   (bfd_vma) nlm_extended_header (abfd)->SharedInitializationOffset,
    760 		(bfd_byte *) thdr.sharedInitializationOffset);
    761       put_word (abfd,
    762 	    (bfd_vma) nlm_extended_header (abfd)->SharedExitProcedureOffset,
    763 		(bfd_byte *) thdr.SharedExitProcedureOffset);
    764       put_word (abfd,
    765 		(bfd_vma) nlm_extended_header (abfd)->productID,
    766 		(bfd_byte *) thdr.productID);
    767       put_word (abfd,
    768 		(bfd_vma) nlm_extended_header (abfd)->reserved0,
    769 		(bfd_byte *) thdr.reserved0);
    770       put_word (abfd,
    771 		(bfd_vma) nlm_extended_header (abfd)->reserved1,
    772 		(bfd_byte *) thdr.reserved1);
    773       put_word (abfd,
    774 		(bfd_vma) nlm_extended_header (abfd)->reserved2,
    775 		(bfd_byte *) thdr.reserved2);
    776       put_word (abfd,
    777 		(bfd_vma) nlm_extended_header (abfd)->reserved3,
    778 		(bfd_byte *) thdr.reserved3);
    779       put_word (abfd,
    780 		(bfd_vma) nlm_extended_header (abfd)->reserved4,
    781 		(bfd_byte *) thdr.reserved4);
    782       put_word (abfd,
    783 		(bfd_vma) nlm_extended_header (abfd)->reserved5,
    784 		(bfd_byte *) thdr.reserved5);
    785       if (bfd_bwrite ((void *) &thdr, (bfd_size_type) sizeof (thdr), abfd)
    786 	  != sizeof (thdr))
    787 	return FALSE;
    788     }
    789 
    790   /* Write out the custom header if there is one.   */
    791   if (find_nonzero (nlm_custom_header (abfd),
    792 		    sizeof (Nlm_Internal_Custom_Header)))
    793     {
    794       Nlm_External_Custom_Header thdr;
    795       bfd_boolean ds;
    796       bfd_size_type hdrLength;
    797 
    798       ds = find_nonzero (nlm_custom_header (abfd)->dataStamp,
    799 			 sizeof (nlm_custom_header (abfd)->dataStamp));
    800       LITMEMCPY (thdr.stamp, "CuStHeAd");
    801       hdrLength = (2 * NLM_TARGET_LONG_SIZE + (ds ? 8 : 0)
    802 		   + nlm_custom_header (abfd)->hdrLength);
    803       put_word (abfd, hdrLength, thdr.length);
    804       put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataOffset,
    805 		thdr.dataOffset);
    806       put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength,
    807 		thdr.dataLength);
    808       if (! ds)
    809 	{
    810 	  BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0);
    811 	  amt = sizeof (thdr) - sizeof (thdr.dataStamp);
    812 	  if (bfd_bwrite ((void *) &thdr, amt, abfd) != amt)
    813 	    return FALSE;
    814 	}
    815       else
    816 	{
    817 	  memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp,
    818 		  sizeof (thdr.dataStamp));
    819 	  amt = sizeof (thdr);
    820 	  if (bfd_bwrite ((void *) &thdr, amt, abfd) != amt)
    821 	    return FALSE;
    822 	  amt = nlm_custom_header (abfd)->hdrLength;
    823 	  if (bfd_bwrite (nlm_custom_header (abfd)->hdr, amt, abfd) != amt)
    824 	    return FALSE;
    825 	}
    826     }
    827 
    828   /* Write out the Cygnus debugging header if there is one.  */
    829   if (find_nonzero (nlm_cygnus_ext_header (abfd),
    830 		    sizeof (Nlm_Internal_Cygnus_Ext_Header)))
    831     {
    832       Nlm_External_Custom_Header thdr;
    833 
    834       LITMEMCPY (thdr.stamp, "CuStHeAd");
    835       put_word (abfd, (bfd_vma) 2 * NLM_TARGET_LONG_SIZE + 8,
    836 		(bfd_byte *) thdr.length);
    837       put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->offset,
    838 		(bfd_byte *) thdr.dataOffset);
    839       put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->length,
    840 		(bfd_byte *) thdr.dataLength);
    841       LITMEMCPY (thdr.dataStamp, "CyGnUsEx");
    842       amt = sizeof (thdr);
    843       if (bfd_bwrite ((void *) &thdr, amt, abfd) != amt)
    844 	return FALSE;
    845     }
    846 
    847   return TRUE;
    848 }
    849 
    850 /* We read the NLM's public symbols and use it to generate a bfd symbol
    851    table (hey, it's better than nothing) on a one-for-one basis.  Thus
    852    use the number of public symbols as the number of bfd symbols we will
    853    have once we actually get around to reading them in.
    854 
    855    Return the number of bytes required to hold the symtab vector, based on
    856    the count plus 1, since we will NULL terminate the vector allocated based
    857    on this size.  */
    858 
    859 long
    860 nlm_get_symtab_upper_bound (bfd *abfd)
    861 {
    862   Nlm_Internal_Fixed_Header *i_fxdhdrp;	/* Nlm file header, internal form.  */
    863   long symcount;
    864   long symtab_size = 0;
    865 
    866   i_fxdhdrp = nlm_fixed_header (abfd);
    867   symcount = (i_fxdhdrp->numberOfPublics
    868 	      + i_fxdhdrp->numberOfDebugRecords
    869 	      + i_fxdhdrp->numberOfExternalReferences);
    870   symtab_size = (symcount + 1) * (sizeof (asymbol));
    871   return symtab_size;
    872 }
    873 
    874 /* Slurp in nlm symbol table.
    875 
    876    In the external (in-file) form, NLM export records are variable length,
    877    with the following form:
    878 
    879 	1 byte		length of the symbol name (N)
    880 	N bytes		the symbol name
    881 	4 bytes		the symbol offset from start of it's section
    882 
    883    We also read in the debugging symbols and import records.  Import
    884    records are treated as undefined symbols.  As we read the import
    885    records we also read in the associated reloc information, which is
    886    attached to the symbol.
    887 
    888    The bfd symbols are copied to SYMvoid *S.
    889 
    890    When we return, the bfd symcount is either zero or contains the correct
    891    number of symbols.  */
    892 
    893 static bfd_boolean
    894 nlm_slurp_symbol_table (bfd *abfd)
    895 {
    896   Nlm_Internal_Fixed_Header *i_fxdhdrp;	/* Nlm file header, internal form.  */
    897   bfd_size_type totsymcount;	/* Number of NLM symbols.  */
    898   bfd_size_type symcount;	/* Counter of NLM symbols.  */
    899   nlm_symbol_type *sym;		/* Pointer to current bfd symbol.  */
    900   unsigned char symlength;	/* Symbol length read into here.  */
    901   unsigned char symtype;	/* Type of debugging symbol.  */
    902   bfd_byte temp[NLM_TARGET_LONG_SIZE];	/* Symbol offsets read into here.  */
    903   bfd_boolean (*read_import_func) (bfd *, nlm_symbol_type *);
    904   bfd_boolean (*set_public_section_func) (bfd *, nlm_symbol_type *);
    905   bfd_size_type amt;
    906 
    907   if (nlm_get_symbols (abfd) != NULL)
    908     return TRUE;
    909 
    910   /* Read each raw NLM symbol, using the information to create a canonical bfd
    911      symbol table entry.
    912 
    913      Note that we allocate the initial bfd canonical symbol buffer based on a
    914      one-to-one mapping of the NLM symbols to canonical symbols.  We actually
    915      use all the NLM symbols, so there will be no space left over at the end.
    916      When we have all the symbols, we build the caller's pointer vector.  */
    917 
    918   abfd->symcount = 0;
    919   i_fxdhdrp = nlm_fixed_header (abfd);
    920   totsymcount = (i_fxdhdrp->numberOfPublics
    921 		 + i_fxdhdrp->numberOfDebugRecords
    922 		 + i_fxdhdrp->numberOfExternalReferences);
    923   if (totsymcount == 0)
    924     return TRUE;
    925 
    926   if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) != 0)
    927     return FALSE;
    928 
    929   amt = totsymcount * sizeof (nlm_symbol_type);
    930   sym = bfd_zalloc (abfd, amt);
    931   if (!sym)
    932     return FALSE;
    933   nlm_set_symbols (abfd, sym);
    934 
    935   /* We use the bfd's symcount directly as the control count, so that early
    936      termination of the loop leaves the symcount correct for the symbols that
    937      were read.  */
    938 
    939   set_public_section_func = nlm_set_public_section_func (abfd);
    940   symcount = i_fxdhdrp->numberOfPublics;
    941   while (abfd->symcount < symcount)
    942     {
    943       amt = sizeof (symlength);
    944       if (bfd_bread ((void *) &symlength, amt, abfd) != amt)
    945 	return FALSE;
    946       amt = symlength;
    947       sym->symbol.the_bfd = abfd;
    948       sym->symbol.name = bfd_alloc (abfd, amt + 1);
    949       if (!sym->symbol.name)
    950 	return FALSE;
    951       if (bfd_bread ((void *) sym->symbol.name, amt, abfd) != amt)
    952 	return FALSE;
    953       /* Cast away const.  */
    954       ((char *) (sym->symbol.name))[symlength] = '\0';
    955       amt = sizeof (temp);
    956       if (bfd_bread ((void *) temp, amt, abfd) != amt)
    957 	return FALSE;
    958       sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
    959       sym->symbol.value = get_word (abfd, temp);
    960       if (set_public_section_func)
    961 	{
    962 	  /* Most backends can use the code below, but unfortunately
    963 	     some use a different scheme.  */
    964 	  if (! (*set_public_section_func) (abfd, sym))
    965 	    return FALSE;
    966 	}
    967       else
    968 	{
    969 	  if (sym->symbol.value & NLM_HIBIT)
    970 	    {
    971 	      sym->symbol.value &= ~NLM_HIBIT;
    972 	      sym->symbol.flags |= BSF_FUNCTION;
    973 	      sym->symbol.section =
    974 		bfd_get_section_by_name (abfd, NLM_CODE_NAME);
    975 	    }
    976 	  else
    977 	    sym->symbol.section =
    978 	      bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
    979 	}
    980       sym->rcnt = 0;
    981       abfd->symcount++;
    982       sym++;
    983     }
    984 
    985   /* Read the debugging records.  */
    986 
    987   if (i_fxdhdrp->numberOfDebugRecords > 0)
    988     {
    989       if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) != 0)
    990 	return FALSE;
    991 
    992       symcount += i_fxdhdrp->numberOfDebugRecords;
    993       while (abfd->symcount < symcount)
    994 	{
    995 	  amt = sizeof (symtype);
    996 	  if (bfd_bread ((void *) &symtype, amt, abfd) != amt)
    997 	    return FALSE;
    998 	  amt = sizeof (temp);
    999 	  if (bfd_bread ((void *) temp, amt, abfd) != amt)
   1000 	    return FALSE;
   1001 	  amt = sizeof (symlength);
   1002 	  if (bfd_bread ((void *) &symlength, amt, abfd) != amt)
   1003 	    return FALSE;
   1004 	  amt = symlength;
   1005 	  sym->symbol.the_bfd = abfd;
   1006 	  sym->symbol.name = bfd_alloc (abfd, amt + 1);
   1007 	  if (!sym->symbol.name)
   1008 	    return FALSE;
   1009 	  if (bfd_bread ((void *) sym->symbol.name, amt, abfd) != amt)
   1010 	    return FALSE;
   1011 	  /* Cast away const.  */
   1012 	  ((char *) (sym->symbol.name))[symlength] = '\0';
   1013 	  sym->symbol.flags = BSF_LOCAL;
   1014 	  sym->symbol.value = get_word (abfd, temp);
   1015 
   1016 	  if (symtype == 0)
   1017 	    sym->symbol.section =
   1018 	      bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
   1019 	  else if (symtype == 1)
   1020 	    {
   1021 	      sym->symbol.flags |= BSF_FUNCTION;
   1022 	      sym->symbol.section =
   1023 		bfd_get_section_by_name (abfd, NLM_CODE_NAME);
   1024 	    }
   1025 	  else
   1026 	    sym->symbol.section = bfd_abs_section_ptr;
   1027 
   1028 	  sym->rcnt = 0;
   1029 	  abfd->symcount++;
   1030 	  sym++;
   1031 	}
   1032     }
   1033 
   1034   /* Read in the import records.  We can only do this if we know how
   1035      to read relocs for this target.  */
   1036   read_import_func = nlm_read_import_func (abfd);
   1037   if (read_import_func != NULL)
   1038     {
   1039       if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET) != 0)
   1040 	return FALSE;
   1041 
   1042       symcount += i_fxdhdrp->numberOfExternalReferences;
   1043       while (abfd->symcount < symcount)
   1044 	{
   1045 	  if (! (*read_import_func) (abfd, sym))
   1046 	    return FALSE;
   1047 	  sym++;
   1048 	  abfd->symcount++;
   1049 	}
   1050     }
   1051 
   1052   return TRUE;
   1053 }
   1054 
   1055 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
   1056    symbol table fails.  */
   1057 
   1058 long
   1059 nlm_canonicalize_symtab (bfd *abfd, asymbol **alocation)
   1060 {
   1061   nlm_symbol_type *symbase;
   1062   bfd_size_type counter = 0;
   1063 
   1064   if (! nlm_slurp_symbol_table (abfd))
   1065     return -1;
   1066   symbase = nlm_get_symbols (abfd);
   1067   while (counter < bfd_get_symcount (abfd))
   1068     {
   1069       *alocation++ = &symbase->symbol;
   1070       symbase++;
   1071       counter++;
   1072     }
   1073   *alocation = NULL;
   1074   return bfd_get_symcount (abfd);
   1075 }
   1076 
   1077 /* Make an NLM symbol.  There is nothing special to do here.  */
   1078 
   1079 asymbol *
   1080 nlm_make_empty_symbol (bfd *abfd)
   1081 {
   1082   bfd_size_type amt = sizeof (nlm_symbol_type);
   1083   nlm_symbol_type *new = bfd_zalloc (abfd, amt);
   1084 
   1085   if (new == NULL)
   1086     return NULL;
   1087   new->symbol.the_bfd = abfd;
   1088   return & new->symbol;
   1089 }
   1090 
   1091 /* Get symbol information.  */
   1092 
   1093 void
   1094 nlm_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
   1095 		     asymbol *symbol,
   1096 		     symbol_info *ret)
   1097 {
   1098   bfd_symbol_info (symbol, ret);
   1099 }
   1100 
   1101 /* Print symbol information.  */
   1102 
   1103 void
   1104 nlm_print_symbol (bfd *abfd,
   1105 		  void * afile,
   1106 		  asymbol *symbol,
   1107 		  bfd_print_symbol_type how)
   1108 {
   1109   FILE *file = (FILE *) afile;
   1110 
   1111   switch (how)
   1112     {
   1113     case bfd_print_symbol_name:
   1114     case bfd_print_symbol_more:
   1115       if (symbol->name)
   1116 	fprintf (file, "%s", symbol->name);
   1117       break;
   1118     case bfd_print_symbol_all:
   1119       bfd_print_symbol_vandf (abfd, (void *) file, symbol);
   1120       fprintf (file, " %-5s", symbol->section->name);
   1121       if (symbol->name)
   1122 	fprintf (file, " %s", symbol->name);
   1123       break;
   1124     }
   1125 }
   1126 
   1127 /* Get the relocs for an NLM file.  There are two types of relocs.
   1129    Imports are relocs against symbols defined in other NLM files.  We
   1130    treat these as relocs against global symbols.  Relocation fixups
   1131    are internal relocs.
   1132 
   1133    The actual format used to store the relocs is machine specific.  */
   1134 
   1135 /* Read in the relocation fixup information.  This is stored in
   1136    nlm_relocation_fixups, an array of arelent structures, and
   1137    nlm_relocation_fixup_secs, an array of section pointers.  The
   1138    section pointers are needed because the relocs are not sorted by
   1139    section.  */
   1140 
   1141 static bfd_boolean
   1142 nlm_slurp_reloc_fixups (bfd *abfd)
   1143 {
   1144   bfd_boolean (*read_func) (bfd *, nlm_symbol_type *, asection **, arelent *);
   1145   bfd_size_type count, amt;
   1146   arelent *rels;
   1147   asection **secs;
   1148 
   1149   if (nlm_relocation_fixups (abfd) != NULL)
   1150     return TRUE;
   1151   read_func = nlm_read_reloc_func (abfd);
   1152   if (read_func == NULL)
   1153     return TRUE;
   1154 
   1155   if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
   1156 		SEEK_SET) != 0)
   1157     return FALSE;
   1158 
   1159   count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
   1160   amt = count * sizeof (arelent);
   1161   rels = bfd_alloc (abfd, amt);
   1162   amt = count * sizeof (asection *);
   1163   secs = bfd_alloc (abfd, amt);
   1164   if ((rels == NULL || secs == NULL) && count != 0)
   1165     return FALSE;
   1166   nlm_relocation_fixups (abfd) = rels;
   1167   nlm_relocation_fixup_secs (abfd) = secs;
   1168 
   1169   /* We have to read piece by piece, because we don't know how large
   1170      the machine specific reloc information is.  */
   1171   while (count-- != 0)
   1172     {
   1173       if (! (*read_func) (abfd, NULL, secs, rels))
   1174 	{
   1175 	  nlm_relocation_fixups (abfd) = NULL;
   1176 	  nlm_relocation_fixup_secs (abfd) = NULL;
   1177 	  return FALSE;
   1178 	}
   1179       ++secs;
   1180       ++rels;
   1181     }
   1182 
   1183   return TRUE;
   1184 }
   1185 
   1186 /* Get the number of relocs.  This really just returns an upper bound,
   1187    since it does not attempt to distinguish them based on the section.
   1188    That will be handled when they are actually read.  */
   1189 
   1190 long
   1191 nlm_get_reloc_upper_bound (bfd *abfd, asection *sec)
   1192 {
   1193   nlm_symbol_type *syms;
   1194   bfd_size_type count;
   1195   unsigned int ret;
   1196 
   1197   /* If we don't know how to read relocs, just return 0.  */
   1198   if (nlm_read_reloc_func (abfd) == NULL)
   1199     return -1;
   1200   /* Make sure we have either the code or the data section.  */
   1201   if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
   1202     return 0;
   1203 
   1204   syms = nlm_get_symbols (abfd);
   1205   if (syms == NULL)
   1206     {
   1207       if (! nlm_slurp_symbol_table (abfd))
   1208 	return -1;
   1209       syms = nlm_get_symbols (abfd);
   1210     }
   1211 
   1212   ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;
   1213 
   1214   count = bfd_get_symcount (abfd);
   1215   while (count-- != 0)
   1216     {
   1217       ret += syms->rcnt;
   1218       ++syms;
   1219     }
   1220 
   1221   return (ret + 1) * sizeof (arelent *);
   1222 }
   1223 
   1224 /* Get the relocs themselves.  */
   1225 
   1226 long
   1227 nlm_canonicalize_reloc (bfd *abfd,
   1228 			asection *sec,
   1229 			arelent **relptr,
   1230 			asymbol **symbols)
   1231 {
   1232   arelent *rels;
   1233   asection **secs;
   1234   bfd_size_type count, i;
   1235   long ret;
   1236 
   1237   /* Get the relocation fixups.  */
   1238   rels = nlm_relocation_fixups (abfd);
   1239   if (rels == NULL)
   1240     {
   1241       if (! nlm_slurp_reloc_fixups (abfd))
   1242 	return -1;
   1243       rels = nlm_relocation_fixups (abfd);
   1244     }
   1245   secs = nlm_relocation_fixup_secs (abfd);
   1246 
   1247   ret = 0;
   1248   count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
   1249   for (i = 0; i < count; i++, rels++, secs++)
   1250     {
   1251       if (*secs == sec)
   1252 	{
   1253 	  *relptr++ = rels;
   1254 	  ++ret;
   1255 	}
   1256     }
   1257 
   1258   /* Get the import symbols.  */
   1259   count = bfd_get_symcount (abfd);
   1260   for (i = 0; i < count; i++, symbols++)
   1261     {
   1262       asymbol *sym;
   1263 
   1264       sym = *symbols;
   1265       if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
   1266 	{
   1267 	  nlm_symbol_type *nlm_sym;
   1268 	  bfd_size_type j;
   1269 
   1270 	  nlm_sym = (nlm_symbol_type *) sym;
   1271 	  for (j = 0; j < nlm_sym->rcnt; j++)
   1272 	    {
   1273 	      if (nlm_sym->relocs[j].section == sec)
   1274 		{
   1275 		  *relptr = &nlm_sym->relocs[j].reloc;
   1276 		  (*relptr)->sym_ptr_ptr = symbols;
   1277 		  ++relptr;
   1278 		  ++ret;
   1279 		}
   1280 	    }
   1281 	}
   1282     }
   1283 
   1284   *relptr = NULL;
   1285 
   1286   return ret;
   1287 }
   1288 
   1289 /* Compute the section file positions for an NLM file.  All variable
   1291    length data in the file headers must be set before this function is
   1292    called.  If the variable length data is changed later, the
   1293    resulting object file will be incorrect.  Unfortunately, there is
   1294    no way to check this.
   1295 
   1296    This routine also sets the Size and Offset fields in the fixed
   1297    header.
   1298 
   1299    It also looks over the symbols and moves any common symbols into
   1300    the .bss section; NLM has no way to represent a common symbol.
   1301    This approach means that either the symbols must already have been
   1302    set at this point, or there must be no common symbols.  We need to
   1303    move the symbols at this point so that mangle_relocs can see the
   1304    final values.  */
   1305 
   1306 static bfd_boolean
   1307 nlm_compute_section_file_positions (bfd *abfd)
   1308 {
   1309   file_ptr sofar;
   1310   asection *sec;
   1311   bfd_vma text, data, bss;
   1312   bfd_vma text_low, data_low;
   1313   unsigned int text_align, data_align, other_align;
   1314   file_ptr text_ptr, data_ptr, other_ptr;
   1315   asection *bss_sec;
   1316   asymbol **sym_ptr_ptr;
   1317 
   1318   if (abfd->output_has_begun)
   1319     return TRUE;
   1320 
   1321   /* Make sure we have a section to hold uninitialized data.  */
   1322   bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
   1323   if (bss_sec == NULL)
   1324     {
   1325       if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
   1326 			    (file_ptr) 0, (bfd_size_type) 0,
   1327 			    SEC_ALLOC))
   1328 	return FALSE;
   1329       bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
   1330     }
   1331 
   1332   abfd->output_has_begun = TRUE;
   1333 
   1334   /* The fixed header.  */
   1335   sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
   1336 
   1337   /* The variable header.  */
   1338   sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
   1339 	    + nlm_variable_header (abfd)->descriptionLength + 1
   1340 	    + NLM_TARGET_LONG_SIZE	/* stackSize */
   1341 	    + NLM_TARGET_LONG_SIZE	/* reserved */
   1342 	    + sizeof (nlm_variable_header (abfd)->oldThreadName)
   1343 	    + sizeof (nlm_variable_header (abfd)->screenNameLength)
   1344 	    + nlm_variable_header (abfd)->screenNameLength + 1
   1345 	    + sizeof (nlm_variable_header (abfd)->threadNameLength)
   1346 	    + nlm_variable_header (abfd)->threadNameLength + 1);
   1347 
   1348   /* The auxiliary headers.  */
   1349   if (find_nonzero (nlm_version_header (abfd),
   1350 		    sizeof (Nlm_Internal_Version_Header)))
   1351     sofar += sizeof (Nlm_External_Version_Header);
   1352   if (find_nonzero (nlm_extended_header (abfd),
   1353 		    sizeof (Nlm_Internal_Extended_Header)))
   1354     sofar += sizeof (Nlm_External_Extended_Header);
   1355   if (find_nonzero (nlm_copyright_header (abfd),
   1356 		    sizeof (Nlm_Internal_Copyright_Header)))
   1357     sofar += (sizeof (Nlm_External_Copyright_Header)
   1358 	      + nlm_copyright_header (abfd)->copyrightMessageLength + 1);
   1359   if (find_nonzero (nlm_custom_header (abfd),
   1360 		    sizeof (Nlm_Internal_Custom_Header)))
   1361     sofar += (sizeof (Nlm_External_Custom_Header)
   1362 	      + nlm_custom_header (abfd)->hdrLength);
   1363   if (find_nonzero (nlm_cygnus_ext_header (abfd),
   1364 		    sizeof (Nlm_Internal_Cygnus_Ext_Header)))
   1365     sofar += sizeof (Nlm_External_Custom_Header);
   1366 
   1367   /* Compute the section file positions in two passes.  First get the
   1368      sizes of the text and data sections, and then set the file
   1369      positions.  This code aligns the sections in the file using the
   1370      same alignment restrictions that apply to the sections in memory;
   1371      this may not be necessary.  */
   1372   text = 0;
   1373   text_low = (bfd_vma) - 1;
   1374   text_align = 0;
   1375   data = 0;
   1376   data_low = (bfd_vma) - 1;
   1377   data_align = 0;
   1378   bss = 0;
   1379   other_align = 0;
   1380   for (sec = abfd->sections; sec != NULL; sec = sec->next)
   1381     {
   1382       flagword f;
   1383 
   1384       sec->size = BFD_ALIGN (sec->size, 1 << sec->alignment_power);
   1385 
   1386       f = bfd_get_section_flags (abfd, sec);
   1387       if (f & SEC_CODE)
   1388 	{
   1389 	  text += sec->size;
   1390 	  if (bfd_get_section_vma (abfd, sec) < text_low)
   1391 	    text_low = bfd_get_section_vma (abfd, sec);
   1392 	  if (sec->alignment_power > text_align)
   1393 	    text_align = sec->alignment_power;
   1394 	}
   1395       else if (f & SEC_DATA)
   1396 	{
   1397 	  data += sec->size;
   1398 	  if (bfd_get_section_vma (abfd, sec) < data_low)
   1399 	    data_low = bfd_get_section_vma (abfd, sec);
   1400 	  if (sec->alignment_power > data_align)
   1401 	    data_align = sec->alignment_power;
   1402 	}
   1403       else if (f & SEC_HAS_CONTENTS)
   1404 	{
   1405 	  if (sec->alignment_power > other_align)
   1406 	    other_align = sec->alignment_power;
   1407 	}
   1408       else if (f & SEC_ALLOC)
   1409 	bss += sec->size;
   1410     }
   1411 
   1412   nlm_set_text_low (abfd, text_low);
   1413   nlm_set_data_low (abfd, data_low);
   1414 
   1415   if (nlm_no_uninitialized_data (abfd))
   1416     {
   1417       /* This NetWare format does not use uninitialized data.  We must
   1418 	 increase the size of the data section.  We will never wind up
   1419 	 writing those file locations, so they will remain zero.  */
   1420       data += bss;
   1421       bss = 0;
   1422     }
   1423 
   1424   text_ptr = BFD_ALIGN (sofar, 1 << text_align);
   1425   data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
   1426   other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
   1427 
   1428   /* Fill in some fields in the header for which we now have the
   1429      information.  */
   1430   nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
   1431   nlm_fixed_header (abfd)->codeImageSize = text;
   1432   nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
   1433   nlm_fixed_header (abfd)->dataImageSize = data;
   1434   nlm_fixed_header (abfd)->uninitializedDataSize = bss;
   1435 
   1436   for (sec = abfd->sections; sec != NULL; sec = sec->next)
   1437     {
   1438       flagword f;
   1439 
   1440       f = bfd_get_section_flags (abfd, sec);
   1441 
   1442       if (f & SEC_CODE)
   1443 	{
   1444 	  sec->filepos = text_ptr;
   1445 	  text_ptr += sec->size;
   1446 	}
   1447       else if (f & SEC_DATA)
   1448 	{
   1449 	  sec->filepos = data_ptr;
   1450 	  data_ptr += sec->size;
   1451 	}
   1452       else if (f & SEC_HAS_CONTENTS)
   1453 	{
   1454 	  sec->filepos = other_ptr;
   1455 	  other_ptr += sec->size;
   1456 	}
   1457     }
   1458 
   1459   nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
   1460 
   1461   /* Move all common symbols into the .bss section.  */
   1462 
   1463   sym_ptr_ptr = bfd_get_outsymbols (abfd);
   1464   if (sym_ptr_ptr != NULL)
   1465     {
   1466       asymbol **sym_end;
   1467       bfd_vma add;
   1468 
   1469       sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
   1470       add = 0;
   1471       for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
   1472 	{
   1473 	  asymbol *sym;
   1474 	  bfd_vma size;
   1475 
   1476 	  sym = *sym_ptr_ptr;
   1477 
   1478 	  if (!bfd_is_com_section (bfd_get_section (sym)))
   1479 	    continue;
   1480 
   1481 	  /* Put the common symbol in the .bss section, and increase
   1482 	     the size of the .bss section by the size of the common
   1483 	     symbol (which is the old value of the symbol).  */
   1484 	  sym->section = bss_sec;
   1485 	  size = sym->value;
   1486 	  sym->value = bss_sec->size + add;
   1487 	  add += size;
   1488 	  add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
   1489 	}
   1490       if (add != 0)
   1491 	{
   1492 	  if (nlm_no_uninitialized_data (abfd))
   1493 	    {
   1494 	      /* We could handle this case, but so far it hasn't been
   1495 		 necessary.  */
   1496 	      abort ();
   1497 	    }
   1498 	  nlm_fixed_header (abfd)->uninitializedDataSize += add;
   1499 	  bss_sec->size += add;
   1500 	}
   1501     }
   1502 
   1503   return TRUE;
   1504 }
   1505 
   1506 /* Set the contents of a section.  To do this we need to know where
   1507    the section is going to be located in the output file.  That means
   1508    that the sizes of all the sections must be set, and all the
   1509    variable size header information must be known.  */
   1510 
   1511 bfd_boolean
   1512 nlm_set_section_contents (bfd *abfd,
   1513 			  asection *section,
   1514 			  const void * location,
   1515 			  file_ptr offset,
   1516 			  bfd_size_type count)
   1517 {
   1518   if (! abfd->output_has_begun
   1519       && ! nlm_compute_section_file_positions (abfd))
   1520     return FALSE;
   1521 
   1522   if (count == 0)
   1523     return TRUE;
   1524 
   1525   /* i386 NetWare has a very restricted set of relocs.  In order for
   1526      objcopy to work, the NLM i386 backend needs a chance to rework
   1527      the section contents so that its set of relocs will work.  If all
   1528      the relocs are already acceptable, this will not do anything.  */
   1529   if (section->reloc_count != 0)
   1530     {
   1531       bfd_boolean (*mangle_relocs_func)
   1532 	(bfd *, asection *, const void *, bfd_vma, bfd_size_type);
   1533 
   1534       mangle_relocs_func = nlm_mangle_relocs_func (abfd);
   1535       if (mangle_relocs_func != NULL)
   1536 	{
   1537 	  if (!(*mangle_relocs_func) (abfd, section, location,
   1538 				      (bfd_vma) offset, count))
   1539 	    return FALSE;
   1540 	}
   1541     }
   1542 
   1543   if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
   1544       || bfd_bwrite (location, count, abfd) != count)
   1545     return FALSE;
   1546 
   1547   return TRUE;
   1548 }
   1549 
   1550 /* We need to sort a list of relocs associated with sections when we
   1551    write out the external relocs.  */
   1552 
   1553 static int
   1554 nlm_external_reloc_compare (const void *p1, const void *p2)
   1555 {
   1556   const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
   1557   const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
   1558   int cmp;
   1559 
   1560   cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name,
   1561 		(*r2->rel->sym_ptr_ptr)->name);
   1562   if (cmp != 0)
   1563     return cmp;
   1564 
   1565   /* We sort by address within symbol to make the sort more stable and
   1566      increase the chances that different hosts will generate bit for
   1567      bit equivalent results.  */
   1568   return (int) (r1->rel->address - r2->rel->address);
   1569 }
   1570 
   1571 /* Write out an NLM file.  We write out the information in this order:
   1572      fixed header
   1573      variable header
   1574      auxiliary headers
   1575      code sections
   1576      data sections
   1577      other sections (custom data, messages, help, shared NLM, RPC,
   1578      		     module dependencies)
   1579      relocation fixups
   1580      external references (imports)
   1581      public symbols (exports)
   1582      debugging records
   1583    This is similar to the order used by the NetWare tools; the
   1584    difference is that NetWare puts the sections other than code, data
   1585    and custom data at the end of the NLM.  It is convenient for us to
   1586    know where the sections are going to be before worrying about the
   1587    size of the other information.
   1588 
   1589    By the time this function is called, all the section data should
   1590    have been output using set_section_contents.  Note that custom
   1591    data, the message file, the help file, the shared NLM file, the RPC
   1592    data, and the module dependencies are all considered to be
   1593    sections; the caller is responsible for filling in the offset and
   1594    length fields in the NLM headers.  The relocation fixups and
   1595    imports are both obtained from the list of relocs attached to each
   1596    section.  The exports and debugging records are obtained from the
   1597    list of outsymbols.  */
   1598 
   1599 bfd_boolean
   1600 nlm_write_object_contents (bfd *abfd)
   1601 {
   1602   asection *sec;
   1603   bfd_boolean (*write_import_func) (bfd *, asection *, arelent *);
   1604   bfd_size_type external_reloc_count, internal_reloc_count, i, c;
   1605   struct reloc_and_sec *external_relocs;
   1606   asymbol **sym_ptr_ptr;
   1607   file_ptr last;
   1608   bfd_boolean (*write_prefix_func) (bfd *);
   1609   unsigned char *fixed_header = NULL;
   1610   file_ptr pos;
   1611   bfd_size_type amt;
   1612 
   1613   fixed_header = bfd_malloc (nlm_fixed_header_size (abfd));
   1614   if (fixed_header == NULL)
   1615     goto error_return;
   1616 
   1617   if (! abfd->output_has_begun
   1618       && ! nlm_compute_section_file_positions (abfd))
   1619     goto error_return;
   1620 
   1621   /* Write out the variable length headers.  */
   1622   pos = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
   1623   if (bfd_seek (abfd, pos, SEEK_SET) != 0)
   1624     goto error_return;
   1625   if (! nlm_swap_variable_header_out (abfd)
   1626       || ! nlm_swap_auxiliary_headers_out (abfd))
   1627     {
   1628       bfd_set_error (bfd_error_system_call);
   1629       goto error_return;
   1630     }
   1631 
   1632   /* A weak check on whether the section file positions were
   1633      reasonable.  */
   1634   if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
   1635     {
   1636       bfd_set_error (bfd_error_invalid_operation);
   1637       goto error_return;
   1638     }
   1639 
   1640   /* Advance to the relocs.  */
   1641   if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
   1642 		SEEK_SET) != 0)
   1643     goto error_return;
   1644 
   1645   /* The format of the relocation entries is dependent upon the
   1646      particular target.  We use an external routine to write the reloc
   1647      out.  */
   1648   write_import_func = nlm_write_import_func (abfd);
   1649 
   1650   /* Write out the internal relocation fixups.  While we're looping
   1651      over the relocs, we also count the external relocs, which is
   1652      needed when they are written out below.  */
   1653   internal_reloc_count = 0;
   1654   external_reloc_count = 0;
   1655   for (sec = abfd->sections; sec != NULL; sec = sec->next)
   1656     {
   1657       arelent **rel_ptr_ptr, **rel_end;
   1658 
   1659       if (sec->reloc_count == 0)
   1660 	continue;
   1661 
   1662       /* We can only represent relocs within a code or data
   1663 	 section.  We ignore them for a debugging section.  */
   1664       if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
   1665 	continue;
   1666 
   1667       /* We need to know how to write out imports */
   1668       if (write_import_func == NULL)
   1669 	{
   1670 	  bfd_set_error (bfd_error_invalid_operation);
   1671 	  goto error_return;
   1672 	}
   1673 
   1674       rel_ptr_ptr = sec->orelocation;
   1675       rel_end = rel_ptr_ptr + sec->reloc_count;
   1676       for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
   1677 	{
   1678 	  arelent *rel;
   1679 	  asymbol *sym;
   1680 
   1681 	  rel = *rel_ptr_ptr;
   1682 	  sym = *rel->sym_ptr_ptr;
   1683 
   1684 	  if (! bfd_is_und_section (bfd_get_section (sym)))
   1685 	    {
   1686 	      ++internal_reloc_count;
   1687 	      if (! (*write_import_func) (abfd, sec, rel))
   1688 		goto error_return;
   1689 	    }
   1690 	  else
   1691 	    ++external_reloc_count;
   1692 	}
   1693     }
   1694   nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
   1695 
   1696   /* Write out the imports (relocs against external symbols).  These
   1697      are output as a symbol name followed by all the relocs for that
   1698      symbol, so we must first gather together all the relocs against
   1699      external symbols and sort them.  */
   1700   amt = external_reloc_count * sizeof (struct reloc_and_sec);
   1701   external_relocs = bfd_alloc (abfd, amt);
   1702   if (external_relocs == NULL)
   1703     goto error_return;
   1704   i = 0;
   1705   for (sec = abfd->sections; sec != NULL; sec = sec->next)
   1706     {
   1707       arelent **rel_ptr_ptr, **rel_end;
   1708 
   1709       if (sec->reloc_count == 0)
   1710 	continue;
   1711 
   1712       rel_ptr_ptr = sec->orelocation;
   1713       rel_end = rel_ptr_ptr + sec->reloc_count;
   1714       for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
   1715 	{
   1716 	  arelent *rel;
   1717 	  asymbol *sym;
   1718 
   1719 	  rel = *rel_ptr_ptr;
   1720 	  sym = *rel->sym_ptr_ptr;
   1721 
   1722 	  if (! bfd_is_und_section (bfd_get_section (sym)))
   1723 	    continue;
   1724 
   1725 	  external_relocs[i].rel = rel;
   1726 	  external_relocs[i].sec = sec;
   1727 	  ++i;
   1728 	}
   1729     }
   1730 
   1731   BFD_ASSERT (i == external_reloc_count);
   1732 
   1733   /* Sort the external relocs by name.  */
   1734   qsort (external_relocs, (size_t) external_reloc_count,
   1735 	 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
   1736 
   1737   /* Write out the external relocs.  */
   1738   nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
   1739   c = 0;
   1740   i = 0;
   1741   while (i < external_reloc_count)
   1742     {
   1743       arelent *rel;
   1744       asymbol *sym;
   1745       bfd_size_type j, cnt;
   1746 
   1747       ++c;
   1748 
   1749       rel = external_relocs[i].rel;
   1750       sym = *rel->sym_ptr_ptr;
   1751 
   1752       cnt = 0;
   1753       for (j = i;
   1754 	   (j < external_reloc_count
   1755 	    && *external_relocs[j].rel->sym_ptr_ptr == sym);
   1756 	   j++)
   1757 	++cnt;
   1758 
   1759       if (! (*nlm_write_external_func (abfd)) (abfd, cnt, sym,
   1760 					       &external_relocs[i]))
   1761 	goto error_return;
   1762 
   1763       i += cnt;
   1764     }
   1765 
   1766   nlm_fixed_header (abfd)->numberOfExternalReferences = c;
   1767 
   1768   /* Write out the public symbols (exports).  */
   1769   sym_ptr_ptr = bfd_get_outsymbols (abfd);
   1770   if (sym_ptr_ptr != NULL)
   1771     {
   1772       bfd_vma (*get_public_offset_func) (bfd *, asymbol *);
   1773       bfd_boolean (*write_export_func) (bfd *, asymbol *, bfd_vma);
   1774 
   1775       asymbol **sym_end;
   1776 
   1777       nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
   1778       get_public_offset_func = nlm_get_public_offset_func (abfd);
   1779       write_export_func = nlm_write_export_func (abfd);
   1780       c = 0;
   1781       sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
   1782       for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
   1783 	{
   1784 	  asymbol *sym;
   1785 	  bfd_byte len;
   1786 	  bfd_vma offset;
   1787 	  bfd_byte temp[NLM_TARGET_LONG_SIZE];
   1788 
   1789 	  sym = *sym_ptr_ptr;
   1790 
   1791 	  if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
   1792 	      || bfd_is_und_section (bfd_get_section (sym)))
   1793 	    continue;
   1794 
   1795 	  ++c;
   1796 
   1797 	  if (get_public_offset_func)
   1798 	    {
   1799 	      /* Most backends can use the code below, but
   1800 		 unfortunately some use a different scheme.  */
   1801 	      offset = (*get_public_offset_func) (abfd, sym);
   1802 	    }
   1803 	  else
   1804 	    {
   1805 	      offset = bfd_asymbol_value (sym);
   1806 	      sec = sym->section;
   1807 	      if (sec->flags & SEC_CODE)
   1808 		{
   1809 		  offset -= nlm_get_text_low (abfd);
   1810 		  offset |= NLM_HIBIT;
   1811 		}
   1812 	      else if (sec->flags & (SEC_DATA | SEC_ALLOC))
   1813 		{
   1814 		  /* SEC_ALLOC is for the .bss section.  */
   1815 		  offset -= nlm_get_data_low (abfd);
   1816 		}
   1817 	      else
   1818 		{
   1819 		  /* We can't handle an exported symbol that is not in
   1820 		     the code or data segment.  */
   1821 		  bfd_set_error (bfd_error_invalid_operation);
   1822 		  goto error_return;
   1823 		}
   1824 	    }
   1825 
   1826 	  if (write_export_func)
   1827 	    {
   1828 	      if (! (*write_export_func) (abfd, sym, offset))
   1829 		goto error_return;
   1830 	    }
   1831 	  else
   1832 	    {
   1833 	      len = strlen (sym->name);
   1834 	      if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
   1835 		   != sizeof (bfd_byte))
   1836 		  || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
   1837 		goto error_return;
   1838 
   1839 	      put_word (abfd, offset, temp);
   1840 	      if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
   1841 		  != sizeof (temp))
   1842 		goto error_return;
   1843 	    }
   1844 	}
   1845       nlm_fixed_header (abfd)->numberOfPublics = c;
   1846 
   1847       /* Write out the debugging records.  The NLM conversion program
   1848 	 wants to be able to inhibit this, so as a special hack if
   1849 	 debugInfoOffset is set to -1 we don't write any debugging
   1850 	 information.  This can not be handled by fiddling with the
   1851 	 symbol table, because exported symbols appear in both the
   1852 	 exported symbol list and the debugging information.  */
   1853       if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1)
   1854 	{
   1855 	  nlm_fixed_header (abfd)->debugInfoOffset = 0;
   1856 	  nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
   1857 	}
   1858       else
   1859 	{
   1860 	  nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
   1861 	  c = 0;
   1862 	  sym_ptr_ptr = bfd_get_outsymbols (abfd);
   1863 	  sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
   1864 	  for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
   1865 	    {
   1866 	      asymbol *sym;
   1867 	      bfd_byte type, len;
   1868 	      bfd_vma offset;
   1869 	      bfd_byte temp[NLM_TARGET_LONG_SIZE];
   1870 
   1871 	      sym = *sym_ptr_ptr;
   1872 
   1873 	      /* The NLM notion of a debugging symbol is actually what
   1874 		 BFD calls a local or global symbol.  What BFD calls a
   1875 		 debugging symbol NLM does not understand at all.  */
   1876 	      if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
   1877 		  || (sym->flags & BSF_DEBUGGING) != 0
   1878 		  || bfd_is_und_section (bfd_get_section (sym)))
   1879 		continue;
   1880 
   1881 	      ++c;
   1882 
   1883 	      offset = bfd_asymbol_value (sym);
   1884 	      sec = sym->section;
   1885 	      if (sec->flags & SEC_CODE)
   1886 		{
   1887 		  offset -= nlm_get_text_low (abfd);
   1888 		  type = 1;
   1889 		}
   1890 	      else if (sec->flags & (SEC_DATA | SEC_ALLOC))
   1891 		{
   1892 		  /* SEC_ALLOC is for the .bss section.  */
   1893 		  offset -= nlm_get_data_low (abfd);
   1894 		  type = 0;
   1895 		}
   1896 	      else
   1897 		type = 2;
   1898 
   1899 	      /* The type is 0 for data, 1 for code, 2 for absolute.  */
   1900 	      if (bfd_bwrite (&type, (bfd_size_type) sizeof (bfd_byte), abfd)
   1901 		  != sizeof (bfd_byte))
   1902 		goto error_return;
   1903 
   1904 	      put_word (abfd, offset, temp);
   1905 	      if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
   1906 		  != sizeof (temp))
   1907 		goto error_return;
   1908 
   1909 	      len = strlen (sym->name);
   1910 	      if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
   1911 		   != sizeof (bfd_byte))
   1912 		  || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
   1913 		goto error_return;
   1914 	    }
   1915 	  nlm_fixed_header (abfd)->numberOfDebugRecords = c;
   1916 	}
   1917     }
   1918 
   1919   /* NLMLINK fills in offset values even if there is no data, so we do
   1920      the same.  */
   1921   last = bfd_tell (abfd);
   1922   if (nlm_fixed_header (abfd)->codeImageOffset == 0)
   1923     nlm_fixed_header (abfd)->codeImageOffset = last;
   1924   if (nlm_fixed_header (abfd)->dataImageOffset == 0)
   1925     nlm_fixed_header (abfd)->dataImageOffset = last;
   1926   if (nlm_fixed_header (abfd)->customDataOffset == 0)
   1927     nlm_fixed_header (abfd)->customDataOffset = last;
   1928   if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
   1929     nlm_fixed_header (abfd)->moduleDependencyOffset = last;
   1930   if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
   1931     nlm_fixed_header (abfd)->relocationFixupOffset = last;
   1932   if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
   1933     nlm_fixed_header (abfd)->externalReferencesOffset = last;
   1934   if (nlm_fixed_header (abfd)->publicsOffset == 0)
   1935     nlm_fixed_header (abfd)->publicsOffset = last;
   1936   if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
   1937     nlm_fixed_header (abfd)->debugInfoOffset = last;
   1938 
   1939   /* At this point everything has been written out except the fixed
   1940      header.  */
   1941   memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
   1942 	  NLM_SIGNATURE_SIZE);
   1943   nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
   1944   nlm_fixed_header (abfd)->codeStartOffset =
   1945     (bfd_get_start_address (abfd)
   1946      - nlm_get_text_low (abfd));
   1947 
   1948   /* We have no convenient way for the caller to pass in the exit
   1949      procedure or the check unload procedure, so the caller must set
   1950      the values in the header to the values of the symbols.  */
   1951   nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
   1952   if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
   1953     nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
   1954       nlm_get_text_low (abfd);
   1955 
   1956   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
   1957     goto error_return;
   1958 
   1959   write_prefix_func = nlm_write_prefix_func (abfd);
   1960   if (write_prefix_func)
   1961     {
   1962       if (! (*write_prefix_func) (abfd))
   1963 	goto error_return;
   1964     }
   1965 
   1966   BFD_ASSERT ((bfd_size_type) bfd_tell (abfd)
   1967 	      == nlm_optional_prefix_size (abfd));
   1968 
   1969   nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
   1970   if (bfd_bwrite (fixed_header, nlm_fixed_header_size (abfd), abfd)
   1971       != nlm_fixed_header_size (abfd))
   1972     goto error_return;
   1973 
   1974   if (fixed_header != NULL)
   1975     free (fixed_header);
   1976   return TRUE;
   1977 
   1978 error_return:
   1979   if (fixed_header != NULL)
   1980     free (fixed_header);
   1981   return FALSE;
   1982 }
   1983