1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
  
     | 
    
      /****************************************************************
 *								*
 * Copyright (c) 2001-2015 Fidelity National Information 	*
 * Services, Inc. and/or its subsidiaries. All rights reserved.	*
 *								*
 *	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
#include "srcline.h"
/* 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;
/* Linkage table entry */
typedef struct
{
	char_ptr_t		ext_ref;	/* Address (quadword on alpha) this linkage entry resolves to or NULL */
} lnk_tabent;
#ifdef AUTORELINK_SUPPORTED
#include "relinkctl.h"		/* Needed for open_relinkctl_sgm type in zro_validation_entry */
/* Link search history entry - contains information to find the record in the relevant relinkctl file and what
 * the cycle was when loaded.
 */
typedef struct
{
	uint4			cycle;			/* Copy of relinkctl file cycle when loaded */
	relinkrec_t		*relinkrec;		/* Pointer to relinkctl record */
	open_relinkctl_sgm	*relinkctl_bkptr;	/* Address of mapped relinkctl file */
} zro_validation_entry;
/* Header for search history block */
typedef struct
{
	uint4			zroutines_cycle;	/* Value of set_zroutines_cycle when history created */
	zro_validation_entry	*end;			/* -> Last record + 1 */
	zro_validation_entry	base[1];		/* First history record (others follow) */
} zro_hist;
/* Structure used to queue up a list of validation entries and routine names before finalizing them into a
 * zro_hist structure.
 */
typedef struct
{
	zro_validation_entry	zro_valent;		/* Validation entry data (this record) */
	mident_fixed		rtnname;		/* Routine name associated with this validation entry */
	int4			rtnname_len;
} zro_search_hist_ent;
#endif
/* 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 */
	boolean_t		shared_object;		/* Linked as a shared object */
	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) */
	boolean_t		rtn_relinked;		/* Routine has been relinked while this version was active. Check on
							 * unwind to see if this routine needs to be cleaned up. */
	unsigned char		*shared_ptext_adr;	/* If shared routine (shared library or object), points to shared copy */
	unsigned char		*ptext_adr;		/* (#) address of start of instructions (offset in original rtnhdr)
							 * If shared routine, points to shared copy unless breakpoints are active.
							 * In that case, points to private copy.
							 */
	unsigned char		*ptext_end_adr;		/* (#) Address of end of instructions + 1 (offset in original rtnhdr) */
	int4			checksum;		/* 4-byte source code checksum (for platforms where MD5 is unavailable) */
	int4			temp_mvals;		/* (#) temp_mvals value of current module version */
	int4			temp_size;		/* (#) temp_size value of current module version */
	boolean_t		has_ZBREAK;		/* This routine has a ZBREAK in it - disable it for autorelink */
	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 */
#	else
	void_ptr_t		filler1;
#	endif
	unsigned char		checksum_128[16];	/* 16-byte MurmurHash3 checksum of routine source code */
	struct rhead_struct	*active_rhead_adr;	/* addr of copy of this (original) header when that new version replaced
							 * this routine and was on M-Stack. See handle_active_versions() rtn. */
	routine_source		*source_code;		/* Source code used by $TEXT */
	ARLINK_ONLY(zro_hist	*zhist;)		/* If shared object -> validation list/array */
	gtm_uint64_t		objhash;		/* When object file is created, contains hash of object file */
	unsigned char		*lbltext_ptr;		/* Label name text blob if shared object replaced */
	uint4			object_len;		/* Length of wrapped GT.M object */
	uint4			routine_source_offset;	/* Offset of M source within literal text pool */
	mstr			*linkage_names;		/* Offset to mstr table of symbol names indexed same as linkage table */
#	ifdef AUTORELINK_SUPPORTED
	open_relinkctl_sgm	*relinkctl_bkptr;	/* Back pointer to relinkctl file that loaded this shared rtnobj */
#	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;
/* Linkage table proxy for run-time linking of indirects. This struct has some overloaded meanings:
 *   1. The group of fields rtnhdr_adr/lnr_adr act as a proxy/surrogate linkage table holding those
 *      two values. They are defined in code with the indexes 0 and 1 respectively.
 *   2. The group of fields lnr_adr/has_parms pretend they are the proxy part of a label table
 *   	entry. Assembler code expects has_parms to be in the location following lnr_adr.
 */
typedef struct
{
	rhdtyp			*rtnhdr_adr;		/* Pointer to routine header for called routine */
	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 */
	int			filler1;		/* 64 bit alignment */
} lnk_tabent_proxy;
#define TABENT_PROXY TREF(lnk_proxy)
/* 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))
#define DYNAMIC_LITERALS_ENABLED(rtnhdr) ((rtnhdr)->compiler_qlf & CQ_DYNAMIC_LITERALS)
#define RW_REL_START_ADR(rtnhdr) (((DYNAMIC_LITERALS_ENABLED(rtnhdr)) ? (char *)VARTAB_ADR(rtnhdr) : (char *)LITERAL_ADR(rtnhdr)))
#define PTEXT_OFFSET SIZEOF(rhdtyp)
/* 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
/* When a routine is recursively linked, the old routine hdr/label table are copied and
 * attached to active_rhead_adr pointer of the replaced routine header. At unwind or goto time,
 * we check if these copies can be cleaned up with the following macro.
 */
#define CLEANUP_COPIED_RECURSIVE_RTN(RTNHDR)											\
{																\
	/* For USHBIN_SUPPORTED routines, if the rtn_relinked flag is ON in the routine header (which results from not cleaning	\
	 * up a routine when it is either explicitly or automatically re-linked), check if the stack contains any more		\
	 * references to this routine header. If not, it is ripe for cleanup as it has been replaced so drive zr_unlink_rtn()	\
	 * on it.														\
	 */															\
	if ((RTNHDR)->rtn_relinked)												\
		zr_cleanup_recursive_rtn(RTNHDR);										\
}
/* 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 <a.out.h>
 * 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		/* cexternal 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, rhdtyp **rtn_vec);
void free_src_tbl(rhdtyp *rtn_vector);
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);
boolean_t find_rtn_tabent(rtn_tabent **res, mstr *name);
bool zlput_rname(rhdtyp *hdr);
void zlmov_lnames(rhdtyp *hdr);
rhdtyp *make_dmode(void);
void comp_lits(rhdtyp *rhead);
int op_rhdaddr(mval *name, int rtnidx);
int op_labaddr(int rtnidx, 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);
boolean_t on_stack(rhdtyp *rtnhdr, boolean_t *need_duplicate);
rhdtyp *op_rhd_ext(mval *rtname, mval *lblname, rhdtyp *rhd, void *lnr);
void *op_lab_ext(void);
void zr_cleanup_recursive_rtn(rhdtyp *rtnhdr);
#ifdef AUTORELINK_SUPPORTED
#include "zroutinessp.h"	/* Needed for zro_ent type for zro_record_zhist declaration */
boolean_t need_relink(rhdtyp *rtnhdr, zro_hist *zhist);
zro_hist *zro_zhist_saverecent(zro_search_hist_ent *zhist_valent, zro_search_hist_ent *zhist_valent_base);
void zro_record_zhist(zro_search_hist_ent *zhist_valent, zro_ent *obj_container, mstr *rtnname);
#endif /* AUTORELINK_DEFINED */
#endif /* RTNHDR_H_INCLUDED */
 
     |