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/* 28164190Sjkoshy * Internal APIs 29164190Sjkoshy */ 30164190Sjkoshy 31164190Sjkoshy#include <sys/cdefs.h> 32164190Sjkoshy__FBSDID("$FreeBSD$"); 33164190Sjkoshy 34164190Sjkoshy#include <sys/errno.h> 35164190Sjkoshy 36164190Sjkoshy#include <assert.h> 37164190Sjkoshy#include <libelf.h> 38164190Sjkoshy#include <stdlib.h> 39164190Sjkoshy#include <string.h> 40164190Sjkoshy 41164190Sjkoshy#include "_libelf.h" 42164190Sjkoshy 43164190SjkoshyElf * 44164190Sjkoshy_libelf_allocate_elf(void) 45164190Sjkoshy{ 46164190Sjkoshy Elf *e; 47164190Sjkoshy 48164190Sjkoshy if ((e = malloc(sizeof(*e))) == NULL) { 49164190Sjkoshy LIBELF_SET_ERROR(RESOURCE, errno); 50164190Sjkoshy return NULL; 51164190Sjkoshy } 52164190Sjkoshy 53164190Sjkoshy e->e_activations = 1; 54164190Sjkoshy e->e_arhdr = NULL; 55164190Sjkoshy e->e_byteorder = ELFDATANONE; 56164190Sjkoshy e->e_class = ELFCLASSNONE; 57164190Sjkoshy e->e_cmd = ELF_C_NULL; 58164190Sjkoshy e->e_fd = -1; 59164190Sjkoshy e->e_flags = 0; 60164190Sjkoshy e->e_kind = ELF_K_NONE; 61164190Sjkoshy e->e_parent = NULL; 62164190Sjkoshy e->e_rawfile = NULL; 63164190Sjkoshy e->e_rawsize = 0; 64164190Sjkoshy e->e_version = LIBELF_PRIVATE(version); 65164190Sjkoshy 66164190Sjkoshy (void) memset(&e->e_u, 0, sizeof(e->e_u)); 67164190Sjkoshy 68164190Sjkoshy return (e); 69164190Sjkoshy} 70164190Sjkoshy 71164190Sjkoshyvoid 72164190Sjkoshy_libelf_init_elf(Elf *e, Elf_Kind kind) 73164190Sjkoshy{ 74164190Sjkoshy assert(e != NULL); 75164190Sjkoshy assert(e->e_kind == ELF_K_NONE); 76164190Sjkoshy 77164190Sjkoshy e->e_kind = kind; 78164190Sjkoshy 79164190Sjkoshy switch (kind) { 80164190Sjkoshy case ELF_K_ELF: 81164190Sjkoshy STAILQ_INIT(&e->e_u.e_elf.e_scn); 82164190Sjkoshy break; 83164190Sjkoshy default: 84164190Sjkoshy break; 85164190Sjkoshy } 86164190Sjkoshy} 87164190Sjkoshy 88164190Sjkoshy#define FREE(P) do { \ 89164190Sjkoshy if (P) \ 90164190Sjkoshy free(P); \ 91164190Sjkoshy } while (0) 92164190Sjkoshy 93164190Sjkoshy 94164190SjkoshyElf * 95164190Sjkoshy_libelf_release_elf(Elf *e) 96164190Sjkoshy{ 97164190Sjkoshy switch (e->e_kind) { 98164190Sjkoshy case ELF_K_AR: 99164190Sjkoshy FREE(e->e_u.e_ar.e_symtab); 100164190Sjkoshy break; 101164190Sjkoshy 102164190Sjkoshy case ELF_K_ELF: 103164190Sjkoshy switch (e->e_class) { 104164190Sjkoshy case ELFCLASS32: 105164190Sjkoshy FREE(e->e_u.e_elf.e_ehdr.e_ehdr32); 106164190Sjkoshy FREE(e->e_u.e_elf.e_phdr.e_phdr32); 107164190Sjkoshy break; 108164190Sjkoshy case ELFCLASS64: 109164190Sjkoshy FREE(e->e_u.e_elf.e_ehdr.e_ehdr64); 110164190Sjkoshy FREE(e->e_u.e_elf.e_phdr.e_phdr64); 111164190Sjkoshy break; 112164190Sjkoshy } 113164190Sjkoshy 114164190Sjkoshy assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); 115164190Sjkoshy 116164190Sjkoshy if (e->e_arhdr) { 117164190Sjkoshy FREE(e->e_arhdr->ar_name); 118164190Sjkoshy FREE(e->e_arhdr->ar_rawname); 119164190Sjkoshy free(e->e_arhdr); 120164190Sjkoshy } 121164190Sjkoshy 122164190Sjkoshy break; 123164190Sjkoshy 124164190Sjkoshy default: 125164190Sjkoshy break; 126164190Sjkoshy } 127164190Sjkoshy 128164190Sjkoshy free(e); 129164190Sjkoshy 130164190Sjkoshy return (NULL); 131164190Sjkoshy} 132164190Sjkoshy 133164190SjkoshyElf_Data * 134164190Sjkoshy_libelf_allocate_data(Elf_Scn *s) 135164190Sjkoshy{ 136164190Sjkoshy Elf_Data *d; 137164190Sjkoshy 138164190Sjkoshy if ((d = calloc((size_t) 1, sizeof(Elf_Data))) == NULL) { 139164190Sjkoshy LIBELF_SET_ERROR(RESOURCE, 0); 140164190Sjkoshy return (NULL); 141164190Sjkoshy } 142164190Sjkoshy 143164190Sjkoshy d->d_scn = s; 144164190Sjkoshy 145164190Sjkoshy return (d); 146164190Sjkoshy} 147164190Sjkoshy 148164190SjkoshyElf_Data * 149164190Sjkoshy_libelf_release_data(Elf_Data *d) 150164190Sjkoshy{ 151164190Sjkoshy 152164190Sjkoshy if (d->d_flags & LIBELF_F_MALLOCED) 153164190Sjkoshy free(d->d_buf); 154164190Sjkoshy 155164190Sjkoshy free(d); 156164190Sjkoshy 157164190Sjkoshy return (NULL); 158164190Sjkoshy} 159164190Sjkoshy 160164190SjkoshyElf_Scn * 161164190Sjkoshy_libelf_allocate_scn(Elf *e, size_t ndx) 162164190Sjkoshy{ 163164190Sjkoshy Elf_Scn *s; 164164190Sjkoshy 165164190Sjkoshy if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) { 166164190Sjkoshy LIBELF_SET_ERROR(RESOURCE, errno); 167164190Sjkoshy return (NULL); 168164190Sjkoshy } 169164190Sjkoshy 170164190Sjkoshy s->s_elf = e; 171164190Sjkoshy s->s_ndx = ndx; 172164190Sjkoshy 173164190Sjkoshy STAILQ_INIT(&s->s_data); 174164190Sjkoshy STAILQ_INIT(&s->s_rawdata); 175164190Sjkoshy 176164190Sjkoshy STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next); 177164190Sjkoshy 178164190Sjkoshy return (s); 179164190Sjkoshy} 180164190Sjkoshy 181164190SjkoshyElf_Scn * 182164190Sjkoshy_libelf_release_scn(Elf_Scn *s) 183164190Sjkoshy{ 184164190Sjkoshy Elf *e; 185164190Sjkoshy Elf_Data *d, *td; 186164190Sjkoshy 187164190Sjkoshy assert(s != NULL); 188164190Sjkoshy 189164190Sjkoshy STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) { 190164190Sjkoshy STAILQ_REMOVE(&s->s_data, d, _Elf_Data, d_next); 191164190Sjkoshy d = _libelf_release_data(d); 192164190Sjkoshy } 193164190Sjkoshy 194166863Sdumbbell STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) { 195164190Sjkoshy assert((d->d_flags & LIBELF_F_MALLOCED) == 0); 196164190Sjkoshy STAILQ_REMOVE(&s->s_rawdata, d, _Elf_Data, d_next); 197164190Sjkoshy d = _libelf_release_data(d); 198164190Sjkoshy } 199164190Sjkoshy 200164190Sjkoshy e = s->s_elf; 201164190Sjkoshy 202164190Sjkoshy assert(e != NULL); 203164190Sjkoshy 204164190Sjkoshy STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next); 205164190Sjkoshy 206164190Sjkoshy free(s); 207164190Sjkoshy 208164190Sjkoshy return (NULL); 209164190Sjkoshy} 210