1 /* vms-gsd.c -- BFD back-end for VAX (openVMS/VAX) and 2 EVAX (openVMS/Alpha) files. 3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 4 Free Software Foundation, Inc. 5 6 go and read the openVMS linker manual (esp. appendix B) 7 if you don't know what's going on here :-) 8 9 Written by Klaus K"ampf (kkaempf@rmi.de) 10 11 This program is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 2 of the License, or 14 (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program; if not, write to the Free Software 23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 24 25 #include "bfd.h" 26 #include "sysdep.h" 27 #include "bfdlink.h" 28 #include "libbfd.h" 29 30 #include "vms.h" 31 32 /* Typical sections for vax object files. */ 33 34 #define VAX_CODE_NAME "$CODE" 35 #define VAX_DATA_NAME "$DATA" 36 #define VAX_ADDRESS_DATA_NAME "$ADDRESS_DATA" 37 38 /* Typical sections for evax object files. */ 39 40 #define EVAX_ABS_NAME "$ABS$" 41 #define EVAX_CODE_NAME "$CODE$" 42 #define EVAX_LINK_NAME "$LINK$" 43 #define EVAX_DATA_NAME "$DATA$" 44 #define EVAX_BSS_NAME "$BSS$" 45 #define EVAX_READONLYADDR_NAME "$READONLY_ADDR$" 46 #define EVAX_READONLY_NAME "$READONLY$" 47 #define EVAX_LITERAL_NAME "$LITERAL$" 48 #define EVAX_COMMON_NAME "$COMMON$" 49 #define EVAX_LOCAL_NAME "$LOCAL$" 50 51 struct sec_flags_struct 52 { 53 char *name; /* Name of section. */ 54 int vflags_always; 55 flagword flags_always; /* Flags we set always. */ 56 int vflags_hassize; 57 flagword flags_hassize; /* Flags we set if the section has a size > 0. */ 58 }; 59 60 /* These flags are deccrtl/vaxcrtl (openVMS 6.2 VAX) compatible. */ 61 62 static struct sec_flags_struct vax_section_flags[] = 63 { 64 { VAX_CODE_NAME, 65 (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_SHR | GPS_S_M_EXE | GPS_S_M_RD), 66 (SEC_CODE), 67 (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_SHR | GPS_S_M_EXE | GPS_S_M_RD), 68 (SEC_IN_MEMORY | SEC_CODE | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, 69 { VAX_DATA_NAME, 70 (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD | GPS_S_M_WRT), 71 (SEC_DATA), 72 (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD | GPS_S_M_WRT), 73 (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, 74 { VAX_ADDRESS_DATA_NAME, 75 (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD), 76 (SEC_DATA | SEC_READONLY), 77 (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD), 78 (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) }, 79 { NULL, 80 (GPS_S_M_PIC | GPS_S_M_OVR | GPS_S_M_REL | GPS_S_M_GBL | GPS_S_M_RD | GPS_S_M_WRT), 81 (SEC_DATA), 82 (GPS_S_M_PIC | GPS_S_M_OVR | GPS_S_M_REL | GPS_S_M_GBL | GPS_S_M_RD | GPS_S_M_WRT), 83 (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) } 84 }; 85 86 /* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible. */ 87 88 static struct sec_flags_struct evax_section_flags[] = 89 { 90 { EVAX_ABS_NAME, 91 (EGPS_S_V_SHR), 92 (SEC_DATA), 93 (EGPS_S_V_SHR), 94 (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, 95 { EVAX_CODE_NAME, 96 (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_EXE), 97 (SEC_CODE), 98 (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_EXE), 99 (SEC_IN_MEMORY | SEC_CODE | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, 100 { EVAX_LITERAL_NAME, 101 (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_RD | EGPS_S_V_NOMOD), 102 (SEC_DATA | SEC_READONLY), 103 (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_RD), 104 (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) }, 105 { EVAX_LINK_NAME, 106 (EGPS_S_V_REL | EGPS_S_V_RD), 107 (SEC_DATA | SEC_READONLY), 108 (EGPS_S_V_REL | EGPS_S_V_RD), 109 (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) }, 110 { EVAX_DATA_NAME, 111 (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT | EGPS_S_V_NOMOD), 112 (SEC_DATA), 113 (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT), 114 (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, 115 { EVAX_BSS_NAME, 116 (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT | EGPS_S_V_NOMOD), 117 (SEC_NO_FLAGS), 118 (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT | EGPS_S_V_NOMOD), 119 (SEC_IN_MEMORY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, 120 { EVAX_READONLYADDR_NAME, 121 (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_RD), 122 (SEC_DATA | SEC_READONLY), 123 (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_RD), 124 (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) }, 125 { EVAX_READONLY_NAME, 126 (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_RD | EGPS_S_V_NOMOD), 127 (SEC_DATA | SEC_READONLY), 128 (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_RD), 129 (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) }, 130 { EVAX_LOCAL_NAME, 131 (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT), 132 (SEC_DATA), 133 (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT), 134 (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, 135 { NULL, 136 (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT), 137 (SEC_DATA), 138 (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT), 139 (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) } 140 }; 141 142 /* Retrieve bfd section flags by name and size. */ 143 144 static flagword 145 vms_secflag_by_name (bfd *abfd, 146 struct sec_flags_struct *section_flags, 147 char *name, 148 int hassize) 149 { 150 int i = 0; 151 152 while (section_flags[i].name != NULL) 153 { 154 if ((PRIV (is_vax)? 155 strcasecmp (name, section_flags[i].name): 156 strcmp (name, section_flags[i].name)) == 0) 157 { 158 if (hassize) 159 return section_flags[i].flags_hassize; 160 else 161 return section_flags[i].flags_always; 162 } 163 i++; 164 } 165 if (hassize) 166 return section_flags[i].flags_hassize; 167 return section_flags[i].flags_always; 168 } 169 170 /* Retrieve vms section flags by name and size. */ 171 172 static flagword 173 vms_esecflag_by_name (struct sec_flags_struct *section_flags, 174 char *name, 175 int hassize) 176 { 177 int i = 0; 178 179 while (section_flags[i].name != NULL) 180 { 181 if (strcmp (name, section_flags[i].name) == 0) 182 { 183 if (hassize) 184 return section_flags[i].vflags_hassize; 185 else 186 return section_flags[i].vflags_always; 187 } 188 i++; 189 } 190 if (hassize) 191 return section_flags[i].vflags_hassize; 192 return section_flags[i].vflags_always; 193 } 194 195 #if VMS_DEBUG 196 197 struct flagdescstruct { char *name; flagword value; }; 198 199 /* Convert flag to printable string. */ 200 201 static char * 202 flag2str (struct flagdescstruct * flagdesc, flagword flags) 203 { 204 static char res[64]; 205 int next = 0; 206 207 res[0] = 0; 208 while (flagdesc->name != NULL) 209 { 210 if ((flags & flagdesc->value) != 0) 211 { 212 if (next) 213 strcat (res, ","); 214 else 215 next = 1; 216 strcat (res, flagdesc->name); 217 } 218 flagdesc++; 219 } 220 return res; 221 } 222 #endif 223 224 /* Input routines. */ 225 226 /* Process GSD/EGSD record 227 return 0 on success, -1 on error. */ 228 229 int 230 _bfd_vms_slurp_gsd (bfd * abfd, int objtype) 231 { 232 #if VMS_DEBUG 233 static struct flagdescstruct gpsflagdesc[] = 234 { 235 { "PIC", 0x0001 }, 236 { "LIB", 0x0002 }, 237 { "OVR", 0x0004 }, 238 { "REL", 0x0008 }, 239 { "GBL", 0x0010 }, 240 { "SHR", 0x0020 }, 241 { "EXE", 0x0040 }, 242 { "RD", 0x0080 }, 243 { "WRT", 0x0100 }, 244 { "VEC", 0x0200 }, 245 { "NOMOD", 0x0400 }, 246 { "COM", 0x0800 }, 247 { NULL, 0 } 248 }; 249 250 static struct flagdescstruct gsyflagdesc[] = 251 { 252 { "WEAK", 0x0001 }, 253 { "DEF", 0x0002 }, 254 { "UNI", 0x0004 }, 255 { "REL", 0x0008 }, 256 { "COMM", 0x0010 }, 257 { "VECEP", 0x0020 }, 258 { "NORM", 0x0040 }, 259 { NULL, 0 } 260 }; 261 #endif 262 263 int gsd_type, gsd_size; 264 asection *section; 265 unsigned char *vms_rec; 266 flagword new_flags, old_flags; 267 char *name; 268 asymbol *symbol; 269 vms_symbol_entry *entry; 270 unsigned long base_addr; 271 unsigned long align_addr; 272 static unsigned int psect_idx = 0; 273 274 #if VMS_DEBUG 275 vms_debug (2, "GSD/EGSD (%d/%x)\n", objtype, objtype); 276 #endif 277 278 switch (objtype) 279 { 280 case EOBJ_S_C_EGSD: 281 PRIV (vms_rec) += 8; /* Skip type, size, l_temp. */ 282 PRIV (rec_size) -= 8; 283 break; 284 case OBJ_S_C_GSD: 285 PRIV (vms_rec) += 1; 286 PRIV (rec_size) -= 1; 287 break; 288 default: 289 return -1; 290 } 291 292 /* Calculate base address for each section. */ 293 base_addr = 0L; 294 295 abfd->symcount = 0; 296 297 while (PRIV (rec_size) > 0) 298 { 299 vms_rec = PRIV (vms_rec); 300 301 if (objtype == OBJ_S_C_GSD) 302 gsd_type = *vms_rec; 303 else 304 { 305 _bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size); 306 gsd_type += EVAX_OFFSET; 307 } 308 309 #if VMS_DEBUG 310 vms_debug (3, "gsd_type %d\n", gsd_type); 311 #endif 312 313 switch (gsd_type) 314 { 315 case GSD_S_C_PSC: 316 { 317 /* Program section definition. */ 318 asection *old_section = 0; 319 320 #if VMS_DEBUG 321 vms_debug (4, "GSD_S_C_PSC\n"); 322 #endif 323 /* If this section isn't a bfd section. */ 324 if (PRIV (is_vax) && (psect_idx < (abfd->section_count-1))) 325 { 326 /* Check for temporary section from TIR record. */ 327 if (psect_idx < PRIV (section_count)) 328 old_section = PRIV (sections)[psect_idx]; 329 else 330 old_section = 0; 331 } 332 333 name = _bfd_vms_save_counted_string (vms_rec + 8); 334 section = bfd_make_section (abfd, name); 335 if (!section) 336 { 337 (*_bfd_error_handler) (_("bfd_make_section (%s) failed"), 338 name); 339 return -1; 340 } 341 old_flags = bfd_getl16 (vms_rec + 2); 342 section->size = bfd_getl32 (vms_rec + 4); /* allocation */ 343 new_flags = vms_secflag_by_name (abfd, vax_section_flags, name, 344 section->size > 0); 345 if (old_flags & EGPS_S_V_REL) 346 new_flags |= SEC_RELOC; 347 if (old_flags & GPS_S_M_OVR) 348 new_flags |= SEC_IS_COMMON; 349 if (!bfd_set_section_flags (abfd, section, new_flags)) 350 { 351 (*_bfd_error_handler) 352 (_("bfd_set_section_flags (%s, %x) failed"), 353 name, new_flags); 354 return -1; 355 } 356 section->alignment_power = vms_rec[1]; 357 align_addr = (1 << section->alignment_power); 358 if ((base_addr % align_addr) != 0) 359 base_addr += (align_addr - (base_addr % align_addr)); 360 section->vma = (bfd_vma)base_addr; 361 base_addr += section->size; 362 363 /* Global section is common symbol. */ 364 365 if (old_flags & GPS_S_M_GBL) 366 { 367 entry = _bfd_vms_enter_symbol (abfd, name); 368 if (entry == NULL) 369 { 370 bfd_set_error (bfd_error_no_memory); 371 return -1; 372 } 373 symbol = entry->symbol; 374 375 symbol->value = 0; 376 symbol->section = section; 377 symbol->flags = (BSF_GLOBAL | BSF_SECTION_SYM | BSF_OLD_COMMON); 378 } 379 380 /* Copy saved contents if old_section set. */ 381 if (old_section != 0) 382 { 383 section->contents = old_section->contents; 384 if (section->size < old_section->size) 385 { 386 (*_bfd_error_handler) 387 (_("Size mismatch section %s=%lx, %s=%lx"), 388 old_section->name, 389 (unsigned long) old_section->size, 390 section->name, 391 (unsigned long) section->size); 392 return -1; 393 } 394 else if (section->size > old_section->size) 395 { 396 section->contents = bfd_realloc (old_section->contents, 397 section->size); 398 if (section->contents == NULL) 399 { 400 bfd_set_error (bfd_error_no_memory); 401 return -1; 402 } 403 } 404 } 405 else 406 { 407 section->contents = bfd_zmalloc (section->size); 408 if (section->contents == NULL) 409 { 410 bfd_set_error (bfd_error_no_memory); 411 return -1; 412 } 413 } 414 #if VMS_DEBUG 415 vms_debug (4, "gsd psc %d (%s, flags %04x=%s) ", 416 section->index, name, old_flags, flag2str (gpsflagdesc, old_flags)); 417 vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n", 418 section->size, section->vma, section->contents); 419 #endif 420 421 gsd_size = vms_rec[8] + 9; 422 423 psect_idx++; 424 } 425 break; 426 427 case GSD_S_C_EPM: 428 case GSD_S_C_EPMW: 429 #if VMS_DEBUG 430 vms_debug (4, "gsd epm\n"); 431 #endif 432 /* Fall through. */ 433 case GSD_S_C_SYM: 434 case GSD_S_C_SYMW: 435 { 436 int name_offset = 0, value_offset = 0; 437 438 /* Symbol specification (definition or reference). */ 439 #if VMS_DEBUG 440 vms_debug (4, "GSD_S_C_SYM(W)\n"); 441 #endif 442 old_flags = bfd_getl16 (vms_rec + 2); 443 new_flags = BSF_NO_FLAGS; 444 445 if (old_flags & GSY_S_M_WEAK) 446 new_flags |= BSF_WEAK; 447 448 switch (gsd_type) 449 { 450 case GSD_S_C_EPM: 451 name_offset = 11; 452 value_offset = 5; 453 new_flags |= BSF_FUNCTION; 454 break; 455 case GSD_S_C_EPMW: 456 name_offset = 12; 457 value_offset = 6; 458 new_flags |= BSF_FUNCTION; 459 break; 460 case GSD_S_C_SYM: 461 if (old_flags & GSY_S_M_DEF) /* Symbol definition. */ 462 name_offset = 9; 463 else 464 name_offset = 4; 465 value_offset = 5; 466 break; 467 case GSD_S_C_SYMW: 468 if (old_flags & GSY_S_M_DEF) /* Symbol definition. */ 469 name_offset = 10; 470 else 471 name_offset = 5; 472 value_offset = 6; 473 break; 474 } 475 476 /* Save symbol in vms_symbol_table. */ 477 entry = _bfd_vms_enter_symbol 478 (abfd, _bfd_vms_save_counted_string (vms_rec + name_offset)); 479 if (entry == NULL) 480 { 481 bfd_set_error (bfd_error_no_memory); 482 return -1; 483 } 484 symbol = entry->symbol; 485 486 if (old_flags & GSY_S_M_DEF) 487 { 488 /* Symbol definition. */ 489 int psect; 490 491 symbol->value = bfd_getl32 (vms_rec + value_offset); 492 if ((gsd_type == GSD_S_C_SYMW) 493 || (gsd_type == GSD_S_C_EPMW)) 494 psect = bfd_getl16 (vms_rec + value_offset - 2); 495 else 496 psect = vms_rec[value_offset-1]; 497 498 symbol->section = (asection *) (size_t) psect; 499 #if VMS_DEBUG 500 vms_debug (4, "gsd sym def #%d (%s, %d [%p], %04x=%s)\n", abfd->symcount, 501 symbol->name, (int)symbol->section, symbol->section, old_flags, flag2str (gsyflagdesc, old_flags)); 502 #endif 503 } 504 else 505 { 506 /* Symbol reference. */ 507 symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME); 508 #if VMS_DEBUG 509 vms_debug (4, "gsd sym ref #%d (%s, %s [%p], %04x=%s)\n", 510 abfd->symcount, symbol->name, symbol->section->name, 511 symbol->section, old_flags, flag2str (gsyflagdesc, old_flags)); 512 #endif 513 } 514 515 gsd_size = vms_rec[name_offset] + name_offset + 1; 516 symbol->flags = new_flags; 517 } 518 519 break; 520 521 case GSD_S_C_PRO: 522 case GSD_S_C_PROW: 523 #if VMS_DEBUG 524 vms_debug (4, "gsd pro\n"); 525 #endif 526 break; 527 case GSD_S_C_IDC: 528 #if VMS_DEBUG 529 vms_debug (4, "gsd idc\n"); 530 #endif 531 break; 532 case GSD_S_C_ENV: 533 #if VMS_DEBUG 534 vms_debug (4, "gsd env\n"); 535 #endif 536 break; 537 case GSD_S_C_LSY: 538 #if VMS_DEBUG 539 vms_debug (4, "gsd lsy\n"); 540 #endif 541 break; 542 case GSD_S_C_LEPM: 543 #if VMS_DEBUG 544 vms_debug (4, "gsd lepm\n"); 545 #endif 546 break; 547 case GSD_S_C_LPRO: 548 #if VMS_DEBUG 549 vms_debug (4, "gsd lpro\n"); 550 #endif 551 break; 552 case GSD_S_C_SPSC: 553 #if VMS_DEBUG 554 vms_debug (4, "gsd spsc\n"); 555 #endif 556 break; 557 case GSD_S_C_SYMV: 558 #if VMS_DEBUG 559 vms_debug (4, "gsd symv\n"); 560 #endif 561 break; 562 case GSD_S_C_EPMV: 563 #if VMS_DEBUG 564 vms_debug (4, "gsd epmv\n"); 565 #endif 566 break; 567 case GSD_S_C_PROV: 568 #if VMS_DEBUG 569 vms_debug (4, "gsd prov\n"); 570 #endif 571 break; 572 573 case EGSD_S_C_PSC + EVAX_OFFSET: 574 { 575 /* Program section definition. */ 576 name = _bfd_vms_save_counted_string (vms_rec + 12); 577 section = bfd_make_section (abfd, name); 578 if (!section) 579 return -1; 580 old_flags = bfd_getl16 (vms_rec + 6); 581 section->size = bfd_getl32 (vms_rec + 8); /* Allocation. */ 582 new_flags = vms_secflag_by_name (abfd, evax_section_flags, name, 583 section->size > 0); 584 if (old_flags & EGPS_S_V_REL) 585 new_flags |= SEC_RELOC; 586 if (!bfd_set_section_flags (abfd, section, new_flags)) 587 return -1; 588 section->alignment_power = vms_rec[4]; 589 align_addr = (1 << section->alignment_power); 590 if ((base_addr % align_addr) != 0) 591 base_addr += (align_addr - (base_addr % align_addr)); 592 section->vma = (bfd_vma)base_addr; 593 base_addr += section->size; 594 section->contents = bfd_zmalloc (section->size); 595 if (section->contents == NULL) 596 return -1; 597 #if VMS_DEBUG 598 vms_debug (4, "egsd psc %d (%s, flags %04x=%s) ", 599 section->index, name, old_flags, flag2str (gpsflagdesc, old_flags)); 600 vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n", 601 section->size, section->vma, section->contents); 602 #endif 603 } 604 break; 605 606 case EGSD_S_C_SYM + EVAX_OFFSET: 607 { 608 /* Symbol specification (definition or reference). */ 609 symbol = bfd_make_empty_symbol (abfd); 610 if (symbol == 0) 611 return -1; 612 613 old_flags = bfd_getl16 (vms_rec + 6); 614 new_flags = BSF_NO_FLAGS; 615 616 if (old_flags & EGSY_S_V_WEAK) 617 new_flags |= BSF_WEAK; 618 619 if (vms_rec[6] & EGSY_S_V_DEF) 620 { 621 /* Symbol definition. */ 622 symbol->name = _bfd_vms_save_counted_string (vms_rec + 32); 623 if (old_flags & EGSY_S_V_NORM) 624 /* Proc def. */ 625 new_flags |= BSF_FUNCTION; 626 627 symbol->value = bfd_getl64 (vms_rec + 8); 628 symbol->section = (asection *) ((unsigned long) bfd_getl32 (vms_rec + 28)); 629 #if VMS_DEBUG 630 vms_debug (4, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount, 631 symbol->name, (int) symbol->section, old_flags, 632 flag2str (gsyflagdesc, old_flags)); 633 #endif 634 } 635 else 636 { 637 /* Symbol reference. */ 638 symbol->name = _bfd_vms_save_counted_string (vms_rec + 8); 639 #if VMS_DEBUG 640 vms_debug (4, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount, 641 symbol->name, old_flags, flag2str (gsyflagdesc, old_flags)); 642 #endif 643 symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME); 644 } 645 646 symbol->flags = new_flags; 647 648 /* Save symbol in vms_symbol_table. */ 649 entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table), 650 symbol->name, 651 TRUE, FALSE); 652 if (entry == NULL) 653 { 654 bfd_set_error (bfd_error_no_memory); 655 return -1; 656 } 657 658 if (entry->symbol != NULL) 659 { 660 /* FIXME ?, DEC C generates this. */ 661 #if VMS_DEBUG 662 vms_debug (4, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name); 663 #endif 664 } 665 else 666 { 667 entry->symbol = symbol; 668 PRIV (gsd_sym_count)++; 669 abfd->symcount++; 670 } 671 } 672 break; 673 674 case EGSD_S_C_IDC + EVAX_OFFSET: 675 break; 676 677 default: 678 (*_bfd_error_handler) (_("unknown gsd/egsd subtype %d"), gsd_type); 679 bfd_set_error (bfd_error_bad_value); 680 return -1; 681 } 682 683 PRIV (rec_size) -= gsd_size; 684 PRIV (vms_rec) += gsd_size; 685 } 686 687 if (abfd->symcount > 0) 688 abfd->flags |= HAS_SYMS; 689 690 return 0; 691 } 692 693 /* Output routines. */ 694 695 /* Write section and symbol directory of bfd abfd. */ 696 697 int 698 _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED) 699 { 700 asection *section; 701 asymbol *symbol; 702 unsigned int symnum; 703 int last_index = -1; 704 char dummy_name[10]; 705 char *sname; 706 flagword new_flags, old_flags; 707 708 #if VMS_DEBUG 709 vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype); 710 #endif 711 712 /* Output sections. */ 713 section = abfd->sections; 714 #if VMS_DEBUG 715 vms_debug (3, "%d sections found\n", abfd->section_count); 716 #endif 717 718 /* Egsd is quadword aligned. */ 719 _bfd_vms_output_alignment (abfd, 8); 720 721 _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1); 722 _bfd_vms_output_long (abfd, 0); 723 /* Prepare output for subrecords. */ 724 _bfd_vms_output_push (abfd); 725 726 while (section != 0) 727 { 728 #if VMS_DEBUG 729 vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->size); 730 #endif 731 732 /* 13 bytes egsd, max 31 chars name -> should be 44 bytes. */ 733 if (_bfd_vms_output_check (abfd, 64) < 0) 734 { 735 _bfd_vms_output_pop (abfd); 736 _bfd_vms_output_end (abfd); 737 _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1); 738 _bfd_vms_output_long (abfd, 0); 739 /* Prepare output for subrecords. */ 740 _bfd_vms_output_push (abfd); 741 } 742 743 /* Create dummy sections to keep consecutive indices. */ 744 while (section->index - last_index > 1) 745 { 746 #if VMS_DEBUG 747 vms_debug (3, "index %d, last %d\n", section->index, last_index); 748 #endif 749 _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1); 750 _bfd_vms_output_short (abfd, 0); 751 _bfd_vms_output_short (abfd, 0); 752 _bfd_vms_output_long (abfd, 0); 753 sprintf (dummy_name, ".DUMMY%02d", last_index); 754 _bfd_vms_output_counted (abfd, dummy_name); 755 _bfd_vms_output_flush (abfd); 756 last_index++; 757 } 758 759 /* Don't know if this is necessary for the linker but for now it keeps 760 vms_slurp_gsd happy */ 761 sname = (char *)section->name; 762 if (*sname == '.') 763 { 764 sname++; 765 if ((*sname == 't') && (strcmp (sname, "text") == 0)) 766 sname = PRIV (is_vax)?VAX_CODE_NAME:EVAX_CODE_NAME; 767 else if ((*sname == 'd') && (strcmp (sname, "data") == 0)) 768 sname = PRIV (is_vax)?VAX_DATA_NAME:EVAX_DATA_NAME; 769 else if ((*sname == 'b') && (strcmp (sname, "bss") == 0)) 770 sname = EVAX_BSS_NAME; 771 else if ((*sname == 'l') && (strcmp (sname, "link") == 0)) 772 sname = EVAX_LINK_NAME; 773 else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0)) 774 sname = EVAX_READONLY_NAME; 775 else if ((*sname == 'l') && (strcmp (sname, "literal") == 0)) 776 sname = EVAX_LITERAL_NAME; 777 else if ((*sname == 'c') && (strcmp (sname, "comm") == 0)) 778 sname = EVAX_COMMON_NAME; 779 else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0)) 780 sname = EVAX_LOCAL_NAME; 781 } 782 else 783 sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ); 784 785 _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1); 786 _bfd_vms_output_short (abfd, section->alignment_power & 0xff); 787 if (bfd_is_com_section (section)) 788 new_flags = (EGPS_S_V_OVR | EGPS_S_V_REL | EGPS_S_V_GBL | EGPS_S_V_RD | EGPS_S_V_WRT | EGPS_S_V_NOMOD | EGPS_S_V_COM); 789 else 790 new_flags = vms_esecflag_by_name (evax_section_flags, sname, 791 section->size > 0); 792 793 _bfd_vms_output_short (abfd, new_flags); 794 _bfd_vms_output_long (abfd, (unsigned long) section->size); 795 _bfd_vms_output_counted (abfd, sname); 796 _bfd_vms_output_flush (abfd); 797 798 last_index = section->index; 799 section = section->next; 800 } 801 802 /* Output symbols. */ 803 #if VMS_DEBUG 804 vms_debug (3, "%d symbols found\n", abfd->symcount); 805 #endif 806 807 bfd_set_start_address (abfd, (bfd_vma) -1); 808 809 for (symnum = 0; symnum < abfd->symcount; symnum++) 810 { 811 char *hash; 812 813 symbol = abfd->outsymbols[symnum]; 814 if (*(symbol->name) == '_') 815 { 816 if (strcmp (symbol->name, "__main") == 0) 817 bfd_set_start_address (abfd, (bfd_vma)symbol->value); 818 } 819 old_flags = symbol->flags; 820 821 if (old_flags & BSF_FILE) 822 continue; 823 824 if (((old_flags & (BSF_GLOBAL | BSF_WEAK)) == 0) /* Not xdef... */ 825 && (!bfd_is_und_section (symbol->section))) /* ...and not xref. */ 826 continue; /* Dont output. */ 827 828 /* 13 bytes egsd, max 64 chars name -> should be 77 bytes. */ 829 if (_bfd_vms_output_check (abfd, 80) < 0) 830 { 831 _bfd_vms_output_pop (abfd); 832 _bfd_vms_output_end (abfd); 833 _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1); 834 _bfd_vms_output_long (abfd, 0); 835 /* Prepare output for subrecords. */ 836 _bfd_vms_output_push (abfd); 837 } 838 839 _bfd_vms_output_begin (abfd, EGSD_S_C_SYM, -1); 840 841 /* Data type, alignment. */ 842 _bfd_vms_output_short (abfd, 0); 843 844 new_flags = 0; 845 846 if (old_flags & BSF_WEAK) 847 new_flags |= EGSY_S_V_WEAK; 848 if (bfd_is_com_section (symbol->section)) 849 new_flags |= (EGSY_S_V_WEAK | EGSY_S_V_COMM); 850 851 if (old_flags & BSF_FUNCTION) 852 { 853 new_flags |= EGSY_S_V_NORM; 854 new_flags |= EGSY_S_V_REL; 855 } 856 if (old_flags & (BSF_GLOBAL | BSF_WEAK)) 857 { 858 new_flags |= EGSY_S_V_DEF; 859 if (!bfd_is_abs_section (symbol->section)) 860 new_flags |= EGSY_S_V_REL; 861 } 862 _bfd_vms_output_short (abfd, new_flags); 863 864 if (old_flags & (BSF_GLOBAL | BSF_WEAK)) 865 { 866 /* Symbol definition. */ 867 uquad code_address = 0; 868 unsigned long ca_psindx = 0; 869 unsigned long psindx; 870 871 if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL) 872 { 873 code_address = ((asymbol *) (symbol->udata.p))->value; 874 ca_psindx = ((asymbol *) (symbol->udata.p))->section->index; 875 } 876 psindx = symbol->section->index; 877 878 _bfd_vms_output_quad (abfd, symbol->value); 879 _bfd_vms_output_quad (abfd, code_address); 880 _bfd_vms_output_long (abfd, ca_psindx); 881 _bfd_vms_output_long (abfd, psindx); 882 } 883 hash = _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ); 884 _bfd_vms_output_counted (abfd, hash); 885 886 _bfd_vms_output_flush (abfd); 887 888 } 889 890 _bfd_vms_output_alignment (abfd, 8); 891 _bfd_vms_output_pop (abfd); 892 _bfd_vms_output_end (abfd); 893 894 return 0; 895 } 896