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