/**************************************************************** * * * Copyright 2001, 2012 Fidelity Information Services, Inc * * * * This source code contains the intellectual property * * of its copyright holder(s), and is made available * * under a license. If you do not know the terms of * * the license, please stop and do not read further. * * * ****************************************************************/ #ifndef RTNHDR_H_INCLUDED #define RTNHDR_H_INCLUDED /* rtnhdr.h - routine header for shared binary Unix platforms */ /* There are several references to this structure from assembly language; these include: * * From Unix: g_msf.si * * Any changes to the routine header must be reflected in those files as well. * * Warning: the list above may not be complete. */ /* Variable table entry */ typedef mname_entry var_tabent; /* the actual variable name is stored in the literal text pool */ /* Linenumber table entry */ typedef int4 lnr_tabent; /* Label table entry */ typedef struct { mident lab_name; /* The name of the label */ lnr_tabent *lnr_adr; /* Pointer to lnrtab entry offset into code for this label */ boolean_t has_parms; /* Flag to indicate whether the callee has a formallist */ GTM64_ONLY(int4 filler;) } lab_tabent; /* Label table entry proxy for run-time linking */ typedef struct { lnr_tabent *lnr_adr; /* Pointer to lnrtab entry offset into code for this label */ boolean_t has_parms; /* Flag to indicate whether the callee has a formallist */ } lab_tabent_proxy; /* Linkage table entry */ typedef struct { char_ptr_t ext_ref; /* Address (quadword on alpha) this linkage entry resolves to or NULL */ } lnk_tabent; /* rhead_struct is the routine header; it occurs at the beginning of the * object code part of each module. Since this structure may be resident in * a shared library, this structure is considered inviolate. Therefore there is * a process-private version of this header that is modified as necessary and * always points to the current version. * * The routine header is initialized when a module is first linked into * an executable. The fields marked with "(#)" are updated when the routine * is replaced by a newer version via explicit zlink. */ typedef struct rhead_struct { char jsb[RHEAD_JSB_SIZE]; /* GTM_CODE object marker */ void_ptr_t shlib_handle; /* Null if header not for shared object. Non-zero means header is * describing shared library resident routine and this is its handle. * Note this is an 8 byte field on Tru64 (hence its position near top). */ mstr src_full_name; /* (#) fully qualified path of routine source code */ uint4 compiler_qlf; /* bit flags of compiler qualifiers used (see cmd_qlf.h) */ uint4 objlabel; /* Object code level/label (see objlable.h). * Note: this field must be the 10th word (11th on Tru64) on 32-bit * environments so that incr_link() can deference object label from old * (pre-V5 32-bit) objects as well. In 64-bit environments though, this * situation wouldn't occur since dlopen() would/should have failed * when a 32-bit shared library is loaded */ mident routine_name; /* external routine name */ var_tabent *vartab_adr; /* (#) address of variable table (offset in original rtnhdr) */ int4 vartab_len; /* (#) number of variable table entries */ lab_tabent *labtab_adr; /* address of label table (offset in original rtnhdr) */ int4 labtab_len; /* number of label table entries */ lnr_tabent *lnrtab_adr; /* address of linenumber table (offset in original rtnhdr) */ int4 lnrtab_len; /* number of linenumber table entries */ unsigned char *literal_text_adr; /* address of literal text pool (offset in original rtnhdr) */ int4 literal_text_len; /* length of literal text pool */ mval *literal_adr; /* (#) address of literal mvals (offset in original rtnhdr) */ int4 literal_len; /* number of literal mvals */ lnk_tabent *linkage_adr; /* (#) address of linkage Psect (offset in original rtnhdr) */ int4 linkage_len; /* number of linkage entries */ int4 rel_table_off; /* offset to relocation table (not kept) */ int4 sym_table_off; /* offset to symbol table (not kept) */ unsigned char *shared_ptext_adr; /* If set, ptext_adr points to local copy, this points to old shared copy */ unsigned char *ptext_adr; /* (#) address of start of instructions (offset in original rtnhdr) */ unsigned char *ptext_end_adr; /* (#) address of end of instructions + 1 (offset in original rtnhdr) */ int4 checksum; /* verification value */ int4 temp_mvals; /* (#) temp_mvals value of current module version */ int4 temp_size; /* (#) temp_size value of current module version */ struct rhead_struct *current_rhead_adr; /* (#) address of routine header of current module version */ struct rhead_struct *old_rhead_adr; /* (#) chain of replaced routine headers */ # ifdef GTM_TRIGGER void_ptr_t trigr_handle; /* Type is void to avoid needing gv_trigger.h for gv_trigger_t type addr */ # endif } rhdtyp; /* Routine table entry */ typedef struct { mident rt_name; /* The name of the routine (in the literal text pool) */ rhdtyp *rt_adr; /* Pointer to its routine header */ } rtn_tabent; /* byte offset of the routine_name field in the routine headers of pre-V5 releases */ #define PRE_V5_RTNHDR_RTNOFF 24 /* byte offset of the routine_name mstr (len,addr) in V50 and V51 - only used in Tru64/HPUX-HPPA */ #if defined(__osf__) || defined(__hppa) # define V50V51_RTNHDR_RTNMSTR_OFFSET 24 # ifdef __osf__ # define V50V51_FTNHDR_LITBASE_OFFSET 68 # elif defined(__hppa) # define V50V51_FTNHDR_LITBASE_OFFSET 64 # else # error "Unsupported platform" # endif typedef struct { unsigned int len; /* Byte length */ int4 *addr; /* Offset at this stage */ } v50v51_mstr; #endif # /* Macros for accessing routine header fields in a portable way */ #define VARTAB_ADR(rtnhdr) ((rtnhdr)->vartab_adr) #define LABTAB_ADR(rtnhdr) ((rtnhdr)->labtab_adr) #define LNRTAB_ADR(rtnhdr) ((rtnhdr)->lnrtab_adr) #define LITERAL_ADR(rtnhdr) ((rtnhdr)->literal_adr) #define LINKAGE_ADR(rtnhdr) ((rtnhdr)->linkage_adr) #define PTEXT_ADR(rtnhdr) ((rtnhdr)->ptext_adr) #define PTEXT_END_ADR(rtnhdr) ((rtnhdr)->ptext_end_adr) #define CURRENT_RHEAD_ADR(rtnhdr) ((rtnhdr)->current_rhead_adr) #define OLD_RHEAD_ADR(rtnhdr) ((rtnhdr)->old_rhead_adr) #define LINE_NUMBER_ADDR(rtnhdr, lnr_tabent_adr) ((rtnhdr)->ptext_adr + *(lnr_tabent_adr)) #define LABENT_LNR_ENTRY(rtnhdr, lab_tabent_adr) ((lab_tabent_adr)->lnr_adr) #define LABEL_ADDR(rtnhdr, lab_tabent_adr) (CODE_BASE_ADDR(rtnhdr) + *(LABENT_LNR_ENTRY(rtnhdr, lab_tabent_adr))) #define CODE_BASE_ADDR(rtnhdr) ((rtnhdr)->ptext_adr) #define CODE_OFFSET(rtnhdr, addr) ((char *)(addr) - (char *)(rtnhdr->ptext_adr)) /* Macro to determine if given address is inside code segment. Note that even though * the PTEXT_END_ADR macro is the address of end_of_code + 1, we still want a <= check * here because in many cases, the address being tested is the RETURN address from a * call that was done as the last instruction in the code segment. Sometimes this call * is to an error or it could be the implicit quit. On HPUX, the delay slot for the * implicit quit call at the end of the module can also cause the problem. Without * the "=" check also being there, the test will fail when it should succeed. */ #define ADDR_IN_CODE(caddr, rtnhdr) (PTEXT_ADR((rtnhdr)) <= (caddr) && (caddr) <= PTEXT_END_ADR((rtnhdr))) /* Types that are different depending on shared/unshared unix binaries */ #define LABENT_LNR_OFFSET lnr_adr /* Format of a relocation datum. */ struct relocation_info { int r_address; /* address which is relocated */ unsigned int r_symbolnum; /* local symbol ordinal */ }; struct rel_table { struct rel_table *next, *resolve; struct relocation_info r; }; /* Format of a symbol table entry; this file is included by * and should be used if you aren't interested the a.out header * or relocation information. */ struct nlist { int4 n_type; /* type flag, i.e. N_TEXT etc; see below */ uint4 n_value; /* value of this symbol (or sdb offset) */ }; struct sym_table { struct sym_table *next; struct nlist n; struct rel_table *resolve; int4 linkage_offset; unsigned short name_len; unsigned char name[1]; }; /* Simple values for n_type. */ #define N_TEXT 0x04 /* text */ #define N_EXT 0x01 /* external bit, or'ed in */ /* Flag values for get_src_line call */ #define VERIFY TRUE #define NOVERIFY FALSE /* Prototypes */ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_t verifytrig); unsigned char *find_line_start(unsigned char *in_addr, rhdtyp *routine); int4 *find_line_addr(rhdtyp *routine, mstr *label, int4 offset, mident **lent_name); rhdtyp *find_rtn_hdr(mstr *name); bool zlput_rname(rhdtyp *hdr); void zlmov_lnames(rhdtyp *hdr); rhdtyp *make_dmode(void); void comp_lits(rhdtyp *rhead); rhdtyp *op_rhdaddr(mval *name, rhdtyp *rhd); lnr_tabent **op_labaddr(rhdtyp *routine, mval *label, int4 offset); void urx_resolve(rhdtyp *rtn, lab_tabent *lbl_tab, lab_tabent *lbl_top); char *rtnlaboff2entryref(char *entryref_buff, mident *rtn, mident *lab, int offset); #endif /* RTNHDR_H_INCLUDED */