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