2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright 2015 Joyent, Inc.
17 * Main conversion entry points. This has been designed such that there can be
18 * any number of different conversion backends. Currently we only have one that
19 * understands DWARFv2 (and bits of DWARFv4). Each backend should be placed in
20 * the ctf_converters list and each will be tried in turn.
23 #include <libctf_impl.h>
26 ctf_convert_f ctf_converters
[] = {
30 #define NCONVERTS (sizeof (ctf_converters) / sizeof (ctf_convert_f))
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
;
40 ctf_convert_ftypes(Elf
*elf
, ctf_convert_source_t
*types
)
43 Elf_Scn
*scn
= NULL
, *strscn
;
44 *types
= CTFCONV_SOURCE_NONE
;
46 Elf_Data
*data
, *strdata
;
48 while ((scn
= elf_nextscn(elf
, scn
)) != NULL
) {
50 if (gelf_getshdr(scn
, &shdr
) == NULL
)
53 if (shdr
.sh_type
== SHT_SYMTAB
)
60 if ((strscn
= elf_getscn(elf
, shdr
.sh_link
)) == NULL
)
63 if ((data
= elf_getdata(scn
, NULL
)) == NULL
)
66 if ((strdata
= elf_getdata(strscn
, NULL
)) == NULL
)
69 for (i
= 0; i
< shdr
.sh_size
/ shdr
.sh_entsize
; i
++) {
74 if (gelf_getsym(data
, i
, &sym
) == NULL
)
77 if (GELF_ST_TYPE(sym
.st_info
) != STT_FILE
)
80 file
= (const char *)((uintptr_t)strdata
->d_buf
+ sym
.st_name
);
82 if (len
< 2 || file
[len
- 2] != '.') {
83 *types
|= CTFCONV_SOURCE_UNKNOWN
;
87 switch (file
[len
- 1]) {
89 *types
|= CTFCONV_SOURCE_C
;
92 /* We traditionally ignore header files... */
95 *types
|= CTFCONV_SOURCE_S
;
98 *types
|= CTFCONV_SOURCE_UNKNOWN
;
105 ctf_elfconvert(int fd
, Elf
*elf
, const char *label
, uint_t nthrs
, uint_t flags
,
106 int *errp
, char *errbuf
, size_t errlen
)
109 ctf_file_t
*fp
= NULL
;
110 boolean_t notsup
= B_TRUE
;
111 ctf_convert_source_t type
;
121 if (flags
& ~CTF_CONVERT_F_IGNNONC
) {
126 if (elf_kind(elf
) != ELF_K_ELF
) {
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
;
141 for (i
= 0; i
< NCONVERTS
; i
++) {
142 ctf_conv_status_t cs
;
145 cs
= ctf_converters
[i
](fd
, elf
, nthrs
, errp
, &fp
, errbuf
,
147 if (cs
== CTF_CONV_SUCCESS
) {
151 if (cs
== CTF_CONV_ERROR
) {
158 if (notsup
== B_TRUE
) {
159 if ((flags
& CTF_CONVERT_F_IGNNONC
) != 0 &&
160 (type
& CTFCONV_SOURCE_C
) == 0) {
161 *errp
= ECTF_CONVNOCSRC
;
164 *errp
= ECTF_NOCONVBKEND
;
169 * Succsesful conversion.
174 if (ctf_add_label(fp
, label
, fp
->ctf_typemax
, 0) == CTF_ERR
) {
175 *errp
= ctf_errno(fp
);
179 if (ctf_update(fp
) == CTF_ERR
) {
180 *errp
= ctf_errno(fp
);
190 ctf_fdconvert(int fd
, const char *label
, uint_t nthrs
, uint_t flags
, int *errp
,
191 char *errbuf
, size_t errlen
)
200 elf
= elf_begin(fd
, ELF_C_READ
, NULL
);
206 fp
= ctf_elfconvert(fd
, elf
, label
, nthrs
, flags
, errp
, errbuf
, errlen
);