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