libelf_allocate.c revision 259065
1179055Sjfv/*- 2171384Sjfv * Copyright (c) 2006 Joseph Koshy 3221041Sjfv * All rights reserved. 4179055Sjfv * 5179055Sjfv * Redistribution and use in source and binary forms, with or without 6179055Sjfv * modification, are permitted provided that the following conditions 7179055Sjfv * are met: 8179055Sjfv * 1. Redistributions of source code must retain the above copyright 9179055Sjfv * notice, this list of conditions and the following disclaimer. 10179055Sjfv * 2. Redistributions in binary form must reproduce the above copyright 11179055Sjfv * notice, this list of conditions and the following disclaimer in the 12179055Sjfv * documentation and/or other materials provided with the distribution. 13179055Sjfv * 14179055Sjfv * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15179055Sjfv * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16179055Sjfv * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17179055Sjfv * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18179055Sjfv * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19179055Sjfv * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20179055Sjfv * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21179055Sjfv * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22179055Sjfv * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23179055Sjfv * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24179055Sjfv * SUCH DAMAGE. 25179055Sjfv */ 26179055Sjfv 27179055Sjfv/* 28179055Sjfv * Internal APIs 29179055Sjfv */ 30179055Sjfv 31171384Sjfv#include <sys/cdefs.h> 32179055Sjfv__FBSDID("$FreeBSD: releng/10.0/lib/libelf/libelf_allocate.c 166863 2007-02-21 08:14:22Z dumbbell $"); 33179055Sjfv 34171384Sjfv#include <sys/errno.h> 35185352Sjfv 36171384Sjfv#include <assert.h> 37171384Sjfv#include <libelf.h> 38171384Sjfv#include <stdlib.h> 39171384Sjfv#include <string.h> 40171384Sjfv 41171384Sjfv#include "_libelf.h" 42194875Sjfv 43194875SjfvElf * 44194875Sjfv_libelf_allocate_elf(void) 45171384Sjfv{ 46171384Sjfv Elf *e; 47171384Sjfv 48171384Sjfv if ((e = malloc(sizeof(*e))) == NULL) { 49171384Sjfv LIBELF_SET_ERROR(RESOURCE, errno); 50171384Sjfv return NULL; 51171384Sjfv } 52171384Sjfv 53171384Sjfv e->e_activations = 1; 54171384Sjfv e->e_arhdr = NULL; 55171384Sjfv e->e_byteorder = ELFDATANONE; 56171384Sjfv e->e_class = ELFCLASSNONE; 57171384Sjfv e->e_cmd = ELF_C_NULL; 58171384Sjfv e->e_fd = -1; 59171384Sjfv e->e_flags = 0; 60171384Sjfv e->e_kind = ELF_K_NONE; 61171384Sjfv e->e_parent = NULL; 62171384Sjfv e->e_rawfile = NULL; 63171384Sjfv e->e_rawsize = 0; 64171384Sjfv e->e_version = LIBELF_PRIVATE(version); 65171384Sjfv 66171384Sjfv (void) memset(&e->e_u, 0, sizeof(e->e_u)); 67171384Sjfv 68171384Sjfv return (e); 69171384Sjfv} 70190873Sjfv 71171384Sjfvvoid 72171384Sjfv_libelf_init_elf(Elf *e, Elf_Kind kind) 73171384Sjfv{ 74171384Sjfv assert(e != NULL); 75171384Sjfv assert(e->e_kind == ELF_K_NONE); 76171384Sjfv 77171384Sjfv e->e_kind = kind; 78171384Sjfv 79171384Sjfv switch (kind) { 80171384Sjfv case ELF_K_ELF: 81171384Sjfv STAILQ_INIT(&e->e_u.e_elf.e_scn); 82171384Sjfv break; 83171384Sjfv default: 84171384Sjfv break; 85171384Sjfv } 86171384Sjfv} 87171384Sjfv 88179055Sjfv#define FREE(P) do { \ 89194875Sjfv if (P) \ 90194875Sjfv free(P); \ 91171384Sjfv } while (0) 92194875Sjfv 93194875Sjfv 94190873SjfvElf * 95190873Sjfv_libelf_release_elf(Elf *e) 96171384Sjfv{ 97171384Sjfv switch (e->e_kind) { 98171384Sjfv case ELF_K_AR: 99171384Sjfv FREE(e->e_u.e_ar.e_symtab); 100171384Sjfv break; 101172043Sjfv 102171384Sjfv case ELF_K_ELF: 103171384Sjfv switch (e->e_class) { 104172043Sjfv case ELFCLASS32: 105172043Sjfv FREE(e->e_u.e_elf.e_ehdr.e_ehdr32); 106171384Sjfv FREE(e->e_u.e_elf.e_phdr.e_phdr32); 107190873Sjfv break; 108172043Sjfv case ELFCLASS64: 109171384Sjfv FREE(e->e_u.e_elf.e_ehdr.e_ehdr64); 110171384Sjfv FREE(e->e_u.e_elf.e_phdr.e_phdr64); 111171384Sjfv break; 112171384Sjfv } 113172043Sjfv 114172043Sjfv assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); 115171384Sjfv 116172043Sjfv if (e->e_arhdr) { 117171384Sjfv FREE(e->e_arhdr->ar_name); 118172043Sjfv FREE(e->e_arhdr->ar_rawname); 119172043Sjfv free(e->e_arhdr); 120172043Sjfv } 121171384Sjfv 122190873Sjfv break; 123172043Sjfv 124171384Sjfv default: 125171384Sjfv break; 126171384Sjfv } 127172043Sjfv 128172043Sjfv free(e); 129172043Sjfv 130171384Sjfv return (NULL); 131171384Sjfv} 132171384Sjfv 133171384SjfvElf_Data * 134185352Sjfv_libelf_allocate_data(Elf_Scn *s) 135171384Sjfv{ 136171384Sjfv Elf_Data *d; 137200239Sjfv 138200239Sjfv if ((d = calloc((size_t) 1, sizeof(Elf_Data))) == NULL) { 139200239Sjfv LIBELF_SET_ERROR(RESOURCE, 0); 140171384Sjfv return (NULL); 141200239Sjfv } 142171384Sjfv 143171384Sjfv d->d_scn = s; 144171384Sjfv 145171384Sjfv return (d); 146171384Sjfv} 147171384Sjfv 148171384SjfvElf_Data * 149171384Sjfv_libelf_release_data(Elf_Data *d) 150171384Sjfv{ 151171384Sjfv 152172043Sjfv if (d->d_flags & LIBELF_F_MALLOCED) 153200239Sjfv free(d->d_buf); 154172043Sjfv 155172043Sjfv free(d); 156171384Sjfv 157171384Sjfv return (NULL); 158171384Sjfv} 159171384Sjfv 160171384SjfvElf_Scn * 161171384Sjfv_libelf_allocate_scn(Elf *e, size_t ndx) 162171384Sjfv{ 163171384Sjfv Elf_Scn *s; 164171384Sjfv 165171384Sjfv if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) { 166171384Sjfv LIBELF_SET_ERROR(RESOURCE, errno); 167171384Sjfv return (NULL); 168171384Sjfv } 169171384Sjfv 170171384Sjfv s->s_elf = e; 171171384Sjfv s->s_ndx = ndx; 172171384Sjfv 173190873Sjfv STAILQ_INIT(&s->s_data); 174190873Sjfv STAILQ_INIT(&s->s_rawdata); 175185352Sjfv 176185352Sjfv STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next); 177171384Sjfv 178171384Sjfv return (s); 179205720Sjfv} 180194875Sjfv 181194875SjfvElf_Scn * 182215911Sjfv_libelf_release_scn(Elf_Scn *s) 183215911Sjfv{ 184215911Sjfv Elf *e; 185171384Sjfv Elf_Data *d, *td; 186205904Sjfv 187205904Sjfv assert(s != NULL); 188205904Sjfv 189205904Sjfv STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) { 190205904Sjfv STAILQ_REMOVE(&s->s_data, d, _Elf_Data, d_next); 191205904Sjfv d = _libelf_release_data(d); 192205904Sjfv } 193172043Sjfv 194190873Sjfv STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) { 195190873Sjfv assert((d->d_flags & LIBELF_F_MALLOCED) == 0); 196190873Sjfv STAILQ_REMOVE(&s->s_rawdata, d, _Elf_Data, d_next); 197190873Sjfv d = _libelf_release_data(d); 198172043Sjfv } 199172043Sjfv 200172043Sjfv e = s->s_elf; 201172043Sjfv 202172043Sjfv assert(e != NULL); 203171384Sjfv 204171384Sjfv STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next); 205171384Sjfv 206185352Sjfv free(s); 207185352Sjfv 208185352Sjfv return (NULL); 209185352Sjfv} 210171384Sjfv