1260684Skaiw/*- 2260684Skaiw * Copyright (c) 2006,2008,2010 Joseph Koshy 3260684Skaiw * All rights reserved. 4260684Skaiw * 5260684Skaiw * Redistribution and use in source and binary forms, with or without 6260684Skaiw * modification, are permitted provided that the following conditions 7260684Skaiw * are met: 8260684Skaiw * 1. Redistributions of source code must retain the above copyright 9260684Skaiw * notice, this list of conditions and the following disclaimer. 10260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright 11260684Skaiw * notice, this list of conditions and the following disclaimer in the 12260684Skaiw * documentation and/or other materials provided with the distribution. 13260684Skaiw * 14260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15260684Skaiw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16260684Skaiw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17260684Skaiw * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18260684Skaiw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19260684Skaiw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20260684Skaiw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21260684Skaiw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22260684Skaiw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23260684Skaiw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24260684Skaiw * SUCH DAMAGE. 25260684Skaiw */ 26260684Skaiw 27260684Skaiw/* 28260684Skaiw * Internal APIs 29260684Skaiw */ 30260684Skaiw 31260684Skaiw#include <assert.h> 32260684Skaiw#include <errno.h> 33260684Skaiw#include <libelf.h> 34260684Skaiw#include <stdlib.h> 35260684Skaiw#include <string.h> 36260684Skaiw 37260684Skaiw#include "_libelf.h" 38260684Skaiw 39280932SemasteELFTC_VCSID("$Id: libelf_allocate.c 3174 2015-03-27 17:13:41Z emaste $"); 40260684Skaiw 41260684SkaiwElf * 42260684Skaiw_libelf_allocate_elf(void) 43260684Skaiw{ 44260684Skaiw Elf *e; 45260684Skaiw 46260684Skaiw if ((e = malloc(sizeof(*e))) == NULL) { 47260684Skaiw LIBELF_SET_ERROR(RESOURCE, errno); 48260684Skaiw return NULL; 49260684Skaiw } 50260684Skaiw 51260684Skaiw e->e_activations = 1; 52260684Skaiw e->e_hdr.e_rawhdr = NULL; 53260684Skaiw e->e_byteorder = ELFDATANONE; 54260684Skaiw e->e_class = ELFCLASSNONE; 55260684Skaiw e->e_cmd = ELF_C_NULL; 56260684Skaiw e->e_fd = -1; 57260684Skaiw e->e_flags = 0; 58260684Skaiw e->e_kind = ELF_K_NONE; 59260684Skaiw e->e_parent = NULL; 60260684Skaiw e->e_rawfile = NULL; 61260684Skaiw e->e_rawsize = 0; 62260684Skaiw e->e_version = LIBELF_PRIVATE(version); 63260684Skaiw 64260684Skaiw (void) memset(&e->e_u, 0, sizeof(e->e_u)); 65260684Skaiw 66260684Skaiw return (e); 67260684Skaiw} 68260684Skaiw 69260684Skaiwvoid 70260684Skaiw_libelf_init_elf(Elf *e, Elf_Kind kind) 71260684Skaiw{ 72260684Skaiw assert(e != NULL); 73260684Skaiw assert(e->e_kind == ELF_K_NONE); 74260684Skaiw 75260684Skaiw e->e_kind = kind; 76260684Skaiw 77260684Skaiw switch (kind) { 78260684Skaiw case ELF_K_ELF: 79260684Skaiw STAILQ_INIT(&e->e_u.e_elf.e_scn); 80260684Skaiw break; 81260684Skaiw default: 82260684Skaiw break; 83260684Skaiw } 84260684Skaiw} 85260684Skaiw 86260684Skaiw#define FREE(P) do { \ 87260684Skaiw if (P) \ 88260684Skaiw free(P); \ 89260684Skaiw } while (0) 90260684Skaiw 91260684Skaiw 92260684SkaiwElf * 93260684Skaiw_libelf_release_elf(Elf *e) 94260684Skaiw{ 95260684Skaiw Elf_Arhdr *arh; 96260684Skaiw 97260684Skaiw switch (e->e_kind) { 98260684Skaiw case ELF_K_AR: 99260684Skaiw FREE(e->e_u.e_ar.e_symtab); 100260684Skaiw break; 101260684Skaiw 102260684Skaiw case ELF_K_ELF: 103260684Skaiw switch (e->e_class) { 104260684Skaiw case ELFCLASS32: 105260684Skaiw FREE(e->e_u.e_elf.e_ehdr.e_ehdr32); 106260684Skaiw FREE(e->e_u.e_elf.e_phdr.e_phdr32); 107260684Skaiw break; 108260684Skaiw case ELFCLASS64: 109260684Skaiw FREE(e->e_u.e_elf.e_ehdr.e_ehdr64); 110260684Skaiw FREE(e->e_u.e_elf.e_phdr.e_phdr64); 111260684Skaiw break; 112260684Skaiw } 113260684Skaiw 114260684Skaiw assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); 115260684Skaiw 116260684Skaiw if (e->e_flags & LIBELF_F_AR_HEADER) { 117260684Skaiw arh = e->e_hdr.e_arhdr; 118260684Skaiw FREE(arh->ar_name); 119260684Skaiw FREE(arh->ar_rawname); 120260684Skaiw free(arh); 121260684Skaiw } 122260684Skaiw 123260684Skaiw break; 124260684Skaiw 125260684Skaiw default: 126260684Skaiw break; 127260684Skaiw } 128260684Skaiw 129260684Skaiw free(e); 130260684Skaiw 131260684Skaiw return (NULL); 132260684Skaiw} 133260684Skaiw 134260684Skaiwstruct _Libelf_Data * 135260684Skaiw_libelf_allocate_data(Elf_Scn *s) 136260684Skaiw{ 137260684Skaiw struct _Libelf_Data *d; 138260684Skaiw 139260684Skaiw if ((d = calloc((size_t) 1, sizeof(*d))) == NULL) { 140260684Skaiw LIBELF_SET_ERROR(RESOURCE, 0); 141260684Skaiw return (NULL); 142260684Skaiw } 143260684Skaiw 144260684Skaiw d->d_scn = s; 145260684Skaiw 146260684Skaiw return (d); 147260684Skaiw} 148260684Skaiw 149260684Skaiwstruct _Libelf_Data * 150260684Skaiw_libelf_release_data(struct _Libelf_Data *d) 151260684Skaiw{ 152260684Skaiw 153260684Skaiw if (d->d_flags & LIBELF_F_DATA_MALLOCED) 154260684Skaiw free(d->d_data.d_buf); 155260684Skaiw 156260684Skaiw free(d); 157260684Skaiw 158260684Skaiw return (NULL); 159260684Skaiw} 160260684Skaiw 161260684SkaiwElf_Scn * 162260684Skaiw_libelf_allocate_scn(Elf *e, size_t ndx) 163260684Skaiw{ 164260684Skaiw Elf_Scn *s; 165260684Skaiw 166260684Skaiw if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) { 167260684Skaiw LIBELF_SET_ERROR(RESOURCE, errno); 168260684Skaiw return (NULL); 169260684Skaiw } 170260684Skaiw 171260684Skaiw s->s_elf = e; 172260684Skaiw s->s_ndx = ndx; 173260684Skaiw 174260684Skaiw STAILQ_INIT(&s->s_data); 175260684Skaiw STAILQ_INIT(&s->s_rawdata); 176260684Skaiw 177260684Skaiw STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next); 178260684Skaiw 179260684Skaiw return (s); 180260684Skaiw} 181260684Skaiw 182260684SkaiwElf_Scn * 183260684Skaiw_libelf_release_scn(Elf_Scn *s) 184260684Skaiw{ 185260684Skaiw Elf *e; 186260684Skaiw struct _Libelf_Data *d, *td; 187260684Skaiw 188260684Skaiw assert(s != NULL); 189260684Skaiw 190260684Skaiw STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) { 191260684Skaiw STAILQ_REMOVE(&s->s_data, d, _Libelf_Data, d_next); 192260684Skaiw d = _libelf_release_data(d); 193260684Skaiw } 194260684Skaiw 195260684Skaiw STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) { 196260684Skaiw assert((d->d_flags & LIBELF_F_DATA_MALLOCED) == 0); 197260684Skaiw STAILQ_REMOVE(&s->s_rawdata, d, _Libelf_Data, d_next); 198260684Skaiw d = _libelf_release_data(d); 199260684Skaiw } 200260684Skaiw 201260684Skaiw e = s->s_elf; 202260684Skaiw 203260684Skaiw assert(e != NULL); 204260684Skaiw 205260684Skaiw STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next); 206260684Skaiw 207260684Skaiw free(s); 208260684Skaiw 209260684Skaiw return (NULL); 210260684Skaiw} 211