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