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.
This commit is contained in:
Tristan Gingold 2009-02-23 09:28:43 +00:00
parent 6f43c46f4b
commit 0c37646508
12 changed files with 4076 additions and 1286 deletions

View File

@ -1,3 +1,215 @@
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.
2009-02-20 Cary Coutant <ccoutant@google.com> 2009-02-20 Cary Coutant <ccoutant@google.com>
* vmsutil.c (vms_file_stats_name): Fix incorrect use of st_mtime * vmsutil.c (vms_file_stats_name): Fix incorrect use of st_mtime

View File

@ -2586,6 +2586,22 @@ share a common GP, and the target address is adjusted for
STO_ALPHA_STD_GPLOAD. */ STO_ALPHA_STD_GPLOAD. */
BFD_RELOC_ALPHA_BRSGP, BFD_RELOC_ALPHA_BRSGP,
/* The NOP relocation outputs a NOP if the longword displacement
between two procedure entry points is < 2^21. */
BFD_RELOC_ALPHA_NOP,
/* The BSR relocation outputs a BSR if the longword displacement
between two procedure entry points is < 2^21. */
BFD_RELOC_ALPHA_BSR,
/* The LDA relocation outputs a LDA if the longword displacement
between two procedure entry points is < 2^16. */
BFD_RELOC_ALPHA_LDA,
/* The BOH relocation outputs a BSR if the longword displacement
between two procedure entry points is < 2^21, or else a hint. */
BFD_RELOC_ALPHA_BOH,
/* Alpha thread-local storage relocations. */ /* Alpha thread-local storage relocations. */
BFD_RELOC_ALPHA_TLSGD, BFD_RELOC_ALPHA_TLSGD,
BFD_RELOC_ALPHA_TLSLDM, BFD_RELOC_ALPHA_TLSLDM,

View File

@ -102,13 +102,21 @@ real_fopen (const char *filename, const char *modes)
} }
else else
{ {
/* Attribute found - rebuild modes. */ /* Attributes found. Split. */
size_t modes_len = vms_attr - modes; size_t modes_len = strlen (modes) + 1;
char attrs[modes_len + 1];
char *at[3];
int i;
BFD_ASSERT (modes_len < sizeof (vms_modes)); memcpy (attrs, modes, modes_len);
memcpy (vms_modes, modes, modes_len); at[0] = attrs;
vms_modes[modes_len] = 0; for (i = 0; i < 2; i++)
return close_on_exec (fopen (filename, vms_modes, vms_attr + 1)); {
at[i + 1] = strchr (at[i], ',');
BFD_ASSERT (at[i + 1] != NULL);
*(at[i + 1]++) = 0; /* Replace ',' with a nul, and skip it. */
}
return close_on_exec (fopen (filename, at[0], at[1], at[2]));
} }
#else /* !VMS */ #else /* !VMS */
#if defined (HAVE_FOPEN64) #if defined (HAVE_FOPEN64)

View File

@ -957,6 +957,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_ALPHA_GPREL_HI16", "BFD_RELOC_ALPHA_GPREL_HI16",
"BFD_RELOC_ALPHA_GPREL_LO16", "BFD_RELOC_ALPHA_GPREL_LO16",
"BFD_RELOC_ALPHA_BRSGP", "BFD_RELOC_ALPHA_BRSGP",
"BFD_RELOC_ALPHA_NOP",
"BFD_RELOC_ALPHA_BSR",
"BFD_RELOC_ALPHA_LDA",
"BFD_RELOC_ALPHA_BOH",
"BFD_RELOC_ALPHA_TLSGD", "BFD_RELOC_ALPHA_TLSGD",
"BFD_RELOC_ALPHA_TLSLDM", "BFD_RELOC_ALPHA_TLSLDM",
"BFD_RELOC_ALPHA_DTPMOD64", "BFD_RELOC_ALPHA_DTPMOD64",

View File

@ -36,13 +36,15 @@ endif
CFLAGS=/include=([],[-.include])$(DEFS) CFLAGS=/include=([],[-.include])$(DEFS)
else else
ifeq ($(ARCH),ALPHA) ifeq ($(ARCH),ALPHA)
DEFS=/define=(SELECT_VECS="&vms_alpha_vec",SELECT_ARCHITECTURES="&bfd_alpha_arch",\ DEFS=/define=(SELECT_VECS="&vms_alpha_vec",\
SELECT_ARCHITECTURES="&bfd_alpha_arch",\
"HAVE_vms_alpha_vec=1","unlink=remove","DEBUGDIR=NULL") "HAVE_vms_alpha_vec=1","unlink=remove","DEBUGDIR=NULL")
else else
DEFS=/define=(SELECT_VECS="&vms_vax_vec",SELECT_ARCHITECTURES="&bfd_vax_arch",\ DEFS=/define=(SELECT_VECS="&vms_vax_vec",SELECT_ARCHITECTURES="&bfd_vax_arch",\
"HAVE_vms_vax_vec=1","unlink=remove","const=") "HAVE_vms_vax_vec=1","unlink=remove")
endif endif
CFLAGS=/noopt/debug/show=incl/name=(as_is,shortened)/include=([],[-.include])$(DEFS)/warnings=disable=(missingreturn,longextern) OPT=/noopt/debug
CFLAGS=/name=(as_is,shortened)/include=([],[-.include])$(DEFS)$(OPT)
endif endif

View File

@ -2109,6 +2109,30 @@ ENUMDOC
share a common GP, and the target address is adjusted for share a common GP, and the target address is adjusted for
STO_ALPHA_STD_GPLOAD. STO_ALPHA_STD_GPLOAD.
ENUM
BFD_RELOC_ALPHA_NOP
ENUMDOC
The NOP relocation outputs a NOP if the longword displacement
between two procedure entry points is < 2^21.
ENUM
BFD_RELOC_ALPHA_BSR
ENUMDOC
The BSR relocation outputs a BSR if the longword displacement
between two procedure entry points is < 2^21.
ENUM
BFD_RELOC_ALPHA_LDA
ENUMDOC
The LDA relocation outputs a LDA if the longword displacement
between two procedure entry points is < 2^16.
ENUM
BFD_RELOC_ALPHA_BOH
ENUMDOC
The BOH relocation outputs a BSR if the longword displacement
between two procedure entry points is < 2^21, or else a hint.
ENUM ENUM
BFD_RELOC_ALPHA_TLSGD BFD_RELOC_ALPHA_TLSGD
ENUMX ENUMX

View File

@ -1,9 +1,12 @@
/* vms-gsd.c -- BFD back-end for VAX (openVMS/VAX) and /* vms-gsd.c -- BFD back-end for VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files. EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 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 :-) if you don't know what's going on here :-)
Written by Klaus K"ampf (kkaempf@rmi.de) Written by Klaus K"ampf (kkaempf@rmi.de)
@ -46,6 +49,7 @@
#define EVAX_READONLYADDR_NAME "$READONLY_ADDR$" #define EVAX_READONLYADDR_NAME "$READONLY_ADDR$"
#define EVAX_READONLY_NAME "$READONLY$" #define EVAX_READONLY_NAME "$READONLY$"
#define EVAX_LITERAL_NAME "$LITERAL$" #define EVAX_LITERAL_NAME "$LITERAL$"
#define EVAX_LITERALS_NAME "$LITERALS"
#define EVAX_COMMON_NAME "$COMMON$" #define EVAX_COMMON_NAME "$COMMON$"
#define EVAX_LOCAL_NAME "$LOCAL$" #define EVAX_LOCAL_NAME "$LOCAL$"
@ -133,6 +137,11 @@ static struct sec_flags_struct evax_section_flags[] =
(SEC_DATA), (SEC_DATA),
(EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT), (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT),
(SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, (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, { NULL,
(EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT), (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT),
(SEC_DATA), (SEC_DATA),
@ -197,6 +206,37 @@ vms_esecflag_by_name (struct sec_flags_struct *section_flags,
struct flagdescstruct { char *name; flagword value; }; 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. */ /* Convert flag to printable string. */
static char * static char *
@ -224,43 +264,15 @@ flag2str (struct flagdescstruct * flagdesc, flagword flags)
/* Input routines. */ /* Input routines. */
static int register_universal_symbol (bfd *abfd, asymbol *symbol,
int vms_flags);
/* Process GSD/EGSD record /* Process GSD/EGSD record
return 0 on success, -1 on error. */ return 0 on success, -1 on error. */
int int
_bfd_vms_slurp_gsd (bfd * abfd, int objtype) _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; int gsd_type, gsd_size;
asection *section; asection *section;
unsigned char *vms_rec; unsigned char *vms_rec;
@ -300,7 +312,7 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype)
vms_rec = PRIV (vms_rec); vms_rec = PRIV (vms_rec);
if (objtype == OBJ_S_C_GSD) if (objtype == OBJ_S_C_GSD)
gsd_type = *vms_rec; gsd_type = vms_rec[0];
else else
{ {
_bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size); _bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size);
@ -362,7 +374,6 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype)
base_addr += section->size; base_addr += section->size;
/* Global section is common symbol. */ /* Global section is common symbol. */
if (old_flags & GPS_S_M_GBL) if (old_flags & GPS_S_M_GBL)
{ {
entry = _bfd_vms_enter_symbol (abfd, name); entry = _bfd_vms_enter_symbol (abfd, name);
@ -496,21 +507,20 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype)
else else
psect = vms_rec[value_offset-1]; psect = vms_rec[value_offset-1];
symbol->section = (asection *) (size_t) psect; symbol->section = (asection *)(unsigned long)psect;
#if VMS_DEBUG #if VMS_DEBUG
vms_debug (4, "gsd sym def #%d (%s, %d [%p], %04x=%s)\n", abfd->symcount, vms_debug (4, "gsd sym def #%d (%s, %ld, %04x=%s)\n", abfd->symcount,
symbol->name, (int)symbol->section, symbol->section, old_flags, flag2str (gsyflagdesc, old_flags)); symbol->name, (long)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
#endif #endif
} }
else else
{ {
/* Symbol reference. */ /* Symbol reference. */
symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
#if VMS_DEBUG #if VMS_DEBUG
vms_debug (4, "gsd sym ref #%d (%s, %s [%p], %04x=%s)\n", vms_debug (4, "gsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount,
abfd->symcount, symbol->name, symbol->section->name, symbol->name, old_flags, flag2str (gsyflagdesc, old_flags));
symbol->section, old_flags, flag2str (gsyflagdesc, old_flags));
#endif #endif
symbol->section = (asection *)(unsigned long)-1;
} }
gsd_size = vms_rec[name_offset] + name_offset + 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: case EGSD_S_C_PSC + EVAX_OFFSET:
{ {
/* Program section definition. */ /* 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); section = bfd_make_section (abfd, name);
if (!section) if (!section)
return -1; return -1;
old_flags = bfd_getl16 (vms_rec + 6); old_flags = bfd_getl16 (vms_rec + EGPS_S_W_FLAGS);
section->size = bfd_getl32 (vms_rec + 8); /* Allocation. */ section->size = bfd_getl32 (vms_rec + EGPS_S_L_ALLOC);
new_flags = vms_secflag_by_name (abfd, evax_section_flags, name, new_flags = vms_secflag_by_name (abfd, evax_section_flags, name,
section->size > 0); section->size > 0);
if (old_flags & EGPS_S_V_REL) if (old_flags & EGPS_S_V_REL)
new_flags |= SEC_RELOC; new_flags |= SEC_RELOC;
if (!bfd_set_section_flags (abfd, section, new_flags)) if (!bfd_set_section_flags (abfd, section, new_flags))
return -1; return -1;
section->alignment_power = vms_rec[4]; section->alignment_power = vms_rec[EGPS_S_B_ALIGN];
align_addr = (1 << section->alignment_power); align_addr = (1 << section->alignment_power);
if ((base_addr % align_addr) != 0) if ((base_addr % align_addr) != 0)
base_addr += (align_addr - (base_addr % align_addr)); base_addr += (align_addr - (base_addr % align_addr));
@ -595,8 +605,9 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype)
section->contents = bfd_zmalloc (section->size); section->contents = bfd_zmalloc (section->size);
if (section->contents == NULL) if (section->contents == NULL)
return -1; return -1;
section->filepos = (unsigned int)-1;
#if VMS_DEBUG #if VMS_DEBUG
vms_debug (4, "egsd psc %d (%s, flags %04x=%s) ", vms_debug (4, "EGSD P-section %d (%s, flags %04x=%s) ",
section->index, name, old_flags, flag2str(gpsflagdesc, old_flags)); section->index, name, old_flags, flag2str(gpsflagdesc, old_flags));
vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n", vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n",
section->size, section->vma, section->contents); section->size, section->vma, section->contents);
@ -606,50 +617,52 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype)
case EGSD_S_C_SYM + EVAX_OFFSET: case EGSD_S_C_SYM + EVAX_OFFSET:
{ {
/* Symbol specification (definition or reference). */ /* Global symbol specification (definition or reference). */
symbol = bfd_make_empty_symbol (abfd); symbol = bfd_make_empty_symbol (abfd);
if (symbol == 0) if (symbol == 0)
return -1; return -1;
old_flags = bfd_getl16 (vms_rec + 6); old_flags = bfd_getl16 (vms_rec + EGSY_S_W_FLAGS);
new_flags = BSF_NO_FLAGS; new_flags = BSF_NO_FLAGS;
if (old_flags & EGSY_S_V_WEAK) if (old_flags & EGSY_S_V_WEAK)
new_flags |= BSF_WEAK; new_flags |= BSF_WEAK;
if (vms_rec[6] & EGSY_S_V_DEF) if (old_flags & EGSY_S_V_DEF)
{ {
/* Symbol definition. */ /* Symbol definition. */
symbol->name = _bfd_vms_save_counted_string (vms_rec + 32);
if (old_flags & EGSY_S_V_NORM) if (old_flags & EGSY_S_V_NORM)
/* Proc def. */
new_flags |= BSF_FUNCTION; new_flags |= BSF_FUNCTION;
symbol->name =
symbol->value = bfd_getl64 (vms_rec + 8); _bfd_vms_save_counted_string (vms_rec + ESDF_S_B_NAMLNG);
symbol->section = (asection *) ((unsigned long) bfd_getl32 (vms_rec + 28)); 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 #if VMS_DEBUG
vms_debug (4, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount, vms_debug (4, "EGSD sym def #%d (%s, %ld, %04x=%s)\n",
symbol->name, (int) symbol->section, old_flags, abfd->symcount, symbol->name, (long)symbol->section,
flag2str (gsyflagdesc, old_flags)); old_flags, flag2str (gsyflagdesc, old_flags));
#endif #endif
} }
else else
{ {
/* Symbol reference. */ /* 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 #if VMS_DEBUG
vms_debug (4, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount, vms_debug (4, "EGSD sym ref #%d (%s, %04x=%s)\n",
symbol->name, old_flags, flag2str (gsyflagdesc, old_flags)); abfd->symcount, symbol->name, old_flags,
flag2str (gsyflagdesc, old_flags));
#endif #endif
symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME); symbol->section = (asection *)(unsigned long)-1;
} }
symbol->flags = new_flags; symbol->flags = new_flags;
/* Save symbol in vms_symbol_table. */ /* Register symbol in VMS symbol table. */
entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table), entry = (vms_symbol_entry *) bfd_hash_lookup
symbol->name, (PRIV (vms_symbol_table), symbol->name, TRUE, FALSE);
TRUE, FALSE);
if (entry == NULL) if (entry == NULL)
{ {
bfd_set_error (bfd_error_no_memory); bfd_set_error (bfd_error_no_memory);
@ -672,11 +685,73 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype)
} }
break; 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: case EGSD_S_C_IDC + EVAX_OFFSET:
break; break;
default: 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); bfd_set_error (bfd_error_bad_value);
return -1; return -1;
} }
@ -691,7 +766,79 @@ _bfd_vms_slurp_gsd (bfd * abfd, int objtype)
return 0; 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. */ /* 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 dummy_name[10];
char *sname; char *sname;
flagword new_flags, old_flags; flagword new_flags, old_flags;
int abs_section_index = 0;
#if VMS_DEBUG #if VMS_DEBUG
vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype); 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); vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->size);
#endif #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. */ /* 13 bytes egsd, max 31 chars name -> should be 44 bytes. */
if (_bfd_vms_output_check (abfd, 64) < 0) 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; sname = EVAX_READONLY_NAME;
else if ((*sname == 'l') && (strcmp (sname, "literal") == 0)) else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
sname = EVAX_LITERAL_NAME; 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)) else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
sname = EVAX_COMMON_NAME; sname = EVAX_COMMON_NAME;
else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0)) 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_begin (abfd, EGSD_S_C_PSC, -1);
_bfd_vms_output_short (abfd, section->alignment_power & 0xff); _bfd_vms_output_short (abfd, section->alignment_power & 0xff);
if (bfd_is_com_section (section)) 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 else
new_flags = vms_esecflag_by_name (evax_section_flags, sname, new_flags = vms_esecflag_by_name (evax_section_flags, sname,
section->size > 0); 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_short (abfd, new_flags);
_bfd_vms_output_long (abfd, (unsigned long) section->size); _bfd_vms_output_long (abfd, (unsigned long) section->size);
_bfd_vms_output_counted (abfd, sname); _bfd_vms_output_counted (abfd, sname);
_bfd_vms_output_flush (abfd); _bfd_vms_output_flush (abfd);
last_index = section->index; last_index = section->index;
done:
section = section->next; section = section->next;
} }
@ -822,9 +996,11 @@ _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
if (old_flags & BSF_FILE) if (old_flags & BSF_FILE)
continue; continue;
if (((old_flags & (BSF_GLOBAL | BSF_WEAK)) == 0) /* Not xdef... */ if ((old_flags & BSF_GLOBAL) == 0 /* Not xdef... */
&& (!bfd_is_und_section (symbol->section))) /* ...and not xref. */ && !bfd_is_und_section (symbol->section) /* and not xref... */
continue; /* Dont output. */ && !((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. */ /* 13 bytes egsd, max 64 chars name -> should be 77 bytes. */
if (_bfd_vms_output_check (abfd, 80) < 0) 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) if (old_flags & BSF_WEAK)
new_flags |= EGSY_S_V_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); new_flags |= (EGSY_S_V_WEAK | EGSY_S_V_COMM);
if (old_flags & BSF_FUNCTION) 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_NORM;
new_flags |= EGSY_S_V_REL; new_flags |= EGSY_S_V_REL;
} }
if (old_flags & (BSF_GLOBAL | BSF_WEAK)) if (old_flags & BSF_GLOBAL)
{ {
new_flags |= EGSY_S_V_DEF; new_flags |= EGSY_S_V_DEF;
if (!bfd_is_abs_section (symbol->section)) 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); _bfd_vms_output_short (abfd, new_flags);
if (old_flags & (BSF_GLOBAL | BSF_WEAK)) if (old_flags & BSF_GLOBAL)
{ {
/* Symbol definition. */ /* Symbol definition. */
uquad code_address = 0; uquad code_address = 0;
@ -871,9 +1047,18 @@ _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL) if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL)
{ {
code_address = ((asymbol *) (symbol->udata.p))->value; asymbol *sym;
ca_psindx = ((asymbol *) (symbol->udata.p))->section->index;
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;
} }
if (bfd_is_abs_section (symbol->section))
psindx = abs_section_index;
else
psindx = symbol->section->index; psindx = symbol->section->index;
_bfd_vms_output_quad (abfd, symbol->value); _bfd_vms_output_quad (abfd, symbol->value);

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,9 @@
/* vms-misc.c -- Miscellaneous functions for VAX (openVMS/VAX) and /* vms-misc.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files. EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2007, 2008 Free Software Foundation, Inc. 2007, 2008, 2009 Free Software Foundation, Inc.
Miscellaneous functions.
Written by Klaus K"ampf (kkaempf@rmi.de) Written by Klaus K"ampf (kkaempf@rmi.de)
@ -30,22 +32,29 @@
#include "libbfd.h" #include "libbfd.h"
#include "vms.h" #include "vms.h"
#define MIN(a,b) ((a) < (b) ? (a) : (b))
static int hash_string PARAMS ((const char *));
static asymbol *new_symbol PARAMS ((bfd *, char *));
static void maybe_adjust_record_pointer_for_object PARAMS ((bfd *));
static int vms_get_remaining_object_record PARAMS ((bfd *, int ));
static int vms_get_remaining_image_record PARAMS ((bfd *, int ));
#if VMS_DEBUG #if VMS_DEBUG
/* Debug functions. */ /* Debug functions. */
/* Debug function for all vms extensions /* Debug function for all vms extensions evaluates environment
evaluates environment variable VMS_DEBUG for a variable VMS_DEBUG for a numerical value on the first call all
numerical value on the first call error levels below this value are printed:
all error levels below this value are printed
levels: Levels:
1 toplevel bfd calls (functions from the bfd vector) 1 toplevel bfd calls (functions from the bfd vector)
2 functions called by bfd calls 2 functions called by bfd calls
... ...
9 almost everything 9 almost everything
level is also indentation level. Indentation is performed Level is also indentation level. Indentation is performed
if level > 0. */ if level > 0. */
void void
@ -167,22 +176,23 @@ _bfd_vms_hash_newfunc (struct bfd_hash_entry *entry,
/* Object file input functions. */ /* Object file input functions. */
/* Return type and length from record header (buf) on Alpha. */ /* Return type and size from record header (buf) on Alpha. */
void void
_bfd_vms_get_header_values (bfd * abfd ATTRIBUTE_UNUSED, _bfd_vms_get_header_values (bfd * abfd ATTRIBUTE_UNUSED,
unsigned char *buf, unsigned char *buf,
int *type, int *type,
int *length) int *size)
{ {
if (type != 0) if (type)
*type = bfd_getl16 (buf); *type = bfd_getl16 (buf);
buf += 2;
if (length != 0) if (size)
*length = bfd_getl16 (buf); *size = bfd_getl16 (buf+2);
#if VMS_DEBUG #if VMS_DEBUG
vms_debug (10, "_bfd_vms_get_header_values type %x, length %x\n", (type?*type:0), (length?*length:0)); vms_debug (10, "_bfd_vms_get_header_values type %x, size %x\n",
type ? *type : 0, size ? *size : 0);
#endif #endif
} }
@ -193,237 +203,341 @@ _bfd_vms_get_header_values (bfd * abfd ATTRIBUTE_UNUSED,
The openVMS object file has 'variable length' which means that The openVMS object file has 'variable length' which means that
read() returns data in chunks of (hopefully) correct and expected read() returns data in chunks of (hopefully) correct and expected
size. The linker (and other tools on vms) depend on that. Unix doesn't size. The linker (and other tools on VMS) depend on that. Unix
know about 'formatted' files, so reading and writing such an object doesn't know about 'formatted' files, so reading and writing such
file in a unix environment is not trivial. an object file in a Unix environment is not trivial.
With the tool 'file' (available on all vms ftp sites), one With the tool 'file' (available on all VMS FTP sites), one
can view and change the attributes of a file. Changing from can view and change the attributes of a file. Changing from
'variable length' to 'fixed length, 512 bytes' reveals the 'variable length' to 'fixed length, 512 bytes' reveals the
record length at the first 2 bytes of every record. The same record size at the first 2 bytes of every record. The same
happens during the transfer of object files from vms to unix, happens during the transfer of object files from VMS to Unix,
at least with ucx, dec's implementation of tcp/ip. at least with UCX, the DEC implementation of TCP/IP.
The vms format repeats the length at bytes 2 & 3 of every record. The VMS format repeats the size at bytes 2 & 3 of every record.
On the first call (file_format == FF_UNKNOWN) we check if On the first call (file_format == FF_UNKNOWN) we check if
the first and the third byte pair (!) of the record match. the first and the third byte pair (!) of the record match.
If they do it's an object file in an unix environment or with If they do it's an object file in an Unix environment or with
wrong attributes (FF_FOREIGN), else we should be in a vms wrong attributes (FF_FOREIGN), else we should be in a VMS
environment where read() returns the record size (FF_NATIVE). environment where read() returns the record size (FF_NATIVE).
Reading is always done in 2 steps. Reading is always done in 2 steps:
First just the record header is read and the length extracted 1. first just the record header is read and the size extracted,
by get_header_values, 2. then the read buffer is adjusted and the remaining bytes are
then the read buffer is adjusted and the remaining bytes are
read in. read in.
All file i/o is always done on even file positions. */ All file I/O is done on even file positions. */
#define VMS_OBJECT_ADJUSTMENT 2
static void
maybe_adjust_record_pointer_for_object (bfd *abfd)
{
/* Set the file format once for all on the first invocation. */
if (PRIV (file_format) == FF_UNKNOWN)
{
if (PRIV (vms_rec)[0] == PRIV (vms_rec)[4]
&& PRIV (vms_rec)[1] == PRIV (vms_rec)[5])
PRIV (file_format) = FF_FOREIGN;
else
PRIV (file_format) = FF_NATIVE;
}
/* The adjustment is needed only in an Unix environment. */
if (PRIV (file_format) == FF_FOREIGN)
PRIV (vms_rec) += VMS_OBJECT_ADJUSTMENT;
}
/* Get first record from file and return the file type. */
int int
_bfd_vms_get_record (bfd * abfd) _bfd_vms_get_first_record (bfd *abfd)
{ {
int test_len, test_start, remaining; unsigned int test_len;
unsigned char *vms_buf;
#if VMS_DEBUG #if VMS_DEBUG
vms_debug (8, "_bfd_vms_get_record\n"); vms_debug (8, "_bfd_vms_get_first_record\n");
#endif #endif
/* Minimum is 6 bytes on Alpha if (PRIV (is_vax))
(2 bytes length, 2 bytes record id, 2 bytes length repeated) test_len = 0;
else
On the VAX there's no length information in the record /* Minimum is 6 bytes for objects (2 bytes size, 2 bytes record id,
so start with OBJ_S_C_MAXRECSIZ. */ 2 bytes size repeated) and 12 bytes for images (4 bytes major id,
4 bytes minor id, 4 bytes length). */
test_len = 12;
/* Size the main buffer. */
if (PRIV (buf_size) == 0) if (PRIV (buf_size) == 0)
{ {
bfd_size_type amt; /* On VAX there's no size information in the record, so
start with OBJ_S_C_MAXRECSIZ. */
if (PRIV (is_vax)) bfd_size_type amt = (test_len ? test_len : OBJ_S_C_MAXRECSIZ);
{ PRIV (vms_buf) = (unsigned char *) bfd_malloc (amt);
amt = OBJ_S_C_MAXRECSIZ;
PRIV (file_format) = FF_VAX;
}
else
amt = 6;
PRIV (vms_buf) = bfd_malloc (amt);
PRIV (buf_size) = amt; PRIV (buf_size) = amt;
} }
vms_buf = PRIV (vms_buf); /* Initialize the record pointer. */
PRIV (vms_rec) = PRIV (vms_buf);
if (vms_buf == 0) /* We only support modules on VAX. */
return -1; if (PRIV (is_vax))
switch (PRIV (file_format))
{ {
case FF_UNKNOWN: if (vms_get_remaining_object_record (abfd, test_len) <= 0)
case FF_FOREIGN: return FT_UNKNOWN;
test_len = 6; /* Probe 6 bytes. */
test_start = 2; /* Where the record starts. */
break;
case FF_NATIVE: #if VMS_DEBUG
test_len = 4; vms_debug (2, "file type is VAX module\n");
test_start = 0; #endif
break;
default: return FT_MODULE;
case FF_VAX: }
if (bfd_bread (PRIV (vms_buf), test_len, abfd) != test_len)
{
bfd_set_error (bfd_error_file_truncated);
return FT_UNKNOWN;
}
/* Is it an image? */
if ((bfd_getl32 (PRIV (vms_rec)) == EIHD_S_K_MAJORID)
&& (bfd_getl32 (PRIV (vms_rec) + 4) == EIHD_S_K_MINORID))
{
if (vms_get_remaining_image_record (abfd, test_len) <= 0)
return FT_UNKNOWN;
#if VMS_DEBUG
vms_debug (2, "file type is image\n");
#endif
return FT_IMAGE;
}
/* Assume it's a module and adjust record pointer if necessary. */
maybe_adjust_record_pointer_for_object (abfd);
/* But is it really a module? */
if (bfd_getl16 (PRIV (vms_rec)) <= EOBJ_S_C_MAXRECTYP
&& bfd_getl16 (PRIV (vms_rec) + 2) <= EOBJ_S_C_MAXRECSIZ)
{
if (vms_get_remaining_object_record (abfd, test_len) <= 0)
return FT_UNKNOWN;
#if VMS_DEBUG
vms_debug (2, "file type is module\n");
#endif
return FT_MODULE;
}
#if VMS_DEBUG
vms_debug (2, "file type is unknown\n");
#endif
return FT_UNKNOWN;
}
/* Implement step #1 of the object record reading procedure.
Return the record type or -1 on failure. */
int
_bfd_vms_get_object_record (bfd *abfd)
{
unsigned int test_len;
int type;
#if VMS_DEBUG
vms_debug (8, "_bfd_vms_get_obj_record\n");
#endif
if (PRIV (is_vax))
test_len = 0; test_len = 0;
test_start = 0;
break;
}
/* Skip odd alignment byte. */
if (bfd_tell (abfd) & 1)
{
if (bfd_bread (PRIV (vms_buf), (bfd_size_type) 1, abfd) != 1)
{
bfd_set_error (bfd_error_file_truncated);
return 0;
}
}
/* Read the record header on Alpha. */
if ((test_len != 0)
&& (bfd_bread (PRIV (vms_buf), (bfd_size_type) test_len, abfd)
!= (bfd_size_type) test_len))
{
bfd_set_error (bfd_error_file_truncated);
return 0;
}
/* Check file format on first call. */
if (PRIV (file_format) == FF_UNKNOWN)
{ /* Record length repeats ? */
if (vms_buf[0] == vms_buf[4]
&& vms_buf[1] == vms_buf[5])
{
PRIV (file_format) = FF_FOREIGN; /* Y: foreign environment. */
test_start = 2;
}
else else
{ {
PRIV (file_format) = FF_NATIVE; /* N: native environment. */ /* See _bfd_vms_get_first_record. */
test_start = 0; test_len = 6;
/* Skip odd alignment byte. */
if (bfd_tell (abfd) & 1)
{
if (bfd_bread (PRIV (vms_buf), 1, abfd) != 1)
{
bfd_set_error (bfd_error_file_truncated);
return -1;
} }
} }
/* Read the record header */
if (bfd_bread (PRIV (vms_buf), test_len, abfd) != test_len)
{
bfd_set_error (bfd_error_file_truncated);
return -1;
}
/* Reset the record pointer. */
PRIV (vms_rec) = PRIV (vms_buf);
maybe_adjust_record_pointer_for_object (abfd);
}
if (vms_get_remaining_object_record (abfd, test_len) <= 0)
return -1;
if (PRIV (is_vax))
type = PRIV (vms_rec) [0];
else
type = bfd_getl16 (PRIV (vms_rec));
#if VMS_DEBUG
vms_debug (8, "_bfd_vms_get_obj_record: rec %p, size %d, type %d\n",
PRIV (vms_rec), PRIV (rec_size), type);
#endif
return type;
}
/* Implement step #2 of the object record reading procedure.
Return the size of the record or 0 on failure. */
static int
vms_get_remaining_object_record (bfd *abfd, int read_so_far)
{
#if VMS_DEBUG
vms_debug (8, "vms_get_remaining_obj_record\n");
#endif
if (PRIV (is_vax)) if (PRIV (is_vax))
{ {
PRIV (rec_length) = bfd_bread (vms_buf, (bfd_size_type) PRIV (buf_size), if (read_so_far != 0)
abfd); abort ();
if (PRIV (rec_length) <= 0)
PRIV (rec_size) = bfd_bread (PRIV (vms_buf), PRIV (buf_size), abfd);
if (PRIV (rec_size) <= 0)
{ {
bfd_set_error (bfd_error_file_truncated); bfd_set_error (bfd_error_file_truncated);
return 0; return 0;
} }
PRIV (vms_rec) = vms_buf;
/* Reset the record pointer. */
PRIV (vms_rec) = PRIV (vms_buf);
} }
else else
{ {
/* Alpha. */ unsigned int to_read;
/* Extract vms record length. */
_bfd_vms_get_header_values (abfd, vms_buf + test_start, NULL, /* Extract record size. */
& PRIV (rec_length)); PRIV (rec_size) = bfd_getl16 (PRIV (vms_rec) + 2);
if (PRIV (rec_length) <= 0) if (PRIV (rec_size) <= 0)
{ {
bfd_set_error (bfd_error_file_truncated); bfd_set_error (bfd_error_file_truncated);
return 0; return 0;
} }
/* That's what the linker manual says. */ /* That's what the linker manual says. */
if (PRIV (rec_size) > EOBJ_S_C_MAXRECSIZ)
if (PRIV (rec_length) > EOBJ_S_C_MAXRECSIZ)
{ {
bfd_set_error (bfd_error_file_truncated); bfd_set_error (bfd_error_file_truncated);
return 0; return 0;
} }
/* Adjust the buffer. */ /* Take into account object adjustment. */
to_read = PRIV (rec_size);
if (PRIV (file_format) == FF_FOREIGN)
to_read += VMS_OBJECT_ADJUSTMENT;
if (PRIV (rec_length) > PRIV (buf_size)) /* Adjust the buffer. */
if (to_read > PRIV (buf_size))
{ {
PRIV (vms_buf) = bfd_realloc_or_free (vms_buf, PRIV (vms_buf)
(bfd_size_type) PRIV (rec_length)); = (unsigned char *) bfd_realloc (PRIV (vms_buf), to_read);
vms_buf = PRIV (vms_buf); if (PRIV (vms_buf) == NULL)
if (vms_buf == 0) return 0;
return -1; PRIV (buf_size) = to_read;
PRIV (buf_size) = PRIV (rec_length);
} }
/* Read the remaining record. */ /* Read the remaining record. */
remaining = PRIV (rec_length) - test_len + test_start; to_read -= read_so_far;
#if VMS_DEBUG #if VMS_DEBUG
vms_debug (10, "bfd_bread remaining %d\n", remaining); vms_debug (8, "vms_get_remaining_obj_record: to_read %d\n", to_read);
#endif #endif
if (bfd_bread (vms_buf + test_len, (bfd_size_type) remaining, abfd) !=
(bfd_size_type) remaining) if (bfd_bread (PRIV (vms_buf) + read_so_far, to_read, abfd) != to_read)
{ {
bfd_set_error (bfd_error_file_truncated); bfd_set_error (bfd_error_file_truncated);
return 0; return 0;
} }
PRIV (vms_rec) = vms_buf + test_start;
/* Reset the record pointer. */
PRIV (vms_rec) = PRIV (vms_buf);
maybe_adjust_record_pointer_for_object (abfd);
} }
#if VMS_DEBUG #if VMS_DEBUG
vms_debug (11, "bfd_bread rec_length %d\n", PRIV (rec_length)); vms_debug (8, "vms_get_remaining_obj_record: size %d\n", PRIV (rec_size));
#endif #endif
return PRIV (rec_length); return PRIV (rec_size);
} }
/* Get next vms record from file /* Implement step #2 of the record reading procedure for images.
update vms_rec and rec_length to new (remaining) values. */ Return the size of the record or 0 on failure. */
int static int
_bfd_vms_next_record (bfd * abfd) vms_get_remaining_image_record (bfd *abfd, int read_so_far)
{ {
#if VMS_DEBUG unsigned int to_read;
vms_debug (8, "_bfd_vms_next_record (len %d, size %d)\n", int remaining;
PRIV (rec_length), PRIV (rec_size));
#endif
if (PRIV (rec_length) > 0) /* Extract record size. */
PRIV (vms_rec) += PRIV (rec_size); PRIV (rec_size) = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SIZE);
else
if (PRIV (rec_size) > PRIV (buf_size))
{ {
if (_bfd_vms_get_record (abfd) <= 0) PRIV (vms_buf) = bfd_realloc (PRIV (vms_buf), PRIV (rec_size));
return -1;
}
if (!PRIV (vms_rec) || !PRIV (vms_buf) if (PRIV (vms_buf) == NULL)
|| PRIV (vms_rec) >= (PRIV (vms_buf) + PRIV (buf_size)))
return -1;
if (PRIV (is_vax))
{ {
PRIV (rec_type) = *(PRIV (vms_rec)); bfd_set_error (bfd_error_no_memory);
PRIV (rec_size) = PRIV (rec_length); return 0;
} }
else
_bfd_vms_get_header_values (abfd, PRIV (vms_rec), &PRIV (rec_type),
&PRIV (rec_size));
PRIV (rec_length) -= PRIV (rec_size); PRIV (buf_size) = PRIV (rec_size);
#if VMS_DEBUG
vms_debug (8, "_bfd_vms_next_record: rec %p, size %d, length %d, type %d\n",
PRIV (vms_rec), PRIV (rec_size), PRIV (rec_length),
PRIV (rec_type));
#endif
return PRIV (rec_type);
} }
/* Copy sized string (string with fixed length) to new allocated area /* Read the remaining record. */
size is string length (size of record) */ remaining = PRIV (rec_size) - read_so_far;
to_read = MIN (VMS_BLOCK_SIZE - read_so_far, remaining);
while (remaining > 0)
{
if (bfd_bread (PRIV (vms_buf) + read_so_far, to_read, abfd) != to_read)
{
bfd_set_error (bfd_error_file_truncated);
return 0;
}
read_so_far += to_read;
remaining -= to_read;
/* Eat trailing 0xff's. */
if (remaining > 0)
while (PRIV (vms_buf) [read_so_far - 1] == 0xff)
read_so_far--;
to_read = MIN (VMS_BLOCK_SIZE, remaining);
}
/* Reset the record pointer. */
PRIV (vms_rec) = PRIV (vms_buf);
return PRIV (rec_size);
}
/* Copy sized string (string with fixed size) to new allocated area
size is string size (size of record) */
char * char *
_bfd_vms_save_sized_string (unsigned char *str, int size) _bfd_vms_save_sized_string (unsigned char *str, int size)
@ -438,8 +552,8 @@ _bfd_vms_save_sized_string (unsigned char *str, int size)
return newstr; return newstr;
} }
/* Copy counted string (string with length at first byte) to new allocated area /* Copy counted string (string with size at first byte) to new allocated area
ptr points to length byte on entry */ ptr points to size byte on entry */
char * char *
_bfd_vms_save_counted_string (unsigned char *ptr) _bfd_vms_save_counted_string (unsigned char *ptr)
@ -501,77 +615,6 @@ _bfd_vms_pop (bfd * abfd, int *psect)
return value; return value;
} }
/* Object file output functions. */
/* GAS tends to write sections in little chunks (bfd_set_section_contents)
which we can't use directly. So we save the little chunks in linked
lists (one per section) and write them later. */
/* Add a new vms_section structure to vms_section_table
- forward chaining -. */
static vms_section *
add_new_contents (bfd * abfd, sec_ptr section)
{
vms_section *sptr, *newptr;
sptr = PRIV (vms_section_table)[section->index];
if (sptr != NULL)
return sptr;
newptr = bfd_alloc (abfd, (bfd_size_type) sizeof (vms_section));
if (newptr == NULL)
return NULL;
newptr->contents = bfd_alloc (abfd, section->size);
if (newptr->contents == NULL)
return NULL;
newptr->offset = 0;
newptr->size = section->size;
newptr->next = 0;
PRIV (vms_section_table)[section->index] = newptr;
return newptr;
}
/* Save section data & offset to a vms_section structure
vms_section_table[] holds the vms_section chain. */
bfd_boolean
_bfd_save_vms_section (bfd * abfd,
sec_ptr section,
const void * data,
file_ptr offset,
bfd_size_type count)
{
vms_section *sptr;
if (section->index >= VMS_SECTION_COUNT)
{
bfd_set_error (bfd_error_nonrepresentable_section);
return FALSE;
}
if (count == (bfd_size_type)0)
return TRUE;
sptr = add_new_contents (abfd, section);
if (sptr == NULL)
return FALSE;
memcpy (sptr->contents + offset, data, (size_t) count);
return TRUE;
}
/* Get vms_section pointer to saved contents for section # index */
vms_section *
_bfd_get_vms_section (bfd * abfd, int index)
{
if (index >= VMS_SECTION_COUNT)
{
bfd_set_error (bfd_error_nonrepresentable_section);
return NULL;
}
return PRIV (vms_section_table)[index];
}
/* Object output routines. */ /* Object output routines. */
/* Begin new record or record header /* Begin new record or record header
@ -691,18 +734,11 @@ _bfd_vms_output_flush (bfd * abfd)
if (PRIV (push_level) == 0) if (PRIV (push_level) == 0)
{ {
if (0 /* File is open in undefined (UDF) format on VMS, but ultimately will be
#ifndef VMS converted to variable length (VAR) format. VAR format has a length
/* Write length first, see FF_FOREIGN in the input routines. */ word first which must be explicitly output in UDF format. */
|| fwrite (PRIV (output_buf) + 2, 2, 1, bfd_bwrite (PRIV (output_buf) + 2, 2, abfd);
(FILE *) abfd->iostream) != 1 bfd_bwrite (PRIV (output_buf), (size_t) real_size, abfd);
#endif
|| (real_size != 0
&& fwrite (PRIV (output_buf), (size_t) real_size, 1,
(FILE *) abfd->iostream) != 1))
/* FIXME: Return error status. */
abort ();
PRIV (output_size) = 0; PRIV (output_size) = 0;
} }
else else
@ -948,7 +984,7 @@ new_symbol (bfd * abfd, char *name)
if (symbol == 0) if (symbol == 0)
return symbol; return symbol;
symbol->name = name; symbol->name = name;
symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME); symbol->section = (asection *)(unsigned long)-1;
return symbol; return symbol;
} }

File diff suppressed because it is too large Load Diff

871
bfd/vms.c

File diff suppressed because it is too large Load Diff

403
bfd/vms.h
View File

@ -1,6 +1,8 @@
/* vms.h -- Header file for VMS (Alpha and Vax) support. /* vms.h -- Header file for VMS (Alpha and Vax) support.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007,
Free Software Foundation, Inc. 2008, 2009 Free Software Foundation, Inc.
Main header file.
Written by Klaus K"ampf (kkaempf@rmi.de) Written by Klaus K"ampf (kkaempf@rmi.de)
@ -25,9 +27,12 @@
#ifndef VMS_H #ifndef VMS_H
#define VMS_H #define VMS_H
/* Constants starting with 'Exxx_' are for openVMS/Alpha (EVAX object language) */ /* Constants starting with 'Exxx_' are for openVMS/Alpha (EVAX object
language). */
/* VMS Text, information and relocation record (TIR/ETIR) definitions. */ #define VMS_BLOCK_SIZE 512
/* VMS Text Information and Relocation Records (TIR/ETIR). */
#define TIR_S_C_STA_GBL 0 #define TIR_S_C_STA_GBL 0
#define TIR_S_C_STA_SB 1 #define TIR_S_C_STA_SB 1
@ -107,7 +112,7 @@
#define ETIR_S_C_STA_GBL 0 /* Stack global symbol value. */ #define ETIR_S_C_STA_GBL 0 /* Stack global symbol value. */
#define ETIR_S_C_STA_LW 1 /* Stack longword. */ #define ETIR_S_C_STA_LW 1 /* Stack longword. */
#define ETIR_S_C_STA_QW 2 /* Stack quadword. */ #define ETIR_S_C_STA_QW 2 /* Stack quadword. */
#define ETIR_S_C_STA_PQ 3 /* Stack psect base plus quadword offset. */ #define ETIR_S_C_STA_PQ 3 /* Stack psect base + quadword off. */
#define ETIR_S_C_STA_LI 4 /* Stack literal. */ #define ETIR_S_C_STA_LI 4 /* Stack literal. */
#define ETIR_S_C_STA_MOD 5 /* Stack module. */ #define ETIR_S_C_STA_MOD 5 /* Stack module. */
#define ETIR_S_C_STA_CKARG 6 /* Check Arguments. */ #define ETIR_S_C_STA_CKARG 6 /* Check Arguments. */
@ -173,7 +178,9 @@
#define ETIR_S_C_STC_NBH_PS 214 /* Store-conditional NOP,BSR or HINT at psect + offset. */ #define ETIR_S_C_STC_NBH_PS 214 /* Store-conditional NOP,BSR or HINT at psect + offset. */
#define ETIR_S_C_MAXSTCCOD 214 /* Maximum store-conditional code. */ #define ETIR_S_C_MAXSTCCOD 214 /* Maximum store-conditional code. */
/* VMS Global symbol definition record (GSD/EGSD). */ #define ETIR_S_C_HEADER_SIZE 4 /* Size of the header of a command */
/* VMS Global Symbol Directory Records (GSD/EGSD). */
#define GSD_S_K_ENTRIES 1 #define GSD_S_K_ENTRIES 1
#define GSD_S_C_ENTRIES 1 #define GSD_S_C_ENTRIES 1
@ -206,6 +213,7 @@
#define EGSD_S_C_SYMG 8 /* EGST - gst version of SYM. */ #define EGSD_S_C_SYMG 8 /* EGST - gst version of SYM. */
#define EGSD_S_C_MAXRECTYP 8 /* Maximum entry type defined. */ #define EGSD_S_C_MAXRECTYP 8 /* Maximum entry type defined. */
/* Program Section Definition. */
#define GPS_S_M_PIC 1 #define GPS_S_M_PIC 1
#define GPS_S_M_LIB 2 #define GPS_S_M_LIB 2
#define GPS_S_M_OVR 4 #define GPS_S_M_OVR 4
@ -219,6 +227,11 @@
#define GPS_S_K_NAME 9 #define GPS_S_K_NAME 9
#define GPS_S_C_NAME 9 #define GPS_S_C_NAME 9
#define EGPS_S_B_ALIGN 4
#define EGPS_S_W_FLAGS 6
#define EGPS_S_L_ALLOC 8
#define EGPS_S_B_NAMLNG 12
#define EGPS_S_V_PIC 0x0001 #define EGPS_S_V_PIC 0x0001
#define EGPS_S_V_LIB 0x0002 #define EGPS_S_V_LIB 0x0002
#define EGPS_S_V_OVR 0x0004 #define EGPS_S_V_OVR 0x0004
@ -231,12 +244,16 @@
#define EGPS_S_V_VEC 0x0200 #define EGPS_S_V_VEC 0x0200
#define EGPS_S_V_NOMOD 0x0400 #define EGPS_S_V_NOMOD 0x0400
#define EGPS_S_V_COM 0x0800 #define EGPS_S_V_COM 0x0800
#define EGPS_S_V_ALLOC_64BIT 0x1000
/* Symbol Defintion or Reference. */
#define GSY_S_M_WEAK 1 #define GSY_S_M_WEAK 1
#define GSY_S_M_DEF 2 #define GSY_S_M_DEF 2
#define GSY_S_M_UNI 4 #define GSY_S_M_UNI 4
#define GSY_S_M_REL 8 #define GSY_S_M_REL 8
#define EGSY_S_W_FLAGS 6
#define EGSY_S_V_WEAK 0x0001 #define EGSY_S_V_WEAK 0x0001
#define EGSY_S_V_DEF 0x0002 #define EGSY_S_V_DEF 0x0002
#define EGSY_S_V_UNI 0x0004 #define EGSY_S_V_UNI 0x0004
@ -244,6 +261,7 @@
#define EGSY_S_V_COMM 0x0010 #define EGSY_S_V_COMM 0x0010
#define EGSY_S_V_VECEP 0x0020 #define EGSY_S_V_VECEP 0x0020
#define EGSY_S_V_NORM 0x0040 #define EGSY_S_V_NORM 0x0040
#define EGSY_S_V_QUAD_VAL 0x0080
#define LSY_S_M_DEF 2 #define LSY_S_M_DEF 2
#define LSY_S_M_REL 8 #define LSY_S_M_REL 8
@ -251,10 +269,26 @@
#define ENV_S_M_DEF 1 #define ENV_S_M_DEF 1
#define ENV_S_M_NESTED 2 #define ENV_S_M_NESTED 2
/* Symbol Definition. */
#define ESDF_S_L_VALUE 8
#define ESDF_S_L_PSINDX 28
#define ESDF_S_B_NAMLNG 32
/* Universal Symbol Definition. */
#define EGST_S_W_FLAGS 6
#define EGST_S_Q_LP_1 16
#define EGST_S_Q_LP_2 24
#define EGST_S_L_PSINDX 32
#define EGST_S_B_NAMLNG 36
/* Symbol Reference. */
#define ESRF_S_B_NAMLNG 8
/* Debugger symbol definitions: These are done by hand, /* Debugger symbol definitions: These are done by hand,
as no machine-readable version seems to be available. */ as no machine-readable version seems to be available. */
#define DST_S_C_C 7 /* Language == "C". */ #define DST_S_C_C 7 /* Language == "C". */
#define DST_S_C_CXX 15 /* Language == "C++". */ #define DST_S_C_CXX 15 /* Language == "C++". */
#define DST_S_C_EPILOG 127
#define DST_S_C_VERSION 153 #define DST_S_C_VERSION 153
#define DST_S_C_SOURCE 155 /* Source file. */ #define DST_S_C_SOURCE 155 /* Source file. */
#define DST_S_C_PROLOG 162 #define DST_S_C_PROLOG 162
@ -269,6 +303,10 @@
#define DST_S_C_MODEND 189 /* End of module. */ #define DST_S_C_MODEND 189 /* End of module. */
#define DST_S_C_RTNBEG 190 /* Beginning of routine.*/ #define DST_S_C_RTNBEG 190 /* Beginning of routine.*/
#define DST_S_C_RTNEND 191 /* End of routine. */ #define DST_S_C_RTNEND 191 /* End of routine. */
/* These are used with DST_S_C_LINE_NUM. */
#define DST_S_C_LINE_NUM_HEADER_SIZE 4
#define DST_S_C_DELTA_PC_W 1 /* Incr PC. */ #define DST_S_C_DELTA_PC_W 1 /* Incr PC. */
#define DST_S_C_INCR_LINUM 2 /* Incr Line #. */ #define DST_S_C_INCR_LINUM 2 /* Incr Line #. */
#define DST_S_C_INCR_LINUM_W 3 /* Incr Line #. */ #define DST_S_C_INCR_LINUM_W 3 /* Incr Line #. */
@ -295,9 +333,32 @@
#define DST_S_C_SRC_SETFILE 2 /* Set source file. */ #define DST_S_C_SRC_SETFILE 2 /* Set source file. */
#define DST_S_C_SRC_SETREC_L 3 /* Set record, longword value. */ #define DST_S_C_SRC_SETREC_L 3 /* Set record, longword value. */
#define DST_S_C_SRC_SETREC_W 4 /* Set record, word value. */ #define DST_S_C_SRC_SETREC_W 4 /* Set record, word value. */
#define DST_S_C_SRC_SETLNUM_L 5 /* Set line, longword value. */
#define DST_S_C_SRC_SETLNUM_W 6 /* Set line, word value. */
#define DST_S_C_SRC_INCRLNUM_B 7 /* Increment line. */
#define DST_S_C_SRC_DEFLINES_W 10 /* # of line, word counter. */ #define DST_S_C_SRC_DEFLINES_W 10 /* # of line, word counter. */
#define DST_S_C_SRC_DEFLINES_B 11 /* # of line, byte counter. */ #define DST_S_C_SRC_DEFLINES_B 11 /* # of line, byte counter. */
#define DST_S_C_SRC_FORMFEED 16 /* ^L counts as a record. */ #define DST_S_C_SRC_FORMFEED 16 /* ^L counts as a record. */
#define DST_S_B_PCLINE_UNSBYTE 1
#define DST_S_W_PCLINE_UNSWORD 1
#define DST_S_L_PCLINE_UNSLONG 1
#define DST_S_B_MODBEG_NAME 14
#define DST_S_L_RTNBEG_ADDRESS 5
#define DST_S_B_RTNBEG_NAME 13
#define DST_S_L_RTNEND_SIZE 5
/* These are used with DST_S_C_SOURCE. */
#define DST_S_C_SOURCE_HEADER_SIZE 4
#define DST_S_B_SRC_DF_LENGTH 1
#define DST_S_W_SRC_DF_FILEID 3
#define DST_S_B_SRC_DF_FILENAME 20
#define DST_S_B_SRC_UNSBYTE 1
#define DST_S_W_SRC_UNSWORD 1
#define DST_S_L_SRC_UNSLONG 1
/* The following are the codes for the various data types. Anything not on /* The following are the codes for the various data types. Anything not on
the list is included under 'advanced_type'. */ the list is included under 'advanced_type'. */
#define DBG_S_C_UCHAR 0x02 #define DBG_S_C_UCHAR 0x02
@ -328,6 +389,7 @@
#define DSC_K_CLASS_D 0x02 /* Dynamic string (not via malloc!). */ #define DSC_K_CLASS_D 0x02 /* Dynamic string (not via malloc!). */
#define DSC_K_CLASS_A 0x04 /* Array. */ #define DSC_K_CLASS_A 0x04 /* Array. */
#define DSC_K_CLASS_UBS 0x0d /* Unaligned bit string. */ #define DSC_K_CLASS_UBS 0x0d /* Unaligned bit string. */
/* These are the codes that are used to generate the definitions of struct /* These are the codes that are used to generate the definitions of struct
union and enum records. */ union and enum records. */
#define DBG_S_C_ENUM_ITEM 0xa4 #define DBG_S_C_ENUM_ITEM 0xa4
@ -379,7 +441,7 @@
#define DBG_S_C_VOID DST_K_TS_PTR #define DBG_S_C_VOID DST_K_TS_PTR
#define DBG_S_C_COMPLEX_ARRAY DST_K_TS_ARRAY #define DBG_S_C_COMPLEX_ARRAY DST_K_TS_ARRAY
/* VMS Module header record (EMH) definitions. */ /* VMS Module Header Records (MHD/EMH). */
#define MHD_S_C_MHD 0 #define MHD_S_C_MHD 0
#define MHD_S_C_LNM 1 #define MHD_S_C_LNM 1
@ -402,31 +464,47 @@
/* vms.c. */ /* vms.c. */
extern asymbol *_bfd_vms_make_empty_symbol (bfd *); extern asymbol *_bfd_vms_make_empty_symbol (bfd *);
extern int _bfd_vms_slurp_object_records (bfd *abfd);
/* vms-gsd.c. */ /* vms-gsd.c. */
extern int _bfd_vms_slurp_gsd (bfd *, int); extern int _bfd_vms_slurp_gsd (bfd *abfd, int objtype);
extern int _bfd_vms_write_gsd (bfd *, int); extern int _bfd_vms_write_gsd (bfd *abfd, int objtype);
extern int _bfd_vms_slurp_dbg (bfd *abfd, int objtype);
extern int _bfd_vms_write_dbg (bfd *abfd, int objtype);
extern int _bfd_vms_slurp_tbt (bfd *abfd, int objtype);
extern int _bfd_vms_write_tbt (bfd *abfd, int objtype);
/* vms-mhd.c. */ /* vms-misc.c. */
extern int _bfd_vms_slurp_hdr (bfd *, int); extern int _bfd_vms_get_object_record (bfd *abfd);
extern int _bfd_vms_write_hdr (bfd *, int); extern int _bfd_vms_get_first_record (bfd *abfd);
extern int _bfd_vms_slurp_eom (bfd *, int);
extern int _bfd_vms_write_eom (bfd *, int); /* vms-hdr.c. */
extern int _bfd_vms_slurp_hdr (bfd *abfd, int objtype);
extern int _bfd_vms_write_hdr (bfd *abfd, int objtype);
extern int _bfd_vms_slurp_eom (bfd *abfd, int objtype);
extern int _bfd_vms_write_eom (bfd *abfd, int objtype);
extern bfd_boolean _bfd_vms_find_nearest_dst_line
(bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset,
const char **file, const char **func, unsigned int *line);
extern int _bfd_vms_slurp_ihd
(bfd *abfd, unsigned int *isd_offset, unsigned int *ihs_offset);
extern int _bfd_vms_slurp_isd (bfd *abfd, unsigned int offset);
extern int _bfd_vms_slurp_ihs (bfd *abfd, unsigned int offset);
/* vms-tir.c. */ /* vms-tir.c. */
extern int _bfd_vms_slurp_tir (bfd *, int); extern int _bfd_vms_slurp_tir (bfd *abfd, int objtype);
extern int _bfd_vms_slurp_dbg (bfd *, int); extern int _bfd_vms_write_tir (bfd *abfd, int objtype);
extern int _bfd_vms_slurp_tbt (bfd *, int); extern int _bfd_vms_slurp_lnk (bfd *abfd, int objtype);
extern int _bfd_vms_slurp_lnk (bfd *, int);
extern int _bfd_vms_write_tir (bfd *, int); extern int _bfd_vms_slurp_relocs (bfd *abfd);
extern int _bfd_vms_write_tbt (bfd *, int); extern int _bfd_vms_decode_relocs
extern int _bfd_vms_write_dbg (bfd *, int); (bfd *abfd, arelent *relocs, asection *section, asymbol **symbols);
/* The r_type field in a reloc is one of he following values. */ /* The r_type field in a reloc is one of the following values. */
#define ALPHA_R_IGNORE 0 #define ALPHA_R_IGNORE 0
#define ALPHA_R_REFQUAD 1 #define ALPHA_R_REFQUAD 1
#define ALPHA_R_BRADDR 2 #define ALPHA_R_BRADDR 2
@ -441,8 +519,12 @@ extern int _bfd_vms_write_dbg (bfd *, int);
#define ALPHA_R_LINKAGE 11 #define ALPHA_R_LINKAGE 11
#define ALPHA_R_REFLONG 12 #define ALPHA_R_REFLONG 12
#define ALPHA_R_CODEADDR 13 #define ALPHA_R_CODEADDR 13
#define ALPHA_R_NOP 14
#define ALPHA_R_BSR 15
#define ALPHA_R_LDA 16
#define ALPHA_R_BOH 17
/* Object language definitions. */ /* VMS Object Language (OBJ/EOBJ). */
#define OBJ_S_C_HDR 0 /* VAX moule header record. */ #define OBJ_S_C_HDR 0 /* VAX moule header record. */
#define OBJ_S_C_GSD 1 /* VAX glbal symbol definition record. */ #define OBJ_S_C_GSD 1 /* VAX glbal symbol definition record. */
@ -453,6 +535,7 @@ extern int _bfd_vms_write_dbg (bfd *, int);
#define OBJ_S_C_LNK 6 /* VAX liker options record. */ #define OBJ_S_C_LNK 6 /* VAX liker options record. */
#define OBJ_S_C_EOMW 7 /* VAX en of module word-psect record. */ #define OBJ_S_C_EOMW 7 /* VAX en of module word-psect record. */
#define OBJ_S_C_MAXRECTYP 7 /* VAX Lat assigned record type. */ #define OBJ_S_C_MAXRECTYP 7 /* VAX Lat assigned record type. */
#define EOBJ_S_C_EMH 8 /* EVAX mdule header record. */ #define EOBJ_S_C_EMH 8 /* EVAX mdule header record. */
#define EOBJ_S_C_EEOM 9 /* EVAX ed of module record. */ #define EOBJ_S_C_EEOM 9 /* EVAX ed of module record. */
#define EOBJ_S_C_EGSD 10 /* EVAX gobal symbol definition record. */ #define EOBJ_S_C_EGSD 10 /* EVAX gobal symbol definition record. */
@ -460,6 +543,7 @@ extern int _bfd_vms_write_dbg (bfd *, int);
#define EOBJ_S_C_EDBG 12 /* EVAX Dbugger information record. */ #define EOBJ_S_C_EDBG 12 /* EVAX Dbugger information record. */
#define EOBJ_S_C_ETBT 13 /* EVAX Taceback information record. */ #define EOBJ_S_C_ETBT 13 /* EVAX Taceback information record. */
#define EOBJ_S_C_MAXRECTYP 13 /* EVAX Lst assigned record type. */ #define EOBJ_S_C_MAXRECTYP 13 /* EVAX Lst assigned record type. */
#define OBJ_S_K_SUBTYP 1 #define OBJ_S_K_SUBTYP 1
#define OBJ_S_C_SUBTYP 1 #define OBJ_S_C_SUBTYP 1
#define EOBJ_S_K_SUBTYP 4 #define EOBJ_S_K_SUBTYP 4
@ -477,6 +561,7 @@ extern int _bfd_vms_write_dbg (bfd *, int);
#define EOBJ_S_C_PSCALILIM 16 /* Maximu p-sect alignment. */ #define EOBJ_S_C_PSCALILIM 16 /* Maximu p-sect alignment. */
#define EVAX_OFFSET 256 /* Type ofset for EVAX codes in switch. */ #define EVAX_OFFSET 256 /* Type ofset for EVAX codes in switch. */
/* Miscellaneous definitions. */ /* Miscellaneous definitions. */
#if __GNUC__ #if __GNUC__
@ -488,52 +573,112 @@ typedef unsigned long uquad;
#define MAX_OUTREC_SIZE 4096 #define MAX_OUTREC_SIZE 4096
#define MIN_OUTREC_LUFT 64 #define MIN_OUTREC_LUFT 64
typedef struct _vms_section
{
unsigned char *contents;
bfd_vma offset;
bfd_size_type size;
struct _vms_section *next;
} vms_section;
extern vms_section * _bfd_get_vms_section (bfd *, int);
typedef struct _vms_reloc
{
struct _vms_reloc *next;
arelent *reloc;
asection *section;
} vms_reloc;
/* VMS module header. */ /* VMS module header. */
struct hdr_struc struct hdr_struct
{ {
int hdr_b_strlvl; char hdr_b_strlvl;
long hdr_l_arch1; int hdr_l_arch1;
long hdr_l_arch2; int hdr_l_arch2;
long hdr_l_recsiz; int hdr_l_recsiz;
char *hdr_t_name; char *hdr_t_name;
char *hdr_t_version; char *hdr_t_version;
char *hdr_t_date; char *hdr_t_date;
char *hdr_c_lnm; char *hdr_c_lnm;
char *hdr_c_src; char *hdr_c_src;
char *hdr_c_ttl; char *hdr_c_ttl;
char *hdr_c_cpr;
}; };
/* VMS end of module. */ #define EMH_S_W_HDRTYP 4
#define EMH_S_B_STRLVL 6
#define EMH_S_L_ARCH1 8
#define EMH_S_L_ARCH2 12
#define EH_S_L_RECSIZ 16
#define EMH_S_B_NAMLNG 20
struct eom_struc #define EMH_DATE_LENGTH 17
/* VMS End-Of-Module records (EOM/EEOM). */
struct eom_struct
{ {
long eom_l_total_lps; int eom_l_total_lps;
unsigned char eom_b_comcod; short eom_w_comcod;
bfd_boolean eom_has_transfer; bfd_boolean eom_has_transfer;
unsigned char eom_b_tfrflg; char eom_b_tfrflg;
long eom_l_psindx; int eom_l_psindx;
long eom_l_tfradr; int eom_l_tfradr;
}; };
enum file_format_enum { FF_UNKNOWN, FF_FOREIGN, FF_NATIVE, FF_VAX }; #define EEOM_S_L_TOTAL_LPS 4
#define EEOM_S_W_COMCOD 8
#define EEOM_S_B_TFRFLG 10
#define EEOM_S_L_PSINDX 12
#define EEOM_S_L_TFRADR 16
/* VMS Image Header Records (IHD/EIHD). */
#define EIHD_S_K_MAJORID 3 /* Major id constant */
#define EIHD_S_K_MINORID 0 /* Minor id constant */
#define EIHD_S_K_EXE 1 /* Executable image */
#define EIHD_S_L_SIZE 8
#define EIHD_S_L_ISDOFF 12
#define EIHD_S_L_SYMDBGOFF 20
#define EIHD_S_Q_SYMVVA 40
#define EIHD_S_L_IMGTYPE 52
/* VMS Image Section Description Records (ISD/EISD). */
#define EISD_S_L_EISDSIZE 8
#define EISD_S_L_SECSIZE 12
#define EISD_S_Q_VIR_ADDR 16
#define EISD_S_L_FLAGS 24
#define EISD_S_L_VBN 28
#define EISD_S_R_CONTROL 32
#define EISD_S_L_IDENT 36
#define EISD_S_T_GBLNAM 40
#define EISD_S_M_GBL 0x0001
#define EISD_S_M_CRF 0x0002
#define EISD_S_M_DZRO 0x0004
#define EISD_S_M_WRT 0x0008
#define EISD_S_M_INITALCODE 0x0010
#define EISD_S_M_BASED 0x0020
#define EISD_S_M_FIXUPVEC 0x0040
#define EISD_S_M_RESIDENT 0x0080
#define EISD_S_M_VECTOR 0x0100
#define EISD_S_M_PROTECT 0x0200
#define EISD_S_M_LASTCLU 0x0400
#define EISD_S_M_EXE 0x0800
#define EISD_S_M_NONSHRADR 0x1000
#define EISD_S_M_QUAD_LENGTH 0x2000
#define EISD_S_M_ALLOC_64BIT 0x4000
/* VMS Image Header Symbol Records (IHS/EIHS). */
#define EIHS_S_L_DSTVBN 8
#define EIHS_S_L_DSTSIZE 12
#define EIHS_S_L_GSTVBN 16
#define EIHS_S_L_GSTSIZE 20
#define EIHS_S_L_DMTVBN 24
#define EIHS_S_L_DMTBYTES 28
/* Debugger symbol definitions. */
#define DBG_S_L_DMT_MODBEG 0
#define DBG_S_L_DST_SIZE 4
#define DBG_S_W_DMT_PSECT_COUNT 8
#define DBG_S_C_DMT_HEADER_SIZE 12
#define DBG_S_L_DMT_PSECT_START 0
#define DBG_S_L_DMT_PSECT_LENGTH 4
#define DBG_S_C_DMT_PSECT_SIZE 8
enum file_format_enum { FF_UNKNOWN, FF_FOREIGN, FF_NATIVE };
enum file_type_enum { FT_UNKNOWN, FT_MODULE, FT_IMAGE };
typedef struct vms_symbol_struct typedef struct vms_symbol_struct
{ {
@ -548,18 +693,73 @@ struct stack_struct
uquad value; uquad value;
int psect; int psect;
}; };
#define STACKSIZE 8192 #define STACKSIZE 8192
/* location stack definitions for CTL_DFLC, CTL_STLOC, and CTL_STKDL */ /* A minimal decoding of DST compilation units. We only decode
what's needed to get to the line number information. */
struct location_struct struct fileinfo
{ {
unsigned long value; char *name;
int psect; unsigned int srec;
}; };
#define LOCATION_SAVE_SIZE 32
#define VMS_SECTION_COUNT 1024 struct srecinfo
{
struct srecinfo *next;
unsigned int line;
unsigned int sfile;
unsigned int srec;
};
struct lineinfo
{
struct lineinfo *next;
bfd_vma address;
unsigned int line;
};
struct funcinfo
{
struct funcinfo *next;
char *name;
bfd_vma low;
bfd_vma high;
};
struct module
{
/* Chain the previously read compilation unit. */
struct module *next;
/* The module name. */
char *name;
/* The start offset and size of debug info in the DST section. */
unsigned int modbeg;
unsigned int size;
/* The lowest and highest addresses contained in this compilation
unit as specified in the compilation unit header. */
bfd_vma low;
bfd_vma high;
/* The listing line table. */
struct lineinfo *line_table;
/* The source record table. */
struct srecinfo *srec_table;
/* A list of the functions found in this module. */
struct funcinfo *func_table;
/* Current allocation of file_table. */
unsigned int file_table_count;
/* An array of the files making up this module. */
struct fileinfo *file_table;
};
struct vms_private_data_struct struct vms_private_data_struct
{ {
@ -567,57 +767,88 @@ struct vms_private_data_struct
bfd_boolean fixup_done; /* Flag to indicate if all bfd_boolean fixup_done; /* Flag to indicate if all
section pointers and PRIV(sections) section pointers and PRIV(sections)
are set up correctly. */ are set up correctly. */
unsigned char *vms_buf; /* Buffer to record. */ unsigned char *vms_buf; /* record buffer */
int buf_size; /* Max size of buffer. */ unsigned int buf_size; /* size of record buffer */
unsigned char *vms_rec; /* Actual record ptr. */ unsigned char *vms_rec; /* record pointer in record buffer */
int rec_length; /* Remaining record length. */ unsigned int rec_size; /* record size */
int rec_size; /* Actual record size. */
int rec_type; /* Actual record type. */
enum file_format_enum file_format; enum file_format_enum file_format;
struct hdr_struc hdr_data; /* Data from HDR/EMH record. */ struct hdr_struct hdr_data; /* data from HDR/EMH record */
struct eom_struc eom_data; /* Data from EOM/EEOM record. */ struct eom_struct eom_data; /* data from EOM/EEOM record */
unsigned int section_count; /* # of sections in following array. */ unsigned int section_count; /* # of sections in following array */
asection **sections; /* Array of GSD/EGSD sections. */ asection **sections; /* array of GSD/EGSD sections */
int gsd_sym_count; /* # of GSD/EGSD symbols. */ unsigned int gsd_sym_count; /* # of GSD/EGSD symbols */
asymbol **symbols; /* Vector of GSD/EGSD symbols. */ asymbol **symbols; /* vector of GSD/EGSD symbols */
struct proc_value *procedure; struct proc_value *procedure;
struct stack_struct *stack; struct stack_struct *stack;
int stackptr; int stackptr;
vms_section *vms_section_table[VMS_SECTION_COUNT];
struct bfd_hash_table *vms_symbol_table; struct bfd_hash_table *vms_symbol_table;
struct bfd_symbol **symcache; struct bfd_symbol **symcache;
int symnum; int symnum;
struct location_struct *location_stack; asection *image_section; /* section for image_ptr */
unsigned char *image_ptr; /* a pointer to section->contents */
asection *image_section; /* Section for image_ptr. */ unsigned char pdsc[8]; /* procedure descriptor */
unsigned char *image_ptr; /* A pointer to section->contents. */
unsigned char pdsc[8]; /* Procedure descriptor. */ struct module *modules; /* list of all compilation units */
/* Output routine storage. */ struct dst_info *dst_info;
unsigned char *output_buf; /* Output data. */ asection *dst_section;
unsigned char *dst_ptr_end;
unsigned int dst_ptr_offsets_count; /* # of offsets in following array */
unsigned int *dst_ptr_offsets; /* array of saved image_ptr offsets */
/* Shared library support */
bfd_vma symvva; /* relative virtual address of symbol vector */
/* Output routine storage */
unsigned char *output_buf; /* output data */
int push_level; int push_level;
int pushed_size; int pushed_size;
int length_pos; int length_pos;
int output_size; int output_size;
int output_alignment; int output_alignment;
/* Linkage index counter /* linkage index counter used by conditional store commands */
used by conditional store commands (TIR_S_C_STC_). */
int vms_linkage_index; int vms_linkage_index;
/* see tc-alpha.c of gas for a descripton. */ /* see tc-alpha.c of gas for a description. */
int flag_hash_long_names; /* -+, hash instead of truncate. */ int flag_hash_long_names; /* -+, hash instead of truncate */
int flag_show_after_trunc; /* -H, shw hashing/truncation. */ int flag_show_after_trunc; /* -H, show hashing/truncation */
}; };
#define PRIV(name) ((struct vms_private_data_struct *)abfd->tdata.any)->name #define PRIV(name) ((struct vms_private_data_struct *)abfd->tdata.any)->name
/* Used to keep extra VMS specific information for a given section.
reloc_size holds the size of the relocation stream, note this
is very different from the number of relocations as VMS relocations
are variable length.
reloc_stream is the actual stream of relocation entries. */
struct vms_section_data_struct
{
bfd_size_type reloc_size;
unsigned char *reloc_stream;
bfd_size_type reloc_offset;
flagword vflags;
};
#define vms_section_data(sec) \
((struct vms_section_data_struct *)sec->used_by_bfd)
struct evax_private_udata_struct
{
asymbol *bsym;
asymbol *enbsym;
char *origname;
int lkindex;
};
#define SECTION_NAME_TEMPLATE "__SEC__%d" #define SECTION_NAME_TEMPLATE "__SEC__%d"
#if VMS_DEBUG #if VMS_DEBUG
@ -635,7 +866,6 @@ extern char * _bfd_vms_save_sized_string (unsigned char *, int);
extern char * _bfd_vms_save_counted_string (unsigned char *); extern char * _bfd_vms_save_counted_string (unsigned char *);
extern void _bfd_vms_push (bfd *, uquad, int); extern void _bfd_vms_push (bfd *, uquad, int);
extern uquad _bfd_vms_pop (bfd *, int *); extern uquad _bfd_vms_pop (bfd *, int *);
extern bfd_boolean _bfd_save_vms_section (bfd *, asection *, const void *, file_ptr, bfd_size_type);
extern void _bfd_vms_output_begin (bfd *, int, int); extern void _bfd_vms_output_begin (bfd *, int, int);
extern void _bfd_vms_output_alignment (bfd *, int); extern void _bfd_vms_output_alignment (bfd *, int);
extern void _bfd_vms_output_push (bfd *); extern void _bfd_vms_output_push (bfd *);
@ -653,4 +883,7 @@ extern void _bfd_vms_output_fill (bfd *, int, int);
extern char * _bfd_vms_length_hash_symbol (bfd *, const char *, int); extern char * _bfd_vms_length_hash_symbol (bfd *, const char *, int);
extern vms_symbol_entry * _bfd_vms_enter_symbol (bfd *, char *); extern vms_symbol_entry * _bfd_vms_enter_symbol (bfd *, char *);
#define EGPS_S_V_NO_SHIFT 16
extern void bfd_vms_set_section_flags (bfd *, asection *, flagword);
#endif /* VMS_H */ #endif /* VMS_H */