📄 vms-gsd.c
字号:
#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 == (vms_symbol_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 *)psect;#if 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 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 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+12); section = bfd_make_section (abfd, name); if (!section) return -1; old_flags = bfd_getl16 (vms_rec + 6); section->_raw_size = bfd_getl32 (vms_rec + 8); /* allocation */ new_flags = vms_secflag_by_name (abfd, evax_section_flags, name, (int) section->_raw_size); 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->_raw_size; section->contents = ((unsigned char *) bfd_malloc (section->_raw_size)); if (section->contents == NULL) return -1; memset (section->contents, 0, (size_t) section->_raw_size); section->_cooked_size = section->_raw_size;#if 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->_raw_size, section->vma, section->contents);#endif } break; case EGSD_S_C_SYM + EVAX_OFFSET: { /* symbol specification (definition or reference) */ symbol = _bfd_vms_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 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 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 == (vms_symbol_entry *)NULL) { bfd_set_error (bfd_error_no_memory); return -1; } if (entry->symbol != (asymbol *)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_IDC + EVAX_OFFSET: break; default: (*_bfd_error_handler) (_("unknown gsd/egsd subtype %d"), gsd_type); bfd_set_error (bfd_error_bad_value); return -1; } /* switch */ PRIV(rec_size) -= gsd_size; PRIV(vms_rec) += gsd_size; } /* while (recsize > 0) */ if (abfd->symcount > 0) abfd->flags |= HAS_SYMS; return 0;}/*-----------------------------------------------------------------------------*//* output routines *//* Write section and symbol directory of bfd abfd */int_bfd_vms_write_gsd (abfd, objtype) bfd *abfd; int objtype ATTRIBUTE_UNUSED;{ asection *section; asymbol *symbol; unsigned int symnum; int last_index = -1; char dummy_name[10]; char *sname; flagword new_flags, old_flags;#if VMS_DEBUG vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype);#endif /* output sections */ section = abfd->sections;#if VMS_DEBUG vms_debug (3, "%d sections found\n", abfd->section_count);#endif /* egsd is quadword aligned */ _bfd_vms_output_alignment (abfd, 8); _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1); _bfd_vms_output_long (abfd, 0); _bfd_vms_output_push (abfd); /* prepare output for subrecords */ while (section != 0) {#if VMS_DEBUG vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->_raw_size);#endif /* 13 bytes egsd, max 31 chars name -> should be 44 bytes */ if (_bfd_vms_output_check (abfd, 64) < 0) { _bfd_vms_output_pop (abfd); _bfd_vms_output_end (abfd); _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1); _bfd_vms_output_long (abfd, 0); _bfd_vms_output_push (abfd); /* prepare output for subrecords */ } /* Create dummy sections to keep consecutive indices */ while (section->index - last_index > 1) {#if VMS_DEBUG vms_debug (3, "index %d, last %d\n", section->index, last_index);#endif _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1); _bfd_vms_output_short (abfd, 0); _bfd_vms_output_short (abfd, 0); _bfd_vms_output_long (abfd, 0); sprintf (dummy_name, ".DUMMY%02d", last_index); _bfd_vms_output_counted (abfd, dummy_name); _bfd_vms_output_flush (abfd); last_index++; } /* Don't know if this is neccesary for the linker but for now it keeps vms_slurp_gsd happy */ sname = (char *)section->name; if (*sname == '.') { sname++; if ((*sname == 't') && (strcmp (sname, "text") == 0)) sname = PRIV(is_vax)?VAX_CODE_NAME:EVAX_CODE_NAME; else if ((*sname == 'd') && (strcmp (sname, "data") == 0)) sname = PRIV(is_vax)?VAX_DATA_NAME:EVAX_DATA_NAME; else if ((*sname == 'b') && (strcmp (sname, "bss") == 0)) sname = EVAX_BSS_NAME; else if ((*sname == 'l') && (strcmp (sname, "link") == 0)) sname = EVAX_LINK_NAME; else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0)) sname = EVAX_READONLY_NAME; else if ((*sname == 'l') && (strcmp (sname, "literal") == 0)) sname = EVAX_LITERAL_NAME; else if ((*sname == 'c') && (strcmp (sname, "comm") == 0)) sname = EVAX_COMMON_NAME; else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0)) sname = EVAX_LOCAL_NAME; } else sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ); _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1); _bfd_vms_output_short (abfd, section->alignment_power & 0xff); if (bfd_is_com_section (section)) { 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); } else { new_flags = vms_esecflag_by_name (evax_section_flags, sname, section->_raw_size); } _bfd_vms_output_short (abfd, new_flags); _bfd_vms_output_long (abfd, section->_raw_size); _bfd_vms_output_counted (abfd, sname); _bfd_vms_output_flush (abfd); last_index = section->index; section = section->next; } /* output symbols */#if VMS_DEBUG vms_debug (3, "%d symbols found\n", abfd->symcount);#endif bfd_set_start_address (abfd, (bfd_vma)-1); for (symnum = 0; symnum < abfd->symcount; symnum++) { symbol = abfd->outsymbols[symnum]; if (*(symbol->name) == '_') { if (strcmp (symbol->name, "__main") == 0) bfd_set_start_address (abfd, (bfd_vma)symbol->value); } old_flags = symbol->flags; if (old_flags & BSF_FILE) continue; if (((old_flags & (BSF_GLOBAL|BSF_WEAK)) == 0) /* not xdef */ && (!bfd_is_und_section (symbol->section))) /* and not xref */ continue; /* dont output */ /* 13 bytes egsd, max 64 chars name -> should be 77 bytes */ if (_bfd_vms_output_check (abfd, 80) < 0) { _bfd_vms_output_pop (abfd); _bfd_vms_output_end (abfd); _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1); _bfd_vms_output_long (abfd, 0); _bfd_vms_output_push (abfd); /* prepare output for subrecords */ } _bfd_vms_output_begin (abfd, EGSD_S_C_SYM, -1); _bfd_vms_output_short (abfd, 0); /* data type, alignment */ new_flags = 0; if (old_flags & BSF_WEAK) new_flags |= EGSY_S_V_WEAK; if (bfd_is_com_section (symbol->section)) /* .comm */ new_flags |= (EGSY_S_V_WEAK|EGSY_S_V_COMM); if (old_flags & BSF_FUNCTION) { new_flags |= EGSY_S_V_NORM; new_flags |= EGSY_S_V_REL; } if (old_flags & (BSF_GLOBAL|BSF_WEAK)) { new_flags |= EGSY_S_V_DEF; if (!bfd_is_abs_section (symbol->section)) new_flags |= EGSY_S_V_REL; } _bfd_vms_output_short (abfd, new_flags); if (old_flags & (BSF_GLOBAL|BSF_WEAK)) /* symbol definition */ { if (old_flags & BSF_FUNCTION) { _bfd_vms_output_quad (abfd, symbol->value); _bfd_vms_output_quad (abfd, ((asymbol *) (symbol->udata.p))->value); _bfd_vms_output_long (abfd, (((asymbol *) (symbol->udata.p)) ->section->index)); _bfd_vms_output_long (abfd, symbol->section->index); } else { _bfd_vms_output_quad (abfd, symbol->value); /* L_VALUE */ _bfd_vms_output_quad (abfd, 0); /* L_CODE_ADDRESS */ _bfd_vms_output_long (abfd, 0); /* L_CA_PSINDX */ _bfd_vms_output_long (abfd, symbol->section->index);/* L_PSINDX */ } } _bfd_vms_output_counted (abfd, _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ)); _bfd_vms_output_flush (abfd); } _bfd_vms_output_alignment (abfd, 8); _bfd_vms_output_pop (abfd); _bfd_vms_output_end (abfd); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -