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