* configure.in (*-*-netware, i[34]86-*-netware): New configs.
[external/binutils.git] / bfd / nlmcode.h
1 /* NLM (NetWare Loadable Module) executable support for BFD.
2    Copyright (C) 1993 Free Software Foundation, Inc.
3
4    Written by Fred Fish @ Cygnus Support, using ELF support as the
5    template.
6
7 This file is part of BFD, the Binary File Descriptor library.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
22
23 #include <string.h>             /* For strrchr and friends */
24 #include "bfd.h"
25 #include "sysdep.h"
26 #include "libbfd.h"
27 #include "libnlm.h"
28
29 #define Nlm_External_Fixed_Header       NAME(Nlm,External_Fixed_Header)
30 #define Nlm_External_Version_Header     NAME(Nlm,External_Version_Header)
31 #define Nlm_External_Copyright_Header   NAME(Nlm,External_Copyright_Header)
32 #define Nlm_External_Extended_Header    NAME(Nlm,External_Extended_Header)
33 #define Nlm_External_Custom_Header      NAME(Nlm,External_Custom_Header)
34
35 #define nlm_symbol_type                 NAME(nlm,symbol_type)
36
37 #define nlm_get_symtab_upper_bound      NAME(bfd_nlm,get_symtab_upper_bound)
38 #define nlm_get_symtab                  NAME(bfd_nlm,get_symtab)
39 #define nlm_make_empty_symbol           NAME(bfd_nlm,make_empty_symbol)
40 #define nlm_print_symbol                NAME(bfd_nlm,print_symbol)
41 #define nlm_get_symbol_info             NAME(bfd_nlm,get_symbol_info)
42 #define nlm_set_arch_mach               NAME(bfd_nlm,set_arch_mach)
43 #define nlm_object_p                    NAME(bfd_nlm,object_p)
44
45 #define MSB (~(~(unsigned long)0 >> 1))
46
47 /* Forward declarations of static functions */
48
49 static boolean add_bfd_section
50   PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword));
51
52 static void nlm_swap_fixed_header_in
53   PARAMS ((bfd *, Nlm_External_Fixed_Header *, Nlm_Internal_Fixed_Header *));
54
55 static boolean nlm_swap_variable_header_in PARAMS ((bfd *));
56
57 static boolean nlm_swap_auxiliary_headers_in PARAMS ((bfd *));
58
59 static struct sec *section_from_nlm_index PARAMS ((bfd *, int));
60
61 static int nlm_section_from_bfd_section PARAMS ((bfd *, struct sec *));
62
63 static boolean nlm_slurp_symbol_table PARAMS ((bfd *, asymbol **));
64
65 static int nlm_symbol_from_bfd_symbol
66   PARAMS ((bfd *, struct symbol_cache_entry **));
67
68 static void nlm_map_symbols PARAMS ((bfd *));
69
70 /* Should perhaps use put_offset, put_word, etc.  For now, the two versions
71    can be handled by explicitly specifying 32 bits or "the long type".  */
72 #if ARCH_SIZE == 64
73 #define put_word        bfd_h_put_64
74 #define get_word        bfd_h_get_64
75 #endif
76 #if ARCH_SIZE == 32
77 #define put_word        bfd_h_put_32
78 #define get_word        bfd_h_get_32
79 #endif
80
81 bfd_target *
82 DEFUN (nlm_object_p, (abfd), bfd * abfd)
83 {
84   Nlm_External_Fixed_Header x_fxdhdr;   /* Nlm file header, external form */
85   Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
86   int shindex;
87
88   /* Read in the fixed length portion of the NLM header in external format.  */
89
90   if (bfd_read ((PTR) &x_fxdhdr, sizeof (x_fxdhdr), 1, abfd) !=
91       sizeof (x_fxdhdr))
92     {
93       bfd_error = system_call_error;
94       return (NULL);
95     }
96
97   /* Check to see if we have an NLM file by matching the NLM signature. */
98
99   if (strncmp (&x_fxdhdr.signature, NLM_SIGNATURE, NLM_SIGNATURE_SIZE) != 0)
100     {
101     wrong:
102       bfd_error = wrong_format;
103       return (NULL);
104     }
105
106   /* There's no supported way to discover the endianess of an NLM, so test for
107      a sane version number after doing byte swapping appropriate for this
108      XVEC.  (Hack alert!) */
109
110   if (get_word (abfd, (bfd_byte *) &x_fxdhdr.version) > 0xFFFF)
111     {
112       goto wrong;
113     }
114
115   /* There's no supported way to check for 32 bit versus 64 bit addresses,
116      so ignore this distinction for now.  (FIXME) */
117
118   /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
119      the tdata pointer in the bfd. */
120
121   nlm_tdata (abfd) = (struct nlm_obj_tdata *)
122     bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata));
123   if (nlm_tdata (abfd) == NULL)
124     {
125       bfd_error = no_memory;
126       return (NULL);
127     }
128
129   /* FIXME:  Any `wrong' exits below here will leak memory (tdata).  */
130
131   /* Swap in the rest of the fixed length header. */
132
133   i_fxdhdrp = nlm_fixed_header (abfd);
134   nlm_swap_fixed_header_in (abfd, &x_fxdhdr, i_fxdhdrp);
135
136   if (!nlm_swap_variable_header_in (abfd)
137       || !nlm_swap_auxiliary_headers_in (abfd)
138       || !add_bfd_section (abfd, NLM_CODE_NAME,
139                            i_fxdhdrp -> codeImageOffset,
140                            i_fxdhdrp -> codeImageSize,
141                            SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
142       || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
143                            i_fxdhdrp -> dataImageOffset,
144                            i_fxdhdrp -> dataImageSize,
145                            SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
146       || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
147                            (file_ptr) 0,
148                            i_fxdhdrp -> uninitializedDataSize,
149                            SEC_DATA | SEC_ALLOC))
150     {
151       return (NULL);
152     }
153
154   return (abfd -> xvec);
155 }
156
157 /* Add a section to the bfd. */
158
159 static boolean
160 DEFUN (add_bfd_section, (abfd, name, offset, size, flags),
161        bfd *abfd AND
162        char *name AND
163        file_ptr offset AND
164        bfd_size_type size AND
165        flagword flags)
166 {
167   asection *newsect;
168
169   newsect = bfd_make_section (abfd, name);
170   if (newsect == NULL)
171     {
172       return (false);
173     }
174   newsect -> vma = 0;                           /* NLM's are relocatable. */
175   newsect -> _raw_size = size;
176   newsect -> filepos = offset;
177   newsect -> flags = flags;
178   newsect -> alignment_power = bfd_log2 (0);    /* FIXME */
179   return (true);
180 }
181
182
183 /* Translate an NLM fixed length file header in external format into an NLM
184    file header in internal format. */
185
186 static void
187 DEFUN (nlm_swap_fixed_header_in, (abfd, src, dst),
188        bfd * abfd AND
189        Nlm_External_Fixed_Header * src AND
190        Nlm_Internal_Fixed_Header * dst)
191 {
192   memcpy (dst -> signature, src -> signature, NLM_SIGNATURE_SIZE);
193   memcpy (dst -> moduleName, src -> moduleName, NLM_MODULE_NAME_SIZE);
194   dst -> version =
195     get_word (abfd, (bfd_byte *) src -> version);
196   dst -> codeImageOffset =
197     get_word (abfd, (bfd_byte *) src -> codeImageOffset);
198   dst -> codeImageSize =
199     get_word (abfd, (bfd_byte *) src -> codeImageSize);
200   dst -> dataImageOffset =
201     get_word (abfd, (bfd_byte *) src -> dataImageOffset);
202   dst -> dataImageSize =
203     get_word (abfd, (bfd_byte *) src -> dataImageSize);
204   dst -> uninitializedDataSize =
205     get_word (abfd, (bfd_byte *) src -> uninitializedDataSize);
206   dst -> customDataOffset =
207     get_word (abfd, (bfd_byte *) src -> customDataOffset);
208   dst -> customDataSize =
209     get_word (abfd, (bfd_byte *) src -> customDataSize);
210   dst -> moduleDependencyOffset =
211     get_word (abfd, (bfd_byte *) src -> moduleDependencyOffset);
212   dst -> numberOfModuleDependencies =
213     get_word (abfd, (bfd_byte *) src -> numberOfModuleDependencies);
214   dst -> relocationFixupOffset =
215     get_word (abfd, (bfd_byte *) src -> relocationFixupOffset);
216   dst -> numberOfRelocationFixups =
217     get_word (abfd, (bfd_byte *) src -> numberOfRelocationFixups);
218   dst -> externalReferencesOffset =
219     get_word (abfd, (bfd_byte *) src -> externalReferencesOffset);
220   dst -> numberOfExternalReferences =
221     get_word (abfd, (bfd_byte *) src -> numberOfExternalReferences);
222   dst -> publicsOffset =
223     get_word (abfd, (bfd_byte *) src -> publicsOffset);
224   dst -> numberOfPublics =
225     get_word (abfd, (bfd_byte *) src -> numberOfPublics);
226   dst -> debugInfoOffset =
227     get_word (abfd, (bfd_byte *) src -> debugInfoOffset);
228   dst -> numberOfDebugRecords =
229     get_word (abfd, (bfd_byte *) src -> numberOfDebugRecords);
230   dst -> codeStartOffset =
231     get_word (abfd, (bfd_byte *) src -> codeStartOffset);
232   dst -> exitProcedureOffset =
233     get_word (abfd, (bfd_byte *) src -> exitProcedureOffset);
234   dst -> checkUnloadProcedureOffset =
235     get_word (abfd, (bfd_byte *) src -> checkUnloadProcedureOffset);
236   dst -> moduleType =
237     get_word (abfd, (bfd_byte *) src -> moduleType);
238   dst -> flags = 
239     get_word (abfd, (bfd_byte *) src -> flags);
240 }
241
242 /* Read and swap in the variable length header.  All the fields must
243    exist in the NLM, and must exist in the order they are read here. */
244
245 static boolean
246 DEFUN (nlm_swap_variable_header_in, (abfd),
247        bfd * abfd)
248 {
249   unsigned char temp [TARGET_LONG_SIZE];
250
251   /* Read the description length and text members. */
252
253   if (bfd_read ((PTR) &nlm_variable_header (abfd) -> descriptionLength,
254                 sizeof (nlm_variable_header (abfd) -> descriptionLength),
255                 1, abfd) !=
256       sizeof (nlm_variable_header (abfd) -> descriptionLength))
257     {
258       bfd_error = system_call_error;
259       return (false);
260     }
261   if (bfd_read ((PTR) nlm_variable_header (abfd) -> descriptionText,
262                 nlm_variable_header (abfd) -> descriptionLength + 1,
263                 1, abfd) !=
264       nlm_variable_header (abfd) -> descriptionLength + 1)
265     {
266       bfd_error = system_call_error;
267       return (false);
268     }
269
270   /* Read and convert the stackSize field. */
271
272   if (bfd_read ((PTR) &temp, sizeof (temp), 1, abfd) != sizeof (temp))
273     {
274       bfd_error = system_call_error;
275       return (false);
276     }
277   nlm_variable_header (abfd) -> stackSize = get_word (abfd, (bfd_byte *) temp);
278
279   /* Read and convert the reserved field. */
280
281   if (bfd_read ((PTR) &temp, sizeof (temp), 1, abfd) != sizeof (temp))
282     {
283       bfd_error = system_call_error;
284       return (false);
285     }
286   nlm_variable_header (abfd) -> reserved = get_word (abfd, (bfd_byte *) temp);
287
288   /* Read the oldThreadName field.  This field is a fixed length string. */
289
290   if (bfd_read ((PTR) nlm_variable_header (abfd) -> oldThreadName,
291                 sizeof (nlm_variable_header (abfd) -> oldThreadName),
292                 1, abfd) !=
293       sizeof (nlm_variable_header (abfd) -> oldThreadName))
294     {
295       bfd_error = system_call_error;
296       return (false);
297     }
298
299   /* Read the screen name length and text members. */
300
301   if (bfd_read ((PTR) &nlm_variable_header (abfd) -> screenNameLength,
302                 sizeof (nlm_variable_header (abfd) -> screenNameLength),
303                 1, abfd) !=
304       sizeof (nlm_variable_header (abfd) -> screenNameLength))
305     {
306       bfd_error = system_call_error;
307       return (false);
308     }
309   if (bfd_read ((PTR) nlm_variable_header (abfd) -> screenName,
310                 nlm_variable_header (abfd) -> screenNameLength + 1,
311                 1, abfd) !=
312       nlm_variable_header (abfd) -> screenNameLength + 1)
313     {
314       bfd_error = system_call_error;
315       return (false);
316     }
317
318   /* Read the thread name length and text members. */
319
320   if (bfd_read ((PTR) &nlm_variable_header (abfd) -> threadNameLength,
321                 sizeof (nlm_variable_header (abfd) -> threadNameLength),
322                 1, abfd) !=
323       sizeof (nlm_variable_header (abfd) -> threadNameLength))
324     {
325       bfd_error = system_call_error;
326       return (false);
327     }
328   if (bfd_read ((PTR) nlm_variable_header (abfd) -> threadName,
329                 nlm_variable_header (abfd) -> threadNameLength + 1,
330                 1, abfd) !=
331       nlm_variable_header (abfd) -> threadNameLength + 1)
332     {
333       bfd_error = system_call_error;
334       return (false);
335     }
336   return (true);
337 }
338
339 /* Read and swap in the contents of all the auxiliary headers.  Because of
340    the braindead design, we have to do strcmps on strings of indeterminate
341    length to figure out what each auxiliary header is.  Even worse, we have
342    no way of knowing how many auxiliary headers there are or where the end
343    of the auxiliary headers are, except by finding something that doesn't
344    look like a known auxiliary header.  This means that the first new type
345    of auxiliary header added will break all existing tools that don't
346    recognize it. */
347
348 static boolean
349 DEFUN (nlm_swap_auxiliary_headers_in, (abfd),
350        bfd * abfd)
351 {
352   unsigned char temp [TARGET_LONG_SIZE];
353   unsigned char tempstr [16];
354   long position;
355
356   for (;;)
357     {
358       position = bfd_tell (abfd);
359       if (bfd_read ((PTR) tempstr, sizeof (tempstr), 1, abfd) !=
360           sizeof (tempstr))
361         {
362           bfd_error = system_call_error;
363           return (false);
364         }
365       if (bfd_seek (abfd, position, SEEK_SET) == -1)
366         {
367           bfd_error = system_call_error;
368           return (false);
369         }
370       if (strncmp (tempstr, "VeRsIoN#", 8) == 0)
371         {
372           Nlm_External_Version_Header thdr;
373           if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
374             {
375               bfd_error = system_call_error;
376               return (false);
377             }
378           memcpy (nlm_version_header (abfd) -> stamp, thdr.stamp,
379                   sizeof (thdr.stamp));
380           nlm_version_header (abfd) -> majorVersion =
381             get_word (abfd, (bfd_byte *) thdr.majorVersion);
382           nlm_version_header (abfd) -> minorVersion =
383             get_word (abfd, (bfd_byte *) thdr.minorVersion);
384           nlm_version_header (abfd) -> revision =
385             get_word (abfd, (bfd_byte *) thdr.revision);
386           nlm_version_header (abfd) -> year =
387             get_word (abfd, (bfd_byte *) thdr.year);
388           nlm_version_header (abfd) -> month =
389             get_word (abfd, (bfd_byte *) thdr.month);
390           nlm_version_header (abfd) -> day =
391             get_word (abfd, (bfd_byte *) thdr.day);
392         }
393       else if (strncmp (tempstr, "MeSsAgEs", 8) == 0)
394         {
395           Nlm_External_Extended_Header thdr;
396           if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
397             {
398               bfd_error = system_call_error;
399               return (false);
400             }
401           memcpy (nlm_extended_header (abfd) -> stamp, thdr.stamp,
402                   sizeof (thdr.stamp));
403           nlm_extended_header (abfd) -> languageID =
404             get_word (abfd, (bfd_byte *) thdr.languageID);
405           nlm_extended_header (abfd) -> messageFileOffset =
406             get_word (abfd, (bfd_byte *) thdr.messageFileOffset);
407           nlm_extended_header (abfd) -> messageFileLength =
408             get_word (abfd, (bfd_byte *) thdr.messageFileLength);
409           nlm_extended_header (abfd) -> messageCount =
410             get_word (abfd, (bfd_byte *) thdr.messageCount);
411           nlm_extended_header (abfd) -> helpFileOffset =
412             get_word (abfd, (bfd_byte *) thdr.helpFileOffset);
413           nlm_extended_header (abfd) -> helpFileLength =
414             get_word (abfd, (bfd_byte *) thdr.helpFileLength);
415           nlm_extended_header (abfd) -> RPCDataOffset =
416             get_word (abfd, (bfd_byte *) thdr.RPCDataOffset);
417           nlm_extended_header (abfd) -> RPCDataLength =
418             get_word (abfd, (bfd_byte *) thdr.RPCDataLength);
419           nlm_extended_header (abfd) -> sharedCodeOffset =
420             get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset);
421           nlm_extended_header (abfd) -> sharedCodeLength =
422             get_word (abfd, (bfd_byte *) thdr.sharedCodeLength);
423           nlm_extended_header (abfd) -> sharedDataOffset =
424             get_word (abfd, (bfd_byte *) thdr.sharedDataOffset);
425           nlm_extended_header (abfd) -> sharedDataLength =
426             get_word (abfd, (bfd_byte *) thdr.sharedDataLength);
427           nlm_extended_header (abfd) -> sharedRelocationFixupOffset =
428             get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset);
429           nlm_extended_header (abfd) -> sharedRelocationFixupCount =
430             get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount);
431           nlm_extended_header (abfd) -> sharedExternalReferenceOffset =
432             get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset);
433           nlm_extended_header (abfd) -> sharedExternalReferenceCount =
434             get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount);
435           nlm_extended_header (abfd) -> sharedPublicsOffset =
436             get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
437           nlm_extended_header (abfd) -> sharedPublicsCount =
438             get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
439           nlm_extended_header (abfd) -> SharedInitializationOffset =
440             get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
441           nlm_extended_header (abfd) -> SharedExitProcedureOffset =
442             get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset);
443           nlm_extended_header (abfd) -> productID =
444             get_word (abfd, (bfd_byte *) thdr.productID);
445           nlm_extended_header (abfd) -> reserved0 =
446             get_word (abfd, (bfd_byte *) thdr.reserved0);
447           nlm_extended_header (abfd) -> reserved1 =
448             get_word (abfd, (bfd_byte *) thdr.reserved1);
449           nlm_extended_header (abfd) -> reserved2 =
450             get_word (abfd, (bfd_byte *) thdr.reserved2);
451           nlm_extended_header (abfd) -> reserved3 =
452             get_word (abfd, (bfd_byte *) thdr.reserved3);
453           nlm_extended_header (abfd) -> reserved4 =
454             get_word (abfd, (bfd_byte *) thdr.reserved4);
455           nlm_extended_header (abfd) -> reserved5 =
456             get_word (abfd, (bfd_byte *) thdr.reserved5);
457         }
458       else if (strncmp (tempstr, "CuStHeAd", 8) == 0)
459         {
460           Nlm_External_Custom_Header thdr;
461           if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
462             {
463               bfd_error = system_call_error;
464               return (false);
465             }
466           memcpy (nlm_custom_header (abfd) -> stamp, thdr.stamp,
467                   sizeof (thdr.stamp));
468           nlm_custom_header (abfd) -> dataLength =
469             get_word (abfd, (bfd_byte *) thdr.dataLength);
470           nlm_custom_header (abfd) -> debugRecOffset =
471             get_word (abfd, (bfd_byte *) thdr.debugRecOffset);
472           nlm_custom_header (abfd) -> debugRecLength =
473             get_word (abfd, (bfd_byte *) thdr.debugRecLength);
474         }
475       else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
476         {
477           Nlm_External_Copyright_Header thdr;
478           if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
479             {
480               bfd_error = system_call_error;
481               return (false);
482             }
483           memcpy (nlm_copyright_header (abfd) -> stamp, thdr.stamp,
484                   sizeof (thdr.stamp));
485           nlm_copyright_header (abfd) -> copyrightMessageLength =
486             get_word (abfd, (bfd_byte *) thdr.copyrightMessageLength);
487           /* The copyright message is a variable length string. */
488           if (bfd_read ((PTR) nlm_copyright_header (abfd) -> copyrightMessage,
489                         nlm_copyright_header (abfd) -> copyrightMessageLength + 1,
490                         1, abfd) !=
491               nlm_copyright_header (abfd) -> copyrightMessageLength + 1)
492             {
493               bfd_error = system_call_error;
494               return (false);
495             }
496         }
497       else
498         {
499           break;
500         }
501     }
502 }
503
504 /* We read the NLM's public symbols and use it to generate a bfd symbol
505    table (hey, it's better than nothing) on a one-for-one basis.  Thus
506    use the number of public symbols as the number of bfd symbols we will
507    have once we actually get around to reading them in.
508
509    Return the number of bytes required to hold the symtab vector, based on
510    the count plus 1, since we will NULL terminate the vector allocated based
511    on this size. */
512
513 unsigned int
514 DEFUN (nlm_get_symtab_upper_bound, (abfd), bfd * abfd)
515 {
516   Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
517   unsigned int symcount;
518   unsigned int symtab_size = 0;
519
520   i_fxdhdrp = nlm_fixed_header (abfd);
521   symcount = i_fxdhdrp -> numberOfPublics;
522   symtab_size = (symcount + 1) * (sizeof (asymbol));
523   return (symtab_size);
524 }
525
526 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
527    symbol table fails. */
528
529 unsigned int
530 DEFUN (nlm_get_symtab, (abfd, alocation),
531        bfd *abfd AND
532        asymbol **alocation)
533 {
534   nlm_slurp_symbol_table (abfd, alocation);
535   return (bfd_get_symcount (abfd));
536 }
537
538 asymbol *
539 DEFUN (nlm_make_empty_symbol, (abfd),           /* FIXME! */
540       bfd * abfd)
541 {
542   asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
543   new -> the_bfd = abfd;
544   return new;
545 }
546
547 void
548 DEFUN (nlm_get_symbol_info, (ignore_abfd, symbol, ret),
549        bfd * ignore_abfd AND
550        asymbol * symbol AND
551        symbol_info * ret)
552 {
553   bfd_symbol_info (symbol, ret);
554 }
555
556 boolean
557 DEFUN (nlm_set_arch_mach, (abfd, arch, machine),
558        bfd * abfd AND
559        enum bfd_architecture arch AND
560        unsigned long machine)
561 {
562    return false;
563 }
564
565 /* Slurp in nlm symbol table.
566
567    In the external (in-file) form, NLM export records are variable length,
568    with the following form:
569
570         1 byte          length of the symbol name (N)
571         N bytes         the symbol name
572         4 bytes         the symbol offset from start of it's section
573
574    Note that we currently ignore the internal debug records.  There is
575    a lot of duplication between the export records and the internal debug
576    records.  We may in the future, want to merge the information from the
577    debug records with the information from the export records to produce
578    a more complete symbol table, treating additional information from the
579    debug records as static symbols. (FIXME)
580
581    If SYMPTRS is non-NULL, the bfd symbols are copied to where it points.
582
583    When we return, the bfd symcount is either zero or contains the correct
584    number of symbols.
585 */
586
587 static boolean
588 DEFUN (nlm_slurp_symbol_table, (abfd, symptrs),
589        bfd *abfd AND
590        asymbol **symptrs)       /* Buffer for generated bfd symbols */
591 {
592   Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
593   int symcount;                         /* Number of external NLM symbols */
594   int idx;
595   nlm_symbol_type *sym;                 /* Pointer to current bfd symbol */
596   nlm_symbol_type *symbase;             /* Buffer for generated bfd symbols */
597   char symlength;                       /* Symbol length read into here */
598   long symoffset;                       /* Symbol offset read into here */
599
600   if (bfd_get_outsymbols (abfd) != NULL)
601     {
602       return (true);
603     }
604
605   /* Read each raw NLM symbol, using the information to create a canonical bfd
606      symbol table entry.
607
608      Note that we allocate the initial bfd canonical symbol buffer based on a
609      one-to-one mapping of the NLM symbols to canonical symbols.  We actually
610      use all the NLM symbols, so there will be no space left over at the end.
611      When we have all the symbols, we build the caller's pointer vector. */
612
613   abfd -> symcount = 0;
614   i_fxdhdrp = nlm_fixed_header (abfd);
615   symcount = i_fxdhdrp -> numberOfPublics;
616   if (symcount == 0)
617     {
618       return (true);
619     }
620   if (bfd_seek (abfd, i_fxdhdrp -> publicsOffset, SEEK_SET) == -1)
621     {
622       bfd_error = system_call_error;
623       return (false);
624     }
625   symbase = (nlm_symbol_type *)
626     bfd_zalloc (abfd, symcount * sizeof (nlm_symbol_type));
627   sym = symbase;
628
629   /* We use the bfd's symcount directly as the control count, so that early
630      termination of the loop leaves the symcount correct for the symbols that
631      were read. */
632
633   while (abfd -> symcount < symcount)
634     {
635       if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
636           != sizeof (symlength))
637         {
638           bfd_error = system_call_error;
639           return (false);
640         }
641       sym -> symbol.the_bfd = abfd;
642       sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
643       if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
644           != symlength)
645         {
646           bfd_error = system_call_error;
647           return (false);
648         }
649       if (bfd_read ((PTR) &symoffset, sizeof (symoffset), 1, abfd)
650           != sizeof (symoffset))
651         {
652           bfd_error = system_call_error;
653           return (false);
654         }
655       sym -> symbol.flags = BSF_GLOBAL | BSF_EXPORT;
656       sym -> symbol.value = get_word (abfd, (bfd_byte *) &symoffset);
657       if (sym -> symbol.value & MSB)
658         {
659           sym -> symbol.value &= ~MSB;
660           sym -> symbol.flags |= BSF_FUNCTION;
661           sym -> symbol.section =
662             bfd_get_section_by_name (abfd, NLM_CODE_NAME);
663         }
664       else
665         {
666           sym -> symbol.section =
667             bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
668         }
669       abfd -> symcount++;
670       sym++;
671     }
672
673   /* Fill in the user's symbol pointer vector if needed.  */
674
675   if (symptrs != NULL)
676     {
677       sym = symbase;
678       symcount = abfd -> symcount;
679       while (symcount-- > 0)
680         {
681           *symptrs++ = &sym -> symbol;
682           sym++;
683         }
684       *symptrs = NULL;          /* Final NULL pointer */
685     }
686
687   return (true);
688 }
689