1165535Sjkoshy/*- 2165535Sjkoshy * Copyright (c) 2006 Joseph Koshy 3165535Sjkoshy * All rights reserved. 4165535Sjkoshy * 5165535Sjkoshy * Redistribution and use in source and binary forms, with or without 6165535Sjkoshy * modification, are permitted provided that the following conditions 7165535Sjkoshy * are met: 8165535Sjkoshy * 1. Redistributions of source code must retain the above copyright 9165535Sjkoshy * notice, this list of conditions and the following disclaimer. 10165535Sjkoshy * 2. Redistributions in binary form must reproduce the above copyright 11165535Sjkoshy * notice, this list of conditions and the following disclaimer in the 12165535Sjkoshy * documentation and/or other materials provided with the distribution. 13165535Sjkoshy * 14165535Sjkoshy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15165535Sjkoshy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16165535Sjkoshy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17165535Sjkoshy * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18165535Sjkoshy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19165535Sjkoshy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20165535Sjkoshy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21165535Sjkoshy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22165535Sjkoshy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23165535Sjkoshy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24165535Sjkoshy * SUCH DAMAGE. 25165535Sjkoshy */ 26165535Sjkoshy 27165535Sjkoshy#include <sys/cdefs.h> 28165535Sjkoshy__FBSDID("$FreeBSD$"); 29165535Sjkoshy 30165535Sjkoshy#include <assert.h> 31165535Sjkoshy#include <libelf.h> 32165535Sjkoshy 33165535Sjkoshy#include "_libelf.h" 34165535Sjkoshy 35165535Sjkoshy/* 36165535Sjkoshy * Retrieve section #0, allocating a new section if needed. 37165535Sjkoshy */ 38165535Sjkoshystatic Elf_Scn * 39165535Sjkoshy_libelf_getscn0(Elf *e) 40165535Sjkoshy{ 41165535Sjkoshy Elf_Scn *s; 42165535Sjkoshy 43165535Sjkoshy if ((s = STAILQ_FIRST(&e->e_u.e_elf.e_scn)) != NULL) 44165535Sjkoshy return (s); 45165535Sjkoshy 46165535Sjkoshy return (_libelf_allocate_scn(e, (size_t) SHN_UNDEF)); 47165535Sjkoshy} 48165535Sjkoshy 49165535Sjkoshyint 50165535Sjkoshy_libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum) 51165535Sjkoshy{ 52165535Sjkoshy Elf_Scn *scn; 53165535Sjkoshy 54165535Sjkoshy if (shnum >= SHN_LORESERVE) { 55165535Sjkoshy if ((scn = _libelf_getscn0(e)) == NULL) 56165535Sjkoshy return (0); 57165535Sjkoshy 58165535Sjkoshy assert(scn->s_ndx == SHN_UNDEF); 59165535Sjkoshy 60165535Sjkoshy if (ec == ELFCLASS32) 61165535Sjkoshy scn->s_shdr.s_shdr32.sh_size = shnum; 62165535Sjkoshy else 63165535Sjkoshy scn->s_shdr.s_shdr64.sh_size = shnum; 64165535Sjkoshy 65165535Sjkoshy (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); 66165535Sjkoshy 67165535Sjkoshy shnum = 0; 68165535Sjkoshy } 69165535Sjkoshy 70165535Sjkoshy if (ec == ELFCLASS32) 71165535Sjkoshy ((Elf32_Ehdr *) eh)->e_shnum = shnum; 72165535Sjkoshy else 73165535Sjkoshy ((Elf64_Ehdr *) eh)->e_shnum = shnum; 74165535Sjkoshy 75165535Sjkoshy 76165535Sjkoshy return (1); 77165535Sjkoshy} 78165535Sjkoshy 79165535Sjkoshyint 80165535Sjkoshy_libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx) 81165535Sjkoshy{ 82165535Sjkoshy Elf_Scn *scn; 83165535Sjkoshy 84165535Sjkoshy if (shstrndx >= SHN_LORESERVE) { 85165535Sjkoshy if ((scn = _libelf_getscn0(e)) == NULL) 86165535Sjkoshy return (0); 87165535Sjkoshy 88165535Sjkoshy assert(scn->s_ndx == SHN_UNDEF); 89165535Sjkoshy 90165535Sjkoshy if (ec == ELFCLASS32) 91165535Sjkoshy scn->s_shdr.s_shdr32.sh_link = shstrndx; 92165535Sjkoshy else 93165535Sjkoshy scn->s_shdr.s_shdr64.sh_link = shstrndx; 94165535Sjkoshy 95165535Sjkoshy (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); 96165535Sjkoshy 97165535Sjkoshy shstrndx = SHN_XINDEX; 98165535Sjkoshy } 99165535Sjkoshy 100165535Sjkoshy if (ec == ELFCLASS32) 101165535Sjkoshy ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx; 102165535Sjkoshy else 103165535Sjkoshy ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx; 104165535Sjkoshy 105165535Sjkoshy return (1); 106165535Sjkoshy} 107165535Sjkoshy 108165535Sjkoshyint 109165535Sjkoshy_libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum) 110165535Sjkoshy{ 111165535Sjkoshy Elf_Scn *scn; 112165535Sjkoshy 113165535Sjkoshy if (phnum >= PN_XNUM) { 114165535Sjkoshy if ((scn = _libelf_getscn0(e)) == NULL) 115165535Sjkoshy return (0); 116165535Sjkoshy 117165535Sjkoshy assert(scn->s_ndx == SHN_UNDEF); 118165535Sjkoshy 119165535Sjkoshy if (ec == ELFCLASS32) 120165535Sjkoshy scn->s_shdr.s_shdr32.sh_info = phnum; 121165535Sjkoshy else 122165535Sjkoshy scn->s_shdr.s_shdr64.sh_info = phnum; 123165535Sjkoshy 124165535Sjkoshy (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); 125165535Sjkoshy 126165535Sjkoshy phnum = PN_XNUM; 127165535Sjkoshy } 128165535Sjkoshy 129165535Sjkoshy if (ec == ELFCLASS32) 130165535Sjkoshy ((Elf32_Ehdr *) eh)->e_phnum = phnum; 131165535Sjkoshy else 132165535Sjkoshy ((Elf64_Ehdr *) eh)->e_phnum = phnum; 133165535Sjkoshy 134165535Sjkoshy return (1); 135165535Sjkoshy} 136165535Sjkoshy 137