1164190Sjkoshy/*- 2164190Sjkoshy * Copyright (c) 2006 Joseph Koshy 3164190Sjkoshy * All rights reserved. 4164190Sjkoshy * 5164190Sjkoshy * Redistribution and use in source and binary forms, with or without 6164190Sjkoshy * modification, are permitted provided that the following conditions 7164190Sjkoshy * are met: 8164190Sjkoshy * 1. Redistributions of source code must retain the above copyright 9164190Sjkoshy * notice, this list of conditions and the following disclaimer. 10164190Sjkoshy * 2. Redistributions in binary form must reproduce the above copyright 11164190Sjkoshy * notice, this list of conditions and the following disclaimer in the 12164190Sjkoshy * documentation and/or other materials provided with the distribution. 13164190Sjkoshy * 14164190Sjkoshy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15164190Sjkoshy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16164190Sjkoshy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17164190Sjkoshy * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18164190Sjkoshy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19164190Sjkoshy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20164190Sjkoshy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21164190Sjkoshy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22164190Sjkoshy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23164190Sjkoshy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24164190Sjkoshy * SUCH DAMAGE. 25164190Sjkoshy */ 26164190Sjkoshy 27164190Sjkoshy#include <sys/cdefs.h> 28164190Sjkoshy__FBSDID("$FreeBSD$"); 29164190Sjkoshy 30164190Sjkoshy#include <sys/limits.h> 31164190Sjkoshy 32164190Sjkoshy#include <assert.h> 33164190Sjkoshy#include <gelf.h> 34164190Sjkoshy#include <libelf.h> 35164190Sjkoshy#include <string.h> 36164190Sjkoshy 37164190Sjkoshy#include "_libelf.h" 38164190Sjkoshy 39164190SjkoshyElf32_Ehdr * 40164190Sjkoshyelf32_getehdr(Elf *e) 41164190Sjkoshy{ 42164190Sjkoshy return (_libelf_ehdr(e, ELFCLASS32, 0)); 43164190Sjkoshy} 44164190Sjkoshy 45164190SjkoshyElf64_Ehdr * 46164190Sjkoshyelf64_getehdr(Elf *e) 47164190Sjkoshy{ 48164190Sjkoshy return (_libelf_ehdr(e, ELFCLASS64, 0)); 49164190Sjkoshy} 50164190Sjkoshy 51164190SjkoshyGElf_Ehdr * 52164190Sjkoshygelf_getehdr(Elf *e, GElf_Ehdr *d) 53164190Sjkoshy{ 54164190Sjkoshy int ec; 55164190Sjkoshy Elf32_Ehdr *eh32; 56164190Sjkoshy Elf64_Ehdr *eh64; 57164190Sjkoshy 58164190Sjkoshy if (d == NULL || e == NULL || 59164190Sjkoshy ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { 60164190Sjkoshy LIBELF_SET_ERROR(ARGUMENT, 0); 61164190Sjkoshy return (NULL); 62164190Sjkoshy } 63164190Sjkoshy 64164190Sjkoshy if (ec == ELFCLASS32) { 65164190Sjkoshy if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL) 66164190Sjkoshy return (NULL); 67164190Sjkoshy 68164190Sjkoshy (void) memcpy(d->e_ident, eh32->e_ident, sizeof(eh32->e_ident)); 69164190Sjkoshy d->e_type = eh32->e_type; 70164190Sjkoshy d->e_machine = eh32->e_machine; 71164190Sjkoshy d->e_version = eh32->e_version; 72164190Sjkoshy d->e_entry = eh32->e_entry; 73164190Sjkoshy d->e_phoff = eh32->e_phoff; 74164190Sjkoshy d->e_shoff = eh32->e_shoff; 75164190Sjkoshy d->e_flags = eh32->e_flags; 76164190Sjkoshy d->e_ehsize = eh32->e_ehsize; 77164190Sjkoshy d->e_phentsize = eh32->e_phentsize; 78164190Sjkoshy d->e_phnum = eh32->e_phnum; 79164190Sjkoshy d->e_shentsize = eh32->e_shentsize; 80164190Sjkoshy d->e_shnum = eh32->e_shnum; 81164190Sjkoshy d->e_shstrndx = eh32->e_shstrndx; 82164190Sjkoshy 83164190Sjkoshy return (d); 84164190Sjkoshy } 85164190Sjkoshy 86164190Sjkoshy assert(ec == ELFCLASS64); 87164190Sjkoshy 88164190Sjkoshy if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL) 89164190Sjkoshy return (NULL); 90164190Sjkoshy *d = *eh64; 91164190Sjkoshy 92164190Sjkoshy return (d); 93164190Sjkoshy} 94164190Sjkoshy 95164190SjkoshyElf32_Ehdr * 96164190Sjkoshyelf32_newehdr(Elf *e) 97164190Sjkoshy{ 98164190Sjkoshy return (_libelf_ehdr(e, ELFCLASS32, 1)); 99164190Sjkoshy} 100164190Sjkoshy 101164190SjkoshyElf64_Ehdr * 102164190Sjkoshyelf64_newehdr(Elf *e) 103164190Sjkoshy{ 104164190Sjkoshy return (_libelf_ehdr(e, ELFCLASS64, 1)); 105164190Sjkoshy} 106164190Sjkoshy 107164190Sjkoshyvoid * 108164190Sjkoshygelf_newehdr(Elf *e, int ec) 109164190Sjkoshy{ 110164190Sjkoshy if (e != NULL && 111164190Sjkoshy (ec == ELFCLASS32 || ec == ELFCLASS64)) 112164190Sjkoshy return (_libelf_ehdr(e, ec, 1)); 113164190Sjkoshy 114164190Sjkoshy LIBELF_SET_ERROR(ARGUMENT, 0); 115164190Sjkoshy return (NULL); 116164190Sjkoshy} 117164190Sjkoshy 118164190Sjkoshyint 119164190Sjkoshygelf_update_ehdr(Elf *e, GElf_Ehdr *s) 120164190Sjkoshy{ 121164190Sjkoshy int ec; 122164190Sjkoshy void *ehdr; 123164190Sjkoshy Elf32_Ehdr *eh32; 124164190Sjkoshy Elf64_Ehdr *eh64; 125164190Sjkoshy 126164190Sjkoshy if (s== NULL || e == NULL || e->e_kind != ELF_K_ELF || 127164190Sjkoshy ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { 128164190Sjkoshy LIBELF_SET_ERROR(ARGUMENT, 0); 129164190Sjkoshy return (0); 130164190Sjkoshy } 131164190Sjkoshy 132164190Sjkoshy if (e->e_cmd == ELF_C_READ) { 133164190Sjkoshy LIBELF_SET_ERROR(MODE, 0); 134164190Sjkoshy return (0); 135164190Sjkoshy } 136164190Sjkoshy 137164190Sjkoshy if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) 138164190Sjkoshy return (0); 139164190Sjkoshy 140210325Skaiw (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); 141210325Skaiw 142164190Sjkoshy if (ec == ELFCLASS64) { 143164190Sjkoshy eh64 = (Elf64_Ehdr *) ehdr; 144164190Sjkoshy *eh64 = *s; 145164190Sjkoshy return (1); 146164190Sjkoshy } 147164190Sjkoshy 148164190Sjkoshy eh32 = (Elf32_Ehdr *) ehdr; 149164190Sjkoshy 150164190Sjkoshy (void) memcpy(eh32->e_ident, s->e_ident, sizeof(eh32->e_ident)); 151164190Sjkoshy 152164190Sjkoshy eh32->e_type = s->e_type; 153164190Sjkoshy eh32->e_machine = s->e_machine; 154164190Sjkoshy eh32->e_version = s->e_version; 155164190Sjkoshy LIBELF_COPY_U32(eh32, s, e_entry); 156164190Sjkoshy LIBELF_COPY_U32(eh32, s, e_phoff); 157164190Sjkoshy LIBELF_COPY_U32(eh32, s, e_shoff); 158164190Sjkoshy eh32->e_flags = s->e_flags; 159164190Sjkoshy eh32->e_ehsize = s->e_ehsize; 160164190Sjkoshy eh32->e_phentsize = s->e_phentsize; 161164190Sjkoshy eh32->e_phnum = s->e_phnum; 162164190Sjkoshy eh32->e_shentsize = s->e_shentsize; 163164190Sjkoshy eh32->e_shnum = s->e_shnum; 164164190Sjkoshy eh32->e_shstrndx = s->e_shstrndx; 165164190Sjkoshy 166164190Sjkoshy return (1); 167164190Sjkoshy} 168