diff options
author | Tristan Gingold <gingold@adacore.com> | 2009-02-23 09:28:43 +0000 |
---|---|---|
committer | Tristan Gingold <gingold@adacore.com> | 2009-02-23 09:28:43 +0000 |
commit | 0c37646508ccd3222db567f20d0ed44a9c3ba1d2 (patch) | |
tree | 494165a5852e9256b4ffc7b97d8a2ae557f26c59 /bfd/vms-gsd.c | |
parent | 6f43c46f4b7ae3ae4506773de7d41c61bd2be4fe (diff) | |
download | gdb-0c37646508ccd3222db567f20d0ed44a9c3ba1d2.zip gdb-0c37646508ccd3222db567f20d0ed44a9c3ba1d2.tar.gz gdb-0c37646508ccd3222db567f20d0ed44a9c3ba1d2.tar.bz2 |
2009-02-23 Tristan Gingold <gingold@adacore.com>
* vms.h: Update copyright year, fix comments, reorder declarations.
(_bfd_save_vms_section): Remove the prototype.
(EGPS_S_V_NO_SHIFT): New constant.
(bfd_vms_set_section_flags): New prototype.
(EGPS_S_B_ALIGN, EGPS_S_W_FLAGS, EGPS_S_L_ALLOC, EGPS_S_B_NAMLNG): New
constants.
(EGSY_S_W_FLAGS): Ditto.
(EGSY_S_V_QUAD_VAL): Ditto.
(ESDF_S_L_VALUE, ESDF_S_L_PSINDX, ESDF_S_B_NAMLNG): Ditto.
(EGST_S_W_FLAGS, EGST_S_Q_LP_1, EGST_S_Q_LP_2, EGST_S_L_PSINDX,
EGST_S_B_NAMLNG): Ditto.
(ESRF_S_B_NAMLNG): Ditto.
(ETIR_S_C_HEADER_SIZE): Ditto.
(EGPS_S_V_ALLOC_64BIT): Ditto.
(DST_S_C_EPILOG): Ditto.
(DST_S_C_SRC_SETLNUM_L, DST_S_C_SRC_SETLNUM_W) : Ditto.
(DST_S_C_SRC_INCRLNUM_B): Ditto.
(DST_S_B_PCLINE_UNSBYTE, DST_S_W_PCLINE_UNSWORD): Ditto.
(DST_S_L_PCLINE_UNSLONG): Ditto.
(DST_S_B_MODBEG_NAME, DST_S_L_RTNBEG_ADDRESS) : Ditto
(DST_S_B_RTNBEG_NAME, DST_S_L_RTNEND_SIZE): Ditto
(DST_S_C_SOURCE_HEADER_SIZE): Ditto.
(DST_S_B_SRC_DF_LENGTH, DST_S_W_SRC_DF_FILEID): Ditto.
(DST_S_B_SRC_DF_FILENAME, DST_S_B_SRC_UNSBYTE): Ditto.
(DST_S_B_SRC_UNSBYTE): Ditto.
(DST_S_W_SRC_UNSWORD, DST_S_L_SRC_UNSLONG): Ditto.
Add prototypes.
(vms_section, vms_reloc): Remove types.
(hdr_struc): Replaced by ...
(hdr_struct): ... new type.
(EMH_S_W_HDRTYP, EMH_S_B_STRLVL, EMH_S_L_ARCH1): New constants.
(EMH_S_L_ARCH2, EMH_S_L_RECSIZ, EMH_S_B_NAMLNG): Ditto.
(EMH_DATE_LENGTH): Ditto.
(eom_struc): Replaced by ...
(eom_struct): ... new type.
(EEOM_S_L_TOTAL_LPS, EEOM_S_W_COMCOD, EEOM_S_B_TFRFLG): New constants.
(EEOM_S_L_PSINDX, EEOM_S_L_TFRADR): Ditto.
(EIHD_S_K_MAJORID, EIHD_S_K_MINORID, EIHD_S_K_EXE): Ditto.
(EIHD_S_L_SIZE, EIHD_S_L_ISDOFF, EIHD_S_L_SYMDBGOFF): Ditto.
(EIHD_S_Q_SYMVVA, EIHD_S_L_IMGTYPE): Ditto.
(EISD_S_L_EISDSIZE, EISD_S_L_SECSIZE, EISD_S_Q_VIR_ADDR): Ditto.
(EISD_S_L_FLAGS, EISD_S_L_VBN, EISD_S_R_CONTROL): Ditto.
(EISD_S_L_IDENT, EISD_S_T_GBLNAM): Ditto.
(EISD_S_M_GBL, EISD_S_M_CRF, EISD_S_M_DZRO, EISD_S_M_WRT): Ditto.
(EISD_S_M_INITALCODE, EISD_S_M_BASED, EISD_S_M_FIXUPVEC): Ditto.
(EISD_S_M_RESIDENT, EISD_S_M_VECTOR, EISD_S_M_PROTECT): Ditto.
(EISD_S_M_LASTCLU, EISD_S_M_EXE, EISD_S_M_NONSHRADR): Ditto.
(EISD_S_M_QUAD_LENGTH, EISD_S_M_ALLOC_64BIT): Ditto.
(EIHS_S_L_DSTVBN, EIHS_S_L_DSTSIZE, EIHS_S_L_GSTVBN): Ditto.
(EIHS_S_L_GSTSIZE, EIHS_S_L_DMTVBN, EIHS_S_L_DMTBYTES): Ditto.
(DBG_S_L_DMT_MODBEG, DBG_S_L_DST_SIZE): Ditto.
(DBG_S_W_DMT_PSECT_COUNT, DBG_S_C_DMT_HEADER_SIZE): Ditto.
(DBG_S_L_DMT_PSECT_START, DBG_S_L_DMT_PSECT_LENGTH)
(DBG_S_C_DMT_PSECT_SIZE): Ditto.
(enum file_type_enum): New type.
(struct location_struct): Removed.
(struct fileinfo, struct srecinfo, struct lineinfo): New types.
(struct funcinfo, struct module): Ditto.
(struct vms_private_data_struct): Update fields.
(struct vms_section_data_struct): New type.
* vms.c: Update copyright year, fix comments,
Fix includes for DECC, add prototypes.
(vms_initialize): Use bfd_alloc instead of bfd_zalloc and remove
some initializers.
Use flavour to set is_vax, location_stack is removed.
(struct pair): Declare.
(fill_section_ptr): Initialize variables at declaration.
Add guard to set SECTION_SYM flag, handlde und section.
(vms_fixup_sections): Use struct pair for fill_section_ptr argument.
(_bfd_vms_slurp_object_records): New function, replaces previous
vms_object_p.
(vms_slurp_module): New function.
(vms_slurp_image): Ditto.
(vms_object_p): Complete rewrite.
(vms_mkobject): Use is_vax field to slect architecture.
(free_reloc_stream): New function.
(vms_convert_to_var): Ditto.
(vms_convert_to_var_1): Ditto.
(vms_convert_to_var_unix_filename): Ditto.
(vms_close_and_cleanup): Call free_reloc_stream, convert file to
VAR format on VMS.
(vms_new_section_hook): Set alignment to 0, allocate private data.
(vms_get_section_contents): Load content.
(vms_get_symbol_info): Handle undefined section.
(vms_find_nearest_line): Handle.
(alloc_reloc_stream): New function.
(vms_slurp_reloc_table): Ditto.
(vms_get_reloc_upper_bound): Make it real.
(vms_canonicalize_reloc): Do the real work.
(alpha_howto_table): Add ALPHA_R_NOP, ALPHA_R_BSR, ALPHA_R_LDA,
ALPHA_R_BOH.
(vms_bfd_reloc_type_lookup): Handle NOP, BSR, LDA and BOH.
(vms_set_arch_mach): Check arch.
(vms_set_section_contents): Copy the content after allocation.
(vms_alpha_vec): Update object flags.
* vms-tir.c: Update copyright year, fix comments,
add prototypes for new functions.
(dst_define_location): New function.
(dst_restore_location): New function.
(dst_retrieve_location): New function.
(dst_check_allocation): New function.
(image_dump): Call dst_check_allocation.
(image_write_b): Ditto.
(image_write_w): Ditto.
(image_write_l): Ditto.
(image_write_q): Ditto.
(cmd_name): Handle STA_LW, STA_QW, STO_OFF, STO_IMM, STO_IMMR, STO_LW,
STO_QW, OPR_ADD, CTL_SETRB, STC_LP_PSB, CTL_DFLOC, CTL_STLOC,
CTL_STKDL.
Call error handler instead of abort if name is not known.
(etir_sta): Add quarter_relocs argument and set it.
Fix cast.
(etir_sto): Ditto.
(etir_opr): Ditto, return FALSE in case of error.
(etir_ctl): Add quarter_relocs argument and set it, fix cast.
Fix CTL_DFLOC, CTL_STLOC, CTL_STKDL.
(etir_stc): Add quarter_relocs argument and set it, fix cast.
Fix STC_LP, STC_LP_PSB, STC_GBL and STC_CGA.
Handle STC_LP_PSB, STC_BSR_GBL, STC_LDA_GBL, STC_BOH_GBL.
Move STC_NOP_PS, STC_BSR_PS, STC_LDA_PS, STC_BOH_PS, STC_NBH_PS.
Return FALSE in case of error.
(tir_sta): Change sign of psect.
(tir_ctl): Ditto.
(tir_cmd): Fix cast. Makes tir_table static const.
(etir_cmd): Add quarter_relocs argument, makes etir_table const,
add argument to explain.
(analyze_etir): Initialize maxptr, add quarter_relocs
declaration, move some declarations into inner scopes.
Handle quarter_relocs and STO_IMM.
(_bfd_vms_slurp_tir): Use constant instead of hard-coded values.
(_bfd_vms_slurp_relocs): New function.
(_bfd_vms_decode_relocs): New function.
(sto_imm): Rewritten.
(start_first_etbt_record): New function.
(start_another_etbt_record): Ditto.
(etir_output_check): Ditto.
(defer_reloc_p): Ditto.
(_bfd_vms_write_tir): Remove nextoffset, convert a while-loop to
a for-loop. Correctly deals with contents, deals with .vmsdebug,
rewritte relocations handling.
(_bfd_vms_write_tbt): Removed.
(_bfd_vms_write_dbg): Ditto.
* vms-misc.c: Update copyright year, Fix comments.
(_bfd_vms_get_header_values): Use 'size' instead of 'length'.
(maybe_adjust_record_pointer_for_object): New function.
(_bfd_vms_get_first_record): New function, replaces ...
(_bfd_vms_get_record): .. removed.
(_bfd_vms_get_object_record): New function.
(_bfd_vms_get_object_record): New function.
(vms_get_remaining_object_record): New function, replaces ...
(_bfd_vms_get_next_record): ... removed.
(add_new_contents): Removed.
(_bfd_save_vms_section): Removed.
(_bfd_get_vms_section): Removed.
(_bfd_vms_output_flush): Write in VAR format.
(new_symbol): Don't make UND section.
* vms-hdr.c: Update copyright year, update list of record handled.
(_bfd_vms_slurp_hdr): rec_length renamed to rec_size.
(_bfd_vms_write_hdr): Strip vms and unix patches,
add comments, truncate module name at 31 characters,
use constants instead of hard-coded value,
write BFD version instead of a fixed string.
(_bfd_vms_slurp_ihd): New function.
(_bfd_vms_slurp_isd): Ditto.
(_bfd_vms_slurp_ihs): Ditto.
(new_module): Ditto.
(parse_module): Ditto
(build_module_list): Ditto.
(module_find_nearest_line): Ditto.
(_bfd_vms_find_nearest_dst_line): Ditto.
(vms_slurp_debug): Ditto.
(_bfd_vms_slurp_dbg): Ditto.
(_bfd_vms_slurp_tbt): Ditto.
(_bfd_vms_write_dbg): Ditto.
(_bfd_vms_write_tbt): Ditto.
* vms-gsd.c: Update copyright year, update list of records handled.
(EVAX_LITERALS_NAME): New macro.
(evax_section_flags): Add an entry for EVAX_LITERALS_NAME.
(gpsflagdesc, gsyflagdesc): Moved out of _bfd_vms_slurp_gsd.
(register_universal_symbol): New function and prototype.
(_bfd_vms_slurp_gsd): Fix indentations and casts,
improve debug messages,
use constants instead of hard-coded value,
fix missing endianness conversion,
handle global symbol (SYMG).
(bfd_vms_set_section_flags): New function.
(_bfd_vms_write_gsd): Don't write .vmsdebug section,
handle section literals,
fix indentation,
handle section bfd and vms flags,
don't output LIB$INITIALIZE symbol,
fix handling of weak symbols,
fix evax vs vax procedure descriptor,
handle absolute symbols.
* reloc.c (BFD_RELOC_ALPHA_NOP, BFD_RELOC_ALPHA_BSR,
BFD_RELOC_ALPHA_LDA, BFD_RELOC_ALPHA_BOH): New relocations.
* makefile.vms (DEFS): Fix flags for VMS.
* bfdio.c (real_fopen): Handle multiple VMS fopen attributes.
* bfd-in2.h: Regenerated.
* libbfd.h: Regenerated.
Diffstat (limited to 'bfd/vms-gsd.c')
-rw-r--r-- | bfd/vms-gsd.c | 347 |
1 files changed, 266 insertions, 81 deletions
diff --git a/bfd/vms-gsd.c b/bfd/vms-gsd.c index 4bdc27c..e641d0d 100644 --- a/bfd/vms-gsd.c +++ b/bfd/vms-gsd.c @@ -1,9 +1,12 @@ /* vms-gsd.c -- BFD back-end for VAX (openVMS/VAX) and EVAX (openVMS/Alpha) files. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2007 Free Software Foundation, Inc. + 2007, 2009 Free Software Foundation, Inc. - go and read the openVMS linker manual (esp. appendix B) + GSD record handling functions + EGSD record handling functions + + Go and read the openVMS linker manual (esp. appendix B) if you don't know what's going on here :-) Written by Klaus K"ampf (kkaempf@rmi.de) @@ -46,6 +49,7 @@ #define EVAX_READONLYADDR_NAME "$READONLY_ADDR$" #define EVAX_READONLY_NAME "$READONLY$" #define EVAX_LITERAL_NAME "$LITERAL$" +#define EVAX_LITERALS_NAME "$LITERALS" #define EVAX_COMMON_NAME "$COMMON$" #define EVAX_LOCAL_NAME "$LOCAL$" @@ -133,6 +137,11 @@ static struct sec_flags_struct evax_section_flags[] = (SEC_DATA), (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT), (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, + { EVAX_LITERALS_NAME, + (EGPS_S_V_PIC | EGPS_S_V_OVR), + (SEC_DATA | SEC_READONLY), + (EGPS_S_V_PIC | EGPS_S_V_OVR), + (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) }, { NULL, (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT), (SEC_DATA), @@ -197,6 +206,37 @@ vms_esecflag_by_name (struct sec_flags_struct *section_flags, struct flagdescstruct { char *name; flagword value; }; +static const struct flagdescstruct gpsflagdesc[] = +{ + { "PIC", GPS_S_M_PIC }, + { "LIB", GPS_S_M_LIB }, + { "OVR", GPS_S_M_OVR }, + { "REL", GPS_S_M_REL }, + { "GBL", GPS_S_M_GBL }, + { "SHR", GPS_S_M_SHR }, + { "EXE", GPS_S_M_EXE }, + { "RD", GPS_S_M_RD }, + { "WRT", GPS_S_M_WRT }, + { "VEC", GPS_S_M_VEC }, + { "NOMOD", EGPS_S_V_NOMOD }, + { "COM", EGPS_S_V_COM }, + { NULL, 0 } +}; + +static const struct flagdescstruct gsyflagdesc[] = +{ + { "WEAK", GSY_S_M_WEAK }, + { "DEF", GSY_S_M_DEF }, + { "UNI", GSY_S_M_UNI }, + { "REL", GSY_S_M_REL }, + { "COMM", EGSY_S_V_COMM }, + { "VECEP", EGSY_S_V_VECEP }, + { "NORM", EGCY_S_V_NORM }, + { NULL, 0 } +}; + +static char *flag2str (struct flagdescstruct *, flagword); + /* Convert flag to printable string. */ static char * @@ -224,43 +264,15 @@ flag2str (struct flagdescstruct * flagdesc, flagword flags) /* Input routines. */ +static int register_universal_symbol (bfd *abfd, asymbol *symbol, + int vms_flags); + /* Process GSD/EGSD record return 0 on success, -1 on error. */ int _bfd_vms_slurp_gsd (bfd * abfd, int objtype) { -#if 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 - int gsd_type, gsd_size; asection *section; unsigned char *vms_rec; @@ -300,7 +312,7 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype) vms_rec = PRIV (vms_rec); if (objtype == OBJ_S_C_GSD) - gsd_type = *vms_rec; + gsd_type = vms_rec[0]; else { _bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size); @@ -322,7 +334,7 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype) 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))) + if (PRIV (is_vax) && (psect_idx < (abfd->section_count - 1))) { /* Check for temporary section from TIR record. */ if (psect_idx < PRIV (section_count)) @@ -362,7 +374,6 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype) base_addr += section->size; /* Global section is common symbol. */ - if (old_flags & GPS_S_M_GBL) { entry = _bfd_vms_enter_symbol (abfd, name); @@ -496,21 +507,20 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype) else psect = vms_rec[value_offset-1]; - symbol->section = (asection *) (size_t) psect; + symbol->section = (asection *)(unsigned long)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)); + 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. */ - 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)); + 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; @@ -574,19 +584,19 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype) case EGSD_S_C_PSC + EVAX_OFFSET: { /* Program section definition. */ - name = _bfd_vms_save_counted_string (vms_rec + 12); + 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 + 6); - section->size = bfd_getl32 (vms_rec + 8); /* Allocation. */ + 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[4]; + 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)); @@ -595,9 +605,10 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype) section->contents = bfd_zmalloc (section->size); if (section->contents == NULL) return -1; + section->filepos = (unsigned int)-1; #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, "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 @@ -606,50 +617,52 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype) case EGSD_S_C_SYM + EVAX_OFFSET: { - /* Symbol specification (definition or reference). */ + /* Global symbol specification (definition or reference). */ symbol = bfd_make_empty_symbol (abfd); if (symbol == 0) return -1; - old_flags = bfd_getl16 (vms_rec + 6); + 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 (vms_rec[6] & EGSY_S_V_DEF) + if (old_flags & 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)); + 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, %d, %04x=%s)\n", abfd->symcount, - symbol->name, (int) symbol->section, old_flags, - flag2str (gsyflagdesc, old_flags)); + 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 + 8); + 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)); + 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->section = (asection *)(unsigned long)-1; } 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); + /* 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); @@ -672,11 +685,73 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype) } break; - case EGSD_S_C_IDC + EVAX_OFFSET: + 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_error_handler) (_("Unknown GSD/EGSD subtype %d"), gsd_type); bfd_set_error (bfd_error_bad_value); return -1; } @@ -691,7 +766,79 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype) return 0; } -/* Output routines. */ +/* Register a universal symbol in the VMS symbol table. */ + +static int +register_universal_symbol (bfd *abfd, asymbol *symbol, int vms_flags) +{ + bfd_vma sbase = 0; + asection *s, *sec = NULL; + vms_symbol_entry *entry; + + /* A universal symbol is by definition global... */ + symbol->flags |= BSF_GLOBAL; + + /* ...and dynamic in shared libraries. */ + if (abfd->flags & DYNAMIC) + symbol->flags |= BSF_DYNAMIC; + + /* Find containing section. */ + for (s = abfd->sections; s; s = s->next) + { + if (symbol->value >= s->vma + && s->vma > sbase + && !(s->flags & SEC_COFF_SHARED_LIBRARY) + && (s->size > 0 || !(vms_flags & EGSY_S_V_REL))) + { + sbase = s->vma; + sec = s; + } + } + + symbol->value -= sbase; + symbol->section = sec; + +#if VMS_DEBUG + vms_debug (4, "EGST sym def #%d (%s, 0x%llx => 0x%llx, %04x=%s)\n", + abfd->symcount, symbol->name, symbol->value + sbase, + symbol->value, vms_flags, + flag2str(gsyflagdesc, vms_flags)); +#endif + + 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) /* FIXME: DEC C generates this */ + { +#if VMS_DEBUG + vms_debug (4, "EGSD_S_C_SYMG: duplicate \"%s\"\n", symbol->name); +#endif + } + else + { + entry->symbol = symbol; + PRIV (gsd_sym_count)++; + abfd->symcount++; + } + + return 0; +} + +/* Set section VMS flags. */ + +void +bfd_vms_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, flagword flags) +{ + vms_section_data (sec)->vflags = flags; +} /* Write section and symbol directory of bfd abfd. */ @@ -705,6 +852,7 @@ _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED) char dummy_name[10]; char *sname; flagword new_flags, old_flags; + int abs_section_index = 0; #if VMS_DEBUG vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype); @@ -730,6 +878,11 @@ _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED) vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->size); #endif + /* Don't write out the VMS debug info section since it is in the + ETBT and EDBG sections in etir. */ + if (!strcmp (section->name, ".vmsdebug")) + goto done; + /* 13 bytes egsd, max 31 chars name -> should be 44 bytes. */ if (_bfd_vms_output_check (abfd, 64) < 0) { @@ -775,6 +928,11 @@ _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED) sname = EVAX_READONLY_NAME; else if ((*sname == 'l') && (strcmp (sname, "literal") == 0)) sname = EVAX_LITERAL_NAME; + else if ((*sname == 'l') && (strcmp (sname, "literals") == 0)) + { + sname = EVAX_LITERALS_NAME; + abs_section_index = section->index; + } else if ((*sname == 'c') && (strcmp (sname, "comm") == 0)) sname = EVAX_COMMON_NAME; else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0)) @@ -785,18 +943,34 @@ _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED) _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); + 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->size > 0); + /* Modify them as directed. */ + if (section->flags & SEC_READONLY) + new_flags &= ~EGPS_S_V_WRT; + + new_flags |= vms_section_data (section)->vflags & 0xffff; + new_flags &= + ~((vms_section_data (section)->vflags >> EGPS_S_V_NO_SHIFT) & 0xffff); + +#if VMS_DEBUG + vms_debug (3, "sec flags %x\n", section->flags); + vms_debug (3, "new_flags %x, _raw_size %d\n", new_flags, section->size); +#endif + _bfd_vms_output_short (abfd, new_flags); _bfd_vms_output_long (abfd, (unsigned long) section->size); _bfd_vms_output_counted (abfd, sname); _bfd_vms_output_flush (abfd); last_index = section->index; +done: section = section->next; } @@ -822,9 +996,11 @@ _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED) 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. */ + if ((old_flags & BSF_GLOBAL) == 0 /* Not xdef... */ + && !bfd_is_und_section (symbol->section) /* and not xref... */ + && !((old_flags & BSF_SECTION_SYM) != 0 /* and not LIB$INITIALIZE. */ + && strcmp (symbol->section->name, "LIB$INITIALIZE") == 0)) + continue; /* 13 bytes egsd, max 64 chars name -> should be 77 bytes. */ if (_bfd_vms_output_check (abfd, 80) < 0) @@ -846,7 +1022,7 @@ _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED) if (old_flags & BSF_WEAK) new_flags |= EGSY_S_V_WEAK; - if (bfd_is_com_section (symbol->section)) + if (bfd_is_com_section (symbol->section)) /* .comm */ new_flags |= (EGSY_S_V_WEAK | EGSY_S_V_COMM); if (old_flags & BSF_FUNCTION) @@ -854,7 +1030,7 @@ _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED) new_flags |= EGSY_S_V_NORM; new_flags |= EGSY_S_V_REL; } - if (old_flags & (BSF_GLOBAL | BSF_WEAK)) + if (old_flags & BSF_GLOBAL) { new_flags |= EGSY_S_V_DEF; if (!bfd_is_abs_section (symbol->section)) @@ -862,7 +1038,7 @@ _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED) } _bfd_vms_output_short (abfd, new_flags); - if (old_flags & (BSF_GLOBAL | BSF_WEAK)) + if (old_flags & BSF_GLOBAL) { /* Symbol definition. */ uquad code_address = 0; @@ -871,10 +1047,19 @@ _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED) if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL) { - code_address = ((asymbol *) (symbol->udata.p))->value; - ca_psindx = ((asymbol *) (symbol->udata.p))->section->index; + asymbol *sym; + + if (bfd_get_flavour (abfd) == bfd_target_evax_flavour) + sym = ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym; + else + sym = (asymbol *)symbol->udata.p; + code_address = sym->value; + ca_psindx = sym->section->index; } - psindx = symbol->section->index; + if (bfd_is_abs_section (symbol->section)) + psindx = abs_section_index; + else + psindx = symbol->section->index; _bfd_vms_output_quad (abfd, symbol->value); _bfd_vms_output_quad (abfd, code_address); |