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_dwarf.c
          +++ new/usr/src/lib/libctf/common/ctf_dwarf.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  /*
  26   26   * Copyright 2012 Jason King.  All rights reserved.
  27   27   * Use is subject to license terms.
  28   28   */
  29   29  
  30   30  /*
  31   31   * Copyright 2019 Joyent, Inc.
  32   32   */
  33   33  
  34   34  /*
  35   35   * CTF DWARF conversion theory.
  36   36   *
  37   37   * DWARF data contains a series of compilation units. Each compilation unit
  38   38   * generally refers to an object file or what once was, in the case of linked
  39   39   * binaries and shared objects. Each compilation unit has a series of what DWARF
  40   40   * calls a DIE (Debugging Information Entry). The set of entries that we care
  41   41   * about have type information stored in a series of attributes. Each DIE also
  42   42   * has a tag that identifies the kind of attributes that it has.
  43   43   *
  44   44   * A given DIE may itself have children. For example, a DIE that represents a
  45   45   * structure has children which represent members. Whenever we encounter a DIE
  46   46   * that has children or other values or types associated with it, we recursively
  47   47   * process those children first so that way we can then refer to the generated
  48   48   * CTF type id while processing its parent. This reduces the amount of unknowns
  49   49   * and fixups that we need. It also ensures that we don't accidentally add types
  50   50   * that an overzealous compiler might add to the DWARF data but aren't used by
  51   51   * anything in the system.
  52   52   *
  53   53   * Once we do a conversion, we store a mapping in an AVL tree that goes from the
  54   54   * DWARF's die offset, which is relative to the given compilation unit, to a
  55   55   * ctf_id_t.
  56   56   *
  57   57   * Unfortunately, some compilers actually will emit duplicate entries for a
  58   58   * given type that look similar, but aren't quite. To that end, we go through
  59   59   * and do a variant on a merge once we're done processing a single compilation
  60   60   * unit which deduplicates all of the types that are in the unit.
  61   61   *
  62   62   * Finally, if we encounter an object that has multiple compilation units, then
  63   63   * we'll convert all of the compilation units separately and then do a merge, so
  64   64   * that way we can result in one single ctf_file_t that represents everything
  65   65   * for the object.
  66   66   *
  67   67   * Conversion Steps
  68   68   * ----------------
  69   69   *
  70   70   * Because a given object we've been given to convert may have multiple
  71   71   * compilation units, we break the work into two halves. The first half
  72   72   * processes each compilation unit (potentially in parallel) and then the second
  73   73   * half optionally merges all of the dies in the first half. First, we'll cover
  74   74   * what's involved in converting a single ctf_cu_t's dwarf to CTF. This covers
  75   75   * the work done in ctf_dwarf_convert_one().
  76   76   *
  77   77   * An individual ctf_cu_t, which represents a compilation unit, is converted to
  78   78   * CTF in a series of multiple passes.
  79   79   *
  80   80   * Pass 1: During the first pass we walk all of the top-level dies and if we
  81   81   * find a function, variable, struct, union, enum or typedef, we recursively
  82   82   * transform all of its types. We don't recurse or process everything, because
  83   83   * we don't want to add some of the types that compilers may add which are
  84   84   * effectively unused.
  85   85   *
  86   86   * During pass 1, if we encounter any structures or unions we mark them for
  87   87   * fixing up later. This is necessary because we may not be able to determine
  88   88   * the full size of a structure at the beginning of time. This will happen if
  89   89   * the DWARF attribute DW_AT_byte_size is not present for a member. Because of
  90   90   * this possibility we defer adding members to structures or even converting
  91   91   * them during pass 1 and save that for pass 2. Adding all of the base
  92   92   * structures without any of their members helps deal with any circular
  93   93   * dependencies that we might encounter.
  94   94   *
  95   95   * Pass 2: This pass is used to do the first half of fixing up structures and
  96   96   * unions. Rather than walk the entire type space again, we actually walk the
  97   97   * list of structures and unions that we marked for later fixing up. Here, we
  98   98   * iterate over every structure and add members to the underlying ctf_file_t,
  99   99   * but not to the structs themselves. One might wonder why we don't, and the
 100  100   * main reason is that libctf requires a ctf_update() be done before adding the
 101  101   * members to structures or unions.
 102  102   *
 103  103   * Pass 3: This pass is used to do the second half of fixing up structures and
 104  104   * unions. During this part we always go through and add members to structures
 105  105   * and unions that we added to the container in the previous pass. In addition,
 106  106   * we set the structure and union's actual size, which may have additional
 107  107   * padding added by the compiler, it isn't simply the last offset. DWARF always
 108  108   * guarantees an attribute exists for this. Importantly no ctf_id_t's change
 109  109   * during pass 2.
 110  110   *
 111  111   * Pass 4: The next phase is to add CTF entries for all of the symbols and
 112  112   * variables that are present in this die. During pass 1 we added entries to a
 113  113   * map for each variable and function. During this pass, we iterate over the
 114  114   * symbol table and when we encounter a symbol that we have in our lists of
 115  115   * translated information which matches, we then add it to the ctf_file_t.
 116  116   *
 117  117   * Pass 5: Here we go and look for any weak symbols and functions and see if
 118  118   * they match anything that we recognize. If so, then we add type information
 119  119   * for them at this point based on the matching type.
 120  120   *
 121  121   * Pass 6: This pass is actually a variant on a merge. The traditional merge
 122  122   * process expects there to be no duplicate types. As such, at the end of
 123  123   * conversion, we do a dedup on all of the types in the system. The
 124  124   * deduplication process is described in lib/libctf/common/ctf_merge.c.
 125  125   *
 126  126   * Once pass 6 is done, we've finished processing the individual compilation
 127  127   * unit.
 128  128   *
 129  129   * The following steps reflect the general process of doing a conversion.
 130  130   *
 131  131   * 1) Walk the dwarf section and determine the number of compilation units
 132  132   * 2) Create a ctf_cu_t for each compilation unit
 133  133   * 3) Add all ctf_cu_t's to a workq
 134  134   * 4) Have the workq process each die with ctf_dwarf_convert_one. This itself
 135  135   *    is comprised of several steps, which were already enumerated.
 136  136   * 5) If we have multiple cu's, we do a ctf merge of all the dies. The mechanics
 137  137   *    of the merge are discussed in lib/libctf/common/ctf_merge.c.
 138  138   * 6) Free everything up and return a ctf_file_t to the user. If we only had a
 139  139   *    single compilation unit, then we give that to the user. Otherwise, we
 140  140   *    return the merged ctf_file_t.
 141  141   *
 142  142   * Threading
 143  143   * ---------
 144  144   *
 145  145   * The process has been designed to be amenable to threading. Each compilation
 146  146   * unit has its own type stream, therefore the logical place to divide and
 147  147   * conquer is at the compilation unit. Each ctf_cu_t has been built to be able
 148  148   * to be processed independently of the others. It has its own libdwarf handle,
 149  149   * as a given libdwarf handle may only be used by a single thread at a time.
 150  150   * This allows the various ctf_cu_t's to be processed in parallel by different
 151  151   * threads.
 152  152   *
 153  153   * All of the ctf_cu_t's are loaded into a workq which allows for a number of
 154  154   * threads to be specified and used as a thread pool to process all of the
 155  155   * queued work. We set the number of threads to use in the workq equal to the
 156  156   * number of threads that the user has specified.
 157  157   *
 158  158   * After all of the compilation units have been drained, we use the same number
 159  159   * of threads when performing a merge of multiple compilation units, if they
 160  160   * exist.
 161  161   *
 162  162   * While all of these different parts do support and allow for multiple threads,
 163  163   * it's important that when only a single thread is specified, that it be the
 164  164   * calling thread. This allows the conversion routines to be used in a context
 165  165   * that doesn't allow additional threads, such as rtld.
 166  166   *
 167  167   * Common DWARF Mechanics and Notes
 168  168   * --------------------------------
 169  169   *
 170  170   * At this time, we really only support DWARFv2, though support for DWARFv4 is
 171  171   * mostly there. There is no intent to support DWARFv3.
 172  172   *
 173  173   * Generally types for something are stored in the DW_AT_type attribute. For
 174  174   * example, a function's return type will be stored in the local DW_AT_type
 175  175   * attribute while the arguments will be in child DIEs. There are also various
 176  176   * times when we don't have any DW_AT_type. In that case, the lack of a type
 177  177   * implies, at least for C, that its C type is void. Because DWARF doesn't emit
 178  178   * one, we have a synthetic void type that we create and manipulate instead and
 179  179   * pass it off to consumers on an as-needed basis. If nothing has a void type,
 180  180   * it will not be emitted.
 181  181   *
 182  182   * Architecture Specific Parts
 183  183   * ---------------------------
 184  184   *
 185  185   * The CTF tooling encodes various information about the various architectures
 186  186   * in the system. Importantly, the tool assumes that every architecture has a
 187  187   * data model where long and pointer are the same size. This is currently the
 188  188   * case, as the two data models illumos supports are ILP32 and LP64.
 189  189   *
 190  190   * In addition, we encode the mapping of various floating point sizes to various
 191  191   * types for each architecture. If a new architecture is being added, it should
 192  192   * be added to the list. The general design of the ctf conversion tools is to be
 193  193   * architecture independent. eg. any of the tools here should be able to convert
 194  194   * any architecture's DWARF into ctf; however, this has not been rigorously
 195  195   * tested and more importantly, the ctf routines don't currently write out the
 196  196   * data in an endian-aware form, they only use that of the currently running
 197  197   * library.
 198  198   */
 199  199  
 200  200  #include <libctf_impl.h>
 201  201  #include <sys/avl.h>
 202  202  #include <sys/debug.h>
 203  203  #include <gelf.h>
 204  204  #include <libdwarf.h>
 205  205  #include <dwarf.h>
 206  206  #include <libgen.h>
 207  207  #include <workq.h>
 208  208  #include <errno.h>
 209  209  
 210  210  #define DWARF_VERSION_TWO       2
 211  211  #define DWARF_VARARGS_NAME      "..."
 212  212  
 213  213  /*
 214  214   * Dwarf may refer recursively to other types that we've already processed. To
 215  215   * see if we've already converted them, we look them up in an AVL tree that's
 216  216   * sorted by the DWARF id.
 217  217   */
 218  218  typedef struct ctf_dwmap {
 219  219          avl_node_t      cdm_avl;
 220  220          Dwarf_Off       cdm_off;
 221  221          Dwarf_Die       cdm_die;
 222  222          ctf_id_t        cdm_id;
 223  223          boolean_t       cdm_fix;
 224  224  } ctf_dwmap_t;
 225  225  
 226  226  typedef struct ctf_dwvar {
 227  227          ctf_list_t      cdv_list;
 228  228          char            *cdv_name;
 229  229          ctf_id_t        cdv_type;
 230  230          boolean_t       cdv_global;
 231  231  } ctf_dwvar_t;
 232  232  
 233  233  typedef struct ctf_dwfunc {
 234  234          ctf_list_t      cdf_list;
 235  235          char            *cdf_name;
 236  236          ctf_funcinfo_t  cdf_fip;
 237  237          ctf_id_t        *cdf_argv;
 238  238          boolean_t       cdf_global;
 239  239  } ctf_dwfunc_t;
 240  240  
 241  241  typedef struct ctf_dwbitf {
 242  242          ctf_list_t      cdb_list;
 243  243          ctf_id_t        cdb_base;
 244  244          uint_t          cdb_nbits;
 245  245          ctf_id_t        cdb_id;
 246  246  } ctf_dwbitf_t;
 247  247  
 248  248  /*
 249  249   * The ctf_cu_t represents a single top-level DWARF die unit. While generally,
 250  250   * the typical object file has only a single die, if we're asked to convert
 251  251   * something that's been linked from multiple sources, multiple dies will exist.
 252  252   */
 253  253  typedef struct ctf_die {
 254  254          Elf             *cu_elf;        /* shared libelf handle */
 255  255          char            *cu_name;       /* basename of the DIE */
 256  256          ctf_merge_t     *cu_cmh;        /* merge handle */
 257  257          ctf_list_t      cu_vars;        /* List of variables */
 258  258          ctf_list_t      cu_funcs;       /* List of functions */
 259  259          ctf_list_t      cu_bitfields;   /* Bit field members */
 260  260          Dwarf_Debug     cu_dwarf;       /* libdwarf handle */
 261  261          Dwarf_Die       cu_cu;          /* libdwarf compilation unit */
 262  262          Dwarf_Off       cu_cuoff;       /* cu's offset */
 263  263          Dwarf_Off       cu_maxoff;      /* maximum offset */
 264  264          ctf_file_t      *cu_ctfp;       /* output CTF file */
 265  265          avl_tree_t      cu_map;         /* map die offsets to CTF types */
 266  266          char            *cu_errbuf;     /* error message buffer */
 267  267          size_t          cu_errlen;      /* error message buffer length */
 268  268          size_t          cu_ptrsz;       /* object's pointer size */
 269  269          boolean_t       cu_bigend;      /* is it big endian */
 270  270          boolean_t       cu_doweaks;     /* should we convert weak symbols? */
 271  271          uint_t          cu_mach;        /* machine type */
 272  272          ctf_id_t        cu_voidtid;     /* void pointer */
 273  273          ctf_id_t        cu_longtid;     /* id for a 'long' */
 274  274  } ctf_cu_t;
 275  275  
 276  276  static int ctf_dwarf_offset(ctf_cu_t *, Dwarf_Die, Dwarf_Off *);
 277  277  static int ctf_dwarf_convert_die(ctf_cu_t *, Dwarf_Die);
 278  278  static int ctf_dwarf_convert_type(ctf_cu_t *, Dwarf_Die, ctf_id_t *, int);
 279  279  
 280  280  static int ctf_dwarf_function_count(ctf_cu_t *, Dwarf_Die, ctf_funcinfo_t *,
 281  281      boolean_t);
 282  282  static int ctf_dwarf_convert_fargs(ctf_cu_t *, Dwarf_Die, ctf_funcinfo_t *,
 283  283      ctf_id_t *);
 284  284  
 285  285  /*
 286  286   * This is a generic way to set a CTF Conversion backend error depending on what
 287  287   * we were doing. Unless it was one of a specific set of errors that don't
 288  288   * indicate a programming / translation bug, eg. ENOMEM, then we transform it
 289  289   * into a CTF backend error and fill in the error buffer.
 290  290   */
 291  291  static int
 292  292  ctf_dwarf_error(ctf_cu_t *cup, ctf_file_t *cfp, int err, const char *fmt, ...)
 293  293  {
 294  294          va_list ap;
 295  295          int ret;
 296  296          size_t off = 0;
 297  297          ssize_t rem = cup->cu_errlen;
 298  298          if (cfp != NULL)
 299  299                  err = ctf_errno(cfp);
 300  300  
 301  301          if (err == ENOMEM)
 302  302                  return (err);
 303  303  
 304  304          ret = snprintf(cup->cu_errbuf, rem, "die %s: ", cup->cu_name);
 305  305          if (ret < 0)
 306  306                  goto err;
 307  307          off += ret;
 308  308          rem = MAX(rem - ret, 0);
 309  309  
 310  310          va_start(ap, fmt);
 311  311          ret = vsnprintf(cup->cu_errbuf + off, rem, fmt, ap);
 312  312          va_end(ap);
 313  313          if (ret < 0)
 314  314                  goto err;
 315  315  
 316  316          off += ret;
 317  317          rem = MAX(rem - ret, 0);
 318  318          if (fmt[strlen(fmt) - 1] != '\n') {
 319  319                  (void) snprintf(cup->cu_errbuf + off, rem,
 320  320                      ": %s\n", ctf_errmsg(err));
 321  321          }
 322  322          va_end(ap);
 323  323          return (ECTF_CONVBKERR);
 324  324  
 325  325  err:
 326  326          cup->cu_errbuf[0] = '\0';
 327  327          return (ECTF_CONVBKERR);
 328  328  }
 329  329  
 330  330  /*
 331  331   * DWARF often opts to put no explicit type to describe a void type. eg. if we
 332  332   * have a reference type whose DW_AT_type member doesn't exist, then we should
 333  333   * instead assume it points to void. Because this isn't represented, we
 334  334   * instead cause it to come into existence.
 335  335   */
 336  336  static ctf_id_t
 337  337  ctf_dwarf_void(ctf_cu_t *cup)
 338  338  {
 339  339          if (cup->cu_voidtid == CTF_ERR) {
 340  340                  ctf_encoding_t enc = { CTF_INT_SIGNED, 0, 0 };
 341  341                  cup->cu_voidtid = ctf_add_integer(cup->cu_ctfp, CTF_ADD_ROOT,
 342  342                      "void", &enc);
 343  343                  if (cup->cu_voidtid == CTF_ERR) {
 344  344                          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 345  345                              "failed to create void type: %s\n",
 346  346                              ctf_errmsg(ctf_errno(cup->cu_ctfp)));
 347  347                  }
 348  348          }
 349  349  
 350  350          return (cup->cu_voidtid);
 351  351  }
 352  352  
 353  353  /*
 354  354   * There are many different forms that an array index may take. However, we just
 355  355   * always force it to be of a type long no matter what. Therefore we use this to
 356  356   * have a single instance of long across everything.
 357  357   */
 358  358  static ctf_id_t
 359  359  ctf_dwarf_long(ctf_cu_t *cup)
 360  360  {
 361  361          if (cup->cu_longtid == CTF_ERR) {
 362  362                  ctf_encoding_t enc;
 363  363  
 364  364                  enc.cte_format = CTF_INT_SIGNED;
 365  365                  enc.cte_offset = 0;
 366  366                  /* All illumos systems are LP */
 367  367                  enc.cte_bits = cup->cu_ptrsz * 8;
 368  368                  cup->cu_longtid = ctf_add_integer(cup->cu_ctfp, CTF_ADD_NONROOT,
 369  369                      "long", &enc);
 370  370                  if (cup->cu_longtid == CTF_ERR) {
 371  371                          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 372  372                              "failed to create long type: %s\n",
 373  373                              ctf_errmsg(ctf_errno(cup->cu_ctfp)));
 374  374                  }
 375  375  
 376  376          }
 377  377  
 378  378          return (cup->cu_longtid);
 379  379  }
 380  380  
 381  381  static int
 382  382  ctf_dwmap_comp(const void *a, const void *b)
 383  383  {
 384  384          const ctf_dwmap_t *ca = a;
 385  385          const ctf_dwmap_t *cb = b;
 386  386  
 387  387          if (ca->cdm_off > cb->cdm_off)
 388  388                  return (1);
 389  389          if (ca->cdm_off < cb->cdm_off)
 390  390                  return (-1);
 391  391          return (0);
 392  392  }
 393  393  
 394  394  static int
 395  395  ctf_dwmap_add(ctf_cu_t *cup, ctf_id_t id, Dwarf_Die die, boolean_t fix)
 396  396  {
 397  397          int ret;
 398  398          avl_index_t index;
 399  399          ctf_dwmap_t *dwmap;
 400  400          Dwarf_Off off;
 401  401  
 402  402          VERIFY(id > 0 && id < CTF_MAX_TYPE);
 403  403  
 404  404          if ((ret = ctf_dwarf_offset(cup, die, &off)) != 0)
 405  405                  return (ret);
 406  406  
 407  407          if ((dwmap = ctf_alloc(sizeof (ctf_dwmap_t))) == NULL)
 408  408                  return (ENOMEM);
 409  409  
 410  410          dwmap->cdm_die = die;
 411  411          dwmap->cdm_off = off;
 412  412          dwmap->cdm_id = id;
 413  413          dwmap->cdm_fix = fix;
 414  414  
 415  415          ctf_dprintf("dwmap: %p %" DW_PR_DUx "->%d\n", dwmap, off, id);
 416  416          VERIFY(avl_find(&cup->cu_map, dwmap, &index) == NULL);
 417  417          avl_insert(&cup->cu_map, dwmap, index);
 418  418          return (0);
 419  419  }
 420  420  
 421  421  static int
 422  422  ctf_dwarf_attribute(ctf_cu_t *cup, Dwarf_Die die, Dwarf_Half name,
 423  423      Dwarf_Attribute *attrp)
 424  424  {
 425  425          int ret;
 426  426          Dwarf_Error derr;
 427  427  
 428  428          if ((ret = dwarf_attr(die, name, attrp, &derr)) == DW_DLV_OK)
 429  429                  return (0);
 430  430          if (ret == DW_DLV_NO_ENTRY) {
 431  431                  *attrp = NULL;
 432  432                  return (ENOENT);
 433  433          }
 434  434          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 435  435              "failed to get attribute for type: %s\n",
 436  436              dwarf_errmsg(derr));
 437  437          return (ECTF_CONVBKERR);
 438  438  }
 439  439  
 440  440  static int
 441  441  ctf_dwarf_ref(ctf_cu_t *cup, Dwarf_Die die, Dwarf_Half name, Dwarf_Off *refp)
 442  442  {
 443  443          int ret;
 444  444          Dwarf_Attribute attr;
 445  445          Dwarf_Error derr;
 446  446  
 447  447          if ((ret = ctf_dwarf_attribute(cup, die, name, &attr)) != 0)
 448  448                  return (ret);
 449  449  
 450  450          if (dwarf_formref(attr, refp, &derr) == DW_DLV_OK) {
 451  451                  dwarf_dealloc(cup->cu_dwarf, attr, DW_DLA_ATTR);
 452  452                  return (0);
 453  453          }
 454  454  
 455  455          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 456  456              "failed to get unsigned attribute for type: %s\n",
 457  457              dwarf_errmsg(derr));
 458  458          return (ECTF_CONVBKERR);
 459  459  }
 460  460  
 461  461  static int
 462  462  ctf_dwarf_refdie(ctf_cu_t *cup, Dwarf_Die die, Dwarf_Half name,
 463  463      Dwarf_Die *diep)
 464  464  {
 465  465          int ret;
 466  466          Dwarf_Off off;
 467  467          Dwarf_Error derr;
 468  468  
 469  469          if ((ret = ctf_dwarf_ref(cup, die, name, &off)) != 0)
 470  470                  return (ret);
 471  471  
 472  472          off += cup->cu_cuoff;
 473  473          if ((ret = dwarf_offdie(cup->cu_dwarf, off, diep, &derr)) !=
 474  474              DW_DLV_OK) {
 475  475                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 476  476                      "failed to get die from offset %" DW_PR_DUu ": %s\n",
 477  477                      off, dwarf_errmsg(derr));
 478  478                  return (ECTF_CONVBKERR);
 479  479          }
 480  480  
 481  481          return (0);
 482  482  }
 483  483  
 484  484  static int
 485  485  ctf_dwarf_signed(ctf_cu_t *cup, Dwarf_Die die, Dwarf_Half name,
 486  486      Dwarf_Signed *valp)
 487  487  {
 488  488          int ret;
 489  489          Dwarf_Attribute attr;
 490  490          Dwarf_Error derr;
 491  491  
 492  492          if ((ret = ctf_dwarf_attribute(cup, die, name, &attr)) != 0)
 493  493                  return (ret);
 494  494  
 495  495          if (dwarf_formsdata(attr, valp, &derr) == DW_DLV_OK) {
 496  496                  dwarf_dealloc(cup->cu_dwarf, attr, DW_DLA_ATTR);
 497  497                  return (0);
 498  498          }
 499  499  
 500  500          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 501  501              "failed to get unsigned attribute for type: %s\n",
 502  502              dwarf_errmsg(derr));
 503  503          return (ECTF_CONVBKERR);
 504  504  }
 505  505  
 506  506  static int
 507  507  ctf_dwarf_unsigned(ctf_cu_t *cup, Dwarf_Die die, Dwarf_Half name,
 508  508      Dwarf_Unsigned *valp)
 509  509  {
 510  510          int ret;
 511  511          Dwarf_Attribute attr;
 512  512          Dwarf_Error derr;
 513  513  
 514  514          if ((ret = ctf_dwarf_attribute(cup, die, name, &attr)) != 0)
 515  515                  return (ret);
 516  516  
 517  517          if (dwarf_formudata(attr, valp, &derr) == DW_DLV_OK) {
 518  518                  dwarf_dealloc(cup->cu_dwarf, attr, DW_DLA_ATTR);
 519  519                  return (0);
 520  520          }
 521  521  
 522  522          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 523  523              "failed to get unsigned attribute for type: %s\n",
 524  524              dwarf_errmsg(derr));
 525  525          return (ECTF_CONVBKERR);
 526  526  }
 527  527  
 528  528  static int
 529  529  ctf_dwarf_boolean(ctf_cu_t *cup, Dwarf_Die die, Dwarf_Half name,
 530  530      Dwarf_Bool *val)
 531  531  {
 532  532          int ret;
 533  533          Dwarf_Attribute attr;
 534  534          Dwarf_Error derr;
 535  535  
 536  536          if ((ret = ctf_dwarf_attribute(cup, die, name, &attr)) != 0)
 537  537                  return (ret);
 538  538  
 539  539          if (dwarf_formflag(attr, val, &derr) == DW_DLV_OK) {
 540  540                  dwarf_dealloc(cup->cu_dwarf, attr, DW_DLA_ATTR);
 541  541                  return (0);
 542  542          }
 543  543  
 544  544          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 545  545              "failed to get boolean attribute for type: %s\n",
 546  546              dwarf_errmsg(derr));
 547  547  
 548  548          return (ECTF_CONVBKERR);
 549  549  }
 550  550  
 551  551  static int
 552  552  ctf_dwarf_string(ctf_cu_t *cup, Dwarf_Die die, Dwarf_Half name, char **strp)
 553  553  {
 554  554          int ret;
 555  555          char *s;
 556  556          Dwarf_Attribute attr;
 557  557          Dwarf_Error derr;
 558  558  
 559  559          *strp = NULL;
 560  560          if ((ret = ctf_dwarf_attribute(cup, die, name, &attr)) != 0)
 561  561                  return (ret);
 562  562  
 563  563          if (dwarf_formstring(attr, &s, &derr) == DW_DLV_OK) {
 564  564                  if ((*strp = ctf_strdup(s)) == NULL)
 565  565                          ret = ENOMEM;
 566  566                  else
 567  567                          ret = 0;
 568  568                  dwarf_dealloc(cup->cu_dwarf, attr, DW_DLA_ATTR);
 569  569                  return (ret);
 570  570          }
 571  571  
 572  572          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 573  573              "failed to get string attribute for type: %s\n",
 574  574              dwarf_errmsg(derr));
 575  575          return (ECTF_CONVBKERR);
 576  576  }
 577  577  
 578  578  static int
 579  579  ctf_dwarf_member_location(ctf_cu_t *cup, Dwarf_Die die, Dwarf_Unsigned *valp)
 580  580  {
 581  581          int ret;
 582  582          Dwarf_Error derr;
 583  583          Dwarf_Attribute attr;
 584  584          Dwarf_Locdesc *loc;
 585  585          Dwarf_Signed locnum;
 586  586  
 587  587          if ((ret = ctf_dwarf_attribute(cup, die, DW_AT_data_member_location,
 588  588              &attr)) != 0)
 589  589                  return (ret);
 590  590  
 591  591          if (dwarf_loclist(attr, &loc, &locnum, &derr) != DW_DLV_OK) {
 592  592                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 593  593                      "failed to obtain location list for member offset: %s",
 594  594                      dwarf_errmsg(derr));
 595  595                  dwarf_dealloc(cup->cu_dwarf, attr, DW_DLA_ATTR);
 596  596                  return (ECTF_CONVBKERR);
 597  597          }
 598  598          dwarf_dealloc(cup->cu_dwarf, attr, DW_DLA_ATTR);
 599  599  
 600  600          if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) {
 601  601                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 602  602                      "failed to parse location structure for member");
 603  603                  dwarf_dealloc(cup->cu_dwarf, loc->ld_s, DW_DLA_LOC_BLOCK);
 604  604                  dwarf_dealloc(cup->cu_dwarf, loc, DW_DLA_LOCDESC);
 605  605                  return (ECTF_CONVBKERR);
 606  606          }
 607  607  
 608  608          *valp = loc->ld_s->lr_number;
 609  609  
 610  610          dwarf_dealloc(cup->cu_dwarf, loc->ld_s, DW_DLA_LOC_BLOCK);
 611  611          dwarf_dealloc(cup->cu_dwarf, loc, DW_DLA_LOCDESC);
 612  612          return (0);
 613  613  }
 614  614  
 615  615  
 616  616  static int
 617  617  ctf_dwarf_offset(ctf_cu_t *cup, Dwarf_Die die, Dwarf_Off *offsetp)
 618  618  {
 619  619          Dwarf_Error derr;
 620  620  
 621  621          if (dwarf_dieoffset(die, offsetp, &derr) == DW_DLV_OK)
 622  622                  return (0);
 623  623  
 624  624          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 625  625              "failed to get die offset: %s\n",
 626  626              dwarf_errmsg(derr));
 627  627          return (ECTF_CONVBKERR);
 628  628  }
 629  629  
 630  630  /* simpler variant for debugging output */
 631  631  static Dwarf_Off
 632  632  ctf_die_offset(Dwarf_Die die)
 633  633  {
 634  634          Dwarf_Off off = -1;
 635  635          Dwarf_Error derr;
 636  636  
 637  637          (void) dwarf_dieoffset(die, &off, &derr);
 638  638          return (off);
 639  639  }
 640  640  
 641  641  static int
 642  642  ctf_dwarf_tag(ctf_cu_t *cup, Dwarf_Die die, Dwarf_Half *tagp)
 643  643  {
 644  644          Dwarf_Error derr;
 645  645  
 646  646          if (dwarf_tag(die, tagp, &derr) == DW_DLV_OK)
 647  647                  return (0);
 648  648  
 649  649          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 650  650              "failed to get tag type: %s\n",
 651  651              dwarf_errmsg(derr));
 652  652          return (ECTF_CONVBKERR);
 653  653  }
 654  654  
 655  655  static int
 656  656  ctf_dwarf_sib(ctf_cu_t *cup, Dwarf_Die base, Dwarf_Die *sibp)
 657  657  {
 658  658          Dwarf_Error derr;
 659  659          int ret;
 660  660  
 661  661          *sibp = NULL;
 662  662          ret = dwarf_siblingof(cup->cu_dwarf, base, sibp, &derr);
 663  663          if (ret == DW_DLV_OK || ret == DW_DLV_NO_ENTRY)
 664  664                  return (0);
 665  665  
 666  666          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 667  667              "failed to sibling from die: %s\n",
 668  668              dwarf_errmsg(derr));
 669  669          return (ECTF_CONVBKERR);
 670  670  }
 671  671  
 672  672  static int
 673  673  ctf_dwarf_child(ctf_cu_t *cup, Dwarf_Die base, Dwarf_Die *childp)
 674  674  {
 675  675          Dwarf_Error derr;
 676  676          int ret;
 677  677  
 678  678          *childp = NULL;
 679  679          ret = dwarf_child(base, childp, &derr);
 680  680          if (ret == DW_DLV_OK || ret == DW_DLV_NO_ENTRY)
 681  681                  return (0);
 682  682  
 683  683          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 684  684              "failed to child from die: %s\n",
 685  685              dwarf_errmsg(derr));
 686  686          return (ECTF_CONVBKERR);
 687  687  }
 688  688  
 689  689  /*
 690  690   * Compilers disagree on what to do to determine if something has global
 691  691   * visiblity. Traditionally gcc has used DW_AT_external to indicate this while
 692  692   * Studio has used DW_AT_visibility. We check DW_AT_visibility first and then
 693  693   * fall back to DW_AT_external. Lack of DW_AT_external implies that it is not.
 694  694   */
 695  695  static int
 696  696  ctf_dwarf_isglobal(ctf_cu_t *cup, Dwarf_Die die, boolean_t *igp)
 697  697  {
 698  698          int ret;
 699  699          Dwarf_Signed vis;
 700  700          Dwarf_Bool ext;
 701  701  
 702  702          if ((ret = ctf_dwarf_signed(cup, die, DW_AT_visibility, &vis)) == 0) {
 703  703                  *igp = vis == DW_VIS_exported;
 704  704                  return (0);
 705  705          } else if (ret != ENOENT) {
 706  706                  return (ret);
 707  707          }
 708  708  
 709  709          if ((ret = ctf_dwarf_boolean(cup, die, DW_AT_external, &ext)) != 0) {
 710  710                  if (ret == ENOENT) {
 711  711                          *igp = B_FALSE;
 712  712                          return (0);
 713  713                  }
 714  714                  return (ret);
 715  715          }
 716  716          *igp = ext != 0 ? B_TRUE : B_FALSE;
 717  717          return (0);
 718  718  }
 719  719  
 720  720  static int
 721  721  ctf_dwarf_die_elfenc(Elf *elf, ctf_cu_t *cup, char *errbuf, size_t errlen)
 722  722  {
 723  723          GElf_Ehdr ehdr;
 724  724  
 725  725          if (gelf_getehdr(elf, &ehdr) == NULL) {
 726  726                  (void) snprintf(errbuf, errlen,
 727  727                      "failed to get ELF header: %s\n",
 728  728                      elf_errmsg(elf_errno()));
 729  729                  return (ECTF_CONVBKERR);
 730  730          }
 731  731  
 732  732          cup->cu_mach = ehdr.e_machine;
 733  733  
 734  734          if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
 735  735                  cup->cu_ptrsz = 4;
 736  736                  VERIFY(ctf_setmodel(cup->cu_ctfp, CTF_MODEL_ILP32) == 0);
 737  737          } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
 738  738                  cup->cu_ptrsz = 8;
 739  739                  VERIFY(ctf_setmodel(cup->cu_ctfp, CTF_MODEL_LP64) == 0);
 740  740          } else {
 741  741                  (void) snprintf(errbuf, errlen,
 742  742                      "unknown ELF class %d", ehdr.e_ident[EI_CLASS]);
 743  743                  return (ECTF_CONVBKERR);
 744  744          }
 745  745  
 746  746          if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB) {
 747  747                  cup->cu_bigend = B_FALSE;
 748  748          } else if (ehdr.e_ident[EI_DATA] == ELFDATA2MSB) {
 749  749                  cup->cu_bigend = B_TRUE;
 750  750          } else {
 751  751                  (void) snprintf(errbuf, errlen,
 752  752                      "unknown ELF data encoding: %hhu", ehdr.e_ident[EI_DATA]);
 753  753                  return (ECTF_CONVBKERR);
 754  754          }
 755  755  
 756  756          return (0);
 757  757  }
 758  758  
 759  759  typedef struct ctf_dwarf_fpent {
 760  760          size_t  cdfe_size;
 761  761          uint_t  cdfe_enc[3];
 762  762  } ctf_dwarf_fpent_t;
 763  763  
 764  764  typedef struct ctf_dwarf_fpmap {
 765  765          uint_t                  cdf_mach;
 766  766          ctf_dwarf_fpent_t       cdf_ents[4];
 767  767  } ctf_dwarf_fpmap_t;
 768  768  
 769  769  static const ctf_dwarf_fpmap_t ctf_dwarf_fpmaps[] = {
 770  770          { EM_SPARC, {
 771  771                  { 4, { CTF_FP_SINGLE, CTF_FP_CPLX, CTF_FP_IMAGRY } },
 772  772                  { 8, { CTF_FP_DOUBLE, CTF_FP_DCPLX, CTF_FP_DIMAGRY } },
 773  773                  { 16, { CTF_FP_LDOUBLE, CTF_FP_LDCPLX, CTF_FP_LDIMAGRY } },
 774  774                  { 0, { 0 } }
 775  775          } },
 776  776          { EM_SPARC32PLUS, {
 777  777                  { 4, { CTF_FP_SINGLE, CTF_FP_CPLX, CTF_FP_IMAGRY } },
 778  778                  { 8, { CTF_FP_DOUBLE, CTF_FP_DCPLX, CTF_FP_DIMAGRY } },
 779  779                  { 16, { CTF_FP_LDOUBLE, CTF_FP_LDCPLX, CTF_FP_LDIMAGRY } },
 780  780                  { 0, { 0 } }
 781  781          } },
 782  782          { EM_SPARCV9, {
 783  783                  { 4, { CTF_FP_SINGLE, CTF_FP_CPLX, CTF_FP_IMAGRY } },
 784  784                  { 8, { CTF_FP_DOUBLE, CTF_FP_DCPLX, CTF_FP_DIMAGRY } },
 785  785                  { 16, { CTF_FP_LDOUBLE, CTF_FP_LDCPLX, CTF_FP_LDIMAGRY } },
 786  786                  { 0, { 0 } }
 787  787          } },
 788  788          { EM_386, {
 789  789                  { 4, { CTF_FP_SINGLE, CTF_FP_CPLX, CTF_FP_IMAGRY } },
 790  790                  { 8, { CTF_FP_DOUBLE, CTF_FP_DCPLX, CTF_FP_DIMAGRY } },
 791  791                  { 12, { CTF_FP_LDOUBLE, CTF_FP_LDCPLX, CTF_FP_LDIMAGRY } },
 792  792                  { 0, { 0 } }
 793  793          } },
 794  794          { EM_X86_64, {
 795  795                  { 4, { CTF_FP_SINGLE, CTF_FP_CPLX, CTF_FP_IMAGRY } },
 796  796                  { 8, { CTF_FP_DOUBLE, CTF_FP_DCPLX, CTF_FP_DIMAGRY } },
 797  797                  { 16, { CTF_FP_LDOUBLE, CTF_FP_LDCPLX, CTF_FP_LDIMAGRY } },
 798  798                  { 0, { 0 } }
 799  799          } },
 800  800          { EM_NONE }
 801  801  };
 802  802  
 803  803  static int
 804  804  ctf_dwarf_float_base(ctf_cu_t *cup, Dwarf_Signed type, ctf_encoding_t *enc)
 805  805  {
 806  806          const ctf_dwarf_fpmap_t *map = &ctf_dwarf_fpmaps[0];
 807  807          const ctf_dwarf_fpent_t *ent;
 808  808          uint_t col = 0, mult = 1;
 809  809  
 810  810          for (map = &ctf_dwarf_fpmaps[0]; map->cdf_mach != EM_NONE; map++) {
 811  811                  if (map->cdf_mach == cup->cu_mach)
 812  812                          break;
 813  813          }
 814  814  
 815  815          if (map->cdf_mach == EM_NONE) {
 816  816                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 817  817                      "Unsupported machine type: %d\n", cup->cu_mach);
 818  818                  return (ENOTSUP);
 819  819          }
 820  820  
 821  821          if (type == DW_ATE_complex_float) {
 822  822                  mult = 2;
 823  823                  col = 1;
 824  824          } else if (type == DW_ATE_imaginary_float ||
 825  825              type == DW_ATE_SUN_imaginary_float) {
 826  826                  col = 2;
 827  827          }
 828  828  
 829  829          ent = &map->cdf_ents[0];
 830  830          for (ent = &map->cdf_ents[0]; ent->cdfe_size != 0; ent++) {
 831  831                  if (ent->cdfe_size * mult * 8 == enc->cte_bits) {
 832  832                          enc->cte_format = ent->cdfe_enc[col];
 833  833                          return (0);
 834  834                  }
 835  835          }
 836  836  
 837  837          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 838  838              "failed to find valid fp mapping for encoding %d, size %d bits\n",
 839  839              type, enc->cte_bits);
 840  840          return (EINVAL);
 841  841  }
 842  842  
 843  843  static int
 844  844  ctf_dwarf_dwarf_base(ctf_cu_t *cup, Dwarf_Die die, int *kindp,
 845  845      ctf_encoding_t *enc)
 846  846  {
 847  847          int ret;
 848  848          Dwarf_Signed type;
 849  849  
 850  850          if ((ret = ctf_dwarf_signed(cup, die, DW_AT_encoding, &type)) != 0)
 851  851                  return (ret);
 852  852  
 853  853          switch (type) {
 854  854          case DW_ATE_unsigned:
 855  855          case DW_ATE_address:
 856  856                  *kindp = CTF_K_INTEGER;
 857  857                  enc->cte_format = 0;
 858  858                  break;
 859  859          case DW_ATE_unsigned_char:
 860  860                  *kindp = CTF_K_INTEGER;
 861  861                  enc->cte_format = CTF_INT_CHAR;
 862  862                  break;
 863  863          case DW_ATE_signed:
 864  864                  *kindp = CTF_K_INTEGER;
 865  865                  enc->cte_format = CTF_INT_SIGNED;
 866  866                  break;
 867  867          case DW_ATE_signed_char:
 868  868                  *kindp = CTF_K_INTEGER;
 869  869                  enc->cte_format = CTF_INT_SIGNED | CTF_INT_CHAR;
 870  870                  break;
 871  871          case DW_ATE_boolean:
 872  872                  *kindp = CTF_K_INTEGER;
 873  873                  enc->cte_format = CTF_INT_SIGNED | CTF_INT_BOOL;
 874  874                  break;
 875  875          case DW_ATE_float:
  
    | 
      ↓ open down ↓ | 
    875 lines elided | 
    
      ↑ open up ↑ | 
  
 876  876          case DW_ATE_complex_float:
 877  877          case DW_ATE_imaginary_float:
 878  878          case DW_ATE_SUN_imaginary_float:
 879  879          case DW_ATE_SUN_interval_float:
 880  880                  *kindp = CTF_K_FLOAT;
 881  881                  if ((ret = ctf_dwarf_float_base(cup, type, enc)) != 0)
 882  882                          return (ret);
 883  883                  break;
 884  884          default:
 885  885                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 886      -                    "encountered unkown DWARF encoding: %d", type);
      886 +                    "encountered unknown DWARF encoding: %d", type);
 887  887                  return (ECTF_CONVBKERR);
 888  888          }
 889  889  
 890  890          return (0);
 891  891  }
 892  892  
 893  893  /*
 894  894   * Different compilers (at least GCC and Studio) use different names for types.
 895  895   * This parses the types and attempts to unify them. If this fails, we just fall
 896  896   * back to using the DWARF itself.
 897  897   */
 898  898  static int
 899  899  ctf_dwarf_parse_base(const char *name, int *kindp, ctf_encoding_t *enc,
 900  900      char **newnamep)
 901  901  {
 902  902          char buf[256];
 903  903          char *base, *c, *last;
 904  904          int nlong = 0, nshort = 0, nchar = 0, nint = 0;
 905  905          int sign = 1;
 906  906  
 907  907          if (strlen(name) + 1 > sizeof (buf))
 908  908                  return (EINVAL);
 909  909  
 910  910          (void) strlcpy(buf, name, sizeof (buf));
 911  911          for (c = strtok_r(buf, " ", &last); c != NULL;
 912  912              c = strtok_r(NULL, " ", &last)) {
 913  913                  if (strcmp(c, "signed") == 0) {
 914  914                          sign = 1;
 915  915                  } else if (strcmp(c, "unsigned") == 0) {
 916  916                          sign = 0;
 917  917                  } else if (strcmp(c, "long") == 0) {
 918  918                          nlong++;
 919  919                  } else if (strcmp(c, "char") == 0) {
 920  920                          nchar++;
 921  921                  } else if (strcmp(c, "short") == 0) {
 922  922                          nshort++;
 923  923                  } else if (strcmp(c, "int") == 0) {
 924  924                          nint++;
 925  925                  } else {
 926  926                          /*
 927  927                           * If we don't recognize any of the tokens, we'll tell
 928  928                           * the caller to fall back to the dwarf-provided
 929  929                           * encoding information.
 930  930                           */
 931  931                          return (EINVAL);
 932  932                  }
 933  933          }
 934  934  
 935  935          if (nchar > 1 || nshort > 1 || nint > 1 || nlong > 2)
 936  936                  return (EINVAL);
 937  937  
 938  938          if (nchar > 0) {
 939  939                  if (nlong > 0 || nshort > 0 || nint > 0)
 940  940                          return (EINVAL);
 941  941                  base = "char";
 942  942          } else if (nshort > 0) {
 943  943                  if (nlong > 0)
 944  944                          return (EINVAL);
 945  945                  base = "short";
 946  946          } else if (nlong > 0) {
 947  947                  base = "long";
 948  948          } else {
 949  949                  base = "int";
 950  950          }
 951  951  
 952  952          if (nchar > 0)
 953  953                  enc->cte_format = CTF_INT_CHAR;
 954  954          else
 955  955                  enc->cte_format = 0;
 956  956  
 957  957          if (sign > 0)
 958  958                  enc->cte_format |= CTF_INT_SIGNED;
 959  959  
 960  960          (void) snprintf(buf, sizeof (buf), "%s%s%s",
 961  961              (sign ? "" : "unsigned "),
 962  962              (nlong > 1 ? "long " : ""),
 963  963              base);
 964  964  
 965  965          *newnamep = ctf_strdup(buf);
 966  966          if (*newnamep == NULL)
 967  967                  return (ENOMEM);
 968  968          *kindp = CTF_K_INTEGER;
 969  969          return (0);
 970  970  }
 971  971  
 972  972  static int
 973  973  ctf_dwarf_create_base(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot,
 974  974      Dwarf_Off off)
 975  975  {
 976  976          int ret;
 977  977          char *name, *nname;
 978  978          Dwarf_Unsigned sz;
 979  979          int kind;
 980  980          ctf_encoding_t enc;
 981  981          ctf_id_t id;
 982  982  
 983  983          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0)
 984  984                  return (ret);
 985  985          if ((ret = ctf_dwarf_unsigned(cup, die, DW_AT_byte_size, &sz)) != 0) {
 986  986                  goto out;
 987  987          }
 988  988          ctf_dprintf("Creating base type %s from off %llu, size: %d\n", name,
 989  989              off, sz);
 990  990  
 991  991          bzero(&enc, sizeof (ctf_encoding_t));
 992  992          enc.cte_bits = sz * 8;
 993  993          if ((ret = ctf_dwarf_parse_base(name, &kind, &enc, &nname)) == 0) {
 994  994                  ctf_free(name, strlen(name) + 1);
 995  995                  name = nname;
 996  996          } else {
 997  997                  if (ret != EINVAL)
 998  998                          return (ret);
 999  999                  ctf_dprintf("falling back to dwarf for base type %s\n", name);
1000 1000                  if ((ret = ctf_dwarf_dwarf_base(cup, die, &kind, &enc)) != 0)
1001 1001                          return (ret);
1002 1002          }
1003 1003  
1004 1004          id = ctf_add_encoded(cup->cu_ctfp, isroot, name, &enc, kind);
1005 1005          if (id == CTF_ERR) {
1006 1006                  ret = ctf_errno(cup->cu_ctfp);
1007 1007          } else {
1008 1008                  *idp = id;
1009 1009                  ret = ctf_dwmap_add(cup, id, die, B_FALSE);
1010 1010          }
1011 1011  out:
1012 1012          ctf_free(name, strlen(name) + 1);
1013 1013          return (ret);
1014 1014  }
1015 1015  
1016 1016  /*
1017 1017   * Getting a member's offset is a surprisingly intricate dance. It works as
1018 1018   * follows:
1019 1019   *
1020 1020   * 1) If we're in DWARFv4, then we either have a DW_AT_data_bit_offset or we
1021 1021   * have a DW_AT_data_member_location. We won't have both. Thus we check first
1022 1022   * for DW_AT_data_bit_offset, and if it exists, we're set.
1023 1023   *
1024 1024   * Next, if we have a bitfield and we don't have a DW_AT_data_bit_offset, then
1025 1025   * we have to grab the data location and use the following dance:
1026 1026   *
1027 1027   * 2) Gather the set of DW_AT_byte_size, DW_AT_bit_offset, and DW_AT_bit_size.
1028 1028   * Of course, the DW_AT_byte_size may be omitted, even though it isn't always.
1029 1029   * When it's been omitted, we then have to say that the size is that of the
1030 1030   * underlying type, which forces that to be after a ctf_update(). Here, we have
1031 1031   * to do different things based on whether or not we're using big endian or
1032 1032   * little endian to obtain the proper offset.
1033 1033   */
1034 1034  static int
1035 1035  ctf_dwarf_member_offset(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t mid,
1036 1036      ulong_t *offp)
1037 1037  {
1038 1038          int ret;
1039 1039          Dwarf_Unsigned loc, bitsz, bytesz;
1040 1040          Dwarf_Signed bitoff;
1041 1041          size_t off;
1042 1042          ssize_t tsz;
1043 1043  
1044 1044          if ((ret = ctf_dwarf_unsigned(cup, die, DW_AT_data_bit_offset,
1045 1045              &loc)) == 0) {
1046 1046                  *offp = loc;
1047 1047                  return (0);
1048 1048          } else if (ret != ENOENT) {
1049 1049                  return (ret);
1050 1050          }
1051 1051  
1052 1052          if ((ret = ctf_dwarf_member_location(cup, die, &loc)) != 0)
1053 1053                  return (ret);
1054 1054          off = loc * 8;
1055 1055  
1056 1056          if ((ret = ctf_dwarf_signed(cup, die, DW_AT_bit_offset,
1057 1057              &bitoff)) != 0) {
1058 1058                  if (ret != ENOENT)
1059 1059                          return (ret);
1060 1060                  *offp = off;
1061 1061                  return (0);
1062 1062          }
1063 1063  
1064 1064          /* At this point we have to have DW_AT_bit_size */
1065 1065          if ((ret = ctf_dwarf_unsigned(cup, die, DW_AT_bit_size, &bitsz)) != 0)
1066 1066                  return (ret);
1067 1067  
1068 1068          if ((ret = ctf_dwarf_unsigned(cup, die, DW_AT_byte_size,
1069 1069              &bytesz)) != 0) {
1070 1070                  if (ret != ENOENT)
1071 1071                          return (ret);
1072 1072                  if ((tsz = ctf_type_size(cup->cu_ctfp, mid)) == CTF_ERR) {
1073 1073                          int e = ctf_errno(cup->cu_ctfp);
1074 1074                          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1075 1075                              "failed to get type size: %s", ctf_errmsg(e));
1076 1076                          return (ECTF_CONVBKERR);
1077 1077                  }
1078 1078          } else {
1079 1079                  tsz = bytesz;
1080 1080          }
1081 1081          tsz *= 8;
1082 1082          if (cup->cu_bigend == B_TRUE) {
1083 1083                  *offp = off + bitoff;
1084 1084          } else {
1085 1085                  *offp = off + tsz - bitoff - bitsz;
1086 1086          }
1087 1087  
1088 1088          return (0);
1089 1089  }
1090 1090  
1091 1091  /*
1092 1092   * We need to determine if the member in question is a bitfield. If it is, then
1093 1093   * we need to go through and create a new type that's based on the actual base
1094 1094   * type, but has a different size. We also rename the type as a result to help
1095 1095   * deal with future collisions.
1096 1096   *
1097 1097   * Here we need to look and see if we have a DW_AT_bit_size value. If we have a
1098 1098   * bit size member and it does not equal the byte size member, then we need to
1099 1099   * create a bitfield type based on this.
1100 1100   *
1101 1101   * Note: When we support DWARFv4, there may be a chance that we need to also
1102 1102   * search for the DW_AT_byte_size if we don't have a DW_AT_bit_size member.
1103 1103   */
1104 1104  static int
1105 1105  ctf_dwarf_member_bitfield(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp)
1106 1106  {
1107 1107          int ret;
1108 1108          Dwarf_Unsigned bitsz;
1109 1109          ctf_encoding_t e;
1110 1110          ctf_dwbitf_t *cdb;
1111 1111          ctf_dtdef_t *dtd;
1112 1112          ctf_id_t base = *idp;
1113 1113          int kind;
1114 1114  
1115 1115          if ((ret = ctf_dwarf_unsigned(cup, die, DW_AT_bit_size, &bitsz)) != 0) {
1116 1116                  if (ret == ENOENT)
1117 1117                          return (0);
1118 1118                  return (ret);
1119 1119          }
1120 1120  
1121 1121          ctf_dprintf("Trying to deal with bitfields on %d:%d\n", base, bitsz);
1122 1122          /*
1123 1123           * Given that we now have a bitsize, time to go do something about it.
1124 1124           * We're going to create a new type based on the current one, but first
1125 1125           * we need to find the base type. This means we need to traverse any
1126 1126           * typedef's, consts, and volatiles until we get to what should be
1127 1127           * something of type integer or enumeration.
1128 1128           */
1129 1129          VERIFY(bitsz < UINT32_MAX);
1130 1130          dtd = ctf_dtd_lookup(cup->cu_ctfp, base);
1131 1131          VERIFY(dtd != NULL);
1132 1132          kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
1133 1133          while (kind == CTF_K_TYPEDEF || kind == CTF_K_CONST ||
1134 1134              kind == CTF_K_VOLATILE) {
1135 1135                  dtd = ctf_dtd_lookup(cup->cu_ctfp, dtd->dtd_data.ctt_type);
1136 1136                  VERIFY(dtd != NULL);
1137 1137                  kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
1138 1138          }
1139 1139          ctf_dprintf("got kind %d\n", kind);
1140 1140          VERIFY(kind == CTF_K_INTEGER || kind == CTF_K_ENUM);
1141 1141  
1142 1142          /*
1143 1143           * As surprising as it may be, it is strictly possible to create a
1144 1144           * bitfield that is based on an enum. Of course, the C standard leaves
1145 1145           * enums sizing as an ABI concern more or less. To that effect, today on
1146 1146           * all illumos platforms the size of an enum is generally that of an
1147 1147           * int as our supported data models and ABIs all agree on that. So what
1148 1148           * we'll do is fake up a CTF encoding here to use. In this case, we'll
1149 1149           * treat it as an unsigned value of whatever size the underlying enum
1150 1150           * currently has (which is in the ctt_size member of its dynamic type
1151 1151           * data).
1152 1152           */
1153 1153          if (kind == CTF_K_INTEGER) {
1154 1154                  e = dtd->dtd_u.dtu_enc;
1155 1155          } else {
1156 1156                  bzero(&e, sizeof (ctf_encoding_t));
1157 1157                  e.cte_bits = dtd->dtd_data.ctt_size * NBBY;
1158 1158          }
1159 1159  
1160 1160          for (cdb = ctf_list_next(&cup->cu_bitfields); cdb != NULL;
1161 1161              cdb = ctf_list_next(cdb)) {
1162 1162                  if (cdb->cdb_base == base && cdb->cdb_nbits == bitsz)
1163 1163                          break;
1164 1164          }
1165 1165  
1166 1166          /*
1167 1167           * Create a new type if none exists. We name all types in a way that is
1168 1168           * guaranteed not to conflict with the corresponding C type. We do this
1169 1169           * by using the ':' operator.
1170 1170           */
1171 1171          if (cdb == NULL) {
1172 1172                  size_t namesz;
1173 1173                  char *name;
1174 1174  
1175 1175                  e.cte_bits = bitsz;
1176 1176                  namesz = snprintf(NULL, 0, "%s:%d", dtd->dtd_name,
1177 1177                      (uint32_t)bitsz);
1178 1178                  name = ctf_alloc(namesz + 1);
1179 1179                  if (name == NULL)
1180 1180                          return (ENOMEM);
1181 1181                  cdb = ctf_alloc(sizeof (ctf_dwbitf_t));
1182 1182                  if (cdb == NULL) {
1183 1183                          ctf_free(name, namesz + 1);
1184 1184                          return (ENOMEM);
1185 1185                  }
1186 1186                  (void) snprintf(name, namesz + 1, "%s:%d", dtd->dtd_name,
1187 1187                      (uint32_t)bitsz);
1188 1188  
1189 1189                  cdb->cdb_base = base;
1190 1190                  cdb->cdb_nbits = bitsz;
1191 1191                  cdb->cdb_id = ctf_add_integer(cup->cu_ctfp, CTF_ADD_NONROOT,
1192 1192                      name, &e);
1193 1193                  if (cdb->cdb_id == CTF_ERR) {
1194 1194                          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1195 1195                              "failed to get add bitfield type %s: %s", name,
1196 1196                              ctf_errmsg(ctf_errno(cup->cu_ctfp)));
1197 1197                          ctf_free(name, namesz + 1);
1198 1198                          ctf_free(cdb, sizeof (ctf_dwbitf_t));
1199 1199                          return (ECTF_CONVBKERR);
1200 1200                  }
1201 1201                  ctf_free(name, namesz + 1);
1202 1202                  ctf_list_append(&cup->cu_bitfields, cdb);
1203 1203          }
1204 1204  
1205 1205          *idp = cdb->cdb_id;
1206 1206  
1207 1207          return (0);
1208 1208  }
1209 1209  
1210 1210  static int
1211 1211  ctf_dwarf_fixup_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t base, boolean_t add)
1212 1212  {
1213 1213          int ret, kind;
1214 1214          Dwarf_Die child, memb;
1215 1215          Dwarf_Unsigned size;
1216 1216          ulong_t nsz;
1217 1217  
1218 1218          kind = ctf_type_kind(cup->cu_ctfp, base);
1219 1219          VERIFY(kind != CTF_ERR);
1220 1220          VERIFY(kind == CTF_K_STRUCT || kind == CTF_K_UNION);
1221 1221  
1222 1222          /*
1223 1223           * Members are in children. However, gcc also allows empty ones.
1224 1224           */
1225 1225          if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1226 1226                  return (ret);
1227 1227          if (child == NULL)
1228 1228                  return (0);
1229 1229  
1230 1230          memb = child;
1231 1231          while (memb != NULL) {
1232 1232                  Dwarf_Die sib, tdie;
1233 1233                  Dwarf_Half tag;
1234 1234                  ctf_id_t mid;
1235 1235                  char *mname;
1236 1236                  ulong_t memboff = 0;
1237 1237  
1238 1238                  if ((ret = ctf_dwarf_tag(cup, memb, &tag)) != 0)
1239 1239                          return (ret);
1240 1240  
1241 1241                  if (tag != DW_TAG_member)
1242 1242                          continue;
1243 1243  
1244 1244                  if ((ret = ctf_dwarf_refdie(cup, memb, DW_AT_type, &tdie)) != 0)
1245 1245                          return (ret);
1246 1246  
1247 1247                  if ((ret = ctf_dwarf_convert_type(cup, tdie, &mid,
1248 1248                      CTF_ADD_NONROOT)) != 0)
1249 1249                          return (ret);
1250 1250                  ctf_dprintf("Got back type id: %d\n", mid);
1251 1251  
1252 1252                  /*
1253 1253                   * If we're not adding a member, just go ahead and return.
1254 1254                   */
1255 1255                  if (add == B_FALSE) {
1256 1256                          if ((ret = ctf_dwarf_member_bitfield(cup, memb,
1257 1257                              &mid)) != 0)
1258 1258                                  return (ret);
1259 1259                          goto next;
1260 1260                  }
1261 1261  
1262 1262                  if ((ret = ctf_dwarf_string(cup, memb, DW_AT_name,
1263 1263                      &mname)) != 0 && ret != ENOENT)
1264 1264                          return (ret);
1265 1265                  if (ret == ENOENT)
1266 1266                          mname = NULL;
1267 1267  
1268 1268                  if (kind == CTF_K_UNION) {
1269 1269                          memboff = 0;
1270 1270                  } else if ((ret = ctf_dwarf_member_offset(cup, memb, mid,
1271 1271                      &memboff)) != 0) {
1272 1272                          if (mname != NULL)
1273 1273                                  ctf_free(mname, strlen(mname) + 1);
1274 1274                          return (ret);
1275 1275                  }
1276 1276  
1277 1277                  if ((ret = ctf_dwarf_member_bitfield(cup, memb, &mid)) != 0)
1278 1278                          return (ret);
1279 1279  
1280 1280                  ret = ctf_add_member(cup->cu_ctfp, base, mname, mid, memboff);
1281 1281                  if (ret == CTF_ERR) {
1282 1282                          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1283 1283                              "failed to add member %s: %s",
1284 1284                              mname, ctf_errmsg(ctf_errno(cup->cu_ctfp)));
1285 1285                          if (mname != NULL)
1286 1286                                  ctf_free(mname, strlen(mname) + 1);
1287 1287                          return (ECTF_CONVBKERR);
1288 1288                  }
1289 1289  
1290 1290                  if (mname != NULL)
1291 1291                          ctf_free(mname, strlen(mname) + 1);
1292 1292  
1293 1293  next:
1294 1294                  if ((ret = ctf_dwarf_sib(cup, memb, &sib)) != 0)
1295 1295                          return (ret);
1296 1296                  memb = sib;
1297 1297          }
1298 1298  
1299 1299          /*
1300 1300           * If we're not adding members, then we don't know the final size of the
1301 1301           * structure, so end here.
1302 1302           */
1303 1303          if (add == B_FALSE)
1304 1304                  return (0);
1305 1305  
1306 1306          /* Finally set the size of the structure to the actual byte size */
1307 1307          if ((ret = ctf_dwarf_unsigned(cup, die, DW_AT_byte_size, &size)) != 0)
1308 1308                  return (ret);
1309 1309          nsz = size;
1310 1310          if ((ctf_set_size(cup->cu_ctfp, base, nsz)) == CTF_ERR) {
1311 1311                  int e = ctf_errno(cup->cu_ctfp);
1312 1312                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1313 1313                      "failed to set type size for %d to 0x%x: %s", base,
1314 1314                      (uint32_t)size, ctf_errmsg(e));
1315 1315                  return (ECTF_CONVBKERR);
1316 1316          }
1317 1317  
1318 1318          return (0);
1319 1319  }
1320 1320  
1321 1321  static int
1322 1322  ctf_dwarf_create_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp,
1323 1323      int kind, int isroot)
1324 1324  {
1325 1325          int ret;
1326 1326          char *name;
1327 1327          ctf_id_t base;
1328 1328          Dwarf_Die child;
1329 1329          Dwarf_Bool decl;
1330 1330  
1331 1331          /*
1332 1332           * Deal with the terribly annoying case of anonymous structs and unions.
1333 1333           * If they don't have a name, set the name to the empty string.
1334 1334           */
1335 1335          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0 &&
1336 1336              ret != ENOENT)
1337 1337                  return (ret);
1338 1338          if (ret == ENOENT)
1339 1339                  name = NULL;
1340 1340  
1341 1341          /*
1342 1342           * We need to check if we just have a declaration here. If we do, then
1343 1343           * instead of creating an actual structure or union, we're just going to
1344 1344           * go ahead and create a forward. During a dedup or merge, the forward
1345 1345           * will be replaced with the real thing.
1346 1346           */
1347 1347          if ((ret = ctf_dwarf_boolean(cup, die, DW_AT_declaration,
1348 1348              &decl)) != 0) {
1349 1349                  if (ret != ENOENT)
1350 1350                          return (ret);
1351 1351                  decl = 0;
1352 1352          }
1353 1353  
1354 1354          if (decl != 0) {
1355 1355                  base = ctf_add_forward(cup->cu_ctfp, isroot, name, kind);
1356 1356          } else if (kind == CTF_K_STRUCT) {
1357 1357                  base = ctf_add_struct(cup->cu_ctfp, isroot, name);
1358 1358          } else {
1359 1359                  base = ctf_add_union(cup->cu_ctfp, isroot, name);
1360 1360          }
1361 1361          ctf_dprintf("added sou %s (%d) (%d)\n", name, kind, base);
1362 1362          if (name != NULL)
1363 1363                  ctf_free(name, strlen(name) + 1);
1364 1364          if (base == CTF_ERR)
1365 1365                  return (ctf_errno(cup->cu_ctfp));
1366 1366          *idp = base;
1367 1367  
1368 1368          /*
1369 1369           * If it's just a declaration, we're not going to mark it for fix up or
1370 1370           * do anything else.
1371 1371           */
1372 1372          if (decl == B_TRUE)
1373 1373                  return (ctf_dwmap_add(cup, base, die, B_FALSE));
1374 1374          if ((ret = ctf_dwmap_add(cup, base, die, B_TRUE)) != 0)
1375 1375                  return (ret);
1376 1376  
1377 1377          /*
1378 1378           * Members are in children. However, gcc also allows empty ones.
1379 1379           */
1380 1380          if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1381 1381                  return (ret);
1382 1382          if (child == NULL)
1383 1383                  return (0);
1384 1384  
1385 1385          return (0);
1386 1386  }
1387 1387  
1388 1388  static int
1389 1389  ctf_dwarf_create_array_range(ctf_cu_t *cup, Dwarf_Die range, ctf_id_t *idp,
1390 1390      ctf_id_t base, int isroot)
1391 1391  {
1392 1392          int ret;
1393 1393          Dwarf_Die sib;
1394 1394          Dwarf_Unsigned val;
1395 1395          Dwarf_Signed sval;
1396 1396          ctf_arinfo_t ar;
1397 1397  
1398 1398          ctf_dprintf("creating array range\n");
1399 1399  
1400 1400          if ((ret = ctf_dwarf_sib(cup, range, &sib)) != 0)
1401 1401                  return (ret);
1402 1402          if (sib != NULL) {
1403 1403                  ctf_id_t id;
1404 1404                  if ((ret = ctf_dwarf_create_array_range(cup, sib, &id,
1405 1405                      base, CTF_ADD_NONROOT)) != 0)
1406 1406                          return (ret);
1407 1407                  ar.ctr_contents = id;
1408 1408          } else {
1409 1409                  ar.ctr_contents = base;
1410 1410          }
1411 1411  
1412 1412          if ((ar.ctr_index = ctf_dwarf_long(cup)) == CTF_ERR)
1413 1413                  return (ctf_errno(cup->cu_ctfp));
1414 1414  
1415 1415          /*
1416 1416           * Array bounds can be signed or unsigned, but there are several kinds
1417 1417           * of signless forms (data1, data2, etc) that take their sign from the
1418 1418           * routine that is trying to interpret them.  That is, data1 can be
1419 1419           * either signed or unsigned, depending on whether you use the signed or
1420 1420           * unsigned accessor function.  GCC will use the signless forms to store
1421 1421           * unsigned values which have their high bit set, so we need to try to
1422 1422           * read them first as unsigned to get positive values.  We could also
1423 1423           * try signed first, falling back to unsigned if we got a negative
1424 1424           * value.
1425 1425           */
1426 1426          if ((ret = ctf_dwarf_unsigned(cup, range, DW_AT_upper_bound,
1427 1427              &val)) == 0) {
1428 1428                  ar.ctr_nelems = val + 1;
1429 1429          } else if (ret != ENOENT) {
1430 1430                  return (ret);
1431 1431          } else if ((ret = ctf_dwarf_signed(cup, range, DW_AT_upper_bound,
1432 1432              &sval)) == 0) {
1433 1433                  ar.ctr_nelems = sval + 1;
1434 1434          } else if (ret != ENOENT) {
1435 1435                  return (ret);
1436 1436          } else {
1437 1437                  ar.ctr_nelems = 0;
1438 1438          }
1439 1439  
1440 1440          if ((*idp = ctf_add_array(cup->cu_ctfp, isroot, &ar)) == CTF_ERR)
1441 1441                  return (ctf_errno(cup->cu_ctfp));
1442 1442  
1443 1443          return (0);
1444 1444  }
1445 1445  
1446 1446  /*
1447 1447   * Try and create an array type. First, the kind of the array is specified in
1448 1448   * the DW_AT_type entry. Next, the number of entries is stored in a more
1449 1449   * complicated form, we should have a child that has the DW_TAG_subrange type.
1450 1450   */
1451 1451  static int
1452 1452  ctf_dwarf_create_array(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot)
1453 1453  {
1454 1454          int ret;
1455 1455          Dwarf_Die tdie, rdie;
1456 1456          ctf_id_t tid;
1457 1457          Dwarf_Half rtag;
1458 1458  
1459 1459          if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) != 0)
1460 1460                  return (ret);
1461 1461          if ((ret = ctf_dwarf_convert_type(cup, tdie, &tid,
1462 1462              CTF_ADD_NONROOT)) != 0)
1463 1463                  return (ret);
1464 1464  
1465 1465          if ((ret = ctf_dwarf_child(cup, die, &rdie)) != 0)
1466 1466                  return (ret);
1467 1467          if ((ret = ctf_dwarf_tag(cup, rdie, &rtag)) != 0)
1468 1468                  return (ret);
1469 1469          if (rtag != DW_TAG_subrange_type) {
1470 1470                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1471 1471                      "encountered array without DW_TAG_subrange_type child\n");
1472 1472                  return (ECTF_CONVBKERR);
1473 1473          }
1474 1474  
1475 1475          /*
1476 1476           * The compiler may opt to describe a multi-dimensional array as one
1477 1477           * giant array or it may opt to instead encode it as a series of
1478 1478           * subranges. If it's the latter, then for each subrange we introduce a
1479 1479           * type. We can always use the base type.
1480 1480           */
1481 1481          if ((ret = ctf_dwarf_create_array_range(cup, rdie, idp, tid,
1482 1482              isroot)) != 0)
1483 1483                  return (ret);
1484 1484          ctf_dprintf("Got back id %d\n", *idp);
1485 1485          return (ctf_dwmap_add(cup, *idp, die, B_FALSE));
1486 1486  }
1487 1487  
1488 1488  static int
1489 1489  ctf_dwarf_create_reference(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp,
1490 1490      int kind, int isroot)
1491 1491  {
1492 1492          int ret;
1493 1493          ctf_id_t id;
1494 1494          Dwarf_Die tdie;
1495 1495          char *name;
1496 1496          size_t namelen;
1497 1497  
1498 1498          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0 &&
1499 1499              ret != ENOENT)
1500 1500                  return (ret);
1501 1501          if (ret == ENOENT) {
1502 1502                  name = NULL;
1503 1503                  namelen = 0;
1504 1504          } else {
1505 1505                  namelen = strlen(name);
1506 1506          }
1507 1507  
1508 1508          ctf_dprintf("reference kind %d %s\n", kind, name != NULL ? name : "<>");
1509 1509  
1510 1510          if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) != 0) {
1511 1511                  if (ret != ENOENT) {
1512 1512                          ctf_free(name, namelen);
1513 1513                          return (ret);
1514 1514                  }
1515 1515                  if ((id = ctf_dwarf_void(cup)) == CTF_ERR) {
1516 1516                          ctf_free(name, namelen);
1517 1517                          return (ctf_errno(cup->cu_ctfp));
1518 1518                  }
1519 1519          } else {
1520 1520                  if ((ret = ctf_dwarf_convert_type(cup, tdie, &id,
1521 1521                      CTF_ADD_NONROOT)) != 0) {
1522 1522                          ctf_free(name, namelen);
1523 1523                          return (ret);
1524 1524                  }
1525 1525          }
1526 1526  
1527 1527          if ((*idp = ctf_add_reftype(cup->cu_ctfp, isroot, name, id, kind)) ==
1528 1528              CTF_ERR) {
1529 1529                  ctf_free(name, namelen);
1530 1530                  return (ctf_errno(cup->cu_ctfp));
1531 1531          }
1532 1532  
1533 1533          ctf_free(name, namelen);
1534 1534          return (ctf_dwmap_add(cup, *idp, die, B_FALSE));
1535 1535  }
1536 1536  
1537 1537  static int
1538 1538  ctf_dwarf_create_enum(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot)
1539 1539  {
1540 1540          int ret;
1541 1541          ctf_id_t id;
1542 1542          Dwarf_Die child;
1543 1543          char *name;
1544 1544  
1545 1545          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0 &&
1546 1546              ret != ENOENT)
1547 1547                  return (ret);
1548 1548          if (ret == ENOENT)
1549 1549                  name = NULL;
1550 1550          id = ctf_add_enum(cup->cu_ctfp, isroot, name);
1551 1551          ctf_dprintf("added enum %s (%d)\n", name, id);
1552 1552          if (name != NULL)
1553 1553                  ctf_free(name, strlen(name) + 1);
1554 1554          if (id == CTF_ERR)
1555 1555                  return (ctf_errno(cup->cu_ctfp));
1556 1556          *idp = id;
1557 1557          if ((ret = ctf_dwmap_add(cup, id, die, B_FALSE)) != 0)
1558 1558                  return (ret);
1559 1559  
1560 1560          if ((ret = ctf_dwarf_child(cup, die, &child)) != 0) {
1561 1561                  if (ret == ENOENT)
1562 1562                          ret = 0;
1563 1563                  return (ret);
1564 1564          }
1565 1565  
1566 1566          while (child != NULL) {
1567 1567                  Dwarf_Half tag;
1568 1568                  Dwarf_Signed sval;
1569 1569                  Dwarf_Unsigned uval;
1570 1570                  Dwarf_Die arg = child;
1571 1571                  int eval;
1572 1572  
1573 1573                  if ((ret = ctf_dwarf_sib(cup, arg, &child)) != 0)
1574 1574                          return (ret);
1575 1575  
1576 1576                  if ((ret = ctf_dwarf_tag(cup, arg, &tag)) != 0)
1577 1577                          return (ret);
1578 1578  
1579 1579                  if (tag != DW_TAG_enumerator) {
1580 1580                          if ((ret = ctf_dwarf_convert_type(cup, arg, NULL,
1581 1581                              CTF_ADD_NONROOT)) != 0)
1582 1582                                  return (ret);
1583 1583                          continue;
1584 1584                  }
1585 1585  
1586 1586                  /*
1587 1587                   * DWARF v4 section 5.7 tells us we'll always have names.
1588 1588                   */
1589 1589                  if ((ret = ctf_dwarf_string(cup, arg, DW_AT_name, &name)) != 0)
1590 1590                          return (ret);
1591 1591  
1592 1592                  /*
1593 1593                   * We have to be careful here: newer GCCs generate DWARF where
1594 1594                   * an unsigned value will happily pass ctf_dwarf_signed().
1595 1595                   * Since negative values will fail ctf_dwarf_unsigned(), we try
1596 1596                   * that first to make sure we get the right value.
1597 1597                   */
1598 1598                  if ((ret = ctf_dwarf_unsigned(cup, arg, DW_AT_const_value,
1599 1599                      &uval)) == 0) {
1600 1600                          eval = (int)uval;
1601 1601                  } else if ((ret = ctf_dwarf_signed(cup, arg, DW_AT_const_value,
1602 1602                      &sval)) == 0) {
1603 1603                          eval = sval;
1604 1604                  }
1605 1605  
1606 1606                  if (ret != 0) {
1607 1607                          if (ret != ENOENT)
1608 1608                                  return (ret);
1609 1609  
1610 1610                          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1611 1611                              "encountered enumeration without constant value\n");
1612 1612                          return (ECTF_CONVBKERR);
1613 1613                  }
1614 1614  
1615 1615                  ret = ctf_add_enumerator(cup->cu_ctfp, id, name, eval);
1616 1616                  if (ret == CTF_ERR) {
1617 1617                          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1618 1618                              "failed to add enumarator %s (%d) to %d\n",
1619 1619                              name, eval, id);
1620 1620                          ctf_free(name, strlen(name) + 1);
1621 1621                          return (ctf_errno(cup->cu_ctfp));
1622 1622                  }
1623 1623                  ctf_free(name, strlen(name) + 1);
1624 1624          }
1625 1625  
1626 1626          return (0);
1627 1627  }
1628 1628  
1629 1629  /*
1630 1630   * For a function pointer, walk over and process all of its children, unless we
1631 1631   * encounter one that's just a declaration. In which case, we error on it.
1632 1632   */
1633 1633  static int
1634 1634  ctf_dwarf_create_fptr(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot)
1635 1635  {
1636 1636          int ret;
1637 1637          Dwarf_Bool b;
1638 1638          ctf_funcinfo_t fi;
1639 1639          Dwarf_Die retdie;
1640 1640          ctf_id_t *argv = NULL;
1641 1641  
1642 1642          bzero(&fi, sizeof (ctf_funcinfo_t));
1643 1643  
1644 1644          if ((ret = ctf_dwarf_boolean(cup, die, DW_AT_declaration, &b)) != 0) {
1645 1645                  if (ret != ENOENT)
1646 1646                          return (ret);
1647 1647          } else {
1648 1648                  if (b != 0)
1649 1649                          return (EPROTOTYPE);
1650 1650          }
1651 1651  
1652 1652          /*
1653 1653           * Return type is in DW_AT_type, if none, it returns void.
1654 1654           */
1655 1655          if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &retdie)) != 0) {
1656 1656                  if (ret != ENOENT)
1657 1657                          return (ret);
1658 1658                  if ((fi.ctc_return = ctf_dwarf_void(cup)) == CTF_ERR)
1659 1659                          return (ctf_errno(cup->cu_ctfp));
1660 1660          } else {
1661 1661                  if ((ret = ctf_dwarf_convert_type(cup, retdie, &fi.ctc_return,
1662 1662                      CTF_ADD_NONROOT)) != 0)
1663 1663                          return (ret);
1664 1664          }
1665 1665  
1666 1666          if ((ret = ctf_dwarf_function_count(cup, die, &fi, B_TRUE)) != 0) {
1667 1667                  return (ret);
1668 1668          }
1669 1669  
1670 1670          if (fi.ctc_argc != 0) {
1671 1671                  argv = ctf_alloc(sizeof (ctf_id_t) * fi.ctc_argc);
1672 1672                  if (argv == NULL)
1673 1673                          return (ENOMEM);
1674 1674  
1675 1675                  if ((ret = ctf_dwarf_convert_fargs(cup, die, &fi, argv)) != 0) {
1676 1676                          ctf_free(argv, sizeof (ctf_id_t) * fi.ctc_argc);
1677 1677                          return (ret);
1678 1678                  }
1679 1679          }
1680 1680  
1681 1681          if ((*idp = ctf_add_funcptr(cup->cu_ctfp, isroot, &fi, argv)) ==
1682 1682              CTF_ERR) {
1683 1683                  ctf_free(argv, sizeof (ctf_id_t) * fi.ctc_argc);
1684 1684                  return (ctf_errno(cup->cu_ctfp));
1685 1685          }
1686 1686  
1687 1687          ctf_free(argv, sizeof (ctf_id_t) * fi.ctc_argc);
1688 1688          return (ctf_dwmap_add(cup, *idp, die, B_FALSE));
1689 1689  }
1690 1690  
1691 1691  static int
1692 1692  ctf_dwarf_convert_type(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp,
1693 1693      int isroot)
1694 1694  {
1695 1695          int ret;
1696 1696          Dwarf_Off offset;
1697 1697          Dwarf_Half tag;
1698 1698          ctf_dwmap_t lookup, *map;
1699 1699          ctf_id_t id;
1700 1700  
1701 1701          if (idp == NULL)
1702 1702                  idp = &id;
1703 1703  
1704 1704          if ((ret = ctf_dwarf_offset(cup, die, &offset)) != 0)
1705 1705                  return (ret);
1706 1706  
1707 1707          if (offset > cup->cu_maxoff) {
1708 1708                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1709 1709                      "die offset %llu beyond maximum for header %llu\n",
1710 1710                      offset, cup->cu_maxoff);
1711 1711                  return (ECTF_CONVBKERR);
1712 1712          }
1713 1713  
1714 1714          /*
1715 1715           * If we've already added an entry for this offset, then we're done.
1716 1716           */
1717 1717          lookup.cdm_off = offset;
1718 1718          if ((map = avl_find(&cup->cu_map, &lookup, NULL)) != NULL) {
1719 1719                  *idp = map->cdm_id;
1720 1720                  return (0);
1721 1721          }
1722 1722  
1723 1723          if ((ret = ctf_dwarf_tag(cup, die, &tag)) != 0)
1724 1724                  return (ret);
1725 1725  
1726 1726          ret = ENOTSUP;
1727 1727          switch (tag) {
1728 1728          case DW_TAG_base_type:
1729 1729                  ctf_dprintf("base\n");
1730 1730                  ret = ctf_dwarf_create_base(cup, die, idp, isroot, offset);
1731 1731                  break;
1732 1732          case DW_TAG_array_type:
1733 1733                  ctf_dprintf("array\n");
1734 1734                  ret = ctf_dwarf_create_array(cup, die, idp, isroot);
1735 1735                  break;
1736 1736          case DW_TAG_enumeration_type:
1737 1737                  ctf_dprintf("enum\n");
1738 1738                  ret = ctf_dwarf_create_enum(cup, die, idp, isroot);
1739 1739                  break;
1740 1740          case DW_TAG_pointer_type:
1741 1741                  ctf_dprintf("pointer\n");
1742 1742                  ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_POINTER,
1743 1743                      isroot);
1744 1744                  break;
1745 1745          case DW_TAG_structure_type:
1746 1746                  ctf_dprintf("struct\n");
1747 1747                  ret = ctf_dwarf_create_sou(cup, die, idp, CTF_K_STRUCT,
1748 1748                      isroot);
1749 1749                  break;
1750 1750          case DW_TAG_subroutine_type:
1751 1751                  ctf_dprintf("fptr\n");
1752 1752                  ret = ctf_dwarf_create_fptr(cup, die, idp, isroot);
1753 1753                  break;
1754 1754          case DW_TAG_typedef:
1755 1755                  ctf_dprintf("typedef\n");
1756 1756                  ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_TYPEDEF,
1757 1757                      isroot);
1758 1758                  break;
1759 1759          case DW_TAG_union_type:
1760 1760                  ctf_dprintf("union\n");
1761 1761                  ret = ctf_dwarf_create_sou(cup, die, idp, CTF_K_UNION,
1762 1762                      isroot);
1763 1763                  break;
1764 1764          case DW_TAG_const_type:
1765 1765                  ctf_dprintf("const\n");
1766 1766                  ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_CONST,
1767 1767                      isroot);
1768 1768                  break;
1769 1769          case DW_TAG_volatile_type:
1770 1770                  ctf_dprintf("volatile\n");
  
    | 
      ↓ open down ↓ | 
    874 lines elided | 
    
      ↑ open up ↑ | 
  
1771 1771                  ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_VOLATILE,
1772 1772                      isroot);
1773 1773                  break;
1774 1774          case DW_TAG_restrict_type:
1775 1775                  ctf_dprintf("restrict\n");
1776 1776                  ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_RESTRICT,
1777 1777                      isroot);
1778 1778                  break;
1779 1779          default:
1780 1780                  ctf_dprintf("ignoring tag type %x\n", tag);
     1781 +                *idp = CTF_ERR;
1781 1782                  ret = 0;
1782 1783                  break;
1783 1784          }
1784 1785          ctf_dprintf("ctf_dwarf_convert_type tag specific handler returned %d\n",
1785 1786              ret);
1786 1787  
1787 1788          return (ret);
1788 1789  }
1789 1790  
1790 1791  static int
1791 1792  ctf_dwarf_walk_lexical(ctf_cu_t *cup, Dwarf_Die die)
1792 1793  {
1793 1794          int ret;
1794 1795          Dwarf_Die child;
1795 1796  
1796 1797          if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1797 1798                  return (ret);
1798 1799  
1799 1800          if (child == NULL)
1800 1801                  return (0);
1801 1802  
1802 1803          return (ctf_dwarf_convert_die(cup, die));
1803 1804  }
1804 1805  
1805 1806  static int
1806 1807  ctf_dwarf_function_count(ctf_cu_t *cup, Dwarf_Die die, ctf_funcinfo_t *fip,
1807 1808      boolean_t fptr)
1808 1809  {
1809 1810          int ret;
1810 1811          Dwarf_Die child, sib, arg;
1811 1812  
1812 1813          if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1813 1814                  return (ret);
1814 1815  
1815 1816          arg = child;
1816 1817          while (arg != NULL) {
1817 1818                  Dwarf_Half tag;
1818 1819  
1819 1820                  if ((ret = ctf_dwarf_tag(cup, arg, &tag)) != 0)
1820 1821                          return (ret);
1821 1822  
1822 1823                  /*
1823 1824                   * We have to check for a varargs type decleration. This will
1824 1825                   * happen in one of two ways. If we have a function pointer
1825 1826                   * type, then it'll be done with a tag of type
1826 1827                   * DW_TAG_unspecified_parameters. However, it only means we have
1827 1828                   * a variable number of arguments, if we have more than one
1828 1829                   * argument found so far. Otherwise, when we have a function
1829 1830                   * type, it instead uses a formal parameter whose name is '...'
1830 1831                   * to indicate a variable arguments member.
1831 1832                   *
1832 1833                   * Also, if we have a function pointer, then we have to expect
1833 1834                   * that we might not get a name at all.
1834 1835                   */
1835 1836                  if (tag == DW_TAG_formal_parameter && fptr == B_FALSE) {
1836 1837                          char *name;
1837 1838                          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name,
1838 1839                              &name)) != 0)
1839 1840                                  return (ret);
1840 1841                          if (strcmp(name, DWARF_VARARGS_NAME) == 0)
1841 1842                                  fip->ctc_flags |= CTF_FUNC_VARARG;
1842 1843                          else
1843 1844                                  fip->ctc_argc++;
1844 1845                          ctf_free(name, strlen(name) + 1);
1845 1846                  } else if (tag == DW_TAG_formal_parameter) {
1846 1847                          fip->ctc_argc++;
1847 1848                  } else if (tag == DW_TAG_unspecified_parameters &&
1848 1849                      fip->ctc_argc > 0) {
1849 1850                          fip->ctc_flags |= CTF_FUNC_VARARG;
1850 1851                  }
1851 1852                  if ((ret = ctf_dwarf_sib(cup, arg, &sib)) != 0)
1852 1853                          return (ret);
1853 1854                  arg = sib;
1854 1855          }
1855 1856  
1856 1857          return (0);
1857 1858  }
1858 1859  
1859 1860  static int
1860 1861  ctf_dwarf_convert_fargs(ctf_cu_t *cup, Dwarf_Die die, ctf_funcinfo_t *fip,
1861 1862      ctf_id_t *argv)
1862 1863  {
1863 1864          int ret;
1864 1865          int i = 0;
1865 1866          Dwarf_Die child, sib, arg;
1866 1867  
1867 1868          if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1868 1869                  return (ret);
1869 1870  
1870 1871          arg = child;
1871 1872          while (arg != NULL) {
1872 1873                  Dwarf_Half tag;
1873 1874  
1874 1875                  if ((ret = ctf_dwarf_tag(cup, arg, &tag)) != 0)
1875 1876                          return (ret);
1876 1877                  if (tag == DW_TAG_formal_parameter) {
1877 1878                          Dwarf_Die tdie;
1878 1879  
1879 1880                          if ((ret = ctf_dwarf_refdie(cup, arg, DW_AT_type,
1880 1881                              &tdie)) != 0)
1881 1882                                  return (ret);
1882 1883  
1883 1884                          if ((ret = ctf_dwarf_convert_type(cup, tdie, &argv[i],
1884 1885                              CTF_ADD_ROOT)) != 0)
1885 1886                                  return (ret);
1886 1887                          i++;
1887 1888  
1888 1889                          /*
1889 1890                           * Once we hit argc entries, we're done. This ensures we
1890 1891                           * don't accidentally hit a varargs which should be the
1891 1892                           * last entry.
1892 1893                           */
1893 1894                          if (i == fip->ctc_argc)
1894 1895                                  break;
1895 1896                  }
1896 1897  
1897 1898                  if ((ret = ctf_dwarf_sib(cup, arg, &sib)) != 0)
1898 1899                          return (ret);
1899 1900                  arg = sib;
1900 1901          }
1901 1902  
1902 1903          return (0);
1903 1904  }
1904 1905  
1905 1906  static int
1906 1907  ctf_dwarf_convert_function(ctf_cu_t *cup, Dwarf_Die die)
1907 1908  {
1908 1909          int ret;
1909 1910          char *name;
1910 1911          ctf_dwfunc_t *cdf;
1911 1912          Dwarf_Die tdie;
1912 1913  
1913 1914          /*
1914 1915           * Functions that don't have a name are generally functions that have
1915 1916           * been inlined and thus most information about them has been lost. If
1916 1917           * we can't get a name, then instead of returning ENOENT, we silently
1917 1918           * swallow the error.
1918 1919           */
1919 1920          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0) {
1920 1921                  if (ret == ENOENT)
1921 1922                          return (0);
1922 1923                  return (ret);
1923 1924          }
1924 1925  
1925 1926          ctf_dprintf("beginning work on function %s\n", name);
1926 1927          if ((cdf = ctf_alloc(sizeof (ctf_dwfunc_t))) == NULL) {
1927 1928                  ctf_free(name, strlen(name) + 1);
1928 1929                  return (ENOMEM);
1929 1930          }
1930 1931          bzero(cdf, sizeof (ctf_dwfunc_t));
1931 1932          cdf->cdf_name = name;
1932 1933  
1933 1934          if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) == 0) {
1934 1935                  if ((ret = ctf_dwarf_convert_type(cup, tdie,
1935 1936                      &(cdf->cdf_fip.ctc_return), CTF_ADD_ROOT)) != 0) {
1936 1937                          ctf_free(name, strlen(name) + 1);
1937 1938                          ctf_free(cdf, sizeof (ctf_dwfunc_t));
1938 1939                          return (ret);
1939 1940                  }
1940 1941          } else if (ret != ENOENT) {
1941 1942                  ctf_free(name, strlen(name) + 1);
1942 1943                  ctf_free(cdf, sizeof (ctf_dwfunc_t));
1943 1944                  return (ret);
1944 1945          } else {
1945 1946                  if ((cdf->cdf_fip.ctc_return = ctf_dwarf_void(cup)) ==
1946 1947                      CTF_ERR) {
1947 1948                          ctf_free(name, strlen(name) + 1);
1948 1949                          ctf_free(cdf, sizeof (ctf_dwfunc_t));
1949 1950                          return (ctf_errno(cup->cu_ctfp));
1950 1951                  }
1951 1952          }
1952 1953  
1953 1954          /*
1954 1955           * A function has a number of children, some of which may not be ones we
1955 1956           * care about. Children that we care about have a type of
1956 1957           * DW_TAG_formal_parameter. We're going to do two passes, the first to
1957 1958           * count the arguments, the second to process them. Afterwards, we
1958 1959           * should be good to go ahead and add this function.
1959 1960           *
1960 1961           * Note, we already got the return type by going in and grabbing it out
1961 1962           * of the DW_AT_type.
1962 1963           */
1963 1964          if ((ret = ctf_dwarf_function_count(cup, die, &cdf->cdf_fip,
1964 1965              B_FALSE)) != 0) {
1965 1966                  ctf_free(name, strlen(name) + 1);
1966 1967                  ctf_free(cdf, sizeof (ctf_dwfunc_t));
1967 1968                  return (ret);
1968 1969          }
1969 1970  
1970 1971          ctf_dprintf("beginning to convert function arguments %s\n", name);
1971 1972          if (cdf->cdf_fip.ctc_argc != 0) {
1972 1973                  uint_t argc = cdf->cdf_fip.ctc_argc;
1973 1974                  cdf->cdf_argv = ctf_alloc(sizeof (ctf_id_t) * argc);
1974 1975                  if (cdf->cdf_argv == NULL) {
1975 1976                          ctf_free(name, strlen(name) + 1);
1976 1977                          ctf_free(cdf, sizeof (ctf_dwfunc_t));
1977 1978                          return (ENOMEM);
1978 1979                  }
1979 1980                  if ((ret = ctf_dwarf_convert_fargs(cup, die,
1980 1981                      &cdf->cdf_fip, cdf->cdf_argv)) != 0) {
1981 1982                          ctf_free(cdf->cdf_argv, sizeof (ctf_id_t) * argc);
1982 1983                          ctf_free(name, strlen(name) + 1);
1983 1984                          ctf_free(cdf, sizeof (ctf_dwfunc_t));
1984 1985                          return (ret);
1985 1986                  }
1986 1987          } else {
1987 1988                  cdf->cdf_argv = NULL;
1988 1989          }
1989 1990  
1990 1991          if ((ret = ctf_dwarf_isglobal(cup, die, &cdf->cdf_global)) != 0) {
1991 1992                  ctf_free(cdf->cdf_argv, sizeof (ctf_id_t) *
1992 1993                      cdf->cdf_fip.ctc_argc);
1993 1994                  ctf_free(name, strlen(name) + 1);
1994 1995                  ctf_free(cdf, sizeof (ctf_dwfunc_t));
1995 1996                  return (ret);
1996 1997          }
1997 1998  
1998 1999          ctf_list_append(&cup->cu_funcs, cdf);
1999 2000          return (ret);
2000 2001  }
2001 2002  
2002 2003  /*
2003 2004   * Convert variables, but only if they're not prototypes and have names.
2004 2005   */
2005 2006  static int
2006 2007  ctf_dwarf_convert_variable(ctf_cu_t *cup, Dwarf_Die die)
2007 2008  {
2008 2009          int ret;
2009 2010          char *name;
2010 2011          Dwarf_Bool b;
2011 2012          Dwarf_Die tdie;
2012 2013          ctf_id_t id;
2013 2014          ctf_dwvar_t *cdv;
2014 2015  
2015 2016          /* Skip "Non-Defining Declarations" */
2016 2017          if ((ret = ctf_dwarf_boolean(cup, die, DW_AT_declaration, &b)) == 0) {
2017 2018                  if (b != 0)
2018 2019                          return (0);
2019 2020          } else if (ret != ENOENT) {
2020 2021                  return (ret);
2021 2022          }
2022 2023  
2023 2024          /*
2024 2025           * If we find a DIE of "Declarations Completing Non-Defining
2025 2026           * Declarations", we will use the referenced type's DIE.  This isn't
2026 2027           * quite correct, e.g. DW_AT_decl_line will be the forward declaration
2027 2028           * not this site.  It's sufficient for what we need, however: in
2028 2029           * particular, we should find DW_AT_external as needed there.
2029 2030           */
2030 2031          if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_specification,
2031 2032              &tdie)) == 0) {
2032 2033                  Dwarf_Off offset;
2033 2034                  if ((ret = ctf_dwarf_offset(cup, tdie, &offset)) != 0)
2034 2035                          return (ret);
2035 2036                  ctf_dprintf("die 0x%llx DW_AT_specification -> die 0x%llx\n",
2036 2037                      ctf_die_offset(die), ctf_die_offset(tdie));
2037 2038                  die = tdie;
2038 2039          } else if (ret != ENOENT) {
2039 2040                  return (ret);
2040 2041          }
2041 2042  
2042 2043          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0 &&
2043 2044              ret != ENOENT)
2044 2045                  return (ret);
2045 2046          if (ret == ENOENT)
2046 2047                  return (0);
2047 2048  
2048 2049          if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) != 0) {
2049 2050                  ctf_free(name, strlen(name) + 1);
2050 2051                  return (ret);
2051 2052          }
2052 2053  
2053 2054          if ((ret = ctf_dwarf_convert_type(cup, tdie, &id,
2054 2055              CTF_ADD_ROOT)) != 0)
2055 2056                  return (ret);
2056 2057  
2057 2058          if ((cdv = ctf_alloc(sizeof (ctf_dwvar_t))) == NULL) {
2058 2059                  ctf_free(name, strlen(name) + 1);
2059 2060                  return (ENOMEM);
2060 2061          }
2061 2062  
2062 2063          cdv->cdv_name = name;
2063 2064          cdv->cdv_type = id;
2064 2065  
2065 2066          if ((ret = ctf_dwarf_isglobal(cup, die, &cdv->cdv_global)) != 0) {
2066 2067                  ctf_free(cdv, sizeof (ctf_dwvar_t));
2067 2068                  ctf_free(name, strlen(name) + 1);
2068 2069                  return (ret);
2069 2070          }
2070 2071  
2071 2072          ctf_list_append(&cup->cu_vars, cdv);
2072 2073          return (0);
2073 2074  }
2074 2075  
2075 2076  /*
2076 2077   * Walk through our set of top-level types and process them.
2077 2078   */
2078 2079  static int
2079 2080  ctf_dwarf_walk_toplevel(ctf_cu_t *cup, Dwarf_Die die)
2080 2081  {
2081 2082          int ret;
2082 2083          Dwarf_Off offset;
2083 2084          Dwarf_Half tag;
2084 2085  
2085 2086          if ((ret = ctf_dwarf_offset(cup, die, &offset)) != 0)
2086 2087                  return (ret);
2087 2088  
2088 2089          if (offset > cup->cu_maxoff) {
2089 2090                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
2090 2091                      "die offset %llu beyond maximum for header %llu\n",
2091 2092                      offset, cup->cu_maxoff);
2092 2093                  return (ECTF_CONVBKERR);
2093 2094          }
2094 2095  
2095 2096          if ((ret = ctf_dwarf_tag(cup, die, &tag)) != 0)
2096 2097                  return (ret);
2097 2098  
2098 2099          ret = 0;
2099 2100          switch (tag) {
2100 2101          case DW_TAG_subprogram:
2101 2102                  ctf_dprintf("top level func\n");
2102 2103                  ret = ctf_dwarf_convert_function(cup, die);
2103 2104                  break;
2104 2105          case DW_TAG_variable:
2105 2106                  ctf_dprintf("top level var\n");
2106 2107                  ret = ctf_dwarf_convert_variable(cup, die);
2107 2108                  break;
2108 2109          case DW_TAG_lexical_block:
2109 2110                  ctf_dprintf("top level block\n");
2110 2111                  ret = ctf_dwarf_walk_lexical(cup, die);
2111 2112                  break;
2112 2113          case DW_TAG_enumeration_type:
2113 2114          case DW_TAG_structure_type:
2114 2115          case DW_TAG_typedef:
2115 2116          case DW_TAG_union_type:
2116 2117                  ctf_dprintf("top level type\n");
2117 2118                  ret = ctf_dwarf_convert_type(cup, die, NULL, B_TRUE);
2118 2119                  break;
2119 2120          default:
2120 2121                  break;
2121 2122          }
2122 2123  
2123 2124          return (ret);
2124 2125  }
2125 2126  
2126 2127  
2127 2128  /*
2128 2129   * We're given a node. At this node we need to convert it and then proceed to
2129 2130   * convert any siblings that are associaed with this die.
2130 2131   */
2131 2132  static int
2132 2133  ctf_dwarf_convert_die(ctf_cu_t *cup, Dwarf_Die die)
2133 2134  {
2134 2135          while (die != NULL) {
2135 2136                  int ret;
2136 2137                  Dwarf_Die sib;
2137 2138  
2138 2139                  if ((ret = ctf_dwarf_walk_toplevel(cup, die)) != 0)
2139 2140                          return (ret);
2140 2141  
2141 2142                  if ((ret = ctf_dwarf_sib(cup, die, &sib)) != 0)
2142 2143                          return (ret);
2143 2144                  die = sib;
2144 2145          }
2145 2146          return (0);
2146 2147  }
2147 2148  
2148 2149  static int
2149 2150  ctf_dwarf_fixup_die(ctf_cu_t *cup, boolean_t addpass)
2150 2151  {
2151 2152          ctf_dwmap_t *map;
2152 2153  
2153 2154          for (map = avl_first(&cup->cu_map); map != NULL;
2154 2155              map = AVL_NEXT(&cup->cu_map, map)) {
2155 2156                  int ret;
2156 2157                  if (map->cdm_fix == B_FALSE)
2157 2158                          continue;
2158 2159                  if ((ret = ctf_dwarf_fixup_sou(cup, map->cdm_die, map->cdm_id,
2159 2160                      addpass)) != 0)
2160 2161                          return (ret);
2161 2162          }
2162 2163  
2163 2164          return (0);
2164 2165  }
2165 2166  
2166 2167  /*
2167 2168   * The DWARF information about a symbol and the information in the symbol table
2168 2169   * may not be the same due to symbol reduction that is performed by ld due to a
2169 2170   * mapfile or other such directive. We process weak symbols at a later time.
2170 2171   *
2171 2172   * The following are the rules that we employ:
2172 2173   *
2173 2174   * 1. A DWARF function that is considered exported matches STB_GLOBAL entries
2174 2175   * with the same name.
2175 2176   *
2176 2177   * 2. A DWARF function that is considered exported matches STB_LOCAL entries
2177 2178   * with the same name and the same file. This case may happen due to mapfile
2178 2179   * reduction.
2179 2180   *
2180 2181   * 3. A DWARF function that is not considered exported matches STB_LOCAL entries
2181 2182   * with the same name and the same file.
2182 2183   *
2183 2184   * 4. A DWARF function that has the same name as the symbol table entry, but the
2184 2185   * files do not match. This is considered a 'fuzzy' match. This may also happen
2185 2186   * due to a mapfile reduction. Fuzzy matching is only used when we know that the
2186 2187   * file in question refers to the primary object. This is because when a symbol
2187 2188   * is reduced in a mapfile, it's always going to be tagged as a local value in
2188 2189   * the generated output and it is considered as to belong to the primary file
2189 2190   * which is the first STT_FILE symbol we see.
2190 2191   */
2191 2192  static boolean_t
2192 2193  ctf_dwarf_symbol_match(const char *symtab_file, const char *symtab_name,
2193 2194      uint_t symtab_bind, const char *dwarf_file, const char *dwarf_name,
2194 2195      boolean_t dwarf_global, boolean_t *is_fuzzy)
2195 2196  {
2196 2197          *is_fuzzy = B_FALSE;
2197 2198  
2198 2199          if (symtab_bind != STB_LOCAL && symtab_bind != STB_GLOBAL) {
2199 2200                  return (B_FALSE);
2200 2201          }
2201 2202  
2202 2203          if (strcmp(symtab_name, dwarf_name) != 0) {
2203 2204                  return (B_FALSE);
2204 2205          }
2205 2206  
2206 2207          if (symtab_bind == STB_GLOBAL) {
2207 2208                  return (dwarf_global);
2208 2209          }
2209 2210  
2210 2211          if (strcmp(symtab_file, dwarf_file) == 0) {
2211 2212                  return (B_TRUE);
2212 2213          }
2213 2214  
2214 2215          if (dwarf_global) {
2215 2216                  *is_fuzzy = B_TRUE;
2216 2217                  return (B_TRUE);
2217 2218          }
2218 2219  
2219 2220          return (B_FALSE);
2220 2221  }
2221 2222  
2222 2223  static ctf_dwfunc_t *
2223 2224  ctf_dwarf_match_func(ctf_cu_t *cup, const char *file, const char *name,
2224 2225      uint_t bind, boolean_t primary)
2225 2226  {
2226 2227          ctf_dwfunc_t *cdf, *fuzzy = NULL;
2227 2228  
2228 2229          if (bind == STB_WEAK)
2229 2230                  return (NULL);
2230 2231  
2231 2232          if (bind == STB_LOCAL && (file == NULL || cup->cu_name == NULL))
2232 2233                  return (NULL);
2233 2234  
2234 2235          for (cdf = ctf_list_next(&cup->cu_funcs); cdf != NULL;
2235 2236              cdf = ctf_list_next(cdf)) {
2236 2237                  boolean_t is_fuzzy = B_FALSE;
2237 2238  
2238 2239                  if (ctf_dwarf_symbol_match(file, name, bind, cup->cu_name,
2239 2240                      cdf->cdf_name, cdf->cdf_global, &is_fuzzy)) {
2240 2241                          if (is_fuzzy) {
2241 2242                                  if (primary) {
2242 2243                                          fuzzy = cdf;
2243 2244                                  }
2244 2245                                  continue;
2245 2246                          } else {
2246 2247                                  return (cdf);
2247 2248                          }
2248 2249                  }
2249 2250          }
2250 2251  
2251 2252          return (fuzzy);
2252 2253  }
2253 2254  
2254 2255  static ctf_dwvar_t *
2255 2256  ctf_dwarf_match_var(ctf_cu_t *cup, const char *file, const char *name,
2256 2257      uint_t bind, boolean_t primary)
2257 2258  {
2258 2259          ctf_dwvar_t *cdv, *fuzzy = NULL;
2259 2260  
2260 2261          if (bind == STB_WEAK)
2261 2262                  return (NULL);
2262 2263  
2263 2264          if (bind == STB_LOCAL && (file == NULL || cup->cu_name == NULL))
2264 2265                  return (NULL);
2265 2266  
2266 2267          for (cdv = ctf_list_next(&cup->cu_vars); cdv != NULL;
2267 2268              cdv = ctf_list_next(cdv)) {
2268 2269                  boolean_t is_fuzzy = B_FALSE;
2269 2270  
2270 2271                  if (ctf_dwarf_symbol_match(file, name, bind, cup->cu_name,
2271 2272                      cdv->cdv_name, cdv->cdv_global, &is_fuzzy)) {
2272 2273                          if (is_fuzzy) {
2273 2274                                  if (primary) {
2274 2275                                          fuzzy = cdv;
2275 2276                                  }
2276 2277                          } else {
2277 2278                                  return (cdv);
2278 2279                          }
2279 2280                  }
2280 2281          }
2281 2282  
2282 2283          return (fuzzy);
2283 2284  }
2284 2285  
2285 2286  static int
2286 2287  ctf_dwarf_conv_funcvars_cb(const Elf64_Sym *symp, ulong_t idx,
2287 2288      const char *file, const char *name, boolean_t primary, void *arg)
2288 2289  {
2289 2290          int ret;
2290 2291          uint_t bind, type;
2291 2292          ctf_cu_t *cup = arg;
2292 2293  
2293 2294          bind = GELF_ST_BIND(symp->st_info);
2294 2295          type = GELF_ST_TYPE(symp->st_info);
2295 2296  
2296 2297          /*
2297 2298           * Come back to weak symbols in another pass
2298 2299           */
2299 2300          if (bind == STB_WEAK)
2300 2301                  return (0);
2301 2302  
2302 2303          if (type == STT_OBJECT) {
2303 2304                  ctf_dwvar_t *cdv = ctf_dwarf_match_var(cup, file, name,
2304 2305                      bind, primary);
2305 2306                  if (cdv == NULL)
2306 2307                          return (0);
2307 2308                  ret = ctf_add_object(cup->cu_ctfp, idx, cdv->cdv_type);
2308 2309                  ctf_dprintf("added object %s->%ld\n", name, cdv->cdv_type);
2309 2310          } else {
2310 2311                  ctf_dwfunc_t *cdf = ctf_dwarf_match_func(cup, file, name,
2311 2312                      bind, primary);
2312 2313                  if (cdf == NULL)
2313 2314                          return (0);
2314 2315                  ret = ctf_add_function(cup->cu_ctfp, idx, &cdf->cdf_fip,
2315 2316                      cdf->cdf_argv);
2316 2317                  ctf_dprintf("added function %s\n", name);
2317 2318          }
2318 2319  
2319 2320          if (ret == CTF_ERR) {
2320 2321                  return (ctf_errno(cup->cu_ctfp));
2321 2322          }
2322 2323  
2323 2324          return (0);
2324 2325  }
2325 2326  
2326 2327  static int
2327 2328  ctf_dwarf_conv_funcvars(ctf_cu_t *cup)
2328 2329  {
2329 2330          return (ctf_symtab_iter(cup->cu_ctfp, ctf_dwarf_conv_funcvars_cb, cup));
2330 2331  }
2331 2332  
2332 2333  /*
2333 2334   * If we have a weak symbol, attempt to find the strong symbol it will resolve
2334 2335   * to.  Note: the code where this actually happens is in sym_process() in
2335 2336   * cmd/sgs/libld/common/syms.c
2336 2337   *
2337 2338   * Finding the matching symbol is unfortunately not trivial.  For a symbol to be
2338 2339   * a candidate, it must:
2339 2340   *
2340 2341   * - have the same type (function, object)
2341 2342   * - have the same value (address)
2342 2343   * - have the same size
2343 2344   * - not be another weak symbol
2344 2345   * - belong to the same section (checked via section index)
2345 2346   *
2346 2347   * To perform this check, we first iterate over the symbol table. For each weak
2347 2348   * symbol that we encounter, we then do a second walk over the symbol table,
2348 2349   * calling ctf_dwarf_conv_check_weak(). If a symbol matches the above, then it's
2349 2350   * either a local or global symbol. If we find a global symbol then we go with
2350 2351   * it and stop searching for additional matches.
2351 2352   *
2352 2353   * If instead, we find a local symbol, things are more complicated. The first
2353 2354   * thing we do is to try and see if we have file information about both symbols
2354 2355   * (STT_FILE). If they both have file information and it matches, then we treat
2355 2356   * that as a good match and stop searching for additional matches.
2356 2357   *
2357 2358   * Otherwise, this means we have a non-matching file and a local symbol. We
2358 2359   * treat this as a candidate and if we find a better match (one of the two cases
2359 2360   * above), use that instead. There are two different ways this can happen.
2360 2361   * Either this is a completely different symbol, or it's a once-global symbol
2361 2362   * that was scoped to local via a mapfile.  In the former case, curfile is
2362 2363   * likely inaccurate since the linker does not preserve the needed curfile in
2363 2364   * the order of the symbol table (see the comments about locally scoped symbols
2364 2365   * in libld's update_osym()).  As we can't tell this case from the former one,
2365 2366   * we use this symbol iff no other matching symbol is found.
2366 2367   *
2367 2368   * What we really need here is a SUNW section containing weak<->strong mappings
2368 2369   * that we can consume.
2369 2370   */
2370 2371  typedef struct ctf_dwarf_weak_arg {
2371 2372          const Elf64_Sym *cweak_symp;
2372 2373          const char *cweak_file;
2373 2374          boolean_t cweak_candidate;
2374 2375          ulong_t cweak_idx;
2375 2376  } ctf_dwarf_weak_arg_t;
2376 2377  
2377 2378  static int
2378 2379  ctf_dwarf_conv_check_weak(const Elf64_Sym *symp, ulong_t idx, const char *file,
2379 2380      const char *name, boolean_t primary, void *arg)
2380 2381  {
2381 2382          ctf_dwarf_weak_arg_t *cweak = arg;
2382 2383  
2383 2384          const Elf64_Sym *wsymp = cweak->cweak_symp;
2384 2385  
2385 2386          ctf_dprintf("comparing weak to %s\n", name);
2386 2387  
2387 2388          if (GELF_ST_BIND(symp->st_info) == STB_WEAK) {
2388 2389                  return (0);
2389 2390          }
2390 2391  
2391 2392          if (GELF_ST_TYPE(wsymp->st_info) != GELF_ST_TYPE(symp->st_info)) {
2392 2393                  return (0);
2393 2394          }
2394 2395  
2395 2396          if (wsymp->st_value != symp->st_value) {
2396 2397                  return (0);
2397 2398          }
2398 2399  
2399 2400          if (wsymp->st_size != symp->st_size) {
2400 2401                  return (0);
2401 2402          }
2402 2403  
2403 2404          if (wsymp->st_shndx != symp->st_shndx) {
2404 2405                  return (0);
2405 2406          }
2406 2407  
2407 2408          /*
2408 2409           * Check if it's a weak candidate.
2409 2410           */
2410 2411          if (GELF_ST_BIND(symp->st_info) == STB_LOCAL &&
2411 2412              (file == NULL || cweak->cweak_file == NULL ||
2412 2413              strcmp(file, cweak->cweak_file) != 0)) {
2413 2414                  cweak->cweak_candidate = B_TRUE;
2414 2415                  cweak->cweak_idx = idx;
2415 2416                  return (0);
2416 2417          }
2417 2418  
2418 2419          /*
2419 2420           * Found a match, break.
2420 2421           */
2421 2422          cweak->cweak_idx = idx;
2422 2423          return (1);
2423 2424  }
2424 2425  
2425 2426  static int
2426 2427  ctf_dwarf_duplicate_sym(ctf_cu_t *cup, ulong_t idx, ulong_t matchidx)
2427 2428  {
2428 2429          ctf_id_t id = ctf_lookup_by_symbol(cup->cu_ctfp, matchidx);
2429 2430  
2430 2431          /*
2431 2432           * If we matched something that for some reason didn't have type data,
2432 2433           * we don't consider that a fatal error and silently swallow it.
2433 2434           */
2434 2435          if (id == CTF_ERR) {
2435 2436                  if (ctf_errno(cup->cu_ctfp) == ECTF_NOTYPEDAT)
2436 2437                          return (0);
2437 2438                  else
2438 2439                          return (ctf_errno(cup->cu_ctfp));
2439 2440          }
2440 2441  
2441 2442          if (ctf_add_object(cup->cu_ctfp, idx, id) == CTF_ERR)
2442 2443                  return (ctf_errno(cup->cu_ctfp));
2443 2444  
2444 2445          return (0);
2445 2446  }
2446 2447  
2447 2448  static int
2448 2449  ctf_dwarf_duplicate_func(ctf_cu_t *cup, ulong_t idx, ulong_t matchidx)
2449 2450  {
2450 2451          int ret;
2451 2452          ctf_funcinfo_t fip;
2452 2453          ctf_id_t *args = NULL;
2453 2454  
2454 2455          if (ctf_func_info(cup->cu_ctfp, matchidx, &fip) == CTF_ERR) {
2455 2456                  if (ctf_errno(cup->cu_ctfp) == ECTF_NOFUNCDAT)
2456 2457                          return (0);
2457 2458                  else
2458 2459                          return (ctf_errno(cup->cu_ctfp));
2459 2460          }
2460 2461  
2461 2462          if (fip.ctc_argc != 0) {
2462 2463                  args = ctf_alloc(sizeof (ctf_id_t) * fip.ctc_argc);
2463 2464                  if (args == NULL)
2464 2465                          return (ENOMEM);
2465 2466  
2466 2467                  if (ctf_func_args(cup->cu_ctfp, matchidx, fip.ctc_argc, args) ==
2467 2468                      CTF_ERR) {
2468 2469                          ctf_free(args, sizeof (ctf_id_t) * fip.ctc_argc);
2469 2470                          return (ctf_errno(cup->cu_ctfp));
2470 2471                  }
2471 2472          }
2472 2473  
2473 2474          ret = ctf_add_function(cup->cu_ctfp, idx, &fip, args);
2474 2475          if (args != NULL)
2475 2476                  ctf_free(args, sizeof (ctf_id_t) * fip.ctc_argc);
2476 2477          if (ret == CTF_ERR)
2477 2478                  return (ctf_errno(cup->cu_ctfp));
2478 2479  
2479 2480          return (0);
2480 2481  }
2481 2482  
2482 2483  static int
2483 2484  ctf_dwarf_conv_weaks_cb(const Elf64_Sym *symp, ulong_t idx, const char *file,
2484 2485      const char *name, boolean_t primary, void *arg)
2485 2486  {
2486 2487          int ret, type;
2487 2488          ctf_dwarf_weak_arg_t cweak;
2488 2489          ctf_cu_t *cup = arg;
2489 2490  
2490 2491          /*
2491 2492           * We only care about weak symbols.
2492 2493           */
2493 2494          if (GELF_ST_BIND(symp->st_info) != STB_WEAK)
2494 2495                  return (0);
2495 2496  
2496 2497          type = GELF_ST_TYPE(symp->st_info);
2497 2498          ASSERT(type == STT_OBJECT || type == STT_FUNC);
2498 2499  
2499 2500          /*
2500 2501           * For each weak symbol we encounter, we need to do a second iteration
2501 2502           * to try and find a match. We should probably think about other
2502 2503           * techniques to try and save us time in the future.
2503 2504           */
2504 2505          cweak.cweak_symp = symp;
2505 2506          cweak.cweak_file = file;
2506 2507          cweak.cweak_candidate = B_FALSE;
2507 2508          cweak.cweak_idx = 0;
2508 2509  
2509 2510          ctf_dprintf("Trying to find weak equiv for %s\n", name);
2510 2511  
2511 2512          ret = ctf_symtab_iter(cup->cu_ctfp, ctf_dwarf_conv_check_weak, &cweak);
2512 2513          VERIFY(ret == 0 || ret == 1);
2513 2514  
2514 2515          /*
2515 2516           * Nothing was ever found, we're not going to add anything for this
2516 2517           * entry.
2517 2518           */
2518 2519          if (ret == 0 && cweak.cweak_candidate == B_FALSE) {
2519 2520                  ctf_dprintf("found no weak match for %s\n", name);
2520 2521                  return (0);
2521 2522          }
2522 2523  
2523 2524          /*
2524 2525           * Now, finally go and add the type based on the match.
2525 2526           */
2526 2527          ctf_dprintf("matched weak symbol %lu to %lu\n", idx, cweak.cweak_idx);
2527 2528          if (type == STT_OBJECT) {
2528 2529                  ret = ctf_dwarf_duplicate_sym(cup, idx, cweak.cweak_idx);
2529 2530          } else {
2530 2531                  ret = ctf_dwarf_duplicate_func(cup, idx, cweak.cweak_idx);
2531 2532          }
2532 2533  
2533 2534          return (ret);
2534 2535  }
2535 2536  
2536 2537  static int
2537 2538  ctf_dwarf_conv_weaks(ctf_cu_t *cup)
2538 2539  {
2539 2540          return (ctf_symtab_iter(cup->cu_ctfp, ctf_dwarf_conv_weaks_cb, cup));
2540 2541  }
2541 2542  
2542 2543  /* ARGSUSED */
2543 2544  static int
2544 2545  ctf_dwarf_convert_one(void *arg, void *unused)
2545 2546  {
2546 2547          int ret;
2547 2548          ctf_file_t *dedup;
2548 2549          ctf_cu_t *cup = arg;
2549 2550  
2550 2551          ctf_dprintf("converting die: %s\n", cup->cu_name);
2551 2552          ctf_dprintf("max offset: %x\n", cup->cu_maxoff);
2552 2553          VERIFY(cup != NULL);
2553 2554  
2554 2555          ret = ctf_dwarf_convert_die(cup, cup->cu_cu);
2555 2556          ctf_dprintf("ctf_dwarf_convert_die (%s) returned %d\n", cup->cu_name,
2556 2557              ret);
2557 2558          if (ret != 0) {
2558 2559                  return (ret);
2559 2560          }
2560 2561          if (ctf_update(cup->cu_ctfp) != 0) {
2561 2562                  return (ctf_dwarf_error(cup, cup->cu_ctfp, 0,
2562 2563                      "failed to update output ctf container"));
2563 2564          }
2564 2565  
2565 2566          ret = ctf_dwarf_fixup_die(cup, B_FALSE);
2566 2567          ctf_dprintf("ctf_dwarf_fixup_die (%s) returned %d\n", cup->cu_name,
2567 2568              ret);
2568 2569          if (ret != 0) {
2569 2570                  return (ret);
2570 2571          }
2571 2572          if (ctf_update(cup->cu_ctfp) != 0) {
2572 2573                  return (ctf_dwarf_error(cup, cup->cu_ctfp, 0,
2573 2574                      "failed to update output ctf container"));
2574 2575          }
2575 2576  
2576 2577          ret = ctf_dwarf_fixup_die(cup, B_TRUE);
2577 2578          ctf_dprintf("ctf_dwarf_fixup_die (%s) returned %d\n", cup->cu_name,
2578 2579              ret);
2579 2580          if (ret != 0) {
2580 2581                  return (ret);
2581 2582          }
2582 2583          if (ctf_update(cup->cu_ctfp) != 0) {
2583 2584                  return (ctf_dwarf_error(cup, cup->cu_ctfp, 0,
2584 2585                      "failed to update output ctf container"));
2585 2586          }
2586 2587  
2587 2588  
2588 2589          if ((ret = ctf_dwarf_conv_funcvars(cup)) != 0) {
2589 2590                  return (ctf_dwarf_error(cup, NULL, ret,
2590 2591                      "failed to convert strong functions and variables"));
2591 2592          }
2592 2593  
2593 2594          if (ctf_update(cup->cu_ctfp) != 0) {
2594 2595                  return (ctf_dwarf_error(cup, cup->cu_ctfp, 0,
2595 2596                      "failed to update output ctf container"));
2596 2597          }
2597 2598  
2598 2599          if (cup->cu_doweaks == B_TRUE) {
2599 2600                  if ((ret = ctf_dwarf_conv_weaks(cup)) != 0) {
2600 2601                          return (ctf_dwarf_error(cup, NULL, ret,
2601 2602                              "failed to convert weak functions and variables"));
2602 2603                  }
2603 2604  
2604 2605                  if (ctf_update(cup->cu_ctfp) != 0) {
2605 2606                          return (ctf_dwarf_error(cup, cup->cu_ctfp, 0,
2606 2607                              "failed to update output ctf container"));
2607 2608                  }
2608 2609          }
2609 2610  
2610 2611          ctf_phase_dump(cup->cu_ctfp, "pre-dwarf-dedup", cup->cu_name);
2611 2612          ctf_dprintf("adding inputs for dedup\n");
2612 2613          if ((ret = ctf_merge_add(cup->cu_cmh, cup->cu_ctfp)) != 0) {
2613 2614                  return (ctf_dwarf_error(cup, NULL, ret,
2614 2615                      "failed to add inputs for merge"));
2615 2616          }
2616 2617  
2617 2618          ctf_dprintf("starting dedup of %s\n", cup->cu_name);
2618 2619          if ((ret = ctf_merge_dedup(cup->cu_cmh, &dedup)) != 0) {
2619 2620                  return (ctf_dwarf_error(cup, NULL, ret,
2620 2621                      "failed to deduplicate die"));
2621 2622          }
2622 2623          ctf_close(cup->cu_ctfp);
2623 2624          cup->cu_ctfp = dedup;
2624 2625          ctf_phase_dump(cup->cu_ctfp, "post-dwarf-dedup", cup->cu_name);
2625 2626  
2626 2627          return (0);
2627 2628  }
2628 2629  
2629 2630  /*
2630 2631   * Note, we expect that if we're returning a ctf_file_t from one of the dies,
2631 2632   * say in the single node case, it's been saved and the entry here has been set
2632 2633   * to NULL, which ctf_close happily ignores.
2633 2634   */
2634 2635  static void
2635 2636  ctf_dwarf_free_die(ctf_cu_t *cup)
2636 2637  {
2637 2638          ctf_dwfunc_t *cdf, *ndf;
2638 2639          ctf_dwvar_t *cdv, *ndv;
2639 2640          ctf_dwbitf_t *cdb, *ndb;
2640 2641          ctf_dwmap_t *map;
2641 2642          void *cookie;
2642 2643          Dwarf_Error derr;
2643 2644  
2644 2645          ctf_dprintf("Beginning to free die: %p\n", cup);
2645 2646          cup->cu_elf = NULL;
2646 2647          ctf_dprintf("Trying to free name: %p\n", cup->cu_name);
2647 2648          if (cup->cu_name != NULL)
2648 2649                  ctf_free(cup->cu_name, strlen(cup->cu_name) + 1);
2649 2650          ctf_dprintf("Trying to free merge handle: %p\n", cup->cu_cmh);
2650 2651          if (cup->cu_cmh != NULL) {
2651 2652                  ctf_merge_fini(cup->cu_cmh);
2652 2653                  cup->cu_cmh = NULL;
2653 2654          }
2654 2655  
2655 2656          ctf_dprintf("Trying to free functions\n");
2656 2657          for (cdf = ctf_list_next(&cup->cu_funcs); cdf != NULL; cdf = ndf) {
2657 2658                  ndf = ctf_list_next(cdf);
2658 2659                  ctf_free(cdf->cdf_name, strlen(cdf->cdf_name) + 1);
2659 2660                  if (cdf->cdf_fip.ctc_argc != 0) {
2660 2661                          ctf_free(cdf->cdf_argv,
2661 2662                              sizeof (ctf_id_t) * cdf->cdf_fip.ctc_argc);
2662 2663                  }
2663 2664                  ctf_free(cdf, sizeof (ctf_dwfunc_t));
2664 2665          }
2665 2666  
2666 2667          ctf_dprintf("Trying to free variables\n");
2667 2668          for (cdv = ctf_list_next(&cup->cu_vars); cdv != NULL; cdv = ndv) {
2668 2669                  ndv = ctf_list_next(cdv);
2669 2670                  ctf_free(cdv->cdv_name, strlen(cdv->cdv_name) + 1);
  
    | 
      ↓ open down ↓ | 
    879 lines elided | 
    
      ↑ open up ↑ | 
  
2670 2671                  ctf_free(cdv, sizeof (ctf_dwvar_t));
2671 2672          }
2672 2673  
2673 2674          ctf_dprintf("Trying to free bitfields\n");
2674 2675          for (cdb = ctf_list_next(&cup->cu_bitfields); cdb != NULL; cdb = ndb) {
2675 2676                  ndb = ctf_list_next(cdb);
2676 2677                  ctf_free(cdb, sizeof (ctf_dwbitf_t));
2677 2678          }
2678 2679  
2679 2680          ctf_dprintf("Trying to clean up dwarf_t: %p\n", cup->cu_dwarf);
2680      -        (void) dwarf_finish(cup->cu_dwarf, &derr);
     2681 +        if (cup->cu_dwarf != NULL)
     2682 +                (void) dwarf_finish(cup->cu_dwarf, &derr);
2681 2683          cup->cu_dwarf = NULL;
2682 2684          ctf_close(cup->cu_ctfp);
2683 2685  
2684 2686          cookie = NULL;
2685 2687          while ((map = avl_destroy_nodes(&cup->cu_map, &cookie)) != NULL) {
2686 2688                  ctf_free(map, sizeof (ctf_dwmap_t));
2687 2689          }
2688 2690          avl_destroy(&cup->cu_map);
2689 2691          cup->cu_errbuf = NULL;
2690 2692  }
2691 2693  
2692 2694  static void
2693 2695  ctf_dwarf_free_dies(ctf_cu_t *cdies, int ndies)
2694 2696  {
2695 2697          int i;
2696 2698  
2697 2699          ctf_dprintf("Beginning to free dies\n");
2698 2700          for (i = 0; i < ndies; i++) {
2699 2701                  ctf_dwarf_free_die(&cdies[i]);
2700 2702          }
2701 2703  
2702 2704          ctf_free(cdies, sizeof (ctf_cu_t) * ndies);
2703 2705  }
2704 2706  
2705 2707  static int
2706 2708  ctf_dwarf_count_dies(Dwarf_Debug dw, Dwarf_Error *derr, int *ndies,
2707 2709      char *errbuf, size_t errlen)
2708 2710  {
2709 2711          int ret;
2710 2712          Dwarf_Half vers;
2711 2713          Dwarf_Unsigned nexthdr;
2712 2714  
2713 2715          while ((ret = dwarf_next_cu_header(dw, NULL, &vers, NULL, NULL,
2714 2716              &nexthdr, derr)) != DW_DLV_NO_ENTRY) {
2715 2717                  if (ret != DW_DLV_OK) {
2716 2718                          (void) snprintf(errbuf, errlen,
2717 2719                              "file does not contain valid DWARF data: %s\n",
2718 2720                              dwarf_errmsg(*derr));
2719 2721                          return (ECTF_CONVBKERR);
  
    | 
      ↓ open down ↓ | 
    29 lines elided | 
    
      ↑ open up ↑ | 
  
2720 2722                  }
2721 2723  
2722 2724                  if (vers != DWARF_VERSION_TWO) {
2723 2725                          (void) snprintf(errbuf, errlen,
2724 2726                              "unsupported DWARF version: %d\n", vers);
2725 2727                          return (ECTF_CONVBKERR);
2726 2728                  }
2727 2729                  *ndies = *ndies + 1;
2728 2730          }
2729 2731  
2730      -        if (*ndies == 0) {
2731      -                (void) snprintf(errbuf, errlen,
2732      -                    "file does not contain valid DWARF data: %s\n",
2733      -                    dwarf_errmsg(*derr));
2734      -                return (ECTF_CONVBKERR);
2735      -        }
2736      -
2737 2732          return (0);
2738 2733  }
2739 2734  
2740 2735  static int
2741 2736  ctf_dwarf_init_die(int fd, Elf *elf, ctf_cu_t *cup, int ndie, char *errbuf,
2742 2737      size_t errlen)
2743 2738  {
2744 2739          int ret;
2745 2740          Dwarf_Unsigned hdrlen, abboff, nexthdr;
2746 2741          Dwarf_Half addrsz;
2747 2742          Dwarf_Unsigned offset = 0;
2748 2743          Dwarf_Error derr;
2749 2744  
2750 2745          while ((ret = dwarf_next_cu_header(cup->cu_dwarf, &hdrlen, NULL,
2751 2746              &abboff, &addrsz, &nexthdr, &derr)) != DW_DLV_NO_ENTRY) {
2752 2747                  char *name;
2753 2748                  Dwarf_Die cu, child;
2754 2749  
2755 2750                  /* Based on the counting above, we should be good to go */
2756 2751                  VERIFY(ret == DW_DLV_OK);
2757 2752                  if (ndie > 0) {
2758 2753                          ndie--;
2759 2754                          offset = nexthdr;
2760 2755                          continue;
2761 2756                  }
  
    | 
      ↓ open down ↓ | 
    15 lines elided | 
    
      ↑ open up ↑ | 
  
2762 2757  
2763 2758                  /*
2764 2759                   * Compilers are apparently inconsistent. Some emit no DWARF for
2765 2760                   * empty files and others emit empty compilation unit.
2766 2761                   */
2767 2762                  cup->cu_voidtid = CTF_ERR;
2768 2763                  cup->cu_longtid = CTF_ERR;
2769 2764                  cup->cu_elf = elf;
2770 2765                  cup->cu_maxoff = nexthdr - 1;
2771 2766                  cup->cu_ctfp = ctf_fdcreate(fd, &ret);
2772      -                if (cup->cu_ctfp == NULL) {
2773      -                        ctf_free(cup, sizeof (ctf_cu_t));
     2767 +                if (cup->cu_ctfp == NULL)
2774 2768                          return (ret);
2775      -                }
     2769 +
2776 2770                  avl_create(&cup->cu_map, ctf_dwmap_comp, sizeof (ctf_dwmap_t),
2777 2771                      offsetof(ctf_dwmap_t, cdm_avl));
2778 2772                  cup->cu_errbuf = errbuf;
2779 2773                  cup->cu_errlen = errlen;
2780 2774                  bzero(&cup->cu_vars, sizeof (ctf_list_t));
2781 2775                  bzero(&cup->cu_funcs, sizeof (ctf_list_t));
2782 2776                  bzero(&cup->cu_bitfields, sizeof (ctf_list_t));
2783 2777  
2784 2778                  if ((ret = ctf_dwarf_die_elfenc(elf, cup, errbuf,
2785      -                    errlen)) != 0) {
2786      -                        avl_destroy(&cup->cu_map);
2787      -                        ctf_free(cup, sizeof (ctf_cu_t));
     2779 +                    errlen)) != 0)
2788 2780                          return (ret);
2789      -                }
2790 2781  
2791      -                if ((ret = ctf_dwarf_sib(cup, NULL, &cu)) != 0) {
2792      -                        avl_destroy(&cup->cu_map);
2793      -                        ctf_free(cup, sizeof (ctf_cu_t));
     2782 +                if ((ret = ctf_dwarf_sib(cup, NULL, &cu)) != 0)
2794 2783                          return (ret);
2795      -                }
     2784 +
2796 2785                  if (cu == NULL) {
2797 2786                          (void) snprintf(errbuf, errlen,
2798      -                            "file does not contain DWARF data\n");
2799      -                        avl_destroy(&cup->cu_map);
2800      -                        ctf_free(cup, sizeof (ctf_cu_t));
2801      -                        return (ECTF_CONVBKERR);
     2787 +                            "file does not contain DWARF data");
     2788 +                        return (ECTF_CONVNODEBUG);
2802 2789                  }
2803 2790  
2804      -                if ((ret = ctf_dwarf_child(cup, cu, &child)) != 0) {
2805      -                        avl_destroy(&cup->cu_map);
2806      -                        ctf_free(cup, sizeof (ctf_cu_t));
     2791 +                if ((ret = ctf_dwarf_child(cup, cu, &child)) != 0)
2807 2792                          return (ret);
2808      -                }
     2793 +
2809 2794                  if (child == NULL) {
2810 2795                          (void) snprintf(errbuf, errlen,
2811      -                            "file does not contain DWARF data\n");
2812      -                        avl_destroy(&cup->cu_map);
2813      -                        ctf_free(cup, sizeof (ctf_cu_t));
2814      -                        return (ECTF_CONVBKERR);
     2796 +                            "file does not contain DWARF data");
     2797 +                        return (ECTF_CONVNODEBUG);
2815 2798                  }
2816 2799  
2817 2800                  cup->cu_cuoff = offset;
2818 2801                  cup->cu_cu = child;
2819 2802  
2820      -                if ((cup->cu_cmh = ctf_merge_init(fd, &ret)) == NULL) {
2821      -                        avl_destroy(&cup->cu_map);
2822      -                        ctf_free(cup, sizeof (ctf_cu_t));
     2803 +                if ((cup->cu_cmh = ctf_merge_init(fd, &ret)) == NULL)
2823 2804                          return (ret);
2824      -                }
2825 2805  
2826 2806                  if (ctf_dwarf_string(cup, cu, DW_AT_name, &name) == 0) {
2827 2807                          size_t len = strlen(name) + 1;
2828 2808                          char *b = basename(name);
2829 2809                          cup->cu_name = strdup(b);
2830 2810                          ctf_free(name, len);
2831 2811                  }
2832 2812                  break;
2833 2813          }
2834 2814  
2835 2815          return (0);
2836 2816  }
2837 2817  
     2818 +/*
     2819 + * This is our only recourse to identify a C source file that is missing debug
     2820 + * info: it will be mentioned as an STT_FILE, but not have a compile unit entry.
     2821 + * (A traditional ctfmerge works on individual files, so can identify missing
     2822 + * DWARF more directly, via ctf_has_c_source() on the .o file.)
     2823 + *
     2824 + * As we operate on basenames, this can of course miss some cases, but it's
     2825 + * better than not checking at all.
     2826 + *
     2827 + * We explicitly whitelist some CRT components.  Failing that, there's always
     2828 + * the -m option.
     2829 + */
     2830 +static boolean_t
     2831 +c_source_has_debug(const char *file, ctf_cu_t *cus, size_t nr_cus)
     2832 +{
     2833 +        const char *basename = strrchr(file, '/');
2838 2834  
2839      -ctf_conv_status_t
2840      -ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, int *errp, ctf_file_t **fpp,
     2835 +        if (basename == NULL)
     2836 +                basename = file;
     2837 +        else
     2838 +                basename++;
     2839 +
     2840 +        if (strcmp(basename, "common-crt.c") == 0 ||
     2841 +            strcmp(basename, "gmon.c") == 0 ||
     2842 +            strcmp(basename, "dlink_init.c") == 0 ||
     2843 +            strcmp(basename, "dlink_common.c") == 0 ||
     2844 +            strncmp(basename, "crt", strlen("crt")) == 0 ||
     2845 +            strncmp(basename, "values-", strlen("values-")) == 0)
     2846 +                return (B_TRUE);
     2847 +
     2848 +        for (size_t i = 0; i < nr_cus; i++) {
     2849 +                if (strcmp(basename, cus[i].cu_name) == 0)
     2850 +                        return (B_TRUE);
     2851 +        }
     2852 +
     2853 +        return (B_FALSE);
     2854 +}
     2855 +
     2856 +static int
     2857 +ctf_dwarf_check_missing(ctf_cu_t *cus, size_t nr_cus, Elf *elf,
2841 2858      char *errmsg, size_t errlen)
2842 2859  {
     2860 +        Elf_Scn *scn, *strscn;
     2861 +        Elf_Data *data, *strdata;
     2862 +        GElf_Shdr shdr;
     2863 +        ulong_t i;
     2864 +
     2865 +        scn = NULL;
     2866 +        while ((scn = elf_nextscn(elf, scn)) != NULL) {
     2867 +                if (gelf_getshdr(scn, &shdr) == NULL) {
     2868 +                        (void) snprintf(errmsg, errlen,
     2869 +                            "failed to get section header: %s\n",
     2870 +                            elf_errmsg(elf_errno()));
     2871 +                        return (EINVAL);
     2872 +                }
     2873 +
     2874 +                if (shdr.sh_type == SHT_SYMTAB)
     2875 +                        break;
     2876 +        }
     2877 +
     2878 +        if (scn == NULL)
     2879 +                return (0);
     2880 +
     2881 +        if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL) {
     2882 +                (void) snprintf(errmsg, errlen,
     2883 +                    "failed to get str section: %s\n",
     2884 +                    elf_errmsg(elf_errno()));
     2885 +                return (EINVAL);
     2886 +        }
     2887 +
     2888 +        if ((data = elf_getdata(scn, NULL)) == NULL) {
     2889 +                (void) snprintf(errmsg, errlen, "failed to read section: %s\n",
     2890 +                    elf_errmsg(elf_errno()));
     2891 +                return (EINVAL);
     2892 +        }
     2893 +
     2894 +        if ((strdata = elf_getdata(strscn, NULL)) == NULL) {
     2895 +                (void) snprintf(errmsg, errlen,
     2896 +                    "failed to read string table: %s\n",
     2897 +                    elf_errmsg(elf_errno()));
     2898 +                return (EINVAL);
     2899 +        }
     2900 +
     2901 +        for (i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
     2902 +                GElf_Sym sym;
     2903 +                const char *file;
     2904 +                size_t len;
     2905 +
     2906 +                if (gelf_getsym(data, i, &sym) == NULL) {
     2907 +                        (void) snprintf(errmsg, errlen,
     2908 +                            "failed to read sym %lu: %s\n",
     2909 +                            i, elf_errmsg(elf_errno()));
     2910 +                        return (EINVAL);
     2911 +                }
     2912 +
     2913 +                if (GELF_ST_TYPE(sym.st_info) != STT_FILE)
     2914 +                        continue;
     2915 +
     2916 +                file = (const char *)((uintptr_t)strdata->d_buf + sym.st_name);
     2917 +                len = strlen(file);
     2918 +                if (len < 2 || strncmp(".c", &file[len - 2], 2) != 0)
     2919 +                        continue;
     2920 +
     2921 +                if (!c_source_has_debug(file, cus, nr_cus)) {
     2922 +                        (void) snprintf(errmsg, errlen,
     2923 +                            "file %s is missing debug info\n", file);
     2924 +                        return (ECTF_CONVNODEBUG);
     2925 +                }
     2926 +        }
     2927 +
     2928 +        return (0);
     2929 +}
     2930 +
     2931 +int
     2932 +ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, uint_t flags,
     2933 +    ctf_file_t **fpp, char *errbuf, size_t errlen)
     2934 +{
2843 2935          int err, ret, ndies, i;
2844 2936          Dwarf_Debug dw;
2845 2937          Dwarf_Error derr;
2846 2938          ctf_cu_t *cdies = NULL, *cup;
2847 2939          workq_t *wqp = NULL;
2848 2940  
2849      -        if (errp == NULL)
2850      -                errp = &err;
2851      -        *errp = 0;
2852 2941          *fpp = NULL;
2853 2942  
2854 2943          ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dw, &derr);
2855 2944          if (ret != DW_DLV_OK) {
2856      -                /*
2857      -                 * We may want to expect DWARF data here and fail conversion if
2858      -                 * it's missing. In this case, if we actually have some amount
2859      -                 * of DWARF, but no section, for now, just go ahead and create
2860      -                 * an empty CTF file.
2861      -                 */
2862 2945                  if (ret == DW_DLV_NO_ENTRY ||
2863 2946                      dwarf_errno(derr) == DW_DLE_DEBUG_INFO_NULL) {
2864      -                        *fpp = ctf_create(errp);
2865      -                        return (*fpp != NULL ? CTF_CONV_SUCCESS :
2866      -                            CTF_CONV_ERROR);
     2947 +                        (void) snprintf(errbuf, errlen,
     2948 +                            "file does not contain DWARF data\n");
     2949 +                        return (ECTF_CONVNODEBUG);
2867 2950                  }
2868      -                (void) snprintf(errmsg, errlen,
2869      -                    "failed to initialize DWARF: %s\n",
2870      -                    dwarf_errmsg(derr));
2871      -                *errp = ECTF_CONVBKERR;
2872      -                return (CTF_CONV_ERROR);
     2951 +
     2952 +                (void) snprintf(errbuf, errlen,
     2953 +                    "dwarf_elf_init() failed: %s\n", dwarf_errmsg(derr));
     2954 +                return (ECTF_CONVBKERR);
2873 2955          }
2874 2956  
2875 2957          /*
2876 2958           * Iterate over all of the compilation units and create a ctf_cu_t for
2877 2959           * each of them.  This is used to determine if we have zero, one, or
2878 2960           * multiple dies to convert. If we have zero, that's an error. If
2879 2961           * there's only one die, that's the simple case.  No merge needed and
2880 2962           * only a single Dwarf_Debug as well.
2881 2963           */
2882 2964          ndies = 0;
2883      -        ret = ctf_dwarf_count_dies(dw, &derr, &ndies, errmsg, errlen);
2884      -        if (ret != 0) {
2885      -                *errp = ret;
2886      -                goto out;
     2965 +        err = ctf_dwarf_count_dies(dw, &derr, &ndies, errbuf, errlen);
     2966 +
     2967 +        ctf_dprintf("found %d DWARF CUs\n", ndies);
     2968 +
     2969 +        if (ndies == 0) {
     2970 +                (void) snprintf(errbuf, errlen,
     2971 +                    "file does not contain DWARF data\n");
     2972 +                return (ECTF_CONVNODEBUG);
2887 2973          }
2888 2974  
2889 2975          (void) dwarf_finish(dw, &derr);
2890 2976          cdies = ctf_alloc(sizeof (ctf_cu_t) * ndies);
2891 2977          if (cdies == NULL) {
2892      -                *errp = ENOMEM;
2893      -                return (CTF_CONV_ERROR);
     2978 +                return (ENOMEM);
2894 2979          }
2895 2980  
     2981 +        bzero(cdies, sizeof (ctf_cu_t) * ndies);
     2982 +
2896 2983          for (i = 0; i < ndies; i++) {
2897 2984                  cup = &cdies[i];
2898 2985                  ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL,
2899 2986                      &cup->cu_dwarf, &derr);
2900 2987                  if (ret != 0) {
2901 2988                          ctf_free(cdies, sizeof (ctf_cu_t) * ndies);
2902      -                        (void) snprintf(errmsg, errlen,
     2989 +                        (void) snprintf(errbuf, errlen,
2903 2990                              "failed to initialize DWARF: %s\n",
2904 2991                              dwarf_errmsg(derr));
2905      -                        *errp = ECTF_CONVBKERR;
2906      -                        return (CTF_CONV_ERROR);
     2992 +                        return (ECTF_CONVBKERR);
2907 2993                  }
2908 2994  
2909      -                ret = ctf_dwarf_init_die(fd, elf, &cdies[i], i, errmsg, errlen);
2910      -                if (ret != 0) {
2911      -                        *errp = ret;
     2995 +                err = ctf_dwarf_init_die(fd, elf, cup, i, errbuf, errlen);
     2996 +                if (err != 0)
2912 2997                          goto out;
2913      -                }
2914 2998  
2915 2999                  cup->cu_doweaks = ndies > 1 ? B_FALSE : B_TRUE;
2916 3000          }
2917 3001  
2918      -        ctf_dprintf("found %d DWARF CUs\n", ndies);
     3002 +        if (!(flags & CTF_ALLOW_MISSING_DEBUG) &&
     3003 +            (err = ctf_dwarf_check_missing(cdies, ndies,
     3004 +            elf, errbuf, errlen)) != 0)
     3005 +                goto out;
2919 3006  
2920 3007          /*
2921 3008           * If we only have one compilation unit, there's no reason to use
2922 3009           * multiple threads, even if the user requested them. After all, they
2923 3010           * just gave us an upper bound.
2924 3011           */
2925 3012          if (ndies == 1)
2926 3013                  nthrs = 1;
2927 3014  
2928 3015          if (workq_init(&wqp, nthrs) == -1) {
2929      -                *errp = errno;
     3016 +                err = errno;
2930 3017                  goto out;
2931 3018          }
2932 3019  
2933 3020          for (i = 0; i < ndies; i++) {
2934 3021                  cup = &cdies[i];
2935 3022                  ctf_dprintf("adding cu %s: %p, %x %x\n", cup->cu_name,
2936 3023                      cup->cu_cu, cup->cu_cuoff, cup->cu_maxoff);
2937 3024                  if (workq_add(wqp, cup) == -1) {
2938      -                        *errp = errno;
     3025 +                        err = errno;
2939 3026                          goto out;
2940 3027                  }
2941 3028          }
2942 3029  
2943      -        ret = workq_work(wqp, ctf_dwarf_convert_one, NULL, errp);
     3030 +        ret = workq_work(wqp, ctf_dwarf_convert_one, NULL, &err);
2944 3031          if (ret == WORKQ_ERROR) {
2945      -                *errp = errno;
     3032 +                err = errno;
2946 3033                  goto out;
2947 3034          } else if (ret == WORKQ_UERROR) {
2948 3035                  ctf_dprintf("internal convert failed: %s\n",
2949      -                    ctf_errmsg(*errp));
     3036 +                    ctf_errmsg(err));
2950 3037                  goto out;
2951 3038          }
2952 3039  
2953 3040          ctf_dprintf("Determining next phase: have %d CUs\n", ndies);
2954 3041          if (ndies != 1) {
2955 3042                  ctf_merge_t *cmp;
2956 3043  
2957      -                cmp = ctf_merge_init(fd, &ret);
2958      -                if (cmp == NULL) {
2959      -                        *errp = ret;
     3044 +                cmp = ctf_merge_init(fd, &err);
     3045 +                if (cmp == NULL)
2960 3046                          goto out;
2961      -                }
2962 3047  
2963 3048                  ctf_dprintf("setting threads\n");
2964      -                if ((ret = ctf_merge_set_nthreads(cmp, nthrs)) != 0) {
     3049 +                if ((err = ctf_merge_set_nthreads(cmp, nthrs)) != 0) {
2965 3050                          ctf_merge_fini(cmp);
2966      -                        *errp = ret;
2967 3051                          goto out;
2968 3052                  }
2969 3053  
2970 3054                  for (i = 0; i < ndies; i++) {
2971 3055                          cup = &cdies[i];
2972      -                        ctf_dprintf("adding cu %s (%p)\n", cup->cu_name,
2973      -                            cup->cu_ctfp);
2974      -                        if ((ret = ctf_merge_add(cmp, cup->cu_ctfp)) != 0) {
     3056 +                        if ((err = ctf_merge_add(cmp, cup->cu_ctfp)) != 0) {
2975 3057                                  ctf_merge_fini(cmp);
2976      -                                *errp = ret;
2977 3058                                  goto out;
2978 3059                          }
2979 3060                  }
2980 3061  
2981 3062                  ctf_dprintf("performing merge\n");
2982      -                ret = ctf_merge_merge(cmp, fpp);
2983      -                if (ret != 0) {
     3063 +                err = ctf_merge_merge(cmp, fpp);
     3064 +                if (err != 0) {
2984 3065                          ctf_dprintf("failed merge!\n");
2985 3066                          *fpp = NULL;
2986 3067                          ctf_merge_fini(cmp);
2987      -                        *errp = ret;
2988 3068                          goto out;
2989 3069                  }
2990 3070                  ctf_merge_fini(cmp);
2991      -                *errp = 0;
     3071 +                err = 0;
2992 3072                  ctf_dprintf("successfully converted!\n");
2993 3073          } else {
2994      -                *errp = 0;
     3074 +                err = 0;
2995 3075                  *fpp = cdies->cu_ctfp;
2996 3076                  cdies->cu_ctfp = NULL;
2997 3077                  ctf_dprintf("successfully converted!\n");
2998 3078          }
2999 3079  
3000 3080  out:
3001 3081          workq_fini(wqp);
3002 3082          ctf_dwarf_free_dies(cdies, ndies);
3003      -        return (*fpp != NULL ? CTF_CONV_SUCCESS : CTF_CONV_ERROR);
     3083 +        return (err);
3004 3084  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX