d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * CDDL HEADER START
d29b2c4438482eb00488be49a1f5d6835f455546ab *
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 *
d29b2c4438482eb00488be49a1f5d6835f455546ab * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d29b2c4438482eb00488be49a1f5d6835f455546ab * or http://www.opensolaris.org/os/licensing.
d29b2c4438482eb00488be49a1f5d6835f455546ab * See the License for the specific language governing permissions
d29b2c4438482eb00488be49a1f5d6835f455546ab * and limitations under the License.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
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 *
d29b2c4438482eb00488be49a1f5d6835f455546ab * CDDL HEADER END
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Use is subject to license terms.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <stdlib.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <stdio.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <unistd.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <libintl.h>
ba2be53024c0b999e74ba9adcd7d80fec5df8c57ab#include <_machelf.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <libelf.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <link.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <strings.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <ctype.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include "msg.h"
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <elfedit.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <conv.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <sys/elf_SPARC.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <sys/elf_amd64.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * ELFCLASS specific code that would otherwise be found in util.c
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * When you modify ELF constructs, you need to tell libelf that you've
d29b2c4438482eb00488be49a1f5d6835f455546ab * done so. Otherwise, the changes may not be flushed back to the
d29b2c4438482eb00488be49a1f5d6835f455546ab * output file.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * The elfedit_modified_*() functions exist to simplify the calls to
d29b2c4438482eb00488be49a1f5d6835f455546ab * the underlying elf_flag*() functions.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_modified_ehdr(elfedit_obj_state_t *obj_state)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab (void) elf_flagehdr(obj_state->os_elf, ELF_C_SET, ELF_F_DIRTY);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_modified_phdr(elfedit_obj_state_t *obj_state)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab (void) elf_flagphdr(obj_state->os_elf, ELF_C_SET, ELF_F_DIRTY);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_modified_shdr(elfedit_section_t *s)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab (void) elf_flagshdr(s->sec_scn, ELF_C_SET, ELF_F_DIRTY);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_modified_data(elfedit_section_t *s)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab (void) elf_flagdata(s->sec_data, ELF_C_SET, ELF_F_DIRTY);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Prepare an elfedit_dyn_elt_t structure for use.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_dyn_elt_init(elfedit_dyn_elt_t *elt)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elt->dn_seen = 0;
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Given a dynamic section item, save it in the given elfedit_dyn_elt_t
d29b2c4438482eb00488be49a1f5d6835f455546ab * structure and mark that structure to show that it is present.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_dyn_elt_save(elfedit_dyn_elt_t *elt, Word ndx, Dyn *dyn)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elt->dn_seen = 1;
d29b2c4438482eb00488be49a1f5d6835f455546ab elt->dn_ndx = ndx;
d29b2c4438482eb00488be49a1f5d6835f455546ab elt->dn_dyn = *dyn;
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Return the index of the first section that has the given name.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * obj_state - Object state.
d29b2c4438482eb00488be49a1f5d6835f455546ab * shnam - Name of desired section
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, returns the section index. On failure, an error
d29b2c4438482eb00488be49a1f5d6835f455546ab * is issued, and this routine does not return to the caller.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abWord
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_name_to_shndx(elfedit_obj_state_t *obj_state, const char *shnam)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *sec = obj_state->os_secarr;
d29b2c4438482eb00488be49a1f5d6835f455546ab Word ndx;
d29b2c4438482eb00488be49a1f5d6835f455546ab Word shnum = obj_state->os_shnum;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab for (ndx = 0; ndx < shnum; ndx++, sec++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab if (strcmp(shnam, sec->sec_name) == 0) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_DEBUG_SHNAM2NDX),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(sec->sec_shndx), sec->sec_name, shnam);
d29b2c4438482eb00488be49a1f5d6835f455546ab return (ndx);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If didn't return in loop above, the name doesn't match */
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOSECNAM), shnam);
d29b2c4438482eb00488be49a1f5d6835f455546ab /*NOTREACHED*/
d29b2c4438482eb00488be49a1f5d6835f455546ab return (SHN_UNDEF);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Return the index of the first section that has the given type.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * obj_state - Object state.
d29b2c4438482eb00488be49a1f5d6835f455546ab * shtype - Type of desired section
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, returns the section index. On failure, an error
d29b2c4438482eb00488be49a1f5d6835f455546ab * is issued, and this routine does not return to the caller.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abWord
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_type_to_shndx(elfedit_obj_state_t *obj_state, Word shtype)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab Conv_inv_buf_t inv_buf;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *sec = obj_state->os_secarr;
d29b2c4438482eb00488be49a1f5d6835f455546ab Word ndx;
d29b2c4438482eb00488be49a1f5d6835f455546ab Word shnum = obj_state->os_shnum;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab for (ndx = 0; ndx < shnum; ndx++, sec++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab if (shtype == sec->sec_shdr->sh_type) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_DEBUG_SHNAM2NDX),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(sec->sec_shndx), sec->sec_name,
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami conv_sec_type(
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami obj_state->os_ehdr->e_ident[EI_OSABI],
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami obj_state->os_ehdr->e_machine,
d29b2c4438482eb00488be49a1f5d6835f455546ab shtype, 0, &inv_buf));
d29b2c4438482eb00488be49a1f5d6835f455546ab return (ndx);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If didn't return in loop above, the name doesn't match */
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOSECTYP),
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami conv_sec_type(obj_state->os_ehdr->e_ident[EI_OSABI],
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami obj_state->os_ehdr->e_machine, shtype, 0, &inv_buf));
d29b2c4438482eb00488be49a1f5d6835f455546ab /*NOTREACHED*/
d29b2c4438482eb00488be49a1f5d6835f455546ab return (SHN_UNDEF);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Locate the index of the first symbol that has the given name
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * obj_state - Object state.
d29b2c4438482eb00488be49a1f5d6835f455546ab * symsec - Symbol section
d29b2c4438482eb00488be49a1f5d6835f455546ab * strsec = String section
d29b2c4438482eb00488be49a1f5d6835f455546ab * name - String giving name of symbol to lookup
d29b2c4438482eb00488be49a1f5d6835f455546ab * msg_type - ELFEDIT_MSG_ type code to use with message
d29b2c4438482eb00488be49a1f5d6835f455546ab * issued if name does not exist in symbol table.
d29b2c4438482eb00488be49a1f5d6835f455546ab * ret_symndx - Address of variable to receive index.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, issues debug message, sets *ret_symndx, and returns
d29b2c4438482eb00488be49a1f5d6835f455546ab * True (1).
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * On failure, issues a message using msg_type to determine
d29b2c4438482eb00488be49a1f5d6835f455546ab * the type of message sent. If the message does not take control away
d29b2c4438482eb00488be49a1f5d6835f455546ab * from the caller, False (0) is returned.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * note:
d29b2c4438482eb00488be49a1f5d6835f455546ab * Although the string table is referenced by the sh_link field of
d29b2c4438482eb00488be49a1f5d6835f455546ab * the symbol table, we require the user to supply it rather than
d29b2c4438482eb00488be49a1f5d6835f455546ab * look it up. The reason for this is that the caller will usually
d29b2c4438482eb00488be49a1f5d6835f455546ab * have looked it up, and we wish to avoid multiple debug messages
d29b2c4438482eb00488be49a1f5d6835f455546ab * from being issued to that effect.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abint
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_name_to_symndx(elfedit_section_t *symsec, elfedit_section_t *strsec,
d29b2c4438482eb00488be49a1f5d6835f455546ab const char *name, elfedit_msg_t msg_type, Word *ret_symndx)
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab Sym *sym = (Sym *) symsec->sec_data->d_buf;
d29b2c4438482eb00488be49a1f5d6835f455546ab Word cnt = symsec->sec_shdr->sh_size / symsec->sec_shdr->sh_entsize;
d29b2c4438482eb00488be49a1f5d6835f455546ab Word ndx, offset;
d29b2c4438482eb00488be49a1f5d6835f455546ab const char *curname;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab for (ndx = 0; ndx < cnt; ndx++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab offset = sym[ndx].st_name;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab curname = elfedit_offset_to_str(strsec, offset,
d29b2c4438482eb00488be49a1f5d6835f455546ab ELFEDIT_MSG_ERR, 0);
d29b2c4438482eb00488be49a1f5d6835f455546ab if (strcmp(curname, name) == 0) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_DEBUG_SYMNAM2NDX),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(symsec->sec_shndx),
d29b2c4438482eb00488be49a1f5d6835f455546ab symsec->sec_name, EC_WORD(ndx), name);
d29b2c4438482eb00488be49a1f5d6835f455546ab *ret_symndx = ndx;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (1);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If didn't return in loop above, the name doesn't match */
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(msg_type, MSG_INTL(MSG_ERR_NOSYM),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(symsec->sec_shndx), symsec->sec_name, name);
d29b2c4438482eb00488be49a1f5d6835f455546ab /*NOTREACHED*/
d29b2c4438482eb00488be49a1f5d6835f455546ab return (0); /* lint */
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Given a section index, turn it into a descriptive string.
d29b2c4438482eb00488be49a1f5d6835f455546ab * - If it is one of the special reserved indexes, the
d29b2c4438482eb00488be49a1f5d6835f455546ab * symbolic name is returned.
d29b2c4438482eb00488be49a1f5d6835f455546ab * - If it is a regular section, in range for the file,
d29b2c4438482eb00488be49a1f5d6835f455546ab * the name associated with the section is returned.
d29b2c4438482eb00488be49a1f5d6835f455546ab * - Otherwise, the number is formatted as numeric ASCII.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * A pointer to the static buffer containing the name is
d29b2c4438482eb00488be49a1f5d6835f455546ab * returned. This pointer is valid until the next call
d29b2c4438482eb00488be49a1f5d6835f455546ab * to elfedit_shndx_to_name(), and which point it may
d29b2c4438482eb00488be49a1f5d6835f455546ab * be overwritten.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abconst char *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_shndx_to_name(elfedit_obj_state_t *obj_state, Word shndx)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * This routine can be called twice within a single C statement,
d29b2c4438482eb00488be49a1f5d6835f455546ab * so we use alternating buffers on each call to allow this
d29b2c4438482eb00488be49a1f5d6835f455546ab * without requiring the caller to supply a buffer (the size of
d29b2c4438482eb00488be49a1f5d6835f455546ab * which they don't know).
d29b2c4438482eb00488be49a1f5d6835f455546ab */
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami static Conv_inv_buf_t buf1, buf2;
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami static Conv_inv_buf_t *buf;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * If it is outside of the reserved area, and inside the
d29b2c4438482eb00488be49a1f5d6835f455546ab * range of section indexes in the ELF file, then show
d29b2c4438482eb00488be49a1f5d6835f455546ab * the section name.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((shndx < obj_state->os_shnum) &&
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami ((shndx < SHN_LORESERVE) || (shndx > SHN_HIRESERVE)) &&
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami (shndx != SHN_UNDEF))
d29b2c4438482eb00488be49a1f5d6835f455546ab return (obj_state->os_secarr[shndx].sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * Anything else is handled by libconv. It will return standard
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * names for known items, or format as a number otherwise.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami buf = (buf == &buf1) ? &buf2 : &buf1; /* Switch buffers */
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami return (conv_sym_shndx(obj_state->os_ehdr->e_ident[EI_OSABI],
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami obj_state->os_ehdr->e_machine, shndx,
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami CONV_FMT_ALT_CF | CONV_FMT_DECIMAL, buf));
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
cce0e03bb2d07f0fe27cabb93acae9c23655859fab/*
cce0e03bb2d07f0fe27cabb93acae9c23655859fab * Locate the arbitrary section specified by shndx for this object.
cce0e03bb2d07f0fe27cabb93acae9c23655859fab *
cce0e03bb2d07f0fe27cabb93acae9c23655859fab * exit:
cce0e03bb2d07f0fe27cabb93acae9c23655859fab * Returns section descriptor on success. On failure, does not return.
cce0e03bb2d07f0fe27cabb93acae9c23655859fab */
cce0e03bb2d07f0fe27cabb93acae9c23655859fabelfedit_section_t *
cce0e03bb2d07f0fe27cabb93acae9c23655859fabelfedit_sec_get(elfedit_obj_state_t *obj_state, Word shndx)
cce0e03bb2d07f0fe27cabb93acae9c23655859fab{
cce0e03bb2d07f0fe27cabb93acae9c23655859fab elfedit_section_t *sec;
cce0e03bb2d07f0fe27cabb93acae9c23655859fab
cce0e03bb2d07f0fe27cabb93acae9c23655859fab if ((shndx == 0) || (shndx >= obj_state->os_shnum))
cce0e03bb2d07f0fe27cabb93acae9c23655859fab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADSECNDX),
cce0e03bb2d07f0fe27cabb93acae9c23655859fab EC_WORD(shndx), EC_WORD(obj_state->os_shnum - 1));
cce0e03bb2d07f0fe27cabb93acae9c23655859fab
cce0e03bb2d07f0fe27cabb93acae9c23655859fab sec = &obj_state->os_secarr[shndx];
cce0e03bb2d07f0fe27cabb93acae9c23655859fab
cce0e03bb2d07f0fe27cabb93acae9c23655859fab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_FNDSEC),
cce0e03bb2d07f0fe27cabb93acae9c23655859fab EC_WORD(shndx), sec->sec_name);
cce0e03bb2d07f0fe27cabb93acae9c23655859fab return (sec);
cce0e03bb2d07f0fe27cabb93acae9c23655859fab}
cce0e03bb2d07f0fe27cabb93acae9c23655859fab
cce0e03bb2d07f0fe27cabb93acae9c23655859fab
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami/*
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * Compare the a specified osabi with that of the current object.
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami *
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * entry:
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * obj_state - Object state for open object to query.
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * issue_err - True if this routine should issue an error and
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * not return to the caller if osabi is not native.
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami *
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * exit:
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * If current osabi is the one specified, True (1) is returned.
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami *
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * Otherwise, if issue_err is True, an error is issued and this
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * routine does not return to the caller. If issue_err is False,
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * False (0) is returned.
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami *
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * note:
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * ELFOSABI_NONE is considered to be equivalent to ELFOSABI_SOLARIS.
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami */
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahramiint
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahramielfedit_test_osabi(elfedit_obj_state_t *obj_state, uchar_t osabi,
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami int issue_err)
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami{
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami uchar_t obj_osabi = obj_state->os_ehdr->e_ident[EI_OSABI];
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami Conv_inv_buf_t inv_buf;
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami if (obj_osabi == ELFOSABI_NONE)
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami obj_osabi = ELFOSABI_SOLARIS;
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami if (osabi == obj_osabi)
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami return (1);
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami if (issue_err)
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADOSABI),
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami conv_ehdr_osabi(osabi, 0, &inv_buf));
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami return (0);
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami}
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Locate the capabilities section for this object
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * obj_state - Object state for open object to query.
d29b2c4438482eb00488be49a1f5d6835f455546ab * cap - Address of variable to recieve pointer to capabilities
d29b2c4438482eb00488be49a1f5d6835f455546ab * section data buffer.
d29b2c4438482eb00488be49a1f5d6835f455546ab * num - Address of variable to receive number of items
d29b2c4438482eb00488be49a1f5d6835f455546ab * referenced by cap.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, returns section descriptor, and sets the
d29b2c4438482eb00488be49a1f5d6835f455546ab * variables referenced by cap and num. On failure,
d29b2c4438482eb00488be49a1f5d6835f455546ab * does not return.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_section_t *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_sec_getcap(elfedit_obj_state_t *obj_state, Cap **cap, Word *num)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab Word cnt;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *cache;
d29b2c4438482eb00488be49a1f5d6835f455546ab
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami (void) elfedit_test_osabi(obj_state, ELFOSABI_SOLARIS, 1);
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami
d29b2c4438482eb00488be49a1f5d6835f455546ab for (cnt = 1; cnt < obj_state->os_shnum; cnt++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab cache = &obj_state->os_secarr[cnt];
d29b2c4438482eb00488be49a1f5d6835f455546ab if (cache->sec_shdr->sh_type == SHT_SUNW_cap) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_DEBUG_FNDCAP),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(cnt), cache->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab *cap = (Cap *) cache->sec_data->d_buf;
d29b2c4438482eb00488be49a1f5d6835f455546ab *num = cache->sec_shdr->sh_size /
d29b2c4438482eb00488be49a1f5d6835f455546ab cache->sec_shdr->sh_entsize;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (cache);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If here, this object has no capabilities section */
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOCAP));
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*NOTREACHED*/
d29b2c4438482eb00488be49a1f5d6835f455546ab return (NULL);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Locate the dynamic section for this object
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * obj_state - Object state for open object to query.
d29b2c4438482eb00488be49a1f5d6835f455546ab * dyn - Address of variable to recieve pointer to dynamic
d29b2c4438482eb00488be49a1f5d6835f455546ab * section data buffer.
d29b2c4438482eb00488be49a1f5d6835f455546ab * numdyn - Address of variable to receive number of items
d29b2c4438482eb00488be49a1f5d6835f455546ab * referenced by dyn.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, returns section descriptor, and sets the
d29b2c4438482eb00488be49a1f5d6835f455546ab * variables referenced by dyn and numdyn. On failure,
d29b2c4438482eb00488be49a1f5d6835f455546ab * does not return.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_section_t *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_sec_getdyn(elfedit_obj_state_t *obj_state, Dyn **dyn, Word *num)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *cache;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if (obj_state->os_dynndx != SHN_UNDEF) {
d29b2c4438482eb00488be49a1f5d6835f455546ab cache = &obj_state->os_secarr[obj_state->os_dynndx];
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_FNDDYN),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(cache->sec_shndx), cache->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab *dyn = (Dyn *) cache->sec_data->d_buf;
d29b2c4438482eb00488be49a1f5d6835f455546ab *num = cache->sec_shdr->sh_size / cache->sec_shdr->sh_entsize;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (cache);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If here, this object has no dynamic section */
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NODYN));
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*NOTREACHED*/
d29b2c4438482eb00488be49a1f5d6835f455546ab return (NULL);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Locate the syminfo section for this object
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * obj_state - Object state for open object to query.
d29b2c4438482eb00488be49a1f5d6835f455546ab * syminfo - Address of variable to recieve pointer to syminfo
d29b2c4438482eb00488be49a1f5d6835f455546ab * section data buffer.
d29b2c4438482eb00488be49a1f5d6835f455546ab * num - Address of variable to receive number of items
d29b2c4438482eb00488be49a1f5d6835f455546ab * referenced by syminfo.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, returns section descriptor, and sets the
d29b2c4438482eb00488be49a1f5d6835f455546ab * variables referenced by syminfo and num. On failure,
d29b2c4438482eb00488be49a1f5d6835f455546ab * does not return.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_section_t *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_sec_getsyminfo(elfedit_obj_state_t *obj_state, Syminfo **syminfo,
d29b2c4438482eb00488be49a1f5d6835f455546ab Word *num)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab Word cnt;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *cache;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab for (cnt = 1; cnt < obj_state->os_shnum; cnt++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab cache = &obj_state->os_secarr[cnt];
d29b2c4438482eb00488be49a1f5d6835f455546ab if (cache->sec_shdr->sh_type == SHT_SUNW_syminfo) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_DEBUG_FNDSYMINFO),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(cnt), cache->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab *syminfo = (Syminfo *) cache->sec_data->d_buf;
d29b2c4438482eb00488be49a1f5d6835f455546ab *num = cache->sec_shdr->sh_size /
d29b2c4438482eb00488be49a1f5d6835f455546ab cache->sec_shdr->sh_entsize;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (cache);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If here, this object has no syminfo section */
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOSYMINFO));
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*NOTREACHED*/
d29b2c4438482eb00488be49a1f5d6835f455546ab return (NULL);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Check the given section to see if it is a known symbol table type.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * obj_state - Object state for open object to query.
d29b2c4438482eb00488be49a1f5d6835f455546ab * sec - Section to check
d29b2c4438482eb00488be49a1f5d6835f455546ab * issue_err - True if this routine should issue an error and
d29b2c4438482eb00488be49a1f5d6835f455546ab * not return to the caller if sec is not a symbol table.
d29b2c4438482eb00488be49a1f5d6835f455546ab * atoui_list - NULL, or address of variable to receive a pointer to
d29b2c4438482eb00488be49a1f5d6835f455546ab * an array of elfedit_atoui_sym_t items describing the
d29b2c4438482eb00488be49a1f5d6835f455546ab * type of symbol table found. This array is useful for
d29b2c4438482eb00488be49a1f5d6835f455546ab * doing command completion.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * If sec is a symbol table:
d29b2c4438482eb00488be49a1f5d6835f455546ab * - If atoui_list is non-NULL, *atoui_list is set to the
d29b2c4438482eb00488be49a1f5d6835f455546ab * appropriate ELFEDIT_CONST_xx list of items.
d29b2c4438482eb00488be49a1f5d6835f455546ab * - True (1) is returned
d29b2c4438482eb00488be49a1f5d6835f455546ab * If sec is not a symbol table and issue_err is True:
d29b2c4438482eb00488be49a1f5d6835f455546ab * - An error is issued, and this routine does not
d29b2c4438482eb00488be49a1f5d6835f455546ab * return to the caller.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Otherwise:
d29b2c4438482eb00488be49a1f5d6835f455546ab * - If atoui_list is non-NULL, *atoui_list is set to NULL.
d29b2c4438482eb00488be49a1f5d6835f455546ab * - False (0) is returned
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abint
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahramielfedit_sec_issymtab(elfedit_obj_state_t *obj_state, elfedit_section_t *sec,
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami int issue_err, elfedit_atoui_sym_t **atoui_list)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_const_t const_type;
d29b2c4438482eb00488be49a1f5d6835f455546ab int ret = 1;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Is the section a symbol table? */
d29b2c4438482eb00488be49a1f5d6835f455546ab switch (sec->sec_shdr->sh_type) {
d29b2c4438482eb00488be49a1f5d6835f455546ab case SHT_SYMTAB:
d29b2c4438482eb00488be49a1f5d6835f455546ab const_type = ELFEDIT_CONST_SHT_SYMTAB;
d29b2c4438482eb00488be49a1f5d6835f455546ab break;
d29b2c4438482eb00488be49a1f5d6835f455546ab case SHT_DYNSYM:
d29b2c4438482eb00488be49a1f5d6835f455546ab const_type = ELFEDIT_CONST_SHT_DYNSYM;
d29b2c4438482eb00488be49a1f5d6835f455546ab break;
d29b2c4438482eb00488be49a1f5d6835f455546ab case SHT_SUNW_LDYNSYM:
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami /*
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * These sections are only known to be symbol tables
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * if the osabi is Solaris.
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami */
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami if (elfedit_test_osabi(obj_state, ELFOSABI_SOLARIS, 0)) {
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami const_type = ELFEDIT_CONST_SHT_LDYNSYM;
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami break;
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami }
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami /*FALLTHROUGH*/
d29b2c4438482eb00488be49a1f5d6835f455546ab default:
d29b2c4438482eb00488be49a1f5d6835f455546ab if (issue_err)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_ERR_NOTSYMTAB),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(sec->sec_shndx), sec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab ret = 0;
d29b2c4438482eb00488be49a1f5d6835f455546ab break;
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if (atoui_list != NULL)
d29b2c4438482eb00488be49a1f5d6835f455546ab *atoui_list = (ret == 0) ? NULL :
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_const_to_atoui(const_type);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab return (ret);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Locate a symbol table section for this object
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * obj_state - Object state for open object to query.
d29b2c4438482eb00488be49a1f5d6835f455546ab * by_index - If True, we want to locate the section with the
d29b2c4438482eb00488be49a1f5d6835f455546ab * section index given by index. If False, we return
d29b2c4438482eb00488be49a1f5d6835f455546ab * the section with the name given by name.
d29b2c4438482eb00488be49a1f5d6835f455546ab * index, name - Key to search for. See by_index.
d29b2c4438482eb00488be49a1f5d6835f455546ab * sym - Address of variable to recieve pointer to symbol
d29b2c4438482eb00488be49a1f5d6835f455546ab * section data buffer.
d29b2c4438482eb00488be49a1f5d6835f455546ab * numsym - Address of variable to receive number of symbols
d29b2c4438482eb00488be49a1f5d6835f455546ab * referenced by sym.
d29b2c4438482eb00488be49a1f5d6835f455546ab * aux_info - Address of variable to receive pointer to the
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit_symtab_t struct that ties the symbol table and
d29b2c4438482eb00488be49a1f5d6835f455546ab * its related auxiliary sections together. NULL if this
d29b2c4438482eb00488be49a1f5d6835f455546ab * information is not required.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, returns section descriptor, and sets the
d29b2c4438482eb00488be49a1f5d6835f455546ab * variables referenced by sym, and numsym. On failure,
d29b2c4438482eb00488be49a1f5d6835f455546ab * does not return.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_section_t *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_sec_getsymtab(elfedit_obj_state_t *obj_state, int by_index,
d29b2c4438482eb00488be49a1f5d6835f455546ab Word index, const char *name, Sym **sym, Word *num,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_symtab_t **aux_info)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab Word ndx;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *symsec = NULL;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_symtab_t *symtab;
d29b2c4438482eb00488be49a1f5d6835f455546ab const char *type_name;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If looking it up by index, make sure the index is in range */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (by_index && (index >= obj_state->os_shnum))
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADSECNDX),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(index), EC_WORD(obj_state->os_shnum - 1));
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Look at each known symbol table in turn until the desired
d29b2c4438482eb00488be49a1f5d6835f455546ab * one is hit, or there are no more.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab symtab = obj_state->os_symtab;
d29b2c4438482eb00488be49a1f5d6835f455546ab for (ndx = 0; ndx < obj_state->os_symtabnum; ndx++, symtab++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *s =
d29b2c4438482eb00488be49a1f5d6835f455546ab &obj_state->os_secarr[symtab->symt_shndx];
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((by_index && (symtab->symt_shndx == index)) ||
d29b2c4438482eb00488be49a1f5d6835f455546ab (!by_index && (strcmp(s->sec_name, name) == 0))) {
d29b2c4438482eb00488be49a1f5d6835f455546ab symsec = s;
d29b2c4438482eb00488be49a1f5d6835f455546ab break;
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Did we get a section? */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (symsec == NULL)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOSYMTAB));
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Got it. Report to the user and return the necessary data */
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami (void) elfedit_sec_issymtab(obj_state, symsec, 1, NULL);
d29b2c4438482eb00488be49a1f5d6835f455546ab type_name = elfedit_atoconst_value_to_str(ELFEDIT_CONST_SHT_ALLSYMTAB,
d29b2c4438482eb00488be49a1f5d6835f455546ab symsec->sec_shdr->sh_type, 1);
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_FNDSYMTAB),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(symsec->sec_shndx), symsec->sec_name, type_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab *sym = (Sym *) symsec->sec_data->d_buf;
d29b2c4438482eb00488be49a1f5d6835f455546ab *num = symsec->sec_shdr->sh_size / symsec->sec_shdr->sh_entsize;
d29b2c4438482eb00488be49a1f5d6835f455546ab if (aux_info != NULL)
d29b2c4438482eb00488be49a1f5d6835f455546ab *aux_info = symtab;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (symsec);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Locate the extended symbol index section associated with a symbol
d29b2c4438482eb00488be49a1f5d6835f455546ab * table section.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * obj_state - Object state for open object to query.
d29b2c4438482eb00488be49a1f5d6835f455546ab * symsec - Symbol table section for which extended index
d29b2c4438482eb00488be49a1f5d6835f455546ab * index section is required.
d29b2c4438482eb00488be49a1f5d6835f455546ab * xshndx - Address of variable to recieve pointer to section index
d29b2c4438482eb00488be49a1f5d6835f455546ab * array data buffer.
d29b2c4438482eb00488be49a1f5d6835f455546ab * numxshndx - Address of variable to receive number of indices
d29b2c4438482eb00488be49a1f5d6835f455546ab * referenced by ndx.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, returns extended index section descriptor, and sets the
d29b2c4438482eb00488be49a1f5d6835f455546ab * variables referenced by xshndx, and numxshndx. On failure,
d29b2c4438482eb00488be49a1f5d6835f455546ab * does not return.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * note:
d29b2c4438482eb00488be49a1f5d6835f455546ab * Since the extended section index is found in the sec_xshndx field
d29b2c4438482eb00488be49a1f5d6835f455546ab * of the elfedit_section_t, the caller may be tempted to bypass this
d29b2c4438482eb00488be49a1f5d6835f455546ab * routine and access it directly. That temptation should be resisted,
d29b2c4438482eb00488be49a1f5d6835f455546ab * as this routine performs useful error checking, and also handles
d29b2c4438482eb00488be49a1f5d6835f455546ab * the issuing of the standard MSG_DEBUG messages.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_section_t *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_sec_getxshndx(elfedit_obj_state_t *obj_state,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *symsec, Word **xshndx, Word *num)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *xshndxsec;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_symtab_t *symtab;
d29b2c4438482eb00488be49a1f5d6835f455546ab Word ndx;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Sanity check: symsec must be a symbol table */
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami (void) elfedit_sec_issymtab(obj_state, symsec, 1, NULL);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab symtab = obj_state->os_symtab;
d29b2c4438482eb00488be49a1f5d6835f455546ab for (ndx = 0; ndx < obj_state->os_symtabnum; ndx++, symtab++)
d29b2c4438482eb00488be49a1f5d6835f455546ab if (symsec->sec_shndx == symtab->symt_shndx)
d29b2c4438482eb00488be49a1f5d6835f455546ab break;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Issue error if the symbol table lacks an extended index section.
d29b2c4438482eb00488be49a1f5d6835f455546ab * The caller won't ask unless they encounter an SHN_XINDEX value,
d29b2c4438482eb00488be49a1f5d6835f455546ab * in which case the lack of the index section denotes a corrupt
d29b2c4438482eb00488be49a1f5d6835f455546ab * ELF file.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((ndx == obj_state->os_symtabnum) ||
d29b2c4438482eb00488be49a1f5d6835f455546ab (symtab->symt_xshndx == SHN_UNDEF))
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOXSHSEC),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(symsec->sec_shndx), symsec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Got it. Report to the user and return the necessary data */
d29b2c4438482eb00488be49a1f5d6835f455546ab xshndxsec = &obj_state->os_secarr[symtab->symt_xshndx];
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_FNDXSHNDX),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(symsec->sec_shndx), symsec->sec_name,
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(xshndxsec->sec_shndx), xshndxsec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab *xshndx = (Word *) xshndxsec->sec_data->d_buf;
d29b2c4438482eb00488be49a1f5d6835f455546ab *num = xshndxsec->sec_shdr->sh_size / xshndxsec->sec_shdr->sh_entsize;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (xshndxsec);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Locate the versym section associated with a symbol table section.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * obj_state - Object state for open object to query.
d29b2c4438482eb00488be49a1f5d6835f455546ab * symsec - Symbol table section for which extended index
d29b2c4438482eb00488be49a1f5d6835f455546ab * index section is required.
d29b2c4438482eb00488be49a1f5d6835f455546ab * versym - Address of variable to recieve pointer to section index
d29b2c4438482eb00488be49a1f5d6835f455546ab * array data buffer.
d29b2c4438482eb00488be49a1f5d6835f455546ab * numversym - Address of variable to receive number of indices
d29b2c4438482eb00488be49a1f5d6835f455546ab * referenced by ndx.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, returns versym section descriptor, and sets the
d29b2c4438482eb00488be49a1f5d6835f455546ab * variables referenced by versym, and numversym. On failure,
d29b2c4438482eb00488be49a1f5d6835f455546ab * does not return.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * note:
d29b2c4438482eb00488be49a1f5d6835f455546ab * Since the versym section index is found in the sec_versym field
d29b2c4438482eb00488be49a1f5d6835f455546ab * of the elfedit_section_t, the caller may be tempted to bypass this
d29b2c4438482eb00488be49a1f5d6835f455546ab * routine and access it directly. That temptation should be resisted,
d29b2c4438482eb00488be49a1f5d6835f455546ab * as this routine performs useful error checking, and also handles
d29b2c4438482eb00488be49a1f5d6835f455546ab * the issuing of the standard MSG_DEBUG messages.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_section_t *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_sec_getversym(elfedit_obj_state_t *obj_state,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *symsec, Versym **versym, Word *num)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *versymsec;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_symtab_t *symtab;
d29b2c4438482eb00488be49a1f5d6835f455546ab Word ndx;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Sanity check: symsec must be a symbol table */
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami (void) elfedit_sec_issymtab(obj_state, symsec, 1, NULL);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab symtab = obj_state->os_symtab;
d29b2c4438482eb00488be49a1f5d6835f455546ab for (ndx = 0; ndx < obj_state->os_symtabnum; ndx++, symtab++)
d29b2c4438482eb00488be49a1f5d6835f455546ab if (symsec->sec_shndx == symtab->symt_shndx)
d29b2c4438482eb00488be49a1f5d6835f455546ab break;
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Issue error if the symbol table lacks a versym section.
d29b2c4438482eb00488be49a1f5d6835f455546ab * The caller won't ask unless they see a non-null
d29b2c4438482eb00488be49a1f5d6835f455546ab * aux.symtab.sec_versym, so this should not be a problem.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((ndx == obj_state->os_symtabnum) ||
d29b2c4438482eb00488be49a1f5d6835f455546ab (symtab->symt_versym == SHN_UNDEF))
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOVERSYMSEC),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(symsec->sec_shndx), symsec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Got it. Report to the user and return the necessary data */
d29b2c4438482eb00488be49a1f5d6835f455546ab versymsec = &obj_state->os_secarr[symtab->symt_versym];
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_FNDVERSYM),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(symsec->sec_shndx), symsec->sec_name,
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(versymsec->sec_shndx), versymsec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab *versym = (Versym *) versymsec->sec_data->d_buf;
d29b2c4438482eb00488be49a1f5d6835f455546ab *num = versymsec->sec_shdr->sh_size / versymsec->sec_shdr->sh_entsize;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (versymsec);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Locate the string table specified by shndx for this object.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * entry:
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * obj_state - Object state.
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * shndx - Section index for string table section
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * allow_shflags - If False (0), only sections of type SHT_STRTAB
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * are accepted as being string tables, and any other type
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * will fail. If True (1), non-stringtable sections with
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * their SHF_STRINGS flag set are also accepted.
55ef6355bc6375ad080b10b10660e3528e2b7e6aab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * Returns section descriptor on success. On failure, does not return.
55ef6355bc6375ad080b10b10660e3528e2b7e6aab *
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * note:
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * At this time, we can only support SHF_STRINGS sections that
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * use single byte characters and which do not require alignment >1.
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * SHF_STRINGS sections that have multi-byte characters or alignment
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * are not currently supported and will draw an error even if
55ef6355bc6375ad080b10b10660e3528e2b7e6aab * allow_shflags is True.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_section_t *
55ef6355bc6375ad080b10b10660e3528e2b7e6aabelfedit_sec_getstr(elfedit_obj_state_t *obj_state, Word shndx,
55ef6355bc6375ad080b10b10660e3528e2b7e6aab int allow_shflags)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *strsec;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((shndx == 0) || (shndx >= obj_state->os_shnum))
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_STRSHNDX),
cce0e03bb2d07f0fe27cabb93acae9c23655859fab EC_WORD(shndx), EC_WORD(obj_state->os_shnum - 1));
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab strsec = &obj_state->os_secarr[shndx];
55ef6355bc6375ad080b10b10660e3528e2b7e6aab if (strsec->sec_shdr->sh_type == SHT_STRTAB) {
55ef6355bc6375ad080b10b10660e3528e2b7e6aab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_FNDSTRTAB),
55ef6355bc6375ad080b10b10660e3528e2b7e6aab EC_WORD(shndx), strsec->sec_name);
55ef6355bc6375ad080b10b10660e3528e2b7e6aab } else if (allow_shflags &&
55ef6355bc6375ad080b10b10660e3528e2b7e6aab ((strsec->sec_shdr->sh_flags & SHF_STRINGS) != 0) &&
55ef6355bc6375ad080b10b10660e3528e2b7e6aab (strsec->sec_shdr->sh_entsize <= 1) &&
55ef6355bc6375ad080b10b10660e3528e2b7e6aab (strsec->sec_shdr->sh_addralign <= 1)) {
55ef6355bc6375ad080b10b10660e3528e2b7e6aab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_FNDSTRTABFL),
55ef6355bc6375ad080b10b10660e3528e2b7e6aab EC_WORD(shndx), strsec->sec_name);
55ef6355bc6375ad080b10b10660e3528e2b7e6aab } else {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOTSTRSH),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(shndx), strsec->sec_name);
55ef6355bc6375ad080b10b10660e3528e2b7e6aab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab return (strsec);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Returns the offset of the specified string from within
d29b2c4438482eb00488be49a1f5d6835f455546ab * the given section.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * sec - Descriptor for section
d29b2c4438482eb00488be49a1f5d6835f455546ab * tail_ign - If non-zero, the # of characters at the end of the
d29b2c4438482eb00488be49a1f5d6835f455546ab * section that should be ignored and not searched.
d29b2c4438482eb00488be49a1f5d6835f455546ab * str - String we are looking for.
d29b2c4438482eb00488be49a1f5d6835f455546ab * ret_offset - Address of variable to receive result
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * Returns 1 for success, and 0 for failure. If successful, *ret_offset
d29b2c4438482eb00488be49a1f5d6835f455546ab * is set to the offset of the found string within the section.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abint
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_sec_findstr(elfedit_section_t *sec, Word tail_ign,
d29b2c4438482eb00488be49a1f5d6835f455546ab const char *str, Word *ret_offset)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab int str_fch = *str; /* First character in str */
d29b2c4438482eb00488be49a1f5d6835f455546ab Word len; /* # characters in table */
d29b2c4438482eb00488be49a1f5d6835f455546ab char *s; /* ptr to strings within table */
d29b2c4438482eb00488be49a1f5d6835f455546ab const char *tail; /* 1 past final character of table */
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Size of the section, minus the reserved part (if any) at the end */
d29b2c4438482eb00488be49a1f5d6835f455546ab len = sec->sec_shdr->sh_size - tail_ign;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Move through the section character by character looking for
d29b2c4438482eb00488be49a1f5d6835f455546ab * a match. Moving character by character instead of skipping
d29b2c4438482eb00488be49a1f5d6835f455546ab * from NULL terminated string to string allows us to use
d29b2c4438482eb00488be49a1f5d6835f455546ab * the tails longer strings (i.e. we want "bar", and "foobar" exists).
d29b2c4438482eb00488be49a1f5d6835f455546ab * We look at the first character manually before calling strcmp()
d29b2c4438482eb00488be49a1f5d6835f455546ab * to lower the cost of this approach.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab s = (char *)sec->sec_data->d_buf;
d29b2c4438482eb00488be49a1f5d6835f455546ab tail = s + len;
d29b2c4438482eb00488be49a1f5d6835f455546ab for (; s <= tail; s++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((*s == str_fch) && (strcmp(s, str) == 0)) {
d29b2c4438482eb00488be49a1f5d6835f455546ab *ret_offset = s - (char *)sec->sec_data->d_buf;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_DEBUG_EXISTSTR),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(sec->sec_shndx), sec->sec_name,
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(*ret_offset), s);
d29b2c4438482eb00488be49a1f5d6835f455546ab return (1);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Didn't find it. Report failure */
d29b2c4438482eb00488be49a1f5d6835f455546ab return (0);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Locate the DT_SUNW_STRPAD element of the given dynamic section if
d29b2c4438482eb00488be49a1f5d6835f455546ab * it exists.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * obj_state - Object state for open object to query.
d29b2c4438482eb00488be49a1f5d6835f455546ab * dynsec - Dynamic section descriptor
d29b2c4438482eb00488be49a1f5d6835f455546ab * dyn_strpad - Address of variable to receive the results.
d29b2c4438482eb00488be49a1f5d6835f455546ab * The caller is responsible for calling elfedit_dyn_elt_init()
d29b2c4438482eb00488be49a1f5d6835f455546ab * on this variable beforehand.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * The dynamic section is searched, and if a DT_SUNW_STRPAD element
d29b2c4438482eb00488be49a1f5d6835f455546ab * is found, dyn_strpad is updated via elfedit_dyn_elt_save() to
d29b2c4438482eb00488be49a1f5d6835f455546ab * reference it.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * Returns the final value of dyn_strpad->dn_seen.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abint
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahramielfedit_dynstr_getpad(elfedit_obj_state_t *obj_state, elfedit_section_t *dynsec,
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami elfedit_dyn_elt_t *dyn_strpad)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab Word numdyn = dynsec->sec_shdr->sh_size / dynsec->sec_shdr->sh_entsize;
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami Dyn *dyn = (Dyn *) dynsec->sec_data->d_buf;
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami Word i;
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami /*
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * DT_SUNW_STRPAD is specific to the Solaris OSABI.
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami * If the object is tagged otherwise, don't even look.
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami */
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami if (!elfedit_test_osabi(obj_state, ELFOSABI_SOLARIS, 0))
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami return (dyn_strpad->dn_seen);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Go through dynamic section tags and find the STRPAD entry */
d29b2c4438482eb00488be49a1f5d6835f455546ab for (i = 0; i < numdyn; i++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab if (dyn[i].d_tag == DT_SUNW_STRPAD) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_dyn_elt_save(dyn_strpad, i, &dyn[i]);
d29b2c4438482eb00488be49a1f5d6835f455546ab break;
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab return (dyn_strpad->dn_seen);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Given references to the dynamic section, its string table,
d29b2c4438482eb00488be49a1f5d6835f455546ab * and the DT_SUNW_STRPAD entry of the dynamic section, returns
d29b2c4438482eb00488be49a1f5d6835f455546ab * the offset of the specified string from within the given string table,
d29b2c4438482eb00488be49a1f5d6835f455546ab * adding it if possible.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * dynsec - Dynamic section descriptor
d29b2c4438482eb00488be49a1f5d6835f455546ab * strsec - Descriptor for string table assocated with dynamic section
d29b2c4438482eb00488be49a1f5d6835f455546ab * dyn_strpad - DT_SUNW_STRPAD element from dynamic section
d29b2c4438482eb00488be49a1f5d6835f455546ab * str - String we are looking for.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, the offset of the given string within the string
d29b2c4438482eb00488be49a1f5d6835f455546ab * table is returned. If the string does not exist within the table,
d29b2c4438482eb00488be49a1f5d6835f455546ab * but there is a valid DT_SUNW_STRPAD reserved section, then we
d29b2c4438482eb00488be49a1f5d6835f455546ab * add the string, and update the dynamic section STRPAD element
d29b2c4438482eb00488be49a1f5d6835f455546ab * to reflect the space we use.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * This routine does not return on failure.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abWord
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_dynstr_insert(elfedit_section_t *dynsec, elfedit_section_t *strsec,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_dyn_elt_t *dyn_strpad, const char *str)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab Word ins_off; /* Table offset to 1st reserved byte */
d29b2c4438482eb00488be49a1f5d6835f455546ab char *s; /* ptr to strings within table */
d29b2c4438482eb00488be49a1f5d6835f455546ab Word len; /* Length of str inc. NULL byte */
d29b2c4438482eb00488be49a1f5d6835f455546ab Word tail_ign; /* # reserved bytes at end of strtab */
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab tail_ign = dyn_strpad->dn_seen ? dyn_strpad->dn_dyn.d_un.d_val : 0;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Does the string already existin the string table? */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (elfedit_sec_findstr(strsec, tail_ign, str, &len))
d29b2c4438482eb00488be49a1f5d6835f455546ab return (len);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * The desired string does not already exist. Do we have
d29b2c4438482eb00488be49a1f5d6835f455546ab * room to add it?
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab len = strlen(str) + 1;
d29b2c4438482eb00488be49a1f5d6835f455546ab if (!dyn_strpad->dn_seen || (len > dyn_strpad->dn_dyn.d_un.d_val))
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOSTRPAD),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(strsec->sec_shdr->sh_link),
d29b2c4438482eb00488be49a1f5d6835f455546ab strsec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * We will add the string at the first byte of the reserved NULL
d29b2c4438482eb00488be49a1f5d6835f455546ab * area at the end. The DT_SUNW_STRPAD dynamic element gives us
d29b2c4438482eb00488be49a1f5d6835f455546ab * the size of that reserved space.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab ins_off = strsec->sec_shdr->sh_size - tail_ign;
d29b2c4438482eb00488be49a1f5d6835f455546ab s = ((char *)strsec->sec_data->d_buf) + ins_off;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Announce the operation */
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_ADDSTR),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(strsec->sec_shndx), strsec->sec_name,
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(ins_off), EC_WORD(len),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(dyn_strpad->dn_dyn.d_un.d_val), str);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Copy the string into the pad area at the end, and
d29b2c4438482eb00488be49a1f5d6835f455546ab * mark the data area as dirty so libelf will flush our
d29b2c4438482eb00488be49a1f5d6835f455546ab * changes to the string data.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab (void) strncpy(s, str, dyn_strpad->dn_dyn.d_un.d_val);
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_modified_data(strsec);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Update the DT_STRPAD dynamic entry */
d29b2c4438482eb00488be49a1f5d6835f455546ab dyn_strpad->dn_dyn.d_un.d_val -= len;
d29b2c4438482eb00488be49a1f5d6835f455546ab ((Dyn *) dynsec->sec_data->d_buf)[dyn_strpad->dn_ndx] =
d29b2c4438482eb00488be49a1f5d6835f455546ab dyn_strpad->dn_dyn;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_modified_data(dynsec);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab return (ins_off);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Test to see if a call to elfedit_strtab_insert() will succeed.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * obj_state - Object state for open object to query.
d29b2c4438482eb00488be49a1f5d6835f455546ab * strsec - Descriptor for string table
d29b2c4438482eb00488be49a1f5d6835f455546ab * dynsec - NULL, or descriptor for dynamic section. Providing
d29b2c4438482eb00488be49a1f5d6835f455546ab * a non-NULL value here will prevent elfedit_strtab_insert()
d29b2c4438482eb00488be49a1f5d6835f455546ab * from looking it up, and the duplicate debug message that
d29b2c4438482eb00488be49a1f5d6835f455546ab * would result.
d29b2c4438482eb00488be49a1f5d6835f455546ab * str - String we are looking for.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * If the string exists within the string table, or if an attempt
d29b2c4438482eb00488be49a1f5d6835f455546ab * to insert it will be successful, quietly return. Otherwise, throw
d29b2c4438482eb00488be49a1f5d6835f455546ab * the error elfedit_strtab_insert() would throw under the
d29b2c4438482eb00488be49a1f5d6835f455546ab * same circumstances.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_strtab_insert_test(elfedit_obj_state_t *obj_state,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *strsec, elfedit_section_t *dynsec, const char *str)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab Word len; /* Length of str inc. NULL byte */
d29b2c4438482eb00488be49a1f5d6835f455546ab int is_dynstr = 0;
d29b2c4438482eb00488be49a1f5d6835f455546ab Word tail_ign = 0;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * The dynstr is a special case, because we can add strings
d29b2c4438482eb00488be49a1f5d6835f455546ab * to it under certain circumstances. So, we look for the
d29b2c4438482eb00488be49a1f5d6835f455546ab * dynamic section, and if it exists, compare its sh_link to
d29b2c4438482eb00488be49a1f5d6835f455546ab * the string section index. If they match, it is the dynstr,
d29b2c4438482eb00488be49a1f5d6835f455546ab * and we use elfedit_dynstr_insert() to do the work.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (dynsec == NULL) {
d29b2c4438482eb00488be49a1f5d6835f455546ab if (obj_state->os_dynndx != SHN_UNDEF) {
d29b2c4438482eb00488be49a1f5d6835f455546ab dynsec = &obj_state->os_secarr[obj_state->os_dynndx];
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((dynsec->sec_shdr->sh_type == SHT_DYNAMIC) &&
d29b2c4438482eb00488be49a1f5d6835f455546ab (strsec->sec_shndx == dynsec->sec_shdr->sh_link)) {
d29b2c4438482eb00488be49a1f5d6835f455546ab is_dynstr = 1;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_DEBUG_FNDDYN),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(dynsec->sec_shndx),
d29b2c4438482eb00488be49a1f5d6835f455546ab dynsec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab } else {
d29b2c4438482eb00488be49a1f5d6835f455546ab if (strsec->sec_shndx == dynsec->sec_shdr->sh_link)
d29b2c4438482eb00488be49a1f5d6835f455546ab is_dynstr = 1;
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if (is_dynstr) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_dyn_elt_t dyn_strpad;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Determine the size of the STRPAD area, if any */
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_dyn_elt_init(&dyn_strpad);
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami if (elfedit_dynstr_getpad(obj_state, dynsec, &dyn_strpad) != 0)
d29b2c4438482eb00488be49a1f5d6835f455546ab tail_ign = dyn_strpad.dn_dyn.d_un.d_val;
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * If the string is already in the string table, we
d29b2c4438482eb00488be49a1f5d6835f455546ab * can't fail.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (elfedit_sec_findstr(strsec, tail_ign, str, &len) != 0)
d29b2c4438482eb00488be49a1f5d6835f455546ab return;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * It's not in the table, but if this is the dynstr, and
d29b2c4438482eb00488be49a1f5d6835f455546ab * there is enough room, we will be able to add it.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (is_dynstr && (tail_ign > strlen(str)))
d29b2c4438482eb00488be49a1f5d6835f455546ab return;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Can't do it. Issue error */
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOSTRPAD),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(strsec->sec_shdr->sh_link), strsec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Returns the offset of the specified string from within
d29b2c4438482eb00488be49a1f5d6835f455546ab * the given string table, adding it if possible.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * obj_state - Object state for open object to query.
d29b2c4438482eb00488be49a1f5d6835f455546ab * strsec - Descriptor for string table
d29b2c4438482eb00488be49a1f5d6835f455546ab * dynsec - NULL, or descriptor for dynamic section. Providing
d29b2c4438482eb00488be49a1f5d6835f455546ab * a non-NULL value here will prevent elfedit_strtab_insert()
d29b2c4438482eb00488be49a1f5d6835f455546ab * from looking it up, and the duplicate debug message that
d29b2c4438482eb00488be49a1f5d6835f455546ab * would result.
d29b2c4438482eb00488be49a1f5d6835f455546ab * str - String we are looking for.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, the offset of the given string within the string
d29b2c4438482eb00488be49a1f5d6835f455546ab * table is returned. If the string does not exist within the table,
d29b2c4438482eb00488be49a1f5d6835f455546ab * and it is possible to add it, elfedit_strtab_insert() will
d29b2c4438482eb00488be49a1f5d6835f455546ab * add the string, and then return the offset.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * If the string does not exist in the string table, and cannot
d29b2c4438482eb00488be49a1f5d6835f455546ab * be added, this routine issues an error message and does not
d29b2c4438482eb00488be49a1f5d6835f455546ab * return to the caller.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abWord
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_strtab_insert(elfedit_obj_state_t *obj_state, elfedit_section_t *strsec,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_section_t *dynsec, const char *str)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab Word len; /* Length of str inc. NULL byte */
d29b2c4438482eb00488be49a1f5d6835f455546ab int is_dynstr = 0;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_dyn_elt_t dyn_strpad;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * The dynstr is a special case, because we can add strings
d29b2c4438482eb00488be49a1f5d6835f455546ab * to it under certain circumstances. So, we look for the
d29b2c4438482eb00488be49a1f5d6835f455546ab * dynamic section, and if it exists, compare its sh_link to
d29b2c4438482eb00488be49a1f5d6835f455546ab * the string section index. If they match, it is the dynstr,
d29b2c4438482eb00488be49a1f5d6835f455546ab * and we use elfedit_dynstr_insert() to do the work.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (dynsec == NULL) {
d29b2c4438482eb00488be49a1f5d6835f455546ab if (obj_state->os_dynndx != SHN_UNDEF) {
d29b2c4438482eb00488be49a1f5d6835f455546ab dynsec = &obj_state->os_secarr[obj_state->os_dynndx];
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((dynsec->sec_shdr->sh_type == SHT_DYNAMIC) &&
d29b2c4438482eb00488be49a1f5d6835f455546ab (strsec->sec_shndx == dynsec->sec_shdr->sh_link)) {
d29b2c4438482eb00488be49a1f5d6835f455546ab is_dynstr = 1;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_DEBUG_FNDDYN),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(dynsec->sec_shndx),
d29b2c4438482eb00488be49a1f5d6835f455546ab dynsec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab } else {
d29b2c4438482eb00488be49a1f5d6835f455546ab if (strsec->sec_shndx == dynsec->sec_shdr->sh_link)
d29b2c4438482eb00488be49a1f5d6835f455546ab is_dynstr = 1;
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if (is_dynstr) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_dyn_elt_init(&dyn_strpad);
4f680cc668fa6cf678c531083400ade9a9c7934cAli Bahrami (void) elfedit_dynstr_getpad(obj_state, dynsec, &dyn_strpad);
d29b2c4438482eb00488be49a1f5d6835f455546ab return (elfedit_dynstr_insert(dynsec, strsec,
d29b2c4438482eb00488be49a1f5d6835f455546ab &dyn_strpad, str));
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * This is not the dynstr, so we are limited to strings that
d29b2c4438482eb00488be49a1f5d6835f455546ab * already exist within it. Try to find one.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (elfedit_sec_findstr(strsec, 0, str, &len))
d29b2c4438482eb00488be49a1f5d6835f455546ab return (len);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Can't do it. Issue error */
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOSTRPAD),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(strsec->sec_shdr->sh_link), strsec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab /*NOTREACHED*/
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab return (0);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Return the string found at the given offset within the specified
d29b2c4438482eb00488be49a1f5d6835f455546ab * string table.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * strsec - Section descriptor for string table section
d29b2c4438482eb00488be49a1f5d6835f455546ab * offset - Offset of desired string in string table
d29b2c4438482eb00488be49a1f5d6835f455546ab * msg_type - ELFEDIT_MSG_ type code to use with message
d29b2c4438482eb00488be49a1f5d6835f455546ab * issued if offset is out of range for the symbol table.
d29b2c4438482eb00488be49a1f5d6835f455546ab * debug_msg - True if should issue debug message for string found.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * If the offset is within the section, the string pointer
d29b2c4438482eb00488be49a1f5d6835f455546ab * is returned. Otherwise an error is issued using msg_type
d29b2c4438482eb00488be49a1f5d6835f455546ab * to determine the type of message. If this routine retains
d29b2c4438482eb00488be49a1f5d6835f455546ab * control after the message is issued, a safe string is returned.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abconst char *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_offset_to_str(elfedit_section_t *strsec, Word offset,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg_t msg_type, int debug_msg)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab const char *str;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Make sure it is a string table section */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (strsec->sec_shdr->sh_type != SHT_STRTAB)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOTSTRSH),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(strsec->sec_shndx), strsec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Ensure the offset is in range */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (offset >= strsec->sec_data->d_size) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(msg_type, MSG_INTL(MSG_ERR_BADSTROFF),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(strsec->sec_shndx), strsec->sec_name,
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(offset), EC_WORD(strsec->sec_data->d_size - 1));
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * If the msg_type is a type that returns, give the
d29b2c4438482eb00488be49a1f5d6835f455546ab * user a safe string to use.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab str = MSG_INTL(MSG_BADSYMOFFSETNAM);
d29b2c4438482eb00488be49a1f5d6835f455546ab } else {
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Return the string */
d29b2c4438482eb00488be49a1f5d6835f455546ab str = ((const char *)strsec->sec_data->d_buf) + offset;
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if (debug_msg)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_FNDSTR),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(strsec->sec_shndx), strsec->sec_name,
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(offset), str);
d29b2c4438482eb00488be49a1f5d6835f455546ab return (str);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Given a string table section, and a dynamic section entry
d29b2c4438482eb00488be49a1f5d6835f455546ab * that supplies a string offset, return the string found at
d29b2c4438482eb00488be49a1f5d6835f455546ab * the given offset. This routine is a convenience wrapper on
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit_offset_to_str().
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * As per elfedit_offset_to_str().
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abconst char *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_dyn_offset_to_str(elfedit_section_t *strsec, elfedit_dyn_elt_t *dynelt)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab return (elfedit_offset_to_str(strsec, dynelt->dn_dyn.d_un.d_val,
d29b2c4438482eb00488be49a1f5d6835f455546ab ELFEDIT_MSG_ERR, 0));
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Given a section, fabricate a string for the form:
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * "[#: name]"
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * as used at the beginning of debug messages. A pointer to static
d29b2c4438482eb00488be49a1f5d6835f455546ab * memory is returned, and is good until the next such call.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abconst char *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_sec_msgprefix(elfedit_section_t *sec)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab static char *buf;
d29b2c4438482eb00488be49a1f5d6835f455546ab static size_t bufsize;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab size_t need;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab need = 64 + strlen(sec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab if (need > bufsize) {
d29b2c4438482eb00488be49a1f5d6835f455546ab buf = elfedit_realloc(MSG_INTL(MSG_ALLOC_SECMSGPRE), buf, need);
d29b2c4438482eb00488be49a1f5d6835f455546ab bufsize = need;
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab (void) snprintf(buf, bufsize, MSG_ORIG(MSG_FMT_SECMSGPRE),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(sec->sec_shndx), sec->sec_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab return (buf);
d29b2c4438482eb00488be49a1f5d6835f455546ab}