Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/elftoolchain/libpe/pe_section.c
39483 views
1
/*-
2
* Copyright (c) 2016 Kai Wang
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
#include <errno.h>
28
#include <string.h>
29
30
#include "_libpe.h"
31
32
ELFTC_VCSID("$Id: pe_section.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
33
34
PE_Scn *
35
pe_getscn(PE *pe, size_t ndx)
36
{
37
PE_Scn *ps;
38
39
if (pe == NULL || ndx < 1 || ndx > 0xFFFFU) {
40
errno = EINVAL;
41
return (NULL);
42
}
43
44
STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) {
45
if (ps->ps_ndx == ndx)
46
return (ps);
47
}
48
49
errno = ENOENT;
50
51
return (NULL);
52
}
53
54
size_t
55
pe_ndxscn(PE_Scn *ps)
56
{
57
58
if (ps == NULL) {
59
errno = EINVAL;
60
return (0);
61
}
62
63
return (ps->ps_ndx);
64
}
65
66
PE_Scn *
67
pe_nextscn(PE *pe, PE_Scn *ps)
68
{
69
70
if (pe == NULL) {
71
errno = EINVAL;
72
return (NULL);
73
}
74
75
if (ps == NULL)
76
ps = STAILQ_FIRST(&pe->pe_scn);
77
else
78
ps = STAILQ_NEXT(ps, ps_next);
79
80
while (ps != NULL) {
81
if (ps->ps_ndx >= 1 && ps->ps_ndx <= 0xFFFFU)
82
return (ps);
83
ps = STAILQ_NEXT(ps, ps_next);
84
}
85
86
return (NULL);
87
}
88
89
PE_Scn *
90
pe_newscn(PE *pe)
91
{
92
PE_Scn *ps, *tps, *_tps;
93
94
if (pe == NULL) {
95
errno = EINVAL;
96
return (NULL);
97
}
98
99
if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
100
errno = EACCES;
101
return (NULL);
102
}
103
104
if ((ps = libpe_alloc_scn(pe)) == NULL)
105
return (NULL);
106
107
if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER) {
108
STAILQ_FOREACH_SAFE(tps, &pe->pe_scn, ps_next, _tps)
109
libpe_release_scn(tps);
110
pe->pe_flags &= ~LIBPE_F_BAD_SEC_HEADER;
111
}
112
113
STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next);
114
115
ps->ps_flags |= PE_F_DIRTY | LIBPE_F_LOAD_SECTION;
116
pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER;
117
118
return (ps);
119
}
120
121
PE_Scn *
122
pe_insertscn(PE *pe, size_t ndx)
123
{
124
PE_Scn *ps, *a, *b;
125
126
if (pe == NULL || ndx < 1 || ndx > 0xFFFFU) {
127
errno = EINVAL;
128
return (NULL);
129
}
130
131
if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
132
errno = EACCES;
133
return (NULL);
134
}
135
136
if ((ps = libpe_alloc_scn(pe)) == NULL)
137
return (NULL);
138
139
if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER) {
140
STAILQ_FOREACH_SAFE(a, &pe->pe_scn, ps_next, b)
141
libpe_release_scn(a);
142
pe->pe_flags &= ~LIBPE_F_BAD_SEC_HEADER;
143
}
144
145
b = NULL;
146
STAILQ_FOREACH(a, &pe->pe_scn, ps_next) {
147
if (a->ps_ndx & 0xFFFF0000U)
148
continue;
149
if (a->ps_ndx == ndx)
150
break;
151
b = a;
152
}
153
154
if (a == NULL) {
155
STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next);
156
if (b == NULL)
157
ps->ps_ndx = 1;
158
else
159
ps->ps_ndx = b->ps_ndx + 1;
160
} else if (b == NULL) {
161
STAILQ_INSERT_HEAD(&pe->pe_scn, ps, ps_next);
162
ps->ps_ndx = 1;
163
} else {
164
STAILQ_INSERT_AFTER(&pe->pe_scn, b, ps, ps_next);
165
ps->ps_ndx = ndx;
166
}
167
168
a = ps;
169
while ((a = STAILQ_NEXT(a, ps_next)) != NULL) {
170
if ((a->ps_ndx & 0xFFFF0000U) == 0)
171
a->ps_ndx++;
172
}
173
174
ps->ps_flags |= PE_F_DIRTY | LIBPE_F_LOAD_SECTION;
175
pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER;
176
177
return (ps);
178
}
179
180
PE_SecHdr *
181
pe_section_header(PE_Scn *ps)
182
{
183
184
if (ps == NULL) {
185
errno = EINVAL;
186
return (NULL);
187
}
188
189
return (&ps->ps_sh);
190
}
191
192
int
193
pe_update_section_header(PE_Scn *ps, PE_SecHdr *sh)
194
{
195
PE *pe;
196
197
if (ps == NULL || sh == NULL) {
198
errno = EINVAL;
199
return (-1);
200
}
201
202
pe = ps->ps_pe;
203
204
if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
205
errno = EACCES;
206
return (-1);
207
}
208
209
ps->ps_sh = *sh;
210
pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER;
211
212
return (0);
213
}
214
215