The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_ctf.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: db_ctf.c,v 1.33 2022/08/14 14:57:38 millert Exp $     */
    2 
    3 /*
    4  * Copyright (c) 2016-2017 Martin Pieuchot
    5  * Copyright (c) 2016 Jasper Lievisse Adriaanse <jasper@openbsd.org>
    6  *
    7  * Permission to use, copy, modify, and distribute this software for any
    8  * purpose with or without fee is hereby granted, provided that the above
    9  * copyright notice and this permission notice appear in all copies.
   10  *
   11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   18  */
   19 
   20 #include <sys/param.h>
   21 #include <sys/stdint.h>
   22 #include <sys/systm.h>
   23 #include <sys/exec.h>
   24 
   25 #include <machine/db_machdep.h>
   26 
   27 #include <ddb/db_extern.h>
   28 #include <ddb/db_command.h>
   29 #include <ddb/db_elf.h>
   30 #include <ddb/db_lex.h>
   31 #include <ddb/db_output.h>
   32 #include <ddb/db_sym.h>
   33 #include <ddb/db_access.h>
   34 
   35 #include <sys/exec_elf.h>
   36 #include <sys/ctf.h>
   37 #include <sys/malloc.h>
   38 #include <lib/libz/zlib.h>
   39 
   40 extern db_symtab_t              db_symtab;
   41 
   42 struct ddb_ctf {
   43         struct ctf_header       *cth;
   44         const char              *rawctf;        /* raw .SUNW_ctf section */
   45         size_t                   rawctflen;     /* raw .SUNW_ctf section size */
   46         const char              *data;          /* decompressed CTF data */
   47         size_t                   dlen;          /* decompressed CTF data size */
   48         char                    *strtab;        /* ELF string table */
   49         uint32_t                 ctf_found;
   50 };
   51 
   52 struct ddb_ctf db_ctf;
   53 
   54 static const char       *db_ctf_off2name(uint32_t);
   55 static Elf_Sym          *db_ctf_idx2sym(size_t *, uint8_t);
   56 static char             *db_ctf_decompress(const char *, size_t, size_t);
   57 
   58 const struct ctf_type   *db_ctf_type_by_name(const char *, unsigned int);
   59 const struct ctf_type   *db_ctf_type_by_symbol(Elf_Sym *);
   60 const struct ctf_type   *db_ctf_type_by_index(uint16_t);
   61 void                     db_ctf_pprint(const struct ctf_type *, vaddr_t);
   62 void                     db_ctf_pprint_struct(const struct ctf_type *, vaddr_t);
   63 void                     db_ctf_pprint_ptr(const struct ctf_type *, vaddr_t);
   64 
   65 /*
   66  * Entrypoint to verify CTF presence, initialize the header, decompress
   67  * the data, etc.
   68  */
   69 void
   70 db_ctf_init(void)
   71 {
   72         db_symtab_t *stab = &db_symtab;
   73         size_t rawctflen;
   74 
   75         /* Assume nothing was correct found until proven otherwise. */
   76         db_ctf.ctf_found = 0;
   77 
   78         if (stab->private == NULL)
   79                 return;
   80 
   81         db_ctf.strtab = db_elf_find_strtab(stab);
   82         if (db_ctf.strtab == NULL)
   83                 return;
   84 
   85         db_ctf.rawctf = db_elf_find_section(stab, &rawctflen, ELF_CTF);
   86         if (db_ctf.rawctf == NULL)
   87                 return;
   88 
   89         db_ctf.rawctflen = rawctflen;
   90         db_ctf.cth = (struct ctf_header *)db_ctf.rawctf;
   91         db_ctf.dlen = db_ctf.cth->cth_stroff + db_ctf.cth->cth_strlen;
   92 
   93         if ((db_ctf.cth->cth_flags & CTF_F_COMPRESS) == 0) {
   94                 db_printf("unsupported non-compressed CTF section\n");
   95                 return;
   96         }
   97 
   98         /* Now decompress the section, take into account to skip the header */
   99         db_ctf.data = db_ctf_decompress(db_ctf.rawctf + sizeof(*db_ctf.cth),
  100             db_ctf.rawctflen - sizeof(*db_ctf.cth), db_ctf.dlen);
  101         if (db_ctf.data == NULL)
  102                 return;
  103 
  104         /* We made it this far, everything seems fine. */
  105         db_ctf.ctf_found = 1;
  106 }
  107 
  108 /*
  109  * Convert an index to a symbol name while ensuring the type is matched.
  110  * It must be noted this only works if the CTF table has the same order
  111  * as the symbol table.
  112  */
  113 Elf_Sym *
  114 db_ctf_idx2sym(size_t *idx, uint8_t type)
  115 {
  116         Elf_Sym *symp, *symtab_start, *symtab_end;
  117         size_t i = *idx + 1;
  118 
  119         symtab_start = STAB_TO_SYMSTART(&db_symtab);
  120         symtab_end = STAB_TO_SYMEND(&db_symtab);
  121 
  122         for (symp = &symtab_start[i]; symp < symtab_end; i++, symp++) {
  123                 if (ELF_ST_TYPE(symp->st_info) != type)
  124                         continue;
  125 
  126                 *idx = i;
  127                 return symp;
  128         }
  129 
  130         return NULL;
  131 }
  132 
  133 /*
  134  * For a given function name, return the number of arguments.
  135  */
  136 int
  137 db_ctf_func_numargs(Elf_Sym *st)
  138 {
  139         Elf_Sym                 *symp;
  140         uint16_t                *fstart, *fend;
  141         uint16_t                *fsp, kind, vlen;
  142         size_t                   i, idx = 0;
  143 
  144         if (!db_ctf.ctf_found || st == NULL)
  145                 return -1;
  146 
  147         fstart = (uint16_t *)(db_ctf.data + db_ctf.cth->cth_funcoff);
  148         fend = (uint16_t *)(db_ctf.data + db_ctf.cth->cth_typeoff);
  149 
  150         fsp = fstart;
  151         while (fsp < fend) {
  152                 symp = db_ctf_idx2sym(&idx, STT_FUNC);
  153                 if (symp == NULL)
  154                         break;
  155 
  156                 kind = CTF_INFO_KIND(*fsp);
  157                 vlen = CTF_INFO_VLEN(*fsp);
  158                 fsp++;
  159 
  160                 if (kind == CTF_K_UNKNOWN && vlen == 0)
  161                         continue;
  162 
  163                 /* Skip return type */
  164                 fsp++;
  165 
  166                 /* Skip argument types */
  167                 for (i = 0; i < vlen; i++)
  168                         fsp++;
  169 
  170                 if (symp == st)
  171                         return vlen;
  172         }
  173 
  174         return 0;
  175 }
  176 
  177 /*
  178  * Return the length of the type record in the CTF section.
  179  */
  180 uint32_t
  181 db_ctf_type_len(const struct ctf_type *ctt)
  182 {
  183         uint16_t                 kind, vlen, i;
  184         uint32_t                 tlen;
  185         uint64_t                 size;
  186 
  187         kind = CTF_INFO_KIND(ctt->ctt_info);
  188         vlen = CTF_INFO_VLEN(ctt->ctt_info);
  189 
  190         if (ctt->ctt_size <= CTF_MAX_SIZE) {
  191                 size = ctt->ctt_size;
  192                 tlen = sizeof(struct ctf_stype);
  193         } else {
  194                 size = CTF_TYPE_LSIZE(ctt);
  195                 tlen = sizeof(struct ctf_type);
  196         }
  197 
  198         switch (kind) {
  199         case CTF_K_UNKNOWN:
  200         case CTF_K_FORWARD:
  201                 break;
  202         case CTF_K_INTEGER:
  203                 tlen += sizeof(uint32_t);
  204                 break;
  205         case CTF_K_FLOAT:
  206                 tlen += sizeof(uint32_t);
  207                 break;
  208         case CTF_K_ARRAY:
  209                 tlen += sizeof(struct ctf_array);
  210                 break;
  211         case CTF_K_FUNCTION:
  212                 tlen += (vlen + (vlen & 1)) * sizeof(uint16_t);
  213                 break;
  214         case CTF_K_STRUCT:
  215         case CTF_K_UNION:
  216                 if (size < CTF_LSTRUCT_THRESH) {
  217                         for (i = 0; i < vlen; i++) {
  218                                 tlen += sizeof(struct ctf_member);
  219                         }
  220                 } else {
  221                         for (i = 0; i < vlen; i++) {
  222                                 tlen += sizeof(struct ctf_lmember);
  223                         }
  224                 }
  225                 break;
  226         case CTF_K_ENUM:
  227                 for (i = 0; i < vlen; i++) {
  228                         tlen += sizeof(struct ctf_enum);
  229                 }
  230                 break;
  231         case CTF_K_POINTER:
  232         case CTF_K_TYPEDEF:
  233         case CTF_K_VOLATILE:
  234         case CTF_K_CONST:
  235         case CTF_K_RESTRICT:
  236                 break;
  237         default:
  238                 return 0;
  239         }
  240 
  241         return tlen;
  242 }
  243 
  244 /*
  245  * Return the CTF type associated to an ELF symbol.
  246  */
  247 const struct ctf_type *
  248 db_ctf_type_by_symbol(Elf_Sym *st)
  249 {
  250         Elf_Sym                 *symp;
  251         uint32_t                 objtoff;
  252         uint16_t                *dsp;
  253         size_t                   idx = 0;
  254 
  255         if (!db_ctf.ctf_found || st == NULL)
  256                 return NULL;
  257 
  258         objtoff = db_ctf.cth->cth_objtoff;
  259 
  260         while (objtoff < db_ctf.cth->cth_funcoff) {
  261                 dsp = (uint16_t *)(db_ctf.data + objtoff);
  262 
  263                 symp = db_ctf_idx2sym(&idx, STT_OBJECT);
  264                 if (symp == NULL)
  265                         break;
  266                 if (symp == st)
  267                         return db_ctf_type_by_index(*dsp);
  268 
  269                 objtoff += sizeof(*dsp);
  270         }
  271 
  272         return NULL;
  273 }
  274 
  275 const struct ctf_type *
  276 db_ctf_type_by_name(const char *name, unsigned int kind)
  277 {
  278         struct ctf_header       *cth;
  279         const struct ctf_type   *ctt;
  280         const char              *tname;
  281         uint32_t                 off, toff;
  282 
  283         if (!db_ctf.ctf_found)
  284                 return (NULL);
  285 
  286         cth = db_ctf.cth;
  287 
  288         for (off = cth->cth_typeoff; off < cth->cth_stroff; off += toff) {
  289                 ctt = (struct ctf_type *)(db_ctf.data + off);
  290                 toff = db_ctf_type_len(ctt);
  291                 if (toff == 0) {
  292                         db_printf("incorrect type at offset %u", off);
  293                         break;
  294                 }
  295 
  296                 if (CTF_INFO_KIND(ctt->ctt_info) != kind)
  297                         continue;
  298 
  299                 tname = db_ctf_off2name(ctt->ctt_name);
  300                 if (tname == NULL)
  301                         continue;
  302 
  303                 if (strcmp(name, tname) == 0)
  304                         return (ctt);
  305         }
  306 
  307         return (NULL);
  308 }
  309 
  310 /*
  311  * Return the CTF type corresponding to a given index in the type section.
  312  */
  313 const struct ctf_type *
  314 db_ctf_type_by_index(uint16_t index)
  315 {
  316         uint32_t                 offset = db_ctf.cth->cth_typeoff;
  317         uint16_t                 idx = 1;
  318 
  319         if (!db_ctf.ctf_found)
  320                 return NULL;
  321 
  322         while (offset < db_ctf.cth->cth_stroff) {
  323                 const struct ctf_type   *ctt;
  324                 uint32_t                 toff;
  325 
  326                 ctt = (struct ctf_type *)(db_ctf.data + offset);
  327                 if (idx == index)
  328                         return ctt;
  329 
  330                 toff = db_ctf_type_len(ctt);
  331                 if (toff == 0) {
  332                         db_printf("incorrect type at offset %u", offset);
  333                         break;
  334                 }
  335                 offset += toff;
  336                 idx++;
  337         }
  338 
  339         return NULL;
  340 }
  341 
  342 /*
  343  * Pretty print `addr'.
  344  */
  345 void
  346 db_ctf_pprint(const struct ctf_type *ctt, vaddr_t addr)
  347 {
  348         vaddr_t                  taddr = (vaddr_t)ctt;
  349         const struct ctf_type   *ref;
  350         uint16_t                 kind;
  351         uint32_t                 eob, toff;
  352 
  353         kind = CTF_INFO_KIND(ctt->ctt_info);
  354         if (ctt->ctt_size <= CTF_MAX_SIZE)
  355                 toff = sizeof(struct ctf_stype);
  356         else
  357                 toff = sizeof(struct ctf_type);
  358 
  359         switch (kind) {
  360         case CTF_K_FLOAT:
  361         case CTF_K_ENUM:
  362         case CTF_K_ARRAY:
  363         case CTF_K_FUNCTION:
  364                 db_printf("%lu", *((unsigned long *)addr));
  365                 break;
  366         case CTF_K_INTEGER:
  367                 eob = db_get_value((taddr + toff), sizeof(eob), 0);
  368                 switch (CTF_INT_BITS(eob)) {
  369                 case 64:
  370                         db_printf("0x%llx", *((long long *)addr));
  371                         break;
  372                 default:
  373                         db_printf("0x%x", *((int *)addr));
  374                         break;
  375                 }
  376                 break;
  377         case CTF_K_STRUCT:
  378         case CTF_K_UNION:
  379                 db_ctf_pprint_struct(ctt, addr);
  380                 break;
  381         case CTF_K_POINTER:
  382                 db_ctf_pprint_ptr(ctt, addr);
  383                 break;
  384         case CTF_K_TYPEDEF:
  385         case CTF_K_VOLATILE:
  386         case CTF_K_CONST:
  387         case CTF_K_RESTRICT:
  388                 ref = db_ctf_type_by_index(ctt->ctt_type);
  389                 db_ctf_pprint(ref, addr);
  390                 break;
  391         case CTF_K_UNKNOWN:
  392         case CTF_K_FORWARD:
  393         default:
  394                 break;
  395         }
  396 }
  397 
  398 void
  399 db_ctf_pprint_struct(const struct ctf_type *ctt, vaddr_t addr)
  400 {
  401         const char              *name, *p = (const char *)ctt;
  402         const struct ctf_type   *ref;
  403         uint32_t                 toff;
  404         uint64_t                 size;
  405         uint16_t                 i, vlen;
  406 
  407         vlen = CTF_INFO_VLEN(ctt->ctt_info);
  408 
  409         if (ctt->ctt_size <= CTF_MAX_SIZE) {
  410                 size = ctt->ctt_size;
  411                 toff = sizeof(struct ctf_stype);
  412         } else {
  413                 size = CTF_TYPE_LSIZE(ctt);
  414                 toff = sizeof(struct ctf_type);
  415         }
  416 
  417         db_printf("{");
  418         if (size < CTF_LSTRUCT_THRESH) {
  419 
  420                 for (i = 0; i < vlen; i++) {
  421                         struct ctf_member       *ctm;
  422 
  423                         ctm = (struct ctf_member *)(p + toff);
  424                         toff += sizeof(struct ctf_member);
  425 
  426                         name = db_ctf_off2name(ctm->ctm_name);
  427                         if (name != NULL)
  428                                 db_printf("%s = ", name);
  429                         ref = db_ctf_type_by_index(ctm->ctm_type);
  430                         db_ctf_pprint(ref, addr + ctm->ctm_offset / 8);
  431                         if (i < vlen - 1)
  432                                 db_printf(", ");
  433                 }
  434         } else {
  435                 for (i = 0; i < vlen; i++) {
  436                         struct ctf_lmember      *ctlm;
  437 
  438                         ctlm = (struct ctf_lmember *)(p + toff);
  439                         toff += sizeof(struct ctf_lmember);
  440 
  441                         name = db_ctf_off2name(ctlm->ctlm_name);
  442                         if (name != NULL)
  443                                 db_printf("%s = ", name);
  444                         ref = db_ctf_type_by_index(ctlm->ctlm_type);
  445                         db_ctf_pprint(ref, addr +
  446                             CTF_LMEM_OFFSET(ctlm) / 8);
  447                         if (i < vlen - 1)
  448                                 db_printf(", ");
  449                 }
  450         }
  451         db_printf("}");
  452 }
  453 
  454 void
  455 db_ctf_pprint_ptr(const struct ctf_type *ctt, vaddr_t addr)
  456 {
  457         const char              *name, *modif = "";
  458         const struct ctf_type   *ref;
  459         uint16_t                 kind;
  460         unsigned long            ptr;
  461 
  462         ref = db_ctf_type_by_index(ctt->ctt_type);
  463         kind = CTF_INFO_KIND(ref->ctt_info);
  464 
  465         switch (kind) {
  466         case CTF_K_VOLATILE:
  467                 modif = "volatile ";
  468                 ref = db_ctf_type_by_index(ref->ctt_type);
  469                 break;
  470         case CTF_K_CONST:
  471                 modif = "const ";
  472                 ref = db_ctf_type_by_index(ref->ctt_type);
  473                 break;
  474         case CTF_K_STRUCT:
  475                 modif = "struct ";
  476                 break;
  477         case CTF_K_UNION:
  478                 modif = "union ";
  479                 break;
  480         default:
  481                 break;
  482         }
  483 
  484         name = db_ctf_off2name(ref->ctt_name);
  485         if (name != NULL)
  486                 db_printf("(%s%s *)", modif, name);
  487 
  488         ptr = (unsigned long)db_get_value(addr, sizeof(ptr), 0);
  489 
  490         db_printf("0x%lx", ptr);
  491 }
  492 
  493 static const char *
  494 db_ctf_off2name(uint32_t offset)
  495 {
  496         const char              *name;
  497 
  498         if (!db_ctf.ctf_found)
  499                 return NULL;
  500 
  501         if (CTF_NAME_STID(offset) != CTF_STRTAB_0)
  502                 return "external";
  503 
  504         if (CTF_NAME_OFFSET(offset) >= db_ctf.cth->cth_strlen)
  505                 return "exceeds strlab";
  506 
  507         if (db_ctf.cth->cth_stroff + CTF_NAME_OFFSET(offset) >= db_ctf.dlen)
  508                 return "invalid";
  509 
  510         name = db_ctf.data + db_ctf.cth->cth_stroff + CTF_NAME_OFFSET(offset);
  511         if (*name == '\0')
  512                 return NULL;
  513 
  514         return name;
  515 }
  516 
  517 static char *
  518 db_ctf_decompress(const char *buf, size_t size, size_t len)
  519 {
  520         z_stream                 stream;
  521         char                    *data;
  522         int                      error;
  523 
  524         data = malloc(len, M_TEMP, M_WAITOK|M_ZERO|M_CANFAIL);
  525         if (data == NULL)
  526                 return NULL;
  527 
  528         memset(&stream, 0, sizeof(stream));
  529         stream.next_in = (void *)buf;
  530         stream.avail_in = size;
  531         stream.next_out = data;
  532         stream.avail_out = len;
  533 
  534         if ((error = inflateInit(&stream)) != Z_OK) {
  535                 db_printf("zlib inflateInit failed: %s", zError(error));
  536                 goto exit;
  537         }
  538 
  539         if ((error = inflate(&stream, Z_FINISH)) != Z_STREAM_END) {
  540                 db_printf("zlib inflate failed: %s", zError(error));
  541                 inflateEnd(&stream);
  542                 goto exit;
  543         }
  544 
  545         if ((error = inflateEnd(&stream)) != Z_OK) {
  546                 db_printf("zlib inflateEnd failed: %s", zError(error));
  547                 goto exit;
  548         }
  549 
  550         if (stream.total_out != len) {
  551                 db_printf("decompression failed: %lu != %zu",
  552                     stream.total_out, len);
  553                 goto exit;
  554         }
  555 
  556         return data;
  557 
  558 exit:
  559         free(data, M_DEVBUF, len);
  560         return NULL;
  561 }
  562 
  563 /*
  564  * pprint <symbol name>
  565  */
  566 void
  567 db_ctf_pprint_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  568 {
  569         Elf_Sym *st;
  570         const struct ctf_type *ctt;
  571         int t;
  572 
  573         if (!db_ctf.ctf_found) {
  574                 db_printf("No CTF data found\n");
  575                 db_flush_lex();
  576                 return;
  577         }
  578 
  579         /*
  580          * Read the struct name from the debugger input.
  581          */
  582         t = db_read_token();
  583         if (t != tIDENT) {
  584                 db_printf("Bad symbol name\n");
  585                 db_flush_lex();
  586                 return;
  587         }
  588 
  589         if ((st = db_symbol_by_name(db_tok_string, &addr)) == NULL) {
  590                 db_printf("Symbol not found %s\n", db_tok_string);
  591                 db_flush_lex();
  592                 return;
  593         }
  594 
  595         if ((ctt = db_ctf_type_by_symbol(st)) == NULL) {
  596                 modif[0] = '\0';
  597                 db_print_cmd(addr, 0, 0, modif);
  598                 db_flush_lex();
  599                 return;
  600         }
  601 
  602         db_printf("%s:\t", db_tok_string);
  603         db_ctf_pprint(ctt, addr);
  604         db_printf("\n");
  605 }
  606 
  607 /*
  608  * show struct <struct name> [addr]: displays the data starting at addr
  609  * (`dot' if unspecified) as a struct of the given type.
  610  */
  611 void
  612 db_ctf_show_struct(db_expr_t addr, int have_addr, db_expr_t count,
  613     char *modifiers)
  614 {
  615         const struct ctf_type *ctt;
  616         const char *name;
  617         uint64_t sz;
  618         int t;
  619 
  620         /*
  621          * Read the struct name from the debugger input.
  622          */
  623         t = db_read_token();
  624         if (t != tIDENT) {
  625                 db_printf("Bad struct name\n");
  626                 db_flush_lex();
  627                 return;
  628         }
  629         name = db_tok_string;
  630 
  631         ctt = db_ctf_type_by_name(name, CTF_K_STRUCT);
  632         if (ctt == NULL) {
  633                 db_printf("unknown struct %s\n", name);
  634                 db_flush_lex();
  635                 return;
  636         }
  637 
  638         /*
  639          * Read the address, if any, from the debugger input.
  640          * In that case, update `dot' value.
  641          */
  642         if (db_expression(&addr)) {
  643                 db_dot = (vaddr_t)addr;
  644                 db_last_addr = db_dot;
  645         } else
  646                 addr = (db_expr_t)db_dot;
  647 
  648         db_skip_to_eol();
  649 
  650         /*
  651          * Display the structure contents.
  652          */
  653         sz = (ctt->ctt_size <= CTF_MAX_SIZE) ?
  654             ctt->ctt_size : CTF_TYPE_LSIZE(ctt);
  655         db_printf("struct %s at %p (%llu bytes) ", name, (void *)addr, sz);
  656         db_ctf_pprint_struct(ctt, addr);
  657 }

Cache object: 5d7beedc4fa0d47f719de0d9bb7814a9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.