1179337Syongari/* $NetBSD: gelf_move.c,v 1.5 2024/03/03 17:37:34 christos Exp $ */ 2179337Syongari 3179337Syongari/*- 4179337Syongari * Copyright (c) 2006,2008 Joseph Koshy 5179337Syongari * All rights reserved. 6179337Syongari * 7179337Syongari * Redistribution and use in source and binary forms, with or without 8179337Syongari * modification, are permitted provided that the following conditions 9179337Syongari * are met: 10179337Syongari * 1. Redistributions of source code must retain the above copyright 11179337Syongari * notice, this list of conditions and the following disclaimer. 12179337Syongari * 2. Redistributions in binary form must reproduce the above copyright 13179337Syongari * notice, this list of conditions and the following disclaimer in the 14179337Syongari * documentation and/or other materials provided with the distribution. 15179337Syongari * 16179337Syongari * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17179337Syongari * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18179337Syongari * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19179337Syongari * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20179337Syongari * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21179337Syongari * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22179337Syongari * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23179337Syongari * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24179337Syongari * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25179337Syongari * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26179337Syongari * SUCH DAMAGE. 27179337Syongari */ 28179337Syongari 29179337Syongari#if HAVE_NBTOOL_CONFIG_H 30179337Syongari# include "nbtool_config.h" 31179337Syongari#endif 32179337Syongari 33179337Syongari#include <sys/cdefs.h> 34179337Syongari 35179337Syongari#include <assert.h> 36179337Syongari#include <gelf.h> 37179337Syongari#include <limits.h> 38179337Syongari#include <stdint.h> 39179337Syongari 40179337Syongari#include "_libelf.h" 41179337Syongari 42182888Syongari__RCSID("$NetBSD: gelf_move.c,v 1.5 2024/03/03 17:37:34 christos Exp $"); 43182888SyongariELFTC_VCSID("Id: gelf_move.c 3977 2022-05-01 06:45:34Z jkoshy"); 44179337Syongari 45179337SyongariGElf_Move * 46179337Syongarigelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst) 47179337Syongari{ 48179337Syongari int ec; 49182888Syongari Elf *e; 50179337Syongari size_t msz; 51183814Syongari Elf_Scn *scn; 52183814Syongari uint32_t sh_type; 53179337Syongari Elf32_Move *move32; 54179337Syongari Elf64_Move *move64; 55179337Syongari struct _Libelf_Data *d; 56179337Syongari 57179337Syongari d = (struct _Libelf_Data *) ed; 58179337Syongari 59179337Syongari if (d == NULL || ndx < 0 || dst == NULL || 60179337Syongari (scn = d->d_scn) == NULL || 61179337Syongari (e = scn->s_elf) == NULL) { 62179337Syongari LIBELF_SET_ERROR(ARGUMENT, 0); 63179337Syongari return (NULL); 64179337Syongari } 65179337Syongari 66179337Syongari ec = e->e_class; 67179337Syongari assert(ec == ELFCLASS32 || ec == ELFCLASS64); 68179337Syongari 69179337Syongari if (ec == ELFCLASS32) 70179337Syongari sh_type = scn->s_shdr.s_shdr32.sh_type; 71179337Syongari else 72179337Syongari sh_type = scn->s_shdr.s_shdr64.sh_type; 73179337Syongari 74179337Syongari if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { 75179337Syongari LIBELF_SET_ERROR(ARGUMENT, 0); 76179337Syongari return (NULL); 77179337Syongari } 78179337Syongari 79179337Syongari if ((msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version)) == 0) 80179337Syongari return (NULL); 81179337Syongari 82179337Syongari assert(ndx >= 0); 83179337Syongari 84179337Syongari if (msz * (size_t) ndx >= d->d_data.d_size) { 85179337Syongari LIBELF_SET_ERROR(ARGUMENT, 0); 86179337Syongari return (NULL); 87179337Syongari } 88179337Syongari 89179337Syongari if (ec == ELFCLASS32) { 90179337Syongari 91179337Syongari move32 = (Elf32_Move *) d->d_data.d_buf + ndx; 92179337Syongari 93179337Syongari dst->m_value = move32->m_value; 94179337Syongari dst->m_info = (Elf64_Xword) move32->m_info; 95179337Syongari dst->m_poffset = (Elf64_Xword) move32->m_poffset; 96179337Syongari dst->m_repeat = move32->m_repeat; 97179337Syongari dst->m_stride = move32->m_stride; 98179337Syongari } else { 99179337Syongari 100179337Syongari move64 = (Elf64_Move *) d->d_data.d_buf + ndx; 101179337Syongari 102179337Syongari *dst = *move64; 103179337Syongari } 104179337Syongari 105179337Syongari return (dst); 106179337Syongari} 107179337Syongari 108179337Syongariint 109179337Syongarigelf_update_move(Elf_Data *ed, int ndx, GElf_Move *gm) 110179337Syongari{ 111179337Syongari int ec; 112179337Syongari Elf *e; 113179337Syongari size_t msz; 114179337Syongari Elf_Scn *scn; 115179337Syongari uint32_t sh_type; 116179337Syongari Elf32_Move *move32; 117179337Syongari Elf64_Move *move64; 118179337Syongari struct _Libelf_Data *d; 119179337Syongari 120179337Syongari d = (struct _Libelf_Data *) ed; 121179337Syongari 122179337Syongari if (d == NULL || ndx < 0 || gm == NULL || 123179337Syongari (scn = d->d_scn) == NULL || 124179337Syongari (e = scn->s_elf) == NULL) { 125179337Syongari LIBELF_SET_ERROR(ARGUMENT, 0); 126179337Syongari return (0); 127179337Syongari } 128179337Syongari 129179337Syongari ec = e->e_class; 130179337Syongari assert(ec == ELFCLASS32 || ec == ELFCLASS64); 131179337Syongari 132179337Syongari if (ec == ELFCLASS32) 133179337Syongari sh_type = scn->s_shdr.s_shdr32.sh_type; 134179337Syongari else 135179337Syongari sh_type = scn->s_shdr.s_shdr64.sh_type; 136179337Syongari 137179337Syongari if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { 138179337Syongari LIBELF_SET_ERROR(ARGUMENT, 0); 139179337Syongari return (0); 140179337Syongari } 141179337Syongari 142179337Syongari if ((msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version)) == 0) 143179337Syongari return (0); 144179337Syongari 145179337Syongari assert(ndx >= 0); 146179337Syongari 147179337Syongari if (msz * (size_t) ndx >= d->d_data.d_size) { 148179337Syongari LIBELF_SET_ERROR(ARGUMENT, 0); 149179337Syongari return (0); 150179337Syongari } 151179337Syongari 152179337Syongari if (ec == ELFCLASS32) { 153179337Syongari move32 = (Elf32_Move *) d->d_data.d_buf + ndx; 154179337Syongari 155179337Syongari move32->m_value = gm->m_value; 156179337Syongari LIBELF_COPY_U32(move32, gm, m_info); 157179337Syongari LIBELF_COPY_U32(move32, gm, m_poffset); 158179337Syongari move32->m_repeat = gm->m_repeat; 159179337Syongari move32->m_stride = gm->m_stride; 160179337Syongari 161179337Syongari } else { 162179337Syongari move64 = (Elf64_Move *) d->d_data.d_buf + ndx; 163179337Syongari 164179337Syongari *move64 = *gm; 165179337Syongari } 166179337Syongari 167179337Syongari return (1); 168179337Syongari} 169179337Syongari