diff options
Diffstat (limited to 'usr/src')
65 files changed, 2892 insertions, 1122 deletions
| diff --git a/usr/src/cmd/sgs/elfedit/common/elfconst.c b/usr/src/cmd/sgs/elfedit/common/elfconst.c index 722a121a7e..084f908a94 100644 --- a/usr/src/cmd/sgs/elfedit/common/elfconst.c +++ b/usr/src/cmd/sgs/elfedit/common/elfconst.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -1197,6 +1197,15 @@ static elfedit_atoui_sym_t sym_shf[] = {  	{ MSG_ORIG(MSG_SHF_TLS),		SHF_TLS },  	{ MSG_ORIG(MSG_SHF_TLS_ALT1),		SHF_TLS }, +	{ MSG_ORIG(MSG_SHF_AMD64_LARGE),	SHF_AMD64_LARGE }, +	{ MSG_ORIG(MSG_SHF_AMD64_LARGE_ALT1),	SHF_AMD64_LARGE }, + +	{ MSG_ORIG(MSG_SHF_ORDERED),		SHF_ORDERED }, +	{ MSG_ORIG(MSG_SHF_ORDERED_ALT1),	SHF_ORDERED }, + +	{ MSG_ORIG(MSG_SHF_EXCLUDE),		SHF_EXCLUDE }, +	{ MSG_ORIG(MSG_SHF_EXCLUDE_ALT1),	SHF_EXCLUDE }, +  	{ NULL }  }; diff --git a/usr/src/cmd/sgs/elfedit/common/elfedit.c b/usr/src/cmd/sgs/elfedit/common/elfedit.c index c3d4c5f379..7a78aaa6b7 100644 --- a/usr/src/cmd/sgs/elfedit/common/elfedit.c +++ b/usr/src/cmd/sgs/elfedit/common/elfedit.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -596,6 +596,104 @@ elfedit_write(const void *ptr, size_t size)  /* + * Convert the NULL terminated string to the form used by the C + * language to represent literal strings: + *	- Printable characters are shown as themselves + *	- Convert special characters to their 2-character escaped forms: + *		alert (bell)	\a + *		backspace	\b + *		formfeed	\f + *		newline		\n + *		return		\r + *		horizontal tab	\t + *		vertical tab	\v + *		backspace	\\ + *		single quote	\' + *		double quote	\" + *	- Display other non-printable characters as 4-character escaped + *		octal constants. + * + * entry: + *	str - String to be processed + *	outfunc - Function to be called to move output characters. Note + *		that this function has the same signature as elfedit_write(), + *		and that function can be used to write the characters to + *		the output. + * + * exit: + *	The string has been processed, with the resulting data passed + *	to outfunc for processing. + */ +void +elfedit_str_to_c_literal(const char *str, elfedit_write_func_t *outfunc) +{ +	char		bs_buf[2];	/* For two-character backslash codes */ +	char		octal_buf[10];	/* For \000 style octal constants */ + +	bs_buf[0] = '\\'; +	while (*str != '\0') { +		switch (*str) { +		case '\a': +			bs_buf[1] = 'a'; +			break; +		case '\b': +			bs_buf[1] = 'b'; +			break; +		case '\f': +			bs_buf[1] = 'f'; +			break; +		case '\n': +			bs_buf[1] = 'n'; +			break; +		case '\r': +			bs_buf[1] = 'r'; +			break; +		case '\t': +			bs_buf[1] = 't'; +			break; +		case '\v': +			bs_buf[1] = 'v'; +			break; +		case '\\': +			bs_buf[1] = '\\'; +			break; +		case '\'': +			bs_buf[1] = '\''; +			break; +		case '"': +			bs_buf[1] = '"'; +			break; +		default: +			bs_buf[1] = '\0'; +		} + +		if (bs_buf[1] != '\0') { +			(*outfunc)(bs_buf, 2); +			str++; +		} else if (isprint(*str)) { +			/* +			 * Output the entire sequence of printable +			 * characters in a single shot. +			 */ +			const char	*tail; +			size_t		outlen = 0; + +			for (tail = str; isprint(*tail); tail++) +				outlen++; +			(*outfunc)(str, outlen); +			str = tail; +		} else { +			/* Generic unprintable character: Use octal notation */ +			(void) snprintf(octal_buf, sizeof (octal_buf), +			    MSG_ORIG(MSG_FMT_OCTCONST), *str); +			(*outfunc)(octal_buf, strlen(octal_buf)); +			str++; +		} +	} +} + + +/*   * Wrappers on malloc() and realloc() that check the result for success   * and issue an error if not. The caller can use the result of these   * functions without checking for a NULL pointer, as we do not return to @@ -1259,7 +1357,7 @@ init_obj_state(const char *file)  } -#if 0 +#ifdef DEBUG_MODULE_LIST  /*   * Debug routine. Dump the module list to stdout.   */ @@ -2181,6 +2279,90 @@ dispatch_user_cmds()  /* + * Given the pointer to the character following a '\' character in + * a C style literal, return the ASCII character code it represents, + * and advance the string pointer to the character following the last + * character in the escape sequence. + * + * entry: + *	str - Address of string pointer to first character following + *		the backslash. + * + * exit: + *	If the character is not valid, an error is thrown and this routine + *	does not return to its caller. Otherwise, it returns the ASCII + *	code for the translated character, and *str has been advanced. + */ +static int +translate_c_esc(char **str) +{ +	char *s = *str; +	int	ch; +	int	i; + +	ch = *s++; +	switch (ch) { +	case 'a': +		ch = '\a'; +		break; +	case 'b': +		ch = '\b'; +		break; +	case 'f': +		ch = '\f'; +		break; +	case 'n': +		ch = '\n'; +		break; +	case 'r': +		ch = '\r'; +		break; +	case 't': +		ch = '\t'; +		break; +	case 'v': +		ch = '\v'; +		break; + +	case '0': +	case '1': +	case '2': +	case '3': +	case '4': +	case '5': +	case '6': +	case '7': +		/* Octal constant: There can be up to 3 digits */ +		ch -= '0'; +		for (i = 0; i < 2; i++) { +			if ((*s < '0') || (*s > '7')) +				break; +			ch = (ch << 3) + (*s++ - '0'); +		} +		break; + +	/* +	 * There are some cases where ch already has the desired value. +	 * These cases exist simply to remove the special meaning that +	 * character would otherwise have. We need to match them to +	 * prevent them from falling into the default error case. +	 */ +	case '\\': +	case '\'': +	case '"': +		break; + +	default: +		elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADCESC), ch); +		break; +	} + +	*str = s; +	return (ch); +} + + +/*   * Prepare a GETTOK_STATE struct for gettok().   *   * entry: @@ -2275,16 +2457,50 @@ gettok(GETTOK_STATE *gettok_state)  				break;  		} +		/* +		 * The semantics of the backslash character depends on +		 * the quote style in use: +		 *	- Within single quotes, backslash is not +		 *		an escape character, and is taken literally. +		 *	- If outside of quotes, the backslash is an escape +		 *		character. The backslash is ignored and the +		 *		following character is taken literally, losing +		 *		any special properties it normally has. +		 *	- Within double quotes, backslash works like a +		 *		backslash escape within a C literal. Certain +		 *		escapes are recognized and replaced with their +		 *		special character. Any others are an error. +		 */  		if (*look == '\\') { +			if (quote_ch == '\'') { +				*str++ = *look; +				continue; +			} +  			look++; -			if (*look == '\0')	/* Esc applied to NULL term? */ -				break; +			if (*look == '\0') {	/* Esc applied to NULL term? */ +				elfedit_msg(ELFEDIT_MSG_ERR, +				    MSG_INTL(MSG_ERR_ESCEOL)); +				/*NOTREACHED*/ +			} + +			if (quote_ch == '"') { +				*str++ = translate_c_esc(&look); +				look--;		/* for() will advance by 1 */ +				continue; +			}  		}  		if (look != str)  			*str = *look;  		str++;  	} + +	/* Don't allow unterminated quoted tokens */ +	if (quote_ch != '\0') +		elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_UNTERMQUOTE), +		    quote_ch); +  	gettok_state->gtok_last_token.tok_len = str -  	    gettok_state->gtok_last_token.tok_str;  	gettok_state->gtok_null_seen = *look == '\0'; @@ -2293,9 +2509,11 @@ gettok(GETTOK_STATE *gettok_state)  	*str = '\0';  	gettok_state->gtok_cur_buf = look; -#if 0 -	printf("GETTOK >%s< len(%d) offset(%d)\n", -	    gettok_state->gtok_last_token.tok_str, +#ifdef DEBUG_GETTOK +	printf("GETTOK >"); +	elfedit_str_to_c_literal(gettok_state->gtok_last_token.tok_str, +	    elfedit_write); +	printf("< \tlen(%d) offset(%d)\n",  	    gettok_state->gtok_last_token.tok_len,  	    gettok_state->gtok_last_token.tok_line_off);  #endif @@ -3044,7 +3262,7 @@ cmd_match_fcn(WordCompletion *cpl, void *data, const char *line, int word_end)  	 * It will put the tty back into normal mode, and it will cause  	 * tecla to redraw the current input line when it gets control back.  	 */ -#if 0 +#ifdef DEBUG_CMD_MATCH  	gl_normal_io(state.input.gl);  #endif @@ -3175,8 +3393,8 @@ cmd_match_fcn(WordCompletion *cpl, void *data, const char *line, int word_end)  		}  	} -#if 0 -	printf("NDX(%d) NUM_OPT(%d) ostyle_ndx(%d)\n", ndx, num_opt, +#ifdef DEBUG_CMD_MATCH +	(void) printf("NDX(%d) NUM_OPT(%d) ostyle_ndx(%d)\n", ndx, num_opt,  	    ostyle_ndx);  #endif diff --git a/usr/src/cmd/sgs/elfedit/common/elfedit.msg b/usr/src/cmd/sgs/elfedit/common/elfedit.msg index 9b9a94ec97..076b768c14 100644 --- a/usr/src/cmd/sgs/elfedit/common/elfedit.msg +++ b/usr/src/cmd/sgs/elfedit/common/elfedit.msg @@ -20,7 +20,7 @@  #  # -# Copyright 2007 Sun Microsystems, Inc.  All rights reserved. +# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.  # Use is subject to license terms.  #  # ident	"%Z%%M%	%I%	%E% SMI" @@ -89,6 +89,7 @@  @ MSG_DEBUG_READONLY	"session is readonly\n";  @ MSG_DEBUG_NOFILE	"no ELF object specified. Limited functionalty is available\n";  @ MSG_DEBUG_DIRTYEXIT	"discarding unsaved edits\n"; +@ MSG_DEBUG_FNDSEC	"[%d: %s]: section\n"  @ MSG_DEBUG_FNDCAP	"[%d: %s]: capabilities section\n"  @ MSG_DEBUG_FNDDYN	"[%d: %s]: dynamic section\n"  @ MSG_DEBUG_FNDSTR	"[%d: %s][%d]: string: %s\n" @@ -133,6 +134,9 @@  @ MSG_ERR_PATHTOOLONG	"path too long: %s/%s.so\n"  @ MSG_ERR_CNTDLOPEN	"unable to load module sharable object %s: %s\n"  @ MSG_ERR_CNTDLCLOSE	"unable to unload module sharable object %s: %s\n" +@ MSG_ERR_ESCEOL	"backslash escape cannot be used at end of line\n" +@ MSG_ERR_BADCESC	"unrecognized escape in double quoted token: \\%c\n" +@ MSG_ERR_UNTERMQUOTE	"command is missing closing quote: %c\n"  @ MSG_ERR_UNRECMOD	"no such module: %s\n"  @ MSG_ERR_UNRECCMD	"no such command: %s:%s\n"  @ MSG_ERR_SONOTMOD	"sharable object is not a valid elfedit module: %s\n" @@ -192,7 +196,7 @@  @ MSG_ERR_NOSYMINFO	"ELF object does not have a syminfo section\n"  @ MSG_ERR_NOTSYMTAB	"[%d: %s]: section is not a symbol table\n"  @ MSG_ERR_STRSHNDX	"string section index %d is outside expected \ -			 range %d - %d\n" +			 range 1 - %d\n"  @ MSG_ERR_NOTSTRSH	"[%d: %s]: Section is not a string table as expected\n"  @ MSG_ERR_NOSTRPAD	"[%d: %s]: String table does not have room to add \  			 string\n" @@ -1281,6 +1285,12 @@  @ MSG_SHF_GROUP_ALT1		"group"  @ MSG_SHF_TLS			"SHF_TLS"		# 0x400  @ MSG_SHF_TLS_ALT1		"tls" +@ MSG_SHF_AMD64_LARGE		"SHF_AMD64_LARGE"	# 0x10000000 +@ MSG_SHF_AMD64_LARGE_ALT1	"amd64_large" +@ MSG_SHF_ORDERED		"SHF_ORDERED"		# 0x40000000 +@ MSG_SHF_ORDERED_ALT1		"ordered" +@ MSG_SHF_EXCLUDE		"SHF_EXCLUDE"		# 0x80000000 +@ MSG_SHF_EXCLUDE_ALT1		"exclude"  # Names of st_info ELF_ST_BIND symbol binding constants @@ -1379,6 +1389,7 @@  @ MSG_FMT_WORDVAL	"%u"  @ MSG_FMT_WRAPUSAGE	"\n%s"  @ MSG_FMT_SECMSGPRE	"[%d: %s]" +@ MSG_FMT_OCTCONST	"\\%03o"  # Miscellaneous clutter diff --git a/usr/src/cmd/sgs/elfedit/common/lintsup.c b/usr/src/cmd/sgs/elfedit/common/lintsup.c index 410f5525a1..09568cefbb 100644 --- a/usr/src/cmd/sgs/elfedit/common/lintsup.c +++ b/usr/src/cmd/sgs/elfedit/common/lintsup.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  /* LINTLIBRARY */ @@ -107,6 +107,7 @@ foo()  	(void) elfedit_name_to_shndx(NULL, NULL);  	(void) elfedit_name_to_symndx(NULL, NULL, NULL, ELFEDIT_MSG_ERR, NULL);  	(void) elfedit_outstyle(); +	(void) elfedit_sec_get(NULL, NULL);  	(void) elfedit_sec_getcap(NULL, NULL, NULL);  	(void) elfedit_sec_getdyn(NULL, NULL, NULL);  	(void) elfedit_sec_getstr(NULL, 0); @@ -116,6 +117,7 @@ foo()  	(void) elfedit_sec_getxshndx(NULL, NULL, NULL, NULL);  	(void) elfedit_sec_msgprefix(NULL);  	(void) elfedit_shndx_to_name(NULL, NULL); +	elfedit_str_to_c_literal(NULL, NULL);  	(void) elfedit_strtab_insert(NULL, NULL, NULL, NULL);  	(void) elfedit_strtab_insert_test(NULL, NULL, NULL, NULL);  	(void) elfedit_type_to_shndx(NULL, 0); diff --git a/usr/src/cmd/sgs/elfedit/common/mapfile-vers b/usr/src/cmd/sgs/elfedit/common/mapfile-vers index 5f0efd4e9e..57bd492730 100644 --- a/usr/src/cmd/sgs/elfedit/common/mapfile-vers +++ b/usr/src/cmd/sgs/elfedit/common/mapfile-vers @@ -20,7 +20,7 @@  #  # -# Copyright 2007 Sun Microsystems, Inc.  All rights reserved. +# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.  # Use is subject to license terms.  #  #ident	"%Z%%M%	%I%	%E% SMI" @@ -50,6 +50,8 @@  		elfedit_pager_init;  		elfedit_printf;  		elfedit_realloc; +		elfedit_str_to_c_literal; +		elfedit_write; @@ -141,6 +143,9 @@  		elfedit32_sec_findstr;  		elfedit64_sec_findstr; +		elfedit32_sec_get; +		elfedit64_sec_get; +  		elfedit32_sec_getcap;  		elfedit64_sec_getcap; diff --git a/usr/src/cmd/sgs/elfedit/common/util_machelf.c b/usr/src/cmd/sgs/elfedit/common/util_machelf.c index f3538ba2fa..3a9074e13f 100644 --- a/usr/src/cmd/sgs/elfedit/common/util_machelf.c +++ b/usr/src/cmd/sgs/elfedit/common/util_machelf.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -314,6 +314,29 @@ elfedit_shndx_to_name(elfedit_obj_state_t *obj_state, Word shndx)  /* + * Locate the arbitrary section specified by shndx for this object. + * + * exit: + *	Returns section descriptor on success. On failure, does not return. + */ +elfedit_section_t * +elfedit_sec_get(elfedit_obj_state_t *obj_state, Word shndx) +{ +	elfedit_section_t *sec; + +	if ((shndx == 0) || (shndx >= obj_state->os_shnum)) +		elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADSECNDX), +		    EC_WORD(shndx), EC_WORD(obj_state->os_shnum - 1)); + +	sec = &obj_state->os_secarr[shndx]; + +	elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_FNDSEC), +	    EC_WORD(shndx), sec->sec_name); +	return (sec); +} + + +/*   * Locate the capabilities section for this object   *   * entry: @@ -706,8 +729,7 @@ elfedit_sec_getstr(elfedit_obj_state_t *obj_state, Word shndx)  	if ((shndx == 0) || (shndx >= obj_state->os_shnum))  		elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_STRSHNDX), -		    EC_WORD(shndx), EC_WORD(1), -		    EC_WORD(obj_state->os_shnum - 1)); +		    EC_WORD(shndx), EC_WORD(obj_state->os_shnum - 1));  	strsec = &obj_state->os_secarr[shndx];  	if (strsec->sec_shdr->sh_type != SHT_STRTAB) diff --git a/usr/src/cmd/sgs/elfedit/modules/common/mapfile-vers b/usr/src/cmd/sgs/elfedit/modules/common/mapfile-vers index 373b5af383..615db35145 100644 --- a/usr/src/cmd/sgs/elfedit/modules/common/mapfile-vers +++ b/usr/src/cmd/sgs/elfedit/modules/common/mapfile-vers @@ -20,7 +20,7 @@  #  # -# Copyright 2007 Sun Microsystems, Inc.  All rights reserved. +# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.  # Use is subject to license terms.  #  # ident	"%Z%%M%	%I%	%E% SMI" @@ -56,6 +56,8 @@ SUNWprivate_1.1 {  		elfedit_pager_init =		PARENT;  		elfedit_printf =		PARENT;  		elfedit_realloc =		PARENT; +		elfedit_str_to_c_literal =	PARENT; +		elfedit_write =			PARENT; @@ -147,6 +149,9 @@ SUNWprivate_1.1 {  		elfedit32_sec_findstr =		PARENT;  		elfedit64_sec_findstr =		PARENT; +		elfedit32_sec_get =		PARENT; +		elfedit64_sec_get =		PARENT; +  		elfedit32_sec_getcap =		PARENT;  		elfedit64_sec_getcap =		PARENT; diff --git a/usr/src/cmd/sgs/elfedit/modules/common/shdr.c b/usr/src/cmd/sgs/elfedit/modules/common/shdr.c index 50a0cd9ac1..2ca78a5c16 100644 --- a/usr/src/cmd/sgs/elfedit/modules/common/shdr.c +++ b/usr/src/cmd/sgs/elfedit/modules/common/shdr.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -107,7 +107,11 @@ typedef enum {  					/*	 ofset rather than string */  	SHDR_OPT_F_OR =		8,	/* -or: OR (|) values to dest */  	SHDR_OPT_F_SHNDX =	16,	/* -shndx: Section by index, not name */ -	SHDR_OPT_F_SHTYP =	32	/* -shtyp: Section by type, not name */ +	SHDR_OPT_F_SHTYP =	32,	/* -shtyp: Section by type, not name */ +	SHDR_OPT_F_VALUE_SHNAM = 64,	/* -value_shnam: Value of sh_info or */ +					/*	sh_link given as section name */ +	SHDR_OPT_F_VALUE_SHTYP = 128	/* -value_shtyp: Value of sh_info or */ +					/*	sh_link given as section type */  } shdr_opt_t; @@ -546,7 +550,17 @@ cmd_body(SHDR_CMD_T cmd, elfedit_obj_state_t *obj_state,  	case SHDR_CMD_T_SH_INFO:  		{ -			Word sh_info = elfedit_atoui(argstate.argv[1], NULL); +			Word sh_info; + +			if (argstate.optmask & SHDR_OPT_F_VALUE_SHNAM) +				sh_info = elfedit_name_to_shndx(obj_state, +				    argstate.argv[1]); +			else if (argstate.optmask & SHDR_OPT_F_VALUE_SHTYP) +				sh_info = elfedit_type_to_shndx(obj_state, +				    elfedit_atoconst(argstate.argv[1], +				    ELFEDIT_CONST_SHT)); +			else +				sh_info = elfedit_atoui(argstate.argv[1], NULL);  			if (shdr->sh_info == sh_info) {  				elfedit_msg(ELFEDIT_MSG_DEBUG, @@ -568,7 +582,17 @@ cmd_body(SHDR_CMD_T cmd, elfedit_obj_state_t *obj_state,  	case SHDR_CMD_T_SH_LINK:  		{ -			Word sh_link = elfedit_atoui(argstate.argv[1], NULL); +			Word sh_link; + +			if (argstate.optmask & SHDR_OPT_F_VALUE_SHNAM) +				sh_link = elfedit_name_to_shndx(obj_state, +				    argstate.argv[1]); +			else if (argstate.optmask & SHDR_OPT_F_VALUE_SHTYP) +				sh_link = elfedit_type_to_shndx(obj_state, +				    elfedit_atoconst(argstate.argv[1], +				    ELFEDIT_CONST_SHT)); +			else +				sh_link = elfedit_atoui(argstate.argv[1], NULL);  			if (shdr->sh_link == sh_link) {  				elfedit_msg(ELFEDIT_MSG_DEBUG, @@ -786,6 +810,49 @@ cpl_sh_flags(elfedit_obj_state_t *obj_state, void *cpldata, int argc,  		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHF);  } +/* + * For shdr:sh_info and shdr:sh_link: The value argument can be an + * integer, section name, or section type. + */ +/*ARGSUSED*/ +static void +cpl_sh_infolink(elfedit_obj_state_t *obj_state, void *cpldata, int argc, +    const char *argv[], int num_opt) +{ +	elfedit_section_t *sec; +	enum { NAME, INTVAL, TYPE } op; +	Word ndx; + +	/* Handle -shXXX options */ +	cpl_1starg_sec(obj_state, cpldata, argc, argv, num_opt); + +	if (argc != (num_opt + 2)) +		return; + +	op = INTVAL; +	for (ndx = 0; ndx < num_opt; ndx++) { +		if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_VALUE_SHNAM)) == 0) +			op = NAME; +		else if (strcmp(argv[ndx], +		    MSG_ORIG(MSG_STR_MINUS_VALUE_SHTYP)) == 0) +			op = TYPE; +	} + +	switch (op) { +	case NAME: +		if (obj_state == NULL) +			break; +		sec = obj_state->os_secarr; +		for (ndx = 0; ndx < obj_state->os_shnum; ndx++, sec++) +			elfedit_cpl_match(cpldata, sec->sec_name, 0); +		break; + +	case TYPE: +		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT); +		break; +	} +} +  /*ARGSUSED*/  static void  cpl_sh_type(elfedit_obj_state_t *obj_state, void *cpldata, int argc, @@ -894,6 +961,32 @@ elfedit_init(elfedit_module_version_t version)  		{ NULL }  	}; +	/* +	 * sh_info and sh_link accept the standard options above, +	 * plus -value_shnam and -value_shtyp. +	 */ +	static elfedit_cmd_optarg_t opt_infolink[] = { +		{ ELFEDIT_STDOA_OPT_O, NULL, +		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, +		{ MSG_ORIG(MSG_STR_MINUS_SHNDX), +		    /* MSG_INTL(MSG_OPTDESC_SHNDX) */ +		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0, +		    SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP }, +		{ MSG_ORIG(MSG_STR_MINUS_SHTYP), +		    /* MSG_INTL(MSG_OPTDESC_SHTYP) */ +		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0, +		    SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX }, +		{ MSG_ORIG(MSG_STR_MINUS_VALUE_SHNAM), +		    /* MSG_INTL(MSG_OPTDESC_VALUE_SHNAM) */ +		    ELFEDIT_I18NHDL(MSG_OPTDESC_VALUE_SHNAM), 0, +		    SHDR_OPT_F_VALUE_SHNAM, SHDR_OPT_F_VALUE_SHNAM }, +		{ MSG_ORIG(MSG_STR_MINUS_VALUE_SHTYP), +		    /* MSG_INTL(MSG_OPTDESC_VALUE_SHTYP) */ +		    ELFEDIT_I18NHDL(MSG_OPTDESC_VALUE_SHTYP), 0, +		    SHDR_OPT_F_VALUE_SHTYP, SHDR_OPT_F_VALUE_SHTYP }, +		{ NULL } +	}; +  	/* shdr:sh_addr */  	static const char *name_sh_addr[] = {  	    MSG_ORIG(MSG_CMD_SH_ADDR), NULL }; @@ -1147,20 +1240,20 @@ elfedit_init(elfedit_module_version_t version)  		    opt_sh_flags, arg_sh_flags },  		/* shdr:sh_info */ -		{ cmd_sh_info, cpl_1starg_sec, name_sh_info, +		{ cmd_sh_info, cpl_sh_infolink, name_sh_info,  		    /* MSG_INTL(MSG_DESC_SH_INFO) */  		    ELFEDIT_I18NHDL(MSG_DESC_SH_INFO),  		    /* MSG_INTL(MSG_HELP_SH_INFO) */  		    ELFEDIT_I18NHDL(MSG_HELP_SH_INFO), -		    opt_std, arg_sh_info }, +		    opt_infolink, arg_sh_info },  		/* shdr:sh_link */ -		{ cmd_sh_link, cpl_1starg_sec, name_sh_link, +		{ cmd_sh_link, cpl_sh_infolink, name_sh_link,  		    /* MSG_INTL(MSG_DESC_SH_LINK) */  		    ELFEDIT_I18NHDL(MSG_DESC_SH_LINK),  		    /* MSG_INTL(MSG_HELP_SH_LINK) */  		    ELFEDIT_I18NHDL(MSG_HELP_SH_LINK), -		    opt_std, arg_sh_link }, +		    opt_infolink, arg_sh_link },  		/* shdr:sh_name */  		{ cmd_sh_name, cpl_1starg_sec, name_sh_name, diff --git a/usr/src/cmd/sgs/elfedit/modules/common/shdr.msg b/usr/src/cmd/sgs/elfedit/modules/common/shdr.msg index 31703e14cb..bb126208b3 100644 --- a/usr/src/cmd/sgs/elfedit/modules/common/shdr.msg +++ b/usr/src/cmd/sgs/elfedit/modules/common/shdr.msg @@ -20,7 +20,7 @@  #  # -# Copyright 2007 Sun Microsystems, Inc.  All rights reserved. +# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.  # Use is subject to license terms.  #  # ident	"%Z%%M%	%I%	%E% SMI" @@ -88,6 +88,17 @@     Interpret the name argument as a string table offset rather\n\     than as a string.\n" +@ MSG_OPTDESC_VALUE_SHNAM	"\ +   Interpret the value argument as a section name rather than\n\ +   as an integer. The index of the first section with the\n\ +   specified name will be used as the value.\n" + +@ MSG_OPTDESC_VALUE_SHTYP	"\ +   Interpret the value argument as a section type rather than\n\ +   as an integer. The index of the first section of the specified\n\ +   type will be used as the value. value can be one of the well\n\ +   known SHT_ symbolic constants, or any integer.\n" +  # Command argument descriptions @@ -347,6 +358,8 @@  @ MSG_STR_MINUS_SHNDX		"-shndx"  @ MSG_STR_MINUS_SHTYP		"-shtyp"  @ MSG_STR_MINUS_NAME_OFFSET	"-name_offset" +@ MSG_STR_MINUS_VALUE_SHNAM	"-value_shnam" +@ MSG_STR_MINUS_VALUE_SHTYP	"-value_shtyp"  @ MSG_STR_NAME			"name"  @ MSG_STR_SEC			"sec"  @ MSG_STR_VALUE			"value" diff --git a/usr/src/cmd/sgs/elfedit/modules/common/str.c b/usr/src/cmd/sgs/elfedit/modules/common/str.c index ddc26fd760..d3cf9db170 100644 --- a/usr/src/cmd/sgs/elfedit/modules/common/str.c +++ b/usr/src/cmd/sgs/elfedit/modules/common/str.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -96,12 +96,13 @@ mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)   * argument allowed by a command in this module.   */  typedef enum { -	STR_OPT_F_END =		1,	/* -end: zero to end of strtab */ -	STR_OPT_F_NOTERM =	2,	/* -noterm: str:set won't term string */ -	STR_OPT_F_SHNAME =	4,	/* -shnam name: section spec. by name */ -	STR_OPT_F_SHNDX =	8,	/* -shndx ndx: strtab spec. by index */ -	STR_OPT_F_SHTYP =	16,	/* -shtyp type: section spec. by type */ -	STR_OPT_F_STRNDX =	32,	/* -strndx: String specified by index */ +	STR_OPT_F_ANY =		1,	/* -any: treat any sec. as strtab */ +	STR_OPT_F_END =		2,	/* -end: zero to end of strtab */ +	STR_OPT_F_NOTERM =	4,	/* -noterm: str:set won't term string */ +	STR_OPT_F_SHNAME =	8,	/* -shnam name: section spec. by name */ +	STR_OPT_F_SHNDX =	16,	/* -shndx ndx: strtab spec. by index */ +	STR_OPT_F_SHTYP =	32,	/* -shtyp type: section spec. by type */ +	STR_OPT_F_STRNDX =	64,	/* -strndx: String specified by index */  } str_opt_t; @@ -131,7 +132,7 @@ typedef struct {  /* - * Given an ELF SHT_ section type constant, shdr_to_strtab() returns + * Given an ELF SHT_ section type constant, shndx_to_strtab() returns   * one of the following   */ @@ -313,19 +314,25 @@ process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[],  	argstate->argc = argc;  	argstate->argv = argv; -	/* -	 * Locate and validate the string table. In the case where -	 * a non-string table section is given that references a string -	 * table, we will use the referenced table. -	 */ -	ndx = shndx_to_strtab(obj_state, ndx); +	if (argstate->optmask & STR_OPT_F_ANY) { +		/* Take the arbitrary section */ +		argstate->str.sec = elfedit_sec_get(obj_state, ndx); -	/* -	 * If ndx is a string table, the following will issue the -	 * proper debug messages. If it is out of range, or of any -	 * other type, an error is issued and it doesn't return. -	 */ -	argstate->str.sec = elfedit_sec_getstr(obj_state, ndx); +	} else { +		/* +		 * Locate and validate the string table. In the case where +		 * a non-string table section is given that references a string +		 * table, we will use the referenced table. +		 */ +		ndx = shndx_to_strtab(obj_state, ndx); + +		/* +		 * If ndx is a string table, the following will issue the +		 * proper debug messages. If it is out of range, or of any +		 * other type, an error is issued and it doesn't return. +		 */ +		argstate->str.sec = elfedit_sec_getstr(obj_state, ndx); +	}  	/*  	 * If there is a dynamic section, check its sh_link to the @@ -479,7 +486,12 @@ print_strtab(int autoprint, ARGSTATE *argstate)  			(void) snprintf(index, sizeof (index),  			    MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(ndx));  		} -		elfedit_printf(MSG_ORIG(MSG_FMT_DUMPENTRY), index, str); +		elfedit_printf(MSG_ORIG(MSG_FMT_DUMPENTRY), index); +		elfedit_write(MSG_ORIG(MSG_STR_DQUOTE), MSG_STR_DQUOTE_SIZE); +		if (start_ndx == ndx) +			elfedit_str_to_c_literal(str, elfedit_write); +		elfedit_write(MSG_ORIG(MSG_STR_DQUOTENL), +		    MSG_STR_DQUOTENL_SIZE);  		str += skip;  		ndx += skip;  	} @@ -925,6 +937,10 @@ elfedit_init(elfedit_module_version_t version)  	    NULL  	};  	static elfedit_cmd_optarg_t opt_dump[] = { +		{ MSG_ORIG(MSG_STR_MINUS_ANY), +		    /* MSG_INTL(MSG_OPTDESC_ANY) */ +		    ELFEDIT_I18NHDL(MSG_OPTDESC_ANY), 0, +		    STR_OPT_F_ANY, 0 },  		{ ELFEDIT_STDOA_OPT_O, NULL,  		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },  		{ MSG_ORIG(MSG_STR_MINUS_SHNAM), @@ -960,6 +976,10 @@ elfedit_init(elfedit_module_version_t version)  	static const char *name_set[] = {  	    MSG_ORIG(MSG_CMD_SET), NULL };  	static elfedit_cmd_optarg_t opt_set[] = { +		{ MSG_ORIG(MSG_STR_MINUS_ANY), +		    /* MSG_INTL(MSG_OPTDESC_ANY) */ +		    ELFEDIT_I18NHDL(MSG_OPTDESC_ANY), 0, +		    STR_OPT_F_ANY, 0 },  		{ ELFEDIT_STDOA_OPT_O, NULL,  		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },  		{ MSG_ORIG(MSG_STR_MINUS_NOTERM), @@ -1034,6 +1054,10 @@ elfedit_init(elfedit_module_version_t version)  	static const char *name_zero[] = {  	    MSG_ORIG(MSG_CMD_ZERO), NULL };  	static elfedit_cmd_optarg_t opt_zero[] = { +		{ MSG_ORIG(MSG_STR_MINUS_ANY), +		    /* MSG_INTL(MSG_OPTDESC_ANY) */ +		    ELFEDIT_I18NHDL(MSG_OPTDESC_ANY), 0, +		    STR_OPT_F_ANY, 0 },  		{ ELFEDIT_STDOA_OPT_O, NULL,  		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },  		{ MSG_ORIG(MSG_STR_MINUS_SHNAM), diff --git a/usr/src/cmd/sgs/elfedit/modules/common/str.msg b/usr/src/cmd/sgs/elfedit/modules/common/str.msg index 05a3aa70d1..5d6af5f8d0 100644 --- a/usr/src/cmd/sgs/elfedit/modules/common/str.msg +++ b/usr/src/cmd/sgs/elfedit/modules/common/str.msg @@ -20,7 +20,7 @@  #  # -# Copyright 2007 Sun Microsystems, Inc.  All rights reserved. +# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.  # Use is subject to license terms.  #  # ident	"%Z%%M%	%I%	%E% SMI" @@ -81,6 +81,13 @@  # Command option description strings +@ MSG_OPTDESC_ANY		"\ +   Normally, only string table sections (section type SHT_STRTAB)\n\ +   are allowed. If -any is set, then the specified section is\n\ +   used without checking its section type, and will be treated as\n\ +   if it is a string table. This can be used to examine sections\n\ +   that are known to be in string table format (i.e. SHT_PROGBITS).\n" +  @ MSG_OPTDESC_END		"\     Zero to the end of the string table. The count argument\n\     cannot be used in conjunction with -end.\n". @@ -146,7 +153,26 @@     \n\     If str:dump is called without arguments, every string in the\n\     string table is shown. If called with the string argument,\n\ -   the information for that string is displayed.\n" +   the information for that string is displayed.\n\ +   \n\ +   The strings are displayed within double quotes. These quotes are\n\ +   not part of the actual string, and serve to visually delimit the\n\ +   actual string. Printable characters are shown as themselves, while\n\ +   non-printable characters are shown using the same notation used\n\ +   by the C programming language for literal string constants:\n\ +   \n\ +   \t\\a\talert (bell)\n\ +   \t\\b\tbackspace\n\ +   \t\\f\tform feed\n\ +   \t\\n\tnewline\n\ +   \t\\r\treturn\n\ +   \t\\t\thorizontal tab\n\ +   \t\\v\tvertical tab\n\ +   \t\\\\\tbackslash\n\ +   \t\\'\tsingle quote\n\ +   \t\\\"\tdouble quote\n\ +   \t\\ooo\tAn octal constant, where ooo is one to three\n\ +   \t\t\toctal digits (0..7)\n"  @ MSG_HELP_SET	"   \     The str:set command is used to display or alter the existing\n\ @@ -260,6 +286,7 @@  # Miscellaneous clutter  @ MSG_STR_EMPTY			"" +@ MSG_STR_MINUS_ANY		"-any"  @ MSG_STR_MINUS_END		"-end"  @ MSG_STR_MINUS_NOTERM		"-noterm"  @ MSG_STR_MINUS_SHNAM		"-shnam" @@ -272,6 +299,8 @@  @ MSG_STR_NEWSTRING		"new-string"  @ MSG_STR_STRING		"string"  @ MSG_STR_TYPE			"type" +@ MSG_STR_DQUOTE		"\"" +@ MSG_STR_DQUOTENL		"\"\n"  # Format strings @@ -279,7 +308,7 @@  @ MSG_FMT_STRNL			"%s\n"  @ MSG_FMT_INDEX			"[%lld]"  @ MSG_FMT_INDEXRANGE		"[%lld-%lld]" -@ MSG_FMT_DUMPENTRY		"%15s  %s\n" +@ MSG_FMT_DUMPENTRY		"%15s  "  @ MSG_FMT_WORDVAL		"%u" diff --git a/usr/src/cmd/sgs/include/_string_table.h b/usr/src/cmd/sgs/include/_string_table.h index de0955ec58..2d2963f9da 100644 --- a/usr/src/cmd/sgs/include/_string_table.h +++ b/usr/src/cmd/sgs/include/_string_table.h @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -55,13 +55,13 @@ extern "C" {  typedef struct {  	avl_node_t	sn_avlnode;	/* AVL book-keeping */  	const char	*sn_str;	/* string */ -	uint_t		sn_refcnt;	/* reference count */ +	size_t		sn_refcnt;	/* reference count */  } StrNode;  typedef struct {  	avl_node_t	ln_avlnode;	/* AVL book-keeping */  	avl_tree_t	*ln_strtree;	/* AVL tree of associated strings */ -	uint_t		ln_strlen;	/* length of associated strings */ +	size_t		ln_strlen;	/* length of associated strings */  } LenNode;  /* @@ -74,9 +74,9 @@ typedef	struct str_master	Str_master;  struct str_master {  	const char	*sm_str;	/* pointer to master string */  	Str_master	*sm_next;	/* used for tracking master strings */ -	uint_t		sm_strlen;	/* length of master string */ +	size_t		sm_strlen;	/* length of master string */  	uint_t		sm_hashval;	/* hashval of master string */ -	uint_t		sm_stroff;	/* offset into destination strtab */ +	size_t		sm_stroff;	/* offset into destination strtab */  };  /* @@ -87,8 +87,8 @@ struct str_master {  typedef	struct str_hash	Str_hash;  struct str_hash { -	uint_t		hi_strlen;	/* string length */ -	uint_t		hi_refcnt;	/* number of references to str */ +	size_t		hi_strlen;	/* string length */ +	size_t		hi_refcnt;	/* number of references to str */  	uint_t		hi_hashval;	/* hash for string */  	Str_master	*hi_mstr;	/* pointer to master string */  	Str_hash	*hi_next;	/* next entry in hash bucket */ @@ -102,10 +102,10 @@ struct str_tbl {  	char		*st_strbuf;		/* string buffer */  	Str_hash	**st_hashbcks;		/* hash buckets */  	Str_master	*st_mstrlist;		/* list of all master strings */ -	uint_t		st_fullstrsize;		/* uncompressed table size */ -	uint_t		st_nextoff;		/* next available string */ -	uint_t		st_strsize;		/* compressed size */ -	uint_t		st_strcnt;		/* number of strings */ +	size_t		st_fullstrsize;		/* uncompressed table size */ +	size_t		st_nextoff;		/* next available string */ +	size_t		st_strsize;		/* compressed size */ +	size_t		st_strcnt;		/* number of strings */  	uint_t		st_hbckcnt;		/* number of buckets in */  						/*    hashlist */  	uint_t		st_flags; diff --git a/usr/src/cmd/sgs/include/alist.h b/usr/src/cmd/sgs/include/alist.h index 33f403a641..e92811f2ee 100644 --- a/usr/src/cmd/sgs/include/alist.h +++ b/usr/src/cmd/sgs/include/alist.h @@ -20,7 +20,7 @@   */  /* - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   *   * Define an Alist, a list maintained as a reallocable array, and a for() loop @@ -41,36 +41,233 @@ extern "C" {  #include <sys/types.h>  #include <sys/machelf.h> -#define	ALO_DATA	(sizeof (Alist) - sizeof (void *)) +/* + * An Alist implements array lists. The functionality is similar to + * that of a linked list. However, an Alist is represented by a single + * contigious allocation of memory. The head of the memory is a header + * that contains control information for the list. Following the header + * is an array used to hold the user data. In the type definitions that + * follow, we define these as an array with a single element, but when + * we allocate the memory, we actually allocate the amount of memory needed. + * + * There are two "flavors" of array list: + * + *	Alist - Contain arbitrary data, usually structs. + *	APlist - Contain pointers to data allocated elsewhere. + * + * This differentiation is useful, because pointer lists are heavily + * used, and support a slightly different set of operations that are + * unique to their purpose. + * + * Array lists are initially represented by a NULL pointer. The memory + * for the list is only allocated if an item is inserted. This is very + * efficient for data structures that may or may not be needed for a + * given linker operation --- you only pay for what you use. In addition: + * + *	- Array lists grow as needed (memory is reallocated as necessary) + *	- Data is kept contiguously (no unused holes in between elements) + *		at the beginning of the data area. This locality has + *		good cache behavior, as access to adjacent items are + *		highly likely to be in the same page of memory. + *	- Insert/Delete operations at the end of the list are very + *		efficient. However, insert/delete operations elsewhere + *		will cause a relatively expensive overlapped memory + *		copy of the data following the insert/delete location. + *	- As with any generic memory alloctor (i.e. malloc()/free()), + *		array lists are not type safe for the data they contain. + *		Data is managed as (void *) pointers to data of a given + *		length, so the Alist module cannot prevent the caller from + *		inserting/extracting the wrong type of data. The caller + *		must guard against this. + *	- To free an array list, simply call the standard free() function + *		on the list pointer. + */ -#define	ALIST_TRAVERSE(LIST, OFF, DATA) \ -	(((LIST) != 0) && ((OFF) = ALO_DATA) && \ -	(((DATA) = (void *)((char *)(LIST) + (OFF))))); \ -	(((LIST) != 0) && ((OFF) < (LIST)->al_next)); \ -	(((OFF) += ((LIST)->al_size)), \ -	((DATA) = (void *)((char *)(LIST) + (OFF)))) -typedef	Word	Aliste; +/* + * Aliste is used to represent list indexes, offsets, and sizes. + */ +typedef	size_t	Aliste; + + + +/* + * Alist is used to hold non-pointer items --- usually structs: + *	- There must be an even number of Aliste fields before the + *		al_data field. This ensures that al_data will have + *		an alignment of 8, no matter whether sizeof(Aliste) + *		is 4 or 8. That means that al_data will have sufficient + *		alignment for any use, just like memory allocated via + *		malloc(). + *	- al_nitems and al_next are redundant, in that they are + *		directly related: + *			al_next = al_nitems * al_size + *		We do this to make ALIST_TRAVERSE_BYOFFSET maximally + *		efficient. This doesn't waste space, because of the + *		requirement to have an even # of Alist fields (above). + * + * Note that Alists allow the data to be referenced by 0 based array + * index, or by their byte offset from the start of the Alist memory + * allocation. The index form is preferred for most use, as it is simpler. + * However, by-offset access is used by rtld link maps, and this ability + * is convenient in that case. + */  typedef struct { -	Aliste 		al_end;		/* offset after last al_data[] */ +	Aliste 		al_arritems;	/* # of items in al_data allocation */ +	Aliste 		al_nitems;	/* # items (index of next avail item) */  	Aliste 		al_next;	/* offset of next available al_data[] */  	Aliste		al_size;	/* size of each al_data[] item */ -	void *		al_data[1];	/* data (can grow) */ +	void 		*al_data[1];	/* data (can grow) */  } Alist; +/* + * APlist is a variant of Alist that contains pointers. There are several + * benefits to this special type: + *	- API is simpler + *	- Pointers are used directly, instead of requiring a + *		pointer-to-pointer double indirection. + *	- The implementation is slightly more efficient. + *	- Operations that make particular sense for pointers + *		can be supported without confusing the API for the + *		regular Alists. + */ +typedef struct { +	Aliste		apl_arritems;	/* # of items in apl_data allocation */ +	Aliste 		apl_nitems;	/* # items (index of next avail item) */ +	void		*apl_data[1];	/* data area: (arrcnt * size) bytes */ +} APlist; +  /* - * Define alist descriptor addition return values. + * The ALIST_OFF_DATA and APLIST_OFF_DATA macros give the byte offset + * from the start of an array list to the first byte of the data area + * used to hold user data. The same trick used by the standard offsetof() + * macro is used. + */ +#define	ALIST_OFF_DATA	((size_t)(((Alist *)0)->al_data)) +#define	APLIST_OFF_DATA	((size_t)(((APlist *)0)->apl_data)) + + +/* + * The TRAVERSE macros are intended to be used within a for(), and + * cause the resulting loop to iterate over each item in the loop, + * in order. + *	ALIST_TRAVERSE: Traverse over the items in an Alist, + *		using the zero based item array index to refer to + *		each item. + *	ALIST_TRAVERSE_BY_OFFSET: Traverse over the items in an + *		Alist using the byte offset from the head of the + *		Alist pointer to refer to each item. It should be noted + *		that the first such offset is given by ALIST_OFF_DATA, + *		and as such, there will never be a 0 offset. Some code + *		uses this fact to treat 0 as a reserved value with + *		special meaning. + * + *		By-offset access is convenient for some parts of + *		rtld, where a value of 0 is used to indicate an + *		uninitialized link map control. + * + *	APLIST_TRAVERSE: Traverse over the pointers in an APlist, using + *		the zero based item array index to refer to each pointer.   */ -#define	ALE_EXISTS	1		/* alist entry already exists */ -#define	ALE_CREATE	2		/* alist entry created */ + +/* + * Within the loop: + * + *	LIST - Pointer to Alist structure for list + *	IDX - The current item index + *	OFF - The current item offset + *	DATA - Pointer to item + */ +#define	ALIST_TRAVERSE(LIST, IDX, DATA) \ +	(IDX) = 0, \ +	((LIST) != NULL) && ((DATA) = (void *)(LIST)->al_data); \ +	\ +	((LIST) != NULL) && ((IDX) < (LIST)->al_nitems); \ +	\ +	(IDX)++, \ +	(DATA) = (void *) (((LIST)->al_size * (IDX)) + (char *)(LIST)->al_data) + +#define	ALIST_TRAVERSE_BY_OFFSET(LIST, OFF, DATA) \ +	(((LIST) != NULL) && ((OFF) = ALIST_OFF_DATA) && \ +	(((DATA) = (void *)((char *)(LIST) + (OFF))))); \ +	\ +	(((LIST) != NULL) && ((OFF) < (LIST)->al_next)); \ +	\ +	(((OFF) += ((LIST)->al_size)), \ +	((DATA) = (void *)((char *)(LIST) + (OFF)))) + +/* + * Within the loop: + * + *	LIST - Pointer to APlist structure for list + *	IDX - The current item index + *	PTR - item value + * + * Note that this macro is designed to ensure that PTR retains the + * value of the final pointer in the list after exiting the for loop, + * and to avoid dereferencing an out of range address. This is done by + * doing the dereference in the middle expression, using the comma + * operator to ensure that a NULL pointer won't stop the loop. + */ +#define	APLIST_TRAVERSE(LIST, IDX, PTR) \ +	(IDX) = 0; \ +	\ +	((LIST) != NULL) && ((IDX) < (LIST)->apl_nitems) && \ +	(((PTR) = ((LIST)->apl_data)[IDX]), 1); \ +	\ +	(IDX)++ + + +/* + * Possible values returned by aplist_test() + */ +typedef enum { +	ALE_ALLOCFAIL = 0,	/* Memory allocation error */ +	ALE_EXISTS =	1,	/* alist entry already exists */ +	ALE_NOTFND =	2,	/* item not found and insert not required */ +	ALE_CREATE =	3	/* alist entry created */ +} aplist_test_t; + + +/* + * Access to an Alist item by index or offset. This is needed because the + * size of an item in an Alist is not known by the C compiler, and we + * have to do the indexing arithmetic explicitly. + * + * For an APlist, index the apl_data field directly --- No macro is needed. + */ +#define	alist_item(_lp, _idx) \ +	((void *)(ALIST_OFF_DATA + ((_idx) * (_lp)->al_size) + (char *)(_lp))) +#define	alist_item_by_offset(_lp, _off) \ +	((void *)((_off) + (char *)(_lp))) + +/* + * # of items currently found in a list. These macros handle the case + * where the list has not been allocated yet. + */ +#define	alist_nitems(_lp) (((_lp) == NULL) ? 0 : (_lp)->al_nitems) +#define	aplist_nitems(_lp) (((_lp) == NULL) ? 0 : (_lp)->apl_nitems) + + +extern void		*alist_append(Alist **, const void *, size_t, Aliste); +extern void		alist_delete(Alist *, Aliste *); +extern void		alist_delete_by_offset(Alist *, Aliste *); +extern void		*alist_insert(Alist **, const void *, size_t, +			    Aliste, Aliste); +extern void		*alist_insert_by_offset(Alist **, const void *, size_t, +			    Aliste, Aliste); +extern void		alist_reset(Alist *); -extern void	*alist_append(Alist **, const void *, size_t, int); -extern int	alist_delete(Alist *, const void *, Aliste *); -extern void	*alist_insert(Alist **, const void *, size_t, int, Aliste); -extern int	alist_test(Alist **, void *, size_t, int); +extern void		*aplist_append(APlist **, const void *, Aliste); +extern void		aplist_delete(APlist *, Aliste *); +extern int		aplist_delete_value(APlist *, const void *); +extern void		*aplist_insert(APlist **, const void *, +			    Aliste, Aliste idx); +extern void		aplist_reset(APlist *); +extern aplist_test_t	aplist_test(APlist **, const void *, Aliste);  #ifdef	__cplusplus  } diff --git a/usr/src/cmd/sgs/include/debug.h b/usr/src/cmd/sgs/include/debug.h index bb77b596d4..5012d2ed53 100644 --- a/usr/src/cmd/sgs/include/debug.h +++ b/usr/src/cmd/sgs/include/debug.h @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -154,7 +154,7 @@ extern "C" {  typedef struct {  	uint_t		d_class;	/* debugging classes */  	uint_t		d_extra;	/* extra information for classes */ -	Alist		*d_list;	/* associated strings */ +	APlist		*d_list;	/* associated strings */  } Dbg_desc;  extern	Dbg_desc	*dbg_desc; @@ -320,11 +320,13 @@ extern	uintptr_t	Dbg_setup(const char *, Dbg_desc *);  #define	Dbg_sec_added		Dbg64_sec_added  #define	Dbg_sec_created		Dbg64_sec_created  #define	Dbg_sec_discarded	Dbg64_sec_discarded +#define	Dbg_sec_genstr_compress	Dbg64_sec_genstr_compress  #define	Dbg_sec_group		Dbg64_sec_group  #define	Dbg_sec_in		Dbg64_sec_in  #define	Dbg_sec_order_error	Dbg64_sec_order_error  #define	Dbg_sec_order_list	Dbg64_sec_order_list  #define	Dbg_sec_strtab		Dbg64_sec_strtab +#define	Dbg_sec_unsup_strmerge	Dbg64_sec_unsup_strmerge  #define	Dbg_seg_desc_entry	Dbg64_seg_desc_entry  #define	Dbg_seg_entry		Dbg64_seg_entry @@ -519,11 +521,13 @@ extern	uintptr_t	Dbg_setup(const char *, Dbg_desc *);  #define	Dbg_sec_added		Dbg32_sec_added  #define	Dbg_sec_created		Dbg32_sec_created  #define	Dbg_sec_discarded	Dbg32_sec_discarded +#define	Dbg_sec_genstr_compress	Dbg32_sec_genstr_compress  #define	Dbg_sec_group		Dbg32_sec_group  #define	Dbg_sec_in		Dbg32_sec_in  #define	Dbg_sec_order_error	Dbg32_sec_order_error  #define	Dbg_sec_order_list	Dbg32_sec_order_list  #define	Dbg_sec_strtab		Dbg32_sec_strtab +#define	Dbg_sec_unsup_strmerge	Dbg32_sec_unsup_strmerge  #define	Dbg_seg_desc_entry	Dbg32_seg_desc_entry  #define	Dbg_seg_entry		Dbg32_seg_entry @@ -752,11 +756,14 @@ extern	void	Dbg_reloc_sloppycomdat(Lm_list *, const char *, Sym_desc *);  extern	void	Dbg_sec_added(Lm_list *, Os_desc *, Sg_desc *);  extern	void	Dbg_sec_created(Lm_list *, Os_desc *, Sg_desc *);  extern	void	Dbg_sec_discarded(Lm_list *, Is_desc *, Is_desc *); +extern	void	Dbg_sec_genstr_compress(Lm_list *, const char *, +		    Xword, Xword);  extern	void	Dbg_sec_group(Lm_list *, Is_desc *, Group_desc *);  extern	void	Dbg_sec_in(Lm_list *, Is_desc *);  extern	void	Dbg_sec_order_error(Lm_list *, Ifl_desc *, Word, int);  extern	void	Dbg_sec_order_list(Ofl_desc *, int);  extern	void	Dbg_sec_strtab(Lm_list *, Os_desc *, Str_tbl *); +extern	void	Dbg_sec_unsup_strmerge(Lm_list *, Is_desc *);  extern	void	Dbg_seg_desc_entry(Lm_list *, Half, int, Sg_desc *);  extern	void	Dbg_seg_entry(Ofl_desc *, int, Sg_desc *); diff --git a/usr/src/cmd/sgs/include/elfedit.h b/usr/src/cmd/sgs/include/elfedit.h index 0c51b6872c..a24da8878b 100644 --- a/usr/src/cmd/sgs/include/elfedit.h +++ b/usr/src/cmd/sgs/include/elfedit.h @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -593,6 +593,11 @@ typedef struct {  typedef elfedit_module_t *elfedit_init_func_t(elfedit_module_version_t version); +/* + * Prototype for elfedit_write(), and for outfunc argument + * to elfedit_str_to_c_literal(). + */ +typedef void elfedit_write_func_t(const void *ptr, size_t size);  /* @@ -609,7 +614,9 @@ extern elfedit_outstyle_t elfedit_outstyle(void);  extern void elfedit_pager_init(void);  extern void elfedit_printf(const char *format, ...);  extern void *elfedit_realloc(const char *item_name, void *ptr, size_t size); -extern void elfedit_write(const void *ptr, size_t size); +extern void elfedit_str_to_c_literal(const char *str, +    elfedit_write_func_t *outfunc); +extern elfedit_write_func_t elfedit_write;  /*   * Core elfedit functions exported for use by sys: module only @@ -924,6 +931,11 @@ extern int elfedit32_sec_findstr(elfedit32_section_t *sec, Elf32_Word tail_ign,  extern int elfedit64_sec_findstr(elfedit64_section_t *sec, Elf64_Word tail_ign,      const char *str, Elf64_Word *ret_offset); +extern elfedit32_section_t *elfedit32_sec_get( +    elfedit32_obj_state_t *obj_state, Elf32_Word shndx); +extern elfedit64_section_t *elfedit64_sec_get( +    elfedit64_obj_state_t *obj_state, Elf64_Word shndx); +  extern elfedit32_section_t *elfedit32_sec_getcap(      elfedit32_obj_state_t *obj_state, Elf32_Cap **cap, Elf32_Word *num);  extern elfedit64_section_t *elfedit64_sec_getcap( @@ -1015,6 +1027,7 @@ extern Elf64_Word elfedit64_type_to_shndx(elfedit64_obj_state_t *obj_state,  #define	elfedit_name_to_symndx		elfedit64_name_to_symndx  #define	elfedit_offset_to_str		elfedit64_offset_to_str  #define	elfedit_sec_findstr		elfedit64_sec_findstr +#define	elfedit_sec_get			elfedit64_sec_get  #define	elfedit_sec_getcap		elfedit64_sec_getcap  #define	elfedit_sec_getdyn		elfedit64_sec_getdyn  #define	elfedit_sec_getstr		elfedit64_sec_getstr @@ -1042,6 +1055,7 @@ extern Elf64_Word elfedit64_type_to_shndx(elfedit64_obj_state_t *obj_state,  #define	elfedit_name_to_symndx		elfedit32_name_to_symndx  #define	elfedit_offset_to_str		elfedit32_offset_to_str  #define	elfedit_sec_findstr		elfedit32_sec_findstr +#define	elfedit_sec_get			elfedit32_sec_get  #define	elfedit_sec_getcap		elfedit32_sec_getcap  #define	elfedit_sec_getdyn		elfedit32_sec_getdyn  #define	elfedit_sec_getstr		elfedit32_sec_getstr diff --git a/usr/src/cmd/sgs/include/libld.h b/usr/src/cmd/sgs/include/libld.h index 9d8318821b..df2fecddf9 100644 --- a/usr/src/cmd/sgs/include/libld.h +++ b/usr/src/cmd/sgs/include/libld.h @@ -74,23 +74,21 @@ extern "C" {   * order to tell the linker that:   *   *      1) There is nothing in the section except null terminated strings. - *      2) If two compatible sections both have these flags set, it is - *		OK to combine identical strings into single instances. - *		In this case, the two sections would be modified to both - *		reference a single string copy. + *	2) Those strings do not contain NULL bytes, except as termination. + *	3) All references to these strings occur via standard relocation + *		records. + * + * As a result, if two compatible sections both have these flags set, it is + * OK to combine the strings they contain into a single merged string table + * with duplicates removed and tail strings merged.   *   * This is a different meaning than the simple concatenating of sections   * that the linker always does. It is a hint that an additional optimization   * is possible, but not required. This means that sections that do not - * share the same SHF_MERGE|SHF_STRINGS values can be merged (concatenated), - * but cannot have their duplicate strings combined. Hence, the values - * of SHF_MERGE|SHF_STRINGS should be ignored when deciding whether two - * sections can be merged (concatenated). - * - * We do not currently implement the SHF_MERGE|SHF_STRINGS optimization, - * but it is possible to add it. If we did, the procedure would be to - * first combine the compatible sections that have these flag bits set, - * and then to concatenate any others to the result. + * share the same SHF_MERGE|SHF_STRINGS values can be concatenated, + * but cannot have their duplicate strings combined. Hence, the + * SHF_MERGE|SHF_STRINGS flags should be ignored when deciding whether + * two sections can be concatenated.   */  #define	ALL_SHF_IGNORE	(ALL_SHF_ORDER | SHF_GROUP | SHF_MERGE | SHF_STRINGS) @@ -412,6 +410,11 @@ struct ofl_desc {  /*   * Relocation (active & output) processing structure - transparent to common   * code. + * + * Note that rel_raddend is primarily only of interest to RELA relocations, + * and is set to 0 for REL. However, there is an exception: If FLG_REL_NADDEND + * is set, then rel_raddend contains a replacement value for the implicit + * addend found in the relocation target.   */  struct rel_desc {  	Os_desc		*rel_osdesc;	/* output section reloc is against */ @@ -466,6 +469,10 @@ struct rel_desc {  #define	FLG_REL_RELA	0x00100000	/* descripter captures a Rela */  #define	FLG_REL_GOTFIX	0x00200000	/* relocation points to GOTOP instr. */  					/*	which needs updating */ +#define	FLG_REL_NADDEND	0x00400000	/* Replace implicit addend in dest */ +					/*	with value in rel_raddend */ +					/*	Relevant to REL (i386) */ +					/*	relocations, not to RELA. */  /*   * Structure to hold a cache of Relocations. @@ -576,6 +583,8 @@ struct is_desc {			/* input section descriptor */  #define	FLG_IS_SECTREF	0x0010		/* section has been referenced */  #define	FLG_IS_GDATADEF	0x0020		/* section contains global data sym */  #define	FLG_IS_EXTERNAL	0x0040		/* isp from an user file */ +#define	FLG_IS_INSTRMRG	0x0080		/* Usable SHF_MERGE|SHF_STRINGS sec */ +#define	FLG_IS_GNSTRMRG	0x0100		/* Generated mergeable string section */  /* @@ -589,6 +598,7 @@ struct os_desc {			/* Output section descriptor */  	List		os_relisdescs;	/* reloc input section descriptors */  					/*	for this output section */  	List		os_isdescs;	/* list of input sections in output */ +	APlist		*os_mstrisdescs; /* FLG_IS_INSTRMRG input sections */  	Sort_desc	*os_sort;	/* used for sorting sections */  	Sg_desc		*os_sgdesc;	/* segment os_desc is placed on */  	Elf_Data	*os_outdata;	/* output sections raw data */ @@ -626,8 +636,8 @@ struct sg_desc {			/* output segment descriptor */  	Xword		sg_round;	/* data rounding required (mapfile) */  	Xword		sg_length;	/* maximum segment length; if 0 */  					/*	segment is not specified */ -	Alist		*sg_osdescs;	/* list of output section descriptors */ -	Alist		*sg_secorder;	/* list specifying section ordering */ +	APlist		*sg_osdescs;	/* list of output section descriptors */ +	APlist		*sg_secorder;	/* list specifying section ordering */  					/*	for the segment */  	Half		sg_flags;  	Sym_desc	*sg_sizesym;	/* size symbol for this segment */ diff --git a/usr/src/cmd/sgs/include/rtld.h b/usr/src/cmd/sgs/include/rtld.h index 386587b780..e50c3d882b 100644 --- a/usr/src/cmd/sgs/include/rtld.h +++ b/usr/src/cmd/sgs/include/rtld.h @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -246,7 +246,7 @@ typedef struct {  typedef struct {  	Rt_map		*lc_head;  	Rt_map		*lc_tail; -	Alist		*lc_now;	/* pending promoted bind-now objects */ +	APlist		*lc_now;	/* pending promoted bind-now objects */  	uint_t		lc_flags;  } Lm_cntl; @@ -261,7 +261,7 @@ struct lm_list {  	 */  	Rt_map		*lm_head;	/* linked list pointers to active */  	Rt_map		*lm_tail;	/*	link-map list */ -	Alist		*lm_handle;	/* not used by rtld_db - but spacing */ +	APlist		*lm_handle;	/* not used by rtld_db - but spacing */  					/*	is required for flags */  	Word		lm_flags;  	/* @@ -279,7 +279,7 @@ struct lm_list {  	uint_t		lm_tls;		/* new obj that require TLS */  	uint_t		lm_lmid;	/* unique link-map list identifier, */  	char		*lm_lmidstr;	/* and associated diagnostic string */ -	Alist		*lm_actaudit;	/* list of pending audit activity */ +	APlist		*lm_actaudit;	/* list of pending audit activity */  	Lc_desc		lm_lcs[CI_MAX];	/* external libc functions */  }; @@ -527,6 +527,17 @@ typedef struct {  } Mmap;  /* + * A given link-map can hold either a supplier or receiver copy + * relocation list, but not both. This union is used to overlap + * the space used for the two lists. + */ +typedef union { +	Alist	*rtc_r;		/* receiver list (Rel_copy) */ +	APlist	*rtc_s;		/* supplier list (Rt_map *) */ +} Rt_map_copy; + + +/*   * Link-map definition.   */  struct rt_map { @@ -544,16 +555,16 @@ struct rt_map {  	/*  	 * END: Exposed to rtld_db - don't move, don't delete  	 */ -	Alist		*rt_alias;	/* list of linked file names */ -	Alist		*rt_fpnode;	/* list of FullpathNode AVL nodes */ +	APlist		*rt_alias;	/* list of linked file names */ +	APlist		*rt_fpnode;	/* list of FullpathNode AVL nodes */  	void		(*rt_init)();	/* address of _init */  	void		(*rt_fini)();	/* address of _fini */  	char		*rt_runpath;	/* LD_RUN_PATH and its equivalent */  	Pnode		*rt_runlist;	/*	Pnode structures */ -	Alist		*rt_depends;	/* list of dependencies */ -	Alist		*rt_callers;	/* list of callers */ -	Alist		*rt_handles;	/* dlopen handles */ -	Alist		*rt_groups;	/* groups we're a member of */ +	APlist		*rt_depends;	/* list of dependencies */ +	APlist		*rt_callers;	/* list of callers */ +	APlist		*rt_handles;	/* dlopen handles */ +	APlist		*rt_groups;	/* groups we're a member of */  	ulong_t		rt_etext;	/* etext address */  	struct fct	*rt_fct;	/* file class table for this object */  	Sym		*(*rt_symintp)(); /* link map symbol interpreter */ @@ -569,7 +580,7 @@ struct rt_map {  	ino_t		rt_stino;	/*	multiple inclusion checks */  	char		*rt_origname;	/* original pathname of loaded object */  	size_t		rt_dirsz;	/*	and its size */ -	Alist		*rt_copy;	/* list of copy relocations */ +	Rt_map_copy	rt_copy;	/* list of copy relocations */  	Audit_desc	*rt_auditors;	/* audit descriptor array */  	Audit_info	*rt_audinfo;	/* audit information descriptor */  	Syminfo		*rt_syminfo;	/* elf .syminfo section - here */ @@ -600,6 +611,11 @@ struct rt_map {  /*   * Structure to allow 64-bit rtld_db to read 32-bit processes out of procfs.   */ +typedef union { +	uint32_t	rtc_r; +	uint32_t	rtc_s; +} Rt_map_copy32; +  typedef struct rt_map32 {  	/*  	 * BEGIN: Exposed to rtld_db - don't move, don't delete @@ -640,7 +656,7 @@ typedef struct rt_map32 {  	uint32_t	rt_stino;  	uint32_t	rt_origname;  	uint32_t	rt_dirsz; -	uint32_t	rt_copy; +	Rt_map_copy32	rt_copy;  	uint32_t 	rt_auditors;  	uint32_t 	rt_audinfo;  	uint32_t	rt_syminfo; @@ -796,7 +812,8 @@ typedef struct rt_map32 {  #define	STINO(X)	((X)->rt_stino)  #define	ORIGNAME(X)	((X)->rt_origname)  #define	DIRSZ(X)	((X)->rt_dirsz) -#define	COPY(X)		((X)->rt_copy) +#define	COPY_R(X)	((X)->rt_copy.rtc_r) +#define	COPY_S(X)	((X)->rt_copy.rtc_s)  #define	AUDITORS(X)	((X)->rt_auditors)  #define	AUDINFO(X)	((X)->rt_audinfo)  #define	SYMINFO(X)	((X)->rt_syminfo) diff --git a/usr/src/cmd/sgs/include/string_table.h b/usr/src/cmd/sgs/include/string_table.h index 1bd2d383e2..e42f81779f 100644 --- a/usr/src/cmd/sgs/include/string_table.h +++ b/usr/src/cmd/sgs/include/string_table.h @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -44,12 +44,12 @@ typedef struct str_tbl	Str_tbl;   */  extern int		st_delstring(Str_tbl *, const char *);  extern void		st_destroy(Str_tbl *); -extern uint_t		st_getstrtab_sz(Str_tbl *); +extern size_t		st_getstrtab_sz(Str_tbl *);  extern const char	*st_getstrbuf(Str_tbl *);  extern int		st_insert(Str_tbl *, const char *);  extern Str_tbl		*st_new(uint_t); -extern int		st_setstrbuf(Str_tbl *, char *, uint_t); -extern int		st_setstring(Str_tbl *, const char *, uint_t *); +extern int		st_setstrbuf(Str_tbl *, char *, size_t); +extern int		st_setstring(Str_tbl *, const char *, size_t *);  /*   * Exported flags values for st_new(). diff --git a/usr/src/cmd/sgs/libld/common/_libld.h b/usr/src/cmd/sgs/libld/common/_libld.h index 47f8c98f04..3b5613a027 100644 --- a/usr/src/cmd/sgs/libld/common/_libld.h +++ b/usr/src/cmd/sgs/libld/common/_libld.h @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -146,17 +146,20 @@ typedef struct {   */  typedef struct {  	Sym_desc	*sft_sdp;	/* symbol descriptor */ -	Aliste		sft_off;	/* offset into dtstr descriptor */ +	Aliste		sft_idx;	/* index into dtstr descriptor */  } Sfltr_desc;  /*   * Define Alist initialization sizes.   */ -#define	AL_CNT_DFLTR	4		/* ofl_dtsfltrs initial alist count */ -#define	AL_CNT_GROUP	20		/* ifl_groups initial alist count */ -#define	AL_CNT_SFLTR	20		/* ofl_symfltrs initial alist count */ -#define	AL_CNT_OSDESC	40		/* sg_osdescs initial alist count */ -#define	AL_CNT_SECORDER	40		/* sg_secorder initial alist count */ +#define	AL_CNT_IFL_GROUPS	20	/* ifl_groups initial alist count */ +#define	AL_CNT_OFL_DTSFLTRS	4	/* ofl_dtsfltrs initial alist count */ +#define	AL_CNT_OFL_SYMFLTRS	20	/* ofl_symfltrs initial alist count */ +#define	AL_CNT_OS_MSTRISDESCS	10	/* os_mstrisdescs */ +#define	AL_CNT_SG_OSDESC	40	/* sg_osdescs initial alist count */ +#define	AL_CNT_SG_SECORDER	40	/* sg_secorder initial alist count */ +#define	AL_CNT_STRMRGREL	500	/* ld_make_strmerge() reloc alist cnt */ +#define	AL_CNT_STRMRGSYM	20	/* ld_make_strmerge() sym alist cnt */  /*   * Return codes for {tls|got}_fixups() routines @@ -320,12 +323,13 @@ extern Sdf_desc		*sdf_find(const char *, List *);  #define	ld_add_libdir		ld64_add_libdir  #define	ld_add_outrel		ld64_add_outrel  #define	ld_adj_movereloc	ld64_adj_movereloc -#define	ld_am_I_partial		ld64_am_I_partial -#define	ld_ar_member		ld64_ar_member -#define	ld_ar_setup		ld64_ar_setup  #if	defined(__sparc)  #define	ld_allocate_got		ld64_allocate_got  #endif +#define	ld_am_I_partial		ld64_am_I_partial +#define	ld_append_isp		ld64_append_isp +#define	ld_ar_member		ld64_ar_member +#define	ld_ar_setup		ld64_ar_setup  #define	ld_assign_got		ld64_assign_got  #define	ld_assign_got_ndx	ld64_assign_got_ndx  #define	ld_assign_got_TLS	ld64_assign_got_TLS @@ -376,10 +380,13 @@ extern Sdf_desc		*sdf_find(const char *, List *);  #define	ld_reloc_register	ld64_reloc_register  #define	ld_reloc_remain_entry	ld64_reloc_remain_entry  #define	ld_reloc_TLS		ld64_reloc_TLS +#define	ld_reloc_targval_get	ld64_reloc_targval_get +#define	ld_reloc_targval_set	ld64_reloc_targval_set  #define	ld_reg_check		ld64_reg_check  #define	ld_reg_enter		ld64_reg_enter  #define	ld_reg_find		ld64_reg_find  #define	ld_sec_validate		ld64_sec_validate +#define	ld_section_reld_name	ld64_section_reld_name  #define	ld_sort_ordered		ld64_sort_ordered  #define	ld_sort_seg_list	ld64_sort_seg_list  #define	ld_sunwmove_preprocess	ld64_sunwmove_preprocess @@ -418,12 +425,13 @@ extern Sdf_desc		*sdf_find(const char *, List *);  #define	ld_add_libdir		ld32_add_libdir  #define	ld_add_outrel		ld32_add_outrel  #define	ld_adj_movereloc	ld32_adj_movereloc -#define	ld_am_I_partial		ld32_am_I_partial -#define	ld_ar_member		ld32_ar_member -#define	ld_ar_setup		ld32_ar_setup  #if	defined(__sparc)  #define	ld_allocate_got		ld32_allocate_got  #endif +#define	ld_am_I_partial		ld32_am_I_partial +#define	ld_append_isp		ld32_append_isp +#define	ld_ar_member		ld32_ar_member +#define	ld_ar_setup		ld32_ar_setup  #define	ld_assign_got		ld32_assign_got  #define	ld_assign_got_ndx	ld32_assign_got_ndx  #define	ld_assign_got_TLS	ld32_assign_got_TLS @@ -439,6 +447,7 @@ extern Sdf_desc		*sdf_find(const char *, List *);  #define	ld_find_gotndx		ld32_find_gotndx  #define	ld_find_library		ld32_find_library  #define	ld_finish_libs		ld32_finish_libs +#define	ld_section_reld_name	ld32_section_reld_name  #define	ld_get_group		ld32_get_group  #define	ld_lib_setup		ld32_lib_setup  #define	ld_init			ld32_init @@ -474,6 +483,8 @@ extern Sdf_desc		*sdf_find(const char *, List *);  #define	ld_reloc_register	ld32_reloc_register  #define	ld_reloc_remain_entry	ld32_reloc_remain_entry  #define	ld_reloc_TLS		ld32_reloc_TLS +#define	ld_reloc_targval_get	ld32_reloc_targval_get +#define	ld_reloc_targval_set	ld32_reloc_targval_set  #define	ld_reg_check		ld32_reg_check  #define	ld_reg_enter		ld32_reg_enter  #define	ld_reg_find		ld32_reg_find @@ -519,6 +530,7 @@ extern uintptr_t	ld_add_libdir(Ofl_desc *, const char *);  extern uintptr_t	ld_add_outrel(Word, Rel_desc *, Ofl_desc *);  extern void 		ld_adj_movereloc(Ofl_desc *, Rel_desc *);  extern Sym_desc * 	ld_am_I_partial(Rel_desc *, Xword); +extern int		ld_append_isp(Ofl_desc *, Os_desc *, Is_desc *, int);  extern void		ld_ar_member(Ar_desc *, Elf_Arsym *, Ar_aux *,  			    Ar_mem *);  extern Ar_desc		*ld_ar_setup(const char *, Elf *, Ofl_desc *); @@ -548,7 +560,9 @@ extern Gotndx *		ld_find_gotndx(List *, Gotref, Ofl_desc *, Rel_desc *);  extern uintptr_t	ld_find_library(const char *, Ofl_desc *);  extern uintptr_t	ld_finish_libs(Ofl_desc *); -extern Group_desc *	ld_get_group(Ofl_desc *, Is_desc *); +extern const char	*ld_section_reld_name(Sym_desc *, Is_desc *); + +extern Group_desc	*ld_get_group(Ofl_desc *, Is_desc *);  extern uintptr_t	ld_lib_setup(Ofl_desc *); @@ -596,7 +610,10 @@ extern uintptr_t	ld_reloc_register(Rel_desc *, Is_desc *, Ofl_desc *);  extern void		ld_reloc_remain_entry(Rel_desc *, Os_desc *,  			    Ofl_desc *);  extern uintptr_t	ld_reloc_TLS(Boolean, Rel_desc *, Ofl_desc *); - +extern int		ld_reloc_targval_get(Ofl_desc *, Rel_desc *, +			    uchar_t *, Xword *); +extern int		ld_reloc_targval_set(Ofl_desc *, Rel_desc *, +			    uchar_t *, Xword);  extern int		ld_reg_check(Sym_desc *, Sym *, const char *,  			    Ifl_desc *, Ofl_desc *);  extern int		ld_reg_enter(Sym_desc *, Ofl_desc *); @@ -646,7 +663,6 @@ extern int		ld_vers_sym_process(Lm_list *, Is_desc *, Ifl_desc *);  extern int		ld_vers_verify(Ofl_desc *);  extern uintptr_t	add_regsym(Sym_desc *, Ofl_desc *); -extern void		*alist_append(Alist **, const void *, size_t, int);  extern Word		hashbkts(Word);  extern Xword		lcm(Xword, Xword);  extern Listnode *	list_where(List *, Word); diff --git a/usr/src/cmd/sgs/libld/common/args.c b/usr/src/cmd/sgs/libld/common/args.c index d547d2faf4..7d55b970f3 100644 --- a/usr/src/cmd/sgs/libld/common/args.c +++ b/usr/src/cmd/sgs/libld/common/args.c @@ -594,7 +594,7 @@ check_flags(Ofl_desc * ofl, int argc)  	 * object, or are set on a per-symbol basis from a mapfile.  	 */  	if (zlflag) { -		if ((ofl->ofl_filtees == 0) && (ofl->ofl_dtsfltrs == 0)) { +		if ((ofl->ofl_filtees == NULL) && (ofl->ofl_dtsfltrs == NULL)) {  			eprintf(ofl->ofl_lml, ERR_FATAL,  			    MSG_INTL(MSG_ARG_NOFLTR),  			    MSG_ORIG(MSG_ARG_ZLOADFLTR)); diff --git a/usr/src/cmd/sgs/libld/common/groups.c b/usr/src/cmd/sgs/libld/common/groups.c index 57ba90f21c..2478fd229e 100644 --- a/usr/src/cmd/sgs/libld/common/groups.c +++ b/usr/src/cmd/sgs/libld/common/groups.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -119,13 +119,13 @@ ld_get_group(Ofl_desc *ofl, Is_desc *isp)  	Elf		*elf = ifl->ifl_elf;  	uint_t		scnndx = isp->is_scnndx;  	Group_desc	*gdp; -	Aliste		off; +	Aliste		idx;  	/*  	 * If this is the first SHF_GROUP section encountered for this file,  	 * establish what group sections exist.  	 */ -	if (ifl->ifl_groups == 0) { +	if (ifl->ifl_groups == NULL) {  		Elf_Scn	*scn = 0;  		while (scn = elf_nextscn(elf, scn)) { @@ -211,7 +211,7 @@ ld_get_group(Ofl_desc *ofl, Is_desc *isp)  				return ((Group_desc *)S_ERROR);  			if (alist_append(&(ifl->ifl_groups), -			    &gd, sizeof (Group_desc), AL_CNT_GROUP) == 0) +			    &gd, sizeof (Group_desc), AL_CNT_IFL_GROUPS) == 0)  				return ((Group_desc *)S_ERROR);  		}  	} @@ -220,7 +220,7 @@ ld_get_group(Ofl_desc *ofl, Is_desc *isp)  	 * Scan the GROUP sections associated with this file to find the  	 * matching group section.  	 */ -	for (ALIST_TRAVERSE(ifl->ifl_groups, off, gdp)) { +	for (ALIST_TRAVERSE(ifl->ifl_groups, idx, gdp)) {  		size_t	ndx;  		Word *	data; diff --git a/usr/src/cmd/sgs/libld/common/ldentry.c b/usr/src/cmd/sgs/libld/common/ldentry.c index 24adc18a11..7d68436fae 100644 --- a/usr/src/cmd/sgs/libld/common/ldentry.c +++ b/usr/src/cmd/sgs/libld/common/ldentry.c @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -44,11 +44,11 @@ static void  sym_muldef_title()  {  	(void) printf(MSG_INTL(MSG_ENT_MUL_FMT_TIL_0), -		MSG_INTL(MSG_ENT_MUL_TIL_0)); +	    MSG_INTL(MSG_ENT_MUL_TIL_0));  	(void) printf(MSG_INTL(MSG_ENT_MUL_FMT_TIL_1), -		MSG_INTL(MSG_ENT_MUL_ITM_SYM), -		MSG_INTL(MSG_ENT_MUL_ITM_DEF_0), -		MSG_INTL(MSG_ENT_MUL_ITM_DEF_1)); +	    MSG_INTL(MSG_ENT_MUL_ITM_SYM), +	    MSG_INTL(MSG_ENT_MUL_ITM_DEF_0), +	    MSG_INTL(MSG_ENT_MUL_ITM_DEF_1));  	symbol_title = FALSE;  } @@ -61,35 +61,34 @@ ld_map_out(Ofl_desc * ofl)  	Sym_avlnode	*sav;  	(void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_1), -		MSG_INTL(MSG_ENT_MAP_TITLE_1)); +	    MSG_INTL(MSG_ENT_MAP_TITLE_1));  	if (ofl->ofl_flags & FLG_OF_RELOBJ)  		(void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_2), -			MSG_INTL(MSG_ENT_ITM_OUTPUT), -			MSG_INTL(MSG_ENT_ITM_INPUT), -			MSG_INTL(MSG_ENT_ITM_NEW), -			MSG_INTL(MSG_ENT_ITM_SECTION), -			MSG_INTL(MSG_ENT_ITM_SECTION), -			MSG_INTL(MSG_ENT_ITM_DISPMNT), -			MSG_INTL(MSG_ENT_ITM_SIZE)); +		    MSG_INTL(MSG_ENT_ITM_OUTPUT), +		    MSG_INTL(MSG_ENT_ITM_INPUT), +		    MSG_INTL(MSG_ENT_ITM_NEW), +		    MSG_INTL(MSG_ENT_ITM_SECTION), +		    MSG_INTL(MSG_ENT_ITM_SECTION), +		    MSG_INTL(MSG_ENT_ITM_DISPMNT), +		    MSG_INTL(MSG_ENT_ITM_SIZE));  	else  		(void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_3), -			MSG_INTL(MSG_ENT_ITM_OUTPUT), -			MSG_INTL(MSG_ENT_ITM_INPUT), -			MSG_INTL(MSG_ENT_ITM_VIRTUAL), -			MSG_INTL(MSG_ENT_ITM_SECTION), -			MSG_INTL(MSG_ENT_ITM_SECTION), -			MSG_INTL(MSG_ENT_ITM_ADDRESS), -			MSG_INTL(MSG_ENT_ITM_SIZE)); +		    MSG_INTL(MSG_ENT_ITM_OUTPUT), +		    MSG_INTL(MSG_ENT_ITM_INPUT), +		    MSG_INTL(MSG_ENT_ITM_VIRTUAL), +		    MSG_INTL(MSG_ENT_ITM_SECTION), +		    MSG_INTL(MSG_ENT_ITM_SECTION), +		    MSG_INTL(MSG_ENT_ITM_ADDRESS), +		    MSG_INTL(MSG_ENT_ITM_SIZE));  	for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { -		Os_desc	**ospp; -		Aliste	off; +		Os_desc	*osp; +		Aliste	idx;  		if (sgp->sg_phdr.p_type != PT_LOAD)  			continue; -		for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { -			Os_desc *osp = *ospp; +		for (APLIST_TRAVERSE(sgp->sg_osdescs, idx, osp)) {  			(void) printf(MSG_INTL(MSG_ENT_MAP_ENTRY_1),  			    osp->os_name, EC_ADDR(osp->os_shdr->sh_addr), @@ -111,13 +110,14 @@ ld_map_out(Ofl_desc * ofl)  				 * sections (ie. .text) existing in the  				 * load-map output.  				 */ -				if (isp->is_flags & FLG_IS_DISCARD) -				    addr = 0; -				else { -				    addr = (Addr)_elf_getxoff(isp->is_indata); -				    if (!(ofl->ofl_flags & FLG_OF_RELOBJ)) -					addr += -					    isp->is_osdesc->os_shdr->sh_addr; +				if (isp->is_flags & FLG_IS_DISCARD) { +					addr = 0; +				} else { +					addr = (Addr) +					    _elf_getxoff(isp->is_indata); +					if (!(ofl->ofl_flags & FLG_OF_RELOBJ)) +						addr += isp->is_osdesc-> +						    os_shdr->sh_addr;  				}  				(void) printf(MSG_INTL(MSG_ENT_MAP_ENTRY_2), @@ -178,7 +178,8 @@ ld_map_out(Ofl_desc * ofl)  			 * Ignore the referenced symbol.  			 */  			if (strcmp(adcp, ducp) != 0) -			    (void) printf(MSG_INTL(MSG_ENT_MUL_ENTRY_2), adcp); +				(void) printf(MSG_INTL(MSG_ENT_MUL_ENTRY_2), +				    adcp);  		}  	}  } diff --git a/usr/src/cmd/sgs/libld/common/libld.msg b/usr/src/cmd/sgs/libld/common/libld.msg index b26d33776e..4d3a3f03b4 100644 --- a/usr/src/cmd/sgs/libld/common/libld.msg +++ b/usr/src/cmd/sgs/libld/common/libld.msg @@ -556,6 +556,8 @@  @ MSG_STR_TLSREL	"(internal TLS relocation requirement)"  @ MSG_STR_SIZES		"sizes"  @ MSG_STR_UNKNOWN       "<unknown>" +@ MSG_STR_SECTION	"%s (section)" +@ MSG_STR_SECTION_MSTR	"%s (merged string section)"  #  # TRANSLATION_NOTE diff --git a/usr/src/cmd/sgs/libld/common/lintsup.c b/usr/src/cmd/sgs/libld/common/lintsup.c index 0b78730219..0091d28426 100644 --- a/usr/src/cmd/sgs/libld/common/lintsup.c +++ b/usr/src/cmd/sgs/libld/common/lintsup.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -32,3 +32,11 @@  #include <debug.h>  #include <elfcap.h>  #include <_libld.h> +#include <sys/debug.h> + + +void +foo() +{ +	assfail3(NULL, 0, NULL, 0, NULL, 0); +} diff --git a/usr/src/cmd/sgs/libld/common/machrel.intel.c b/usr/src/cmd/sgs/libld/common/machrel.intel.c index 33a828be25..9b1e8940a4 100644 --- a/usr/src/cmd/sgs/libld/common/machrel.intel.c +++ b/usr/src/cmd/sgs/libld/common/machrel.intel.c @@ -24,7 +24,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -273,6 +273,24 @@ ld_perform_outreloc(Rel_desc * orsp, Ofl_desc * ofl)  	} else  		ndx = sdp->sd_symndx; +	/* +	 * If we have a replacement value for the relocation +	 * target, put it in place now. +	 */ +	if (orsp->rel_flags & FLG_REL_NADDEND) { +		Xword	addend = orsp->rel_raddend; +		uchar_t	*addr; + +		/* +		 * Get the address of the data item we need to modify. +		 */ +		addr = (uchar_t *)((uintptr_t)orsp->rel_roffset + +		    (uintptr_t)_elf_getxoff(orsp->rel_isdesc->is_indata)); +		addr += (uintptr_t)orsp->rel_osdesc->os_outdata->d_buf; +		if (ld_reloc_targval_set(ofl, orsp, addr, addend) == 0) +			return (S_ERROR); +	} +  	relbits = (char *)relosp->os_outdata->d_buf;  	rea.r_info = ELF_R_INFO(ndx, orsp->rel_rtype); @@ -987,6 +1005,18 @@ ld_do_activerelocs(Ofl_desc *ofl)  				value -= *addr;  			/* +			 * If we have a replacement value for the relocation +			 * target, put it in place now. +			 */ +			if (arsp->rel_flags & FLG_REL_NADDEND) { +				Xword addend = arsp->rel_raddend; + +				if (ld_reloc_targval_set(ofl, arsp, +				    addr, addend) == 0) +					return (S_ERROR); +			} + +			/*  			 * If '-z noreloc' is specified - skip the do_reloc_ld  			 * stage.  			 */ diff --git a/usr/src/cmd/sgs/libld/common/map.c b/usr/src/cmd/sgs/libld/common/map.c index edabc1c724..5d4838aea4 100644 --- a/usr/src/cmd/sgs/libld/common/map.c +++ b/usr/src/cmd/sgs/libld/common/map.c @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -1123,8 +1123,8 @@ map_pipe(Ofl_desc *ofl, const char *mapfile, Sg_desc *sgp)  	sc_order->sco_secname = sec_name;  	sc_order->sco_index = ++index; -	if (alist_append(&(sgp->sg_secorder), &sc_order, -	    sizeof (Sec_order *), AL_CNT_SECORDER) == 0) +	if (aplist_append(&sgp->sg_secorder, sc_order, +	    AL_CNT_SG_SECORDER) == NULL)  		return (S_ERROR);  	DBG_CALL(Dbg_map_pipe(ofl->ofl_lml, sgp, sec_name, index)); @@ -2035,36 +2035,39 @@ map_version(const char *mapfile, char *name, Ofl_desc *ofl)  			if (filtee) {  				Dfltr_desc *	dftp;  				Sfltr_desc	sft; -				Aliste		off = 0, _off; +				Aliste		idx, _idx, nitems;  				/*  				 * Make sure we don't duplicate any filtee  				 * strings, and create a new descriptor if  				 * necessary.  				 */ -				for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, _off, +				idx = nitems = alist_nitems(ofl->ofl_dtsfltrs); +				for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, _idx,  				    dftp)) {  					if ((dftflag != dftp->dft_flag) ||  					    (strcmp(dftp->dft_str, filtee)))  						continue; -					off = _off; +					idx = _idx;  					break;  				} -				if (off == 0) { +				if (idx == nitems) {  					Dfltr_desc	dft;  					dft.dft_str = filtee;  					dft.dft_flag = dftflag;  					dft.dft_ndx = 0; -					if ((dftp = -					    alist_append(&(ofl->ofl_dtsfltrs), +					/* +					 * The following append puts the new +					 * item at the offset contained in +					 * idx, because we know idx contains +					 * the index of the next available slot. +					 */ +					if (alist_append(&ofl->ofl_dtsfltrs,  					    &dft, sizeof (Dfltr_desc), -					    AL_CNT_DFLTR)) == 0) +					    AL_CNT_OFL_DTSFLTRS) == NULL)  						return (S_ERROR); - -					off = (Aliste)((char *)dftp - -					    (char *)ofl->ofl_dtsfltrs);  				}  				/* @@ -2072,11 +2075,11 @@ map_version(const char *mapfile, char *name, Ofl_desc *ofl)  				 * symbol.  				 */  				sft.sft_sdp = sdp; -				sft.sft_off = off; +				sft.sft_idx = idx; -				if (alist_append(&(ofl->ofl_symfltrs), +				if (alist_append(&ofl->ofl_symfltrs,  				    &sft, sizeof (Sfltr_desc), -				    AL_CNT_SFLTR) == 0) +				    AL_CNT_OFL_SYMFLTRS) == NULL)  					return (S_ERROR);  			}  			break; diff --git a/usr/src/cmd/sgs/libld/common/order.c b/usr/src/cmd/sgs/libld/common/order.c index 1382ff4189..c9980434c9 100644 --- a/usr/src/cmd/sgs/libld/common/order.c +++ b/usr/src/cmd/sgs/libld/common/order.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -280,13 +280,11 @@ ld_sec_validate(Ofl_desc *ofl)  	int 		key = 1;  	for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { -		Sec_order	**scopp; -		Os_desc		**ospp; -		Aliste		off; - -		for (ALIST_TRAVERSE(sgp->sg_secorder, off, scopp)) { -			Sec_order	*scop = *scopp; +		Sec_order	*scop; +		Os_desc		*osp; +		Aliste		idx; +		for (APLIST_TRAVERSE(sgp->sg_secorder, idx, scop)) {  			if ((scop->sco_flags & FLG_SGO_USED) == 0) {  				eprintf(ofl->ofl_lml, ERR_WARNING,  				    MSG_INTL(MSG_MAP_SECORDER), @@ -296,10 +294,9 @@ ld_sec_validate(Ofl_desc *ofl)  		if ((sgp->sg_flags & FLG_SG_KEY) == 0)  			continue; -		for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { +		for (APLIST_TRAVERSE(sgp->sg_osdescs, idx, osp)) {  			Listnode	*lnp2;  			Is_desc		*isp; -			Os_desc		*osp = *ospp;  			if ((osp->os_flags & FLG_OS_ORDER_KEY) == 0)  				continue; @@ -428,14 +425,13 @@ ld_sort_ordered(Ofl_desc *ofl)  		 */  		if (st->st_ordercnt != 0)  			qsort((char *)st->st_order, st->st_ordercnt, -				sizeof (Is_desc *), comp); +			    sizeof (Is_desc *), comp);  		/*  		 * Place SHN_BEFORE at head of list  		 */  		for (i = 0; i < st->st_beforecnt; i++) { -			if (list_appendc(&(osp->os_isdescs), -			    st->st_before[i]) == 0) +			if (ld_append_isp(ofl, osp, st->st_before[i], 0) == 0)  				return (S_ERROR);  		} @@ -443,14 +439,17 @@ ld_sort_ordered(Ofl_desc *ofl)  		 * Next come 'linked' ordered sections  		 */  		for (i = 0; i < st->st_ordercnt; i++) { -			if (list_appendc(&(osp->os_isdescs), -			    st->st_order[i]) == 0) +			if (ld_append_isp(ofl, osp, st->st_order[i], 0) == 0)  				return (S_ERROR);  		}  		/*  		 * Now we list any sections which have no sorting  		 * specifications - in the order they were input. +		 * +		 * We use list_appendc() here instead of ld_append_isp(), +		 * because these items have already been inserted once, and +		 * we don't want any duplicate entries in osp->os_mstridescs.  		 */  		for (LIST_TRAVERSE(&islist, lnp2, isp)) {  			if (isp->is_flags & FLG_IS_ORDERED) @@ -464,8 +463,7 @@ ld_sort_ordered(Ofl_desc *ofl)  		 * And the end of the list are the SHN_AFTER sections.  		 */  		for (i = 0; i < st->st_aftercnt; i++) { -			if (list_appendc(&(osp->os_isdescs), -			    st->st_after[i]) == 0) +			if (ld_append_isp(ofl, osp, st->st_after[i], 0) == 0)  				return (S_ERROR);  		}  	} diff --git a/usr/src/cmd/sgs/libld/common/outfile.c b/usr/src/cmd/sgs/libld/common/outfile.c index 9332de698c..97e26c401b 100644 --- a/usr/src/cmd/sgs/libld/common/outfile.c +++ b/usr/src/cmd/sgs/libld/common/outfile.c @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -85,7 +85,7 @@ ld_open_outfile(Ofl_desc * ofl)  	 * are creating.  	 */  	mode = (ofl->ofl_flags & (FLG_OF_EXEC | FLG_OF_SHAROBJ)) -		? 0777 : 0666; +	    ? 0777 : 0666;  	/* Determine if the output file already exists */  	if (stat(ofl->ofl_name, &status) == 0) { @@ -142,8 +142,8 @@ ld_open_outfile(Ofl_desc * ofl)  				int err = errno;  				eprintf(ofl->ofl_lml, ERR_FATAL, -					MSG_INTL(MSG_SYS_UNLINK), -					ofl->ofl_name, strerror(err)); +				    MSG_INTL(MSG_SYS_UNLINK), +				    ofl->ofl_name, strerror(err));  				return (S_ERROR);  			}  		} @@ -215,8 +215,8 @@ pad_outfile(Ofl_desc *ofl)  	 */  	for (LIST_TRAVERSE(&ofl->ofl_segs, lnp, sgp)) {  		Phdr	*phdr = &(sgp->sg_phdr); -		Os_desc	**ospp, *osp; -		Aliste	off; +		Os_desc	*osp; +		Aliste	idx;  		/*  		 * If we've already processed a loadable segment, the `scn' @@ -251,11 +251,8 @@ pad_outfile(Ofl_desc *ofl)  		 * offset of each section. Retain the final section descriptor  		 * as this will be where any padding buffer will be added.  		 */ -		for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { -			Shdr	*shdr; - -			osp = *ospp; -			shdr = osp->os_shdr; +		for (APLIST_TRAVERSE(sgp->sg_osdescs, idx, osp)) { +			Shdr	*shdr = osp->os_shdr;  			offset = (off_t)S_ROUND(offset, shdr->sh_addralign);  			offset += shdr->sh_size; @@ -366,10 +363,10 @@ ld_create_outfile(Ofl_desc *ofl)  {  	Listnode	*lnp1;  	Sg_desc		*sgp; -	Os_desc		**ospp; +	Os_desc		*osp;  	Is_desc		*isp;  	Elf_Data	*tlsdata = 0; -	Aliste		off; +	Aliste		idx;  	Word		flags = ofl->ofl_flags;  	Word		flags1 = ofl->ofl_flags1;  	size_t		ndx = 0, fndx = 0; @@ -498,9 +495,8 @@ ld_create_outfile(Ofl_desc *ofl)  		}  		shidx = 0; -		for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { +		for (APLIST_TRAVERSE(sgp->sg_osdescs, idx, osp)) {  			Listnode	*lnp2; -			Os_desc		*osp = *ospp;  			dataidx = 0;  			for (LIST_TRAVERSE(&(osp->os_isdescs), lnp2, isp)) { @@ -531,11 +527,14 @@ ld_create_outfile(Ofl_desc *ofl)  					Lm_list	*lml = ofl->ofl_lml;  					if (ifl->ifl_flags & FLG_IF_IGNORE) { -					    isp->is_flags |= FLG_IS_DISCARD; -					    DBG_CALL(Dbg_unused_sec(lml, isp)); -					    continue; -					} else -					    DBG_CALL(Dbg_unused_sec(lml, isp)); +						isp->is_flags |= FLG_IS_DISCARD; +						DBG_CALL(Dbg_unused_sec(lml, +						    isp)); +						continue; +					} else { +						DBG_CALL(Dbg_unused_sec(lml, +						    isp)); +					}  				}  				/* @@ -743,13 +742,11 @@ ld_create_outfile(Ofl_desc *ofl)  	 */  	for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) {  		Phdr	*_phdr = &(sgp->sg_phdr); -		Os_desc	**ospp; -		Aliste	off; +		Os_desc	*osp; +		Aliste	idx;  		Boolean	recorded = FALSE; -		for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { -			Os_desc	*osp = *ospp; - +		for (APLIST_TRAVERSE(sgp->sg_osdescs, idx, osp)) {  			/*  			 * Make sure that an output section was originally  			 * created.  Input sections that had been marked as @@ -759,7 +756,7 @@ ld_create_outfile(Ofl_desc *ofl)  			 * have to compensate for this empty section.  			 */  			if (osp->os_scn == NULL) { -				(void) alist_delete(sgp->sg_osdescs, 0, &off); +				aplist_delete(sgp->sg_osdescs, &idx);  				continue;  			} diff --git a/usr/src/cmd/sgs/libld/common/place.c b/usr/src/cmd/sgs/libld/common/place.c index 13d7fed630..c7872d557b 100644 --- a/usr/src/cmd/sgs/libld/common/place.c +++ b/usr/src/cmd/sgs/libld/common/place.c @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -73,6 +73,79 @@ set_addralign(Ofl_desc *ofl, Os_desc *osp, Is_desc *isp)  }  /* + * Append an input section to an output section + * + * entry: + *	ofl - File descriptor + *	isp - Input section descriptor + *	osp - Output section descriptor + *	mstr_only - True if should only append to the merge string section + *		list. + * + * exit: + *	- If mstr_only is not true, the input section is appended to the + *		end of the output section's list of input sections (os_isdescs). + *	- If the input section is a candidate for string table merging, + *		then it is appended to the output section's list of merge + *		candidates (os_mstridescs). + * + *	On success, returns True (1). On failure, False (0). + */ +int +ld_append_isp(Ofl_desc * ofl, Os_desc *osp, Is_desc *isp, int mstr_only) +{ +	if (!mstr_only && (list_appendc(&(osp->os_isdescs), isp) == 0)) +		return (0); + +	/* +	 * To be mergeable: +	 *	- The SHF_MERGE|SHF_STRINGS flags must be set +	 *	- String table compression must not be disabled (-znocompstrtab) +	 *	- It must not be the generated section being built to +	 *		replace the sections on this list. +	 */ +	if (((isp->is_shdr->sh_flags & (SHF_MERGE | SHF_STRINGS)) != +	    (SHF_MERGE | SHF_STRINGS)) || +	    ((ofl->ofl_flags1 & FLG_OF1_NCSTTAB) != 0) || +	    ((isp->is_flags & FLG_IS_GNSTRMRG) != 0)) +		return (1); + +	/* +	 * Skip sections with (sh_entsize > 1) or (sh_addralign > 1). +	 * +	 * sh_entsize: +	 *	We are currently only able to merge string tables containing +	 *	strings with 1-byte (char) characters. Support for wide +	 *	characters will require our string table compression code +	 *	to be extended to handle larger character sizes. +	 * +	 * sh_addralign: +	 *	Alignments greater than 1 would require our string table +	 *	compression code to insert null bytes to move each +	 *	string to the required alignment. +	 */ +	if ((isp->is_shdr->sh_entsize > 1) || +	    (isp->is_shdr->sh_addralign > 1)) { +		DBG_CALL(Dbg_sec_unsup_strmerge(ofl->ofl_lml, isp)); +		return (1); +	} + +	if (aplist_append(&osp->os_mstrisdescs, isp, +	    AL_CNT_OS_MSTRISDESCS) == NULL) +		return (0); + +	/* +	 * The SHF_MERGE|SHF_STRINGS flags tell us that the program that +	 * created the section intended it to be mergeable. The +	 * FLG_IS_INSTRMRG flag says that we have done validity testing +	 * and decided that it is safe to act on that hint. +	 */ +	isp->is_flags |= FLG_IS_INSTRMRG; + +	return (1); +} + +/*   * Place a section into the appropriate segment.   */  Os_desc * @@ -81,8 +154,8 @@ ld_place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)  	Listnode *	lnp1, * lnp2;  	Ent_desc *	enp;  	Sg_desc	*	sgp; -	Os_desc		**ospp, *osp; -	Aliste		off1, off2; +	Os_desc		*osp; +	Aliste		idx1, idx2;  	int		os_ndx;  	Shdr *		shdr = isp->is_shdr;  	Xword		shflagmask, shflags = shdr->sh_flags; @@ -288,7 +361,7 @@ ld_place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)  		 */  		set_addralign(ofl, osp, isp); -		if (list_appendc(&(osp->os_isdescs), isp) == 0) +		if (ld_append_isp(ofl, osp, isp, 0) == 0)  			return ((Os_desc *)S_ERROR);  		isp->is_osdesc = osp; @@ -305,12 +378,10 @@ ld_place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)  	 */  	os_ndx = 0;  	if (sgp->sg_secorder) { -		Aliste		off; -		Sec_order	**scopp; - -		for (ALIST_TRAVERSE(sgp->sg_secorder, off, scopp)) { -			Sec_order	*scop = *scopp; +		Aliste		idx; +		Sec_order	*scop; +		for (APLIST_TRAVERSE(sgp->sg_secorder, idx, scop)) {  			if (strcmp(scop->sco_secname, isp->is_name) == 0) {  				scop->sco_flags |= FLG_SGO_USED;  				os_ndx = scop->sco_index; @@ -331,18 +402,15 @@ ld_place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)  	 * flags that do not prevent a merge.  	 */  	shflagmask = (ofl->ofl_flags & FLG_OF_RELOBJ) -		? ALL_SHF_ORDER : ALL_SHF_IGNORE; +	    ? ALL_SHF_ORDER : ALL_SHF_IGNORE;  	/*  	 * Traverse the input section list for the output section we have been  	 * assigned. If we find a matching section simply add this new section.  	 */ -	off2 = 0; -	for (ALIST_TRAVERSE(sgp->sg_osdescs, off1, ospp)) { -		Shdr	*_shdr; - -		osp = *ospp; -		_shdr = osp->os_shdr; +	idx2 = 0; +	for (APLIST_TRAVERSE(sgp->sg_osdescs, idx1, osp)) { +		Shdr	*_shdr = osp->os_shdr;  		if ((ident == osp->os_scnsymndx) && (ident != M_ID_REL) &&  		    (isp->is_namehash == osp->os_namehash) && @@ -416,9 +484,12 @@ ld_place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)  					    isp) == 0)  						return ((Os_desc *)S_ERROR);  				} -			} else +			} else {  				if (list_appendc(&(osp->os_isdescs), isp) == 0)  					return ((Os_desc *)S_ERROR); +			} +			if (ld_append_isp(ofl, osp, isp, 1) == 0) +				return ((Os_desc *)S_ERROR);  			isp->is_osdesc = osp; @@ -452,7 +523,7 @@ ld_place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)  					/* insert section here. */  					break;  				else { -					off2 = off1; +					idx2 = idx1 + 1;  					continue;  				}  			} else { @@ -460,7 +531,7 @@ ld_place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)  				break;  			}  		} else if (osp->os_txtndx) { -			off2 = off1; +			idx2 = idx1 + 1;  			continue;  		} @@ -472,7 +543,7 @@ ld_place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)  		if (ident < osp->os_scnsymndx)  			break; -		off2 = off1; +		idx2 = idx1 + 1;  	}  	/* @@ -595,27 +666,21 @@ ld_place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)  	 */  	set_addralign(ofl, osp, isp); -	if (list_appendc(&(osp->os_isdescs), isp) == 0) +	if (ld_append_isp(ofl, osp, isp, 0) == 0)  		return ((Os_desc *)S_ERROR);  	DBG_CALL(Dbg_sec_created(ofl->ofl_lml, osp, sgp));  	isp->is_osdesc = osp; -	if (off2) { -		/* -		 * Insert the new section after the section identified by off2. -		 */ -		off2 += sizeof (Os_desc *); -		if (alist_insert(&(sgp->sg_osdescs), &osp, -		    sizeof (Os_desc *), AL_CNT_OSDESC, off2) == 0) -			return ((Os_desc *)S_ERROR); -	} else { -		/* -		 * Prepend this section to the section list. -		 */ -		if (alist_insert(&(sgp->sg_osdescs), &osp, -		    sizeof (Os_desc *), AL_CNT_OSDESC, ALO_DATA) == 0) -			return ((Os_desc *)S_ERROR); -	} +	/* +	 * Insert the new section at the offset given by idx2. If no +	 * position for it was identified above, this will be index 0, +	 * causing the new section to be prepended to the beginning of +	 * the section list. Otherwise, it is the index following the section +	 * that was identified. +	 */ +	if (aplist_insert(&sgp->sg_osdescs, osp, AL_CNT_SG_OSDESC, +	    idx2) == NULL) +		return ((Os_desc *)S_ERROR);  	return (osp);  } diff --git a/usr/src/cmd/sgs/libld/common/relocate.c b/usr/src/cmd/sgs/libld/common/relocate.c index 5973d007f3..9fb0bb7a2e 100644 --- a/usr/src/cmd/sgs/libld/common/relocate.c +++ b/usr/src/cmd/sgs/libld/common/relocate.c @@ -285,7 +285,8 @@ disp_scansyms(Ifl_desc * ifl, Rel_desc *rld, Boolean rlocal, int inspect,  	 * if the reference symbol is included in the target symbol.  	 */  	value = rsym->st_value; -	value += rld->rel_raddend; +	if ((rld->rel_flags & FLG_REL_RELA) == FLG_REL_RELA) +		value += rld->rel_raddend;  	if ((rld->rel_roffset >= value) &&  	    (rld->rel_roffset < (value + rsym->st_size))) @@ -1472,6 +1473,71 @@ sloppy_comdat_reloc(Ofl_desc *ofl, Rel_desc *reld, Sym_desc *sdp)  	return (NULL);  } + +/* + * Generate a name for a relocation descriptor that has an STT_SECTION + * symbol associated with it. If it is a regular input section, it will + * look like: + * + *	"XXX (section)" + * + * If it is a generated section created to receive the strings from + * input SHF_MERGE|SHF_STRINGS sections, then it will look like: + * + *	"XXX (merged string section)" + * + * STT_SECTION relocations to the same section tend to come in clusters, + * so we use a static variable to retain the last string we generate. If + * another one comes along for the same section before some other section + * intervenes, we will reuse the string. + * + * entry: + *	sdp - STT_SECTION symbol for which a relocation descriptor name + *		should be generated. + *	sd_isc - NULL, or input section that should be used instead of + *		the input section already assocated with the symbol + *		(sdp->sd_isc). This value is set to a non-NULL value when + *		a transition from the old input section to a new one is + *		being made, but the symbol has not yet been updated. + */ +const const char * +ld_section_reld_name(Sym_desc *sdp, Is_desc *sd_isc) +{ +	static Is_desc	*last_sd_isc = NULL; +	static char	*namestr; + +	const char	*fmt; +	size_t		len; + +	/* +	 * If caller didn't supply a replacement input section, +	 * use the one referenced by the symbol. +	 */ +	if (sd_isc == NULL) +		sd_isc = sdp->sd_isc; + +	if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) && +	    (sd_isc != NULL) && (sd_isc->is_name != NULL)) { +		if (last_sd_isc != sd_isc) { +			fmt = (sd_isc->is_flags & FLG_IS_GNSTRMRG) ? +			    MSG_INTL(MSG_STR_SECTION_MSTR) : +			    MSG_INTL(MSG_STR_SECTION); +			len = strlen(fmt) + +			    strlen(sd_isc->is_name) + 1; + +			if ((namestr = libld_malloc(len)) == 0) +				return (NULL); +			(void) snprintf(namestr, len, fmt, +			    sd_isc->is_name); +			last_sd_isc = sd_isc;	/* Remember for next time */ +		} +		return (namestr); +	} + +	return (NULL); +} + +  /*   * Generate relocation descriptor and dispatch   */ @@ -1511,15 +1577,24 @@ process_reld(Ofl_desc *ofl, Is_desc *isp, Rel_desc *reld, Word rsndx,  	}  	/* -	 * Determine whether we're dealing with a named symbol.  Note, bogus -	 * relocations can result in a null symbol descriptor (sdp), the error -	 * condition should be caught below after determining whether a valid -	 * symbol name exists. +	 * Come up with a descriptive name for the symbol: +	 *	- If it is a named symbol, use the name as is +	 *	- If it is an STT_SECTION symbol, generate a descriptive +	 *		string that incorporates the section name. +	 *	- Otherwise, supply an "unknown" string. +	 * Note that bogus relocations can result in a null symbol descriptor +	 * (sdp), the error condition should be caught below after determining +	 * whether a valid symbol name exists.  	 */  	sdp = ifl->ifl_oldndx[rsndx]; -	if (sdp != NULL && sdp->sd_name && *sdp->sd_name) +	if ((sdp != NULL) && sdp->sd_name && *sdp->sd_name) {  		reld->rel_sname = sdp->sd_name; -	else { +	} else if ((sdp != NULL) && +	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) && +	    (sdp->sd_isc != NULL) && (sdp->sd_isc->is_name != NULL)) { +		if ((reld->rel_sname = ld_section_reld_name(sdp, NULL)) == NULL) +			return (S_ERROR); +	} else {  		static char *strunknown;  		if (strunknown == 0) @@ -1724,16 +1799,15 @@ reloc_segments(int wr_flag, Ofl_desc *ofl)  	Is_desc		*isp;  	for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { -		Os_desc	**ospp; -		Aliste	off; +		Os_desc	*osp; +		Aliste	idx;  		if ((sgp->sg_phdr.p_flags & PF_W) != wr_flag)  			continue; -		for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { +		for (APLIST_TRAVERSE(sgp->sg_osdescs, idx, osp)) {  			Is_desc		*risp;  			Listnode	*lnp3; -			Os_desc		*osp = *ospp;  			osp->os_szoutrels = 0;  			for (LIST_TRAVERSE(&(osp->os_relisdescs), lnp3, risp)) { @@ -2172,7 +2246,7 @@ do_sorted_outrelocs(Ofl_desc *ofl)  /*   * Process relocations.  Finds every input relocation section for each output - * section and invokes reloc_sec() to relocate that section. + * section and invokes reloc_section() to relocate that section.   */  uintptr_t  ld_reloc_process(Ofl_desc *ofl) @@ -2222,12 +2296,10 @@ ld_reloc_process(Ofl_desc *ofl)  		 *	which the relocation must be applied (sh_info).  		 */  		for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { -			Os_desc **ospp; -			Aliste	off; - -			for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { -				osp = *ospp; +			Os_desc *osp; +			Aliste	idx; +			for (APLIST_TRAVERSE(sgp->sg_osdescs, idx, osp)) {  				if (osp->os_relosdesc == 0)  					continue; @@ -2518,6 +2590,115 @@ ld_am_I_partial(Rel_desc *reld, Xword val)  	return ((Sym_desc *) 0);  } + +/* + * Obtain the current value at the given relocation target. + * + * entry: + *	ofl - Output file descriptor + *	rsp - Relocation record + *	data - Pointer to relocation target + *	value - Address of variable to recieve value + * + * exit: + *	The value of the data at the relocation target has + *	been stored in value. + */ +int +ld_reloc_targval_get(Ofl_desc *ofl, Rel_desc *rsp, uchar_t *data, Xword *value) +{ +	const Rel_entry	*rep; + +	/* We do not currently support running as a cross linker */ +	if (OFL_SWAP_RELOC_DATA(ofl, rsp)) { +		REL_ERR_NOSWAP(ofl->ofl_lml, +		    rsp->rel_isdesc->is_file->ifl_name, rsp->rel_sname, +		    rsp->rel_rtype); +		return (0); +	} + +	rep = &reloc_table[rsp->rel_rtype]; + +	switch (rep->re_fsize) { +	case 1: +		/* LINTED */ +		*value = (Xword) *((uchar_t *)data); +		break; +	case 2: +		/* LINTED */ +		*value = (Xword) *((Half *)data); +		break; +	case 4: +		/* LINTED */ +		*value = *((Xword *)data); +		break; +	default: +		/* +		 * To keep chkmsg() happy: MSG_INTL(MSG_REL_UNSUPSZ) +		 */ +		REL_ERR_UNSUPSZ(ofl->ofl_lml, +		    rsp->rel_isdesc->is_file->ifl_name, rsp->rel_sname, +		    rsp->rel_rtype, rep->re_fsize); +		return (0); +	} +	return (1); +} + + +/* + * Set the value at the given relocation target. + * + * entry: + *	ofl - Output file descriptor + *	rsp - Relocation record + *	data - Pointer to relocation target + *	value - Address of variable to recieve value + * + * exit: + *	The value of the data at the relocation target has + *	been stored in value. + */ +int +ld_reloc_targval_set(Ofl_desc *ofl, Rel_desc *rsp, uchar_t *data, Xword value) +{ +	const Rel_entry	*rep; + +	/* We do not currently support running as a cross linker */ +	if (OFL_SWAP_RELOC_DATA(ofl, rsp)) { +		REL_ERR_NOSWAP(ofl->ofl_lml, +		    rsp->rel_isdesc->is_file->ifl_name, rsp->rel_sname, +		    rsp->rel_rtype); +		return (0); +	} + +	rep = &reloc_table[rsp->rel_rtype]; + +	switch (rep->re_fsize) { +	case 1: +		/* LINTED */ +		*((uchar_t *)data) = (uchar_t)value; +		break; +	case 2: +		/* LINTED */ +		*((Half *)data) = (Half)value; +		break; +	case 4: +		/* LINTED */ +		*((Xword *)data) = value; +		break; +	default: +		/* +		 * To keep chkmsg() happy: MSG_INTL(MSG_REL_UNSUPSZ) +		 */ +		REL_ERR_UNSUPSZ(ofl->ofl_lml, +		    rsp->rel_isdesc->is_file->ifl_name, rsp->rel_sname, +		    rsp->rel_rtype, rep->re_fsize); +		return (0); +	} +	return (1); +} + +  /*   * Because of the combinations of 32-bit lib providing 64-bit support, and   * visa-versa, the use of krtld's dorelocs can result in differing message diff --git a/usr/src/cmd/sgs/libld/common/sections.c b/usr/src/cmd/sgs/libld/common/sections.c index c47bf723bb..90b64cd870 100644 --- a/usr/src/cmd/sgs/libld/common/sections.c +++ b/usr/src/cmd/sgs/libld/common/sections.c @@ -330,7 +330,7 @@ ignore_section_processing(Ofl_desc *ofl)   * exit:   *	On error, returns S_ERROR. On success, returns (1), and the   *	ret_ pointers have been updated to point at the new structures, - *	which has been filled in. To finish the task, the caller must + *	which have been filled in. To finish the task, the caller must   *	update any fields within the supplied descriptors that differ   *	from its needs, and then call ld_place_section().   */ @@ -544,6 +544,69 @@ new_section(Ofl_desc *ofl, Word shtype, const char *shname, Xword entcnt,  }  /* + * Use an existing input section as a template to create a new + * input section with the same values as the original, other than + * the size of the data area which is supplied by the caller. + * + * entry: + *	ofl - Output file descriptor + *	ifl - Input file section to use as a template + *	size - Size of data area for new section + *	ret_isec, ret_shdr, ret_data - Address of pointers to + *		receive address of newly allocated structs. + * + * exit: + *	On error, returns S_ERROR. On success, returns (1), and the + *	ret_ pointers have been updated to point at the new structures, + *	which have been filled in. To finish the task, the caller must + *	update any fields within the supplied descriptors that differ + *	from its needs, and then call ld_place_section(). + */ +static uintptr_t +new_section_from_template(Ofl_desc *ofl, Is_desc *tmpl_isp, size_t size, +	Is_desc **ret_isec, Shdr **ret_shdr, Elf_Data **ret_data) +{ +	Shdr		*shdr; +	Elf_Data	*data; +	Is_desc		*isec; + +	/* +	 * Allocate and initialize the Elf_Data structure. +	 */ +	if ((data = libld_calloc(sizeof (Elf_Data), 1)) == 0) +		return (S_ERROR); +	data->d_type = tmpl_isp->is_indata->d_type; +	data->d_size = size; +	data->d_align = tmpl_isp->is_shdr->sh_addralign; +	data->d_version = ofl->ofl_dehdr->e_version; + +	/* +	 * Allocate and initialize the Shdr structure. +	 */ +	if ((shdr = libld_malloc(sizeof (Shdr))) == 0) +		return (S_ERROR); +	*shdr = *tmpl_isp->is_shdr; +	shdr->sh_addr = 0; +	shdr->sh_offset = 0; +	shdr->sh_size = size; + +	/* +	 * Allocate and initialize the Is_desc structure. +	 */ +	if ((isec = libld_calloc(1, sizeof (Is_desc))) == 0) +		return (S_ERROR); +	isec->is_name = tmpl_isp->is_name; +	isec->is_shdr = shdr; +	isec->is_indata = data; + + +	*ret_isec = isec; +	*ret_shdr = shdr; +	*ret_data = data; +	return (1); +} + +/*   * Build a .bss section for allocation of tentative definitions.  Any `static'   * .bss definitions would have been associated to their own .bss sections and   * thus collected from the input files.  `global' .bss definitions are tagged @@ -836,14 +899,7 @@ make_dynamic(Ofl_desc *ofl)  	/*  	 * Reserve entries for any per-symbol auxiliary/filter strings.  	 */ -	if (ofl->ofl_dtsfltrs) { -		/* LINTED */ -		Dfltr_desc *	dftp; -		Aliste		off; - -		for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, off, dftp)) -			cnt++; -	} +	cnt += alist_nitems(ofl->ofl_dtsfltrs);  	/*  	 * Reserve entries for any _init() and _fini() section addresses. @@ -1693,11 +1749,11 @@ make_dynstr(Ofl_desc *ofl)  	/*  	 * Reserve entries for any per-symbol auxiliary/filter strings.  	 */ -	if (ofl->ofl_dtsfltrs) { -		Dfltr_desc *	dftp; -		Aliste		off; +	if (ofl->ofl_dtsfltrs != NULL) { +		Dfltr_desc	*dftp; +		Aliste		idx; -		for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, off, dftp)) +		for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, idx, dftp))  			if (st_insert(ofl->ofl_dynstrtab, dftp->dft_str) == -1)  				return (S_ERROR);  	} @@ -2062,6 +2118,405 @@ ld_make_sunwmove(Ofl_desc *ofl, int mv_nums)  /* + * Given a relocation descriptor that references a string table + * input section, locate the string referenced and return a pointer + * to it. + */ +static const char * +strmerge_get_reloc_str(Ofl_desc *ofl, Rel_desc *rsp) +{ +	Sym_desc *sdp = rsp->rel_sym; +	Xword	 str_off; + +	/* +	 * In the case of an STT_SECTION symbol, the addend of the +	 * relocation gives the offset into the string section. For +	 * other symbol types, the symbol value is the offset. +	 */ + +	if (ELF_ST_TYPE(sdp->sd_sym->st_info) != STT_SECTION) { +		str_off = sdp->sd_sym->st_value; +	} else if ((rsp->rel_flags & FLG_REL_RELA) == FLG_REL_RELA) { +		/* +		 * For SHT_RELA, the addend value is found in the +		 * rel_raddend field of the relocation. +		 */ +		str_off = rsp->rel_raddend; +	} else {	/* REL and STT_SECTION */ +		/* +		 * For SHT_REL, the "addend" is not part of the relocation +		 * record. Instead, it is found at the relocation target +		 * address. +		 */ +		uchar_t *addr = (uchar_t *)((uintptr_t)rsp->rel_roffset + +		    (uintptr_t)rsp->rel_isdesc->is_indata->d_buf); + +		if (ld_reloc_targval_get(ofl, rsp, addr, &str_off) == 0) +			return (0); +	} + +	return (str_off + (char *)sdp->sd_isc->is_indata->d_buf); +} + +/* + * First pass over the relocation records for string table merging. + * Build lists of relocations and symbols that will need modification, + * and insert the strings they reference into the mstrtab string table. + * + * entry: + *	ofl, osp - As passed to ld_make_strmerge(). + *	mstrtab - String table to receive input strings. This table + *		must be in its first (initialization) pass and not + *		yet cooked (st_getstrtab_sz() not yet called). + *	rel_aplist - APlist to receive pointer to any relocation + *		descriptors with STT_SECTION symbols that reference + *		one of the input sections being merged. + *	sym_aplist - APlist to receive pointer to any symbols that reference + *		one of the input sections being merged. + *	reloc_list - List of relocation descriptors to examine. + *		Either ofl->&ofl->ofl_actrels (active relocations) + *		or &ofl->ofl_outrels (output relocations). + * + * exit: + *	On success, rel_aplist and sym_aplist are updated, and + *	any strings in the mergable input sections referenced by + *	a relocation has been entered into mstrtab. True (1) is returned. + * + *	On failure, False (0) is returned. + */ +static int +strmerge_pass1(Ofl_desc *ofl, Os_desc *osp, Str_tbl *mstrtab, +    APlist **rel_aplist, APlist **sym_aplist, List *reloc_list) +{ +	Listnode	*lnp; +	Rel_cache	*rcp; +	Sym_desc	*sdp; +	Sym_desc	*last_sdp = NULL; +	Rel_desc	*rsp; +	const char	*name; + +	for (LIST_TRAVERSE(reloc_list, lnp, rcp)) { +		/* LINTED */ +		for (rsp = (Rel_desc *)(rcp + 1); rsp < rcp->rc_free; rsp++) { +			sdp = rsp->rel_sym; +			if ((sdp->sd_isc == NULL) || +			    ((sdp->sd_isc->is_flags & +			    (FLG_IS_DISCARD | FLG_IS_INSTRMRG)) != +			    FLG_IS_INSTRMRG) || +			    (sdp->sd_isc->is_osdesc != osp)) +				continue; + +			/* +			 * Remember symbol for use in the third pass. +			 * There is no reason to save a given symbol more +			 * than once, so we take advantage of the fact that +			 * relocations to a given symbol tend to cluster +			 * in the list. If this is the same symbol we saved +			 * last time, don't bother. +			 */ +			if (last_sdp != sdp) { +				if (aplist_append(sym_aplist, sdp, +				    AL_CNT_STRMRGSYM) == 0) +					return (0); +				last_sdp = sdp; +			} + +			/* Enter the string into our new string table */ +			name = strmerge_get_reloc_str(ofl, rsp); +			if (st_insert(mstrtab, name) == -1) +				return (0); + +			/* +			 * If this is an STT_SECTION symbol, then the +			 * second pass will need to modify this relocation, +			 * so hang on to it. +			 */ +			if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == +			    STT_SECTION) && +			    (aplist_append(rel_aplist, rsp, +			    AL_CNT_STRMRGREL) == 0)) +				return (0); +		} +	} + +	return (1); +} + +/* + * If the output section has any SHF_MERGE|SHF_STRINGS input sections, + * replace them with a single merged/compressed input section. + * + * entry: + *	ofl - Output file descriptor + *	osp - Output section descriptor + *	rel_aplist, sym_aplist, - Address of 2 APlists, to be used + *		for internal processing. On the initial call to + *		ld_make_strmerge, these list pointers must be NULL. + *		The caller is encouraged to pass the same lists back for + *		successive calls to this function without freeing + *		them in between calls. This causes a single pair of + *		memory allocations to be reused multiple times. + * + * exit: + *	If section merging is possible, it is done. If no errors are + *	encountered, True (1) is returned. On error, S_ERROR. + * + *	The contents of rel_aplist and sym_aplist on exit are + *	undefined. The caller can free them, or pass them back to a subsequent + *	call to this routine, but should not examine their contents. + */ +static uintptr_t +ld_make_strmerge(Ofl_desc *ofl, Os_desc *osp, APlist **rel_aplist, +    APlist **sym_aplist) +{ +	Str_tbl		*mstrtab;	/* string table for string merge secs */ +	Is_desc		*mstrsec;	/* Generated string merge section */ +	Is_desc		*isp; +	Shdr		*mstr_shdr; +	Elf_Data	*mstr_data; +	Sym_desc	*sdp; +	Rel_desc	*rsp; +	Aliste		idx; +	size_t		data_size; +	int		st_setstring_status; +	size_t		stoff; + +	/* If string table compression is disabled, there's nothing to do */ +	if ((ofl->ofl_flags1 & FLG_OF1_NCSTTAB) != 0) +		return (1); + +	/* +	 * Pass over the mergeable input sections, and if they haven't +	 * all been discarded, create a string table. +	 */ +	mstrtab = NULL; +	for (APLIST_TRAVERSE(osp->os_mstrisdescs, idx, isp)) { +		if (isp->is_flags & FLG_IS_DISCARD) +			continue; + +		/* +		 * We have at least one non-discarded section. +		 * Create a string table descriptor. +		 */ +		if ((mstrtab = st_new(FLG_STNEW_COMPRESS)) == NULL) +			return (S_ERROR); +		break; +	} + +	/* If no string table was created, we have no mergeable sections */ +	if (mstrtab == NULL) +		return (1); + +	/* +	 * This routine has to make 3 passes: +	 * +	 *	1) Examine all relocations, insert strings from relocations +	 *		to the mergable input sections into the string table. +	 *	2) Modify the relocation values to be correct for the +	 *		new merged section. +	 *	3) Modify the symbols used by the relocations to reference +	 *		the new section. +	 * +	 * These passes cannot be combined: +	 *	- The string table code works in two passes, and all +	 *		strings have to be loaded in pass one before the +	 *		offset of any strings can be determined. +	 *	- Multiple relocations reference a single symbol, so the +	 *		symbol cannot be modified until all relocations are +	 *		fixed. +	 * +	 * The number of relocations related to section merging is usually +	 * a mere fraction of the overall active and output relocation lists, +	 * and the number of symbols is usually a fraction of the number +	 * of related relocations. We therefore build APlists for the +	 * relocations and symbols in the first pass, and then use those +	 * lists to accelerate the operation of pass 2 and 3. +	 * +	 * Reinitialize the lists to a completely empty state. +	 */ +	aplist_reset(*rel_aplist); +	aplist_reset(*sym_aplist); + +	/* +	 * Pass 1: +	 * +	 * Every relocation related to this output section (and the input +	 * sections that make it up) is found in either the active, or the +	 * output relocation list, depending on whether the relocation is to +	 * be processed by this invocation of the linker, or inserted into the +	 * output object. +	 * +	 * Build lists of relocations and symbols that will need modification, +	 * and insert the strings they reference into the mstrtab string table. +	 */ +	if (strmerge_pass1(ofl, osp, mstrtab, rel_aplist, sym_aplist, +	    &ofl->ofl_actrels) == 0) +		goto return_s_error; +	if (strmerge_pass1(ofl, osp, mstrtab, rel_aplist, sym_aplist, +	    &ofl->ofl_outrels) == 0) +		goto return_s_error; + +	/* +	 * Get the size of the new input section. Requesting the +	 * string table size "cooks" the table, and finalizes its contents. +	 */ +	data_size = st_getstrtab_sz(mstrtab); + +	/* Create a new input section to hold the merged strings */ +	if (new_section_from_template(ofl, isp, data_size, +	    &mstrsec, &mstr_shdr, &mstr_data) == S_ERROR) +		goto return_s_error; +	mstrsec->is_flags |= FLG_IS_GNSTRMRG; + +	/* +	 * Allocate a data buffer for the new input section. +	 * Then, associate the buffer with the string table descriptor. +	 */ +	if ((mstr_data->d_buf = libld_malloc(data_size)) == 0) +		goto return_s_error; +	if (st_setstrbuf(mstrtab, mstr_data->d_buf, data_size) == -1) +		goto return_s_error; + +	/* Add the new section to the output image */ +	if (ld_place_section(ofl, mstrsec, osp->os_scnsymndx, 0) == +	    (Os_desc *)S_ERROR) +		goto return_s_error; + +	/* +	 * Pass 2: +	 * +	 * Revisit the relocation descriptors with STT_SECTION symbols +	 * that were saved by the first pass. Update each relocation +	 * record so that the offset it contains is for the new section +	 * instead of the original. +	 */ +	for (APLIST_TRAVERSE(*rel_aplist, idx, rsp)) { +		const char	*name; + +		/* Put the string into the merged string table */ +		name = strmerge_get_reloc_str(ofl, rsp); +		st_setstring_status = st_setstring(mstrtab, name, &stoff); +		if (st_setstring_status == -1) { +			/* +			 * A failure to insert at this point means that +			 * something is corrupt. This isn't a resource issue. +			 */ +			assert(st_setstring_status != -1); +			goto return_s_error; +		} + +		/* +		 * Alter the relocation to access the string at the +		 * new offset in our new string table. +		 * +		 * For SHT_RELA platforms, it suffices to simply +		 * update the rel_raddend field of the relocation. +		 * +		 * For SHT_REL platforms, the new "addend" value +		 * needs to be written at the address being relocated. +		 * However, we can't alter the input sections which +		 * are mapped readonly, and the output image has not +		 * been created yet. So, we defer this operation, +		 * using the rel_raddend field of the relocation +		 * which is normally 0 on a REL platform, to pass the +		 * new "addend" value to ld_perform_outreloc() or +		 * ld_do_activerelocs(). The FLG_REL_NADDEND flag +		 * tells them that this is the case. +		 */ +		if ((rsp->rel_flags & FLG_REL_RELA) == 0)   /* REL */ +			rsp->rel_flags |= FLG_REL_NADDEND; +		rsp->rel_raddend = (Sxword)stoff; + +		/* +		 * Change the descriptor name to reflect the fact that it +		 * points at our merged section. This shows up in debug +		 * output and helps show how the relocation has changed +		 * from its original input section to our merged one. +		 */ +		rsp->rel_sname = ld_section_reld_name(rsp->rel_sym, mstrsec); +		if (rsp->rel_sname == NULL) +			goto return_s_error; +	} + +	/* +	 * Pass 3: +	 * +	 * Modify the symbols referenced by the relocation descriptors +	 * so that they reference the new input section containing the +	 * merged strings instead of the original input sections. +	 */ +	for (APLIST_TRAVERSE(*sym_aplist, idx, sdp)) { +		/* +		 * If we've already processed this symbol, don't do it +		 * twice. strmerge_pass1() uses a heuristic (relocations to +		 * the same symbol clump together) to avoid inserting a +		 * given symbol more than once, but repeat symbols in +		 * the list can occur. +		 */ +		if ((sdp->sd_isc->is_flags & FLG_IS_INSTRMRG) == 0) +			continue; + +		if (ELF_ST_TYPE(sdp->sd_sym->st_info) != STT_SECTION) { +			/* +			 * This is not an STT_SECTION symbol, so its +			 * value is the offset of the string within the +			 * input section. Update the address to reflect +			 * the address in our new merged section. +			 */ +			const char *name = sdp->sd_sym->st_value + +			    (char *)sdp->sd_isc->is_indata->d_buf; + +			st_setstring_status = +			    st_setstring(mstrtab, name, &stoff); +			if (st_setstring_status == -1) { +				/* +				 * A failure to insert at this point means +				 * something is corrupt. This isn't a +				 * resource issue. +				 */ +				assert(st_setstring_status != -1); +				goto return_s_error; +			} + +			if (ld_sym_copy(sdp) == S_ERROR) +				goto return_s_error; +			sdp->sd_sym->st_value = (Word)stoff; +		} + +		/* Redirect the symbol to our new merged section */ +		sdp->sd_isc = mstrsec; +	} + +	/* +	 * There are no references left to the original input string sections. +	 * Mark them as discarded so they don't go into the output image. +	 * At the same time, add up the sizes of the replaced sections. +	 */ +	data_size = 0; +	for (APLIST_TRAVERSE(osp->os_mstrisdescs, idx, isp)) { +		if (isp->is_flags & (FLG_IS_DISCARD | FLG_IS_GNSTRMRG)) +			continue; + +		data_size += isp->is_indata->d_size; + +		isp->is_flags |= FLG_IS_DISCARD; +		DBG_CALL(Dbg_sec_discarded(ofl->ofl_lml, isp, mstrsec)); +	} + +	/* Report how much space we saved in the output section */ +	Dbg_sec_genstr_compress(ofl->ofl_lml, osp->os_name, data_size, +	    mstr_data->d_size); + +	st_destroy(mstrtab); +	return (1); + +return_s_error: +	st_destroy(mstrtab); +	return (S_ERROR); +} + + +/*   * The following sections are built after all input file processing and symbol   * validation has been carried out.  The order is important (because the   * addition of a section adds a new symbol there is a chicken and egg problem @@ -2121,6 +2576,44 @@ ld_make_sections(Ofl_desc *ofl)  	}  	/* +	 * Do any of the output sections contain input sections that +	 * are candidates for string table merging? For each such case, +	 * we create a replacement section, insert it, and discard the +	 * originals. +	 * +	 * rel_aplist and sym_aplist are used by ld_make_strmerge() +	 * for its internal processing. We are responsible for the +	 * initialization and cleanup, and ld_make_strmerge() handles the rest. +	 * This allows us to reuse a single pair of memory buffers allocatated +	 * for this processing for all the output sections. +	 */ +	if ((ofl->ofl_flags1 & FLG_OF1_NCSTTAB) == 0) { +		int error_seen = 0; +		APlist *rel_aplist = NULL; +		APlist *sym_aplist = NULL; + +		for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { +			Os_desc	*osp; +			Aliste	idx; + +			for (APLIST_TRAVERSE(sgp->sg_osdescs, idx, osp)) +				if ((osp->os_mstrisdescs != NULL) && +				    (ld_make_strmerge(ofl, osp, +				    &rel_aplist, &sym_aplist) == +				    S_ERROR)) { +					error_seen = 1; +					break; +				} +		} +		if (rel_aplist != NULL) +			free(rel_aplist); +		if (sym_aplist != NULL) +			free(sym_aplist); +		if (error_seen != 0) +			return (S_ERROR); +	} + +	/*  	 * Add any necessary versioning information.  	 */  	if ((flags & (FLG_OF_VERNEED | FLG_OF_NOVERSEC)) == FLG_OF_VERNEED) { @@ -2165,12 +2658,10 @@ ld_make_sections(Ofl_desc *ofl)  		 * insuring that this pointer isn't re-examined.  		 */  		for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { -			Os_desc	**ospp, *posp = 0; -			Aliste	off; - -			for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { -				Os_desc	*osp = *ospp; +			Os_desc	*osp, *posp = 0; +			Aliste	idx; +			for (APLIST_TRAVERSE(sgp->sg_osdescs, idx, osp)) {  				if ((osp != posp) && osp->os_szoutrels &&  				    (osp != ofl->ofl_osplt)) {  					if (make_reloc(ofl, osp) == S_ERROR) diff --git a/usr/src/cmd/sgs/libld/common/update.c b/usr/src/cmd/sgs/libld/common/update.c index 0492e61b4a..912e9cbdb2 100644 --- a/usr/src/cmd/sgs/libld/common/update.c +++ b/usr/src/cmd/sgs/libld/common/update.c @@ -222,7 +222,7 @@ update_osym(Ofl_desc *ofl)  	Sym_s_list	*sorted_syms;	/* table to hold sorted symbols */  	Word		ssndx;		/* global index into sorted_syms */  	Word		scndx;		/* scoped index into sorted_syms */ -	uint_t		stoff;		/* string offset */ +	size_t		stoff;		/* string offset */  	/*  	 * Initialize pointers to the symbol table entries and the symbol @@ -375,8 +375,8 @@ update_osym(Ofl_desc *ofl)  	 */  	for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) {  		Phdr	*phd = &(sgp->sg_phdr); -		Os_desc	**ospp; -		Aliste	off; +		Os_desc	*osp; +		Aliste	idx;  		if (phd->p_type == PT_LOAD) {  			if (sgp->sg_osdescs != NULL) { @@ -393,11 +393,9 @@ update_osym(Ofl_desc *ofl)  		/*  		 * Generate a section symbol for each output section.  		 */ -		for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { +		for (APLIST_TRAVERSE(sgp->sg_osdescs, idx, osp)) {  			Word	sectndx; -			osp = *ospp; -  			sym = &_sym;  			sym->st_value = osp->os_shdr->sh_addr;  			sym->st_info = ELF_ST_INFO(STB_LOCAL, STT_SECTION); @@ -572,17 +570,14 @@ update_osym(Ofl_desc *ofl)  			 * it as an absolute.  			 */  			if (sgp->sg_osdescs != NULL) { -				Os_desc	**ospp; -				Alist	*alp = sgp->sg_osdescs; -				Aliste	last = alp->al_next - alp->al_size; -  				/*  				 * Determine the last section for this segment.  				 */ +				Os_desc	*osp = sgp->sg_osdescs->apl_data +				    [sgp->sg_osdescs->apl_nitems - 1]; +  				/* LINTED */ -				ospp = (Os_desc **)((char *)alp + last); -				/* LINTED */ -				end_ndx = elf_ndxscn((*ospp)->os_scn); +				end_ndx = elf_ndxscn(osp->os_scn);  			} else {  				end_ndx = SHN_ABS;  				end_abs = 1; @@ -1971,7 +1966,7 @@ update_odynamic(Ofl_desc *ofl)  	Dyn		*_dyn = (Dyn *)ofl->ofl_osdynamic->os_outdata->d_buf;  	Dyn		*dyn;  	Str_tbl		*dynstr; -	uint_t		stoff; +	size_t		stoff;  	Word		flags = ofl->ofl_flags;  	Word		cnt; @@ -2013,11 +2008,11 @@ update_odynamic(Ofl_desc *ofl)  		dyn++;  	} -	if (ofl->ofl_dtsfltrs) { -		Dfltr_desc *	dftp; -		Aliste		off; +	if (ofl->ofl_dtsfltrs != NULL) { +		Dfltr_desc	*dftp; +		Aliste		idx; -		for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, off, dftp)) { +		for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, idx, dftp)) {  			if (dftp->dft_flag == FLG_SY_AUXFLTR)  				dyn->d_tag = DT_SUNW_AUXILIARY;  			else @@ -2457,7 +2452,7 @@ update_overdef(Ofl_desc *ofl)  		if (vdp->vd_flags & VER_FLG_BASE) {  			const char	*name = vdp->vd_name; -			uint_t		stoff; +			size_t		stoff;  			/*  			 * Create a new string table entry to represent the base @@ -2468,12 +2463,12 @@ update_overdef(Ofl_desc *ofl)  				(void) st_setstring(ofl->ofl_strtab,  				    name, &stoff);  				/* LINTED */ -				vdp->vd_name = (const char *)(uintptr_t)stoff; +				vdp->vd_name = (const char *)stoff;  			} else {  				(void) st_setstring(ofl->ofl_dynstrtab,  				    name, &stoff);  				/* LINTED */ -				vdp->vd_name = (const char *)(uintptr_t)stoff; +				vdp->vd_name = (const char *)stoff;  			}  		} else {  			sdp = ld_sym_find(vdp->vd_name, vdp->vd_hash, 0, ofl); @@ -2592,7 +2587,7 @@ update_overneed(Ofl_desc *ofl)  		Half		_cnt;  		Vernaux		*_vnap, *vnap;  		Sdf_desc	*sdf = ifl->ifl_sdfdesc; -		uint_t		stoff; +		size_t		stoff;  		if (!(ifl->ifl_flags & FLG_IF_VERNEED))  			continue; @@ -2712,7 +2707,7 @@ update_osyminfo(Ofl_desc * ofl)  	char		*strtab;  	Listnode *	lnp;  	Sym_desc *	sdp; -	Aliste		off; +	Aliste		idx;  	Sfltr_desc *	sftp;  	if (ofl->ofl_flags & FLG_OF_RELOBJ) { @@ -2745,12 +2740,10 @@ update_osyminfo(Ofl_desc * ofl)  	/*  	 * Update any filtee references with the index into the dynamic table.  	 */ -	for (ALIST_TRAVERSE(ofl->ofl_symfltrs, off, sftp)) { -		Dfltr_desc *	dftp; +	for (ALIST_TRAVERSE(ofl->ofl_symfltrs, idx, sftp)) { +		Dfltr_desc	*dftp; -		/* LINTED */ -		dftp = (Dfltr_desc *)((char *)ofl->ofl_dtsfltrs + -		    sftp->sft_off); +		dftp = alist_item(ofl->ofl_dtsfltrs, sftp->sft_idx);  		sip[sftp->sft_sdp->sd_symndx].si_boundto = dftp->dft_ndx;  	} @@ -3109,7 +3102,7 @@ update_ostrtab(Os_desc *osp, Str_tbl *stp, uint_t extra)  	data = osp->os_outdata;  	assert(data->d_size == (st_getstrtab_sz(stp) + extra)); -	(void) st_setstrbuf(stp, data->d_buf, (uint_t)data->d_size - extra); +	(void) st_setstrbuf(stp, data->d_buf, data->d_size - extra);  	/* If leaving an extra hole at the end, zero it */  	if (extra > 0)  		(void) memset((char *)data->d_buf + data->d_size - extra, @@ -3191,7 +3184,7 @@ ld_update_outfile(Ofl_desc *ofl)  	Addr		size, etext, vaddr = ofl->ofl_segorigin;  	Listnode	*lnp1, *lnp2;  	Sg_desc		*sgp, *dtracesgp = 0, *capsgp = 0; -	Os_desc		**ospp, *osp; +	Os_desc		*osp;  	int		phdrndx = 0, segndx = -1, secndx;  	int		dtracepndx, dtracesndx, cappndx, capsndx;  	Ehdr		*ehdr = ofl->ofl_nehdr; @@ -3201,7 +3194,7 @@ ld_update_outfile(Ofl_desc *ofl)  	Word		flags = ofl->ofl_flags, ehdrsz = ehdr->e_ehsize;  	Boolean		nobits;  	Off		offset; -	Aliste		off; +	Aliste		idx;  	/*  	 * Loop through the segment descriptors and pick out what we need. @@ -3437,7 +3430,7 @@ ld_update_outfile(Ofl_desc *ofl)  		 * information provided from elf_update().  		 * Allow for multiple NOBITS sections.  		 */ -		osp = (Os_desc *)sgp->sg_osdescs->al_data[0]; +		osp = sgp->sg_osdescs->apl_data[0];  		hshdr = osp->os_shdr;  		phdr->p_filesz = 0; @@ -3447,11 +3440,8 @@ ld_update_outfile(Ofl_desc *ofl)  		nobits = ((hshdr->sh_type == SHT_NOBITS) &&  		    ((sgp->sg_flags & FLG_SG_PHREQ) == 0)); -		for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { -			Shdr	*shdr; - -			osp = *ospp; -			shdr = osp->os_shdr; +		for (APLIST_TRAVERSE(sgp->sg_osdescs, idx, osp)) { +			Shdr	*shdr = osp->os_shdr;  			p_align = 0;  			if (shdr->sh_addralign > p_align) @@ -3605,11 +3595,8 @@ ld_update_outfile(Ofl_desc *ofl)  		 */  		secndx = 0;  		hshdr = 0; -		for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { -			Shdr	*shdr; - -			osp = *ospp; -			shdr = osp->os_shdr; +		for (APLIST_TRAVERSE(sgp->sg_osdescs, idx, osp)) { +			Shdr	*shdr = osp->os_shdr;  			if (shdr->sh_link)  				shdr->sh_link = translate_link(ofl, osp, diff --git a/usr/src/cmd/sgs/liblddbg/common/debug.c b/usr/src/cmd/sgs/liblddbg/common/debug.c index bc45db0638..903f23cae4 100644 --- a/usr/src/cmd/sgs/liblddbg/common/debug.c +++ b/usr/src/cmd/sgs/liblddbg/common/debug.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -244,15 +244,15 @@ Dbg_setup(const char *string, Dbg_desc *dbp)  					continue;  				if (set == TRUE) { -				    if (opt->o_class) -					dbp->d_class |= opt->o_class; -				    if (opt->o_extra) -					dbp->d_extra |= opt->o_extra; +					if (opt->o_class) +						dbp->d_class |= opt->o_class; +					if (opt->o_extra) +						dbp->d_extra |= opt->o_extra;  				} else { -				    if (opt->o_class) -					dbp->d_class &= ~(opt->o_class); -				    if (opt->o_extra) -					dbp->d_extra &= ~(opt->o_extra); +					if (opt->o_class) +						dbp->d_class &= ~(opt->o_class); +					if (opt->o_extra) +						dbp->d_extra &= ~(opt->o_extra);  				}  				found = TRUE;  				break; @@ -286,8 +286,8 @@ Dbg_setup(const char *string, Dbg_desc *dbp)  				 * been reallocated, so these names will remain  				 * once this routine returns.  				 */ -				if (alist_append(&(dbp->d_list), &name, -				    sizeof (char *), AL_CNT_DEBUG) == 0) +				if (aplist_append(&dbp->d_list, name, +				    AL_CNT_DEBUG) == 0)  					return (S_ERROR);  				found = TRUE; diff --git a/usr/src/cmd/sgs/liblddbg/common/files.c b/usr/src/cmd/sgs/liblddbg/common/files.c index 83cbe3e1f0..da3df14923 100644 --- a/usr/src/cmd/sgs/liblddbg/common/files.c +++ b/usr/src/cmd/sgs/liblddbg/common/files.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -302,8 +302,8 @@ Dbg_file_bindings(Rt_map *lmp, int flag)  	/* LINTED */  	for (tlmp = lmp; tlmp; tlmp = (Rt_map *)NEXT(tlmp)) { -		Bnd_desc	**bdpp; -		Aliste		off; +		Bnd_desc	*bdp; +		Aliste		idx;  		/*  		 * For .init processing, only collect objects that have been @@ -330,15 +330,15 @@ Dbg_file_bindings(Rt_map *lmp, int flag)  		if (next++)  			Dbg_util_nl(lml, DBG_NL_STD); -		if (DEPENDS(tlmp) == 0) +		if (DEPENDS(tlmp) == NULL)  			dbg_print(lml, MSG_INTL(MSG_FIL_DEP_NONE), NAME(tlmp));  		else {  			dbg_print(lml, MSG_INTL(MSG_FIL_DEP_ENT), NAME(tlmp)); -			for (ALIST_TRAVERSE(DEPENDS(tlmp), off, bdpp)) { +			for (APLIST_TRAVERSE(DEPENDS(tlmp), idx, bdp)) {  				dbg_print(lml, MSG_INTL(MSG_FIL_BND_FILE), -				    NAME((*bdpp)->b_depend), -				    conv_bnd_type((*bdpp)->b_flags, +				    NAME(bdp->b_depend), +				    conv_bnd_type(bdp->b_flags,  				    &bnd_type_buf));  			}  		} @@ -602,7 +602,7 @@ Dbg_file_cntl(Lm_list *lml, Aliste flmco, Aliste tlmco)  	dbg_print(lml, MSG_INTL(MSG_CNTL_TITLE), EC_XWORD(flmco),  	    EC_XWORD(tlmco)); -	for (ALIST_TRAVERSE(lml->lm_lists, off, lmc)) { +	for (ALIST_TRAVERSE_BY_OFFSET(lml->lm_lists, off, lmc)) {  		Rt_map	*lmp;  		/* LINTED */ diff --git a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg index b5b412568c..67f7932a1d 100644 --- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg +++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg @@ -20,7 +20,7 @@  #  # -# Copyright 2007 Sun Microsystems, Inc.  All rights reserved. +# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.  # Use is subject to license terms.  #  # ident	"%Z%%M%	%I%	%E% SMI" @@ -556,21 +556,29 @@  # Section messages  @ MSG_SEC_INPUT		"section=%s; input from file=%s" +@ MSG_SEC_INPUT_GENSTR	"section=%s; input generated merged string section"  @ MSG_SEC_ADDED		"section=%s; added to segment=%s"  @ MSG_SEC_CREATED	"section=%s; added to segment=%s (created)"  @ MSG_SEC_DISCARDED	"section=%s; input from file=%s; \  			 discarded in favor of section=%s from file=%s" +@ MSG_SEC_STRMERGE_DISCARDED	"section=%s; input from file=%s; \ +			 discarded in favor of generated merged string section" +@ MSG_SEC_STRMERGE_UNSUP "section=%s; input from file=%s; sh_addralign=%lld; \ +			 sh_entsize=%lld; unable to merge sections with this \ +			 size and alignment"  @ MSG_SEC_GRP_INPUT	"section=%s; input from file=%s; \  			 member of group: %s:%s"  @ MSG_SEC_GRP_DISCARDED	"section=%s; input from file=%s; \  			 discarded: member of existing group: %s:%s" -@ MSG_SEC_STRTAB_STND	"strtab=%s; full size: %d; uncompressed" -@ MSG_SEC_STRTAB_COMP	"strtab=%s; full size: %d; compressed down to: %d" +@ MSG_SEC_STRTAB_STND	"strtab=%s; full size: %lld; uncompressed" +@ MSG_SEC_STRTAB_COMP	"strtab=%s; full size: %lld; compressed down to: %lld" +@ MSG_SEC_GENSTR_COMP	"section=%s (generated merged string section); \ +			 full size: %lld; compressed down to: %lld"  @ MSG_SEC_STRTAB_HD	"strtab=%s; compression information [%d buckets]:"  @ MSG_SEC_STRTAB_BCKT	" bucket[%d]:" -@ MSG_SEC_STRTAB_MSTR	"   [%d] %s  <master>" -@ MSG_SEC_STRTAB_SUFSTR	"   [%d] %s  <suffix of: %s>" +@ MSG_SEC_STRTAB_MSTR	"   [%lld] %s  <master>" +@ MSG_SEC_STRTAB_SUFSTR	"   [%lld] %s  <suffix of: %s>"  # Unused messages diff --git a/usr/src/cmd/sgs/liblddbg/common/lintsup.c b/usr/src/cmd/sgs/liblddbg/common/lintsup.c index 0d5b13435a..e61b8fbe94 100644 --- a/usr/src/cmd/sgs/liblddbg/common/lintsup.c +++ b/usr/src/cmd/sgs/liblddbg/common/lintsup.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -40,6 +40,7 @@  #include <rtld.h>  #include <conv.h>  #include <msg.h> +#include <sys/debug.h>  /*   * Get the Elf32 side to think that the _ELF64 side @@ -56,3 +57,9 @@  #endif  void	Dbg_reloc_doactiverel(void); + +void +foo() +{ +	assfail3(NULL, 0, NULL, 0, NULL, 0); +} diff --git a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers index 61a40a3ad8..0de413a7ef 100644 --- a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers +++ b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers @@ -20,7 +20,7 @@  #  # -# Copyright 2007 Sun Microsystems, Inc.  All rights reserved. +# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.  # Use is subject to license terms.  #  # ident	"%Z%%M%	%I%	%E% SMI" @@ -272,6 +272,8 @@ SUNWprivate_4.61 {  		Dbg64_sec_created;  		Dbg32_sec_discarded;  		Dbg64_sec_discarded; +		Dbg32_sec_genstr_compress; +		Dbg64_sec_genstr_compress;  		Dbg32_sec_group;  		Dbg64_sec_group;  		Dbg32_sec_in; @@ -282,6 +284,8 @@ SUNWprivate_4.61 {  		Dbg64_sec_order_list;  		Dbg32_sec_strtab;  		Dbg64_sec_strtab; +		Dbg32_sec_unsup_strmerge; +		Dbg64_sec_unsup_strmerge;  		Dbg32_seg_entry;  		Dbg64_seg_entry; diff --git a/usr/src/cmd/sgs/liblddbg/common/sections.c b/usr/src/cmd/sgs/liblddbg/common/sections.c index bd1b76e2de..02bb9d779f 100644 --- a/usr/src/cmd/sgs/liblddbg/common/sections.c +++ b/usr/src/cmd/sgs/liblddbg/common/sections.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -44,10 +44,10 @@ Dbg_sec_strtab(Lm_list *lml, Os_desc *osp, Str_tbl *stp)  	Dbg_util_nl(lml, DBG_NL_STD);  	if (stp->st_flags & FLG_STTAB_COMPRESS)  		dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_COMP), osp->os_name, -		    stp->st_fullstrsize, stp->st_strsize); +		    EC_XWORD(stp->st_fullstrsize), EC_XWORD(stp->st_strsize));  	else  		dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_STND), osp->os_name, -		    stp->st_fullstrsize); +		    EC_XWORD(stp->st_fullstrsize));  	if ((DBG_NOTDETAIL()) ||  	    ((stp->st_flags & FLG_STTAB_COMPRESS) == 0)) @@ -66,16 +66,16 @@ Dbg_sec_strtab(Lm_list *lml, Os_desc *osp, Str_tbl *stp)  		dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_BCKT), cnt);  		while (strhash) { -			uint_t	stroff = strhash->hi_mstr->sm_strlen - +			size_t	stroff = strhash->hi_mstr->sm_strlen -  			    strhash->hi_strlen;  			if (stroff == 0) {  				dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_MSTR), -				    strhash->hi_refcnt, +				    EC_XWORD(strhash->hi_refcnt),  				    strhash->hi_mstr->sm_str);  			} else {  				dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_SUFSTR), -				    strhash->hi_refcnt, +				    EC_XWORD(strhash->hi_refcnt),  				    &strhash->hi_mstr->sm_str[stroff],  				    strhash->hi_mstr->sm_str);  			} @@ -86,6 +86,41 @@ Dbg_sec_strtab(Lm_list *lml, Os_desc *osp, Str_tbl *stp)  }  void +Dbg_sec_genstr_compress(Lm_list *lml, const char *os_name, +    Xword raw_size, Xword merge_size) +{ +	if (DBG_NOTCLASS(DBG_C_SECTIONS)) +		return; + +	dbg_print(lml, MSG_INTL(MSG_SEC_GENSTR_COMP), os_name, +	    EC_XWORD(raw_size), EC_XWORD(merge_size)); +} + +void +Dbg_sec_unsup_strmerge(Lm_list *lml, Is_desc *isp) +{ +	const char *str; + +	if (DBG_NOTCLASS(DBG_C_SECTIONS)) +		return; + +	/* +	 * We can only merge string table sections with single byte +	 * (char) characters. For any other (wide) character types, +	 * issue a message so the user will understand why these +	 * sections are not being picked up. +	 */ +	if ((isp->is_shdr->sh_entsize > 1) || +	    (isp->is_shdr->sh_addralign > 1)) { +		str = (isp->is_file != NULL) ? isp->is_file->ifl_name : +		    MSG_INTL(MSG_STR_NULL); +		dbg_print(lml, MSG_INTL(MSG_SEC_STRMERGE_UNSUP), +		    isp->is_basename, str, EC_XWORD(isp->is_shdr->sh_addralign), +		    EC_XWORD(isp->is_shdr->sh_entsize)); +	} +} + +void  Dbg_sec_in(Lm_list *lml, Is_desc *isp)  {  	const char	*str; @@ -93,12 +128,22 @@ Dbg_sec_in(Lm_list *lml, Is_desc *isp)  	if (DBG_NOTCLASS(DBG_C_SECTIONS))  		return; -	if (isp->is_file != NULL) -		str = isp->is_file->ifl_name; -	else -		str = MSG_INTL(MSG_STR_NULL); - -	dbg_print(lml, MSG_INTL(MSG_SEC_INPUT), isp->is_name, str); +	if (isp->is_flags & FLG_IS_GNSTRMRG) { +		/* +		 * This section was generated because we have 1 or +		 * more SHF_MERGE|SHF_STRINGS input sections that we +		 * wish to merge. This new section will ultimately +		 * end up replacing those sections once it has been filled +		 * with their strings (merged and compressed) and relocations +		 * have been redirected. +		 */ +		dbg_print(lml, MSG_INTL(MSG_SEC_INPUT_GENSTR), isp->is_name); +	} else { +		/* Standard input section */ +		str = (isp->is_file != NULL) ? isp->is_file->ifl_name : +		    MSG_INTL(MSG_STR_NULL); +		dbg_print(lml, MSG_INTL(MSG_SEC_INPUT), isp->is_name, str); +	}  }  void @@ -139,9 +184,20 @@ Dbg_sec_discarded(Lm_list *lml, Is_desc *isp, Is_desc *disp)  	if (DBG_NOTCLASS(DBG_C_SECTIONS | DBG_C_UNUSED))  		return; -	dbg_print(lml, MSG_INTL(MSG_SEC_DISCARDED), isp->is_basename, -	    isp->is_file->ifl_name, disp->is_basename, -	    disp->is_file->ifl_name); +	if ((isp->is_flags & FLG_IS_INSTRMRG) && +	    (disp->is_flags & FLG_IS_GNSTRMRG)) { +		/* +		 * This SHF_MERGE|SHF_STRINGS input section is being +		 * discarded in favor of the generated merged string section. +		 */ +		dbg_print(lml, MSG_INTL(MSG_SEC_STRMERGE_DISCARDED), +		    isp->is_basename, isp->is_file->ifl_name); +	} else { +		/* Generic section discard */ +		dbg_print(lml, MSG_INTL(MSG_SEC_DISCARDED), isp->is_basename, +		    isp->is_file->ifl_name, disp->is_basename, +		    disp->is_file->ifl_name); +	}  }  void diff --git a/usr/src/cmd/sgs/liblddbg/common/segments.c b/usr/src/cmd/sgs/liblddbg/common/segments.c index cf1e3558e2..7276b10b12 100644 --- a/usr/src/cmd/sgs/liblddbg/common/segments.c +++ b/usr/src/cmd/sgs/liblddbg/common/segments.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -58,16 +58,13 @@ Dbg_seg_desc_entry(Lm_list *lml, Half mach, int ndx, Sg_desc *sgp)  		    Dbg_demangle_name(sgp->sg_sizesym->sd_name));  	if (sgp->sg_secorder) { -		Aliste		off; -		Sec_order	**scopp; +		Aliste		idx; +		Sec_order	*scop;  		dbg_print(lml, MSG_ORIG(MSG_SEG_ORDER)); -		for (ALIST_TRAVERSE(sgp->sg_secorder, off, scopp)) { -			Sec_order	*scop = *scopp; - +		for (APLIST_TRAVERSE(sgp->sg_secorder, idx, scop))  			dbg_print(lml, MSG_ORIG(MSG_SEG_SECTION),  			    scop->sco_secname, EC_WORD(scop->sco_index)); -		}  	}  	Dbg_util_nl(lml, DBG_NL_STD);  } diff --git a/usr/src/cmd/sgs/librtld/common/dynamic.c b/usr/src/cmd/sgs/librtld/common/dynamic.c index 23a35484c9..f11ff24da2 100644 --- a/usr/src/cmd/sgs/librtld/common/dynamic.c +++ b/usr/src/cmd/sgs/librtld/common/dynamic.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   *   * Update any dynamic entry offsets.  One issue with dynamic entries is that @@ -72,15 +72,15 @@ update_dynamic(Cache *cache, Cache *_cache, Rt_map *lmp, int flags,  				 */  				if (dlmp = is_so_loaded(LIST(lmp),  				    (strs + dyn->d_un.d_val))) { -					Bnd_desc	**bdpp; -					Aliste		off; +					Bnd_desc	*bdp; +					Aliste		idx; -					for (ALIST_TRAVERSE(DEPENDS(lmp), off, -					    bdpp)) { -						if (dlmp == (*bdpp)->b_depend) { -						    posdyn->d_un.d_val &= -							~DF_P1_LAZYLOAD; -						    break; +					for (APLIST_TRAVERSE(DEPENDS(lmp), idx, +					    bdp)) { +						if (dlmp == bdp->b_depend) { +							posdyn->d_un.d_val &= +							    ~DF_P1_LAZYLOAD; +							break;  						}  					}  				} @@ -167,7 +167,7 @@ update_dynamic(Cache *cache, Cache *_cache, Rt_map *lmp, int flags,  		case DT_JMPREL:  			dyn->d_un.d_ptr = (addr + off + -				((null + data) * entsize)); +			    ((null + data) * entsize));  			break;  		/* diff --git a/usr/src/cmd/sgs/librtld/common/relocate.c b/usr/src/cmd/sgs/librtld/common/relocate.c index 9adfc4b8eb..76eaeabf6b 100644 --- a/usr/src/cmd/sgs/librtld/common/relocate.c +++ b/usr/src/cmd/sgs/librtld/common/relocate.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -308,7 +308,7 @@ count_reloc(Cache *cache, Cache *_cache, Rt_map *lmp, int flags, Addr addr,  				    (FLAGS(_lmp) & FLG_RT_PRELOAD)) ||  				    ((flags & RTLD_REL_SELF) &&  				    (lmp == _lmp))) { -					Aliste	off; +					Aliste	idx;  					Word	*ndx;  					_bound = 1; @@ -318,7 +318,7 @@ count_reloc(Cache *cache, Cache *_cache, Rt_map *lmp, int flags, Addr addr,  					 * as nodirect, don't allow any local  					 * binding.  					 */ -					for (ALIST_TRAVERSE(nodirect, off, +					for (ALIST_TRAVERSE(nodirect, idx,  					    ndx)) {  						if (*ndx == rsymndx) {  							_bound = 0; diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README index 8269dd89ca..e98ee1d44b 100644 --- a/usr/src/cmd/sgs/packages/common/SUNWonld-README +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README @@ -1306,3 +1306,4 @@ Bugid   Risk Synopsis  6642769 ld(1) -z combreloc should become default behavior (D)  	PSARC/2008/006: make ld(1) -z combreloc become default behavior  6634436 XFFLAG should be updated.  (link-editor components only) +6492726 Merge SHF_MERGE|SHF_STRINGS input sections diff --git a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c index 8e4bed7a3c..74568869ab 100644 --- a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c +++ b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -469,7 +469,7 @@ elf_reloc(Rt_map *lmp, uint_t plt)  	int		relacount = RELACOUNT(lmp), plthint = 0;  	Rela		*rel;  	uint_t		binfo, pbinfo; -	Alist		*bound = 0; +	APlist		*bound = NULL;  	/*  	 * Although only necessary for lazy binding, initialize the first @@ -854,8 +854,7 @@ elf_reloc(Rt_map *lmp, uint_t plt)  					 */  					if ((lmp != _lmp) && ((FLAGS1(_lmp) &  					    FL1_RT_NOINIFIN) == 0)) { -						if (alist_test(&bound, _lmp, -						    sizeof (Rt_map *), +						if (aplist_test(&bound, _lmp,  						    AL_CNT_RELBIND) == 0) {  							ret = 0;  							break; diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h index d3c2505d8e..fdbae1ae45 100644 --- a/usr/src/cmd/sgs/rtld/common/_rtld.h +++ b/usr/src/cmd/sgs/rtld/common/_rtld.h @@ -23,7 +23,7 @@   *	  All Rights Reserved   *   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -391,12 +391,6 @@ typedef struct {  #define	TKN_DOTSLASH	0x00000002	/* path contains a "./" */  /* - * Define alist descriptor addition return values (see hdl_add()). - */ -#define	ALE_EXISTS	1		/* alist entry already exists */ -#define	ALE_CREATE	2		/* alist entry created */ - -/*   * Define _caller flags.   */  #define	CL_NONE		0 @@ -504,9 +498,6 @@ extern ulong_t		sfcap;		/* software capabilities */   * Function declarations.   */  extern void		addfree(void *, size_t); -extern void *		alist_append(Alist **, const void *, size_t, int); -extern int		alist_delete(Alist *, const void *, Aliste *); -extern int		alist_test(Alist **, void *, size_t, int);  extern int		append_alias(Rt_map *, const char *, int *);  extern int		analyze_lmc(Lm_list *, Aliste, Rt_map *);  extern Am_ret		anon_map(Lm_list *, caddr_t *, size_t, int, int); @@ -605,7 +596,7 @@ extern int		readenv_user(const char **, Word *, Word *, int);  extern int		readenv_config(Rtc_env *, Addr, int);  extern void		rejection_inherit(Rej_desc *, Rej_desc *);  extern int		relocate_lmc(Lm_list *, Aliste, Rt_map *, Rt_map *); -extern int		relocate_finish(Rt_map *, Alist *, int, int); +extern int		relocate_finish(Rt_map *, APlist *, int, int);  extern void		remove_cntl(Lm_list *, Aliste);  extern int		remove_hdl(Grp_hdl *, Rt_map *, int *);  extern void		remove_lmc(Lm_list *, Rt_map *, Lm_cntl *, Aliste, diff --git a/usr/src/cmd/sgs/rtld/common/analyze.c b/usr/src/cmd/sgs/rtld/common/analyze.c index 06474d3ad5..2e3236f3cd 100644 --- a/usr/src/cmd/sgs/rtld/common/analyze.c +++ b/usr/src/cmd/sgs/rtld/common/analyze.c @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -113,7 +113,7 @@ analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp)  	 * are added to a new link-map control list.  	 */  	/* LINTED */ -	nlmc = (Lm_cntl *)((char *)lml->lm_lists + nlmco); +	nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);  	if (nlmc->lc_flags & LMC_FLG_ANALYZING)  		return (1); @@ -184,7 +184,7 @@ analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp)  		 * dependencies.  		 */  		/* LINTED */ -		nlmc = (Lm_cntl *)((char *)lml->lm_lists + nlmco); +		nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);  		if (nlmc->lc_flags & LMC_FLG_REANALYZE) {  			nlmc->lc_flags &= ~LMC_FLG_REANALYZE;  			lmp = nlmc->lc_head; @@ -192,7 +192,7 @@ analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp)  	}  	/* LINTED */ -	nlmc = (Lm_cntl *)((char *)lml->lm_lists + nlmco); +	nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);  	nlmc->lc_flags &= ~LMC_FLG_ANALYZING;  	return (ret); @@ -307,21 +307,23 @@ _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated)  	 * Perform special copy relocations.  These are only meaningful for  	 * dynamic executables (fixed and head of their link-map list).  If  	 * this ever has to change then the infrastructure of COPY() has to -	 * change as presently this element is used to capture both receiver -	 * and supplier of copy data. +	 * change. Presently, a given link map can only have a receiver or +	 * supplier of copy data, so a union is used to overlap the storage +	 * for the COPY_R() and COPY_S() lists. These lists would need to +	 * be separated.  	 */  	if ((FLAGS(nlmp) & FLG_RT_FIXED) && (nlmp == LIST(nlmp)->lm_head) &&  	    (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) ||  	    (lml->lm_flags & LML_FLG_TRC_WARN))) { -		Rt_map **	lmpp; -		Aliste		off1; +		Rt_map		*lmp; +		Aliste		idx1;  		Word		tracing;  #if	defined(__i386)  		if (elf_copy_gen(nlmp) == 0)  			return (0);  #endif -		if (COPY(nlmp) == 0) +		if (COPY_S(nlmp) == NULL)  			return (1);  		if ((LIST(nlmp)->lm_flags & LML_FLG_TRC_ENABLE) && @@ -333,12 +335,11 @@ _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated)  		DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD)); -		for (ALIST_TRAVERSE(COPY(nlmp), off1, lmpp)) { -			Rt_map *	lmp = *lmpp; +		for (APLIST_TRAVERSE(COPY_S(nlmp), idx1, lmp)) {  			Rel_copy *	rcp; -			Aliste		off2; +			Aliste		idx2; -			for (ALIST_TRAVERSE(COPY(lmp), off2, rcp)) { +			for (ALIST_TRAVERSE(COPY_R(lmp), idx2, rcp)) {  				int zero;  				/* @@ -365,8 +366,8 @@ _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated)  		DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD)); -		free(COPY(nlmp)); -		COPY(nlmp) = 0; +		free(COPY_S(nlmp)); +		COPY_S(nlmp) = 0;  	}  	return (1);  } @@ -375,7 +376,7 @@ int  relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp)  {  	int	lret = 1, pret = 1; -	Alist	*alp; +	APlist	*alp;  	Aliste	plmco;  	Lm_cntl	*plmc, *nlmc; @@ -388,7 +389,7 @@ relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp)  	 * are added to a new link-map control list.  	 */  	/* LINTED */ -	nlmc = (Lm_cntl *)((char *)lml->lm_lists + nlmco); +	nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);  	if (nlmc->lc_flags & LMC_FLG_RELOCATING)  		return (1); @@ -427,7 +428,7 @@ relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp)  		 * are demoted to standard objects.  Their interposition can't  		 * be guaranteed once relocations have been carried out.  		 */ -		if (nlmco == ALO_DATA) +		if (nlmco == ALIST_OFF_DATA)  			lml->lm_flags |= LML_FLG_STARTREL;  		/* @@ -439,7 +440,7 @@ relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp)  		 * failed objects now.  		 */  		lret = _relocate_lmc(lml, nlmp, &relocated); -		if ((lret == 0) && (nlmco != ALO_DATA)) +		if ((lret == 0) && (nlmco != ALIST_OFF_DATA))  			remove_lmc(lml, clmp, nlmc, nlmco, NAME(nlmp));  	} @@ -447,14 +448,14 @@ relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp)  	 * Determine the new, and previous link-map control lists.  	 */  	/* LINTED */ -	nlmc = (Lm_cntl *)((char *)lml->lm_lists + nlmco); -	if (nlmco == ALO_DATA) { +	nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); +	if (nlmco == ALIST_OFF_DATA) {  		plmco = nlmco;  		plmc = nlmc;  	} else {  		plmco = nlmco - lml->lm_lists->al_size;  		/* LINTED */ -		plmc = (Lm_cntl *)((char *)lml->lm_lists + plmco); +		plmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, plmco);  	}  	/* @@ -465,7 +466,7 @@ relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp)  	 * be moved up one control list so as to preserve the link-map order  	 * that may have already been traversed in search of symbols.  	 */ -	if (lret && (nlmco != ALO_DATA) && nlmc->lc_head) +	if (lret && (nlmco != ALIST_OFF_DATA) && nlmc->lc_head)  		lm_move(lml, nlmco, plmco, nlmc, plmc);  	/* @@ -477,20 +478,18 @@ relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp)  	 * prevents relocations from being bound to objects that might yet fail  	 * to relocate themselves.  	 */ -	while ((alp = plmc->lc_now) != 0) { -		Aliste	off; -		Rt_map	**lmpp; +	while ((alp = plmc->lc_now) != NULL) { +		Aliste	idx; +		Rt_map	*lmp;  		/*  		 * Remove the relocation promotion list, as performing more  		 * relocations may result in discovering more objects that need  		 * promotion.  		 */ -		plmc->lc_now = 0; - -		for (ALIST_TRAVERSE(alp, off, lmpp)) { -			Rt_map	*lmp = *lmpp; +		plmc->lc_now = NULL; +		for (APLIST_TRAVERSE(alp, idx, lmp)) {  			/*  			 * If the original relocation of the link-map control  			 * list failed, or one of the relocation promotions of @@ -526,10 +525,10 @@ relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp)  		 * link-map control list.  		 */  		/* LINTED */ -		nlmc = (Lm_cntl *)((char *)lml->lm_lists + nlmco); +		nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);  		/* LINTED */ -		plmc = (Lm_cntl *)((char *)lml->lm_lists + plmco); -		if ((nlmco != ALO_DATA) && nlmc->lc_head) +		plmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, plmco); +		if ((nlmco != ALIST_OFF_DATA) && nlmc->lc_head)  			lm_move(lml, nlmco, plmco, nlmc, plmc);  		free(alp);  	} @@ -542,7 +541,7 @@ relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp)  	 */  	if (lret && pret) {  		/* LINTED */ -		nlmc = (Lm_cntl *)((char *)lml->lm_lists + nlmco); +		nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);  		nlmc->lc_flags &= ~LMC_FLG_RELOCATING;  		return (1); @@ -741,8 +740,8 @@ _is_so_matched(const char *name, const char *str, int path)  static Rt_map *  is_so_matched(Rt_map *lmp, const char *name, int path)  { -	Aliste		off; -	const char	**cpp; +	Aliste		idx; +	const char	*cp;  	/*  	 * A pathname is typically going to match a NAME() or PATHNAME(), so @@ -767,12 +766,12 @@ is_so_matched(Rt_map *lmp, const char *name, int path)  	 * If this is a simple filename, or a pathname has failed to match the  	 * NAME() and PATHNAME() check above, look through the ALIAS() list.  	 */ -	for (ALIST_TRAVERSE(ALIAS(lmp), off, cpp)) { +	for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp)) {  		/*  		 * If we're looking for a simple filename, _is_so_matched()  		 * will reduce the ALIAS name to its simple name.  		 */ -		if (_is_so_matched(name, *cpp, path) == 0) +		if (_is_so_matched(name, cp, path) == 0)  			return (lmp);  	} @@ -823,7 +822,7 @@ is_so_loaded(Lm_list *lml, const char *name)  	Rt_map		*lmp;  	avl_index_t	where;  	Lm_cntl		*lmc; -	Aliste		off; +	Aliste		idx;  	int		path = 0;  	/* @@ -844,7 +843,7 @@ is_so_loaded(Lm_list *lml, const char *name)  	/*  	 * Loop through the callers link-map lists.  	 */ -	for (ALIST_TRAVERSE(lml->lm_lists, off, lmc)) { +	for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) {  		for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp)) {  			if (FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE))  				continue; @@ -978,9 +977,9 @@ update_mode(Rt_map *lmp, int omode, int nmode)  		Lm_cntl	*lmc;  		/* LINTED */ -		lmc = (Lm_cntl *)((char *)(LIST(lmp)->lm_lists) + CNTL(lmp)); -		(void) alist_append(&(lmc->lc_now), &lmp, sizeof (Rt_map *), -		    AL_CNT_LMNOW); +		lmc = (Lm_cntl *)alist_item_by_offset(LIST(lmp)->lm_lists, +		    CNTL(lmp)); +		(void) aplist_append(&lmc->lc_now, lmp, AL_CNT_LMNOW);  	}  #ifdef	SIEBEL_DISABLE @@ -1028,14 +1027,14 @@ update_mode(Rt_map *lmp, int omode, int nmode)  int  append_alias(Rt_map *lmp, const char *str, int *added)  { -	Aliste	off; -	char	**cpp, *cp; +	Aliste	idx; +	char	*cp;  	/*  	 * Determine if this filename is already on the alias list.  	 */ -	for (ALIST_TRAVERSE(ALIAS(lmp), off, cpp)) { -		if (strcmp(*cpp, str) == 0) +	for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp)) { +		if (strcmp(cp, str) == 0)  			return (1);  	} @@ -1045,8 +1044,7 @@ append_alias(Rt_map *lmp, const char *str, int *added)  	if ((cp = strdup(str)) == NULL)  		return (0); -	if (alist_append(&ALIAS(lmp), &cp, sizeof (char *), -	    AL_CNT_ALIAS) == 0) { +	if (aplist_append(&ALIAS(lmp), cp, AL_CNT_ALIAS) == NULL) {  		free(cp);  		return (0);  	} @@ -1064,7 +1062,7 @@ is_devinode_loaded(struct stat *status, Lm_list *lml, const char *name,      uint_t flags)  {  	Lm_cntl	*lmc; -	Aliste	off; +	Aliste	idx;  	/*  	 * If this is an auditor, it will have been opened on a new link-map. @@ -1093,7 +1091,7 @@ is_devinode_loaded(struct stat *status, Lm_list *lml, const char *name,  	 * information if this file is actually linked to one we already have  	 * mapped.  This catches symlink names not caught by is_so_loaded().  	 */ -	for (ALIST_TRAVERSE(lml->lm_lists, off, lmc)) { +	for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) {  		Rt_map	*nlmp;  		for (nlmp = lmc->lc_head; nlmp; nlmp = (Rt_map *)NEXT(nlmp)) { @@ -1945,8 +1943,8 @@ static int  load_finish(Lm_list *lml, const char *name, Rt_map *clmp, int nmode,      uint_t flags, Grp_hdl **hdl, Rt_map *nlmp)  { -	Aliste		off; -	Grp_hdl		*ghp, **ghpp; +	Aliste		idx; +	Grp_hdl		*ghp;  	int		promote;  	/* @@ -2096,7 +2094,7 @@ load_finish(Lm_list *lml, const char *name, Rt_map *clmp, int nmode,  	/*  	 * If the caller isn't part of a group we're done.  	 */ -	if (GROUPS(clmp) == 0) +	if (GROUPS(clmp) == NULL)  		return (1);  	/* @@ -2106,21 +2104,19 @@ load_finish(Lm_list *lml, const char *name, Rt_map *clmp, int nmode,  	 * new link-map to those groups.  	 */  	DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ADD)); -	for (ALIST_TRAVERSE(GROUPS(clmp), off, ghpp)) { -		Aliste		off1; +	for (APLIST_TRAVERSE(GROUPS(clmp), idx, ghp)) { +		Aliste		idx1;  		Grp_desc	*gdp;  		int		exist; -		Rt_map		**lmpp; -		Alist		*lmalp = 0; - -		ghp = *ghpp; +		Rt_map		*dlmp1; +		APlist		*lmalp = NULL;  		/*  		 * If the caller doesn't indicate that its dependencies should  		 * be added to a handle, ignore it.  This case identifies a  		 * parent of a dlopen(RTLD_PARENT) request.  		 */ -		for (ALIST_TRAVERSE(ghp->gh_depends, off1, gdp)) { +		for (ALIST_TRAVERSE(ghp->gh_depends, idx1, gdp)) {  			if (gdp->gd_depend == clmp)  				break;  		} @@ -2145,35 +2141,32 @@ load_finish(Lm_list *lml, const char *name, Rt_map *clmp, int nmode,  		 * dependencies we're also done.  		 */  		if (((FLAGS(nlmp) & FLG_RT_ANALYZED) == 0) || -		    (DEPENDS(nlmp) == 0)) +		    (DEPENDS(nlmp) == NULL))  			continue;  		/*  		 * Otherwise, this object exists and has dependencies, so add  		 * all of its dependencies to the handle were operating on.  		 */ -		if (alist_append(&lmalp, &nlmp, sizeof (Rt_map *), -		    AL_CNT_DEPCLCT) == 0) +		if (aplist_append(&lmalp, nlmp, AL_CNT_DEPCLCT) == 0)  			return (0); -		for (ALIST_TRAVERSE(lmalp, off1, lmpp)) { -			Rt_map *	dlmp1 = *lmpp; -			Aliste		off2; -			Bnd_desc **	bdpp; +		for (APLIST_TRAVERSE(lmalp, idx1, dlmp1)) { +			Aliste		idx2; +			Bnd_desc 	*bdp;  			/*  			 * Add any dependencies of this dependency to the  			 * dynamic dependency list so they can be further  			 * processed.  			 */ -			for (ALIST_TRAVERSE(DEPENDS(dlmp1), off2, bdpp)) { -				Bnd_desc *	bdp = *bdpp; +			for (APLIST_TRAVERSE(DEPENDS(dlmp1), idx2, bdp)) {  				Rt_map *	dlmp2 = bdp->b_depend;  				if ((bdp->b_flags & BND_NEEDED) == 0)  					continue; -				if (alist_test(&lmalp, dlmp2, sizeof (Rt_map *), +				if (aplist_test(&lmalp, dlmp2,  				    AL_CNT_DEPCLCT) == 0) {  					free(lmalp);  					return (0); @@ -2454,9 +2447,9 @@ lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list *lml,  	 */  	if (FLAGS1(*dlmp) & FL1_RT_COPYTOOK) {  		Rel_copy	*rcp; -		Aliste		off; +		Aliste		idx; -		for (ALIST_TRAVERSE(COPY(*dlmp), off, rcp)) { +		for (ALIST_TRAVERSE(COPY_R(*dlmp), idx, rcp)) {  			if ((sym == rcp->r_dsym) || (sym->st_value &&  			    (sym->st_value == rcp->r_dsym->st_value))) {  				*dlmp = rcp->r_rlmp; @@ -2564,16 +2557,16 @@ lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip,  	sym = 0;  	if (sip->si_boundto == SYMINFO_BT_PARENT) { -		Aliste		off1; -		Bnd_desc	**bdpp; -		Grp_hdl		**ghpp; +		Aliste		idx1; +		Bnd_desc	*bdp; +		Grp_hdl		*ghp;  		/*  		 * Determine the parent of this explicit dependency from its  		 * CALLERS()'s list.  		 */ -		for (ALIST_TRAVERSE(CALLERS(clmp), off1, bdpp)) { -			sl.sl_imap = lmp = (*bdpp)->b_caller; +		for (APLIST_TRAVERSE(CALLERS(clmp), idx1, bdp)) { +			sl.sl_imap = lmp = bdp->b_caller;  			if ((sym = SYMINTP(lmp)(&sl, dlmp, binfo)) != 0)  				goto found;  		} @@ -2585,12 +2578,11 @@ lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip,  		 * explicit dependencies of the dlopen()'ed object, and the  		 * calling parent.  		 */ -		for (ALIST_TRAVERSE(HANDLES(clmp), off1, ghpp)) { -			Grp_hdl		*ghp = *ghpp; +		for (APLIST_TRAVERSE(HANDLES(clmp), idx1, ghp)) {  			Grp_desc	*gdp; -			Aliste		off2; +			Aliste		idx2; -			for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { +			for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {  				if ((gdp->gd_flags & GPD_PARENT) == 0)  					continue;  				sl.sl_imap = lmp = gdp->gd_depend; @@ -2641,7 +2633,7 @@ core_lookup_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo,  	 * Copy relocations should start their search after the head of the  	 * main link-map control list.  	 */ -	if ((off == ALO_DATA) && (slp->sl_flags & LKUP_COPY) && ilmp) +	if ((off == ALIST_OFF_DATA) && (slp->sl_flags & LKUP_COPY) && ilmp)  		lmp = (Rt_map *)NEXT(ilmp);  	else  		lmp = ilmp; @@ -2813,14 +2805,14 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)  		sym = NULL; -		for (ALIST_TRAVERSE(LIST(clmp)->lm_lists, off, lmc)) { +		for (ALIST_TRAVERSE_BY_OFFSET(LIST(clmp)->lm_lists, off, lmc)) {  			if (((sym = core_lookup_sym(lmc->lc_head, &sl, dlmp,  			    binfo, off)) != NULL) ||  			    (*binfo & BINFO_REJSINGLE))  				break;  		}  	} else -		sym = core_lookup_sym(ilmp, &sl, dlmp, binfo, ALO_DATA); +		sym = core_lookup_sym(ilmp, &sl, dlmp, binfo, ALIST_OFF_DATA);  	/*  	 * If a symbol binding was rejected, because a binding occurred to a @@ -2854,10 +2846,10 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)  		if (sl.sl_flags & LKUP_NEXT)  			sym = _lazy_find_sym(clmp, &sl, dlmp, binfo);  		else { -			Aliste	off; +			Aliste	idx;  			Lm_cntl	*lmc; -			for (ALIST_TRAVERSE(LIST(clmp)->lm_lists, off, lmc)) { +			for (ALIST_TRAVERSE(LIST(clmp)->lm_lists, idx, lmc)) {  				sl.sl_flags |= LKUP_NOFALBACK;  				if ((sym = _lazy_find_sym(lmc->lc_head, &sl,  				    dlmp, binfo)) != 0) @@ -2969,17 +2961,15 @@ lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)  int  bind_one(Rt_map *clmp, Rt_map *dlmp, uint_t flags)  { -	Bnd_desc	**bdpp, *bdp; -	Aliste		off; +	Bnd_desc	*bdp; +	Aliste		idx;  	int		found = ALE_CREATE;  	/*  	 * Determine whether a binding descriptor already exists between the  	 * two objects.  	 */ -	for (ALIST_TRAVERSE(DEPENDS(clmp), off, bdpp)) { -		bdp = *bdpp; - +	for (APLIST_TRAVERSE(DEPENDS(clmp), idx, bdp)) {  		if (bdp->b_depend == dlmp) {  			found = ALE_EXISTS;  			break; @@ -3001,12 +2991,10 @@ bind_one(Rt_map *clmp, Rt_map *dlmp, uint_t flags)  		 * Append the binding descriptor to the caller and the  		 * dependency.  		 */ -		if (alist_append(&DEPENDS(clmp), &bdp, -		    sizeof (Bnd_desc *), AL_CNT_DEPENDS) == 0) +		if (aplist_append(&DEPENDS(clmp), bdp, AL_CNT_DEPENDS) == 0)  			return (0); -		if (alist_append(&CALLERS(dlmp), &bdp, -		    sizeof (Bnd_desc *), AL_CNT_CALLERS) == 0) +		if (aplist_append(&CALLERS(dlmp), bdp, AL_CNT_CALLERS) == 0)  			return (0);  	} @@ -3025,7 +3013,7 @@ bind_one(Rt_map *clmp, Rt_map *dlmp, uint_t flags)   * Cleanup after relocation processing.   */  int -relocate_finish(Rt_map *lmp, Alist *bound, int textrel, int ret) +relocate_finish(Rt_map *lmp, APlist *bound, int textrel, int ret)  {  	DBG_CALL(Dbg_reloc_run(lmp, 0, ret, DBG_REL_FINISH)); @@ -3033,12 +3021,12 @@ relocate_finish(Rt_map *lmp, Alist *bound, int textrel, int ret)  	 * Establish bindings to all objects that have been bound to.  	 */  	if (bound) { -		Aliste	off; -		Rt_map	**lmpp; +		Aliste	idx; +		Rt_map	*_lmp;  		if (ret) { -			for (ALIST_TRAVERSE(bound, off, lmpp)) { -				if (bind_one(lmp, *lmpp, BND_REFER) == 0) { +			for (APLIST_TRAVERSE(bound, idx, _lmp)) { +				if (bind_one(lmp, _lmp, BND_REFER) == 0) {  					ret = 0;  					break;  				} diff --git a/usr/src/cmd/sgs/rtld/common/audit.c b/usr/src/cmd/sgs/rtld/common/audit.c index 4c43c4199d..133ad2e0ae 100644 --- a/usr/src/cmd/sgs/rtld/common/audit.c +++ b/usr/src/cmd/sgs/rtld/common/audit.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   *   * Audit interfaces.  Auditing can be enabled in two ways: @@ -222,8 +222,8 @@ _audit_activity(List *list, Rt_map *clmp, uint_t flags)  			if (alml->lm_flags & LML_FLG_AUDITNOTIFY)  				continue; -			if (alist_append(&(clml->lm_actaudit), &clmp, -			    sizeof (Rt_map *), AL_CNT_ACTAUDIT) == 0) +			if (aplist_append(&clml->lm_actaudit, clmp, +			    AL_CNT_ACTAUDIT) == NULL)  				return;  			alml->lm_flags |= LML_FLG_AUDITNOTIFY; @@ -749,7 +749,7 @@ audit_desc_cleanup(Rt_map *clmp)  	Audit_desc	*adp = AUDITORS(clmp);  	Audit_list	*alp;  	Listnode	*lnp, *olnp; -	Alist		*ghalp = 0; +	APlist		*ghalp = NULL;  	if (adp == 0)  		return; @@ -758,8 +758,7 @@ audit_desc_cleanup(Rt_map *clmp)  	olnp = 0;  	for (LIST_TRAVERSE(&(adp->ad_list), lnp, alp)) { -		(void) alist_append(&ghalp, &(alp->al_ghp), sizeof (Grp_hdl *), -		    AL_CNT_GROUPS); +		(void) aplist_append(&ghalp, alp->al_ghp, AL_CNT_GROUPS);  		if (olnp)  			free(olnp); @@ -772,11 +771,11 @@ audit_desc_cleanup(Rt_map *clmp)  	AUDITORS(clmp) = 0;  	if (ghalp) { -		Grp_hdl **	ghpp; -		Aliste		off; +		Grp_hdl		*ghp; +		Aliste		idx; -		for (ALIST_TRAVERSE(ghalp, off, ghpp)) { -			(void) dlclose_intn(*ghpp, clmp); +		for (APLIST_TRAVERSE(ghalp, idx, ghp)) { +			(void) dlclose_intn(ghp, clmp);  		}  		free(ghalp);  	} diff --git a/usr/src/cmd/sgs/rtld/common/cap.c b/usr/src/cmd/sgs/rtld/common/cap.c index 5329fec2b0..77d38b6c50 100644 --- a/usr/src/cmd/sgs/rtld/common/cap.c +++ b/usr/src/cmd/sgs/rtld/common/cap.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -143,7 +143,7 @@ remove_fdesc(Fdesc *fdp)   * When $HWCAP is used to represent dependencies, take the associated directory   * and analyze all the files it contains.   */ -int +static int  hwcap_dir(Alist **fdalpp, Lm_list *lml, const char *name, Rt_map *clmp,      uint_t flags, Rej_desc *rej)  { @@ -151,8 +151,8 @@ hwcap_dir(Alist **fdalpp, Lm_list *lml, const char *name, Rt_map *clmp,  	const char	*src;  	DIR		*dir;  	struct dirent	*dirent; -	Aliste		off; -	Alist		*fdalp = 0; +	Aliste		idx; +	Alist		*fdalp = NULL;  	Fdesc		*fdp;  	int		error = 0; @@ -259,9 +259,9 @@ hwcap_dir(Alist **fdalpp, Lm_list *lml, const char *name, Rt_map *clmp,  	 * error occurred while processing any object, remove any objects that  	 * had already been added to the list and return.  	 */ -	if ((fdalp == 0) || error) { +	if ((fdalp == NULL) || error) {  		if (fdalp) { -			for (ALIST_TRAVERSE(fdalp, off, fdp)) +			for (ALIST_TRAVERSE(fdalp, idx, fdp))  				remove_fdesc(fdp);  			free(fdalp);  		} @@ -272,8 +272,7 @@ hwcap_dir(Alist **fdalpp, Lm_list *lml, const char *name, Rt_map *clmp,  	 * Having processed and retained all candidates from this directory,  	 * sort them, based on the precedence of their hardware capabilities.  	 */ -	qsort(&(fdalp->al_data[0]), ((fdalp->al_next - (sizeof (Alist) - -	    sizeof (void *))) / fdalp->al_size), fdalp->al_size, compare); +	qsort(fdalp->al_data, fdalp->al_nitems, fdalp->al_size, compare);  	*fdalpp = fdalp;  	return (1); @@ -283,8 +282,8 @@ static Pnode *  _hwcap_filtees(Pnode **pnpp, Aliste nlmco, Lm_cntl *nlmc, Rt_map *flmp,      const char *ref, const char *dir, int mode, uint_t flags)  { -	Alist		*fdalp = 0; -	Aliste		off; +	Alist		*fdalp = NULL; +	Aliste		idx;  	Pnode		*fpnp = 0, *lpnp, *npnp = (*pnpp)->p_next;  	Fdesc		*fdp;  	Lm_list		*lml = LIST(flmp); @@ -300,7 +299,7 @@ _hwcap_filtees(Pnode **pnpp, Aliste nlmco, Lm_cntl *nlmc, Rt_map *flmp,  	 * Now complete the mapping of each of the ordered objects, adding  	 * each object to a new Pnode.  	 */ -	for (ALIST_TRAVERSE(fdalp, off, fdp)) { +	for (ALIST_TRAVERSE(fdalp, idx, fdp)) {  		Rt_map	*nlmp;  		Grp_hdl	*ghp = 0;  		Pnode	*pnp; @@ -475,8 +474,8 @@ Rt_map *  load_hwcap(Lm_list *lml, Aliste lmco, const char *dir, Rt_map *clmp,      uint_t mode, uint_t flags, Grp_hdl **hdl, Rej_desc *rej)  { -	Alist		*fdalp = 0; -	Aliste		off; +	Alist		*fdalp = NULL; +	Aliste		idx;  	Fdesc		*fdp;  	int		found = 0;  	Rt_map		*lmp = 0; @@ -491,7 +490,7 @@ load_hwcap(Lm_list *lml, Aliste lmco, const char *dir, Rt_map *clmp,  	 * From the list of hardware capability objects, use the first and  	 * discard the rest.  	 */ -	for (ALIST_TRAVERSE(fdalp, off, fdp)) { +	for (ALIST_TRAVERSE(fdalp, idx, fdp)) {  		if ((found == 0) && ((lmp = load_path(lml, lmco, &fdp->fd_nname,  		    clmp, mode, flags, hdl, fdp, rej)) != 0))  			found++; diff --git a/usr/src/cmd/sgs/rtld/common/debug.c b/usr/src/cmd/sgs/rtld/common/debug.c index c069456261..ffbaf0ff32 100644 --- a/usr/src/cmd/sgs/rtld/common/debug.c +++ b/usr/src/cmd/sgs/rtld/common/debug.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -132,11 +132,11 @@ dbg_setup(const char *options, Dbg_desc *dbp)  static int  dbg_lmid(Lm_list *lml)  { -	const char	**str; -	Aliste		off; +	const char	*str; +	Aliste		idx; -	for (ALIST_TRAVERSE(dbg_desc->d_list, off, str)) { -		if (strcmp(lml->lm_lmidstr, *str) == 0) +	for (APLIST_TRAVERSE(dbg_desc->d_list, idx, str)) { +		if (strcmp(lml->lm_lmidstr, str) == 0)  			return (1);  	}  	return (0); diff --git a/usr/src/cmd/sgs/rtld/common/dlfcns.c b/usr/src/cmd/sgs/rtld/common/dlfcns.c index 61038dbfed..82705ffbb4 100644 --- a/usr/src/cmd/sgs/rtld/common/dlfcns.c +++ b/usr/src/cmd/sgs/rtld/common/dlfcns.c @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -67,10 +67,10 @@ _caller(caddr_t cpc, int flags)  	Listnode *	lnp;  	for (LIST_TRAVERSE(&dynlm_list, lnp, lml)) { -		Aliste	off; +		Aliste	idx;  		Lm_cntl	*lmc; -		for (ALIST_TRAVERSE(lml->lm_lists, off, lmc)) { +		for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) {  			Rt_map	*lmp;  			for (lmp = lmc->lc_head; lmp; @@ -134,14 +134,14 @@ int  hdl_add(Grp_hdl *ghp, Rt_map *lmp, uint_t flags)  {  	Grp_desc	*gdp; -	Aliste		off; +	Aliste		idx;  	int		found = ALE_CREATE;  	uint_t		oflags;  	/*  	 * Make sure this dependency hasn't already been recorded.  	 */ -	for (ALIST_TRAVERSE(ghp->gh_depends, off, gdp)) { +	for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {  		if (gdp->gd_depend == lmp) {  			found = ALE_EXISTS;  			break; @@ -160,14 +160,14 @@ hdl_add(Grp_hdl *ghp, Rt_map *lmp, uint_t flags)  		/*  		 * Indicate this object is a part of this handles group.  		 */ -		if (alist_append(&GROUPS(lmp), &ghp, -		    sizeof (Grp_hdl *), AL_CNT_GROUPS) == 0) +		if (aplist_append(&GROUPS(lmp), ghp, +		    AL_CNT_GROUPS) == 0)  			return (0);  		/*  		 * Append the new dependency to this handle.  		 */ -		if ((gdp = alist_append(&(ghp->gh_depends), &gd, +		if ((gdp = alist_append(&ghp->gh_depends, &gd,  		    sizeof (Grp_desc), AL_CNT_DEPENDS)) == 0)  			return (0);  	} @@ -216,9 +216,9 @@ Grp_hdl *  hdl_create(Lm_list *lml, Rt_map *nlmp, Rt_map *clmp, uint_t hflags,      uint_t ndflags, uint_t cdflags)  { -	Grp_hdl	*ghp = 0, **ghpp; -	Alist	**alpp; -	Aliste	off; +	Grp_hdl	*ghp = 0, *_ghp; +	APlist	**alpp; +	Aliste	idx;  	/*  	 * For dlopen(0) the handle is maintained as part of the link-map list, @@ -238,9 +238,9 @@ hdl_create(Lm_list *lml, Rt_map *nlmp, Rt_map *clmp, uint_t hflags,  	 * sense for RTLD_FIRST.  Determine if an appropriate handle already  	 * exists.  	 */ -	for (ALIST_TRAVERSE(*alpp, off, ghpp)) { -		if (((*ghpp)->gh_flags & GPH_FIRST) == (hflags & GPH_FIRST)) { -			ghp = *ghpp; +	for (APLIST_TRAVERSE(*alpp, idx, _ghp)) { +		if ((_ghp->gh_flags & GPH_FIRST) == (hflags & GPH_FIRST)) { +			ghp = _ghp;  			break;  		}  	} @@ -255,8 +255,7 @@ hdl_create(Lm_list *lml, Rt_map *nlmp, Rt_map *clmp, uint_t hflags,  		if ((ghp = hdl_alloc()) == 0)  			return (0); -		if (alist_append(alpp, &ghp, sizeof (Grp_hdl *), -		    AL_CNT_GROUPS) == 0) +		if (aplist_append(alpp, ghp, AL_CNT_GROUPS) == 0)  			return (0);  		/* @@ -323,11 +322,11 @@ hdl_create(Lm_list *lml, Rt_map *nlmp, Rt_map *clmp, uint_t hflags,  			(void) list_append(&hdl_list[ndx], ghp);  			if (DBG_ENABLED) { -				Aliste		off; +				Aliste		idx;  				Grp_desc	*gdp;  				DBG_CALL(Dbg_file_hdl_title(DBG_HDL_REINST)); -				for (ALIST_TRAVERSE(ghp->gh_depends, off, gdp)) +				for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp))  					DBG_CALL(Dbg_file_hdl_action(ghp,  					    gdp->gd_depend, DBG_DEP_REINST, 0));  			} @@ -355,7 +354,7 @@ hdl_create(Lm_list *lml, Rt_map *nlmp, Rt_map *clmp, uint_t hflags,  int  hdl_initialize(Grp_hdl *ghp, Rt_map *nlmp, int mode, int promote)  { -	Aliste		off; +	Aliste		idx;  	Grp_desc	*gdp;  	/* @@ -374,10 +373,10 @@ hdl_initialize(Grp_hdl *ghp, Rt_map *nlmp, int mode, int promote)  	}  	DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ADD)); -	for (ALIST_TRAVERSE(ghp->gh_depends, off, gdp)) { +	for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {  		Rt_map *	lmp = gdp->gd_depend; -		Aliste		off1; -		Bnd_desc **	bdpp; +		Aliste		idx1; +		Bnd_desc	*bdp;  		/*  		 * If this dependency doesn't indicate that its dependencies @@ -387,8 +386,7 @@ hdl_initialize(Grp_hdl *ghp, Rt_map *nlmp, int mode, int promote)  		if ((gdp->gd_flags & GPD_ADDEPS) == 0)  			continue; -		for (ALIST_TRAVERSE(DEPENDS(lmp), off1, bdpp)) { -			Bnd_desc	*bdp = *bdpp; +		for (APLIST_TRAVERSE(DEPENDS(lmp), idx1, bdp)) {  			Rt_map		*dlmp = bdp->b_depend;  			if ((bdp->b_flags & BND_NEEDED) == 0) @@ -661,7 +659,8 @@ dlmopen_core(Lm_list *lml, const char *path, int mode, Rt_map *clmp,  				promote = 1;  		}  		if (promote) -			(void) relocate_lmc(lml, ALO_DATA, clmp, lml->lm_head); +			(void) relocate_lmc(lml, ALIST_OFF_DATA, clmp, +			    lml->lm_head);  		return (ghp);  	} @@ -688,7 +687,7 @@ dlmopen_core(Lm_list *lml, const char *path, int mode, Rt_map *clmp,  	 * Create a new link-map control list for this request, and load the  	 * associated object.  	 */ -	if ((lmc = alist_append(&(lml->lm_lists), 0, sizeof (Lm_cntl), +	if ((lmc = alist_append(&lml->lm_lists, 0, sizeof (Lm_cntl),  	    AL_CNT_LMLISTS)) == 0) {  		remove_pnode(pnp);  		return (0); @@ -720,7 +719,7 @@ dlmopen_core(Lm_list *lml, const char *path, int mode, Rt_map *clmp,  		remove_cntl(lml, olmco);  		lml = LIST(nlmp);  		olmco = 0; -		nlmco = ALO_DATA; +		nlmco = ALIST_OFF_DATA;  	}  	/* @@ -1064,9 +1063,9 @@ dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo)  		 * link-maps.  		 */  		Grp_desc	*gdp; -		Aliste		off; +		Aliste		idx; -		for (ALIST_TRAVERSE(ghp->gh_depends, off, gdp)) { +		for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {  			if ((gdp->gd_flags & GPD_DLSYM) == 0)  				continue; @@ -1089,7 +1088,7 @@ dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo)  			DBG_CALL(Dbg_syms_lazy_rescan(LIST(lmp), name)); -			for (ALIST_TRAVERSE(ghp->gh_depends, off, gdp)) { +			for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {  				nlmp = gdp->gd_depend;  				if (((gdp->gd_flags & GPD_DLSYM) == 0) || @@ -1301,7 +1300,7 @@ dlsym_intn(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)  {  	Rt_map		*llmp = 0;  	void		*error; -	Aliste		off; +	Aliste		idx;  	Grp_desc	*gdp;  	/* @@ -1319,7 +1318,7 @@ dlsym_intn(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)  		if (ghp->gh_ownlmp)  			llmp = LIST(ghp->gh_ownlmp)->lm_tail;  		else { -			for (ALIST_TRAVERSE(ghp->gh_depends, off, gdp)) { +			for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {  				if ((llmp = LIST(gdp->gd_depend)->lm_tail) != 0)  					break;  			} diff --git a/usr/src/cmd/sgs/rtld/common/elf.c b/usr/src/cmd/sgs/rtld/common/elf.c index 9d3a21547d..42589fff1e 100644 --- a/usr/src/cmd/sgs/rtld/common/elf.c +++ b/usr/src/cmd/sgs/rtld/common/elf.c @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -250,7 +250,7 @@ elf_rtld_load()  	 * As we need to refer to the DYNINFO() information, insure that it has  	 * been initialized.  	 */ -	if (elf_needed(lml, ALO_DATA, lmp) == 0) +	if (elf_needed(lml, ALIST_OFF_DATA, lmp) == 0)  		return (0);  #if	defined(__i386) @@ -320,7 +320,7 @@ elf_lazy_load(Rt_map *clmp, uint_t ndx, const char *sym)  	 */  	hlmp = lml->lm_head;  	if (FLAGS(hlmp) & FLG_RT_RELOCED) { -		if ((lmc = alist_append(&(lml->lm_lists), 0, sizeof (Lm_cntl), +		if ((lmc = alist_append(&lml->lm_lists, 0, sizeof (Lm_cntl),  		    AL_CNT_LMLISTS)) == 0) {  			remove_pnode(pnp);  			return (0); @@ -328,7 +328,7 @@ elf_lazy_load(Rt_map *clmp, uint_t ndx, const char *sym)  		lmco = (Aliste)((char *)lmc - (char *)lml->lm_lists);  	} else {  		lmc = 0; -		lmco = ALO_DATA; +		lmco = ALIST_OFF_DATA;  	}  	/* @@ -1350,15 +1350,13 @@ _elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)  		    (LML_FLG_TRC_UNREF | LML_FLG_TRC_UNUSED));  		if (tracing || DBG_ENABLED) { -			Bnd_desc **	bdpp; -			Aliste		off; +			Bnd_desc 	*bdp; +			Aliste		idx;  			FLAGS1(ilmp) |= FL1_RT_USED;  			if ((tracing & LML_FLG_TRC_UNREF) || DBG_ENABLED) { -				for (ALIST_TRAVERSE(CALLERS(ilmp), off, bdpp)) { -					Bnd_desc *	bdp = *bdpp; - +				for (APLIST_TRAVERSE(CALLERS(ilmp), idx, bdp)) {  					if (bdp->b_caller == clmp) {  						bdp->b_flags |= BND_REFER;  						break; @@ -1437,14 +1435,14 @@ _elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)  			Aliste	lmco;  			if (FLAGS(lml->lm_head) & FLG_RT_RELOCED) { -				if ((lmc = alist_append(&(lml->lm_lists), 0, +				if ((lmc = alist_append(&lml->lm_lists, 0,  				    sizeof (Lm_cntl), AL_CNT_LMLISTS)) == 0)  					return ((Sym *)0);  				lmco = (Aliste)((char *)lmc -  				    (char *)lml->lm_lists);  			} else {  				lmc = 0; -				lmco = ALO_DATA; +				lmco = ALIST_OFF_DATA;  			}  			pnp = hwcap_filtees(pnpp, lmco, lmc, dip, ilmp, filtees, @@ -1527,7 +1525,7 @@ _elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)  				 */  				if (FLAGS(lml->lm_head) & FLG_RT_RELOCED) {  					if ((lmc = -					    alist_append(&(lml->lm_lists), 0, +					    alist_append(&lml->lm_lists, 0,  					    sizeof (Lm_cntl),  					    AL_CNT_LMLISTS)) == 0)  						return ((Sym *)0); @@ -1535,7 +1533,7 @@ _elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)  					    (char *)lml->lm_lists);  				} else {  					lmc = 0; -					lmco = ALO_DATA; +					lmco = ALIST_OFF_DATA;  				}  				/* @@ -1642,7 +1640,7 @@ _elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)  		if (name) {  			Grp_desc	*gdp;  			Sym		*sym = 0; -			Aliste		off; +			Aliste		idx;  			Slookup		sl = *slp;  			sl.sl_flags |= LKUP_FIRST; @@ -1651,7 +1649,7 @@ _elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)  			/*  			 * Look for the symbol in the handles dependencies.  			 */ -			for (ALIST_TRAVERSE(ghp->gh_depends, off, gdp)) { +			for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {  				if ((gdp->gd_flags & GPD_DLSYM) == 0)  					continue; @@ -2988,7 +2986,7 @@ elf_copy_reloc(char *name, Sym *rsym, Rt_map *rlmp, void *radd, Sym *dsym,  	else  		rc.r_size = (size_t)rsym->st_size; -	if (alist_append(©(dlmp), &rc, sizeof (Rel_copy), +	if (alist_append(©_R(dlmp), &rc, sizeof (Rel_copy),  	    AL_CNT_COPYREL) == 0) {  		if (!(lml->lm_flags & LML_FLG_TRC_WARN))  			return (0); @@ -2996,8 +2994,8 @@ elf_copy_reloc(char *name, Sym *rsym, Rt_map *rlmp, void *radd, Sym *dsym,  			return (1);  	}  	if (!(FLAGS1(dlmp) & FL1_RT_COPYTOOK)) { -		if (alist_append(©(rlmp), &dlmp, -		    sizeof (Rt_map *), AL_CNT_COPYREL) == 0) { +		if (aplist_append(©_S(rlmp), dlmp, +		    AL_CNT_COPYREL) == NULL) {  			if (!(lml->lm_flags & LML_FLG_TRC_WARN))  				return (0);  			else @@ -3238,16 +3236,16 @@ elf_dladdr(ulong_t addr, Rt_map *lmp, Dl_info *dlip, void **info, int flags)  }  static void -elf_lazy_cleanup(Alist *alp) +elf_lazy_cleanup(APlist *alp)  { -	Rt_map	**lmpp; -	Aliste	off; +	Rt_map	*lmp; +	Aliste	idx;  	/*  	 * Cleanup any link-maps added to this dynamic list and free it.  	 */ -	for (ALIST_TRAVERSE(alp, off, lmpp)) -		FLAGS(*lmpp) &= ~FLG_RT_DLSYM; +	for (APLIST_TRAVERSE(alp, idx, lmp)) +		FLAGS(lmp) &= ~FLG_RT_DLSYM;  	free(alp);  } @@ -3270,16 +3268,16 @@ Sym *  elf_lazy_find_sym(Slookup *slp, Rt_map **_lmp, uint_t *binfo)  {  	Sym		*sym = 0; -	Alist *		alist = 0; -	Aliste		off; -	Rt_map **	lmpp, *	lmp = slp->sl_imap; +	APlist		*alist = NULL; +	Aliste		idx; +	Rt_map		*lmp1, *lmp = slp->sl_imap;  	const char	*name = slp->sl_name; -	if (alist_append(&alist, &lmp, sizeof (Rt_map *), AL_CNT_LAZYFIND) == 0) -		return (0); +	if (aplist_append(&alist, lmp, AL_CNT_LAZYFIND) == NULL) +		return (NULL);  	FLAGS(lmp) |= FLG_RT_DLSYM; -	for (ALIST_TRAVERSE(alist, off, lmpp)) { +	for (APLIST_TRAVERSE(alist, idx, lmp1)) {  		uint_t	cnt = 0;  		Slookup	sl = *slp;  		Dyninfo	*dip; @@ -3290,7 +3288,7 @@ elf_lazy_find_sym(Slookup *slp, Rt_map **_lmp, uint_t *binfo)  		 * added to the alist, so that its DT_NEEDED entires may be  		 * examined.  		 */ -		lmp = *lmpp; +		lmp = lmp1;  		for (dip = DYNINFO(lmp); cnt < DYNINFOCNT(lmp); cnt++, dip++) {  			Rt_map *nlmp; @@ -3335,8 +3333,8 @@ elf_lazy_find_sym(Slookup *slp, Rt_map **_lmp, uint_t *binfo)  			 * build our own dynamic dependency list.  			 */  			if ((sl.sl_flags & LKUP_NODESCENT) == 0) { -				if (alist_append(&alist, &nlmp, -				    sizeof (Rt_map *), AL_CNT_LAZYFIND) == 0) { +				if (aplist_append(&alist, nlmp, +				    AL_CNT_LAZYFIND) == 0) {  					elf_lazy_cleanup(alist);  					return (0);  				} diff --git a/usr/src/cmd/sgs/rtld/common/external.c b/usr/src/cmd/sgs/rtld/common/external.c index f47f900035..c17b5f1f77 100644 --- a/usr/src/cmd/sgs/rtld/common/external.c +++ b/usr/src/cmd/sgs/rtld/common/external.c @@ -367,10 +367,10 @@ int  rt_get_extern(Lm_list *lml, Rt_map *lmp)  {  	if (lml->lm_rti) { -		Aliste		off; +		Aliste		idx;  		Rti_desc	*rti; -		for (ALIST_TRAVERSE(lml->lm_rti, off, rti)) +		for (ALIST_TRAVERSE(lml->lm_rti, idx, rti))  			get_lcinterface(rti->rti_lmp, rti->rti_info);  		free(lml->lm_rti); diff --git a/usr/src/cmd/sgs/rtld/common/object.c b/usr/src/cmd/sgs/rtld/common/object.c index 5886d7ab15..ec5968d7b9 100644 --- a/usr/src/cmd/sgs/rtld/common/object.c +++ b/usr/src/cmd/sgs/rtld/common/object.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -225,9 +225,9 @@ elf_obj_fini(Lm_list *lml, Rt_map *lmp)  	 */  	NEXT((Rt_map *)PREV(nlmp)) = 0;  	/* LINTED */ -	lmc = (Lm_cntl *)((char *)lml->lm_lists + CNTL(nlmp)); +	lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, CNTL(nlmp));  	lmc->lc_tail = (Rt_map *)PREV(nlmp); -	if (CNTL(nlmp) == ALO_DATA) +	if (CNTL(nlmp) == ALIST_OFF_DATA)  		lml->lm_tail = (Rt_map *)PREV(nlmp);  	lml->lm_obj--; diff --git a/usr/src/cmd/sgs/rtld/common/remove.c b/usr/src/cmd/sgs/rtld/common/remove.c index 68a73cd579..efb517656a 100644 --- a/usr/src/cmd/sgs/rtld/common/remove.c +++ b/usr/src/cmd/sgs/rtld/common/remove.c @@ -19,7 +19,7 @@   * CDDL HEADER END   *   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   *   * Remove objects.  Objects need removal from a process as part of: @@ -291,11 +291,11 @@ remove_so(Lm_list *lml, Rt_map *lmp)  	 * Remove any alias names.  	 */  	if (ALIAS(lmp)) { -		Aliste	off; -		char	**cpp; +		Aliste	idx; +		char	*cp; -		for (ALIST_TRAVERSE(ALIAS(lmp), off, cpp)) -			free(*cpp); +		for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp)) +			free(cp);  		free(ALIAS(lmp));  	} @@ -331,8 +331,14 @@ remove_so(Lm_list *lml, Rt_map *lmp)  	if (CONDVAR(lmp))  		free(CONDVAR(lmp)); -	if (COPY(lmp)) -		free(COPY(lmp)); +	/* +	 * Note that COPY_R() and COPY_S() reference the same memory +	 * location, and that we want to release the memory referenced +	 * without regard to which list it logically belongs to. We can +	 * use either pointer to do this. +	 */ +	if (COPY_R(lmp)) +		free(COPY_R(lmp));  	if (MMAPS(lmp))  		free(MMAPS(lmp)); @@ -343,20 +349,19 @@ remove_so(Lm_list *lml, Rt_map *lmp)  	 * Therefore if this object indicates that its part of a group tear  	 * these associations down.  	 */ -	if (GROUPS(lmp)) { -		Aliste	off1; -		Grp_hdl	**ghpp; +	if (GROUPS(lmp) != NULL) { +		Aliste	idx1; +		Grp_hdl	*ghp; -		for (ALIST_TRAVERSE(GROUPS(lmp), off1, ghpp)) { -			Grp_hdl		*ghp = *ghpp; +		for (APLIST_TRAVERSE(GROUPS(lmp), idx1, ghp)) {  			Grp_desc	*gdp; -			Aliste		off2; +			Aliste		idx2; -			for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { +			for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {  				if (gdp->gd_depend != lmp)  					continue; -				(void) alist_delete(ghp->gh_depends, 0, &off2); +				alist_delete(ghp->gh_depends, &idx2);  				break;  			}  		} @@ -424,32 +429,30 @@ remove_so(Lm_list *lml, Rt_map *lmp)  void  remove_lists(Rt_map *lmp, int lazy)  { -	Aliste		off1; -	Bnd_desc	**bdpp; +	Aliste		idx1; +	Bnd_desc	*bdp;  	/*  	 * First, traverse this objects dependencies.  	 */ -	for (ALIST_TRAVERSE(DEPENDS(lmp), off1, bdpp)) { -		Bnd_desc	*bdp = *bdpp; +	for (APLIST_TRAVERSE(DEPENDS(lmp), idx1, bdp)) {  		Rt_map		*dlmp = bdp->b_depend;  		/*  		 * Remove this object from the dependencies callers.  		 */ -		(void) alist_delete(CALLERS(dlmp), &bdp, 0); +		(void) aplist_delete_value(CALLERS(dlmp), bdp);  		free(bdp);  	}  	if (DEPENDS(lmp)) {  		free(DEPENDS(lmp)); -		DEPENDS(lmp) = 0; +		DEPENDS(lmp) = NULL;  	}  	/*  	 * Second, traverse this objects callers.  	 */ -	for (ALIST_TRAVERSE(CALLERS(lmp), off1,  bdpp)) { -		Bnd_desc	*bdp = *bdpp; +	for (APLIST_TRAVERSE(CALLERS(lmp), idx1,  bdp)) {  		Rt_map		*clmp = bdp->b_caller;  		/* @@ -482,12 +485,12 @@ remove_lists(Rt_map *lmp, int lazy)  			}  		} -		(void) alist_delete(DEPENDS(clmp), &bdp, 0); +		(void) aplist_delete_value(DEPENDS(clmp), bdp);  		free(bdp);  	}  	if (CALLERS(lmp)) {  		free(CALLERS(lmp)); -		CALLERS(lmp) = 0; +		CALLERS(lmp) = NULL;  	}  } @@ -497,17 +500,19 @@ remove_lists(Rt_map *lmp, int lazy)  void  remove_cntl(Lm_list *lml, Aliste lmco)  { -	if (lmco && (lmco != ALO_DATA)) { +	if (lmco && (lmco != ALIST_OFF_DATA)) {  		Aliste	_lmco = lmco;  #if	DEBUG -		Lm_cntl	*lmc = (Lm_cntl *)((char *)lml->lm_lists + lmco); +		Lm_cntl	*lmc; + +		lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, lmco);  		/*  		 * This element should be empty.  		 */  		ASSERT(lmc->lc_head == 0);  #endif -		(void) alist_delete(lml->lm_lists, 0, &_lmco); +		alist_delete_by_offset(lml->lm_lists, &_lmco);  	}  } @@ -523,7 +528,7 @@ remove_incomplete(Lm_list *lml, Aliste lmco)  	Lm_cntl	*lmc;  	/* LINTED */ -	lmc = (Lm_cntl *)((char *)lml->lm_lists + lmco); +	lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, lmco);  	/*  	 * First, remove any lists that may point between objects. @@ -545,12 +550,12 @@ remove_incomplete(Lm_list *lml, Aliste lmco)  /*   * Determine whether an object is deletable.   */ -int -is_deletable(Alist **lmalp, Alist **ghalp, Rt_map *lmp) +static int +is_deletable(APlist **lmalp, APlist **ghalp, Rt_map *lmp)  { -	Aliste		off; -	Bnd_desc	**bdpp; -	Grp_hdl		**ghpp; +	Aliste		idx; +	Bnd_desc	*bdp; +	Grp_hdl		*ghp;  	/*  	 * If the object hasn't yet been relocated take this as a sign that @@ -559,7 +564,7 @@ is_deletable(Alist **lmalp, Alist **ghalp, Rt_map *lmp)  	 * and exists on the main link-map control list.  	 */  	if ((FLAGS(lmp) & FLG_RT_RELOCED) && -	    (MODE(lmp) & RTLD_NODELETE) && (CNTL(lmp) == ALO_DATA)) +	    (MODE(lmp) & RTLD_NODELETE) && (CNTL(lmp) == ALIST_OFF_DATA))  		return (0);  	/* @@ -573,9 +578,8 @@ is_deletable(Alist **lmalp, Alist **ghalp, Rt_map *lmp)  	 * callers registered for itself.  Thus, but looking for objects with  	 * handles we can ferret out these outsiders.  	 */ -	for (ALIST_TRAVERSE(HANDLES(lmp), off, ghpp)) { -		if (alist_test(ghalp, *ghpp, -		    sizeof (Grp_hdl *), 0) != ALE_EXISTS) +	for (APLIST_TRAVERSE(HANDLES(lmp), idx, ghp)) { +		if (aplist_test(ghalp, ghp, 0) != ALE_EXISTS)  			return (0);  	} @@ -583,9 +587,9 @@ is_deletable(Alist **lmalp, Alist **ghalp, Rt_map *lmp)  	 * If this object is called by any object outside of the family of  	 * objects selected for deletion, it can't be deleted.  	 */ -	for (ALIST_TRAVERSE(CALLERS(lmp), off, bdpp)) { -		if (alist_test(lmalp, (*bdpp)->b_caller, -		    sizeof (Rt_map *), 0) != ALE_EXISTS) +	for (APLIST_TRAVERSE(CALLERS(lmp), idx, bdp)) { +		if (aplist_test(lmalp, bdp->b_caller, 0) != +		    ALE_EXISTS)  			return (0);  	} @@ -601,9 +605,9 @@ is_deletable(Alist **lmalp, Alist **ghalp, Rt_map *lmp)   * enced from the objects within the groups that are candidates for deletion.   */  static int -gdp_collect(Alist **ghalpp, Alist **lmalpp, Grp_hdl *ghp1) +gdp_collect(APlist **ghalpp, APlist **lmalpp, Grp_hdl *ghp1)  { -	Aliste		off; +	Aliste		idx;  	Grp_desc	*gdp;  	int		action; @@ -611,15 +615,15 @@ gdp_collect(Alist **ghalpp, Alist **lmalpp, Grp_hdl *ghp1)  	 * Add this group to our group collection.  If it isn't added either an  	 * allocation has failed, or it already exists.  	 */ -	if ((action = alist_test(ghalpp, ghp1, sizeof (Grp_hdl *), -	    AL_CNT_GRPCLCT)) != ALE_CREATE) +	if ((action = aplist_test(ghalpp, ghp1, AL_CNT_GRPCLCT)) != +	    ALE_CREATE)  		return (action);  	/*  	 * Traverse the dependencies of the group and collect the associated  	 * objects.  	 */ -	for (ALIST_TRAVERSE(ghp1->gh_depends, off, gdp)) { +	for (ALIST_TRAVERSE(ghp1->gh_depends, idx, gdp)) {  		Rt_map	*lmp = gdp->gd_depend;  		/* @@ -632,8 +636,8 @@ gdp_collect(Alist **ghalpp, Alist **lmalpp, Grp_hdl *ghp1)  		    ((gdp->gd_flags & GPD_ADDEPS) == 0))  			continue; -		if ((action = alist_test(lmalpp, lmp, sizeof (Rt_map *), -		    AL_CNT_GRPCLCT)) == 0) +		if ((action = aplist_test(lmalpp, lmp, AL_CNT_GRPCLCT)) == +		    ALE_ALLOCFAIL)  			return (0);  		if (action == ALE_EXISTS)  			continue; @@ -653,7 +657,7 @@ gdp_collect(Alist **ghalpp, Alist **lmalpp, Grp_hdl *ghp1)  		 *  .   the object isn't tagged as non-deletable.  		 */  		if ((((FLAGS(lmp) & FLG_RT_RELOCED) == 0) || -		    (CNTL(lmp) != ALO_DATA) || +		    (CNTL(lmp) != ALIST_OFF_DATA) ||  		    ((MODE(lmp) & RTLD_NODELETE) == 0)) &&  		    (FLAGS1(lmp) & MSK_RT_FILTER)) {  			Dyninfo	*dip = DYNINFO(lmp); @@ -691,16 +695,15 @@ gdp_collect(Alist **ghalpp, Alist **lmalpp, Grp_hdl *ghp1)   * any deletions pending we can discontinue any further processing.   */  static int -remove_rescan(Alist *lmalp, Alist *ghalp, int *delcnt) +remove_rescan(APlist *lmalp, APlist *ghalp, int *delcnt)  { -	Aliste		off1; -	Rt_map		**lmpp; +	Aliste		idx1; +	Rt_map		*lmp;  	int		rescan = 0; -	for (ALIST_TRAVERSE(lmalp, off1, lmpp)) { -		Aliste		off2; -		Bnd_desc	**bdpp; -		Rt_map		*lmp = *lmpp; +	for (APLIST_TRAVERSE(lmalp, idx1, lmp)) { +		Aliste		idx2; +		Bnd_desc	*bdp;  		Dyninfo		*dip;  		uint_t		cnt, max; @@ -711,8 +714,8 @@ remove_rescan(Alist *lmalp, Alist *ghalp, int *delcnt)  		 * As this object can't be deleted, make sure its dependencies  		 * aren't deleted either.  		 */ -		for (ALIST_TRAVERSE(DEPENDS(lmp), off2, bdpp)) { -			Rt_map	*dlmp = (*bdpp)->b_depend; +		for (APLIST_TRAVERSE(DEPENDS(lmp), idx2, bdp)) { +			Rt_map	*dlmp = bdp->b_depend;  			if (FLAGS(dlmp) & FLG_RT_DELETE) {  				FLAGS(dlmp) &= ~FLG_RT_DELETE; @@ -748,11 +751,11 @@ remove_rescan(Alist *lmalp, Alist *ghalp, int *delcnt)  				    ((ghp = (Grp_hdl *)pnp->p_info) == 0))  					continue; -				if (alist_test(&ghalp, ghp, -				    sizeof (Grp_hdl *), 0) == ALE_EXISTS) +				if (aplist_test(&ghalp, ghp, 0) == +				    ALE_EXISTS)  					continue; -				for (ALIST_TRAVERSE(ghp->gh_depends, off2, +				for (ALIST_TRAVERSE(ghp->gh_depends, idx2,  				    gdp)) {  					Rt_map	*dlmp = gdp->gd_depend; @@ -768,7 +771,7 @@ remove_rescan(Alist *lmalp, Alist *ghalp, int *delcnt)  				 * Remove this group handle from our dynamic  				 * deletion list.  				 */ -				(void) alist_delete(ghalp, &ghp, 0); +				(void) aplist_delete_value(ghalp, ghp);  			}  		}  	} @@ -779,7 +782,7 @@ remove_rescan(Alist *lmalp, Alist *ghalp, int *delcnt)   * Cleanup any collection alists we've created.   */  static void -remove_collect(Alist *ghalp, Alist *lmalp) +remove_collect(APlist *ghalp, APlist *lmalp)  {  	if (ghalp)  		free(ghalp); @@ -799,17 +802,17 @@ void  free_hdl(Grp_hdl *ghp, Rt_map *clmp, uint_t cdflags)  {  	Grp_desc	*gdp; -	Aliste		off; +	Aliste		idx;  	if (--(ghp->gh_refcnt) == 0) {  		uintptr_t	ndx; -		for (ALIST_TRAVERSE(ghp->gh_depends, off, gdp)) { +		for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {  			Rt_map	*lmp = gdp->gd_depend;  			if (ghp->gh_ownlmp == lmp) -				(void) alist_delete(HANDLES(lmp), &ghp, 0); -			(void) alist_delete(GROUPS(lmp), &ghp, 0); +				(void) aplist_delete_value(HANDLES(lmp), ghp); +			(void) aplist_delete_value(GROUPS(lmp), ghp);  		}  		(void) free(ghp->gh_depends); @@ -827,15 +830,15 @@ free_hdl(Grp_hdl *ghp, Rt_map *clmp, uint_t cdflags)  		 * from the handle, or if the caller is used for any other  		 * reason, clear the promotion flag.  		 */ -		for (ALIST_TRAVERSE(ghp->gh_depends, off, gdp)) { +		for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {  			Rt_map	*lmp = gdp->gd_depend;  			if (lmp != clmp)  				continue;  			if (gdp->gd_flags == cdflags) { -				(void) alist_delete(ghp->gh_depends, 0, &off); -				(void) alist_delete(GROUPS(lmp), &ghp, 0); +				alist_delete(ghp->gh_depends, &idx); +				(void) aplist_delete_value(GROUPS(lmp), ghp);  			} else {  				gdp->gd_flags &= ~cdflags;  			} @@ -874,7 +877,7 @@ remove_lmc(Lm_list *lml, Rt_map *clmp, Lm_cntl *lmc, Aliste lmco,  {  	Grp_hdl		*ghp;  	Grp_desc	*gdp; -	Aliste		off; +	Aliste		idx;  	Rt_map		*lmp;  	DBG_CALL(Dbg_file_cleanup(lml, name, lmco)); @@ -886,7 +889,7 @@ remove_lmc(Lm_list *lml, Rt_map *clmp, Lm_cntl *lmc, Aliste lmco,  	 */  	lmp = lmc->lc_head;  	if (HANDLES(lmp)) { -		ghp = (Grp_hdl *)HANDLES(lmp)->al_data[0]; +		ghp = (Grp_hdl *)HANDLES(lmp)->apl_data[0];  	} else if (lmc->lc_flags & LMC_FLG_RELOCATING) {  		/* @@ -933,7 +936,7 @@ remove_lmc(Lm_list *lml, Rt_map *clmp, Lm_cntl *lmc, Aliste lmco,  	 * must be broken to allow the objects on this link-map list to be  	 * removed.  	 */ -	for (ALIST_TRAVERSE(ghp->gh_depends, off, gdp)) { +	for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {  		Rt_map	*lmp = gdp->gd_depend;  		/* @@ -966,8 +969,8 @@ remove_lmc(Lm_list *lml, Rt_map *clmp, Lm_cntl *lmc, Aliste lmco,  				}  			}  		} -		(void) alist_delete(GROUPS(lmp), &ghp, 0); -		(void) alist_delete(ghp->gh_depends, 0, &off); +		(void) aplist_delete_value(GROUPS(lmp), ghp); +		alist_delete(ghp->gh_depends, &idx);  	}  	/* @@ -988,7 +991,7 @@ remove_lmc(Lm_list *lml, Rt_map *clmp, Lm_cntl *lmc, Aliste lmco,  		plmco = lmco - lml->lm_lists->al_size;  		/* LINTED */ -		plmc = (Lm_cntl *)((char *)lml->lm_lists + plmco); +		plmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, plmco);  		lm_move(lml, lmco, plmco, lmc, plmc);  	} @@ -1025,14 +1028,14 @@ remove_lmc(Lm_list *lml, Rt_map *clmp, Lm_cntl *lmc, Aliste lmco,  int  remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  { -	Rt_map		*lmp, **lmpp; +	Rt_map		*lmp;  	int		rescan = 0;  	int		delcnt = 0, rmcnt = 0, error = 0, orphans; -	Alist		*lmalp = 0, *ghalp = 0; -	Aliste		off1, off2; -	Grp_hdl		**ghpp; +	APlist		*lmalp = NULL, *ghalp = NULL; +	Aliste		idx1, idx2; +	Grp_hdl		*ghp2;  	Grp_desc	*gdp; -	Lm_list		*lml = 0; +	Lm_list		*lml = NULL;  	/*  	 * Generate the family of groups and objects that are candidates for @@ -1053,8 +1056,8 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  	 * of the family of objects collected for this deletion, it can not be  	 * removed.  	 */ -	for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { -		Grp_hdl	*ghp = *ghpp; +	for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) { +		Grp_hdl	*ghp = ghp2;  		DBG_CALL(Dbg_file_hdl_collect(ghp, 0)); @@ -1070,13 +1073,13 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  		if (ghp->gh_flags & GPH_LDSO) {  			DBG_CALL(Dbg_file_hdl_collect(ghp,  			    NAME(lml_rtld.lm_head))); -			(void) alist_delete(ghalp, 0, &off1); +			aplist_delete(ghalp, &idx1);  			continue;  		} -		for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { -			Grp_hdl	**ghpp3; -			Aliste	off3; +		for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) { +			Grp_hdl	*ghp3; +			Aliste	idx3;  			/*  			 * Determine whether this dependency is the filtee's @@ -1088,8 +1091,8 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  			    (GPD_FILTER | GPD_ADDEPS)) != GPD_FILTER)  				continue; -			if (alist_test(&lmalp, gdp->gd_depend, -			    sizeof (Rt_map *), 0) == ALE_EXISTS) +			if (aplist_test(&lmalp, gdp->gd_depend, 0) == +			    ALE_EXISTS)  				continue;  			/* @@ -1100,21 +1103,20 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  			 */  			DBG_CALL(Dbg_file_hdl_collect(ghp,  			    NAME(gdp->gd_depend))); -			(void) alist_delete(ghalp, 0, &off1); +			aplist_delete(ghalp, &idx1);  			free(lmalp); -			lmalp = 0; -			for (ALIST_TRAVERSE(ghalp, off3, ghpp3)) { -				Aliste		off4; +			lmalp = NULL; +			for (APLIST_TRAVERSE(ghalp, idx3, ghp3)) { +				Aliste		idx4;  				Grp_desc	*gdp4; -				for (ALIST_TRAVERSE((*ghpp3)->gh_depends, -				    off4, gdp4))  { +				for (ALIST_TRAVERSE(ghp3->gh_depends, +				    idx4, gdp4))  {  					if ((gdp4->gd_flags & GPD_ADDEPS) == 0)  						continue; -					if (alist_test(&lmalp, gdp4->gd_depend, -					    sizeof (Rt_map *), -					    AL_CNT_GRPCLCT) == 0) { +					if (aplist_test(&lmalp, gdp4->gd_depend, +					    AL_CNT_GRPCLCT) == ALE_ALLOCFAIL) {  						remove_collect(ghalp, lmalp);  						return (0);  					} @@ -1128,9 +1130,7 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  	 * Now that we've collected all the handles dependencies, traverse the  	 * collection determining whether they are a candidate for deletion.  	 */ -	for (ALIST_TRAVERSE(lmalp, off1, lmpp)) { -		lmp = *lmpp; - +	for (APLIST_TRAVERSE(lmalp, idx1, lmp)) {  		/*  		 * Establish which link-map list we're dealing with for later  		 * .fini processing. @@ -1161,8 +1161,8 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  	 * for removal, mark each group descriptor as a candidate for removal  	 * from the group.  	 */ -	for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { -		for (ALIST_TRAVERSE((*ghpp)->gh_depends, off2, gdp)) +	for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) { +		for (ALIST_TRAVERSE(ghp2->gh_depends, idx2, gdp))  			gdp->gd_flags |= GPD_REMOVE;  	} @@ -1171,22 +1171,22 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  	 * determine whether they still need to remain identified as belonging  	 * to this group to be able to continue binding to one another.  	 */ -	for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { -		Grp_hdl	*ghp = *ghpp; +	for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) { +		Grp_hdl	*ghp = ghp2; -		for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { -			Aliste		off3; -			Bnd_desc	**bdpp; +		for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) { +			Aliste		idx3; +			Bnd_desc	*bdp;  			lmp = gdp->gd_depend;  			if (FLAGS(lmp) & FLG_RT_DELETE)  				continue; -			for (ALIST_TRAVERSE(DEPENDS(lmp), off3, bdpp)) { -				Aliste 		off4; +			for (APLIST_TRAVERSE(DEPENDS(lmp), idx3, bdp)) { +				Aliste 		idx4;  				Grp_desc	*gdp4; -				Rt_map		*dlmp = (*bdpp)->b_depend; +				Rt_map		*dlmp = bdp->b_depend;  				/*  				 * If this dependency (dlmp) can be referenced @@ -1209,7 +1209,7 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  					gdp->gd_flags &= ~GPD_REMOVE;  				for (ALIST_TRAVERSE(ghp->gh_depends, -				    off4, gdp4)) { +				    idx4, gdp4)) {  					if (gdp4->gd_depend != dlmp)  						continue; @@ -1230,8 +1230,8 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  	 * list, so that it can be re-associated to the owner if a dlopen()  	 * of this object reoccurs.  	 */ -	for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { -		Grp_hdl	*ghp = *ghpp; +	for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) { +		Grp_hdl	*ghp = ghp2;  		/*  		 * If this handle is already an orphan, or if it's owner is @@ -1245,7 +1245,7 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  		 * Make sure all handle dependencies aren't removed or the  		 * dependencies themselves aren't deleted.  		 */ -		for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { +		for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {  			lmp = gdp->gd_depend;  			/* @@ -1273,12 +1273,12 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  	 * performed on the collected handles before firing .fini's (which  	 * produces additional diagnostics).  	 */ -	for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { -		Grp_hdl	*ghp = *ghpp; +	for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) { +		Grp_hdl	*ghp = ghp2;  		DBG_CALL(Dbg_file_hdl_title(DBG_HDL_DELETE)); -		for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { +		for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {  			int	flag;  			lmp = gdp->gd_depend; @@ -1351,8 +1351,8 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  		 * call_fini(), but as the link-maps CALLERS was removed  		 * already we do the local auditors explicitly.  		 */ -		for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { -			Grp_hdl	*ghp = *ghpp; +		for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) { +			Grp_hdl	*ghp = ghp2;  			Rt_map	*dlmp = ghp->gh_ownlmp;  			if (clmp && dlmp && @@ -1368,12 +1368,10 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  	 * is complete, remove all inter-dependency lists from those objects  	 * selected for deletion.  	 */ -	for (ALIST_TRAVERSE(lmalp, off1, lmpp)) { +	for (APLIST_TRAVERSE(lmalp, idx1, lmp)) {  		Dyninfo	*dip;  		uint_t	cnt, max; -		lmp = *lmpp; -  		if (FLAGS(lmp) & FLG_RT_DELETE)  			remove_lists(lmp, 0); @@ -1406,8 +1404,7 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  				 * Determine whether this filtee's handle is a  				 * part of the list of handles being deleted.  				 */ -				if (alist_test(&ghalp, ghp, -				    sizeof (Grp_hdl *), 0) == ALE_EXISTS) { +				if (aplist_test(&ghalp, ghp, 0) == ALE_EXISTS) {  					/*  					 * If this handle exists on the deletion  					 * list, then it has been removed.  If @@ -1448,8 +1445,8 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  	 * Finally remove any handle infrastructure and remove any objects  	 * marked for deletion.  	 */ -	for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { -		Grp_hdl	*ghp = *ghpp; +	for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) { +		Grp_hdl	*ghp = ghp2;  		/*  		 * If we're not dealing with orphaned handles remove this handle @@ -1469,7 +1466,7 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  		 * information is deleted as part of the alist removal that  		 * occurs before we inspect the object for deletion).  		 */ -		for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { +		for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {  			uint_t	flags = gdp->gd_flags;  			if ((flags & GPD_REMOVE) == 0) @@ -1483,12 +1480,12 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  			 * association in case the handle is retained.  			 */  			if (ghp->gh_ownlmp == lmp) { -				(void) alist_delete(HANDLES(lmp), &ghp, 0); +				(void) aplist_delete_value(HANDLES(lmp), ghp);  				ghp->gh_ownlmp = 0;  			} -			(void) alist_delete(GROUPS(lmp), &ghp, 0); -			(void) alist_delete(ghp->gh_depends, 0, &off2); +			(void) aplist_delete_value(GROUPS(lmp), ghp); +			alist_delete(ghp->gh_depends, &idx2);  			/*  			 * Complete the link-map deletion if appropriate. @@ -1517,7 +1514,7 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  		 * handles are re-examined to determine if their deletion can  		 * be completed.  		 */ -		if (ghp->gh_depends->al_data[0] == 0) { +		if (ghp->gh_depends->al_nitems == 0) {  			free(ghp->gh_depends);  			free(ghp); @@ -1530,7 +1527,7 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)  			if (DBG_ENABLED) {  				DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ORPHAN)); -				for (ALIST_TRAVERSE(ghp->gh_depends, off1, gdp)) +				for (ALIST_TRAVERSE(ghp->gh_depends, idx1, gdp))  					DBG_CALL(Dbg_file_hdl_action(ghp,  					    gdp->gd_depend, DBG_DEP_ORPHAN, 0));  			} diff --git a/usr/src/cmd/sgs/rtld/common/setup.c b/usr/src/cmd/sgs/rtld/common/setup.c index b373e3aa99..0ea14d3c7c 100644 --- a/usr/src/cmd/sgs/rtld/common/setup.c +++ b/usr/src/cmd/sgs/rtld/common/setup.c @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -113,7 +113,7 @@ preload(const char *str, Rt_map *lmp)  		if (rtld_flags & RT_FL_SECURE)  			rtld_flags2 |= RT_FL2_FTL2WARN;  		if ((pnp = expand_paths(clmp, ptr, PN_SER_EXTLOAD, 0)) != 0) -			nlmp = load_one(&lml_main, ALO_DATA, pnp, clmp, +			nlmp = load_one(&lml_main, ALIST_OFF_DATA, pnp, clmp,  			    MODE(lmp), flags, 0);  		if (pnp)  			remove_pnode(pnp); @@ -354,8 +354,8 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,  	 * Create a link map structure for ld.so.1.  	 */  	if ((rlmp = elf_new_lm(&lml_rtld, _rtldname, rtldname, dyn_ptr, ld_base, -	    (ulong_t)&_etext, ALO_DATA, (ulong_t)(eaddr - ld_base), 0, ld_base, -	    (ulong_t)(eaddr - ld_base), mmaps, 2)) == 0) { +	    (ulong_t)&_etext, ALIST_OFF_DATA, (ulong_t)(eaddr - ld_base), 0, +	    ld_base, (ulong_t)(eaddr - ld_base), mmaps, 2)) == 0) {  		return (0);  	} @@ -425,8 +425,8 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,  		/*  		 * Map in object.  		 */ -		if ((mlmp = (ftp->fct_map_so)(&lml_main, ALO_DATA, execname, -		    argvname, fd)) == 0) +		if ((mlmp = (ftp->fct_map_so)(&lml_main, ALIST_OFF_DATA, +		    execname, argvname, fd)) == 0)  			return (0);  		/* @@ -494,7 +494,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,  		if (aoutdyn) {  #ifdef A_OUT  			if ((mlmp = aout_new_lm(&lml_main, execname, argvname, -			    aoutdyn, 0, 0, ALO_DATA)) == 0) +			    aoutdyn, 0, 0, ALIST_OFF_DATA)) == 0)  				return (0);  			/* @@ -637,8 +637,9 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,  				entry += (ulong_t)ehdr;  			if ((mlmp = elf_new_lm(&lml_main, execname, argvname, -			    dyn, (Addr)ehdr, etext, ALO_DATA, memsize, entry, -			    (ulong_t)ehdr, memsize, mmaps, mmapcnt)) == 0) { +			    dyn, (Addr)ehdr, etext, ALIST_OFF_DATA, memsize, +			    entry, (ulong_t)ehdr, memsize, mmaps, +			    mmapcnt)) == 0) {  				return (0);  			}  			if (tlsphdr && @@ -858,17 +859,18 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,  	if (DBG_ENABLED) {  		DBG_CALL(Dbg_file_ldso(rlmp, envp, auxv, -		    LIST(rlmp)->lm_lmidstr, ALO_DATA)); +		    LIST(rlmp)->lm_lmidstr, ALIST_OFF_DATA));  		if (FCT(mlmp) == &elf_fct) {  			DBG_CALL(Dbg_file_elf(&lml_main, PATHNAME(mlmp),  			    (ulong_t)DYN(mlmp), ADDR(mlmp), MSIZE(mlmp), -			    ENTRY(mlmp), LIST(mlmp)->lm_lmidstr, ALO_DATA)); +			    ENTRY(mlmp), LIST(mlmp)->lm_lmidstr, +			    ALIST_OFF_DATA));  		} else {  			DBG_CALL(Dbg_file_aout(&lml_main, PATHNAME(mlmp),  			    (ulong_t)AOUTDYN(mlmp), (ulong_t)ADDR(mlmp),  			    (ulong_t)MSIZE(mlmp), LIST(mlmp)->lm_lmidstr, -			    ALO_DATA)); +			    ALIST_OFF_DATA));  		}  	} @@ -967,7 +969,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,  	/*  	 * Load all dependent (needed) objects.  	 */ -	if (analyze_lmc(&lml_main, ALO_DATA, mlmp) == 0) +	if (analyze_lmc(&lml_main, ALIST_OFF_DATA, mlmp) == 0)  		return (0);  	/* @@ -988,7 +990,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,  		DBG_CALL(Dbg_util_nl(&lml_main, DBG_NL_STD)); -		if (relocate_lmc(&lml_main, ALO_DATA, mlmp, mlmp) == 0) +		if (relocate_lmc(&lml_main, ALIST_OFF_DATA, mlmp, mlmp) == 0)  			return (0);  		/* diff --git a/usr/src/cmd/sgs/rtld/common/tsort.c b/usr/src/cmd/sgs/rtld/common/tsort.c index 30a10cba41..1e48b15652 100644 --- a/usr/src/cmd/sgs/rtld/common/tsort.c +++ b/usr/src/cmd/sgs/rtld/common/tsort.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -58,8 +58,8 @@ typedef struct {  	Rt_map		**s_lmpa;	/* link-map[] (returned to caller) */  	Rt_map		*s_lmp;		/* originating link-map */  	Rt_map		**s_stack;	/* strongly connected component stack */ -	Alist 		*s_scc;		/* cyclic list */ -	Alist		*s_queue;	/* depth queue for cyclic components */ +	APlist 		*s_scc;		/* cyclic list */ +	APlist		*s_queue;	/* depth queue for cyclic components */  	int		s_sndx;		/* present stack index */  	int 		s_lndx;		/* present link-map index */  	int		s_num;		/* number of objects to sort */ @@ -107,25 +107,24 @@ sort_scc(Sort * sort, int fndx, int flag)  	 * of the number of objects that will be inspected (logic matches that  	 * used by dlsym() to traverse lazy dependencies).  	 */ -	if (sort->s_queue == 0) { -		Aliste	off; -		Rt_map	*lmp, **lmpp; +	if (sort->s_queue == NULL) { +		Aliste	idx1; +		Rt_map	*lmp, *lmp2;  		lmp = sort->s_lmp;  		ndx = 1; -		if (alist_append(&(sort->s_queue), &lmp, sizeof (Rt_map *), -		    sort->s_num) == 0) +		if (aplist_append(&sort->s_queue, lmp, sort->s_num) == NULL)  			return (0);  		IDX(lmp) = ndx++; -		for (ALIST_TRAVERSE(sort->s_queue, off, lmpp)) { -			Bnd_desc	**bdpp; -			Aliste		off; +		for (APLIST_TRAVERSE(sort->s_queue, idx1, lmp2)) { +			Bnd_desc	*bdp; +			Aliste		idx2; -			for (ALIST_TRAVERSE(DEPENDS(*lmpp), off, bdpp)) { -				Rt_map	*lmp = (*bdpp)->b_depend; +			for (APLIST_TRAVERSE(DEPENDS(lmp2), idx2, bdp)) { +				Rt_map	*lmp = bdp->b_depend;  				if (IDX(lmp))  					continue; @@ -138,8 +137,8 @@ sort_scc(Sort * sort, int fndx, int flag)  				    (FLAGS(lmp) & FLG_RT_INITCALL))  					continue; -				if (alist_append(&(sort->s_queue), &lmp, -				    sizeof (Rt_map *), sort->s_num) == 0) +				if (aplist_append(&sort->s_queue, lmp, +				    sort->s_num) == NULL)  					return (0);  				IDX(lmp) = ndx++; @@ -199,10 +198,9 @@ sort_scc(Sort * sort, int fndx, int flag)  	 * cyclic components are referenced from outside of the cycle.  	 */  	if (unref || DBG_ENABLED) { -		Bnd_desc **	bdpp; -  		for (ndx = fndx; ndx < sort->s_lndx; ndx++) { -			Aliste	off; +			Bnd_desc	*bdp; +			Aliste		idx;  			lmp = sort->s_lmpa[ndx]; @@ -217,8 +215,7 @@ sort_scc(Sort * sort, int fndx, int flag)  			 * Traverse this objects callers looking for outside  			 * references.  			 */ -			for (ALIST_TRAVERSE(CALLERS(lmp), off, bdpp)) { -				Bnd_desc	*bdp = *bdpp; +			for (APLIST_TRAVERSE(CALLERS(lmp), idx, bdp)) {  				Rt_map		*clmp = bdp->b_caller;  				if ((bdp->b_flags & BND_REFER) == 0) @@ -251,7 +248,7 @@ sort_scc(Sort * sort, int fndx, int flag)  static int  visit(Lm_list *lml, Rt_map * lmp, Sort *sort, int flag)  { -	Alist		*alpp = 0; +	APlist		*alp = NULL;  	int		num = sort->s_lndx;  	Word		tracing = lml->lm_flags & LML_FLG_TRC_ENABLE;  	Rt_map		*tlmp; @@ -285,7 +282,7 @@ visit(Lm_list *lml, Rt_map * lmp, Sort *sort, int flag)  		/*  		 * If tracing, save the strongly connected component.  		 */ -		if (tracing && (alist_append(&alpp, &tlmp, sizeof (Rt_map *), +		if (tracing && (aplist_append(&alp, tlmp,  		    AL_CNT_SCC) == 0))  			return (0);  	} while (tlmp != lmp); @@ -298,11 +295,11 @@ visit(Lm_list *lml, Rt_map * lmp, Sort *sort, int flag)  		if (sort_scc(sort, num, flag) == 0)  			return (0); -		if (tracing && (alist_append(&(sort->s_scc), &alpp, -		    sizeof (Alist *), AL_CNT_SCC) == 0)) +		if (tracing && (aplist_append(&sort->s_scc, alp, +		    AL_CNT_SCC) == 0))  			return (0); -	} else if (alpp) -		free(alpp); +	} else if (alp) +		free(alp);  	return (1);  } @@ -397,8 +394,8 @@ dep_visit(Lm_list *lml, Rt_map *clmp, uint_t cbflags, Rt_map *lmp, Sort *sort,      int flag)  {  	int 		min; -	Aliste		off; -	Bnd_desc	**bdpp; +	Aliste		idx; +	Bnd_desc	*bdp;  	Dyninfo		*dip;  	min = SORTVAL(lmp) = sort->s_sndx; @@ -412,9 +409,9 @@ dep_visit(Lm_list *lml, Rt_map *clmp, uint_t cbflags, Rt_map *lmp, Sort *sort,  	/*  	 * Traverse both explicit and implicit dependencies.  	 */ -	for (ALIST_TRAVERSE(DEPENDS(lmp), off, bdpp)) { -		if ((min = _dep_visit(lml, min, lmp, (*bdpp)->b_depend, -		    (*bdpp)->b_flags, sort, flag)) == -1) +	for (APLIST_TRAVERSE(DEPENDS(lmp), idx, bdp)) { +		if ((min = _dep_visit(lml, min, lmp, bdp->b_depend, +		    bdp->b_flags, sort, flag)) == -1)  			return (-1);  	} @@ -439,7 +436,7 @@ dep_visit(Lm_list *lml, Rt_map *clmp, uint_t cbflags, Rt_map *lmp, Sort *sort,  				    ((ghp = (Grp_hdl *)pnp->p_info) == 0))  					continue; -				for (ALIST_TRAVERSE(ghp->gh_depends, off, +				for (ALIST_TRAVERSE(ghp->gh_depends, idx,  				    gdp)) {  					if (gdp->gd_depend == lmp) @@ -521,19 +518,19 @@ fb_visit(Rt_map * lmp, Sort * sort, int flag)  /*   * Find corresponding strongly connected component structure.   */ -static Alist * -trace_find_scc(Sort * sort, Rt_map * lmp) +static APlist * +trace_find_scc(Sort *sort, Rt_map *lmp)  { -	Alist		**alpp; -	Aliste		off1; +	APlist		*alp; +	Aliste		idx1; -	for (ALIST_TRAVERSE(sort->s_scc, off1, alpp)) { -		Rt_map	**lmpp; -		Aliste	off2; +	for (APLIST_TRAVERSE(sort->s_scc, idx1, alp)) { +		Rt_map	*lmp2; +		Aliste	idx2; -		for (ALIST_TRAVERSE(*alpp, off2, lmpp)) { -			if (lmp == *lmpp) -				return (*alpp); +		for (APLIST_TRAVERSE(alp, idx2, lmp2)) { +			if (lmp == lmp2) +				return (alp);  		}  	}  	return (NULL); @@ -546,15 +543,15 @@ static void  trace_sort(Sort * sort)  {  	int 		ndx = 0; -	Alist		*alp; +	APlist		*alp;  	Rt_map		*lmp1;  	(void) printf(MSG_ORIG(MSG_STR_NL));  	while ((lmp1 = sort->s_lmpa[ndx++]) != NULL) {  		static const char	*ffmt, *cfmt = 0, *sfmt = 0; -		Bnd_desc **		bdpp; -		Aliste			off1; +		Bnd_desc		*bdp; +		Aliste			idx1;  		if ((INIT(lmp1) == 0) || (FLAGS(lmp1) & FLG_RT_INITCALL))  			continue; @@ -587,15 +584,15 @@ trace_sort(Sort * sort)  		(void) printf(cfmt, NAME(lmp1), CYCGROUP(lmp1)); -		for (ALIST_TRAVERSE(CALLERS(lmp1), off1, bdpp)) { -			Rt_map	**lmpp3, *lmp2 = (*bdpp)->b_caller; -			Aliste	off2; +		for (APLIST_TRAVERSE(CALLERS(lmp1), idx1, bdp)) { +			Rt_map	*lmp3, *lmp2 = bdp->b_caller; +			Aliste	idx2; -			for (ALIST_TRAVERSE(alp, off2, lmpp3)) { -				if (lmp2 != *lmpp3) +			for (APLIST_TRAVERSE(alp, idx2, lmp3)) { +				if (lmp2 != lmp3)  					continue; -				(void) printf(ffmt, NAME(*lmpp3)); +				(void) printf(ffmt, NAME(lmp3));  			}  		}  	} @@ -910,8 +907,8 @@ tsort(Rt_map *lmp, int num, int flag)  		free(sort.s_stack);  	if (sort.s_queue) { -		Aliste	off; -		Rt_map	**lmpp; +		Aliste idx; +		Rt_map	*lmp2;  		/*  		 * Traverse the link-maps collected on the sort queue and @@ -919,18 +916,18 @@ tsort(Rt_map *lmp, int num, int flag)  		 * again to sort other components either for inits, and almost  		 * certainly for .finis.  		 */ -		for (ALIST_TRAVERSE(sort.s_queue, off, lmpp)) -			IDX(*lmpp) = 0; +		for (APLIST_TRAVERSE(sort.s_queue, idx, lmp2)) +			IDX(lmp2) = 0;  		free(sort.s_queue);  	}  	if (sort.s_scc) { -		Aliste	off; -		Alist	**alpp; +		Aliste	idx; +		APlist	*alp; -		for (ALIST_TRAVERSE(sort.s_scc, off, alpp)) -			free(*alpp); +		for (APLIST_TRAVERSE(sort.s_scc, idx, alp)) +			free(alp);  		free(sort.s_scc);  	} diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c index bc7f3c72d5..959259e8e7 100644 --- a/usr/src/cmd/sgs/rtld/common/util.c +++ b/usr/src/cmd/sgs/rtld/common/util.c @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -444,8 +444,7 @@ fpavl_insert(Lm_list *lml, Rt_map *lmp, const char *name, avl_index_t where)  	fpnp->fpn_hash = sgs_str_hash(name);  	fpnp->fpn_lmp = lmp; -	if (alist_append(&FPNODE(lmp), &fpnp, sizeof (FullpathNode *), -	    AL_CNT_FPNODE) == 0) { +	if (aplist_append(&FPNODE(lmp), fpnp, AL_CNT_FPNODE) == NULL) {  		free(fpnp);  		return (0);  	} @@ -463,17 +462,15 @@ fpavl_insert(Lm_list *lml, Rt_map *lmp, const char *name, avl_index_t where)  void  fpavl_remove(Rt_map *lmp)  { -	FullpathNode	**fpnpp; -	Aliste		off; - -	for (ALIST_TRAVERSE(FPNODE(lmp), off, fpnpp)) { -		FullpathNode	*fpnp = *fpnpp; +	FullpathNode	*fpnp; +	Aliste		idx; +	for (APLIST_TRAVERSE(FPNODE(lmp), idx, fpnp)) {  		avl_remove(LIST(lmp)->lm_fpavl, fpnp);  		free(fpnp);  	}  	free(FPNODE(lmp)); -	FPNODE(lmp) = 0; +	FPNODE(lmp) = NULL;  } @@ -646,8 +643,8 @@ call_init(Rt_map ** tobj, int flag)  			rtld_flags |= RT_FL_INITFIRST;  		if (INITARRAY(lmp) || iptr) { -			Aliste		off; -			Bnd_desc **	bdpp; +			Aliste		idx; +			Bnd_desc 	*bdp;  			/*  			 * Make sure that all dependencies that have been @@ -656,9 +653,7 @@ call_init(Rt_map ** tobj, int flag)  			 * on an external item that must first be initialized  			 * by its associated object is satisfied.  			 */ -			for (ALIST_TRAVERSE(DEPENDS(lmp), off, bdpp)) { -				Bnd_desc *	bdp = *bdpp; - +			for (APLIST_TRAVERSE(DEPENDS(lmp), idx, bdp)) {  				if ((bdp->b_flags & BND_REFER) == 0)  					continue;  				is_dep_ready(bdp->b_depend, lmp, DBG_WAIT_INIT); @@ -735,9 +730,9 @@ call_fini(Lm_list * lml, Rt_map ** tobj)  	Rt_map **_tobj;  	for (_tobj = tobj; *_tobj != NULL; _tobj++) { -		Rt_map *	clmp, * lmp = *_tobj; -		Aliste		off; -		Bnd_desc **	bdpp; +		Rt_map		*clmp, * lmp = *_tobj; +		Aliste		idx; +		Bnd_desc	*bdp;  		/*  		 * If concurrency checking isn't enabled only fire .fini if @@ -795,9 +790,7 @@ call_fini(Lm_list * lml, Rt_map ** tobj)  		if (FLAGS1(lmp) & LML_TFLG_AUD_OBJCLOSE)  			_audit_objclose(&(AUDITORS(lmp)->ad_list), lmp); -		for (ALIST_TRAVERSE(CALLERS(lmp), off, bdpp)) { -			Bnd_desc *	bdp = *bdpp; - +		for (APLIST_TRAVERSE(CALLERS(lmp), idx, bdp)) {  			clmp = bdp->b_caller;  			if (FLAGS1(clmp) & LML_TFLG_AUD_OBJCLOSE) { @@ -1099,11 +1092,12 @@ lm_append(Lm_list *lml, Aliste lmco, Rt_map *lmp)  	 * are loaded.  Individual objects are also loaded on the main link-map  	 * control list of new alternative link-map control lists.  	 */ -	if ((lmco == ALO_DATA) && ((lml->lm_flags & LML_FLG_DBNOTIF) == 0)) +	if ((lmco == ALIST_OFF_DATA) && +	    ((lml->lm_flags & LML_FLG_DBNOTIF) == 0))  		rd_event(lml, RD_DLACTIVITY, RT_ADD);  	/* LINTED */ -	lmc = (Lm_cntl *)((char *)lml->lm_lists + lmco); +	lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, lmco);  	/*  	 * A link-map list header points to one of more link-map control lists @@ -1197,7 +1191,7 @@ lm_append(Lm_list *lml, Aliste lmco, Rt_map *lmp)  	 * For backward compatibility with debuggers, the link-map list contains  	 * pointers to the main control list.  	 */ -	if (lmco == ALO_DATA) { +	if (lmco == ALIST_OFF_DATA) {  		lml->lm_head = lmc->lc_head;  		lml->lm_tail = lmc->lc_tail;  	} @@ -1222,11 +1216,12 @@ lm_delete(Lm_list *lml, Rt_map *lmp)  	 * If we're about to delete an object from the main link-map control  	 * list, alert the debuggers that we are about to mess with this list.  	 */ -	if ((CNTL(lmp) == ALO_DATA) && ((lml->lm_flags & LML_FLG_DBNOTIF) == 0)) +	if ((CNTL(lmp) == ALIST_OFF_DATA) && +	    ((lml->lm_flags & LML_FLG_DBNOTIF) == 0))  		rd_event(lml, RD_DLACTIVITY, RT_DELETE);  	/* LINTED */ -	lmc = (Lm_cntl *)((char *)lml->lm_lists + CNTL(lmp)); +	lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, CNTL(lmp));  	if (lmc->lc_head == lmp)  		lmc->lc_head = (Rt_map *)NEXT(lmp); @@ -1242,7 +1237,7 @@ lm_delete(Lm_list *lml, Rt_map *lmp)  	 * For backward compatibility with debuggers, the link-map list contains  	 * pointers to the main control list.  	 */ -	if (lmc == (Lm_cntl *)&(lml->lm_lists->al_data)) { +	if (lmc == (Lm_cntl *)&lml->lm_lists->al_data) {  		lml->lm_head = lmc->lc_head;  		lml->lm_tail = lmc->lc_tail;  	} @@ -1270,7 +1265,8 @@ lm_move(Lm_list *lml, Aliste nlmco, Aliste plmco, Lm_cntl *nlmc, Lm_cntl *plmc)  	 * list.  Additions of object families to the main link-map control  	 * list occur during lazy loading, filtering and dlopen().  	 */ -	if ((plmco == ALO_DATA) && ((lml->lm_flags & LML_FLG_DBNOTIF) == 0)) +	if ((plmco == ALIST_OFF_DATA) && +	    ((lml->lm_flags & LML_FLG_DBNOTIF) == 0))  		rd_event(lml, RD_DLACTIVITY, RT_ADD);  	DBG_CALL(Dbg_file_cntl(lml, nlmco, plmco)); @@ -1301,7 +1297,7 @@ lm_move(Lm_list *lml, Aliste nlmco, Aliste plmco, Lm_cntl *nlmc, Lm_cntl *plmc)  	 * For backward compatibility with debuggers, the link-map list contains  	 * pointers to the main control list.  	 */ -	if (plmco == ALO_DATA) { +	if (plmco == ALIST_OFF_DATA) {  		lml->lm_head = plmc->lc_head;  		lml->lm_tail = plmc->lc_tail;  	} @@ -3136,11 +3132,10 @@ unused(Lm_list *lml)  		 * referenced it.  		 */  		if ((tracing & LML_FLG_TRC_UNREF) || DBG_ENABLED) { -			Bnd_desc **	bdpp; -			Aliste		off; +			Bnd_desc	*bdp; +			Aliste		idx; -			for (ALIST_TRAVERSE(CALLERS(lmp), off, bdpp)) { -				Bnd_desc *	bdp = *bdpp; +			for (APLIST_TRAVERSE(CALLERS(lmp), idx, bdp)) {  				Rt_map *	clmp;  				if (bdp->b_flags & BND_REFER) @@ -3250,8 +3245,8 @@ void  leave(Lm_list *lml)  {  	Lm_list	*elml = lml; -	Rt_map	**clmpp; -	Aliste	off; +	Rt_map	*clmp; +	Aliste	idx;  	/*  	 * Alert the debuggers that the link-maps are consistent.  Note, in the @@ -3266,10 +3261,10 @@ leave(Lm_list *lml)  	/*  	 * Alert any auditors that the link-maps are consistent.  	 */ -	for (ALIST_TRAVERSE(elml->lm_actaudit, off, clmpp)) { -		audit_activity(*clmpp, LA_ACT_CONSISTENT); +	for (APLIST_TRAVERSE(elml->lm_actaudit, idx, clmp)) { +		audit_activity(clmp, LA_ACT_CONSISTENT); -		(void) alist_delete(elml->lm_actaudit, 0, &off); +		aplist_delete(elml->lm_actaudit, &idx);  	}  	if (dz_fd != FD_UNAVAIL) { @@ -3316,9 +3311,9 @@ leave(Lm_list *lml)  int  callable(Rt_map *clmp, Rt_map *dlmp, Grp_hdl *ghp, uint_t slflags)  { -	Alist		*calp, *dalp; -	Aliste		off1, off2; -	Grp_hdl		**ghpp1, **ghpp2; +	APlist		*calp, *dalp; +	Aliste		idx1, idx2; +	Grp_hdl		*ghp1, *ghp2;  	/*  	 * An object can always find symbols within itself. @@ -3352,28 +3347,28 @@ callable(Rt_map *clmp, Rt_map *dlmp, Grp_hdl *ghp, uint_t slflags)  	 * member of the same group.  	 */  	if (((MODE(clmp) & RTLD_GROUP) == 0) || -	    ((calp = GROUPS(clmp)) == 0) || ((dalp = GROUPS(dlmp)) == 0)) +	    ((calp = GROUPS(clmp)) == NULL) || ((dalp = GROUPS(dlmp)) == NULL))  		return (0);  	/*  	 * Traverse the list of groups the caller is a part of.  	 */ -	for (ALIST_TRAVERSE(calp, off1, ghpp1)) { +	for (APLIST_TRAVERSE(calp, idx1, ghp1)) {  		/*  		 * If we're testing for the ability of two objects to bind to  		 * each other regardless of a specific group, ignore that group.  		 */ -		if (ghp && (*ghpp1 == ghp)) +		if (ghp && (ghp1 == ghp))  			continue;  		/*  		 * Traverse the list of groups the destination is a part of.  		 */ -		for (ALIST_TRAVERSE(dalp, off2, ghpp2)) { +		for (APLIST_TRAVERSE(dalp, idx2, ghp2)) {  			Grp_desc	*gdp; -			Aliste		off3; +			Aliste		idx3; -			if (*ghpp1 != *ghpp2) +			if (ghp1 != ghp2)  				continue;  			/* @@ -3384,7 +3379,7 @@ callable(Rt_map *clmp, Rt_map *dlmp, Grp_hdl *ghp, uint_t slflags)  			 * parent doesn't provide symbols for the destination  			 * to relocate against.  			 */ -			for (ALIST_TRAVERSE((*ghpp2)->gh_depends, off3, gdp)) { +			for (ALIST_TRAVERSE(ghp2->gh_depends, idx3, gdp)) {  				if (dlmp != gdp->gd_depend)  					continue; diff --git a/usr/src/cmd/sgs/rtld/i386/i386_elf.c b/usr/src/cmd/sgs/rtld/i386/i386_elf.c index f646738fcf..e4216871ec 100644 --- a/usr/src/cmd/sgs/rtld/i386/i386_elf.c +++ b/usr/src/cmd/sgs/rtld/i386/i386_elf.c @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -445,7 +445,7 @@ elf_reloc(Rt_map *lmp, uint_t plt)  	int		relacount = RELACOUNT(lmp), plthint = 0;  	Rel		*rel;  	uint_t		binfo, pbinfo; -	Alist		*bound = 0; +	APlist		*bound = NULL;  	/*  	 * Although only necessary for lazy binding, initialize the first @@ -811,8 +811,7 @@ elf_reloc(Rt_map *lmp, uint_t plt)  					 */  					if ((lmp != _lmp) && ((FLAGS1(_lmp) &  					    FL1_RT_NOINIFIN) == 0)) { -						if (alist_test(&bound, _lmp, -						    sizeof (Rt_map *), +						if (aplist_test(&bound, _lmp,  						    AL_CNT_RELBIND) == 0) {  							ret = 0;  							break; diff --git a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c index 056929df2b..c2dbdbda14 100644 --- a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c +++ b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -275,34 +275,31 @@ static int  Depends(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv,      uint_t flg, const char *msg)  { -	Alist		al; -	uintptr_t	listcalc, listnext; -	size_t		ucnt, tcnt; +	APlist		apl; +	uintptr_t	listcalc, listndx;  	Bnd_desc *	bdp;  	/* -	 * Obtain the Alist and determine its number of elements and those +	 * Obtain the APlist and determine its number of elements and those  	 * that are in use.  	 */ -	if (mdb_vread(&al, sizeof (Alist), addr) == -1) { -		mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_STR_ALIST), addr); +	if (mdb_vread(&apl, sizeof (APlist), addr) == -1) { +		mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_STR_APLIST), +		    addr);  		return (DCMD_ERR);  	} -	ucnt = (al.al_next - sizeof (Alist) + sizeof (void *)) / al.al_size; -	tcnt = (al.al_end - sizeof (Alist) + sizeof (void *)) / al.al_size; -	mdb_printf(msg, addr, ucnt, tcnt); +	mdb_printf(msg, addr, (size_t)apl.apl_nitems, +	    (size_t)apl.apl_arritems); -	if (((flg & RTLD_FLG_VERBOSE) == 0) || (ucnt == 0)) +	if (((flg & RTLD_FLG_VERBOSE) == 0) || (apl.apl_nitems == 0))  		return (DCMD_OK);  	/* -	 * Under verbose mode print the name of each dependency.  An Alist can +	 * Under verbose mode print the name of each dependency.  An APlist can  	 * have a variable number of data items, so read each individual entry.  	 */ -	listcalc = (uintptr_t)(&(al.al_data[0])); -	listcalc -= (uintptr_t)(&al); -	listcalc += addr; +	listcalc = APLIST_OFF_DATA + (uintptr_t)addr;  	if (mdb_vread(&bdp, sizeof (Bnd_desc *), listcalc) == -1) {  		mdb_warn(MSG_ORIG(MSG_ERR_READ),  		    MSG_ORIG(MSG_BNDDESC_STR), listcalc); @@ -317,9 +314,8 @@ Depends(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv,  		return (DCMD_ERR);  	} -	listnext = (uintptr_t)(al.al_next + addr); -	for (listcalc += al.al_size; listcalc < listnext; -	    listcalc += al.al_size) { +	for (listndx = 1; listndx < apl.apl_nitems; listndx++) { +		listcalc += sizeof (void *);  		if (mdb_vread(&bdp, sizeof (Bnd_desc *), listcalc) == -1) {  			mdb_warn(MSG_ORIG(MSG_ERR_READ),  			    MSG_ORIG(MSG_BNDDESC_STR), listcalc); @@ -368,7 +364,7 @@ dcmd_Depends(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  	mdb_printf(MSG_ORIG(MSG_DEPENDS_LINE1), str);  	mdb_printf(MSG_ORIG(MSG_STR_DASHES)); -	if (DEPENDS(&rtmap) == 0) +	if (DEPENDS(&rtmap) == NULL)  		return (DCMD_OK);  	return (Depends((uintptr_t)DEPENDS(&rtmap), flags, argc, argv, flg, @@ -413,7 +409,7 @@ dcmd_Callers(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  	mdb_printf(MSG_ORIG(MSG_CALLERS_LINE1), str);  	mdb_printf(MSG_ORIG(MSG_STR_DASHES)); -	if (CALLERS(&rtmap) == 0) +	if (CALLERS(&rtmap) == NULL)  		return (DCMD_OK);  	return (Depends((uintptr_t)CALLERS(&rtmap), flags, argc, argv, flg, @@ -869,7 +865,6 @@ _dcmd_Lm_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  	if (lml.lm_lists) {  		Alist		al; -		size_t		ucnt, tcnt;  		Lm_cntl		lmc;  		uintptr_t	listcalc; @@ -884,18 +879,11 @@ _dcmd_Lm_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  		 * Determine whether the Alist has been populated.  Note, the  		 * implementation first reserves an alist entry, and initializes  		 * this element when the first link-map is processed.  Thus, -		 * there's a window when ucnt is updated, but before the next +		 * there's a window when nitems is updated, but before the next  		 * element has been initialized.  		 */ -		ucnt = (al.al_next - sizeof (Alist) + sizeof (void *)) / -		    al.al_size; -		tcnt = (al.al_end - sizeof (Alist) + sizeof (void *)) / -		    al.al_size; - -		if (ucnt && (flg & RTLD_FLG_VERBOSE)) { -			listcalc = (uintptr_t)(&(al.al_data[0])); -			listcalc -= (uintptr_t)(&al); -			listcalc += addr; +		if (al.al_nitems && (flg & RTLD_FLG_VERBOSE)) { +			listcalc = ALIST_OFF_DATA + (uintptr_t)addr;  			if (mdb_vread(&lmc, sizeof (Lm_cntl),  			    listcalc) == -1) { @@ -905,12 +893,13 @@ _dcmd_Lm_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  			}  		} -		mdb_printf(MSG_ORIG(MSG_LMLIST_LINE0), addr, ucnt, tcnt); +		mdb_printf(MSG_ORIG(MSG_LMLIST_LINE0), addr, +		    (size_t)al.al_nitems, (size_t)al.al_arritems);  		mdb_inc_indent(2);  		mdb_printf(MSG_ORIG(MSG_STR_DASHES)); -		if (ucnt && (flg & RTLD_FLG_VERBOSE)) { -			uintptr_t	listnext; +		if (al.al_nitems && (flg & RTLD_FLG_VERBOSE)) { +			uintptr_t	listndx;  			mdb_inc_indent(2);  			mdb_printf(MSG_ORIG(MSG_LMC_LINE1), listcalc); @@ -937,9 +926,8 @@ _dcmd_Lm_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  			mdb_printf(MSG_ORIG(MSG_STR_DASHES)); -			listnext = (uintptr_t)(al.al_next + addr); -			for (listcalc += al.al_size; listcalc < listnext; -			    listcalc += al.al_size) { +			for (listndx = 1; listndx < al.al_nitems; listndx++) { +				listcalc += al.al_size;  				if (mdb_vread(&lmc, sizeof (Lm_cntl),  				    listcalc) == -1) {  					mdb_warn(MSG_ORIG(MSG_ERR_READ), @@ -1100,10 +1088,9 @@ dcmd_GrpHdl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  {  	Grp_hdl		gh;  	Alist		al; -	uintptr_t	listcalc, listnext; +	uintptr_t	listcalc, listidx;  	char		*str;  	uint_t		flg = 0; -	size_t		ucnt, tcnt;  	/*  	 * Insure we have a valid address, and provide for a -v option. @@ -1150,11 +1137,10 @@ dcmd_GrpHdl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  		return (DCMD_ERR);  	} -	ucnt = (al.al_next - sizeof (Alist) + sizeof (void *)) / al.al_size; -	tcnt = (al.al_end - sizeof (Alist) + sizeof (void *)) / al.al_size; -	mdb_printf(MSG_ORIG(MSG_GRPHDL_LINE5), gh.gh_refcnt, addr, ucnt, tcnt); +	mdb_printf(MSG_ORIG(MSG_GRPHDL_LINE5), gh.gh_refcnt, addr, +	    (size_t)al.al_nitems, (size_t)al.al_arritems); -	if (((flg & RTLD_FLG_VERBOSE) == 0) || (ucnt == 0)) +	if (((flg & RTLD_FLG_VERBOSE) == 0) || (al.al_nitems == 0))  		return (DCMD_OK);  	mdb_inc_indent(4); @@ -1164,17 +1150,14 @@ dcmd_GrpHdl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  	 * Under verbose mode print the name of each dependency.  An Alist can  	 * have a variable number of data items, so read each individual entry.  	 */ -	listcalc = (uintptr_t)(&(al.al_data[0])); -	listcalc -= (uintptr_t)(&al); -	listcalc += addr; +	listcalc = ALIST_OFF_DATA + (uintptr_t)addr;  	if (dcmd_GrpDesc(listcalc, flags, argc, argv) == DCMD_ERR) {  		mdb_dec_indent(4);  		return (DCMD_ERR);  	} -	listnext = (uintptr_t)(al.al_next + addr); -	for (listcalc += al.al_size; listcalc < listnext; -	    listcalc += al.al_size) { +	for (listidx = 1; listidx < al.al_nitems; listidx++) { +		listcalc += al.al_size;  		mdb_printf(MSG_ORIG(MSG_STR_DASHES));  		if (dcmd_GrpDesc(listcalc, flags, argc, argv) == DCMD_ERR) {  			mdb_dec_indent(4); @@ -1198,9 +1181,8 @@ dcmd_Handles(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  	Rt_map		rtmap;  	char		*str;  	uint_t		flg = 0; -	Alist		al; -	uintptr_t	listcalc, listnext; -	size_t		ucnt, tcnt; +	APlist		apl; +	uintptr_t	listcalc, listndx;  	Grp_hdl *	ghp;  	/* @@ -1232,25 +1214,23 @@ dcmd_Handles(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  		return (DCMD_OK);  	addr = (uintptr_t)HANDLES(&rtmap); -	if (mdb_vread(&al, sizeof (Alist), addr) == -1) { -		mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_STR_ALIST), addr); +	if (mdb_vread(&apl, sizeof (APlist), addr) == -1) { +		mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_STR_APLIST), +		    addr);  		return (DCMD_ERR);  	} -	ucnt = (al.al_next - sizeof (Alist) + sizeof (void *)) / al.al_size; -	tcnt = (al.al_end - sizeof (Alist) + sizeof (void *)) / al.al_size; -	mdb_printf(MSG_ORIG(MSG_HANDLES_LINE2), addr, ucnt, tcnt); +	mdb_printf(MSG_ORIG(MSG_HANDLES_LINE2), addr, (size_t)apl.apl_nitems, +	    (size_t)apl.apl_arritems); -	if (((flg & RTLD_FLG_VERBOSE) == 0) || (ucnt == 0)) +	if (((flg & RTLD_FLG_VERBOSE) == 0) || (apl.apl_nitems == 0))  		return (DCMD_OK);  	/* -	 * Under verbose mode print the name of each dependency.  An Alist can +	 * Under verbose mode print the name of each dependency.  An APlist can  	 * have a variable number of data items, so read each individual entry.  	 */ -	listcalc = (uintptr_t)(&(al.al_data[0])); -	listcalc -= (uintptr_t)(&al); -	listcalc += addr; +	listcalc = addr + APLIST_OFF_DATA;  	if (mdb_vread(&ghp, sizeof (Grp_hdl *), listcalc) == -1) {  		mdb_warn(MSG_ORIG(MSG_ERR_READ),  		    MSG_ORIG(MSG_GRPHDL_STR), listcalc); @@ -1265,9 +1245,9 @@ dcmd_Handles(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  		return (DCMD_ERR);  	} -	listnext = (uintptr_t)(al.al_next + addr); -	for (listcalc += al.al_size; listcalc < listnext; -	    listcalc += al.al_size) { +	listndx = 1; +	for (listndx = 1; listndx < apl.apl_nitems; listndx++) { +		listcalc += sizeof (void *);  		if (mdb_vread(&ghp, sizeof (Grp_hdl *), listcalc) == -1) {  			mdb_warn(MSG_ORIG(MSG_ERR_READ),  			    MSG_ORIG(MSG_GRPHDL_STR), listcalc); @@ -1297,10 +1277,9 @@ dcmd_Groups(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  {  	Rt_map		rtmap;  	char		*str; -	Alist		al; +	APlist		apl;  	uint_t		flg = 0; -	uintptr_t	listcalc, listnext; -	size_t		ucnt, tcnt; +	uintptr_t	listcalc, listndx;  	Grp_hdl *	ghp;  	/* @@ -1332,25 +1311,23 @@ dcmd_Groups(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  		return (DCMD_OK);  	addr = (uintptr_t)GROUPS(&rtmap); -	if (mdb_vread(&al, sizeof (Alist), addr) == -1) { -		mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_STR_ALIST), addr); +	if (mdb_vread(&apl, sizeof (APlist), addr) == -1) { +		mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_STR_APLIST), +		    addr);  		return (DCMD_ERR);  	} -	ucnt = (al.al_next - sizeof (Alist) + sizeof (void *)) / al.al_size; -	tcnt = (al.al_end - sizeof (Alist) + sizeof (void *)) / al.al_size; -	mdb_printf(MSG_ORIG(MSG_GROUPS_LINE2), addr, ucnt, tcnt); +	mdb_printf(MSG_ORIG(MSG_GROUPS_LINE2), addr, (size_t)apl.apl_nitems, +	    (size_t)apl.apl_arritems); -	if (((flg & RTLD_FLG_VERBOSE) == 0) || (ucnt == 0)) +	if (((flg & RTLD_FLG_VERBOSE) == 0) || (apl.apl_nitems == 0))  		return (DCMD_OK);  	/* -	 * Under verbose mode print the name of each dependency.  An Alist can +	 * Under verbose mode print the name of each dependency.  An APlist can  	 * have a variable number of data items, so read each individual entry.  	 */ -	listcalc = (uintptr_t)(&(al.al_data[0])); -	listcalc -= (uintptr_t)(&al); -	listcalc += addr; +	listcalc = addr + APLIST_OFF_DATA;  	if (mdb_vread(&ghp, sizeof (Grp_hdl *), listcalc) == -1) {  		mdb_warn(MSG_ORIG(MSG_ERR_READ),  		    MSG_ORIG(MSG_GRPHDL_STR), listcalc); @@ -1365,9 +1342,8 @@ dcmd_Groups(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)  		return (DCMD_ERR);  	} -	listnext = (uintptr_t)(al.al_next + addr); -	for (listcalc += al.al_size; listcalc < listnext; -	    listcalc += al.al_size) { +	for (listndx = 1; listndx < apl.apl_nitems; listndx++) { +		listcalc += sizeof (void *);  		if (mdb_vread(&ghp, sizeof (Grp_hdl *), listcalc) == -1) {  			mdb_warn(MSG_ORIG(MSG_ERR_READ),  			    MSG_ORIG(MSG_GRPHDL_STR), listcalc); diff --git a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg index 8cd151f8c0..5891c80cac 100644 --- a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg +++ b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg @@ -20,7 +20,7 @@  #  # -# Copyright 2007 Sun Microsystems, Inc.  All rights reserved. +# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.  # Use is subject to license terms.  #  # pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -41,6 +41,7 @@  @ MSG_STR_LDSO1		"ld.so.1"  @ MSG_STR_DYNLMLIST	"dynlm_list"  @ MSG_STR_ALIST		"Alist" +@ MSG_STR_APLIST	"APlist"  @ MSG_STR_LISTNODE	"Listnode"  @ MSG_STR_EMPTY		""  @ MSG_STR_ORPHANED	"<orphaned>" @@ -552,20 +553,20 @@  @ MSG_DEPENDS_DCD	"Display Rt_map DEPENDS binding descriptors"  @ MSG_DEPENDS_LINE1	"DEPENDS for %s\n" -@ MSG_DEPENDS_LINE2	"  Depends: 0x%0?p Alist[used %u: total %u]\n" +@ MSG_DEPENDS_LINE2	"  Depends: 0x%0?p APlist[used %u: total %u]\n"  @ MSG_DEPENDS_HELP	"\     Display the binding descriptor list of DEPENDS() of the Rt_map\n\ -   specified by addr.  A DEPENDS() entry consists of an Alist\n\ +   specified by addr.  A DEPENDS() entry consists of an APlist\n\     defining each dependency.\n\     \n\ -   The -v option walks the Alist descriptor displaying each dependency.\n\ +   The -v option walks the APlist descriptor displaying each dependency.\n\     \n\     Example:\n\n\     \t> 0xff3b0554::Depends -v\n\     \tDEPENDS for /lib/libc.so.1\n\     \t----------------------------------------------\n\ -   \t  Depends: 0xff3b0bc4 Alist[used 2: total 4]\n\ +   \t  Depends: 0xff3b0bc4 APlist[used 2: total 4]\n\     \t    ----------------------------------------------\n\     \t    Binding descriptor located at: 0xff3b08f8\n\     \t       caller: 0xff3b0554    /lib/libc.so.1\n\ @@ -586,20 +587,20 @@  @ MSG_CALLERS_DCD	"Display Rt_map CALLERS binding descriptors"  @ MSG_CALLERS_LINE1	"CALLERS for %s\n" -@ MSG_CALLERS_LINE2	"  Callers: 0x%0?p Alist[used %u: total %u]\n" +@ MSG_CALLERS_LINE2	"  Callers: 0x%0?p APlist[used %u: total %u]\n"  @ MSG_CALLERS_HELP	"\     Display the binding descriptor list of CALLERS() of the Rt_map\n\ -   specified by addr.  A CALLERS() entry consists of an Alist\n\ +   specified by addr.  A CALLERS() entry consists of an APlist\n\     defining each caller.\n\     \n\ -   The -v option walks the Alist descriptor displaying each caller.\n\ +   The -v option walks the APlist descriptor displaying each caller.\n\     \n\     Example:\n\n\     \t> 0xff3b0554::Callers -v\n\     \tCALLERS for /lib/libc.so.1\n\     \t----------------------------------------------\n\ -   \t  Callers: 0xff3b08cc Alist[used 1: total 4]\n\ +   \t  Callers: 0xff3b08cc APlist[used 1: total 4]\n\     \t    ----------------------------------------------\n\     \t    Binding descriptor located at: 0xff3b0514\n\     \t       caller: 0xff3b0214    a.out\n\ @@ -616,21 +617,21 @@  @ MSG_HANDLES_DCD	"Display Rt_map HANDLES group descriptors"  @ MSG_HANDLES_LINE1	"HANDLES for %s\n" -@ MSG_HANDLES_LINE2	"  HANDLE: 0x%0?p Alist[used %u: total %u]\n" +@ MSG_HANDLES_LINE2	"  HANDLE: 0x%0?p APlist[used %u: total %u]\n"  @ MSG_HANDLES_HELP	"\     Display the list of HANDLES() that the Rt_map, specified by addr, is the\n\ -   owner of.  A HANDLES() entry consists of an Alist of Grp_hdl descriptors.\n\ -   See GrpHdl.  Each Grp_hdl() consists of an Alist of Grp_desc descriptors\n\ +   owner of.  A HANDLES() entry consists of an APlist of Grp_hdl descriptors.\n\ +   See GrpHdl.  Each Grp_hdl() consists of an APlist of Grp_desc descriptors\n\     that define each caller.  See GrpDesc.\n\     \n\ -   The -v option walks all Alists displaying each member of the handle.\n\ +   The -v option walks all APlists displaying each member of the handle.\n\     \n\     Example:\n\n\     \t> 0xff3b0f6c::Handles -v\n\     \tHANDLES for ./sub.so\n\     \t----------------------------------------------\n\ -   \t  HANDLE: 0xff3b1310 Alist[used 1: total 1]\n\ +   \t  HANDLE: 0xff3b1310 APlist[used 1: total 1]\n\     \t    ----------------------------------------------\n\     \t    Group Handle located at: 0xff3b1270\n\     \t    ----------------------------------------------\n\ @@ -659,21 +660,21 @@  @ MSG_GROUPS_DCD	"Display Rt_map GROUPS group handles"  @ MSG_GROUPS_LINE1	"GROUPS for %s\n" -@ MSG_GROUPS_LINE2	"  Groups: 0x%0?p Alist[used %u: total %u]\n" +@ MSG_GROUPS_LINE2	"  Groups: 0x%0?p APlist[used %u: total %u]\n"  @ MSG_GROUPS_HELP	"\     Display the list of GROUPS() that the Rt_map, specified by addr, is a \ -   member\nof.  A GROUPS() entry consists of an Alist of Grp_hdl entries.  \ +   member\nof.  A GROUPS() entry consists of an APlist of Grp_hdl entries.  \     See GrpHdl.\n\     \n\ -   The -v option walks the Alist descriptor displaying each member of the\n\ +   The -v option walks the APlist descriptor displaying each member of the\n\     handle.\n\     \n\     Example:\n\n\     \t> 0xff3b0f6c::Groups -v\n\     \tGROUPS for ./sub.so\n\     \t----------------------------------------------\n\ -   \t  Groups: 0xff3b12a8 Alist[used 1: total 1]\n\ +   \t  Groups: 0xff3b12a8 APlist[used 1: total 1]\n\     \t    ----------------------------------------------\n\     \t    Group Handle located at: 0xff3b1270\n\     \t    ----------------------------------------------\n\ diff --git a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c b/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c index 8a037aab94..ad84bb5b24 100644 --- a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c +++ b/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	All Rights Reserved   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -221,7 +221,7 @@ aout_reloc(Rt_map * lmp, uint_t plt)  	Rt_map *	_lmp;		/* lm which holds symbol definition */  	Sym *		sym;		/* symbol definition */  	int		textrel = 0, ret = 1; -	Alist		*bound = 0; +	APlist		*bound = NULL;  	Lm_list		*lml = LIST(lmp);  	DBG_CALL(Dbg_reloc_run(lmp, SHT_RELA, plt, DBG_REL_START)); @@ -312,7 +312,7 @@ aout_reloc(Rt_map * lmp, uint_t plt)  			 */  			if ((lmp != _lmp) &&  			    ((FLAGS1(_lmp) & FL1_RT_NOINIFIN) == 0)) { -				if (alist_test(&bound, _lmp, sizeof (Rt_map *), +				if (aplist_test(&bound, _lmp,  				    AL_CNT_RELBIND) == 0) {  					ret = 0;  					break; diff --git a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c index ef0bd38fa4..316c7f6426 100644 --- a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c +++ b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c @@ -23,7 +23,7 @@   *	Copyright (c) 1988 AT&T   *	  All Rights Reserved   * - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -552,7 +552,7 @@ elf_reloc(Rt_map *lmp, uint_t plt)  	Rela		*rel;  	Pltbindtype	pbtype;  	uint_t		binfo, pbinfo; -	Alist		*bound = 0; +	APlist		*bound = NULL;  	/*  	 * If an object has any DT_REGISTER entries associated with @@ -893,8 +893,7 @@ elf_reloc(Rt_map *lmp, uint_t plt)  					 */  					if ((lmp != _lmp) && ((FLAGS1(_lmp) &  					    FL1_RT_NOINIFIN) == 0)) { -						if (alist_test(&bound, _lmp, -						    sizeof (Rt_map *), +						if (aplist_test(&bound, _lmp,  						    AL_CNT_RELBIND) == 0) {  							ret = 0;  							break; diff --git a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c index de4c4bd95a..43ee59c4b9 100644 --- a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c +++ b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #pragma ident	"%Z%%M%	%I%	%E% SMI" @@ -772,7 +772,7 @@ elf_reloc(Rt_map *lmp, uint_t plt)  	Rela		*rel;  	Pltbindtype	pbtype;  	List		pltpadlist = {0, 0}; -	Alist		*bound = 0; +	APlist		*bound = NULL;  	/*  	 * If an object has any DT_REGISTER entries associated with @@ -1136,8 +1136,7 @@ elf_reloc(Rt_map *lmp, uint_t plt)  					 */  					if ((lmp != _lmp) && ((FLAGS1(_lmp) &  					    FL1_RT_NOINIFIN) == 0)) { -						if (alist_test(&bound, _lmp, -						    sizeof (Rt_map *), +						if (aplist_test(&bound, _lmp,  						    AL_CNT_RELBIND) == 0) {  							ret = 0;  							break; diff --git a/usr/src/cmd/sgs/tools/common/alist.c b/usr/src/cmd/sgs/tools/common/alist.c index 80a4bd4cc1..54a528aec9 100644 --- a/usr/src/cmd/sgs/tools/common/alist.c +++ b/usr/src/cmd/sgs/tools/common/alist.c @@ -20,173 +20,477 @@   */  /* - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms. - * + */ + +#pragma ident	"%Z%%M%	%I%	%E% SMI" + +#include <sgs.h> +#include <string.h> +#include <stdio.h> +#include <sys/debug.h> + + + +/*   * Alist manipulation.  An Alist is a list of elements formed into an array.   * Traversal of the list is an array scan, which because of the locality of   * each reference is probably more efficient than a link-list traversal.   * - * The elements of an Alist are variable length.  They can be pointers to - * other data structures, or data structures themselves.  Traversal of an Alist - * thus returns a pointer to each data element. - * - * Alist elements can be deleted.  This involve sliding any following elements - * over the element being deleted.  ALIST_TRAVERSE() may be employed to traverse - * the list, at the same time elements are being deleted.  Therefore, the next - * element is always determined as an offset from the beginning of the list. + * See alist.h for more background information about array lists.   */ -#pragma ident	"%Z%%M%	%I%	%E% SMI" -#include <sgs.h> -#include <string.h>  /* - * Insert a value into an Alist.  An offset of 0 indicates that the value should - * be appended to the Alist.  A non-zero offset indicates the position at which - * the value should be inserted. + * Insert a value into an array at a specified index: + * + *	alist_insert(): Insert an item into an Alist at the specified index + *	alist_insert_by_offset(): Insert an item into an Alist at the + *		specified offset relative to the list address. + *	aplist_insert() Insert a pointer into an APlist at the specified index + * + * entry: + *	Note: All the arguments for all three routines are listed here. + *	The routine to which a given argument applies is given with + *	each description. + * + *	llp [all] - Address of a pointer to an Alist/APlist. The pointer should + *		be initialized to NULL before its first use. + *	datap [alist_insert / aplist_insert] - Pointer to item data, or + *		NULL. If non-null the data referenced is copied into the + *		Alist item. Otherwise, the list item is zeroed, and + *		further initialization is left to the caller. + *	ptr [aplist_insert] - Pointer to be inserted. + *	size [alist_insert / alist_insert_by_offset] - Size of an item + *		in the array list, in bytes. As with any array, A given + *		Alist can support any item size, but every item in that + *		list must have the same size. + *	init_arritems [all] - Initial allocation size: On the first insertion + *		into the array list, room for init_arritems items is allocated. + *	idx [alist_insert / aplist_insert] - Index at which to insert the + *		new item. This index must lie within the existing list, + *		or be the next index following. + *	off [alist_insert_by_offset] - Offset at which  to insert the new + *		item, based from the start of the Alist. The offset of + *		the first item is ALIST_OFF_DATA. + * + * exit: + *	The item is inserted at the specified position. This operation + *	can cause memory for the list to be allocated, or reallocated, + *	either of which will cause the value of the list pointer + *	to change. + * + *	These routines can only fail if unable to allocate memory, + *	in which case NULL is returned. + * + *	If a pointer list (aplist_insert), then the pointer + *	is stored in the requested index. On success, the address + *	of the pointer within the list is returned. + * + *	If the list contains arbitrary data (not aplist_insert): If datap + *	is non-NULL, the data it references is copied into the item at + *	the index. If datap is NULL, the specified item is zeroed. + *	On success, a pointer to the inserted item is returned. + * + *	The  caller must not retain the returned pointer from this + *	routine across calls to the list module. It is only safe to use + *	it until the next call to this module for the given list. + *   */  void * -alist_insert(Alist **alpp, const void *item, size_t size, int cnt, Aliste off) +alist_insert(Alist **lpp, const void *datap, size_t size, +    Aliste init_arritems, Aliste idx)  { -	Alist	*alp = *alpp; -	void	*new; +	Alist	*lp = *lpp; +	char	*addr; -	if (alp == 0) { -		Aliste	bsize, esize = (Aliste)S_ROUND(size, sizeof (void *)); +	/* The size and initial array count need to be non-zero */ +	ASSERT(init_arritems != 0); +	ASSERT(size != 0); -		/* -		 * First time here, allocate a new Alist.  Note that the Alist -		 * al_desc[] entry accounts for one void * already. -		 */ -		bsize = (Aliste)(sizeof (Alist) - sizeof (void *) + -		    (size * cnt)); -		if ((alp = malloc((size_t)bsize)) == 0) -			return (0); -		alp->al_next = sizeof (Alist) - sizeof (void *); -		alp->al_end = bsize; -		alp->al_size = esize; - -	} else if (alp->al_next == alp->al_end) { -		Aliste	bsize; +	if (lp == NULL) { +		Aliste bsize;  		/* -		 * The list is full, add another block of elements.  Determine -		 * the present number of elements and double them. +		 * First time here, allocate a new Alist.  Note that the +		 * Alist al_desc[] entry is defined for 1 element, +		 * but we actually allocate the number we need.  		 */ -		bsize = (Aliste)((alp->al_end * 2) - sizeof (Alist) + -		    sizeof (void *)); -		if ((alp = realloc((void *)alp, (size_t)bsize)) == 0) -			return (0); -		alp->al_end = bsize; +		bsize = size * init_arritems; +		bsize = S_ROUND(bsize, sizeof (void *)); +		bsize = ALIST_OFF_DATA + bsize; +		if ((lp = malloc((size_t)bsize)) == NULL) +			return (NULL); +		lp->al_arritems = init_arritems; +		lp->al_nitems = 0; +		lp->al_next = ALIST_OFF_DATA; +		lp->al_size = size; +		*lpp = lp; +	} else { +		/* We must get the same value for size every time */ +		ASSERT(size == lp->al_size); + +		if (lp->al_nitems >= lp->al_arritems) { +			/* +			 * The list is full: Increase the memory allocation +			 * by doubling it. +			 */ +			Aliste	bsize; + +			bsize = lp->al_size * lp->al_arritems * 2; +			bsize = S_ROUND(bsize, sizeof (void *)); +			bsize = ALIST_OFF_DATA + bsize; +			if ((lp = realloc((void *)lp, (size_t)bsize)) == 0) +				return (NULL); +			lp->al_arritems *= 2; +			*lpp = lp; +		}  	}  	/* +	 * The caller is not supposed to use an index that +	 * would introduce a "hole" in the array. +	 */ +	ASSERT(idx <= lp->al_nitems); + +	addr = (idx * lp->al_size) + (char *)lp->al_data; + +	/*  	 * An appended item is added to the next available array element. -	 * An inserted item requires that the data items that exist at the point -	 * of insertion be shifted prior to the insertion. +	 * An insert at any other spot requires that the data items that +	 * exist at the point of insertion be shifted down to open a slot.  	 */ -	if ((off == 0) || (off == alp->al_next)) { -		new = (void *)((char *)alp + alp->al_next); +	if (idx < lp->al_nitems) +		(void) memmove(addr + lp->al_size, addr, +		    (lp->al_nitems - idx) * lp->al_size); + +	lp->al_nitems++; +	lp->al_next += lp->al_size; +	if (datap != NULL) +		(void) memcpy(addr, datap, lp->al_size); +	else +		(void) memset(addr, 0, lp->al_size); +	return (addr); +} + +void * +alist_insert_by_offset(Alist **lpp, const void *datap, size_t size, +    Aliste init_arritems, Aliste off) +{ +	Aliste idx; + +	if (*lpp == NULL) { +		ASSERT(off == ALIST_OFF_DATA); +		idx = 0;  	} else { -		new = (void *)((char *)alp + off); -		(void) memmove((void *)((char *)new + alp->al_size), new, -		    (alp->al_next - off)); +		idx = (off - ALIST_OFF_DATA) / (*lpp)->al_size; +	} + +	return (alist_insert(lpp, datap, size, init_arritems, idx)); +} + +void * +aplist_insert(APlist **lpp, const void *ptr, Aliste init_arritems, Aliste idx) +{ +	APlist	*lp = *lpp; + +	/* The initial array count needs to be non-zero */ +	ASSERT(init_arritems != 0); + +	if (lp == NULL) { +		Aliste bsize; + +		/* +		 * First time here, allocate a new APlist.  Note that the +		 * APlist apl_desc[] entry is defined for 1 element, +		 * but we actually allocate the number we need. +		 */ +		bsize = APLIST_OFF_DATA + (sizeof (void *) * init_arritems); +		if ((lp = malloc((size_t)bsize)) == NULL) +			return (NULL); +		lp->apl_arritems = init_arritems; +		lp->apl_nitems = 0; +		*lpp = lp; +	} else if (lp->apl_nitems >= lp->apl_arritems) { +		/* +		 * The list is full: Increase the memory allocation +		 * by doubling it. +		 */ +		Aliste	bsize; + +		bsize = APLIST_OFF_DATA + +		    (2 * sizeof (void *) * lp->apl_arritems); +		if ((lp = realloc((void *)lp, (size_t)bsize)) == 0) +			return (NULL); +		lp->apl_arritems *= 2; +		*lpp = lp;  	} -	alp->al_next += alp->al_size;  	/* -	 * If a data item has been provided, initialize the current alist entry -	 * with this item.  Otherwise, initialize the entry to zero, presumably -	 * the caller will fill this in. +	 * The caller is not supposed to use an index that +	 * would introduce a "hole" in the array.  	 */ -	if (item) -		(void) memcpy(new, item, alp->al_size); -	else -		(void) memset(new, 0, alp->al_size); +	ASSERT(idx <= lp->apl_nitems); -	*alpp = alp; -	return (new); +	/* +	 * An appended item is added to the next available array element. +	 * An insert at any other spot requires that the data items that +	 * exist at the point of insertion be shifted down to open a slot. +	 */ +	if (idx < lp->apl_nitems) +		(void) memmove((char *)&lp->apl_data[idx + 1], +		    (char *)&lp->apl_data[idx], +		    (lp->apl_nitems - idx) * sizeof (void *)); + +	lp->apl_nitems++; +	lp->apl_data[idx] = (void *)ptr; +	return (&lp->apl_data[idx]);  } + + + +  /* - * Append a value to an Alist. + * Append a value to a list. These are convenience wrappers on top + * of the insert operation. See the decription of those routine above + * for details.   */  void * -alist_append(Alist **alpp, const void *item, size_t size, int cnt) +alist_append(Alist **lpp, const void *datap, size_t size, +    Aliste init_arritems)  { -	return (alist_insert(alpp, item, size, cnt, 0)); +	Aliste ndx = ((*lpp) == NULL) ? 0 : (*lpp)->al_nitems; + +	return (alist_insert(lpp, datap, size, init_arritems, ndx));  } +void * +aplist_append(APlist **lpp, const void *ptr, Aliste init_arritems) +{ +	Aliste ndx = ((*lpp) == NULL) ? 0 : (*lpp)->apl_nitems; + +	return (aplist_insert(lpp, ptr, init_arritems, ndx)); +} + + + + +  /* - * Delete an element from an Alist.  If a count is provided then the caller - * already knows what element to remove.  Return a decremented count value so - * that the caller can continue an ALIST_TRAVERSE scan. + * Delete the item at a specified index/offset, and decrement the variable + * containing the index: + * + *	alist_delete - Delete an item from an Alist at the specified + *		index. + *	alist_delete_by_offset - Delete an item from an Alist at the + *		specified offset from the list pointer. + *	aplist_delete - Delete a pointer from an APlist at the specified + *		index. + * + * entry: + *	alp - List to delete item from + *	idxp - Address of variable containing the index of the + *		item to delete. + *	offp - Address of variable containing the offset of the + *		item to delete. + * + * exit: + *	The item at the position given by (*idxp) or (*offp), depending + *	on the routine, is removed from the list. Then, the position + *	variable (*idxp or *offp) is decremented by one item. This is done + *	to facilitate use of this routine within a TRAVERSE loop. + * + * note: + *	Deleting the last element in an array list is cheap, but + *	deleting any other item causes a memory copy to occur to + *	move the following items up. If you intend to traverse the + *	entire list, deleting every item as you go, it will be cheaper + *	to omit the delete within the traverse, and then call + *	the reset function reset() afterwards.   */ -int -alist_delete(Alist *alp, const void *item, Aliste *offp) +void +alist_delete(Alist *lp, Aliste *idxp)  { -	void	*addr; -	Aliste	off; +	Aliste	idx = *idxp; -	if (offp) { -		off = *offp; -		addr = (void *)((char *)alp + off); -	} else { -		for (ALIST_TRAVERSE(alp, off, addr)) { -			if (memcmp(addr, item, alp->al_size) == 0) -				break; -		} -	} -	if (off >= alp->al_next) -		return (0); +	/* The list must be allocated and the index in range */ +	ASSERT(lp != NULL); +	ASSERT(idx < lp->al_nitems);  	/*  	 * If the element to be removed is not the last entry of the array,  	 * slide the following elements over the present element.  	 */ -	if (off < (alp->al_next -= alp->al_size)) { -		(void) memmove((void *)addr, (void *)((char *)addr + -		    alp->al_size), (alp->al_next - off)); +	if (idx < --lp->al_nitems) { +		char *addr = (idx * lp->al_size) + (char *)lp->al_data; + +		(void) memmove(addr, addr + lp->al_size, +		    (lp->al_nitems - idx) * lp->al_size);  	} +	lp->al_next -= lp->al_size; + +	/* Decrement the callers index variable */ +	(*idxp)--; +} + +void +alist_delete_by_offset(Alist *lp, Aliste *offp) +{ +	Aliste idx; + +	ASSERT(lp != NULL); +	idx = (*offp - ALIST_OFF_DATA) / lp->al_size; + +	alist_delete(lp, &idx); +	*offp -= lp->al_size; +} + +void +aplist_delete(APlist *lp, Aliste *idxp) +{ +	Aliste	idx = *idxp; + + +	/* The list must be allocated and the index in range */ +	ASSERT(lp != NULL); +	ASSERT(idx < lp->apl_nitems);  	/* -	 * Reset the new offset, and decrement the callers count control -	 * variable if necessary.  Null out the old tail element. +	 * If the element to be removed is not the last entry of the array, +	 * slide the following elements over the present element.  	 */ -	addr = (void *)((char *)alp + alp->al_next); -	(void) memset(addr, 0, alp->al_size); +	if (idx < --lp->apl_nitems) +		(void) memmove(&lp->apl_data[idx], &lp->apl_data[idx + 1], +		    (lp->apl_nitems - idx) * sizeof (void *)); -	if (offp) -		*offp -= alp->al_size; - -	return (1); +	/* Decrement the callers index variable */ +	(*idxp)--;  } + + + +  /* - * Generic alist test and append routine. + * Delete the pointer with a specified value from the APlist. + * + * entry: + *	lp - Initialized APlist to delete item from + *	ptr - Pointer to be deleted. + * + * exit: + *	The list is searched for an item containing the given pointer, + *	and if a match is found, that item is delted and True (1) returned. + *	If no match is found, then False (0) is returned. + * + * note: + *	See note for delete operation, above.   */  int -alist_test(Alist ** alpp, void * ip, size_t size, int cnt) +aplist_delete_value(APlist *lp, const void *ptr)  { -	Aliste	off; -	void **	ipp; +	size_t	idx; -	for (ALIST_TRAVERSE(*alpp, off, ipp)) { -		if (size == sizeof (uintptr_t)) { -			if (ip == *ipp) -				return (ALE_EXISTS); -		} else { -			if (memcmp(ip, *ipp, size) == 0) -				return (ALE_EXISTS); +	/* +	 * If the pointer is found in the list, use aplist_delete to +	 * remove it, and we're done. +	 */ +	for (idx = 0; idx < lp->apl_nitems; idx++) +		if (ptr == lp->apl_data[idx]) { +			aplist_delete(lp, &idx); +			return (1);  		} -	} -	if (cnt) { -		if (alist_append(alpp, &ip, size, cnt) == 0) -			return (0); -	} +	/* If we get here, the item was not in the list */ +	return (0); +} + + + + + + + +/* + * Search the APlist for an element with a given value, and + * if not found, optionally append the element to the end of the list. + * + * entry: + *	lpp, ptr - As per aplist_insert(). + *	init_arritems - As per aplist_insert() if a non-zero value. + *		A value of zero is special, and is taken to indicate + *		that no insert operation should be performed if + *		the item is not found in the list. + * + * exit + *	The given item is compared to every item in the given APlist. + *	If it is found, ALE_EXISTS is returned. + * + *	If it is not found: If init_arr_items is False (0), then + *	ALE_NOTFOUND is returned. If init_arr_items is True, then + *	the item is appended to the list, and ALE_CREATE returned on success. + * + *	On failure, which can only occur due to memory allocation failure, + *	ALE_ALLOCFAIL is returned. + * + * note: + *	The test operation used by this routine is a linear + *	O(N) operation, and is not efficient for more than a + *	few items. + */ +aplist_test_t +aplist_test(APlist **lpp, const void *ptr, Aliste init_arritems) +{ +	APlist	*lp = *lpp; +	size_t	idx; + +	/* Is the pointer already in the list? */ +	if (lp != NULL) +		for (idx = 0; idx < lp->apl_nitems; idx++) +			if (ptr == lp->apl_data[idx]) +				return (ALE_EXISTS); + +	/* Is this a no-insert case? If so, report that the item is not found */ +	if (init_arritems == 0) +		return (ALE_NOTFND); + +	/* Add it to the end of the list */ +	if (aplist_append(lpp, ptr, init_arritems) == NULL) +		return (ALE_ALLOCFAIL);  	return (ALE_CREATE);  } + + + + + + + +/* + * Reset the given list to its empty state. Any memory allocated by the + * list is preserved, ready for reuse, but the list is set to its + * empty state, equivalent to having called the delete operation for + * every item. + * + * Note that no cleanup of the discarded items is done. The caller must + * take care of any necessary cleanup before calling aplist_reset(). + */ +void +alist_reset(Alist *lp) +{ +	if (lp != NULL) { +		lp->al_nitems = 0; +		lp->al_next = ALIST_OFF_DATA; +	} +} + +void +aplist_reset(APlist *lp) +{ +	if (lp != NULL) +		lp->apl_nitems = 0; +} diff --git a/usr/src/cmd/sgs/tools/common/sgsmsg.c b/usr/src/cmd/sgs/tools/common/sgsmsg.c index 3b06e5ff6a..9b2e37b507 100644 --- a/usr/src/cmd/sgs/tools/common/sgsmsg.c +++ b/usr/src/cmd/sgs/tools/common/sgsmsg.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   *   * sgsmsg generates several message files from an input template file.  Messages @@ -320,12 +320,12 @@ dump_stringtab(Str_tbl *stp)  	uint_t	cnt;  	if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) { -		(void) printf("string table full size: %d: uncompressed\n", +		(void) printf("string table full size: %ld: uncompressed\n",  		    stp->st_fullstrsize);  		return;  	} -	(void) printf("string table full size: %d compressed down to: %d\n\n", +	(void) printf("string table full size: %ld compressed down to: %ld\n\n",  	    stp->st_fullstrsize, stp->st_strsize);  	(void) printf("string table compression information [%d buckets]:\n",  	    stp->st_hbckcnt); @@ -339,14 +339,14 @@ dump_stringtab(Str_tbl *stp)  		(void) printf(" bucket: [%d]\n", cnt);  		while (sthash) { -			uint_t	stroff = sthash->hi_mstr->sm_strlen - +			size_t	stroff = sthash->hi_mstr->sm_strlen -  			    sthash->hi_strlen;  			if (stroff == 0) { -				(void) printf("  [%d]: '%s'  <master>\n", +				(void) printf("  [%ld]: '%s'  <master>\n",  				    sthash->hi_refcnt, sthash->hi_mstr->sm_str);  			} else { -				(void) printf("  [%d]: '%s'  <suffix of: " +				(void) printf("  [%ld]: '%s'  <suffix of: "  				    "'%s'>\n", sthash->hi_refcnt,  				    &sthash->hi_mstr->sm_str[stroff],  				    sthash->hi_mstr->sm_str); @@ -533,7 +533,7 @@ static int  output_defs(void)  {  	msg_string	*msg; -	uint_t		stbufsize; +	size_t		stbufsize;  	char		*stbuf;  	stbufsize = st_getstrtab_sz(stp); @@ -543,12 +543,12 @@ output_defs(void)  	}  	(void) st_setstrbuf(stp, stbuf, stbufsize);  	for (msg = msg_head; msg; msg = msg->ms_next) { -		uint_t	stoff; +		size_t	stoff;  		if ((st_setstring(stp, msg->ms_message, &stoff)) == -1) {  			(void) fprintf(stderr, Errmsg_mnfn, msg->ms_message);  			return (1);  		} -		if (fprintf(fddefs, "\n#define\t%s\t%d\n", +		if (fprintf(fddefs, "\n#define\t%s\t%ld\n",  		    msg->ms_defn, stoff) < 0) {  			(void) fprintf(stderr, Errmsg_wrte,  			    fldefs, strerror(errno)); @@ -571,9 +571,9 @@ output_defs(void)  static int  output_data(void)  { -	uint_t		stbufsize; -	uint_t		ndx; -	uint_t		column = 1; +	size_t		stbufsize; +	size_t		ndx; +	size_t		column = 1;  	const char	*stbuf;  	const char	*fmtstr; @@ -591,7 +591,7 @@ output_data(void)  	else  		fmtstr = (const char *)"const"; -	if (fprintf(fddata, "\n%s char __%s[%d] = { ", +	if (fprintf(fddata, "\n%s char __%s[%ld] = { ",  	    fmtstr, interface, stbufsize) < 0) {  		(void) fprintf(stderr, Errmsg_wrte, fldata, strerror(errno));  		return (1); @@ -600,7 +600,7 @@ output_data(void)  	for (ndx = 0; ndx < (stbufsize - 1); ndx++) {  		if (column == 1) {  			if (fddata && fprintf(fddata, -			    "\n/* %4d */ 0x%.2x,", ndx, +			    "\n/* %4ld */ 0x%.2x,", ndx,  			    (unsigned char)stbuf[ndx]) < 0) {  				(void) fprintf(stderr, Errmsg_wrte,  				    fldata, strerror(errno)); diff --git a/usr/src/cmd/sgs/tools/common/string_table.c b/usr/src/cmd/sgs/tools/common/string_table.c index b3b669a8c3..e174acaf04 100644 --- a/usr/src/cmd/sgs/tools/common/string_table.c +++ b/usr/src/cmd/sgs/tools/common/string_table.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -120,7 +120,7 @@  static int  avl_len_compare(const void *n1, const void *n2)  { -	uint_t	len1, len2; +	size_t	len1, len2;  	len1 = ((LenNode *)n1)->ln_strlen;  	len2 = ((LenNode *)n2)->ln_strlen; @@ -197,7 +197,7 @@ st_new(uint_t flags)  int  st_insert(Str_tbl *stp, const char *str)  { -	uint_t		len; +	size_t		len;  	StrNode		*snp, sn = { 0 };  	LenNode		*lnp, ln = { 0 };  	avl_index_t	where; @@ -211,7 +211,7 @@ st_insert(Str_tbl *stp, const char *str)  	 * Null strings always point to the head of the string  	 * table - no reason to keep searching.  	 */ -	if ((len = (uint_t)strlen(str)) == 0) +	if ((len = strlen(str)) == 0)  		return (0);  	stp->st_fullstrsize += len + 1; @@ -262,7 +262,7 @@ st_insert(Str_tbl *stp, const char *str)  int  st_delstring(Str_tbl *stp, const char *str)  { -	uint_t		len; +	size_t		len;  	LenNode		*lnp, ln = { 0 };  	StrNode		*snp, sn = { 0 }; @@ -271,7 +271,7 @@ st_delstring(Str_tbl *stp, const char *str)  	 */  	assert((stp->st_flags & FLG_STTAB_COOKED) == 0); -	len = (uint_t)strlen(str); +	len = strlen(str);  	stp->st_fullstrsize -= len + 1;  	if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) @@ -347,9 +347,9 @@ st_destroy(Str_tbl *stp)   * the Str_tbl.   */  int -st_setstring(Str_tbl *stp, const char *str, uint_t *stoff) +st_setstring(Str_tbl *stp, const char *str, size_t *stoff)  { -	uint_t		stlen; +	size_t		stlen;  	uint_t		hashval;  	Str_hash	*sthash;  	Str_master	*mstr; @@ -361,7 +361,7 @@ st_setstring(Str_tbl *stp, const char *str, uint_t *stoff)  	assert(stp->st_strbuf);  	assert(stp->st_flags & FLG_STTAB_COOKED); -	stlen = (uint_t)strlen(str); +	stlen = strlen(str);  	/*  	 * Null string always points to head of string table  	 */ @@ -371,7 +371,7 @@ st_setstring(Str_tbl *stp, const char *str, uint_t *stoff)  	}  	if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) { -		uint_t		_stoff; +		size_t		_stoff;  		stlen++;	/* count for trailing '\0' */  		_stoff = stp->st_nextoff; @@ -419,7 +419,7 @@ st_setstring(Str_tbl *stp, const char *str, uint_t *stoff)  	 */  	mstr = sthash->hi_mstr;  	if (mstr->sm_stroff == 0) { -		uint_t	mstrlen = mstr->sm_strlen + 1; +		size_t	mstrlen = mstr->sm_strlen + 1;  		mstr->sm_stroff = stp->st_nextoff; @@ -444,7 +444,7 @@ st_setstring(Str_tbl *stp, const char *str, uint_t *stoff)  static int -st_hash_insert(Str_tbl *stp, const char *str, uint_t len) +st_hash_insert(Str_tbl *stp, const char *str, size_t len)  {  	int		i;  	uint_t		hashval = HASHSEED; @@ -549,7 +549,7 @@ st_hash_insert(Str_tbl *stp, const char *str, uint_t len)  /*   * Return amount of space required for the string table.   */ -uint_t +size_t  st_getstrtab_sz(Str_tbl *stp)  {  	assert(stp->st_fullstrsize > 0); @@ -657,7 +657,7 @@ st_getstrbuf(Str_tbl *stp)  }  int -st_setstrbuf(Str_tbl *stp, char *stbuf, uint_t bufsize) +st_setstrbuf(Str_tbl *stp, char *stbuf, size_t bufsize)  {  	assert(stp->st_flags & FLG_STTAB_COOKED); | 
