elfconst.c revision 08278a5e91755ccdb5850c19d21d42fb2e16b50e
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdlib.h>
#include <stdio.h>
#include <_elfedit.h>
#include <conv.h>
#include <msg.h>
/*
* This file contains support for mapping well known ELF constants
* to their numeric values. It is a layer on top of the elfedit_atoui()
* routines defined in util.c. The idea is that centralizing all the
* support for such constants will improve consistency between modules,
* allow for sharing of commonly needed items, and make the modules
* simpler.
*/
/*
* elfedit output style, with and without leading -o
*/
static elfedit_atoui_sym_t sym_outstyle[] = {
{ NULL }
};
static elfedit_atoui_sym_t sym_minus_o_outstyle[] = {
{ NULL }
};
/*
* Booleans
*/
static elfedit_atoui_sym_t sym_bool[] = {
{ MSG_ORIG(MSG_STR_FALSE), 0 },
{ MSG_ORIG(MSG_STR_OFF), 0 },
{ MSG_ORIG(MSG_STR_NO), 0 },
{ NULL }
};
/*
* ELF strings for SHT_STRTAB
*/
static elfedit_atoui_sym_t sym_sht_strtab[] = {
{ NULL }
};
/*
* Strings for SHT_SYMTAB
*/
static elfedit_atoui_sym_t sym_sht_symtab[] = {
{ NULL }
};
/*
* Strings for SHT_DYNSYM
*/
static elfedit_atoui_sym_t sym_sht_dynsym[] = {
{ NULL }
};
/*
* Strings for SHT_SUNW_LDYNSYM
*/
static elfedit_atoui_sym_t sym_sht_ldynsym[] = {
{ NULL }
};
/*
* Types of items found in sym_table[]. All items other than STE_STATIC
* pulls strings from libconv, differing in the interface required by
* the libconv iteration function used.
*/
typedef enum {
STE_STATIC = 0, /* Constants are statically defined */
} ste_type_t;
/*
* Interface of functions called to fill strings from libconv
*/
typedef conv_iter_ret_t (* libconv_iter_func_simple_t)(
Conv_fmt_flags_t, conv_iter_cb_t, void *);
Conv_fmt_flags_t, conv_iter_cb_t, void *);
Conv_fmt_flags_t, conv_iter_cb_t, void *);
Conv_fmt_flags_t, conv_iter_cb_t, void *);
typedef union {
/*
* State for each type of constant
*/
typedef struct {
void *ste_alloc; /* Current memory allocation */
/*
* Array of state for each constant type, including the array of atoui
* pointers, for each constant type, indexed by elfedit_const_t value.
* The number and order of entries in this table must agree with the
* definition of elfedit_const_t in elfedit.h.
*
* note:
* - STE_STATIC items must supply a statically allocated buffer here.
* - The non-STE_STATIC items use libconv strings. These items are
* initialized by init_libconv_strings() at runtime, and are represented
* by a simple { 0 } here. The memory used for these arrays is dynamic,
* and can be released and rebuilt at runtime as necessary to keep up
* with changes in osabi or machine type.
*/
/* #: ELFEDIT_CONST_xxx */
{ 0 }, /* 7: SHN */
{ 0 }, /* 8: SHT */
{ 0 }, /* 9: SHT_ALLSYMTAB */
{ 0 }, /* 10: DT */
{ 0 }, /* 11: DF */
{ 0 }, /* 12: DF_P1 */
{ 0 }, /* 13: DF_1 */
{ 0 }, /* 14: DTF_1 */
{ 0 }, /* 15: EI */
{ 0 }, /* 16: ET */
{ 0 }, /* 17: ELFCLASS */
{ 0 }, /* 18: ELFDATA */
{ 0 }, /* 19: EF */
{ 0 }, /* 20: EV */
{ 0 }, /* 21: EM */
{ 0 }, /* 22: ELFOSABI */
{ 0 }, /* 23: EAV osabi version */
{ 0 }, /* 24: PT */
{ 0 }, /* 25: PF */
{ 0 }, /* 26: SHF */
{ 0 }, /* 27: STB */
{ 0 }, /* 28: STT */
{ 0 }, /* 29: STV */
{ 0 }, /* 30: SYMINFO_BT */
{ 0 }, /* 31: SYMINFO_FLG */
{ 0 }, /* 32: CA */
{ 0 }, /* 33: AV */
{ 0 }, /* 34: SF1_SUNW */
};
#if ELFEDIT_CONST_NUM != (ELFEDIT_CONST_SF1_SUNW)
error "ELFEDIT_CONST_NUM has grown. Update sym_table[]"
#endif
/*
* Used to count the number of descriptors that will be needed to hold
* strings from libconv.
*/
/*ARGSUSED*/
static conv_iter_ret_t
{
(*cnt)++;
return (CONV_ITER_CONT);
}
/*
* Used to fill in the descriptors with strings from libconv.
*/
typedef struct {
static conv_iter_ret_t
{
return (CONV_ITER_CONT);
}
/*
* Call the iteration function using the correct calling sequence for
* the libconv routine.
*/
static void
{
case STE_LC:
break;
case STE_LC_OS:
break;
case STE_LC_MACH:
break;
case STE_LC_OS_MACH:
break;
}
}
/*
*/
static void
{
/* How many descriptors will we need? */
/*
* If there is an existing allocation, and it is not large enough,
* release it.
*/
}
/* Allocate memory if don't already have an allocation */
}
/* Fill the array */
fill_state.cur = 0;
/* Add null termination */
/* atoui array for this item is now available */
}
/*
* Should be called on first call to elfedit_const_to_atoui(). Does the
* runtime initialization of sym_table.
*/
static void
{
/*
* It is critical that the ste_type and ste_conv_func values
* agree. Since the libconv iteration function signatures can
* change (gain or lose an osabi or mach argument), we want to
* ensure that the compiler will catch such changes.
*
* The compiler will catch an attempt to assign a function of
* the wrong type to ste_conv_func. Using these macros, we ensure
* that the ste_type and function assignment happen as a unit.
*/
/*
* No input file: Supply the maximal set of strings for
* all osabi and mach values understood by libconv.
*/
*osabi = CONV_OSABI_ALL;
*mach = CONV_MACH_ALL;
} else {
}
/* Set up non- STE_STATIC libconv fill functions */
}
/*
* If the user has changed the osabi or machine type of the object,
* then we need to discard the strings we've loaded from libconv
* that are dependent on these values.
*/
static void
{
int osabi_change, mach_change;
int i;
/* Reset the ELF header change notification */
} else {
}
/* What has changed? */
if (!(mach_change || osabi_change))
return;
/*
* Set the ste_arr pointer to NULL for any items that
* depend on the things that have changed. Note that we
* do not release the allocated memory --- it may turn
* out to be large enough to hold the new strings, so we
* keep the allocation and leave that decision to the fill
* routine, which will run the next time those strings are
* needed.
*/
continue;
case STE_LC_OS:
if (osabi_change)
break;
case STE_LC_MACH:
if (mach_change)
break;
case STE_LC_OS_MACH:
if (osabi_change || mach_change)
break;
}
}
}
/*
* Given an elfedit_const_t value, return the array of elfedit_atoui_sym_t
* entries that it represents.
*/
{
static int first = 1;
static conv_iter_osabi_t osabi;
if (first) {
first = 0;
}
if ((const_type < 0) ||
/*
* If the constant is not STE_STATIC, then we may need to fetch
* the strings from libconv.
*/
/*
* If the ELF header has changed since the last
* time we were called, then we need to invalidate any
* strings previously pulled from libconv that have
* an osabi or machine dependency.
*/
/* If we don't already have the strings, get them */
}
}