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