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>
*** 19,176 ****
* understands DWARFv2 (and bits of DWARFv4). Each backend should be placed in
* the ctf_converters list and each will be tried in turn.
*/
#include <libctf_impl.h>
#include <gelf.h>
ctf_convert_f ctf_converters[] = {
ctf_dwarf_convert
};
#define NCONVERTS (sizeof (ctf_converters) / sizeof (ctf_convert_f))
! typedef enum ctf_convert_source {
! CTFCONV_SOURCE_NONE = 0x0,
! CTFCONV_SOURCE_UNKNOWN = 0x01,
! CTFCONV_SOURCE_C = 0x02,
! CTFCONV_SOURCE_S = 0x04
! } ctf_convert_source_t;
!
! static void
! ctf_convert_ftypes(Elf *elf, ctf_convert_source_t *types)
{
! int i;
! Elf_Scn *scn = NULL, *strscn;
! *types = CTFCONV_SOURCE_NONE;
! GElf_Shdr shdr;
Elf_Data *data, *strdata;
while ((scn = elf_nextscn(elf, scn)) != NULL) {
- if (gelf_getshdr(scn, &shdr) == NULL)
- return;
-
if (shdr.sh_type == SHT_SYMTAB)
break;
}
if (scn == NULL)
! return;
! if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL)
! return;
! if ((data = elf_getdata(scn, NULL)) == NULL)
! return;
! if ((strdata = elf_getdata(strscn, NULL)) == NULL)
! return;
for (i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
GElf_Sym sym;
const char *file;
size_t len;
! if (gelf_getsym(data, i, &sym) == NULL)
! return;
if (GELF_ST_TYPE(sym.st_info) != STT_FILE)
continue;
file = (const char *)((uintptr_t)strdata->d_buf + sym.st_name);
len = strlen(file);
! if (len < 2 || file[len - 2] != '.') {
! *types |= CTFCONV_SOURCE_UNKNOWN;
! continue;
! }
!
! switch (file[len - 1]) {
! case 'c':
! *types |= CTFCONV_SOURCE_C;
break;
- case 'h':
- /* We traditionally ignore header files... */
- break;
- case 's':
- *types |= CTFCONV_SOURCE_S;
- break;
- default:
- *types |= CTFCONV_SOURCE_UNKNOWN;
- break;
}
}
}
static ctf_file_t *
ctf_elfconvert(int fd, Elf *elf, const char *label, uint_t nthrs, uint_t flags,
int *errp, char *errbuf, size_t errlen)
{
int err, i;
ctf_file_t *fp = NULL;
- boolean_t notsup = B_TRUE;
- ctf_convert_source_t type;
if (errp == NULL)
errp = &err;
if (elf == NULL) {
*errp = EINVAL;
return (NULL);
}
! if (flags & ~CTF_CONVERT_F_IGNNONC) {
*errp = EINVAL;
return (NULL);
}
if (elf_kind(elf) != ELF_K_ELF) {
*errp = ECTF_FMT;
return (NULL);
}
! ctf_convert_ftypes(elf, &type);
! ctf_dprintf("got types: %d\n", type);
! if (flags & CTF_CONVERT_F_IGNNONC) {
! if (type == CTFCONV_SOURCE_NONE ||
! (type & CTFCONV_SOURCE_UNKNOWN)) {
*errp = ECTF_CONVNOCSRC;
return (NULL);
}
- }
for (i = 0; i < NCONVERTS; i++) {
- ctf_conv_status_t cs;
-
fp = NULL;
! cs = ctf_converters[i](fd, elf, nthrs, errp, &fp, errbuf,
! errlen);
! if (cs == CTF_CONV_SUCCESS) {
! notsup = B_FALSE;
break;
}
- if (cs == CTF_CONV_ERROR) {
- fp = NULL;
- notsup = B_FALSE;
- break;
- }
- }
! if (notsup == B_TRUE) {
! if ((flags & CTF_CONVERT_F_IGNNONC) != 0 &&
! (type & CTFCONV_SOURCE_C) == 0) {
! *errp = ECTF_CONVNOCSRC;
return (NULL);
}
- *errp = ECTF_NOCONVBKEND;
- return (NULL);
- }
! /*
! * Succsesful conversion.
! */
! if (fp != NULL && label != NULL) {
if (ctf_add_label(fp, label, fp->ctf_typemax, 0) == CTF_ERR) {
*errp = ctf_errno(fp);
ctf_close(fp);
return (NULL);
}
--- 19,160 ----
* understands DWARFv2 (and bits of DWARFv4). Each backend should be placed in
* the ctf_converters list and each will be tried in turn.
*/
#include <libctf_impl.h>
+ #include <assert.h>
#include <gelf.h>
ctf_convert_f ctf_converters[] = {
ctf_dwarf_convert
};
#define NCONVERTS (sizeof (ctf_converters) / sizeof (ctf_convert_f))
! ctf_hsc_ret_t
! ctf_has_c_source(Elf *elf, char *errmsg, size_t errlen)
{
! ctf_hsc_ret_t ret = CHR_NO_C_SOURCE;
! Elf_Scn *scn, *strscn;
Elf_Data *data, *strdata;
+ GElf_Shdr shdr;
+ ulong_t i;
+ scn = NULL;
while ((scn = elf_nextscn(elf, scn)) != NULL) {
+ if (gelf_getshdr(scn, &shdr) == NULL) {
+ (void) snprintf(errmsg, errlen,
+ "failed to get section header: %s",
+ elf_errmsg(elf_errno()));
+ return (CHR_ERROR);
+ }
if (shdr.sh_type == SHT_SYMTAB)
break;
}
if (scn == NULL)
! return (CHR_NO_C_SOURCE);
! if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL) {
! (void) snprintf(errmsg, errlen, "failed to get str section: %s",
! elf_errmsg(elf_errno()));
! return (CHR_ERROR);
! }
! if ((data = elf_getdata(scn, NULL)) == NULL) {
! (void) snprintf(errmsg, errlen, "failed to read section: %s",
! elf_errmsg(elf_errno()));
! return (CHR_ERROR);
! }
! if ((strdata = elf_getdata(strscn, NULL)) == NULL) {
! (void) snprintf(errmsg, errlen,
! "failed to read string table: %s", elf_errmsg(elf_errno()));
! return (CHR_ERROR);
! }
for (i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
GElf_Sym sym;
const char *file;
size_t len;
! if (gelf_getsym(data, i, &sym) == NULL) {
! (void) snprintf(errmsg, errlen,
! "failed to read sym %lu: %s",
! i, elf_errmsg(elf_errno()));
! return (CHR_ERROR);
! }
if (GELF_ST_TYPE(sym.st_info) != STT_FILE)
continue;
file = (const char *)((uintptr_t)strdata->d_buf + sym.st_name);
len = strlen(file);
! if (len >= 2 && strncmp(".c", &file[len - 2], 2) == 0) {
! ret = CHR_HAS_C_SOURCE;
break;
}
}
+
+ return (ret);
}
static ctf_file_t *
ctf_elfconvert(int fd, Elf *elf, const char *label, uint_t nthrs, uint_t flags,
int *errp, char *errbuf, size_t errlen)
{
int err, i;
ctf_file_t *fp = NULL;
if (errp == NULL)
errp = &err;
if (elf == NULL) {
*errp = EINVAL;
return (NULL);
}
! if (flags & ~CTF_ALLOW_MISSING_DEBUG) {
*errp = EINVAL;
return (NULL);
}
if (elf_kind(elf) != ELF_K_ELF) {
*errp = ECTF_FMT;
return (NULL);
}
! switch (ctf_has_c_source(elf, errbuf, errlen)) {
! case CHR_ERROR:
! *errp = ECTF_ELF;
! return (NULL);
!
! case CHR_NO_C_SOURCE:
*errp = ECTF_CONVNOCSRC;
return (NULL);
+
+ default:
+ break;
}
for (i = 0; i < NCONVERTS; i++) {
fp = NULL;
! err = ctf_converters[i](fd, elf, nthrs, flags,
! &fp, errbuf, errlen);
!
! if (err != ECTF_CONVNODEBUG)
break;
}
! if (err != 0) {
! assert(fp == NULL);
! *errp = err;
return (NULL);
}
! if (label != NULL) {
if (ctf_add_label(fp, label, fp->ctf_typemax, 0) == CTF_ERR) {
*errp = ctf_errno(fp);
ctf_close(fp);
return (NULL);
}