xref: /onnv-gate/usr/src/cmd/sgs/elfedit/common/elfconst.c (revision 9273:9a0603d78ad3)
15088Sab196087 /*
25088Sab196087  * CDDL HEADER START
35088Sab196087  *
45088Sab196087  * The contents of this file are subject to the terms of the
55088Sab196087  * Common Development and Distribution License (the "License").
65088Sab196087  * You may not use this file except in compliance with the License.
75088Sab196087  *
85088Sab196087  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95088Sab196087  * or http://www.opensolaris.org/os/licensing.
105088Sab196087  * See the License for the specific language governing permissions
115088Sab196087  * and limitations under the License.
125088Sab196087  *
135088Sab196087  * When distributing Covered Code, include this CDDL HEADER in each
145088Sab196087  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155088Sab196087  * If applicable, add the following below this CDDL HEADER, with the
165088Sab196087  * fields enclosed by brackets "[]" replaced with your own identifying
175088Sab196087  * information: Portions Copyright [yyyy] [name of copyright owner]
185088Sab196087  *
195088Sab196087  * CDDL HEADER END
205088Sab196087  */
215088Sab196087 
225088Sab196087 /*
239085SAli.Bahrami@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
245088Sab196087  * Use is subject to license terms.
255088Sab196087  */
265088Sab196087 
275088Sab196087 #include	<stdlib.h>
285088Sab196087 #include	<stdio.h>
295088Sab196087 #include	<_elfedit.h>
30*9273SAli.Bahrami@Sun.COM #include	<conv.h>
315088Sab196087 #include	<msg.h>
325088Sab196087 
335088Sab196087 
345088Sab196087 
355088Sab196087 /*
365088Sab196087  * This file contains support for mapping well known ELF constants
375088Sab196087  * to their numeric values. It is a layer on top of the elfedit_atoui()
385088Sab196087  * routines defined in util.c. The idea is that centralizing all the
395088Sab196087  * support for such constants will improve consistency between modules,
405088Sab196087  * allow for sharing of commonly needed items, and make the modules
415088Sab196087  * simpler.
425088Sab196087  */
435088Sab196087 
445088Sab196087 
455088Sab196087 
465088Sab196087 
475088Sab196087 /*
485088Sab196087  * elfedit output style, with and without leading -o
495088Sab196087  */
505088Sab196087 static elfedit_atoui_sym_t sym_outstyle[] = {
515088Sab196087 	{ MSG_ORIG(MSG_STR_DEFAULT),		ELFEDIT_OUTSTYLE_DEFAULT },
525088Sab196087 	{ MSG_ORIG(MSG_STR_SIMPLE),		ELFEDIT_OUTSTYLE_SIMPLE },
535088Sab196087 	{ MSG_ORIG(MSG_STR_NUM),		ELFEDIT_OUTSTYLE_NUM },
545088Sab196087 	{ NULL }
555088Sab196087 };
565088Sab196087 static elfedit_atoui_sym_t sym_minus_o_outstyle[] = {
575088Sab196087 	{ MSG_ORIG(MSG_STR_MINUS_O_DEFAULT),	ELFEDIT_OUTSTYLE_DEFAULT },
585088Sab196087 	{ MSG_ORIG(MSG_STR_MINUS_O_SIMPLE),	ELFEDIT_OUTSTYLE_SIMPLE },
595088Sab196087 	{ MSG_ORIG(MSG_STR_MINUS_O_NUM),	ELFEDIT_OUTSTYLE_NUM },
605088Sab196087 	{ NULL }
615088Sab196087 };
625088Sab196087 
635088Sab196087 
645088Sab196087 /*
655088Sab196087  * Booleans
665088Sab196087  */
675088Sab196087 static elfedit_atoui_sym_t sym_bool[] = {
685088Sab196087 	{ MSG_ORIG(MSG_STR_T),			1 },
695088Sab196087 	{ MSG_ORIG(MSG_STR_F),			0 },
705088Sab196087 	{ MSG_ORIG(MSG_STR_TRUE),		1 },
715088Sab196087 	{ MSG_ORIG(MSG_STR_FALSE),		0 },
725088Sab196087 	{ MSG_ORIG(MSG_STR_ON),			1 },
735088Sab196087 	{ MSG_ORIG(MSG_STR_OFF),		0 },
745088Sab196087 	{ MSG_ORIG(MSG_STR_YES),		1 },
755088Sab196087 	{ MSG_ORIG(MSG_STR_NO),			0 },
765088Sab196087 	{ MSG_ORIG(MSG_STR_Y),			1 },
775088Sab196087 	{ MSG_ORIG(MSG_STR_N),			0 },
785088Sab196087 	{ NULL }
795088Sab196087 };
805088Sab196087 
815088Sab196087 /*
82*9273SAli.Bahrami@Sun.COM  * ELF strings for SHT_STRTAB
835088Sab196087  */
845088Sab196087 static elfedit_atoui_sym_t sym_sht_strtab[] = {
855088Sab196087 	{ MSG_ORIG(MSG_SHT_STRTAB),		SHT_STRTAB },
865088Sab196087 	{ MSG_ORIG(MSG_SHT_STRTAB_ALT1),	SHT_STRTAB },
875088Sab196087 
885088Sab196087 	{ NULL }
895088Sab196087 };
905088Sab196087 
915088Sab196087 
925088Sab196087 /*
93*9273SAli.Bahrami@Sun.COM  * Strings for SHT_SYMTAB
945088Sab196087  */
955088Sab196087 static elfedit_atoui_sym_t sym_sht_symtab[] = {
965088Sab196087 	{ MSG_ORIG(MSG_SHT_SYMTAB),		SHT_SYMTAB },
975088Sab196087 	{ MSG_ORIG(MSG_SHT_SYMTAB_ALT1),	SHT_SYMTAB },
985088Sab196087 
995088Sab196087 	{ NULL }
1005088Sab196087 };
1015088Sab196087 
1025088Sab196087 /*
103*9273SAli.Bahrami@Sun.COM  * Strings for SHT_DYNSYM
1045088Sab196087  */
1055088Sab196087 static elfedit_atoui_sym_t sym_sht_dynsym[] = {
1065088Sab196087 	{ MSG_ORIG(MSG_SHT_DYNSYM),		SHT_DYNSYM },
1075088Sab196087 	{ MSG_ORIG(MSG_SHT_DYNSYM_ALT1),	SHT_DYNSYM },
1085088Sab196087 
1095088Sab196087 	{ NULL }
1105088Sab196087 };
1115088Sab196087 
1125088Sab196087 /*
113*9273SAli.Bahrami@Sun.COM  * Strings for SHT_SUNW_LDYNSYM
1145088Sab196087  */
1155088Sab196087 static elfedit_atoui_sym_t sym_sht_ldynsym[] = {
1165088Sab196087 	{ MSG_ORIG(MSG_SHT_SUNW_LDYNSYM),	SHT_SUNW_LDYNSYM },
1175088Sab196087 	{ MSG_ORIG(MSG_SHT_SUNW_LDYNSYM_ALT1),	SHT_SUNW_LDYNSYM },
1185088Sab196087 
1195088Sab196087 	{ NULL }
1205088Sab196087 };
1215088Sab196087 
1225088Sab196087 
1235088Sab196087 
1245088Sab196087 /*
125*9273SAli.Bahrami@Sun.COM  * Types of items found in sym_table[]. All items other than STE_STATIC
126*9273SAli.Bahrami@Sun.COM  * pulls strings from libconv, differing in the interface required by
127*9273SAli.Bahrami@Sun.COM  * the libconv iteration function used.
1285088Sab196087  */
129*9273SAli.Bahrami@Sun.COM typedef enum {
130*9273SAli.Bahrami@Sun.COM 	STE_STATIC =		0,	/* Constants are statically defined */
131*9273SAli.Bahrami@Sun.COM 	STE_LC =		1,	/* Libconv, pull once */
132*9273SAli.Bahrami@Sun.COM 	STE_LC_OS =		2,	/* From libconv, osabi dependency */
133*9273SAli.Bahrami@Sun.COM 	STE_LC_MACH =		3,	/* From libconv, mach dependency */
134*9273SAli.Bahrami@Sun.COM 	STE_LC_OS_MACH =	4	/* From libconv, osabi/mach dep. */
135*9273SAli.Bahrami@Sun.COM } ste_type_t;
1365088Sab196087 
1375088Sab196087 /*
138*9273SAli.Bahrami@Sun.COM  * Interface of functions called to fill strings from libconv
1395088Sab196087  */
140*9273SAli.Bahrami@Sun.COM typedef conv_iter_ret_t	(* libconv_iter_func_simple_t)(
141*9273SAli.Bahrami@Sun.COM 			    Conv_fmt_flags_t, conv_iter_cb_t, void *);
142*9273SAli.Bahrami@Sun.COM typedef conv_iter_ret_t	(* libconv_iter_func_os_t)(conv_iter_osabi_t,
143*9273SAli.Bahrami@Sun.COM 			    Conv_fmt_flags_t, conv_iter_cb_t, void *);
144*9273SAli.Bahrami@Sun.COM typedef conv_iter_ret_t	(* libconv_iter_func_mach_t)(Half,
145*9273SAli.Bahrami@Sun.COM 			    Conv_fmt_flags_t, conv_iter_cb_t, void *);
146*9273SAli.Bahrami@Sun.COM typedef conv_iter_ret_t	(* libconv_iter_func_os_mach_t)(conv_iter_osabi_t, Half,
147*9273SAli.Bahrami@Sun.COM 			    Conv_fmt_flags_t, conv_iter_cb_t, void *);
148*9273SAli.Bahrami@Sun.COM typedef union {
149*9273SAli.Bahrami@Sun.COM 	libconv_iter_func_simple_t	simple;
150*9273SAli.Bahrami@Sun.COM 	libconv_iter_func_os_t		osabi;
151*9273SAli.Bahrami@Sun.COM 	libconv_iter_func_mach_t	mach;
152*9273SAli.Bahrami@Sun.COM 	libconv_iter_func_os_mach_t	osabi_mach;
153*9273SAli.Bahrami@Sun.COM } libconv_iter_func_t;
1545088Sab196087 
155*9273SAli.Bahrami@Sun.COM /*
156*9273SAli.Bahrami@Sun.COM  * State for each type of constant
157*9273SAli.Bahrami@Sun.COM  */
158*9273SAli.Bahrami@Sun.COM typedef struct {
159*9273SAli.Bahrami@Sun.COM 	ste_type_t		ste_type;	/* Type of entry */
160*9273SAli.Bahrami@Sun.COM 	elfedit_atoui_sym_t	*ste_arr;	/* NULL, or atoui array */
161*9273SAli.Bahrami@Sun.COM 	void			*ste_alloc;	/* Current memory allocation */
162*9273SAli.Bahrami@Sun.COM 	size_t			ste_nelts;	/* # items in ste_alloc */
163*9273SAli.Bahrami@Sun.COM 	libconv_iter_func_t	ste_conv_func;	/* libconv fill function */
164*9273SAli.Bahrami@Sun.COM } sym_table_ent_t;
1655088Sab196087 
1665088Sab196087 
1675088Sab196087 /*
168*9273SAli.Bahrami@Sun.COM  * Array of state for each constant type, including the array of atoui
169*9273SAli.Bahrami@Sun.COM  * pointers, for each constant type, indexed by elfedit_const_t value.
170*9273SAli.Bahrami@Sun.COM  * The number and order of entries in this table must agree with the
171*9273SAli.Bahrami@Sun.COM  * definition of elfedit_const_t in elfedit.h.
172*9273SAli.Bahrami@Sun.COM  *
173*9273SAli.Bahrami@Sun.COM  * note:
174*9273SAli.Bahrami@Sun.COM  * -	STE_STATIC items must supply a statically allocated buffer here.
175*9273SAli.Bahrami@Sun.COM  * -	The non-STE_STATIC items use libconv strings. These items are
176*9273SAli.Bahrami@Sun.COM  *	initialized by init_libconv_strings() at runtime, and are represented
177*9273SAli.Bahrami@Sun.COM  *	by a simple { 0 } here. The memory used for these arrays is dynamic,
178*9273SAli.Bahrami@Sun.COM  *	and can be released and rebuilt at runtime as necessary to keep up
179*9273SAli.Bahrami@Sun.COM  *	with changes in osabi or machine type.
1805088Sab196087  */
181*9273SAli.Bahrami@Sun.COM static sym_table_ent_t sym_table[ELFEDIT_CONST_NUM] = {
182*9273SAli.Bahrami@Sun.COM 						/* #: ELFEDIT_CONST_xxx */
183*9273SAli.Bahrami@Sun.COM 	{ STE_STATIC, sym_outstyle },		/* 0: OUTSTYLE */
184*9273SAli.Bahrami@Sun.COM 	{ STE_STATIC, sym_minus_o_outstyle },	/* 1: OUTSTYLE_MO */
185*9273SAli.Bahrami@Sun.COM 	{ STE_STATIC, sym_bool },		/* 2: BOOL */
186*9273SAli.Bahrami@Sun.COM 	{ STE_STATIC, sym_sht_strtab },		/* 3: SHT_STRTAB */
187*9273SAli.Bahrami@Sun.COM 	{ STE_STATIC, sym_sht_symtab },		/* 4: SHT_SYMTAB */
188*9273SAli.Bahrami@Sun.COM 	{ STE_STATIC, sym_sht_dynsym },		/* 5: SHT_DYNSYM */
189*9273SAli.Bahrami@Sun.COM 	{ STE_STATIC, sym_sht_ldynsym },	/* 6: SHT_LDYNSYM */
190*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 7: SHN */
191*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 8: SHT */
192*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 9: SHT_ALLSYMTAB */
193*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 10: DT */
194*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 11: DF */
195*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 12: DF_P1 */
196*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 13: DF_1 */
197*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 14: DTF_1 */
198*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 15: EI */
199*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 16: ET */
200*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 17: ELFCLASS */
201*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 18: ELFDATA */
202*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 19: EF */
203*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 20: EV */
204*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 21: EM */
205*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 22: ELFOSABI */
206*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 23: EAV osabi version */
207*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 24: PT */
208*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 25: PF */
209*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 26: SHF */
210*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 27: STB */
211*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 28: STT */
212*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 29: STV */
213*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 30: SYMINFO_BT */
214*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 31: SYMINFO_FLG */
215*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 32: CA */
216*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 33: AV */
217*9273SAli.Bahrami@Sun.COM 	{ 0 },					/* 34: SF1_SUNW */
2185088Sab196087 };
219*9273SAli.Bahrami@Sun.COM #if ELFEDIT_CONST_NUM != (ELFEDIT_CONST_SF1_SUNW)
220*9273SAli.Bahrami@Sun.COM error "ELFEDIT_CONST_NUM has grown. Update sym_table[]"
2215088Sab196087 #endif
2225088Sab196087 
2235088Sab196087 
2245088Sab196087 
2255088Sab196087 
2265088Sab196087 /*
227*9273SAli.Bahrami@Sun.COM  * Used to count the number of descriptors that will be needed to hold
228*9273SAli.Bahrami@Sun.COM  * strings from libconv.
229*9273SAli.Bahrami@Sun.COM  */
230*9273SAli.Bahrami@Sun.COM /*ARGSUSED*/
231*9273SAli.Bahrami@Sun.COM static conv_iter_ret_t
232*9273SAli.Bahrami@Sun.COM libconv_count_cb(const char *str, Conv_elfvalue_t value, void *uvalue)
233*9273SAli.Bahrami@Sun.COM {
234*9273SAli.Bahrami@Sun.COM 	size_t *cnt = (size_t *)uvalue;
235*9273SAli.Bahrami@Sun.COM 
236*9273SAli.Bahrami@Sun.COM 	(*cnt)++;
237*9273SAli.Bahrami@Sun.COM 	return (CONV_ITER_CONT);
238*9273SAli.Bahrami@Sun.COM }
239*9273SAli.Bahrami@Sun.COM 
240*9273SAli.Bahrami@Sun.COM /*
241*9273SAli.Bahrami@Sun.COM  * Used to fill in the descriptors with strings from libconv.
2425088Sab196087  */
243*9273SAli.Bahrami@Sun.COM typedef struct {
244*9273SAli.Bahrami@Sun.COM 	size_t			cur;	/* Index of next descriptor */
245*9273SAli.Bahrami@Sun.COM 	size_t			cnt;	/* # of descriptors */
246*9273SAli.Bahrami@Sun.COM 	elfedit_atoui_sym_t	*desc;	/* descriptors */
247*9273SAli.Bahrami@Sun.COM } libconv_fill_state_t;
2485088Sab196087 
249*9273SAli.Bahrami@Sun.COM static conv_iter_ret_t
250*9273SAli.Bahrami@Sun.COM libconv_fill_cb(const char *str, Conv_elfvalue_t value, void *uvalue)
251*9273SAli.Bahrami@Sun.COM {
252*9273SAli.Bahrami@Sun.COM 	libconv_fill_state_t	*fill_state = (libconv_fill_state_t *)uvalue;
253*9273SAli.Bahrami@Sun.COM 	elfedit_atoui_sym_t	*sym = &fill_state->desc[fill_state->cur++];
2545088Sab196087 
255*9273SAli.Bahrami@Sun.COM 	sym->sym_name = str;
256*9273SAli.Bahrami@Sun.COM 	sym->sym_value = value;
257*9273SAli.Bahrami@Sun.COM 	return (CONV_ITER_CONT);
258*9273SAli.Bahrami@Sun.COM }
2595088Sab196087 
2605088Sab196087 
2615088Sab196087 /*
262*9273SAli.Bahrami@Sun.COM  * Call the iteration function using the correct calling sequence for
263*9273SAli.Bahrami@Sun.COM  * the libconv routine.
264*9273SAli.Bahrami@Sun.COM  */
265*9273SAli.Bahrami@Sun.COM static void
266*9273SAli.Bahrami@Sun.COM libconv_fill_iter(sym_table_ent_t *sym, conv_iter_osabi_t osabi, Half mach,
267*9273SAli.Bahrami@Sun.COM     conv_iter_cb_t func, void *uvalue)
268*9273SAli.Bahrami@Sun.COM {
269*9273SAli.Bahrami@Sun.COM 	switch (sym->ste_type) {
270*9273SAli.Bahrami@Sun.COM 	case STE_LC:
271*9273SAli.Bahrami@Sun.COM 		(void) (* sym->ste_conv_func.simple)(
272*9273SAli.Bahrami@Sun.COM 		    CONV_FMT_ALT_CF, func, uvalue);
273*9273SAli.Bahrami@Sun.COM 		(void) (* sym->ste_conv_func.simple)(
274*9273SAli.Bahrami@Sun.COM 		    CONV_FMT_ALT_NF, func, uvalue);
275*9273SAli.Bahrami@Sun.COM 		break;
276*9273SAli.Bahrami@Sun.COM 
277*9273SAli.Bahrami@Sun.COM 	case STE_LC_OS:
278*9273SAli.Bahrami@Sun.COM 		(void) (* sym->ste_conv_func.osabi)(osabi,
279*9273SAli.Bahrami@Sun.COM 		    CONV_FMT_ALT_CF, func, uvalue);
280*9273SAli.Bahrami@Sun.COM 		(void) (* sym->ste_conv_func.osabi)(osabi,
281*9273SAli.Bahrami@Sun.COM 		    CONV_FMT_ALT_NF, func, uvalue);
282*9273SAli.Bahrami@Sun.COM 		break;
283*9273SAli.Bahrami@Sun.COM 
284*9273SAli.Bahrami@Sun.COM 	case STE_LC_MACH:
285*9273SAli.Bahrami@Sun.COM 		(void) (* sym->ste_conv_func.mach)(mach,
286*9273SAli.Bahrami@Sun.COM 		    CONV_FMT_ALT_CF, func, uvalue);
287*9273SAli.Bahrami@Sun.COM 		(void) (* sym->ste_conv_func.mach)(mach,
288*9273SAli.Bahrami@Sun.COM 		    CONV_FMT_ALT_NF, func, uvalue);
289*9273SAli.Bahrami@Sun.COM 		break;
290*9273SAli.Bahrami@Sun.COM 
291*9273SAli.Bahrami@Sun.COM 	case STE_LC_OS_MACH:
292*9273SAli.Bahrami@Sun.COM 		(void) (* sym->ste_conv_func.osabi_mach)(osabi, mach,
293*9273SAli.Bahrami@Sun.COM 		    CONV_FMT_ALT_CF, func, uvalue);
294*9273SAli.Bahrami@Sun.COM 		(void) (* sym->ste_conv_func.osabi_mach)(osabi, mach,
295*9273SAli.Bahrami@Sun.COM 		    CONV_FMT_ALT_NF, func, uvalue);
296*9273SAli.Bahrami@Sun.COM 		break;
297*9273SAli.Bahrami@Sun.COM 	}
298*9273SAli.Bahrami@Sun.COM }
299*9273SAli.Bahrami@Sun.COM 
300*9273SAli.Bahrami@Sun.COM /*
301*9273SAli.Bahrami@Sun.COM  * Allocate/Fill an atoui array for the specified constant.
302*9273SAli.Bahrami@Sun.COM  */
303*9273SAli.Bahrami@Sun.COM static void
304*9273SAli.Bahrami@Sun.COM libconv_fill(sym_table_ent_t *sym, conv_iter_osabi_t osabi, Half mach)
305*9273SAli.Bahrami@Sun.COM {
306*9273SAli.Bahrami@Sun.COM 	libconv_fill_state_t	fill_state;
307*9273SAli.Bahrami@Sun.COM 
308*9273SAli.Bahrami@Sun.COM 	/* How many descriptors will we need? */
309*9273SAli.Bahrami@Sun.COM 	fill_state.cnt = 1;		/* Extra for NULL termination */
310*9273SAli.Bahrami@Sun.COM 	libconv_fill_iter(sym, osabi, mach, libconv_count_cb, &fill_state.cnt);
311*9273SAli.Bahrami@Sun.COM 
312*9273SAli.Bahrami@Sun.COM 	/*
313*9273SAli.Bahrami@Sun.COM 	 * If there is an existing allocation, and it is not large enough,
314*9273SAli.Bahrami@Sun.COM 	 * release it.
315*9273SAli.Bahrami@Sun.COM 	 */
316*9273SAli.Bahrami@Sun.COM 	if ((sym->ste_alloc != NULL) && (fill_state.cnt > sym->ste_nelts)) {
317*9273SAli.Bahrami@Sun.COM 		free(sym->ste_alloc);
318*9273SAli.Bahrami@Sun.COM 		sym->ste_alloc = NULL;
319*9273SAli.Bahrami@Sun.COM 		sym->ste_nelts = 0;
320*9273SAli.Bahrami@Sun.COM 	}
321*9273SAli.Bahrami@Sun.COM 
322*9273SAli.Bahrami@Sun.COM 	/* Allocate memory if don't already have an allocation */
323*9273SAli.Bahrami@Sun.COM 	if (sym->ste_alloc == NULL) {
324*9273SAli.Bahrami@Sun.COM 		sym->ste_alloc = elfedit_malloc(MSG_INTL(MSG_ALLOC_ELFCONDESC),
325*9273SAli.Bahrami@Sun.COM 		    fill_state.cnt * sizeof (*fill_state.desc));
326*9273SAli.Bahrami@Sun.COM 		sym->ste_nelts = fill_state.cnt;
327*9273SAli.Bahrami@Sun.COM 	}
328*9273SAli.Bahrami@Sun.COM 
329*9273SAli.Bahrami@Sun.COM 	/* Fill the array */
330*9273SAli.Bahrami@Sun.COM 	fill_state.desc = sym->ste_alloc;
331*9273SAli.Bahrami@Sun.COM 	fill_state.cur = 0;
332*9273SAli.Bahrami@Sun.COM 	libconv_fill_iter(sym, osabi, mach, libconv_fill_cb, &fill_state);
333*9273SAli.Bahrami@Sun.COM 
334*9273SAli.Bahrami@Sun.COM 	/* Add null termination */
335*9273SAli.Bahrami@Sun.COM 	fill_state.desc[fill_state.cur].sym_name = NULL;
336*9273SAli.Bahrami@Sun.COM 	fill_state.desc[fill_state.cur].sym_value = 0;
337*9273SAli.Bahrami@Sun.COM 
338*9273SAli.Bahrami@Sun.COM 	/* atoui array for this item is now available */
339*9273SAli.Bahrami@Sun.COM 	sym->ste_arr = fill_state.desc;
340*9273SAli.Bahrami@Sun.COM }
341*9273SAli.Bahrami@Sun.COM 
342*9273SAli.Bahrami@Sun.COM /*
343*9273SAli.Bahrami@Sun.COM  * Should be called on first call to elfedit_const_to_atoui(). Does the
344*9273SAli.Bahrami@Sun.COM  * runtime initialization of sym_table.
3455565Sab196087  */
3465565Sab196087 static void
347*9273SAli.Bahrami@Sun.COM init_libconv_strings(conv_iter_osabi_t *osabi, Half *mach)
3485565Sab196087 {
349*9273SAli.Bahrami@Sun.COM 	/*
350*9273SAli.Bahrami@Sun.COM 	 * It is critical that the ste_type and ste_conv_func values
351*9273SAli.Bahrami@Sun.COM 	 * agree. Since the libconv iteration function signatures can
352*9273SAli.Bahrami@Sun.COM 	 * change (gain or lose an osabi or mach argument), we want to
353*9273SAli.Bahrami@Sun.COM 	 * ensure that the compiler will catch such changes.
354*9273SAli.Bahrami@Sun.COM 	 *
355*9273SAli.Bahrami@Sun.COM 	 * The compiler will catch an attempt to assign a function of
356*9273SAli.Bahrami@Sun.COM 	 * the wrong type to ste_conv_func. Using these macros, we ensure
357*9273SAli.Bahrami@Sun.COM 	 * that the ste_type and function assignment happen as a unit.
358*9273SAli.Bahrami@Sun.COM 	 */
359*9273SAli.Bahrami@Sun.COM #define	LC(_ndx, _func) sym_table[_ndx].ste_type = STE_LC; \
360*9273SAli.Bahrami@Sun.COM 	sym_table[_ndx].ste_conv_func.simple = _func;
361*9273SAli.Bahrami@Sun.COM #define	LC_OS(_ndx, _func) sym_table[_ndx].ste_type = STE_LC_OS; \
362*9273SAli.Bahrami@Sun.COM 	sym_table[_ndx].ste_conv_func.osabi = _func;
363*9273SAli.Bahrami@Sun.COM #define	LC_MACH(_ndx, _func) sym_table[_ndx].ste_type = STE_LC_MACH; \
364*9273SAli.Bahrami@Sun.COM 	sym_table[_ndx].ste_conv_func.mach = _func;
365*9273SAli.Bahrami@Sun.COM #define	LC_OS_MACH(_ndx, _func) sym_table[_ndx].ste_type = STE_LC_OS_MACH; \
366*9273SAli.Bahrami@Sun.COM 	sym_table[_ndx].ste_conv_func.osabi_mach = _func;
367*9273SAli.Bahrami@Sun.COM 
368*9273SAli.Bahrami@Sun.COM 
369*9273SAli.Bahrami@Sun.COM 	if (!state.file.present) {
370*9273SAli.Bahrami@Sun.COM 		/*
371*9273SAli.Bahrami@Sun.COM 		 * No input file: Supply the maximal set of strings for
372*9273SAli.Bahrami@Sun.COM 		 * all osabi and mach values understood by libconv.
373*9273SAli.Bahrami@Sun.COM 		 */
374*9273SAli.Bahrami@Sun.COM 		*osabi = CONV_OSABI_ALL;
375*9273SAli.Bahrami@Sun.COM 		*mach = CONV_MACH_ALL;
376*9273SAli.Bahrami@Sun.COM 	} else if (state.elf.elfclass == ELFCLASS32) {
377*9273SAli.Bahrami@Sun.COM 		*osabi = state.elf.obj_state.s32->os_ehdr->e_ident[EI_OSABI];
378*9273SAli.Bahrami@Sun.COM 		*mach = state.elf.obj_state.s32->os_ehdr->e_machine;
379*9273SAli.Bahrami@Sun.COM 	} else {
380*9273SAli.Bahrami@Sun.COM 		*osabi = state.elf.obj_state.s64->os_ehdr->e_ident[EI_OSABI];
381*9273SAli.Bahrami@Sun.COM 		*mach = state.elf.obj_state.s64->os_ehdr->e_machine;
382*9273SAli.Bahrami@Sun.COM 	}
3835565Sab196087 
384*9273SAli.Bahrami@Sun.COM 	/* Set up non- STE_STATIC libconv fill functions */
385*9273SAli.Bahrami@Sun.COM 	LC_OS_MACH(ELFEDIT_CONST_SHN,		conv_iter_sym_shndx);
386*9273SAli.Bahrami@Sun.COM 	LC_OS_MACH(ELFEDIT_CONST_SHT,		conv_iter_sec_type);
387*9273SAli.Bahrami@Sun.COM 	LC_OS(ELFEDIT_CONST_SHT_ALLSYMTAB,	conv_iter_sec_symtab);
388*9273SAli.Bahrami@Sun.COM 	LC_OS_MACH(ELFEDIT_CONST_DT,		conv_iter_dyn_tag);
389*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_DF,			conv_iter_dyn_flag);
390*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_DF_P1,			conv_iter_dyn_posflag1);
391*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_DF_1,			conv_iter_dyn_flag1);
392*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_DTF_1,			conv_iter_dyn_feature1);
393*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_EI,			conv_iter_ehdr_eident);
394*9273SAli.Bahrami@Sun.COM 	LC_OS(ELFEDIT_CONST_ET,			conv_iter_ehdr_type);
395*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_ELFCLASS,		conv_iter_ehdr_class);
396*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_ELFDATA,		conv_iter_ehdr_data);
397*9273SAli.Bahrami@Sun.COM 	LC_MACH(ELFEDIT_CONST_EF,		conv_iter_ehdr_flags);
398*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_EV,			conv_iter_ehdr_vers);
399*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_EM,			conv_iter_ehdr_mach);
400*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_ELFOSABI,		conv_iter_ehdr_osabi);
401*9273SAli.Bahrami@Sun.COM 	LC_OS(ELFEDIT_CONST_EAV,		conv_iter_ehdr_abivers);
402*9273SAli.Bahrami@Sun.COM 	LC_OS(ELFEDIT_CONST_PT,			conv_iter_phdr_type);
403*9273SAli.Bahrami@Sun.COM 	LC_OS(ELFEDIT_CONST_PF,			conv_iter_phdr_flags);
404*9273SAli.Bahrami@Sun.COM 	LC_OS_MACH(ELFEDIT_CONST_SHF,		conv_iter_sec_flags);
405*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_STB,			conv_iter_sym_info_bind);
406*9273SAli.Bahrami@Sun.COM 	LC_MACH(ELFEDIT_CONST_STT,		conv_iter_sym_info_type);
407*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_STV,			conv_iter_sym_other_vis);
408*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_SYMINFO_BT,		conv_iter_syminfo_boundto);
409*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_SYMINFO_FLG,		conv_iter_syminfo_flags);
410*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_CA,			conv_iter_cap_tags);
411*9273SAli.Bahrami@Sun.COM 	LC_MACH(ELFEDIT_CONST_AV,		conv_iter_cap_val_hw1);
412*9273SAli.Bahrami@Sun.COM 	LC(ELFEDIT_CONST_SF1_SUNW,		conv_iter_cap_val_sf1);
413*9273SAli.Bahrami@Sun.COM 
414*9273SAli.Bahrami@Sun.COM #undef LC
415*9273SAli.Bahrami@Sun.COM #undef LC_OS
416*9273SAli.Bahrami@Sun.COM #undef LC_MACH
417*9273SAli.Bahrami@Sun.COM #undef LC_OS_MACH
418*9273SAli.Bahrami@Sun.COM }
419*9273SAli.Bahrami@Sun.COM 
420*9273SAli.Bahrami@Sun.COM /*
421*9273SAli.Bahrami@Sun.COM  * If the user has changed the osabi or machine type of the object,
422*9273SAli.Bahrami@Sun.COM  * then we need to discard the strings we've loaded from libconv
423*9273SAli.Bahrami@Sun.COM  * that are dependent on these values.
424*9273SAli.Bahrami@Sun.COM  */
425*9273SAli.Bahrami@Sun.COM static void
426*9273SAli.Bahrami@Sun.COM invalidate_libconv_strings(conv_iter_osabi_t *osabi, Half *mach)
427*9273SAli.Bahrami@Sun.COM {
428*9273SAli.Bahrami@Sun.COM 	uchar_t		cur_osabi;
429*9273SAli.Bahrami@Sun.COM 	Half		cur_mach;
430*9273SAli.Bahrami@Sun.COM 	sym_table_ent_t	*sym;
431*9273SAli.Bahrami@Sun.COM 	int		osabi_change, mach_change;
432*9273SAli.Bahrami@Sun.COM 	int		i;
433*9273SAli.Bahrami@Sun.COM 
434*9273SAli.Bahrami@Sun.COM 
435*9273SAli.Bahrami@Sun.COM 	/* Reset the ELF header change notification */
436*9273SAli.Bahrami@Sun.COM 	state.elf.elfconst_ehdr_change = 0;
437*9273SAli.Bahrami@Sun.COM 
438*9273SAli.Bahrami@Sun.COM 	if (state.elf.elfclass == ELFCLASS32) {
439*9273SAli.Bahrami@Sun.COM 		cur_osabi = state.elf.obj_state.s32->os_ehdr->e_ident[EI_OSABI];
440*9273SAli.Bahrami@Sun.COM 		cur_mach = state.elf.obj_state.s32->os_ehdr->e_machine;
441*9273SAli.Bahrami@Sun.COM 	} else {
442*9273SAli.Bahrami@Sun.COM 		cur_osabi = state.elf.obj_state.s64->os_ehdr->e_ident[EI_OSABI];
443*9273SAli.Bahrami@Sun.COM 		cur_mach = state.elf.obj_state.s64->os_ehdr->e_machine;
444*9273SAli.Bahrami@Sun.COM 	}
445*9273SAli.Bahrami@Sun.COM 
446*9273SAli.Bahrami@Sun.COM 	/* What has changed? */
447*9273SAli.Bahrami@Sun.COM 	mach_change = *mach != cur_mach;
448*9273SAli.Bahrami@Sun.COM 	osabi_change = *osabi != cur_osabi;
449*9273SAli.Bahrami@Sun.COM 	if (!(mach_change || osabi_change))
450*9273SAli.Bahrami@Sun.COM 		return;
451*9273SAli.Bahrami@Sun.COM 
452*9273SAli.Bahrami@Sun.COM 	/*
453*9273SAli.Bahrami@Sun.COM 	 * Set the ste_arr pointer to NULL for any items that
454*9273SAli.Bahrami@Sun.COM 	 * depend on the things that have changed. Note that we
455*9273SAli.Bahrami@Sun.COM 	 * do not release the allocated memory --- it may turn
456*9273SAli.Bahrami@Sun.COM 	 * out to be large enough to hold the new strings, so we
457*9273SAli.Bahrami@Sun.COM 	 * keep the allocation and leave that decision to the fill
458*9273SAli.Bahrami@Sun.COM 	 * routine, which will run the next time those strings are
459*9273SAli.Bahrami@Sun.COM 	 * needed.
460*9273SAli.Bahrami@Sun.COM 	 */
461*9273SAli.Bahrami@Sun.COM 	for (i = 0, sym = sym_table;
462*9273SAli.Bahrami@Sun.COM 	    i < (sizeof (sym_table) / sizeof (sym_table[0])); i++, sym++) {
463*9273SAli.Bahrami@Sun.COM 		if (sym->ste_arr == NULL)
4645565Sab196087 			continue;
4655565Sab196087 
466*9273SAli.Bahrami@Sun.COM 		switch (sym->ste_type) {
467*9273SAli.Bahrami@Sun.COM 		case STE_LC_OS:
468*9273SAli.Bahrami@Sun.COM 			if (osabi_change)
469*9273SAli.Bahrami@Sun.COM 				sym->ste_arr = NULL;
470*9273SAli.Bahrami@Sun.COM 			break;
4715565Sab196087 
472*9273SAli.Bahrami@Sun.COM 		case STE_LC_MACH:
473*9273SAli.Bahrami@Sun.COM 			if (mach_change)
474*9273SAli.Bahrami@Sun.COM 				sym->ste_arr = NULL;
475*9273SAli.Bahrami@Sun.COM 			break;
476*9273SAli.Bahrami@Sun.COM 
477*9273SAli.Bahrami@Sun.COM 		case STE_LC_OS_MACH:
478*9273SAli.Bahrami@Sun.COM 			if (osabi_change || mach_change)
479*9273SAli.Bahrami@Sun.COM 				sym->ste_arr = NULL;
480*9273SAli.Bahrami@Sun.COM 			break;
481*9273SAli.Bahrami@Sun.COM 		}
4825565Sab196087 	}
4835565Sab196087 
484*9273SAli.Bahrami@Sun.COM 	*mach = cur_mach;
485*9273SAli.Bahrami@Sun.COM 	*osabi = cur_osabi;
4865565Sab196087 }
4875565Sab196087 
4885565Sab196087 
4895565Sab196087 
4905565Sab196087 /*
4915088Sab196087  * Given an elfedit_const_t value, return the array of elfedit_atoui_sym_t
4925088Sab196087  * entries that it represents.
4935088Sab196087  */
4945088Sab196087 elfedit_atoui_sym_t *
4955088Sab196087 elfedit_const_to_atoui(elfedit_const_t const_type)
4965088Sab196087 {
497*9273SAli.Bahrami@Sun.COM 	static int			first = 1;
498*9273SAli.Bahrami@Sun.COM 	static conv_iter_osabi_t	osabi;
499*9273SAli.Bahrami@Sun.COM 	static Half			mach;
500*9273SAli.Bahrami@Sun.COM 
501*9273SAli.Bahrami@Sun.COM 	sym_table_ent_t	*sym;
502*9273SAli.Bahrami@Sun.COM 
503*9273SAli.Bahrami@Sun.COM 	if (first) {
504*9273SAli.Bahrami@Sun.COM 		init_libconv_strings(&osabi, &mach);
505*9273SAli.Bahrami@Sun.COM 		first = 0;
506*9273SAli.Bahrami@Sun.COM 	}
507*9273SAli.Bahrami@Sun.COM 
5085088Sab196087 	if ((const_type < 0) ||
5095088Sab196087 	    (const_type >= (sizeof (sym_table) / sizeof (sym_table[0]))))
5105088Sab196087 		elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADCONST));
511*9273SAli.Bahrami@Sun.COM 	sym = &sym_table[const_type];
5125088Sab196087 
513*9273SAli.Bahrami@Sun.COM 	/*
514*9273SAli.Bahrami@Sun.COM 	 * If the constant is not STE_STATIC, then we may need to fetch
515*9273SAli.Bahrami@Sun.COM 	 * the strings from libconv.
516*9273SAli.Bahrami@Sun.COM 	 */
517*9273SAli.Bahrami@Sun.COM 	if (sym->ste_type != STE_STATIC) {
518*9273SAli.Bahrami@Sun.COM 		/*
519*9273SAli.Bahrami@Sun.COM 		 * If the ELF header has changed since the last
520*9273SAli.Bahrami@Sun.COM 		 * time we were called, then we need to invalidate any
521*9273SAli.Bahrami@Sun.COM 		 * strings previously pulled from libconv that have
522*9273SAli.Bahrami@Sun.COM 		 * an osabi or machine dependency.
523*9273SAli.Bahrami@Sun.COM 		 */
524*9273SAli.Bahrami@Sun.COM 		if (state.elf.elfconst_ehdr_change)
525*9273SAli.Bahrami@Sun.COM 			invalidate_libconv_strings(&osabi, &mach);
526*9273SAli.Bahrami@Sun.COM 
527*9273SAli.Bahrami@Sun.COM 		/* If we don't already have the strings, get them */
528*9273SAli.Bahrami@Sun.COM 		if (sym->ste_arr == NULL)
529*9273SAli.Bahrami@Sun.COM 			libconv_fill(sym, osabi, mach);
5305565Sab196087 	}
5315565Sab196087 
532*9273SAli.Bahrami@Sun.COM 	return (sym->ste_arr);
5335088Sab196087 }
534