Branch data Line data Source code
1 : : /* Append new section.
2 : : Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
3 : : This file is part of elfutils.
4 : : Written by Ulrich Drepper <drepper@redhat.com>, 1998.
5 : :
6 : : This file is free software; you can redistribute it and/or modify
7 : : it under the terms of either
8 : :
9 : : * the GNU Lesser General Public License as published by the Free
10 : : Software Foundation; either version 3 of the License, or (at
11 : : your option) any later version
12 : :
13 : : or
14 : :
15 : : * the GNU General Public License as published by the Free
16 : : Software Foundation; either version 2 of the License, or (at
17 : : your option) any later version
18 : :
19 : : or both in parallel, as here.
20 : :
21 : : elfutils is distributed in the hope that it will be useful, but
22 : : WITHOUT ANY WARRANTY; without even the implied warranty of
23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : : General Public License for more details.
25 : :
26 : : You should have received copies of the GNU General Public License and
27 : : the GNU Lesser General Public License along with this program. If
28 : : not, see <http://www.gnu.org/licenses/>. */
29 : :
30 : : #ifdef HAVE_CONFIG_H
31 : : # include <config.h>
32 : : #endif
33 : :
34 : : #include <assert.h>
35 : : #include <stdbool.h>
36 : : #include <stddef.h>
37 : : #include <stdlib.h>
38 : : #include <string.h>
39 : :
40 : : #include "libelfP.h"
41 : :
42 : :
43 : : Elf_Scn *
44 : 199288 : elf_newscn (elf)
45 : : Elf *elf;
46 : : {
47 : 199288 : Elf_Scn *result = NULL;
48 : 199288 : bool first = false;
49 : :
50 [ + - ]: 199288 : if (elf == NULL)
51 : : return NULL;
52 : :
53 : : /* We rely on the prefix of the `elf', `elf32', and `elf64' element
54 : : being the same. */
55 : : assert (offsetof (Elf, state.elf.scns_last)
56 : : == offsetof (Elf, state.elf32.scns_last));
57 : : assert (offsetof (Elf, state.elf.scns_last)
58 : : == offsetof (Elf, state.elf64.scns_last));
59 : : assert (offsetof (Elf, state.elf32.scns)
60 : : == offsetof (Elf, state.elf64.scns));
61 : :
62 : : rwlock_wrlock (elf->lock);
63 : :
64 : : again:
65 [ + + ]: 199349 : if (elf->state.elf.scns_last->cnt < elf->state.elf.scns_last->max)
66 : : {
67 : 199244 : result = &elf->state.elf.scns_last->data[elf->state.elf.scns_last->cnt];
68 : :
69 [ + + ]: 199244 : if (++elf->state.elf.scns_last->cnt == 1
70 [ - + ]: 61 : && (elf->state.elf.scns_last
71 : : == (elf->class == ELFCLASS32
72 : : || (offsetof (Elf, state.elf32.scns)
73 : : == offsetof (Elf, state.elf64.scns))
74 : 61 : ? &elf->state.elf32.scns : &elf->state.elf64.scns)))
75 : : /* This is zeroth section. */
76 : : first = true;
77 : : else
78 : : {
79 [ - + ]: 199183 : assert (elf->state.elf.scns_last->cnt > 1);
80 : 199183 : result->index = result[-1].index + 1;
81 : : }
82 : : }
83 : : else
84 : : {
85 : : /* We must allocate a new element. */
86 : : Elf_ScnList *newp;
87 : :
88 [ - + ]: 105 : assert (elf->state.elf.scnincr > 0);
89 : :
90 : 105 : newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList)
91 : 105 : + ((elf->state.elf.scnincr *= 2)
92 : 105 : * sizeof (Elf_Scn)), 1);
93 [ - + ]: 105 : if (newp == NULL)
94 : : {
95 : 0 : __libelf_seterrno (ELF_E_NOMEM);
96 : 0 : goto out;
97 : : }
98 : :
99 : 105 : result = &newp->data[0];
100 : :
101 : : /* One section used. */
102 : 105 : ++newp->cnt;
103 : :
104 : : /* This is the number of sections we allocated. */
105 : 105 : newp->max = elf->state.elf.scnincr;
106 : :
107 : : /* Remember the index for the first section in this block. */
108 : : newp->data[0].index
109 : 105 : = 1 + elf->state.elf.scns_last->data[elf->state.elf.scns_last->max - 1].index;
110 : :
111 : : /* Enqueue the new list element. */
112 : 105 : elf->state.elf.scns_last = elf->state.elf.scns_last->next = newp;
113 : : }
114 : :
115 : : /* Create a section header for this section. */
116 [ + + ]: 199349 : if (elf->class == ELFCLASS32)
117 : : {
118 : 198484 : result->shdr.e32 = (Elf32_Shdr *) calloc (1, sizeof (Elf32_Shdr));
119 [ - + ]: 198484 : if (result->shdr.e32 == NULL)
120 : : {
121 : 0 : __libelf_seterrno (ELF_E_NOMEM);
122 : 0 : goto out;
123 : : }
124 : : }
125 : : else
126 : : {
127 : 865 : result->shdr.e64 = (Elf64_Shdr *) calloc (1, sizeof (Elf64_Shdr));
128 [ - + ]: 865 : if (result->shdr.e64 == NULL)
129 : : {
130 : 0 : __libelf_seterrno (ELF_E_NOMEM);
131 : 0 : goto out;
132 : : }
133 : : }
134 : :
135 : 199349 : result->elf = elf;
136 : 199349 : result->shdr_flags = ELF_F_DIRTY | ELF_F_MALLOCED;
137 : 199349 : result->list = elf->state.elf.scns_last;
138 : :
139 : : /* Initialize the data part. */
140 : 199349 : result->data_read = 1;
141 [ + + ]: 199349 : if (unlikely (first))
142 : : {
143 : : /* For the first section we mark the data as already available. */
144 : : //result->data_list_rear = &result->data_list;
145 : : first = false;
146 : : goto again;
147 : : }
148 : :
149 : 199288 : result->flags |= ELF_F_DIRTY;
150 : :
151 : : out:
152 : : rwlock_unlock (elf->lock);
153 : :
154 : 199288 : return result;
155 : : }
|