Exemple #1
0
boolean_t job_addr(mstr *rtn, mstr *label, int4 offset, char **hdr, char **labaddr, boolean_t *need_rtnobj_shm_free)
{
	rhdtyp		*rt_hdr;
	int4		*lp;
	mval		rt;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	if (NULL == (rt_hdr = find_rtn_hdr(rtn)))
	{
		rt.mvtype = MV_STR;
		rt.str = *rtn;
		op_zlink(&rt, NULL);
		rt_hdr = find_rtn_hdr(rtn);
		if (NULL == rt_hdr)
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZLINKFILE, 2, rtn->len, rtn->addr,
				      ERR_ZLMODULE, 2, STRLEN(&zlink_mname.c[0]), &zlink_mname);
		*need_rtnobj_shm_free = ARLINK_ONLY(rt_hdr->shared_object) NON_ARLINK_ONLY(FALSE);
		*hdr = (char *)rt_hdr;
	} else
		*need_rtnobj_shm_free = FALSE;
	lp = NULL;
	if ((rt_hdr->compiler_qlf & CQ_LINE_ENTRY) || (0 == offset))
		/* Label offset with routine compiled with NOLINE_ENTRY should cause error. */
		lp = find_line_addr(rt_hdr, label, offset, NULL);
	if (!lp)
		return (FALSE);
	/* Set the pointer to address / offset for line number entry storage in TABENT_PROXY. */
#	ifdef USHBIN_SUPPORTED
	ARLINK_ONLY((TABENT_PROXY).rtnhdr_adr = rt_hdr);
	(TABENT_PROXY).lnr_adr = lp;
#	else
	/* On non-shared-binary, calculcate the offset to the corresponding lnr_tabent record by subtracting
	 * the base address (routine header) from line number entry's address, and save the result in
	 * lab_ln_ptr field of TABENT_PROXY structure.
	 */
	(TABENT_PROXY).lab_ln_ptr = ((int4)lp - (int4)rt_hdr);
#	endif
	if (NULL != labaddr)
		*labaddr = (char *)LINE_NUMBER_ADDR(rt_hdr, lp);
	*hdr = (char *)rt_hdr;
	return (TRUE);
}
Exemple #2
0
/* Routine to parse the value of $ZROUTINES and create the list of structures that define the (new) routine
 * search list order and define which (if any) directories can use auto-relink.
 *
 * Parameter:
 *   str   - string to parse (usually dollar_zroutines)
 *
 * Return code:
 *   none
 */
void zro_load(mstr *str)
{
	unsigned		toktyp, status;
	boolean_t		enable_autorelink;
	mstr			tok, transtr;
	char			*lp, *top;
	zro_ent			array[ZRO_MAX_ENTS], *op;
	int			oi, si, total_ents;
	struct  stat		outbuf;
	int			stat_res;
	char			tranbuf[MAX_FBUFF + 1];
	parse_blk		pblk;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	ARLINK_ONLY(TREF(arlink_enabled) = FALSE);	/* Set if any zro entry is enabled for autorelink */
	memset(array, 0, SIZEOF(array));
	lp = str->addr;
	top = lp + str->len;
	while ((lp < top) && (ZRO_DEL == *lp))	/* Bypass leading blanks */
		lp++;
	array[0].type = ZRO_TYPE_COUNT;
	array[0].count = 0;
	memset(&pblk, 0, SIZEOF(pblk));
	pblk.buffer = tranbuf;
	toktyp = GETTOK;
	if (ZRO_EOL == toktyp)
	{	/* Null string - set default - implies current working directory only */
		array[0].count = 1;
		array[1].type = ZRO_TYPE_OBJECT;
		array[1].str.len = 0;
		array[2].type = ZRO_TYPE_COUNT;
		array[2].count = 1;
		array[3].type = ZRO_TYPE_SOURCE;
		array[3].str.len = 0;
		si = 4;
	} else
	{	/* String supplied - parse it */
		for (oi = 1;;)
		{
			if (ZRO_IDN != toktyp)
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FSEXP);
			if (ZRO_MAX_ENTS <= (oi + 1))
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_MAXARGCNT, 1,
					      ZRO_MAX_ENTS);
			/* We have type ZRO_IDN (an identifier/name of some sort). See if token has a "*" (ZRO_ALF) at the end
			 * of it indicating that it is supposed to (1) be a directory and not a shared library and (2) that the
			 * user desires this directory to have auto-relink capability.
			 */
			enable_autorelink = FALSE;
			/* All platforms allow the auto-relink indicator on object directories but only autorelink able platforms
			 * (#ifdef AUTORELINK_SUPPORTED is set) do anything with it. Other platforms just ignore it. Specifying
			 * "*" at end of non-object directories causes an error further downstream (FILEPARSE) when the "*" is
			 * not stripped off the file name - unless someone has managed to create a directory with a "*" suffix.
			 */
			if (ZRO_ALF == *(tok.addr + tok.len - 1))
			{	/* Auto-relink is indicated */
				enable_autorelink = TRUE;
				TREF(arlink_enabled) = TRUE;
				--tok.len;		/* Remove indicator from name so we can use it */
				assert(0 <= tok.len);
			}
			if (SIZEOF(tranbuf) <= tok.len)
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr,
					      ERR_FILEPARSE, 2, tok.len, tok.addr);
			/* Run specified directory through parse_file to fill in any missing pieces and get some info on it */
			pblk.buff_size = MAX_FBUFF;	/* Don't count null terminator here */
			pblk.fnb = 0;
			status = parse_file(&tok, &pblk);
			if (!(status & 1))
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr,
					      ERR_FILEPARSE, 2, tok.len, tok.addr, status);
			tranbuf[pblk.b_esl] = 0;		/* Needed for some subsequent STAT_FILE */
			STAT_FILE(tranbuf, &outbuf, stat_res);
			if (-1 == stat_res)
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr,
					      ERR_FILEPARSE, 2, tok.len, tok.addr, errno);
			if (S_ISREG(outbuf.st_mode))
			{	/* Regular file - a shared library file */
				if (enable_autorelink)
					/* Auto-relink indicator on shared library not permitted */
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr,
						      ERR_FILEPARSE, 2, tok.len, tok.addr);
				array[oi].shrlib = zro_shlibs_find(tranbuf);
				array[oi].type = ZRO_TYPE_OBJLIB;
				si = oi + 1;
			} else
			{
				if (!S_ISDIR(outbuf.st_mode))
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr,
						      ERR_INVZROENT, 2, tok.len, tok.addr);
				array[oi].type = ZRO_TYPE_OBJECT;
				array[oi + 1].type = ZRO_TYPE_COUNT;
				si = oi + 2;
#				ifdef AUTORELINK_SUPPORTED
#					ifdef DEBUG
					/* If env var gtm_test_autorelink_always is set in dbg version, treat every
					 * object directory specified in $zroutines as if * has been additionally specified.
					 */
					if (TREF(gtm_test_autorelink_always))
					{
						enable_autorelink = TRUE;
						TREF(arlink_enabled) = TRUE;
					}
#					endif
				if (enable_autorelink)
				{	/* Only setup autorelink struct if it is enabled */
					if (!TREF(is_mu_rndwn_rlnkctl))
					{
						transtr.addr = tranbuf;
						transtr.len = pblk.b_esl;
						array[oi].relinkctl_sgmaddr = (void_ptr_t)relinkctl_attach(&transtr, NULL, 0);
					} else
					{	/* If zro_load() is called as a part of MUPIP RUNDOWN -RELINKCTL, then we do not
						 * want to do relinkctl_attach() on all relinkctl files at once because we leave
						 * the function holding the linkctl lock, which might potentially cause a deadlock
						 * if multiple processes are run concurrently with different $gtmroutines. However,
						 * we need a way to tell mu_rndwn_rlnkctl() which object directories are autorelink-
						 * enabled. For that we set a negative number to the presently unused count field of
						 * object directory entries in the zro_ent linked list. If we ever decide to make
						 * that value meaningful, then, perhaps, ensuring that this count remains negative
						 * in case of MUPIP RUNDOWN -RELINKCTL but has the correct absolute value would do
						 * the trick.
						 */
						array[oi].count = ZRO_DIR_ENABLE_AR;
					}
				}
#				endif
			}
			array[0].count++;
			array[oi].str = tok;
			toktyp = GETTOK;
			if (ZRO_LBR == toktyp)
			{
				if (ZRO_TYPE_OBJLIB == array[oi].type)
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr,
						      ERR_NOLBRSRC);
				toktyp = GETTOK;
				if (ZRO_DEL == toktyp)
					toktyp = GETTOK;
				if ((ZRO_IDN != toktyp) && (ZRO_RBR != toktyp))
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr,
						      ERR_QUALEXP);
				array[oi + 1].count = 0;
				for (;;)
				{
					if (ZRO_RBR == toktyp)
						break;
					if (ZRO_IDN != toktyp)
						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr,
							      ERR_FSEXP);
					if (ZRO_MAX_ENTS <= si)
						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_ZROSYNTAX, 2, str->len, str->addr,
							      ERR_MAXARGCNT, 1, ZRO_MAX_ENTS);
					if (SIZEOF(tranbuf) <= tok.len)
						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr,
							      ERR_FILEPARSE, 2, tok.len, tok.addr);
					pblk.buff_size = MAX_FBUFF;
					pblk.fnb = 0;
					status = parse_file(&tok, &pblk);
					if (!(status & 1))
						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr,
							      ERR_FILEPARSE, 2, tok.len, tok.addr, status);
					tranbuf[pblk.b_esl] = 0;
					STAT_FILE(tranbuf, &outbuf, stat_res);
					if (-1 == stat_res)
						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr,
							      ERR_FILEPARSE, 2, tok.len, tok.addr, errno);
					if (!S_ISDIR(outbuf.st_mode))
						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr,
							      ERR_DIRONLY, 2, tok.len, tok.addr);
					array[oi + 1].count++;
					array[si].type = ZRO_TYPE_SOURCE;
					array[si].str = tok;
					si++;
					toktyp = GETTOK;
					if (ZRO_DEL == toktyp)
						toktyp = GETTOK;
				}
				toktyp = GETTOK;
			} else
			{
				if ((ZRO_TYPE_OBJLIB != array[oi].type) && ((ZRO_DEL == toktyp) || (ZRO_EOL == toktyp)))
				{
					if (ZRO_MAX_ENTS <= si)
						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_ZROSYNTAX, 2, str->len, str->addr,
							      ERR_MAXARGCNT, 1, ZRO_MAX_ENTS);
					array[oi + 1].count = 1;
					array[si] = array[oi];
					array[si].type = ZRO_TYPE_SOURCE;
					si++;
				}
			}
			if (ZRO_EOL == toktyp)
				break;
			if (ZRO_DEL == toktyp)
				toktyp = GETTOK;
			else
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZROSYNTAX, 2, str->len, str->addr);
			oi = si;
		}
	}
	total_ents = si;
	if (TREF(zro_root))
	{
		assert((TREF(zro_root))->type == ZRO_TYPE_COUNT);
		oi = (TREF(zro_root))->count;
		assert(oi);
		for (op = TREF(zro_root) + 1; 0 < oi--;)
		{	/* Release space held by translated entries */
			assert((ZRO_TYPE_OBJECT == op->type) || (ZRO_TYPE_OBJLIB == op->type));
			if (op->str.len)
				free(op->str.addr);
			if (ZRO_TYPE_OBJLIB == (op++)->type)
				continue;	/* i.e. no sources for shared library */
			assert(ZRO_TYPE_COUNT == op->type);
			si = (op++)->count;
			for (; si-- > 0; op++)
			{
				assert(ZRO_TYPE_SOURCE == op->type);
				if (op->str.len)
					free(op->str.addr);
			}
		}
		free(TREF(zro_root));
	}
	TREF(zro_root) = (zro_ent *)malloc(total_ents * SIZEOF(zro_ent));
	memcpy((uchar_ptr_t)TREF(zro_root), (uchar_ptr_t)array, total_ents * SIZEOF(zro_ent));
	assert(ZRO_TYPE_COUNT == (TREF(zro_root))->type);
	oi = (TREF(zro_root))->count;
	assert(oi);
	for (op = TREF(zro_root) + 1; 0 < oi--;)
	{
		assert((ZRO_TYPE_OBJECT == op->type) || (ZRO_TYPE_OBJLIB == op->type));
		if (op->str.len)
		{
			pblk.buff_size = MAX_FBUFF;
			pblk.fnb = 0;
			status = parse_file(&op->str, &pblk);
			if (!(status & 1))
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr,
					      ERR_FILEPARSE, 2, op->str.len, op->str.addr, status);
			op->str.addr = (char *)malloc(pblk.b_esl);
			op->str.len = pblk.b_esl;
			memcpy(op->str.addr, pblk.buffer, pblk.b_esl);
		}
		if (ZRO_TYPE_OBJLIB == (op++)->type)
			continue;
		assert(ZRO_TYPE_COUNT == op->type);
		si = (op++)->count;
		for (; 0 < si--; op++)
		{
			assert(ZRO_TYPE_SOURCE == op->type);
			if (op->str.len)
			{
				pblk.buff_size = MAX_FBUFF;
				pblk.fnb = 0;
				status = parse_file(&op->str, &pblk);
				if (!(status & 1))
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr,
						      ERR_FILEPARSE, 2, op->str.len, op->str.addr, status);
				op->str.addr = (char *)malloc(pblk.b_esl);
				op->str.len = pblk.b_esl;
				memcpy(op->str.addr, pblk.buffer, pblk.b_esl);
			}
		}
	}
	(TREF(set_zroutines_cycle))++;		/* Signal need to recompute zroutines histories for each linked routine */
}
Exemple #3
0
void op_zshow(mval *func, int type, lv_val *lvn)
{
	const char	*ptr;
	boolean_t	do_all = FALSE,
			done_a = FALSE,
			done_b = FALSE,
			done_c = FALSE,
			done_d = FALSE,
			done_g = FALSE,
			done_i = FALSE,
			done_l = FALSE,
			done_r = FALSE,
			done_s = FALSE,
			done_v = FALSE;
	int		i;
  	zshow_out	output;

	MAXSTR_BUFF_DECL(buff);

	MV_FORCE_STR(func);
	for (i = 0, ptr = func->str.addr; i < func->str.len; i++, ptr++)
	{
		switch (*ptr)
		{
			case 'A':
			case 'a':
			case 'B':
			case 'b':
			case 'C':
			case 'c':
			case 'D':
			case 'd':
			case 'G':
			case 'g':
			case 'I':
			case 'i':
			case 'L':
			case 'l':
			case 'R':
			case 'r':
			case 'S':
			case 's':
			case 'V':
			case 'v':
				continue;
			case '*':
				do_all = TRUE;
				break;
			default:
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZSHOWBADFUNC);
		}
	}
	if (do_all)
	{
		ptr = ZSHOW_ALL;
		i = STR_LIT_LEN(ZSHOW_ALL);
	} else
	{
		ptr = func->str.addr;
		i = func->str.len;
	}
	memset(&output, 0, SIZEOF(output));
	if (type == ZSHOW_LOCAL)
		output.out_var.lv.lvar = lvn;
	else if (type == ZSHOW_GLOBAL)
	{
		output.out_var.gv.end = gv_currkey->end;
		output.out_var.gv.prev = gv_currkey->prev;
	}
	MAXSTR_BUFF_INIT;
	output.type = type;
	output.buff = &buff[0];
	output.size = SIZEOF(buff);
	output.ptr = output.buff;
	for ( ; i ; i--, ptr++)
	{
		output.line_num = 1;
		switch (*ptr)
		{
			case 'A':
			case 'a':
				if (done_a)
					break;
				done_a = TRUE;
				output.code = 'A';
				ARLINK_ONLY(zshow_rctldump(&output));
				break;
			case 'B':
			case 'b':
				if (done_b)
					break;
				done_b = TRUE;
				output.code = 'B';
				zshow_zbreaks(&output);
				break;
			case 'C':
			case 'c':
				if (done_c)
					break;
				done_c = TRUE;
				output.code = 'C';
				zshow_zcalls(&output);
				break;
			case 'D':
			case 'd':
				if (done_d)
					break;
				done_d = TRUE;
				output.code = 'D';
				zshow_devices(&output);
				break;
			case 'G':
			case 'g':
				if (done_g)
					break;
				done_g = TRUE;
				output.code = 'G';
				output.line_num = 0;	/* G statistics start at 0 for <*,*> output and not 1 like the others */
				zshow_gvstats(&output);
				break;
			case 'I':
			case 'i':
				if (done_i)
					break;
				done_i = TRUE;
				output.code = 'I';
				zshow_svn(&output, SV_ALL);
				break;
			case 'L':
			case 'l':
				if (done_l)
					break;
				done_l = TRUE;
				output.code = 'L';
				output.line_num = 0;	/* L statistics start at 0 for <LUS,LUF> output and not 1 like the others */
				zshow_locks(&output);
				break;
			case 'R':
			case 'r':
				if (done_r)
					break;
				done_r = TRUE;
				output.code = 'R';
				zshow_stack(&output, TRUE);	/* show_checksum = TRUE */
				break;
			case 'S':
			case 's':
				if (done_s)
					break;
				done_s = TRUE;
				output.code = 'S';
				zshow_stack(&output, FALSE);	/* show_checksum = FALSE */
				break;
			case 'V':
			case 'v':
				if (done_v)
					break;
				done_v = TRUE;
				output.code = 'V';
				zshow_zwrite(&output);
				break;
		}
	}
	output.code = 0;
	output.flush = TRUE;
	zshow_output(&output,0);
	MAXSTR_BUFF_FINI;
	/* If ZSHOW was done onto a subscripted lvn but no zshow records got dumped in that lvn, it might have $data = 0.
	 * Kill it in that case as otherwise it will create an out-of-design situation for $query(lvn).
	 */
	if ((type == ZSHOW_LOCAL) && (NULL != active_lv) && lcl_arg1_is_desc_of_arg2(active_lv, lvn))
		UNDO_ACTIVE_LV(actlv_op_zshow);
}