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