11558Srgrimes/*- 21558Srgrimes * Copyright (c) 2006 Joseph Koshy 31558Srgrimes * All rights reserved. 41558Srgrimes * 51558Srgrimes * Redistribution and use in source and binary forms, with or without 61558Srgrimes * modification, are permitted provided that the following conditions 71558Srgrimes * are met: 81558Srgrimes * 1. Redistributions of source code must retain the above copyright 91558Srgrimes * notice, this list of conditions and the following disclaimer. 101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer in the 121558Srgrimes * documentation and/or other materials provided with the distribution. 131558Srgrimes * 141558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 151558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 161558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 181558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 201558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 241558Srgrimes * SUCH DAMAGE. 251558Srgrimes */ 261558Srgrimes 271558Srgrimes#include <sys/cdefs.h> 281558Srgrimes__FBSDID("$FreeBSD$"); 291558Srgrimes 301558Srgrimes#include <sys/limits.h> 3136997Scharnier 321558Srgrimes#include <assert.h> 3336997Scharnier#include <gelf.h> 3436997Scharnier#include <osreldate.h> 3550476Speter 361558Srgrimes#include "_libelf.h" 371558Srgrimes 381558Srgrimes#if __FreeBSD_version >= 700025 3971787Sphk 401558SrgrimesGElf_Move * 411558Srgrimesgelf_getmove(Elf_Data *d, int ndx, GElf_Move *dst) 421558Srgrimes{ 431558Srgrimes int ec; 441558Srgrimes Elf *e; 451558Srgrimes Elf_Scn *scn; 461558Srgrimes Elf32_Move *move32; 471558Srgrimes Elf64_Move *move64; 48103949Smike size_t msz; 491558Srgrimes uint32_t sh_type; 501558Srgrimes 511558Srgrimes if (d == NULL || ndx < 0 || dst == NULL || 5299562Siedowse (scn = d->d_scn) == NULL || 531558Srgrimes (e = scn->s_elf) == NULL) { 541558Srgrimes LIBELF_SET_ERROR(ARGUMENT, 0); 551558Srgrimes return (NULL); 5671787Sphk } 5771787Sphk 5871787Sphk ec = e->e_class; 5971787Sphk assert(ec == ELFCLASS32 || ec == ELFCLASS64); 6071787Sphk 611558Srgrimes if (ec == ELFCLASS32) 621558Srgrimes sh_type = scn->s_shdr.s_shdr32.sh_type; 631558Srgrimes else 6492837Simp sh_type = scn->s_shdr.s_shdr64.sh_type; 6592837Simp 6692837Simp if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { 6792837Simp LIBELF_SET_ERROR(ARGUMENT, 0); 681558Srgrimes return (NULL); 691558Srgrimes } 7092837Simp 711558Srgrimes msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); 721558Srgrimes 731558Srgrimes assert(msz > 0); 741558Srgrimes 751558Srgrimes if (msz * ndx >= d->d_size) { 7674873Sobrien LIBELF_SET_ERROR(ARGUMENT, 0); 771558Srgrimes return (NULL); 7874872Sobrien } 791558Srgrimes 801558Srgrimes if (ec == ELFCLASS32) { 811558Srgrimes 821558Srgrimes move32 = (Elf32_Move *) d->d_buf + ndx; 831558Srgrimes 841558Srgrimes dst->m_value = move32->m_value; 8574873Sobrien dst->m_info = (Elf64_Xword) move32->m_info; 861558Srgrimes dst->m_poffset = (Elf64_Xword) move32->m_poffset; 8774872Sobrien dst->m_repeat = move32->m_repeat; 881558Srgrimes dst->m_stride = move32->m_stride; 891558Srgrimes } else { 901558Srgrimes 911558Srgrimes move64 = (Elf64_Move *) d->d_buf + ndx; 921558Srgrimes 931558Srgrimes *dst = *move64; 941558Srgrimes } 951558Srgrimes 961558Srgrimes return (dst); 971558Srgrimes} 981558Srgrimes 991558Srgrimesint 1001558Srgrimesgelf_update_move(Elf_Data *d, int ndx, GElf_Move *gm) 1011558Srgrimes{ 10292837Simp int ec; 1031558Srgrimes Elf *e; 10486473Siedowse Elf_Scn *scn; 10586473Siedowse Elf32_Move *move32; 1061558Srgrimes Elf64_Move *move64; 1071558Srgrimes size_t msz; 1081558Srgrimes uint32_t sh_type; 1091558Srgrimes 1101558Srgrimes if (d == NULL || ndx < 0 || gm == NULL || 1111558Srgrimes (scn = d->d_scn) == NULL || 11271787Sphk (e = scn->s_elf) == NULL) { 1131558Srgrimes LIBELF_SET_ERROR(ARGUMENT, 0); 1141558Srgrimes return (0); 1151558Srgrimes } 1161558Srgrimes 1171558Srgrimes ec = e->e_class; 1181558Srgrimes assert(ec == ELFCLASS32 || ec == ELFCLASS64); 1191558Srgrimes 1201558Srgrimes if (ec == ELFCLASS32) 12171787Sphk sh_type = scn->s_shdr.s_shdr32.sh_type; 12271787Sphk else 1231558Srgrimes sh_type = scn->s_shdr.s_shdr64.sh_type; 1241558Srgrimes 1251558Srgrimes if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { 1261558Srgrimes LIBELF_SET_ERROR(ARGUMENT, 0); 12792837Simp return (0); 1281558Srgrimes } 12986473Siedowse 13086473Siedowse msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); 1311558Srgrimes assert(msz > 0); 1321558Srgrimes 1331558Srgrimes if (msz * ndx >= d->d_size) { 1341558Srgrimes LIBELF_SET_ERROR(ARGUMENT, 0); 135179275Smckusick return (0); 1361558Srgrimes } 1371558Srgrimes 1381558Srgrimes if (ec == ELFCLASS32) { 139179275Smckusick move32 = (Elf32_Move *) d->d_buf + ndx; 1401558Srgrimes 1411558Srgrimes move32->m_value = gm->m_value; 1421558Srgrimes LIBELF_COPY_U32(move32, gm, m_info); 1431558Srgrimes LIBELF_COPY_U32(move32, gm, m_poffset); 1441558Srgrimes move32->m_repeat = gm->m_repeat; 1451558Srgrimes move32->m_stride = gm->m_stride; 1461558Srgrimes 1471558Srgrimes } else { 1481558Srgrimes move64 = (Elf64_Move *) d->d_buf + ndx; 1491558Srgrimes 1501558Srgrimes *move64 = *gm; 15198542Smckusick } 1521558Srgrimes 15398542Smckusick return (1); 1541558Srgrimes} 1551558Srgrimes 1561558Srgrimes#endif /* __FreeBSD_version >= 700025 */ 1571558Srgrimes