1d29b2c44Sab196087 /* 2d29b2c44Sab196087 * CDDL HEADER START 3d29b2c44Sab196087 * 4d29b2c44Sab196087 * The contents of this file are subject to the terms of the 5d29b2c44Sab196087 * Common Development and Distribution License (the "License"). 6d29b2c44Sab196087 * You may not use this file except in compliance with the License. 7d29b2c44Sab196087 * 8d29b2c44Sab196087 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9d29b2c44Sab196087 * or http://www.opensolaris.org/os/licensing. 10d29b2c44Sab196087 * See the License for the specific language governing permissions 11d29b2c44Sab196087 * and limitations under the License. 12d29b2c44Sab196087 * 13d29b2c44Sab196087 * When distributing Covered Code, include this CDDL HEADER in each 14d29b2c44Sab196087 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15d29b2c44Sab196087 * If applicable, add the following below this CDDL HEADER, with the 16d29b2c44Sab196087 * fields enclosed by brackets "[]" replaced with your own identifying 17d29b2c44Sab196087 * information: Portions Copyright [yyyy] [name of copyright owner] 18d29b2c44Sab196087 * 19d29b2c44Sab196087 * CDDL HEADER END 20d29b2c44Sab196087 */ 21d29b2c44Sab196087 22d29b2c44Sab196087 /* 23*08278a5eSRod Evans * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24d29b2c44Sab196087 * Use is subject to license terms. 25d29b2c44Sab196087 */ 26d29b2c44Sab196087 27d29b2c44Sab196087 #include <stdlib.h> 28d29b2c44Sab196087 #include <stdio.h> 29d29b2c44Sab196087 #include <_elfedit.h> 304f680cc6SAli Bahrami #include <conv.h> 31d29b2c44Sab196087 #include <msg.h> 32d29b2c44Sab196087 33d29b2c44Sab196087 34d29b2c44Sab196087 35d29b2c44Sab196087 /* 36d29b2c44Sab196087 * This file contains support for mapping well known ELF constants 37d29b2c44Sab196087 * to their numeric values. It is a layer on top of the elfedit_atoui() 38d29b2c44Sab196087 * routines defined in util.c. The idea is that centralizing all the 39d29b2c44Sab196087 * support for such constants will improve consistency between modules, 40d29b2c44Sab196087 * allow for sharing of commonly needed items, and make the modules 41d29b2c44Sab196087 * simpler. 42d29b2c44Sab196087 */ 43d29b2c44Sab196087 44d29b2c44Sab196087 45d29b2c44Sab196087 46d29b2c44Sab196087 47d29b2c44Sab196087 /* 48d29b2c44Sab196087 * elfedit output style, with and without leading -o 49d29b2c44Sab196087 */ 50d29b2c44Sab196087 static elfedit_atoui_sym_t sym_outstyle[] = { 51d29b2c44Sab196087 { MSG_ORIG(MSG_STR_DEFAULT), ELFEDIT_OUTSTYLE_DEFAULT }, 52d29b2c44Sab196087 { MSG_ORIG(MSG_STR_SIMPLE), ELFEDIT_OUTSTYLE_SIMPLE }, 53d29b2c44Sab196087 { MSG_ORIG(MSG_STR_NUM), ELFEDIT_OUTSTYLE_NUM }, 54d29b2c44Sab196087 { NULL } 55d29b2c44Sab196087 }; 56d29b2c44Sab196087 static elfedit_atoui_sym_t sym_minus_o_outstyle[] = { 57d29b2c44Sab196087 { MSG_ORIG(MSG_STR_MINUS_O_DEFAULT), ELFEDIT_OUTSTYLE_DEFAULT }, 58d29b2c44Sab196087 { MSG_ORIG(MSG_STR_MINUS_O_SIMPLE), ELFEDIT_OUTSTYLE_SIMPLE }, 59d29b2c44Sab196087 { MSG_ORIG(MSG_STR_MINUS_O_NUM), ELFEDIT_OUTSTYLE_NUM }, 60d29b2c44Sab196087 { NULL } 61d29b2c44Sab196087 }; 62d29b2c44Sab196087 63d29b2c44Sab196087 64d29b2c44Sab196087 /* 65d29b2c44Sab196087 * Booleans 66d29b2c44Sab196087 */ 67d29b2c44Sab196087 static elfedit_atoui_sym_t sym_bool[] = { 68d29b2c44Sab196087 { MSG_ORIG(MSG_STR_T), 1 }, 69d29b2c44Sab196087 { MSG_ORIG(MSG_STR_F), 0 }, 70d29b2c44Sab196087 { MSG_ORIG(MSG_STR_TRUE), 1 }, 71d29b2c44Sab196087 { MSG_ORIG(MSG_STR_FALSE), 0 }, 72d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ON), 1 }, 73d29b2c44Sab196087 { MSG_ORIG(MSG_STR_OFF), 0 }, 74d29b2c44Sab196087 { MSG_ORIG(MSG_STR_YES), 1 }, 75d29b2c44Sab196087 { MSG_ORIG(MSG_STR_NO), 0 }, 76d29b2c44Sab196087 { MSG_ORIG(MSG_STR_Y), 1 }, 77d29b2c44Sab196087 { MSG_ORIG(MSG_STR_N), 0 }, 78d29b2c44Sab196087 { NULL } 79d29b2c44Sab196087 }; 80d29b2c44Sab196087 81d29b2c44Sab196087 /* 824f680cc6SAli Bahrami * ELF strings for SHT_STRTAB 83d29b2c44Sab196087 */ 84d29b2c44Sab196087 static elfedit_atoui_sym_t sym_sht_strtab[] = { 85d29b2c44Sab196087 { MSG_ORIG(MSG_SHT_STRTAB), SHT_STRTAB }, 86d29b2c44Sab196087 { MSG_ORIG(MSG_SHT_STRTAB_ALT1), SHT_STRTAB }, 87d29b2c44Sab196087 88d29b2c44Sab196087 { NULL } 89d29b2c44Sab196087 }; 90d29b2c44Sab196087 91d29b2c44Sab196087 92d29b2c44Sab196087 /* 934f680cc6SAli Bahrami * Strings for SHT_SYMTAB 94d29b2c44Sab196087 */ 95d29b2c44Sab196087 static elfedit_atoui_sym_t sym_sht_symtab[] = { 96d29b2c44Sab196087 { MSG_ORIG(MSG_SHT_SYMTAB), SHT_SYMTAB }, 97d29b2c44Sab196087 { MSG_ORIG(MSG_SHT_SYMTAB_ALT1), SHT_SYMTAB }, 98d29b2c44Sab196087 99d29b2c44Sab196087 { NULL } 100d29b2c44Sab196087 }; 101d29b2c44Sab196087 102d29b2c44Sab196087 /* 1034f680cc6SAli Bahrami * Strings for SHT_DYNSYM 104d29b2c44Sab196087 */ 105d29b2c44Sab196087 static elfedit_atoui_sym_t sym_sht_dynsym[] = { 106d29b2c44Sab196087 { MSG_ORIG(MSG_SHT_DYNSYM), SHT_DYNSYM }, 107d29b2c44Sab196087 { MSG_ORIG(MSG_SHT_DYNSYM_ALT1), SHT_DYNSYM }, 108d29b2c44Sab196087 109d29b2c44Sab196087 { NULL } 110d29b2c44Sab196087 }; 111d29b2c44Sab196087 112d29b2c44Sab196087 /* 1134f680cc6SAli Bahrami * Strings for SHT_SUNW_LDYNSYM 114d29b2c44Sab196087 */ 115d29b2c44Sab196087 static elfedit_atoui_sym_t sym_sht_ldynsym[] = { 116d29b2c44Sab196087 { MSG_ORIG(MSG_SHT_SUNW_LDYNSYM), SHT_SUNW_LDYNSYM }, 117d29b2c44Sab196087 { MSG_ORIG(MSG_SHT_SUNW_LDYNSYM_ALT1), SHT_SUNW_LDYNSYM }, 118d29b2c44Sab196087 119d29b2c44Sab196087 { NULL } 120d29b2c44Sab196087 }; 121d29b2c44Sab196087 122d29b2c44Sab196087 123d29b2c44Sab196087 124d29b2c44Sab196087 /* 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. 128d29b2c44Sab196087 */ 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; 136d29b2c44Sab196087 1374f680cc6SAli Bahrami /* 1384f680cc6SAli Bahrami * Interface of functions called to fill strings from libconv 1394f680cc6SAli Bahrami */ 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; 154d29b2c44Sab196087 1554f680cc6SAli Bahrami /* 1564f680cc6SAli Bahrami * State for each type of constant 1574f680cc6SAli Bahrami */ 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; 165d29b2c44Sab196087 166d29b2c44Sab196087 167d29b2c44Sab196087 /* 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. 180d29b2c44Sab196087 */ 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 */ 218d29b2c44Sab196087 }; 2194f680cc6SAli Bahrami #if ELFEDIT_CONST_NUM != (ELFEDIT_CONST_SF1_SUNW) 2204f680cc6SAli Bahrami error "ELFEDIT_CONST_NUM has grown. Update sym_table[]" 221d29b2c44Sab196087 #endif 222d29b2c44Sab196087 223d29b2c44Sab196087 224d29b2c44Sab196087 225d29b2c44Sab196087 226d29b2c44Sab196087 /* 2274f680cc6SAli Bahrami * Used to count the number of descriptors that will be needed to hold 2284f680cc6SAli Bahrami * strings from libconv. 229d29b2c44Sab196087 */ 2304f680cc6SAli Bahrami /*ARGSUSED*/ 2314f680cc6SAli Bahrami static conv_iter_ret_t 2324f680cc6SAli Bahrami libconv_count_cb(const char *str, Conv_elfvalue_t value, void *uvalue) 23399f63845Sab196087 { 2344f680cc6SAli Bahrami size_t *cnt = (size_t *)uvalue; 23599f63845Sab196087 2364f680cc6SAli Bahrami (*cnt)++; 2374f680cc6SAli Bahrami return (CONV_ITER_CONT); 23899f63845Sab196087 } 23999f63845Sab196087 2404f680cc6SAli Bahrami /* 2414f680cc6SAli Bahrami * Used to fill in the descriptors with strings from libconv. 2424f680cc6SAli Bahrami */ 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; 2484f680cc6SAli Bahrami 2494f680cc6SAli Bahrami static conv_iter_ret_t 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++]; 2544f680cc6SAli Bahrami 2554f680cc6SAli Bahrami sym->sym_name = str; 2564f680cc6SAli Bahrami sym->sym_value = value; 2574f680cc6SAli Bahrami return (CONV_ITER_CONT); 2584f680cc6SAli Bahrami } 2594f680cc6SAli Bahrami 2604f680cc6SAli Bahrami 2614f680cc6SAli Bahrami /* 2624f680cc6SAli Bahrami * Call the iteration function using the correct calling sequence for 2634f680cc6SAli Bahrami * the libconv routine. 2644f680cc6SAli Bahrami */ 2654f680cc6SAli Bahrami static void 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; 2764f680cc6SAli Bahrami 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; 2834f680cc6SAli Bahrami 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; 2904f680cc6SAli Bahrami 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 } 2994f680cc6SAli Bahrami 3004f680cc6SAli Bahrami /* 3014f680cc6SAli Bahrami * Allocate/Fill an atoui array for the specified constant. 3024f680cc6SAli Bahrami */ 3034f680cc6SAli Bahrami static void 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 } 3214f680cc6SAli Bahrami 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 } 3284f680cc6SAli Bahrami 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); 3334f680cc6SAli Bahrami 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; 3374f680cc6SAli Bahrami 3384f680cc6SAli Bahrami /* atoui array for this item is now available */ 3394f680cc6SAli Bahrami sym->ste_arr = fill_state.desc; 3404f680cc6SAli Bahrami } 3414f680cc6SAli Bahrami 3424f680cc6SAli Bahrami /* 3434f680cc6SAli Bahrami * Should be called on first call to elfedit_const_to_atoui(). Does the 3444f680cc6SAli Bahrami * runtime initialization of sym_table. 3454f680cc6SAli Bahrami */ 3464f680cc6SAli Bahrami static void 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 } 3834f680cc6SAli Bahrami 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 } 4204f680cc6SAli Bahrami 4214f680cc6SAli Bahrami /* 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. 4254f680cc6SAli Bahrami */ 4264f680cc6SAli Bahrami static void 4274f680cc6SAli Bahrami invalidate_libconv_strings(conv_iter_osabi_t *osabi, Half *mach) 4284f680cc6SAli Bahrami { 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 } 4464f680cc6SAli Bahrami 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) 4654f680cc6SAli Bahrami continue; 4664f680cc6SAli Bahrami 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 } 4834f680cc6SAli Bahrami } 4844f680cc6SAli Bahrami 4854f680cc6SAli Bahrami *mach = cur_mach; 4864f680cc6SAli Bahrami *osabi = cur_osabi; 48799f63845Sab196087 } 48899f63845Sab196087 48999f63845Sab196087 49099f63845Sab196087 49199f63845Sab196087 /* 492d29b2c44Sab196087 * Given an elfedit_const_t value, return the array of elfedit_atoui_sym_t 493d29b2c44Sab196087 * entries that it represents. 494d29b2c44Sab196087 */ 495d29b2c44Sab196087 elfedit_atoui_sym_t * 496d29b2c44Sab196087 elfedit_const_to_atoui(elfedit_const_t const_type) 497d29b2c44Sab196087 { 4984f680cc6SAli Bahrami static int first = 1; 4994f680cc6SAli Bahrami static conv_iter_osabi_t osabi; 5004f680cc6SAli Bahrami static Half mach; 5014f680cc6SAli Bahrami 5024f680cc6SAli Bahrami sym_table_ent_t *sym; 5034f680cc6SAli Bahrami 5044f680cc6SAli Bahrami if (first) { 5054f680cc6SAli Bahrami init_libconv_strings(&osabi, &mach); 5064f680cc6SAli Bahrami first = 0; 5074f680cc6SAli Bahrami } 5084f680cc6SAli Bahrami 509d29b2c44Sab196087 if ((const_type < 0) || 510d29b2c44Sab196087 (const_type >= (sizeof (sym_table) / sizeof (sym_table[0])))) 511d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADCONST)); 5124f680cc6SAli Bahrami sym = &sym_table[const_type]; 513d29b2c44Sab196087 514d29b2c44Sab196087 /* 5154f680cc6SAli Bahrami * If the constant is not STE_STATIC, then we may need to fetch 5164f680cc6SAli Bahrami * the strings from libconv. 517d29b2c44Sab196087 */ 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); 527d29b2c44Sab196087 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); 531d29b2c44Sab196087 } 532d29b2c44Sab196087 5334f680cc6SAli Bahrami return (sym->ste_arr); 534d29b2c44Sab196087 } 535