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 /*
23*11827SRod.Evans@Sun.COM * Copyright 2010 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>
309273SAli.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 /*
829273SAli.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 /*
939273SAli.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 /*
1039273SAli.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 /*
1139273SAli.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 /*
1259273SAli.Bahrami@Sun.COM * Types of items found in sym_table[]. All items other than STE_STATIC
1269273SAli.Bahrami@Sun.COM * pulls strings from libconv, differing in the interface required by
1279273SAli.Bahrami@Sun.COM * the libconv iteration function used.
1285088Sab196087 */
1299273SAli.Bahrami@Sun.COM typedef enum {
1309273SAli.Bahrami@Sun.COM STE_STATIC = 0, /* Constants are statically defined */
1319273SAli.Bahrami@Sun.COM STE_LC = 1, /* Libconv, pull once */
1329273SAli.Bahrami@Sun.COM STE_LC_OS = 2, /* From libconv, osabi dependency */
1339273SAli.Bahrami@Sun.COM STE_LC_MACH = 3, /* From libconv, mach dependency */
1349273SAli.Bahrami@Sun.COM STE_LC_OS_MACH = 4 /* From libconv, osabi/mach dep. */
1359273SAli.Bahrami@Sun.COM } ste_type_t;
1365088Sab196087
1375088Sab196087 /*
1389273SAli.Bahrami@Sun.COM * Interface of functions called to fill strings from libconv
1395088Sab196087 */
1409273SAli.Bahrami@Sun.COM typedef conv_iter_ret_t (* libconv_iter_func_simple_t)(
1419273SAli.Bahrami@Sun.COM Conv_fmt_flags_t, conv_iter_cb_t, void *);
1429273SAli.Bahrami@Sun.COM typedef conv_iter_ret_t (* libconv_iter_func_os_t)(conv_iter_osabi_t,
1439273SAli.Bahrami@Sun.COM Conv_fmt_flags_t, conv_iter_cb_t, void *);
1449273SAli.Bahrami@Sun.COM typedef conv_iter_ret_t (* libconv_iter_func_mach_t)(Half,
1459273SAli.Bahrami@Sun.COM Conv_fmt_flags_t, conv_iter_cb_t, void *);
1469273SAli.Bahrami@Sun.COM typedef conv_iter_ret_t (* libconv_iter_func_os_mach_t)(conv_iter_osabi_t, Half,
1479273SAli.Bahrami@Sun.COM Conv_fmt_flags_t, conv_iter_cb_t, void *);
1489273SAli.Bahrami@Sun.COM typedef union {
1499273SAli.Bahrami@Sun.COM libconv_iter_func_simple_t simple;
1509273SAli.Bahrami@Sun.COM libconv_iter_func_os_t osabi;
1519273SAli.Bahrami@Sun.COM libconv_iter_func_mach_t mach;
1529273SAli.Bahrami@Sun.COM libconv_iter_func_os_mach_t osabi_mach;
1539273SAli.Bahrami@Sun.COM } libconv_iter_func_t;
1545088Sab196087
1559273SAli.Bahrami@Sun.COM /*
1569273SAli.Bahrami@Sun.COM * State for each type of constant
1579273SAli.Bahrami@Sun.COM */
1589273SAli.Bahrami@Sun.COM typedef struct {
1599273SAli.Bahrami@Sun.COM ste_type_t ste_type; /* Type of entry */
1609273SAli.Bahrami@Sun.COM elfedit_atoui_sym_t *ste_arr; /* NULL, or atoui array */
1619273SAli.Bahrami@Sun.COM void *ste_alloc; /* Current memory allocation */
1629273SAli.Bahrami@Sun.COM size_t ste_nelts; /* # items in ste_alloc */
1639273SAli.Bahrami@Sun.COM libconv_iter_func_t ste_conv_func; /* libconv fill function */
1649273SAli.Bahrami@Sun.COM } sym_table_ent_t;
1655088Sab196087
1665088Sab196087
1675088Sab196087 /*
1689273SAli.Bahrami@Sun.COM * Array of state for each constant type, including the array of atoui
1699273SAli.Bahrami@Sun.COM * pointers, for each constant type, indexed by elfedit_const_t value.
1709273SAli.Bahrami@Sun.COM * The number and order of entries in this table must agree with the
1719273SAli.Bahrami@Sun.COM * definition of elfedit_const_t in elfedit.h.
1729273SAli.Bahrami@Sun.COM *
1739273SAli.Bahrami@Sun.COM * note:
1749273SAli.Bahrami@Sun.COM * - STE_STATIC items must supply a statically allocated buffer here.
1759273SAli.Bahrami@Sun.COM * - The non-STE_STATIC items use libconv strings. These items are
1769273SAli.Bahrami@Sun.COM * initialized by init_libconv_strings() at runtime, and are represented
1779273SAli.Bahrami@Sun.COM * by a simple { 0 } here. The memory used for these arrays is dynamic,
1789273SAli.Bahrami@Sun.COM * and can be released and rebuilt at runtime as necessary to keep up
1799273SAli.Bahrami@Sun.COM * with changes in osabi or machine type.
1805088Sab196087 */
1819273SAli.Bahrami@Sun.COM static sym_table_ent_t sym_table[ELFEDIT_CONST_NUM] = {
1829273SAli.Bahrami@Sun.COM /* #: ELFEDIT_CONST_xxx */
1839273SAli.Bahrami@Sun.COM { STE_STATIC, sym_outstyle }, /* 0: OUTSTYLE */
1849273SAli.Bahrami@Sun.COM { STE_STATIC, sym_minus_o_outstyle }, /* 1: OUTSTYLE_MO */
1859273SAli.Bahrami@Sun.COM { STE_STATIC, sym_bool }, /* 2: BOOL */
1869273SAli.Bahrami@Sun.COM { STE_STATIC, sym_sht_strtab }, /* 3: SHT_STRTAB */
1879273SAli.Bahrami@Sun.COM { STE_STATIC, sym_sht_symtab }, /* 4: SHT_SYMTAB */
1889273SAli.Bahrami@Sun.COM { STE_STATIC, sym_sht_dynsym }, /* 5: SHT_DYNSYM */
1899273SAli.Bahrami@Sun.COM { STE_STATIC, sym_sht_ldynsym }, /* 6: SHT_LDYNSYM */
1909273SAli.Bahrami@Sun.COM { 0 }, /* 7: SHN */
1919273SAli.Bahrami@Sun.COM { 0 }, /* 8: SHT */
1929273SAli.Bahrami@Sun.COM { 0 }, /* 9: SHT_ALLSYMTAB */
1939273SAli.Bahrami@Sun.COM { 0 }, /* 10: DT */
1949273SAli.Bahrami@Sun.COM { 0 }, /* 11: DF */
1959273SAli.Bahrami@Sun.COM { 0 }, /* 12: DF_P1 */
1969273SAli.Bahrami@Sun.COM { 0 }, /* 13: DF_1 */
1979273SAli.Bahrami@Sun.COM { 0 }, /* 14: DTF_1 */
1989273SAli.Bahrami@Sun.COM { 0 }, /* 15: EI */
1999273SAli.Bahrami@Sun.COM { 0 }, /* 16: ET */
2009273SAli.Bahrami@Sun.COM { 0 }, /* 17: ELFCLASS */
2019273SAli.Bahrami@Sun.COM { 0 }, /* 18: ELFDATA */
2029273SAli.Bahrami@Sun.COM { 0 }, /* 19: EF */
2039273SAli.Bahrami@Sun.COM { 0 }, /* 20: EV */
2049273SAli.Bahrami@Sun.COM { 0 }, /* 21: EM */
2059273SAli.Bahrami@Sun.COM { 0 }, /* 22: ELFOSABI */
2069273SAli.Bahrami@Sun.COM { 0 }, /* 23: EAV osabi version */
2079273SAli.Bahrami@Sun.COM { 0 }, /* 24: PT */
2089273SAli.Bahrami@Sun.COM { 0 }, /* 25: PF */
2099273SAli.Bahrami@Sun.COM { 0 }, /* 26: SHF */
2109273SAli.Bahrami@Sun.COM { 0 }, /* 27: STB */
2119273SAli.Bahrami@Sun.COM { 0 }, /* 28: STT */
2129273SAli.Bahrami@Sun.COM { 0 }, /* 29: STV */
2139273SAli.Bahrami@Sun.COM { 0 }, /* 30: SYMINFO_BT */
2149273SAli.Bahrami@Sun.COM { 0 }, /* 31: SYMINFO_FLG */
2159273SAli.Bahrami@Sun.COM { 0 }, /* 32: CA */
2169273SAli.Bahrami@Sun.COM { 0 }, /* 33: AV */
2179273SAli.Bahrami@Sun.COM { 0 }, /* 34: SF1_SUNW */
2185088Sab196087 };
2199273SAli.Bahrami@Sun.COM #if ELFEDIT_CONST_NUM != (ELFEDIT_CONST_SF1_SUNW)
2209273SAli.Bahrami@Sun.COM error "ELFEDIT_CONST_NUM has grown. Update sym_table[]"
2215088Sab196087 #endif
2225088Sab196087
2235088Sab196087
2245088Sab196087
2255088Sab196087
2265088Sab196087 /*
2279273SAli.Bahrami@Sun.COM * Used to count the number of descriptors that will be needed to hold
2289273SAli.Bahrami@Sun.COM * strings from libconv.
2299273SAli.Bahrami@Sun.COM */
2309273SAli.Bahrami@Sun.COM /*ARGSUSED*/
2319273SAli.Bahrami@Sun.COM static conv_iter_ret_t
2329273SAli.Bahrami@Sun.COM libconv_count_cb(const char *str, Conv_elfvalue_t value, void *uvalue)
2339273SAli.Bahrami@Sun.COM {
2349273SAli.Bahrami@Sun.COM size_t *cnt = (size_t *)uvalue;
2359273SAli.Bahrami@Sun.COM
2369273SAli.Bahrami@Sun.COM (*cnt)++;
2379273SAli.Bahrami@Sun.COM return (CONV_ITER_CONT);
2389273SAli.Bahrami@Sun.COM }
2399273SAli.Bahrami@Sun.COM
2409273SAli.Bahrami@Sun.COM /*
2419273SAli.Bahrami@Sun.COM * Used to fill in the descriptors with strings from libconv.
2425088Sab196087 */
2439273SAli.Bahrami@Sun.COM typedef struct {
2449273SAli.Bahrami@Sun.COM size_t cur; /* Index of next descriptor */
2459273SAli.Bahrami@Sun.COM size_t cnt; /* # of descriptors */
2469273SAli.Bahrami@Sun.COM elfedit_atoui_sym_t *desc; /* descriptors */
2479273SAli.Bahrami@Sun.COM } libconv_fill_state_t;
2485088Sab196087
2499273SAli.Bahrami@Sun.COM static conv_iter_ret_t
libconv_fill_cb(const char * str,Conv_elfvalue_t value,void * uvalue)2509273SAli.Bahrami@Sun.COM libconv_fill_cb(const char *str, Conv_elfvalue_t value, void *uvalue)
2519273SAli.Bahrami@Sun.COM {
2529273SAli.Bahrami@Sun.COM libconv_fill_state_t *fill_state = (libconv_fill_state_t *)uvalue;
2539273SAli.Bahrami@Sun.COM elfedit_atoui_sym_t *sym = &fill_state->desc[fill_state->cur++];
2545088Sab196087
2559273SAli.Bahrami@Sun.COM sym->sym_name = str;
2569273SAli.Bahrami@Sun.COM sym->sym_value = value;
2579273SAli.Bahrami@Sun.COM return (CONV_ITER_CONT);
2589273SAli.Bahrami@Sun.COM }
2595088Sab196087
2605088Sab196087
2615088Sab196087 /*
2629273SAli.Bahrami@Sun.COM * Call the iteration function using the correct calling sequence for
2639273SAli.Bahrami@Sun.COM * the libconv routine.
2649273SAli.Bahrami@Sun.COM */
2659273SAli.Bahrami@Sun.COM static void
libconv_fill_iter(sym_table_ent_t * sym,conv_iter_osabi_t osabi,Half mach,conv_iter_cb_t func,void * uvalue)2669273SAli.Bahrami@Sun.COM libconv_fill_iter(sym_table_ent_t *sym, conv_iter_osabi_t osabi, Half mach,
2679273SAli.Bahrami@Sun.COM conv_iter_cb_t func, void *uvalue)
2689273SAli.Bahrami@Sun.COM {
2699273SAli.Bahrami@Sun.COM switch (sym->ste_type) {
2709273SAli.Bahrami@Sun.COM case STE_LC:
2719273SAli.Bahrami@Sun.COM (void) (* sym->ste_conv_func.simple)(
2729273SAli.Bahrami@Sun.COM CONV_FMT_ALT_CF, func, uvalue);
2739273SAli.Bahrami@Sun.COM (void) (* sym->ste_conv_func.simple)(
2749273SAli.Bahrami@Sun.COM CONV_FMT_ALT_NF, func, uvalue);
2759273SAli.Bahrami@Sun.COM break;
2769273SAli.Bahrami@Sun.COM
2779273SAli.Bahrami@Sun.COM case STE_LC_OS:
2789273SAli.Bahrami@Sun.COM (void) (* sym->ste_conv_func.osabi)(osabi,
2799273SAli.Bahrami@Sun.COM CONV_FMT_ALT_CF, func, uvalue);
2809273SAli.Bahrami@Sun.COM (void) (* sym->ste_conv_func.osabi)(osabi,
2819273SAli.Bahrami@Sun.COM CONV_FMT_ALT_NF, func, uvalue);
2829273SAli.Bahrami@Sun.COM break;
2839273SAli.Bahrami@Sun.COM
2849273SAli.Bahrami@Sun.COM case STE_LC_MACH:
2859273SAli.Bahrami@Sun.COM (void) (* sym->ste_conv_func.mach)(mach,
2869273SAli.Bahrami@Sun.COM CONV_FMT_ALT_CF, func, uvalue);
2879273SAli.Bahrami@Sun.COM (void) (* sym->ste_conv_func.mach)(mach,
2889273SAli.Bahrami@Sun.COM CONV_FMT_ALT_NF, func, uvalue);
2899273SAli.Bahrami@Sun.COM break;
2909273SAli.Bahrami@Sun.COM
2919273SAli.Bahrami@Sun.COM case STE_LC_OS_MACH:
2929273SAli.Bahrami@Sun.COM (void) (* sym->ste_conv_func.osabi_mach)(osabi, mach,
2939273SAli.Bahrami@Sun.COM CONV_FMT_ALT_CF, func, uvalue);
2949273SAli.Bahrami@Sun.COM (void) (* sym->ste_conv_func.osabi_mach)(osabi, mach,
2959273SAli.Bahrami@Sun.COM CONV_FMT_ALT_NF, func, uvalue);
2969273SAli.Bahrami@Sun.COM break;
2979273SAli.Bahrami@Sun.COM }
2989273SAli.Bahrami@Sun.COM }
2999273SAli.Bahrami@Sun.COM
3009273SAli.Bahrami@Sun.COM /*
3019273SAli.Bahrami@Sun.COM * Allocate/Fill an atoui array for the specified constant.
3029273SAli.Bahrami@Sun.COM */
3039273SAli.Bahrami@Sun.COM static void
libconv_fill(sym_table_ent_t * sym,conv_iter_osabi_t osabi,Half mach)3049273SAli.Bahrami@Sun.COM libconv_fill(sym_table_ent_t *sym, conv_iter_osabi_t osabi, Half mach)
3059273SAli.Bahrami@Sun.COM {
3069273SAli.Bahrami@Sun.COM libconv_fill_state_t fill_state;
3079273SAli.Bahrami@Sun.COM
3089273SAli.Bahrami@Sun.COM /* How many descriptors will we need? */
3099273SAli.Bahrami@Sun.COM fill_state.cnt = 1; /* Extra for NULL termination */
3109273SAli.Bahrami@Sun.COM libconv_fill_iter(sym, osabi, mach, libconv_count_cb, &fill_state.cnt);
3119273SAli.Bahrami@Sun.COM
3129273SAli.Bahrami@Sun.COM /*
3139273SAli.Bahrami@Sun.COM * If there is an existing allocation, and it is not large enough,
3149273SAli.Bahrami@Sun.COM * release it.
3159273SAli.Bahrami@Sun.COM */
3169273SAli.Bahrami@Sun.COM if ((sym->ste_alloc != NULL) && (fill_state.cnt > sym->ste_nelts)) {
3179273SAli.Bahrami@Sun.COM free(sym->ste_alloc);
3189273SAli.Bahrami@Sun.COM sym->ste_alloc = NULL;
3199273SAli.Bahrami@Sun.COM sym->ste_nelts = 0;
3209273SAli.Bahrami@Sun.COM }
3219273SAli.Bahrami@Sun.COM
3229273SAli.Bahrami@Sun.COM /* Allocate memory if don't already have an allocation */
3239273SAli.Bahrami@Sun.COM if (sym->ste_alloc == NULL) {
3249273SAli.Bahrami@Sun.COM sym->ste_alloc = elfedit_malloc(MSG_INTL(MSG_ALLOC_ELFCONDESC),
3259273SAli.Bahrami@Sun.COM fill_state.cnt * sizeof (*fill_state.desc));
3269273SAli.Bahrami@Sun.COM sym->ste_nelts = fill_state.cnt;
3279273SAli.Bahrami@Sun.COM }
3289273SAli.Bahrami@Sun.COM
3299273SAli.Bahrami@Sun.COM /* Fill the array */
3309273SAli.Bahrami@Sun.COM fill_state.desc = sym->ste_alloc;
3319273SAli.Bahrami@Sun.COM fill_state.cur = 0;
3329273SAli.Bahrami@Sun.COM libconv_fill_iter(sym, osabi, mach, libconv_fill_cb, &fill_state);
3339273SAli.Bahrami@Sun.COM
3349273SAli.Bahrami@Sun.COM /* Add null termination */
3359273SAli.Bahrami@Sun.COM fill_state.desc[fill_state.cur].sym_name = NULL;
3369273SAli.Bahrami@Sun.COM fill_state.desc[fill_state.cur].sym_value = 0;
3379273SAli.Bahrami@Sun.COM
3389273SAli.Bahrami@Sun.COM /* atoui array for this item is now available */
3399273SAli.Bahrami@Sun.COM sym->ste_arr = fill_state.desc;
3409273SAli.Bahrami@Sun.COM }
3419273SAli.Bahrami@Sun.COM
3429273SAli.Bahrami@Sun.COM /*
3439273SAli.Bahrami@Sun.COM * Should be called on first call to elfedit_const_to_atoui(). Does the
3449273SAli.Bahrami@Sun.COM * runtime initialization of sym_table.
3455565Sab196087 */
3465565Sab196087 static void
init_libconv_strings(conv_iter_osabi_t * osabi,Half * mach)3479273SAli.Bahrami@Sun.COM init_libconv_strings(conv_iter_osabi_t *osabi, Half *mach)
3485565Sab196087 {
3499273SAli.Bahrami@Sun.COM /*
3509273SAli.Bahrami@Sun.COM * It is critical that the ste_type and ste_conv_func values
3519273SAli.Bahrami@Sun.COM * agree. Since the libconv iteration function signatures can
3529273SAli.Bahrami@Sun.COM * change (gain or lose an osabi or mach argument), we want to
3539273SAli.Bahrami@Sun.COM * ensure that the compiler will catch such changes.
3549273SAli.Bahrami@Sun.COM *
3559273SAli.Bahrami@Sun.COM * The compiler will catch an attempt to assign a function of
3569273SAli.Bahrami@Sun.COM * the wrong type to ste_conv_func. Using these macros, we ensure
3579273SAli.Bahrami@Sun.COM * that the ste_type and function assignment happen as a unit.
3589273SAli.Bahrami@Sun.COM */
3599273SAli.Bahrami@Sun.COM #define LC(_ndx, _func) sym_table[_ndx].ste_type = STE_LC; \
3609273SAli.Bahrami@Sun.COM sym_table[_ndx].ste_conv_func.simple = _func;
3619273SAli.Bahrami@Sun.COM #define LC_OS(_ndx, _func) sym_table[_ndx].ste_type = STE_LC_OS; \
3629273SAli.Bahrami@Sun.COM sym_table[_ndx].ste_conv_func.osabi = _func;
3639273SAli.Bahrami@Sun.COM #define LC_MACH(_ndx, _func) sym_table[_ndx].ste_type = STE_LC_MACH; \
3649273SAli.Bahrami@Sun.COM sym_table[_ndx].ste_conv_func.mach = _func;
3659273SAli.Bahrami@Sun.COM #define LC_OS_MACH(_ndx, _func) sym_table[_ndx].ste_type = STE_LC_OS_MACH; \
3669273SAli.Bahrami@Sun.COM sym_table[_ndx].ste_conv_func.osabi_mach = _func;
3679273SAli.Bahrami@Sun.COM
3689273SAli.Bahrami@Sun.COM
3699273SAli.Bahrami@Sun.COM if (!state.file.present) {
3709273SAli.Bahrami@Sun.COM /*
3719273SAli.Bahrami@Sun.COM * No input file: Supply the maximal set of strings for
3729273SAli.Bahrami@Sun.COM * all osabi and mach values understood by libconv.
3739273SAli.Bahrami@Sun.COM */
3749273SAli.Bahrami@Sun.COM *osabi = CONV_OSABI_ALL;
3759273SAli.Bahrami@Sun.COM *mach = CONV_MACH_ALL;
3769273SAli.Bahrami@Sun.COM } else if (state.elf.elfclass == ELFCLASS32) {
3779273SAli.Bahrami@Sun.COM *osabi = state.elf.obj_state.s32->os_ehdr->e_ident[EI_OSABI];
3789273SAli.Bahrami@Sun.COM *mach = state.elf.obj_state.s32->os_ehdr->e_machine;
3799273SAli.Bahrami@Sun.COM } else {
3809273SAli.Bahrami@Sun.COM *osabi = state.elf.obj_state.s64->os_ehdr->e_ident[EI_OSABI];
3819273SAli.Bahrami@Sun.COM *mach = state.elf.obj_state.s64->os_ehdr->e_machine;
3829273SAli.Bahrami@Sun.COM }
3835565Sab196087
3849273SAli.Bahrami@Sun.COM /* Set up non- STE_STATIC libconv fill functions */
3859273SAli.Bahrami@Sun.COM LC_OS_MACH(ELFEDIT_CONST_SHN, conv_iter_sym_shndx);
3869273SAli.Bahrami@Sun.COM LC_OS_MACH(ELFEDIT_CONST_SHT, conv_iter_sec_type);
3879273SAli.Bahrami@Sun.COM LC_OS(ELFEDIT_CONST_SHT_ALLSYMTAB, conv_iter_sec_symtab);
3889273SAli.Bahrami@Sun.COM LC_OS_MACH(ELFEDIT_CONST_DT, conv_iter_dyn_tag);
3899273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_DF, conv_iter_dyn_flag);
3909273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_DF_P1, conv_iter_dyn_posflag1);
3919273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_DF_1, conv_iter_dyn_flag1);
3929273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_DTF_1, conv_iter_dyn_feature1);
3939273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_EI, conv_iter_ehdr_eident);
3949273SAli.Bahrami@Sun.COM LC_OS(ELFEDIT_CONST_ET, conv_iter_ehdr_type);
3959273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_ELFCLASS, conv_iter_ehdr_class);
3969273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_ELFDATA, conv_iter_ehdr_data);
3979273SAli.Bahrami@Sun.COM LC_MACH(ELFEDIT_CONST_EF, conv_iter_ehdr_flags);
3989273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_EV, conv_iter_ehdr_vers);
3999273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_EM, conv_iter_ehdr_mach);
4009273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_ELFOSABI, conv_iter_ehdr_osabi);
4019273SAli.Bahrami@Sun.COM LC_OS(ELFEDIT_CONST_EAV, conv_iter_ehdr_abivers);
4029273SAli.Bahrami@Sun.COM LC_OS(ELFEDIT_CONST_PT, conv_iter_phdr_type);
4039273SAli.Bahrami@Sun.COM LC_OS(ELFEDIT_CONST_PF, conv_iter_phdr_flags);
4049273SAli.Bahrami@Sun.COM LC_OS_MACH(ELFEDIT_CONST_SHF, conv_iter_sec_flags);
4059273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_STB, conv_iter_sym_info_bind);
4069273SAli.Bahrami@Sun.COM LC_MACH(ELFEDIT_CONST_STT, conv_iter_sym_info_type);
4079273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_STV, conv_iter_sym_other_vis);
4089273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_SYMINFO_BT, conv_iter_syminfo_boundto);
4099273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_SYMINFO_FLG, conv_iter_syminfo_flags);
4109273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_CA, conv_iter_cap_tags);
411*11827SRod.Evans@Sun.COM LC_MACH(ELFEDIT_CONST_HW1_SUNW, conv_iter_cap_val_hw1);
4129273SAli.Bahrami@Sun.COM LC(ELFEDIT_CONST_SF1_SUNW, conv_iter_cap_val_sf1);
413*11827SRod.Evans@Sun.COM LC_MACH(ELFEDIT_CONST_HW2_SUNW, conv_iter_cap_val_hw2);
4149273SAli.Bahrami@Sun.COM
4159273SAli.Bahrami@Sun.COM #undef LC
4169273SAli.Bahrami@Sun.COM #undef LC_OS
4179273SAli.Bahrami@Sun.COM #undef LC_MACH
4189273SAli.Bahrami@Sun.COM #undef LC_OS_MACH
4199273SAli.Bahrami@Sun.COM }
4209273SAli.Bahrami@Sun.COM
4219273SAli.Bahrami@Sun.COM /*
4229273SAli.Bahrami@Sun.COM * If the user has changed the osabi or machine type of the object,
4239273SAli.Bahrami@Sun.COM * then we need to discard the strings we've loaded from libconv
4249273SAli.Bahrami@Sun.COM * that are dependent on these values.
4259273SAli.Bahrami@Sun.COM */
4269273SAli.Bahrami@Sun.COM static void
invalidate_libconv_strings(conv_iter_osabi_t * osabi,Half * mach)4279273SAli.Bahrami@Sun.COM invalidate_libconv_strings(conv_iter_osabi_t *osabi, Half *mach)
4289273SAli.Bahrami@Sun.COM {
4299273SAli.Bahrami@Sun.COM uchar_t cur_osabi;
4309273SAli.Bahrami@Sun.COM Half cur_mach;
4319273SAli.Bahrami@Sun.COM sym_table_ent_t *sym;
4329273SAli.Bahrami@Sun.COM int osabi_change, mach_change;
4339273SAli.Bahrami@Sun.COM int i;
4349273SAli.Bahrami@Sun.COM
4359273SAli.Bahrami@Sun.COM
4369273SAli.Bahrami@Sun.COM /* Reset the ELF header change notification */
4379273SAli.Bahrami@Sun.COM state.elf.elfconst_ehdr_change = 0;
4389273SAli.Bahrami@Sun.COM
4399273SAli.Bahrami@Sun.COM if (state.elf.elfclass == ELFCLASS32) {
4409273SAli.Bahrami@Sun.COM cur_osabi = state.elf.obj_state.s32->os_ehdr->e_ident[EI_OSABI];
4419273SAli.Bahrami@Sun.COM cur_mach = state.elf.obj_state.s32->os_ehdr->e_machine;
4429273SAli.Bahrami@Sun.COM } else {
4439273SAli.Bahrami@Sun.COM cur_osabi = state.elf.obj_state.s64->os_ehdr->e_ident[EI_OSABI];
4449273SAli.Bahrami@Sun.COM cur_mach = state.elf.obj_state.s64->os_ehdr->e_machine;
4459273SAli.Bahrami@Sun.COM }
4469273SAli.Bahrami@Sun.COM
4479273SAli.Bahrami@Sun.COM /* What has changed? */
4489273SAli.Bahrami@Sun.COM mach_change = *mach != cur_mach;
4499273SAli.Bahrami@Sun.COM osabi_change = *osabi != cur_osabi;
4509273SAli.Bahrami@Sun.COM if (!(mach_change || osabi_change))
4519273SAli.Bahrami@Sun.COM return;
4529273SAli.Bahrami@Sun.COM
4539273SAli.Bahrami@Sun.COM /*
4549273SAli.Bahrami@Sun.COM * Set the ste_arr pointer to NULL for any items that
4559273SAli.Bahrami@Sun.COM * depend on the things that have changed. Note that we
4569273SAli.Bahrami@Sun.COM * do not release the allocated memory --- it may turn
4579273SAli.Bahrami@Sun.COM * out to be large enough to hold the new strings, so we
4589273SAli.Bahrami@Sun.COM * keep the allocation and leave that decision to the fill
4599273SAli.Bahrami@Sun.COM * routine, which will run the next time those strings are
4609273SAli.Bahrami@Sun.COM * needed.
4619273SAli.Bahrami@Sun.COM */
4629273SAli.Bahrami@Sun.COM for (i = 0, sym = sym_table;
4639273SAli.Bahrami@Sun.COM i < (sizeof (sym_table) / sizeof (sym_table[0])); i++, sym++) {
4649273SAli.Bahrami@Sun.COM if (sym->ste_arr == NULL)
4655565Sab196087 continue;
4665565Sab196087
4679273SAli.Bahrami@Sun.COM switch (sym->ste_type) {
4689273SAli.Bahrami@Sun.COM case STE_LC_OS:
4699273SAli.Bahrami@Sun.COM if (osabi_change)
4709273SAli.Bahrami@Sun.COM sym->ste_arr = NULL;
4719273SAli.Bahrami@Sun.COM break;
4725565Sab196087
4739273SAli.Bahrami@Sun.COM case STE_LC_MACH:
4749273SAli.Bahrami@Sun.COM if (mach_change)
4759273SAli.Bahrami@Sun.COM sym->ste_arr = NULL;
4769273SAli.Bahrami@Sun.COM break;
4779273SAli.Bahrami@Sun.COM
4789273SAli.Bahrami@Sun.COM case STE_LC_OS_MACH:
4799273SAli.Bahrami@Sun.COM if (osabi_change || mach_change)
4809273SAli.Bahrami@Sun.COM sym->ste_arr = NULL;
4819273SAli.Bahrami@Sun.COM break;
4829273SAli.Bahrami@Sun.COM }
4835565Sab196087 }
4845565Sab196087
4859273SAli.Bahrami@Sun.COM *mach = cur_mach;
4869273SAli.Bahrami@Sun.COM *osabi = cur_osabi;
4875565Sab196087 }
4885565Sab196087
4895565Sab196087
4905565Sab196087
4915565Sab196087 /*
4925088Sab196087 * Given an elfedit_const_t value, return the array of elfedit_atoui_sym_t
4935088Sab196087 * entries that it represents.
4945088Sab196087 */
4955088Sab196087 elfedit_atoui_sym_t *
elfedit_const_to_atoui(elfedit_const_t const_type)4965088Sab196087 elfedit_const_to_atoui(elfedit_const_t const_type)
4975088Sab196087 {
4989273SAli.Bahrami@Sun.COM static int first = 1;
4999273SAli.Bahrami@Sun.COM static conv_iter_osabi_t osabi;
5009273SAli.Bahrami@Sun.COM static Half mach;
5019273SAli.Bahrami@Sun.COM
5029273SAli.Bahrami@Sun.COM sym_table_ent_t *sym;
5039273SAli.Bahrami@Sun.COM
5049273SAli.Bahrami@Sun.COM if (first) {
5059273SAli.Bahrami@Sun.COM init_libconv_strings(&osabi, &mach);
5069273SAli.Bahrami@Sun.COM first = 0;
5079273SAli.Bahrami@Sun.COM }
5089273SAli.Bahrami@Sun.COM
5095088Sab196087 if ((const_type < 0) ||
5105088Sab196087 (const_type >= (sizeof (sym_table) / sizeof (sym_table[0]))))
5115088Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADCONST));
5129273SAli.Bahrami@Sun.COM sym = &sym_table[const_type];
5135088Sab196087
5149273SAli.Bahrami@Sun.COM /*
5159273SAli.Bahrami@Sun.COM * If the constant is not STE_STATIC, then we may need to fetch
5169273SAli.Bahrami@Sun.COM * the strings from libconv.
5179273SAli.Bahrami@Sun.COM */
5189273SAli.Bahrami@Sun.COM if (sym->ste_type != STE_STATIC) {
5199273SAli.Bahrami@Sun.COM /*
5209273SAli.Bahrami@Sun.COM * If the ELF header has changed since the last
5219273SAli.Bahrami@Sun.COM * time we were called, then we need to invalidate any
5229273SAli.Bahrami@Sun.COM * strings previously pulled from libconv that have
5239273SAli.Bahrami@Sun.COM * an osabi or machine dependency.
5249273SAli.Bahrami@Sun.COM */
5259273SAli.Bahrami@Sun.COM if (state.elf.elfconst_ehdr_change)
5269273SAli.Bahrami@Sun.COM invalidate_libconv_strings(&osabi, &mach);
5279273SAli.Bahrami@Sun.COM
5289273SAli.Bahrami@Sun.COM /* If we don't already have the strings, get them */
5299273SAli.Bahrami@Sun.COM if (sym->ste_arr == NULL)
5309273SAli.Bahrami@Sun.COM libconv_fill(sym, osabi, mach);
5315565Sab196087 }
5325565Sab196087
5339273SAli.Bahrami@Sun.COM return (sym->ste_arr);
5345088Sab196087 }
535