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