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