Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #include	<stdlib.h>
     28 #include	<stdio.h>
     29 #include	<_elfedit.h>
     30 #include	<conv.h>
     31 #include	<msg.h>
     32 
     33 
     34 
     35 /*
     36  * This file contains support for mapping well known ELF constants
     37  * to their numeric values. It is a layer on top of the elfedit_atoui()
     38  * routines defined in util.c. The idea is that centralizing all the
     39  * support for such constants will improve consistency between modules,
     40  * allow for sharing of commonly needed items, and make the modules
     41  * simpler.
     42  */
     43 
     44 
     45 
     46 
     47 /*
     48  * elfedit output style, with and without leading -o
     49  */
     50 static elfedit_atoui_sym_t sym_outstyle[] = {
     51 	{ MSG_ORIG(MSG_STR_DEFAULT),		ELFEDIT_OUTSTYLE_DEFAULT },
     52 	{ MSG_ORIG(MSG_STR_SIMPLE),		ELFEDIT_OUTSTYLE_SIMPLE },
     53 	{ MSG_ORIG(MSG_STR_NUM),		ELFEDIT_OUTSTYLE_NUM },
     54 	{ NULL }
     55 };
     56 static elfedit_atoui_sym_t sym_minus_o_outstyle[] = {
     57 	{ MSG_ORIG(MSG_STR_MINUS_O_DEFAULT),	ELFEDIT_OUTSTYLE_DEFAULT },
     58 	{ MSG_ORIG(MSG_STR_MINUS_O_SIMPLE),	ELFEDIT_OUTSTYLE_SIMPLE },
     59 	{ MSG_ORIG(MSG_STR_MINUS_O_NUM),	ELFEDIT_OUTSTYLE_NUM },
     60 	{ NULL }
     61 };
     62 
     63 
     64 /*
     65  * Booleans
     66  */
     67 static elfedit_atoui_sym_t sym_bool[] = {
     68 	{ MSG_ORIG(MSG_STR_T),			1 },
     69 	{ MSG_ORIG(MSG_STR_F),			0 },
     70 	{ MSG_ORIG(MSG_STR_TRUE),		1 },
     71 	{ MSG_ORIG(MSG_STR_FALSE),		0 },
     72 	{ MSG_ORIG(MSG_STR_ON),			1 },
     73 	{ MSG_ORIG(MSG_STR_OFF),		0 },
     74 	{ MSG_ORIG(MSG_STR_YES),		1 },
     75 	{ MSG_ORIG(MSG_STR_NO),			0 },
     76 	{ MSG_ORIG(MSG_STR_Y),			1 },
     77 	{ MSG_ORIG(MSG_STR_N),			0 },
     78 	{ NULL }
     79 };
     80 
     81 /*
     82  * ELF strings for SHT_STRTAB
     83  */
     84 static elfedit_atoui_sym_t sym_sht_strtab[] = {
     85 	{ MSG_ORIG(MSG_SHT_STRTAB),		SHT_STRTAB },
     86 	{ MSG_ORIG(MSG_SHT_STRTAB_ALT1),	SHT_STRTAB },
     87 
     88 	{ NULL }
     89 };
     90 
     91 
     92 /*
     93  * Strings for SHT_SYMTAB
     94  */
     95 static elfedit_atoui_sym_t sym_sht_symtab[] = {
     96 	{ MSG_ORIG(MSG_SHT_SYMTAB),		SHT_SYMTAB },
     97 	{ MSG_ORIG(MSG_SHT_SYMTAB_ALT1),	SHT_SYMTAB },
     98 
     99 	{ NULL }
    100 };
    101 
    102 /*
    103  * Strings for SHT_DYNSYM
    104  */
    105 static elfedit_atoui_sym_t sym_sht_dynsym[] = {
    106 	{ MSG_ORIG(MSG_SHT_DYNSYM),		SHT_DYNSYM },
    107 	{ MSG_ORIG(MSG_SHT_DYNSYM_ALT1),	SHT_DYNSYM },
    108 
    109 	{ NULL }
    110 };
    111 
    112 /*
    113  * Strings for SHT_SUNW_LDYNSYM
    114  */
    115 static elfedit_atoui_sym_t sym_sht_ldynsym[] = {
    116 	{ MSG_ORIG(MSG_SHT_SUNW_LDYNSYM),	SHT_SUNW_LDYNSYM },
    117 	{ MSG_ORIG(MSG_SHT_SUNW_LDYNSYM_ALT1),	SHT_SUNW_LDYNSYM },
    118 
    119 	{ NULL }
    120 };
    121 
    122 
    123 
    124 /*
    125  * Types of items found in sym_table[]. All items other than STE_STATIC
    126  * pulls strings from libconv, differing in the interface required by
    127  * the libconv iteration function used.
    128  */
    129 typedef enum {
    130 	STE_STATIC =		0,	/* Constants are statically defined */
    131 	STE_LC =		1,	/* Libconv, pull once */
    132 	STE_LC_OS =		2,	/* From libconv, osabi dependency */
    133 	STE_LC_MACH =		3,	/* From libconv, mach dependency */
    134 	STE_LC_OS_MACH =	4	/* From libconv, osabi/mach dep. */
    135 } ste_type_t;
    136 
    137 /*
    138  * Interface of functions called to fill strings from libconv
    139  */
    140 typedef conv_iter_ret_t	(* libconv_iter_func_simple_t)(
    141 			    Conv_fmt_flags_t, conv_iter_cb_t, void *);
    142 typedef conv_iter_ret_t	(* libconv_iter_func_os_t)(conv_iter_osabi_t,
    143 			    Conv_fmt_flags_t, conv_iter_cb_t, void *);
    144 typedef conv_iter_ret_t	(* libconv_iter_func_mach_t)(Half,
    145 			    Conv_fmt_flags_t, conv_iter_cb_t, void *);
    146 typedef conv_iter_ret_t	(* libconv_iter_func_os_mach_t)(conv_iter_osabi_t, Half,
    147 			    Conv_fmt_flags_t, conv_iter_cb_t, void *);
    148 typedef union {
    149 	libconv_iter_func_simple_t	simple;
    150 	libconv_iter_func_os_t		osabi;
    151 	libconv_iter_func_mach_t	mach;
    152 	libconv_iter_func_os_mach_t	osabi_mach;
    153 } libconv_iter_func_t;
    154 
    155 /*
    156  * State for each type of constant
    157  */
    158 typedef struct {
    159 	ste_type_t		ste_type;	/* Type of entry */
    160 	elfedit_atoui_sym_t	*ste_arr;	/* NULL, or atoui array */
    161 	void			*ste_alloc;	/* Current memory allocation */
    162 	size_t			ste_nelts;	/* # items in ste_alloc */
    163 	libconv_iter_func_t	ste_conv_func;	/* libconv fill function */
    164 } sym_table_ent_t;
    165 
    166 
    167 /*
    168  * Array of state for each constant type, including the array of atoui
    169  * pointers, for each constant type, indexed by elfedit_const_t value.
    170  * The number and order of entries in this table must agree with the
    171  * definition of elfedit_const_t in elfedit.h.
    172  *
    173  * note:
    174  * -	STE_STATIC items must supply a statically allocated buffer here.
    175  * -	The non-STE_STATIC items use libconv strings. These items are
    176  *	initialized by init_libconv_strings() at runtime, and are represented
    177  *	by a simple { 0 } here. The memory used for these arrays is dynamic,
    178  *	and can be released and rebuilt at runtime as necessary to keep up
    179  *	with changes in osabi or machine type.
    180  */
    181 static sym_table_ent_t sym_table[ELFEDIT_CONST_NUM] = {
    182 						/* #: ELFEDIT_CONST_xxx */
    183 	{ STE_STATIC, sym_outstyle },		/* 0: OUTSTYLE */
    184 	{ STE_STATIC, sym_minus_o_outstyle },	/* 1: OUTSTYLE_MO */
    185 	{ STE_STATIC, sym_bool },		/* 2: BOOL */
    186 	{ STE_STATIC, sym_sht_strtab },		/* 3: SHT_STRTAB */
    187 	{ STE_STATIC, sym_sht_symtab },		/* 4: SHT_SYMTAB */
    188 	{ STE_STATIC, sym_sht_dynsym },		/* 5: SHT_DYNSYM */
    189 	{ STE_STATIC, sym_sht_ldynsym },	/* 6: SHT_LDYNSYM */
    190 	{ 0 },					/* 7: SHN */
    191 	{ 0 },					/* 8: SHT */
    192 	{ 0 },					/* 9: SHT_ALLSYMTAB */
    193 	{ 0 },					/* 10: DT */
    194 	{ 0 },					/* 11: DF */
    195 	{ 0 },					/* 12: DF_P1 */
    196 	{ 0 },					/* 13: DF_1 */
    197 	{ 0 },					/* 14: DTF_1 */
    198 	{ 0 },					/* 15: EI */
    199 	{ 0 },					/* 16: ET */
    200 	{ 0 },					/* 17: ELFCLASS */
    201 	{ 0 },					/* 18: ELFDATA */
    202 	{ 0 },					/* 19: EF */
    203 	{ 0 },					/* 20: EV */
    204 	{ 0 },					/* 21: EM */
    205 	{ 0 },					/* 22: ELFOSABI */
    206 	{ 0 },					/* 23: EAV osabi version */
    207 	{ 0 },					/* 24: PT */
    208 	{ 0 },					/* 25: PF */
    209 	{ 0 },					/* 26: SHF */
    210 	{ 0 },					/* 27: STB */
    211 	{ 0 },					/* 28: STT */
    212 	{ 0 },					/* 29: STV */
    213 	{ 0 },					/* 30: SYMINFO_BT */
    214 	{ 0 },					/* 31: SYMINFO_FLG */
    215 	{ 0 },					/* 32: CA */
    216 	{ 0 },					/* 33: AV */
    217 	{ 0 },					/* 34: SF1_SUNW */
    218 };
    219 #if ELFEDIT_CONST_NUM != (ELFEDIT_CONST_SF1_SUNW)
    220 error "ELFEDIT_CONST_NUM has grown. Update sym_table[]"
    221 #endif
    222 
    223 
    224 
    225 
    226 /*
    227  * Used to count the number of descriptors that will be needed to hold
    228  * strings from libconv.
    229  */
    230 /*ARGSUSED*/
    231 static conv_iter_ret_t
    232 libconv_count_cb(const char *str, Conv_elfvalue_t value, void *uvalue)
    233 {
    234 	size_t *cnt = (size_t *)uvalue;
    235 
    236 	(*cnt)++;
    237 	return (CONV_ITER_CONT);
    238 }
    239 
    240 /*
    241  * Used to fill in the descriptors with strings from libconv.
    242  */
    243 typedef struct {
    244 	size_t			cur;	/* Index of next descriptor */
    245 	size_t			cnt;	/* # of descriptors */
    246 	elfedit_atoui_sym_t	*desc;	/* descriptors */
    247 } libconv_fill_state_t;
    248 
    249 static conv_iter_ret_t
    250 libconv_fill_cb(const char *str, Conv_elfvalue_t value, void *uvalue)
    251 {
    252 	libconv_fill_state_t	*fill_state = (libconv_fill_state_t *)uvalue;
    253 	elfedit_atoui_sym_t	*sym = &fill_state->desc[fill_state->cur++];
    254 
    255 	sym->sym_name = str;
    256 	sym->sym_value = value;
    257 	return (CONV_ITER_CONT);
    258 }
    259 
    260 
    261 /*
    262  * Call the iteration function using the correct calling sequence for
    263  * the libconv routine.
    264  */
    265 static void
    266 libconv_fill_iter(sym_table_ent_t *sym, conv_iter_osabi_t osabi, Half mach,
    267     conv_iter_cb_t func, void *uvalue)
    268 {
    269 	switch (sym->ste_type) {
    270 	case STE_LC:
    271 		(void) (* sym->ste_conv_func.simple)(
    272 		    CONV_FMT_ALT_CF, func, uvalue);
    273 		(void) (* sym->ste_conv_func.simple)(
    274 		    CONV_FMT_ALT_NF, func, uvalue);
    275 		break;
    276 
    277 	case STE_LC_OS:
    278 		(void) (* sym->ste_conv_func.osabi)(osabi,
    279 		    CONV_FMT_ALT_CF, func, uvalue);
    280 		(void) (* sym->ste_conv_func.osabi)(osabi,
    281 		    CONV_FMT_ALT_NF, func, uvalue);
    282 		break;
    283 
    284 	case STE_LC_MACH:
    285 		(void) (* sym->ste_conv_func.mach)(mach,
    286 		    CONV_FMT_ALT_CF, func, uvalue);
    287 		(void) (* sym->ste_conv_func.mach)(mach,
    288 		    CONV_FMT_ALT_NF, func, uvalue);
    289 		break;
    290 
    291 	case STE_LC_OS_MACH:
    292 		(void) (* sym->ste_conv_func.osabi_mach)(osabi, mach,
    293 		    CONV_FMT_ALT_CF, func, uvalue);
    294 		(void) (* sym->ste_conv_func.osabi_mach)(osabi, mach,
    295 		    CONV_FMT_ALT_NF, func, uvalue);
    296 		break;
    297 	}
    298 }
    299 
    300 /*
    301  * Allocate/Fill an atoui array for the specified constant.
    302  */
    303 static void
    304 libconv_fill(sym_table_ent_t *sym, conv_iter_osabi_t osabi, Half mach)
    305 {
    306 	libconv_fill_state_t	fill_state;
    307 
    308 	/* How many descriptors will we need? */
    309 	fill_state.cnt = 1;		/* Extra for NULL termination */
    310 	libconv_fill_iter(sym, osabi, mach, libconv_count_cb, &fill_state.cnt);
    311 
    312 	/*
    313 	 * If there is an existing allocation, and it is not large enough,
    314 	 * release it.
    315 	 */
    316 	if ((sym->ste_alloc != NULL) && (fill_state.cnt > sym->ste_nelts)) {
    317 		free(sym->ste_alloc);
    318 		sym->ste_alloc = NULL;
    319 		sym->ste_nelts = 0;
    320 	}
    321 
    322 	/* Allocate memory if don't already have an allocation */
    323 	if (sym->ste_alloc == NULL) {
    324 		sym->ste_alloc = elfedit_malloc(MSG_INTL(MSG_ALLOC_ELFCONDESC),
    325 		    fill_state.cnt * sizeof (*fill_state.desc));
    326 		sym->ste_nelts = fill_state.cnt;
    327 	}
    328 
    329 	/* Fill the array */
    330 	fill_state.desc = sym->ste_alloc;
    331 	fill_state.cur = 0;
    332 	libconv_fill_iter(sym, osabi, mach, libconv_fill_cb, &fill_state);
    333 
    334 	/* Add null termination */
    335 	fill_state.desc[fill_state.cur].sym_name = NULL;
    336 	fill_state.desc[fill_state.cur].sym_value = 0;
    337 
    338 	/* atoui array for this item is now available */
    339 	sym->ste_arr = fill_state.desc;
    340 }
    341 
    342 /*
    343  * Should be called on first call to elfedit_const_to_atoui(). Does the
    344  * runtime initialization of sym_table.
    345  */
    346 static void
    347 init_libconv_strings(conv_iter_osabi_t *osabi, Half *mach)
    348 {
    349 	/*
    350 	 * It is critical that the ste_type and ste_conv_func values
    351 	 * agree. Since the libconv iteration function signatures can
    352 	 * change (gain or lose an osabi or mach argument), we want to
    353 	 * ensure that the compiler will catch such changes.
    354 	 *
    355 	 * The compiler will catch an attempt to assign a function of
    356 	 * the wrong type to ste_conv_func. Using these macros, we ensure
    357 	 * that the ste_type and function assignment happen as a unit.
    358 	 */
    359 #define	LC(_ndx, _func) sym_table[_ndx].ste_type = STE_LC; \
    360 	sym_table[_ndx].ste_conv_func.simple = _func;
    361 #define	LC_OS(_ndx, _func) sym_table[_ndx].ste_type = STE_LC_OS; \
    362 	sym_table[_ndx].ste_conv_func.osabi = _func;
    363 #define	LC_MACH(_ndx, _func) sym_table[_ndx].ste_type = STE_LC_MACH; \
    364 	sym_table[_ndx].ste_conv_func.mach = _func;
    365 #define	LC_OS_MACH(_ndx, _func) sym_table[_ndx].ste_type = STE_LC_OS_MACH; \
    366 	sym_table[_ndx].ste_conv_func.osabi_mach = _func;
    367 
    368 
    369 	if (!state.file.present) {
    370 		/*
    371 		 * No input file: Supply the maximal set of strings for
    372 		 * all osabi and mach values understood by libconv.
    373 		 */
    374 		*osabi = CONV_OSABI_ALL;
    375 		*mach = CONV_MACH_ALL;
    376 	} else if (state.elf.elfclass == ELFCLASS32) {
    377 		*osabi = state.elf.obj_state.s32->os_ehdr->e_ident[EI_OSABI];
    378 		*mach = state.elf.obj_state.s32->os_ehdr->e_machine;
    379 	} else {
    380 		*osabi = state.elf.obj_state.s64->os_ehdr->e_ident[EI_OSABI];
    381 		*mach = state.elf.obj_state.s64->os_ehdr->e_machine;
    382 	}
    383 
    384 	/* Set up non- STE_STATIC libconv fill functions */
    385 	LC_OS_MACH(ELFEDIT_CONST_SHN,		conv_iter_sym_shndx);
    386 	LC_OS_MACH(ELFEDIT_CONST_SHT,		conv_iter_sec_type);
    387 	LC_OS(ELFEDIT_CONST_SHT_ALLSYMTAB,	conv_iter_sec_symtab);
    388 	LC_OS_MACH(ELFEDIT_CONST_DT,		conv_iter_dyn_tag);
    389 	LC(ELFEDIT_CONST_DF,			conv_iter_dyn_flag);
    390 	LC(ELFEDIT_CONST_DF_P1,			conv_iter_dyn_posflag1);
    391 	LC(ELFEDIT_CONST_DF_1,			conv_iter_dyn_flag1);
    392 	LC(ELFEDIT_CONST_DTF_1,			conv_iter_dyn_feature1);
    393 	LC(ELFEDIT_CONST_EI,			conv_iter_ehdr_eident);
    394 	LC_OS(ELFEDIT_CONST_ET,			conv_iter_ehdr_type);
    395 	LC(ELFEDIT_CONST_ELFCLASS,		conv_iter_ehdr_class);
    396 	LC(ELFEDIT_CONST_ELFDATA,		conv_iter_ehdr_data);
    397 	LC_MACH(ELFEDIT_CONST_EF,		conv_iter_ehdr_flags);
    398 	LC(ELFEDIT_CONST_EV,			conv_iter_ehdr_vers);
    399 	LC(ELFEDIT_CONST_EM,			conv_iter_ehdr_mach);
    400 	LC(ELFEDIT_CONST_ELFOSABI,		conv_iter_ehdr_osabi);
    401 	LC_OS(ELFEDIT_CONST_EAV,		conv_iter_ehdr_abivers);
    402 	LC_OS(ELFEDIT_CONST_PT,			conv_iter_phdr_type);
    403 	LC_OS(ELFEDIT_CONST_PF,			conv_iter_phdr_flags);
    404 	LC_OS_MACH(ELFEDIT_CONST_SHF,		conv_iter_sec_flags);
    405 	LC(ELFEDIT_CONST_STB,			conv_iter_sym_info_bind);
    406 	LC_MACH(ELFEDIT_CONST_STT,		conv_iter_sym_info_type);
    407 	LC(ELFEDIT_CONST_STV,			conv_iter_sym_other_vis);
    408 	LC(ELFEDIT_CONST_SYMINFO_BT,		conv_iter_syminfo_boundto);
    409 	LC(ELFEDIT_CONST_SYMINFO_FLG,		conv_iter_syminfo_flags);
    410 	LC(ELFEDIT_CONST_CA,			conv_iter_cap_tags);
    411 	LC_MACH(ELFEDIT_CONST_AV,		conv_iter_cap_val_hw1);
    412 	LC(ELFEDIT_CONST_SF1_SUNW,		conv_iter_cap_val_sf1);
    413 
    414 #undef LC
    415 #undef LC_OS
    416 #undef LC_MACH
    417 #undef LC_OS_MACH
    418 }
    419 
    420 /*
    421  * If the user has changed the osabi or machine type of the object,
    422  * then we need to discard the strings we've loaded from libconv
    423  * that are dependent on these values.
    424  */
    425 static void
    426 invalidate_libconv_strings(conv_iter_osabi_t *osabi, Half *mach)
    427 {
    428 	uchar_t		cur_osabi;
    429 	Half		cur_mach;
    430 	sym_table_ent_t	*sym;
    431 	int		osabi_change, mach_change;
    432 	int		i;
    433 
    434 
    435 	/* Reset the ELF header change notification */
    436 	state.elf.elfconst_ehdr_change = 0;
    437 
    438 	if (state.elf.elfclass == ELFCLASS32) {
    439 		cur_osabi = state.elf.obj_state.s32->os_ehdr->e_ident[EI_OSABI];
    440 		cur_mach = state.elf.obj_state.s32->os_ehdr->e_machine;
    441 	} else {
    442 		cur_osabi = state.elf.obj_state.s64->os_ehdr->e_ident[EI_OSABI];
    443 		cur_mach = state.elf.obj_state.s64->os_ehdr->e_machine;
    444 	}
    445 
    446 	/* What has changed? */
    447 	mach_change = *mach != cur_mach;
    448 	osabi_change = *osabi != cur_osabi;
    449 	if (!(mach_change || osabi_change))
    450 		return;
    451 
    452 	/*
    453 	 * Set the ste_arr pointer to NULL for any items that
    454 	 * depend on the things that have changed. Note that we
    455 	 * do not release the allocated memory --- it may turn
    456 	 * out to be large enough to hold the new strings, so we
    457 	 * keep the allocation and leave that decision to the fill
    458 	 * routine, which will run the next time those strings are
    459 	 * needed.
    460 	 */
    461 	for (i = 0, sym = sym_table;
    462 	    i < (sizeof (sym_table) / sizeof (sym_table[0])); i++, sym++) {
    463 		if (sym->ste_arr == NULL)
    464 			continue;
    465 
    466 		switch (sym->ste_type) {
    467 		case STE_LC_OS:
    468 			if (osabi_change)
    469 				sym->ste_arr = NULL;
    470 			break;
    471 
    472 		case STE_LC_MACH:
    473 			if (mach_change)
    474 				sym->ste_arr = NULL;
    475 			break;
    476 
    477 		case STE_LC_OS_MACH:
    478 			if (osabi_change || mach_change)
    479 				sym->ste_arr = NULL;
    480 			break;
    481 		}
    482 	}
    483 
    484 	*mach = cur_mach;
    485 	*osabi = cur_osabi;
    486 }
    487 
    488 
    489 
    490 /*
    491  * Given an elfedit_const_t value, return the array of elfedit_atoui_sym_t
    492  * entries that it represents.
    493  */
    494 elfedit_atoui_sym_t *
    495 elfedit_const_to_atoui(elfedit_const_t const_type)
    496 {
    497 	static int			first = 1;
    498 	static conv_iter_osabi_t	osabi;
    499 	static Half			mach;
    500 
    501 	sym_table_ent_t	*sym;
    502 
    503 	if (first) {
    504 		init_libconv_strings(&osabi, &mach);
    505 		first = 0;
    506 	}
    507 
    508 	if ((const_type < 0) ||
    509 	    (const_type >= (sizeof (sym_table) / sizeof (sym_table[0]))))
    510 		elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADCONST));
    511 	sym = &sym_table[const_type];
    512 
    513 	/*
    514 	 * If the constant is not STE_STATIC, then we may need to fetch
    515 	 * the strings from libconv.
    516 	 */
    517 	if (sym->ste_type != STE_STATIC) {
    518 		/*
    519 		 * If the ELF header has changed since the last
    520 		 * time we were called, then we need to invalidate any
    521 		 * strings previously pulled from libconv that have
    522 		 * an osabi or machine dependency.
    523 		 */
    524 		if (state.elf.elfconst_ehdr_change)
    525 			invalidate_libconv_strings(&osabi, &mach);
    526 
    527 		/* If we don't already have the strings, get them */
    528 		if (sym->ste_arr == NULL)
    529 			libconv_fill(sym, osabi, mach);
    530 	}
    531 
    532 	return (sym->ste_arr);
    533 }
    534