Print this page
10812 ctf tools shouldn't add blank labels
10813 ctf symbol mapping needs work
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
↓ 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 2015 Joyent, Inc.
13 + * Copyright 2019 Joyent, Inc.
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 24 #include <gelf.h>
25 25
26 26 ctf_convert_f ctf_converters[] = {
27 27 ctf_dwarf_convert
28 28 };
29 29
30 30 #define NCONVERTS (sizeof (ctf_converters) / sizeof (ctf_convert_f))
31 31
32 32 typedef enum ctf_convert_source {
33 33 CTFCONV_SOURCE_NONE = 0x0,
34 34 CTFCONV_SOURCE_UNKNOWN = 0x01,
35 35 CTFCONV_SOURCE_C = 0x02,
36 36 CTFCONV_SOURCE_S = 0x04
37 37 } ctf_convert_source_t;
38 38
39 39 static void
40 40 ctf_convert_ftypes(Elf *elf, ctf_convert_source_t *types)
41 41 {
42 42 int i;
43 43 Elf_Scn *scn = NULL, *strscn;
44 44 *types = CTFCONV_SOURCE_NONE;
45 45 GElf_Shdr shdr;
46 46 Elf_Data *data, *strdata;
47 47
48 48 while ((scn = elf_nextscn(elf, scn)) != NULL) {
49 49
50 50 if (gelf_getshdr(scn, &shdr) == NULL)
51 51 return;
52 52
53 53 if (shdr.sh_type == SHT_SYMTAB)
54 54 break;
55 55 }
56 56
57 57 if (scn == NULL)
58 58 return;
59 59
60 60 if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL)
61 61 return;
62 62
63 63 if ((data = elf_getdata(scn, NULL)) == NULL)
64 64 return;
65 65
66 66 if ((strdata = elf_getdata(strscn, NULL)) == NULL)
67 67 return;
68 68
69 69 for (i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
70 70 GElf_Sym sym;
71 71 const char *file;
72 72 size_t len;
73 73
74 74 if (gelf_getsym(data, i, &sym) == NULL)
75 75 return;
76 76
77 77 if (GELF_ST_TYPE(sym.st_info) != STT_FILE)
78 78 continue;
79 79
80 80 file = (const char *)((uintptr_t)strdata->d_buf + sym.st_name);
81 81 len = strlen(file);
82 82 if (len < 2 || file[len - 2] != '.') {
83 83 *types |= CTFCONV_SOURCE_UNKNOWN;
84 84 continue;
85 85 }
86 86
87 87 switch (file[len - 1]) {
88 88 case 'c':
89 89 *types |= CTFCONV_SOURCE_C;
90 90 break;
91 91 case 'h':
92 92 /* We traditionally ignore header files... */
93 93 break;
94 94 case 's':
95 95 *types |= CTFCONV_SOURCE_S;
96 96 break;
97 97 default:
98 98 *types |= CTFCONV_SOURCE_UNKNOWN;
99 99 break;
100 100 }
101 101 }
102 102 }
103 103
104 104 static ctf_file_t *
105 105 ctf_elfconvert(int fd, Elf *elf, const char *label, uint_t nthrs, uint_t flags,
106 106 int *errp, char *errbuf, size_t errlen)
107 107 {
108 108 int err, i;
109 109 ctf_file_t *fp = NULL;
110 110 boolean_t notsup = B_TRUE;
111 111 ctf_convert_source_t type;
112 112
113 113 if (errp == NULL)
114 114 errp = &err;
115 115
116 116 if (elf == NULL) {
117 117 *errp = EINVAL;
118 118 return (NULL);
119 119 }
120 120
121 121 if (flags & ~CTF_CONVERT_F_IGNNONC) {
122 122 *errp = EINVAL;
123 123 return (NULL);
124 124 }
125 125
126 126 if (elf_kind(elf) != ELF_K_ELF) {
127 127 *errp = ECTF_FMT;
128 128 return (NULL);
129 129 }
130 130
131 131 ctf_convert_ftypes(elf, &type);
132 132 ctf_dprintf("got types: %d\n", type);
133 133 if (flags & CTF_CONVERT_F_IGNNONC) {
134 134 if (type == CTFCONV_SOURCE_NONE ||
135 135 (type & CTFCONV_SOURCE_UNKNOWN)) {
136 136 *errp = ECTF_CONVNOCSRC;
137 137 return (NULL);
138 138 }
139 139 }
140 140
141 141 for (i = 0; i < NCONVERTS; i++) {
142 142 ctf_conv_status_t cs;
143 143
144 144 fp = NULL;
145 145 cs = ctf_converters[i](fd, elf, nthrs, errp, &fp, errbuf,
146 146 errlen);
147 147 if (cs == CTF_CONV_SUCCESS) {
148 148 notsup = B_FALSE;
149 149 break;
150 150 }
151 151 if (cs == CTF_CONV_ERROR) {
152 152 fp = NULL;
153 153 notsup = B_FALSE;
154 154 break;
155 155 }
156 156 }
157 157
158 158 if (notsup == B_TRUE) {
159 159 if ((flags & CTF_CONVERT_F_IGNNONC) != 0 &&
160 160 (type & CTFCONV_SOURCE_C) == 0) {
↓ open down ↓ |
137 lines elided |
↑ open up ↑ |
161 161 *errp = ECTF_CONVNOCSRC;
162 162 return (NULL);
163 163 }
164 164 *errp = ECTF_NOCONVBKEND;
165 165 return (NULL);
166 166 }
167 167
168 168 /*
169 169 * Succsesful conversion.
170 170 */
171 - if (fp != NULL) {
172 - if (label == NULL)
173 - label = "";
171 + if (fp != NULL && label != NULL) {
174 172 if (ctf_add_label(fp, label, fp->ctf_typemax, 0) == CTF_ERR) {
175 173 *errp = ctf_errno(fp);
176 174 ctf_close(fp);
177 175 return (NULL);
178 176 }
179 177 if (ctf_update(fp) == CTF_ERR) {
180 178 *errp = ctf_errno(fp);
181 179 ctf_close(fp);
182 180 return (NULL);
183 181 }
184 182 }
185 183
186 184 return (fp);
187 185 }
188 186
189 187 ctf_file_t *
190 188 ctf_fdconvert(int fd, const char *label, uint_t nthrs, uint_t flags, int *errp,
191 189 char *errbuf, size_t errlen)
192 190 {
193 191 int err;
194 192 Elf *elf;
195 193 ctf_file_t *fp;
196 194
197 195 if (errp == NULL)
198 196 errp = &err;
199 197
200 198 elf = elf_begin(fd, ELF_C_READ, NULL);
201 199 if (elf == NULL) {
202 200 *errp = ECTF_FMT;
203 201 return (NULL);
204 202 }
205 203
206 204 fp = ctf_elfconvert(fd, elf, label, nthrs, flags, errp, errbuf, errlen);
207 205
208 206 (void) elf_end(elf);
209 207 return (fp);
210 208 }
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX