source: rtems-tools/rtemstoolkit/elftoolchain/libelf/libelf_allocate.c @ 6f48c91

5
Last change on this file since 6f48c91 was 6f48c91, checked in by Chris Johns <chrisj@…>, on 04/30/18 at 03:39:09

Revert "rtemstoolkit: Update elftoolchain to the latest code."

This reverts commit 0c5db2dd13b8270bb80c497d5f53ae2471f8a819.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*-
2 * Copyright (c) 2006,2008,2010 Joseph Koshy
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Internal APIs
29 */
30
31#include <sys/cdefs.h>
32
33#include <sys/errno.h>
34
35#include <assert.h>
36#include <errno.h>
37#include <libelf.h>
38#include <stdlib.h>
39#include <string.h>
40
41#include "_libelf.h"
42
43LIBELF_VCSID("$Id: libelf_allocate.c 1341 2011-01-01 04:28:29Z jkoshy $");
44
45Elf *
46_libelf_allocate_elf(void)
47{
48        Elf *e;
49
50        if ((e = malloc(sizeof(*e))) == NULL) {
51                LIBELF_SET_ERROR(RESOURCE, errno);
52                return NULL;
53        }
54
55        e->e_activations = 1;
56        e->e_hdr.e_rawhdr = NULL;
57        e->e_byteorder   = ELFDATANONE;
58        e->e_class       = ELFCLASSNONE;
59        e->e_cmd         = ELF_C_NULL;
60        e->e_fd          = -1;
61        e->e_flags       = 0;
62        e->e_kind        = ELF_K_NONE;
63        e->e_parent      = NULL;
64        e->e_rawfile     = NULL;
65        e->e_rawsize     = 0;
66        e->e_version     = LIBELF_PRIVATE(version);
67
68        (void) memset(&e->e_u, 0, sizeof(e->e_u));
69
70        return (e);
71}
72
73void
74_libelf_init_elf(Elf *e, Elf_Kind kind)
75{
76        assert(e != NULL);
77        assert(e->e_kind == ELF_K_NONE);
78
79        e->e_kind = kind;
80
81        switch (kind) {
82        case ELF_K_ELF:
83                STAILQ_INIT(&e->e_u.e_elf.e_scn);
84                break;
85        default:
86                break;
87        }
88}
89
90#define FREE(P)         do {                            \
91                if (P)                                  \
92                        free(P);                        \
93        } while (0)
94
95
96Elf *
97_libelf_release_elf(Elf *e)
98{
99        Elf_Arhdr *arh;
100
101        switch (e->e_kind) {
102        case ELF_K_AR:
103                FREE(e->e_u.e_ar.e_symtab);
104                break;
105
106        case ELF_K_ELF:
107                switch (e->e_class) {
108                case ELFCLASS32:
109                        FREE(e->e_u.e_elf.e_ehdr.e_ehdr32);
110                        FREE(e->e_u.e_elf.e_phdr.e_phdr32);
111                        break;
112                case ELFCLASS64:
113                        FREE(e->e_u.e_elf.e_ehdr.e_ehdr64);
114                        FREE(e->e_u.e_elf.e_phdr.e_phdr64);
115                        break;
116                }
117
118                assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn));
119
120                if (e->e_flags & LIBELF_F_AR_HEADER) {
121                        arh = e->e_hdr.e_arhdr;
122                        FREE(arh->ar_name);
123                        FREE(arh->ar_rawname);
124                        free(arh);
125                }
126
127                break;
128
129        default:
130                break;
131        }
132
133        free(e);
134
135        return (NULL);
136}
137
138Elf_Data *
139_libelf_allocate_data(Elf_Scn *s)
140{
141        Elf_Data *d;
142
143        if ((d = calloc((size_t) 1, sizeof(Elf_Data))) == NULL) {
144                LIBELF_SET_ERROR(RESOURCE, 0);
145                return (NULL);
146        }
147
148        d->d_scn = s;
149
150        return (d);
151}
152
153Elf_Data *
154_libelf_release_data(Elf_Data *d)
155{
156
157        if (d->d_flags & LIBELF_F_DATA_MALLOCED)
158                free(d->d_buf);
159
160        free(d);
161
162        return (NULL);
163}
164
165Elf_Scn *
166_libelf_allocate_scn(Elf *e, size_t ndx)
167{
168        Elf_Scn *s;
169
170        if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) {
171                LIBELF_SET_ERROR(RESOURCE, errno);
172                return (NULL);
173        }
174
175        s->s_elf = e;
176        s->s_ndx = ndx;
177
178        STAILQ_INIT(&s->s_data);
179        STAILQ_INIT(&s->s_rawdata);
180
181        STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next);
182
183        return (s);
184}
185
186Elf_Scn *
187_libelf_release_scn(Elf_Scn *s)
188{
189        Elf *e;
190        Elf_Data *d, *td;
191
192        assert(s != NULL);
193
194        STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) {
195                STAILQ_REMOVE(&s->s_data, d, _Elf_Data, d_next);
196                d = _libelf_release_data(d);
197        }
198
199        STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) {
200                assert((d->d_flags & LIBELF_F_DATA_MALLOCED) == 0);
201                STAILQ_REMOVE(&s->s_rawdata, d, _Elf_Data, d_next);
202                d = _libelf_release_data(d);
203        }
204
205        e = s->s_elf;
206
207        assert(e != NULL);
208
209        STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next);
210
211        free(s);
212
213        return (NULL);
214}
Note: See TracBrowser for help on using the repository browser.