1234287Sdim/*- 2234287Sdim * Copyright (c) 2006,2008,2010 Joseph Koshy 3234287Sdim * All rights reserved. 4234287Sdim * 5234287Sdim * Redistribution and use in source and binary forms, with or without 6234287Sdim * modification, are permitted provided that the following conditions 7234287Sdim * are met: 8234287Sdim * 1. Redistributions of source code must retain the above copyright 9234287Sdim * notice, this list of conditions and the following disclaimer. 10234287Sdim * 2. Redistributions in binary form must reproduce the above copyright 11234287Sdim * notice, this list of conditions and the following disclaimer in the 12234287Sdim * documentation and/or other materials provided with the distribution. 13234287Sdim * 14234287Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15234287Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16249423Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17234287Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18234287Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19234287Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20234287Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21234287Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22234287Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23234287Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24234287Sdim * SUCH DAMAGE. 25234287Sdim */ 26249423Sdim 27234287Sdim/* 28234287Sdim * Internal APIs 29234287Sdim */ 30234287Sdim 31234287Sdim#include <assert.h> 32234287Sdim#include <errno.h> 33234287Sdim#include <libelf.h> 34234287Sdim#include <stdlib.h> 35234287Sdim#include <string.h> 36234287Sdim 37234287Sdim#include "_libelf.h" 38243830Sdim 39234287SdimELFTC_VCSID("$Id: libelf_allocate.c 3738 2019-05-05 21:49:06Z jkoshy $"); 40234287Sdim 41234287SdimElf * 42234287Sdim_libelf_allocate_elf(void) 43234287Sdim{ 44234287Sdim Elf *e; 45234287Sdim 46234287Sdim if ((e = calloc((size_t) 1, sizeof(*e))) == NULL) { 47234287Sdim LIBELF_SET_ERROR(RESOURCE, errno); 48234287Sdim return NULL; 49234287Sdim } 50234287Sdim 51234287Sdim e->e_activations = 1; 52234287Sdim e->e_byteorder = ELFDATANONE; 53234287Sdim e->e_class = ELFCLASSNONE; 54234287Sdim e->e_cmd = ELF_C_NULL; 55234287Sdim e->e_fd = -1; 56234287Sdim e->e_kind = ELF_K_NONE; 57234287Sdim e->e_version = LIBELF_PRIVATE(version); 58234287Sdim 59234287Sdim return (e); 60234287Sdim} 61234287Sdim 62234287Sdimvoid 63234287Sdim_libelf_init_elf(Elf *e, Elf_Kind kind) 64234287Sdim{ 65234287Sdim assert(e != NULL); 66234287Sdim assert(e->e_kind == ELF_K_NONE); 67234287Sdim 68234287Sdim e->e_kind = kind; 69234287Sdim 70234287Sdim switch (kind) { 71234287Sdim case ELF_K_ELF: 72249423Sdim RB_INIT(&e->e_u.e_elf.e_scn); 73234287Sdim break; 74234287Sdim default: 75234287Sdim break; 76234287Sdim } 77234287Sdim} 78234287Sdim 79234287Sdimvoid 80234287Sdim_libelf_release_elf(Elf *e) 81234287Sdim{ 82234287Sdim Elf_Arhdr *arh; 83234287Sdim 84234287Sdim switch (e->e_kind) { 85234287Sdim case ELF_K_AR: 86234287Sdim free(e->e_u.e_ar.e_symtab); 87234287Sdim break; 88249423Sdim 89249423Sdim case ELF_K_ELF: 90249423Sdim switch (e->e_class) { 91249423Sdim case ELFCLASS32: 92234287Sdim free(e->e_u.e_elf.e_ehdr.e_ehdr32); 93234287Sdim free(e->e_u.e_elf.e_phdr.e_phdr32); 94234287Sdim break; 95234287Sdim case ELFCLASS64: 96234287Sdim free(e->e_u.e_elf.e_ehdr.e_ehdr64); 97234287Sdim free(e->e_u.e_elf.e_phdr.e_phdr64); 98234287Sdim break; 99234287Sdim } 100234287Sdim 101234287Sdim assert(RB_EMPTY(&e->e_u.e_elf.e_scn)); 102234287Sdim 103234287Sdim if (e->e_flags & LIBELF_F_AR_HEADER) { 104234287Sdim arh = e->e_hdr.e_arhdr; 105234287Sdim free(arh->ar_name); 106234287Sdim free(arh->ar_rawname); 107234287Sdim free(arh); 108234287Sdim } 109234287Sdim 110234287Sdim break; 111234287Sdim 112234287Sdim default: 113234287Sdim break; 114234287Sdim } 115234287Sdim 116234287Sdim free(e); 117234287Sdim} 118234287Sdim 119234287Sdimstruct _Libelf_Data * 120234287Sdim_libelf_allocate_data(Elf_Scn *s) 121234287Sdim{ 122234287Sdim struct _Libelf_Data *d; 123234287Sdim 124249423Sdim if ((d = calloc((size_t) 1, sizeof(*d))) == NULL) { 125249423Sdim LIBELF_SET_ERROR(RESOURCE, 0); 126249423Sdim return (NULL); 127249423Sdim } 128234287Sdim 129234287Sdim d->d_scn = s; 130234287Sdim 131234287Sdim return (d); 132234287Sdim} 133234287Sdim 134234287Sdimstruct _Libelf_Data * 135234287Sdim_libelf_release_data(struct _Libelf_Data *d) 136234287Sdim{ 137234287Sdim 138234287Sdim if (d->d_flags & LIBELF_F_DATA_MALLOCED) 139234287Sdim free(d->d_data.d_buf); 140234287Sdim 141234287Sdim free(d); 142234287Sdim 143234287Sdim return (NULL); 144234287Sdim} 145234287Sdim 146234287SdimElf_Scn * 147234287Sdim_libelf_allocate_scn(Elf *e, size_t ndx) 148234287Sdim{ 149234287Sdim Elf_Scn *s; 150234287Sdim 151234287Sdim if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) { 152234287Sdim LIBELF_SET_ERROR(RESOURCE, errno); 153234287Sdim return (NULL); 154234287Sdim } 155234287Sdim 156234287Sdim s->s_elf = e; 157234287Sdim s->s_ndx = ndx; 158 159 STAILQ_INIT(&s->s_data); 160 STAILQ_INIT(&s->s_rawdata); 161 162 RB_INSERT(scntree, &e->e_u.e_elf.e_scn, s); 163 164 return (s); 165} 166 167Elf_Scn * 168_libelf_release_scn(Elf_Scn *s) 169{ 170 Elf *e; 171 struct _Libelf_Data *d, *td; 172 173 assert(s != NULL); 174 175 STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) { 176 STAILQ_REMOVE(&s->s_data, d, _Libelf_Data, d_next); 177 d = _libelf_release_data(d); 178 } 179 180 STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) { 181 assert((d->d_flags & LIBELF_F_DATA_MALLOCED) == 0); 182 STAILQ_REMOVE(&s->s_rawdata, d, _Libelf_Data, d_next); 183 d = _libelf_release_data(d); 184 } 185 186 e = s->s_elf; 187 188 assert(e != NULL); 189 190 RB_REMOVE(scntree, &e->e_u.e_elf.e_scn, s); 191 192 free(s); 193 194 return (NULL); 195} 196