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/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Use is subject to license terms.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab#pragma ident "%Z%%M% %I% %E% SMI"
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <stdlib.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <stdio.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <unistd.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <libintl.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <libelf.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <sys/machelf.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <link.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <strings.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <ctype.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <elfedit.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <_elfedit.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <sys/elf_SPARC.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <sys/elf_amd64.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab#include <msg.h>
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * This file contains utility functions that are of general use
d29b2c4438482eb00488be49a1f5d6835f455546ab * to different elfedit modules for solving common problems.
d29b2c4438482eb00488be49a1f5d6835f455546ab * The functions in this file are not ELFCLASS specific. Those
d29b2c4438482eb00488be49a1f5d6835f455546ab * functions are found in util_machelf.c
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * NOTE: This module contains functions with names
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit_atoi, and elfedit_atoui, that are otherwise identical.
d29b2c4438482eb00488be49a1f5d6835f455546ab * These functions are for signed, and unsigned integers, respectively.
d29b2c4438482eb00488be49a1f5d6835f455546ab * In general, I supply one comment header for each such pair,
d29b2c4438482eb00488be49a1f5d6835f455546ab * and put their implementations together.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * There are also functions with names elfedit_atoconst. These are
d29b2c4438482eb00488be49a1f5d6835f455546ab * convenience wrappers that use the corresponding elfedit_atoui()
d29b2c4438482eb00488be49a1f5d6835f455546ab * function to process an array of symbolic names provided by a call
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit_const_to_atoui().
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Given a value and an array of elfedit_ato[u]i items, return a pointer
d29b2c4438482eb00488be49a1f5d6835f455546ab * to the symbolic name for the value.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * sym - NULL terminated array of name->value mappings.
d29b2c4438482eb00488be49a1f5d6835f455546ab * value - Value to be found
d29b2c4438482eb00488be49a1f5d6835f455546ab * required - If True, and value is not found, an error is issued.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Callers should only set required to True when they know
d29b2c4438482eb00488be49a1f5d6835f455546ab * a priori that the value will be found --- the error
d29b2c4438482eb00488be49a1f5d6835f455546ab * is reported as an internal programming error.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * If the array contains an entry with the given value, the
d29b2c4438482eb00488be49a1f5d6835f455546ab * name for the first such entry will be returned.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * If no entry is found: If required is True (1), an error is
d29b2c4438482eb00488be49a1f5d6835f455546ab * issued and this routine does not return to the caller. If required
d29b2c4438482eb00488be49a1f5d6835f455546ab * is False (0), then NULL is returned.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abconst char *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoi_value_to_str(const elfedit_atoi_sym_t *sym, elfedit_atoi_t value,
d29b2c4438482eb00488be49a1f5d6835f455546ab int required)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab for (; sym->sym_name != NULL; sym++)
d29b2c4438482eb00488be49a1f5d6835f455546ab if (value == sym->sym_value)
d29b2c4438482eb00488be49a1f5d6835f455546ab return (sym->sym_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Value did not match any of the entries */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (required)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADGETVAL));
d29b2c4438482eb00488be49a1f5d6835f455546ab return (NULL);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abconst char *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoui_value_to_str(const elfedit_atoui_sym_t *sym,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoui_t value, int required)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab for (; sym->sym_name != NULL; sym++)
d29b2c4438482eb00488be49a1f5d6835f455546ab if (value == sym->sym_value)
d29b2c4438482eb00488be49a1f5d6835f455546ab return (sym->sym_name);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Value did not match any of the entries */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (required)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADGETVAL));
d29b2c4438482eb00488be49a1f5d6835f455546ab return (NULL);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abconst char *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoconst_value_to_str(elfedit_const_t const_type, elfedit_atoui_t value,
d29b2c4438482eb00488be49a1f5d6835f455546ab int required)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab return (elfedit_atoui_value_to_str(elfedit_const_to_atoui(const_type),
d29b2c4438482eb00488be49a1f5d6835f455546ab value, required));
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Process the symbolic name to value mappings passed to the
d29b2c4438482eb00488be49a1f5d6835f455546ab * atoi and atoui functions.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * sym - NULL terminated array of name->value mappings.
d29b2c4438482eb00488be49a1f5d6835f455546ab * value - Address of variable to recieve corresponding value.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * If a mapping is found, *value is set to it, and True is returned.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Otherwise False is returned.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abstatic int
d29b2c4438482eb00488be49a1f5d6835f455546abatoi_sym_process(const char *str, const elfedit_atoi_sym_t *sym,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoi_t *value)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab size_t cmp_len;
d29b2c4438482eb00488be49a1f5d6835f455546ab const char *tail;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab while (isspace(*str))
d29b2c4438482eb00488be49a1f5d6835f455546ab str++;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab tail = str + strlen(str);
d29b2c4438482eb00488be49a1f5d6835f455546ab while ((tail > str) && isspace(*(tail - 1)))
d29b2c4438482eb00488be49a1f5d6835f455546ab tail--;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab cmp_len = tail - str;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab for (; sym->sym_name != NULL; sym++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((strlen(sym->sym_name) == cmp_len) &&
d29b2c4438482eb00488be49a1f5d6835f455546ab (strncasecmp(sym->sym_name, str, cmp_len) == 0)) {
d29b2c4438482eb00488be49a1f5d6835f455546ab *value = sym->sym_value;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (1);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* No symbolic mapping was found */
d29b2c4438482eb00488be49a1f5d6835f455546ab return (0);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abstatic int
d29b2c4438482eb00488be49a1f5d6835f455546abatoui_sym_process(const char *str, const elfedit_atoui_sym_t *sym,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoui_t *value)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab size_t cmp_len;
d29b2c4438482eb00488be49a1f5d6835f455546ab const char *tail;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab while (isspace(*str))
d29b2c4438482eb00488be49a1f5d6835f455546ab str++;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab tail = str + strlen(str);
d29b2c4438482eb00488be49a1f5d6835f455546ab while ((tail > str) && isspace(*(tail - 1)))
d29b2c4438482eb00488be49a1f5d6835f455546ab tail--;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab cmp_len = tail - str;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab for (; sym->sym_name != NULL; sym++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((strlen(sym->sym_name) == cmp_len) &&
d29b2c4438482eb00488be49a1f5d6835f455546ab (strncasecmp(sym->sym_name, str, cmp_len) == 0)) {
d29b2c4438482eb00488be49a1f5d6835f455546ab *value = sym->sym_value;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (1);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* No symbolic mapping was found */
d29b2c4438482eb00488be49a1f5d6835f455546ab return (0);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * A command completion function for atoi and atoui mappings.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_cpl_atoi(void *cpldata, const elfedit_atoi_sym_t *sym)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab for (; sym->sym_name != NULL; sym++)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_cpl_match(cpldata, sym->sym_name, 1);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_cpl_atoui(void *cpldata, const elfedit_atoui_sym_t *sym)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab for (; sym->sym_name != NULL; sym++)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_cpl_match(cpldata, sym->sym_name, 1);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_cpl_atoconst(void *cpldata, elfedit_const_t const_type)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_cpl_atoui(cpldata, elfedit_const_to_atoui(const_type));
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Convert a string to a numeric value. Strings starting with '0'
d29b2c4438482eb00488be49a1f5d6835f455546ab * are taken to be octal, those staring with '0x' are hex, and all
d29b2c4438482eb00488be49a1f5d6835f455546ab * others are decimal.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * str - String to be converted
d29b2c4438482eb00488be49a1f5d6835f455546ab * sym - NULL, or NULL terminated array of name/value pairs.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * [elfedit_atoi2() and elfedit_atoui2() only]
d29b2c4438482eb00488be49a1f5d6835f455546ab * v - Address of variable to receive resulting value.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit_atoi2() and elfedit_atoui2():
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, returns True (1) and *v is set to the value.
d29b2c4438482eb00488be49a1f5d6835f455546ab * On failure, returns False (0) and *v is undefined.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit_atoi() and elfedit_atoui():
d29b2c4438482eb00488be49a1f5d6835f455546ab * If the string is convertable, the value is returned.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Otherwise an error is issued and this routine does
d29b2c4438482eb00488be49a1f5d6835f455546ab * not return to the caller.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abint
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoi2(const char *str, const elfedit_atoi_sym_t *sym, elfedit_atoi_t *v)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab char *endptr;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if (sym && atoi_sym_process(str, sym, v))
d29b2c4438482eb00488be49a1f5d6835f455546ab return (1);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab *v = strtoll(str, &endptr, 0);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If the left over part contains anything but whitespace, fail */
d29b2c4438482eb00488be49a1f5d6835f455546ab for (; *endptr; endptr++)
d29b2c4438482eb00488be49a1f5d6835f455546ab if (!isspace(*endptr))
d29b2c4438482eb00488be49a1f5d6835f455546ab return (0);
d29b2c4438482eb00488be49a1f5d6835f455546ab return (1);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoi_t
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoi(const char *str, const elfedit_atoi_sym_t *sym)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoi_t v;
d29b2c4438482eb00488be49a1f5d6835f455546ab if (elfedit_atoi2(str, sym, &v) == 0)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_ERR_BADATOISTR), str);
d29b2c4438482eb00488be49a1f5d6835f455546ab return (v);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abint
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoui2(const char *str, const elfedit_atoui_sym_t *sym,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoui_t *v)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab char *endptr;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if (sym && atoui_sym_process(str, sym, v))
d29b2c4438482eb00488be49a1f5d6835f455546ab return (1);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab *v = strtoull(str, &endptr, 0);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If the left over part contains anything but whitespace, fail */
d29b2c4438482eb00488be49a1f5d6835f455546ab for (; *endptr; endptr++)
d29b2c4438482eb00488be49a1f5d6835f455546ab if (!isspace(*endptr))
d29b2c4438482eb00488be49a1f5d6835f455546ab return (0);
d29b2c4438482eb00488be49a1f5d6835f455546ab return (1);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoui_t
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoui(const char *str, const elfedit_atoui_sym_t *sym)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoui_t v;
d29b2c4438482eb00488be49a1f5d6835f455546ab if (elfedit_atoui2(str, sym, &v) == 0)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_ERR_BADATOISTR), str);
d29b2c4438482eb00488be49a1f5d6835f455546ab return (v);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abint
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoconst2(const char *str, elfedit_const_t const_type,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoui_t *v)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab return (elfedit_atoui2(str, elfedit_const_to_atoui(const_type), v));
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoui_t
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoconst(const char *str, elfedit_const_t const_type)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab return (elfedit_atoui(str, elfedit_const_to_atoui(const_type)));
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Convert a string to a numeric value using elfedit_ato[u]i and
d29b2c4438482eb00488be49a1f5d6835f455546ab * ensure that the resulting value lies within a given range.
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit_ato[u]i_range() requires values to be in the range
d29b2c4438482eb00488be49a1f5d6835f455546ab * (min <= value <= max).
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * str - String to be converted
d29b2c4438482eb00488be49a1f5d6835f455546ab * min, max - If check_range is true, the allowed range that the
d29b2c4438482eb00488be49a1f5d6835f455546ab * resulting value must lie in.
d29b2c4438482eb00488be49a1f5d6835f455546ab * sym - NULL, or NULL terminated array of name/value pairs.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry [elfedit_atoi_range() and elfedit_atoui_range() only]:
d29b2c4438482eb00488be49a1f5d6835f455546ab * item_name - String describing item for which value is being read.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry [elfedit_atoi_range2() and elfedit_atoui_range2() only]:
d29b2c4438482eb00488be49a1f5d6835f455546ab * v - Address of variable to receive resulting value.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit_atoi_range2() and elfedit_atoui_range2():
d29b2c4438482eb00488be49a1f5d6835f455546ab * On success, returns True (1) and *v is set to the value.
d29b2c4438482eb00488be49a1f5d6835f455546ab * On failure, returns False (0) and *v is undefined.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit_atoi_range() and elfedit_atoui_range():
d29b2c4438482eb00488be49a1f5d6835f455546ab * If the string is convertable, the value is returned.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Otherwise an error is issued and this routine does
d29b2c4438482eb00488be49a1f5d6835f455546ab * not return to the caller.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abint
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoi_range2(const char *str, elfedit_atoi_t min, elfedit_atoi_t max,
d29b2c4438482eb00488be49a1f5d6835f455546ab const elfedit_atoi_sym_t *sym, elfedit_atoi_t *v)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab return ((elfedit_atoi2(str, sym, v) != 0) &&
d29b2c4438482eb00488be49a1f5d6835f455546ab (*v >= min) && (*v <= max));
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoi_t
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoi_range(const char *str, const char *item_name,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoi_t min, elfedit_atoi_t max, const elfedit_atoi_sym_t *sym)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoi_t v = elfedit_atoi(str, sym);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((v < min) || (v > max))
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_ATOIRANGE),
d29b2c4438482eb00488be49a1f5d6835f455546ab item_name, EC_XWORD(min), EC_XWORD(max), EC_XWORD(v));
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab return (v);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abint
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoui_range2(const char *str, elfedit_atoui_t min, elfedit_atoui_t max,
d29b2c4438482eb00488be49a1f5d6835f455546ab const elfedit_atoui_sym_t *sym, elfedit_atoui_t *v)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab return ((elfedit_atoui2(str, sym, v) != 0) &&
d29b2c4438482eb00488be49a1f5d6835f455546ab (*v >= min) && (*v <= max));
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoui_t
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoui_range(const char *str, const char *item_name,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoui_t min, elfedit_atoui_t max, const elfedit_atoui_sym_t *sym)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoui_t v = elfedit_atoui(str, sym);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((v < min) || (v > max))
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_ATOUIRANGE),
d29b2c4438482eb00488be49a1f5d6835f455546ab item_name, EC_XWORD(min), EC_XWORD(max), EC_XWORD(v));
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab return (v);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abint
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoconst_range2(const char *str, elfedit_atoui_t min,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoui_t max, elfedit_const_t const_type, elfedit_atoui_t *v)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab return (elfedit_atoui_range2(str, min, max,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_const_to_atoui(const_type), v));
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoui_t
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoconst_range(const char *str, const char *item_name,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoui_t min, elfedit_atoui_t max, elfedit_const_t const_type)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab return (elfedit_atoui_range(str, item_name, min, max,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_const_to_atoui(const_type)));
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Convenience wrapper on elfedit_atoui_range() that expects to see
d29b2c4438482eb00488be49a1f5d6835f455546ab * boolean values. Returns 1 for true, and 0 for false.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abint
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atobool(const char *str, const char *item_name)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab return (elfedit_atoconst_range(str, item_name, 0, 1,
d29b2c4438482eb00488be49a1f5d6835f455546ab ELFEDIT_CONST_BOOL) != 0);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Convenience wrapper on elfedit_atoui() to read a section index
d29b2c4438482eb00488be49a1f5d6835f455546ab * that understands the special SHN_ names.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * str - String to process
d29b2c4438482eb00488be49a1f5d6835f455546ab * shnum - Number of sections in the ELF file
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * If it is possible to convert str to a number, that value
d29b2c4438482eb00488be49a1f5d6835f455546ab * is returned. If the value is out of range for the file,
d29b2c4438482eb00488be49a1f5d6835f455546ab * a warning message to that effect is issued. On failure,
d29b2c4438482eb00488be49a1f5d6835f455546ab * an error is issued and this routine does not return to
d29b2c4438482eb00488be49a1f5d6835f455546ab * the caller.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoui_t
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atoshndx(const char *str, size_t shnum)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoui_t ndx;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab ndx = elfedit_atoconst(str, ELFEDIT_CONST_SHN);
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((ndx >= shnum) && ((ndx < SHN_LORESERVE) || (ndx > SHN_HIRESERVE)))
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_SHNDX_RANGE),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(ndx), EC_WORD(shnum-1));
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab return (ndx);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Convert an output style string into it's integer constant. This
d29b2c4438482eb00488be49a1f5d6835f455546ab * routine reports success/failure via the return value rather than
d29b2c4438482eb00488be49a1f5d6835f455546ab * by throwing errors so that it can be used to process command
d29b2c4438482eb00488be49a1f5d6835f455546ab * line options at program startup, before
d29b2c4438482eb00488be49a1f5d6835f455546ab * the elfedit framework is initialized.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abint
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_atooutstyle(const char *str, elfedit_outstyle_t *outstyle)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab int ret;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_atoui_t value;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab ret = atoui_sym_process(str,
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_const_to_atoui(ELFEDIT_CONST_OUTSTYLE), &value);
d29b2c4438482eb00488be49a1f5d6835f455546ab if (ret != 0)
d29b2c4438482eb00488be49a1f5d6835f455546ab *outstyle = value;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (ret);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Initialize a state block for processing by elfedit_getopt().
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * state - State block to initialize
d29b2c4438482eb00488be49a1f5d6835f455546ab * cmd_name - NULL, or name of command for which we are processing
d29b2c4438482eb00488be49a1f5d6835f455546ab * options.
d29b2c4438482eb00488be49a1f5d6835f455546ab * argc, argv - Address of variables giving number of options and
d29b2c4438482eb00488be49a1f5d6835f455546ab * access to the option strings.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * note:
d29b2c4438482eb00488be49a1f5d6835f455546ab * cmd_name can only be set to NULL when this routine is called
d29b2c4438482eb00488be49a1f5d6835f455546ab * by, or below, a currently active command. Otherwise, results
d29b2c4438482eb00488be49a1f5d6835f455546ab * are undefined (crashing or corruption) if there isn't one.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_getopt_init(elfedit_getopt_state_t *state,
d29b2c4438482eb00488be49a1f5d6835f455546ab int *argc, const char **argv[])
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfeditGC_cmd_t *cmd = elfedit_curcmd();
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_argc = argc;
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_argv = argv;
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_optarg = cmd->cmd_opt;
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_idmask = 0;
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_done = 0;
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_sglgrp = NULL;
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit-centric version of getopt()
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * state - Getopt state, which must have been previously initialized
d29b2c4438482eb00488be49a1f5d6835f455546ab * via a call to elfedit_getopt_init.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * If an option is matched, this routine returns a pointer to an
d29b2c4438482eb00488be49a1f5d6835f455546ab * elfedit_getopt_ret_t buffer (which comes from the storage used
d29b2c4438482eb00488be49a1f5d6835f455546ab * for state). If there are no more options to process, NULL is returned.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * Syntax errors are reported via elfedit_command_usage(), and this
d29b2c4438482eb00488be49a1f5d6835f455546ab * routine does not return to the caller.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * note:
d29b2c4438482eb00488be49a1f5d6835f455546ab * - The caller should not access the contents of state directly.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Those contents are private, and subject to change.
d29b2c4438482eb00488be49a1f5d6835f455546ab * - Once a call to this routine returns NULL, the argc/argv have
d29b2c4438482eb00488be49a1f5d6835f455546ab * have been ajusted so that they reference the plain arguments.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_getopt_ret_t *
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_getopt(elfedit_getopt_state_t *state)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_cmd_optarg_t *optarg;
d29b2c4438482eb00488be49a1f5d6835f455546ab const char *argstr;
d29b2c4438482eb00488be49a1f5d6835f455546ab int argc = *(state->go_argc);
d29b2c4438482eb00488be49a1f5d6835f455546ab const char **argv = *(state->go_argv);
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_optarg_item_t item;
d29b2c4438482eb00488be49a1f5d6835f455546ab struct {
d29b2c4438482eb00488be49a1f5d6835f455546ab int valid;
d29b2c4438482eb00488be49a1f5d6835f455546ab int is_outstyle;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_getopt_ret_t ret;
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_cmd_oa_mask_t excmask;
d29b2c4438482eb00488be49a1f5d6835f455546ab } sgl_with_value;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if (state->go_sglgrp == NULL) {
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Reasons to bail out immediately:
d29b2c4438482eb00488be49a1f5d6835f455546ab * - The command does not accept options
d29b2c4438482eb00488be49a1f5d6835f455546ab * - We've already reported the final option.
d29b2c4438482eb00488be49a1f5d6835f455546ab * - There are no more arguments.
d29b2c4438482eb00488be49a1f5d6835f455546ab * - The next argument does not start with '-'
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((state->go_optarg == NULL) || state->go_done ||
d29b2c4438482eb00488be49a1f5d6835f455546ab (argc <= 0) || (*(argv[0]) != '-')) {
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_done = 1;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (NULL);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab argstr = argv[0];
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* A '-' by itself is a syntax error */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (argstr[1] == '\0')
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_command_usage();
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* A '--' option means we should stop at this point */
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((argstr[1] == '-') && (argstr[2] == '\0')) {
d29b2c4438482eb00488be49a1f5d6835f455546ab (*state->go_argc)--;
d29b2c4438482eb00488be49a1f5d6835f455546ab (*state->go_argv)++;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (NULL);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * We have a string that starts with a '-'.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Does it match an option?
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab sgl_with_value.valid = 0;
d29b2c4438482eb00488be49a1f5d6835f455546ab for (optarg = state->go_optarg; optarg->oa_name != NULL; ) {
d29b2c4438482eb00488be49a1f5d6835f455546ab int is_outstyle =
d29b2c4438482eb00488be49a1f5d6835f455546ab (optarg->oa_flags & ELFEDIT_CMDOA_F_INHERIT) &&
d29b2c4438482eb00488be49a1f5d6835f455546ab (optarg->oa_name == ELFEDIT_STDOA_OPT_O);
d29b2c4438482eb00488be49a1f5d6835f455546ab int need_value;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_next_optarg(&optarg, &item);
d29b2c4438482eb00488be49a1f5d6835f455546ab need_value = item.oai_flags & ELFEDIT_CMDOA_F_VALUE;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * If the option is a single letter that accepts
d29b2c4438482eb00488be49a1f5d6835f455546ab * a value, then we allow the combined syntax
d29b2c4438482eb00488be49a1f5d6835f455546ab * -ovalue, where no space is reqired between the
d29b2c4438482eb00488be49a1f5d6835f455546ab * option flag and the value string.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((item.oai_name[2] == '\0') && need_value &&
d29b2c4438482eb00488be49a1f5d6835f455546ab (argstr[1] == item.oai_name[1]) &&
d29b2c4438482eb00488be49a1f5d6835f455546ab (argstr[2] != '\0')) {
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * We have a match. However, there may also
d29b2c4438482eb00488be49a1f5d6835f455546ab * be a straightforward match that we have
d29b2c4438482eb00488be49a1f5d6835f455546ab * not yet found. If so, we want to prefer that
d29b2c4438482eb00488be49a1f5d6835f455546ab * case over this one. So rather than return
d29b2c4438482eb00488be49a1f5d6835f455546ab * it immediately, we capture the information
d29b2c4438482eb00488be49a1f5d6835f455546ab * and keep looking. If nothing else surfaces,
d29b2c4438482eb00488be49a1f5d6835f455546ab * we'll use this later.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab sgl_with_value.valid = 1;
d29b2c4438482eb00488be49a1f5d6835f455546ab sgl_with_value.ret.gor_idmask = item.oai_idmask;
d29b2c4438482eb00488be49a1f5d6835f455546ab sgl_with_value.excmask = item.oai_excmask;
d29b2c4438482eb00488be49a1f5d6835f455546ab sgl_with_value.ret.gor_value = argstr + 2;
d29b2c4438482eb00488be49a1f5d6835f455546ab sgl_with_value.is_outstyle = is_outstyle;
d29b2c4438482eb00488be49a1f5d6835f455546ab continue;
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Try for a straightforward match */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (strcmp(argstr, item.oai_name) == 0) {
d29b2c4438482eb00488be49a1f5d6835f455546ab (*state->go_argc) = --argc;
d29b2c4438482eb00488be49a1f5d6835f455546ab (*state->go_argv) = ++argv;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Mutually exclusive option already seen? */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (item.oai_excmask & state->go_idmask)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_command_usage();
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Return the match */
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_idmask |= item.oai_idmask;
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_ret.gor_idmask = item.oai_idmask;
d29b2c4438482eb00488be49a1f5d6835f455546ab if (need_value) {
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If out of args, syntax error */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (argc <= 0)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_command_usage();
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_ret.gor_value = argv[0];
d29b2c4438482eb00488be49a1f5d6835f455546ab (*state->go_argc)--;
d29b2c4438482eb00488be49a1f5d6835f455546ab (*state->go_argv)++;
d29b2c4438482eb00488be49a1f5d6835f455546ab } else {
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_ret.gor_value = NULL;
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab if (is_outstyle)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_set_cmd_outstyle(
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_ret.gor_value);
d29b2c4438482eb00488be49a1f5d6835f455546ab return (&state->go_ret);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * No straightforward matches: Did we get a match with
d29b2c4438482eb00488be49a1f5d6835f455546ab * the special single letter and combined value? If so
d29b2c4438482eb00488be49a1f5d6835f455546ab * return that now.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (sgl_with_value.valid) {
d29b2c4438482eb00488be49a1f5d6835f455546ab (*state->go_argc)--;
d29b2c4438482eb00488be49a1f5d6835f455546ab (*state->go_argv)++;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Mutually exclusive option already seen? */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (sgl_with_value.excmask & state->go_idmask)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_command_usage();
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_idmask |= sgl_with_value.ret.gor_idmask;
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_ret = sgl_with_value.ret;
d29b2c4438482eb00488be49a1f5d6835f455546ab if (sgl_with_value.is_outstyle)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_set_cmd_outstyle(
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_ret.gor_value);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab return (&state->go_ret);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * If nothing above matched, make this option the single
d29b2c4438482eb00488be49a1f5d6835f455546ab * group string and see if the characters in it all match
d29b2c4438482eb00488be49a1f5d6835f455546ab * as single letter options without values.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_sglgrp = argstr + 1; /* Skip '-' */
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * If there is a single group string, take the first character
d29b2c4438482eb00488be49a1f5d6835f455546ab * and try to match it to an 1-letter option that does not
d29b2c4438482eb00488be49a1f5d6835f455546ab * require a value.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (state->go_sglgrp != NULL) {
d29b2c4438482eb00488be49a1f5d6835f455546ab int ch = *state->go_sglgrp++;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If that is the last character, clear single group mode */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (*state->go_sglgrp == '\0') {
d29b2c4438482eb00488be49a1f5d6835f455546ab (*state->go_argc)--;
d29b2c4438482eb00488be49a1f5d6835f455546ab (*state->go_argv)++;
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_sglgrp = NULL;
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab for (optarg = state->go_optarg; optarg->oa_name != NULL; ) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_next_optarg(&optarg, &item);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((item.oai_name[2] == '\0') &&
d29b2c4438482eb00488be49a1f5d6835f455546ab (ch == item.oai_name[1])) {
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * It matches. If the option requires a value
d29b2c4438482eb00488be49a1f5d6835f455546ab * then it cannot be in a group.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (item.oai_flags & ELFEDIT_CMDOA_F_VALUE)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_command_usage();
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Mutually exclusive option already seen? */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (item.oai_excmask & state->go_idmask)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_command_usage();
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Return the match */
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_idmask |= item.oai_idmask;
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_ret.gor_idmask = item.oai_idmask;
d29b2c4438482eb00488be49a1f5d6835f455546ab state->go_ret.gor_value = NULL;
d29b2c4438482eb00488be49a1f5d6835f455546ab return (&state->go_ret);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Nothing matched. We have a syntax error */
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_command_usage();
d29b2c4438482eb00488be49a1f5d6835f455546ab /*NOTREACHED*/
d29b2c4438482eb00488be49a1f5d6835f455546ab return (NULL);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Return the count of non-zero bits in the value v.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * v - Value to test
d29b2c4438482eb00488be49a1f5d6835f455546ab * sizeof_orig_v - The result of using the sizeof operator
d29b2c4438482eb00488be49a1f5d6835f455546ab * on the original value of v. The value received
d29b2c4438482eb00488be49a1f5d6835f455546ab * by this routine has been cast to an unsigned 64-bit
d29b2c4438482eb00488be49a1f5d6835f455546ab * integer, so having the caller use sizeof allows us to
d29b2c4438482eb00488be49a1f5d6835f455546ab * avoid testing bits that were not in the original.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abint
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_bits_set(u_longlong_t v, int sizeof_orig_v)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab int nbits = sizeof_orig_v * 8;
d29b2c4438482eb00488be49a1f5d6835f455546ab int mask;
d29b2c4438482eb00488be49a1f5d6835f455546ab int cnt = 0;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab for (mask = 1; (nbits-- > 0) && (cnt < 2); mask *= 2)
d29b2c4438482eb00488be49a1f5d6835f455546ab if (v & mask)
d29b2c4438482eb00488be49a1f5d6835f455546ab cnt++;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab return (cnt);
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * "delete" items in an array by copying the following items up
d29b2c4438482eb00488be49a1f5d6835f455546ab * over the "deleted" items and then zero filling the vacated
d29b2c4438482eb00488be49a1f5d6835f455546ab * slots at the bottom.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * name_str - Array identification prefix to use for debug message
d29b2c4438482eb00488be49a1f5d6835f455546ab * data_start - Address of 1st byte in array
d29b2c4438482eb00488be49a1f5d6835f455546ab * entsize - sizeof a single element of the array
d29b2c4438482eb00488be49a1f5d6835f455546ab * num_ent - # of elements in array
d29b2c4438482eb00488be49a1f5d6835f455546ab * start_ndx - Index of first item to be deleted
d29b2c4438482eb00488be49a1f5d6835f455546ab * cnt - # of items to delete
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * Any errors are issued and control does not return to the
d29b2c4438482eb00488be49a1f5d6835f455546ab * caller. On success, the items have been removed, zero filling
d29b2c4438482eb00488be49a1f5d6835f455546ab * has been done, and debug messages issued.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_array_elts_delete(const char *name_str, void *data_start,
d29b2c4438482eb00488be49a1f5d6835f455546ab size_t entsize, size_t num_ent, size_t start_ndx, size_t cnt)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab char *data = data_start;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* The specified index and range must be in bounds */
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((start_ndx + cnt) > num_ent)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_ARRBNDS),
d29b2c4438482eb00488be49a1f5d6835f455546ab name_str, EC_WORD(num_ent), EC_WORD(num_ent - 1));
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Everything below the deleted items moves up.
d29b2c4438482eb00488be49a1f5d6835f455546ab * Note that bcopy() is documented to handle overlapping
d29b2c4438482eb00488be49a1f5d6835f455546ab * src/dst correctly, so we make no effort to handle this
d29b2c4438482eb00488be49a1f5d6835f455546ab * element by element, but issue a single operation.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * If we're doing the last element, there is nothing to
d29b2c4438482eb00488be49a1f5d6835f455546ab * move up, and we skip this step, moving on to the zeroing below.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (start_ndx < (num_ent - 1)) {
d29b2c4438482eb00488be49a1f5d6835f455546ab size_t ncpy = num_ent - (start_ndx + cnt);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab bcopy(data + ((start_ndx + cnt) * entsize),
d29b2c4438482eb00488be49a1f5d6835f455546ab data + (start_ndx * entsize), ncpy * entsize);
d29b2c4438482eb00488be49a1f5d6835f455546ab if (ncpy == 1) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_DEBUG_ARRCPY_1), name_str,
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(start_ndx + cnt), EC_WORD(start_ndx));
d29b2c4438482eb00488be49a1f5d6835f455546ab } else {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_DEBUG_ARRCPY_N), name_str,
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(start_ndx + cnt),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(start_ndx + cnt + ncpy - 1),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(start_ndx),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(start_ndx + ncpy - 1));
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Zero out the vacated elements at the end */
d29b2c4438482eb00488be49a1f5d6835f455546ab bzero(data + ((num_ent - cnt) * entsize), entsize * cnt);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if (cnt == 1) {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_ARRZERO_1),
d29b2c4438482eb00488be49a1f5d6835f455546ab name_str, EC_WORD(num_ent - 1));
d29b2c4438482eb00488be49a1f5d6835f455546ab } else {
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_ARRZERO_N),
d29b2c4438482eb00488be49a1f5d6835f455546ab name_str, EC_WORD(num_ent - cnt),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(num_ent - 1), EC_WORD(cnt));
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab}
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab/*
d29b2c4438482eb00488be49a1f5d6835f455546ab * move the location of items in an array by shifting the surround
d29b2c4438482eb00488be49a1f5d6835f455546ab * items into the vacated hole and them putting the values into
d29b2c4438482eb00488be49a1f5d6835f455546ab * the new location.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * entry:
d29b2c4438482eb00488be49a1f5d6835f455546ab * name_str - Array identification prefix to use for debug message
d29b2c4438482eb00488be49a1f5d6835f455546ab * data_start - Address of 1st byte in array
d29b2c4438482eb00488be49a1f5d6835f455546ab * entsize - sizeof a single element of the array
d29b2c4438482eb00488be49a1f5d6835f455546ab * num_ent - # of elements in array
d29b2c4438482eb00488be49a1f5d6835f455546ab * start_ndx - Index of first item to be moved
d29b2c4438482eb00488be49a1f5d6835f455546ab * dst_ndx - Index to receive the moved block
d29b2c4438482eb00488be49a1f5d6835f455546ab * cnt - # of items to move
d29b2c4438482eb00488be49a1f5d6835f455546ab * scr_item - Space allocated by the caller sufficient to hold
d29b2c4438482eb00488be49a1f5d6835f455546ab * one item from the array. Used to swap elements.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * exit:
d29b2c4438482eb00488be49a1f5d6835f455546ab * Any errors are issued and control does not return to the
d29b2c4438482eb00488be49a1f5d6835f455546ab * caller. On success, the items have been moved, and debug
d29b2c4438482eb00488be49a1f5d6835f455546ab * messages issued.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546abvoid
d29b2c4438482eb00488be49a1f5d6835f455546abelfedit_array_elts_move(const char *name_str, void *data_start,
d29b2c4438482eb00488be49a1f5d6835f455546ab size_t entsize, size_t num_ent, size_t srcndx,
d29b2c4438482eb00488be49a1f5d6835f455546ab size_t dstndx, size_t cnt, void *scr_item)
d29b2c4438482eb00488be49a1f5d6835f455546ab{
d29b2c4438482eb00488be49a1f5d6835f455546ab char *data = data_start;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* The specified source and destination ranges must be in bounds */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (((srcndx + cnt) > num_ent) || ((dstndx + cnt) > num_ent))
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_ARRBNDS),
d29b2c4438482eb00488be49a1f5d6835f455546ab name_str, EC_WORD(num_ent), EC_WORD(num_ent - 1));
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /* If source and destination are same, there's nothing to do */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (srcndx == dstndx)
d29b2c4438482eb00488be49a1f5d6835f455546ab return;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * It is meaningless to do a move where the source and destination
d29b2c4438482eb00488be49a1f5d6835f455546ab * are overlapping, because this "move" amounts to shifting
d29b2c4438482eb00488be49a1f5d6835f455546ab * the existing items around into a new position. If there is
d29b2c4438482eb00488be49a1f5d6835f455546ab * more than one element, then overlap is possible and we need
d29b2c4438482eb00488be49a1f5d6835f455546ab * to test for it.
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab if (cnt > 1) {
d29b2c4438482eb00488be49a1f5d6835f455546ab size_t low, hi;
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if (srcndx > dstndx) {
d29b2c4438482eb00488be49a1f5d6835f455546ab low = dstndx;
d29b2c4438482eb00488be49a1f5d6835f455546ab hi = srcndx;
d29b2c4438482eb00488be49a1f5d6835f455546ab } else {
d29b2c4438482eb00488be49a1f5d6835f455546ab low = srcndx;
d29b2c4438482eb00488be49a1f5d6835f455546ab hi = dstndx;
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab /* Ensure that the src and dst don't overlap */
d29b2c4438482eb00488be49a1f5d6835f455546ab if ((low + cnt) > hi)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_ERR,
d29b2c4438482eb00488be49a1f5d6835f455546ab MSG_INTL(MSG_ERR_ARRMVOVERLAP), name_str,
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(srcndx), EC_WORD(srcndx + cnt - 1),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(dstndx), EC_WORD(dstndx + cnt - 1));
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if (cnt == 1)
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_ARRMOVE_1),
d29b2c4438482eb00488be49a1f5d6835f455546ab name_str, EC_WORD(srcndx), EC_WORD(dstndx));
d29b2c4438482eb00488be49a1f5d6835f455546ab else
d29b2c4438482eb00488be49a1f5d6835f455546ab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_ARRMOVE_N),
d29b2c4438482eb00488be49a1f5d6835f455546ab name_str, EC_WORD(cnt),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(srcndx), EC_WORD(srcndx + cnt - 1),
d29b2c4438482eb00488be49a1f5d6835f455546ab EC_WORD(dstndx), EC_WORD(dstndx + cnt - 1));
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab if (srcndx < dstndx) {
d29b2c4438482eb00488be49a1f5d6835f455546ab srcndx += cnt - 1;
d29b2c4438482eb00488be49a1f5d6835f455546ab dstndx += cnt - 1;
d29b2c4438482eb00488be49a1f5d6835f455546ab for (; cnt-- > 0; srcndx--, dstndx--) {
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Copy item at srcndx to scratch location
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * save = dyn[srcndx];
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab bcopy(data + (srcndx * entsize), scr_item, entsize);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Shift items after source up through destination
d29b2c4438482eb00488be49a1f5d6835f455546ab * to source. bcopy() handles overlapped copies.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * for (i = srcndx; i < dstndx; i++)
d29b2c4438482eb00488be49a1f5d6835f455546ab * dyn[i] = dyn[i + 1];
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab bcopy(data + ((srcndx + 1) * entsize),
d29b2c4438482eb00488be49a1f5d6835f455546ab data + (srcndx * entsize),
d29b2c4438482eb00488be49a1f5d6835f455546ab (dstndx - srcndx) * entsize);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Copy saved item into destination slot
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * dyn[dstndx] = save;
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab bcopy(scr_item, data + (dstndx * entsize), entsize);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab } else {
d29b2c4438482eb00488be49a1f5d6835f455546ab for (; cnt-- > 0; srcndx++, dstndx++) {
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Copy item at srcndx to scratch location
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * save = dyn[srcndx];
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab bcopy(data + (srcndx * entsize), scr_item, entsize);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Shift items from destination through item below
d29b2c4438482eb00488be49a1f5d6835f455546ab * source up one. bcopy() handles overlapped copies.
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * for (i = srcndx; i > dstndx; i--)
d29b2c4438482eb00488be49a1f5d6835f455546ab * dyn[i] = dyn[i - 1];
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab bcopy(data + (dstndx * entsize),
d29b2c4438482eb00488be49a1f5d6835f455546ab data + ((dstndx + 1) * entsize),
d29b2c4438482eb00488be49a1f5d6835f455546ab (srcndx - dstndx) * entsize);
d29b2c4438482eb00488be49a1f5d6835f455546ab
d29b2c4438482eb00488be49a1f5d6835f455546ab /*
d29b2c4438482eb00488be49a1f5d6835f455546ab * Copy saved item into destination slot
d29b2c4438482eb00488be49a1f5d6835f455546ab *
d29b2c4438482eb00488be49a1f5d6835f455546ab * dyn[dstndx] = save;
d29b2c4438482eb00488be49a1f5d6835f455546ab */
d29b2c4438482eb00488be49a1f5d6835f455546ab bcopy(scr_item, data + (dstndx * entsize), entsize);
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab }
d29b2c4438482eb00488be49a1f5d6835f455546ab}