diff options
Diffstat (limited to 'usr/src/lib/libctf/common')
-rw-r--r-- | usr/src/lib/libctf/common/ctf_convert.c | 35 | ||||
-rw-r--r-- | usr/src/lib/libctf/common/libctf.h | 11 |
2 files changed, 38 insertions, 8 deletions
diff --git a/usr/src/lib/libctf/common/ctf_convert.c b/usr/src/lib/libctf/common/ctf_convert.c index b38831aa0e..dcf84e57c9 100644 --- a/usr/src/lib/libctf/common/ctf_convert.c +++ b/usr/src/lib/libctf/common/ctf_convert.c @@ -53,8 +53,10 @@ ctf_has_c_source(Elf *elf, char *errmsg, size_t errlen) break; } - if (scn == NULL) + if (scn == NULL) { + ctf_dprintf("Could not find symbol table section\n"); return (CHR_NO_C_SOURCE); + } if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL) { (void) snprintf(errmsg, errlen, "failed to get str section: %s", @@ -74,6 +76,8 @@ ctf_has_c_source(Elf *elf, char *errmsg, size_t errlen) return (CHR_ERROR); } + ctf_dprintf("Walking string table looking for .c files\n"); + for (i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) { GElf_Sym sym; const char *file; @@ -86,13 +90,19 @@ ctf_has_c_source(Elf *elf, char *errmsg, size_t errlen) return (CHR_ERROR); } - if (GELF_ST_TYPE(sym.st_info) != STT_FILE) + file = (const char *)((uintptr_t)strdata->d_buf + sym.st_name); + + if (GELF_ST_TYPE(sym.st_info) != STT_FILE) { + ctf_dprintf("'%s'\n", file); continue; + } + + ctf_dprintf("'%s'; is a file\n", file); - 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; + ctf_dprintf("Found .c file - '%s'\n", file); break; } } @@ -106,6 +116,7 @@ ctf_elfconvert(ctf_convert_t *cch, int fd, Elf *elf, int *errp, char *errbuf, { int err, i; ctf_file_t *fp = NULL; + boolean_t no_c_src = B_FALSE; if (errp == NULL) errp = &err; @@ -126,8 +137,12 @@ ctf_elfconvert(ctf_convert_t *cch, int fd, Elf *elf, int *errp, char *errbuf, return (NULL); case CHR_NO_C_SOURCE: - *errp = ECTF_CONVNOCSRC; - return (NULL); + if ((cch->cch_flags & CTF_FORCE_CONVERSION) == 0) { + *errp = ECTF_CONVNOCSRC; + return (NULL); + } + no_c_src = B_TRUE; + break; default: break; @@ -143,7 +158,15 @@ ctf_elfconvert(ctf_convert_t *cch, int fd, Elf *elf, int *errp, char *errbuf, if (err != 0) { assert(fp == NULL); - *errp = err; + /* + * If no C source was found but we attempted conversion anyway + * due to CTF_FORCE_CONVERSION, and none of the converters + * was able to process the object, return ECTF_CONVNOCSRC. + */ + if (no_c_src && err == ECTF_CONVNODEBUG) + *errp = ECTF_CONVNOCSRC; + else + *errp = err; return (NULL); } diff --git a/usr/src/lib/libctf/common/libctf.h b/usr/src/lib/libctf/common/libctf.h index 5f0721e99f..8f6a232057 100644 --- a/usr/src/lib/libctf/common/libctf.h +++ b/usr/src/lib/libctf/common/libctf.h @@ -91,11 +91,18 @@ typedef enum ctf_convert_flag { * to CTF format, such as an enum with too many values. This flag * allows us to continue and convert what we can. */ - CTF_ALLOW_TRUNCATION = 0x02 + CTF_ALLOW_TRUNCATION = 0x02, + /* + * Conversion is not usually attempted for objects that don't appear + * to be built from C sources. This flag overrides this and attempts + * conversion anyway. + */ + CTF_FORCE_CONVERSION = 0x04 } ctf_convert_flag_t; #define CTF_CONVERT_ALL_FLAGS (CTF_ALLOW_MISSING_DEBUG | \ - CTF_ALLOW_TRUNCATION) + CTF_ALLOW_TRUNCATION | \ + CTF_FORCE_CONVERSION) /* opaque handle for ctfconvert functions */ struct ctf_convert_handle; |