d29b2c4438482eb00488be49a1f5d6835f455546ab * CDDL HEADER START
d29b2c4438482eb00488be49a1f5d6835f455546ab * The contents of this file are subject to the terms of the
d29b2c4438482eb00488be49a1f5d6835f455546ab * Common Development and Distribution License (the "License").
d29b2c4438482eb00488be49a1f5d6835f455546ab * You may not use this file except in compliance with the License.
d29b2c4438482eb00488be49a1f5d6835f455546ab * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d29b2c4438482eb00488be49a1f5d6835f455546ab * See the License for the specific language governing permissions
d29b2c4438482eb00488be49a1f5d6835f455546ab * and limitations under the License.
d29b2c4438482eb00488be49a1f5d6835f455546ab * When distributing Covered Code, include this CDDL HEADER in each
d29b2c4438482eb00488be49a1f5d6835f455546ab * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d29b2c4438482eb00488be49a1f5d6835f455546ab * If applicable, add the following below this CDDL HEADER, with the
d29b2c4438482eb00488be49a1f5d6835f455546ab * fields enclosed by brackets "[]" replaced with your own identifying
d29b2c4438482eb00488be49a1f5d6835f455546ab * information: Portions Copyright [yyyy] [name of copyright owner]
d29b2c4438482eb00488be49a1f5d6835f455546ab * CDDL HEADER END
62b628a68db596a2d75a316dc7ffef658079231fAli Bahrami * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Use is subject to license terms.
d29b2c4438482eb00488be49a1f5d6835f455546ab * ELFCLASS specific code for elfedit, built once for each class
ba2be53024c0b999e74ba9adcd7d80fec5df8c57ab#include <_machelf.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab * Look up the elfedit_symtab_t that corresponds to the symbol table
d29b2c4438482eb00488be49a1f5d6835f455546ab * referenced by the sh_link field of the given auxiliary section.
d29b2c4438482eb00488be49a1f5d6835f455546ab * obj_state - Partially constructed object state from
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit_init_obj_state().
d29b2c4438482eb00488be49a1f5d6835f455546ab * auxsec - Section that is associated with the symbol table section
d29b2c4438482eb00488be49a1f5d6835f455546ab * Returns the pointer to the elfedit_symtab_t entry that is
d29b2c4438482eb00488be49a1f5d6835f455546ab * referenced by the auxiliary section. If not found,
d29b2c4438482eb00488be49a1f5d6835f455546ab * outputs a debug message, and returns NULL.
d29b2c4438482eb00488be49a1f5d6835f455546abget_symtab(elfedit_obj_state_t *obj_state, elfedit_section_t *auxsec)
d29b2c4438482eb00488be49a1f5d6835f455546ab * If we don't return above, it doesn't reference a valid
d29b2c4438482eb00488be49a1f5d6835f455546ab * symbol table. Issue warning.
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_AUX_LINK),
d29b2c4438482eb00488be49a1f5d6835f455546ab * Fill in state.elf.obj_state with a a dynamically allocated
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit_obj_state_t struct of the appropriate ELFCLASS.
d29b2c4438482eb00488be49a1f5d6835f455546ab * This pre-chewed form is fed to each command, reducing the amount
d29b2c4438482eb00488be49a1f5d6835f455546ab * of ELF boilerplate code each command needs to contain.
d29b2c4438482eb00488be49a1f5d6835f455546ab * file - Name of file to process
d29b2c4438482eb00488be49a1f5d6835f455546ab * fd - Descriptor of open file which has been successfully
d29b2c4438482eb00488be49a1f5d6835f455546ab * processed by elf_begin().
d29b2c4438482eb00488be49a1f5d6835f455546ab * elf - Elf handle returned by elf_begin
d29b2c4438482eb00488be49a1f5d6835f455546ab * An elfedit_obj_state_t struct of the appropriate ELFCLASS has
d29b2c4438482eb00488be49a1f5d6835f455546ab * been dynamically allocated, and state.elf.obj_state references it.
d29b2c4438482eb00488be49a1f5d6835f455546ab * On failure, this routine does not return to the caller.
d29b2c4438482eb00488be49a1f5d6835f455546ab * note: The resulting elfedit_obj_state_t is allocated from a single
d29b2c4438482eb00488be49a1f5d6835f455546ab * piece of memory, such that a single call to free() suffices
d29b2c4438482eb00488be49a1f5d6835f455546ab * to release it as well as any memory it references.
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit64_init_obj_state(const char *file, int fd, Elf *elf)
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit32_init_obj_state(const char *file, int fd, Elf *elf)
62b628a68db596a2d75a316dc7ffef658079231fAli Bahrami * These macros are used to call functions from libelf.
62b628a68db596a2d75a316dc7ffef658079231fAli Bahrami * LIBELF_FAIL encapsulates the common way in which we handle
62b628a68db596a2d75a316dc7ffef658079231fAli Bahrami * all of these errors: libelf_fail_name is set and execution
62b628a68db596a2d75a316dc7ffef658079231fAli Bahrami * jumps to the libelf_failure label for handling.
62b628a68db596a2d75a316dc7ffef658079231fAli Bahrami * LIBELF is used for the common case in which the function returns
62b628a68db596a2d75a316dc7ffef658079231fAli Bahrami * NULL for failure and something else for success.
62b628a68db596a2d75a316dc7ffef658079231fAli Bahrami#define LIBELF_FAIL(_name) { libelf_fail_name = _name; goto libelf_failure; }
d29b2c4438482eb00488be49a1f5d6835f455546ab const char *libelf_fail_name; /* Used for LIBELF errors */
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Program header array count and address */
62b628a68db596a2d75a316dc7ffef658079231fAli Bahrami if (elf_getphdrnum(tstate.os_elf, &tstate.os_phnum) == -1)
62b628a68db596a2d75a316dc7ffef658079231fAli Bahrami if (elf_getshdrnum(tstate.os_elf, &tstate.os_shnum) == -1)
d29b2c4438482eb00488be49a1f5d6835f455546ab * Obtain the .shstrtab data buffer to provide the required section
d29b2c4438482eb00488be49a1f5d6835f455546ab * name strings.
62b628a68db596a2d75a316dc7ffef658079231fAli Bahrami if (elf_getshdrstrndx(tstate.os_elf, &tstate.os_shstrndx) == -1)
d29b2c4438482eb00488be49a1f5d6835f455546ab LIBELF((scn = elf_getscn(tstate.os_elf, tstate.os_shstrndx)),
d29b2c4438482eb00488be49a1f5d6835f455546ab LIBELF((data = elf_getdata(scn, NULL)), MSG_ORIG(MSG_ELF_GETDATA))
d29b2c4438482eb00488be49a1f5d6835f455546ab * Count the number of symbol tables and capture their indexes.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Find the dynamic section.
d29b2c4438482eb00488be49a1f5d6835f455546ab for (ndx = 1, scn = NULL; scn = elf_nextscn(tstate.os_elf, scn);
d29b2c4438482eb00488be49a1f5d6835f455546ab LIBELF(shdr = elf_getshdr(scn), MSG_ORIG(MSG_ELF_GETSHDR));
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Save index of dynamic section for use below */
d29b2c4438482eb00488be49a1f5d6835f455546ab * Allocate space to hold the state. We allocate space for everything
d29b2c4438482eb00488be49a1f5d6835f455546ab * in one chunk to make releasing it easy:
d29b2c4438482eb00488be49a1f5d6835f455546ab * (1) elfedit_obj_state_t struct
d29b2c4438482eb00488be49a1f5d6835f455546ab * (2) The array of elfedit_section_t items referenced from
d29b2c4438482eb00488be49a1f5d6835f455546ab * the elfedit_obj_state_t struct.
d29b2c4438482eb00488be49a1f5d6835f455546ab * (3) The array of elfedit_symtab_t items referenced from
d29b2c4438482eb00488be49a1f5d6835f455546ab * the elfedit_obj_state_t struct.
d29b2c4438482eb00488be49a1f5d6835f455546ab * (4) The file name.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Note that we round up the size of (1) and (2) to a double boundary
d29b2c4438482eb00488be49a1f5d6835f455546ab * to ensure proper alignment of (2) and (3). (4) can align on any
d29b2c4438482eb00488be49a1f5d6835f455546ab * boundary.
d29b2c4438482eb00488be49a1f5d6835f455546ab secarr_size = (tstate.os_shnum * sizeof (elfedit_section_t));
d29b2c4438482eb00488be49a1f5d6835f455546ab (tstate.os_symtabnum * sizeof (elfedit_symtab_t)) + len);
d29b2c4438482eb00488be49a1f5d6835f455546ab /*LINTED E_BAD_PTR_CAST_ALIGN*/
d29b2c4438482eb00488be49a1f5d6835f455546ab /*LINTED E_BAD_PTR_CAST_ALIGN*/
d29b2c4438482eb00488be49a1f5d6835f455546ab (void) strncpy((char *)obj_state->os_file, tstate.os_file, len);
d29b2c4438482eb00488be49a1f5d6835f455546ab * Fill in obj_state->os_secarr with information for each section.
d29b2c4438482eb00488be49a1f5d6835f455546ab * At the same time, fill in obj_state->os_symtab with the symbol
d29b2c4438482eb00488be49a1f5d6835f455546ab * table related data.
d29b2c4438482eb00488be49a1f5d6835f455546ab bzero(obj_state->os_secarr, sizeof (obj_state->os_secarr[0]));
d29b2c4438482eb00488be49a1f5d6835f455546ab LIBELF(_cache->sec_shdr = elf_getshdr(scn), MSG_ORIG(MSG_ELF_GETSHDR));
d29b2c4438482eb00488be49a1f5d6835f455546ab _cache->sec_name = (_cache->sec_shdr->sh_name < names_len) ?
d29b2c4438482eb00488be49a1f5d6835f455546ab (names + _cache->sec_shdr->sh_name) : MSG_INTL(MSG_UNKNOWNSECNAM);
d29b2c4438482eb00488be49a1f5d6835f455546ab sizeof (obj_state->os_symtab[0]) * obj_state->os_symtabnum);
d29b2c4438482eb00488be49a1f5d6835f455546ab for (ndx = 1, scn = NULL; scn = elf_nextscn(tstate.os_elf, scn);
d29b2c4438482eb00488be49a1f5d6835f455546ab _cache->sec_name = (_cache->sec_shdr->sh_name < names_len) ?
d29b2c4438482eb00488be49a1f5d6835f455546ab * Sanity check the symbol tables, and discard any auxiliary
d29b2c4438482eb00488be49a1f5d6835f455546ab * sections without enough elements.
d29b2c4438482eb00488be49a1f5d6835f455546ab for (ndx = 0; ndx < obj_state->os_symtabnum; ndx++, symtab++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Extended section indexes */
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Syminfo */
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Versym */
d29b2c4438482eb00488be49a1f5d6835f455546ab * If this object has a dynsym section with a FLAGS_1 field,
d29b2c4438482eb00488be49a1f5d6835f455546ab * then set the DF_1_EDITED bit. elfedit allows changes that
d29b2c4438482eb00488be49a1f5d6835f455546ab * can break the resulting program, so knowing that a file was
d29b2c4438482eb00488be49a1f5d6835f455546ab * edited can be helpful when encountering a core file or other
d29b2c4438482eb00488be49a1f5d6835f455546ab * unexpected failure in the field. A single bit can't tell you
d29b2c4438482eb00488be49a1f5d6835f455546ab * what was changed, but it will alert you to the possibility that
d29b2c4438482eb00488be49a1f5d6835f455546ab * some additional questions might be in order.
d29b2c4438482eb00488be49a1f5d6835f455546ab for (i = 0; i < numdyn; i++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab * Remember state of the first DT_NULL. If there
d29b2c4438482eb00488be49a1f5d6835f455546ab * are more than one (i.e. the first one is not
d29b2c4438482eb00488be49a1f5d6835f455546ab * in the final spot), and there is no flags1,
d29b2c4438482eb00488be49a1f5d6835f455546ab * then we will turn the first one into a
d29b2c4438482eb00488be49a1f5d6835f455546ab * DT_FLAGS_1.
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If don't have a flags1 field, can we make one from a NULL? */
d29b2c4438482eb00488be49a1f5d6835f455546ab * If there is a flags 1 field, add the edit flag if
d29b2c4438482eb00488be49a1f5d6835f455546ab * it is not present, and report it's presence otherwise.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Control comes here if there is an error with LIBELF.
d29b2c4438482eb00488be49a1f5d6835f455546ab * libelf_fail_name - Name of failing libelf function
d29b2c4438482eb00488be49a1f5d6835f455546ab * tstate.os_file - Name of ELF file being processed
d29b2c4438482eb00488be49a1f5d6835f455546ab * tstate.os_fd - Descriptor of open ELF file
d29b2c4438482eb00488be49a1f5d6835f455546ab * - dynamic memory is released if necessary
d29b2c4438482eb00488be49a1f5d6835f455546ab * - The error issued