Print this page
10816 ctf_dwarf_convert_type() relies on un-initialized id
10817 ctfconvert -i option is mis-handled
10818 Improve ctfconvert error messages
10819 ctfconvert should handle empty dies
10820 ctfconvert -i never converts
10821 bad free in ctf_dwarf_init_die
10815 shouldn't build gcore.c as part of kmdb
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/ctfmerge/ctfmerge.c
+++ new/usr/src/cmd/ctfmerge/ctfmerge.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 - * Copyright (c) 2017, Joyent, Inc.
13 + * Copyright (c) 2019, Joyent, Inc.
14 14 */
15 15
16 16 /*
17 17 * merge CTF containers
18 18 */
19 19
20 20 #include <stdio.h>
21 21 #include <libctf.h>
22 22 #include <sys/stat.h>
23 23 #include <sys/types.h>
24 24 #include <fcntl.h>
25 25 #include <errno.h>
26 26 #include <strings.h>
27 27 #include <assert.h>
28 28 #include <unistd.h>
29 29 #include <sys/fcntl.h>
30 30 #include <stdlib.h>
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
31 31 #include <libelf.h>
32 32 #include <gelf.h>
33 33 #include <sys/mman.h>
34 34 #include <libgen.h>
35 35 #include <stdarg.h>
36 36 #include <limits.h>
37 37
38 38 static char *g_progname;
39 39 static char *g_unique;
40 40 static char *g_outfile;
41 -static boolean_t g_req;
42 41 static uint_t g_nctf;
43 42
44 43 #define CTFMERGE_OK 0
45 44 #define CTFMERGE_FATAL 1
46 45 #define CTFMERGE_USAGE 2
47 46
48 47 #define CTFMERGE_DEFAULT_NTHREADS 8
49 48 #define CTFMERGE_ALTEXEC "CTFMERGE_ALTEXEC"
50 49
51 50 static void
52 51 ctfmerge_fatal(const char *fmt, ...)
53 52 {
54 53 va_list ap;
55 54
56 55 (void) fprintf(stderr, "%s: ", g_progname);
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
57 56 va_start(ap, fmt);
58 57 (void) vfprintf(stderr, fmt, ap);
59 58 va_end(ap);
60 59
61 60 if (g_outfile != NULL)
62 61 (void) unlink(g_outfile);
63 62
64 63 exit(CTFMERGE_FATAL);
65 64 }
66 65
67 -static boolean_t
68 -ctfmerge_expect_ctf(const char *name, Elf *elf)
66 +/*
67 + * We failed to find CTF for this file, check if it's OK. If we're not derived
68 + * from C, or we have the -m option, we let missing CTF pass.
69 + */
70 +static void
71 +ctfmerge_check_for_c(const char *name, Elf *elf, uint_t flags)
69 72 {
70 - Elf_Scn *scn, *strscn;
71 - Elf_Data *data, *strdata;
72 - GElf_Shdr shdr;
73 - ulong_t i;
73 + char errmsg[1024];
74 74
75 - if (g_req == B_FALSE)
76 - return (B_FALSE);
75 + if (flags & CTF_ALLOW_MISSING_DEBUG)
76 + return;
77 77
78 - scn = NULL;
79 - while ((scn = elf_nextscn(elf, scn)) != NULL) {
80 - if (gelf_getshdr(scn, &shdr) == NULL) {
81 - ctfmerge_fatal("failed to get section header for file "
82 - "%s: %s\n", name, elf_errmsg(elf_errno()));
83 - }
78 + switch (ctf_has_c_source(elf, errmsg, sizeof (errmsg))) {
79 + case CHR_ERROR:
80 + ctfmerge_fatal("failed to open %s: %s\n", name, errmsg);
81 + break;
84 82
85 - if (shdr.sh_type == SHT_SYMTAB)
86 - break;
87 - }
83 + case CHR_NO_C_SOURCE:
84 + return;
88 85
89 - if (scn == NULL)
90 - return (B_FALSE);
91 -
92 - if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL)
93 - ctfmerge_fatal("failed to get section header for file %s: %s\n",
94 - name, elf_errmsg(elf_errno()));
95 -
96 - if ((data = elf_getdata(scn, NULL)) == NULL)
97 - ctfmerge_fatal("failed to read symbol table for %s: %s\n",
98 - name, elf_errmsg(elf_errno()));
99 -
100 - if ((strdata = elf_getdata(strscn, NULL)) == NULL)
101 - ctfmerge_fatal("failed to read string table for %s: %s\n",
102 - name, elf_errmsg(elf_errno()));
103 -
104 - for (i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
105 - GElf_Sym sym;
106 - const char *file;
107 - size_t len;
108 -
109 - if (gelf_getsym(data, i, &sym) == NULL)
110 - ctfmerge_fatal("failed to read symbol table entry %lu "
111 - "for %s: %s\n", i, name, elf_errmsg(elf_errno()));
112 -
113 - if (GELF_ST_TYPE(sym.st_info) != STT_FILE)
114 - continue;
115 -
116 - file = (const char *)((uintptr_t)strdata->d_buf + sym.st_name);
117 - len = strlen(file);
118 - if (len < 2 || name[len - 2] != '.')
119 - continue;
120 -
121 - if (name[len - 1] == 'c')
122 - return (B_TRUE);
86 + default:
87 + ctfmerge_fatal("failed to open %s: %s\n", name,
88 + ctf_errmsg(ECTF_NOCTFDATA));
89 + break;
123 90 }
124 -
125 - return (B_FALSE);
126 91 }
127 92
128 93 /*
129 94 * Go through and construct enough information for this Elf Object to try and do
130 95 * a ctf_bufopen().
131 96 */
132 -static void
133 -ctfmerge_elfopen(const char *name, Elf *elf, ctf_merge_t *cmh)
97 +static int
98 +ctfmerge_elfopen(const char *name, Elf *elf, ctf_merge_t *cmh, uint_t flags)
134 99 {
135 100 GElf_Ehdr ehdr;
136 101 GElf_Shdr shdr;
137 102 Elf_Scn *scn;
138 103 Elf_Data *ctf_data, *str_data, *sym_data;
139 104 ctf_sect_t ctfsect, symsect, strsect;
140 105 ctf_file_t *fp;
141 106 int err;
142 107
143 108 if (gelf_getehdr(elf, &ehdr) == NULL)
144 109 ctfmerge_fatal("failed to get ELF header for %s: %s\n",
145 110 name, elf_errmsg(elf_errno()));
146 111
147 112 bzero(&ctfsect, sizeof (ctf_sect_t));
148 113 bzero(&symsect, sizeof (ctf_sect_t));
149 114 bzero(&strsect, sizeof (ctf_sect_t));
150 115
151 116 scn = NULL;
152 117 while ((scn = elf_nextscn(elf, scn)) != NULL) {
153 118 const char *sname;
154 119
155 120 if (gelf_getshdr(scn, &shdr) == NULL)
156 121 ctfmerge_fatal("failed to get section header for "
157 122 "file %s: %s\n", name, elf_errmsg(elf_errno()));
158 123
159 124 sname = elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name);
160 125 if (shdr.sh_type == SHT_PROGBITS &&
161 126 strcmp(sname, ".SUNW_ctf") == 0) {
162 127 ctfsect.cts_name = sname;
163 128 ctfsect.cts_type = shdr.sh_type;
164 129 ctfsect.cts_flags = shdr.sh_flags;
165 130 ctfsect.cts_size = shdr.sh_size;
166 131 ctfsect.cts_entsize = shdr.sh_entsize;
167 132 ctfsect.cts_offset = (off64_t)shdr.sh_offset;
168 133
169 134 ctf_data = elf_getdata(scn, NULL);
170 135 if (ctf_data == NULL)
171 136 ctfmerge_fatal("failed to get ELF CTF "
172 137 "data section for %s: %s\n", name,
173 138 elf_errmsg(elf_errno()));
174 139 ctfsect.cts_data = ctf_data->d_buf;
175 140 } else if (shdr.sh_type == SHT_SYMTAB) {
176 141 Elf_Scn *strscn;
177 142 GElf_Shdr strhdr;
178 143
179 144 symsect.cts_name = sname;
180 145 symsect.cts_type = shdr.sh_type;
181 146 symsect.cts_flags = shdr.sh_flags;
182 147 symsect.cts_size = shdr.sh_size;
183 148 symsect.cts_entsize = shdr.sh_entsize;
184 149 symsect.cts_offset = (off64_t)shdr.sh_offset;
185 150
186 151 if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL ||
187 152 gelf_getshdr(strscn, &strhdr) == NULL)
188 153 ctfmerge_fatal("failed to get "
189 154 "string table for file %s: %s\n", name,
190 155 elf_errmsg(elf_errno()));
191 156
192 157 strsect.cts_name = elf_strptr(elf, ehdr.e_shstrndx,
193 158 strhdr.sh_name);
194 159 strsect.cts_type = strhdr.sh_type;
195 160 strsect.cts_flags = strhdr.sh_flags;
196 161 strsect.cts_size = strhdr.sh_size;
197 162 strsect.cts_entsize = strhdr.sh_entsize;
198 163 strsect.cts_offset = (off64_t)strhdr.sh_offset;
199 164
200 165 sym_data = elf_getdata(scn, NULL);
201 166 if (sym_data == NULL)
202 167 ctfmerge_fatal("failed to get ELF CTF "
203 168 "data section for %s: %s\n", name,
204 169 elf_errmsg(elf_errno()));
205 170 symsect.cts_data = sym_data->d_buf;
206 171
↓ open down ↓ |
63 lines elided |
↑ open up ↑ |
207 172 str_data = elf_getdata(strscn, NULL);
208 173 if (str_data == NULL)
209 174 ctfmerge_fatal("failed to get ELF CTF "
210 175 "data section for %s: %s\n", name,
211 176 elf_errmsg(elf_errno()));
212 177 strsect.cts_data = str_data->d_buf;
213 178 }
214 179 }
215 180
216 181 if (ctfsect.cts_type == SHT_NULL) {
217 - if (ctfmerge_expect_ctf(name, elf) == B_FALSE)
218 - return;
219 - ctfmerge_fatal("failed to open %s: %s\n", name,
220 - ctf_errmsg(ECTF_NOCTFDATA));
182 + ctfmerge_check_for_c(name, elf, flags);
183 + return (ENOENT);
221 184 }
222 185
223 186 if (symsect.cts_type != SHT_NULL && strsect.cts_type != SHT_NULL) {
224 187 fp = ctf_bufopen(&ctfsect, &symsect, &strsect, &err);
225 188 } else {
226 189 fp = ctf_bufopen(&ctfsect, NULL, NULL, &err);
227 190 }
228 191
229 192 if (fp == NULL) {
230 - if (ctfmerge_expect_ctf(name, elf) == B_TRUE) {
231 - ctfmerge_fatal("failed to open file %s: %s\n",
232 - name, ctf_errmsg(err));
233 - }
234 - } else {
235 - if ((err = ctf_merge_add(cmh, fp)) != 0) {
236 - ctfmerge_fatal("failed to add input %s: %s\n",
237 - name, ctf_errmsg(err));
238 - }
239 - g_nctf++;
193 + ctfmerge_fatal("failed to open file %s: %s\n",
194 + name, ctf_errmsg(err));
240 195 }
196 +
197 + if ((err = ctf_merge_add(cmh, fp)) != 0) {
198 + ctfmerge_fatal("failed to add input %s: %s\n",
199 + name, ctf_errmsg(err));
200 + }
201 +
202 + g_nctf++;
203 + return (0);
241 204 }
242 205
243 206 static void
244 207 ctfmerge_read_archive(const char *name, int fd, Elf *elf,
245 - ctf_merge_t *cmh)
208 + ctf_merge_t *cmh, uint_t flags)
246 209 {
247 - Elf *aelf;
248 210 Elf_Cmd cmd = ELF_C_READ;
249 211 int cursec = 1;
250 - char *nname;
212 + Elf *aelf;
251 213
252 214 while ((aelf = elf_begin(fd, cmd, elf)) != NULL) {
215 + char *nname = NULL;
253 216 Elf_Arhdr *arhdr;
254 - boolean_t leakelf = B_FALSE;
255 217
256 218 if ((arhdr = elf_getarhdr(aelf)) == NULL)
257 219 ctfmerge_fatal("failed to get archive header %d for "
258 220 "%s: %s\n", cursec, name, elf_errmsg(elf_errno()));
259 221
222 + cmd = elf_next(aelf);
223 +
260 224 if (*(arhdr->ar_name) == '/')
261 225 goto next;
262 226
263 227 if (asprintf(&nname, "%s.%s.%d", name, arhdr->ar_name,
264 228 cursec) < 0)
265 229 ctfmerge_fatal("failed to allocate memory for archive "
266 230 "%d of file %s\n", cursec, name);
267 231
268 232 switch (elf_kind(aelf)) {
269 233 case ELF_K_AR:
270 - ctfmerge_read_archive(nname, fd, aelf, cmh);
271 - free(nname);
234 + ctfmerge_read_archive(nname, fd, aelf, cmh, flags);
272 235 break;
273 236 case ELF_K_ELF:
274 - ctfmerge_elfopen(nname, aelf, cmh);
275 - free(nname);
276 - leakelf = B_TRUE;
237 + /* ctfmerge_elfopen() takes ownership of aelf. */
238 + if (ctfmerge_elfopen(nname, aelf, cmh, flags) == 0)
239 + aelf = NULL;
277 240 break;
278 241 default:
279 242 ctfmerge_fatal("unknown elf kind (%d) in archive %d "
280 243 "for %s\n", elf_kind(aelf), cursec, name);
244 + break;
281 245 }
282 246
283 247 next:
284 - cmd = elf_next(aelf);
285 - if (leakelf == B_FALSE)
286 - (void) elf_end(aelf);
248 + (void) elf_end(aelf);
249 + free(nname);
287 250 cursec++;
288 251 }
289 252 }
290 253
291 254 static void
255 +ctfmerge_file_add(ctf_merge_t *cmh, const char *file, uint_t flags)
256 +{
257 + Elf *e;
258 + int fd;
259 +
260 + if ((fd = open(file, O_RDONLY)) < 0) {
261 + ctfmerge_fatal("failed to open file %s: %s\n",
262 + file, strerror(errno));
263 + }
264 +
265 + if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
266 + (void) close(fd);
267 + ctfmerge_fatal("failed to open %s: %s\n",
268 + file, elf_errmsg(elf_errno()));
269 + }
270 +
271 + switch (elf_kind(e)) {
272 + case ELF_K_AR:
273 + ctfmerge_read_archive(file, fd, e, cmh, flags);
274 + break;
275 +
276 + case ELF_K_ELF:
277 + /* ctfmerge_elfopen() takes ownership of e. */
278 + if (ctfmerge_elfopen(file, e, cmh, flags) == 0)
279 + e = NULL;
280 + break;
281 +
282 + default:
283 + ctfmerge_fatal("unknown elf kind (%d) for %s\n",
284 + elf_kind(e), file);
285 + }
286 +
287 + (void) elf_end(e);
288 + (void) close(fd);
289 +}
290 +
291 +static void
292 292 ctfmerge_usage(const char *fmt, ...)
293 293 {
294 294 if (fmt != NULL) {
295 295 va_list ap;
296 296
297 297 (void) fprintf(stderr, "%s: ", g_progname);
298 298 va_start(ap, fmt);
299 299 (void) vfprintf(stderr, fmt, ap);
300 300 va_end(ap);
301 301 }
302 302
303 - (void) fprintf(stderr, "Usage: %s [-t] [-d uniqfile] [-l label] "
303 + (void) fprintf(stderr, "Usage: %s [-m] [-d uniqfile] [-l label] "
304 304 "[-L labelenv] [-j nthrs] -o outfile file ...\n"
305 305 "\n"
306 306 "\t-d uniquify merged output against uniqfile\n"
307 307 "\t-j use nthrs threads to perform the merge\n"
308 308 "\t-l set output container's label to specified value\n"
309 309 "\t-L set output container's label to value from environment\n"
310 - "\t-o file to add CTF data to\n"
311 - "\t-t require CTF data from all inputs built from C sources\n",
310 + "\t-m allow C-based input files to not have CTF\n"
311 + "\t-o file to add CTF data to\n",
312 312 g_progname);
313 313 }
314 314
315 315 static void
316 316 ctfmerge_altexec(char **argv)
317 317 {
318 318 const char *alt;
319 319 char *altexec;
320 320
321 321 alt = getenv(CTFMERGE_ALTEXEC);
322 322 if (alt == NULL || *alt == '\0')
323 323 return;
324 324
325 325 altexec = strdup(alt);
326 326 if (altexec == NULL)
327 327 ctfmerge_fatal("failed to allocate memory for altexec\n");
328 328 if (unsetenv(CTFMERGE_ALTEXEC) != 0)
329 329 ctfmerge_fatal("failed to unset %s from environment: %s\n",
330 330 CTFMERGE_ALTEXEC, strerror(errno));
331 331
332 332 (void) execv(altexec, argv);
333 333 ctfmerge_fatal("failed to execute alternate program %s: %s",
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
334 334 altexec, strerror(errno));
335 335 }
336 336
337 337 int
338 338 main(int argc, char *argv[])
339 339 {
340 340 int err, i, c, ofd;
341 341 uint_t nthreads = CTFMERGE_DEFAULT_NTHREADS;
342 342 char *tmpfile = NULL, *label = NULL;
343 343 int wflags = CTF_ELFWRITE_F_COMPRESS;
344 - ctf_file_t *ofp;
344 + uint_t flags = 0;
345 345 ctf_merge_t *cmh;
346 + ctf_file_t *ofp;
346 347 long argj;
347 348 char *eptr;
348 349
349 350 g_progname = basename(argv[0]);
350 351
351 352 ctfmerge_altexec(argv);
352 353
353 354 /*
354 355 * We support a subset of the old CTF merge flags, mostly for
355 - * compatability.
356 + * compatibility.
356 357 */
357 - while ((c = getopt(argc, argv, ":d:fgj:l:L:o:t")) != -1) {
358 + while ((c = getopt(argc, argv, ":d:fgj:l:L:mo:t")) != -1) {
358 359 switch (c) {
359 360 case 'd':
360 361 g_unique = optarg;
361 362 break;
362 363 case 'f':
363 364 /* Silently ignored for compatibility */
364 365 break;
365 366 case 'g':
366 367 /* Silently ignored for compatibility */
367 368 break;
368 369 case 'j':
369 370 errno = 0;
370 371 argj = strtol(optarg, &eptr, 10);
371 372 if (errno != 0 || argj == LONG_MAX ||
372 373 argj > 1024 || *eptr != '\0') {
373 374 ctfmerge_fatal("invalid argument for -j: %s\n",
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
374 375 optarg);
375 376 }
376 377 nthreads = (uint_t)argj;
377 378 break;
378 379 case 'l':
379 380 label = optarg;
380 381 break;
381 382 case 'L':
382 383 label = getenv(optarg);
383 384 break;
385 + case 'm':
386 + flags |= CTF_ALLOW_MISSING_DEBUG;
387 + break;
384 388 case 'o':
385 389 g_outfile = optarg;
386 390 break;
387 391 case 't':
388 - g_req = B_TRUE;
392 + /* Silently ignored for compatibility */
389 393 break;
390 394 case ':':
391 395 ctfmerge_usage("Option -%c requires an operand\n",
392 396 optopt);
393 397 return (CTFMERGE_USAGE);
394 398 case '?':
395 399 ctfmerge_usage("Unknown option: -%c\n", optopt);
396 400 return (CTFMERGE_USAGE);
397 401 }
398 402 }
399 403
400 404 if (g_outfile == NULL) {
401 405 ctfmerge_usage("missing required -o output file\n");
402 406 return (CTFMERGE_USAGE);
403 407 }
404 408
405 409 (void) elf_version(EV_CURRENT);
406 410
407 411 /*
408 412 * Obviously this isn't atomic, but at least gives us a good starting
409 413 * point.
410 414 */
411 415 if ((ofd = open(g_outfile, O_RDWR)) < 0)
412 416 ctfmerge_fatal("cannot open output file %s: %s\n", g_outfile,
413 417 strerror(errno));
414 418
415 419 argc -= optind;
416 420 argv += optind;
417 421
418 422 if (argc < 1) {
419 423 ctfmerge_usage("no input files specified");
420 424 return (CTFMERGE_USAGE);
421 425 }
422 426
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
423 427 cmh = ctf_merge_init(ofd, &err);
424 428 if (cmh == NULL)
425 429 ctfmerge_fatal("failed to create merge handle: %s\n",
426 430 ctf_errmsg(err));
427 431
428 432 if ((err = ctf_merge_set_nthreads(cmh, nthreads)) != 0)
429 433 ctfmerge_fatal("failed to set parallelism to %u: %s\n",
430 434 nthreads, ctf_errmsg(err));
431 435
432 436 for (i = 0; i < argc; i++) {
433 - ctf_file_t *ifp;
434 - int fd;
435 -
436 - if ((fd = open(argv[i], O_RDONLY)) < 0)
437 - ctfmerge_fatal("failed to open file %s: %s\n",
438 - argv[i], strerror(errno));
439 - ifp = ctf_fdopen(fd, &err);
440 - if (ifp == NULL) {
441 - Elf *e;
442 -
443 - if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
444 - (void) close(fd);
445 - ctfmerge_fatal("failed to open %s: %s\n",
446 - argv[i], ctf_errmsg(err));
447 - }
448 -
449 - /*
450 - * It's an ELF file, check if we have an archive or if
451 - * we're expecting CTF here.
452 - */
453 - switch (elf_kind(e)) {
454 - case ELF_K_AR:
455 - break;
456 - case ELF_K_ELF:
457 - if (ctfmerge_expect_ctf(argv[i], e) == B_TRUE) {
458 - (void) elf_end(e);
459 - (void) close(fd);
460 - ctfmerge_fatal("failed to "
461 - "open %s: file was built from C "
462 - "sources, but missing CTF\n",
463 - argv[i]);
464 - }
465 - (void) elf_end(e);
466 - (void) close(fd);
467 - continue;
468 - default:
469 - (void) elf_end(e);
470 - (void) close(fd);
471 - ctfmerge_fatal("failed to open %s: "
472 - "unsupported ELF file type", argv[i]);
473 - }
474 -
475 - ctfmerge_read_archive(argv[i], fd, e, cmh);
476 - (void) elf_end(e);
477 - (void) close(fd);
478 - continue;
479 - }
480 - (void) close(fd);
481 - if ((err = ctf_merge_add(cmh, ifp)) != 0)
482 - ctfmerge_fatal("failed to add input %s: %s\n",
483 - argv[i], ctf_errmsg(err));
484 - g_nctf++;
437 + ctfmerge_file_add(cmh, argv[i], flags);
485 438 }
486 439
487 440 if (g_nctf == 0) {
488 441 ctf_merge_fini(cmh);
489 442 return (0);
490 443 }
491 444
492 445 if (g_unique != NULL) {
493 446 ctf_file_t *ufp;
494 447 char *base;
495 448
496 449 ufp = ctf_open(g_unique, &err);
497 450 if (ufp == NULL) {
498 451 ctfmerge_fatal("failed to open uniquify file %s: %s\n",
499 452 g_unique, ctf_errmsg(err));
500 453 }
501 454
502 455 base = basename(g_unique);
503 456 (void) ctf_merge_uniquify(cmh, ufp, base);
504 457 }
505 458
506 459 if (label != NULL) {
507 460 if ((err = ctf_merge_label(cmh, label)) != 0)
508 461 ctfmerge_fatal("failed to add label %s: %s\n", label,
509 462 ctf_errmsg(err));
510 463 }
511 464
512 465 err = ctf_merge_merge(cmh, &ofp);
513 466 if (err != 0)
514 467 ctfmerge_fatal("failed to merge types: %s\n", ctf_errmsg(err));
515 468 ctf_merge_fini(cmh);
516 469
517 470 if (asprintf(&tmpfile, "%s.ctf", g_outfile) == -1)
518 471 ctfmerge_fatal("ran out of memory for temporary file name\n");
519 472 err = ctf_elfwrite(ofp, g_outfile, tmpfile, wflags);
520 473 if (err == CTF_ERR) {
521 474 (void) unlink(tmpfile);
522 475 free(tmpfile);
523 476 ctfmerge_fatal("encountered a libctf error: %s!\n",
524 477 ctf_errmsg(ctf_errno(ofp)));
525 478 }
526 479
527 480 if (rename(tmpfile, g_outfile) != 0) {
528 481 (void) unlink(tmpfile);
529 482 free(tmpfile);
530 483 ctfmerge_fatal("failed to rename temporary file: %s\n",
531 484 strerror(errno));
532 485 }
533 486 free(tmpfile);
534 487
535 488 return (CTFMERGE_OK);
536 489 }
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX