00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "bfd.h"
00029 #include "sysdep.h"
00030 #include "libbfd.h"
00031 #include "libnlm.h"
00032
00033
00034
00035
00036
00037
00038
00039
00040 #define Nlm_External_Fixed_Header NlmNAME(External_Fixed_Header)
00041 #define Nlm_External_Version_Header NlmNAME(External_Version_Header)
00042 #define Nlm_External_Copyright_Header NlmNAME(External_Copyright_Header)
00043 #define Nlm_External_Extended_Header NlmNAME(External_Extended_Header)
00044 #define Nlm_External_Custom_Header NlmNAME(External_Custom_Header)
00045 #define Nlm_External_Cygnus_Ext_Header NlmNAME(External_Cygnus_Ext_Header)
00046
00047 #define nlm_symbol_type nlmNAME(symbol_type)
00048 #define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound)
00049 #define nlm_canonicalize_symtab nlmNAME(canonicalize_symtab)
00050 #define nlm_make_empty_symbol nlmNAME(make_empty_symbol)
00051 #define nlm_print_symbol nlmNAME(print_symbol)
00052 #define nlm_get_symbol_info nlmNAME(get_symbol_info)
00053 #define nlm_get_reloc_upper_bound nlmNAME(get_reloc_upper_bound)
00054 #define nlm_canonicalize_reloc nlmNAME(canonicalize_reloc)
00055 #define nlm_object_p nlmNAME(object_p)
00056 #define nlm_set_section_contents nlmNAME(set_section_contents)
00057 #define nlm_write_object_contents nlmNAME(write_object_contents)
00058
00059 #define nlm_swap_fixed_header_in(abfd,src,dst) \
00060 (nlm_swap_fixed_header_in_func(abfd)) (abfd,src,dst)
00061 #define nlm_swap_fixed_header_out(abfd,src,dst) \
00062 (nlm_swap_fixed_header_out_func(abfd)) (abfd,src,dst)
00063
00064
00065
00066 static bfd_boolean add_bfd_section
00067 PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword));
00068 static bfd_boolean nlm_swap_variable_header_in
00069 PARAMS ((bfd *));
00070 static bfd_boolean nlm_swap_variable_header_out
00071 PARAMS ((bfd *));
00072 static bfd_boolean find_nonzero
00073 PARAMS ((PTR, size_t));
00074 static bfd_boolean nlm_swap_auxiliary_headers_in
00075 PARAMS ((bfd *));
00076 static bfd_boolean nlm_swap_auxiliary_headers_out
00077 PARAMS ((bfd *));
00078 static bfd_boolean nlm_slurp_symbol_table
00079 PARAMS ((bfd *));
00080 static bfd_boolean nlm_slurp_reloc_fixups
00081 PARAMS ((bfd *));
00082 static bfd_boolean nlm_compute_section_file_positions
00083 PARAMS ((bfd *));
00084 static int nlm_external_reloc_compare
00085 PARAMS ((const void *, const void *));
00086
00087
00088
00089 #if ARCH_SIZE == 64
00090 #define put_word H_PUT_64
00091 #define get_word H_GET_64
00092 #endif
00093 #if ARCH_SIZE == 32
00094 #define put_word H_PUT_32
00095 #define get_word H_GET_32
00096 #endif
00097
00098 const bfd_target *
00099 nlm_object_p (abfd)
00100 bfd *abfd;
00101 {
00102 struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd);
00103 bfd_boolean (*backend_object_p) PARAMS ((bfd *));
00104 PTR x_fxdhdr = NULL;
00105 Nlm_Internal_Fixed_Header *i_fxdhdrp;
00106 struct nlm_obj_tdata *new_tdata = NULL;
00107 const char *signature;
00108 enum bfd_architecture arch;
00109 bfd_size_type amt;
00110
00111
00112
00113 backend_object_p = nlm_backend_object_p_func (abfd);
00114 if (backend_object_p)
00115 {
00116 if (!(*backend_object_p) (abfd))
00117 goto got_wrong_format_error;
00118 }
00119
00120
00121 amt = nlm_fixed_header_size (abfd);
00122 x_fxdhdr = (PTR) bfd_malloc (amt);
00123 if (x_fxdhdr == NULL)
00124 goto got_no_match;
00125
00126 if (bfd_bread ((PTR) x_fxdhdr, amt, abfd) != amt)
00127 {
00128 if (bfd_get_error () != bfd_error_system_call)
00129 goto got_wrong_format_error;
00130 else
00131 goto got_no_match;
00132 }
00133
00134
00135
00136 amt = sizeof (struct nlm_obj_tdata);
00137 new_tdata = (struct nlm_obj_tdata *) bfd_zalloc (abfd, amt);
00138 if (new_tdata == NULL)
00139 goto got_no_match;
00140
00141 nlm_tdata (abfd) = new_tdata;
00142
00143 i_fxdhdrp = nlm_fixed_header (abfd);
00144 nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp);
00145 free (x_fxdhdr);
00146 x_fxdhdr = NULL;
00147
00148
00149
00150 signature = nlm_signature (abfd);
00151 if (signature != NULL
00152 && *signature != '\0'
00153 && strncmp ((char *) i_fxdhdrp->signature, signature,
00154 NLM_SIGNATURE_SIZE) != 0)
00155 goto got_wrong_format_error;
00156
00157
00158
00159
00160 if (i_fxdhdrp->version > 0xFFFF)
00161 goto got_wrong_format_error;
00162
00163
00164
00165
00166 if (!nlm_swap_variable_header_in (abfd))
00167 {
00168 if (bfd_get_error () != bfd_error_system_call)
00169 goto got_wrong_format_error;
00170 else
00171 goto got_no_match;
00172 }
00173
00174
00175
00176
00177
00178
00179 if (!add_bfd_section (abfd, NLM_CODE_NAME,
00180 i_fxdhdrp->codeImageOffset,
00181 i_fxdhdrp->codeImageSize,
00182 (SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
00183 | SEC_RELOC))
00184 || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
00185 i_fxdhdrp->dataImageOffset,
00186 i_fxdhdrp->dataImageSize,
00187 (SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
00188 | SEC_RELOC))
00189 || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
00190 (file_ptr) 0,
00191 i_fxdhdrp->uninitializedDataSize,
00192 SEC_ALLOC))
00193 goto got_no_match;
00194
00195 if (!nlm_swap_auxiliary_headers_in (abfd))
00196 goto got_no_match;
00197
00198 if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
00199 || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
00200 abfd->flags |= HAS_RELOC;
00201 if (nlm_fixed_header (abfd)->numberOfPublics != 0
00202 || nlm_fixed_header (abfd)->numberOfDebugRecords != 0
00203 || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
00204 abfd->flags |= HAS_SYMS;
00205
00206 arch = nlm_architecture (abfd);
00207 if (arch != bfd_arch_unknown)
00208 bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
00209
00210 abfd->flags |= EXEC_P;
00211 bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset;
00212
00213 return (abfd->xvec);
00214
00215 got_wrong_format_error:
00216 bfd_set_error (bfd_error_wrong_format);
00217 got_no_match:
00218 nlm_tdata (abfd) = preserved_tdata;
00219 if (new_tdata != NULL)
00220 bfd_release (abfd, new_tdata);
00221 if (x_fxdhdr != NULL)
00222 free (x_fxdhdr);
00223 return (NULL);
00224 }
00225
00226
00227
00228 static bfd_boolean
00229 add_bfd_section (abfd, name, offset, size, flags)
00230 bfd *abfd;
00231 char *name;
00232 file_ptr offset;
00233 bfd_size_type size;
00234 flagword flags;
00235 {
00236 asection *newsect;
00237
00238 newsect = bfd_make_section (abfd, name);
00239 if (newsect == NULL)
00240 return FALSE;
00241
00242 newsect->vma = 0;
00243 newsect->size = size;
00244 newsect->filepos = offset;
00245 newsect->flags = flags;
00246 newsect->alignment_power = bfd_log2 ((bfd_vma) 0);
00247
00248 return TRUE;
00249 }
00250
00251
00252
00253
00254 static bfd_boolean
00255 nlm_swap_variable_header_in (abfd)
00256 bfd *abfd;
00257 {
00258 unsigned char temp[NLM_TARGET_LONG_SIZE];
00259 bfd_size_type amt;
00260
00261
00262
00263 amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
00264 if (bfd_bread ((PTR) &nlm_variable_header (abfd)->descriptionLength,
00265 amt, abfd) != amt)
00266 return FALSE;
00267 amt = nlm_variable_header (abfd)->descriptionLength + 1;
00268 if (bfd_bread ((PTR) nlm_variable_header (abfd)->descriptionText,
00269 amt, abfd) != amt)
00270 return FALSE;
00271
00272
00273
00274 amt = sizeof (temp);
00275 if (bfd_bread ((PTR) temp, amt, abfd) != amt)
00276 return FALSE;
00277 nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);
00278
00279
00280
00281 amt = sizeof (temp);
00282 if (bfd_bread ((PTR) temp, amt, abfd) != amt)
00283 return FALSE;
00284 nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);
00285
00286
00287
00288 amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
00289 if (bfd_bread ((PTR) nlm_variable_header (abfd)->oldThreadName,
00290 amt, abfd) != amt)
00291 return FALSE;
00292
00293
00294
00295 amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
00296 if (bfd_bread ((PTR) & nlm_variable_header (abfd)->screenNameLength,
00297 amt, abfd) != amt)
00298 return FALSE;
00299 amt = nlm_variable_header (abfd)->screenNameLength + 1;
00300 if (bfd_bread ((PTR) nlm_variable_header (abfd)->screenName,
00301 amt, abfd) != amt)
00302 return FALSE;
00303
00304
00305
00306 amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
00307 if (bfd_bread ((PTR) & nlm_variable_header (abfd)->threadNameLength,
00308 amt, abfd) != amt)
00309 return FALSE;
00310 amt = nlm_variable_header (abfd)->threadNameLength + 1;
00311 if (bfd_bread ((PTR) nlm_variable_header (abfd)->threadName,
00312 amt, abfd) != amt)
00313 return FALSE;
00314 return TRUE;
00315 }
00316
00317
00318
00319
00320 static bfd_boolean
00321 nlm_swap_variable_header_out (abfd)
00322 bfd *abfd;
00323 {
00324 unsigned char temp[NLM_TARGET_LONG_SIZE];
00325 bfd_size_type amt;
00326
00327
00328 amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
00329 if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->descriptionLength, amt,
00330 abfd) != amt)
00331 return FALSE;
00332 amt = nlm_variable_header (abfd)->descriptionLength + 1;
00333 if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->descriptionText, amt,
00334 abfd) != amt)
00335 return FALSE;
00336
00337
00338 put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize,
00339 (bfd_byte *) temp);
00340 amt = sizeof (temp);
00341 if (bfd_bwrite ((PTR) temp, amt, abfd) != amt)
00342 return FALSE;
00343
00344
00345 put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved,
00346 (bfd_byte *) temp);
00347 amt = sizeof (temp);
00348 if (bfd_bwrite ((PTR) temp, amt, abfd) != amt)
00349 return FALSE;
00350
00351
00352 amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
00353 if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->oldThreadName, amt,
00354 abfd) != amt)
00355 return FALSE;
00356
00357
00358 amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
00359 if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->screenNameLength, amt,
00360 abfd) != amt)
00361 return FALSE;
00362 amt = nlm_variable_header (abfd)->screenNameLength + 1;
00363 if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->screenName, amt,
00364 abfd) != amt)
00365 return FALSE;
00366
00367
00368 amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
00369 if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->threadNameLength, amt,
00370 abfd) != amt)
00371 return FALSE;
00372 amt = nlm_variable_header (abfd)->threadNameLength + 1;
00373 if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->threadName, amt,
00374 abfd) != amt)
00375 return FALSE;
00376 return TRUE;
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 static bfd_boolean
00389 nlm_swap_auxiliary_headers_in (abfd)
00390 bfd *abfd;
00391 {
00392 char tempstr[16];
00393 file_ptr position;
00394 bfd_size_type amt;
00395
00396 for (;;)
00397 {
00398 position = bfd_tell (abfd);
00399 amt = sizeof (tempstr);
00400 if (bfd_bread ((PTR) tempstr, amt, abfd) != amt)
00401 return FALSE;
00402 if (bfd_seek (abfd, position, SEEK_SET) != 0)
00403 return FALSE;
00404 if (strncmp (tempstr, "VeRsIoN#", 8) == 0)
00405 {
00406 Nlm_External_Version_Header thdr;
00407
00408 amt = sizeof (thdr);
00409 if (bfd_bread ((PTR) &thdr, amt, abfd) != amt)
00410 return FALSE;
00411 memcpy (nlm_version_header (abfd)->stamp, thdr.stamp,
00412 sizeof (thdr.stamp));
00413 nlm_version_header (abfd)->majorVersion =
00414 get_word (abfd, (bfd_byte *) thdr.majorVersion);
00415 nlm_version_header (abfd)->minorVersion =
00416 get_word (abfd, (bfd_byte *) thdr.minorVersion);
00417 nlm_version_header (abfd)->revision =
00418 get_word (abfd, (bfd_byte *) thdr.revision);
00419 nlm_version_header (abfd)->year =
00420 get_word (abfd, (bfd_byte *) thdr.year);
00421 nlm_version_header (abfd)->month =
00422 get_word (abfd, (bfd_byte *) thdr.month);
00423 nlm_version_header (abfd)->day =
00424 get_word (abfd, (bfd_byte *) thdr.day);
00425 }
00426 else if (strncmp (tempstr, "MeSsAgEs", 8) == 0)
00427 {
00428 Nlm_External_Extended_Header thdr;
00429
00430 amt = sizeof (thdr);
00431 if (bfd_bread ((PTR) &thdr, amt, abfd) != amt)
00432 return FALSE;
00433 memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp,
00434 sizeof (thdr.stamp));
00435 nlm_extended_header (abfd)->languageID =
00436 get_word (abfd, (bfd_byte *) thdr.languageID);
00437 nlm_extended_header (abfd)->messageFileOffset =
00438 get_word (abfd, (bfd_byte *) thdr.messageFileOffset);
00439 nlm_extended_header (abfd)->messageFileLength =
00440 get_word (abfd, (bfd_byte *) thdr.messageFileLength);
00441 nlm_extended_header (abfd)->messageCount =
00442 get_word (abfd, (bfd_byte *) thdr.messageCount);
00443 nlm_extended_header (abfd)->helpFileOffset =
00444 get_word (abfd, (bfd_byte *) thdr.helpFileOffset);
00445 nlm_extended_header (abfd)->helpFileLength =
00446 get_word (abfd, (bfd_byte *) thdr.helpFileLength);
00447 nlm_extended_header (abfd)->RPCDataOffset =
00448 get_word (abfd, (bfd_byte *) thdr.RPCDataOffset);
00449 nlm_extended_header (abfd)->RPCDataLength =
00450 get_word (abfd, (bfd_byte *) thdr.RPCDataLength);
00451 nlm_extended_header (abfd)->sharedCodeOffset =
00452 get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset);
00453 nlm_extended_header (abfd)->sharedCodeLength =
00454 get_word (abfd, (bfd_byte *) thdr.sharedCodeLength);
00455 nlm_extended_header (abfd)->sharedDataOffset =
00456 get_word (abfd, (bfd_byte *) thdr.sharedDataOffset);
00457 nlm_extended_header (abfd)->sharedDataLength =
00458 get_word (abfd, (bfd_byte *) thdr.sharedDataLength);
00459 nlm_extended_header (abfd)->sharedRelocationFixupOffset =
00460 get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset);
00461 nlm_extended_header (abfd)->sharedRelocationFixupCount =
00462 get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount);
00463 nlm_extended_header (abfd)->sharedExternalReferenceOffset =
00464 get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset);
00465 nlm_extended_header (abfd)->sharedExternalReferenceCount =
00466 get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount);
00467 nlm_extended_header (abfd)->sharedPublicsOffset =
00468 get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
00469 nlm_extended_header (abfd)->sharedPublicsCount =
00470 get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
00471 nlm_extended_header (abfd)->sharedDebugRecordOffset =
00472 get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordOffset);
00473 nlm_extended_header (abfd)->sharedDebugRecordCount =
00474 get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordCount);
00475 nlm_extended_header (abfd)->SharedInitializationOffset =
00476 get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
00477 nlm_extended_header (abfd)->SharedExitProcedureOffset =
00478 get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset);
00479 nlm_extended_header (abfd)->productID =
00480 get_word (abfd, (bfd_byte *) thdr.productID);
00481 nlm_extended_header (abfd)->reserved0 =
00482 get_word (abfd, (bfd_byte *) thdr.reserved0);
00483 nlm_extended_header (abfd)->reserved1 =
00484 get_word (abfd, (bfd_byte *) thdr.reserved1);
00485 nlm_extended_header (abfd)->reserved2 =
00486 get_word (abfd, (bfd_byte *) thdr.reserved2);
00487 nlm_extended_header (abfd)->reserved3 =
00488 get_word (abfd, (bfd_byte *) thdr.reserved3);
00489 nlm_extended_header (abfd)->reserved4 =
00490 get_word (abfd, (bfd_byte *) thdr.reserved4);
00491 nlm_extended_header (abfd)->reserved5 =
00492 get_word (abfd, (bfd_byte *) thdr.reserved5);
00493 }
00494 else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
00495 {
00496 amt = sizeof (nlm_copyright_header (abfd)->stamp);
00497 if (bfd_bread ((PTR) nlm_copyright_header (abfd)->stamp,
00498 amt, abfd) != amt)
00499 return FALSE;
00500 if (bfd_bread ((PTR) &(nlm_copyright_header (abfd)
00501 ->copyrightMessageLength),
00502 (bfd_size_type) 1, abfd) != 1)
00503 return FALSE;
00504
00505 amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
00506 if (bfd_bread ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
00507 amt, abfd) != amt)
00508 return FALSE;
00509 }
00510 else if (strncmp (tempstr, "CuStHeAd", 8) == 0)
00511 {
00512 Nlm_External_Custom_Header thdr;
00513 bfd_size_type hdrLength;
00514 file_ptr dataOffset;
00515 bfd_size_type dataLength;
00516 char dataStamp[8];
00517 PTR hdr;
00518
00519
00520 amt = sizeof (thdr.stamp);
00521 if (bfd_bread ((PTR) thdr.stamp, amt, abfd) != amt)
00522 return FALSE;
00523
00524 amt = sizeof (thdr.length);
00525 if (bfd_bread ((PTR) thdr.length, amt, abfd) != amt)
00526 return FALSE;
00527 hdrLength = get_word (abfd, (bfd_byte *) thdr.length);
00528
00529 if (hdrLength < NLM_TARGET_LONG_SIZE)
00530 dataOffset = 0;
00531 else
00532 {
00533 amt = sizeof (thdr.dataOffset);
00534 if (bfd_bread ((PTR) thdr.dataOffset, amt, abfd) != amt)
00535 return FALSE;
00536 dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset);
00537 }
00538 if (hdrLength < 2 * NLM_TARGET_LONG_SIZE)
00539 dataLength = 0;
00540 else
00541 {
00542 amt = sizeof (thdr.dataLength);
00543 if (bfd_bread ((PTR) thdr.dataLength, amt, abfd) != amt)
00544 return FALSE;
00545 dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength);
00546 }
00547 if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8)
00548 memset (dataStamp, 0, sizeof (dataStamp));
00549 else
00550 {
00551 amt = sizeof (dataStamp);
00552 if (bfd_bread ((PTR) dataStamp, amt, abfd) != amt)
00553 return FALSE;
00554 }
00555
00556
00557 if (hdrLength <= 2 * NLM_TARGET_LONG_SIZE + 8)
00558 {
00559 hdr = NULL;
00560 hdrLength = 0;
00561 }
00562 else
00563 {
00564 hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8;
00565 hdr = bfd_alloc (abfd, hdrLength);
00566 if (hdr == NULL)
00567 return FALSE;
00568 if (bfd_bread (hdr, hdrLength, abfd) != hdrLength)
00569 return FALSE;
00570 }
00571
00572
00573
00574
00575 if (strncmp (dataStamp, "CyGnUsEx", 8) == 0)
00576 {
00577 file_ptr pos;
00578 bfd_byte *contents;
00579 bfd_byte *p, *pend;
00580
00581 BFD_ASSERT (hdrLength == 0 && hdr == NULL);
00582
00583 pos = bfd_tell (abfd);
00584 if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0)
00585 return FALSE;
00586 contents = (bfd_byte *) bfd_alloc (abfd, dataLength);
00587 if (contents == NULL)
00588 return FALSE;
00589 if (bfd_bread (contents, dataLength, abfd) != dataLength)
00590 return FALSE;
00591 if (bfd_seek (abfd, pos, SEEK_SET) != 0)
00592 return FALSE;
00593
00594 memcpy (nlm_cygnus_ext_header (abfd), "CyGnUsEx", 8);
00595 nlm_cygnus_ext_header (abfd)->offset = dataOffset;
00596 nlm_cygnus_ext_header (abfd)->length = dataLength;
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 p = contents;
00609 pend = p + dataLength;
00610 while (p < pend)
00611 {
00612 char *name;
00613 size_t l;
00614 file_ptr filepos;
00615 bfd_size_type size;
00616 asection *newsec;
00617
00618
00619
00620
00621
00622
00623
00624
00625 name = (char *) p;
00626 l = strlen (name) + 1;
00627 l = (l + 3) &~ (size_t) 3;
00628 p += l;
00629 filepos = H_GET_32 (abfd, p);
00630 p += 4;
00631 size = H_GET_32 (abfd, p);
00632 p += 4;
00633
00634 newsec = bfd_make_section_anyway (abfd, name);
00635 if (newsec == (asection *) NULL)
00636 return FALSE;
00637 newsec->size = size;
00638 if (filepos != 0)
00639 {
00640 newsec->filepos = filepos;
00641 newsec->flags |= SEC_HAS_CONTENTS;
00642 }
00643 }
00644 }
00645 else
00646 {
00647 memcpy (nlm_custom_header (abfd)->stamp, thdr.stamp,
00648 sizeof (thdr.stamp));
00649 nlm_custom_header (abfd)->hdrLength = hdrLength;
00650 nlm_custom_header (abfd)->dataOffset = dataOffset;
00651 nlm_custom_header (abfd)->dataLength = dataLength;
00652 memcpy (nlm_custom_header (abfd)->dataStamp, dataStamp,
00653 sizeof (dataStamp));
00654 nlm_custom_header (abfd)->hdr = hdr;
00655 }
00656 }
00657 else
00658 break;
00659 }
00660 return TRUE;
00661 }
00662
00663
00664
00665 static bfd_boolean
00666 find_nonzero (buf, size)
00667 PTR buf;
00668 size_t size;
00669 {
00670 char *p = (char *) buf;
00671
00672 while (size-- != 0)
00673 if (*p++ != 0)
00674 return TRUE;
00675 return FALSE;
00676 }
00677
00678
00679
00680
00681
00682 static bfd_boolean
00683 nlm_swap_auxiliary_headers_out (abfd)
00684 bfd *abfd;
00685 {
00686 bfd_size_type amt;
00687
00688
00689 if (find_nonzero ((PTR) nlm_version_header (abfd),
00690 sizeof (Nlm_Internal_Version_Header)))
00691 {
00692 Nlm_External_Version_Header thdr;
00693
00694 memcpy (thdr.stamp, "VeRsIoN#", 8);
00695 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->majorVersion,
00696 (bfd_byte *) thdr.majorVersion);
00697 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->minorVersion,
00698 (bfd_byte *) thdr.minorVersion);
00699 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->revision,
00700 (bfd_byte *) thdr.revision);
00701 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->year,
00702 (bfd_byte *) thdr.year);
00703 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->month,
00704 (bfd_byte *) thdr.month);
00705 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->day,
00706 (bfd_byte *) thdr.day);
00707 if (bfd_bwrite ((PTR) &thdr, (bfd_size_type) sizeof (thdr), abfd)
00708 != sizeof (thdr))
00709 return FALSE;
00710 }
00711
00712
00713
00714
00715
00716 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
00717 sizeof (Nlm_Internal_Copyright_Header)))
00718 {
00719 Nlm_External_Copyright_Header thdr;
00720
00721 memcpy (thdr.stamp, "CoPyRiGhT=", 10);
00722 amt = sizeof (thdr.stamp);
00723 if (bfd_bwrite ((PTR) thdr.stamp, amt, abfd) != amt)
00724 return FALSE;
00725 thdr.copyrightMessageLength[0] =
00726 nlm_copyright_header (abfd)->copyrightMessageLength;
00727 amt = 1;
00728 if (bfd_bwrite ((PTR) thdr.copyrightMessageLength, amt, abfd) != amt)
00729 return FALSE;
00730
00731 amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
00732 if (bfd_bwrite ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
00733 amt, abfd) != amt)
00734 return FALSE;
00735 }
00736
00737
00738 if (find_nonzero ((PTR) nlm_extended_header (abfd),
00739 sizeof (Nlm_Internal_Extended_Header)))
00740 {
00741 Nlm_External_Extended_Header thdr;
00742
00743 memcpy (thdr.stamp, "MeSsAgEs", 8);
00744 put_word (abfd,
00745 (bfd_vma) nlm_extended_header (abfd)->languageID,
00746 (bfd_byte *) thdr.languageID);
00747 put_word (abfd,
00748 (bfd_vma) nlm_extended_header (abfd)->messageFileOffset,
00749 (bfd_byte *) thdr.messageFileOffset);
00750 put_word (abfd,
00751 (bfd_vma) nlm_extended_header (abfd)->messageFileLength,
00752 (bfd_byte *) thdr.messageFileLength);
00753 put_word (abfd,
00754 (bfd_vma) nlm_extended_header (abfd)->messageCount,
00755 (bfd_byte *) thdr.messageCount);
00756 put_word (abfd,
00757 (bfd_vma) nlm_extended_header (abfd)->helpFileOffset,
00758 (bfd_byte *) thdr.helpFileOffset);
00759 put_word (abfd,
00760 (bfd_vma) nlm_extended_header (abfd)->helpFileLength,
00761 (bfd_byte *) thdr.helpFileLength);
00762 put_word (abfd,
00763 (bfd_vma) nlm_extended_header (abfd)->RPCDataOffset,
00764 (bfd_byte *) thdr.RPCDataOffset);
00765 put_word (abfd,
00766 (bfd_vma) nlm_extended_header (abfd)->RPCDataLength,
00767 (bfd_byte *) thdr.RPCDataLength);
00768 put_word (abfd,
00769 (bfd_vma) nlm_extended_header (abfd)->sharedCodeOffset,
00770 (bfd_byte *) thdr.sharedCodeOffset);
00771 put_word (abfd,
00772 (bfd_vma) nlm_extended_header (abfd)->sharedCodeLength,
00773 (bfd_byte *) thdr.sharedCodeLength);
00774 put_word (abfd,
00775 (bfd_vma) nlm_extended_header (abfd)->sharedDataOffset,
00776 (bfd_byte *) thdr.sharedDataOffset);
00777 put_word (abfd,
00778 (bfd_vma) nlm_extended_header (abfd)->sharedDataLength,
00779 (bfd_byte *) thdr.sharedDataLength);
00780 put_word (abfd,
00781 (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupOffset,
00782 (bfd_byte *) thdr.sharedRelocationFixupOffset);
00783 put_word (abfd,
00784 (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupCount,
00785 (bfd_byte *) thdr.sharedRelocationFixupCount);
00786 put_word (abfd,
00787 (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceOffset,
00788 (bfd_byte *) thdr.sharedExternalReferenceOffset);
00789 put_word (abfd,
00790 (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceCount,
00791 (bfd_byte *) thdr.sharedExternalReferenceCount);
00792 put_word (abfd,
00793 (bfd_vma) nlm_extended_header (abfd)->sharedPublicsOffset,
00794 (bfd_byte *) thdr.sharedPublicsOffset);
00795 put_word (abfd,
00796 (bfd_vma) nlm_extended_header (abfd)->sharedPublicsCount,
00797 (bfd_byte *) thdr.sharedPublicsCount);
00798 put_word (abfd,
00799 (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordOffset,
00800 (bfd_byte *) thdr.sharedDebugRecordOffset);
00801 put_word (abfd,
00802 (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordCount,
00803 (bfd_byte *) thdr.sharedDebugRecordCount);
00804 put_word (abfd,
00805 (bfd_vma) nlm_extended_header (abfd)->SharedInitializationOffset,
00806 (bfd_byte *) thdr.sharedInitializationOffset);
00807 put_word (abfd,
00808 (bfd_vma) nlm_extended_header (abfd)->SharedExitProcedureOffset,
00809 (bfd_byte *) thdr.SharedExitProcedureOffset);
00810 put_word (abfd,
00811 (bfd_vma) nlm_extended_header (abfd)->productID,
00812 (bfd_byte *) thdr.productID);
00813 put_word (abfd,
00814 (bfd_vma) nlm_extended_header (abfd)->reserved0,
00815 (bfd_byte *) thdr.reserved0);
00816 put_word (abfd,
00817 (bfd_vma) nlm_extended_header (abfd)->reserved1,
00818 (bfd_byte *) thdr.reserved1);
00819 put_word (abfd,
00820 (bfd_vma) nlm_extended_header (abfd)->reserved2,
00821 (bfd_byte *) thdr.reserved2);
00822 put_word (abfd,
00823 (bfd_vma) nlm_extended_header (abfd)->reserved3,
00824 (bfd_byte *) thdr.reserved3);
00825 put_word (abfd,
00826 (bfd_vma) nlm_extended_header (abfd)->reserved4,
00827 (bfd_byte *) thdr.reserved4);
00828 put_word (abfd,
00829 (bfd_vma) nlm_extended_header (abfd)->reserved5,
00830 (bfd_byte *) thdr.reserved5);
00831 if (bfd_bwrite ((PTR) &thdr, (bfd_size_type) sizeof (thdr), abfd)
00832 != sizeof (thdr))
00833 return FALSE;
00834 }
00835
00836
00837 if (find_nonzero ((PTR) nlm_custom_header (abfd),
00838 sizeof (Nlm_Internal_Custom_Header)))
00839 {
00840 Nlm_External_Custom_Header thdr;
00841 bfd_boolean ds;
00842 bfd_size_type hdrLength;
00843
00844 ds = find_nonzero ((PTR) nlm_custom_header (abfd)->dataStamp,
00845 sizeof (nlm_custom_header (abfd)->dataStamp));
00846 memcpy (thdr.stamp, "CuStHeAd", 8);
00847 hdrLength = (2 * NLM_TARGET_LONG_SIZE + (ds ? 8 : 0)
00848 + nlm_custom_header (abfd)->hdrLength);
00849 put_word (abfd, hdrLength, thdr.length);
00850 put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataOffset,
00851 thdr.dataOffset);
00852 put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength,
00853 thdr.dataLength);
00854 if (! ds)
00855 {
00856 BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0);
00857 amt = sizeof (thdr) - sizeof (thdr.dataStamp);
00858 if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt)
00859 return FALSE;
00860 }
00861 else
00862 {
00863 memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp,
00864 sizeof (thdr.dataStamp));
00865 amt = sizeof (thdr);
00866 if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt)
00867 return FALSE;
00868 amt = nlm_custom_header (abfd)->hdrLength;
00869 if (bfd_bwrite (nlm_custom_header (abfd)->hdr, amt, abfd) != amt)
00870 return FALSE;
00871 }
00872 }
00873
00874
00875 if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
00876 sizeof (Nlm_Internal_Cygnus_Ext_Header)))
00877 {
00878 Nlm_External_Custom_Header thdr;
00879
00880 memcpy (thdr.stamp, "CuStHeAd", 8);
00881 put_word (abfd, (bfd_vma) 2 * NLM_TARGET_LONG_SIZE + 8,
00882 (bfd_byte *) thdr.length);
00883 put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->offset,
00884 (bfd_byte *) thdr.dataOffset);
00885 put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->length,
00886 (bfd_byte *) thdr.dataLength);
00887 memcpy (thdr.dataStamp, "CyGnUsEx", 8);
00888 amt = sizeof (thdr);
00889 if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt)
00890 return FALSE;
00891 }
00892
00893 return TRUE;
00894 }
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905 long
00906 nlm_get_symtab_upper_bound (abfd)
00907 bfd *abfd;
00908 {
00909 Nlm_Internal_Fixed_Header *i_fxdhdrp;
00910 long symcount;
00911 long symtab_size = 0;
00912
00913 i_fxdhdrp = nlm_fixed_header (abfd);
00914 symcount = (i_fxdhdrp->numberOfPublics
00915 + i_fxdhdrp->numberOfDebugRecords
00916 + i_fxdhdrp->numberOfExternalReferences);
00917 symtab_size = (symcount + 1) * (sizeof (asymbol));
00918 return (symtab_size);
00919 }
00920
00921
00922
00923
00924 long
00925 nlm_canonicalize_symtab (abfd, alocation)
00926 bfd *abfd;
00927 asymbol **alocation;
00928 {
00929 nlm_symbol_type *symbase;
00930 bfd_size_type counter = 0;
00931
00932 if (! nlm_slurp_symbol_table (abfd))
00933 return -1;
00934 symbase = nlm_get_symbols (abfd);
00935 while (counter < bfd_get_symcount (abfd))
00936 {
00937 *alocation++ = &symbase->symbol;
00938 symbase++;
00939 counter++;
00940 }
00941 *alocation = (asymbol *) NULL;
00942 return bfd_get_symcount (abfd);
00943 }
00944
00945
00946
00947 asymbol *
00948 nlm_make_empty_symbol (abfd)
00949 bfd *abfd;
00950 {
00951 bfd_size_type amt = sizeof (nlm_symbol_type);
00952 nlm_symbol_type *new = (nlm_symbol_type *) bfd_zalloc (abfd, amt);
00953
00954 if (new)
00955 new->symbol.the_bfd = abfd;
00956 return &new->symbol;
00957 }
00958
00959
00960
00961 void
00962 nlm_get_symbol_info (ignore_abfd, symbol, ret)
00963 bfd *ignore_abfd ATTRIBUTE_UNUSED;
00964 asymbol *symbol;
00965 symbol_info *ret;
00966 {
00967 bfd_symbol_info (symbol, ret);
00968 }
00969
00970
00971
00972 void
00973 nlm_print_symbol (abfd, afile, symbol, how)
00974 bfd *abfd;
00975 PTR afile;
00976 asymbol *symbol;
00977 bfd_print_symbol_type how;
00978 {
00979 FILE *file = (FILE *) afile;
00980
00981 switch (how)
00982 {
00983 case bfd_print_symbol_name:
00984 case bfd_print_symbol_more:
00985 if (symbol->name)
00986 fprintf (file, "%s", symbol->name);
00987 break;
00988 case bfd_print_symbol_all:
00989 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
00990 fprintf (file, " %-5s", symbol->section->name);
00991 if (symbol->name)
00992 fprintf (file, " %s", symbol->name);
00993 break;
00994 }
00995 }
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016 static bfd_boolean
01017 nlm_slurp_symbol_table (abfd)
01018 bfd *abfd;
01019 {
01020 Nlm_Internal_Fixed_Header *i_fxdhdrp;
01021 bfd_size_type totsymcount;
01022 bfd_size_type symcount;
01023 nlm_symbol_type *sym;
01024 unsigned char symlength;
01025 unsigned char symtype;
01026 bfd_byte temp[NLM_TARGET_LONG_SIZE];
01027 bfd_boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *));
01028 bfd_boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *));
01029 bfd_size_type amt;
01030
01031 if (nlm_get_symbols (abfd) != NULL)
01032 return TRUE;
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 abfd->symcount = 0;
01043 i_fxdhdrp = nlm_fixed_header (abfd);
01044 totsymcount = (i_fxdhdrp->numberOfPublics
01045 + i_fxdhdrp->numberOfDebugRecords
01046 + i_fxdhdrp->numberOfExternalReferences);
01047 if (totsymcount == 0)
01048 return TRUE;
01049
01050 if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) != 0)
01051 return FALSE;
01052
01053 amt = totsymcount * sizeof (nlm_symbol_type);
01054 sym = ((nlm_symbol_type *) bfd_zalloc (abfd, amt));
01055 if (!sym)
01056 return FALSE;
01057 nlm_set_symbols (abfd, sym);
01058
01059
01060
01061
01062
01063 set_public_section_func = nlm_set_public_section_func (abfd);
01064 symcount = i_fxdhdrp->numberOfPublics;
01065 while (abfd->symcount < symcount)
01066 {
01067 amt = sizeof (symlength);
01068 if (bfd_bread ((PTR) &symlength, amt, abfd) != amt)
01069 return FALSE;
01070 amt = symlength;
01071 sym->symbol.the_bfd = abfd;
01072 sym->symbol.name = bfd_alloc (abfd, amt + 1);
01073 if (!sym->symbol.name)
01074 return FALSE;
01075 if (bfd_bread ((PTR) sym->symbol.name, amt, abfd) != amt)
01076 return FALSE;
01077
01078 ((char *) (sym->symbol.name))[symlength] = '\0';
01079 amt = sizeof (temp);
01080 if (bfd_bread ((PTR) temp, amt, abfd) != amt)
01081 return FALSE;
01082 sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
01083 sym->symbol.value = get_word (abfd, temp);
01084 if (set_public_section_func)
01085 {
01086
01087
01088 if (! (*set_public_section_func) (abfd, sym))
01089 return FALSE;
01090 }
01091 else
01092 {
01093 if (sym->symbol.value & NLM_HIBIT)
01094 {
01095 sym->symbol.value &= ~NLM_HIBIT;
01096 sym->symbol.flags |= BSF_FUNCTION;
01097 sym->symbol.section =
01098 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
01099 }
01100 else
01101 {
01102 sym->symbol.section =
01103 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
01104 }
01105 }
01106 sym->rcnt = 0;
01107 abfd->symcount++;
01108 sym++;
01109 }
01110
01111
01112
01113 if (i_fxdhdrp->numberOfDebugRecords > 0)
01114 {
01115 if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) != 0)
01116 return FALSE;
01117
01118 symcount += i_fxdhdrp->numberOfDebugRecords;
01119 while (abfd->symcount < symcount)
01120 {
01121 amt = sizeof (symtype);
01122 if (bfd_bread ((PTR) &symtype, amt, abfd) != amt)
01123 return FALSE;
01124 amt = sizeof (temp);
01125 if (bfd_bread ((PTR) temp, amt, abfd) != amt)
01126 return FALSE;
01127 amt = sizeof (symlength);
01128 if (bfd_bread ((PTR) &symlength, amt, abfd) != amt)
01129 return FALSE;
01130 amt = symlength;
01131 sym->symbol.the_bfd = abfd;
01132 sym->symbol.name = bfd_alloc (abfd, amt + 1);
01133 if (!sym->symbol.name)
01134 return FALSE;
01135 if (bfd_bread ((PTR) sym->symbol.name, amt, abfd) != amt)
01136 return FALSE;
01137
01138 ((char *) (sym->symbol.name))[symlength] = '\0';
01139 sym->symbol.flags = BSF_LOCAL;
01140 sym->symbol.value = get_word (abfd, temp);
01141 if (symtype == 0)
01142 {
01143 sym->symbol.section =
01144 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
01145 }
01146 else if (symtype == 1)
01147 {
01148 sym->symbol.flags |= BSF_FUNCTION;
01149 sym->symbol.section =
01150 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
01151 }
01152 else
01153 {
01154 sym->symbol.section = bfd_abs_section_ptr;
01155 }
01156 sym->rcnt = 0;
01157 abfd->symcount++;
01158 sym++;
01159 }
01160 }
01161
01162
01163
01164 read_import_func = nlm_read_import_func (abfd);
01165 if (read_import_func != NULL)
01166 {
01167 if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET) != 0)
01168 return FALSE;
01169
01170 symcount += i_fxdhdrp->numberOfExternalReferences;
01171 while (abfd->symcount < symcount)
01172 {
01173 if (! (*read_import_func) (abfd, sym))
01174 return FALSE;
01175 sym++;
01176 abfd->symcount++;
01177 }
01178 }
01179
01180 return TRUE;
01181 }
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196 static bfd_boolean
01197 nlm_slurp_reloc_fixups (abfd)
01198 bfd *abfd;
01199 {
01200 bfd_boolean (*read_func)
01201 PARAMS ((bfd *, nlm_symbol_type *, asection **, arelent *));
01202 bfd_size_type count, amt;
01203 arelent *rels;
01204 asection **secs;
01205
01206 if (nlm_relocation_fixups (abfd) != NULL)
01207 return TRUE;
01208 read_func = nlm_read_reloc_func (abfd);
01209 if (read_func == NULL)
01210 return TRUE;
01211
01212 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
01213 SEEK_SET) != 0)
01214 return FALSE;
01215
01216 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
01217 amt = count * sizeof (arelent);
01218 rels = (arelent *) bfd_alloc (abfd, amt);
01219 amt = count * sizeof (asection *);
01220 secs = (asection **) bfd_alloc (abfd, amt);
01221 if ((rels == NULL || secs == NULL) && count != 0)
01222 return FALSE;
01223 nlm_relocation_fixups (abfd) = rels;
01224 nlm_relocation_fixup_secs (abfd) = secs;
01225
01226
01227
01228 while (count-- != 0)
01229 {
01230 if (! (*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels))
01231 {
01232 nlm_relocation_fixups (abfd) = NULL;
01233 nlm_relocation_fixup_secs (abfd) = NULL;
01234 return FALSE;
01235 }
01236 ++secs;
01237 ++rels;
01238 }
01239
01240 return TRUE;
01241 }
01242
01243
01244
01245
01246
01247 long
01248 nlm_get_reloc_upper_bound (abfd, sec)
01249 bfd *abfd;
01250 asection *sec;
01251 {
01252 nlm_symbol_type *syms;
01253 bfd_size_type count;
01254 unsigned int ret;
01255
01256
01257 if (nlm_read_reloc_func (abfd) == NULL)
01258 return -1;
01259
01260 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
01261 return 0;
01262
01263 syms = nlm_get_symbols (abfd);
01264 if (syms == NULL)
01265 {
01266 if (! nlm_slurp_symbol_table (abfd))
01267 return -1;
01268 syms = nlm_get_symbols (abfd);
01269 }
01270
01271 ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;
01272
01273 count = bfd_get_symcount (abfd);
01274 while (count-- != 0)
01275 {
01276 ret += syms->rcnt;
01277 ++syms;
01278 }
01279
01280 return (ret + 1) * sizeof (arelent *);
01281 }
01282
01283
01284
01285 long
01286 nlm_canonicalize_reloc (abfd, sec, relptr, symbols)
01287 bfd *abfd;
01288 asection *sec;
01289 arelent **relptr;
01290 asymbol **symbols;
01291 {
01292 arelent *rels;
01293 asection **secs;
01294 bfd_size_type count, i;
01295 unsigned int ret;
01296
01297
01298 rels = nlm_relocation_fixups (abfd);
01299 if (rels == NULL)
01300 {
01301 if (! nlm_slurp_reloc_fixups (abfd))
01302 return -1;
01303 rels = nlm_relocation_fixups (abfd);
01304 }
01305 secs = nlm_relocation_fixup_secs (abfd);
01306
01307 ret = 0;
01308 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
01309 for (i = 0; i < count; i++, rels++, secs++)
01310 {
01311 if (*secs == sec)
01312 {
01313 *relptr++ = rels;
01314 ++ret;
01315 }
01316 }
01317
01318
01319 count = bfd_get_symcount (abfd);
01320 for (i = 0; i < count; i++, symbols++)
01321 {
01322 asymbol *sym;
01323
01324 sym = *symbols;
01325 if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
01326 {
01327 nlm_symbol_type *nlm_sym;
01328 bfd_size_type j;
01329
01330 nlm_sym = (nlm_symbol_type *) sym;
01331 for (j = 0; j < nlm_sym->rcnt; j++)
01332 {
01333 if (nlm_sym->relocs[j].section == sec)
01334 {
01335 *relptr = &nlm_sym->relocs[j].reloc;
01336 (*relptr)->sym_ptr_ptr = symbols;
01337 ++relptr;
01338 ++ret;
01339 }
01340 }
01341 }
01342 }
01343
01344 *relptr = NULL;
01345
01346 return ret;
01347 }
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365 static bfd_boolean
01366 nlm_compute_section_file_positions (abfd)
01367 bfd *abfd;
01368 {
01369 file_ptr sofar;
01370 asection *sec;
01371 bfd_vma text, data, bss;
01372 bfd_vma text_low, data_low;
01373 unsigned int text_align, data_align, other_align;
01374 file_ptr text_ptr, data_ptr, other_ptr;
01375 asection *bss_sec;
01376 asymbol **sym_ptr_ptr;
01377
01378 if (abfd->output_has_begun)
01379 return TRUE;
01380
01381
01382 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
01383 if (bss_sec == NULL)
01384 {
01385 if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
01386 (file_ptr) 0, (bfd_size_type) 0,
01387 SEC_ALLOC))
01388 return FALSE;
01389 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
01390 }
01391
01392 abfd->output_has_begun = TRUE;
01393
01394
01395 sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
01396
01397
01398 sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
01399 + nlm_variable_header (abfd)->descriptionLength + 1
01400 + NLM_TARGET_LONG_SIZE
01401 + NLM_TARGET_LONG_SIZE
01402 + sizeof (nlm_variable_header (abfd)->oldThreadName)
01403 + sizeof (nlm_variable_header (abfd)->screenNameLength)
01404 + nlm_variable_header (abfd)->screenNameLength + 1
01405 + sizeof (nlm_variable_header (abfd)->threadNameLength)
01406 + nlm_variable_header (abfd)->threadNameLength + 1);
01407
01408
01409 if (find_nonzero ((PTR) nlm_version_header (abfd),
01410 sizeof (Nlm_Internal_Version_Header)))
01411 sofar += sizeof (Nlm_External_Version_Header);
01412 if (find_nonzero ((PTR) nlm_extended_header (abfd),
01413 sizeof (Nlm_Internal_Extended_Header)))
01414 sofar += sizeof (Nlm_External_Extended_Header);
01415 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
01416 sizeof (Nlm_Internal_Copyright_Header)))
01417 sofar += (sizeof (Nlm_External_Copyright_Header)
01418 + nlm_copyright_header (abfd)->copyrightMessageLength + 1);
01419 if (find_nonzero ((PTR) nlm_custom_header (abfd),
01420 sizeof (Nlm_Internal_Custom_Header)))
01421 sofar += (sizeof (Nlm_External_Custom_Header)
01422 + nlm_custom_header (abfd)->hdrLength);
01423 if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
01424 sizeof (Nlm_Internal_Cygnus_Ext_Header)))
01425 sofar += sizeof (Nlm_External_Custom_Header);
01426
01427
01428
01429
01430
01431
01432 text = 0;
01433 text_low = (bfd_vma) - 1;
01434 text_align = 0;
01435 data = 0;
01436 data_low = (bfd_vma) - 1;
01437 data_align = 0;
01438 bss = 0;
01439 other_align = 0;
01440 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
01441 {
01442 flagword f;
01443
01444 sec->size = BFD_ALIGN (sec->size, 1 << sec->alignment_power);
01445
01446 f = bfd_get_section_flags (abfd, sec);
01447 if (f & SEC_CODE)
01448 {
01449 text += sec->size;
01450 if (bfd_get_section_vma (abfd, sec) < text_low)
01451 text_low = bfd_get_section_vma (abfd, sec);
01452 if (sec->alignment_power > text_align)
01453 text_align = sec->alignment_power;
01454 }
01455 else if (f & SEC_DATA)
01456 {
01457 data += sec->size;
01458 if (bfd_get_section_vma (abfd, sec) < data_low)
01459 data_low = bfd_get_section_vma (abfd, sec);
01460 if (sec->alignment_power > data_align)
01461 data_align = sec->alignment_power;
01462 }
01463 else if (f & SEC_HAS_CONTENTS)
01464 {
01465 if (sec->alignment_power > other_align)
01466 other_align = sec->alignment_power;
01467 }
01468 else if (f & SEC_ALLOC)
01469 bss += sec->size;
01470 }
01471
01472 nlm_set_text_low (abfd, text_low);
01473 nlm_set_data_low (abfd, data_low);
01474
01475 if (nlm_no_uninitialized_data (abfd))
01476 {
01477
01478
01479
01480 data += bss;
01481 bss = 0;
01482 }
01483
01484 text_ptr = BFD_ALIGN (sofar, 1 << text_align);
01485 data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
01486 other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
01487
01488
01489
01490 nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
01491 nlm_fixed_header (abfd)->codeImageSize = text;
01492 nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
01493 nlm_fixed_header (abfd)->dataImageSize = data;
01494 nlm_fixed_header (abfd)->uninitializedDataSize = bss;
01495
01496 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
01497 {
01498 flagword f;
01499
01500 f = bfd_get_section_flags (abfd, sec);
01501
01502 if (f & SEC_CODE)
01503 {
01504 sec->filepos = text_ptr;
01505 text_ptr += sec->size;
01506 }
01507 else if (f & SEC_DATA)
01508 {
01509 sec->filepos = data_ptr;
01510 data_ptr += sec->size;
01511 }
01512 else if (f & SEC_HAS_CONTENTS)
01513 {
01514 sec->filepos = other_ptr;
01515 other_ptr += sec->size;
01516 }
01517 }
01518
01519 nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
01520
01521
01522
01523 sym_ptr_ptr = bfd_get_outsymbols (abfd);
01524 if (sym_ptr_ptr != NULL)
01525 {
01526 asymbol **sym_end;
01527 bfd_vma add;
01528
01529 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
01530 add = 0;
01531 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
01532 {
01533 asymbol *sym;
01534 bfd_vma size;
01535
01536 sym = *sym_ptr_ptr;
01537
01538 if (!bfd_is_com_section (bfd_get_section (sym)))
01539 continue;
01540
01541
01542
01543
01544 sym->section = bss_sec;
01545 size = sym->value;
01546 sym->value = bss_sec->size + add;
01547 add += size;
01548 add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
01549 }
01550 if (add != 0)
01551 {
01552 if (nlm_no_uninitialized_data (abfd))
01553 {
01554
01555
01556 abort ();
01557 }
01558 nlm_fixed_header (abfd)->uninitializedDataSize += add;
01559 bss_sec->size += add;
01560 }
01561 }
01562
01563 return TRUE;
01564 }
01565
01566
01567
01568
01569
01570
01571 bfd_boolean
01572 nlm_set_section_contents (abfd, section, location, offset, count)
01573 bfd *abfd;
01574 asection *section;
01575 const PTR location;
01576 file_ptr offset;
01577 bfd_size_type count;
01578 {
01579 if (! abfd->output_has_begun
01580 && ! nlm_compute_section_file_positions (abfd))
01581 return FALSE;
01582
01583 if (count == 0)
01584 return TRUE;
01585
01586
01587
01588
01589
01590 if (section->reloc_count != 0)
01591 {
01592 bfd_boolean (*mangle_relocs_func)
01593 PARAMS ((bfd *, asection *, const PTR, bfd_vma, bfd_size_type));
01594
01595 mangle_relocs_func = nlm_mangle_relocs_func (abfd);
01596 if (mangle_relocs_func != NULL)
01597 {
01598 if (!(*mangle_relocs_func) (abfd, section, location,
01599 (bfd_vma) offset, count))
01600 return FALSE;
01601 }
01602 }
01603
01604 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
01605 || bfd_bwrite (location, count, abfd) != count)
01606 return FALSE;
01607
01608 return TRUE;
01609 }
01610
01611
01612
01613
01614 static int
01615 nlm_external_reloc_compare (p1, p2)
01616 const void *p1;
01617 const void *p2;
01618 {
01619 const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
01620 const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
01621 int cmp;
01622
01623 cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name,
01624 (*r2->rel->sym_ptr_ptr)->name);
01625 if (cmp != 0)
01626 return cmp;
01627
01628
01629
01630
01631 return (int) (r1->rel->address - r2->rel->address);
01632 }
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662 bfd_boolean
01663 nlm_write_object_contents (abfd)
01664 bfd *abfd;
01665 {
01666 asection *sec;
01667 bfd_boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *));
01668 bfd_size_type external_reloc_count, internal_reloc_count, i, c;
01669 struct reloc_and_sec *external_relocs;
01670 asymbol **sym_ptr_ptr;
01671 file_ptr last;
01672 bfd_boolean (*write_prefix_func) PARAMS ((bfd *));
01673 unsigned char *fixed_header = NULL;
01674 file_ptr pos;
01675 bfd_size_type amt;
01676
01677 fixed_header = ((unsigned char *)
01678 bfd_malloc (nlm_fixed_header_size (abfd)));
01679 if (fixed_header == NULL)
01680 goto error_return;
01681
01682 if (! abfd->output_has_begun
01683 && ! nlm_compute_section_file_positions (abfd))
01684 goto error_return;
01685
01686
01687 pos = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
01688 if (bfd_seek (abfd, pos, SEEK_SET) != 0)
01689 goto error_return;
01690 if (! nlm_swap_variable_header_out (abfd)
01691 || ! nlm_swap_auxiliary_headers_out (abfd))
01692 {
01693 bfd_set_error (bfd_error_system_call);
01694 goto error_return;
01695 }
01696
01697
01698
01699 if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
01700 {
01701 bfd_set_error (bfd_error_invalid_operation);
01702 goto error_return;
01703 }
01704
01705
01706 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
01707 SEEK_SET) != 0)
01708 goto error_return;
01709
01710
01711
01712
01713 write_import_func = nlm_write_import_func (abfd);
01714
01715
01716
01717
01718 internal_reloc_count = 0;
01719 external_reloc_count = 0;
01720 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
01721 {
01722 arelent **rel_ptr_ptr, **rel_end;
01723
01724 if (sec->reloc_count == 0)
01725 continue;
01726
01727
01728
01729 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
01730 continue;
01731
01732
01733 if (write_import_func == NULL)
01734 {
01735 bfd_set_error (bfd_error_invalid_operation);
01736 goto error_return;
01737 }
01738
01739 rel_ptr_ptr = sec->orelocation;
01740 rel_end = rel_ptr_ptr + sec->reloc_count;
01741 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
01742 {
01743 arelent *rel;
01744 asymbol *sym;
01745
01746 rel = *rel_ptr_ptr;
01747 sym = *rel->sym_ptr_ptr;
01748
01749 if (! bfd_is_und_section (bfd_get_section (sym)))
01750 {
01751 ++internal_reloc_count;
01752 if (! (*write_import_func) (abfd, sec, rel))
01753 goto error_return;
01754 }
01755 else
01756 ++external_reloc_count;
01757 }
01758 }
01759 nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
01760
01761
01762
01763
01764
01765 amt = external_reloc_count * sizeof (struct reloc_and_sec);
01766 external_relocs = (struct reloc_and_sec *) bfd_alloc (abfd, amt);
01767 if (external_relocs == (struct reloc_and_sec *) NULL)
01768 goto error_return;
01769 i = 0;
01770 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
01771 {
01772 arelent **rel_ptr_ptr, **rel_end;
01773
01774 if (sec->reloc_count == 0)
01775 continue;
01776
01777 rel_ptr_ptr = sec->orelocation;
01778 rel_end = rel_ptr_ptr + sec->reloc_count;
01779 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
01780 {
01781 arelent *rel;
01782 asymbol *sym;
01783
01784 rel = *rel_ptr_ptr;
01785 sym = *rel->sym_ptr_ptr;
01786
01787 if (! bfd_is_und_section (bfd_get_section (sym)))
01788 continue;
01789
01790 external_relocs[i].rel = rel;
01791 external_relocs[i].sec = sec;
01792 ++i;
01793 }
01794 }
01795
01796 BFD_ASSERT (i == external_reloc_count);
01797
01798
01799 qsort ((PTR) external_relocs, (size_t) external_reloc_count,
01800 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
01801
01802
01803 nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
01804 c = 0;
01805 i = 0;
01806 while (i < external_reloc_count)
01807 {
01808 arelent *rel;
01809 asymbol *sym;
01810 bfd_size_type j, cnt;
01811
01812 ++c;
01813
01814 rel = external_relocs[i].rel;
01815 sym = *rel->sym_ptr_ptr;
01816
01817 cnt = 0;
01818 for (j = i;
01819 (j < external_reloc_count
01820 && *external_relocs[j].rel->sym_ptr_ptr == sym);
01821 j++)
01822 ++cnt;
01823
01824 if (! (*nlm_write_external_func (abfd)) (abfd, cnt, sym,
01825 &external_relocs[i]))
01826 goto error_return;
01827
01828 i += cnt;
01829 }
01830
01831 nlm_fixed_header (abfd)->numberOfExternalReferences = c;
01832
01833
01834 sym_ptr_ptr = bfd_get_outsymbols (abfd);
01835 if (sym_ptr_ptr != (asymbol **) NULL)
01836 {
01837 bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *));
01838 bfd_boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma));
01839
01840 asymbol **sym_end;
01841
01842 nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
01843 get_public_offset_func = nlm_get_public_offset_func (abfd);
01844 write_export_func = nlm_write_export_func (abfd);
01845 c = 0;
01846 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
01847 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
01848 {
01849 asymbol *sym;
01850 bfd_byte len;
01851 bfd_vma offset;
01852 bfd_byte temp[NLM_TARGET_LONG_SIZE];
01853
01854 sym = *sym_ptr_ptr;
01855
01856 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
01857 || bfd_is_und_section (bfd_get_section (sym)))
01858 continue;
01859
01860 ++c;
01861
01862 if (get_public_offset_func)
01863 {
01864
01865
01866 offset = (*get_public_offset_func) (abfd, sym);
01867 }
01868 else
01869 {
01870 offset = bfd_asymbol_value (sym);
01871 sec = sym->section;
01872 if (sec->flags & SEC_CODE)
01873 {
01874 offset -= nlm_get_text_low (abfd);
01875 offset |= NLM_HIBIT;
01876 }
01877 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
01878 {
01879
01880 offset -= nlm_get_data_low (abfd);
01881 }
01882 else
01883 {
01884
01885
01886 bfd_set_error (bfd_error_invalid_operation);
01887 goto error_return;
01888 }
01889 }
01890
01891 if (write_export_func)
01892 {
01893 if (! (*write_export_func) (abfd, sym, offset))
01894 goto error_return;
01895 }
01896 else
01897 {
01898 len = strlen (sym->name);
01899 if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
01900 != sizeof (bfd_byte))
01901 || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
01902 goto error_return;
01903
01904 put_word (abfd, offset, temp);
01905 if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
01906 != sizeof (temp))
01907 goto error_return;
01908 }
01909 }
01910 nlm_fixed_header (abfd)->numberOfPublics = c;
01911
01912
01913
01914
01915
01916
01917
01918 if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1)
01919 {
01920 nlm_fixed_header (abfd)->debugInfoOffset = 0;
01921 nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
01922 }
01923 else
01924 {
01925 nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
01926 c = 0;
01927 sym_ptr_ptr = bfd_get_outsymbols (abfd);
01928 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
01929 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
01930 {
01931 asymbol *sym;
01932 bfd_byte type, len;
01933 bfd_vma offset;
01934 bfd_byte temp[NLM_TARGET_LONG_SIZE];
01935
01936 sym = *sym_ptr_ptr;
01937
01938
01939
01940
01941 if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
01942 || (sym->flags & BSF_DEBUGGING) != 0
01943 || bfd_is_und_section (bfd_get_section (sym)))
01944 continue;
01945
01946 ++c;
01947
01948 offset = bfd_asymbol_value (sym);
01949 sec = sym->section;
01950 if (sec->flags & SEC_CODE)
01951 {
01952 offset -= nlm_get_text_low (abfd);
01953 type = 1;
01954 }
01955 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
01956 {
01957
01958 offset -= nlm_get_data_low (abfd);
01959 type = 0;
01960 }
01961 else
01962 type = 2;
01963
01964
01965 if (bfd_bwrite (&type, (bfd_size_type) sizeof (bfd_byte), abfd)
01966 != sizeof (bfd_byte))
01967 goto error_return;
01968
01969 put_word (abfd, offset, temp);
01970 if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
01971 != sizeof (temp))
01972 goto error_return;
01973
01974 len = strlen (sym->name);
01975 if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
01976 != sizeof (bfd_byte))
01977 || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
01978 goto error_return;
01979 }
01980 nlm_fixed_header (abfd)->numberOfDebugRecords = c;
01981 }
01982 }
01983
01984
01985
01986 last = bfd_tell (abfd);
01987 if (nlm_fixed_header (abfd)->codeImageOffset == 0)
01988 nlm_fixed_header (abfd)->codeImageOffset = last;
01989 if (nlm_fixed_header (abfd)->dataImageOffset == 0)
01990 nlm_fixed_header (abfd)->dataImageOffset = last;
01991 if (nlm_fixed_header (abfd)->customDataOffset == 0)
01992 nlm_fixed_header (abfd)->customDataOffset = last;
01993 if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
01994 nlm_fixed_header (abfd)->moduleDependencyOffset = last;
01995 if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
01996 nlm_fixed_header (abfd)->relocationFixupOffset = last;
01997 if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
01998 nlm_fixed_header (abfd)->externalReferencesOffset = last;
01999 if (nlm_fixed_header (abfd)->publicsOffset == 0)
02000 nlm_fixed_header (abfd)->publicsOffset = last;
02001 if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
02002 nlm_fixed_header (abfd)->debugInfoOffset = last;
02003
02004
02005
02006 memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
02007 NLM_SIGNATURE_SIZE);
02008 nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
02009 nlm_fixed_header (abfd)->codeStartOffset =
02010 (bfd_get_start_address (abfd)
02011 - nlm_get_text_low (abfd));
02012
02013
02014
02015
02016 nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
02017 if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
02018 nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
02019 nlm_get_text_low (abfd);
02020
02021 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
02022 goto error_return;
02023
02024 write_prefix_func = nlm_write_prefix_func (abfd);
02025 if (write_prefix_func)
02026 {
02027 if (! (*write_prefix_func) (abfd))
02028 goto error_return;
02029 }
02030
02031 BFD_ASSERT ((bfd_size_type) bfd_tell (abfd)
02032 == nlm_optional_prefix_size (abfd));
02033
02034 nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
02035 if (bfd_bwrite (fixed_header, nlm_fixed_header_size (abfd), abfd)
02036 != nlm_fixed_header_size (abfd))
02037 goto error_return;
02038
02039 if (fixed_header != NULL)
02040 free (fixed_header);
02041 return TRUE;
02042
02043 error_return:
02044 if (fixed_header != NULL)
02045 free (fixed_header);
02046 return FALSE;
02047 }