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