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