int _bfd_vms_slurp_gsd (bfd * abfd, int objtype) { int gsd_type, gsd_size; asection *section; unsigned char *vms_rec; flagword new_flags, old_flags; char *name; asymbol *symbol; vms_symbol_entry *entry; unsigned long base_addr; unsigned long align_addr; static unsigned int psect_idx = 0; #if VMS_DEBUG vms_debug (2, "GSD/EGSD (%d/%x)\n", objtype, objtype); #endif switch (objtype) { case EOBJ_S_C_EGSD: PRIV (vms_rec) += 8; /* Skip type, size, l_temp. */ PRIV (rec_size) -= 8; break; case OBJ_S_C_GSD: PRIV (vms_rec) += 1; PRIV (rec_size) -= 1; break; default: return -1; } /* Calculate base address for each section. */ base_addr = 0L; abfd->symcount = 0; while (PRIV (rec_size) > 0) { vms_rec = PRIV (vms_rec); if (objtype == OBJ_S_C_GSD) gsd_type = vms_rec[0]; else { _bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size); gsd_type += EVAX_OFFSET; } #if VMS_DEBUG vms_debug (3, "gsd_type %d\n", gsd_type); #endif switch (gsd_type) { case GSD_S_C_PSC: { /* Program section definition. */ asection *old_section = 0; #if VMS_DEBUG vms_debug (4, "GSD_S_C_PSC\n"); #endif /* If this section isn't a bfd section. */ if (PRIV (is_vax) && (psect_idx < (abfd->section_count - 1))) { /* Check for temporary section from TIR record. */ if (psect_idx < PRIV (section_count)) old_section = PRIV (sections)[psect_idx]; else old_section = 0; } name = _bfd_vms_save_counted_string (vms_rec + 8); section = bfd_make_section (abfd, name); if (!section) { (*_bfd_error_handler) (_("bfd_make_section (%s) failed"), name); return -1; } old_flags = bfd_getl16 (vms_rec + 2); section->size = bfd_getl32 (vms_rec + 4); /* allocation */ new_flags = vms_secflag_by_name (abfd, vax_section_flags, name, section->size > 0); if (old_flags & EGPS_S_V_REL) new_flags |= SEC_RELOC; if (old_flags & GPS_S_M_OVR) new_flags |= SEC_IS_COMMON; if (!bfd_set_section_flags (abfd, section, new_flags)) { (*_bfd_error_handler) (_("bfd_set_section_flags (%s, %x) failed"), name, new_flags); return -1; } section->alignment_power = vms_rec[1]; align_addr = (1 << section->alignment_power); if ((base_addr % align_addr) != 0) base_addr += (align_addr - (base_addr % align_addr)); section->vma = (bfd_vma)base_addr; base_addr += section->size; /* Global section is common symbol. */ if (old_flags & GPS_S_M_GBL) { entry = _bfd_vms_enter_symbol (abfd, name); if (entry == NULL) { bfd_set_error (bfd_error_no_memory); return -1; } symbol = entry->symbol; symbol->value = 0; symbol->section = section; symbol->flags = (BSF_GLOBAL | BSF_SECTION_SYM | BSF_OLD_COMMON); } /* Copy saved contents if old_section set. */ if (old_section != 0) { section->contents = old_section->contents; if (section->size < old_section->size) { (*_bfd_error_handler) (_("Size mismatch section %s=%lx, %s=%lx"), old_section->name, (unsigned long) old_section->size, section->name, (unsigned long) section->size); return -1; } else if (section->size > old_section->size) { section->contents = bfd_realloc (old_section->contents, section->size); if (section->contents == NULL) { bfd_set_error (bfd_error_no_memory); return -1; } } } else { section->contents = bfd_zmalloc (section->size); if (section->contents == NULL) { bfd_set_error (bfd_error_no_memory); return -1; } } #if VMS_DEBUG vms_debug (4, "gsd psc %d (%s, flags %04x=%s) ", section->index, name, old_flags, flag2str (gpsflagdesc, old_flags)); vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n", section->size, section->vma, section->contents); #endif gsd_size = vms_rec[8] + 9; psect_idx++; } break; case GSD_S_C_EPM: case GSD_S_C_EPMW: #if VMS_DEBUG vms_debug (4, "gsd epm\n"); #endif /* Fall through. */ case GSD_S_C_SYM: case GSD_S_C_SYMW: { int name_offset = 0, value_offset = 0; /* Symbol specification (definition or reference). */ #if VMS_DEBUG vms_debug (4, "GSD_S_C_SYM(W)\n"); #endif old_flags = bfd_getl16 (vms_rec + 2); new_flags = BSF_NO_FLAGS; if (old_flags & GSY_S_M_WEAK) new_flags |= BSF_WEAK; switch (gsd_type) { case GSD_S_C_EPM: name_offset = 11; value_offset = 5; new_flags |= BSF_FUNCTION; break; case GSD_S_C_EPMW: name_offset = 12; value_offset = 6; new_flags |= BSF_FUNCTION; break; case GSD_S_C_SYM: if (old_flags & GSY_S_M_DEF) /* Symbol definition. */ name_offset = 9; else name_offset = 4; value_offset = 5; break; case GSD_S_C_SYMW: if (old_flags & GSY_S_M_DEF) /* Symbol definition. */ name_offset = 10; else name_offset = 5; value_offset = 6; break; } /* Save symbol in vms_symbol_table. */ entry = _bfd_vms_enter_symbol (abfd, _bfd_vms_save_counted_string (vms_rec + name_offset)); if (entry == NULL) { bfd_set_error (bfd_error_no_memory); return -1; } symbol = entry->symbol; if (old_flags & GSY_S_M_DEF) { /* Symbol definition. */ int psect; symbol->value = bfd_getl32 (vms_rec + value_offset); if ((gsd_type == GSD_S_C_SYMW) || (gsd_type == GSD_S_C_EPMW)) psect = bfd_getl16 (vms_rec + value_offset - 2); else psect = vms_rec[value_offset-1]; symbol->section = (asection *)(unsigned long)psect; #if VMS_DEBUG vms_debug (4, "gsd sym def #%d (%s, %ld, %04x=%s)\n", abfd->symcount, symbol->name, (long)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags)); #endif } else { /* Symbol reference. */ #if VMS_DEBUG vms_debug (4, "gsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount, symbol->name, old_flags, flag2str (gsyflagdesc, old_flags)); #endif symbol->section = (asection *)(unsigned long)-1; } gsd_size = vms_rec[name_offset] + name_offset + 1; symbol->flags = new_flags; } break; case GSD_S_C_PRO: case GSD_S_C_PROW: #if VMS_DEBUG vms_debug (4, "gsd pro\n"); #endif break; case GSD_S_C_IDC: #if VMS_DEBUG vms_debug (4, "gsd idc\n"); #endif break; case GSD_S_C_ENV: #if VMS_DEBUG vms_debug (4, "gsd env\n"); #endif break; case GSD_S_C_LSY: #if VMS_DEBUG vms_debug (4, "gsd lsy\n"); #endif break; case GSD_S_C_LEPM: #if VMS_DEBUG vms_debug (4, "gsd lepm\n"); #endif break; case GSD_S_C_LPRO: #if VMS_DEBUG vms_debug (4, "gsd lpro\n"); #endif break; case GSD_S_C_SPSC: #if VMS_DEBUG vms_debug (4, "gsd spsc\n"); #endif break; case GSD_S_C_SYMV: #if VMS_DEBUG vms_debug (4, "gsd symv\n"); #endif break; case GSD_S_C_EPMV: #if VMS_DEBUG vms_debug (4, "gsd epmv\n"); #endif break; case GSD_S_C_PROV: #if VMS_DEBUG vms_debug (4, "gsd prov\n"); #endif break; case EGSD_S_C_PSC + EVAX_OFFSET: { /* Program section definition. */ name = _bfd_vms_save_counted_string (vms_rec + EGPS_S_B_NAMLNG); section = bfd_make_section (abfd, name); if (!section) return -1; old_flags = bfd_getl16 (vms_rec + EGPS_S_W_FLAGS); section->size = bfd_getl32 (vms_rec + EGPS_S_L_ALLOC); new_flags = vms_secflag_by_name (abfd, evax_section_flags, name, section->size > 0); if (old_flags & EGPS_S_V_REL) new_flags |= SEC_RELOC; if (!bfd_set_section_flags (abfd, section, new_flags)) return -1; section->alignment_power = vms_rec[EGPS_S_B_ALIGN]; align_addr = (1 << section->alignment_power); if ((base_addr % align_addr) != 0) base_addr += (align_addr - (base_addr % align_addr)); section->vma = (bfd_vma)base_addr; base_addr += section->size; section->contents = bfd_zmalloc (section->size); if (section->contents == NULL) return -1; section->filepos = (unsigned int)-1; #if VMS_DEBUG vms_debug (4, "EGSD P-section %d (%s, flags %04x=%s) ", section->index, name, old_flags, flag2str(gpsflagdesc, old_flags)); vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n", section->size, section->vma, section->contents); #endif } break; case EGSD_S_C_SYM + EVAX_OFFSET: { /* Global symbol specification (definition or reference). */ symbol = bfd_make_empty_symbol (abfd); if (symbol == 0) return -1; old_flags = bfd_getl16 (vms_rec + EGSY_S_W_FLAGS); new_flags = BSF_NO_FLAGS; if (old_flags & EGSY_S_V_WEAK) new_flags |= BSF_WEAK; if (old_flags & EGSY_S_V_DEF) { /* Symbol definition. */ if (old_flags & EGSY_S_V_NORM) new_flags |= BSF_FUNCTION; symbol->name = _bfd_vms_save_counted_string (vms_rec + ESDF_S_B_NAMLNG); symbol->value = bfd_getl64 (vms_rec + ESDF_S_L_VALUE); symbol->section = (asection *)(unsigned long) bfd_getl32 (vms_rec + ESDF_S_L_PSINDX); #if VMS_DEBUG vms_debug (4, "EGSD sym def #%d (%s, %ld, %04x=%s)\n", abfd->symcount, symbol->name, (long)symbol->section, old_flags, flag2str (gsyflagdesc, old_flags)); #endif } else { /* Symbol reference. */ symbol->name = _bfd_vms_save_counted_string (vms_rec + ESRF_S_B_NAMLNG); #if VMS_DEBUG vms_debug (4, "EGSD sym ref #%d (%s, %04x=%s)\n", abfd->symcount, symbol->name, old_flags, flag2str (gsyflagdesc, old_flags)); #endif symbol->section = (asection *)(unsigned long)-1; } symbol->flags = new_flags; /* Register symbol in VMS symbol table. */ entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table), symbol->name, TRUE, FALSE); if (entry == NULL) { bfd_set_error (bfd_error_no_memory); return -1; } if (entry->symbol != NULL) { /* FIXME ?, DEC C generates this. */ #if VMS_DEBUG vms_debug (4, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name); #endif } else { entry->symbol = symbol; PRIV (gsd_sym_count)++; abfd->symcount++; } } break; case EGSD_S_C_SYMG + EVAX_OFFSET: { /* Universal symbol specification (definition). */ symbol = bfd_make_empty_symbol (abfd); if (symbol == 0) return -1; old_flags = bfd_getl16 (vms_rec + EGST_S_W_FLAGS); new_flags = BSF_NO_FLAGS; if (old_flags & EGSY_S_V_WEAK) new_flags |= BSF_WEAK; if (old_flags & EGSY_S_V_DEF) /* symbol definition */ { if (old_flags & EGSY_S_V_NORM) new_flags |= BSF_FUNCTION; symbol->name = _bfd_vms_save_counted_string (vms_rec + EGST_S_B_NAMLNG); /* For BSF_FUNCTION symbols, the entry point is in LP_1 and the descriptor in LP_2. For other symbols, the unique value is in LP_2. */ symbol->value = bfd_getl64 (vms_rec + EGST_S_Q_LP_2); /* Adding this offset is necessary in order for GDB to read the DWARF-2 debug info from shared libraries. */ if (abfd->flags & DYNAMIC && strstr (symbol->name, "$DWARF2.DEBUG") != 0) symbol->value += PRIV (symvva); } else /* symbol reference */ (*_bfd_error_handler) ("Invalid EGST reference"); symbol->flags = new_flags; if (register_universal_symbol (abfd, symbol, old_flags) < 0) return -1; /* Make a second symbol for the entry point. */ if (symbol->flags & BSF_FUNCTION) { asymbol *en_sym; char *name = bfd_alloc (abfd, strlen (symbol->name) + 5); en_sym = bfd_make_empty_symbol (abfd); if (en_sym == 0) return -1; strcpy (name, symbol->name); strcat (name, "..en"); en_sym->name = name; en_sym->value = bfd_getl64 (vms_rec + EGST_S_Q_LP_1); if (register_universal_symbol (abfd, en_sym, old_flags) < 0) return -1; } } break; case EGSD_S_C_IDC + EVAX_OFFSET: break; default: (*_bfd_error_handler) (_("Unknown GSD/EGSD subtype %d"), gsd_type); bfd_set_error (bfd_error_bad_value); return -1; } PRIV (rec_size) -= gsd_size; PRIV (vms_rec) += gsd_size; } if (abfd->symcount > 0) abfd->flags |= HAS_SYMS; return 0; }
/* Process GSD/EGSD record. * Return 0 on success, -1 on error. */ int _bfd_vms_slurp_gsd(bfd * abfd, int objtype) { #if defined(VMS_DEBUG) && VMS_DEBUG static struct flagdescstruct gpsflagdesc[] = { { "PIC", 0x0001 }, { "LIB", 0x0002 }, { "OVR", 0x0004 }, { "REL", 0x0008 }, { "GBL", 0x0010 }, { "SHR", 0x0020 }, { "EXE", 0x0040 }, { "RD", 0x0080 }, { "WRT", 0x0100 }, { "VEC", 0x0200 }, { "NOMOD", 0x0400 }, { "COM", 0x0800 }, { NULL, 0 } }; static struct flagdescstruct gsyflagdesc[] = { { "WEAK", 0x0001 }, { "DEF", 0x0002 }, { "UNI", 0x0004 }, { "REL", 0x0008 }, { "COMM", 0x0010 }, { "VECEP", 0x0020 }, { "NORM", 0x0040 }, { NULL, 0 } }; #endif /* VMS_DEBUG */ int gsd_type, gsd_size; asection *section; unsigned char *vms_rec; flagword new_flags, old_flags; char *name; asymbol *symbol; vms_symbol_entry *entry; unsigned long base_addr; unsigned long align_addr; static unsigned int psect_idx = 0; gsd_size = 0; #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug(2, "GSD/EGSD (%d/%x)\n", objtype, objtype); #endif /* VMS_DEBUG */ switch (objtype) { case EOBJ_S_C_EGSD: PRIV(vms_rec) += 8; /* Skip type, size, l_temp. */ PRIV(rec_size) -= 8; break; case OBJ_S_C_GSD: PRIV(vms_rec) += 1; PRIV(rec_size) -= 1; break; default: return -1; } /* Calculate base address for each section: */ base_addr = 0L; abfd->symcount = 0; while (PRIV(rec_size) > 0) { vms_rec = PRIV(vms_rec); if (objtype == OBJ_S_C_GSD) gsd_type = *vms_rec; else { _bfd_vms_get_header_values(abfd, vms_rec, &gsd_type, &gsd_size); gsd_type += EVAX_OFFSET; } #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (3, "gsd_type %d\n", gsd_type); #endif switch (gsd_type) { case GSD_S_C_PSC: { /* Program section definition. */ asection *old_section = 0; #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "GSD_S_C_PSC\n"); #endif /* If this section isn't a bfd section. */ if (PRIV (is_vax) && (psect_idx < (abfd->section_count-1))) { /* Check for temporary section from TIR record. */ if (psect_idx < PRIV (section_count)) old_section = PRIV (sections)[psect_idx]; else old_section = 0; } name = _bfd_vms_save_counted_string (vms_rec + 8); section = bfd_make_section (abfd, name); if (!section) { (*_bfd_error_handler) (_("bfd_make_section (%s) failed"), name); return -1; } old_flags = bfd_getl16 (vms_rec + 2); section->size = bfd_getl32 (vms_rec + 4); /* allocation */ new_flags = vms_secflag_by_name (abfd, vax_section_flags, name, section->size > 0); if (old_flags & EGPS_S_V_REL) new_flags |= SEC_RELOC; if (old_flags & GPS_S_M_OVR) new_flags |= SEC_IS_COMMON; if (!bfd_set_section_flags (abfd, section, new_flags)) { (*_bfd_error_handler) (_("bfd_set_section_flags (%s, %x) failed"), name, new_flags); return -1; } section->alignment_power = vms_rec[1]; align_addr = (1 << section->alignment_power); if ((base_addr % align_addr) != 0) base_addr += (align_addr - (base_addr % align_addr)); section->vma = (bfd_vma)base_addr; base_addr += section->size; /* Global section is common symbol. */ if (old_flags & GPS_S_M_GBL) { entry = _bfd_vms_enter_symbol (abfd, name); if (entry == NULL) { bfd_set_error (bfd_error_no_memory); return -1; } symbol = entry->symbol; symbol->value = 0; symbol->section = section; symbol->flags = (BSF_GLOBAL | BSF_SECTION_SYM | BSF_OLD_COMMON); } /* Copy saved contents if old_section set. */ if (old_section != 0) { section->contents = old_section->contents; if (section->size < old_section->size) { (*_bfd_error_handler) (_("Size mismatch section %s=%lx, %s=%lx"), old_section->name, (unsigned long) old_section->size, section->name, (unsigned long) section->size); return -1; } else if (section->size > old_section->size) { section->contents = (unsigned char *)bfd_realloc(old_section->contents, section->size); if (section->contents == NULL) { bfd_set_error (bfd_error_no_memory); return -1; } } } else { section->contents = (unsigned char *)bfd_zmalloc(section->size); if (section->contents == NULL) { bfd_set_error (bfd_error_no_memory); return -1; } } #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd psc %d (%s, flags %04x=%s) ", section->index, name, old_flags, flag2str (gpsflagdesc, old_flags)); vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n", section->size, section->vma, section->contents); #endif /* VMS_DEBUG */ gsd_size = vms_rec[8] + 9; psect_idx++; } break; case GSD_S_C_EPM: case GSD_S_C_EPMW: #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd epm\n"); #endif /* Fall through. */ case GSD_S_C_SYM: case GSD_S_C_SYMW: { int name_offset = 0, value_offset = 0; /* Symbol specification (definition or reference). */ #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug(4, "GSD_S_C_SYM(W)\n"); #endif old_flags = bfd_getl16 (vms_rec + 2); new_flags = BSF_NO_FLAGS; if (old_flags & GSY_S_M_WEAK) new_flags |= BSF_WEAK; switch (gsd_type) { case GSD_S_C_EPM: name_offset = 11; value_offset = 5; new_flags |= BSF_FUNCTION; break; case GSD_S_C_EPMW: name_offset = 12; value_offset = 6; new_flags |= BSF_FUNCTION; break; case GSD_S_C_SYM: if (old_flags & GSY_S_M_DEF) /* Symbol definition. */ name_offset = 9; else name_offset = 4; value_offset = 5; break; case GSD_S_C_SYMW: if (old_flags & GSY_S_M_DEF) /* Symbol definition. */ name_offset = 10; else name_offset = 5; value_offset = 6; break; default: break; } /* end "switch (gsd_type)" */ /* Save symbol in vms_symbol_table: */ entry = _bfd_vms_enter_symbol(abfd, _bfd_vms_save_counted_string(vms_rec + name_offset)); if (entry == NULL) { bfd_set_error (bfd_error_no_memory); return -1; } symbol = entry->symbol; if (old_flags & GSY_S_M_DEF) { /* Symbol definition. */ int psect; symbol->value = bfd_getl32 (vms_rec + value_offset); if ((gsd_type == GSD_S_C_SYMW) || (gsd_type == GSD_S_C_EPMW)) psect = bfd_getl16 (vms_rec + value_offset - 2); else psect = vms_rec[value_offset-1]; symbol->section = (asection *) (size_t) psect; #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd sym def #%d (%s, %d [%p], %04x=%s)\n", abfd->symcount, symbol->name, (int)symbol->section, symbol->section, old_flags, flag2str (gsyflagdesc, old_flags)); #endif } else { /* Symbol reference. */ symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME); #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd sym ref #%d (%s, %s [%p], %04x=%s)\n", abfd->symcount, symbol->name, symbol->section->name, symbol->section, old_flags, flag2str (gsyflagdesc, old_flags)); #endif } gsd_size = vms_rec[name_offset] + name_offset + 1; symbol->flags = new_flags; } break; case GSD_S_C_PRO: case GSD_S_C_PROW: #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd pro\n"); #endif break; case GSD_S_C_IDC: #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd idc\n"); #endif break; case GSD_S_C_ENV: #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd env\n"); #endif break; case GSD_S_C_LSY: #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd lsy\n"); #endif break; case GSD_S_C_LEPM: #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd lepm\n"); #endif break; case GSD_S_C_LPRO: #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd lpro\n"); #endif break; case GSD_S_C_SPSC: #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd spsc\n"); #endif break; case GSD_S_C_SYMV: #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd symv\n"); #endif break; case GSD_S_C_EPMV: #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd epmv\n"); #endif break; case GSD_S_C_PROV: #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "gsd prov\n"); #endif break; case EGSD_S_C_PSC + EVAX_OFFSET: { /* Program section definition. */ name = _bfd_vms_save_counted_string (vms_rec + 12); section = bfd_make_section (abfd, name); if (!section) return -1; old_flags = bfd_getl16 (vms_rec + 6); section->size = bfd_getl32 (vms_rec + 8); /* Allocation. */ new_flags = vms_secflag_by_name (abfd, evax_section_flags, name, section->size > 0); if (old_flags & EGPS_S_V_REL) new_flags |= SEC_RELOC; if (!bfd_set_section_flags (abfd, section, new_flags)) return -1; section->alignment_power = vms_rec[4]; align_addr = (1 << section->alignment_power); if ((base_addr % align_addr) != 0) base_addr += (align_addr - (base_addr % align_addr)); section->vma = (bfd_vma)base_addr; base_addr += section->size; section->contents = (unsigned char *)bfd_zmalloc(section->size); if (section->contents == NULL) return -1; #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "egsd psc %d (%s, flags %04x=%s) ", section->index, name, old_flags, flag2str (gpsflagdesc, old_flags)); vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n", section->size, section->vma, section->contents); #endif } break; case EGSD_S_C_SYM + EVAX_OFFSET: { /* Symbol specification (definition or reference). */ symbol = bfd_make_empty_symbol (abfd); if (symbol == 0) return -1; old_flags = bfd_getl16 (vms_rec + 6); new_flags = BSF_NO_FLAGS; if (old_flags & EGSY_S_V_WEAK) new_flags |= BSF_WEAK; if (vms_rec[6] & EGSY_S_V_DEF) { /* Symbol definition. */ symbol->name = _bfd_vms_save_counted_string (vms_rec + 32); if (old_flags & EGSY_S_V_NORM) /* Proc def. */ new_flags |= BSF_FUNCTION; symbol->value = bfd_getl64 (vms_rec + 8); symbol->section = (asection *) ((unsigned long) bfd_getl32 (vms_rec + 28)); #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount, symbol->name, (int) symbol->section, old_flags, flag2str (gsyflagdesc, old_flags)); #endif } else { /* Symbol reference. */ symbol->name = _bfd_vms_save_counted_string (vms_rec + 8); #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug (4, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount, symbol->name, old_flags, flag2str (gsyflagdesc, old_flags)); #endif symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME); } symbol->flags = new_flags; /* Save symbol in vms_symbol_table: */ entry = (vms_symbol_entry *)bfd_hash_lookup(PRIV(vms_symbol_table), symbol->name, TRUE, FALSE); if (entry == NULL) { bfd_set_error(bfd_error_no_memory); return -1; } if (entry->symbol != NULL) { /* FIXME ?, DEC C generates this. */ #if defined(VMS_DEBUG) && VMS_DEBUG vms_debug(4, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name); #endif /* VMS_DEBUG */ } else { entry->symbol = symbol; PRIV(gsd_sym_count)++; abfd->symcount++; } } break; case EGSD_S_C_IDC + EVAX_OFFSET: break; default: (*_bfd_error_handler)(_("unknown gsd/egsd subtype %d"), gsd_type); bfd_set_error(bfd_error_bad_value); return -1; } PRIV(rec_size) -= gsd_size; PRIV(vms_rec) += gsd_size; } if (abfd->symcount > 0) abfd->flags |= HAS_SYMS; return 0; }