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