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