Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/cddl/contrib/opensolaris/tools/ctf/cvt/util.c
39586 views
1
/*
2
* CDDL HEADER START
3
*
4
* The contents of this file are subject to the terms of the
5
* Common Development and Distribution License (the "License").
6
* You may not use this file except in compliance with the License.
7
*
8
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9
* or http://www.opensolaris.org/os/licensing.
10
* See the License for the specific language governing permissions
11
* and limitations under the License.
12
*
13
* When distributing Covered Code, include this CDDL HEADER in each
14
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15
* If applicable, add the following below this CDDL HEADER, with the
16
* fields enclosed by brackets "[]" replaced with your own identifying
17
* information: Portions Copyright [yyyy] [name of copyright owner]
18
*
19
* CDDL HEADER END
20
*/
21
/*
22
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23
* Use is subject to license terms.
24
*/
25
26
#pragma ident "%Z%%M% %I% %E% SMI"
27
28
/*
29
* Utility functions
30
*/
31
32
#include <assert.h>
33
#include <stdio.h>
34
#include <stdlib.h>
35
#include <string.h>
36
#include <libelf.h>
37
#include <gelf.h>
38
#include <errno.h>
39
#include <stdarg.h>
40
#include <pthread.h>
41
#include <unistd.h>
42
#include <sys/param.h>
43
44
#include "ctftools.h"
45
#include "memory.h"
46
47
static void (*terminate_cleanup)(void) = NULL;
48
49
/* returns 1 if s1 == s2, 0 otherwise */
50
int
51
streq(const char *s1, const char *s2)
52
{
53
if (s1 == NULL) {
54
if (s2 != NULL)
55
return (0);
56
} else if (s2 == NULL)
57
return (0);
58
else if (strcmp(s1, s2) != 0)
59
return (0);
60
61
return (1);
62
}
63
64
int
65
findelfsecidx(Elf *elf, const char *file, const char *tofind)
66
{
67
Elf_Scn *scn = NULL;
68
GElf_Ehdr ehdr;
69
GElf_Shdr shdr;
70
71
if (gelf_getehdr(elf, &ehdr) == NULL)
72
elfterminate(file, "Couldn't read ehdr");
73
74
while ((scn = elf_nextscn(elf, scn)) != NULL) {
75
char *name;
76
77
if (gelf_getshdr(scn, &shdr) == NULL) {
78
elfterminate(file,
79
"Couldn't read header for section %d",
80
elf_ndxscn(scn));
81
}
82
83
if ((name = elf_strptr(elf, ehdr.e_shstrndx,
84
(size_t)shdr.sh_name)) == NULL) {
85
elfterminate(file,
86
"Couldn't get name for section %d",
87
elf_ndxscn(scn));
88
}
89
90
if (strcmp(name, tofind) == 0)
91
return (elf_ndxscn(scn));
92
}
93
94
return (-1);
95
}
96
97
size_t
98
elf_ptrsz(Elf *elf)
99
{
100
GElf_Ehdr ehdr;
101
102
if (gelf_getehdr(elf, &ehdr) == NULL) {
103
terminate("failed to read ELF header: %s\n",
104
elf_errmsg(-1));
105
}
106
107
if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
108
return (4);
109
else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
110
return (8);
111
else
112
terminate("unknown ELF class %d\n", ehdr.e_ident[EI_CLASS]);
113
114
/*NOTREACHED*/
115
return (0);
116
}
117
118
/*PRINTFLIKE2*/
119
static void
120
whine(const char *type, const char *format, va_list ap)
121
{
122
int error = errno;
123
124
fprintf(stderr, "%s: %s: ", type, progname);
125
vfprintf(stderr, format, ap);
126
127
if (format[strlen(format) - 1] != '\n')
128
fprintf(stderr, ": %s\n", strerror(error));
129
}
130
131
void
132
set_terminate_cleanup(void (*cleanup)(void))
133
{
134
terminate_cleanup = cleanup;
135
}
136
137
/*PRINTFLIKE1*/
138
void
139
terminate(const char *format, ...)
140
{
141
va_list ap;
142
143
va_start(ap, format);
144
whine("ERROR", format, ap);
145
va_end(ap);
146
147
if (terminate_cleanup)
148
terminate_cleanup();
149
150
if (getenv("CTF_ABORT_ON_TERMINATE") != NULL)
151
abort();
152
#if defined(__FreeBSD__)
153
/*
154
* For the time being just output the termination message, but don't
155
* return an exit status that would cause the build to fail. We need
156
* to get as much stuff built as possible before going back and
157
* figuring out what is wrong with certain files.
158
*/
159
exit(0);
160
#else
161
exit(1);
162
#endif
163
}
164
165
/*PRINTFLIKE1*/
166
void
167
aborterr(const char *format, ...)
168
{
169
va_list ap;
170
171
va_start(ap, format);
172
whine("ERROR", format, ap);
173
va_end(ap);
174
175
#ifdef illumos
176
abort();
177
#else
178
exit(0);
179
#endif
180
}
181
182
/*PRINTFLIKE1*/
183
void
184
warning(const char *format, ...)
185
{
186
va_list ap;
187
188
va_start(ap, format);
189
whine("WARNING", format, ap);
190
va_end(ap);
191
192
if (debug_level >= 3)
193
terminate("Termination due to warning\n");
194
}
195
196
/*PRINTFLIKE2*/
197
void
198
vadebug(int level, const char *format, va_list ap)
199
{
200
if (level > debug_level)
201
return;
202
203
(void) fprintf(DEBUG_STREAM, "DEBUG: ");
204
(void) vfprintf(DEBUG_STREAM, format, ap);
205
fflush(DEBUG_STREAM);
206
}
207
208
/*PRINTFLIKE2*/
209
void
210
debug(int level, const char *format, ...)
211
{
212
va_list ap;
213
214
if (level > debug_level)
215
return;
216
217
va_start(ap, format);
218
(void) vadebug(level, format, ap);
219
va_end(ap);
220
}
221
222
char *
223
mktmpname(const char *origname, const char *suffix)
224
{
225
char *newname;
226
227
newname = xmalloc(strlen(origname) + strlen(suffix) + 1);
228
(void) strcpy(newname, origname);
229
(void) strcat(newname, suffix);
230
return (newname);
231
}
232
233
/*PRINTFLIKE2*/
234
void
235
elfterminate(const char *file, const char *fmt, ...)
236
{
237
static char msgbuf[BUFSIZ];
238
va_list ap;
239
240
va_start(ap, fmt);
241
vsnprintf(msgbuf, sizeof (msgbuf), fmt, ap);
242
va_end(ap);
243
244
terminate("%s: %s: %s\n", file, msgbuf, elf_errmsg(-1));
245
}
246
247
const char *
248
tdesc_name(tdesc_t *tdp)
249
{
250
return (tdp->t_name == NULL ? "(anon)" : tdp->t_name);
251
}
252
253
static char *watch_address = NULL;
254
static int watch_length = 0;
255
256
void
257
watch_set(void *addr, int len)
258
{
259
watch_address = addr;
260
watch_length = len;
261
}
262
263
void
264
watch_dump(int v)
265
{
266
char *p = watch_address;
267
int i;
268
269
if (watch_address == NULL || watch_length == 0)
270
return;
271
272
printf("%d: watch %p len %d\n",v,watch_address,watch_length);
273
for (i = 0; i < watch_length; i++) {
274
if (*p >= 0x20 && *p < 0x7f) {
275
printf(" %c",*p++ & 0xff);
276
} else {
277
printf(" %02x",*p++ & 0xff);
278
}
279
}
280
printf("\n");
281
282
}
283
284
285
286