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
↓ 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                  }
↓ open down ↓ 27 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX