1d29b2c44Sab /*
2d29b2c44Sab  * CDDL HEADER START
3d29b2c44Sab  *
4d29b2c44Sab  * The contents of this file are subject to the terms of the
5d29b2c44Sab  * Common Development and Distribution License (the "License").
6d29b2c44Sab  * You may not use this file except in compliance with the License.
7d29b2c44Sab  *
8d29b2c44Sab  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d29b2c44Sab  * or http://www.opensolaris.org/os/licensing.
10d29b2c44Sab  * See the License for the specific language governing permissions
11d29b2c44Sab  * and limitations under the License.
12d29b2c44Sab  *
13d29b2c44Sab  * When distributing Covered Code, include this CDDL HEADER in each
14d29b2c44Sab  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d29b2c44Sab  * If applicable, add the following below this CDDL HEADER, with the
16d29b2c44Sab  * fields enclosed by brackets "[]" replaced with your own identifying
17d29b2c44Sab  * information: Portions Copyright [yyyy] [name of copyright owner]
18d29b2c44Sab  *
19d29b2c44Sab  * CDDL HEADER END
20d29b2c44Sab  */
21d29b2c44Sab 
22d29b2c44Sab /*
23*08278a5eSRod Evans  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24d29b2c44Sab  * Use is subject to license terms.
25d29b2c44Sab  */
26d29b2c44Sab 
27d29b2c44Sab #include	<stdlib.h>
28d29b2c44Sab #include	<stdio.h>
29d29b2c44Sab #include	<_elfedit.h>
304f680cc6SAli Bahrami #include	<conv.h>
31d29b2c44Sab #include	<msg.h>
32d29b2c44Sab 
33d29b2c44Sab 
34d29b2c44Sab 
35d29b2c44Sab /*
36d29b2c44Sab  * This file contains support for mapping well known ELF constants
37d29b2c44Sab  * to their numeric values. It is a layer on top of the elfedit_atoui()
38d29b2c44Sab  * routines defined in util.c. The idea is that centralizing all the
39d29b2c44Sab  * support for such constants will improve consistency between modules,
40d29b2c44Sab  * allow for sharing of commonly needed items, and make the modules
41d29b2c44Sab  * simpler.
42d29b2c44Sab  */
43d29b2c44Sab 
44d29b2c44Sab 
45d29b2c44Sab 
46d29b2c44Sab 
47d29b2c44Sab /*
48d29b2c44Sab  * elfedit output style, with and without leading -o
49d29b2c44Sab  */
50d29b2c44Sab static elfedit_atoui_sym_t sym_outstyle[] = {
51d29b2c44Sab 	{ MSG_ORIG(MSG_STR_DEFAULT),		ELFEDIT_OUTSTYLE_DEFAULT },
52d29b2c44Sab 	{ MSG_ORIG(MSG_STR_SIMPLE),		ELFEDIT_OUTSTYLE_SIMPLE },
53d29b2c44Sab 	{ MSG_ORIG(MSG_STR_NUM),		ELFEDIT_OUTSTYLE_NUM },
54d29b2c44Sab 	{ NULL }
55d29b2c44Sab };
56d29b2c44Sab static elfedit_atoui_sym_t sym_minus_o_outstyle[] = {
57d29b2c44Sab 	{ MSG_ORIG(MSG_STR_MINUS_O_DEFAULT),	ELFEDIT_OUTSTYLE_DEFAULT },
58d29b2c44Sab 	{ MSG_ORIG(MSG_STR_MINUS_O_SIMPLE),	ELFEDIT_OUTSTYLE_SIMPLE },
59d29b2c44Sab 	{ MSG_ORIG(MSG_STR_MINUS_O_NUM),	ELFEDIT_OUTSTYLE_NUM },
60d29b2c44Sab 	{ NULL }
61d29b2c44Sab };
62d29b2c44Sab 
63d29b2c44Sab 
64d29b2c44Sab /*
65d29b2c44Sab  * Booleans
66d29b2c44Sab  */
67d29b2c44Sab static elfedit_atoui_sym_t sym_bool[] = {
68d29b2c44Sab 	{ MSG_ORIG(MSG_STR_T),			1 },
69d29b2c44Sab 	{ MSG_ORIG(MSG_STR_F),			0 },
70d29b2c44Sab 	{ MSG_ORIG(MSG_STR_TRUE),		1 },
71d29b2c44Sab 	{ MSG_ORIG(MSG_STR_FALSE),		0 },
72d29b2c44Sab 	{ MSG_ORIG(MSG_STR_ON),			1 },
73d29b2c44Sab 	{ MSG_ORIG(MSG_STR_OFF),		0 },
74d29b2c44Sab 	{ MSG_ORIG(MSG_STR_YES),		1 },
75d29b2c44Sab 	{ MSG_ORIG(MSG_STR_NO),			0 },
76d29b2c44Sab 	{ MSG_ORIG(MSG_STR_Y),			1 },
77d29b2c44Sab 	{ MSG_ORIG(MSG_STR_N),			0 },
78d29b2c44Sab 	{ NULL }
79d29b2c44Sab };
80d29b2c44Sab 
81d29b2c44Sab /*
824f680cc6SAli Bahrami  * ELF strings for SHT_STRTAB
83d29b2c44Sab  */
844f680cc6SAli Bahrami static elfedit_atoui_sym_t sym_sht_strtab[] = {
854f680cc6SAli Bahrami 	{ MSG_ORIG(MSG_SHT_STRTAB),		SHT_STRTAB },
864f680cc6SAli Bahrami 	{ MSG_ORIG(MSG_SHT_STRTAB_ALT1),	SHT_STRTAB },
87d29b2c44Sab 
88d29b2c44Sab 	{ NULL }
89d29b2c44Sab };
90d29b2c44Sab 
91d29b2c44Sab 
92d29b2c44Sab /*
934f680cc6SAli Bahrami  * Strings for SHT_SYMTAB
94d29b2c44Sab  */
954f680cc6SAli Bahrami static elfedit_atoui_sym_t sym_sht_symtab[] = {
964f680cc6SAli Bahrami 	{ MSG_ORIG(MSG_SHT_SYMTAB),		SHT_SYMTAB },
974f680cc6SAli Bahrami 	{ MSG_ORIG(MSG_SHT_SYMTAB_ALT1),	SHT_SYMTAB },
98d29b2c44Sab 
99d29b2c44Sab 	{ NULL }
100d29b2c44Sab };
101d29b2c44Sab 
102d29b2c44Sab /*
1034f680cc6SAli Bahrami  * Strings for SHT_DYNSYM
104d29b2c44Sab  */
1054f680cc6SAli Bahrami static elfedit_atoui_sym_t sym_sht_dynsym[] = {
1064f680cc6SAli Bahrami 	{ MSG_ORIG(MSG_SHT_DYNSYM),		SHT_DYNSYM },
1074f680cc6SAli Bahrami 	{ MSG_ORIG(MSG_SHT_DYNSYM_ALT1),	SHT_DYNSYM },
108d29b2c44Sab 
109d29b2c44Sab 	{ NULL }
110d29b2c44Sab };
111d29b2c44Sab 
112d29b2c44Sab /*
1134f680cc6SAli Bahrami  * Strings for SHT_SUNW_LDYNSYM
114d29b2c44Sab  */
1154f680cc6SAli Bahrami static elfedit_atoui_sym_t sym_sht_ldynsym[] = {
1164f680cc6SAli Bahrami 	{ MSG_ORIG(MSG_SHT_SUNW_LDYNSYM),	SHT_SUNW_LDYNSYM },
1174f680cc6SAli Bahrami 	{ MSG_ORIG(MSG_SHT_SUNW_LDYNSYM_ALT1),	SHT_SUNW_LDYNSYM },
118d29b2c44Sab 
119d29b2c44Sab 	{ NULL }
120d29b2c44Sab };
121d29b2c44Sab 
122d29b2c44Sab 
123d29b2c44Sab 
124d29b2c44Sab /*
1254f680cc6SAli Bahrami  * Types of items found in sym_table[]. All items other than STE_STATIC
1264f680cc6SAli Bahrami  * pulls strings from libconv, differing in the interface required by
1274f680cc6SAli Bahrami  * the libconv iteration function used.
128d29b2c44Sab  */
1294f680cc6SAli Bahrami typedef enum {
1304f680cc6SAli Bahrami 	STE_STATIC =		0,	/* Constants are statically defined */
1314f680cc6SAli Bahrami 	STE_LC =		1,	/* Libconv, pull once */
1324f680cc6SAli Bahrami 	STE_LC_OS =		2,	/* From libconv, osabi dependency */
1334f680cc6SAli Bahrami 	STE_LC_MACH =		3,	/* From libconv, mach dependency */
1344f680cc6SAli Bahrami 	STE_LC_OS_MACH =	4	/* From libconv, osabi/mach dep. */
1354f680cc6SAli Bahrami } ste_type_t;
136d29b2c44Sab 
137d29b2c44Sab /*
1384f680cc6SAli Bahrami  * Interface of functions called to fill strings from libconv
139d29b2c44Sab  */
1404f680cc6SAli Bahrami typedef conv_iter_ret_t	(* libconv_iter_func_simple_t)(
1414f680cc6SAli Bahrami 			    Conv_fmt_flags_t, conv_iter_cb_t, void *);
1424f680cc6SAli Bahrami typedef conv_iter_ret_t	(* libconv_iter_func_os_t)(conv_iter_osabi_t,
1434f680cc6SAli Bahrami 			    Conv_fmt_flags_t, conv_iter_cb_t, void *);
1444f680cc6SAli Bahrami typedef conv_iter_ret_t	(* libconv_iter_func_mach_t)(Half,
1454f680cc6SAli Bahrami 			    Conv_fmt_flags_t, conv_iter_cb_t, void *);
1464f680cc6SAli Bahrami typedef conv_iter_ret_t	(* libconv_iter_func_os_mach_t)(conv_iter_osabi_t, Half,
1474f680cc6SAli Bahrami 			    Conv_fmt_flags_t, conv_iter_cb_t, void *);
1484f680cc6SAli Bahrami typedef union {
1494f680cc6SAli Bahrami 	libconv_iter_func_simple_t	simple;
1504f680cc6SAli Bahrami 	libconv_iter_func_os_t		osabi;
1514f680cc6SAli Bahrami 	libconv_iter_func_mach_t	mach;
1524f680cc6SAli Bahrami 	libconv_iter_func_os_mach_t	osabi_mach;
1534f680cc6SAli Bahrami } libconv_iter_func_t;
154d29b2c44Sab 
155d29b2c44Sab /*
1564f680cc6SAli Bahrami  * State for each type of constant
157d29b2c44Sab  */
1584f680cc6SAli Bahrami typedef struct {
1594f680cc6SAli Bahrami 	ste_type_t		ste_type;	/* Type of entry */
1604f680cc6SAli Bahrami 	elfedit_atoui_sym_t	*ste_arr;	/* NULL, or atoui array */
1614f680cc6SAli Bahrami 	void			*ste_alloc;	/* Current memory allocation */
1624f680cc6SAli Bahrami 	size_t			ste_nelts;	/* # items in ste_alloc */
1634f680cc6SAli Bahrami 	libconv_iter_func_t	ste_conv_func;	/* libconv fill function */
1644f680cc6SAli Bahrami } sym_table_ent_t;
165d29b2c44Sab 
166d29b2c44Sab 
167d29b2c44Sab /*
1684f680cc6SAli Bahrami  * Array of state for each constant type, including the array of atoui
1694f680cc6SAli Bahrami  * pointers, for each constant type, indexed by elfedit_const_t value.
1704f680cc6SAli Bahrami  * The number and order of entries in this table must agree with the
1714f680cc6SAli Bahrami  * definition of elfedit_const_t in elfedit.h.
1724f680cc6SAli Bahrami  *
1734f680cc6SAli Bahrami  * note:
1744f680cc6SAli Bahrami  * -	STE_STATIC items must supply a statically allocated buffer here.
1754f680cc6SAli Bahrami  * -	The non-STE_STATIC items use libconv strings. These items are
1764f680cc6SAli Bahrami  *	initialized by init_libconv_strings() at runtime, and are represented
1774f680cc6SAli Bahrami  *	by a simple { 0 } here. The memory used for these arrays is dynamic,
1784f680cc6SAli Bahrami  *	and can be released and rebuilt at runtime as necessary to keep up
1794f680cc6SAli Bahrami  *	with changes in osabi or machine type.
1804f680cc6SAli Bahrami  */
1814f680cc6SAli Bahrami static sym_table_ent_t sym_table[ELFEDIT_CONST_NUM] = {
1824f680cc6SAli Bahrami 						/* #: ELFEDIT_CONST_xxx */
1834f680cc6SAli Bahrami 	{ STE_STATIC, sym_outstyle },		/* 0: OUTSTYLE */
1844f680cc6SAli Bahrami 	{ STE_STATIC, sym_minus_o_outstyle },	/* 1: OUTSTYLE_MO */
1854f680cc6SAli Bahrami 	{ STE_STATIC, sym_bool },		/* 2: BOOL */
1864f680cc6SAli Bahrami 	{ STE_STATIC, sym_sht_strtab },		/* 3: SHT_STRTAB */
1874f680cc6SAli Bahrami 	{ STE_STATIC, sym_sht_symtab },		/* 4: SHT_SYMTAB */
1884f680cc6SAli Bahrami 	{ STE_STATIC, sym_sht_dynsym },		/* 5: SHT_DYNSYM */
1894f680cc6SAli Bahrami 	{ STE_STATIC, sym_sht_ldynsym },	/* 6: SHT_LDYNSYM */
1904f680cc6SAli Bahrami 	{ 0 },					/* 7: SHN */
1914f680cc6SAli Bahrami 	{ 0 },					/* 8: SHT */
1924f680cc6SAli Bahrami 	{ 0 },					/* 9: SHT_ALLSYMTAB */
1934f680cc6SAli Bahrami 	{ 0 },					/* 10: DT */
1944f680cc6SAli Bahrami 	{ 0 },					/* 11: DF */
1954f680cc6SAli Bahrami 	{ 0 },					/* 12: DF_P1 */
1964f680cc6SAli Bahrami 	{ 0 },					/* 13: DF_1 */
1974f680cc6SAli Bahrami 	{ 0 },					/* 14: DTF_1 */
1984f680cc6SAli Bahrami 	{ 0 },					/* 15: EI */
1994f680cc6SAli Bahrami 	{ 0 },					/* 16: ET */
2004f680cc6SAli Bahrami 	{ 0 },					/* 17: ELFCLASS */
2014f680cc6SAli Bahrami 	{ 0 },					/* 18: ELFDATA */
2024f680cc6SAli Bahrami 	{ 0 },					/* 19: EF */
2034f680cc6SAli Bahrami 	{ 0 },					/* 20: EV */
2044f680cc6SAli Bahrami 	{ 0 },					/* 21: EM */
2054f680cc6SAli Bahrami 	{ 0 },					/* 22: ELFOSABI */
2064f680cc6SAli Bahrami 	{ 0 },					/* 23: EAV osabi version */
2074f680cc6SAli Bahrami 	{ 0 },					/* 24: PT */
2084f680cc6SAli Bahrami 	{ 0 },					/* 25: PF */
2094f680cc6SAli Bahrami 	{ 0 },					/* 26: SHF */
2104f680cc6SAli Bahrami 	{ 0 },					/* 27: STB */
2114f680cc6SAli Bahrami 	{ 0 },					/* 28: STT */
2124f680cc6SAli Bahrami 	{ 0 },					/* 29: STV */
2134f680cc6SAli Bahrami 	{ 0 },					/* 30: SYMINFO_BT */
2144f680cc6SAli Bahrami 	{ 0 },					/* 31: SYMINFO_FLG */
2154f680cc6SAli Bahrami 	{ 0 },					/* 32: CA */
2164f680cc6SAli Bahrami 	{ 0 },					/* 33: AV */
2174f680cc6SAli Bahrami 	{ 0 },					/* 34: SF1_SUNW */
2184f680cc6SAli Bahrami };
2194f680cc6SAli Bahrami #if ELFEDIT_CONST_NUM != (ELFEDIT_CONST_SF1_SUNW)
2204f680cc6SAli Bahrami error "ELFEDIT_CONST_NUM has grown. Update sym_table[]"
2214f680cc6SAli Bahrami #endif
22260758829Srie 
22360758829Srie 
22460758829Srie 
225d29b2c44Sab 
226d29b2c44Sab /*
2274f680cc6SAli Bahrami  * Used to count the number of descriptors that will be needed to hold
2284f680cc6SAli Bahrami  * strings from libconv.
229d29b2c44Sab  */
2304f680cc6SAli Bahrami /*ARGSUSED*/
2314f680cc6SAli Bahrami static conv_iter_ret_t
2324f680cc6SAli Bahrami libconv_count_cb(const char *str, Conv_elfvalue_t value, void *uvalue)
2334f680cc6SAli Bahrami {
2344f680cc6SAli Bahrami 	size_t *cnt = (size_t *)uvalue;
235d29b2c44Sab 
2364f680cc6SAli Bahrami 	(*cnt)++;
2374f680cc6SAli Bahrami 	return (CONV_ITER_CONT);
2384f680cc6SAli Bahrami }
239d29b2c44Sab 
240d29b2c44Sab /*
2414f680cc6SAli Bahrami  * Used to fill in the descriptors with strings from libconv.
242d29b2c44Sab  */
2434f680cc6SAli Bahrami typedef struct {
2444f680cc6SAli Bahrami 	size_t			cur;	/* Index of next descriptor */
2454f680cc6SAli Bahrami 	size_t			cnt;	/* # of descriptors */
2464f680cc6SAli Bahrami 	elfedit_atoui_sym_t	*desc;	/* descriptors */
2474f680cc6SAli Bahrami } libconv_fill_state_t;
248d29b2c44Sab 
2494f680cc6SAli Bahrami static conv_iter_ret_t
libconv_fill_cb(const char * str,Conv_elfvalue_t value,void * uvalue)2504f680cc6SAli Bahrami libconv_fill_cb(const char *str, Conv_elfvalue_t value, void *uvalue)
2514f680cc6SAli Bahrami {
2524f680cc6SAli Bahrami 	libconv_fill_state_t	*fill_state = (libconv_fill_state_t *)uvalue;
2534f680cc6SAli Bahrami 	elfedit_atoui_sym_t	*sym = &fill_state->desc[fill_state->cur++];
254d29b2c44Sab 
2554f680cc6SAli Bahrami 	sym->sym_name = str;
2564f680cc6SAli Bahrami 	sym->sym_value = value;
2574f680cc6SAli Bahrami 	return (CONV_ITER_CONT);
2584f680cc6SAli Bahrami }
259d29b2c44Sab 
260d29b2c44Sab 
261d29b2c44Sab /*
2624f680cc6SAli Bahrami  * Call the iteration function using the correct calling sequence for
2634f680cc6SAli Bahrami  * the libconv routine.
264d29b2c44Sab  */
2654f680cc6SAli Bahrami static void
libconv_fill_iter(sym_table_ent_t * sym,conv_iter_osabi_t osabi,Half mach,conv_iter_cb_t func,void * uvalue)2664f680cc6SAli Bahrami libconv_fill_iter(sym_table_ent_t *sym, conv_iter_osabi_t osabi, Half mach,
2674f680cc6SAli Bahrami     conv_iter_cb_t func, void *uvalue)
2684f680cc6SAli Bahrami {
2694f680cc6SAli Bahrami 	switch (sym->ste_type) {
2704f680cc6SAli Bahrami 	case STE_LC:
2714f680cc6SAli Bahrami 		(void) (* sym->ste_conv_func.simple)(
2724f680cc6SAli Bahrami 		    CONV_FMT_ALT_CF, func, uvalue);
2734f680cc6SAli Bahrami 		(void) (* sym->ste_conv_func.simple)(
2744f680cc6SAli Bahrami 		    CONV_FMT_ALT_NF, func, uvalue);
2754f680cc6SAli Bahrami 		break;
276d29b2c44Sab 
2774f680cc6SAli Bahrami 	case STE_LC_OS:
2784f680cc6SAli Bahrami 		(void) (* sym->ste_conv_func.osabi)(osabi,
2794f680cc6SAli Bahrami 		    CONV_FMT_ALT_CF, func, uvalue);
2804f680cc6SAli Bahrami 		(void) (* sym->ste_conv_func.osabi)(osabi,
2814f680cc6SAli Bahrami 		    CONV_FMT_ALT_NF, func, uvalue);
2824f680cc6SAli Bahrami 		break;
28399f63845Sab 
2844f680cc6SAli Bahrami 	case STE_LC_MACH:
2854f680cc6SAli Bahrami 		(void) (* sym->ste_conv_func.mach)(mach,
2864f680cc6SAli Bahrami 		    CONV_FMT_ALT_CF, func, uvalue);
2874f680cc6SAli Bahrami 		(void) (* sym->ste_conv_func.mach)(mach,
2884f680cc6SAli Bahrami 		    CONV_FMT_ALT_NF, func, uvalue);
2894f680cc6SAli Bahrami 		break;
290d29b2c44Sab 
2914f680cc6SAli Bahrami 	case STE_LC_OS_MACH:
2924f680cc6SAli Bahrami 		(void) (* sym->ste_conv_func.osabi_mach)(osabi, mach,
2934f680cc6SAli Bahrami 		    CONV_FMT_ALT_CF, func, uvalue);
2944f680cc6SAli Bahrami 		(void) (* sym->ste_conv_func.osabi_mach)(osabi, mach,
2954f680cc6SAli Bahrami 		    CONV_FMT_ALT_NF, func, uvalue);
2964f680cc6SAli Bahrami 		break;
2974f680cc6SAli Bahrami 	}
2984f680cc6SAli Bahrami }
299d29b2c44Sab 
300d29b2c44Sab /*
3014f680cc6SAli Bahrami  * Allocate/Fill an atoui array for the specified constant.
302d29b2c44Sab  */
3034f680cc6SAli Bahrami static void
libconv_fill(sym_table_ent_t * sym,conv_iter_osabi_t osabi,Half mach)3044f680cc6SAli Bahrami libconv_fill(sym_table_ent_t *sym, conv_iter_osabi_t osabi, Half mach)
3054f680cc6SAli Bahrami {
3064f680cc6SAli Bahrami 	libconv_fill_state_t	fill_state;
3074f680cc6SAli Bahrami 
3084f680cc6SAli Bahrami 	/* How many descriptors will we need? */
3094f680cc6SAli Bahrami 	fill_state.cnt = 1;		/* Extra for NULL termination */
3104f680cc6SAli Bahrami 	libconv_fill_iter(sym, osabi, mach, libconv_count_cb, &fill_state.cnt);
3114f680cc6SAli Bahrami 
3124f680cc6SAli Bahrami 	/*
3134f680cc6SAli Bahrami 	 * If there is an existing allocation, and it is not large enough,
3144f680cc6SAli Bahrami 	 * release it.
3154f680cc6SAli Bahrami 	 */
3164f680cc6SAli Bahrami 	if ((sym->ste_alloc != NULL) && (fill_state.cnt > sym->ste_nelts)) {
3174f680cc6SAli Bahrami 		free(sym->ste_alloc);
3184f680cc6SAli Bahrami 		sym->ste_alloc = NULL;
3194f680cc6SAli Bahrami 		sym->ste_nelts = 0;
3204f680cc6SAli Bahrami 	}
321d29b2c44Sab 
3224f680cc6SAli Bahrami 	/* Allocate memory if don't already have an allocation */
3234f680cc6SAli Bahrami 	if (sym->ste_alloc == NULL) {
3244f680cc6SAli Bahrami 		sym->ste_alloc = elfedit_malloc(MSG_INTL(MSG_ALLOC_ELFCONDESC),
3254f680cc6SAli Bahrami 		    fill_state.cnt * sizeof (*fill_state.desc));
3264f680cc6SAli Bahrami 		sym->ste_nelts = fill_state.cnt;
3274f680cc6SAli Bahrami 	}
328d29b2c44Sab 
3294f680cc6SAli Bahrami 	/* Fill the array */
3304f680cc6SAli Bahrami 	fill_state.desc = sym->ste_alloc;
3314f680cc6SAli Bahrami 	fill_state.cur = 0;
3324f680cc6SAli Bahrami 	libconv_fill_iter(sym, osabi, mach, libconv_fill_cb, &fill_state);
333d29b2c44Sab 
3344f680cc6SAli Bahrami 	/* Add null termination */
3354f680cc6SAli Bahrami 	fill_state.desc[fill_state.cur].sym_name = NULL;
3364f680cc6SAli Bahrami 	fill_state.desc[fill_state.cur].sym_value = 0;
337d29b2c44Sab 
3384f680cc6SAli Bahrami 	/* atoui array for this item is now available */
3394f680cc6SAli Bahrami 	sym->ste_arr = fill_state.desc;
3404f680cc6SAli Bahrami }
341d29b2c44Sab 
342d29b2c44Sab /*
3434f680cc6SAli Bahrami  * Should be called on first call to elfedit_const_to_atoui(). Does the
3444f680cc6SAli Bahrami  * runtime initialization of sym_table.
345d29b2c44Sab  */
3464f680cc6SAli Bahrami static void
init_libconv_strings(conv_iter_osabi_t * osabi,Half * mach)3474f680cc6SAli Bahrami init_libconv_strings(conv_iter_osabi_t *osabi, Half *mach)
3484f680cc6SAli Bahrami {
3494f680cc6SAli Bahrami 	/*
3504f680cc6SAli Bahrami 	 * It is critical that the ste_type and ste_conv_func values
3514f680cc6SAli Bahrami 	 * agree. Since the libconv iteration function signatures can
3524f680cc6SAli Bahrami 	 * change (gain or lose an osabi or mach argument), we want to
3534f680cc6SAli Bahrami 	 * ensure that the compiler will catch such changes.
3544f680cc6SAli Bahrami 	 *
3554f680cc6SAli Bahrami 	 * The compiler will catch an attempt to assign a function of
3564f680cc6SAli Bahrami 	 * the wrong type to ste_conv_func. Using these macros, we ensure
3574f680cc6SAli Bahrami 	 * that the ste_type and function assignment happen as a unit.
3584f680cc6SAli Bahrami 	 */
3594f680cc6SAli Bahrami #define	LC(_ndx, _func) sym_table[_ndx].ste_type = STE_LC; \
3604f680cc6SAli Bahrami 	sym_table[_ndx].ste_conv_func.simple = _func;
3614f680cc6SAli Bahrami #define	LC_OS(_ndx, _func) sym_table[_ndx].ste_type = STE_LC_OS; \
3624f680cc6SAli Bahrami 	sym_table[_ndx].ste_conv_func.osabi = _func;
3634f680cc6SAli Bahrami #define	LC_MACH(_ndx, _func) sym_table[_ndx].ste_type = STE_LC_MACH; \
3644f680cc6SAli Bahrami 	sym_table[_ndx].ste_conv_func.mach = _func;
3654f680cc6SAli Bahrami #define	LC_OS_MACH(_ndx, _func) sym_table[_ndx].ste_type = STE_LC_OS_MACH; \
3664f680cc6SAli Bahrami 	sym_table[_ndx].ste_conv_func.osabi_mach = _func;
3674f680cc6SAli Bahrami 
3684f680cc6SAli Bahrami 
3694f680cc6SAli Bahrami 	if (!state.file.present) {
3704f680cc6SAli Bahrami 		/*
3714f680cc6SAli Bahrami 		 * No input file: Supply the maximal set of strings for
3724f680cc6SAli Bahrami 		 * all osabi and mach values understood by libconv.
3734f680cc6SAli Bahrami 		 */
3744f680cc6SAli Bahrami 		*osabi = CONV_OSABI_ALL;
3754f680cc6SAli Bahrami 		*mach = CONV_MACH_ALL;
3764f680cc6SAli Bahrami 	} else if (state.elf.elfclass == ELFCLASS32) {
3774f680cc6SAli Bahrami 		*osabi = state.elf.obj_state.s32->os_ehdr->e_ident[EI_OSABI];
3784f680cc6SAli Bahrami 		*mach = state.elf.obj_state.s32->os_ehdr->e_machine;
3794f680cc6SAli Bahrami 	} else {
3804f680cc6SAli Bahrami 		*osabi = state.elf.obj_state.s64->os_ehdr->e_ident[EI_OSABI];
3814f680cc6SAli Bahrami 		*mach = state.elf.obj_state.s64->os_ehdr->e_machine;
3824f680cc6SAli Bahrami 	}
383d29b2c44Sab 
3844f680cc6SAli Bahrami 	/* Set up non- STE_STATIC libconv fill functions */
3854f680cc6SAli Bahrami 	LC_OS_MACH(ELFEDIT_CONST_SHN,		conv_iter_sym_shndx);
3864f680cc6SAli Bahrami 	LC_OS_MACH(ELFEDIT_CONST_SHT,		conv_iter_sec_type);
3874f680cc6SAli Bahrami 	LC_OS(ELFEDIT_CONST_SHT_ALLSYMTAB,	conv_iter_sec_symtab);
3884f680cc6SAli Bahrami 	LC_OS_MACH(ELFEDIT_CONST_DT,		conv_iter_dyn_tag);
3894f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_DF,			conv_iter_dyn_flag);
3904f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_DF_P1,			conv_iter_dyn_posflag1);
3914f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_DF_1,			conv_iter_dyn_flag1);
3924f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_DTF_1,			conv_iter_dyn_feature1);
3934f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_EI,			conv_iter_ehdr_eident);
3944f680cc6SAli Bahrami 	LC_OS(ELFEDIT_CONST_ET,			conv_iter_ehdr_type);
3954f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_ELFCLASS,		conv_iter_ehdr_class);
3964f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_ELFDATA,		conv_iter_ehdr_data);
3974f680cc6SAli Bahrami 	LC_MACH(ELFEDIT_CONST_EF,		conv_iter_ehdr_flags);
3984f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_EV,			conv_iter_ehdr_vers);
3994f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_EM,			conv_iter_ehdr_mach);
4004f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_ELFOSABI,		conv_iter_ehdr_osabi);
4014f680cc6SAli Bahrami 	LC_OS(ELFEDIT_CONST_EAV,		conv_iter_ehdr_abivers);
4024f680cc6SAli Bahrami 	LC_OS(ELFEDIT_CONST_PT,			conv_iter_phdr_type);
4034f680cc6SAli Bahrami 	LC_OS(ELFEDIT_CONST_PF,			conv_iter_phdr_flags);
4044f680cc6SAli Bahrami 	LC_OS_MACH(ELFEDIT_CONST_SHF,		conv_iter_sec_flags);
4054f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_STB,			conv_iter_sym_info_bind);
4064f680cc6SAli Bahrami 	LC_MACH(ELFEDIT_CONST_STT,		conv_iter_sym_info_type);
4074f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_STV,			conv_iter_sym_other_vis);
4084f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_SYMINFO_BT,		conv_iter_syminfo_boundto);
4094f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_SYMINFO_FLG,		conv_iter_syminfo_flags);
4104f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_CA,			conv_iter_cap_tags);
411*08278a5eSRod Evans 	LC_MACH(ELFEDIT_CONST_HW1_SUNW,		conv_iter_cap_val_hw1);
4124f680cc6SAli Bahrami 	LC(ELFEDIT_CONST_SF1_SUNW,		conv_iter_cap_val_sf1);
413*08278a5eSRod Evans 	LC_MACH(ELFEDIT_CONST_HW2_SUNW,		conv_iter_cap_val_hw2);
4144f680cc6SAli Bahrami 
4154f680cc6SAli Bahrami #undef LC
4164f680cc6SAli Bahrami #undef LC_OS
4174f680cc6SAli Bahrami #undef LC_MACH
4184f680cc6SAli Bahrami #undef LC_OS_MACH
4194f680cc6SAli Bahrami }
420d29b2c44Sab 
42199f63845Sab /*
4224f680cc6SAli Bahrami  * If the user has changed the osabi or machine type of the object,
4234f680cc6SAli Bahrami  * then we need to discard the strings we've loaded from libconv
4244f680cc6SAli Bahrami  * that are dependent on these values.
42599f63845Sab  */
42699f63845Sab static void
invalidate_libconv_strings(conv_iter_osabi_t * osabi,Half * mach)4274f680cc6SAli Bahrami invalidate_libconv_strings(conv_iter_osabi_t *osabi, Half *mach)
42899f63845Sab {
4294f680cc6SAli Bahrami 	uchar_t		cur_osabi;
4304f680cc6SAli Bahrami 	Half		cur_mach;
4314f680cc6SAli Bahrami 	sym_table_ent_t	*sym;
4324f680cc6SAli Bahrami 	int		osabi_change, mach_change;
4334f680cc6SAli Bahrami 	int		i;
4344f680cc6SAli Bahrami 
4354f680cc6SAli Bahrami 
4364f680cc6SAli Bahrami 	/* Reset the ELF header change notification */
4374f680cc6SAli Bahrami 	state.elf.elfconst_ehdr_change = 0;
4384f680cc6SAli Bahrami 
4394f680cc6SAli Bahrami 	if (state.elf.elfclass == ELFCLASS32) {
4404f680cc6SAli Bahrami 		cur_osabi = state.elf.obj_state.s32->os_ehdr->e_ident[EI_OSABI];
4414f680cc6SAli Bahrami 		cur_mach = state.elf.obj_state.s32->os_ehdr->e_machine;
4424f680cc6SAli Bahrami 	} else {
4434f680cc6SAli Bahrami 		cur_osabi = state.elf.obj_state.s64->os_ehdr->e_ident[EI_OSABI];
4444f680cc6SAli Bahrami 		cur_mach = state.elf.obj_state.s64->os_ehdr->e_machine;
4454f680cc6SAli Bahrami 	}
44699f63845Sab 
4474f680cc6SAli Bahrami 	/* What has changed? */
4484f680cc6SAli Bahrami 	mach_change = *mach != cur_mach;
4494f680cc6SAli Bahrami 	osabi_change = *osabi != cur_osabi;
4504f680cc6SAli Bahrami 	if (!(mach_change || osabi_change))
4514f680cc6SAli Bahrami 		return;
4524f680cc6SAli Bahrami 
4534f680cc6SAli Bahrami 	/*
4544f680cc6SAli Bahrami 	 * Set the ste_arr pointer to NULL for any items that
4554f680cc6SAli Bahrami 	 * depend on the things that have changed. Note that we
4564f680cc6SAli Bahrami 	 * do not release the allocated memory --- it may turn
4574f680cc6SAli Bahrami 	 * out to be large enough to hold the new strings, so we
4584f680cc6SAli Bahrami 	 * keep the allocation and leave that decision to the fill
4594f680cc6SAli Bahrami 	 * routine, which will run the next time those strings are
4604f680cc6SAli Bahrami 	 * needed.
4614f680cc6SAli Bahrami 	 */
4624f680cc6SAli Bahrami 	for (i = 0, sym = sym_table;
4634f680cc6SAli Bahrami 	    i < (sizeof (sym_table) / sizeof (sym_table[0])); i++, sym++) {
4644f680cc6SAli Bahrami 		if (sym->ste_arr == NULL)
46599f63845Sab 			continue;
46699f63845Sab 
4674f680cc6SAli Bahrami 		switch (sym->ste_type) {
4684f680cc6SAli Bahrami 		case STE_LC_OS:
4694f680cc6SAli Bahrami 			if (osabi_change)
4704f680cc6SAli Bahrami 				sym->ste_arr = NULL;
4714f680cc6SAli Bahrami 			break;
4724f680cc6SAli Bahrami 
4734f680cc6SAli Bahrami 		case STE_LC_MACH:
4744f680cc6SAli Bahrami 			if (mach_change)
4754f680cc6SAli Bahrami 				sym->ste_arr = NULL;
4764f680cc6SAli Bahrami 			break;
4774f680cc6SAli Bahrami 
4784f680cc6SAli Bahrami 		case STE_LC_OS_MACH:
4794f680cc6SAli Bahrami 			if (osabi_change || mach_change)
4804f680cc6SAli Bahrami 				sym->ste_arr = NULL;
4814f680cc6SAli Bahrami 			break;
4824f680cc6SAli Bahrami 		}
48399f63845Sab 	}
48499f63845Sab 
4854f680cc6SAli Bahrami 	*mach = cur_mach;
4864f680cc6SAli Bahrami 	*osabi = cur_osabi;
48799f63845Sab }
48899f63845Sab 
48999f63845Sab 
49099f63845Sab 
491d29b2c44Sab /*
492d29b2c44Sab  * Given an elfedit_const_t value, return the array of elfedit_atoui_sym_t
493d29b2c44Sab  * entries that it represents.
494d29b2c44Sab  */
495d29b2c44Sab elfedit_atoui_sym_t *
elfedit_const_to_atoui(elfedit_const_t const_type)496d29b2c44Sab elfedit_const_to_atoui(elfedit_const_t const_type)
497d29b2c44Sab {
4984f680cc6SAli Bahrami 	static int			first = 1;
4994f680cc6SAli Bahrami 	static conv_iter_osabi_t	osabi;
5004f680cc6SAli Bahrami 	static Half			mach;
501d29b2c44Sab 
5024f680cc6SAli Bahrami 	sym_table_ent_t	*sym;
50399f63845Sab 
5044f680cc6SAli Bahrami 	if (first) {
5054f680cc6SAli Bahrami 		init_libconv_strings(&osabi, &mach);
5064f680cc6SAli Bahrami 		first = 0;
5074f680cc6SAli Bahrami 	}
508d29b2c44Sab 
5094f680cc6SAli Bahrami 	if ((const_type < 0) ||
5104f680cc6SAli Bahrami 	    (const_type >= (sizeof (sym_table) / sizeof (sym_table[0]))))
5114f680cc6SAli Bahrami 		elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADCONST));
5124f680cc6SAli Bahrami 	sym = &sym_table[const_type];
513d29b2c44Sab 
5144f680cc6SAli Bahrami 	/*
5154f680cc6SAli Bahrami 	 * If the constant is not STE_STATIC, then we may need to fetch
5164f680cc6SAli Bahrami 	 * the strings from libconv.
5174f680cc6SAli Bahrami 	 */
5184f680cc6SAli Bahrami 	if (sym->ste_type != STE_STATIC) {
5194f680cc6SAli Bahrami 		/*
5204f680cc6SAli Bahrami 		 * If the ELF header has changed since the last
5214f680cc6SAli Bahrami 		 * time we were called, then we need to invalidate any
5224f680cc6SAli Bahrami 		 * strings previously pulled from libconv that have
5234f680cc6SAli Bahrami 		 * an osabi or machine dependency.
5244f680cc6SAli Bahrami 		 */
5254f680cc6SAli Bahrami 		if (state.elf.elfconst_ehdr_change)
5264f680cc6SAli Bahrami 			invalidate_libconv_strings(&osabi, &mach);
527d29b2c44Sab 
5284f680cc6SAli Bahrami 		/* If we don't already have the strings, get them */
5294f680cc6SAli Bahrami 		if (sym->ste_arr == NULL)
5304f680cc6SAli Bahrami 			libconv_fill(sym, osabi, mach);
531d29b2c44Sab 	}
532d29b2c44Sab 
5334f680cc6SAli Bahrami 	return (sym->ste_arr);
534d29b2c44Sab }
535