diff options
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); |