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