Print this page
    
12259 CTF shouldn't assume enum size
    
      
        | 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   */
  
    | 
      ↓ open down ↓ | 
    20 lines elided | 
    
      ↑ open up ↑ | 
  
  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      - * Copyright 2019, Joyent, Inc.
       31 + * Copyright 2020 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:
 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  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;
  
    | 
      ↓ open down ↓ | 
    1164 lines elided | 
    
      ↑ open up ↑ | 
  
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      -        ulong_t nsz;
1217 1216  
1218 1217          kind = ctf_type_kind(cup->cu_ctfp, base);
1219 1218          VERIFY(kind != CTF_ERR);
1220 1219          VERIFY(kind == CTF_K_STRUCT || kind == CTF_K_UNION);
1221 1220  
1222 1221          /*
1223 1222           * Members are in children. However, gcc also allows empty ones.
1224 1223           */
1225 1224          if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1226 1225                  return (ret);
1227 1226          if (child == NULL)
1228 1227                  return (0);
1229 1228  
1230 1229          memb = child;
1231 1230          while (memb != NULL) {
1232 1231                  Dwarf_Die sib, tdie;
1233 1232                  Dwarf_Half tag;
1234 1233                  ctf_id_t mid;
1235 1234                  char *mname;
1236 1235                  ulong_t memboff = 0;
1237 1236  
1238 1237                  if ((ret = ctf_dwarf_tag(cup, memb, &tag)) != 0)
1239 1238                          return (ret);
1240 1239  
1241 1240                  if (tag != DW_TAG_member)
1242 1241                          continue;
1243 1242  
1244 1243                  if ((ret = ctf_dwarf_refdie(cup, memb, DW_AT_type, &tdie)) != 0)
1245 1244                          return (ret);
1246 1245  
1247 1246                  if ((ret = ctf_dwarf_convert_type(cup, tdie, &mid,
1248 1247                      CTF_ADD_NONROOT)) != 0)
1249 1248                          return (ret);
1250 1249                  ctf_dprintf("Got back type id: %d\n", mid);
1251 1250  
1252 1251                  /*
1253 1252                   * If we're not adding a member, just go ahead and return.
1254 1253                   */
1255 1254                  if (add == B_FALSE) {
1256 1255                          if ((ret = ctf_dwarf_member_bitfield(cup, memb,
1257 1256                              &mid)) != 0)
1258 1257                                  return (ret);
1259 1258                          goto next;
1260 1259                  }
1261 1260  
1262 1261                  if ((ret = ctf_dwarf_string(cup, memb, DW_AT_name,
1263 1262                      &mname)) != 0 && ret != ENOENT)
1264 1263                          return (ret);
1265 1264                  if (ret == ENOENT)
1266 1265                          mname = NULL;
1267 1266  
1268 1267                  if (kind == CTF_K_UNION) {
1269 1268                          memboff = 0;
1270 1269                  } else if ((ret = ctf_dwarf_member_offset(cup, memb, mid,
1271 1270                      &memboff)) != 0) {
1272 1271                          if (mname != NULL)
1273 1272                                  ctf_free(mname, strlen(mname) + 1);
1274 1273                          return (ret);
1275 1274                  }
1276 1275  
1277 1276                  if ((ret = ctf_dwarf_member_bitfield(cup, memb, &mid)) != 0)
1278 1277                          return (ret);
1279 1278  
1280 1279                  ret = ctf_add_member(cup->cu_ctfp, base, mname, mid, memboff);
1281 1280                  if (ret == CTF_ERR) {
1282 1281                          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1283 1282                              "failed to add member %s: %s",
1284 1283                              mname, ctf_errmsg(ctf_errno(cup->cu_ctfp)));
1285 1284                          if (mname != NULL)
1286 1285                                  ctf_free(mname, strlen(mname) + 1);
1287 1286                          return (ECTF_CONVBKERR);
1288 1287                  }
1289 1288  
1290 1289                  if (mname != NULL)
1291 1290                          ctf_free(mname, strlen(mname) + 1);
1292 1291  
1293 1292  next:
1294 1293                  if ((ret = ctf_dwarf_sib(cup, memb, &sib)) != 0)
1295 1294                          return (ret);
1296 1295                  memb = sib;
1297 1296          }
1298 1297  
  
    | 
      ↓ open down ↓ | 
    72 lines elided | 
    
      ↑ open up ↑ | 
  
1299 1298          /*
1300 1299           * If we're not adding members, then we don't know the final size of the
1301 1300           * structure, so end here.
1302 1301           */
1303 1302          if (add == B_FALSE)
1304 1303                  return (0);
1305 1304  
1306 1305          /* Finally set the size of the structure to the actual byte size */
1307 1306          if ((ret = ctf_dwarf_unsigned(cup, die, DW_AT_byte_size, &size)) != 0)
1308 1307                  return (ret);
1309      -        nsz = size;
1310      -        if ((ctf_set_size(cup->cu_ctfp, base, nsz)) == CTF_ERR) {
     1308 +        if ((ctf_set_size(cup->cu_ctfp, base, size)) == CTF_ERR) {
1311 1309                  int e = ctf_errno(cup->cu_ctfp);
1312 1310                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1313 1311                      "failed to set type size for %d to 0x%x: %s", base,
1314 1312                      (uint32_t)size, ctf_errmsg(e));
1315 1313                  return (ECTF_CONVBKERR);
1316 1314          }
1317 1315  
1318 1316          return (0);
1319 1317  }
1320 1318  
1321 1319  static int
1322 1320  ctf_dwarf_create_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp,
1323 1321      int kind, int isroot)
1324 1322  {
1325 1323          int ret;
1326 1324          char *name;
1327 1325          ctf_id_t base;
1328 1326          Dwarf_Die child;
1329 1327          Dwarf_Bool decl;
1330 1328  
1331 1329          /*
1332 1330           * Deal with the terribly annoying case of anonymous structs and unions.
1333 1331           * If they don't have a name, set the name to the empty string.
1334 1332           */
1335 1333          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0 &&
1336 1334              ret != ENOENT)
1337 1335                  return (ret);
1338 1336          if (ret == ENOENT)
1339 1337                  name = NULL;
1340 1338  
1341 1339          /*
1342 1340           * We need to check if we just have a declaration here. If we do, then
1343 1341           * instead of creating an actual structure or union, we're just going to
1344 1342           * go ahead and create a forward. During a dedup or merge, the forward
1345 1343           * will be replaced with the real thing.
1346 1344           */
1347 1345          if ((ret = ctf_dwarf_boolean(cup, die, DW_AT_declaration,
1348 1346              &decl)) != 0) {
1349 1347                  if (ret != ENOENT)
1350 1348                          return (ret);
1351 1349                  decl = 0;
1352 1350          }
1353 1351  
1354 1352          if (decl != 0) {
1355 1353                  base = ctf_add_forward(cup->cu_ctfp, isroot, name, kind);
1356 1354          } else if (kind == CTF_K_STRUCT) {
1357 1355                  base = ctf_add_struct(cup->cu_ctfp, isroot, name);
1358 1356          } else {
1359 1357                  base = ctf_add_union(cup->cu_ctfp, isroot, name);
1360 1358          }
1361 1359          ctf_dprintf("added sou %s (%d) (%d)\n", name, kind, base);
1362 1360          if (name != NULL)
1363 1361                  ctf_free(name, strlen(name) + 1);
1364 1362          if (base == CTF_ERR)
1365 1363                  return (ctf_errno(cup->cu_ctfp));
1366 1364          *idp = base;
1367 1365  
1368 1366          /*
1369 1367           * If it's just a declaration, we're not going to mark it for fix up or
1370 1368           * do anything else.
1371 1369           */
1372 1370          if (decl == B_TRUE)
1373 1371                  return (ctf_dwmap_add(cup, base, die, B_FALSE));
1374 1372          if ((ret = ctf_dwmap_add(cup, base, die, B_TRUE)) != 0)
1375 1373                  return (ret);
1376 1374  
1377 1375          /*
1378 1376           * Members are in children. However, gcc also allows empty ones.
1379 1377           */
1380 1378          if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1381 1379                  return (ret);
1382 1380          if (child == NULL)
1383 1381                  return (0);
1384 1382  
1385 1383          return (0);
1386 1384  }
1387 1385  
1388 1386  static int
1389 1387  ctf_dwarf_create_array_range(ctf_cu_t *cup, Dwarf_Die range, ctf_id_t *idp,
1390 1388      ctf_id_t base, int isroot)
1391 1389  {
1392 1390          int ret;
1393 1391          Dwarf_Die sib;
1394 1392          Dwarf_Unsigned val;
1395 1393          Dwarf_Signed sval;
1396 1394          ctf_arinfo_t ar;
1397 1395  
1398 1396          ctf_dprintf("creating array range\n");
1399 1397  
1400 1398          if ((ret = ctf_dwarf_sib(cup, range, &sib)) != 0)
1401 1399                  return (ret);
1402 1400          if (sib != NULL) {
1403 1401                  ctf_id_t id;
1404 1402                  if ((ret = ctf_dwarf_create_array_range(cup, sib, &id,
1405 1403                      base, CTF_ADD_NONROOT)) != 0)
1406 1404                          return (ret);
1407 1405                  ar.ctr_contents = id;
1408 1406          } else {
1409 1407                  ar.ctr_contents = base;
1410 1408          }
1411 1409  
1412 1410          if ((ar.ctr_index = ctf_dwarf_long(cup)) == CTF_ERR)
1413 1411                  return (ctf_errno(cup->cu_ctfp));
1414 1412  
1415 1413          /*
1416 1414           * Array bounds can be signed or unsigned, but there are several kinds
1417 1415           * of signless forms (data1, data2, etc) that take their sign from the
1418 1416           * routine that is trying to interpret them.  That is, data1 can be
1419 1417           * either signed or unsigned, depending on whether you use the signed or
1420 1418           * unsigned accessor function.  GCC will use the signless forms to store
1421 1419           * unsigned values which have their high bit set, so we need to try to
1422 1420           * read them first as unsigned to get positive values.  We could also
1423 1421           * try signed first, falling back to unsigned if we got a negative
1424 1422           * value.
1425 1423           */
1426 1424          if ((ret = ctf_dwarf_unsigned(cup, range, DW_AT_upper_bound,
1427 1425              &val)) == 0) {
1428 1426                  ar.ctr_nelems = val + 1;
1429 1427          } else if (ret != ENOENT) {
1430 1428                  return (ret);
1431 1429          } else if ((ret = ctf_dwarf_signed(cup, range, DW_AT_upper_bound,
1432 1430              &sval)) == 0) {
1433 1431                  ar.ctr_nelems = sval + 1;
1434 1432          } else if (ret != ENOENT) {
1435 1433                  return (ret);
1436 1434          } else {
1437 1435                  ar.ctr_nelems = 0;
1438 1436          }
1439 1437  
1440 1438          if ((*idp = ctf_add_array(cup->cu_ctfp, isroot, &ar)) == CTF_ERR)
1441 1439                  return (ctf_errno(cup->cu_ctfp));
1442 1440  
1443 1441          return (0);
1444 1442  }
1445 1443  
1446 1444  /*
1447 1445   * Try and create an array type. First, the kind of the array is specified in
1448 1446   * the DW_AT_type entry. Next, the number of entries is stored in a more
1449 1447   * complicated form, we should have a child that has the DW_TAG_subrange type.
1450 1448   */
1451 1449  static int
1452 1450  ctf_dwarf_create_array(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot)
1453 1451  {
1454 1452          int ret;
1455 1453          Dwarf_Die tdie, rdie;
1456 1454          ctf_id_t tid;
1457 1455          Dwarf_Half rtag;
1458 1456  
1459 1457          if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) != 0)
1460 1458                  return (ret);
1461 1459          if ((ret = ctf_dwarf_convert_type(cup, tdie, &tid,
1462 1460              CTF_ADD_NONROOT)) != 0)
1463 1461                  return (ret);
1464 1462  
1465 1463          if ((ret = ctf_dwarf_child(cup, die, &rdie)) != 0)
1466 1464                  return (ret);
1467 1465          if ((ret = ctf_dwarf_tag(cup, rdie, &rtag)) != 0)
1468 1466                  return (ret);
1469 1467          if (rtag != DW_TAG_subrange_type) {
1470 1468                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1471 1469                      "encountered array without DW_TAG_subrange_type child\n");
1472 1470                  return (ECTF_CONVBKERR);
1473 1471          }
1474 1472  
1475 1473          /*
1476 1474           * The compiler may opt to describe a multi-dimensional array as one
1477 1475           * giant array or it may opt to instead encode it as a series of
1478 1476           * subranges. If it's the latter, then for each subrange we introduce a
1479 1477           * type. We can always use the base type.
1480 1478           */
1481 1479          if ((ret = ctf_dwarf_create_array_range(cup, rdie, idp, tid,
1482 1480              isroot)) != 0)
1483 1481                  return (ret);
1484 1482          ctf_dprintf("Got back id %d\n", *idp);
1485 1483          return (ctf_dwmap_add(cup, *idp, die, B_FALSE));
1486 1484  }
1487 1485  
1488 1486  /*
1489 1487   * Given "const int const_array3[11]", GCC7 at least will create a DIE tree of
1490 1488   * DW_TAG_const_type:DW_TAG_array_type:DW_Tag_const_type:<member_type>.
1491 1489   *
1492 1490   * Given C's syntax, this renders out as "const const int const_array3[11]".  To
1493 1491   * get closer to round-tripping (and make the unit tests work), we'll peek for
1494 1492   * this case, and avoid adding the extraneous qualifier if we see that the
1495 1493   * underlying array referent already has the same qualifier.
1496 1494   *
1497 1495   * This is unfortunately less trivial than it could be: this issue applies to
1498 1496   * qualifier sets like "const volatile", as well as multi-dimensional arrays, so
1499 1497   * we need to descend down those.
1500 1498   *
1501 1499   * Returns CTF_ERR on error, or a boolean value otherwise.
1502 1500   */
1503 1501  static int
1504 1502  needed_array_qualifier(ctf_cu_t *cup, int kind, ctf_id_t ref_id)
1505 1503  {
1506 1504          const ctf_type_t *t;
1507 1505          ctf_arinfo_t arinfo;
1508 1506          int akind;
1509 1507  
1510 1508          if (kind != CTF_K_CONST && kind != CTF_K_VOLATILE &&
1511 1509              kind != CTF_K_RESTRICT)
1512 1510                  return (1);
1513 1511  
1514 1512          if ((t = ctf_dyn_lookup_by_id(cup->cu_ctfp, ref_id)) == NULL)
1515 1513                  return (CTF_ERR);
1516 1514  
1517 1515          if (LCTF_INFO_KIND(cup->cu_ctfp, t->ctt_info) != CTF_K_ARRAY)
1518 1516                  return (1);
1519 1517  
1520 1518          if (ctf_dyn_array_info(cup->cu_ctfp, ref_id, &arinfo) != 0)
1521 1519                  return (CTF_ERR);
1522 1520  
1523 1521          ctf_id_t id = arinfo.ctr_contents;
1524 1522  
1525 1523          for (;;) {
1526 1524                  if ((t = ctf_dyn_lookup_by_id(cup->cu_ctfp, id)) == NULL)
1527 1525                          return (CTF_ERR);
1528 1526  
1529 1527                  akind = LCTF_INFO_KIND(cup->cu_ctfp, t->ctt_info);
1530 1528  
1531 1529                  if (akind == kind)
1532 1530                          break;
1533 1531  
1534 1532                  if (akind == CTF_K_ARRAY) {
1535 1533                          if (ctf_dyn_array_info(cup->cu_ctfp,
1536 1534                              id, &arinfo) != 0)
1537 1535                                  return (CTF_ERR);
1538 1536                          id = arinfo.ctr_contents;
1539 1537                          continue;
1540 1538                  }
1541 1539  
1542 1540                  if (akind != CTF_K_CONST && akind != CTF_K_VOLATILE &&
1543 1541                      akind != CTF_K_RESTRICT)
1544 1542                          break;
1545 1543  
1546 1544                  id = t->ctt_type;
1547 1545          }
1548 1546  
1549 1547          if (kind == akind) {
1550 1548                  ctf_dprintf("ignoring extraneous %s qualifier for array %d\n",
1551 1549                      ctf_kind_name(cup->cu_ctfp, kind), ref_id);
1552 1550          }
1553 1551  
1554 1552          return (kind != akind);
1555 1553  }
1556 1554  
1557 1555  static int
1558 1556  ctf_dwarf_create_reference(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp,
1559 1557      int kind, int isroot)
1560 1558  {
1561 1559          int ret;
1562 1560          ctf_id_t id;
1563 1561          Dwarf_Die tdie;
1564 1562          char *name;
1565 1563          size_t namelen;
1566 1564  
1567 1565          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0 &&
1568 1566              ret != ENOENT)
1569 1567                  return (ret);
1570 1568          if (ret == ENOENT) {
1571 1569                  name = NULL;
1572 1570                  namelen = 0;
1573 1571          } else {
1574 1572                  namelen = strlen(name);
1575 1573          }
1576 1574  
1577 1575          ctf_dprintf("reference kind %d %s\n", kind, name != NULL ? name : "<>");
1578 1576  
1579 1577          if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) != 0) {
1580 1578                  if (ret != ENOENT) {
1581 1579                          ctf_free(name, namelen);
1582 1580                          return (ret);
1583 1581                  }
1584 1582                  if ((id = ctf_dwarf_void(cup)) == CTF_ERR) {
1585 1583                          ctf_free(name, namelen);
1586 1584                          return (ctf_errno(cup->cu_ctfp));
1587 1585                  }
1588 1586          } else {
1589 1587                  if ((ret = ctf_dwarf_convert_type(cup, tdie, &id,
1590 1588                      CTF_ADD_NONROOT)) != 0) {
1591 1589                          ctf_free(name, namelen);
1592 1590                          return (ret);
1593 1591                  }
1594 1592          }
1595 1593  
1596 1594          if ((ret = needed_array_qualifier(cup, kind, id)) <= 0) {
1597 1595                  if (ret != 0) {
1598 1596                          ret = (ctf_errno(cup->cu_ctfp));
1599 1597                  } else {
1600 1598                          *idp = id;
1601 1599                  }
1602 1600  
1603 1601                  ctf_free(name, namelen);
1604 1602                  return (ret);
1605 1603          }
1606 1604  
  
    | 
      ↓ open down ↓ | 
    286 lines elided | 
    
      ↑ open up ↑ | 
  
1607 1605          if ((*idp = ctf_add_reftype(cup->cu_ctfp, isroot, name, id, kind)) ==
1608 1606              CTF_ERR) {
1609 1607                  ctf_free(name, namelen);
1610 1608                  return (ctf_errno(cup->cu_ctfp));
1611 1609          }
1612 1610  
1613 1611          ctf_free(name, namelen);
1614 1612          return (ctf_dwmap_add(cup, *idp, die, B_FALSE));
1615 1613  }
1616 1614  
     1615 +/*
     1616 + * Get the size of the type of a particular die. Note that this is a simple
     1617 + * version that doesn't attempt to traverse further than expecting a single
     1618 + * sized type reference (so no qualifiers etc.). Nor does it attempt to do as
     1619 + * much as ctf_type_size() - which we cannot use here as that doesn't look up
     1620 + * dynamic types, and we don't yet want to do a ctf_update().
     1621 + */
1617 1622  static int
1618      -ctf_dwarf_create_enum(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot)
     1623 +ctf_dwarf_get_type_size(ctf_cu_t *cup, Dwarf_Die die, size_t *sizep)
1619 1624  {
     1625 +        const ctf_type_t *t;
     1626 +        Dwarf_Die tdie;
     1627 +        ctf_id_t tid;
1620 1628          int ret;
1621      -        ctf_id_t id;
     1629 +
     1630 +        if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) != 0)
     1631 +                return (ret);
     1632 +
     1633 +        if ((ret = ctf_dwarf_convert_type(cup, tdie, &tid,
     1634 +            CTF_ADD_NONROOT)) != 0)
     1635 +                return (ret);
     1636 +
     1637 +        if ((t = ctf_dyn_lookup_by_id(cup->cu_ctfp, tid)) == NULL)
     1638 +                return (ENOENT);
     1639 +
     1640 +        *sizep = ctf_get_ctt_size(cup->cu_ctfp, t, NULL, NULL);
     1641 +        return (0);
     1642 +}
     1643 +
     1644 +static int
     1645 +ctf_dwarf_create_enum(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot)
     1646 +{
     1647 +        size_t size = 0;
1622 1648          Dwarf_Die child;
     1649 +        ctf_id_t id;
1623 1650          char *name;
     1651 +        int ret;
1624 1652  
1625 1653          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0 &&
1626 1654              ret != ENOENT)
1627 1655                  return (ret);
1628 1656          if (ret == ENOENT)
1629 1657                  name = NULL;
1630      -        id = ctf_add_enum(cup->cu_ctfp, isroot, name);
     1658 +
     1659 +        (void) ctf_dwarf_get_type_size(cup, die, &size);
     1660 +
     1661 +        id = ctf_add_enum(cup->cu_ctfp, isroot, name, size);
1631 1662          ctf_dprintf("added enum %s (%d)\n", name, id);
1632 1663          if (name != NULL)
1633 1664                  ctf_free(name, strlen(name) + 1);
1634 1665          if (id == CTF_ERR)
1635 1666                  return (ctf_errno(cup->cu_ctfp));
1636 1667          *idp = id;
1637 1668          if ((ret = ctf_dwmap_add(cup, id, die, B_FALSE)) != 0)
1638 1669                  return (ret);
1639 1670  
1640 1671          if ((ret = ctf_dwarf_child(cup, die, &child)) != 0) {
1641 1672                  if (ret == ENOENT)
1642 1673                          ret = 0;
1643 1674                  return (ret);
1644 1675          }
1645 1676  
1646 1677          while (child != NULL) {
1647 1678                  Dwarf_Half tag;
1648 1679                  Dwarf_Signed sval;
1649 1680                  Dwarf_Unsigned uval;
1650 1681                  Dwarf_Die arg = child;
1651 1682                  int eval;
1652 1683  
1653 1684                  if ((ret = ctf_dwarf_sib(cup, arg, &child)) != 0)
1654 1685                          return (ret);
1655 1686  
1656 1687                  if ((ret = ctf_dwarf_tag(cup, arg, &tag)) != 0)
1657 1688                          return (ret);
1658 1689  
1659 1690                  if (tag != DW_TAG_enumerator) {
1660 1691                          if ((ret = ctf_dwarf_convert_type(cup, arg, NULL,
1661 1692                              CTF_ADD_NONROOT)) != 0)
1662 1693                                  return (ret);
1663 1694                          continue;
1664 1695                  }
1665 1696  
1666 1697                  /*
1667 1698                   * DWARF v4 section 5.7 tells us we'll always have names.
1668 1699                   */
1669 1700                  if ((ret = ctf_dwarf_string(cup, arg, DW_AT_name, &name)) != 0)
1670 1701                          return (ret);
1671 1702  
1672 1703                  /*
1673 1704                   * We have to be careful here: newer GCCs generate DWARF where
1674 1705                   * an unsigned value will happily pass ctf_dwarf_signed().
1675 1706                   * Since negative values will fail ctf_dwarf_unsigned(), we try
1676 1707                   * that first to make sure we get the right value.
1677 1708                   */
1678 1709                  if ((ret = ctf_dwarf_unsigned(cup, arg, DW_AT_const_value,
1679 1710                      &uval)) == 0) {
1680 1711                          eval = (int)uval;
1681 1712                  } else if ((ret = ctf_dwarf_signed(cup, arg, DW_AT_const_value,
1682 1713                      &sval)) == 0) {
1683 1714                          eval = sval;
1684 1715                  }
1685 1716  
1686 1717                  if (ret != 0) {
1687 1718                          if (ret != ENOENT)
1688 1719                                  return (ret);
1689 1720  
1690 1721                          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1691 1722                              "encountered enumeration without constant value\n");
1692 1723                          return (ECTF_CONVBKERR);
1693 1724                  }
1694 1725  
1695 1726                  ret = ctf_add_enumerator(cup->cu_ctfp, id, name, eval);
1696 1727                  if (ret == CTF_ERR) {
1697 1728                          (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1698 1729                              "failed to add enumarator %s (%d) to %d\n",
1699 1730                              name, eval, id);
1700 1731                          ctf_free(name, strlen(name) + 1);
1701 1732                          return (ctf_errno(cup->cu_ctfp));
1702 1733                  }
1703 1734                  ctf_free(name, strlen(name) + 1);
1704 1735          }
1705 1736  
1706 1737          return (0);
1707 1738  }
1708 1739  
1709 1740  /*
1710 1741   * For a function pointer, walk over and process all of its children, unless we
1711 1742   * encounter one that's just a declaration. In which case, we error on it.
1712 1743   */
1713 1744  static int
1714 1745  ctf_dwarf_create_fptr(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot)
1715 1746  {
1716 1747          int ret;
1717 1748          Dwarf_Bool b;
1718 1749          ctf_funcinfo_t fi;
1719 1750          Dwarf_Die retdie;
1720 1751          ctf_id_t *argv = NULL;
1721 1752  
1722 1753          bzero(&fi, sizeof (ctf_funcinfo_t));
1723 1754  
1724 1755          if ((ret = ctf_dwarf_boolean(cup, die, DW_AT_declaration, &b)) != 0) {
1725 1756                  if (ret != ENOENT)
1726 1757                          return (ret);
1727 1758          } else {
1728 1759                  if (b != 0)
1729 1760                          return (EPROTOTYPE);
1730 1761          }
1731 1762  
1732 1763          /*
1733 1764           * Return type is in DW_AT_type, if none, it returns void.
1734 1765           */
1735 1766          if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &retdie)) != 0) {
1736 1767                  if (ret != ENOENT)
1737 1768                          return (ret);
1738 1769                  if ((fi.ctc_return = ctf_dwarf_void(cup)) == CTF_ERR)
1739 1770                          return (ctf_errno(cup->cu_ctfp));
1740 1771          } else {
1741 1772                  if ((ret = ctf_dwarf_convert_type(cup, retdie, &fi.ctc_return,
1742 1773                      CTF_ADD_NONROOT)) != 0)
1743 1774                          return (ret);
1744 1775          }
1745 1776  
1746 1777          if ((ret = ctf_dwarf_function_count(cup, die, &fi, B_TRUE)) != 0) {
1747 1778                  return (ret);
1748 1779          }
1749 1780  
1750 1781          if (fi.ctc_argc != 0) {
1751 1782                  argv = ctf_alloc(sizeof (ctf_id_t) * fi.ctc_argc);
1752 1783                  if (argv == NULL)
1753 1784                          return (ENOMEM);
1754 1785  
1755 1786                  if ((ret = ctf_dwarf_convert_fargs(cup, die, &fi, argv)) != 0) {
1756 1787                          ctf_free(argv, sizeof (ctf_id_t) * fi.ctc_argc);
1757 1788                          return (ret);
1758 1789                  }
1759 1790          }
1760 1791  
1761 1792          if ((*idp = ctf_add_funcptr(cup->cu_ctfp, isroot, &fi, argv)) ==
1762 1793              CTF_ERR) {
1763 1794                  ctf_free(argv, sizeof (ctf_id_t) * fi.ctc_argc);
1764 1795                  return (ctf_errno(cup->cu_ctfp));
1765 1796          }
1766 1797  
1767 1798          ctf_free(argv, sizeof (ctf_id_t) * fi.ctc_argc);
1768 1799          return (ctf_dwmap_add(cup, *idp, die, B_FALSE));
1769 1800  }
1770 1801  
1771 1802  static int
1772 1803  ctf_dwarf_convert_type(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp,
1773 1804      int isroot)
1774 1805  {
1775 1806          int ret;
1776 1807          Dwarf_Off offset;
1777 1808          Dwarf_Half tag;
1778 1809          ctf_dwmap_t lookup, *map;
1779 1810          ctf_id_t id;
1780 1811  
1781 1812          if (idp == NULL)
1782 1813                  idp = &id;
1783 1814  
1784 1815          if ((ret = ctf_dwarf_offset(cup, die, &offset)) != 0)
1785 1816                  return (ret);
1786 1817  
1787 1818          if (offset > cup->cu_maxoff) {
1788 1819                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1789 1820                      "die offset %llu beyond maximum for header %llu\n",
1790 1821                      offset, cup->cu_maxoff);
1791 1822                  return (ECTF_CONVBKERR);
1792 1823          }
1793 1824  
1794 1825          /*
1795 1826           * If we've already added an entry for this offset, then we're done.
1796 1827           */
1797 1828          lookup.cdm_off = offset;
1798 1829          if ((map = avl_find(&cup->cu_map, &lookup, NULL)) != NULL) {
1799 1830                  *idp = map->cdm_id;
1800 1831                  return (0);
1801 1832          }
1802 1833  
1803 1834          if ((ret = ctf_dwarf_tag(cup, die, &tag)) != 0)
1804 1835                  return (ret);
1805 1836  
1806 1837          ret = ENOTSUP;
1807 1838          switch (tag) {
1808 1839          case DW_TAG_base_type:
1809 1840                  ctf_dprintf("base\n");
1810 1841                  ret = ctf_dwarf_create_base(cup, die, idp, isroot, offset);
1811 1842                  break;
1812 1843          case DW_TAG_array_type:
1813 1844                  ctf_dprintf("array\n");
1814 1845                  ret = ctf_dwarf_create_array(cup, die, idp, isroot);
1815 1846                  break;
1816 1847          case DW_TAG_enumeration_type:
1817 1848                  ctf_dprintf("enum\n");
1818 1849                  ret = ctf_dwarf_create_enum(cup, die, idp, isroot);
1819 1850                  break;
1820 1851          case DW_TAG_pointer_type:
1821 1852                  ctf_dprintf("pointer\n");
1822 1853                  ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_POINTER,
1823 1854                      isroot);
1824 1855                  break;
1825 1856          case DW_TAG_structure_type:
1826 1857                  ctf_dprintf("struct\n");
1827 1858                  ret = ctf_dwarf_create_sou(cup, die, idp, CTF_K_STRUCT,
1828 1859                      isroot);
1829 1860                  break;
1830 1861          case DW_TAG_subroutine_type:
1831 1862                  ctf_dprintf("fptr\n");
1832 1863                  ret = ctf_dwarf_create_fptr(cup, die, idp, isroot);
1833 1864                  break;
1834 1865          case DW_TAG_typedef:
1835 1866                  ctf_dprintf("typedef\n");
1836 1867                  ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_TYPEDEF,
1837 1868                      isroot);
1838 1869                  break;
1839 1870          case DW_TAG_union_type:
1840 1871                  ctf_dprintf("union\n");
1841 1872                  ret = ctf_dwarf_create_sou(cup, die, idp, CTF_K_UNION,
1842 1873                      isroot);
1843 1874                  break;
1844 1875          case DW_TAG_const_type:
1845 1876                  ctf_dprintf("const\n");
1846 1877                  ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_CONST,
1847 1878                      isroot);
1848 1879                  break;
1849 1880          case DW_TAG_volatile_type:
1850 1881                  ctf_dprintf("volatile\n");
1851 1882                  ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_VOLATILE,
1852 1883                      isroot);
1853 1884                  break;
1854 1885          case DW_TAG_restrict_type:
1855 1886                  ctf_dprintf("restrict\n");
1856 1887                  ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_RESTRICT,
1857 1888                      isroot);
1858 1889                  break;
1859 1890          default:
1860 1891                  ctf_dprintf("ignoring tag type %x\n", tag);
1861 1892                  *idp = CTF_ERR;
1862 1893                  ret = 0;
1863 1894                  break;
1864 1895          }
1865 1896          ctf_dprintf("ctf_dwarf_convert_type tag specific handler returned %d\n",
1866 1897              ret);
1867 1898  
1868 1899          return (ret);
1869 1900  }
1870 1901  
1871 1902  static int
1872 1903  ctf_dwarf_walk_lexical(ctf_cu_t *cup, Dwarf_Die die)
1873 1904  {
1874 1905          int ret;
1875 1906          Dwarf_Die child;
1876 1907  
1877 1908          if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1878 1909                  return (ret);
1879 1910  
1880 1911          if (child == NULL)
1881 1912                  return (0);
1882 1913  
1883 1914          return (ctf_dwarf_convert_die(cup, die));
1884 1915  }
1885 1916  
1886 1917  static int
1887 1918  ctf_dwarf_function_count(ctf_cu_t *cup, Dwarf_Die die, ctf_funcinfo_t *fip,
1888 1919      boolean_t fptr)
1889 1920  {
1890 1921          int ret;
1891 1922          Dwarf_Die child, sib, arg;
1892 1923  
1893 1924          if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1894 1925                  return (ret);
1895 1926  
1896 1927          arg = child;
1897 1928          while (arg != NULL) {
1898 1929                  Dwarf_Half tag;
1899 1930  
1900 1931                  if ((ret = ctf_dwarf_tag(cup, arg, &tag)) != 0)
1901 1932                          return (ret);
1902 1933  
1903 1934                  /*
1904 1935                   * We have to check for a varargs type declaration. This will
1905 1936                   * happen in one of two ways. If we have a function pointer
1906 1937                   * type, then it'll be done with a tag of type
1907 1938                   * DW_TAG_unspecified_parameters. However, it only means we have
1908 1939                   * a variable number of arguments, if we have more than one
1909 1940                   * argument found so far. Otherwise, when we have a function
1910 1941                   * type, it instead uses a formal parameter whose name is '...'
1911 1942                   * to indicate a variable arguments member.
1912 1943                   *
1913 1944                   * Also, if we have a function pointer, then we have to expect
1914 1945                   * that we might not get a name at all.
1915 1946                   */
1916 1947                  if (tag == DW_TAG_formal_parameter && fptr == B_FALSE) {
1917 1948                          char *name;
1918 1949                          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name,
1919 1950                              &name)) != 0)
1920 1951                                  return (ret);
1921 1952                          if (strcmp(name, DWARF_VARARGS_NAME) == 0)
1922 1953                                  fip->ctc_flags |= CTF_FUNC_VARARG;
1923 1954                          else
1924 1955                                  fip->ctc_argc++;
1925 1956                          ctf_free(name, strlen(name) + 1);
1926 1957                  } else if (tag == DW_TAG_formal_parameter) {
1927 1958                          fip->ctc_argc++;
1928 1959                  } else if (tag == DW_TAG_unspecified_parameters &&
1929 1960                      fip->ctc_argc > 0) {
1930 1961                          fip->ctc_flags |= CTF_FUNC_VARARG;
1931 1962                  }
1932 1963                  if ((ret = ctf_dwarf_sib(cup, arg, &sib)) != 0)
1933 1964                          return (ret);
1934 1965                  arg = sib;
1935 1966          }
1936 1967  
1937 1968          return (0);
1938 1969  }
1939 1970  
1940 1971  static int
1941 1972  ctf_dwarf_convert_fargs(ctf_cu_t *cup, Dwarf_Die die, ctf_funcinfo_t *fip,
1942 1973      ctf_id_t *argv)
1943 1974  {
1944 1975          int ret;
1945 1976          int i = 0;
1946 1977          Dwarf_Die child, sib, arg;
1947 1978  
1948 1979          if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1949 1980                  return (ret);
1950 1981  
1951 1982          arg = child;
1952 1983          while (arg != NULL) {
1953 1984                  Dwarf_Half tag;
1954 1985  
1955 1986                  if ((ret = ctf_dwarf_tag(cup, arg, &tag)) != 0)
1956 1987                          return (ret);
1957 1988                  if (tag == DW_TAG_formal_parameter) {
1958 1989                          Dwarf_Die tdie;
1959 1990  
1960 1991                          if ((ret = ctf_dwarf_refdie(cup, arg, DW_AT_type,
1961 1992                              &tdie)) != 0)
1962 1993                                  return (ret);
1963 1994  
1964 1995                          if ((ret = ctf_dwarf_convert_type(cup, tdie, &argv[i],
1965 1996                              CTF_ADD_ROOT)) != 0)
1966 1997                                  return (ret);
1967 1998                          i++;
1968 1999  
1969 2000                          /*
1970 2001                           * Once we hit argc entries, we're done. This ensures we
1971 2002                           * don't accidentally hit a varargs which should be the
1972 2003                           * last entry.
1973 2004                           */
1974 2005                          if (i == fip->ctc_argc)
1975 2006                                  break;
1976 2007                  }
1977 2008  
1978 2009                  if ((ret = ctf_dwarf_sib(cup, arg, &sib)) != 0)
1979 2010                          return (ret);
1980 2011                  arg = sib;
1981 2012          }
1982 2013  
1983 2014          return (0);
1984 2015  }
1985 2016  
1986 2017  static int
1987 2018  ctf_dwarf_convert_function(ctf_cu_t *cup, Dwarf_Die die)
1988 2019  {
1989 2020          ctf_dwfunc_t *cdf;
1990 2021          Dwarf_Die tdie;
1991 2022          Dwarf_Bool b;
1992 2023          char *name;
1993 2024          int ret;
1994 2025  
1995 2026          /*
1996 2027           * Functions that don't have a name are generally functions that have
1997 2028           * been inlined and thus most information about them has been lost. If
1998 2029           * we can't get a name, then instead of returning ENOENT, we silently
1999 2030           * swallow the error.
2000 2031           */
2001 2032          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0) {
2002 2033                  if (ret == ENOENT)
2003 2034                          return (0);
2004 2035                  return (ret);
2005 2036          }
2006 2037  
2007 2038          ctf_dprintf("beginning work on function %s (die %llx)\n",
2008 2039              name, ctf_die_offset(die));
2009 2040  
2010 2041          if ((ret = ctf_dwarf_boolean(cup, die, DW_AT_declaration, &b)) != 0) {
2011 2042                  if (ret != ENOENT)
2012 2043                          return (ret);
2013 2044          } else if (b != 0) {
2014 2045                  /*
2015 2046                   * GCC7 at least creates empty DW_AT_declarations for functions
2016 2047                   * defined in headers.  As they lack details on the function
2017 2048                   * prototype, we need to ignore them.  If we later actually
2018 2049                   * see the relevant function's definition, we will see another
2019 2050                   * DW_TAG_subprogram that is more complete.
2020 2051                   */
2021 2052                  ctf_dprintf("ignoring declaration of function %s (die %llx)\n",
2022 2053                      name, ctf_die_offset(die));
2023 2054                  return (0);
2024 2055          }
2025 2056  
2026 2057          if ((cdf = ctf_alloc(sizeof (ctf_dwfunc_t))) == NULL) {
2027 2058                  ctf_free(name, strlen(name) + 1);
2028 2059                  return (ENOMEM);
2029 2060          }
2030 2061          bzero(cdf, sizeof (ctf_dwfunc_t));
2031 2062          cdf->cdf_name = name;
2032 2063  
2033 2064          if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) == 0) {
2034 2065                  if ((ret = ctf_dwarf_convert_type(cup, tdie,
2035 2066                      &(cdf->cdf_fip.ctc_return), CTF_ADD_ROOT)) != 0) {
2036 2067                          ctf_free(name, strlen(name) + 1);
2037 2068                          ctf_free(cdf, sizeof (ctf_dwfunc_t));
2038 2069                          return (ret);
2039 2070                  }
2040 2071          } else if (ret != ENOENT) {
2041 2072                  ctf_free(name, strlen(name) + 1);
2042 2073                  ctf_free(cdf, sizeof (ctf_dwfunc_t));
2043 2074                  return (ret);
2044 2075          } else {
2045 2076                  if ((cdf->cdf_fip.ctc_return = ctf_dwarf_void(cup)) ==
2046 2077                      CTF_ERR) {
2047 2078                          ctf_free(name, strlen(name) + 1);
2048 2079                          ctf_free(cdf, sizeof (ctf_dwfunc_t));
2049 2080                          return (ctf_errno(cup->cu_ctfp));
2050 2081                  }
2051 2082          }
2052 2083  
2053 2084          /*
2054 2085           * A function has a number of children, some of which may not be ones we
2055 2086           * care about. Children that we care about have a type of
2056 2087           * DW_TAG_formal_parameter. We're going to do two passes, the first to
2057 2088           * count the arguments, the second to process them. Afterwards, we
2058 2089           * should be good to go ahead and add this function.
2059 2090           *
2060 2091           * Note, we already got the return type by going in and grabbing it out
2061 2092           * of the DW_AT_type.
2062 2093           */
2063 2094          if ((ret = ctf_dwarf_function_count(cup, die, &cdf->cdf_fip,
2064 2095              B_FALSE)) != 0) {
2065 2096                  ctf_free(name, strlen(name) + 1);
2066 2097                  ctf_free(cdf, sizeof (ctf_dwfunc_t));
2067 2098                  return (ret);
2068 2099          }
2069 2100  
2070 2101          ctf_dprintf("beginning to convert function arguments %s\n", name);
2071 2102          if (cdf->cdf_fip.ctc_argc != 0) {
2072 2103                  uint_t argc = cdf->cdf_fip.ctc_argc;
2073 2104                  cdf->cdf_argv = ctf_alloc(sizeof (ctf_id_t) * argc);
2074 2105                  if (cdf->cdf_argv == NULL) {
2075 2106                          ctf_free(name, strlen(name) + 1);
2076 2107                          ctf_free(cdf, sizeof (ctf_dwfunc_t));
2077 2108                          return (ENOMEM);
2078 2109                  }
2079 2110                  if ((ret = ctf_dwarf_convert_fargs(cup, die,
2080 2111                      &cdf->cdf_fip, cdf->cdf_argv)) != 0) {
2081 2112                          ctf_free(cdf->cdf_argv, sizeof (ctf_id_t) * argc);
2082 2113                          ctf_free(name, strlen(name) + 1);
2083 2114                          ctf_free(cdf, sizeof (ctf_dwfunc_t));
2084 2115                          return (ret);
2085 2116                  }
2086 2117          } else {
2087 2118                  cdf->cdf_argv = NULL;
2088 2119          }
2089 2120  
2090 2121          if ((ret = ctf_dwarf_isglobal(cup, die, &cdf->cdf_global)) != 0) {
2091 2122                  ctf_free(cdf->cdf_argv, sizeof (ctf_id_t) *
2092 2123                      cdf->cdf_fip.ctc_argc);
2093 2124                  ctf_free(name, strlen(name) + 1);
2094 2125                  ctf_free(cdf, sizeof (ctf_dwfunc_t));
2095 2126                  return (ret);
2096 2127          }
2097 2128  
2098 2129          ctf_list_append(&cup->cu_funcs, cdf);
2099 2130          return (ret);
2100 2131  }
2101 2132  
2102 2133  /*
2103 2134   * Convert variables, but only if they're not prototypes and have names.
2104 2135   */
2105 2136  static int
2106 2137  ctf_dwarf_convert_variable(ctf_cu_t *cup, Dwarf_Die die)
2107 2138  {
2108 2139          int ret;
2109 2140          char *name;
2110 2141          Dwarf_Bool b;
2111 2142          Dwarf_Die tdie;
2112 2143          ctf_id_t id;
2113 2144          ctf_dwvar_t *cdv;
2114 2145  
2115 2146          /* Skip "Non-Defining Declarations" */
2116 2147          if ((ret = ctf_dwarf_boolean(cup, die, DW_AT_declaration, &b)) == 0) {
2117 2148                  if (b != 0)
2118 2149                          return (0);
2119 2150          } else if (ret != ENOENT) {
2120 2151                  return (ret);
2121 2152          }
2122 2153  
2123 2154          /*
2124 2155           * If we find a DIE of "Declarations Completing Non-Defining
2125 2156           * Declarations", we will use the referenced type's DIE.  This isn't
2126 2157           * quite correct, e.g. DW_AT_decl_line will be the forward declaration
2127 2158           * not this site.  It's sufficient for what we need, however: in
2128 2159           * particular, we should find DW_AT_external as needed there.
2129 2160           */
2130 2161          if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_specification,
2131 2162              &tdie)) == 0) {
2132 2163                  Dwarf_Off offset;
2133 2164                  if ((ret = ctf_dwarf_offset(cup, tdie, &offset)) != 0)
2134 2165                          return (ret);
2135 2166                  ctf_dprintf("die 0x%llx DW_AT_specification -> die 0x%llx\n",
2136 2167                      ctf_die_offset(die), ctf_die_offset(tdie));
2137 2168                  die = tdie;
2138 2169          } else if (ret != ENOENT) {
2139 2170                  return (ret);
2140 2171          }
2141 2172  
2142 2173          if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0 &&
2143 2174              ret != ENOENT)
2144 2175                  return (ret);
2145 2176          if (ret == ENOENT)
2146 2177                  return (0);
2147 2178  
2148 2179          if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) != 0) {
2149 2180                  ctf_free(name, strlen(name) + 1);
2150 2181                  return (ret);
2151 2182          }
2152 2183  
2153 2184          if ((ret = ctf_dwarf_convert_type(cup, tdie, &id,
2154 2185              CTF_ADD_ROOT)) != 0)
2155 2186                  return (ret);
2156 2187  
2157 2188          if ((cdv = ctf_alloc(sizeof (ctf_dwvar_t))) == NULL) {
2158 2189                  ctf_free(name, strlen(name) + 1);
2159 2190                  return (ENOMEM);
2160 2191          }
2161 2192  
2162 2193          cdv->cdv_name = name;
2163 2194          cdv->cdv_type = id;
2164 2195  
2165 2196          if ((ret = ctf_dwarf_isglobal(cup, die, &cdv->cdv_global)) != 0) {
2166 2197                  ctf_free(cdv, sizeof (ctf_dwvar_t));
2167 2198                  ctf_free(name, strlen(name) + 1);
2168 2199                  return (ret);
2169 2200          }
2170 2201  
2171 2202          ctf_list_append(&cup->cu_vars, cdv);
2172 2203          return (0);
2173 2204  }
2174 2205  
2175 2206  /*
2176 2207   * Walk through our set of top-level types and process them.
2177 2208   */
2178 2209  static int
2179 2210  ctf_dwarf_walk_toplevel(ctf_cu_t *cup, Dwarf_Die die)
2180 2211  {
2181 2212          int ret;
2182 2213          Dwarf_Off offset;
2183 2214          Dwarf_Half tag;
2184 2215  
2185 2216          if ((ret = ctf_dwarf_offset(cup, die, &offset)) != 0)
2186 2217                  return (ret);
2187 2218  
2188 2219          if (offset > cup->cu_maxoff) {
2189 2220                  (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
2190 2221                      "die offset %llu beyond maximum for header %llu\n",
2191 2222                      offset, cup->cu_maxoff);
2192 2223                  return (ECTF_CONVBKERR);
2193 2224          }
2194 2225  
2195 2226          if ((ret = ctf_dwarf_tag(cup, die, &tag)) != 0)
2196 2227                  return (ret);
2197 2228  
2198 2229          ret = 0;
2199 2230          switch (tag) {
2200 2231          case DW_TAG_subprogram:
2201 2232                  ctf_dprintf("top level func\n");
2202 2233                  ret = ctf_dwarf_convert_function(cup, die);
2203 2234                  break;
2204 2235          case DW_TAG_variable:
2205 2236                  ctf_dprintf("top level var\n");
2206 2237                  ret = ctf_dwarf_convert_variable(cup, die);
2207 2238                  break;
2208 2239          case DW_TAG_lexical_block:
2209 2240                  ctf_dprintf("top level block\n");
2210 2241                  ret = ctf_dwarf_walk_lexical(cup, die);
2211 2242                  break;
2212 2243          case DW_TAG_enumeration_type:
2213 2244          case DW_TAG_structure_type:
2214 2245          case DW_TAG_typedef:
2215 2246          case DW_TAG_union_type:
2216 2247                  ctf_dprintf("top level type\n");
2217 2248                  ret = ctf_dwarf_convert_type(cup, die, NULL, B_TRUE);
2218 2249                  break;
2219 2250          default:
2220 2251                  break;
2221 2252          }
2222 2253  
2223 2254          return (ret);
2224 2255  }
2225 2256  
2226 2257  
2227 2258  /*
2228 2259   * We're given a node. At this node we need to convert it and then proceed to
2229 2260   * convert any siblings that are associaed with this die.
2230 2261   */
2231 2262  static int
2232 2263  ctf_dwarf_convert_die(ctf_cu_t *cup, Dwarf_Die die)
2233 2264  {
2234 2265          while (die != NULL) {
2235 2266                  int ret;
2236 2267                  Dwarf_Die sib;
2237 2268  
2238 2269                  if ((ret = ctf_dwarf_walk_toplevel(cup, die)) != 0)
2239 2270                          return (ret);
2240 2271  
2241 2272                  if ((ret = ctf_dwarf_sib(cup, die, &sib)) != 0)
2242 2273                          return (ret);
2243 2274                  die = sib;
2244 2275          }
2245 2276          return (0);
2246 2277  }
2247 2278  
2248 2279  static int
2249 2280  ctf_dwarf_fixup_die(ctf_cu_t *cup, boolean_t addpass)
2250 2281  {
2251 2282          ctf_dwmap_t *map;
2252 2283  
2253 2284          for (map = avl_first(&cup->cu_map); map != NULL;
2254 2285              map = AVL_NEXT(&cup->cu_map, map)) {
2255 2286                  int ret;
2256 2287                  if (map->cdm_fix == B_FALSE)
2257 2288                          continue;
2258 2289                  if ((ret = ctf_dwarf_fixup_sou(cup, map->cdm_die, map->cdm_id,
2259 2290                      addpass)) != 0)
2260 2291                          return (ret);
2261 2292          }
2262 2293  
2263 2294          return (0);
2264 2295  }
2265 2296  
2266 2297  /*
2267 2298   * The DWARF information about a symbol and the information in the symbol table
2268 2299   * may not be the same due to symbol reduction that is performed by ld due to a
2269 2300   * mapfile or other such directive. We process weak symbols at a later time.
2270 2301   *
2271 2302   * The following are the rules that we employ:
2272 2303   *
2273 2304   * 1. A DWARF function that is considered exported matches STB_GLOBAL entries
2274 2305   * with the same name.
2275 2306   *
2276 2307   * 2. A DWARF function that is considered exported matches STB_LOCAL entries
2277 2308   * with the same name and the same file. This case may happen due to mapfile
2278 2309   * reduction.
2279 2310   *
2280 2311   * 3. A DWARF function that is not considered exported matches STB_LOCAL entries
2281 2312   * with the same name and the same file.
2282 2313   *
2283 2314   * 4. A DWARF function that has the same name as the symbol table entry, but the
2284 2315   * files do not match. This is considered a 'fuzzy' match. This may also happen
2285 2316   * due to a mapfile reduction. Fuzzy matching is only used when we know that the
2286 2317   * file in question refers to the primary object. This is because when a symbol
2287 2318   * is reduced in a mapfile, it's always going to be tagged as a local value in
2288 2319   * the generated output and it is considered as to belong to the primary file
2289 2320   * which is the first STT_FILE symbol we see.
2290 2321   */
2291 2322  static boolean_t
2292 2323  ctf_dwarf_symbol_match(const char *symtab_file, const char *symtab_name,
2293 2324      uint_t symtab_bind, const char *dwarf_file, const char *dwarf_name,
2294 2325      boolean_t dwarf_global, boolean_t *is_fuzzy)
2295 2326  {
2296 2327          *is_fuzzy = B_FALSE;
2297 2328  
2298 2329          if (symtab_bind != STB_LOCAL && symtab_bind != STB_GLOBAL) {
2299 2330                  return (B_FALSE);
2300 2331          }
2301 2332  
2302 2333          if (strcmp(symtab_name, dwarf_name) != 0) {
2303 2334                  return (B_FALSE);
2304 2335          }
2305 2336  
2306 2337          if (symtab_bind == STB_GLOBAL) {
2307 2338                  return (dwarf_global);
2308 2339          }
2309 2340  
2310 2341          if (strcmp(symtab_file, dwarf_file) == 0) {
2311 2342                  return (B_TRUE);
2312 2343          }
2313 2344  
2314 2345          if (dwarf_global) {
2315 2346                  *is_fuzzy = B_TRUE;
2316 2347                  return (B_TRUE);
2317 2348          }
2318 2349  
2319 2350          return (B_FALSE);
2320 2351  }
2321 2352  
2322 2353  static ctf_dwfunc_t *
2323 2354  ctf_dwarf_match_func(ctf_cu_t *cup, const char *file, const char *name,
2324 2355      uint_t bind, boolean_t primary)
2325 2356  {
2326 2357          ctf_dwfunc_t *cdf, *fuzzy = NULL;
2327 2358  
2328 2359          if (bind == STB_WEAK)
2329 2360                  return (NULL);
2330 2361  
2331 2362          if (bind == STB_LOCAL && (file == NULL || cup->cu_name == NULL))
2332 2363                  return (NULL);
2333 2364  
2334 2365          for (cdf = ctf_list_next(&cup->cu_funcs); cdf != NULL;
2335 2366              cdf = ctf_list_next(cdf)) {
2336 2367                  boolean_t is_fuzzy = B_FALSE;
2337 2368  
2338 2369                  if (ctf_dwarf_symbol_match(file, name, bind, cup->cu_name,
2339 2370                      cdf->cdf_name, cdf->cdf_global, &is_fuzzy)) {
2340 2371                          if (is_fuzzy) {
2341 2372                                  if (primary) {
2342 2373                                          fuzzy = cdf;
2343 2374                                  }
2344 2375                                  continue;
2345 2376                          } else {
2346 2377                                  return (cdf);
2347 2378                          }
2348 2379                  }
2349 2380          }
2350 2381  
2351 2382          return (fuzzy);
2352 2383  }
2353 2384  
2354 2385  static ctf_dwvar_t *
2355 2386  ctf_dwarf_match_var(ctf_cu_t *cup, const char *file, const char *name,
2356 2387      uint_t bind, boolean_t primary)
2357 2388  {
2358 2389          ctf_dwvar_t *cdv, *fuzzy = NULL;
2359 2390  
2360 2391          if (bind == STB_WEAK)
2361 2392                  return (NULL);
2362 2393  
2363 2394          if (bind == STB_LOCAL && (file == NULL || cup->cu_name == NULL))
2364 2395                  return (NULL);
2365 2396  
2366 2397          for (cdv = ctf_list_next(&cup->cu_vars); cdv != NULL;
2367 2398              cdv = ctf_list_next(cdv)) {
2368 2399                  boolean_t is_fuzzy = B_FALSE;
2369 2400  
2370 2401                  if (ctf_dwarf_symbol_match(file, name, bind, cup->cu_name,
2371 2402                      cdv->cdv_name, cdv->cdv_global, &is_fuzzy)) {
2372 2403                          if (is_fuzzy) {
2373 2404                                  if (primary) {
2374 2405                                          fuzzy = cdv;
2375 2406                                  }
2376 2407                          } else {
2377 2408                                  return (cdv);
2378 2409                          }
2379 2410                  }
2380 2411          }
2381 2412  
2382 2413          return (fuzzy);
2383 2414  }
2384 2415  
2385 2416  static int
2386 2417  ctf_dwarf_conv_funcvars_cb(const Elf64_Sym *symp, ulong_t idx,
2387 2418      const char *file, const char *name, boolean_t primary, void *arg)
2388 2419  {
2389 2420          int ret;
2390 2421          uint_t bind, type;
2391 2422          ctf_cu_t *cup = arg;
2392 2423  
2393 2424          bind = GELF_ST_BIND(symp->st_info);
2394 2425          type = GELF_ST_TYPE(symp->st_info);
2395 2426  
2396 2427          /*
2397 2428           * Come back to weak symbols in another pass
2398 2429           */
2399 2430          if (bind == STB_WEAK)
2400 2431                  return (0);
2401 2432  
2402 2433          if (type == STT_OBJECT) {
2403 2434                  ctf_dwvar_t *cdv = ctf_dwarf_match_var(cup, file, name,
2404 2435                      bind, primary);
2405 2436                  if (cdv == NULL)
2406 2437                          return (0);
2407 2438                  ret = ctf_add_object(cup->cu_ctfp, idx, cdv->cdv_type);
2408 2439                  ctf_dprintf("added object %s->%ld\n", name, cdv->cdv_type);
2409 2440          } else {
2410 2441                  ctf_dwfunc_t *cdf = ctf_dwarf_match_func(cup, file, name,
2411 2442                      bind, primary);
2412 2443                  if (cdf == NULL)
2413 2444                          return (0);
2414 2445                  ret = ctf_add_function(cup->cu_ctfp, idx, &cdf->cdf_fip,
2415 2446                      cdf->cdf_argv);
2416 2447                  ctf_dprintf("added function %s\n", name);
2417 2448          }
2418 2449  
2419 2450          if (ret == CTF_ERR) {
2420 2451                  return (ctf_errno(cup->cu_ctfp));
2421 2452          }
2422 2453  
2423 2454          return (0);
2424 2455  }
2425 2456  
2426 2457  static int
2427 2458  ctf_dwarf_conv_funcvars(ctf_cu_t *cup)
2428 2459  {
2429 2460          return (ctf_symtab_iter(cup->cu_ctfp, ctf_dwarf_conv_funcvars_cb, cup));
2430 2461  }
2431 2462  
2432 2463  /*
2433 2464   * If we have a weak symbol, attempt to find the strong symbol it will resolve
2434 2465   * to.  Note: the code where this actually happens is in sym_process() in
2435 2466   * cmd/sgs/libld/common/syms.c
2436 2467   *
2437 2468   * Finding the matching symbol is unfortunately not trivial.  For a symbol to be
2438 2469   * a candidate, it must:
2439 2470   *
2440 2471   * - have the same type (function, object)
2441 2472   * - have the same value (address)
2442 2473   * - have the same size
2443 2474   * - not be another weak symbol
2444 2475   * - belong to the same section (checked via section index)
2445 2476   *
2446 2477   * To perform this check, we first iterate over the symbol table. For each weak
2447 2478   * symbol that we encounter, we then do a second walk over the symbol table,
2448 2479   * calling ctf_dwarf_conv_check_weak(). If a symbol matches the above, then it's
2449 2480   * either a local or global symbol. If we find a global symbol then we go with
2450 2481   * it and stop searching for additional matches.
2451 2482   *
2452 2483   * If instead, we find a local symbol, things are more complicated. The first
2453 2484   * thing we do is to try and see if we have file information about both symbols
2454 2485   * (STT_FILE). If they both have file information and it matches, then we treat
2455 2486   * that as a good match and stop searching for additional matches.
2456 2487   *
2457 2488   * Otherwise, this means we have a non-matching file and a local symbol. We
2458 2489   * treat this as a candidate and if we find a better match (one of the two cases
2459 2490   * above), use that instead. There are two different ways this can happen.
2460 2491   * Either this is a completely different symbol, or it's a once-global symbol
2461 2492   * that was scoped to local via a mapfile.  In the former case, curfile is
2462 2493   * likely inaccurate since the linker does not preserve the needed curfile in
2463 2494   * the order of the symbol table (see the comments about locally scoped symbols
2464 2495   * in libld's update_osym()).  As we can't tell this case from the former one,
2465 2496   * we use this symbol iff no other matching symbol is found.
2466 2497   *
2467 2498   * What we really need here is a SUNW section containing weak<->strong mappings
2468 2499   * that we can consume.
2469 2500   */
2470 2501  typedef struct ctf_dwarf_weak_arg {
2471 2502          const Elf64_Sym *cweak_symp;
2472 2503          const char *cweak_file;
2473 2504          boolean_t cweak_candidate;
2474 2505          ulong_t cweak_idx;
2475 2506  } ctf_dwarf_weak_arg_t;
2476 2507  
2477 2508  static int
2478 2509  ctf_dwarf_conv_check_weak(const Elf64_Sym *symp, ulong_t idx, const char *file,
2479 2510      const char *name, boolean_t primary, void *arg)
2480 2511  {
2481 2512          ctf_dwarf_weak_arg_t *cweak = arg;
2482 2513  
2483 2514          const Elf64_Sym *wsymp = cweak->cweak_symp;
2484 2515  
2485 2516          ctf_dprintf("comparing weak to %s\n", name);
2486 2517  
2487 2518          if (GELF_ST_BIND(symp->st_info) == STB_WEAK) {
2488 2519                  return (0);
2489 2520          }
2490 2521  
2491 2522          if (GELF_ST_TYPE(wsymp->st_info) != GELF_ST_TYPE(symp->st_info)) {
2492 2523                  return (0);
2493 2524          }
2494 2525  
2495 2526          if (wsymp->st_value != symp->st_value) {
2496 2527                  return (0);
2497 2528          }
2498 2529  
2499 2530          if (wsymp->st_size != symp->st_size) {
2500 2531                  return (0);
2501 2532          }
2502 2533  
2503 2534          if (wsymp->st_shndx != symp->st_shndx) {
2504 2535                  return (0);
2505 2536          }
2506 2537  
2507 2538          /*
2508 2539           * Check if it's a weak candidate.
2509 2540           */
2510 2541          if (GELF_ST_BIND(symp->st_info) == STB_LOCAL &&
2511 2542              (file == NULL || cweak->cweak_file == NULL ||
2512 2543              strcmp(file, cweak->cweak_file) != 0)) {
2513 2544                  cweak->cweak_candidate = B_TRUE;
2514 2545                  cweak->cweak_idx = idx;
2515 2546                  return (0);
2516 2547          }
2517 2548  
2518 2549          /*
2519 2550           * Found a match, break.
2520 2551           */
2521 2552          cweak->cweak_idx = idx;
2522 2553          return (1);
2523 2554  }
2524 2555  
2525 2556  static int
2526 2557  ctf_dwarf_duplicate_sym(ctf_cu_t *cup, ulong_t idx, ulong_t matchidx)
2527 2558  {
2528 2559          ctf_id_t id = ctf_lookup_by_symbol(cup->cu_ctfp, matchidx);
2529 2560  
2530 2561          /*
2531 2562           * If we matched something that for some reason didn't have type data,
2532 2563           * we don't consider that a fatal error and silently swallow it.
2533 2564           */
2534 2565          if (id == CTF_ERR) {
2535 2566                  if (ctf_errno(cup->cu_ctfp) == ECTF_NOTYPEDAT)
2536 2567                          return (0);
2537 2568                  else
2538 2569                          return (ctf_errno(cup->cu_ctfp));
2539 2570          }
2540 2571  
2541 2572          if (ctf_add_object(cup->cu_ctfp, idx, id) == CTF_ERR)
2542 2573                  return (ctf_errno(cup->cu_ctfp));
2543 2574  
2544 2575          return (0);
2545 2576  }
2546 2577  
2547 2578  static int
2548 2579  ctf_dwarf_duplicate_func(ctf_cu_t *cup, ulong_t idx, ulong_t matchidx)
2549 2580  {
2550 2581          int ret;
2551 2582          ctf_funcinfo_t fip;
2552 2583          ctf_id_t *args = NULL;
2553 2584  
2554 2585          if (ctf_func_info(cup->cu_ctfp, matchidx, &fip) == CTF_ERR) {
2555 2586                  if (ctf_errno(cup->cu_ctfp) == ECTF_NOFUNCDAT)
2556 2587                          return (0);
2557 2588                  else
2558 2589                          return (ctf_errno(cup->cu_ctfp));
2559 2590          }
2560 2591  
2561 2592          if (fip.ctc_argc != 0) {
2562 2593                  args = ctf_alloc(sizeof (ctf_id_t) * fip.ctc_argc);
2563 2594                  if (args == NULL)
2564 2595                          return (ENOMEM);
2565 2596  
2566 2597                  if (ctf_func_args(cup->cu_ctfp, matchidx, fip.ctc_argc, args) ==
2567 2598                      CTF_ERR) {
2568 2599                          ctf_free(args, sizeof (ctf_id_t) * fip.ctc_argc);
2569 2600                          return (ctf_errno(cup->cu_ctfp));
2570 2601                  }
2571 2602          }
2572 2603  
2573 2604          ret = ctf_add_function(cup->cu_ctfp, idx, &fip, args);
2574 2605          if (args != NULL)
2575 2606                  ctf_free(args, sizeof (ctf_id_t) * fip.ctc_argc);
2576 2607          if (ret == CTF_ERR)
2577 2608                  return (ctf_errno(cup->cu_ctfp));
2578 2609  
2579 2610          return (0);
2580 2611  }
2581 2612  
2582 2613  static int
2583 2614  ctf_dwarf_conv_weaks_cb(const Elf64_Sym *symp, ulong_t idx, const char *file,
2584 2615      const char *name, boolean_t primary, void *arg)
2585 2616  {
2586 2617          int ret, type;
2587 2618          ctf_dwarf_weak_arg_t cweak;
2588 2619          ctf_cu_t *cup = arg;
2589 2620  
2590 2621          /*
2591 2622           * We only care about weak symbols.
2592 2623           */
2593 2624          if (GELF_ST_BIND(symp->st_info) != STB_WEAK)
2594 2625                  return (0);
2595 2626  
2596 2627          type = GELF_ST_TYPE(symp->st_info);
2597 2628          ASSERT(type == STT_OBJECT || type == STT_FUNC);
2598 2629  
2599 2630          /*
2600 2631           * For each weak symbol we encounter, we need to do a second iteration
2601 2632           * to try and find a match. We should probably think about other
2602 2633           * techniques to try and save us time in the future.
2603 2634           */
2604 2635          cweak.cweak_symp = symp;
2605 2636          cweak.cweak_file = file;
2606 2637          cweak.cweak_candidate = B_FALSE;
2607 2638          cweak.cweak_idx = 0;
2608 2639  
2609 2640          ctf_dprintf("Trying to find weak equiv for %s\n", name);
2610 2641  
2611 2642          ret = ctf_symtab_iter(cup->cu_ctfp, ctf_dwarf_conv_check_weak, &cweak);
2612 2643          VERIFY(ret == 0 || ret == 1);
2613 2644  
2614 2645          /*
2615 2646           * Nothing was ever found, we're not going to add anything for this
2616 2647           * entry.
2617 2648           */
2618 2649          if (ret == 0 && cweak.cweak_candidate == B_FALSE) {
2619 2650                  ctf_dprintf("found no weak match for %s\n", name);
2620 2651                  return (0);
2621 2652          }
2622 2653  
2623 2654          /*
2624 2655           * Now, finally go and add the type based on the match.
2625 2656           */
2626 2657          ctf_dprintf("matched weak symbol %lu to %lu\n", idx, cweak.cweak_idx);
2627 2658          if (type == STT_OBJECT) {
2628 2659                  ret = ctf_dwarf_duplicate_sym(cup, idx, cweak.cweak_idx);
2629 2660          } else {
2630 2661                  ret = ctf_dwarf_duplicate_func(cup, idx, cweak.cweak_idx);
2631 2662          }
2632 2663  
2633 2664          return (ret);
2634 2665  }
2635 2666  
2636 2667  static int
2637 2668  ctf_dwarf_conv_weaks(ctf_cu_t *cup)
2638 2669  {
2639 2670          return (ctf_symtab_iter(cup->cu_ctfp, ctf_dwarf_conv_weaks_cb, cup));
2640 2671  }
2641 2672  
2642 2673  /* ARGSUSED */
2643 2674  static int
2644 2675  ctf_dwarf_convert_one(void *arg, void *unused)
2645 2676  {
2646 2677          int ret;
2647 2678          ctf_file_t *dedup;
2648 2679          ctf_cu_t *cup = arg;
2649 2680  
2650 2681          ctf_dprintf("converting die: %s\n", cup->cu_name);
2651 2682          ctf_dprintf("max offset: %x\n", cup->cu_maxoff);
2652 2683          VERIFY(cup != NULL);
2653 2684  
2654 2685          ret = ctf_dwarf_convert_die(cup, cup->cu_cu);
2655 2686          ctf_dprintf("ctf_dwarf_convert_die (%s) returned %d\n", cup->cu_name,
2656 2687              ret);
2657 2688          if (ret != 0) {
2658 2689                  return (ret);
2659 2690          }
2660 2691          if (ctf_update(cup->cu_ctfp) != 0) {
2661 2692                  return (ctf_dwarf_error(cup, cup->cu_ctfp, 0,
2662 2693                      "failed to update output ctf container"));
2663 2694          }
2664 2695  
2665 2696          ret = ctf_dwarf_fixup_die(cup, B_FALSE);
2666 2697          ctf_dprintf("ctf_dwarf_fixup_die (%s) returned %d\n", cup->cu_name,
2667 2698              ret);
2668 2699          if (ret != 0) {
2669 2700                  return (ret);
2670 2701          }
2671 2702          if (ctf_update(cup->cu_ctfp) != 0) {
2672 2703                  return (ctf_dwarf_error(cup, cup->cu_ctfp, 0,
2673 2704                      "failed to update output ctf container"));
2674 2705          }
2675 2706  
2676 2707          ret = ctf_dwarf_fixup_die(cup, B_TRUE);
2677 2708          ctf_dprintf("ctf_dwarf_fixup_die (%s) returned %d\n", cup->cu_name,
2678 2709              ret);
2679 2710          if (ret != 0) {
2680 2711                  return (ret);
2681 2712          }
2682 2713          if (ctf_update(cup->cu_ctfp) != 0) {
2683 2714                  return (ctf_dwarf_error(cup, cup->cu_ctfp, 0,
2684 2715                      "failed to update output ctf container"));
2685 2716          }
2686 2717  
2687 2718  
2688 2719          if ((ret = ctf_dwarf_conv_funcvars(cup)) != 0) {
2689 2720                  return (ctf_dwarf_error(cup, NULL, ret,
2690 2721                      "failed to convert strong functions and variables"));
2691 2722          }
2692 2723  
2693 2724          if (ctf_update(cup->cu_ctfp) != 0) {
2694 2725                  return (ctf_dwarf_error(cup, cup->cu_ctfp, 0,
2695 2726                      "failed to update output ctf container"));
2696 2727          }
2697 2728  
2698 2729          if (cup->cu_doweaks == B_TRUE) {
2699 2730                  if ((ret = ctf_dwarf_conv_weaks(cup)) != 0) {
2700 2731                          return (ctf_dwarf_error(cup, NULL, ret,
2701 2732                              "failed to convert weak functions and variables"));
2702 2733                  }
2703 2734  
2704 2735                  if (ctf_update(cup->cu_ctfp) != 0) {
2705 2736                          return (ctf_dwarf_error(cup, cup->cu_ctfp, 0,
2706 2737                              "failed to update output ctf container"));
2707 2738                  }
2708 2739          }
2709 2740  
2710 2741          ctf_phase_dump(cup->cu_ctfp, "pre-dwarf-dedup", cup->cu_name);
2711 2742          ctf_dprintf("adding inputs for dedup\n");
2712 2743          if ((ret = ctf_merge_add(cup->cu_cmh, cup->cu_ctfp)) != 0) {
2713 2744                  return (ctf_dwarf_error(cup, NULL, ret,
2714 2745                      "failed to add inputs for merge"));
2715 2746          }
2716 2747  
2717 2748          ctf_dprintf("starting dedup of %s\n", cup->cu_name);
2718 2749          if ((ret = ctf_merge_dedup(cup->cu_cmh, &dedup)) != 0) {
2719 2750                  return (ctf_dwarf_error(cup, NULL, ret,
2720 2751                      "failed to deduplicate die"));
2721 2752          }
2722 2753          ctf_close(cup->cu_ctfp);
2723 2754          cup->cu_ctfp = dedup;
2724 2755          ctf_phase_dump(cup->cu_ctfp, "post-dwarf-dedup", cup->cu_name);
2725 2756  
2726 2757          return (0);
2727 2758  }
2728 2759  
2729 2760  /*
2730 2761   * Note, we expect that if we're returning a ctf_file_t from one of the dies,
2731 2762   * say in the single node case, it's been saved and the entry here has been set
2732 2763   * to NULL, which ctf_close happily ignores.
2733 2764   */
2734 2765  static void
2735 2766  ctf_dwarf_free_die(ctf_cu_t *cup)
2736 2767  {
2737 2768          ctf_dwfunc_t *cdf, *ndf;
2738 2769          ctf_dwvar_t *cdv, *ndv;
2739 2770          ctf_dwbitf_t *cdb, *ndb;
2740 2771          ctf_dwmap_t *map;
2741 2772          void *cookie;
2742 2773          Dwarf_Error derr;
2743 2774  
2744 2775          ctf_dprintf("Beginning to free die: %p\n", cup);
2745 2776          cup->cu_elf = NULL;
2746 2777          ctf_dprintf("Trying to free name: %p\n", cup->cu_name);
2747 2778          if (cup->cu_name != NULL)
2748 2779                  ctf_free(cup->cu_name, strlen(cup->cu_name) + 1);
2749 2780          ctf_dprintf("Trying to free merge handle: %p\n", cup->cu_cmh);
2750 2781          if (cup->cu_cmh != NULL) {
2751 2782                  ctf_merge_fini(cup->cu_cmh);
2752 2783                  cup->cu_cmh = NULL;
2753 2784          }
2754 2785  
2755 2786          ctf_dprintf("Trying to free functions\n");
2756 2787          for (cdf = ctf_list_next(&cup->cu_funcs); cdf != NULL; cdf = ndf) {
2757 2788                  ndf = ctf_list_next(cdf);
2758 2789                  ctf_free(cdf->cdf_name, strlen(cdf->cdf_name) + 1);
2759 2790                  if (cdf->cdf_fip.ctc_argc != 0) {
2760 2791                          ctf_free(cdf->cdf_argv,
2761 2792                              sizeof (ctf_id_t) * cdf->cdf_fip.ctc_argc);
2762 2793                  }
2763 2794                  ctf_free(cdf, sizeof (ctf_dwfunc_t));
2764 2795          }
2765 2796  
2766 2797          ctf_dprintf("Trying to free variables\n");
2767 2798          for (cdv = ctf_list_next(&cup->cu_vars); cdv != NULL; cdv = ndv) {
2768 2799                  ndv = ctf_list_next(cdv);
2769 2800                  ctf_free(cdv->cdv_name, strlen(cdv->cdv_name) + 1);
2770 2801                  ctf_free(cdv, sizeof (ctf_dwvar_t));
2771 2802          }
2772 2803  
2773 2804          ctf_dprintf("Trying to free bitfields\n");
2774 2805          for (cdb = ctf_list_next(&cup->cu_bitfields); cdb != NULL; cdb = ndb) {
2775 2806                  ndb = ctf_list_next(cdb);
2776 2807                  ctf_free(cdb, sizeof (ctf_dwbitf_t));
2777 2808          }
2778 2809  
2779 2810          ctf_dprintf("Trying to clean up dwarf_t: %p\n", cup->cu_dwarf);
2780 2811          if (cup->cu_dwarf != NULL)
2781 2812                  (void) dwarf_finish(cup->cu_dwarf, &derr);
2782 2813          cup->cu_dwarf = NULL;
2783 2814          ctf_close(cup->cu_ctfp);
2784 2815  
2785 2816          cookie = NULL;
2786 2817          while ((map = avl_destroy_nodes(&cup->cu_map, &cookie)) != NULL) {
2787 2818                  ctf_free(map, sizeof (ctf_dwmap_t));
2788 2819          }
2789 2820          avl_destroy(&cup->cu_map);
2790 2821          cup->cu_errbuf = NULL;
2791 2822  }
2792 2823  
2793 2824  static void
2794 2825  ctf_dwarf_free_dies(ctf_cu_t *cdies, int ndies)
2795 2826  {
2796 2827          int i;
2797 2828  
2798 2829          ctf_dprintf("Beginning to free dies\n");
2799 2830          for (i = 0; i < ndies; i++) {
2800 2831                  ctf_dwarf_free_die(&cdies[i]);
2801 2832          }
2802 2833  
2803 2834          ctf_free(cdies, sizeof (ctf_cu_t) * ndies);
2804 2835  }
2805 2836  
2806 2837  static int
2807 2838  ctf_dwarf_count_dies(Dwarf_Debug dw, Dwarf_Error *derr, int *ndies,
2808 2839      char *errbuf, size_t errlen)
2809 2840  {
2810 2841          int ret;
2811 2842          Dwarf_Half vers;
2812 2843          Dwarf_Unsigned nexthdr;
2813 2844  
2814 2845          while ((ret = dwarf_next_cu_header(dw, NULL, &vers, NULL, NULL,
2815 2846              &nexthdr, derr)) != DW_DLV_NO_ENTRY) {
2816 2847                  if (ret != DW_DLV_OK) {
2817 2848                          (void) snprintf(errbuf, errlen,
2818 2849                              "file does not contain valid DWARF data: %s\n",
2819 2850                              dwarf_errmsg(*derr));
2820 2851                          return (ECTF_CONVBKERR);
2821 2852                  }
2822 2853  
2823 2854                  if (vers != DWARF_VERSION_TWO) {
2824 2855                          (void) snprintf(errbuf, errlen,
2825 2856                              "unsupported DWARF version: %d\n", vers);
2826 2857                          return (ECTF_CONVBKERR);
2827 2858                  }
2828 2859                  *ndies = *ndies + 1;
2829 2860          }
2830 2861  
2831 2862          return (0);
2832 2863  }
2833 2864  
2834 2865  static int
2835 2866  ctf_dwarf_init_die(int fd, Elf *elf, ctf_cu_t *cup, int ndie, char *errbuf,
2836 2867      size_t errlen)
2837 2868  {
2838 2869          int ret;
2839 2870          Dwarf_Unsigned hdrlen, abboff, nexthdr;
2840 2871          Dwarf_Half addrsz;
2841 2872          Dwarf_Unsigned offset = 0;
2842 2873          Dwarf_Error derr;
2843 2874  
2844 2875          while ((ret = dwarf_next_cu_header(cup->cu_dwarf, &hdrlen, NULL,
2845 2876              &abboff, &addrsz, &nexthdr, &derr)) != DW_DLV_NO_ENTRY) {
2846 2877                  char *name;
2847 2878                  Dwarf_Die cu, child;
2848 2879  
2849 2880                  /* Based on the counting above, we should be good to go */
2850 2881                  VERIFY(ret == DW_DLV_OK);
2851 2882                  if (ndie > 0) {
2852 2883                          ndie--;
2853 2884                          offset = nexthdr;
2854 2885                          continue;
2855 2886                  }
2856 2887  
2857 2888                  /*
2858 2889                   * Compilers are apparently inconsistent. Some emit no DWARF for
2859 2890                   * empty files and others emit empty compilation unit.
2860 2891                   */
2861 2892                  cup->cu_voidtid = CTF_ERR;
2862 2893                  cup->cu_longtid = CTF_ERR;
2863 2894                  cup->cu_elf = elf;
2864 2895                  cup->cu_maxoff = nexthdr - 1;
2865 2896                  cup->cu_ctfp = ctf_fdcreate(fd, &ret);
2866 2897                  if (cup->cu_ctfp == NULL)
2867 2898                          return (ret);
2868 2899  
2869 2900                  avl_create(&cup->cu_map, ctf_dwmap_comp, sizeof (ctf_dwmap_t),
2870 2901                      offsetof(ctf_dwmap_t, cdm_avl));
2871 2902                  cup->cu_errbuf = errbuf;
2872 2903                  cup->cu_errlen = errlen;
2873 2904                  bzero(&cup->cu_vars, sizeof (ctf_list_t));
2874 2905                  bzero(&cup->cu_funcs, sizeof (ctf_list_t));
2875 2906                  bzero(&cup->cu_bitfields, sizeof (ctf_list_t));
2876 2907  
2877 2908                  if ((ret = ctf_dwarf_die_elfenc(elf, cup, errbuf,
2878 2909                      errlen)) != 0)
2879 2910                          return (ret);
2880 2911  
2881 2912                  if ((ret = ctf_dwarf_sib(cup, NULL, &cu)) != 0)
2882 2913                          return (ret);
2883 2914  
2884 2915                  if (cu == NULL) {
2885 2916                          (void) snprintf(errbuf, errlen,
2886 2917                              "file does not contain DWARF data");
2887 2918                          return (ECTF_CONVNODEBUG);
2888 2919                  }
2889 2920  
2890 2921                  if ((ret = ctf_dwarf_child(cup, cu, &child)) != 0)
2891 2922                          return (ret);
2892 2923  
2893 2924                  if (child == NULL) {
2894 2925                          (void) snprintf(errbuf, errlen,
2895 2926                              "file does not contain DWARF data");
2896 2927                          return (ECTF_CONVNODEBUG);
2897 2928                  }
2898 2929  
2899 2930                  cup->cu_cuoff = offset;
2900 2931                  cup->cu_cu = child;
2901 2932  
2902 2933                  if ((cup->cu_cmh = ctf_merge_init(fd, &ret)) == NULL)
2903 2934                          return (ret);
2904 2935  
2905 2936                  if (ctf_dwarf_string(cup, cu, DW_AT_name, &name) == 0) {
2906 2937                          size_t len = strlen(name) + 1;
2907 2938                          char *b = basename(name);
2908 2939                          cup->cu_name = strdup(b);
2909 2940                          ctf_free(name, len);
2910 2941                  }
2911 2942                  break;
2912 2943          }
2913 2944  
2914 2945          return (0);
2915 2946  }
2916 2947  
2917 2948  /*
2918 2949   * This is our only recourse to identify a C source file that is missing debug
2919 2950   * info: it will be mentioned as an STT_FILE, but not have a compile unit entry.
2920 2951   * (A traditional ctfmerge works on individual files, so can identify missing
2921 2952   * DWARF more directly, via ctf_has_c_source() on the .o file.)
2922 2953   *
2923 2954   * As we operate on basenames, this can of course miss some cases, but it's
2924 2955   * better than not checking at all.
2925 2956   *
2926 2957   * We explicitly whitelist some CRT components.  Failing that, there's always
2927 2958   * the -m option.
2928 2959   */
2929 2960  static boolean_t
2930 2961  c_source_has_debug(const char *file, ctf_cu_t *cus, size_t nr_cus)
2931 2962  {
2932 2963          const char *basename = strrchr(file, '/');
2933 2964  
2934 2965          if (basename == NULL)
2935 2966                  basename = file;
2936 2967          else
2937 2968                  basename++;
2938 2969  
2939 2970          if (strcmp(basename, "common-crt.c") == 0 ||
2940 2971              strcmp(basename, "gmon.c") == 0 ||
2941 2972              strcmp(basename, "dlink_init.c") == 0 ||
2942 2973              strcmp(basename, "dlink_common.c") == 0 ||
2943 2974              strncmp(basename, "crt", strlen("crt")) == 0 ||
2944 2975              strncmp(basename, "values-", strlen("values-")) == 0)
2945 2976                  return (B_TRUE);
2946 2977  
2947 2978          for (size_t i = 0; i < nr_cus; i++) {
2948 2979                  if (strcmp(basename, cus[i].cu_name) == 0)
2949 2980                          return (B_TRUE);
2950 2981          }
2951 2982  
2952 2983          return (B_FALSE);
2953 2984  }
2954 2985  
2955 2986  static int
2956 2987  ctf_dwarf_check_missing(ctf_cu_t *cus, size_t nr_cus, Elf *elf,
2957 2988      char *errmsg, size_t errlen)
2958 2989  {
2959 2990          Elf_Scn *scn, *strscn;
2960 2991          Elf_Data *data, *strdata;
2961 2992          GElf_Shdr shdr;
2962 2993          ulong_t i;
2963 2994  
2964 2995          scn = NULL;
2965 2996          while ((scn = elf_nextscn(elf, scn)) != NULL) {
2966 2997                  if (gelf_getshdr(scn, &shdr) == NULL) {
2967 2998                          (void) snprintf(errmsg, errlen,
2968 2999                              "failed to get section header: %s\n",
2969 3000                              elf_errmsg(elf_errno()));
2970 3001                          return (EINVAL);
2971 3002                  }
2972 3003  
2973 3004                  if (shdr.sh_type == SHT_SYMTAB)
2974 3005                          break;
2975 3006          }
2976 3007  
2977 3008          if (scn == NULL)
2978 3009                  return (0);
2979 3010  
2980 3011          if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL) {
2981 3012                  (void) snprintf(errmsg, errlen,
2982 3013                      "failed to get str section: %s\n",
2983 3014                      elf_errmsg(elf_errno()));
2984 3015                  return (EINVAL);
2985 3016          }
2986 3017  
2987 3018          if ((data = elf_getdata(scn, NULL)) == NULL) {
2988 3019                  (void) snprintf(errmsg, errlen, "failed to read section: %s\n",
2989 3020                      elf_errmsg(elf_errno()));
2990 3021                  return (EINVAL);
2991 3022          }
2992 3023  
2993 3024          if ((strdata = elf_getdata(strscn, NULL)) == NULL) {
2994 3025                  (void) snprintf(errmsg, errlen,
2995 3026                      "failed to read string table: %s\n",
2996 3027                      elf_errmsg(elf_errno()));
2997 3028                  return (EINVAL);
2998 3029          }
2999 3030  
3000 3031          for (i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
3001 3032                  GElf_Sym sym;
3002 3033                  const char *file;
3003 3034                  size_t len;
3004 3035  
3005 3036                  if (gelf_getsym(data, i, &sym) == NULL) {
3006 3037                          (void) snprintf(errmsg, errlen,
3007 3038                              "failed to read sym %lu: %s\n",
3008 3039                              i, elf_errmsg(elf_errno()));
3009 3040                          return (EINVAL);
3010 3041                  }
3011 3042  
3012 3043                  if (GELF_ST_TYPE(sym.st_info) != STT_FILE)
3013 3044                          continue;
3014 3045  
3015 3046                  file = (const char *)((uintptr_t)strdata->d_buf + sym.st_name);
3016 3047                  len = strlen(file);
3017 3048                  if (len < 2 || strncmp(".c", &file[len - 2], 2) != 0)
3018 3049                          continue;
3019 3050  
3020 3051                  if (!c_source_has_debug(file, cus, nr_cus)) {
3021 3052                          (void) snprintf(errmsg, errlen,
3022 3053                              "file %s is missing debug info\n", file);
3023 3054                          return (ECTF_CONVNODEBUG);
3024 3055                  }
3025 3056          }
3026 3057  
3027 3058          return (0);
3028 3059  }
3029 3060  
3030 3061  int
3031 3062  ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, uint_t flags,
3032 3063      ctf_file_t **fpp, char *errbuf, size_t errlen)
3033 3064  {
3034 3065          int err, ret, ndies, i;
3035 3066          Dwarf_Debug dw;
3036 3067          Dwarf_Error derr;
3037 3068          ctf_cu_t *cdies = NULL, *cup;
3038 3069          workq_t *wqp = NULL;
3039 3070  
3040 3071          *fpp = NULL;
3041 3072  
3042 3073          ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dw, &derr);
3043 3074          if (ret != DW_DLV_OK) {
3044 3075                  if (ret == DW_DLV_NO_ENTRY ||
3045 3076                      dwarf_errno(derr) == DW_DLE_DEBUG_INFO_NULL) {
3046 3077                          (void) snprintf(errbuf, errlen,
3047 3078                              "file does not contain DWARF data\n");
3048 3079                          return (ECTF_CONVNODEBUG);
3049 3080                  }
3050 3081  
3051 3082                  (void) snprintf(errbuf, errlen,
3052 3083                      "dwarf_elf_init() failed: %s\n", dwarf_errmsg(derr));
3053 3084                  return (ECTF_CONVBKERR);
3054 3085          }
3055 3086  
3056 3087          /*
3057 3088           * Iterate over all of the compilation units and create a ctf_cu_t for
3058 3089           * each of them.  This is used to determine if we have zero, one, or
3059 3090           * multiple dies to convert. If we have zero, that's an error. If
3060 3091           * there's only one die, that's the simple case.  No merge needed and
3061 3092           * only a single Dwarf_Debug as well.
3062 3093           */
3063 3094          ndies = 0;
3064 3095          err = ctf_dwarf_count_dies(dw, &derr, &ndies, errbuf, errlen);
3065 3096  
3066 3097          ctf_dprintf("found %d DWARF CUs\n", ndies);
3067 3098  
3068 3099          if (ndies == 0) {
3069 3100                  (void) snprintf(errbuf, errlen,
3070 3101                      "file does not contain DWARF data\n");
3071 3102                  return (ECTF_CONVNODEBUG);
3072 3103          }
3073 3104  
3074 3105          (void) dwarf_finish(dw, &derr);
3075 3106          cdies = ctf_alloc(sizeof (ctf_cu_t) * ndies);
3076 3107          if (cdies == NULL) {
3077 3108                  return (ENOMEM);
3078 3109          }
3079 3110  
3080 3111          bzero(cdies, sizeof (ctf_cu_t) * ndies);
3081 3112  
3082 3113          for (i = 0; i < ndies; i++) {
3083 3114                  cup = &cdies[i];
3084 3115                  ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL,
3085 3116                      &cup->cu_dwarf, &derr);
3086 3117                  if (ret != 0) {
3087 3118                          ctf_free(cdies, sizeof (ctf_cu_t) * ndies);
3088 3119                          (void) snprintf(errbuf, errlen,
3089 3120                              "failed to initialize DWARF: %s\n",
3090 3121                              dwarf_errmsg(derr));
3091 3122                          return (ECTF_CONVBKERR);
3092 3123                  }
3093 3124  
3094 3125                  err = ctf_dwarf_init_die(fd, elf, cup, i, errbuf, errlen);
3095 3126                  if (err != 0)
3096 3127                          goto out;
3097 3128  
3098 3129                  cup->cu_doweaks = ndies > 1 ? B_FALSE : B_TRUE;
3099 3130          }
3100 3131  
3101 3132          if (!(flags & CTF_ALLOW_MISSING_DEBUG) &&
3102 3133              (err = ctf_dwarf_check_missing(cdies, ndies,
3103 3134              elf, errbuf, errlen)) != 0)
3104 3135                  goto out;
3105 3136  
3106 3137          /*
3107 3138           * If we only have one compilation unit, there's no reason to use
3108 3139           * multiple threads, even if the user requested them. After all, they
3109 3140           * just gave us an upper bound.
3110 3141           */
3111 3142          if (ndies == 1)
3112 3143                  nthrs = 1;
3113 3144  
3114 3145          if (workq_init(&wqp, nthrs) == -1) {
3115 3146                  err = errno;
3116 3147                  goto out;
3117 3148          }
3118 3149  
3119 3150          for (i = 0; i < ndies; i++) {
3120 3151                  cup = &cdies[i];
3121 3152                  ctf_dprintf("adding cu %s: %p, %x %x\n", cup->cu_name,
3122 3153                      cup->cu_cu, cup->cu_cuoff, cup->cu_maxoff);
3123 3154                  if (workq_add(wqp, cup) == -1) {
3124 3155                          err = errno;
3125 3156                          goto out;
3126 3157                  }
3127 3158          }
3128 3159  
3129 3160          ret = workq_work(wqp, ctf_dwarf_convert_one, NULL, &err);
3130 3161          if (ret == WORKQ_ERROR) {
3131 3162                  err = errno;
3132 3163                  goto out;
3133 3164          } else if (ret == WORKQ_UERROR) {
3134 3165                  ctf_dprintf("internal convert failed: %s\n",
3135 3166                      ctf_errmsg(err));
3136 3167                  goto out;
3137 3168          }
3138 3169  
3139 3170          ctf_dprintf("Determining next phase: have %d CUs\n", ndies);
3140 3171          if (ndies != 1) {
3141 3172                  ctf_merge_t *cmp;
3142 3173  
3143 3174                  cmp = ctf_merge_init(fd, &err);
3144 3175                  if (cmp == NULL)
3145 3176                          goto out;
3146 3177  
3147 3178                  ctf_dprintf("setting threads\n");
3148 3179                  if ((err = ctf_merge_set_nthreads(cmp, nthrs)) != 0) {
3149 3180                          ctf_merge_fini(cmp);
3150 3181                          goto out;
3151 3182                  }
3152 3183  
3153 3184                  for (i = 0; i < ndies; i++) {
3154 3185                          cup = &cdies[i];
3155 3186                          if ((err = ctf_merge_add(cmp, cup->cu_ctfp)) != 0) {
3156 3187                                  ctf_merge_fini(cmp);
3157 3188                                  goto out;
3158 3189                          }
3159 3190                  }
3160 3191  
3161 3192                  ctf_dprintf("performing merge\n");
3162 3193                  err = ctf_merge_merge(cmp, fpp);
3163 3194                  if (err != 0) {
3164 3195                          ctf_dprintf("failed merge!\n");
3165 3196                          *fpp = NULL;
3166 3197                          ctf_merge_fini(cmp);
3167 3198                          goto out;
3168 3199                  }
3169 3200                  ctf_merge_fini(cmp);
3170 3201                  err = 0;
3171 3202                  ctf_dprintf("successfully converted!\n");
3172 3203          } else {
3173 3204                  err = 0;
3174 3205                  *fpp = cdies->cu_ctfp;
3175 3206                  cdies->cu_ctfp = NULL;
3176 3207                  ctf_dprintf("successfully converted!\n");
3177 3208          }
3178 3209  
3179 3210  out:
3180 3211          workq_fini(wqp);
3181 3212          ctf_dwarf_free_dies(cdies, ndies);
3182 3213          return (err);
3183 3214  }
  
    | 
      ↓ open down ↓ | 
    1543 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX