~ubuntu-branches/ubuntu/hoary/binutils/hoary

« back to all changes in this revision

Viewing changes to bfd/nlmcode.h

  • Committer: Bazaar Package Importer
  • Author(s): James Troup
  • Date: 2004-05-19 10:35:44 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040519103544-17h3o6e8pwndydrg
Tags: 2.14.90.0.7-8
debian/rules: don't use gcc-2.95 on m68k.  Thanks to Adam Conrad for
pointing this out.

Show diffs side-by-side

added added

removed removed

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