00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "bfd.h"
00030 #include "sysdep.h"
00031 #include "bfdlink.h"
00032 #include "libbfd.h"
00033
00034 #include "vms.h"
00035
00036
00037
00038
00039
00040 #define VAX_CODE_NAME "$CODE"
00041 #define VAX_DATA_NAME "$DATA"
00042 #define VAX_ADDRESS_DATA_NAME "$ADDRESS_DATA"
00043
00044
00045
00046 #define EVAX_ABS_NAME "$ABS$"
00047 #define EVAX_CODE_NAME "$CODE$"
00048 #define EVAX_LINK_NAME "$LINK$"
00049 #define EVAX_DATA_NAME "$DATA$"
00050 #define EVAX_BSS_NAME "$BSS$"
00051 #define EVAX_READONLYADDR_NAME "$READONLY_ADDR$"
00052 #define EVAX_READONLY_NAME "$READONLY$"
00053 #define EVAX_LITERAL_NAME "$LITERAL$"
00054 #define EVAX_COMMON_NAME "$COMMON$"
00055 #define EVAX_LOCAL_NAME "$LOCAL$"
00056
00057 struct sec_flags_struct {
00058 char *name;
00059 int vflags_always;
00060 flagword flags_always;
00061 int vflags_hassize;
00062 flagword flags_hassize;
00063 };
00064
00065
00066
00067 static struct sec_flags_struct vax_section_flags[] = {
00068 { VAX_CODE_NAME,
00069 (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD),
00070 (SEC_CODE),
00071 (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD),
00072 (SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
00073 { VAX_DATA_NAME,
00074 (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT),
00075 (SEC_DATA),
00076 (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT),
00077 (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
00078 { VAX_ADDRESS_DATA_NAME,
00079 (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD),
00080 (SEC_DATA|SEC_READONLY),
00081 (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD),
00082 (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
00083 { NULL,
00084 (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT),
00085 (SEC_DATA),
00086 (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT),
00087 (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }
00088 };
00089
00090
00091
00092 static struct sec_flags_struct evax_section_flags[] = {
00093 { EVAX_ABS_NAME,
00094 (EGPS_S_V_SHR),
00095 (SEC_DATA),
00096 (EGPS_S_V_SHR),
00097 (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
00098 { EVAX_CODE_NAME,
00099 (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
00100 (SEC_CODE),
00101 (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
00102 (SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
00103 { EVAX_LITERAL_NAME,
00104 (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
00105 (SEC_DATA|SEC_READONLY),
00106 (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
00107 (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
00108 { EVAX_LINK_NAME,
00109 (EGPS_S_V_REL|EGPS_S_V_RD),
00110 (SEC_DATA|SEC_READONLY),
00111 (EGPS_S_V_REL|EGPS_S_V_RD),
00112 (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
00113 { EVAX_DATA_NAME,
00114 (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
00115 (SEC_DATA),
00116 (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
00117 (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
00118 { EVAX_BSS_NAME,
00119 (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
00120 (SEC_NO_FLAGS),
00121 (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
00122 (SEC_IN_MEMORY|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
00123 { EVAX_READONLYADDR_NAME,
00124 (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
00125 (SEC_DATA|SEC_READONLY),
00126 (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
00127 (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
00128 { EVAX_READONLY_NAME,
00129 (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
00130 (SEC_DATA|SEC_READONLY),
00131 (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
00132 (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
00133 { EVAX_LOCAL_NAME,
00134 (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
00135 (SEC_DATA),
00136 (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
00137 (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
00138 { NULL,
00139 (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
00140 (SEC_DATA),
00141 (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
00142 (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }
00143 };
00144
00145 static flagword vms_secflag_by_name PARAMS ((bfd *, struct sec_flags_struct *, char *, int));
00146 static flagword vms_esecflag_by_name PARAMS ((struct sec_flags_struct *, char *, int));
00147
00148
00149
00150 static flagword
00151 vms_secflag_by_name (abfd, section_flags, name, hassize)
00152 bfd *abfd;
00153 struct sec_flags_struct *section_flags;
00154 char *name;
00155 int hassize;
00156 {
00157 int i = 0;
00158
00159 while (section_flags[i].name != NULL)
00160 {
00161 if ((PRIV(is_vax)?
00162 strcasecmp (name, section_flags[i].name):
00163 strcmp (name, section_flags[i].name)) == 0)
00164 {
00165 if (hassize)
00166 return section_flags[i].flags_hassize;
00167 else
00168 return section_flags[i].flags_always;
00169 }
00170 i++;
00171 }
00172 if (hassize)
00173 return section_flags[i].flags_hassize;
00174 return section_flags[i].flags_always;
00175 }
00176
00177
00178
00179 static flagword
00180 vms_esecflag_by_name (section_flags, name, hassize)
00181 struct sec_flags_struct *section_flags;
00182 char *name;
00183 int hassize;
00184 {
00185 int i = 0;
00186
00187 while (section_flags[i].name != NULL)
00188 {
00189 if (strcmp (name, section_flags[i].name) == 0)
00190 {
00191 if (hassize)
00192 return section_flags[i].vflags_hassize;
00193 else
00194 return section_flags[i].vflags_always;
00195 }
00196 i++;
00197 }
00198 if (hassize)
00199 return section_flags[i].vflags_hassize;
00200 return section_flags[i].vflags_always;
00201 }
00202
00203
00204 #if VMS_DEBUG
00205
00206
00207 struct flagdescstruct { char *name; flagword value; };
00208
00209
00210
00211 static char *
00212 flag2str(flagdesc, flags)
00213 struct flagdescstruct *flagdesc;
00214 flagword flags;
00215 {
00216
00217 static char res[64];
00218 int next = 0;
00219
00220 res[0] = 0;
00221 while (flagdesc->name != NULL)
00222 {
00223 if ((flags & flagdesc->value) != 0)
00224 {
00225 if (next)
00226 strcat(res, ",");
00227 else
00228 next = 1;
00229 strcat (res, flagdesc->name);
00230 }
00231 flagdesc++;
00232 }
00233 return res;
00234 }
00235 #endif
00236
00237
00238
00239
00240
00241
00242
00243 int
00244 _bfd_vms_slurp_gsd (abfd, objtype)
00245 bfd *abfd;
00246 int objtype;
00247 {
00248 #if VMS_DEBUG
00249 static struct flagdescstruct gpsflagdesc[] =
00250 {
00251 { "PIC", 0x0001 },
00252 { "LIB", 0x0002 },
00253 { "OVR", 0x0004 },
00254 { "REL", 0x0008 },
00255 { "GBL", 0x0010 },
00256 { "SHR", 0x0020 },
00257 { "EXE", 0x0040 },
00258 { "RD", 0x0080 },
00259 { "WRT", 0x0100 },
00260 { "VEC", 0x0200 },
00261 { "NOMOD", 0x0400 },
00262 { "COM", 0x0800 },
00263 { NULL, 0 }
00264 };
00265
00266 static struct flagdescstruct gsyflagdesc[] =
00267 {
00268 { "WEAK", 0x0001 },
00269 { "DEF", 0x0002 },
00270 { "UNI", 0x0004 },
00271 { "REL", 0x0008 },
00272 { "COMM", 0x0010 },
00273 { "VECEP", 0x0020 },
00274 { "NORM", 0x0040 },
00275 { NULL, 0 }
00276 };
00277 #endif
00278
00279 int gsd_type, gsd_size;
00280 asection *section;
00281 unsigned char *vms_rec;
00282 flagword new_flags, old_flags;
00283 char *name;
00284 asymbol *symbol;
00285 vms_symbol_entry *entry;
00286 unsigned long base_addr;
00287 unsigned long align_addr;
00288 static unsigned int psect_idx = 0;
00289
00290 #if VMS_DEBUG
00291 vms_debug (2, "GSD/EGSD (%d/%x)\n", objtype, objtype);
00292 #endif
00293
00294 switch (objtype)
00295 {
00296 case EOBJ_S_C_EGSD:
00297 PRIV(vms_rec) += 8;
00298 PRIV(rec_size) -= 8;
00299 break;
00300 case OBJ_S_C_GSD:
00301 PRIV(vms_rec) += 1;
00302 PRIV(rec_size) -= 1;
00303 break;
00304 default:
00305 return -1;
00306 }
00307
00308
00309 base_addr = 0L;
00310
00311 abfd->symcount = 0;
00312
00313 while (PRIV(rec_size) > 0)
00314 {
00315 vms_rec = PRIV(vms_rec);
00316
00317 if (objtype == OBJ_S_C_GSD)
00318 {
00319 gsd_type = *vms_rec;
00320 }
00321 else
00322 {
00323 _bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size);
00324 gsd_type += EVAX_OFFSET;
00325 }
00326
00327 #if VMS_DEBUG
00328 vms_debug (3, "gsd_type %d\n", gsd_type);
00329 #endif
00330
00331 switch (gsd_type)
00332 {
00333 case GSD_S_C_PSC:
00334 {
00335
00336
00337
00338
00339 asection *old_section = 0;
00340
00341 #if VMS_DEBUG
00342 vms_debug (4, "GSD_S_C_PSC\n");
00343 #endif
00344
00345
00346 if (PRIV(is_vax) && (psect_idx < (abfd->section_count-1)))
00347 {
00348
00349
00350 if (psect_idx < PRIV(section_count))
00351 old_section = PRIV(sections)[psect_idx];
00352 else
00353 old_section = 0;
00354 }
00355
00356 name = _bfd_vms_save_counted_string (vms_rec + 8);
00357 section = bfd_make_section (abfd, name);
00358 if (!section)
00359 {
00360 (*_bfd_error_handler) (_("bfd_make_section (%s) failed"),
00361 name);
00362 return -1;
00363 }
00364 old_flags = bfd_getl16 (vms_rec + 2);
00365 section->size = bfd_getl32 (vms_rec + 4);
00366 new_flags = vms_secflag_by_name (abfd, vax_section_flags, name,
00367 section->size > 0);
00368 if (old_flags & EGPS_S_V_REL)
00369 new_flags |= SEC_RELOC;
00370 if (old_flags & GPS_S_M_OVR)
00371 new_flags |= SEC_IS_COMMON;
00372 if (!bfd_set_section_flags (abfd, section, new_flags))
00373 {
00374 (*_bfd_error_handler)
00375 (_("bfd_set_section_flags (%s, %x) failed"),
00376 name, new_flags);
00377 return -1;
00378 }
00379 section->alignment_power = vms_rec[1];
00380 align_addr = (1 << section->alignment_power);
00381 if ((base_addr % align_addr) != 0)
00382 base_addr += (align_addr - (base_addr % align_addr));
00383 section->vma = (bfd_vma)base_addr;
00384 base_addr += section->size;
00385
00386
00387
00388 if (old_flags & GPS_S_M_GBL)
00389 {
00390 entry = _bfd_vms_enter_symbol (abfd, name);
00391 if (entry == (vms_symbol_entry *)NULL)
00392 {
00393 bfd_set_error (bfd_error_no_memory);
00394 return -1;
00395 }
00396 symbol = entry->symbol;
00397
00398 symbol->value = 0;
00399 symbol->section = section;
00400 symbol->flags = (BSF_GLOBAL|BSF_SECTION_SYM|BSF_OLD_COMMON);
00401 }
00402
00403
00404
00405 if (old_section != 0)
00406 {
00407 section->contents = old_section->contents;
00408 if (section->size < old_section->size)
00409 {
00410 (*_bfd_error_handler)
00411 (_("Size mismatch section %s=%lx, %s=%lx"),
00412 old_section->name,
00413 (unsigned long) old_section->size,
00414 section->name,
00415 (unsigned long) section->size);
00416 return -1;
00417 }
00418 else if (section->size > old_section->size)
00419 {
00420 section->contents = ((unsigned char *)
00421 bfd_realloc (old_section->contents,
00422 section->size));
00423 if (section->contents == NULL)
00424 {
00425 bfd_set_error (bfd_error_no_memory);
00426 return -1;
00427 }
00428 }
00429 }
00430 else
00431 {
00432 section->contents = ((unsigned char *)
00433 bfd_zmalloc (section->size));
00434 if (section->contents == NULL)
00435 {
00436 bfd_set_error (bfd_error_no_memory);
00437 return -1;
00438 }
00439 }
00440 #if VMS_DEBUG
00441 vms_debug (4, "gsd psc %d (%s, flags %04x=%s) ",
00442 section->index, name, old_flags, flag2str (gpsflagdesc, old_flags));
00443 vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n",
00444 section->size, section->vma, section->contents);
00445 #endif
00446
00447 gsd_size = vms_rec[8] + 9;
00448
00449 psect_idx++;
00450 }
00451 break;
00452
00453 case GSD_S_C_EPM:
00454 case GSD_S_C_EPMW:
00455 #if VMS_DEBUG
00456 vms_debug(4, "gsd epm\n");
00457 #endif
00458
00459 case GSD_S_C_SYM:
00460 case GSD_S_C_SYMW:
00461 {
00462 int name_offset = 0, value_offset = 0;
00463
00464
00465
00466
00467
00468 #if VMS_DEBUG
00469 vms_debug (4, "GSD_S_C_SYM(W)\n");
00470 #endif
00471 old_flags = bfd_getl16 (vms_rec + 2);
00472 new_flags = BSF_NO_FLAGS;
00473
00474 if (old_flags & GSY_S_M_WEAK)
00475 new_flags |= BSF_WEAK;
00476
00477 switch (gsd_type)
00478 {
00479 case GSD_S_C_EPM:
00480 name_offset = 11;
00481 value_offset = 5;
00482 new_flags |= BSF_FUNCTION;
00483 break;
00484 case GSD_S_C_EPMW:
00485 name_offset = 12;
00486 value_offset = 6;
00487 new_flags |= BSF_FUNCTION;
00488 break;
00489 case GSD_S_C_SYM:
00490 if (old_flags & GSY_S_M_DEF)
00491 name_offset = 9;
00492 else
00493 name_offset = 4;
00494 value_offset = 5;
00495 break;
00496 case GSD_S_C_SYMW:
00497 if (old_flags & GSY_S_M_DEF)
00498 name_offset = 10;
00499 else
00500 name_offset = 5;
00501 value_offset = 6;
00502 break;
00503 }
00504
00505
00506
00507 entry = _bfd_vms_enter_symbol (abfd,
00508 _bfd_vms_save_counted_string (vms_rec + name_offset));
00509 if (entry == (vms_symbol_entry *)NULL)
00510 {
00511 bfd_set_error (bfd_error_no_memory);
00512 return -1;
00513 }
00514 symbol = entry->symbol;
00515
00516 if (old_flags & GSY_S_M_DEF)
00517 {
00518 int psect;
00519
00520 symbol->value = bfd_getl32 (vms_rec+value_offset);
00521 if ((gsd_type == GSD_S_C_SYMW)
00522 || (gsd_type == GSD_S_C_EPMW))
00523 psect = bfd_getl16 (vms_rec + value_offset - 2);
00524 else
00525 psect = vms_rec[value_offset-1];
00526
00527 symbol->section = (asection *) (size_t) psect;
00528 #if VMS_DEBUG
00529 vms_debug(4, "gsd sym def #%d (%s, %d [%p], %04x=%s)\n", abfd->symcount,
00530 symbol->name, (int)symbol->section, symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
00531 #endif
00532 }
00533 else
00534 {
00535 symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
00536 #if VMS_DEBUG
00537 vms_debug (4, "gsd sym ref #%d (%s, %s [%p], %04x=%s)\n", abfd->symcount,
00538 symbol->name, symbol->section->name, symbol->section, old_flags, flag2str (gsyflagdesc, old_flags));
00539 #endif
00540 }
00541
00542 gsd_size = vms_rec[name_offset] + name_offset + 1;
00543 symbol->flags = new_flags;
00544 }
00545
00546 break;
00547
00548 case GSD_S_C_PRO:
00549 case GSD_S_C_PROW:
00550 #if VMS_DEBUG
00551 vms_debug(4, "gsd pro\n");
00552 #endif
00553 break;
00554 case GSD_S_C_IDC:
00555 #if VMS_DEBUG
00556 vms_debug(4, "gsd idc\n");
00557 #endif
00558 break;
00559 case GSD_S_C_ENV:
00560 #if VMS_DEBUG
00561 vms_debug(4, "gsd env\n");
00562 #endif
00563 break;
00564 case GSD_S_C_LSY:
00565 #if VMS_DEBUG
00566 vms_debug(4, "gsd lsy\n");
00567 #endif
00568 break;
00569 case GSD_S_C_LEPM:
00570 #if VMS_DEBUG
00571 vms_debug(4, "gsd lepm\n");
00572 #endif
00573 break;
00574 case GSD_S_C_LPRO:
00575 #if VMS_DEBUG
00576 vms_debug(4, "gsd lpro\n");
00577 #endif
00578 break;
00579 case GSD_S_C_SPSC:
00580 #if VMS_DEBUG
00581 vms_debug(4, "gsd spsc\n");
00582 #endif
00583 break;
00584 case GSD_S_C_SYMV:
00585 #if VMS_DEBUG
00586 vms_debug(4, "gsd symv\n");
00587 #endif
00588 break;
00589 case GSD_S_C_EPMV:
00590 #if VMS_DEBUG
00591 vms_debug(4, "gsd epmv\n");
00592 #endif
00593 break;
00594 case GSD_S_C_PROV:
00595 #if VMS_DEBUG
00596 vms_debug(4, "gsd prov\n");
00597 #endif
00598 break;
00599
00600 case EGSD_S_C_PSC + EVAX_OFFSET:
00601 {
00602
00603
00604 name = _bfd_vms_save_counted_string (vms_rec+12);
00605 section = bfd_make_section (abfd, name);
00606 if (!section)
00607 return -1;
00608 old_flags = bfd_getl16 (vms_rec + 6);
00609 section->size = bfd_getl32 (vms_rec + 8);
00610 new_flags = vms_secflag_by_name (abfd, evax_section_flags, name,
00611 section->size > 0);
00612 if (old_flags & EGPS_S_V_REL)
00613 new_flags |= SEC_RELOC;
00614 if (!bfd_set_section_flags (abfd, section, new_flags))
00615 return -1;
00616 section->alignment_power = vms_rec[4];
00617 align_addr = (1 << section->alignment_power);
00618 if ((base_addr % align_addr) != 0)
00619 base_addr += (align_addr - (base_addr % align_addr));
00620 section->vma = (bfd_vma)base_addr;
00621 base_addr += section->size;
00622 section->contents = ((unsigned char *)
00623 bfd_zmalloc (section->size));
00624 if (section->contents == NULL)
00625 return -1;
00626 #if VMS_DEBUG
00627 vms_debug(4, "egsd psc %d (%s, flags %04x=%s) ",
00628 section->index, name, old_flags, flag2str(gpsflagdesc, old_flags));
00629 vms_debug(4, "%d bytes at 0x%08lx (mem %p)\n",
00630 section->size, section->vma, section->contents);
00631 #endif
00632 }
00633 break;
00634
00635 case EGSD_S_C_SYM + EVAX_OFFSET:
00636 {
00637
00638
00639 symbol = bfd_make_empty_symbol (abfd);
00640 if (symbol == 0)
00641 return -1;
00642
00643 old_flags = bfd_getl16 (vms_rec + 6);
00644 new_flags = BSF_NO_FLAGS;
00645
00646 if (old_flags & EGSY_S_V_WEAK)
00647 new_flags |= BSF_WEAK;
00648
00649 if (vms_rec[6] & EGSY_S_V_DEF)
00650 {
00651 symbol->name =
00652 _bfd_vms_save_counted_string (vms_rec+32);
00653 if (old_flags & EGSY_S_V_NORM)
00654 {
00655 new_flags |= BSF_FUNCTION;
00656 }
00657 symbol->value = bfd_getl64 (vms_rec+8);
00658 symbol->section = (asection *) ((unsigned long) bfd_getl32 (vms_rec+28));
00659 #if VMS_DEBUG
00660 vms_debug(4, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount,
00661 symbol->name, (int)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
00662 #endif
00663 }
00664 else
00665 {
00666 symbol->name =
00667 _bfd_vms_save_counted_string (vms_rec+8);
00668 #if VMS_DEBUG
00669 vms_debug(4, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount,
00670 symbol->name, old_flags, flag2str(gsyflagdesc, old_flags));
00671 #endif
00672 symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
00673 }
00674
00675 symbol->flags = new_flags;
00676
00677
00678
00679 entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV(vms_symbol_table),
00680 symbol->name,
00681 TRUE, FALSE);
00682 if (entry == (vms_symbol_entry *)NULL)
00683 {
00684 bfd_set_error (bfd_error_no_memory);
00685 return -1;
00686 }
00687 if (entry->symbol != (asymbol *)NULL)
00688 {
00689 #if VMS_DEBUG
00690 vms_debug(4, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name);
00691 #endif
00692 }
00693 else
00694 {
00695 entry->symbol = symbol;
00696 PRIV(gsd_sym_count)++;
00697 abfd->symcount++;
00698 }
00699 }
00700 break;
00701
00702 case EGSD_S_C_IDC + EVAX_OFFSET:
00703 break;
00704
00705 default:
00706 (*_bfd_error_handler) (_("unknown gsd/egsd subtype %d"), gsd_type);
00707 bfd_set_error (bfd_error_bad_value);
00708 return -1;
00709
00710 }
00711
00712 PRIV(rec_size) -= gsd_size;
00713 PRIV(vms_rec) += gsd_size;
00714
00715 }
00716
00717 if (abfd->symcount > 0)
00718 abfd->flags |= HAS_SYMS;
00719
00720 return 0;
00721 }
00722
00723
00724
00725
00726
00727
00728 int
00729 _bfd_vms_write_gsd (abfd, objtype)
00730 bfd *abfd;
00731 int objtype ATTRIBUTE_UNUSED;
00732 {
00733 asection *section;
00734 asymbol *symbol;
00735 unsigned int symnum;
00736 int last_index = -1;
00737 char dummy_name[10];
00738 char *sname;
00739 flagword new_flags, old_flags;
00740
00741 #if VMS_DEBUG
00742 vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype);
00743 #endif
00744
00745
00746
00747 section = abfd->sections;
00748 #if VMS_DEBUG
00749 vms_debug (3, "%d sections found\n", abfd->section_count);
00750 #endif
00751
00752
00753
00754 _bfd_vms_output_alignment (abfd, 8);
00755
00756 _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
00757 _bfd_vms_output_long (abfd, 0);
00758 _bfd_vms_output_push (abfd);
00759
00760 while (section != 0)
00761 {
00762 #if VMS_DEBUG
00763 vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->size);
00764 #endif
00765
00766
00767 if (_bfd_vms_output_check (abfd, 64) < 0)
00768 {
00769 _bfd_vms_output_pop (abfd);
00770 _bfd_vms_output_end (abfd);
00771 _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
00772 _bfd_vms_output_long (abfd, 0);
00773 _bfd_vms_output_push (abfd);
00774 }
00775
00776
00777
00778 while (section->index - last_index > 1)
00779 {
00780 #if VMS_DEBUG
00781 vms_debug (3, "index %d, last %d\n", section->index, last_index);
00782 #endif
00783 _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
00784 _bfd_vms_output_short (abfd, 0);
00785 _bfd_vms_output_short (abfd, 0);
00786 _bfd_vms_output_long (abfd, 0);
00787 sprintf (dummy_name, ".DUMMY%02d", last_index);
00788 _bfd_vms_output_counted (abfd, dummy_name);
00789 _bfd_vms_output_flush (abfd);
00790 last_index++;
00791 }
00792
00793
00794
00795
00796 sname = (char *)section->name;
00797 if (*sname == '.')
00798 {
00799 sname++;
00800 if ((*sname == 't') && (strcmp (sname, "text") == 0))
00801 sname = PRIV(is_vax)?VAX_CODE_NAME:EVAX_CODE_NAME;
00802 else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
00803 sname = PRIV(is_vax)?VAX_DATA_NAME:EVAX_DATA_NAME;
00804 else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
00805 sname = EVAX_BSS_NAME;
00806 else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
00807 sname = EVAX_LINK_NAME;
00808 else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
00809 sname = EVAX_READONLY_NAME;
00810 else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
00811 sname = EVAX_LITERAL_NAME;
00812 else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
00813 sname = EVAX_COMMON_NAME;
00814 else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
00815 sname = EVAX_LOCAL_NAME;
00816 }
00817 else
00818 sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ);
00819
00820 _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
00821 _bfd_vms_output_short (abfd, section->alignment_power & 0xff);
00822 if (bfd_is_com_section (section))
00823 {
00824 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);
00825 }
00826 else
00827 {
00828 new_flags = vms_esecflag_by_name (evax_section_flags, sname,
00829 section->size > 0);
00830 }
00831 _bfd_vms_output_short (abfd, new_flags);
00832 _bfd_vms_output_long (abfd, (unsigned long) section->size);
00833 _bfd_vms_output_counted (abfd, sname);
00834 _bfd_vms_output_flush (abfd);
00835
00836 last_index = section->index;
00837 section = section->next;
00838 }
00839
00840
00841
00842 #if VMS_DEBUG
00843 vms_debug (3, "%d symbols found\n", abfd->symcount);
00844 #endif
00845
00846 bfd_set_start_address (abfd, (bfd_vma)-1);
00847
00848 for (symnum = 0; symnum < abfd->symcount; symnum++)
00849 {
00850 char *hash;
00851
00852 symbol = abfd->outsymbols[symnum];
00853 if (*(symbol->name) == '_')
00854 {
00855 if (strcmp (symbol->name, "__main") == 0)
00856 bfd_set_start_address (abfd, (bfd_vma)symbol->value);
00857 }
00858 old_flags = symbol->flags;
00859
00860 if (old_flags & BSF_FILE)
00861 continue;
00862
00863 if (((old_flags & (BSF_GLOBAL|BSF_WEAK)) == 0)
00864 && (!bfd_is_und_section (symbol->section)))
00865 continue;
00866
00867
00868
00869 if (_bfd_vms_output_check (abfd, 80) < 0)
00870 {
00871 _bfd_vms_output_pop (abfd);
00872 _bfd_vms_output_end (abfd);
00873 _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
00874 _bfd_vms_output_long (abfd, 0);
00875 _bfd_vms_output_push (abfd);
00876 }
00877
00878 _bfd_vms_output_begin (abfd, EGSD_S_C_SYM, -1);
00879
00880 _bfd_vms_output_short (abfd, 0);
00881
00882 new_flags = 0;
00883
00884 if (old_flags & BSF_WEAK)
00885 new_flags |= EGSY_S_V_WEAK;
00886 if (bfd_is_com_section (symbol->section))
00887 new_flags |= (EGSY_S_V_WEAK|EGSY_S_V_COMM);
00888
00889 if (old_flags & BSF_FUNCTION)
00890 {
00891 new_flags |= EGSY_S_V_NORM;
00892 new_flags |= EGSY_S_V_REL;
00893 }
00894 if (old_flags & (BSF_GLOBAL|BSF_WEAK))
00895 {
00896 new_flags |= EGSY_S_V_DEF;
00897 if (!bfd_is_abs_section (symbol->section))
00898 new_flags |= EGSY_S_V_REL;
00899 }
00900 _bfd_vms_output_short (abfd, new_flags);
00901
00902 if (old_flags & (BSF_GLOBAL | BSF_WEAK))
00903 {
00904 uquad code_address = 0;
00905 unsigned long ca_psindx = 0;
00906 unsigned long psindx;
00907
00908 if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL)
00909 {
00910 code_address = ((asymbol *) (symbol->udata.p))->value;
00911 ca_psindx = ((asymbol *) (symbol->udata.p))->section->index;
00912 }
00913 psindx = symbol->section->index;
00914
00915 _bfd_vms_output_quad (abfd, symbol->value);
00916 _bfd_vms_output_quad (abfd, code_address);
00917 _bfd_vms_output_long (abfd, ca_psindx);
00918 _bfd_vms_output_long (abfd, psindx);
00919 }
00920 hash = _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ);
00921 _bfd_vms_output_counted (abfd, hash);
00922
00923 _bfd_vms_output_flush (abfd);
00924
00925 }
00926
00927 _bfd_vms_output_alignment (abfd, 8);
00928 _bfd_vms_output_pop (abfd);
00929 _bfd_vms_output_end (abfd);
00930
00931 return 0;
00932 }