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/lib/libctf/common/ctf_convert.c
+++ new/usr/src/lib/libctf/common/ctf_convert.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
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 13 * Copyright 2019 Joyent, Inc.
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 */
15 15
16 16 /*
17 17 * Main conversion entry points. This has been designed such that there can be
18 18 * any number of different conversion backends. Currently we only have one that
19 19 * understands DWARFv2 (and bits of DWARFv4). Each backend should be placed in
20 20 * the ctf_converters list and each will be tried in turn.
21 21 */
22 22
23 23 #include <libctf_impl.h>
24 +#include <assert.h>
24 25 #include <gelf.h>
25 26
26 27 ctf_convert_f ctf_converters[] = {
27 28 ctf_dwarf_convert
28 29 };
29 30
30 31 #define NCONVERTS (sizeof (ctf_converters) / sizeof (ctf_convert_f))
31 32
32 -typedef enum ctf_convert_source {
33 - CTFCONV_SOURCE_NONE = 0x0,
34 - CTFCONV_SOURCE_UNKNOWN = 0x01,
35 - CTFCONV_SOURCE_C = 0x02,
36 - CTFCONV_SOURCE_S = 0x04
37 -} ctf_convert_source_t;
38 -
39 -static void
40 -ctf_convert_ftypes(Elf *elf, ctf_convert_source_t *types)
33 +ctf_hsc_ret_t
34 +ctf_has_c_source(Elf *elf, char *errmsg, size_t errlen)
41 35 {
42 - int i;
43 - Elf_Scn *scn = NULL, *strscn;
44 - *types = CTFCONV_SOURCE_NONE;
45 - GElf_Shdr shdr;
36 + ctf_hsc_ret_t ret = CHR_NO_C_SOURCE;
37 + Elf_Scn *scn, *strscn;
46 38 Elf_Data *data, *strdata;
39 + GElf_Shdr shdr;
40 + ulong_t i;
47 41
42 + scn = NULL;
48 43 while ((scn = elf_nextscn(elf, scn)) != NULL) {
44 + if (gelf_getshdr(scn, &shdr) == NULL) {
45 + (void) snprintf(errmsg, errlen,
46 + "failed to get section header: %s",
47 + elf_errmsg(elf_errno()));
48 + return (CHR_ERROR);
49 + }
49 50
50 - if (gelf_getshdr(scn, &shdr) == NULL)
51 - return;
52 -
53 51 if (shdr.sh_type == SHT_SYMTAB)
54 52 break;
55 53 }
56 54
57 55 if (scn == NULL)
58 - return;
56 + return (CHR_NO_C_SOURCE);
59 57
60 - if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL)
61 - return;
58 + if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL) {
59 + (void) snprintf(errmsg, errlen, "failed to get str section: %s",
60 + elf_errmsg(elf_errno()));
61 + return (CHR_ERROR);
62 + }
62 63
63 - if ((data = elf_getdata(scn, NULL)) == NULL)
64 - return;
64 + if ((data = elf_getdata(scn, NULL)) == NULL) {
65 + (void) snprintf(errmsg, errlen, "failed to read section: %s",
66 + elf_errmsg(elf_errno()));
67 + return (CHR_ERROR);
68 + }
65 69
66 - if ((strdata = elf_getdata(strscn, NULL)) == NULL)
67 - return;
70 + if ((strdata = elf_getdata(strscn, NULL)) == NULL) {
71 + (void) snprintf(errmsg, errlen,
72 + "failed to read string table: %s", elf_errmsg(elf_errno()));
73 + return (CHR_ERROR);
74 + }
68 75
69 76 for (i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
70 77 GElf_Sym sym;
71 78 const char *file;
72 79 size_t len;
73 80
74 - if (gelf_getsym(data, i, &sym) == NULL)
75 - return;
81 + if (gelf_getsym(data, i, &sym) == NULL) {
82 + (void) snprintf(errmsg, errlen,
83 + "failed to read sym %lu: %s",
84 + i, elf_errmsg(elf_errno()));
85 + return (CHR_ERROR);
86 + }
76 87
77 88 if (GELF_ST_TYPE(sym.st_info) != STT_FILE)
78 89 continue;
79 90
80 91 file = (const char *)((uintptr_t)strdata->d_buf + sym.st_name);
81 92 len = strlen(file);
82 - if (len < 2 || file[len - 2] != '.') {
83 - *types |= CTFCONV_SOURCE_UNKNOWN;
84 - continue;
85 - }
86 -
87 - switch (file[len - 1]) {
88 - case 'c':
89 - *types |= CTFCONV_SOURCE_C;
93 + if (len >= 2 && strncmp(".c", &file[len - 2], 2) == 0) {
94 + ret = CHR_HAS_C_SOURCE;
90 95 break;
91 - case 'h':
92 - /* We traditionally ignore header files... */
93 - break;
94 - case 's':
95 - *types |= CTFCONV_SOURCE_S;
96 - break;
97 - default:
98 - *types |= CTFCONV_SOURCE_UNKNOWN;
99 - break;
100 96 }
101 97 }
98 +
99 + return (ret);
102 100 }
103 101
104 102 static ctf_file_t *
105 103 ctf_elfconvert(int fd, Elf *elf, const char *label, uint_t nthrs, uint_t flags,
106 104 int *errp, char *errbuf, size_t errlen)
107 105 {
108 106 int err, i;
109 107 ctf_file_t *fp = NULL;
110 - boolean_t notsup = B_TRUE;
111 - ctf_convert_source_t type;
112 108
113 109 if (errp == NULL)
114 110 errp = &err;
115 111
116 112 if (elf == NULL) {
117 113 *errp = EINVAL;
118 114 return (NULL);
119 115 }
120 116
121 - if (flags & ~CTF_CONVERT_F_IGNNONC) {
117 + if (flags & ~CTF_ALLOW_MISSING_DEBUG) {
122 118 *errp = EINVAL;
123 119 return (NULL);
124 120 }
125 121
126 122 if (elf_kind(elf) != ELF_K_ELF) {
127 123 *errp = ECTF_FMT;
128 124 return (NULL);
129 125 }
130 126
131 - ctf_convert_ftypes(elf, &type);
132 - ctf_dprintf("got types: %d\n", type);
133 - if (flags & CTF_CONVERT_F_IGNNONC) {
134 - if (type == CTFCONV_SOURCE_NONE ||
135 - (type & CTFCONV_SOURCE_UNKNOWN)) {
136 - *errp = ECTF_CONVNOCSRC;
137 - return (NULL);
138 - }
127 + switch (ctf_has_c_source(elf, errbuf, errlen)) {
128 + case CHR_ERROR:
129 + *errp = ECTF_ELF;
130 + return (NULL);
131 +
132 + case CHR_NO_C_SOURCE:
133 + *errp = ECTF_CONVNOCSRC;
134 + return (NULL);
135 +
136 + default:
137 + break;
139 138 }
140 139
141 140 for (i = 0; i < NCONVERTS; i++) {
142 - ctf_conv_status_t cs;
143 -
144 141 fp = NULL;
145 - cs = ctf_converters[i](fd, elf, nthrs, errp, &fp, errbuf,
146 - errlen);
147 - if (cs == CTF_CONV_SUCCESS) {
148 - notsup = B_FALSE;
142 + err = ctf_converters[i](fd, elf, nthrs, flags,
143 + &fp, errbuf, errlen);
144 +
145 + if (err != ECTF_CONVNODEBUG)
149 146 break;
150 - }
151 - if (cs == CTF_CONV_ERROR) {
152 - fp = NULL;
153 - notsup = B_FALSE;
154 - break;
155 - }
156 147 }
157 148
158 - if (notsup == B_TRUE) {
159 - if ((flags & CTF_CONVERT_F_IGNNONC) != 0 &&
160 - (type & CTFCONV_SOURCE_C) == 0) {
161 - *errp = ECTF_CONVNOCSRC;
162 - return (NULL);
163 - }
164 - *errp = ECTF_NOCONVBKEND;
149 + if (err != 0) {
150 + assert(fp == NULL);
151 + *errp = err;
165 152 return (NULL);
166 153 }
167 154
168 - /*
169 - * Succsesful conversion.
170 - */
171 - if (fp != NULL && label != NULL) {
155 + if (label != NULL) {
172 156 if (ctf_add_label(fp, label, fp->ctf_typemax, 0) == CTF_ERR) {
173 157 *errp = ctf_errno(fp);
174 158 ctf_close(fp);
175 159 return (NULL);
176 160 }
177 161 if (ctf_update(fp) == CTF_ERR) {
178 162 *errp = ctf_errno(fp);
179 163 ctf_close(fp);
180 164 return (NULL);
181 165 }
182 166 }
183 167
184 168 return (fp);
185 169 }
186 170
187 171 ctf_file_t *
188 172 ctf_fdconvert(int fd, const char *label, uint_t nthrs, uint_t flags, int *errp,
189 173 char *errbuf, size_t errlen)
190 174 {
191 175 int err;
192 176 Elf *elf;
193 177 ctf_file_t *fp;
194 178
195 179 if (errp == NULL)
196 180 errp = &err;
197 181
198 182 elf = elf_begin(fd, ELF_C_READ, NULL);
199 183 if (elf == NULL) {
200 184 *errp = ECTF_FMT;
201 185 return (NULL);
202 186 }
203 187
204 188 fp = ctf_elfconvert(fd, elf, label, nthrs, flags, errp, errbuf, errlen);
205 189
206 190 (void) elf_end(elf);
207 191 return (fp);
208 192 }
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX