* nlmcode.h (nlm_get_reloc_upper_bound): Test return value
[deliverable/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) == false)
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) == false)
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 It also looks over the symbols and moves any common symbols into
1343 the .bss section; NLM has no way to represent a common symbol.
1344 This approach means that either the symbols must already have been
1345 set at this point, or there must be no common symbols. We need to
1346 move the symbols at this point so that mangle_relocs can see the
1347 final values. */
1348
1349 static boolean
1350 nlm_compute_section_file_positions (abfd)
1351 bfd *abfd;
1352 {
1353 file_ptr sofar;
1354 asection *sec;
1355 bfd_vma text, data, bss;
1356 bfd_vma text_low, data_low;
1357 int text_align, data_align, other_align;
1358 file_ptr text_ptr, data_ptr, other_ptr;
1359 asymbol **sym_ptr_ptr;
1360
1361 if (abfd->output_has_begun == true)
1362 return true;
1363
1364 abfd->output_has_begun = true;
1365
1366 /* The fixed header. */
1367 sofar = sizeof (Nlm_External_Fixed_Header);
1368
1369 /* The variable header. */
1370 sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
1371 + nlm_variable_header (abfd) -> descriptionLength + 1
1372 + NLM_TARGET_LONG_SIZE /* stackSize */
1373 + NLM_TARGET_LONG_SIZE /* reserved */
1374 + sizeof (nlm_variable_header (abfd) -> oldThreadName)
1375 + sizeof (nlm_variable_header (abfd) -> screenNameLength)
1376 + nlm_variable_header (abfd) -> screenNameLength + 1
1377 + sizeof (nlm_variable_header (abfd) -> threadNameLength)
1378 + nlm_variable_header (abfd) -> threadNameLength + 1);
1379
1380 /* The auxiliary headers. */
1381 if (find_nonzero ((PTR) nlm_version_header (abfd),
1382 sizeof (Nlm_Internal_Version_Header)))
1383 sofar += sizeof (Nlm_External_Version_Header);
1384 if (find_nonzero ((PTR) nlm_extended_header (abfd),
1385 sizeof (Nlm_Internal_Extended_Header)))
1386 sofar += sizeof (Nlm_External_Extended_Header);
1387 if (find_nonzero ((PTR) nlm_custom_header (abfd),
1388 sizeof (Nlm_Internal_Custom_Header)))
1389 sofar += sizeof (Nlm_External_Custom_Header);
1390 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
1391 sizeof (Nlm_Internal_Copyright_Header)))
1392 sofar += (sizeof (Nlm_External_Copyright_Header)
1393 + nlm_copyright_header (abfd) -> copyrightMessageLength + 1);
1394
1395 /* Compute the section file positions in two passes. First get the
1396 sizes of the text and data sections, and then set the file
1397 positions. This code aligns the sections in the file using the
1398 same alignment restrictions that apply to the sections in memory;
1399 this may not be necessary. */
1400 text = 0;
1401 text_low = (bfd_vma) -1;
1402 text_align = 0;
1403 data = 0;
1404 data_low = (bfd_vma) -1;
1405 data_align = 0;
1406 bss = 0;
1407 other_align = 0;
1408 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1409 {
1410 flagword f;
1411
1412 sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
1413
1414 f = bfd_get_section_flags (abfd, sec);
1415 if (f & SEC_CODE)
1416 {
1417 text += sec->_raw_size;
1418 if (bfd_get_section_vma (abfd, sec) < text_low)
1419 text_low = bfd_get_section_vma (abfd, sec);
1420 if (sec->alignment_power > text_align)
1421 text_align = sec->alignment_power;
1422 }
1423 else if (f & SEC_DATA)
1424 {
1425 data += sec->_raw_size;
1426 if (bfd_get_section_vma (abfd, sec) < data_low)
1427 data_low = bfd_get_section_vma (abfd, sec);
1428 if (sec->alignment_power > data_align)
1429 data_align = sec->alignment_power;
1430 }
1431 else if (f & SEC_HAS_CONTENTS)
1432 {
1433 if (sec->alignment_power > other_align)
1434 other_align = sec->alignment_power;
1435 }
1436 else if (f & SEC_ALLOC)
1437 bss += sec->_raw_size;
1438 }
1439
1440 nlm_set_text_low (abfd, text_low);
1441 nlm_set_data_low (abfd, data_low);
1442
1443 text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1444 data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1445 other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1446
1447 /* Fill in some fields in the header for which we now have the
1448 information. */
1449 nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1450 nlm_fixed_header (abfd)->codeImageSize = text;
1451 nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1452 nlm_fixed_header (abfd)->dataImageSize = data;
1453 nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1454
1455 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1456 {
1457 flagword f;
1458
1459 f = bfd_get_section_flags (abfd, sec);
1460
1461 if (f & SEC_CODE)
1462 {
1463 sec->filepos = text_ptr;
1464 text_ptr += sec->_raw_size;
1465 }
1466 else if (f & SEC_DATA)
1467 {
1468 sec->filepos = data_ptr;
1469 data_ptr += sec->_raw_size;
1470 }
1471 else if (f & SEC_HAS_CONTENTS)
1472 {
1473 sec->filepos = other_ptr;
1474 other_ptr += sec->_raw_size;
1475 }
1476 }
1477
1478 nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1479
1480 /* Move all common symbols into the .bss section. */
1481
1482 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1483 if (sym_ptr_ptr != NULL)
1484 {
1485 asymbol **sym_end;
1486 asection *bss_sec;
1487 bfd_vma add;
1488
1489 /* Make sure we have a section to hold uninitialized data. */
1490 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1491 if (bss_sec == NULL)
1492 {
1493 if (! add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
1494 (file_ptr) 0, (bfd_size_type) 0,
1495 SEC_ALLOC))
1496 return false;
1497 bss_sec = bfd_get_section_by_name (abfd,
1498 NLM_UNINITIALIZED_DATA_NAME);
1499 bss_sec->vma = data_low + data;
1500 }
1501
1502 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1503 add = 0;
1504 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1505 {
1506 asymbol *sym;
1507 bfd_vma size;
1508
1509 sym = *sym_ptr_ptr;
1510
1511 if (! bfd_is_com_section (bfd_get_section (sym)))
1512 continue;
1513
1514 /* Put the common symbol in the .bss section, and increase
1515 the size of the .bss section by the size of the common
1516 symbol (which is the old value of the symbol). */
1517 sym->section = bss_sec;
1518 size = sym->value;
1519 sym->value = bss_sec->_raw_size + add;
1520 add += size;
1521 add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
1522 }
1523 nlm_fixed_header (abfd)->uninitializedDataSize += add;
1524 bss_sec->_raw_size += add;
1525 }
1526
1527 return true;
1528 }
1529
1530 /* Set the contents of a section. To do this we need to know where
1531 the section is going to be located in the output file. That means
1532 that the sizes of all the sections must be set, and all the
1533 variable size header information must be known. */
1534
1535 boolean
1536 nlm_set_section_contents (abfd, section, location, offset, count)
1537 bfd *abfd;
1538 asection *section;
1539 PTR location;
1540 file_ptr offset;
1541 bfd_size_type count;
1542 {
1543 if (abfd->output_has_begun == false
1544 && nlm_compute_section_file_positions (abfd) == false)
1545 return false;
1546
1547 if (count == 0)
1548 return true;
1549
1550 /* i386 NetWare has a very restricted set of relocs. In order for
1551 objcopy to work, the NLM i386 backend needs a chance to rework
1552 the section contents so that its set of relocs will work. If all
1553 the relocs are already acceptable, this will not do anything. */
1554 if (section->reloc_count != 0)
1555 {
1556 boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR data,
1557 bfd_vma offset,
1558 bfd_size_type count));
1559
1560 mangle_relocs_func = nlm_mangle_relocs_func (abfd);
1561 if (mangle_relocs_func != NULL)
1562 {
1563 if (! (*mangle_relocs_func) (abfd, section, location,
1564 (bfd_vma) offset, count))
1565 return false;
1566 }
1567 }
1568
1569 if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
1570 || bfd_write (location, 1, count, abfd) != count)
1571 {
1572 bfd_error = system_call_error;
1573 return false;
1574 }
1575
1576 return true;
1577 }
1578
1579 /* We need to sort a list of relocs associated with sections when we
1580 write out the external relocs. */
1581
1582 struct reloc_and_sec
1583 {
1584 arelent *rel;
1585 asection *sec;
1586 };
1587
1588 static int
1589 nlm_external_reloc_compare (p1, p2)
1590 const void *p1;
1591 const void *p2;
1592 {
1593 const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
1594 const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
1595
1596 return strcmp ((*r1->rel->sym_ptr_ptr)->name,
1597 (*r2->rel->sym_ptr_ptr)->name);
1598 }
1599
1600 /* Write out an NLM file. We write out the information in this order:
1601 fixed header
1602 variable header
1603 auxiliary headers
1604 code sections
1605 data sections
1606 other sections (custom data, messages, help, shared NLM, RPC,
1607 module dependencies)
1608 relocation fixups
1609 external references (imports)
1610 public symbols (exports)
1611 debugging records
1612 This is similar to the order used by the NetWare tools; the
1613 difference is that NetWare puts the sections other than code, data
1614 and custom data at the end of the NLM. It is convenient for us to
1615 know where the sections are going to be before worrying about the
1616 size of the other information.
1617
1618 By the time this function is called, all the section data should
1619 have been output using set_section_contents. Note that custom
1620 data, the message file, the help file, the shared NLM file, the RPC
1621 data, and the module dependencies are all considered to be
1622 sections; the caller is responsible for filling in the offset and
1623 length fields in the NLM headers. The relocation fixups and
1624 imports are both obtained from the list of relocs attached to each
1625 section. The exports and debugging records are obtained from the
1626 list of outsymbols. */
1627
1628 boolean
1629 nlm_write_object_contents (abfd)
1630 bfd *abfd;
1631 {
1632 Nlm_External_Fixed_Header fixed_header;
1633 asection *sec;
1634 boolean (*write_reloc_func) PARAMS ((bfd *, asection *, arelent *));
1635 bfd_size_type external_reloc_count, internal_reloc_count, i, c;
1636 struct reloc_and_sec *external_relocs;
1637 asymbol **sym_ptr_ptr;
1638
1639 if (abfd->output_has_begun == false
1640 && nlm_compute_section_file_positions (abfd) == false)
1641 return false;
1642
1643 /* Write out the variable length headers. */
1644 if (bfd_seek (abfd, sizeof (Nlm_External_Fixed_Header), SEEK_SET) != 0)
1645 {
1646 bfd_error = system_call_error;
1647 return false;
1648 }
1649 if (nlm_swap_variable_header_out (abfd) == false
1650 || nlm_swap_auxiliary_headers_out (abfd) == false)
1651 {
1652 bfd_error = system_call_error;
1653 return false;
1654 }
1655
1656 /* A weak check on whether the section file positions were
1657 reasonable. */
1658 if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
1659 {
1660 bfd_error = invalid_operation;
1661 return false;
1662 }
1663
1664 /* Advance to the relocs. */
1665 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1666 SEEK_SET) != 0)
1667 {
1668 bfd_error = system_call_error;
1669 return false;
1670 }
1671
1672 /* The format of the relocation entries is dependent upon the
1673 particular target. We use an external routine to write the reloc
1674 out. */
1675 write_reloc_func = nlm_write_reloc_func (abfd);
1676
1677 /* Write out the internal relocation fixups. While we're looping
1678 over the relocs, we also count the external relocs, which is
1679 needed when they are written out below. */
1680 internal_reloc_count = 0;
1681 external_reloc_count = 0;
1682 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1683 {
1684 arelent **rel_ptr_ptr, **rel_end;
1685
1686 if (sec->reloc_count == 0)
1687 continue;
1688
1689 /* We can only represent relocs within a code or data
1690 section. */
1691 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1692 {
1693 bfd_error = invalid_operation;
1694 return false;
1695 }
1696
1697 /* We need to know how to write out relocs. */
1698 if (write_reloc_func == NULL)
1699 {
1700 bfd_error = invalid_operation;
1701 return false;
1702 }
1703
1704 rel_ptr_ptr = sec->orelocation;
1705 rel_end = rel_ptr_ptr + sec->reloc_count;
1706 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1707 {
1708 arelent *rel;
1709 asymbol *sym;
1710
1711 rel = *rel_ptr_ptr;
1712 sym = *rel->sym_ptr_ptr;
1713
1714 if (bfd_get_section (sym) != &bfd_und_section)
1715 {
1716 ++internal_reloc_count;
1717 if ((*write_reloc_func) (abfd, sec, rel) == false)
1718 return false;
1719 }
1720 else
1721 ++external_reloc_count;
1722 }
1723 }
1724 nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
1725
1726 /* Write out the imports (relocs against external symbols). These
1727 are output as a symbol name followed by all the relocs for that
1728 symbol, so we must first gather together all the relocs against
1729 external symbols and sort them. */
1730 external_relocs =
1731 (struct reloc_and_sec *) bfd_alloc (abfd,
1732 (external_reloc_count
1733 * sizeof (struct reloc_and_sec)));
1734 if (external_relocs == (struct reloc_and_sec *) NULL)
1735 {
1736 bfd_error = no_memory;
1737 return false;
1738 }
1739 i = 0;
1740 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1741 {
1742 arelent **rel_ptr_ptr, **rel_end;
1743
1744 if (sec->reloc_count == 0)
1745 continue;
1746
1747 rel_ptr_ptr = sec->orelocation;
1748 rel_end = rel_ptr_ptr + sec->reloc_count;
1749 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1750 {
1751 arelent *rel;
1752 asymbol *sym;
1753
1754 rel = *rel_ptr_ptr;
1755 sym = *rel->sym_ptr_ptr;
1756
1757 if (bfd_get_section (sym) != &bfd_und_section)
1758 continue;
1759
1760 external_relocs[i].rel = rel;
1761 external_relocs[i].sec = sec;
1762 ++i;
1763 }
1764 }
1765
1766 BFD_ASSERT (i == external_reloc_count);
1767
1768 /* Sort the external relocs by name. */
1769 qsort (external_relocs, external_reloc_count,
1770 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
1771
1772 /* Write out the external relocs. */
1773 nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
1774 c = 0;
1775 i = 0;
1776 while (i < external_reloc_count)
1777 {
1778 arelent *rel;
1779 asymbol *sym;
1780 bfd_byte len;
1781 bfd_size_type j, cnt;
1782 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1783
1784 ++c;
1785
1786 rel = external_relocs[i].rel;
1787 sym = *rel->sym_ptr_ptr;
1788
1789 len = strlen (sym->name);
1790 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1791 != sizeof (bfd_byte))
1792 || bfd_write (sym->name, len, 1, abfd) != len)
1793 {
1794 bfd_error = system_call_error;
1795 return false;
1796 }
1797
1798 cnt = 0;
1799 for (j = i;
1800 (j < external_reloc_count
1801 && *external_relocs[j].rel->sym_ptr_ptr == sym);
1802 j++)
1803 ++cnt;
1804
1805 put_word (abfd, (bfd_vma) cnt, temp);
1806 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1807 {
1808 bfd_error = system_call_error;
1809 return false;
1810 }
1811
1812 while (cnt-- != 0)
1813 {
1814 if ((*write_reloc_func) (abfd, external_relocs[i].sec,
1815 external_relocs[i].rel) == false)
1816 return false;
1817 ++i;
1818 }
1819 }
1820 nlm_fixed_header (abfd)->numberOfExternalReferences = c;
1821
1822 /* Write out the public symbols (exports). */
1823 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1824 if (sym_ptr_ptr != (asymbol **) NULL)
1825 {
1826 asymbol **sym_end;
1827
1828 nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
1829 c = 0;
1830 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1831 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1832 {
1833 asymbol *sym;
1834 bfd_byte len;
1835 bfd_vma offset;
1836 asection *sec;
1837 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1838
1839 sym = *sym_ptr_ptr;
1840
1841 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
1842 || bfd_get_section (sym) == &bfd_und_section)
1843 continue;
1844
1845 ++c;
1846
1847 len = strlen (sym->name);
1848 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1849 != sizeof (bfd_byte))
1850 || bfd_write (sym->name, len, 1, abfd) != len)
1851 {
1852 bfd_error = system_call_error;
1853 return false;
1854 }
1855
1856 offset = bfd_asymbol_value (sym);
1857 sec = sym->section;
1858 if (sec->flags & SEC_CODE)
1859 {
1860 offset -= nlm_get_text_low (abfd);
1861 offset |= NLM_HIBIT;
1862 }
1863 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1864 {
1865 /* SEC_ALLOC is for the .bss section. */
1866 offset -= nlm_get_data_low (abfd);
1867 }
1868 else
1869 {
1870 /* We can't handle an exported symbol that is not in the
1871 code or data segment. */
1872 bfd_error = invalid_operation;
1873 return false;
1874 }
1875
1876 put_word (abfd, offset, temp);
1877 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1878 {
1879 bfd_error = system_call_error;
1880 return false;
1881 }
1882 }
1883 nlm_fixed_header (abfd)->numberOfPublics = c;
1884
1885 nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
1886 c = 0;
1887 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1888 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1889 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1890 {
1891 asymbol *sym;
1892 bfd_byte type, len;
1893 bfd_vma offset;
1894 asection *sec;
1895 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1896
1897 sym = *sym_ptr_ptr;
1898
1899 /* The NLM notion of a debugging symbol is actually what BFD
1900 calls a local or global symbol. What BFD calls a
1901 debugging symbol NLM does not understand at all. */
1902 if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
1903 || (sym->flags & BSF_DEBUGGING) != 0
1904 || bfd_get_section (sym) == &bfd_und_section)
1905 continue;
1906
1907 ++c;
1908
1909 offset = bfd_asymbol_value (sym);
1910 sec = sym->section;
1911 if (sec->flags & SEC_CODE)
1912 {
1913 offset -= nlm_get_text_low (abfd);
1914 type = 1;
1915 }
1916 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1917 {
1918 offset -= nlm_get_data_low (abfd);
1919 type = 0;
1920 }
1921 else
1922 type = 2;
1923
1924 /* The type is 0 for data, 1 for code, 2 for absolute. */
1925 if (bfd_write (&type, sizeof (bfd_byte), 1, abfd)
1926 != sizeof (bfd_byte))
1927 {
1928 bfd_error = system_call_error;
1929 return false;
1930 }
1931
1932 put_word (abfd, offset, temp);
1933 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1934 {
1935 bfd_error = system_call_error;
1936 return false;
1937 }
1938
1939 len = strlen (sym->name);
1940 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1941 != sizeof (bfd_byte))
1942 || bfd_write (sym->name, len, 1, abfd) != len)
1943 {
1944 bfd_error = system_call_error;
1945 return false;
1946 }
1947
1948 /* Exported symbols may get an additional debugging record
1949 without the prefix. */
1950 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
1951 {
1952 char *s;
1953
1954 s = strchr (sym->name, '@');
1955 if (s != NULL)
1956 {
1957 ++c;
1958
1959 if ((bfd_write (&type, sizeof (bfd_byte), 1, abfd)
1960 != sizeof (bfd_byte))
1961 || (bfd_write (temp, sizeof (temp), 1, abfd)
1962 != sizeof (temp)))
1963 {
1964 bfd_error = system_call_error;
1965 return false;
1966 }
1967
1968 ++s;
1969
1970 len = strlen (s);
1971 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1972 != sizeof (bfd_byte))
1973 || bfd_write (s, len, 1, abfd) != len)
1974 {
1975 bfd_error = system_call_error;
1976 return false;
1977 }
1978 }
1979 }
1980 }
1981 nlm_fixed_header (abfd)->numberOfDebugRecords = c;
1982 }
1983
1984 /* At this point everything has been written out except the fixed
1985 header. */
1986 memcpy (nlm_fixed_header (abfd)->signature, NLM_SIGNATURE,
1987 NLM_SIGNATURE_SIZE);
1988 nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
1989 nlm_fixed_header (abfd)->codeStartOffset =
1990 bfd_get_start_address (abfd) - nlm_get_text_low (abfd);
1991
1992 /* We have no convenient way for the caller to pass in the exit
1993 procedure or the check unload procedure, so the caller must set
1994 the values in the header to the values of the symbols. */
1995 if (nlm_fixed_header (abfd)->exitProcedureOffset != 0)
1996 nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
1997 if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
1998 nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
1999 nlm_get_text_low (abfd);
2000
2001 nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), &fixed_header);
2002 if (bfd_seek (abfd, 0, SEEK_SET) != 0
2003 || (bfd_write (&fixed_header, sizeof fixed_header, 1, abfd)
2004 != sizeof fixed_header))
2005 {
2006 bfd_error = system_call_error;
2007 return false;
2008 }
2009
2010 return true;
2011 }
This page took 0.097157 seconds and 5 git commands to generate.