[Patch] update of the alpha vms bfd back-end
Tristan Gingold
gingold@adacore.com
Tue Feb 17 11:22:00 GMT 2009
Hi,
at AdaCore we have used binutils for Alpha VMS for a long time and we have
patches in our own tree to fix issues and add features.
This first large patch updates the bfd back-end. It mostly add support for
handling relocation and debug informations.
Most of the patch only modified vms-* files but it only adds relocations to
reloc.c and modify VMS specific code in bfdio.c
Tristan.
bfd/
2009-02-17 Tristan Gingold <gingold@adacore.com>
Eric Botcazou <ebotcazou@adacore.com>
Douglas B Rupp <rupp@gnat.com>
Major update of alpha vms back-end.
* 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.
-------------- next part --------------
bfd/
2009-02-17 Tristan Gingold <gingold@adacore.com>
Eric Botcazou <ebotcazou@adacore.com>
Douglas B Rupp <rupp@gnat.com>
Major update of alpha vms back-end.
* 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.
Index: bfd/bfdio.c
===================================================================
RCS file: /cvs/src/src/bfd/bfdio.c,v
retrieving revision 1.19
diff -c -r1.19 bfdio.c
*** bfd/bfdio.c 14 Nov 2008 09:57:33 -0000 1.19
--- bfd/bfdio.c 17 Feb 2009 11:13:08 -0000
***************
*** 102,114 ****
}
else
{
! /* Attribute found - rebuild modes. */
! size_t modes_len = vms_attr - modes;
!
! BFD_ASSERT (modes_len < sizeof (vms_modes));
! memcpy (vms_modes, modes, modes_len);
! vms_modes[modes_len] = 0;
! return close_on_exec (fopen (filename, vms_modes, vms_attr + 1));
}
#else /* !VMS */
#if defined (HAVE_FOPEN64)
--- 102,122 ----
}
else
{
! /* Attributes found. Split. */
! size_t modes_len = strlen (modes) + 1;
! char attrs[modes_len + 1];
! char *at[3];
! int i;
!
! memcpy (attrs, modes, modes_len);
! at[0] = attrs;
! for (i = 0; i < 2; i++)
! {
! 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 */
#if defined (HAVE_FOPEN64)
Index: bfd/makefile.vms
===================================================================
RCS file: /cvs/src/src/bfd/makefile.vms,v
retrieving revision 1.2
diff -c -r1.2 makefile.vms
*** bfd/makefile.vms 14 Nov 2008 09:57:33 -0000 1.2
--- bfd/makefile.vms 17 Feb 2009 11:13:09 -0000
***************
*** 36,48 ****
CFLAGS=/include=([],[-.include])$(DEFS)
else
ifeq ($(ARCH),ALPHA)
! DEFS=/define=(SELECT_VECS="&vms_alpha_vec",SELECT_ARCHITECTURES="&bfd_alpha_arch",\
! "HAVE_vms_alpha_vec=1","unlink=remove","DEBUGDIR=NULL")
else
DEFS=/define=(SELECT_VECS="&vms_vax_vec",SELECT_ARCHITECTURES="&bfd_vax_arch",\
! "HAVE_vms_vax_vec=1","unlink=remove","const=")
endif
! CFLAGS=/noopt/debug/show=incl/name=(as_is,shortened)/include=([],[-.include])$(DEFS)/warnings=disable=(missingreturn,longextern)
endif
--- 36,50 ----
CFLAGS=/include=([],[-.include])$(DEFS)
else
ifeq ($(ARCH),ALPHA)
! DEFS=/define=(SELECT_VECS="&vms_alpha_vec",\
! SELECT_ARCHITECTURES="&bfd_alpha_arch",\
! "HAVE_vms_alpha_vec=1","unlink=remove","DEBUGDIR=NULL")
else
DEFS=/define=(SELECT_VECS="&vms_vax_vec",SELECT_ARCHITECTURES="&bfd_vax_arch",\
! "HAVE_vms_vax_vec=1","unlink=remove")
endif
! OPT=/noopt/debug
! CFLAGS=/name=(as_is,shortened)/include=([],[-.include])$(DEFS)$(OPT)
endif
Index: bfd/reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.182
diff -c -r1.182 reloc.c
*** bfd/reloc.c 3 Feb 2009 14:36:46 -0000 1.182
--- bfd/reloc.c 17 Feb 2009 11:13:09 -0000
***************
*** 2110,2115 ****
--- 2110,2139 ----
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
BFD_RELOC_ALPHA_TLSGD
ENUMX
BFD_RELOC_ALPHA_TLSLDM
Index: bfd/vms-gsd.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-gsd.c,v
retrieving revision 1.21
diff -c -r1.21 vms-gsd.c
*** bfd/vms-gsd.c 3 Jul 2007 14:26:42 -0000 1.21
--- bfd/vms-gsd.c 17 Feb 2009 11:13:09 -0000
***************
*** 1,9 ****
/* 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.
! 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)
--- 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, 2009 Free Software Foundation, Inc.
! 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,51 ****
--- 49,55 ----
#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,138 ****
--- 137,147 ----
(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,202 ****
--- 206,242 ----
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,266 ****
/* Input routines. */
/* 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;
--- 264,278 ----
/* 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)
{
int gsd_type, gsd_size;
asection *section;
unsigned char *vms_rec;
***************
*** 300,306 ****
vms_rec = PRIV (vms_rec);
if (objtype == OBJ_S_C_GSD)
! gsd_type = *vms_rec;
else
{
_bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size);
--- 312,318 ----
vms_rec = PRIV (vms_rec);
if (objtype == OBJ_S_C_GSD)
! gsd_type = vms_rec[0];
else
{
_bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size);
***************
*** 322,328 ****
vms_debug (4, "GSD_S_C_PSC\n");
#endif
/* If this section isn't a bfd section. */
! if (PRIV (is_vax) && (psect_idx < (abfd->section_count-1)))
{
/* Check for temporary section from TIR record. */
if (psect_idx < PRIV (section_count))
--- 334,340 ----
vms_debug (4, "GSD_S_C_PSC\n");
#endif
/* If this section isn't a bfd section. */
! if (PRIV (is_vax) && (psect_idx < (abfd->section_count - 1)))
{
/* Check for temporary section from TIR record. */
if (psect_idx < PRIV (section_count))
***************
*** 362,368 ****
base_addr += section->size;
/* Global section is common symbol. */
-
if (old_flags & GPS_S_M_GBL)
{
entry = _bfd_vms_enter_symbol (abfd, name);
--- 374,379 ----
***************
*** 496,516 ****
else
psect = vms_rec[value_offset-1];
! symbol->section = (asection *) (size_t) psect;
#if VMS_DEBUG
! vms_debug (4, "gsd sym def #%d (%s, %d [%p], %04x=%s)\n", abfd->symcount,
! symbol->name, (int)symbol->section, symbol->section, old_flags, flag2str (gsyflagdesc, old_flags));
#endif
}
else
{
/* Symbol reference. */
- symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
#if VMS_DEBUG
! vms_debug (4, "gsd sym ref #%d (%s, %s [%p], %04x=%s)\n",
! abfd->symcount, symbol->name, symbol->section->name,
! symbol->section, old_flags, flag2str (gsyflagdesc, old_flags));
#endif
}
gsd_size = vms_rec[name_offset] + name_offset + 1;
--- 507,526 ----
else
psect = vms_rec[value_offset-1];
! symbol->section = (asection *)(unsigned long)psect;
#if VMS_DEBUG
! vms_debug (4, "gsd sym def #%d (%s, %ld, %04x=%s)\n", abfd->symcount,
! symbol->name, (long)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
#endif
}
else
{
/* Symbol reference. */
#if VMS_DEBUG
! vms_debug (4, "gsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount,
! symbol->name, old_flags, flag2str (gsyflagdesc, old_flags));
#endif
+ symbol->section = (asection *)(unsigned long)-1;
}
gsd_size = vms_rec[name_offset] + name_offset + 1;
***************
*** 574,592 ****
case EGSD_S_C_PSC + EVAX_OFFSET:
{
/* Program section definition. */
! name = _bfd_vms_save_counted_string (vms_rec + 12);
section = bfd_make_section (abfd, name);
if (!section)
return -1;
! old_flags = bfd_getl16 (vms_rec + 6);
! section->size = bfd_getl32 (vms_rec + 8); /* Allocation. */
new_flags = vms_secflag_by_name (abfd, evax_section_flags, name,
section->size > 0);
if (old_flags & EGPS_S_V_REL)
new_flags |= SEC_RELOC;
if (!bfd_set_section_flags (abfd, section, new_flags))
return -1;
! section->alignment_power = vms_rec[4];
align_addr = (1 << section->alignment_power);
if ((base_addr % align_addr) != 0)
base_addr += (align_addr - (base_addr % align_addr));
--- 584,602 ----
case EGSD_S_C_PSC + EVAX_OFFSET:
{
/* Program section definition. */
! name = _bfd_vms_save_counted_string (vms_rec + EGPS_S_B_NAMLNG);
section = bfd_make_section (abfd, name);
if (!section)
return -1;
! old_flags = bfd_getl16 (vms_rec + EGPS_S_W_FLAGS);
! section->size = bfd_getl32 (vms_rec + EGPS_S_L_ALLOC);
new_flags = vms_secflag_by_name (abfd, evax_section_flags, name,
section->size > 0);
if (old_flags & EGPS_S_V_REL)
new_flags |= SEC_RELOC;
if (!bfd_set_section_flags (abfd, section, new_flags))
return -1;
! section->alignment_power = vms_rec[EGPS_S_B_ALIGN];
align_addr = (1 << section->alignment_power);
if ((base_addr % align_addr) != 0)
base_addr += (align_addr - (base_addr % align_addr));
***************
*** 595,603 ****
section->contents = bfd_zmalloc (section->size);
if (section->contents == NULL)
return -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, "%d bytes at 0x%08lx (mem %p)\n",
section->size, section->vma, section->contents);
#endif
--- 605,614 ----
section->contents = bfd_zmalloc (section->size);
if (section->contents == NULL)
return -1;
+ section->filepos = (unsigned int)-1;
#if VMS_DEBUG
! vms_debug (4, "EGSD P-section %d (%s, flags %04x=%s) ",
! section->index, name, old_flags, flag2str(gpsflagdesc, old_flags));
vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n",
section->size, section->vma, section->contents);
#endif
***************
*** 606,655 ****
case EGSD_S_C_SYM + EVAX_OFFSET:
{
! /* Symbol specification (definition or reference). */
symbol = bfd_make_empty_symbol (abfd);
if (symbol == 0)
return -1;
! old_flags = bfd_getl16 (vms_rec + 6);
new_flags = BSF_NO_FLAGS;
if (old_flags & EGSY_S_V_WEAK)
new_flags |= BSF_WEAK;
! if (vms_rec[6] & EGSY_S_V_DEF)
{
/* Symbol definition. */
- symbol->name = _bfd_vms_save_counted_string (vms_rec + 32);
if (old_flags & EGSY_S_V_NORM)
- /* Proc def. */
new_flags |= BSF_FUNCTION;
!
! symbol->value = bfd_getl64 (vms_rec + 8);
! symbol->section = (asection *) ((unsigned long) bfd_getl32 (vms_rec + 28));
! #if VMS_DEBUG
! vms_debug (4, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount,
! symbol->name, (int) symbol->section, old_flags,
! flag2str (gsyflagdesc, old_flags));
#endif
}
else
{
/* Symbol reference. */
! symbol->name = _bfd_vms_save_counted_string (vms_rec + 8);
#if VMS_DEBUG
! vms_debug (4, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount,
! symbol->name, old_flags, flag2str (gsyflagdesc, old_flags));
#endif
! symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
}
symbol->flags = new_flags;
! /* Save symbol in vms_symbol_table. */
! entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
! symbol->name,
! TRUE, FALSE);
if (entry == NULL)
{
bfd_set_error (bfd_error_no_memory);
--- 617,668 ----
case EGSD_S_C_SYM + EVAX_OFFSET:
{
! /* Global symbol specification (definition or reference). */
symbol = bfd_make_empty_symbol (abfd);
if (symbol == 0)
return -1;
! old_flags = bfd_getl16 (vms_rec + EGSY_S_W_FLAGS);
new_flags = BSF_NO_FLAGS;
if (old_flags & EGSY_S_V_WEAK)
new_flags |= BSF_WEAK;
! if (old_flags & EGSY_S_V_DEF)
{
/* Symbol definition. */
if (old_flags & EGSY_S_V_NORM)
new_flags |= BSF_FUNCTION;
! symbol->name =
! _bfd_vms_save_counted_string (vms_rec + ESDF_S_B_NAMLNG);
! symbol->value = bfd_getl64 (vms_rec + ESDF_S_L_VALUE);
! symbol->section =
! (asection *)(unsigned long) bfd_getl32 (vms_rec + ESDF_S_L_PSINDX);
! #if VMS_DEBUG
! vms_debug (4, "EGSD sym def #%d (%s, %ld, %04x=%s)\n",
! abfd->symcount, symbol->name, (long)symbol->section,
! old_flags, flag2str (gsyflagdesc, old_flags));
#endif
}
else
{
/* Symbol reference. */
! symbol->name =
! _bfd_vms_save_counted_string (vms_rec + ESRF_S_B_NAMLNG);
#if VMS_DEBUG
! vms_debug (4, "EGSD sym ref #%d (%s, %04x=%s)\n",
! abfd->symcount, symbol->name, old_flags,
! flag2str (gsyflagdesc, old_flags));
#endif
! symbol->section = (asection *)(unsigned long)-1;
}
symbol->flags = new_flags;
! /* Register symbol in VMS symbol table. */
! entry = (vms_symbol_entry *) bfd_hash_lookup
! (PRIV (vms_symbol_table), symbol->name, TRUE, FALSE);
!
if (entry == NULL)
{
bfd_set_error (bfd_error_no_memory);
***************
*** 672,682 ****
}
break;
! case EGSD_S_C_IDC + EVAX_OFFSET:
break;
default:
! (*_bfd_error_handler) (_("unknown gsd/egsd subtype %d"), gsd_type);
bfd_set_error (bfd_error_bad_value);
return -1;
}
--- 685,757 ----
}
break;
! case EGSD_S_C_SYMG + EVAX_OFFSET:
! {
! /* Universal symbol specification (definition). */
! symbol = bfd_make_empty_symbol (abfd);
! if (symbol == 0)
! return -1;
!
! old_flags = bfd_getl16 (vms_rec + EGST_S_W_FLAGS);
! new_flags = BSF_NO_FLAGS;
!
! if (old_flags & EGSY_S_V_WEAK)
! new_flags |= BSF_WEAK;
!
! if (old_flags & EGSY_S_V_DEF) /* symbol definition */
! {
! if (old_flags & EGSY_S_V_NORM)
! new_flags |= BSF_FUNCTION;
!
! symbol->name =
! _bfd_vms_save_counted_string (vms_rec + EGST_S_B_NAMLNG);
!
! /* For BSF_FUNCTION symbols, the entry point is in LP_1
! and the descriptor in LP_2. For other symbols, the
! unique value is in LP_2. */
! symbol->value = bfd_getl64 (vms_rec + EGST_S_Q_LP_2);
!
! /* Adding this offset is necessary in order for GDB to
! read the DWARF-2 debug info from shared libraries. */
! if (abfd->flags & DYNAMIC
! && strstr (symbol->name, "$DWARF2.DEBUG") != 0)
! symbol->value += PRIV (symvva);
! }
! else /* symbol reference */
! (*_bfd_error_handler) ("Invalid EGST reference");
!
! symbol->flags = new_flags;
!
! if (register_universal_symbol (abfd, symbol, old_flags) < 0)
! return -1;
!
! /* Make a second symbol for the entry point. */
! if (symbol->flags & BSF_FUNCTION)
! {
! asymbol *en_sym;
! char *name = bfd_alloc (abfd, strlen (symbol->name) + 5);
!
! en_sym = bfd_make_empty_symbol (abfd);
! if (en_sym == 0)
! return -1;
!
! strcpy (name, symbol->name);
! strcat (name, "..en");
!
! en_sym->name = name;
! en_sym->value = bfd_getl64 (vms_rec + EGST_S_Q_LP_1);
!
! if (register_universal_symbol (abfd, en_sym, old_flags) < 0)
! return -1;
! }
! }
break;
+ case EGSD_S_C_IDC + EVAX_OFFSET:
+ break;
+
default:
! (*_bfd_error_handler) (_("Unknown GSD/EGSD subtype %d"), gsd_type);
bfd_set_error (bfd_error_bad_value);
return -1;
}
***************
*** 691,697 ****
return 0;
}
! /* Output routines. */
/* Write section and symbol directory of bfd abfd. */
--- 766,844 ----
return 0;
}
! /* 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,710 ****
--- 852,858 ----
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,735 ****
--- 878,888 ----
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,780 ****
--- 928,938 ----
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,802 ****
_bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
_bfd_vms_output_short (abfd, section->alignment_power & 0xff);
if (bfd_is_com_section (section))
! new_flags = (EGPS_S_V_OVR | EGPS_S_V_REL | EGPS_S_V_GBL | EGPS_S_V_RD | EGPS_S_V_WRT | EGPS_S_V_NOMOD | EGPS_S_V_COM);
else
new_flags = vms_esecflag_by_name (evax_section_flags, sname,
section->size > 0);
_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;
section = section->next;
}
--- 943,976 ----
_bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
_bfd_vms_output_short (abfd, section->alignment_power & 0xff);
+
if (bfd_is_com_section (section))
! new_flags = (EGPS_S_V_OVR | EGPS_S_V_REL | EGPS_S_V_GBL | EGPS_S_V_RD
! | EGPS_S_V_WRT | EGPS_S_V_NOMOD | EGPS_S_V_COM);
else
new_flags = vms_esecflag_by_name (evax_section_flags, sname,
section->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,830 ****
if (old_flags & BSF_FILE)
continue;
! if (((old_flags & (BSF_GLOBAL | BSF_WEAK)) == 0) /* Not xdef... */
! && (!bfd_is_und_section (symbol->section))) /* ...and not xref. */
! continue; /* Dont output. */
/* 13 bytes egsd, max 64 chars name -> should be 77 bytes. */
if (_bfd_vms_output_check (abfd, 80) < 0)
--- 996,1006 ----
if (old_flags & BSF_FILE)
continue;
! 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,852 ****
if (old_flags & BSF_WEAK)
new_flags |= EGSY_S_V_WEAK;
! if (bfd_is_com_section (symbol->section))
new_flags |= (EGSY_S_V_WEAK | EGSY_S_V_COMM);
if (old_flags & BSF_FUNCTION)
--- 1022,1028 ----
if (old_flags & BSF_WEAK)
new_flags |= EGSY_S_V_WEAK;
! if (bfd_is_com_section (symbol->section)) /* .comm */
new_flags |= (EGSY_S_V_WEAK | EGSY_S_V_COMM);
if (old_flags & BSF_FUNCTION)
***************
*** 854,860 ****
new_flags |= EGSY_S_V_NORM;
new_flags |= EGSY_S_V_REL;
}
! if (old_flags & (BSF_GLOBAL | BSF_WEAK))
{
new_flags |= EGSY_S_V_DEF;
if (!bfd_is_abs_section (symbol->section))
--- 1030,1036 ----
new_flags |= EGSY_S_V_NORM;
new_flags |= EGSY_S_V_REL;
}
! if (old_flags & BSF_GLOBAL)
{
new_flags |= EGSY_S_V_DEF;
if (!bfd_is_abs_section (symbol->section))
***************
*** 862,868 ****
}
_bfd_vms_output_short (abfd, new_flags);
! if (old_flags & (BSF_GLOBAL | BSF_WEAK))
{
/* Symbol definition. */
uquad code_address = 0;
--- 1038,1044 ----
}
_bfd_vms_output_short (abfd, new_flags);
! if (old_flags & BSF_GLOBAL)
{
/* Symbol definition. */
uquad code_address = 0;
***************
*** 871,880 ****
if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL)
{
! code_address = ((asymbol *) (symbol->udata.p))->value;
! ca_psindx = ((asymbol *) (symbol->udata.p))->section->index;
}
! psindx = symbol->section->index;
_bfd_vms_output_quad (abfd, symbol->value);
_bfd_vms_output_quad (abfd, code_address);
--- 1047,1065 ----
if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL)
{
! 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;
}
! 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);
Index: bfd/vms-hdr.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-hdr.c,v
retrieving revision 1.22
diff -c -r1.22 vms-hdr.c
*** bfd/vms-hdr.c 14 Nov 2008 09:57:33 -0000 1.22
--- bfd/vms-hdr.c 17 Feb 2009 11:13:09 -0000
***************
*** 1,14 ****
/* vms-hdr.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
! 2007 Free Software Foundation, Inc.
HDR record handling functions
EMH record handling functions
! and
EOM record handling functions
EEOM record handling functions
Written by Klaus K"ampf (kkaempf@rmi.de)
This program is free software; you can redistribute it and/or modify
--- 1,31 ----
/* vms-hdr.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
! 2007, 2008, 2009 Free Software Foundation, Inc.
HDR record handling functions
EMH record handling functions
!
EOM record handling functions
EEOM record handling functions
+ IHD record handling functions
+ EIHD record handling functions
+
+ ISD record handling functions
+ EISD record handling functions
+
+ IHS record handling functions
+ EIHS record handling functions
+
+ DBG record handling functions
+ EDBG record handling functions
+
+ TBT record handling functions
+ ETBT record handling functions
+
+ DST/DMT section handling functions
+
Written by Klaus K"ampf (kkaempf@rmi.de)
This program is free software; you can redistribute it and/or modify
***************
*** 39,44 ****
--- 56,75 ----
#include <alloca.h>
#endif
+ static struct module *new_module (bfd *);
+ static void parse_module
+ (bfd *, struct module *, unsigned char *, unsigned int);
+ static struct module *build_module_list (bfd *);
+ static bfd_boolean module_find_nearest_line
+ (bfd *, struct module *, bfd_vma, const char **, const char **,
+ unsigned int *);
+ static int vms_slurp_debug (bfd *);
+
+ #define SET_MODULE_PARSED(m) \
+ do { if ((m)->name == NULL) (m)->name = ""; } while (0)
+ #define IS_MODULE_PARSED(m) ((m)->name != NULL)
+
+
/* Read & process emh record
return 0 on success, -1 on error. */
***************
*** 85,99 ****
break;
case MHD_S_C_LNM:
! PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_length - 2));
break;
case MHD_S_C_SRC:
! PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_length - 2));
break;
case MHD_S_C_TTL:
! PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_length - 2));
break;
case EMH_S_C_MHD + EVAX_OFFSET:
--- 116,130 ----
break;
case MHD_S_C_LNM:
! PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
break;
case MHD_S_C_SRC:
! PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
break;
case MHD_S_C_TTL:
! PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
break;
case EMH_S_C_MHD + EVAX_OFFSET:
***************
*** 110,124 ****
break;
case EMH_S_C_LNM + EVAX_OFFSET:
! PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_length - 6));
break;
case EMH_S_C_SRC + EVAX_OFFSET:
! PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_length - 6));
break;
case EMH_S_C_TTL + EVAX_OFFSET:
! PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_length - 6));
break;
case MHD_S_C_CPR:
--- 141,155 ----
break;
case EMH_S_C_LNM + EVAX_OFFSET:
! PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
break;
case EMH_S_C_SRC + EVAX_OFFSET:
! PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
break;
case EMH_S_C_TTL + EVAX_OFFSET:
! PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
break;
case MHD_S_C_CPR:
***************
*** 189,194 ****
--- 220,226 ----
unsigned int symnum;
int had_case = 0;
int had_file = 0;
+ char version [256];
#if VMS_DEBUG
vms_debug (2, "vms_write_hdr (%p)\n", abfd);
***************
*** 213,239 ****
fptr = bfd_get_filename (abfd);
fname = strdup (fptr);
fout = strrchr (fname, ']');
! if (fout == 0)
fout = strchr (fname, ':');
! if (fout != 0)
fout++;
else
fout = fname;
/* Strip .obj suffix. */
! fptr = strrchr (fname, '.');
! if ((fptr != 0)
! && (strcasecmp (fptr, ".OBJ") == 0))
*fptr = 0;
fptr = fout;
while (*fptr != 0)
{
*fptr = TOUPPER (*fptr);
fptr++;
! if ((*fptr == ';')
! || ((fptr - fout) > 31))
*fptr = 0;
}
_bfd_vms_output_counted (abfd, fout);
--- 245,278 ----
fptr = bfd_get_filename (abfd);
fname = strdup (fptr);
+
+ /* Strip VMS path. */
fout = strrchr (fname, ']');
! if (fout == NULL)
fout = strchr (fname, ':');
! if (fout != NULL)
fout++;
else
fout = fname;
+ /* Strip UNIX path. */
+ fptr = strrchr (fout, '/');
+ if (fptr != NULL)
+ fout = fptr + 1;
+
/* Strip .obj suffix. */
! fptr = strrchr (fout, '.');
! if (fptr != 0 && strcasecmp (fptr, ".OBJ") == 0)
*fptr = 0;
+ /* Convert to upper case and truncate at 31 characters.
+ (VMS object file format restricts module name length to 31). */
fptr = fout;
while (*fptr != 0)
{
*fptr = TOUPPER (*fptr);
fptr++;
! if (*fptr == ';' || (fptr - fout) >= 31)
*fptr = 0;
}
_bfd_vms_output_counted (abfd, fout);
***************
*** 243,255 ****
_bfd_vms_output_counted (abfd, "NONAME");
_bfd_vms_output_counted (abfd, BFD_VERSION_STRING);
! _bfd_vms_output_dump (abfd, get_vms_time_string (), 17);
! _bfd_vms_output_fill (abfd, 0, 17);
_bfd_vms_output_flush (abfd);
/* LMN. */
_bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
! _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("GAS proGIS"));
_bfd_vms_output_flush (abfd);
/* SRC. */
--- 282,295 ----
_bfd_vms_output_counted (abfd, "NONAME");
_bfd_vms_output_counted (abfd, BFD_VERSION_STRING);
! _bfd_vms_output_dump (abfd, get_vms_time_string (), EMH_DATE_LENGTH);
! _bfd_vms_output_fill (abfd, 0, EMH_DATE_LENGTH);
_bfd_vms_output_flush (abfd);
/* LMN. */
_bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
! snprintf (version, sizeof (version), "GAS BFD v%s", BFD_VERSION_STRING);
! _bfd_vms_output_dump (abfd, (unsigned char *)version, strlen (version));
_bfd_vms_output_flush (abfd);
/* SRC. */
***************
*** 320,329 ****
}
else
{
! PRIV (eom_data).eom_l_total_lps = bfd_getl32 (vms_rec + 4);
! PRIV (eom_data).eom_b_comcod = *(vms_rec + 8);
!
! if (PRIV (eom_data).eom_b_comcod > 1)
{
(*_bfd_error_handler) (_("Object module NOT error-free !\n"));
bfd_set_error (bfd_error_bad_value);
--- 360,369 ----
}
else
{
! PRIV (eom_data).eom_l_total_lps
! = bfd_getl32 (vms_rec + EEOM_S_L_TOTAL_LPS);
! PRIV (eom_data).eom_w_comcod = bfd_getl16 (vms_rec + EEOM_S_W_COMCOD);
! if (PRIV (eom_data).eom_w_comcod > 1)
{
(*_bfd_error_handler) (_("Object module NOT error-free !\n"));
bfd_set_error (bfd_error_bad_value);
***************
*** 333,341 ****
if (PRIV (rec_size) > 10)
{
PRIV (eom_data).eom_has_transfer = TRUE;
! PRIV (eom_data).eom_b_tfrflg = *(vms_rec + 9);
! PRIV (eom_data).eom_l_psindx = bfd_getl32 (vms_rec + 12);
! PRIV (eom_data).eom_l_tfradr = bfd_getl32 (vms_rec + 16);
abfd->start_address = PRIV (eom_data).eom_l_tfradr;
}
--- 373,383 ----
if (PRIV (rec_size) > 10)
{
PRIV (eom_data).eom_has_transfer = TRUE;
! PRIV (eom_data).eom_b_tfrflg = vms_rec[EEOM_S_B_TFRFLG];
! PRIV (eom_data).eom_l_psindx
! = bfd_getl32 (vms_rec + EEOM_S_L_PSINDX);
! PRIV (eom_data).eom_l_tfradr
! = bfd_getl32 (vms_rec + EEOM_S_L_TFRADR);
abfd->start_address = PRIV (eom_data).eom_l_tfradr;
}
***************
*** 377,379 ****
--- 419,1419 ----
_bfd_vms_output_end (abfd);
return 0;
}
+
+ /* Read & process IHD/EIHD record.
+ Return 0 on success, -1 on error */
+ int
+ _bfd_vms_slurp_ihd (bfd *abfd, unsigned int *isd_offset,
+ unsigned int *ihs_offset)
+ {
+ unsigned int imgtype, size;
+ bfd_vma symvva;
+
+ #if VMS_DEBUG
+ vms_debug (8, "_bfd_vms_slurp_ihd\n");
+ #endif
+
+ size = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SIZE);
+ imgtype = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_IMGTYPE);
+
+ if (imgtype == EIHD_S_K_EXE)
+ abfd->flags |= EXEC_P;
+
+ symvva = bfd_getl64 (PRIV (vms_rec) + EIHD_S_Q_SYMVVA);
+ if (symvva != 0)
+ {
+ PRIV (symvva) = symvva;
+ abfd->flags |= DYNAMIC;
+ }
+
+ *isd_offset = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_ISDOFF);
+ *ihs_offset = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SYMDBGOFF);
+
+ #if VMS_DEBUG
+ vms_debug (4, "EIHD record size %d imgtype %d symvva 0x%llx isd %d ihs %d\n",
+ size, imgtype, symvva, *isd_offset, *ihs_offset);
+ #endif
+
+ return 0;
+ }
+
+ /* Read & process ISD/EISD record
+ return 0 on success, -1 on error */
+
+ int
+ _bfd_vms_slurp_isd (bfd *abfd, unsigned int offset)
+ {
+ int section_count = 0;
+ unsigned char *p;
+ unsigned int rec_size;
+
+ #if VMS_DEBUG
+ vms_debug (8, "_bfd_vms_slurp_isd\n");
+ #endif
+
+ for (p = PRIV (vms_rec) + offset;
+ (rec_size = bfd_getl32 (p + EISD_S_L_EISDSIZE)) != 0;
+ p += rec_size)
+ {
+ unsigned long long vaddr = bfd_getl64 (p + EISD_S_Q_VIR_ADDR);
+ unsigned int size = bfd_getl32 (p + EISD_S_L_SECSIZE);
+ unsigned int flags = bfd_getl32 (p + EISD_S_L_FLAGS);
+ unsigned int vbn = bfd_getl32 (p + EISD_S_L_VBN);
+ char *name = NULL;
+ asection *section;
+ flagword bfd_flags;
+
+ #if VMS_DEBUG
+ vms_debug (4, "EISD record at 0x%x size 0x%x addr 0x%x bfd_flags 0x%x block %d\n",
+ p - PRIV (vms_rec), size, vaddr, flags, vbn);
+ #endif
+
+ /* VMS combines psects from .obj files into isects in the .exe. This
+ process doesn't preserve enough information to reliably determine
+ what's in each section without examining the data. This is
+ especially true of DWARF debug sections. */
+ bfd_flags = SEC_ALLOC;
+
+ if (flags & EISD_S_M_EXE)
+ bfd_flags |= SEC_CODE | SEC_HAS_CONTENTS | SEC_LOAD;
+
+ if (flags & EISD_S_M_NONSHRADR)
+ bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
+
+ if (!(flags & EISD_S_M_WRT))
+ bfd_flags |= SEC_READONLY;
+
+ if (flags & EISD_S_M_DZRO)
+ bfd_flags |= SEC_DATA;
+
+ if (flags & EISD_S_M_FIXUPVEC)
+ bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
+
+ if (flags & EISD_S_M_CRF)
+ bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD;
+
+ if (flags & EISD_S_M_GBL)
+ {
+ name = _bfd_vms_save_counted_string (p + EISD_S_T_GBLNAM);
+ bfd_flags |= SEC_COFF_SHARED_LIBRARY;
+ bfd_flags &= ~(SEC_ALLOC | SEC_LOAD);
+ }
+ else
+ {
+ name = (char*) bfd_alloc (abfd, 32);
+ sprintf (name, "$LOCAL_%03d$", section_count++);
+ }
+
+ section = bfd_make_section (abfd, name);
+
+ if (!section)
+ return -1;
+
+ section->filepos = vbn ? VMS_BLOCK_SIZE * (vbn - 1) : (unsigned int)-1;
+ section->size = size;
+ section->vma = vaddr;
+
+ if (!bfd_set_section_flags (abfd, section, bfd_flags))
+ return -1;
+ }
+
+ return 0;
+ }
+
+ /* Read & process IHS/EIHS record
+ return 0 on success, -1 on error */
+ int
+ _bfd_vms_slurp_ihs (bfd *abfd, unsigned int offset)
+ {
+ unsigned char *p = PRIV (vms_rec) + offset;
+ unsigned int gstvbn = bfd_getl32 (p + EIHS_S_L_GSTVBN);
+ unsigned int gstsize ATTRIBUTE_UNUSED = bfd_getl32 (p + EIHS_S_L_GSTSIZE);
+ unsigned int dstvbn = bfd_getl32 (p + EIHS_S_L_DSTVBN);
+ unsigned int dstsize = bfd_getl32 (p + EIHS_S_L_DSTSIZE);
+ unsigned int dmtvbn = bfd_getl32 (p + EIHS_S_L_DMTVBN);
+ unsigned int dmtbytes = bfd_getl32 (p + EIHS_S_L_DMTBYTES);
+ asection *section;
+
+ #if VMS_DEBUG
+ vms_debug (8, "_bfd_vms_slurp_ihs\n");
+ vms_debug (4, "EIHS record gstvbn %d gstsize %d dstvbn %d dstsize %d dmtvbn %d dmtbytes %d\n",
+ gstvbn, gstsize, dstvbn, dstsize, dmtvbn, dmtbytes);
+ #endif
+
+ if (dstvbn)
+ {
+ flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
+
+ section = bfd_make_section (abfd, "$DST$");
+ if (!section)
+ return -1;
+
+ section->size = dstsize;
+ section->filepos = VMS_BLOCK_SIZE * (dstvbn - 1);
+
+ if (!bfd_set_section_flags (abfd, section, bfd_flags))
+ return -1;
+
+ PRIV (dst_section) = section;
+ abfd->flags |= (HAS_DEBUG | HAS_LINENO);
+ }
+
+ if (dmtvbn)
+ {
+ flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
+
+ section = bfd_make_section (abfd, "$DMT$");
+ if (!section)
+ return -1;
+
+ section->size = dmtbytes;
+ section->filepos = VMS_BLOCK_SIZE * (dmtvbn - 1);
+
+ if (!bfd_set_section_flags (abfd, section, bfd_flags))
+ return -1;
+ }
+
+ if (gstvbn)
+ {
+ flagword bfd_flags = SEC_HAS_CONTENTS;
+
+ section = bfd_make_section (abfd, "$GST$");
+ if (!section)
+ return -1;
+
+ if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET))
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return -1;
+ }
+
+ if (_bfd_vms_slurp_object_records (abfd) != 0)
+ return -1;
+
+ section->filepos = VMS_BLOCK_SIZE * (gstvbn - 1);
+ section->size = bfd_tell (abfd) - section->filepos;
+
+ if (!bfd_set_section_flags (abfd, section, bfd_flags))
+ return -1;
+
+ abfd->flags |= HAS_SYMS;
+ }
+
+ return 0;
+ }
+
+ /* Build a new module for the specified BFD. */
+
+ static struct module *
+ new_module (bfd *abfd)
+ {
+ struct module *module
+ = (struct module *) bfd_zalloc (abfd, sizeof (struct module));
+ module->file_table_count = 16; /* Arbitrary. */
+ module->file_table
+ = bfd_malloc (module->file_table_count * sizeof (struct fileinfo));
+ return module;
+ }
+
+ /* Parse debug info for a module and internalize it. */
+
+ static void
+ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
+ unsigned int length)
+ {
+ unsigned char *maxptr = ptr + length, *src_ptr, *pcl_ptr;
+ unsigned int prev_linum = 0, curr_linenum = 0;
+ bfd_vma prev_pc = 0, curr_pc = 0;
+ struct srecinfo *curr_srec, *srec;
+ struct lineinfo *curr_line, *line;
+ struct funcinfo *funcinfo;
+
+ /* Initialize tables with zero element. */
+ curr_srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
+ module->srec_table = curr_srec;
+
+ curr_line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
+ module->line_table = curr_line;
+
+ while (ptr < maxptr)
+ {
+ /* The first byte is not counted in the recorded length. */
+ int rec_length = bfd_getl16 (ptr) + 1;
+ int rec_type = bfd_getl16 (ptr + 2);
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (2, "DST record: length %d, type %d\n",
+ rec_length, rec_type);
+ #endif
+
+ switch (rec_type)
+ {
+ case DST_S_C_MODBEG:
+ module->name
+ = _bfd_vms_save_counted_string (ptr + DST_S_B_MODBEG_NAME);
+
+ curr_pc = 0;
+ prev_pc = 0;
+ curr_linenum = 0;
+ prev_linum = 0;
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "module: %s\n", module->name);
+ #endif
+ break;
+
+ case DST_S_C_MODEND:
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "end module\n");
+ #endif
+ break;
+
+ case DST_S_C_RTNBEG:
+ funcinfo = (struct funcinfo *)
+ bfd_zalloc (abfd, sizeof (struct funcinfo));
+ funcinfo->name
+ = _bfd_vms_save_counted_string (ptr + DST_S_B_RTNBEG_NAME);
+ funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS);
+ funcinfo->next = module->func_table;
+ module->func_table = funcinfo;
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "routine: %s at 0x%x\n",
+ funcinfo->name, funcinfo->low);
+ #endif
+ break;
+
+ case DST_S_C_RTNEND:
+ module->func_table->high = module->func_table->low
+ + bfd_getl32 (ptr + DST_S_L_RTNEND_SIZE) - 1;
+
+ if (module->func_table->high > module->high)
+ module->high = module->func_table->high;
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "end routine\n");
+ #endif
+ break;
+
+ case DST_S_C_PROLOG:
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "prologue\n");
+ #endif
+ break;
+
+ case DST_S_C_EPILOG:
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "epilog\n");
+ #endif
+ break;
+
+ case DST_S_C_BLKBEG:
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "block\n");
+ #endif
+ break;
+
+ case DST_S_C_BLKEND:
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "end block\n");
+ #endif
+ break;
+
+ case DST_S_C_SOURCE:
+ src_ptr = ptr + DST_S_C_SOURCE_HEADER_SIZE;
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "source info\n");
+ #endif
+
+ while (src_ptr < ptr + rec_length)
+ {
+ int cmd = src_ptr[0], cmd_length, data;
+
+ switch (cmd)
+ {
+ case DST_S_C_SRC_DECLFILE:
+ {
+ unsigned int fileid
+ = bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID);
+ char *filename
+ = _bfd_vms_save_counted_string (src_ptr
+ + DST_S_B_SRC_DF_FILENAME);
+
+ while (fileid >= module->file_table_count)
+ {
+ module->file_table_count *= 2;
+ module->file_table
+ = bfd_realloc (module->file_table,
+ module->file_table_count
+ * sizeof (struct fileinfo));
+ }
+
+ module->file_table [fileid].name = filename;
+ module->file_table [fileid].srec = 1;
+ cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SRC_DECLFILE: %d, %s\n",
+ fileid,
+ module->file_table [fileid].name);
+ #endif
+ }
+ break;
+
+ case DST_S_C_SRC_DEFLINES_B:
+ /* Perform the association and set the next higher index
+ to the limit. */
+ data = src_ptr[DST_S_B_SRC_UNSBYTE];
+ srec = (struct srecinfo *)
+ bfd_zalloc (abfd, sizeof (struct srecinfo));
+ srec->line = curr_srec->line + data;
+ srec->srec = curr_srec->srec + data;
+ srec->sfile = curr_srec->sfile;
+ curr_srec->next = srec;
+ curr_srec = srec;
+ cmd_length = 2;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SRC_DEFLINES_B: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SRC_DEFLINES_W:
+ /* Perform the association and set the next higher index
+ to the limit. */
+ data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
+ srec = (struct srecinfo *)
+ bfd_zalloc (abfd, sizeof (struct srecinfo));
+ srec->line = curr_srec->line + data;
+ srec->srec = curr_srec->srec + data,
+ srec->sfile = curr_srec->sfile;
+ curr_srec->next = srec;
+ curr_srec = srec;
+ cmd_length = 3;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SRC_DEFLINES_W: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SRC_INCRLNUM_B:
+ data = src_ptr[DST_S_B_SRC_UNSBYTE];
+ curr_srec->line += data;
+ cmd_length = 2;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SRC_INCRLNUM_B: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SRC_SETFILE:
+ data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
+ curr_srec->sfile = data;
+ curr_srec->srec = module->file_table[data].srec;
+ cmd_length = 3;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SRC_SETFILE: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SRC_SETLNUM_L:
+ data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
+ curr_srec->line = data;
+ cmd_length = 5;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SRC_SETLNUM_L: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SRC_SETLNUM_W:
+ data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
+ curr_srec->line = data;
+ cmd_length = 3;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SRC_SETLNUM_W: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SRC_SETREC_L:
+ data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
+ curr_srec->srec = data;
+ module->file_table[curr_srec->sfile].srec = data;
+ cmd_length = 5;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SRC_SETREC_L: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SRC_SETREC_W:
+ data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
+ curr_srec->srec = data;
+ module->file_table[curr_srec->sfile].srec = data;
+ cmd_length = 3;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SRC_SETREC_W: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SRC_FORMFEED:
+ cmd_length = 1;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SRC_FORMFEED\n");
+ #endif
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("unknown source command %d"),
+ cmd);
+ cmd_length = 2;
+ break;
+ }
+
+ src_ptr += cmd_length;
+ }
+ break;
+
+ case DST_S_C_LINE_NUM:
+ pcl_ptr = ptr + DST_S_C_LINE_NUM_HEADER_SIZE;
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "line info\n");
+ #endif
+
+ while (pcl_ptr < ptr + rec_length)
+ {
+ /* The command byte is signed so we must sign-extend it. */
+ int cmd = ((signed char *)pcl_ptr)[0], cmd_length, data;
+
+ switch (cmd)
+ {
+ case DST_S_C_DELTA_PC_W:
+ data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
+ curr_pc += data;
+ curr_linenum += 1;
+ cmd_length = 3;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_DELTA_PC_W: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_DELTA_PC_L:
+ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+ curr_pc += data;
+ curr_linenum += 1;
+ cmd_length = 5;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_DELTA_PC_L: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_INCR_LINUM:
+ data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
+ curr_linenum += data;
+ cmd_length = 2;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_INCR_LINUM: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_INCR_LINUM_W:
+ data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
+ curr_linenum += data;
+ cmd_length = 3;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_INCR_LINUM_W: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_INCR_LINUM_L:
+ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+ curr_linenum += data;
+ cmd_length = 5;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_INCR_LINUM_L: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SET_LINUM_INCR:
+ (*_bfd_error_handler)
+ (_("DST_S_C_SET_LINUM_INCR not implemented"));
+ cmd_length = 2;
+ break;
+
+ case DST_S_C_SET_LINUM_INCR_W:
+ (*_bfd_error_handler)
+ (_("DST_S_C_SET_LINUM_INCR_W not implemented"));
+ cmd_length = 3;
+ break;
+
+ case DST_S_C_RESET_LINUM_INCR:
+ (*_bfd_error_handler)
+ (_("DST_S_C_RESET_LINUM_INCR not implemented"));
+ cmd_length = 1;
+ break;
+
+ case DST_S_C_BEG_STMT_MODE:
+ (*_bfd_error_handler)
+ (_("DST_S_C_BEG_STMT_MODE not implemented"));
+ cmd_length = 1;
+ break;
+
+ case DST_S_C_END_STMT_MODE:
+ (*_bfd_error_handler)
+ (_("DST_S_C_END_STMT_MODE not implemented"));
+ cmd_length = 1;
+ break;
+
+ case DST_S_C_SET_LINUM_B:
+ data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
+ curr_linenum = data;
+ cmd_length = 2;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SET_LINUM_B: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SET_LINE_NUM:
+ data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
+ curr_linenum = data;
+ cmd_length = 3;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SET_LINE_NUM: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SET_LINUM_L:
+ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+ curr_linenum = data;
+ cmd_length = 5;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SET_LINUM_L: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SET_PC:
+ (*_bfd_error_handler)
+ (_("DST_S_C_SET_PC not implemented"));
+ cmd_length = 2;
+ break;
+
+ case DST_S_C_SET_PC_W:
+ (*_bfd_error_handler)
+ (_("DST_S_C_SET_PC_W not implemented"));
+ cmd_length = 3;
+ break;
+
+ case DST_S_C_SET_PC_L:
+ (*_bfd_error_handler)
+ (_("DST_S_C_SET_PC_L not implemented"));
+ cmd_length = 5;
+ break;
+
+ case DST_S_C_SET_STMTNUM:
+ (*_bfd_error_handler)
+ (_("DST_S_C_SET_STMTNUM not implemented"));
+ cmd_length = 2;
+ break;
+
+ case DST_S_C_TERM:
+ data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
+ curr_pc += data;
+ cmd_length = 2;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_TERM: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_TERM_W:
+ data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
+ curr_pc += data;
+ cmd_length = 3;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_TERM_W: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_TERM_L:
+ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+ curr_pc += data;
+ cmd_length = 5;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_TERM_L: %d\n", data);
+ #endif
+ break;
+
+ case DST_S_C_SET_ABS_PC:
+ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+ curr_pc = data;
+ cmd_length = 5;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "DST_S_C_SET_ABS_PC: 0x%x\n", data);
+ #endif
+ break;
+
+ default:
+ if (cmd <= 0)
+ {
+ curr_pc -= cmd;
+ curr_linenum += 1;
+ cmd_length = 1;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "bump pc to 0x%llx and line to %d\n",
+ curr_pc, curr_linenum);
+ #endif
+ }
+ else
+ {
+ (*_bfd_error_handler) (_("unknown line command %d"),
+ cmd);
+ cmd_length = 2;
+ }
+ break;
+ }
+
+ if ((curr_linenum != prev_linum && curr_pc != prev_pc)
+ || cmd <= 0
+ || cmd == DST_S_C_DELTA_PC_L
+ || cmd == DST_S_C_DELTA_PC_W)
+ {
+ line = (struct lineinfo *)
+ bfd_zalloc (abfd, sizeof (struct lineinfo));
+ line->address = curr_pc;
+ line->line = curr_linenum;
+
+ curr_line->next = line;
+ curr_line = line;
+
+ prev_linum = curr_linenum;
+ prev_pc = curr_pc;
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "-> correlate pc 0x%llx with line %d\n",
+ curr_pc, curr_linenum);
+ #endif
+ }
+
+ pcl_ptr += cmd_length;
+ }
+ break;
+
+ case 0x17: /* Undocumented type used by DEC C to declare equates. */
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "undocumented type 0x17\n");
+ #endif
+ break;
+
+ default:
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "ignoring record\n");
+ #endif
+ break;
+
+ }
+
+ ptr += rec_length;
+ }
+
+ /* Finalize tables with EOL marker. */
+ srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
+ srec->line = (unsigned int) -1;
+ srec->srec = (unsigned int) -1;
+ curr_srec->next = srec;
+
+ line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
+ line->line = (unsigned int) -1;
+ line->address = (bfd_vma) -1;
+ curr_line->next = line;
+
+ /* Advertise that this module has been parsed. This is needed
+ because parsing can be either performed at module creation
+ or deferred until debug info is consumed. */
+ SET_MODULE_PARSED (module);
+ }
+
+ /* Build the list of modules for the specified BFD. */
+
+ static struct module *
+ build_module_list (bfd *abfd)
+ {
+ struct module *module, *list = NULL;
+ asection *dmt;
+
+ if ((dmt = bfd_get_section_by_name (abfd, "$DMT$")))
+ {
+ /* We have a DMT section so this must be an image. Parse the
+ section and build the list of modules. This is sufficient
+ since we can compute the start address and the end address
+ of every module from the section contents. */
+ bfd_size_type size = bfd_get_section_size (dmt);
+ unsigned char *ptr, *end;
+
+ ptr = (unsigned char *) bfd_alloc (abfd, size);
+ if (! ptr)
+ return NULL;
+
+ if (! bfd_get_section_contents (abfd, dmt, ptr, 0, size))
+ return NULL;
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (2, "DMT\n");
+ #endif
+
+ end = ptr + size;
+
+ while (ptr < end)
+ {
+ /* Each header declares a module with its start offset and size
+ of debug info in the DST section, as well as the count of
+ program sections (i.e. address spans) it contains. */
+ int modbeg = bfd_getl32 (ptr + DBG_S_L_DMT_MODBEG);
+ int size = bfd_getl32 (ptr + DBG_S_L_DST_SIZE);
+ int count = bfd_getl16 (ptr + DBG_S_W_DMT_PSECT_COUNT);
+ ptr += DBG_S_C_DMT_HEADER_SIZE;
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "module: modbeg = %d, size = %d, count = %d\n",
+ modbeg, size, count);
+ #endif
+
+ /* We create a 'module' structure for each program section since
+ we only support contiguous addresses in a 'module' structure.
+ As a consequence, the actual debug info in the DST section is
+ shared and can be parsed multiple times; that doesn't seem to
+ cause problems in practice. */
+ while (count-- > 0)
+ {
+ int start = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_START);
+ int length = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_LENGTH);
+ module = new_module (abfd);
+ module->modbeg = modbeg;
+ module->size = size;
+ module->low = start;
+ module->high = start + length;
+ module->next = list;
+ list = module;
+ ptr += DBG_S_C_DMT_PSECT_SIZE;
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "section: start = 0x%x, length = %d\n",
+ start, length);
+ #endif
+ }
+ }
+ }
+ else
+ {
+ /* We don't have a DMT section so this must be an object. Parse
+ the module right now in order to compute its start address and
+ end address. */
+ module = new_module (abfd);
+ parse_module (abfd, module, PRIV (dst_section)->contents,
+ PRIV (dst_ptr_end) - PRIV (dst_section)->contents);
+ list = module;
+ }
+
+ return list;
+ }
+
+ /* Calculate and return the name of the source file and the line nearest
+ to the wanted location in the specified module. */
+
+ static bfd_boolean
+ module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr,
+ const char **file, const char **func,
+ unsigned int *line)
+ {
+ struct funcinfo *funcinfo;
+ struct lineinfo *lineinfo;
+ struct srecinfo *srecinfo;
+ bfd_boolean ret = FALSE;
+
+ /* Parse this module if that was not done at module creation. */
+ if (! IS_MODULE_PARSED (module))
+ {
+ unsigned int size = module->size;
+ unsigned int modbeg = PRIV (dst_section)->filepos + module->modbeg;
+ unsigned char *buffer = (unsigned char *) bfd_malloc (module->size);
+
+ if (bfd_seek (abfd, modbeg, SEEK_SET) != 0
+ || bfd_bread (buffer, size, abfd) != size)
+ {
+ bfd_set_error (bfd_error_no_debug_section);
+ return FALSE;
+ }
+
+ parse_module (abfd, module, buffer, size);
+ free (buffer);
+ }
+
+ /* Find out the function (if any) that contains the address. */
+ for (funcinfo = module->func_table; funcinfo; funcinfo = funcinfo->next)
+ if (addr >= funcinfo->low && addr <= funcinfo->high)
+ {
+ *func = funcinfo->name;
+ ret = TRUE;
+ break;
+ }
+
+ /* Find out the source file and the line nearest to the address. */
+ for (lineinfo = module->line_table; lineinfo; lineinfo = lineinfo->next)
+ if (lineinfo->next && addr < lineinfo->next->address)
+ {
+ for (srecinfo = module->srec_table; srecinfo; srecinfo = srecinfo->next)
+ if (srecinfo->next && lineinfo->line < srecinfo->next->line)
+ {
+ if (srecinfo->sfile > 0)
+ {
+ *file = module->file_table[srecinfo->sfile].name;
+ *line = srecinfo->srec + lineinfo->line - srecinfo->line;
+ }
+ else
+ {
+ *file = module->name;
+ *line = lineinfo->line;
+ }
+ return TRUE;
+ }
+
+ break;
+ }
+
+ return ret;
+ }
+
+ /* Provided a BFD, a section and an offset into the section, calculate and
+ return the name of the source file and the line nearest to the wanted
+ location. */
+
+ bfd_boolean
+ _bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section,
+ asymbol **symbols ATTRIBUTE_UNUSED,
+ bfd_vma offset, const char **file,
+ const char **func, unsigned int *line)
+ {
+ struct module *module;
+
+ /* What address are we looking for? */
+ bfd_vma addr = section->vma + offset;
+
+ *file = NULL;
+ *func = NULL;
+ *line = 0;
+
+ if (PRIV (dst_section) == NULL)
+ return FALSE;
+
+ if (PRIV (modules) == NULL)
+ {
+ PRIV (modules) = build_module_list (abfd);
+ if (PRIV (modules) == NULL)
+ return FALSE;
+ }
+
+ for (module = PRIV (modules); module; module = module->next)
+ if (addr >= module->low && addr <= module->high)
+ return module_find_nearest_line (abfd, module, addr, file, func, line);
+
+ return FALSE;
+ }
+
+ /* Process EDBG/ETBT record.
+ Return 0 on success, -1 on error */
+
+ static int
+ vms_slurp_debug (bfd *abfd)
+ {
+ if (PRIV (dst_section) == NULL)
+ {
+ /* We have no way to find out beforehand how much debug info there
+ is in an object file, so pick an initial amount and grow it as
+ needed later. */
+ flagword flags = SEC_HAS_CONTENTS | SEC_DEBUGGING | SEC_RELOC;
+ asection *section = bfd_make_section (abfd, "$DST$");
+ if (!section)
+ return -1;
+ section->size = 1024;
+ if (!bfd_set_section_flags (abfd, section, flags))
+ return -1;
+ section->contents = ((unsigned char *)
+ bfd_zmalloc (section->size));
+ if (section->contents == NULL)
+ return -1;
+ section->filepos = (unsigned int)-1;
+ PRIV (dst_section) = section;
+ }
+
+ PRIV (image_section) = PRIV (dst_section);
+ PRIV (image_ptr) = PRIV (dst_section)->contents;
+
+ return _bfd_vms_slurp_tir (abfd, EOBJ_S_C_ETIR);
+ }
+
+ /* Process DBG/EDBG record.
+ Return 0 on success, -1 on error. */
+
+ int
+ _bfd_vms_slurp_dbg (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
+ {
+ #if VMS_DEBUG
+ _bfd_vms_debug (2, "DBG/EDBG\n");
+ #endif
+
+ abfd->flags |= (HAS_DEBUG | HAS_LINENO);
+
+ return vms_slurp_debug (abfd);
+ }
+
+ /* Process TBT/ETBT record.
+ Return 0 on success, -1 on error. */
+
+ int
+ _bfd_vms_slurp_tbt (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
+ {
+ #if VMS_DEBUG
+ _bfd_vms_debug (2, "TBT/ETBT\n");
+ #endif
+
+ abfd->flags |= HAS_LINENO;
+
+ return vms_slurp_debug (abfd);
+ }
+
+ /* Write DBG/EDBG record. */
+
+ int
+ _bfd_vms_write_dbg (bfd *abfd ATTRIBUTE_UNUSED, int objtype ATTRIBUTE_UNUSED)
+ {
+ #if VMS_DEBUG
+ _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
+ #endif
+
+ return 0;
+ }
+
+ /* Write TBT/ETBT record. */
+
+ int
+ _bfd_vms_write_tbt (bfd *abfd ATTRIBUTE_UNUSED, int objtype ATTRIBUTE_UNUSED)
+ {
+ #if VMS_DEBUG
+ _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
+ #endif
+
+ return 0;
+ }
Index: bfd/vms-misc.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-misc.c,v
retrieving revision 1.29
diff -c -r1.29 vms-misc.c
*** bfd/vms-misc.c 30 Jul 2008 04:34:56 -0000 1.29
--- bfd/vms-misc.c 17 Feb 2009 11:13:09 -0000
***************
*** 1,7 ****
! /* vms-misc.c -- Miscellaneous functions for VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
! 2007, 2008 Free Software Foundation, Inc.
Written by Klaus K"ampf (kkaempf@rmi.de)
--- 1,9 ----
! /* vms-misc.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
! 2007, 2008, 2009 Free Software Foundation, Inc.
!
! Miscellaneous functions.
Written by Klaus K"ampf (kkaempf@rmi.de)
***************
*** 30,51 ****
#include "libbfd.h"
#include "vms.h"
!
#if VMS_DEBUG
/* Debug functions. */
! /* Debug function for all vms extensions
! evaluates environment variable VMS_DEBUG for a
! numerical value on the first call
! all error levels below this value are printed
! levels:
1 toplevel bfd calls (functions from the bfd vector)
2 functions called by bfd calls
...
9 almost everything
! level is also indentation level. Indentation is performed
if level > 0. */
void
--- 32,60 ----
#include "libbfd.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
/* Debug functions. */
! /* Debug function for all vms extensions evaluates environment
! variable VMS_DEBUG for a numerical value on the first call all
! error levels below this value are printed:
! Levels:
1 toplevel bfd calls (functions from the bfd vector)
2 functions called by bfd calls
...
9 almost everything
! Level is also indentation level. Indentation is performed
if level > 0. */
void
***************
*** 167,188 ****
/* Object file input functions. */
! /* Return type and length from record header (buf) on Alpha. */
void
_bfd_vms_get_header_values (bfd * abfd ATTRIBUTE_UNUSED,
unsigned char *buf,
int *type,
! int *length)
{
! if (type != 0)
*type = bfd_getl16 (buf);
! buf += 2;
! if (length != 0)
! *length = bfd_getl16 (buf);
#if VMS_DEBUG
! vms_debug (10, "_bfd_vms_get_header_values type %x, length %x\n", (type?*type:0), (length?*length:0));
#endif
}
--- 176,198 ----
/* Object file input functions. */
! /* Return type and size from record header (buf) on Alpha. */
void
_bfd_vms_get_header_values (bfd * abfd ATTRIBUTE_UNUSED,
unsigned char *buf,
int *type,
! int *size)
{
! if (type)
*type = bfd_getl16 (buf);
!
! if (size)
! *size = bfd_getl16 (buf+2);
#if VMS_DEBUG
! vms_debug (10, "_bfd_vms_get_header_values type %x, size %x\n",
! type ? *type : 0, size ? *size : 0);
#endif
}
***************
*** 193,429 ****
The openVMS object file has 'variable length' which means that
read() returns data in chunks of (hopefully) correct and expected
! size. The linker (and other tools on vms) depend on that. Unix doesn't
! know about 'formatted' files, so reading and writing such an object
! file in a unix environment is not trivial.
! With the tool 'file' (available on all vms ftp sites), one
! can view and change the attributes of a file. Changing from
'variable length' to 'fixed length, 512 bytes' reveals the
! record length at the first 2 bytes of every record. The same
! happens during the transfer of object files from vms to unix,
! at least with ucx, dec's implementation of tcp/ip.
! The vms format repeats the length at bytes 2 & 3 of every record.
On the first call (file_format == FF_UNKNOWN) we check if
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
! wrong attributes (FF_FOREIGN), else we should be in a vms
environment where read() returns the record size (FF_NATIVE).
! Reading is always done in 2 steps.
! First just the record header is read and the length extracted
! by get_header_values,
! then the read buffer is adjusted and the remaining bytes are
! read in.
! All file i/o is always done on even file positions. */
int
! _bfd_vms_get_record (bfd * abfd)
{
! int test_len, test_start, remaining;
! unsigned char *vms_buf;
#if VMS_DEBUG
! vms_debug (8, "_bfd_vms_get_record\n");
#endif
! /* Minimum is 6 bytes on Alpha
! (2 bytes length, 2 bytes record id, 2 bytes length repeated)
!
! On the VAX there's no length information in the record
! so start with OBJ_S_C_MAXRECSIZ. */
if (PRIV (buf_size) == 0)
{
! bfd_size_type amt;
!
! if (PRIV (is_vax))
! {
! amt = OBJ_S_C_MAXRECSIZ;
! PRIV (file_format) = FF_VAX;
! }
! else
! amt = 6;
! PRIV (vms_buf) = bfd_malloc (amt);
PRIV (buf_size) = amt;
}
! vms_buf = PRIV (vms_buf);
! if (vms_buf == 0)
! return -1;
!
! switch (PRIV (file_format))
{
! case FF_UNKNOWN:
! case FF_FOREIGN:
! test_len = 6; /* Probe 6 bytes. */
! test_start = 2; /* Where the record starts. */
! break;
! case FF_NATIVE:
! test_len = 4;
! test_start = 0;
! break;
! default:
! case FF_VAX:
! 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
{
! PRIV (file_format) = FF_NATIVE; /* N: native environment. */
! test_start = 0;
}
}
if (PRIV (is_vax))
{
! PRIV (rec_length) = bfd_bread (vms_buf, (bfd_size_type) PRIV (buf_size),
! abfd);
! if (PRIV (rec_length) <= 0)
{
bfd_set_error (bfd_error_file_truncated);
return 0;
}
! PRIV (vms_rec) = vms_buf;
}
else
{
! /* Alpha. */
! /* Extract vms record length. */
! _bfd_vms_get_header_values (abfd, vms_buf + test_start, NULL,
! & PRIV (rec_length));
! if (PRIV (rec_length) <= 0)
{
bfd_set_error (bfd_error_file_truncated);
return 0;
}
/* That's what the linker manual says. */
!
! if (PRIV (rec_length) > EOBJ_S_C_MAXRECSIZ)
{
bfd_set_error (bfd_error_file_truncated);
return 0;
}
! /* Adjust the buffer. */
! if (PRIV (rec_length) > PRIV (buf_size))
{
! PRIV (vms_buf) = bfd_realloc_or_free (vms_buf,
! (bfd_size_type) PRIV (rec_length));
! vms_buf = PRIV (vms_buf);
! if (vms_buf == 0)
! return -1;
! PRIV (buf_size) = PRIV (rec_length);
}
/* Read the remaining record. */
! remaining = PRIV (rec_length) - test_len + test_start;
#if VMS_DEBUG
! vms_debug (10, "bfd_bread remaining %d\n", remaining);
#endif
! if (bfd_bread (vms_buf + test_len, (bfd_size_type) remaining, abfd) !=
! (bfd_size_type) remaining)
{
bfd_set_error (bfd_error_file_truncated);
return 0;
}
! PRIV (vms_rec) = vms_buf + test_start;
}
#if VMS_DEBUG
! vms_debug (11, "bfd_bread rec_length %d\n", PRIV (rec_length));
#endif
! return PRIV (rec_length);
}
! /* Get next vms record from file
! update vms_rec and rec_length to new (remaining) values. */
! int
! _bfd_vms_next_record (bfd * abfd)
{
! #if VMS_DEBUG
! vms_debug (8, "_bfd_vms_next_record (len %d, size %d)\n",
! PRIV (rec_length), PRIV (rec_size));
! #endif
! if (PRIV (rec_length) > 0)
! PRIV (vms_rec) += PRIV (rec_size);
! else
{
! if (_bfd_vms_get_record (abfd) <= 0)
! return -1;
}
! if (!PRIV (vms_rec) || !PRIV (vms_buf)
! || PRIV (vms_rec) >= (PRIV (vms_buf) + PRIV (buf_size)))
! return -1;
! if (PRIV (is_vax))
{
! PRIV (rec_type) = *(PRIV (vms_rec));
! PRIV (rec_size) = PRIV (rec_length);
! }
! else
! _bfd_vms_get_header_values (abfd, PRIV (vms_rec), &PRIV (rec_type),
! &PRIV (rec_size));
! PRIV (rec_length) -= 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
! size is string length (size of record) */
char *
_bfd_vms_save_sized_string (unsigned char *str, int size)
--- 203,543 ----
The openVMS object file has 'variable length' which means that
read() returns data in chunks of (hopefully) correct and expected
! size. The linker (and other tools on VMS) depend on that. Unix
! doesn't know about 'formatted' files, so reading and writing such
! an object file in a Unix environment is not trivial.
! With the tool 'file' (available on all VMS FTP sites), one
! can view and change the attributes of a file. Changing from
'variable length' to 'fixed length, 512 bytes' reveals the
! record size at the first 2 bytes of every record. The same
! happens during the transfer of object files from VMS to Unix,
! at least with UCX, the DEC implementation of TCP/IP.
! The VMS format repeats the size at bytes 2 & 3 of every record.
On the first call (file_format == FF_UNKNOWN) we check if
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
! wrong attributes (FF_FOREIGN), else we should be in a VMS
environment where read() returns the record size (FF_NATIVE).
! Reading is always done in 2 steps:
! 1. first just the record header is read and the size extracted,
! 2. then the read buffer is adjusted and the remaining bytes are
! read in.
!
! 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
! _bfd_vms_get_first_record (bfd *abfd)
{
! unsigned int test_len;
#if VMS_DEBUG
! vms_debug (8, "_bfd_vms_get_first_record\n");
#endif
! if (PRIV (is_vax))
! test_len = 0;
! else
! /* Minimum is 6 bytes for objects (2 bytes size, 2 bytes record id,
! 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)
{
! /* On VAX there's no size information in the record, so
! start with OBJ_S_C_MAXRECSIZ. */
! bfd_size_type amt = (test_len ? test_len : OBJ_S_C_MAXRECSIZ);
! PRIV (vms_buf) = (unsigned char *) bfd_malloc (amt);
PRIV (buf_size) = amt;
}
! /* Initialize the record pointer. */
! PRIV (vms_rec) = PRIV (vms_buf);
! /* We only support modules on VAX. */
! if (PRIV (is_vax))
{
! if (vms_get_remaining_object_record (abfd, test_len) <= 0)
! return FT_UNKNOWN;
! #if VMS_DEBUG
! vms_debug (2, "file type is VAX module\n");
! #endif
! return FT_MODULE;
}
! 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;
! else
! {
! /* See _bfd_vms_get_first_record. */
! 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 (read_so_far != 0)
! abort ();
!
! PRIV (rec_size) = bfd_bread (PRIV (vms_buf), PRIV (buf_size), abfd);
!
! if (PRIV (rec_size) <= 0)
{
bfd_set_error (bfd_error_file_truncated);
return 0;
}
!
! /* Reset the record pointer. */
! PRIV (vms_rec) = PRIV (vms_buf);
}
else
{
! unsigned int to_read;
! /* Extract record size. */
! PRIV (rec_size) = bfd_getl16 (PRIV (vms_rec) + 2);
! if (PRIV (rec_size) <= 0)
{
bfd_set_error (bfd_error_file_truncated);
return 0;
}
/* That's what the linker manual says. */
! if (PRIV (rec_size) > EOBJ_S_C_MAXRECSIZ)
{
bfd_set_error (bfd_error_file_truncated);
return 0;
}
! /* Take into account object adjustment. */
! to_read = PRIV (rec_size);
! if (PRIV (file_format) == FF_FOREIGN)
! to_read += VMS_OBJECT_ADJUSTMENT;
! /* Adjust the buffer. */
! if (to_read > PRIV (buf_size))
{
! PRIV (vms_buf)
! = (unsigned char *) bfd_realloc (PRIV (vms_buf), to_read);
! if (PRIV (vms_buf) == NULL)
! return 0;
! PRIV (buf_size) = to_read;
}
/* Read the remaining record. */
! to_read -= read_so_far;
#if VMS_DEBUG
! vms_debug (8, "vms_get_remaining_obj_record: to_read %d\n", to_read);
#endif
!
! if (bfd_bread (PRIV (vms_buf) + read_so_far, to_read, abfd) != to_read)
{
bfd_set_error (bfd_error_file_truncated);
return 0;
}
!
! /* Reset the record pointer. */
! PRIV (vms_rec) = PRIV (vms_buf);
! maybe_adjust_record_pointer_for_object (abfd);
}
#if VMS_DEBUG
! vms_debug (8, "vms_get_remaining_obj_record: size %d\n", PRIV (rec_size));
#endif
! return PRIV (rec_size);
}
! /* Implement step #2 of the record reading procedure for images.
! Return the size of the record or 0 on failure. */
! static int
! vms_get_remaining_image_record (bfd *abfd, int read_so_far)
{
! unsigned int to_read;
! int remaining;
! /* Extract record size. */
! PRIV (rec_size) = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SIZE);
!
! if (PRIV (rec_size) > PRIV (buf_size))
{
! PRIV (vms_buf) = bfd_realloc (PRIV (vms_buf), PRIV (rec_size));
!
! if (PRIV (vms_buf) == NULL)
! {
! bfd_set_error (bfd_error_no_memory);
! return 0;
! }
!
! PRIV (buf_size) = PRIV (rec_size);
}
! /* Read the remaining 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 *
_bfd_vms_save_sized_string (unsigned char *str, int size)
***************
*** 438,445 ****
return newstr;
}
! /* Copy counted string (string with length at first byte) to new allocated area
! ptr points to length byte on entry */
char *
_bfd_vms_save_counted_string (unsigned char *ptr)
--- 552,559 ----
return newstr;
}
! /* Copy counted string (string with size at first byte) to new allocated area
! ptr points to size byte on entry */
char *
_bfd_vms_save_counted_string (unsigned char *ptr)
***************
*** 501,583 ****
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. */
/* Begin new record or record header
write 2 bytes rectype
write 2 bytes record length (filled in at flush)
! write 2 bytes header type (ommitted if rechead == -1). */
void
_bfd_vms_output_begin (bfd * abfd, int rectype, int rechead)
--- 615,626 ----
return value;
}
/* Object output routines. */
/* Begin new record or record header
write 2 bytes rectype
write 2 bytes record length (filled in at flush)
! write 2 bytes header type (ommitted if rechead == -1). */
void
_bfd_vms_output_begin (bfd * abfd, int rectype, int rechead)
***************
*** 691,708 ****
if (PRIV (push_level) == 0)
{
! if (0
! #ifndef VMS
! /* Write length first, see FF_FOREIGN in the input routines. */
! || fwrite (PRIV (output_buf) + 2, 2, 1,
! (FILE *) abfd->iostream) != 1
! #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;
}
else
--- 734,744 ----
if (PRIV (push_level) == 0)
{
! /* File is open in undefined (UDF) format on VMS, but ultimately will be
! converted to variable length (VAR) format. VAR format has a length
! word first which must be explicitly output in UDF format. */
! bfd_bwrite (PRIV (output_buf) + 2, 2, abfd);
! bfd_bwrite (PRIV (output_buf), (size_t) real_size, abfd);
PRIV (output_size) = 0;
}
else
***************
*** 948,954 ****
if (symbol == 0)
return symbol;
symbol->name = name;
! symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
return symbol;
}
--- 984,990 ----
if (symbol == 0)
return symbol;
symbol->name = name;
! symbol->section = (asection *)(unsigned long)-1;
return symbol;
}
Index: bfd/vms-tir.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-tir.c,v
retrieving revision 1.20
diff -c -r1.20 vms-tir.c
*** bfd/vms-tir.c 20 Feb 2008 17:42:36 -0000 1.20
--- bfd/vms-tir.c 17 Feb 2009 11:13:10 -0000
***************
*** 1,12 ****
/* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
! Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008
! Free Software Foundation, Inc.
TIR record handling functions
ETIR 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)
--- 1,12 ----
/* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
! Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007,
! 2008, 2009 Free Software Foundation, Inc.
TIR record handling functions
ETIR 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)
***************
*** 26,32 ****
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
-
/* The following type abbreviations are used:
cs counted string (ascii string with length byte)
--- 26,31 ----
***************
*** 41,46 ****
--- 40,72 ----
#include "bfdlink.h"
#include "libbfd.h"
#include "vms.h"
+
+ static int check_section (bfd *, int);
+ static void image_set_ptr (bfd *abfd, int psect, uquad offset);
+ static void image_inc_ptr (bfd *abfd, uquad offset);
+ static void dst_define_location (bfd *abfd, uquad loc);
+ static void dst_restore_location (bfd *abfd, uquad loc);
+ static unsigned int dst_retrieve_location (bfd *abfd, uquad loc);
+ static void dst_check_allocation (bfd *abfd, unsigned int size);
+ static void image_dump (bfd *abfd, unsigned char *ptr, int size, int offset);
+ static void image_write_b (bfd *abfd, unsigned int value);
+ static void image_write_w (bfd *abfd, unsigned int value);
+ static void image_write_l (bfd *abfd, unsigned long value);
+ static void image_write_q (bfd *abfd, uquad value);
+ static bfd_boolean etir_sta (bfd *, int, unsigned char *, int *);
+ static bfd_boolean etir_sto (bfd *, int, unsigned char *, int *);
+ static bfd_boolean etir_opr (bfd *, int, unsigned char *, int *);
+ static bfd_boolean etir_ctl (bfd *, int, unsigned char *, int *);
+ static bfd_boolean etir_stc (bfd *, int, unsigned char *, int *);
+ static asection *new_section (bfd *, int);
+ static int alloc_section (bfd *, unsigned int);
+ static int etir_cmd (bfd *, int, unsigned char *, int *);
+ static int analyze_tir (bfd *, unsigned char *, unsigned int);
+ static int analyze_etir (bfd *, unsigned char *, unsigned int);
+ static unsigned char *tir_opr (bfd *, unsigned char *);
+ static const char *tir_cmd_name (int);
+ static const char *cmd_name (int);
+
static int
check_section (bfd * abfd, int size)
***************
*** 92,97 ****
--- 118,194 ----
PRIV (image_ptr) += offset;
}
+ /* Save current DST location counter under specified index. */
+
+ static void
+ dst_define_location (bfd *abfd, uquad loc)
+ {
+ asection *dst_section = PRIV (dst_section);
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "dst_define_location (%d)\n", (int)loc);
+ #endif
+
+ /* Grow the ptr offset table if necessary. */
+ if (loc + 1 > PRIV (dst_ptr_offsets_count))
+ {
+ PRIV (dst_ptr_offsets) = bfd_realloc (PRIV (dst_ptr_offsets),
+ (loc + 1) * sizeof (unsigned int));
+ PRIV (dst_ptr_offsets_count) = loc + 1;
+ }
+
+ PRIV (dst_ptr_offsets)[loc] = PRIV (image_ptr) - dst_section->contents;
+ }
+
+ /* Restore saved DST location counter from specified index. */
+
+ static void
+ dst_restore_location (bfd *abfd, uquad loc)
+ {
+ asection *dst_section = PRIV (dst_section);
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "dst_restore_location (%d)\n", (int)loc);
+ #endif
+
+ PRIV (image_ptr) = dst_section->contents + PRIV (dst_ptr_offsets)[loc];
+ }
+
+ /* Retrieve saved DST location counter from specified index. */
+
+ static unsigned int
+ dst_retrieve_location (bfd *abfd, uquad loc)
+ {
+ #if VMS_DEBUG
+ _bfd_vms_debug (4, "dst_retrieve_location (%d)\n", (int)loc);
+ #endif
+
+ return PRIV (dst_ptr_offsets)[loc];
+ }
+
+ /* Check that the DST section is big enough for the specified
+ amount of bytes. */
+
+ static void
+ dst_check_allocation (bfd *abfd, unsigned int size)
+ {
+ asection *dst_section = PRIV (dst_section);
+
+ bfd_size_type used = PRIV (image_ptr) - dst_section->contents;
+ bfd_size_type left = dst_section->size - used;
+
+ /* Grow the DST section as necessary */
+ if (size > left)
+ {
+ dst_section->size *= 2;
+ dst_section->contents
+ = bfd_realloc (dst_section->contents, dst_section->size);
+ PRIV (image_ptr) = dst_section->contents + used;
+
+ dst_check_allocation (abfd, size);
+ }
+ }
+
/* Dump multiple bytes to section image. */
static void
***************
*** 109,114 ****
--- 206,214 ----
if (PRIV (is_vax) && check_section (abfd, size))
return;
+ if (PRIV (dst_section))
+ dst_check_allocation (abfd, size);
+
while (size-- > 0)
*PRIV (image_ptr)++ = *ptr++;
}
***************
*** 125,130 ****
--- 225,233 ----
if (PRIV (is_vax) && check_section (abfd, 1))
return;
+ if (PRIV (dst_section))
+ dst_check_allocation (abfd, 1);
+
*PRIV (image_ptr)++ = (value & 0xff);
}
***************
*** 140,145 ****
--- 243,251 ----
if (PRIV (is_vax) && check_section (abfd, 2))
return;
+ if (PRIV (dst_section))
+ dst_check_allocation (abfd, 2);
+
bfd_putl16 ((bfd_vma) value, PRIV (image_ptr));
PRIV (image_ptr) += 2;
}
***************
*** 156,161 ****
--- 262,270 ----
if (PRIV (is_vax) && check_section (abfd, 4))
return;
+ if (PRIV (dst_section))
+ dst_check_allocation (abfd, 4);
+
bfd_putl32 ((bfd_vma) value, PRIV (image_ptr));
PRIV (image_ptr) += 4;
}
***************
*** 172,177 ****
--- 281,289 ----
if (PRIV (is_vax) && check_section (abfd, 8))
return;
+ if (PRIV (dst_section))
+ dst_check_allocation (abfd, 8);
+
bfd_putl64 (value, PRIV (image_ptr));
PRIV (image_ptr) += 8;
}
***************
*** 182,187 ****
--- 294,301 ----
switch (cmd)
{
case ETIR_S_C_STA_GBL: return "ETIR_S_C_STA_GBL";
+ case ETIR_S_C_STA_LW: return "ETIR_S_C_STA_LW";
+ case ETIR_S_C_STA_QW: return "ETIR_S_C_STA_QW";
case ETIR_S_C_STA_PQ: return "ETIR_S_C_STA_PQ";
case ETIR_S_C_STA_LI: return "ETIR_S_C_STA_LI";
case ETIR_S_C_STA_MOD: return "ETIR_S_C_STA_MOD";
***************
*** 192,201 ****
--- 306,321 ----
case ETIR_S_C_STO_CA: return "ETIR_S_C_STO_CA";
case ETIR_S_C_STO_RB: return "ETIR_S_C_STO_RB";
case ETIR_S_C_STO_AB: return "ETIR_S_C_STO_AB";
+ case ETIR_S_C_STO_OFF: return "ETIR_S_C_STO_OFF";
+ case ETIR_S_C_STO_IMM: return "ETIR_S_C_STO_IMM";
+ case ETIR_S_C_STO_IMMR: return "ETIR_S_C_STO_IMMR";
+ case ETIR_S_C_STO_LW: return "ETIR_S_C_STO_LW";
+ case ETIR_S_C_STO_QW: return "ETIR_S_C_STO_QW";
case ETIR_S_C_STO_GBL_LW: return "ETIR_S_C_STO_GBL_LW";
case ETIR_S_C_STO_LP_PSB: return "ETIR_S_C_STO_LP_PSB";
case ETIR_S_C_STO_HINT_GBL: return "ETIR_S_C_STO_HINT_GBL";
case ETIR_S_C_STO_HINT_PS: return "ETIR_S_C_STO_HINT_PS";
+ case ETIR_S_C_OPR_ADD: return "ETIR_S_C_OPR_ADD";
case ETIR_S_C_OPR_INSV: return "ETIR_S_C_OPR_INSV";
case ETIR_S_C_OPR_USH: return "ETIR_S_C_OPR_USH";
case ETIR_S_C_OPR_ROT: return "ETIR_S_C_OPR_ROT";
***************
*** 215,248 ****
case ETIR_S_C_STC_BOH_GBL: return "ETIR_S_C_STC_BOH_GBL";
case ETIR_S_C_STC_BOH_PS: return "ETIR_S_C_STC_BOH_PS";
case ETIR_S_C_STC_NBH_GBL: return "ETIR_S_C_STC_NBH_GBL";
default:
/* These names have not yet been added to this switch statement. */
! abort ();
}
}
#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
/* etir_sta
! vms stack commands
! handle sta_xxx commands in etir section
! ptr points to data area in record
! see table B-8 of the openVMS linker manual. */
static bfd_boolean
! etir_sta (bfd * abfd, int cmd, unsigned char *ptr)
{
#if VMS_DEBUG
_bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd);
! _bfd_hexdump (8, ptr, 16, (int) ptr);
#endif
switch (cmd)
{
! /* stack global
arg: cs symbol name
stack 32 bit value of symbol (high bits set to 0). */
--- 335,375 ----
case ETIR_S_C_STC_BOH_GBL: return "ETIR_S_C_STC_BOH_GBL";
case ETIR_S_C_STC_BOH_PS: return "ETIR_S_C_STC_BOH_PS";
case ETIR_S_C_STC_NBH_GBL: return "ETIR_S_C_STC_NBH_GBL";
+ case ETIR_S_C_CTL_SETRB: return "ETIR_S_C_CTL_SETRB";
+ case ETIR_S_C_STC_LP_PSB: return "ETIR_S_C_STC_LP_PSB";
+ case ETIR_S_C_CTL_DFLOC: return "ETIR_S_C_CTL_DFLOC";
+ case ETIR_S_C_CTL_STLOC: return "ETIR_S_C_CTL_STLOC";
+ case ETIR_S_C_CTL_STKDL: return "ETIR_S_C_CTL_STKDL";
default:
/* These names have not yet been added to this switch statement. */
! (*_bfd_error_handler) (_("unknown ETIR command %d"), cmd);
}
+
+ return NULL;
}
#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
/* etir_sta
! Vms stack commands.
! Handle sta_xxx commands in etir section,
! ptr points to data area in record.
! See table B-8 of the openVMS linker manual. */
static bfd_boolean
! etir_sta (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
{
#if VMS_DEBUG
_bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd);
! _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
switch (cmd)
{
! /* Stack global
arg: cs symbol name
stack 32 bit value of symbol (high bits set to 0). */
***************
*** 265,301 ****
else
_bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
}
break;
! /* stack longword
arg: lw value
stack 32 bit value, sign extend to 64 bit. */
case ETIR_S_C_STA_LW:
_bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
break;
! /* stack global
arg: qw value
stack 64 bit value of symbol. */
case ETIR_S_C_STA_QW:
_bfd_vms_push (abfd, (uquad) bfd_getl64 (ptr), -1);
break;
! /* stack psect base plus quadword offset
arg: lw section index
qw signed quadword offset (low 32 bits)
! stack qw argument and section index
(see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB). */
case ETIR_S_C_STA_PQ:
{
uquad dummy;
! unsigned int psect;
psect = bfd_getl32 (ptr);
! if (psect >= PRIV (section_count))
{
(*_bfd_error_handler) (_("bad section index in %s"),
cmd_name (cmd));
--- 392,441 ----
else
_bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
}
+ *quarter_relocs = 1;
break;
! /* Stack longword
arg: lw value
stack 32 bit value, sign extend to 64 bit. */
case ETIR_S_C_STA_LW:
_bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
+ /* This one is special as it is both part of the section header
+ and of the ALPHA_R_REFLONG relocation. */
+ if (bfd_getl16 (ptr - 4 + bfd_getl16 (ptr - 2)) == ETIR_S_C_CTL_DFLOC)
+ *quarter_relocs = 0;
+ else if (*quarter_relocs)
+ *quarter_relocs += 1;
+ else
+ *quarter_relocs = 2;
break;
! /* Stack quadword
arg: qw value
stack 64 bit value of symbol. */
case ETIR_S_C_STA_QW:
_bfd_vms_push (abfd, (uquad) bfd_getl64 (ptr), -1);
+ if (*quarter_relocs)
+ *quarter_relocs += 1;
+ else
+ *quarter_relocs = 2;
break;
! /* Stack psect base plus quadword offset
arg: lw section index
qw signed quadword offset (low 32 bits)
! Stack qw argument and section index
(see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB). */
case ETIR_S_C_STA_PQ:
{
uquad dummy;
! int psect;
psect = bfd_getl32 (ptr);
! if ((unsigned int) psect >= PRIV (section_count))
{
(*_bfd_error_handler) (_("bad section index in %s"),
cmd_name (cmd));
***************
*** 305,327 ****
dummy = bfd_getl64 (ptr + 4);
_bfd_vms_push (abfd, dummy, (int) psect);
}
break;
case ETIR_S_C_STA_LI:
case ETIR_S_C_STA_MOD:
case ETIR_S_C_STA_CKARG:
(*_bfd_error_handler) (_("unsupported STA cmd %s"), cmd_name (cmd));
return FALSE;
- break;
default:
(*_bfd_error_handler) (_("reserved STA cmd %d"), cmd);
return FALSE;
- break;
}
#if VMS_DEBUG
_bfd_vms_debug (5, "etir_sta true\n");
#endif
return TRUE;
}
--- 445,475 ----
dummy = bfd_getl64 (ptr + 4);
_bfd_vms_push (abfd, dummy, (int) psect);
}
+ /* This one is special as it is both part of the section header
+ and of the ALPHA_R_REFLONG and ALPHA_R_REFQUAD relocations. */
+ if (bfd_getl16 (ptr - 4 + bfd_getl16 (ptr - 2)) == ETIR_S_C_CTL_SETRB)
+ *quarter_relocs = 0;
+ else
+ *quarter_relocs = 2;
break;
case ETIR_S_C_STA_LI:
case ETIR_S_C_STA_MOD:
case ETIR_S_C_STA_CKARG:
(*_bfd_error_handler) (_("unsupported STA cmd %s"), cmd_name (cmd));
+ *quarter_relocs = 0;
return FALSE;
default:
(*_bfd_error_handler) (_("reserved STA cmd %d"), cmd);
+ *quarter_relocs = 0;
return FALSE;
}
+
#if VMS_DEBUG
_bfd_vms_debug (5, "etir_sta true\n");
#endif
+
return TRUE;
}
***************
*** 335,348 ****
see table B-9 of the openVMS linker manual. */
static bfd_boolean
! etir_sto (bfd * abfd, int cmd, unsigned char *ptr)
{
uquad dummy;
int psect;
#if VMS_DEBUG
_bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd);
! _bfd_hexdump (8, ptr, 16, (int) ptr);
#endif
switch (cmd)
--- 483,496 ----
see table B-9 of the openVMS linker manual. */
static bfd_boolean
! etir_sto (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
{
uquad dummy;
int psect;
#if VMS_DEBUG
_bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd);
! _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
switch (cmd)
***************
*** 353,358 ****
--- 501,507 ----
dummy = _bfd_vms_pop (abfd, &psect);
/* FIXME: check top bits. */
image_write_b (abfd, (unsigned int) dummy & 0xff);
+ *quarter_relocs = 0;
break;
/* Store word: pop stack, write word
***************
*** 361,366 ****
--- 510,516 ----
dummy = _bfd_vms_pop (abfd, &psect);
/* FIXME: check top bits */
image_write_w (abfd, (unsigned int) dummy & 0xffff);
+ *quarter_relocs = 0;
break;
/* Store longword: pop stack, write longword
***************
*** 370,375 ****
--- 520,529 ----
dummy += (PRIV (sections)[psect])->vma;
/* FIXME: check top bits. */
image_write_l (abfd, (unsigned int) dummy & 0xffffffff);
+ if (*quarter_relocs == 2)
+ *quarter_relocs = 4;
+ else
+ *quarter_relocs += 1;
break;
/* Store quadword: pop stack, write quadword
***************
*** 379,384 ****
--- 533,542 ----
dummy += (PRIV (sections)[psect])->vma;
/* FIXME: check top bits. */
image_write_q (abfd, dummy);
+ if (*quarter_relocs == 2)
+ *quarter_relocs = 4;
+ else
+ *quarter_relocs += 1;
break;
/* Store immediate repeated: pop stack for repeat count
***************
*** 393,398 ****
--- 551,557 ----
while (dummy-- > 0)
image_dump (abfd, ptr+4, size, 0);
}
+ *quarter_relocs = 0;
break;
/* Store global: write symbol value
***************
*** 406,420 ****
entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
name, FALSE, FALSE);
if (entry == NULL)
! {
! (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
! cmd_name (cmd), name);
! return FALSE;
! }
else
/* FIXME, reloc. */
image_write_q (abfd, (uquad) (entry->symbol->value));
}
break;
/* Store code address: write address of entry point
--- 565,577 ----
entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
name, FALSE, FALSE);
if (entry == NULL)
! /* FIXME, reloc. */
! image_write_q (abfd, (uquad) (0));
else
/* FIXME, reloc. */
image_write_q (abfd, (uquad) (entry->symbol->value));
}
+ *quarter_relocs = 4;
break;
/* Store code address: write address of entry point
***************
*** 428,442 ****
entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
name, FALSE, FALSE);
if (entry == NULL)
! {
! (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
! cmd_name (cmd), name);
! return FALSE;
! }
else
/* FIXME, reloc. */
image_write_q (abfd, (uquad) (entry->symbol->value));
}
break;
/* Store offset to psect: pop stack, add low 32 bits to base of psect
--- 585,597 ----
entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
name, FALSE, FALSE);
if (entry == NULL)
! /* FIXME, reloc. */
! image_write_q (abfd, (uquad) (0));
else
/* FIXME, reloc. */
image_write_q (abfd, (uquad) (entry->symbol->value));
}
+ *quarter_relocs = 4;
break;
/* Store offset to psect: pop stack, add low 32 bits to base of psect
***************
*** 450,455 ****
--- 605,611 ----
q += (PRIV (sections)[psect1])->vma;
image_write_q (abfd, q);
}
+ *quarter_relocs += 2;
break;
/* Store immediate
***************
*** 462,467 ****
--- 618,624 ----
size = bfd_getl32 (ptr);
image_dump (abfd, ptr+4, size, 0);
}
+ *quarter_relocs = 0;
break;
/* This code is 'reserved to digital' according to the openVMS
***************
*** 489,510 ****
/* FIXME, reloc. */
image_write_l (abfd, (unsigned long) (entry->symbol->value));
}
break;
case ETIR_S_C_STO_RB:
case ETIR_S_C_STO_AB:
case ETIR_S_C_STO_LP_PSB:
(*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
! break;
case ETIR_S_C_STO_HINT_GBL:
case ETIR_S_C_STO_HINT_PS:
(*_bfd_error_handler) (_("%s: not implemented"), cmd_name (cmd));
! break;
default:
(*_bfd_error_handler) (_("reserved STO cmd %d"), cmd);
! break;
}
return TRUE;
--- 646,671 ----
/* FIXME, reloc. */
image_write_l (abfd, (unsigned long) (entry->symbol->value));
}
+ *quarter_relocs = 4;
break;
case ETIR_S_C_STO_RB:
case ETIR_S_C_STO_AB:
case ETIR_S_C_STO_LP_PSB:
(*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
! *quarter_relocs = 0;
! return FALSE;
case ETIR_S_C_STO_HINT_GBL:
case ETIR_S_C_STO_HINT_PS:
(*_bfd_error_handler) (_("%s: not implemented"), cmd_name (cmd));
! *quarter_relocs = 0;
! return FALSE;
default:
(*_bfd_error_handler) (_("reserved STO cmd %d"), cmd);
! *quarter_relocs = 0;
! return FALSE;
}
return TRUE;
***************
*** 518,532 ****
see table B-10 of the openVMS linker manual. */
static bfd_boolean
! etir_opr (bfd * abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED)
{
long op1, op2;
#if VMS_DEBUG
_bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd);
! _bfd_hexdump (8, ptr, 16, (int) ptr);
#endif
switch (cmd)
{
case ETIR_S_C_OPR_NOP: /* No-op. */
--- 679,700 ----
see table B-10 of the openVMS linker manual. */
static bfd_boolean
! etir_opr (bfd *abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED,
! int *quarter_relocs)
{
long op1, op2;
#if VMS_DEBUG
_bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd);
! _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
+ /* No relocation uses OPR commands except ETIR_S_C_OPR_ADD. */
+ if (cmd == ETIR_S_C_OPR_ADD)
+ *quarter_relocs += 1;
+ else
+ *quarter_relocs = 0;
+
switch (cmd)
{
case ETIR_S_C_OPR_NOP: /* No-op. */
***************
*** 604,610 ****
case ETIR_S_C_OPR_REDEF: /* Redefine symbol to current location. */
case ETIR_S_C_OPR_DFLIT: /* Define a literal. */
(*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
! break;
case ETIR_S_C_OPR_SEL: /* Select. */
if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
--- 772,778 ----
case ETIR_S_C_OPR_REDEF: /* Redefine symbol to current location. */
case ETIR_S_C_OPR_DFLIT: /* Define a literal. */
(*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
! return FALSE;
case ETIR_S_C_OPR_SEL: /* Select. */
if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
***************
*** 619,625 ****
default:
(*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd);
! break;
}
return TRUE;
--- 787,793 ----
default:
(*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd);
! return FALSE;
}
return TRUE;
***************
*** 630,645 ****
See table B-11 of the openVMS linker manual. */
static bfd_boolean
! etir_ctl (bfd * abfd, int cmd, unsigned char *ptr)
{
! uquad dummy;
int psect;
#if VMS_DEBUG
_bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd);
! _bfd_hexdump (8, ptr, 16, (int) ptr);
#endif
switch (cmd)
{
/* Det relocation base: pop stack, set image location counter
--- 798,816 ----
See table B-11 of the openVMS linker manual. */
static bfd_boolean
! etir_ctl (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
{
! uquad dummy;
int psect;
#if VMS_DEBUG
_bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd);
! _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
+ /* No relocation uses CTL commands. */
+ *quarter_relocs = 0;
+
switch (cmd)
{
/* Det relocation base: pop stack, set image location counter
***************
*** 660,686 ****
arg: none. */
case ETIR_S_C_CTL_DFLOC:
dummy = _bfd_vms_pop (abfd, NULL);
! /* FIXME */
break;
/* Set location: pop index, restore location counter from index
arg: none. */
case ETIR_S_C_CTL_STLOC:
! dummy = _bfd_vms_pop (abfd, &psect);
! /* FIXME */
break;
/* Stack defined location: pop index, push location counter from index
arg: none. */
case ETIR_S_C_CTL_STKDL:
! dummy = _bfd_vms_pop (abfd, &psect);
! /* FIXME. */
break;
default:
(*_bfd_error_handler) (_("reserved CTL cmd %d"), cmd);
! break;
}
return TRUE;
}
--- 831,858 ----
arg: none. */
case ETIR_S_C_CTL_DFLOC:
dummy = _bfd_vms_pop (abfd, NULL);
! dst_define_location (abfd, dummy);
break;
/* Set location: pop index, restore location counter from index
arg: none. */
case ETIR_S_C_CTL_STLOC:
! dummy = _bfd_vms_pop (abfd, NULL);
! dst_restore_location (abfd, dummy);
break;
/* Stack defined location: pop index, push location counter from index
arg: none. */
case ETIR_S_C_CTL_STKDL:
! dummy = _bfd_vms_pop (abfd, NULL);
! _bfd_vms_push (abfd, dst_retrieve_location (abfd, dummy), -1);
break;
default:
(*_bfd_error_handler) (_("reserved CTL cmd %d"), cmd);
! return FALSE;
}
+
return TRUE;
}
***************
*** 689,699 ****
See table B-12 and B-13 of the openVMS linker manual. */
static bfd_boolean
! etir_stc (bfd * abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED)
{
#if VMS_DEBUG
_bfd_vms_debug (5, "etir_stc %d/%x\n", cmd, cmd);
! _bfd_hexdump (8, ptr, 16, (int) ptr);
#endif
switch (cmd)
--- 861,872 ----
See table B-12 and B-13 of the openVMS linker manual. */
static bfd_boolean
! etir_stc (bfd *abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED,
! int *quarter_relocs)
{
#if VMS_DEBUG
_bfd_vms_debug (5, "etir_stc %d/%x\n", cmd, cmd);
! _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
switch (cmd)
***************
*** 701,732 ****
/* 200 Store-conditional Linkage Pair
arg: none. */
case ETIR_S_C_STC_LP:
- (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
- break;
-
- /* 201 Store-conditional Linkage Pair with Procedure Signature
- arg: lw linkage index
- cs procedure name
- by signature length
- da signature. */
- case ETIR_S_C_STC_LP_PSB:
- image_inc_ptr (abfd, (uquad) 16); /* skip entry,procval */
- break;
/* 202 Store-conditional Address at global address
arg: lw linkage index
cs global name. */
case ETIR_S_C_STC_GBL:
- (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
- break;
/* 203 Store-conditional Code Address at global address
arg: lw linkage index
cs procedure name. */
case ETIR_S_C_STC_GCA:
- (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
- break;
/* 204 Store-conditional Address at psect + offset
arg: lw linkage index
--- 874,890 ----
***************
*** 734,789 ****
qw offset. */
case ETIR_S_C_STC_PS:
(*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
break;
/* 205 Store-conditional NOP at address of global
arg: none. */
case ETIR_S_C_STC_NOP_GBL:
!
! /* 206 Store-conditional NOP at pect + offset
! arg: none. */
! case ETIR_S_C_STC_NOP_PS:
/* 207 Store-conditional BSR at global address
arg: none. */
- case ETIR_S_C_STC_BSR_GBL:
! /* 208 Store-conditional BSR at pect + offset
! arg: none. */
! case ETIR_S_C_STC_BSR_PS:
/* 209 Store-conditional LDA at global address
arg: none. */
- case ETIR_S_C_STC_LDA_GBL:
! /* 210 Store-conditional LDA at psect + offset
! arg: none. */
! case ETIR_S_C_STC_LDA_PS:
/* 211 Store-conditional BSR or Hint at global address
arg: none. */
- case ETIR_S_C_STC_BOH_GBL:
! /* 212 Store-conditional BSR or Hint at pect + offset
! arg: none. */
! case ETIR_S_C_STC_BOH_PS:
/* 213 Store-conditional NOP,BSR or HINT at global address
arg: none. */
case ETIR_S_C_STC_NBH_GBL:
! /* 214 Store-conditional NOP,BSR or HINT at psect + offset
arg: none. */
case ETIR_S_C_STC_NBH_PS:
! /* FIXME */
! break;
default:
! #if VMS_DEBUG
! _bfd_vms_debug (3, "reserved STC cmd %d", cmd);
! #endif
! break;
}
return TRUE;
}
--- 892,973 ----
qw offset. */
case ETIR_S_C_STC_PS:
(*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
+ *quarter_relocs = 0;
+ return FALSE;
+
+ /* 201 Store-conditional Linkage Pair with Procedure Signature
+ arg: lw linkage index
+ cs procedure name
+ by signature length
+ da signature. */
+
+ case ETIR_S_C_STC_LP_PSB:
+ image_inc_ptr (abfd, (uquad) 16); /* skip entry,procval */
+ *quarter_relocs = 4;
break;
/* 205 Store-conditional NOP at address of global
arg: none. */
case ETIR_S_C_STC_NOP_GBL:
! /* ALPHA_R_NOP */
/* 207 Store-conditional BSR at global address
arg: none. */
! case ETIR_S_C_STC_BSR_GBL:
! /* ALPHA_R_BSR */
/* 209 Store-conditional LDA at global address
arg: none. */
! case ETIR_S_C_STC_LDA_GBL:
! /* ALPHA_R_LDA */
/* 211 Store-conditional BSR or Hint at global address
arg: none. */
! case ETIR_S_C_STC_BOH_GBL:
! *quarter_relocs = 4;
! break;
/* 213 Store-conditional NOP,BSR or HINT at global address
arg: none. */
+
case ETIR_S_C_STC_NBH_GBL:
! /* 206 Store-conditional NOP at pect + offset
! arg: none. */
!
! case ETIR_S_C_STC_NOP_PS:
!
! /* 208 Store-conditional BSR at pect + offset
! arg: none. */
!
! case ETIR_S_C_STC_BSR_PS:
!
! /* 210 Store-conditional LDA at psect + offset
! arg: none. */
!
! case ETIR_S_C_STC_LDA_PS:
!
! /* 212 Store-conditional BSR or Hint at pect + offset
! arg: none. */
!
! case ETIR_S_C_STC_BOH_PS:
!
! /* 214 Store-conditional NOP, BSR or HINT at psect + offset
arg: none. */
case ETIR_S_C_STC_NBH_PS:
! (*_bfd_error_handler) ("%s: not supported", cmd_name (cmd));
! *quarter_relocs = 0;
! return FALSE;
default:
! (*_bfd_error_handler) (_("reserved STC cmd %d"), cmd);
! *quarter_relocs = 0;
! return FALSE;
}
+
return TRUE;
}
***************
*** 851,860 ****
/* tir_sta
! vax stack commands
! Handle sta_xxx commands in tir section
! ptr points to data area in record
See table 7-3 of the VAX/VMS linker manual. */
--- 1035,1044 ----
/* tir_sta
! Vax stack commands.
! Handle sta_xxx commands in tir section,
! ptr points to data area in record.
See table 7-3 of the VAX/VMS linker manual. */
***************
*** 924,930 ****
by signed byte offset. */
{
unsigned long dummy;
! unsigned int psect;
if (cmd == TIR_S_C_STA_PB)
psect = *ptr++;
--- 1108,1114 ----
by signed byte offset. */
{
unsigned long dummy;
! int psect;
if (cmd == TIR_S_C_STA_PB)
psect = *ptr++;
***************
*** 934,945 ****
ptr += 2;
}
! if (psect >= PRIV (section_count))
alloc_section (abfd, psect);
dummy = (long) *ptr++;
dummy += (PRIV (sections)[psect])->vma;
! _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
}
break;
--- 1118,1129 ----
ptr += 2;
}
! if ((unsigned int) psect >= PRIV (section_count))
alloc_section (abfd, psect);
dummy = (long) *ptr++;
dummy += (PRIV (sections)[psect])->vma;
! _bfd_vms_push (abfd, (uquad) dummy, psect);
}
break;
***************
*** 951,957 ****
sh signed short offset. */
{
unsigned long dummy;
! unsigned int psect;
if (cmd == TIR_S_C_STA_PW)
psect = *ptr++;
--- 1135,1141 ----
sh signed short offset. */
{
unsigned long dummy;
! int psect;
if (cmd == TIR_S_C_STA_PW)
psect = *ptr++;
***************
*** 961,972 ****
ptr += 2;
}
! if (psect >= PRIV (section_count))
alloc_section (abfd, psect);
dummy = bfd_getl16 (ptr); ptr+=2;
dummy += (PRIV (sections)[psect])->vma;
! _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
}
break;
--- 1145,1156 ----
ptr += 2;
}
! if ((unsigned int) psect >= PRIV (section_count))
alloc_section (abfd, psect);
dummy = bfd_getl16 (ptr); ptr+=2;
dummy += (PRIV (sections)[psect])->vma;
! _bfd_vms_push (abfd, (uquad) dummy, psect);
}
break;
***************
*** 978,984 ****
lw signed longword offset. */
{
unsigned long dummy;
! unsigned int psect;
if (cmd == TIR_S_C_STA_PL)
psect = *ptr++;
--- 1162,1168 ----
lw signed longword offset. */
{
unsigned long dummy;
! int psect;
if (cmd == TIR_S_C_STA_PL)
psect = *ptr++;
***************
*** 988,999 ****
ptr += 2;
}
! if (psect >= PRIV (section_count))
alloc_section (abfd, psect);
dummy = bfd_getl32 (ptr); ptr += 4;
dummy += (PRIV (sections)[psect])->vma;
! _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
}
break;
--- 1172,1183 ----
ptr += 2;
}
! if ((unsigned int) psect >= PRIV (section_count))
alloc_section (abfd, psect);
dummy = bfd_getl32 (ptr); ptr += 4;
dummy += (PRIV (sections)[psect])->vma;
! _bfd_vms_push (abfd, (uquad) dummy, psect);
}
break;
***************
*** 1457,1463 ****
tir_ctl (bfd * abfd, unsigned char *ptr)
{
unsigned long dummy;
! unsigned int psect;
#if VMS_DEBUG
_bfd_vms_debug (5, "tir_ctl %d\n", *ptr);
--- 1641,1647 ----
tir_ctl (bfd * abfd, unsigned char *ptr)
{
unsigned long dummy;
! int psect;
#if VMS_DEBUG
_bfd_vms_debug (5, "tir_ctl %d\n", *ptr);
***************
*** 1468,1477 ****
case TIR_S_C_CTL_SETRB:
/* Set relocation base: pop stack, set image location counter
arg: none. */
! dummy = _bfd_vms_pop (abfd, (int *) &psect);
! if (psect >= PRIV (section_count))
alloc_section (abfd, psect);
! image_set_ptr (abfd, (int) psect, (uquad) dummy);
break;
case TIR_S_C_CTL_AUGRB:
--- 1652,1661 ----
case TIR_S_C_CTL_SETRB:
/* Set relocation base: pop stack, set image location counter
arg: none. */
! dummy = _bfd_vms_pop (abfd, &psect);
! if ((unsigned int) psect >= PRIV (section_count))
alloc_section (abfd, psect);
! image_set_ptr (abfd, psect, (uquad) dummy);
break;
case TIR_S_C_CTL_AUGRB:
***************
*** 1492,1498 ****
case TIR_S_C_CTL_STLOC:
/* Set location: pop index, restore location counter from index
arg: none. */
! dummy = _bfd_vms_pop (abfd, (int *) &psect);
(*_bfd_error_handler) (_("%s: not fully implemented"),
tir_cmd_name (ptr[-1]));
break;
--- 1676,1682 ----
case TIR_S_C_CTL_STLOC:
/* Set location: pop index, restore location counter from index
arg: none. */
! dummy = _bfd_vms_pop (abfd, &psect);
(*_bfd_error_handler) (_("%s: not fully implemented"),
tir_cmd_name (ptr[-1]));
break;
***************
*** 1500,1506 ****
case TIR_S_C_CTL_STKDL:
/* Stack defined location: pop index, push location counter from index
arg: none. */
! dummy = _bfd_vms_pop (abfd, (int *) &psect);
(*_bfd_error_handler) (_("%s: not fully implemented"),
tir_cmd_name (ptr[-1]));
break;
--- 1684,1690 ----
case TIR_S_C_CTL_STKDL:
/* Stack defined location: pop index, push location counter from index
arg: none. */
! dummy = _bfd_vms_pop (abfd, &psect);
(*_bfd_error_handler) (_("%s: not fully implemented"),
tir_cmd_name (ptr[-1]));
break;
***************
*** 1517,1523 ****
static unsigned char *
tir_cmd (bfd * abfd, unsigned char *ptr)
{
! struct
{
int mincod;
int maxcod;
--- 1701,1707 ----
static unsigned char *
tir_cmd (bfd * abfd, unsigned char *ptr)
{
! static const struct
{
int mincod;
int maxcod;
***************
*** 1535,1541 ****
#if VMS_DEBUG
_bfd_vms_debug (4, "tir_cmd %d/%x\n", *ptr, *ptr);
! _bfd_hexdump (8, ptr, 16, (int) ptr);
#endif
if (*ptr & 0x80)
--- 1719,1725 ----
#if VMS_DEBUG
_bfd_vms_debug (4, "tir_cmd %d/%x\n", *ptr, *ptr);
! _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
if (*ptr & 0x80)
***************
*** 1570,1582 ****
/* Handle command from ETIR section. */
static int
! etir_cmd (bfd * abfd, int cmd, unsigned char *ptr)
{
! static struct
{
int mincod;
int maxcod;
! bfd_boolean (*explain) (bfd *, int, unsigned char *);
}
etir_table[] =
{
--- 1754,1766 ----
/* Handle command from ETIR section. */
static int
! etir_cmd (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
{
! static const struct
{
int mincod;
int maxcod;
! bfd_boolean (*explain) (bfd *, int, unsigned char *, int *);
}
etir_table[] =
{
***************
*** 1591,1598 ****
int i = 0;
#if VMS_DEBUG
! _bfd_vms_debug (4, "etir_cmd %d/%x\n", cmd, cmd);
! _bfd_hexdump (8, ptr, 16, (int) ptr);
#endif
while (etir_table[i].mincod >= 0)
--- 1775,1782 ----
int i = 0;
#if VMS_DEBUG
! _bfd_vms_debug (4, "etir_cmd: %s(%d)\n", cmd_name (cmd), cmd);
! _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
while (etir_table[i].mincod >= 0)
***************
*** 1600,1606 ****
if ( (etir_table[i].mincod <= cmd)
&& (cmd <= etir_table[i].maxcod))
{
! if (!etir_table[i].explain (abfd, cmd, ptr))
return -1;
break;
}
--- 1784,1790 ----
if ( (etir_table[i].mincod <= cmd)
&& (cmd <= etir_table[i].maxcod))
{
! if (!etir_table[i].explain (abfd, cmd, ptr, quarter_relocs))
return -1;
break;
}
***************
*** 1608,1614 ****
}
#if VMS_DEBUG
! _bfd_vms_debug (4, "etir_cmd: = 0\n");
#endif
return 0;
}
--- 1792,1798 ----
}
#if VMS_DEBUG
! _bfd_vms_debug (4, "etir_cmd: result = 0\n");
#endif
return 0;
}
***************
*** 1643,1670 ****
static int
analyze_etir (bfd * abfd, unsigned char *ptr, unsigned int length)
{
! int cmd;
! unsigned char *maxptr;
int result = 0;
#if VMS_DEBUG
_bfd_vms_debug (3, "analyze_etir: %d bytes\n", length);
#endif
- maxptr = ptr + length;
-
while (ptr < maxptr)
{
! cmd = bfd_getl16 (ptr);
! length = bfd_getl16 (ptr + 2);
! result = etir_cmd (abfd, cmd, ptr+4);
if (result != 0)
break;
! ptr += length;
}
#if VMS_DEBUG
! _bfd_vms_debug (3, "analyze_etir: = %d\n", result);
#endif
return result;
--- 1827,1893 ----
static int
analyze_etir (bfd * abfd, unsigned char *ptr, unsigned int length)
{
! unsigned char *maxptr = ptr + length;
! /* Relocations are made of 1, 2 or 4 ETIR commands.
! We therefore count them using quarters. */
! int quarter_relocs = 0;
int result = 0;
#if VMS_DEBUG
_bfd_vms_debug (3, "analyze_etir: %d bytes\n", length);
#endif
while (ptr < maxptr)
{
! int cmd = bfd_getl16 (ptr);
! int cmd_length = bfd_getl16 (ptr + 2);
! result = etir_cmd (abfd, cmd, ptr + 4, &quarter_relocs);
if (result != 0)
break;
!
! /* If we have a relocation, we record its length to size
! future buffers and bump the reloc count of the section. */
! if (quarter_relocs)
! {
! vms_section_data (PRIV (image_section))->reloc_size += cmd_length;
! abfd->flags |= HAS_RELOC;
!
! if (quarter_relocs == 4)
! {
! PRIV (image_section)->reloc_count++;
!
! #if VMS_DEBUG
! _bfd_vms_debug (4, "-> reloc %d at 0x%x\n",
! PRIV (image_section)->reloc_count-1,
! ptr - (maxptr - length));
! #endif
!
! quarter_relocs = 0;
! }
! else if (quarter_relocs > 4)
! {
!
! #if VMS_DEBUG
! _bfd_vms_debug (4, "Reloc count error (%d) in section %s\n",
! PRIV (image_section)->reloc_count,
! PRIV (image_section)->name);
! #endif
!
! quarter_relocs = 0;
! }
! }
!
! /* If we have a Store Immediate, we reserve space for the
! count argument. */
! else if (cmd == ETIR_S_C_STO_IMM)
! vms_section_data (PRIV (image_section))->reloc_size
! += ETIR_S_C_HEADER_SIZE + 4;
!
! ptr += cmd_length;
}
#if VMS_DEBUG
! _bfd_vms_debug (3, "analyze_etir: result = %d\n", result);
#endif
return result;
***************
*** 1685,1692 ****
switch (objtype)
{
case EOBJ_S_C_ETIR:
! PRIV (vms_rec) += 4; /* Skip type, size. */
! PRIV (rec_size) -= 4;
result = analyze_etir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
break;
case OBJ_S_C_TIR:
--- 1908,1915 ----
switch (objtype)
{
case EOBJ_S_C_ETIR:
! PRIV (vms_rec) += ETIR_S_C_HEADER_SIZE;
! PRIV (rec_size) -= ETIR_S_C_HEADER_SIZE;
result = analyze_etir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
break;
case OBJ_S_C_TIR:
***************
*** 1702,1734 ****
return result;
}
! /* Process EDBG record
! Return 0 on success, -1 on error
!
! Not implemented yet. */
int
! _bfd_vms_slurp_dbg (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
{
#if VMS_DEBUG
! _bfd_vms_debug (2, "DBG/EDBG\n");
#endif
- abfd->flags |= (HAS_DEBUG | HAS_LINENO);
return 0;
}
! /* Process ETBT record
! Return 0 on success, -1 on error
!
! Not implemented yet. */
int
! _bfd_vms_slurp_tbt (bfd * abfd ATTRIBUTE_UNUSED,
! int objtype ATTRIBUTE_UNUSED)
{
#if VMS_DEBUG
! _bfd_vms_debug (2, "TBT/ETBT\n");
#endif
return 0;
--- 1925,2285 ----
return result;
}
! /* Slurp relocs from ETIR sections and (temporarily) save them
! in the per-section reloc buffer. */
int
! _bfd_vms_slurp_relocs (bfd *abfd)
{
+ struct vms_section_data_struct *vsd;
+ unsigned char *begin = PRIV (vms_rec) + 4;
+ unsigned char *end = PRIV (vms_rec) + PRIV (rec_size);
+ unsigned char *ptr;
+ int cmd, length, slurped_length;
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "_bfd_vms_slurp_relocs: %d bytes\n", PRIV (rec_size));
+ #endif
+
+ for (ptr = begin; ptr < end; ptr += length)
+ {
+ cmd = bfd_getl16 (ptr);
+ length = bfd_getl16 (ptr + 2);
+ slurped_length = length;
+
+ switch (cmd)
+ {
+ case ETIR_S_C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */
+ /* This one is special as it is both part of the section header
+ and of the ALPHA_R_REFLONG and ALPHA_R_REFQUAD relocations. */
+ if (bfd_getl16 (ptr + length) == ETIR_S_C_CTL_SETRB)
+ {
+ int psect = bfd_getl32 (ptr + ETIR_S_C_HEADER_SIZE);
+ PRIV (image_section) = PRIV (sections)[psect];
+ continue;
+ }
+
+ case ETIR_S_C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */
+ /* ALPHA_R_REFQUAD und_section, step 1 */
+ break;
+
+ case ETIR_S_C_STA_LW: /* ALPHA_R_REFLONG und_section, step 2 */
+ /* ALPHA_R_REFLONG abs_section, step 1 */
+ /* This one is special as it is both part of the section header
+ and of the ALPHA_R_REFLONG relocation. */
+ if (bfd_getl16 (ptr + length) == ETIR_S_C_CTL_DFLOC)
+ {
+ PRIV (image_section) = PRIV (dst_section);
+ continue;
+ }
+
+ case ETIR_S_C_STA_QW: /* ALPHA_R_REFQUAD und_section, step 2 */
+ /* ALPHA_R_REFQUAD abs_section, step 1 */
+
+ case ETIR_S_C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */
+ /* ALPHA_R_REFLONG abs_section, step 2 */
+ /* ALPHA_R_REFLONG others, step 2 */
+
+ case ETIR_S_C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */
+ /* ALPHA_R_REFQUAD abs_section, step 2 */
+
+ case ETIR_S_C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */
+
+ case ETIR_S_C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */
+ /* ALPHA_R_REFQUAD und_section, step 3 */
+
+ case ETIR_S_C_STO_CA: /* ALPHA_R_CODEADDR */
+ case ETIR_S_C_STO_GBL: /* ALPHA_R_REFQUAD und_section */
+ case ETIR_S_C_STO_GBL_LW: /* ALPHA_R_REFLONG und_section */
+ case ETIR_S_C_STC_LP_PSB: /* ALPHA_R_LINKAGE */
+ case ETIR_S_C_STC_NOP_GBL: /* ALPHA_R_NOP */
+ case ETIR_S_C_STC_BSR_GBL: /* ALPHA_R_BSR */
+ case ETIR_S_C_STC_LDA_GBL: /* ALPHA_R_LDA */
+ case ETIR_S_C_STC_BOH_GBL: /* ALPHA_R_BOH */
+ break;
+
+ case ETIR_S_C_STO_IMM:
+ if (PRIV (image_section)->reloc_count == 0)
+ continue;
+ /* This is not a relocation, but we nevertheless slurp the
+ count argument. We'll use it to compute the addresses
+ of the relocations. */
+ slurped_length = ETIR_S_C_HEADER_SIZE + 4;
+ break;
+
+ default:
+ continue;
+ }
+
+ vsd = vms_section_data (PRIV (image_section));
+ memcpy (vsd->reloc_stream + vsd->reloc_offset, ptr, slurped_length);
+ vsd->reloc_offset += slurped_length;
+ if (vsd->reloc_offset > vsd->reloc_size)
+ {
+ (*_bfd_error_handler) (_("Reloc size error in section %s"),
+ PRIV (image_section)->name);
+ return -1;
+ }
+ }
+
#if VMS_DEBUG
! _bfd_vms_debug (3, "_bfd_vms_slurp_relocs: result = 0\n");
#endif
return 0;
}
! /* Decode relocs from the reloc buffer of the specified section
! and internalize them in the specified buffer. */
int
! _bfd_vms_decode_relocs (bfd *abfd, arelent *relocs, asection *section,
! asymbol **symbols ATTRIBUTE_UNUSED)
{
+ int saved_cmd, saved_sym_offset, saved_sec_offset, saved_addend_offset;
+ int cmd, sym_offset, sec_offset, address_offset, addend_offset;
+ struct vms_section_data_struct *vsd = vms_section_data (section);
+ bfd_reloc_code_real_type reloc_code;
+ vms_symbol_entry *entry;
+ bfd_vma vaddr = 0;
+ unsigned char *begin = vsd->reloc_stream;
+ unsigned char *end = vsd->reloc_stream + vsd->reloc_size;
+ unsigned char *ptr, *arg_ptr;
+ const char *name;
+ int length;
+
+ #if VMS_DEBUG
+ _bfd_vms_debug (3, "_bfd_vms_decode_relocs: %d bytes\n", vsd->reloc_size);
+ #endif
+
+ #define PUSH_CMD() \
+ { \
+ saved_cmd = cmd; \
+ saved_sym_offset = sym_offset - length; \
+ saved_sec_offset = sec_offset - length; \
+ saved_addend_offset = addend_offset - length; \
+ continue; \
+ }
+
+ #define POP_CMD() \
+ { \
+ cmd = saved_cmd; \
+ saved_cmd = ETIR_S_C_MAXSTCCOD + 1; \
+ sym_offset = saved_sym_offset; \
+ sec_offset = saved_sec_offset; \
+ addend_offset= saved_addend_offset; \
+ }
+
+ #define CMD_PUSHED (saved_cmd != ETIR_S_C_MAXSTCCOD + 1)
+
+ #define NO_OFFSET -128
+
+ saved_cmd = ETIR_S_C_MAXSTCCOD + 1;
+ saved_sym_offset = NO_OFFSET;
+ saved_sec_offset = NO_OFFSET;
+ saved_addend_offset = NO_OFFSET;
+
+ for (ptr = begin; ptr < end; ptr += length)
+ {
+ cmd = bfd_getl16 (ptr);
+ length = bfd_getl16 (ptr + 2);
+
+ arg_ptr = ptr + ETIR_S_C_HEADER_SIZE;
+ sym_offset = NO_OFFSET;
+ sec_offset = NO_OFFSET;
+ address_offset = NO_OFFSET;
+ addend_offset = NO_OFFSET;
+
+ switch (cmd)
+ {
+ case ETIR_S_C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */
+ /* ALPHA_R_REFQUAD und_section, step 1 */
+ sym_offset = 0;
+ PUSH_CMD ()
+
+ case ETIR_S_C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */
+ sec_offset = 0;
+ addend_offset = 4;
+ PUSH_CMD ()
+
+ case ETIR_S_C_STA_LW: /* ALPHA_R_REFLONG abs_section, step 1 */
+ /* ALPHA_R_REFLONG und_section, step 2 */
+ if (CMD_PUSHED)
+ {
+ POP_CMD ()
+ if (cmd != ETIR_S_C_STA_GBL)
+ {
+ (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+ cmd_name (cmd),
+ cmd_name (ETIR_S_C_STA_LW));
+ return 0;
+ }
+ cmd = ETIR_S_C_STA_LW;
+ }
+ addend_offset = 0;
+ PUSH_CMD ()
+
+ case ETIR_S_C_STA_QW: /* ALPHA_R_REFQUAD abs_section, step 1 */
+ /* ALPHA_R_REFQUAD und_section, step 2 */
+ if (CMD_PUSHED)
+ {
+ POP_CMD ()
+ if (cmd != ETIR_S_C_STA_GBL)
+ {
+ (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+ cmd_name (cmd),
+ cmd_name (ETIR_S_C_STA_QW));
+ return 0;
+ }
+ cmd = ETIR_S_C_STA_QW;
+ }
+ addend_offset = 0;
+ PUSH_CMD ()
+
+ case ETIR_S_C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */
+ /* ALPHA_R_REFLONG abs_section, step 2 */
+ /* ALPHA_R_REFLONG others, step 2 */
+ POP_CMD ()
+ if (cmd != ETIR_S_C_OPR_ADD
+ && cmd != ETIR_S_C_STA_LW
+ && cmd != ETIR_S_C_STA_PQ)
+ {
+ (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+ cmd_name (cmd), cmd_name (ETIR_S_C_STO_LW));
+ return 0;
+ }
+ reloc_code = BFD_RELOC_32;
+ break;
+
+ case ETIR_S_C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */
+ /* ALPHA_R_REFQUAD abs_section, step 2 */
+ POP_CMD ()
+ if (cmd != ETIR_S_C_OPR_ADD && cmd != ETIR_S_C_STA_QW)
+ {
+ (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+ cmd_name (cmd), cmd_name (ETIR_S_C_STO_QW));
+ return 0;
+ }
+ reloc_code = BFD_RELOC_64;
+ break;
+
+ case ETIR_S_C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */
+ POP_CMD ()
+ if (cmd != ETIR_S_C_STA_PQ)
+ {
+ (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+ cmd_name (cmd), cmd_name (ETIR_S_C_STO_OFF));
+ return 0;
+ }
+ reloc_code = BFD_RELOC_64;
+ break;
+
+ case ETIR_S_C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */
+ /* ALPHA_R_REFQUAD und_section, step 3 */
+ POP_CMD ()
+ if (cmd != ETIR_S_C_STA_LW && cmd != ETIR_S_C_STA_QW)
+ {
+ (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+ cmd_name (cmd), cmd_name (ETIR_S_C_OPR_ADD));
+ return 0;
+ }
+ cmd = ETIR_S_C_OPR_ADD;
+ PUSH_CMD ()
+
+ case ETIR_S_C_STO_CA: /* ALPHA_R_CODEADDR */
+ reloc_code = BFD_RELOC_ALPHA_CODEADDR;
+ sym_offset = 0;
+ break;
+
+ case ETIR_S_C_STO_GBL: /* ALPHA_R_REFQUAD und_section */
+ reloc_code = BFD_RELOC_64;
+ sym_offset = 0;
+ break;
+
+ case ETIR_S_C_STO_GBL_LW: /* ALPHA_R_REFLONG und_section */
+ reloc_code = BFD_RELOC_32;
+ sym_offset = 0;
+ break;
+
+ case ETIR_S_C_STC_LP_PSB: /* ALPHA_R_LINKAGE */
+ reloc_code = BFD_RELOC_ALPHA_LINKAGE;
+ sym_offset = 4;
+ break;
+
+ case ETIR_S_C_STC_NOP_GBL: /* ALPHA_R_NOP */
+ reloc_code = BFD_RELOC_ALPHA_NOP;
+ goto call_reloc;
+
+ case ETIR_S_C_STC_BSR_GBL: /* ALPHA_R_BSR */
+ reloc_code = BFD_RELOC_ALPHA_BSR;
+ goto call_reloc;
+
+ case ETIR_S_C_STC_LDA_GBL: /* ALPHA_R_LDA */
+ reloc_code = BFD_RELOC_ALPHA_LDA;
+ goto call_reloc;
+
+ case ETIR_S_C_STC_BOH_GBL: /* ALPHA_R_BOH */
+ reloc_code = BFD_RELOC_ALPHA_BOH;
+ goto call_reloc;
+
+ call_reloc:
+ sym_offset = 32;
+ address_offset = 8;
+ addend_offset = 24;
+ break;
+
+ case ETIR_S_C_STO_IMM:
+ vaddr += bfd_getl32 (arg_ptr);
+ length = ETIR_S_C_HEADER_SIZE + 4;
+ continue;
+
+ default:
+ continue;
+ }
+
+ relocs->howto = bfd_reloc_type_lookup (abfd, reloc_code);
+
+ if (sym_offset > NO_OFFSET)
+ {
+ name = _bfd_vms_save_counted_string (arg_ptr + sym_offset);
+ entry = (vms_symbol_entry *)
+ bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
+ if (entry == NULL)
+ {
+ (*_bfd_error_handler) (_("Unknown symbol %s in command %s"),
+ name, cmd_name (cmd));
+ relocs->sym_ptr_ptr = NULL;
+ }
+ else
+ /* ??? This is a hack. We should point in 'symbols'. */
+ relocs->sym_ptr_ptr = &entry->symbol;
+ }
+ else if (sec_offset > NO_OFFSET)
+ relocs->sym_ptr_ptr
+ = PRIV (sections)[bfd_getl32 (arg_ptr + sec_offset)]->symbol_ptr_ptr;
+ else
+ relocs->sym_ptr_ptr = NULL;
+
+ if (address_offset > NO_OFFSET)
+ relocs->address = bfd_getl64 (arg_ptr + address_offset);
+ else
+ relocs->address = vaddr;
+
+ if (addend_offset > NO_OFFSET)
+ relocs->addend = bfd_getl64 (arg_ptr + addend_offset);
+ else
+ relocs->addend = 0;
+
+ vaddr += bfd_get_reloc_size (relocs->howto);
+ relocs++;
+ }
+
+ #undef PUSH_CMD
+ #undef POP_CMD
+ #undef NO_OFFSET
+
#if VMS_DEBUG
! _bfd_vms_debug (3, "_bfd_vms_decode_relocs: result = 0\n");
#endif
return 0;
***************
*** 1750,1755 ****
--- 2301,2320 ----
return 0;
}
+ /* WRITE ETIR SECTION
+
+ This is still under construction and therefore not documented. */
+
+ static void start_etir_record (bfd *abfd, int index, uquad offset,
+ bfd_boolean justoffset);
+ static void start_first_etbt_record (bfd *abfd);
+ static void start_another_etbt_record (bfd *abfd);
+ static void sto_imm (bfd *abfd, bfd_size_type, unsigned char *, bfd_vma vaddr,
+ int index, const char *name);
+ static void end_etir_record (bfd *abfd);
+ static void etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr,
+ int checklen);
+
/* Start ETIR record for section #index at virtual addr offset. */
static void
***************
*** 1780,1804 ****
_bfd_vms_output_end (abfd);
}
! /* WRITE ETIR SECTION
!
! This is still under construction and therefore not documented. */
static void
! sto_imm (bfd * abfd, vms_section *sptr, bfd_vma vaddr, int index)
{
! int size;
! int ssize;
! unsigned char *cptr;
#if VMS_DEBUG
! _bfd_vms_debug (8, "sto_imm %d bytes\n", sptr->size);
! _bfd_hexdump (9, sptr->contents, (int) sptr->size, (int) vaddr);
#endif
- ssize = sptr->size;
- cptr = sptr->contents;
-
while (ssize > 0)
{
/* Try all the rest. */
--- 2345,2364 ----
_bfd_vms_output_end (abfd);
}
! /* Output a STO_IMM command for SSIZE bytes of data from CPR at virtual
! address VADDR in section specified by INDEX and NAME. */
static void
! sto_imm (bfd *abfd, bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr,
! int index, const char *name)
{
! bfd_size_type size;
#if VMS_DEBUG
! _bfd_vms_debug (8, "sto_imm %d bytes\n", ssize);
! _bfd_hexdump (9, cptr, (int) ssize, (int) vaddr);
#endif
while (ssize > 0)
{
/* Try all the rest. */
***************
*** 1808,1818 ****
{
/* Doesn't fit, split ! */
end_etir_record (abfd);
! start_etir_record (abfd, index, vaddr, FALSE);
! /* Get max size. */
! size = _bfd_vms_output_check (abfd, 0);
! /* More than what's left ? */
! if (size > ssize)
size = ssize;
}
--- 2368,2381 ----
{
/* Doesn't fit, split ! */
end_etir_record (abfd);
!
! if (name [0] && name[1] == 'v' && !strcmp (name, ".vmsdebug"))
! start_another_etbt_record (abfd);
! else
! start_etir_record (abfd, index, vaddr, FALSE);
!
! size = _bfd_vms_output_check (abfd, 0); /* get max size */
! if (size > ssize) /* more than what's left ? */
size = ssize;
}
***************
*** 1827,1834 ****
#endif
vaddr += size;
- ssize -= size;
cptr += size;
}
}
--- 2390,2452 ----
#endif
vaddr += size;
cptr += size;
+ ssize -= size;
+ }
+ }
+
+ /* Start ETBT record for section #index at virtual addr offset. */
+
+ static void
+ start_first_etbt_record (bfd *abfd)
+ {
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_ETBT, -1);
+ _bfd_vms_output_push (abfd);
+
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1); /* push start offset */
+ _bfd_vms_output_long (abfd, (unsigned long) 0);
+ _bfd_vms_output_flush (abfd);
+
+ _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_DFLOC, -1); /* start = pop() */
+ _bfd_vms_output_flush (abfd);
+ }
+
+ static void
+ start_another_etbt_record (bfd *abfd)
+ {
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_ETBT, -1);
+ _bfd_vms_output_push (abfd);
+ }
+
+ static void
+ etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, int checklen)
+ {
+ if (_bfd_vms_output_check (abfd, checklen) < 0)
+ {
+ end_etir_record (abfd);
+ if (section->name[0] && section->name[1] == 'v'
+ && !strcmp (section->name, ".vmsdebug"))
+ start_another_etbt_record (abfd);
+ else
+ start_etir_record (abfd, section->index, vaddr, FALSE);
+ }
+ }
+
+ /* Return whether RELOC must be deferred till the end. */
+
+ static int
+ defer_reloc_p (arelent *reloc)
+ {
+ switch (reloc->howto->type)
+ {
+ case ALPHA_R_NOP:
+ case ALPHA_R_LDA:
+ case ALPHA_R_BSR:
+ case ALPHA_R_BOH:
+ return 1;
+
+ default:
+ return 0;
}
}
***************
*** 1838,1845 ****
_bfd_vms_write_tir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
{
asection *section;
- vms_section *sptr;
- int nextoffset;
#if VMS_DEBUG
_bfd_vms_debug (2, "vms_write_tir (%p, %d)\n", abfd, objtype);
--- 2456,2461 ----
***************
*** 1847,2237 ****
_bfd_vms_output_alignment (abfd, 4);
- nextoffset = 0;
PRIV (vms_linkage_index) = 1;
! /* Dump all other sections. */
! section = abfd->sections;
!
! while (section != NULL)
{
-
#if VMS_DEBUG
_bfd_vms_debug (4, "writing %d. section '%s' (%d bytes)\n",
section->index, section->name,
(int) (section->size));
#endif
if (section->flags & SEC_RELOC)
{
! int i;
- if ((i = section->reloc_count) <= 0)
- (*_bfd_error_handler) (_("SEC_RELOC with no relocs in section %s"),
- section->name);
#if VMS_DEBUG
else
{
! arelent **rptr;
_bfd_vms_debug (4, "%d relocations:\n", i);
- rptr = section->orelocation;
while (i-- > 0)
{
! _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, addr %08lx, off %08lx, len %d: %s\n",
(*(*rptr)->sym_ptr_ptr)->name,
(*(*rptr)->sym_ptr_ptr)->section->name,
(long) (*(*rptr)->sym_ptr_ptr)->value,
(*rptr)->address, (*rptr)->addend,
bfd_get_reloc_size ((*rptr)->howto),
! (*rptr)->howto->name);
rptr++;
}
}
#endif
- }
-
- if ((section->flags & SEC_HAS_CONTENTS)
- && (! bfd_is_com_section (section)))
- {
- /* Virtual addr in section. */
- bfd_vma vaddr;
! sptr = _bfd_get_vms_section (abfd, section->index);
! if (sptr == NULL)
{
! bfd_set_error (bfd_error_no_contents);
! return -1;
! }
! vaddr = (bfd_vma) (sptr->offset);
! start_etir_record (abfd, section->index, (uquad) sptr->offset,
! FALSE);
! while (sptr != NULL)
! {
! /* One STA_PQ, CTL_SETRB per vms_section. */
! if (section->flags & SEC_RELOC)
! {
! /* Check for relocs. */
! arelent **rptr = section->orelocation;
! int i = section->reloc_count;
! for (;;)
{
! bfd_size_type addr = (*rptr)->address;
! bfd_size_type len = bfd_get_reloc_size ((*rptr)->howto);
! if (sptr->offset < addr)
{
! /* Sptr starts before reloc. */
! bfd_size_type before = addr - sptr->offset;
! if (sptr->size <= before)
! {
! /* Complete before. */
! sto_imm (abfd, sptr, vaddr, section->index);
! vaddr += sptr->size;
! break;
! }
! else
! {
! /* Partly before. */
! int after = sptr->size - before;
!
! sptr->size = before;
! sto_imm (abfd, sptr, vaddr, section->index);
! vaddr += sptr->size;
! sptr->contents += before;
! sptr->offset += before;
! sptr->size = after;
! }
! }
! else if (sptr->offset == addr)
! {
! /* Sptr starts at reloc. */
! asymbol *sym = *(*rptr)->sym_ptr_ptr;
! asection *sec = sym->section;
!
! switch ((*rptr)->howto->type)
! {
! case ALPHA_R_IGNORE:
! break;
!
! case ALPHA_R_REFLONG:
! {
! if (bfd_is_und_section (sym->section))
! {
! int slen = strlen ((char *) sym->name);
! char *hash;
!
! if (_bfd_vms_output_check (abfd, slen) < 0)
! {
! end_etir_record (abfd);
! start_etir_record (abfd,
! section->index,
! vaddr, FALSE);
! }
! _bfd_vms_output_begin (abfd,
! ETIR_S_C_STO_GBL_LW,
! -1);
! hash = (_bfd_vms_length_hash_symbol
! (abfd, sym->name, EOBJ_S_C_SYMSIZ));
! _bfd_vms_output_counted (abfd, hash);
! _bfd_vms_output_flush (abfd);
! }
! else if (bfd_is_abs_section (sym->section))
! {
! if (_bfd_vms_output_check (abfd, 16) < 0)
! {
! end_etir_record (abfd);
! start_etir_record (abfd,
! section->index,
! vaddr, FALSE);
! }
! _bfd_vms_output_begin (abfd,
! ETIR_S_C_STA_LW,
! -1);
! _bfd_vms_output_quad (abfd,
! (uquad) sym->value);
! _bfd_vms_output_flush (abfd);
! _bfd_vms_output_begin (abfd,
! ETIR_S_C_STO_LW,
! -1);
! _bfd_vms_output_flush (abfd);
! }
! else
! {
! if (_bfd_vms_output_check (abfd, 32) < 0)
! {
! end_etir_record (abfd);
! start_etir_record (abfd,
! section->index,
! vaddr, FALSE);
! }
! _bfd_vms_output_begin (abfd,
! ETIR_S_C_STA_PQ,
! -1);
! _bfd_vms_output_long (abfd,
! (unsigned long) (sec->index));
! _bfd_vms_output_quad (abfd,
! ((uquad) (*rptr)->addend
! + (uquad) sym->value));
! _bfd_vms_output_flush (abfd);
! _bfd_vms_output_begin (abfd,
! ETIR_S_C_STO_LW,
! -1);
! _bfd_vms_output_flush (abfd);
! }
! }
! break;
!
! case ALPHA_R_REFQUAD:
! {
! if (bfd_is_und_section (sym->section))
! {
! int slen = strlen ((char *) sym->name);
! char *hash;
!
! if (_bfd_vms_output_check (abfd, slen) < 0)
! {
! end_etir_record (abfd);
! start_etir_record (abfd,
! section->index,
! vaddr, FALSE);
! }
! _bfd_vms_output_begin (abfd,
! ETIR_S_C_STO_GBL,
! -1);
! hash = (_bfd_vms_length_hash_symbol
! (abfd, sym->name, EOBJ_S_C_SYMSIZ));
! _bfd_vms_output_counted (abfd, hash);
! _bfd_vms_output_flush (abfd);
! }
! else if (bfd_is_abs_section (sym->section))
! {
! if (_bfd_vms_output_check (abfd, 16) < 0)
! {
! end_etir_record (abfd);
! start_etir_record (abfd,
! section->index,
! vaddr, FALSE);
! }
! _bfd_vms_output_begin (abfd,
! ETIR_S_C_STA_QW,
! -1);
! _bfd_vms_output_quad (abfd,
! (uquad) sym->value);
! _bfd_vms_output_flush (abfd);
! _bfd_vms_output_begin (abfd,
! ETIR_S_C_STO_QW,
! -1);
! _bfd_vms_output_flush (abfd);
! }
! else
! {
! if (_bfd_vms_output_check (abfd, 32) < 0)
! {
! end_etir_record (abfd);
! start_etir_record (abfd,
! section->index,
! vaddr, FALSE);
! }
! _bfd_vms_output_begin (abfd,
! ETIR_S_C_STA_PQ,
! -1);
! _bfd_vms_output_long (abfd,
! (unsigned long) (sec->index));
! _bfd_vms_output_quad (abfd,
! ((uquad) (*rptr)->addend
! + (uquad) sym->value));
! _bfd_vms_output_flush (abfd);
! _bfd_vms_output_begin (abfd,
! ETIR_S_C_STO_OFF,
! -1);
! _bfd_vms_output_flush (abfd);
! }
! }
! break;
!
! case ALPHA_R_HINT:
! {
! int hint_size;
! char *hash ATTRIBUTE_UNUSED;
!
! hint_size = sptr->size;
! sptr->size = len;
! sto_imm (abfd, sptr, vaddr, section->index);
! sptr->size = hint_size;
! }
! break;
! case ALPHA_R_LINKAGE:
! {
! char *hash;
!
! if (_bfd_vms_output_check (abfd, 64) < 0)
! {
! end_etir_record (abfd);
! start_etir_record (abfd, section->index,
! vaddr, FALSE);
! }
! _bfd_vms_output_begin (abfd,
! ETIR_S_C_STC_LP_PSB,
! -1);
! _bfd_vms_output_long (abfd,
! (unsigned long) PRIV (vms_linkage_index));
! PRIV (vms_linkage_index) += 2;
! hash = (_bfd_vms_length_hash_symbol
! (abfd, sym->name, EOBJ_S_C_SYMSIZ));
! _bfd_vms_output_counted (abfd, hash);
! _bfd_vms_output_byte (abfd, 0);
! _bfd_vms_output_flush (abfd);
! }
! break;
!
! case ALPHA_R_CODEADDR:
! {
! int slen = strlen ((char *) sym->name);
! char *hash;
! if (_bfd_vms_output_check (abfd, slen) < 0)
! {
! end_etir_record (abfd);
! start_etir_record (abfd,
! section->index,
! vaddr, FALSE);
! }
! _bfd_vms_output_begin (abfd,
! ETIR_S_C_STO_CA,
! -1);
! hash = (_bfd_vms_length_hash_symbol
! (abfd, sym->name, EOBJ_S_C_SYMSIZ));
! _bfd_vms_output_counted (abfd, hash);
! _bfd_vms_output_flush (abfd);
! }
! break;
!
! default:
! (*_bfd_error_handler) (_("Unhandled relocation %s"),
! (*rptr)->howto->name);
! break;
! }
!
! vaddr += len;
!
! if (len == sptr->size)
! {
! break;
! }
! else
! {
! sptr->contents += len;
! sptr->offset += len;
! sptr->size -= len;
! i--;
! rptr++;
! }
}
else
{
! /* Sptr starts after reloc. */
! i--;
! /* Check next reloc. */
! rptr++;
}
! if (i == 0)
{
! /* All reloc checked. */
! if (sptr->size > 0)
! {
! /* Dump rest. */
! sto_imm (abfd, sptr, vaddr, section->index);
! vaddr += sptr->size;
! }
! break;
}
}
}
! else
{
! /* No relocs, just dump. */
! sto_imm (abfd, sptr, vaddr, section->index);
! vaddr += sptr->size;
}
-
- sptr = sptr->next;
}
-
- end_etir_record (abfd);
}
! section = section->next;
}
_bfd_vms_output_alignment (abfd, 2);
return 0;
}
-
- /* Write traceback data for bfd abfd. */
-
- int
- _bfd_vms_write_tbt (bfd * abfd ATTRIBUTE_UNUSED,
- int objtype ATTRIBUTE_UNUSED)
- {
- #if VMS_DEBUG
- _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
- #endif
-
- return 0;
- }
-
- /* Write debug info for bfd abfd. */
-
- int
- _bfd_vms_write_dbg (bfd * abfd ATTRIBUTE_UNUSED,
- int objtype ATTRIBUTE_UNUSED)
- {
- #if VMS_DEBUG
- _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
- #endif
-
- return 0;
- }
--- 2463,2808 ----
_bfd_vms_output_alignment (abfd, 4);
PRIV (vms_linkage_index) = 1;
! for (section = abfd->sections; section; section = section->next)
{
#if VMS_DEBUG
_bfd_vms_debug (4, "writing %d. section '%s' (%d bytes)\n",
section->index, section->name,
(int) (section->size));
#endif
+ if (!(section->flags & SEC_HAS_CONTENTS)
+ || bfd_is_com_section (section))
+ continue;
+
+ if (!section->contents)
+ {
+ bfd_set_error (bfd_error_no_contents);
+ return -1;
+ }
+
+ if (section->name[0]
+ && section->name[1] == 'v'
+ && !strcmp (section->name, ".vmsdebug"))
+ start_first_etbt_record (abfd);
+ else
+ start_etir_record (abfd, section->index, 0, FALSE);
+
if (section->flags & SEC_RELOC)
{
! bfd_vma curr_addr = 0;
! unsigned char *curr_data = section->contents;
! bfd_size_type size;
! int pass2_needed = 0;
! int pass2_in_progress = 0;
! unsigned int irel;
!
! if (section->reloc_count <= 0)
! (*_bfd_error_handler)
! (_("SEC_RELOC with no relocs in section %s"), section->name);
#if VMS_DEBUG
else
{
! int i = section->reloc_count;
! arelent **rptr = section->orelocation;
_bfd_vms_debug (4, "%d relocations:\n", i);
while (i-- > 0)
{
! _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, "
! "addr %08lx, off %08lx, len %d: %s\n",
(*(*rptr)->sym_ptr_ptr)->name,
(*(*rptr)->sym_ptr_ptr)->section->name,
(long) (*(*rptr)->sym_ptr_ptr)->value,
(*rptr)->address, (*rptr)->addend,
bfd_get_reloc_size ((*rptr)->howto),
! ( *rptr)->howto->name);
rptr++;
}
}
#endif
! new_pass:
! for (irel = 0; irel < section->reloc_count; irel++)
{
! struct evax_private_udata_struct *udata;
! arelent *rptr = section->orelocation [irel];
! bfd_vma addr = rptr->address;
! asymbol *sym = *rptr->sym_ptr_ptr;
! asection *sec = sym->section;
! int defer = defer_reloc_p (rptr);
! unsigned int slen;
! char *hash;
! if (pass2_in_progress)
! {
! /* Non-deferred relocs have already been output. */
! if (!defer)
! continue;
! }
! else
! {
! /* Deferred relocs must be output at the very end. */
! if (defer)
! {
! pass2_needed = 1;
! continue;
! }
! /* Regular relocs are intertwined with binary data. */
! if (curr_addr > addr)
! (*_bfd_error_handler) (_("Size error in section %s"),
! section->name);
! size = addr - curr_addr;
! sto_imm (abfd, size, curr_data, curr_addr,
! section->index, section->name);
! curr_data += size;
! curr_addr += size;
! }
! size = bfd_get_reloc_size (rptr->howto);
!
! switch (rptr->howto->type)
! {
! case ALPHA_R_IGNORE:
! break;
! case ALPHA_R_REFLONG:
! if (bfd_is_und_section (sym->section))
{
! bfd_vma addend = rptr->addend;
! slen = strlen ((char *) sym->name);
! hash = _bfd_vms_length_hash_symbol
! (abfd, sym->name, EOBJ_S_C_SYMSIZ);
! etir_output_check (abfd, section, curr_addr, slen);
! if (addend)
{
! _bfd_vms_output_begin (abfd, ETIR_S_C_STA_GBL, -1);
! _bfd_vms_output_counted (abfd, hash);
! _bfd_vms_output_flush (abfd);
! _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1);
! _bfd_vms_output_long (abfd, (unsigned long) addend);
! _bfd_vms_output_flush (abfd);
! _bfd_vms_output_begin (abfd, ETIR_S_C_OPR_ADD, -1);
! _bfd_vms_output_flush (abfd);
! _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1);
! _bfd_vms_output_flush (abfd);
}
else
{
! _bfd_vms_output_begin (abfd, ETIR_S_C_STO_GBL_LW, -1);
! _bfd_vms_output_counted (abfd, hash);
! _bfd_vms_output_flush (abfd);
}
+ }
+ else if (bfd_is_abs_section (sym->section))
+ {
+ etir_output_check (abfd, section, curr_addr, 16);
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1);
+ _bfd_vms_output_long (abfd, (unsigned long) sym->value);
+ _bfd_vms_output_flush (abfd);
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1);
+ _bfd_vms_output_flush (abfd);
+ }
+ else
+ {
+ etir_output_check (abfd, section, curr_addr, 32);
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
+ _bfd_vms_output_long (abfd, (unsigned long) sec->index);
+ _bfd_vms_output_quad (abfd, (uquad) rptr->addend
+ + (uquad) sym->value);
+ _bfd_vms_output_flush (abfd);
+ /* ??? Table B-8 of the OpenVMS Linker Utilily Manual
+ says that we should have a ETIR_S_C_STO_OFF here.
+ But the relocation would not be BFD_RELOC_32 then.
+ This case is very likely unreachable. */
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1);
+ _bfd_vms_output_flush (abfd);
+ }
+ break;
! case ALPHA_R_REFQUAD:
! if (bfd_is_und_section (sym->section))
! {
! bfd_vma addend = rptr->addend;
! slen = strlen ((char *) sym->name);
! hash = _bfd_vms_length_hash_symbol
! (abfd, sym->name, EOBJ_S_C_SYMSIZ);
! etir_output_check (abfd, section, curr_addr, slen);
! if (addend)
! {
! _bfd_vms_output_begin (abfd, ETIR_S_C_STA_GBL, -1);
! _bfd_vms_output_counted (abfd, hash);
! _bfd_vms_output_flush (abfd);
! _bfd_vms_output_begin (abfd, ETIR_S_C_STA_QW, -1);
! _bfd_vms_output_quad (abfd, (uquad) addend);
! _bfd_vms_output_flush (abfd);
! _bfd_vms_output_begin (abfd, ETIR_S_C_OPR_ADD, -1);
! _bfd_vms_output_flush (abfd);
! _bfd_vms_output_begin (abfd, ETIR_S_C_STO_QW, -1);
! _bfd_vms_output_flush (abfd);
! }
! else
{
! _bfd_vms_output_begin (abfd, ETIR_S_C_STO_GBL, -1);
! _bfd_vms_output_counted (abfd, hash);
! _bfd_vms_output_flush (abfd);
}
}
+ else if (bfd_is_abs_section (sym->section))
+ {
+ etir_output_check (abfd, section, curr_addr, 16);
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STA_QW, -1);
+ _bfd_vms_output_quad (abfd, (uquad) sym->value);
+ _bfd_vms_output_flush (abfd);
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STO_QW, -1);
+ _bfd_vms_output_flush (abfd);
+ }
+ else
+ {
+ etir_output_check (abfd, section, curr_addr, 32);
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
+ _bfd_vms_output_long (abfd, (unsigned long) sec->index);
+ _bfd_vms_output_quad (abfd, (uquad) rptr->addend
+ + (uquad) sym->value);
+ _bfd_vms_output_flush (abfd);
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STO_OFF, -1);
+ _bfd_vms_output_flush (abfd);
+ }
+ break;
+
+ case ALPHA_R_HINT:
+ sto_imm (abfd, size, curr_data, curr_addr,
+ section->index, section->name);
+ break;
+
+ case ALPHA_R_LINKAGE:
+ etir_output_check (abfd, section, curr_addr, 64);
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STC_LP_PSB, -1);
+ _bfd_vms_output_long
+ (abfd, (unsigned long) PRIV (vms_linkage_index));
+ PRIV (vms_linkage_index) += 2;
+ hash = _bfd_vms_length_hash_symbol
+ (abfd, sym->name, EOBJ_S_C_SYMSIZ);
+ _bfd_vms_output_counted (abfd, hash);
+ _bfd_vms_output_byte (abfd, 0);
+ _bfd_vms_output_flush (abfd);
+ break;
+
+ case ALPHA_R_CODEADDR:
+ slen = strlen ((char *) sym->name);
+ hash = _bfd_vms_length_hash_symbol
+ (abfd, sym->name, EOBJ_S_C_SYMSIZ);
+ etir_output_check (abfd, section, curr_addr, slen);
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STO_CA, -1);
+ _bfd_vms_output_counted (abfd, hash);
+ _bfd_vms_output_flush (abfd);
+ break;
+
+ case ALPHA_R_NOP:
+ udata
+ = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
+ etir_output_check (abfd, section, curr_addr,
+ 32 + 1 + strlen (udata->origname));
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STC_NOP_GBL, -1);
+ _bfd_vms_output_long (abfd, (unsigned long) udata->lkindex);
+ _bfd_vms_output_long
+ (abfd, (unsigned long) udata->enbsym->section->index);
+ _bfd_vms_output_quad (abfd, (uquad) rptr->address);
+ _bfd_vms_output_long (abfd, (unsigned long) 0x47ff041f);
+ _bfd_vms_output_long
+ (abfd, (unsigned long) udata->enbsym->section->index);
+ _bfd_vms_output_quad (abfd, (uquad) rptr->addend);
+ _bfd_vms_output_counted
+ (abfd, _bfd_vms_length_hash_symbol
+ (abfd, udata->origname, EOBJ_S_C_SYMSIZ));
+ _bfd_vms_output_flush (abfd);
+ break;
+
+ case ALPHA_R_BSR:
+ (*_bfd_error_handler) (_("Spurious ALPHA_R_BSR reloc"));
+ break;
+
+ case ALPHA_R_LDA:
+ udata
+ = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
+ etir_output_check (abfd, section, curr_addr,
+ 32 + 1 + strlen (udata->origname));
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STC_LDA_GBL, -1);
+ _bfd_vms_output_long
+ (abfd, (unsigned long) udata->lkindex + 1);
+ _bfd_vms_output_long
+ (abfd, (unsigned long) udata->enbsym->section->index);
+ _bfd_vms_output_quad (abfd, (uquad) rptr->address);
+ _bfd_vms_output_long (abfd, (unsigned long) 0x237B0000);
+ _bfd_vms_output_long
+ (abfd, (unsigned long) udata->bsym->section->index);
+ _bfd_vms_output_quad (abfd, (uquad) rptr->addend);
+ _bfd_vms_output_counted
+ (abfd, _bfd_vms_length_hash_symbol
+ (abfd, udata->origname, EOBJ_S_C_SYMSIZ));
+ _bfd_vms_output_flush (abfd);
+ break;
+
+ case ALPHA_R_BOH:
+ udata
+ = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
+ etir_output_check (abfd, section, curr_addr,
+ 32 + 1 + strlen (udata->origname));
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STC_BOH_GBL, -1);
+ _bfd_vms_output_long (abfd, (unsigned long) udata->lkindex);
+ _bfd_vms_output_long
+ (abfd, (unsigned long) udata->enbsym->section->index);
+ _bfd_vms_output_quad (abfd, (uquad) rptr->address);
+ _bfd_vms_output_long (abfd, (unsigned long) 0xD3400000);
+ _bfd_vms_output_long
+ (abfd, (unsigned long) udata->enbsym->section->index);
+ _bfd_vms_output_quad (abfd, (uquad) rptr->addend);
+ _bfd_vms_output_counted
+ (abfd, _bfd_vms_length_hash_symbol
+ (abfd, udata->origname, EOBJ_S_C_SYMSIZ));
+ _bfd_vms_output_flush (abfd);
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Unhandled relocation %s"),
+ rptr->howto->name);
+ break;
}
!
! curr_data += size;
! curr_addr += size;
! } /* End of relocs loop. */
!
! if (!pass2_in_progress)
! {
! /* Output rest of section. */
! if (curr_addr > section->size)
! (*_bfd_error_handler) (_("Size error in section %s"),
! section->name);
! size = section->size - curr_addr;
! sto_imm (abfd, size, curr_data, curr_addr,
! section->index, section->name);
! curr_data += size;
! curr_addr += size;
!
! if (pass2_needed)
{
! pass2_in_progress = 1;
! goto new_pass;
}
}
}
+
+ else /* (section->flags & SEC_RELOC) */
+ sto_imm (abfd, section->size, section->contents, 0,
+ section->index, section->name);
! end_etir_record (abfd);
}
_bfd_vms_output_alignment (abfd, 2);
return 0;
}
Index: bfd/vms.c
===================================================================
RCS file: /cvs/src/src/bfd/vms.c,v
retrieving revision 1.45
diff -c -r1.45 vms.c
*** bfd/vms.c 20 Feb 2008 17:42:36 -0000 1.45
--- bfd/vms.c 17 Feb 2009 11:13:10 -0000
***************
*** 1,7 ****
/* vms.c -- BFD back-end for VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
! 2006, 2007, 2008 Free Software Foundation, Inc.
Written by Klaus K"ampf (kkaempf@rmi.de)
--- 1,9 ----
/* vms.c -- BFD back-end for VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
! 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
!
! Main file.
Written by Klaus K"ampf (kkaempf@rmi.de)
***************
*** 20,25 ****
--- 22,34 ----
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
+ #ifdef VMS
+ #include <rms.h>
+ #include <starlet.h>
+ #define RME$C_SETRFM 0x00000001
+ #include <unistd.h>
+ #endif
+
#include "sysdep.h"
#include "bfd.h"
#include "bfdlink.h"
***************
*** 27,32 ****
--- 36,143 ----
#include "vms.h"
+ static bfd_boolean vms_initialize (bfd *);
+ static bfd_boolean fill_section_ptr (struct bfd_hash_entry *, PTR);
+ static bfd_boolean vms_fixup_sections (bfd *);
+ static bfd_boolean copy_symbols (struct bfd_hash_entry *, PTR);
+ static bfd_reloc_status_type reloc_nil (bfd *, arelent *, asymbol *, PTR,
+ asection *, bfd *, char **);
+ static int vms_slurp_module (bfd *abfd);
+ static int vms_slurp_image (bfd *abfd);
+ static const struct bfd_target *vms_object_p (bfd *abfd);
+ static const struct bfd_target *vms_archive_p (bfd *abfd);
+ static bfd_boolean vms_mkobject (bfd *abfd);
+ static bfd_boolean vms_write_object_contents (bfd *abfd);
+ static void free_reloc_stream (bfd *abfd, asection *section, void *data);
+ static bfd_boolean vms_close_and_cleanup (bfd *abfd);
+ static bfd_boolean vms_bfd_free_cached_info (bfd *abfd);
+ static bfd_boolean vms_new_section_hook (bfd *abfd, asection *section);
+ static bfd_boolean vms_get_section_contents
+ (bfd *abfd, asection *section, PTR x1, file_ptr x2, bfd_size_type x3);
+ static bfd_boolean vms_get_section_contents_in_window
+ (bfd *abfd, asection *section, bfd_window *w, file_ptr offset,
+ bfd_size_type count);
+ static bfd_boolean vms_bfd_copy_private_bfd_data (bfd *src, bfd *dest);
+ static bfd_boolean vms_bfd_copy_private_section_data
+ (bfd *srcbfd, asection *srcsec, bfd *dstbfd, asection *dstsec);
+ static bfd_boolean vms_bfd_copy_private_symbol_data
+ (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym);
+ static bfd_boolean vms_bfd_print_private_bfd_data (bfd *abfd, void *file);
+ static char *vms_core_file_failing_command (bfd *abfd);
+ static int vms_core_file_failing_signal (bfd *abfd);
+ static bfd_boolean vms_core_file_matches_executable_p (bfd *abfd, bfd *bbfd);
+ static bfd_boolean vms_slurp_armap (bfd *abfd);
+ static bfd_boolean vms_slurp_extended_name_table (bfd *abfd);
+ static bfd_boolean vms_construct_extended_name_table
+ (bfd *abfd, char **tabloc, bfd_size_type *tablen, const char **name);
+ static void vms_truncate_arname (bfd *abfd, const char *pathname, char *arhdr);
+ static bfd_boolean vms_write_armap
+ (bfd *arch, unsigned int elen, struct orl *map, unsigned int cnt, int idx);
+ static PTR vms_read_ar_hdr (bfd *abfd);
+ static bfd *vms_get_elt_at_index (bfd *abfd, symindex index);
+ static bfd *vms_openr_next_archived_file (bfd *arch, bfd *prev);
+ static bfd_boolean vms_update_armap_timestamp (bfd *abfd);
+ static int vms_generic_stat_arch_elt (bfd *, struct stat *);
+ static long vms_get_symtab_upper_bound (bfd *abfd);
+ static long vms_canonicalize_symtab (bfd *abfd, asymbol **symbols);
+ static void vms_print_symbol (bfd *abfd, PTR file, asymbol *symbol,
+ bfd_print_symbol_type how);
+ static void vms_get_symbol_info (bfd *abfd, asymbol *symbol, symbol_info *ret);
+ static bfd_boolean vms_bfd_is_local_label_name (bfd *abfd, const char *);
+ static alent *vms_get_lineno (bfd *abfd, asymbol *symbol);
+ static bfd_boolean vms_find_nearest_line
+ (bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset,
+ const char **file, const char **func, unsigned int *line);
+ static asymbol *vms_bfd_make_debug_symbol (bfd *abfd, void *ptr,
+ unsigned long size);
+ static long vms_read_minisymbols (bfd *abfd, bfd_boolean dynamic,
+ PTR *minisymsp, unsigned int *sizep);
+ static asymbol *vms_minisymbol_to_symbol
+ (bfd *abfd, bfd_boolean dynamic, const PTR minisym, asymbol *sym);
+ static void alloc_reloc_stream (bfd *abfd, asection *section,
+ void *alloc_error);
+ static bfd_boolean vms_slurp_reloc_table (bfd *abfd, asection *section,
+ asymbol **symbols);
+ static long vms_get_reloc_upper_bound (bfd *abfd, asection *sect);
+ static long vms_canonicalize_reloc (bfd *abfd, asection *srcsec,
+ arelent **location, asymbol **symbols);
+ static const struct reloc_howto_struct *vms_bfd_reloc_type_lookup
+ (bfd *abfd, bfd_reloc_code_real_type code);
+ static bfd_boolean vms_set_arch_mach
+ (bfd *abfd, enum bfd_architecture arch, unsigned long mach);
+ static bfd_boolean vms_set_section_contents
+ (bfd *abfd, asection *section, const PTR location, file_ptr offset,
+ bfd_size_type count);
+ static int vms_sizeof_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED);
+ static bfd_byte *vms_bfd_get_relocated_section_contents
+ (bfd *abfd, struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order, bfd_byte *data,
+ bfd_boolean relocatable, asymbol **symbols);
+ static bfd_boolean vms_bfd_relax_section
+ (bfd *abfd, asection *section, struct bfd_link_info *link_info,
+ bfd_boolean *again);
+ static bfd_boolean vms_bfd_gc_sections
+ (bfd *abfd, struct bfd_link_info *link_info);
+ static bfd_boolean vms_bfd_merge_sections
+ (bfd *abfd, struct bfd_link_info *link_info);
+ static struct bfd_link_hash_table *vms_bfd_link_hash_table_create (bfd *abfd);
+ static void vms_bfd_link_hash_table_free (struct bfd_link_hash_table *hash);
+ static bfd_boolean vms_bfd_link_add_symbols
+ (bfd *abfd, struct bfd_link_info *link_info);
+ static bfd_boolean vms_bfd_final_link (bfd *abfd,
+ struct bfd_link_info *link_info);
+ static bfd_boolean vms_bfd_link_split_section (bfd *abfd, asection *section);
+ static long vms_get_dynamic_symtab_upper_bound (bfd *abfd);
+ static long vms_canonicalize_dynamic_symtab
+ (bfd *abfd, asymbol **symbols);
+ #define vms_get_synthetic_symtab _bfd_nodynamic_get_synthetic_symtab
+ static long vms_get_dynamic_reloc_upper_bound (bfd *abfd);
+ static long vms_canonicalize_dynamic_reloc
+ (bfd *abfd, arelent **arel, asymbol **symbols);
+ static bfd_boolean vms_bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd);
+ static bfd_boolean vms_bfd_set_private_flags (bfd *abfd, flagword flags);
+
#define vms_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
#define vms_make_empty_symbol _bfd_generic_make_empty_symbol
#define vms_bfd_link_just_syms _bfd_generic_link_just_syms
***************
*** 36,77 ****
#define vms_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
#define vms_get_synthetic_symtab _bfd_nodynamic_get_synthetic_symtab
! static unsigned int priv_section_count;
extern const bfd_target vms_vax_vec;
extern const bfd_target vms_alpha_vec;
-
- /* Initialize private data. */
static bfd_boolean
vms_initialize (bfd * abfd)
{
- int i;
bfd_size_type amt;
bfd_set_start_address (abfd, (bfd_vma) -1);
amt = sizeof (struct vms_private_data_struct);
! abfd->tdata.any = bfd_alloc (abfd, amt);
if (abfd->tdata.any == NULL)
return FALSE;
! #ifdef __ALPHA
! PRIV (is_vax) = FALSE;
! #else
! PRIV (is_vax) = TRUE;
! #endif
! PRIV (vms_buf) = NULL;
! PRIV (buf_size) = 0;
! PRIV (rec_length) = 0;
PRIV (file_format) = FF_UNKNOWN;
- PRIV (fixup_done) = FALSE;
- PRIV (sections) = NULL;
amt = sizeof (struct stack_struct) * STACKSIZE;
PRIV (stack) = bfd_alloc (abfd, amt);
if (PRIV (stack) == NULL)
goto error_ret1;
- PRIV (stackptr) = 0;
amt = sizeof (struct bfd_hash_table);
PRIV (vms_symbol_table) = bfd_alloc (abfd, amt);
--- 147,184 ----
#define vms_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
#define vms_get_synthetic_symtab _bfd_nodynamic_get_synthetic_symtab
!
! #ifdef VMS_DEBUG
! /* Cause debug info to be emitted for the structure. */
! struct vms_private_data_struct _vms_private_data_struct_dummy;
! struct vms_section_data_struct _vms_section_data_struct_dummy;
! #endif
!
extern const bfd_target vms_vax_vec;
extern const bfd_target vms_alpha_vec;
+ /* Initialize private data */
static bfd_boolean
vms_initialize (bfd * abfd)
{
bfd_size_type amt;
bfd_set_start_address (abfd, (bfd_vma) -1);
amt = sizeof (struct vms_private_data_struct);
! abfd->tdata.any = bfd_zalloc (abfd, amt);
if (abfd->tdata.any == NULL)
return FALSE;
! if (bfd_get_flavour (abfd) == bfd_target_ovax_flavour)
! PRIV (is_vax) = TRUE;
!
PRIV (file_format) = FF_UNKNOWN;
amt = sizeof (struct stack_struct) * STACKSIZE;
PRIV (stack) = bfd_alloc (abfd, amt);
if (PRIV (stack) == NULL)
goto error_ret1;
amt = sizeof (struct bfd_hash_table);
PRIV (vms_symbol_table) = bfd_alloc (abfd, amt);
***************
*** 82,105 ****
sizeof (vms_symbol_entry)))
goto error_ret1;
- amt = sizeof (struct location_struct) * LOCATION_SAVE_SIZE;
- PRIV (location_stack) = bfd_alloc (abfd, amt);
- if (PRIV (location_stack) == NULL)
- goto error_ret2;
-
- for (i = 0; i < VMS_SECTION_COUNT; i++)
- PRIV (vms_section_table)[i] = NULL;
-
amt = MAX_OUTREC_SIZE;
PRIV (output_buf) = bfd_alloc (abfd, amt);
if (PRIV (output_buf) == NULL)
goto error_ret2;
- PRIV (push_level) = 0;
- PRIV (pushed_size) = 0;
PRIV (length_pos) = 2;
- PRIV (output_size) = 0;
- PRIV (output_alignment) = 1;
return TRUE;
--- 189,200 ----
***************
*** 111,264 ****
return FALSE;
}
! /* Fill symbol->section with section ptr
symbol->section is filled with the section index for defined symbols
! during reading the GSD/EGSD section. But we need the pointer to the
bfd section later.
! It has the correct value for referenced (undefined section) symbols
! called from bfd_hash_traverse in vms_fixup_sections. */
static bfd_boolean
! fill_section_ptr (struct bfd_hash_entry * entry, void * sections)
{
! asection *sec;
! asymbol *sym;
!
! sym = ((vms_symbol_entry *) entry)->symbol;
! sec = sym->section;
#if VMS_DEBUG
vms_debug (6, "fill_section_ptr: sym %p, sec %p\n", sym, sec);
#endif
! /* Fill forward references (these contain section number, not section ptr). */
! if ((unsigned int) (size_t) sec < priv_section_count)
! sec = ((vms_symbol_entry *) entry)->symbol->section =
! ((asection **) sections)[(unsigned int) (size_t) sec];
!
! if (strcmp (sym->name, sec->name) == 0)
! sym->flags |= BSF_SECTION_SYM;
return TRUE;
}
! /* Fixup sections
! set up all pointers and arrays, counters and sizes are fixed now
!
! we build a private sections vector for easy access since sections
! are always referenced by an index number.
!
! alloc PRIV(sections) according to abfd->section_count
! copy abfd->sections to PRIV(sections). */
!
static bfd_boolean
vms_fixup_sections (bfd * abfd)
{
if (PRIV (fixup_done))
return TRUE;
! /* Traverse symbol table and fill in all section pointers. */
!
! /* Can't provide section count as argument to fill_section_ptr(). */
! priv_section_count = PRIV (section_count);
! bfd_hash_traverse (PRIV (vms_symbol_table), fill_section_ptr, (PRIV (sections)));
PRIV (fixup_done) = TRUE;
-
return TRUE;
}
-
- /* Check the format for a file being read.
- Return a (bfd_target *) if it's an object file or zero if not. */
! static const struct bfd_target *
! vms_object_p (bfd * abfd)
{
! int err = 0;
! int prev_type;
! const struct bfd_target *target_vector = NULL;
! const bfd_arch_info_type *arch = NULL;
! void * tdata_save = abfd->tdata.any;
! bfd_vma saddr_save = bfd_get_start_address (abfd);
!
! #if VMS_DEBUG
! vms_debug (1, "vms_object_p (%p)\n", abfd);
! #endif
!
! if (!vms_initialize (abfd))
! goto error_ret;
!
! if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
! goto err_wrong_format;
!
! prev_type = -1;
do
{
#if VMS_DEBUG
vms_debug (7, "reading at %08lx\n", bfd_tell (abfd));
#endif
! if (_bfd_vms_next_record (abfd) < 0)
{
#if VMS_DEBUG
vms_debug (2, "next_record failed\n");
#endif
! goto err_wrong_format;
}
! if ((prev_type == EOBJ_S_C_EGSD)
! && (PRIV (rec_type) != EOBJ_S_C_EGSD))
{
if (! vms_fixup_sections (abfd))
{
#if VMS_DEBUG
vms_debug (2, "vms_fixup_sections failed\n");
#endif
! goto err_wrong_format;
}
}
! prev_type = PRIV (rec_type);
!
! if (target_vector == NULL)
! {
! if (prev_type <= OBJ_S_C_MAXRECTYP)
! target_vector = & vms_vax_vec;
! else
! target_vector = & vms_alpha_vec;
! }
! switch (prev_type)
{
case OBJ_S_C_HDR:
case EOBJ_S_C_EMH:
! err = _bfd_vms_slurp_hdr (abfd, prev_type);
break;
case OBJ_S_C_EOM:
case OBJ_S_C_EOMW:
case EOBJ_S_C_EEOM:
! err = _bfd_vms_slurp_eom (abfd, prev_type);
break;
case OBJ_S_C_GSD:
case EOBJ_S_C_EGSD:
! err = _bfd_vms_slurp_gsd (abfd, prev_type);
break;
case OBJ_S_C_TIR:
case EOBJ_S_C_ETIR:
! err = _bfd_vms_slurp_tir (abfd, prev_type);
break;
case OBJ_S_C_DBG:
case EOBJ_S_C_EDBG:
! err = _bfd_vms_slurp_dbg (abfd, prev_type);
break;
case OBJ_S_C_TBT:
case EOBJ_S_C_ETBT:
! err = _bfd_vms_slurp_tbt (abfd, prev_type);
break;
case OBJ_S_C_LNK:
! err = _bfd_vms_slurp_lnk (abfd, prev_type);
break;
default:
err = -1;
--- 206,332 ----
return FALSE;
}
! struct pair
! {
! unsigned int section_count;
! asection **sections;
! };
!
! /* Fill symbol->section with section pointer.
!
symbol->section is filled with the section index for defined symbols
! during reading the GSD/EGSD section. But we need the pointer to the
bfd section later.
! It has the correct value for referenced (undefined section) symbols.
! Called from bfd_hash_traverse in vms_fixup_sections. */
static bfd_boolean
! fill_section_ptr (struct bfd_hash_entry *entry, void *sections)
{
! asymbol *sym = ((vms_symbol_entry *)entry)->symbol;
! struct pair *data = (struct pair *)sections;
! unsigned long sec = (unsigned long)sym->section;
#if VMS_DEBUG
vms_debug (6, "fill_section_ptr: sym %p, sec %p\n", sym, sec);
#endif
! if (sec < data->section_count)
! {
! sym->section = data->sections[sec];
+ if (strcmp (sym->name, sym->section->name) == 0)
+ sym->flags |= BSF_SECTION_SYM;
+ }
+ else if (sec == (unsigned long)-1)
+ sym->section = &bfd_und_section;
+
return TRUE;
}
! /* Fixup section pointers in symbols. */
static bfd_boolean
vms_fixup_sections (bfd * abfd)
{
+ struct pair data;
+
if (PRIV (fixup_done))
return TRUE;
! data.section_count = PRIV (section_count);
! data.sections = PRIV (sections);
! bfd_hash_traverse (PRIV (vms_symbol_table), fill_section_ptr, &data);
PRIV (fixup_done) = TRUE;
return TRUE;
}
! /* Slurp an ordered set of VMS object records. */
! int
! _bfd_vms_slurp_object_records (bfd * abfd)
{
! int err, new_type, type = -1;
do
{
#if VMS_DEBUG
vms_debug (7, "reading at %08lx\n", bfd_tell (abfd));
#endif
! new_type = _bfd_vms_get_object_record (abfd);
! if (new_type < 0)
{
#if VMS_DEBUG
vms_debug (2, "next_record failed\n");
#endif
! return -1;
}
! if (type == EOBJ_S_C_EGSD && new_type != EOBJ_S_C_EGSD)
{
if (! vms_fixup_sections (abfd))
{
#if VMS_DEBUG
vms_debug (2, "vms_fixup_sections failed\n");
#endif
! return -1;
}
}
! type = new_type;
! switch (type)
{
case OBJ_S_C_HDR:
case EOBJ_S_C_EMH:
! err = _bfd_vms_slurp_hdr (abfd, type);
break;
case OBJ_S_C_EOM:
case OBJ_S_C_EOMW:
case EOBJ_S_C_EEOM:
! err = _bfd_vms_slurp_eom (abfd, type);
break;
case OBJ_S_C_GSD:
case EOBJ_S_C_EGSD:
! err = _bfd_vms_slurp_gsd (abfd, type);
break;
case OBJ_S_C_TIR:
case EOBJ_S_C_ETIR:
! err = _bfd_vms_slurp_tir (abfd, type);
break;
case OBJ_S_C_DBG:
case EOBJ_S_C_EDBG:
! err = _bfd_vms_slurp_dbg (abfd, type);
! PRIV (dst_ptr_end) = PRIV (image_ptr);
break;
case OBJ_S_C_TBT:
case EOBJ_S_C_ETBT:
! err = _bfd_vms_slurp_tbt (abfd, type);
! PRIV (dst_ptr_end) = PRIV (image_ptr);
break;
case OBJ_S_C_LNK:
! err = _bfd_vms_slurp_lnk (abfd, type);
break;
default:
err = -1;
***************
*** 266,279 ****
if (err != 0)
{
#if VMS_DEBUG
! vms_debug (2, "slurp type %d failed with %d\n", prev_type, err);
#endif
! goto err_wrong_format;
}
}
! while ((prev_type != EOBJ_S_C_EEOM) && (prev_type != OBJ_S_C_EOM) && (prev_type != OBJ_S_C_EOMW));
! if (target_vector == & vms_vax_vec)
{
if (! vms_fixup_sections (abfd))
{
--- 334,438 ----
if (err != 0)
{
#if VMS_DEBUG
! vms_debug (2, "slurp type %d failed with %d\n", type, err);
#endif
! return err;
}
}
! while (type != EOBJ_S_C_EEOM && type != OBJ_S_C_EOM && type != OBJ_S_C_EOMW);
!
! return 0;
! }
!
! /* Slurp a VMS module and return an error status. */
!
! static int
! vms_slurp_module (bfd *abfd)
! {
! int type, err;
!
! if (PRIV (is_vax))
! type = PRIV (vms_rec)[0];
! else
! type = bfd_getl16 (PRIV (vms_rec));
!
! err = _bfd_vms_slurp_hdr (abfd, type);
! if (err != 0)
! {
! bfd_set_error (bfd_error_wrong_format);
! return err;
! }
!
! return _bfd_vms_slurp_object_records (abfd);
! }
!
! /* Slurp a VMS image and return an error status. */
!
! static int
! vms_slurp_image (bfd *abfd)
! {
! unsigned int isd_offset, ihs_offset;
! int err;
!
! err = _bfd_vms_slurp_ihd (abfd, &isd_offset, &ihs_offset);
! if (err != 0)
! {
! bfd_set_error (bfd_error_wrong_format);
! return err;
! }
!
! err = _bfd_vms_slurp_isd (abfd, isd_offset);
! if (err != 0)
! {
! bfd_set_error (bfd_error_wrong_format);
! return err;
! }
!
! return _bfd_vms_slurp_ihs (abfd, ihs_offset);
! }
!
! /* Check the format for a file being read.
! Return a (bfd_target *) if it's an object file or zero if not. */
!
! static const struct bfd_target *
! vms_object_p (bfd *abfd)
! {
! const struct bfd_target *target_vector;
! const bfd_arch_info_type *arch;
! PTR tdata_save = abfd->tdata.any;
! bfd_vma saddr_save = bfd_get_start_address (abfd);
! int err = 0;
!
! #if VMS_DEBUG
! vms_debug (1, "vms_object_p(%p)\n", abfd);
! #endif
!
! if (!vms_initialize (abfd))
! goto error_ret;
!
! if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
! goto err_wrong_format;
!
! switch (_bfd_vms_get_first_record (abfd))
! {
! case FT_UNKNOWN:
! default:
! err = -1;
! break;
!
! case FT_MODULE:
! err = vms_slurp_module (abfd);
! break;
!
! case FT_IMAGE:
! err = vms_slurp_image (abfd);
! break;
! }
!
! if (err != 0)
! goto err_wrong_format;
! if (PRIV (is_vax))
{
if (! vms_fixup_sections (abfd))
{
***************
*** 283,320 ****
goto err_wrong_format;
}
! /* Set arch_info to vax. */
!
arch = bfd_scan_arch ("vax");
! PRIV (is_vax) = TRUE;
#if VMS_DEBUG
vms_debug (2, "arch is vax\n");
#endif
}
! else if (target_vector == & vms_alpha_vec)
{
/* Set arch_info to alpha. */
!
arch = bfd_scan_arch ("alpha");
- PRIV (is_vax) = FALSE;
#if VMS_DEBUG
vms_debug (2, "arch is alpha\n");
#endif
}
- if (arch == NULL)
- {
- #if VMS_DEBUG
- vms_debug (2, "arch not found\n");
- #endif
- goto err_wrong_format;
- }
abfd->arch_info = arch;
-
return target_vector;
err_wrong_format:
bfd_set_error (bfd_error_wrong_format);
error_ret:
if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
bfd_release (abfd, abfd->tdata.any);
--- 442,470 ----
goto err_wrong_format;
}
! target_vector = &vms_vax_vec;
arch = bfd_scan_arch ("vax");
!
#if VMS_DEBUG
vms_debug (2, "arch is vax\n");
#endif
}
! else
{
/* Set arch_info to alpha. */
! target_vector = &vms_alpha_vec;
arch = bfd_scan_arch ("alpha");
#if VMS_DEBUG
vms_debug (2, "arch is alpha\n");
#endif
}
abfd->arch_info = arch;
return target_vector;
err_wrong_format:
bfd_set_error (bfd_error_wrong_format);
+
error_ret:
if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
bfd_release (abfd, abfd->tdata.any);
***************
*** 341,346 ****
--- 491,498 ----
static bfd_boolean
vms_mkobject (bfd * abfd)
{
+ const bfd_arch_info_type *arch;
+
#if VMS_DEBUG
vms_debug (1, "vms_mkobject (%p)\n", abfd);
#endif
***************
*** 348,367 ****
if (!vms_initialize (abfd))
return FALSE;
! {
! #ifdef __VAX
! const bfd_arch_info_type *arch = bfd_scan_arch ("vax");
! #else
! const bfd_arch_info_type *arch = bfd_scan_arch ("alpha");
! #endif
! if (arch == NULL)
! {
! bfd_set_error (bfd_error_wrong_format);
! return FALSE;
! }
! abfd->arch_info = arch;
! }
return TRUE;
}
--- 500,517 ----
if (!vms_initialize (abfd))
return FALSE;
! if (PRIV (is_vax))
! arch = bfd_scan_arch ("vax");
! else
! arch = bfd_scan_arch ("alpha");
!
! if (arch == 0)
! {
! bfd_set_error(bfd_error_wrong_format);
! return FALSE;
! }
+ abfd->arch_info = arch;
return TRUE;
}
***************
*** 420,425 ****
--- 570,631 ----
/* 4.1, generic. */
+ /* Free the reloc buffer for the specified section. */
+
+ static void
+ free_reloc_stream (bfd *abfd ATTRIBUTE_UNUSED, asection *section,
+ void *data ATTRIBUTE_UNUSED)
+ {
+ if (vms_section_data (section)->reloc_stream)
+ free (vms_section_data (section)->reloc_stream);
+ }
+
+ #ifdef VMS
+ /* Convert the file to variable record length format. This is done
+ using undocumented system call sys$modify().
+ Pure VMS version. */
+
+ static void
+ vms_convert_to_var (char *vms_filename)
+ {
+ struct FAB fab = cc$rms_fab;
+
+ fab.fab$l_fna = vms_filename;
+ fab.fab$b_fns = strlen (vms_filename);
+ fab.fab$b_fac = FAB$M_PUT;
+ fab.fab$l_fop = FAB$M_ESC;
+ fab.fab$l_ctx = RME$C_SETRFM;
+
+ sys$open (&fab);
+
+ fab.fab$b_rfm = FAB$C_VAR;
+
+ sys$modify (&fab);
+ sys$close (&fab);
+ }
+
+ static int
+ vms_convert_to_var_1 (char *filename, int type)
+ {
+ if (type != DECC$K_FILE)
+ return FALSE;
+ vms_convert_to_var (filename);
+ return TRUE;
+ }
+
+ /* Convert the file to variable record length format. This is done
+ using undocumented system call sys$modify().
+ Unix filename version. */
+
+ static int
+ vms_convert_to_var_unix_filename (const char *unix_filename)
+ {
+ if (decc$to_vms (unix_filename, &vms_convert_to_var_1, 0, 1) != 1)
+ return FALSE;
+ return TRUE;
+ }
+ #endif /* VMS */
+
/* Called when the BFD is being closed to do any necessary cleanup. */
static bfd_boolean
***************
*** 428,435 ****
#if VMS_DEBUG
vms_debug (1, "vms_close_and_cleanup (%p)\n", abfd);
#endif
! if (abfd == NULL
! || abfd->tdata.any == NULL)
return TRUE;
if (PRIV (vms_buf) != NULL)
--- 634,640 ----
#if VMS_DEBUG
vms_debug (1, "vms_close_and_cleanup (%p)\n", abfd);
#endif
! if (abfd == NULL || abfd->tdata.any == NULL)
return TRUE;
if (PRIV (vms_buf) != NULL)
***************
*** 441,449 ****
--- 646,668 ----
if (PRIV (vms_symbol_table))
bfd_hash_table_free (PRIV (vms_symbol_table));
+ bfd_map_over_sections (abfd, free_reloc_stream, NULL);
+
bfd_release (abfd, abfd->tdata.any);
abfd->tdata.any = NULL;
+ #ifdef VMS
+ if (abfd->direction == write_direction)
+ {
+ /* Last step on VMS is to convert the file to variable record length
+ format. */
+ if (bfd_cache_close (abfd) != TRUE)
+ return FALSE;
+ if (vms_convert_to_var_unix_filename (abfd->filename) != TRUE)
+ return FALSE;
+ }
+ #endif
+
return TRUE;
}
***************
*** 463,468 ****
--- 682,689 ----
static bfd_boolean
vms_new_section_hook (bfd * abfd, asection *section)
{
+ bfd_size_type amt;
+
/* Count hasn't been incremented yet. */
unsigned int section_count = abfd->section_count + 1;
***************
*** 470,476 ****
vms_debug (1, "vms_new_section_hook (%p, [%d]%s), count %d\n",
abfd, section->index, section->name, section_count);
#endif
! bfd_set_section_alignment (abfd, section, 4);
if (section_count > PRIV (section_count))
{
--- 691,698 ----
vms_debug (1, "vms_new_section_hook (%p, [%d]%s), count %d\n",
abfd, section->index, section->name, section_count);
#endif
!
! bfd_set_section_alignment (abfd, section, 0);
if (section_count > PRIV (section_count))
{
***************
*** 481,494 ****
--- 703,724 ----
return FALSE;
PRIV (section_count) = section_count;
}
+
#if VMS_DEBUG
vms_debug (6, "section_count: %d\n", PRIV (section_count));
#endif
+
PRIV (sections)[section->index] = section;
+
#if VMS_DEBUG
vms_debug (7, "%d: %s\n", section->index, section->name);
#endif
+ amt = sizeof (struct vms_section_data_struct);
+ section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
+ if (section->used_by_bfd == NULL)
+ return FALSE;
+
return _bfd_generic_new_section_hook (abfd, section);
}
***************
*** 503,515 ****
file_ptr offset ATTRIBUTE_UNUSED,
bfd_size_type buf_size ATTRIBUTE_UNUSED)
{
#if VMS_DEBUG
vms_debug (1, "vms_get_section_contents (%p, %s, %p, off %ld, size %d)\n",
abfd, section->name, buf, offset, (int)buf_size);
#endif
! /* Shouldn't be called, since all sections are IN_MEMORY. */
! return FALSE;
}
/* Read the contents of a section.
--- 733,774 ----
file_ptr offset ATTRIBUTE_UNUSED,
bfd_size_type buf_size ATTRIBUTE_UNUSED)
{
+ bfd_size_type size = section->size;
+
#if VMS_DEBUG
vms_debug (1, "vms_get_section_contents (%p, %s, %p, off %ld, size %d)\n",
abfd, section->name, buf, offset, (int)buf_size);
#endif
! if (section->contents)
! abort ();
!
! section->contents = (unsigned char *) bfd_malloc (size);
!
! if (section->contents == NULL)
! {
! bfd_set_error (bfd_error_no_memory);
! return FALSE;
! }
!
! if (bfd_seek (abfd, section->filepos, SEEK_SET))
! {
! bfd_set_error (bfd_error_file_truncated);
! return FALSE;
! }
!
! if (bfd_bread (section->contents, size, abfd) != size)
! {
! bfd_set_error (bfd_error_file_truncated);
! return FALSE;
! }
!
! section->flags |= SEC_IN_MEMORY;
!
! if (buf)
! memcpy (buf, section->contents + offset, (size_t) buf_size);
!
! return TRUE;
}
/* Read the contents of a section.
***************
*** 703,709 ****
#if VMS_DEBUG
vms_debug (1, "vms_truncate_arname (%p, %s, %s)\n", abfd, pathname, arhdr);
#endif
- return;
}
/* ??? write archive map. */
--- 962,967 ----
***************
*** 906,912 ****
if (ret == NULL)
return;
! if (bfd_is_com_section (sec))
ret->type = 'C';
else if (bfd_is_abs_section (sec))
ret->type = 'A';
--- 1164,1172 ----
if (ret == NULL)
return;
! if (sec == 0)
! ret->type = 'U';
! else if (bfd_is_com_section (sec))
ret->type = 'C';
else if (bfd_is_abs_section (sec))
ret->type = 'A';
***************
*** 972,978 ****
vms_debug (1, "vms_find_nearest_line (%p, %s, %p, %ld, <ret>, <ret>, <ret>)\n",
abfd, section->name, symbols, (long int)offset);
#endif
! return FALSE;
}
static bfd_boolean
--- 1232,1238 ----
vms_debug (1, "vms_find_nearest_line (%p, %s, %p, %ld, <ret>, <ret>, <ret>)\n",
abfd, section->name, symbols, (long int)offset);
#endif
! return _bfd_vms_find_nearest_dst_line (abfd, section, symbols, offset, file, func, line);
}
static bfd_boolean
***************
*** 1037,1072 ****
/* Part 4.6, relocations. */
! /* Return the number of bytes required to store the relocation information
! associated with section sect attached to bfd abfd.
! If an error occurs, return -1. */
! static long
! vms_get_reloc_upper_bound (bfd * abfd ATTRIBUTE_UNUSED,
! asection *section ATTRIBUTE_UNUSED)
{
#if VMS_DEBUG
! vms_debug (1, "vms_get_reloc_upper_bound (%p, %s)\n", abfd, section->name);
#endif
! return -1L;
}
! /* Call the back end associated with the open BFD abfd and translate the
! external form of the relocation information attached to sec into the
! internal canonical form. Place the table into memory at loc, which has
! been preallocated, usually by a call to bfd_get_reloc_upper_bound.
! Returns the number of relocs, or -1 on error. */
static long
! vms_canonicalize_reloc (bfd * abfd ATTRIBUTE_UNUSED,
! asection *section ATTRIBUTE_UNUSED,
! arelent **location ATTRIBUTE_UNUSED,
! asymbol **symbols ATTRIBUTE_UNUSED)
{
! #if VMS_DEBUG
! vms_debug (1, "vms_canonicalize_reloc (%p, %s, <ret>, <ret>)\n", abfd, section->name);
! #endif
! return FALSE;
}
/* This is just copied from ecoff-alpha, needs to be fixed probably. */
--- 1297,1456 ----
/* Part 4.6, relocations. */
! /* Allocate the reloc buffer for the specified section. */
! static void
! alloc_reloc_stream (bfd *abfd ATTRIBUTE_UNUSED, asection *section,
! void *alloc_error)
! {
! unsigned char *ptr;
!
! /* If there were no relocations, there is nothing to do. */
! if (section->reloc_count == 0)
! return;
!
! ptr = bfd_malloc (vms_section_data (section)->reloc_size);
! if (ptr == NULL)
! {
! *(bfd_boolean *)alloc_error = TRUE;
! return;
! }
!
! vms_section_data (section)->reloc_stream = ptr;
! }
!
! /* Read in the relocs for the specified section and internalize them.
!
! The implementation is loosely based on the SOM code and made up
! of 3 distinct phases:
!
! 1. When the VMS object is opened and parsed, the number and the size
! of the relocations are computed for all sections. This makes it
! possible to know upfront both which sections have no relocs and
! the size of the reloc buffers for the other sections, at virtually
! no cost for consumers that don't care about relocs at all.
!
! 2. When vms_slurp_reloc_table is invoked for the first time on a section
! with relocs, the object is traversed and all the reloc information
! is saved in per-section reloc buffers. It would be very inefficient
! to scan the whole file on each invocation, so we slurp for all the
! sections at once.
!
! 3. On subsequent invocations of vms_slurp_reloc_table, the relocs for the
! specified section are fetched from the buffer, decoded and internalized.
! The buffer is then freed since the internalized relocs are attached to
! the section, turning additional invocations of vms_slurp_reloc_table
! on the same section into no-ops.
!
! Since VMS objects have very few sections, it could be profitable to merge
! phase #2 and phase #3, i.e. to decode and internalize the relocs for all
! the sections at once. The current implementation is more elegant. */
!
! static bfd_boolean
! vms_slurp_reloc_table (bfd *abfd, asection *section, asymbol **symbols)
{
+ arelent *internal_relocs;
+ bfd_size_type amt;
+ int err;
+
+ /* If there were no relocations, there is nothing to do. */
+ if (section->reloc_count == 0)
+ return TRUE;
+
+ /* Return saved information about the relocations if it is available. */
+ if (section->relocation != NULL)
+ return TRUE;
+
+ /* If the relocation stream has not been slurped, do it now. */
+ if (vms_section_data (section)->reloc_stream == NULL)
+ {
+ bfd_boolean alloc_error = FALSE;
+ int type;
+
+ /* Size the reloc buffer for each section. */
+ bfd_map_over_sections (abfd, alloc_reloc_stream, &alloc_error);
+ if (alloc_error)
+ return FALSE;
+
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ return FALSE;
+
+ /* Reset section pointer. */
+ PRIV (image_section) = NULL;
+
+ do
+ {
+ type = _bfd_vms_get_object_record (abfd);
+ if (type != EOBJ_S_C_ETIR
+ && type != EOBJ_S_C_EDBG
+ && type != EOBJ_S_C_ETBT)
+ continue;
+ err = _bfd_vms_slurp_relocs (abfd);
+ if (err != 0)
+ {
#if VMS_DEBUG
! vms_debug (2, "slurp relocs failed with %d\n", err);
#endif
! return FALSE;
! }
! }
! while (type != EOBJ_S_C_EEOM);
! }
!
! amt = section->reloc_count * sizeof (arelent);
! internal_relocs = (arelent *) bfd_zalloc (abfd, amt);
! if (internal_relocs == NULL)
! return FALSE;
!
! /* Decode and internalize the relocations. */
! err = _bfd_vms_decode_relocs (abfd, internal_relocs, section, symbols);
! if (err != 0)
! {
! #if VMS_DEBUG
! vms_debug (2, "decode relocs failed with %d\n", err);
! #endif
! return FALSE;
! }
!
! /* We're done with the external relocations. Free them. */
! free (vms_section_data (section)->reloc_stream);
! vms_section_data (section)->reloc_stream = NULL;
!
! /* Save our results and return success. */
! section->relocation = internal_relocs;
! return TRUE;
}
! /* Return the number of bytes required to store the relocation
! information associated with the given section. */
static long
! vms_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *section)
{
! return (section->reloc_count + 1) * sizeof (arelent *);
! }
!
! /* Convert relocations from VMS (external) form into BFD internal
! form. Return the number of relocations. */
!
! static long
! vms_canonicalize_reloc (bfd *abfd, asection *section, arelent **relptr,
! asymbol **symbols)
! {
! arelent *tblptr;
! int count;
!
! if (! vms_slurp_reloc_table (abfd, section, symbols))
! return -1;
!
! count = section->reloc_count;
! tblptr = section->relocation;
!
! while (count--)
! *relptr++ = tblptr++;
!
! *relptr = (arelent *) NULL;
! return section->reloc_count;
}
/* This is just copied from ecoff-alpha, needs to be fixed probably. */
***************
*** 1317,1322 ****
--- 1701,1764 ----
0xffffffff, /* Dest mask. */
FALSE), /* PC rel offset. */
+ HOWTO (ALPHA_R_NOP, /* Type. */
+ 0, /* Rightshift. */
+ 3, /* Size (0 = byte, 1 = short, 2 = long). */
+ 0, /* Bitsize. */
+ /* The following value must match that of ALPHA_R_BSR/ALPHA_R_BOH
+ because the calculations for the 3 relocations are the same.
+ See B.4.5.2 of the OpenVMS Linker Utility Manual. */
+ TRUE, /* PC relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont,/* Complain_on_overflow. */
+ reloc_nil, /* Special_function. */
+ "NOP", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0xffffffff, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel offset. */
+
+ HOWTO (ALPHA_R_BSR, /* Type. */
+ 0, /* Rightshift. */
+ 3, /* Size (0 = byte, 1 = short, 2 = long). */
+ 0, /* Bitsize. */
+ TRUE, /* PC relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont,/* Complain_on_overflow. */
+ reloc_nil, /* Special_function. */
+ "BSR", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0xffffffff, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel offset. */
+
+ HOWTO (ALPHA_R_LDA, /* Type. */
+ 0, /* Rightshift. */
+ 3, /* Size (0 = byte, 1 = short, 2 = long). */
+ 0, /* Bitsize. */
+ FALSE, /* PC relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont,/* Complain_on_overflow. */
+ reloc_nil, /* Special_function. */
+ "LDA", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0xffffffff, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel offset. */
+
+ HOWTO (ALPHA_R_BOH, /* Type. */
+ 0, /* Rightshift. */
+ 3, /* Size (0 = byte, 1 = short, 2 = long, 3 = nil). */
+ 0, /* Bitsize. */
+ TRUE, /* PC relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont,/* Complain_on_overflow. */
+ reloc_nil, /* Special_function. */
+ "BOH", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0xffffffff, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel offset. */
};
/* Return a pointer to a howto structure which, when invoked, will perform
***************
*** 1345,1350 ****
--- 1787,1796 ----
case BFD_RELOC_64_PCREL: alpha_type = ALPHA_R_SREL64; break;
case BFD_RELOC_ALPHA_LINKAGE: alpha_type = ALPHA_R_LINKAGE; break;
case BFD_RELOC_ALPHA_CODEADDR: alpha_type = ALPHA_R_CODEADDR; break;
+ case BFD_RELOC_ALPHA_NOP: alpha_type = ALPHA_R_NOP; break;
+ case BFD_RELOC_ALPHA_BSR: alpha_type = ALPHA_R_BSR; break;
+ case BFD_RELOC_ALPHA_LDA: alpha_type = ALPHA_R_LDA; break;
+ case BFD_RELOC_ALPHA_BOH: alpha_type = ALPHA_R_BOH; break;
default:
(*_bfd_error_handler) ("reloc (%d) is *UNKNOWN*", code);
return NULL;
***************
*** 1385,1398 ****
#if VMS_DEBUG
vms_debug (1, "vms_set_arch_mach (%p, %d, %ld)\n", abfd, arch, mach);
#endif
- abfd->arch_info = bfd_scan_arch ("alpha");
! return TRUE;
}
/* Sets the contents of the section section in BFD abfd to the data starting
! in memory at data. The data is written to the output section starting at
! offset offset for count bytes.
Normally TRUE is returned, else FALSE. Possible error returns are:
o bfd_error_no_contents - The output section does not have the
--- 1831,1848 ----
#if VMS_DEBUG
vms_debug (1, "vms_set_arch_mach (%p, %d, %ld)\n", abfd, arch, mach);
#endif
! if (arch != bfd_arch_alpha
! && arch != bfd_arch_vax
! && arch != bfd_arch_unknown)
! return FALSE;
!
! return bfd_default_set_arch_mach (abfd, arch, mach);
}
/* Sets the contents of the section section in BFD abfd to the data starting
! in memory at LOCATION. The data is written to the output section starting
! at offset offset for count bytes.
Normally TRUE is returned, else FALSE. Possible error returns are:
o bfd_error_no_contents - The output section does not have the
***************
*** 1411,1417 ****
abfd, section->name, location, (long int)offset, (int)count);
vms_debug (2, "size %d\n", (int) section->size);
#endif
! return _bfd_save_vms_section (abfd, section, location, offset, count);
}
/* Part 4.8, linker. */
--- 1861,1876 ----
abfd, section->name, location, (long int)offset, (int)count);
vms_debug (2, "size %d\n", (int) section->size);
#endif
! if (count == (bfd_size_type)0)
! return TRUE;
!
! if (section->contents == NULL)
! section->contents = bfd_alloc (abfd, section->size);
! if (section->contents == NULL)
! return FALSE;
!
! memcpy (section->contents + offset, location, (size_t) count);
! return TRUE;
}
/* Part 4.8, linker. */
***************
*** 1550,1556 ****
#if VMS_DEBUG
vms_debug (1, "vms_get_dynamic_symtab_upper_bound (%p)\n", abfd);
#endif
! return 0;
}
static bfd_boolean
--- 2009,2015 ----
#if VMS_DEBUG
vms_debug (1, "vms_get_dynamic_symtab_upper_bound (%p)\n", abfd);
#endif
! return 0L;
}
static bfd_boolean
***************
*** 1601,1619 ****
const bfd_target vms_alpha_vec =
{
! "vms-alpha", /* Name. */
bfd_target_evax_flavour,
! BFD_ENDIAN_LITTLE, /* Data byte order is little. */
! BFD_ENDIAN_LITTLE, /* Header byte order is little. */
! (HAS_RELOC | HAS_SYMS
! | WP_TEXT | D_PAGED), /* Object flags. */
(SEC_ALLOC | SEC_LOAD | SEC_RELOC
| SEC_READONLY | SEC_CODE | SEC_DATA
! | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* Sect flags. */
! 0, /* Symbol_leading_char. */
! ' ', /* AR_pad_char. */
! 15, /* AR_max_namelen. */
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
bfd_getl16, bfd_getl_signed_16, bfd_putl16,
--- 2060,2078 ----
const bfd_target vms_alpha_vec =
{
! "vms-alpha", /* name */
bfd_target_evax_flavour,
! BFD_ENDIAN_LITTLE, /* data byte order is little */
! BFD_ENDIAN_LITTLE, /* header byte order is little */
! (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
! | WP_TEXT | D_PAGED), /* object flags */
(SEC_ALLOC | SEC_LOAD | SEC_RELOC
| SEC_READONLY | SEC_CODE | SEC_DATA
! | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* sect flags */
! 0, /* symbol_leading_char */
! ' ', /* ar_pad_char */
! 15, /* ar_max_namelen */
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
bfd_getl16, bfd_getl_signed_16, bfd_putl16,
***************
*** 1621,1631 ****
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
bfd_getl16, bfd_getl_signed_16, bfd_putl16,
! {_bfd_dummy_target, vms_object_p, /* bfd_check_format. */
vms_archive_p, _bfd_dummy_target},
! {bfd_false, vms_mkobject, /* bfd_set_format. */
_bfd_generic_mkarchive, bfd_false},
! {bfd_false, vms_write_object_contents, /* bfd_write_contents. */
_bfd_write_archive_contents, bfd_false},
BFD_JUMP_TABLE_GENERIC (vms),
--- 2080,2090 ----
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
bfd_getl16, bfd_getl_signed_16, bfd_putl16,
! {_bfd_dummy_target, vms_object_p, /* bfd_check_format */
vms_archive_p, _bfd_dummy_target},
! {bfd_false, vms_mkobject, /* bfd_set_format */
_bfd_generic_mkarchive, bfd_false},
! {bfd_false, vms_write_object_contents, /* bfd_write_contents */
_bfd_write_archive_contents, bfd_false},
BFD_JUMP_TABLE_GENERIC (vms),
***************
*** 1640,1677 ****
NULL,
! NULL
};
const bfd_target vms_vax_vec =
{
! "vms-vax", /* Name. */
bfd_target_ovax_flavour,
! BFD_ENDIAN_LITTLE, /* Data byte order is little. */
! BFD_ENDIAN_LITTLE, /* Header byte order is little. */
! (HAS_RELOC | HAS_SYMS /* Object flags. */
| WP_TEXT | D_PAGED
| HAS_LINENO | HAS_DEBUG | HAS_LOCALS),
(SEC_ALLOC | SEC_LOAD | SEC_RELOC
| SEC_READONLY | SEC_CODE | SEC_DATA
! | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* Sect flags. */
! 0, /* Symbol_leading_char. */
! ' ', /* AR_pad_char. */
! 15, /* AR_max_namelen. */
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
! bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
! bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers. */
! {_bfd_dummy_target, vms_object_p, /* bfd_check_format. */
vms_archive_p, _bfd_dummy_target},
! {bfd_false, vms_mkobject, /* bfd_set_format. */
_bfd_generic_mkarchive, bfd_false},
! {bfd_false, vms_write_object_contents, /* bfd_write_contents. */
_bfd_write_archive_contents, bfd_false},
BFD_JUMP_TABLE_GENERIC (vms),
--- 2099,2136 ----
NULL,
! (PTR) 0
};
const bfd_target vms_vax_vec =
{
! "vms-vax", /* name */
bfd_target_ovax_flavour,
! BFD_ENDIAN_LITTLE, /* data byte order is little */
! BFD_ENDIAN_LITTLE, /* header byte order is little */
! (HAS_RELOC | HAS_SYMS /* object flags */
| WP_TEXT | D_PAGED
| HAS_LINENO | HAS_DEBUG | HAS_LOCALS),
(SEC_ALLOC | SEC_LOAD | SEC_RELOC
| SEC_READONLY | SEC_CODE | SEC_DATA
! | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* sect flags */
! 0, /* symbol_leading_char */
! ' ', /* ar_pad_char */
! 15, /* ar_max_namelen */
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
! bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
! bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
! {_bfd_dummy_target, vms_object_p, /* bfd_check_format */
vms_archive_p, _bfd_dummy_target},
! {bfd_false, vms_mkobject, /* bfd_set_format */
_bfd_generic_mkarchive, bfd_false},
! {bfd_false, vms_write_object_contents, /* bfd_write_contents */
_bfd_write_archive_contents, bfd_false},
BFD_JUMP_TABLE_GENERIC (vms),
***************
*** 1686,1690 ****
NULL,
! NULL
};
--- 2145,2149 ----
NULL,
! (PTR) 0
};
Index: bfd/vms.h
===================================================================
RCS file: /cvs/src/src/bfd/vms.h,v
retrieving revision 1.13
diff -c -r1.13 vms.h
*** bfd/vms.h 3 Jul 2007 14:26:43 -0000 1.13
--- bfd/vms.h 17 Feb 2009 11:13:10 -0000
***************
*** 1,6 ****
/* vms.h -- Header file for VMS (Alpha and Vax) support.
! Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
! Free Software Foundation, Inc.
Written by Klaus K"ampf (kkaempf@rmi.de)
--- 1,8 ----
/* vms.h -- Header file for VMS (Alpha and Vax) support.
! Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007,
! 2008, 2009 Free Software Foundation, Inc.
!
! Main header file.
Written by Klaus K"ampf (kkaempf@rmi.de)
***************
*** 25,33 ****
#ifndef VMS_H
#define VMS_H
! /* Constants starting with 'Exxx_' are for openVMS/Alpha (EVAX object language) */
! /* VMS Text, information and relocation record (TIR/ETIR) definitions. */
#define TIR_S_C_STA_GBL 0
#define TIR_S_C_STA_SB 1
--- 27,38 ----
#ifndef VMS_H
#define VMS_H
! /* Constants starting with 'Exxx_' are for openVMS/Alpha (EVAX object
! language). */
!
! #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_SB 1
***************
*** 107,113 ****
#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_QW 2 /* Stack quadword. */
! #define ETIR_S_C_STA_PQ 3 /* Stack psect base plus quadword offset. */
#define ETIR_S_C_STA_LI 4 /* Stack literal. */
#define ETIR_S_C_STA_MOD 5 /* Stack module. */
#define ETIR_S_C_STA_CKARG 6 /* Check Arguments. */
--- 112,118 ----
#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_QW 2 /* Stack quadword. */
! #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_MOD 5 /* Stack module. */
#define ETIR_S_C_STA_CKARG 6 /* Check Arguments. */
***************
*** 173,179 ****
#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. */
! /* VMS Global symbol definition record (GSD/EGSD). */
#define GSD_S_K_ENTRIES 1
#define GSD_S_C_ENTRIES 1
--- 178,186 ----
#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_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_C_ENTRIES 1
***************
*** 206,211 ****
--- 213,219 ----
#define EGSD_S_C_SYMG 8 /* EGST - gst version of SYM. */
#define EGSD_S_C_MAXRECTYP 8 /* Maximum entry type defined. */
+ /* Program Section Definition. */
#define GPS_S_M_PIC 1
#define GPS_S_M_LIB 2
#define GPS_S_M_OVR 4
***************
*** 219,249 ****
#define GPS_S_K_NAME 9
#define GPS_S_C_NAME 9
! #define EGPS_S_V_PIC 0x0001
! #define EGPS_S_V_LIB 0x0002
! #define EGPS_S_V_OVR 0x0004
! #define EGPS_S_V_REL 0x0008
! #define EGPS_S_V_GBL 0x0010
! #define EGPS_S_V_SHR 0x0020
! #define EGPS_S_V_EXE 0x0040
! #define EGPS_S_V_RD 0x0080
! #define EGPS_S_V_WRT 0x0100
! #define EGPS_S_V_VEC 0x0200
! #define EGPS_S_V_NOMOD 0x0400
! #define EGPS_S_V_COM 0x0800
#define GSY_S_M_WEAK 1
#define GSY_S_M_DEF 2
#define GSY_S_M_UNI 4
#define GSY_S_M_REL 8
! #define EGSY_S_V_WEAK 0x0001
! #define EGSY_S_V_DEF 0x0002
! #define EGSY_S_V_UNI 0x0004
! #define EGSY_S_V_REL 0x0008
! #define EGSY_S_V_COMM 0x0010
! #define EGSY_S_V_VECEP 0x0020
! #define EGSY_S_V_NORM 0x0040
#define LSY_S_M_DEF 2
#define LSY_S_M_REL 8
--- 227,267 ----
#define GPS_S_K_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_LIB 0x0002
! #define EGPS_S_V_OVR 0x0004
! #define EGPS_S_V_REL 0x0008
! #define EGPS_S_V_GBL 0x0010
! #define EGPS_S_V_SHR 0x0020
! #define EGPS_S_V_EXE 0x0040
! #define EGPS_S_V_RD 0x0080
! #define EGPS_S_V_WRT 0x0100
! #define EGPS_S_V_VEC 0x0200
! #define EGPS_S_V_NOMOD 0x0400
! #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_DEF 2
#define GSY_S_M_UNI 4
#define GSY_S_M_REL 8
! #define EGSY_S_W_FLAGS 6
!
! #define EGSY_S_V_WEAK 0x0001
! #define EGSY_S_V_DEF 0x0002
! #define EGSY_S_V_UNI 0x0004
! #define EGSY_S_V_REL 0x0008
! #define EGSY_S_V_COMM 0x0010
! #define EGSY_S_V_VECEP 0x0020
! #define EGSY_S_V_NORM 0x0040
! #define EGSY_S_V_QUAD_VAL 0x0080
#define LSY_S_M_DEF 2
#define LSY_S_M_REL 8
***************
*** 251,260 ****
--- 269,294 ----
#define ENV_S_M_DEF 1
#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,
as no machine-readable version seems to be available. */
#define DST_S_C_C 7 /* 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_SOURCE 155 /* Source file. */
#define DST_S_C_PROLOG 162
***************
*** 269,283 ****
#define DST_S_C_MODEND 189 /* End of module. */
#define DST_S_C_RTNBEG 190 /* Beginning of routine.*/
#define DST_S_C_RTNEND 191 /* End of routine. */
! #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_W 3 /* Incr Line #. */
! #define DST_S_C_SET_LINUM_INCR 4
#define DST_S_C_SET_LINUM_INCR_W 5
#define DST_S_C_RESET_LINUM_INCR 6
! #define DST_S_C_BEG_STMT_MODE 7
! #define DST_S_C_END_STMT_MODE 8
! #define DST_S_C_SET_LINE_NUM 9 /* Set Line #. */
#define DST_S_C_SET_PC 10
#define DST_S_C_SET_PC_W 11
#define DST_S_C_SET_PC_L 12
--- 303,321 ----
#define DST_S_C_MODEND 189 /* End of module. */
#define DST_S_C_RTNBEG 190 /* Beginning 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_INCR_LINUM 2 /* Incr Line #. */
! #define DST_S_C_INCR_LINUM_W 3 /* Incr Line #. */
! #define DST_S_C_SET_LINUM_INCR 4
#define DST_S_C_SET_LINUM_INCR_W 5
#define DST_S_C_RESET_LINUM_INCR 6
! #define DST_S_C_BEG_STMT_MODE 7
! #define DST_S_C_END_STMT_MODE 8
! #define DST_S_C_SET_LINE_NUM 9 /* Set Line #. */
#define DST_S_C_SET_PC 10
#define DST_S_C_SET_PC_W 11
#define DST_S_C_SET_PC_L 12
***************
*** 295,303 ****
--- 333,364 ----
#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_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_B 11 /* # of line, byte counter. */
#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 list is included under 'advanced_type'. */
#define DBG_S_C_UCHAR 0x02
***************
*** 328,333 ****
--- 389,395 ----
#define DSC_K_CLASS_D 0x02 /* Dynamic string (not via malloc!). */
#define DSC_K_CLASS_A 0x04 /* Array. */
#define DSC_K_CLASS_UBS 0x0d /* Unaligned bit string. */
+
/* These are the codes that are used to generate the definitions of struct
union and enum records. */
#define DBG_S_C_ENUM_ITEM 0xa4
***************
*** 336,342 ****
#define DBG_S_C_STRUCT_ITEM DST_K_VFLAGS_BITOFFS /* 0xff */
#define DBG_S_C_STRUCT_START 0xab
#define DBG_S_C_STRUCT_END 0xac
! #define DST_K_TYPSPEC 0xaf /* Type specification. */
/* These codes are used in the generation of the symbol definition records. */
#define DST_K_VFLAGS_NOVAL 0x80 /* Struct definition only. */
#define DST_K_VFLAGS_DSC 0xfa /* Descriptor used. */
--- 398,404 ----
#define DBG_S_C_STRUCT_ITEM DST_K_VFLAGS_BITOFFS /* 0xff */
#define DBG_S_C_STRUCT_START 0xab
#define DBG_S_C_STRUCT_END 0xac
! #define DST_K_TYPSPEC 0xaf /* Type specification. */
/* These codes are used in the generation of the symbol definition records. */
#define DST_K_VFLAGS_NOVAL 0x80 /* Struct definition only. */
#define DST_K_VFLAGS_DSC 0xfa /* Descriptor used. */
***************
*** 379,385 ****
#define DBG_S_C_VOID DST_K_TS_PTR
#define DBG_S_C_COMPLEX_ARRAY DST_K_TS_ARRAY
! /* VMS Module header record (EMH) definitions. */
#define MHD_S_C_MHD 0
#define MHD_S_C_LNM 1
--- 441,447 ----
#define DBG_S_C_VOID DST_K_TS_PTR
#define DBG_S_C_COMPLEX_ARRAY DST_K_TS_ARRAY
! /* VMS Module Header Records (MHD/EMH). */
#define MHD_S_C_MHD 0
#define MHD_S_C_LNM 1
***************
*** 402,449 ****
/* vms.c. */
extern asymbol *_bfd_vms_make_empty_symbol (bfd *);
/* vms-gsd.c. */
! extern int _bfd_vms_slurp_gsd (bfd *, int);
! extern int _bfd_vms_write_gsd (bfd *, int);
! /* vms-mhd.c. */
! extern int _bfd_vms_slurp_hdr (bfd *, int);
! extern int _bfd_vms_write_hdr (bfd *, int);
! extern int _bfd_vms_slurp_eom (bfd *, int);
! extern int _bfd_vms_write_eom (bfd *, int);
! /* vms-tir.c. */
- extern int _bfd_vms_slurp_tir (bfd *, int);
- extern int _bfd_vms_slurp_dbg (bfd *, int);
- extern int _bfd_vms_slurp_tbt (bfd *, int);
- extern int _bfd_vms_slurp_lnk (bfd *, int);
-
- extern int _bfd_vms_write_tir (bfd *, int);
- extern int _bfd_vms_write_tbt (bfd *, int);
- extern int _bfd_vms_write_dbg (bfd *, int);
-
- /* The r_type field in a reloc is one of he following values. */
- #define ALPHA_R_IGNORE 0
- #define ALPHA_R_REFQUAD 1
- #define ALPHA_R_BRADDR 2
- #define ALPHA_R_HINT 3
- #define ALPHA_R_SREL16 4
- #define ALPHA_R_SREL32 5
- #define ALPHA_R_SREL64 6
- #define ALPHA_R_OP_PUSH 7
- #define ALPHA_R_OP_STORE 8
- #define ALPHA_R_OP_PSUB 9
- #define ALPHA_R_OP_PRSHIFT 10
- #define ALPHA_R_LINKAGE 11
- #define ALPHA_R_REFLONG 12
- #define ALPHA_R_CODEADDR 13
-
- /* Object language definitions. */
-
#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_TIR 2 /* VAX tet information record. */
--- 464,531 ----
/* vms.c. */
extern asymbol *_bfd_vms_make_empty_symbol (bfd *);
+ extern int _bfd_vms_slurp_object_records (bfd *abfd);
/* vms-gsd.c. */
! extern int _bfd_vms_slurp_gsd (bfd *abfd, int objtype);
! 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-misc.c. */
!
! extern int _bfd_vms_get_object_record (bfd *abfd);
! extern int _bfd_vms_get_first_record (bfd *abfd);
!
! /* 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. */
! extern int _bfd_vms_slurp_tir (bfd *abfd, int objtype);
! extern int _bfd_vms_write_tir (bfd *abfd, int objtype);
! extern int _bfd_vms_slurp_lnk (bfd *abfd, int objtype);
!
! extern int _bfd_vms_slurp_relocs (bfd *abfd);
! extern int _bfd_vms_decode_relocs
! (bfd *abfd, arelent *relocs, asection *section, asymbol **symbols);
!
! /* The r_type field in a reloc is one of the following values. */
! #define ALPHA_R_IGNORE 0
! #define ALPHA_R_REFQUAD 1
! #define ALPHA_R_BRADDR 2
! #define ALPHA_R_HINT 3
! #define ALPHA_R_SREL16 4
! #define ALPHA_R_SREL32 5
! #define ALPHA_R_SREL64 6
! #define ALPHA_R_OP_PUSH 7
! #define ALPHA_R_OP_STORE 8
! #define ALPHA_R_OP_PSUB 9
! #define ALPHA_R_OP_PRSHIFT 10
! #define ALPHA_R_LINKAGE 11
! #define ALPHA_R_REFLONG 12
! #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
! /* VMS Object Language (OBJ/EOBJ). */
#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_TIR 2 /* VAX tet information record. */
***************
*** 453,465 ****
#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_MAXRECTYP 7 /* VAX Lat assigned record type. */
#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_EGSD 10 /* EVAX gobal symbol definition record.*/
! #define EOBJ_S_C_ETIR 11 /* EVAX txt 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_MAXRECTYP 13 /* EVAX Lst assigned record type. */
#define OBJ_S_K_SUBTYP 1
#define OBJ_S_C_SUBTYP 1
#define EOBJ_S_K_SUBTYP 4
--- 535,549 ----
#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_MAXRECTYP 7 /* VAX Lat assigned record type. */
+
#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_EGSD 10 /* EVAX gobal symbol definition record. */
! #define EOBJ_S_C_ETIR 11 /* EVAX txt 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_MAXRECTYP 13 /* EVAX Lst assigned record type. */
+
#define OBJ_S_K_SUBTYP 1
#define OBJ_S_C_SUBTYP 1
#define EOBJ_S_K_SUBTYP 4
***************
*** 475,482 ****
#define EOBJ_S_C_STOREPLIM -1 /* Maximu repeat count on store commands. */
#define OBJ_S_C_PSCALILIM 9 /* 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. */
/* Miscellaneous definitions. */
#if __GNUC__
--- 559,567 ----
#define EOBJ_S_C_STOREPLIM -1 /* Maximu repeat count on store commands. */
#define OBJ_S_C_PSCALILIM 9 /* 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. */
+
/* Miscellaneous definitions. */
#if __GNUC__
***************
*** 484,623 ****
#else
typedef unsigned long uquad;
#endif
!
! #define MAX_OUTREC_SIZE 4096
! #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. */
!
! struct hdr_struc
! {
! int hdr_b_strlvl;
! long hdr_l_arch1;
! long hdr_l_arch2;
! long hdr_l_recsiz;
! char * hdr_t_name;
! char * hdr_t_version;
! char * hdr_t_date;
! char * hdr_c_lnm;
! char * hdr_c_src;
! char * hdr_c_ttl;
! };
!
! /* VMS end of module. */
!
! struct eom_struc
! {
! long eom_l_total_lps;
! unsigned char eom_b_comcod;
! bfd_boolean eom_has_transfer;
! unsigned char eom_b_tfrflg;
! long eom_l_psindx;
! long eom_l_tfradr;
! };
!
! enum file_format_enum { FF_UNKNOWN, FF_FOREIGN, FF_NATIVE, FF_VAX };
!
! typedef struct vms_symbol_struct
! {
! struct bfd_hash_entry bfd_hash;
! asymbol *symbol;
! } vms_symbol_entry;
!
/* Stack value for push/pop commands. */
!
! struct stack_struct
! {
! uquad value;
! int psect;
! };
! #define STACKSIZE 8192
!
! /* location stack definitions for CTL_DFLC, CTL_STLOC, and CTL_STKDL */
!
! struct location_struct
! {
! unsigned long value;
! int psect;
! };
! #define LOCATION_SAVE_SIZE 32
!
! #define VMS_SECTION_COUNT 1024
!
! struct vms_private_data_struct
! {
! bfd_boolean is_vax;
bfd_boolean fixup_done; /* Flag to indicate if all
section pointers and PRIV(sections)
are set up correctly. */
! unsigned char *vms_buf; /* Buffer to record. */
! int buf_size; /* Max size of buffer. */
! unsigned char *vms_rec; /* Actual record ptr. */
! int rec_length; /* Remaining record length. */
! int rec_size; /* Actual record size. */
! int rec_type; /* Actual record type. */
! enum file_format_enum file_format;
!
! struct hdr_struc hdr_data; /* Data from HDR/EMH record. */
! struct eom_struc eom_data; /* Data from EOM/EEOM record. */
! unsigned int section_count; /* # of sections in following array. */
! asection **sections; /* Array of GSD/EGSD sections. */
! int gsd_sym_count; /* # of GSD/EGSD symbols. */
! asymbol **symbols; /* Vector of GSD/EGSD symbols. */
! struct proc_value *procedure;
!
! struct stack_struct *stack;
! int stackptr;
!
! vms_section *vms_section_table[VMS_SECTION_COUNT];
!
struct bfd_hash_table *vms_symbol_table;
! struct bfd_symbol **symcache;
! int symnum;
!
! struct location_struct *location_stack;
!
! asection *image_section; /* Section for image_ptr. */
! unsigned char *image_ptr; /* A pointer to section->contents. */
!
! unsigned char pdsc[8]; /* Procedure descriptor. */
!
! /* Output routine storage. */
! unsigned char *output_buf; /* Output data. */
! int push_level;
! int pushed_size;
! int length_pos;
! int output_size;
! int output_alignment;
!
! /* Linkage index counter
! used by conditional store commands (TIR_S_C_STC_). */
! int vms_linkage_index;
!
! /* see tc-alpha.c of gas for a descripton. */
! int flag_hash_long_names; /* -+, hash instead of truncate. */
! int flag_show_after_trunc; /* -H, shw hashing/truncation. */
! };
!
! #define PRIV(name) ((struct vms_private_data_struct *) abfd->tdata.any)->name
!
#define SECTION_NAME_TEMPLATE "__SEC__%d"
#if VMS_DEBUG
--- 569,854 ----
#else
typedef unsigned long uquad;
#endif
!
! #define MAX_OUTREC_SIZE 4096
! #define MIN_OUTREC_LUFT 64
!
/* VMS module header. */
!
! struct hdr_struct
! {
! char hdr_b_strlvl;
! int hdr_l_arch1;
! int hdr_l_arch2;
! int hdr_l_recsiz;
! char *hdr_t_name;
! char *hdr_t_version;
! char *hdr_t_date;
! char *hdr_c_lnm;
! char *hdr_c_src;
! char *hdr_c_ttl;
! char *hdr_c_cpr;
! };
!
! #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
!
! #define EMH_DATE_LENGTH 17
!
! /* VMS End-Of-Module records (EOM/EEOM). */
!
! struct eom_struct
! {
! int eom_l_total_lps;
! short eom_w_comcod;
! bfd_boolean eom_has_transfer;
! char eom_b_tfrflg;
! int eom_l_psindx;
! int eom_l_tfradr;
! };
!
! #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
! {
! struct bfd_hash_entry bfd_hash;
! asymbol *symbol;
! } vms_symbol_entry;
!
/* Stack value for push/pop commands. */
!
! struct stack_struct
! {
! uquad value;
! int psect;
! };
!
! #define STACKSIZE 8192
!
! /* A minimal decoding of DST compilation units. We only decode
! what's needed to get to the line number information. */
!
! struct fileinfo
! {
! char *name;
! unsigned int srec;
! };
!
! 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
! {
! bfd_boolean is_vax;
bfd_boolean fixup_done; /* Flag to indicate if all
section pointers and PRIV(sections)
are set up correctly. */
! unsigned char *vms_buf; /* record buffer */
! unsigned int buf_size; /* size of record buffer */
! unsigned char *vms_rec; /* record pointer in record buffer */
! unsigned int rec_size; /* record size */
! enum file_format_enum file_format;
!
! struct hdr_struct hdr_data; /* data from HDR/EMH record */
! struct eom_struct eom_data; /* data from EOM/EEOM record */
! unsigned int section_count; /* # of sections in following array */
! asection **sections; /* array of GSD/EGSD sections */
! unsigned int gsd_sym_count; /* # of GSD/EGSD symbols */
! asymbol **symbols; /* vector of GSD/EGSD symbols */
! struct proc_value *procedure;
!
! struct stack_struct *stack;
! int stackptr;
!
struct bfd_hash_table *vms_symbol_table;
! struct bfd_symbol **symcache;
! int symnum;
!
! asection *image_section; /* section for image_ptr */
! unsigned char *image_ptr; /* a pointer to section->contents */
!
! unsigned char pdsc[8]; /* procedure descriptor */
!
! struct module *modules; /* list of all compilation units */
!
! struct dst_info *dst_info;
! 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 pushed_size;
! int length_pos;
! int output_size;
! int output_alignment;
!
! /* linkage index counter used by conditional store commands */
! int vms_linkage_index;
!
! /* see tc-alpha.c of gas for a description. */
! int flag_hash_long_names; /* -+, hash instead of truncate */
! int flag_show_after_trunc; /* -H, show hashing/truncation */
! };
!
! #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"
#if VMS_DEBUG
***************
*** 635,641 ****
extern char * _bfd_vms_save_counted_string (unsigned char *);
extern void _bfd_vms_push (bfd *, uquad, 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_alignment (bfd *, int);
extern void _bfd_vms_output_push (bfd *);
--- 866,871 ----
***************
*** 653,656 ****
--- 883,889 ----
extern char * _bfd_vms_length_hash_symbol (bfd *, const char *, int);
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 */
More information about the Binutils
mailing list