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