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 /* 2311734SAli.Bahrami@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 245088Sab196087 * Use is subject to license terms. 255088Sab196087 */ 265088Sab196087 275088Sab196087 #ifndef _ELFEDIT_H 285088Sab196087 #define _ELFEDIT_H 295088Sab196087 305088Sab196087 #include <stdio.h> 315088Sab196087 #include <stdlib.h> 325088Sab196087 #include <sys/types.h> 335088Sab196087 #include <libelf.h> 345088Sab196087 #include <stdarg.h> 355088Sab196087 365088Sab196087 /* The following are here to support use of elfedit_msg() */ 375088Sab196087 #include <sys/machelf.h> /* EC_ macros */ 385088Sab196087 #include <libintl.h> 395088Sab196087 405088Sab196087 #ifdef __cplusplus 415088Sab196087 extern "C" { 425088Sab196087 #endif 435088Sab196087 445088Sab196087 455088Sab196087 /* 465088Sab196087 * elfedit uses elfedit_printf() to produce generic output to stdout. 475088Sab196087 * elfedit_msg() is used to produce error message, or specific types 485088Sab196087 * of terse informational messages: 495088Sab196087 * 505088Sab196087 * ELFEDIT_MSG_ERR: 515088Sab196087 * Issues an error to stderr. elfedit_msg() does not return 525088Sab196087 * to the caller. Control returns to the outer loop in 535088Sab196087 * interactive use. elfedit exits in non-interactive use. 545088Sab196087 * 555088Sab196087 * ELFEDIT_MSG_FATAL: 565088Sab196087 * Issues an error to stderr. elfedit_msg() exits the process, 575088Sab196087 * and does not return to the caller. 585088Sab196087 * 595088Sab196087 * ELFEDIT_MSG_USAGE: 605088Sab196087 * Issues an elfedit usage message to stderr, and 615088Sab196087 * returns to the caller. 625088Sab196087 * 635088Sab196087 * ELFEDIT_MSG_CMDUSAGE 645088Sab196087 * Issues an elfedit usage message to stderr, and 655088Sab196087 * does not return to the caller. 665088Sab196087 * 675088Sab196087 * ELFEDIT_MSG_DEBUG 685088Sab196087 * If the ELFEDIT_F_DEBUG flag is set, the message 695088Sab196087 * is printed to stdout, otherwise no output is produced. 705088Sab196087 * elfedit_msg() returns to the caller. 715088Sab196087 * 725088Sab196087 * ELFEDIT_MSG_QUIET 735088Sab196087 * This is a very special case, intended to handle the 745088Sab196087 * case where the pager subprocess exits before we are 755088Sab196087 * done producing output (the user presses 'q'). It acts 765088Sab196087 * just like ELFEDIT_MSG_ERR, except that no message is 775088Sab196087 * actually printed. 785088Sab196087 * 795088Sab196087 * In the cases where elfedit_msg() does not return to the caller, the 805088Sab196087 * behavior depends on the mode of execution. If running in interactive 815088Sab196087 * mode (reading from a tty), control is returned directly to the outer 825088Sab196087 * elfedit control loop to read another command. If not running in interactive 835088Sab196087 * mode, elfedit exits with a non-zero status. 845088Sab196087 */ 855088Sab196087 typedef enum { 865088Sab196087 ELFEDIT_MSG_ERR = 0, 875088Sab196087 ELFEDIT_MSG_FATAL = 1, 885088Sab196087 ELFEDIT_MSG_USAGE = 2, 895088Sab196087 ELFEDIT_MSG_CMDUSAGE = 3, 905088Sab196087 ELFEDIT_MSG_DEBUG = 4, 915088Sab196087 ELFEDIT_MSG_QUIET = 5 925088Sab196087 } elfedit_msg_t; 935088Sab196087 945088Sab196087 955088Sab196087 /* 965088Sab196087 * Information for a single ELF section. 975088Sab196087 * 985088Sab196087 * NOTE: sec_xshndx 995088Sab196087 * A symbol table can have an associated SHT_SYMTAB_SHNDX section. This 1005088Sab196087 * happens when the number of sections is too large to fit in the 1015088Sab196087 * ELF symbol st_shndx field, which is a 16-bit value. The sec_xshndx 1025088Sab196087 * field will be SHN_UNDEF if there is no such section, and will be 1035088Sab196087 * the section index of the extended section index section assocated 1045088Sab196087 * with the symbol table otherwise. 1055088Sab196087 * 1065088Sab196087 * NOTE: sec_versym 1075088Sab196087 * Symbol table sections can have an SHT_SUNW_VERSYM section that 1085088Sab196087 * contains its version indices. Other types of section will have 1095088Sab196087 * this field set to SHN_UNDEF. 1105088Sab196087 */ 1115088Sab196087 typedef struct { 1125088Sab196087 Elf32_Word sec_shndx; /* Section index */ 1135088Sab196087 Elf_Scn *sec_scn; /* Section descriptor */ 1145088Sab196087 Elf32_Shdr *sec_shdr; /* Section header */ 1155088Sab196087 Elf_Data *sec_data; /* Data region of section */ 1165088Sab196087 const char *sec_name; /* Name of section */ 1175088Sab196087 } elfedit32_section_t; 1185088Sab196087 1195088Sab196087 typedef struct { 1205088Sab196087 Elf64_Word sec_shndx; 1215088Sab196087 Elf_Scn *sec_scn; 1225088Sab196087 Elf64_Shdr *sec_shdr; 1235088Sab196087 Elf_Data *sec_data; 1245088Sab196087 const char *sec_name; 1255088Sab196087 } elfedit64_section_t; 1265088Sab196087 1275088Sab196087 #ifdef _ELF64 1285088Sab196087 #define elfedit_section_t elfedit64_section_t 1295088Sab196087 #else 1305088Sab196087 #define elfedit_section_t elfedit32_section_t 1315088Sab196087 #endif 1325088Sab196087 1335088Sab196087 1345088Sab196087 /* 1355088Sab196087 * We maintain extra information for symbol tables. We look them 1365088Sab196087 * up frequently, so we want to eliminate expensive linear searches 1375088Sab196087 * of the entire section header array. Also, symbol tables usually 1385088Sab196087 * have associated parallal sections (syminfo, versym, extended indexes, etc) 1395088Sab196087 * and we want to eliminate repeated linear lookups for them, as well as 1405088Sab196087 * the basic error checking that is necessary to ensure they match the 1415088Sab196087 * symbol table they're given. 1425088Sab196087 * 1435088Sab196087 * This extra information is kept in elfedit_symtab_t structs. Each field 1445088Sab196087 * is a section index, with SHN_UNDEF used for those that do not apply. 1455088Sab196087 */ 1465088Sab196087 typedef struct { 1475088Sab196087 Elf32_Word symt_shndx; /* Symbol table section index */ 1485088Sab196087 Elf32_Word symt_xshndx; /* Index of extended index section */ 1495088Sab196087 Elf32_Word symt_syminfo; /* Index of versym section */ 1505088Sab196087 Elf32_Word symt_versym; /* Index of versym section */ 1515088Sab196087 } elfedit32_symtab_t; 1525088Sab196087 1535088Sab196087 typedef struct { 1545088Sab196087 Elf64_Word symt_shndx; 1555088Sab196087 Elf64_Word symt_xshndx; 1565088Sab196087 Elf64_Word symt_versym; 1575088Sab196087 Elf64_Word symt_syminfo; 1585088Sab196087 } elfedit64_symtab_t; 1595088Sab196087 1605088Sab196087 #ifdef _ELF64 1615088Sab196087 #define elfedit_symtab_t elfedit64_symtab_t 1625088Sab196087 #else 1635088Sab196087 #define elfedit_symtab_t elfedit32_symtab_t 1645088Sab196087 #endif 1655088Sab196087 1665088Sab196087 1675088Sab196087 /* 1685088Sab196087 * Information for a single ELF object. 1695088Sab196087 * 1705088Sab196087 * note: 1715088Sab196087 * elfedit is intended to be an expert's tool, capable of modifying 1725088Sab196087 * nearly everything in the file, whether or not such modifications 1735088Sab196087 * are a good idea. At the same time, elfedit, via libelf, relies 1745088Sab196087 * on the contents of the object to properly locate information in 1755088Sab196087 * the file. As this is the same information that elfedit allows the 1765088Sab196087 * user to modify, it should be obvious that the potential exists 1775088Sab196087 * for users to corrupt the file to the degree that elfedit itself 1785088Sab196087 * may fail, or produce spurious results. We allow such changes for 1795088Sab196087 * several reasons: 1805088Sab196087 * 1815088Sab196087 * 1) Such corruption does not happen in the most obvious and 1825088Sab196087 * useful operations elfedit supports, but comes as a result 1835088Sab196087 * of modifying fields that contain size and offset information 1845088Sab196087 * used to navigate the file. Non-ELF developers have 1855088Sab196087 * little practical reason to change such things. 1865088Sab196087 * 1875088Sab196087 * 2) Producing a corrupt ELF file can be very useful 1885088Sab196087 * for R&D and/or testing purposes. 1895088Sab196087 * 1905088Sab196087 * 3) ELF is sufficiently complex that no absolute guarantees can 1915088Sab196087 * be made about "safe" operations, beyond the basic 1925088Sab196087 * and obvious things that are of practical use. 1935088Sab196087 * 1945088Sab196087 * One way we protect ourselves is via the information cached in 1955088Sab196087 * the elfedit_obj_state_t structure at startup. By using this 1965088Sab196087 * information, rather than constantly fetching it via libelf, 1975088Sab196087 * we protect ourselves against many user changes, such as changing the 1985088Sab196087 * program or section header offsets, or similar size/position fields. 1995088Sab196087 * 2005088Sab196087 * Of course, we make no assurances that that we will be able to 2015088Sab196087 * read the resulting file in a subsequent session. 2025088Sab196087 */ 2035088Sab196087 typedef struct { 2045088Sab196087 const char *os_file; /* Path to ELF file */ 2055088Sab196087 int os_fd; /* Open file descriptor */ 2065088Sab196087 Elf *os_elf; /* ELF descriptor */ 2075088Sab196087 Elf32_Ehdr *os_ehdr; /* ELF header */ 2085088Sab196087 Elf32_Word os_dynndx; /* Index of dynamic section */ 2095088Sab196087 size_t os_shstrndx; /* Index of section header */ 2105088Sab196087 /* string table section */ 2115088Sab196087 size_t os_shnum; /* # of sections in file */ 2125088Sab196087 elfedit32_section_t *os_secarr; /* Section data */ 2135088Sab196087 size_t os_phnum; /* # of program headers */ 2145088Sab196087 Elf32_Phdr *os_phdr; /* Program header array */ 2155088Sab196087 size_t os_symtabnum; /* # items in os_symtab[] */ 2165088Sab196087 elfedit32_symtab_t *os_symtab; /* Array of symbol tbl info */ 2175088Sab196087 } elfedit32_obj_state_t; 2185088Sab196087 2195088Sab196087 typedef struct { 2205088Sab196087 const char *os_file; 2215088Sab196087 int os_fd; 2225088Sab196087 Elf *os_elf; 2235088Sab196087 Elf64_Ehdr *os_ehdr; 2245088Sab196087 Elf64_Word os_dynndx; 2255088Sab196087 size_t os_shstrndx; 2265088Sab196087 size_t os_shnum; 2275088Sab196087 elfedit64_section_t *os_secarr; 2285088Sab196087 size_t os_phnum; 2295088Sab196087 Elf64_Phdr *os_phdr; 2305088Sab196087 size_t os_symtabnum; 2315088Sab196087 elfedit64_symtab_t *os_symtab; 2325088Sab196087 } elfedit64_obj_state_t; 2335088Sab196087 2345088Sab196087 #ifdef _ELF64 2355088Sab196087 #define elfedit_obj_state_t elfedit64_obj_state_t 2365088Sab196087 #else 2375088Sab196087 #define elfedit_obj_state_t elfedit32_obj_state_t 2385088Sab196087 #endif 2395088Sab196087 2405088Sab196087 2415088Sab196087 /* 2425088Sab196087 * Bit values for editor state. 2435088Sab196087 */ 2445088Sab196087 typedef enum { 2455088Sab196087 ELFEDIT_F_AUTOPRINT = 1, /* Print informational text about edits */ 2465088Sab196087 ELFEDIT_F_DEBUG = 2, /* Print informational text about operations */ 2475088Sab196087 ELFEDIT_F_READONLY = 4, /* File is processed readonly */ 2485088Sab196087 } elfedit_flag_t; 2495088Sab196087 2505088Sab196087 /* 2515088Sab196087 * Type used to represent the output style for printing ELF values. 2525088Sab196087 * 2535088Sab196087 * DEFAULT - Output is in 'elfdump' style, designed for human eyes. 2545088Sab196087 * Headers, and additional information are shown. 2555088Sab196087 * SIMPLE - Output is simple, consisting only of the target item. 2565088Sab196087 * Integer values are shown as symbolic constants when possible, 2575088Sab196087 * and integers otherwise. 2585088Sab196087 * NUM - Like SIMPLE, except integer values are always shown as 2595088Sab196087 * integer constants, and strings are shown as the integer 2605088Sab196087 * offset into the string table. 2615088Sab196087 */ 2625088Sab196087 typedef enum { 2635088Sab196087 ELFEDIT_OUTSTYLE_DEFAULT = 0, 2645088Sab196087 ELFEDIT_OUTSTYLE_SIMPLE = 1, 2655088Sab196087 ELFEDIT_OUTSTYLE_NUM = 2 2665088Sab196087 } elfedit_outstyle_t; 2675088Sab196087 2685088Sab196087 2695088Sab196087 /* 2705088Sab196087 * The elfedit_module_t, and the types it references, are defined 2715088Sab196087 * by loadable elfedit modules, and used by elfedit. These structures 2725088Sab196087 * need to communicate internationalized strings for elfedit to print. 2735088Sab196087 * 2745088Sab196087 * We want to leave the choice of internationalization APIs, as well as 2755088Sab196087 * the decision about whether or not to even to it to the individual 2765088Sab196087 * modules. Hence, we do not use a simple (const char *) pointer to 2775088Sab196087 * communicate potentially internationalized strings. Instead, we define 2785088Sab196087 * elfedit_i18nhdl_t, an opaque type guaranteed to be large enough 2795088Sab196087 * to hold a pointer. Each module casts the handle needed to access the 2805088Sab196087 * string to this type. Each module also supplies a function 2815088Sab196087 * (mod_i18nhdl_to_str field of elfedit_module_t) that given one 2825088Sab196087 * of these opaque keys, will return a (const char *) pointer to the 2835088Sab196087 * actual string, for elfedit to print. 2845088Sab196087 * 2855088Sab196087 * If the underlying module doesn't want to implement i18n support, 2865088Sab196087 * all it has to do is cast the strings to elfedit_i18nhdl_t and 2875088Sab196087 * back. 2885088Sab196087 */ 2895088Sab196087 typedef uintptr_t elfedit_i18nhdl_t; 2905088Sab196087 2915088Sab196087 2925088Sab196087 2935088Sab196087 /* 2945088Sab196087 * Macro to handle casting international string "handles" to the 2955088Sab196087 * elfedit_i18nhdl_t opaque type. 2965088Sab196087 */ 2975088Sab196087 #define ELFEDIT_I18NHDL(_i18n_str_ref) ((elfedit_i18nhdl_t)_i18n_str_ref) 2985088Sab196087 2995088Sab196087 3005088Sab196087 /* 3015088Sab196087 * Return values from command functions 3025088Sab196087 */ 3035088Sab196087 typedef enum { 3045088Sab196087 ELFEDIT_CMDRET_NONE = 0, /* Nothing to report */ 3055088Sab196087 ELFEDIT_CMDRET_MOD = 1, /* Command modified output ELF file */ 3069273SAli.Bahrami@Sun.COM ELFEDIT_CMDRET_MOD_OS_MACH = 2, /* As per _MOD, include ELF header */ 3079273SAli.Bahrami@Sun.COM /* osabi or machine change */ 3089273SAli.Bahrami@Sun.COM ELFEDIT_CMDRET_FLUSH = 3 /* Output file flushed: elf_update() */ 3095088Sab196087 } elfedit_cmdret_t; 3105088Sab196087 3115088Sab196087 /* 3125088Sab196087 * Prototype of an implementation function for an edit command. Note that 3135088Sab196087 * commands do not return a status: 3145088Sab196087 * - Success is indicated by a normal return. 3155088Sab196087 * - The command indicates a fatal error by calling elfedit_msg() with the 3165088Sab196087 * ELFEDIT_MSG_ERR type, in which case execution does not return 3175088Sab196087 * to the command, and the elfedit command loop knows that an 3185088Sab196087 * error occurred. 3195088Sab196087 * - The command is responsible for using the standard libelf 3205088Sab196087 * mechanisms to indicate when changes have been made to 3215088Sab196087 * the ELF file. 3225088Sab196087 */ 3235088Sab196087 typedef elfedit_cmdret_t elfedit32_cmd_func_t(elfedit32_obj_state_t *state, 3245088Sab196087 int argc, const char *argv[]); 3255088Sab196087 typedef elfedit_cmdret_t elfedit64_cmd_func_t(elfedit64_obj_state_t *state, 3265088Sab196087 int argc, const char *argv[]); 3275088Sab196087 #ifdef _ELF64 3285088Sab196087 #define elfedit_cmd_func_t elfedit64_cmd_func_t 3295088Sab196087 #else 3305088Sab196087 #define elfedit_cmd_func_t elfedit32_cmd_func_t 3315088Sab196087 #endif 3325088Sab196087 3335088Sab196087 3345088Sab196087 /* 3355088Sab196087 * An elfedit command (elfedit_cmd_t) has a cmd_cpl field that 3365088Sab196087 * can be set to a command completion function. If such a function 3375088Sab196087 * is present (non-NULL), and the user presses the tab key at the 3385088Sab196087 * command line while the cursor is at a plain (non option) argument, 3395088Sab196087 * elfedit calls the function, passing it all the tokens up through 3405088Sab196087 * the one needing completion. The function can use elfedit_cpl_match() 3415088Sab196087 * to enter possible alternatives. Additionally, there are helper 3425088Sab196087 * functions built on top of elfedit_cpl_match() that simplify common cases. 3435088Sab196087 * 3445088Sab196087 * elfedit_cpl_ato[iu]() - enter matches from elfedit_ato[iu]_sym_t 3455088Sab196087 * mappings. 3465088Sab196087 * elfedit_cpl_atoconst() - Enter matches for well known constants 3475088Sab196087 * elfedit_cpl_command() - enter matches for all known commands 3485088Sab196087 * elfedit_cpl_mod() - enter matches for all known modules. 3496225Sab196087 * elfedit_cpl_ndx() - enter numeric index as a match 3505088Sab196087 * 3515088Sab196087 * The completion function is passed the following arguments: 3525088Sab196087 * 3535088Sab196087 * obj_state - Object state. Will be NULL if elfedit session does not 3545088Sab196087 * have an active object. The completion function must test 3555088Sab196087 * the pointer before using it. 3565088Sab196087 * cpldata - Completion data, to be passed to elfedit_cpl_match() 3575088Sab196087 * or the helper functions built on it to register alternative 3585088Sab196087 * strings. 35911734SAli.Bahrami@Sun.COM * argc, argv - The tokens from the start of the line through 3605088Sab196087 * the one needing completion, which will always 3615088Sab196087 * be cmdcpl_argv[cmdcpl_argc - 1]. 3625088Sab196087 * num_opt - A count of the optional arguments (those starting with 3635088Sab196087 * '-' at the beginning of argv. This means that argv[num_opt] 3645088Sab196087 * is the first plain argument, and the 1-based positional 3655088Sab196087 * number of the plain argument for which command completion 3665088Sab196087 * is needed is (argc - num_opt). 3675088Sab196087 */ 3685088Sab196087 typedef void elfedit32_cmdcpl_func_t(elfedit32_obj_state_t *state, 3695088Sab196087 void *cpldata, int argc, const char *argv[], int num_opt); 3705088Sab196087 typedef void elfedit64_cmdcpl_func_t(elfedit64_obj_state_t *state, 3715088Sab196087 void *cpldata, int argc, const char *argv[], int num_opt); 3725088Sab196087 #ifdef _ELF64 3735088Sab196087 #define elfedit_cmdcpl_func_t elfedit64_cmdcpl_func_t 3745088Sab196087 #else 3755088Sab196087 #define elfedit_cmdcpl_func_t elfedit32_cmdcpl_func_t 3765088Sab196087 #endif 3775088Sab196087 3785088Sab196087 3795088Sab196087 3805088Sab196087 3815088Sab196087 /* 3825088Sab196087 * Command option/argument descriptor. These structures 3835088Sab196087 * are used to represent each option and plain argument accepted 3845088Sab196087 * by a command, via the cmd_opt and cmd_args fields in the 3855088Sab196087 * command definition (elfedit_cmd_t). Each descriptor consists 3865088Sab196087 * of a name, a help string (formatted for display via sys:help), 3875088Sab196087 * and a flags field that conveys extra information about the 3885088Sab196087 * item: 3895088Sab196087 * 3905088Sab196087 * ELFEDIT_CMDOA_F_OPT 3915088Sab196087 * The item is optional. This flag is implicit for options 3925088Sab196087 * and need only be set for plain arguments. 3935088Sab196087 * 3945088Sab196087 * ELFEDIT_CMDOA_F_VALUE 3955088Sab196087 * The item has a value, which is found in the following 3965088Sab196087 * item. This flag only has meaning for options, and should 3975088Sab196087 * not be set for plain arguments. The descriptor for the 3985088Sab196087 * value is found in the next array element, and only the 3995088Sab196087 * oa_name field is used (the other should be set t 0). 4005088Sab196087 * 4015088Sab196087 * ELFEDIT_CMDOA_F_MULT 4025088Sab196087 * More than one of the specified items may be specified 4035088Sab196087 * 4045088Sab196087 * ELFEDIT_CMDOA_F_INHERIT 4055088Sab196087 * This is an item for which a common definition exists. 4065088Sab196087 * Elfedit will substitute the standard values for the 4075088Sab196087 * name, help text, and flags. This enforces consistency 4085088Sab196087 * in documentation, plus it is easier for the module author. 4095088Sab196087 * When ELFEDIT_CMDOA_F_INHERIT is set: 4105088Sab196087 * - oa_name should be set to one of the ELFEDIT_STDOA_ 4115088Sab196087 * values to specifiy which standard item is being 4125088Sab196087 * inherited. 4135088Sab196087 * - oa_help must be set to NULL. 4145088Sab196087 * - It is an error to set any other flags with 4155088Sab196087 * ELFEDIT_CMDOA_F_INHERIT. 4165088Sab196087 * - oa_idmask and oa_excmask are used in the normal way. 4175088Sab196087 * 4185088Sab196087 * The oa_idmask and oa_excmask fields are used to identify options, 4195088Sab196087 * and to support mutual exclusion (when two or more options cannot be 4205088Sab196087 * used together). They are ignored for arguments, and should be set to 0. 4215088Sab196087 * oa_idmask is used to uniquely identify each item. When elfedit_getopt() 4225088Sab196087 * matches an option, it returns the value of oa_idmask to the caller to 4235088Sab196087 * indicate which option was matched. elfedit enforces the following rules 4245088Sab196087 * for oa_idmask, and will refuse to load a module that does not follow them: 4255088Sab196087 * - The value of oa_idmask must be 0, or have a value that 4265088Sab196087 * is a power of 2 (i.e. only has one bit set). 4275088Sab196087 * - Each item that sets a non-0 value for oa_idmask must have 4285088Sab196087 * a unique value. 4295088Sab196087 * - If oa_idmask is 0, oa_excmask must be 0 also. 4305088Sab196087 * - oa_excmask is set to 0 if an item is not mutually exclusive 4315088Sab196087 * to any other item. Otherwise, it should set the bit 4325088Sab196087 * values representing the items it is mutually exclusive to. 4335088Sab196087 * - An oa_idmask value of 0 can be used for any item that 4345088Sab196087 * the module does not need to identify, and which 4355088Sab196087 * is not mutually exclusive to any other item. 4365088Sab196087 * As elfedit_getopt() processes items, it maintains a bitmask combining the 4375088Sab196087 * oa_idmask fields of all the options already seen. For each option, it uses 4385088Sab196087 * oa_excmask to check for conflicts. 4395088Sab196087 * 4405088Sab196087 * note: elfedit enforces the rule that options consist of a '-' 4415088Sab196087 * character followed by at least one character when a module 4425088Sab196087 * is loaded. 4435088Sab196087 */ 4445088Sab196087 typedef enum { 4455088Sab196087 ELFEDIT_CMDOA_F_OPT = 1, /* Item is optional */ 4465088Sab196087 ELFEDIT_CMDOA_F_VALUE = 2, /* Item has a value arg following */ 4475088Sab196087 ELFEDIT_CMDOA_F_MULT = 4, /* More than one are allowed */ 4485088Sab196087 ELFEDIT_CMDOA_F_INHERIT = 8, /* Inherit definition: See above */ 4495088Sab196087 } elfedit_cmd_oa_flag_t; 4505088Sab196087 4515088Sab196087 typedef u_longlong_t elfedit_cmd_oa_mask_t; 4525088Sab196087 4535088Sab196087 typedef struct { 4545088Sab196087 const char *oa_name; /* Name of option */ 4555088Sab196087 elfedit_i18nhdl_t oa_help; /* Help text for option */ 4565088Sab196087 elfedit_cmd_oa_flag_t oa_flags; /* Additional attributes */ 4575088Sab196087 elfedit_cmd_oa_mask_t oa_idmask; /* Unique id, returned by */ 4585088Sab196087 /* elfedit_getopt */ 4595088Sab196087 /* for use by caller */ 4605088Sab196087 elfedit_cmd_oa_mask_t oa_excmask; /* Mutual exclusion mask */ 4615088Sab196087 } elfedit_cmd_optarg_t; 4625088Sab196087 4635088Sab196087 4645088Sab196087 4655088Sab196087 /* 4665088Sab196087 * These values define the standard options and arguments that a module 4675088Sab196087 * can inherit using the ELFEDIT_CMDOA_F_INHERIT flag (described above). 4685088Sab196087 * New items must be added at the end --- reordering the list will 4695088Sab196087 * require all modules to be rebuilt. 4705088Sab196087 * 4715088Sab196087 * Note: 0 cannot be used as a ELFEDIT_STDOA_ value, because a NULL 4725088Sab196087 * value of oa_name is used to terminate argument and options lists. 4735088Sab196087 * Therefore, these values start at 1. 4745088Sab196087 */ 4755088Sab196087 #define ELFEDIT_STDOA_OPT_O ((const char *) 1) /* -o ostyle */ 4765088Sab196087 #define ELFEDIT_STDOA_OPT_AND ((const char *) 2) /* -and */ 4775088Sab196087 #define ELFEDIT_STDOA_OPT_CMP ((const char *) 3) /* -cmp */ 4785088Sab196087 #define ELFEDIT_STDOA_OPT_OR ((const char *) 4) /* -or */ 4795088Sab196087 4805088Sab196087 #define ELFEDIT_NUM_STDOA 4 /* # of ELFEDIT_STDOA_ definitions */ 4815088Sab196087 4825088Sab196087 4835088Sab196087 4845088Sab196087 /* 4855088Sab196087 * Definition of a command 4865088Sab196087 * 4875088Sab196087 * This structure includes an elfedit_cmd_func_t pointer, which has 4885088Sab196087 * different definitions for different ELFCLASS. Rather than needlessly 4895088Sab196087 * complicate the code with three versions of this type, and any 4905088Sab196087 * type that uses it, we simply use the GenericClass type. elfedit 4915088Sab196087 * will always cast this to the correct type before calling a module. 4925088Sab196087 * 4935088Sab196087 * cmd_name is an array of pointers to the names for the command. 4945088Sab196087 * The "primary" name should always be first, followed by any alias 4955088Sab196087 * names. The final element of the array must be a NULL pointer, 4965088Sab196087 * which terminates the list. Every command is required to have at 4975088Sab196087 * least one name, so code is allowed to assume that the first element 4985088Sab196087 * of cmd_name is non-NULL, and contains the primary name. 4995088Sab196087 * 5005088Sab196087 * Many modules provide a "default" command, which is a command 5015088Sab196087 * that is run if only the module name is specified, followed 5025088Sab196087 * by a colon (i.e. "sym:"). The way this is implemented is to 5035088Sab196087 * give the desired default command an empty string as an alias. 5045088Sab196087 * Note that the primary name cannot be an empty string, only the 5055088Sab196087 * alias name. 5065088Sab196087 * 5075088Sab196087 * cmd_opts and cmd_args are each an array of elfedit_cmd_argdesc_t 5085088Sab196087 * structures, that describe the options and plain arguments accepted 5095088Sab196087 * by the command. These arrays are used to general help text for 5105088Sab196087 * the commands. The cmd_opts array is also used to provide command 5115088Sab196087 * completion for options. Both of these arrays are terminated by 5125088Sab196087 * a final NULL element (all fields zero). 5135088Sab196087 */ 5145088Sab196087 typedef struct { 5155088Sab196087 elfedit32_cmd_func_t *cmd_func; /* Implementation */ 5165088Sab196087 elfedit32_cmdcpl_func_t *cmd_cplfunc; /* Completion function */ 5175088Sab196087 const char **cmd_name; /* Cmd names (null term.) */ 5185088Sab196087 elfedit_i18nhdl_t cmd_desc; /* Short desc. of cmd purpose */ 5195088Sab196087 elfedit_i18nhdl_t cmd_help; /* Help text for the command */ 5205088Sab196087 elfedit_cmd_optarg_t *cmd_opt; /* Options */ 5215088Sab196087 elfedit_cmd_optarg_t *cmd_args; /* Plain arguments */ 5225088Sab196087 } elfedit32_cmd_t; 5235088Sab196087 5245088Sab196087 typedef struct { 5255088Sab196087 elfedit64_cmd_func_t *cmd_func; 5265088Sab196087 elfedit64_cmdcpl_func_t *cmd_cplfunc; 5275088Sab196087 const char **cmd_name; 5285088Sab196087 elfedit_i18nhdl_t cmd_desc; 5295088Sab196087 elfedit_i18nhdl_t cmd_help; 5305088Sab196087 elfedit_cmd_optarg_t *cmd_opt; 5315088Sab196087 elfedit_cmd_optarg_t *cmd_args; 5325088Sab196087 } elfedit64_cmd_t; 5335088Sab196087 5345088Sab196087 #ifdef _ELF64 5355088Sab196087 #define elfedit_cmd_t elfedit64_cmd_t 5365088Sab196087 #else 5375088Sab196087 #define elfedit_cmd_t elfedit32_cmd_t 5385088Sab196087 #endif 5395088Sab196087 5405088Sab196087 5415088Sab196087 5425088Sab196087 /* 5435088Sab196087 * elfedit modules version themselves so that we can alter the definition 5445088Sab196087 * of elfedit_module_t in a backward compatible way. 5455088Sab196087 */ 5465088Sab196087 typedef enum { 5475088Sab196087 ELFEDIT_VER_NONE = 0, 5485088Sab196087 ELFEDIT_VER_CURRENT = 1, 5495088Sab196087 ELFEDIT_VER_NUM = 2 5505088Sab196087 } elfedit_module_version_t; 5515088Sab196087 5525088Sab196087 5535088Sab196087 /* 5545088Sab196087 * Each module returns a pointer to an elfedit_module_t, describing 5555088Sab196087 * what commands the module provides. 5565088Sab196087 * 5575088Sab196087 * Note: mod_cmds is a NULL terminated array of command defs. This 5585088Sab196087 * means that the final element in the array should have all of its 5595088Sab196087 * fields set to NULL. 5605088Sab196087 * 5615088Sab196087 * The mod_i18nhdl_to_str function pointer is explained above 5625088Sab196087 * with the definition of elfedit_i18nhdl_t. 5635088Sab196087 */ 5645088Sab196087 typedef const char *(* elfedit_mod_i18nhdl_to_str_func_t)(elfedit_i18nhdl_t); 5655088Sab196087 5665088Sab196087 typedef struct { 5675088Sab196087 elfedit_module_version_t mod_version; /* version */ 5685088Sab196087 const char *mod_name; /* Name of module */ 5695088Sab196087 elfedit_i18nhdl_t mod_desc; /* Short desc. of mod purpose */ 5705088Sab196087 elfedit32_cmd_t *mod_cmds; /* Array of command defs */ 5715088Sab196087 /* i18n -> (char *) fcn */ 5725088Sab196087 elfedit_mod_i18nhdl_to_str_func_t mod_i18nhdl_to_str; 5735088Sab196087 } elfedit32_module_t; 5745088Sab196087 5755088Sab196087 typedef struct { 5765088Sab196087 elfedit_module_version_t mod_version; 5775088Sab196087 const char *mod_name; 5785088Sab196087 elfedit_i18nhdl_t mod_desc; 5795088Sab196087 elfedit64_cmd_t *mod_cmds; 5805088Sab196087 elfedit_mod_i18nhdl_to_str_func_t mod_i18nhdl_to_str; 5815088Sab196087 } elfedit64_module_t; 5825088Sab196087 5835088Sab196087 #ifdef _ELF64 5845088Sab196087 #define elfedit_module_t elfedit64_module_t 5855088Sab196087 #else 5865088Sab196087 #define elfedit_module_t elfedit32_module_t 5875088Sab196087 #endif 5885088Sab196087 5895088Sab196087 5905088Sab196087 /* 5915088Sab196087 * Each module is a sharable library, expected to provide a single global 5925088Sab196087 * function, named elfedit_init(), with the following prototype. 5935088Sab196087 */ 5945088Sab196087 typedef elfedit_module_t *elfedit_init_func_t(elfedit_module_version_t version); 5955088Sab196087 5965088Sab196087 5975892Sab196087 /* 5985892Sab196087 * Prototype for elfedit_write(), and for outfunc argument 5995892Sab196087 * to elfedit_str_to_c_literal(). 6005892Sab196087 */ 6015892Sab196087 typedef void elfedit_write_func_t(const void *ptr, size_t size); 6025088Sab196087 6035088Sab196087 6045088Sab196087 /* 6055088Sab196087 * Core elfedit functions exported for use by modules 6065088Sab196087 */ 6075088Sab196087 extern void elfedit_command_usage(void); 6085088Sab196087 extern void elfedit_cpl_command(void *cpldata); 6095088Sab196087 extern void elfedit_cpl_match(void *cpldata, const char *str, int casefold); 6106225Sab196087 extern void elfedit_cpl_ndx(void *cpldata, uint_t ndx); 6115088Sab196087 extern void elfedit_elferr(const char *file, const char *libelf_rtn_name); 6125088Sab196087 extern elfedit_flag_t elfedit_flags(void); 6135088Sab196087 extern void *elfedit_malloc(const char *item_name, size_t size); 6145088Sab196087 extern void elfedit_msg(elfedit_msg_t type, const char *format, ...); 6155088Sab196087 extern elfedit_outstyle_t elfedit_outstyle(void); 6165088Sab196087 extern void elfedit_pager_init(void); 6175088Sab196087 extern void elfedit_printf(const char *format, ...); 6185088Sab196087 extern void *elfedit_realloc(const char *item_name, void *ptr, size_t size); 6195892Sab196087 extern void elfedit_str_to_c_literal(const char *str, 6205892Sab196087 elfedit_write_func_t *outfunc); 6215892Sab196087 extern elfedit_write_func_t elfedit_write; 6225088Sab196087 6235088Sab196087 /* 6245088Sab196087 * Core elfedit functions exported for use by sys: module only 6255088Sab196087 */ 6265088Sab196087 extern void elfedit_cpl_module(void *cpldata, int load_all_modules); 6275088Sab196087 6285088Sab196087 6295088Sab196087 /* 6305088Sab196087 * elfedit modules are expected to define two functions, one for 6315088Sab196087 * each ELFCLASS. Define a generic name for this function, based on 6325088Sab196087 * the class being supported by the including module. 6335088Sab196087 */ 6345088Sab196087 #ifdef _ELF64 6355088Sab196087 #define elfedit_init elfedit64_init 6365088Sab196087 #else 6375088Sab196087 #define elfedit_init elfedit32_init 6385088Sab196087 #endif 6395088Sab196087 6405088Sab196087 6415088Sab196087 6425088Sab196087 /* 6435088Sab196087 * It is common to search the dynamic section for specific elements. 6445088Sab196087 * Structures of this type are used to represent the contents of such 6455088Sab196087 * elements in a systematic way. The elfedit_dyn_elt_init() function 6465088Sab196087 * is used to prepare these strucutres for use. 6475088Sab196087 */ 6485088Sab196087 typedef struct { 6495088Sab196087 int dn_seen; /* True if this item has been seen */ 6505088Sab196087 Elf32_Word dn_ndx; /* Index of item in dynamic array */ 6515088Sab196087 Elf32_Dyn dn_dyn; /* Contents of dynamic item */ 6525088Sab196087 } elfedit32_dyn_elt_t; 6535088Sab196087 6545088Sab196087 typedef struct { 6555088Sab196087 int dn_seen; 6565088Sab196087 Elf64_Word dn_ndx; 6575088Sab196087 Elf64_Dyn dn_dyn; 6585088Sab196087 } elfedit64_dyn_elt_t; 6595088Sab196087 6605088Sab196087 #ifdef _ELF64 6615088Sab196087 #define elfedit_dyn_elt_t elfedit64_dyn_elt_t 6625088Sab196087 #else 6635088Sab196087 #define elfedit_dyn_elt_t elfedit32_dyn_elt_t 6645088Sab196087 #endif 6655088Sab196087 6665088Sab196087 /* 6675088Sab196087 * The elfedit_atoi() and elfedit_atoui() functions can optionally 6685088Sab196087 * accept an array of these structures, giving symbolic names that 6695088Sab196087 * will be accepted instead of numeric codes. If such an array is 6705088Sab196087 * present, the supplied string has it's leading and trailing whitespace 6715088Sab196087 * removed and is then compared to the list, and if there is a match, 6725088Sab196087 * the corresponding integer value is returned. 6735088Sab196087 * 6745088Sab196087 * The final array element must have its name field set to NULL. 6755088Sab196087 */ 6765088Sab196087 typedef u_longlong_t elfedit_atoui_t; 6775088Sab196087 typedef struct { 6785088Sab196087 const char *sym_name; 6795088Sab196087 elfedit_atoui_t sym_value; 6805088Sab196087 } elfedit_atoui_sym_t; 6815088Sab196087 typedef longlong_t elfedit_atoi_t; 6825088Sab196087 typedef struct { 6835088Sab196087 const char *sym_name; 6845088Sab196087 elfedit_atoi_t sym_value; 6855088Sab196087 } elfedit_atoi_sym_t; 6865088Sab196087 6875088Sab196087 6885088Sab196087 /* 6895088Sab196087 * The elfedit_atoconst*() functions are built on top of the atoui routines. 6905088Sab196087 * These routines accept an elfedit_const_t code instead of a 6915088Sab196087 * pointer to an elfedit_atoui_sym_t array, and use internally 6925088Sab196087 * predefined tables of elfedit_atoui_sym_t in order to do the desired 6935088Sab196087 * mappings. elfedit modules are encouraged to use these standard 6945088Sab196087 * tables instead of defining their own elfedit_atoui_sym_t arrays. 6955088Sab196087 * 6965088Sab196087 * note: 6975088Sab196087 * - The values assigned here must be in agreement with the 6985088Sab196087 * sym_table[] array defined in elfconst.c. 6995088Sab196087 * - Once defined, these values must not change. Reordering the 7005088Sab196087 * list will require all modules to be rebuilt, and will 7015088Sab196087 * break backward compatability. New items should be 7025088Sab196087 * added to the end. 7035088Sab196087 */ 7045088Sab196087 typedef enum { 7055088Sab196087 ELFEDIT_CONST_OUTSTYLE = 0, /* elfedit output styles */ 7065088Sab196087 ELFEDIT_CONST_OUTSTYLE_MO = 1, /* ostyles with -o prefix */ 7075088Sab196087 ELFEDIT_CONST_BOOL = 2, /* boolean names */ 7089273SAli.Bahrami@Sun.COM ELFEDIT_CONST_SHT_STRTAB = 3, /* ELF SHT_STRTAB */ 7099273SAli.Bahrami@Sun.COM ELFEDIT_CONST_SHT_SYMTAB = 4, /* ELF SHT_SYMTAB */ 7109273SAli.Bahrami@Sun.COM ELFEDIT_CONST_SHT_DYNSYM = 5, /* ELF SHT_DYNSYM */ 7119273SAli.Bahrami@Sun.COM ELFEDIT_CONST_SHT_LDYNSYM = 6, /* ELF SHT_SUNW_LDYNSYM */ 7129273SAli.Bahrami@Sun.COM ELFEDIT_CONST_SHN = 7, /* ELF SHN_ section indexes */ 7139273SAli.Bahrami@Sun.COM ELFEDIT_CONST_SHT = 8, /* ELF SHT_ section types */ 7149273SAli.Bahrami@Sun.COM ELFEDIT_CONST_SHT_ALLSYMTAB = 9, /* ELF SHT_ symbol table */ 7155088Sab196087 /* section types */ 7165088Sab196087 ELFEDIT_CONST_DT = 10, /* Dynamic tags: DT_ */ 7175088Sab196087 ELFEDIT_CONST_DF = 11, /* DT_FLAGS bits */ 7185088Sab196087 ELFEDIT_CONST_DF_P1 = 12, /* DF_POSFLAG_1 bits */ 7195088Sab196087 ELFEDIT_CONST_DF_1 = 13, /* DT_FLAGS_1 bits */ 7205088Sab196087 ELFEDIT_CONST_DTF_1 = 14, /* DT_FEATURE_1 bits */ 7215088Sab196087 ELFEDIT_CONST_EI = 15, /* ELF header e_ident indexes */ 7225088Sab196087 ELFEDIT_CONST_ET = 16, /* Ehdr obj type */ 7235088Sab196087 ELFEDIT_CONST_ELFCLASS = 17, /* Ehdr wordsize (32,64) */ 7245088Sab196087 ELFEDIT_CONST_ELFDATA = 18, /* Ehdr endian */ 7255088Sab196087 ELFEDIT_CONST_EF = 19, /* Ehdr flags */ 7265088Sab196087 ELFEDIT_CONST_EV = 20, /* Ehdr version */ 7275088Sab196087 ELFEDIT_CONST_EM = 21, /* Ehdr machine */ 7285088Sab196087 ELFEDIT_CONST_ELFOSABI = 22, /* Ehdr ABI */ 7299273SAli.Bahrami@Sun.COM ELFEDIT_CONST_EAV = 23, /* Ehdr ABI version */ 7309273SAli.Bahrami@Sun.COM ELFEDIT_CONST_PT = 24, /* Phdr type */ 7319273SAli.Bahrami@Sun.COM ELFEDIT_CONST_PF = 25, /* Phdr flags */ 7329273SAli.Bahrami@Sun.COM ELFEDIT_CONST_SHF = 26, /* Shdr flags */ 7339273SAli.Bahrami@Sun.COM ELFEDIT_CONST_STB = 27, /* Sym binding */ 7349273SAli.Bahrami@Sun.COM ELFEDIT_CONST_STT = 28, /* Sym type */ 7359273SAli.Bahrami@Sun.COM ELFEDIT_CONST_STV = 29, /* Sym visibility */ 7369273SAli.Bahrami@Sun.COM ELFEDIT_CONST_SYMINFO_BT = 30, /* Syminfo boundto */ 7379273SAli.Bahrami@Sun.COM ELFEDIT_CONST_SYMINFO_FLG = 31, /* Syminfo flags */ 7389273SAli.Bahrami@Sun.COM ELFEDIT_CONST_CA = 32, /* Capabilities tags */ 739*11827SRod.Evans@Sun.COM ELFEDIT_CONST_HW1_SUNW = 33, /* hardware capabilities */ 7405088Sab196087 ELFEDIT_CONST_SF1_SUNW = 34, /* software capabilities */ 741*11827SRod.Evans@Sun.COM ELFEDIT_CONST_HW2_SUNW = 35, /* hardware capabilities */ 7429273SAli.Bahrami@Sun.COM 743*11827SRod.Evans@Sun.COM ELFEDIT_CONST_NUM = 36, /* # of constant types */ 7445088Sab196087 } elfedit_const_t; 7455088Sab196087 7465088Sab196087 /* 7475088Sab196087 * Given an elfedit_const_t, return the array of elfedit_atoui_sym_t 7485088Sab196087 * entries that it represents. 7495088Sab196087 */ 7505088Sab196087 extern elfedit_atoui_sym_t *elfedit_const_to_atoui(elfedit_const_t const_type); 7515088Sab196087 7525088Sab196087 /* 7535088Sab196087 * ato[u]i and const routines, used to turn strings into numeric values, 7545088Sab196087 * with support for mapping symbol names to numbers, and range checking. 7555088Sab196087 */ 7565088Sab196087 extern elfedit_atoi_t elfedit_atoi(const char *str, 7575088Sab196087 const elfedit_atoi_sym_t *sym); 7585088Sab196087 extern elfedit_atoui_t elfedit_atoui(const char *str, 7595088Sab196087 const elfedit_atoui_sym_t *sym); 7605088Sab196087 extern elfedit_atoui_t elfedit_atoconst(const char *str, 7615088Sab196087 elfedit_const_t const_type); 7625088Sab196087 7635088Sab196087 extern int elfedit_atoi2(const char *str, const elfedit_atoi_sym_t *sym, 7645088Sab196087 elfedit_atoi_t *v); 7655088Sab196087 extern int elfedit_atoui2(const char *str, const elfedit_atoui_sym_t *sym, 7665088Sab196087 elfedit_atoui_t *); 7675088Sab196087 extern int elfedit_atoconst2(const char *str, elfedit_const_t const_type, 7685088Sab196087 elfedit_atoui_t *); 7695088Sab196087 7705088Sab196087 extern elfedit_atoi_t elfedit_atoi_range(const char *str, 7715088Sab196087 const char *item_name, elfedit_atoi_t min, elfedit_atoi_t max, 7725088Sab196087 const elfedit_atoi_sym_t *sym); 7735088Sab196087 extern elfedit_atoui_t elfedit_atoui_range(const char *str, 7745088Sab196087 const char *item_name, elfedit_atoui_t min, elfedit_atoui_t max, 7755088Sab196087 const elfedit_atoui_sym_t *sym); 7765088Sab196087 extern elfedit_atoui_t elfedit_atoconst_range(const char *str, 7775088Sab196087 const char *item_name, elfedit_atoui_t min, elfedit_atoui_t max, 7785088Sab196087 elfedit_const_t const_type); 7795088Sab196087 7805088Sab196087 extern int elfedit_atoi_range2(const char *str, elfedit_atoi_t min, 7815088Sab196087 elfedit_atoi_t max, const elfedit_atoi_sym_t *sym, elfedit_atoi_t *v); 7825088Sab196087 extern int elfedit_atoui_range2(const char *str, elfedit_atoui_t min, 7835088Sab196087 elfedit_atoui_t max, const elfedit_atoui_sym_t *sym, elfedit_atoui_t *v); 7845088Sab196087 extern int elfedit_atoconst_range2(const char *str, elfedit_atoui_t min, 7855088Sab196087 elfedit_atoui_t max, elfedit_const_t const_type, elfedit_atoui_t *v); 7865088Sab196087 7875088Sab196087 extern const char *elfedit_atoi_value_to_str(const elfedit_atoi_sym_t *sym, 7885088Sab196087 elfedit_atoi_t value, int required); 7895088Sab196087 extern const char *elfedit_atoui_value_to_str(const elfedit_atoui_sym_t *sym, 7905088Sab196087 elfedit_atoui_t value, int required); 7915088Sab196087 extern const char *elfedit_atoconst_value_to_str(elfedit_const_t const_type, 7925088Sab196087 elfedit_atoui_t value, int required); 7935088Sab196087 7945088Sab196087 extern void elfedit_cpl_atoi(void *cpldata, const elfedit_atoi_sym_t *sym); 7955088Sab196087 extern void elfedit_cpl_atoui(void *cpldata, const elfedit_atoui_sym_t *sym); 7965088Sab196087 extern void elfedit_cpl_atoconst(void *cpldata, elfedit_const_t const_type); 7975088Sab196087 7985088Sab196087 7995088Sab196087 /* 8005088Sab196087 * Convenience functions built on top of the ato[u]i routines. 8015088Sab196087 */ 8025088Sab196087 extern int elfedit_atobool(const char *str, const char *item_name); 8035088Sab196087 extern elfedit_atoui_t elfedit_atoshndx(const char *str, size_t shnum); 8045088Sab196087 8055088Sab196087 8065088Sab196087 /* 8075088Sab196087 * elfedit provides a getopt utility for use by the module commands. 8085088Sab196087 * elfedit_getopt_state_t is the state block used by elfedit_getopt(). 8095088Sab196087 * elfedit_getopt_ret_t is the definition of the values returned to 8105088Sab196087 * the user by elfedit_getopt() when an option is matched. Elfedit 8115088Sab196087 * getopt processing is done as follows: 8125088Sab196087 * 8135088Sab196087 * 1) The caller initializes an elfedit_getopt_state_t struct via 8145088Sab196087 * a call to elfedit_getopt_init(). The contents of this structure 8155088Sab196087 * must not be accessed by the caller, as they are all private and 8165088Sab196087 * subject to change. 8175088Sab196087 * 2) Repeated calls are made to elfedit_getopt(), as long as it returns 8185088Sab196087 * a non-NULL pointer to an elfedit_getopt_ret_t structure. If the 8195088Sab196087 * matched option has a value (ELFEDIT_CMDOA_F_VALUE), then the gor_value 8205088Sab196087 * field contains the pointer to the string. Otherwise, gor_value is NULL. 8215088Sab196087 * 3) As elfedit_getopt() consumes optional arguments from the argc/argv 8225088Sab196087 * passed to elfedit_getopt_init(), it adjusts argc/argc to skip over 8235088Sab196087 * them. Once elfedit_getopt() returns NULL to indicate that there are no 8245088Sab196087 * more options to match, argc/argv have been adjusted so that they 8255088Sab196087 * reference the plain arguments. 8265088Sab196087 */ 8275088Sab196087 typedef struct { 8285088Sab196087 elfedit_cmd_oa_mask_t gor_idmask; /* oa_idmask from matching */ 8295088Sab196087 /* elfedit_cmd_optarg_t. Can be */ 8305088Sab196087 /* used to quickly identify opt */ 8315088Sab196087 const char *gor_value; /* Opt value if ELFEDIT_CMDOA_F_VALUE */ 8325088Sab196087 /* Otherwise, NULL */ 8335088Sab196087 } elfedit_getopt_ret_t; 8345088Sab196087 typedef struct { 8355088Sab196087 int *go_argc; /* Pointer to # of options */ 8365088Sab196087 const char ***go_argv; /* Ptr to array of opt strs */ 8375088Sab196087 elfedit_cmd_optarg_t *go_optarg; /* Array of allowed options */ 8385088Sab196087 elfedit_cmd_oa_mask_t go_idmask; /* Combined id masks of all */ 8395088Sab196087 /* seen options */ 8405088Sab196087 int go_done; /* True if last option seen */ 8415088Sab196087 const char *go_sglgrp; /* Group of 1-letter opts */ 8425088Sab196087 elfedit_getopt_ret_t go_ret; /* Data returned to user */ 8435088Sab196087 } elfedit_getopt_state_t; 8445088Sab196087 8455088Sab196087 8465088Sab196087 8475088Sab196087 /* 8485088Sab196087 * getopt related routines 8495088Sab196087 */ 8505088Sab196087 extern void elfedit_getopt_init(elfedit_getopt_state_t *, 8515088Sab196087 int *, const char ***); 8525088Sab196087 extern elfedit_getopt_ret_t *elfedit_getopt(elfedit_getopt_state_t *); 8535088Sab196087 8545088Sab196087 8555088Sab196087 8565088Sab196087 /* 8575088Sab196087 * Additional utility functions exported for use by modules 8585088Sab196087 */ 8595088Sab196087 extern void elfedit_array_elts_delete(const char *name_str, void *data_start, 8605088Sab196087 size_t entsize, size_t num_ent, size_t start_ndx, size_t cnt); 8615088Sab196087 8625088Sab196087 extern void elfedit_array_elts_move(const char *name_str, void *data_start, 8635088Sab196087 size_t entsize, size_t num_ent, size_t srcndx, 8645088Sab196087 size_t dstndx, size_t cnt, void *scr_item); 8655088Sab196087 8665088Sab196087 extern int elfedit_bits_set(u_longlong_t v, int sizeof_orig_v); 8675088Sab196087 8685088Sab196087 extern void elfedit32_dyn_elt_init(elfedit32_dyn_elt_t *dyn_elt); 8695088Sab196087 extern void elfedit64_dyn_elt_init(elfedit64_dyn_elt_t *dyn_elt); 8705088Sab196087 8715088Sab196087 extern void elfedit32_dyn_elt_save(elfedit32_dyn_elt_t *elt, Elf32_Word ndx, 8725088Sab196087 Elf32_Dyn *dyn); 8735088Sab196087 extern void elfedit64_dyn_elt_save(elfedit64_dyn_elt_t *elt, Elf64_Word ndx, 8745088Sab196087 Elf64_Dyn *dyn); 8755088Sab196087 8765088Sab196087 const char *elfedit32_dyn_offset_to_str(elfedit32_section_t *strsec, 8775088Sab196087 elfedit32_dyn_elt_t *dynelt); 8785088Sab196087 const char *elfedit64_dyn_offset_to_str(elfedit64_section_t *strsec, 8795088Sab196087 elfedit64_dyn_elt_t *dynelt); 8805088Sab196087 8819273SAli.Bahrami@Sun.COM extern int elfedit32_dynstr_getpad(elfedit32_obj_state_t *obj_state, 8829273SAli.Bahrami@Sun.COM elfedit32_section_t *dynsec, elfedit32_dyn_elt_t *dyn_strpad); 8839273SAli.Bahrami@Sun.COM extern int elfedit64_dynstr_getpad(elfedit64_obj_state_t *obj_state, 8849273SAli.Bahrami@Sun.COM elfedit64_section_t *dynsec, elfedit64_dyn_elt_t *dyn_strpad); 8855088Sab196087 8865088Sab196087 extern Elf32_Word elfedit32_dynstr_insert(elfedit32_section_t *dynsec, 8875088Sab196087 elfedit32_section_t *strsec, elfedit32_dyn_elt_t *dyn_strpad, 8885088Sab196087 const char *str); 8895088Sab196087 extern Elf64_Word elfedit64_dynstr_insert(elfedit64_section_t *dynsec, 8905088Sab196087 elfedit64_section_t *strsec, elfedit64_dyn_elt_t *dyn_strpad, 8915088Sab196087 const char *str); 8925088Sab196087 8935088Sab196087 extern void elfedit32_modified_data(elfedit32_section_t *s); 8945088Sab196087 extern void elfedit64_modified_data(elfedit64_section_t *s); 8955088Sab196087 8965088Sab196087 extern void elfedit32_modified_ehdr(elfedit32_obj_state_t *obj_state); 8975088Sab196087 extern void elfedit64_modified_ehdr(elfedit64_obj_state_t *obj_state); 8985088Sab196087 8995088Sab196087 extern void elfedit32_modified_phdr(elfedit32_obj_state_t *obj_state); 9005088Sab196087 extern void elfedit64_modified_phdr(elfedit64_obj_state_t *obj_state); 9015088Sab196087 9025088Sab196087 extern void elfedit32_modified_shdr(elfedit32_section_t *s); 9035088Sab196087 extern void elfedit64_modified_shdr(elfedit64_section_t *s); 9045088Sab196087 9055088Sab196087 extern Elf32_Word elfedit32_name_to_shndx(elfedit32_obj_state_t *obj_state, 9065088Sab196087 const char *shnam); 9075088Sab196087 extern Elf64_Word elfedit64_name_to_shndx(elfedit64_obj_state_t *obj_state, 9085088Sab196087 const char *shnam); 9095088Sab196087 9105088Sab196087 extern int elfedit32_name_to_symndx(elfedit32_section_t *symsec, 9115088Sab196087 elfedit32_section_t *strsec, const char *name, elfedit_msg_t msg_type, 9125088Sab196087 Elf32_Word *ret_symndx); 9135088Sab196087 extern int elfedit64_name_to_symndx(elfedit64_section_t *symsec, 9145088Sab196087 elfedit64_section_t *strsec, const char *name, elfedit_msg_t msg_type, 9155088Sab196087 Elf64_Word *ret_symndx); 9165088Sab196087 9175088Sab196087 extern const char *elfedit32_offset_to_str(elfedit32_section_t *strsec, 9185088Sab196087 Elf32_Word offset, elfedit_msg_t msg_type, int debug_msg); 9195088Sab196087 extern const char *elfedit64_offset_to_str(elfedit64_section_t *strsec, 9205088Sab196087 Elf64_Word offset, elfedit_msg_t msg_type, int debug_msg); 9215088Sab196087 9225088Sab196087 extern int elfedit32_sec_findstr(elfedit32_section_t *sec, Elf32_Word tail_ign, 9235088Sab196087 const char *str, Elf32_Word *ret_offset); 9245088Sab196087 extern int elfedit64_sec_findstr(elfedit64_section_t *sec, Elf64_Word tail_ign, 9255088Sab196087 const char *str, Elf64_Word *ret_offset); 9265088Sab196087 9275892Sab196087 extern elfedit32_section_t *elfedit32_sec_get( 9285892Sab196087 elfedit32_obj_state_t *obj_state, Elf32_Word shndx); 9295892Sab196087 extern elfedit64_section_t *elfedit64_sec_get( 9305892Sab196087 elfedit64_obj_state_t *obj_state, Elf64_Word shndx); 9315892Sab196087 9325088Sab196087 extern elfedit32_section_t *elfedit32_sec_getcap( 9335088Sab196087 elfedit32_obj_state_t *obj_state, Elf32_Cap **cap, Elf32_Word *num); 9345088Sab196087 extern elfedit64_section_t *elfedit64_sec_getcap( 9355088Sab196087 elfedit64_obj_state_t *obj_state, Elf64_Cap **cap, Elf64_Word *num); 9365088Sab196087 9375088Sab196087 extern elfedit32_section_t *elfedit32_sec_getdyn( 9385088Sab196087 elfedit32_obj_state_t *obj_state, Elf32_Dyn **dyn, Elf32_Word *num); 9395088Sab196087 extern elfedit64_section_t *elfedit64_sec_getdyn( 9405088Sab196087 elfedit64_obj_state_t *obj_state, Elf64_Dyn **dyn, Elf64_Word *num); 9415088Sab196087 9425088Sab196087 extern elfedit32_section_t *elfedit32_sec_getstr( 9436225Sab196087 elfedit32_obj_state_t *obj_state, Elf32_Word shndx, int); 9445088Sab196087 extern elfedit64_section_t *elfedit64_sec_getstr( 9456225Sab196087 elfedit64_obj_state_t *obj_state, Elf64_Word shndx, int); 9465088Sab196087 9475088Sab196087 extern elfedit32_section_t *elfedit32_sec_getsyminfo( 9485088Sab196087 elfedit32_obj_state_t *obj_state, Elf32_Syminfo **syminfo, Elf32_Word *num); 9495088Sab196087 extern elfedit64_section_t *elfedit64_sec_getsyminfo( 9505088Sab196087 elfedit64_obj_state_t *obj_state, Elf64_Syminfo **syminfo, Elf64_Word *num); 9515088Sab196087 9525088Sab196087 extern elfedit32_section_t *elfedit32_sec_getsymtab( 9535088Sab196087 elfedit32_obj_state_t *obj_state, int by_index, Elf32_Word index, 9545088Sab196087 const char *name, Elf32_Sym **sym, Elf32_Word *num, 9555088Sab196087 elfedit32_symtab_t **aux_info); 9565088Sab196087 extern elfedit64_section_t *elfedit64_sec_getsymtab( 9575088Sab196087 elfedit64_obj_state_t *obj_state, int by_index, Elf64_Word index, 9585088Sab196087 const char *name, Elf64_Sym **sym, Elf64_Word *num, 9595088Sab196087 elfedit64_symtab_t **aux_info); 9605088Sab196087 9615088Sab196087 extern elfedit32_section_t *elfedit32_sec_getversym( 9625088Sab196087 elfedit32_obj_state_t *obj_state, elfedit32_section_t *symsec, 9635088Sab196087 Elf32_Versym **versym, Elf32_Word *num); 9645088Sab196087 extern elfedit64_section_t *elfedit64_sec_getversym( 9655088Sab196087 elfedit64_obj_state_t *obj_state, elfedit64_section_t *symsec, 9665088Sab196087 Elf64_Versym **versym, Elf64_Word *num); 9675088Sab196087 9685088Sab196087 extern elfedit32_section_t *elfedit32_sec_getxshndx( 9695088Sab196087 elfedit32_obj_state_t *obj_state, elfedit32_section_t *symsec, 9705088Sab196087 Elf32_Word **xshndx, Elf32_Word *num); 9715088Sab196087 extern elfedit64_section_t *elfedit64_sec_getxshndx( 9725088Sab196087 elfedit64_obj_state_t *obj_state, elfedit64_section_t *symsec, 9735088Sab196087 Elf64_Word **xshndx, Elf64_Word *num); 9745088Sab196087 9759273SAli.Bahrami@Sun.COM extern int elfedit32_sec_issymtab(elfedit32_obj_state_t *obj_state, 9769273SAli.Bahrami@Sun.COM elfedit32_section_t *sec, int issue_err, elfedit_atoui_sym_t **atoui_list); 9779273SAli.Bahrami@Sun.COM extern int elfedit64_sec_issymtab(elfedit64_obj_state_t *obj_state, 9789273SAli.Bahrami@Sun.COM elfedit64_section_t *sec, int issue_err, elfedit_atoui_sym_t **atoui_list); 9795088Sab196087 9805088Sab196087 extern const char *elfedit32_sec_msgprefix(elfedit32_section_t *sec); 9815088Sab196087 extern const char *elfedit64_sec_msgprefix(elfedit64_section_t *sec); 9825088Sab196087 9835088Sab196087 extern const char *elfedit32_shndx_to_name(elfedit32_obj_state_t *obj_state, 9845088Sab196087 Elf32_Word shndx); 9855088Sab196087 extern const char *elfedit64_shndx_to_name(elfedit64_obj_state_t *obj_state, 9865088Sab196087 Elf64_Word shndx); 9875088Sab196087 9885088Sab196087 extern Elf32_Word elfedit32_strtab_insert(elfedit32_obj_state_t *obj_state, 9895088Sab196087 elfedit32_section_t *strsec, elfedit32_section_t *dynsec, const char *str); 9905088Sab196087 extern Elf64_Word elfedit64_strtab_insert(elfedit64_obj_state_t *obj_state, 9915088Sab196087 elfedit64_section_t *strsec, elfedit64_section_t *dynsec, const char *str); 9925088Sab196087 9935088Sab196087 extern void elfedit32_strtab_insert_test(elfedit32_obj_state_t *obj_state, 9945088Sab196087 elfedit32_section_t *strsec, elfedit32_section_t *dynsec, const char *str); 9955088Sab196087 extern void elfedit64_strtab_insert_test(elfedit64_obj_state_t *obj_state, 9965088Sab196087 elfedit64_section_t *strsec, elfedit64_section_t *dynsec, const char *str); 9975088Sab196087 9989273SAli.Bahrami@Sun.COM extern int elfedit32_test_osabi(elfedit32_obj_state_t *obj_state, uchar_t osabi, 9999273SAli.Bahrami@Sun.COM int issue_err); 10009273SAli.Bahrami@Sun.COM extern int elfedit64_test_osabi(elfedit64_obj_state_t *obj_state, uchar_t osabi, 10019273SAli.Bahrami@Sun.COM int issue_err); 10029273SAli.Bahrami@Sun.COM 10035088Sab196087 extern Elf32_Word elfedit32_type_to_shndx(elfedit32_obj_state_t *obj_state, 10045088Sab196087 Elf32_Word shtype); 10055088Sab196087 extern Elf64_Word elfedit64_type_to_shndx(elfedit64_obj_state_t *obj_state, 10065088Sab196087 Elf64_Word shtype); 10075088Sab196087 10085088Sab196087 10095088Sab196087 10105088Sab196087 /* 10115088Sab196087 * Map the generic names for each of the ELFCLASS specific routines 10125088Sab196087 * above to reference the proper routine for the current compilation. 10135088Sab196087 */ 10145088Sab196087 #ifdef _ELF64 10155088Sab196087 #define elfedit_dyn_elt_init elfedit64_dyn_elt_init 10165088Sab196087 #define elfedit_dyn_elt_save elfedit64_dyn_elt_save 10175088Sab196087 #define elfedit_dyn_offset_to_str elfedit64_dyn_offset_to_str 10185088Sab196087 #define elfedit_dynstr_getpad elfedit64_dynstr_getpad 10195088Sab196087 #define elfedit_dynstr_insert elfedit64_dynstr_insert 10205088Sab196087 #define elfedit_modified_data elfedit64_modified_data 10215088Sab196087 #define elfedit_modified_ehdr elfedit64_modified_ehdr 10225088Sab196087 #define elfedit_modified_phdr elfedit64_modified_phdr 10235088Sab196087 #define elfedit_modified_shdr elfedit64_modified_shdr 10245088Sab196087 #define elfedit_name_to_shndx elfedit64_name_to_shndx 10255088Sab196087 #define elfedit_name_to_symndx elfedit64_name_to_symndx 10265088Sab196087 #define elfedit_offset_to_str elfedit64_offset_to_str 10275088Sab196087 #define elfedit_sec_findstr elfedit64_sec_findstr 10285892Sab196087 #define elfedit_sec_get elfedit64_sec_get 10295088Sab196087 #define elfedit_sec_getcap elfedit64_sec_getcap 10305088Sab196087 #define elfedit_sec_getdyn elfedit64_sec_getdyn 10315088Sab196087 #define elfedit_sec_getstr elfedit64_sec_getstr 10325088Sab196087 #define elfedit_sec_getsyminfo elfedit64_sec_getsyminfo 10335088Sab196087 #define elfedit_sec_getsymtab elfedit64_sec_getsymtab 10345088Sab196087 #define elfedit_sec_getversym elfedit64_sec_getversym 10355088Sab196087 #define elfedit_sec_getxshndx elfedit64_sec_getxshndx 10365088Sab196087 #define elfedit_sec_issymtab elfedit64_sec_issymtab 10375088Sab196087 #define elfedit_shndx_to_name elfedit64_shndx_to_name 10385088Sab196087 #define elfedit_sec_msgprefix elfedit64_sec_msgprefix 10395088Sab196087 #define elfedit_strtab_insert elfedit64_strtab_insert 10405088Sab196087 #define elfedit_strtab_insert_test elfedit64_strtab_insert_test 10419273SAli.Bahrami@Sun.COM #define elfedit_test_osabi elfedit64_test_osabi 10425088Sab196087 #define elfedit_type_to_shndx elfedit64_type_to_shndx 10435088Sab196087 #else 10445088Sab196087 #define elfedit_dyn_elt_init elfedit32_dyn_elt_init 10455088Sab196087 #define elfedit_dyn_elt_save elfedit32_dyn_elt_save 10465088Sab196087 #define elfedit_dyn_offset_to_str elfedit32_dyn_offset_to_str 10475088Sab196087 #define elfedit_dynstr_getpad elfedit32_dynstr_getpad 10485088Sab196087 #define elfedit_dynstr_insert elfedit32_dynstr_insert 10495088Sab196087 #define elfedit_modified_data elfedit32_modified_data 10505088Sab196087 #define elfedit_modified_ehdr elfedit32_modified_ehdr 10515088Sab196087 #define elfedit_modified_phdr elfedit32_modified_phdr 10525088Sab196087 #define elfedit_modified_shdr elfedit32_modified_shdr 10535088Sab196087 #define elfedit_name_to_shndx elfedit32_name_to_shndx 10545088Sab196087 #define elfedit_name_to_symndx elfedit32_name_to_symndx 10555088Sab196087 #define elfedit_offset_to_str elfedit32_offset_to_str 10565088Sab196087 #define elfedit_sec_findstr elfedit32_sec_findstr 10575892Sab196087 #define elfedit_sec_get elfedit32_sec_get 10585088Sab196087 #define elfedit_sec_getcap elfedit32_sec_getcap 10595088Sab196087 #define elfedit_sec_getdyn elfedit32_sec_getdyn 10605088Sab196087 #define elfedit_sec_getstr elfedit32_sec_getstr 10615088Sab196087 #define elfedit_sec_getsyminfo elfedit32_sec_getsyminfo 10625088Sab196087 #define elfedit_sec_getsymtab elfedit32_sec_getsymtab 10635088Sab196087 #define elfedit_sec_getversym elfedit32_sec_getversym 10645088Sab196087 #define elfedit_sec_getxshndx elfedit32_sec_getxshndx 10655088Sab196087 #define elfedit_sec_issymtab elfedit32_sec_issymtab 10665088Sab196087 #define elfedit_shndx_to_name elfedit32_shndx_to_name 10675088Sab196087 #define elfedit_sec_msgprefix elfedit32_sec_msgprefix 10685088Sab196087 #define elfedit_strtab_insert elfedit32_strtab_insert 10695088Sab196087 #define elfedit_strtab_insert_test elfedit32_strtab_insert_test 10709273SAli.Bahrami@Sun.COM #define elfedit_test_osabi elfedit32_test_osabi 10715088Sab196087 #define elfedit_type_to_shndx elfedit32_type_to_shndx 10725088Sab196087 #endif 10735088Sab196087 10745088Sab196087 10755088Sab196087 #ifdef __cplusplus 10765088Sab196087 } 10775088Sab196087 #endif 10785088Sab196087 10795088Sab196087 #endif /* _ELFEDIT_H */ 1080