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