LCOV - code coverage report
Current view: top level - ddb - db_ctf.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 282 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: db_ctf.c,v 1.27 2018/08/31 11:57:04 bluhm 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, off_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           0 : db_ctf_init(void)
      71             : {
      72             :         db_symtab_t *stab = &db_symtab;
      73           0 :         size_t rawctflen;
      74             : 
      75             :         /* Assume nothing was correct found until proven otherwise. */
      76           0 :         db_ctf.ctf_found = 0;
      77             : 
      78           0 :         if (stab->private == NULL)
      79           0 :                 return;
      80             : 
      81           0 :         db_ctf.strtab = db_elf_find_strtab(stab);
      82           0 :         if (db_ctf.strtab == NULL)
      83           0 :                 return;
      84             : 
      85           0 :         db_ctf.rawctf = db_elf_find_section(stab, &rawctflen, ELF_CTF);
      86           0 :         if (db_ctf.rawctf == NULL)
      87           0 :                 return;
      88             : 
      89           0 :         db_ctf.rawctflen = rawctflen;
      90           0 :         db_ctf.cth = (struct ctf_header *)db_ctf.rawctf;
      91           0 :         db_ctf.dlen = db_ctf.cth->cth_stroff + db_ctf.cth->cth_strlen;
      92             : 
      93           0 :         if ((db_ctf.cth->cth_flags & CTF_F_COMPRESS) == 0) {
      94           0 :                 db_printf("unsupported non-compressed CTF section\n");
      95           0 :                 return;
      96             :         }
      97             : 
      98             :         /* Now decompress the section, take into account to skip the header */
      99           0 :         db_ctf.data = db_ctf_decompress(db_ctf.rawctf + sizeof(*db_ctf.cth),
     100           0 :             db_ctf.rawctflen - sizeof(*db_ctf.cth), db_ctf.dlen);
     101           0 :         if (db_ctf.data == NULL)
     102           0 :                 return;
     103             : 
     104             :         /* We made it this far, everything seems fine. */
     105           0 :         db_ctf.ctf_found = 1;
     106           0 : }
     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           0 : db_ctf_idx2sym(size_t *idx, uint8_t type)
     115             : {
     116             :         Elf_Sym *symp, *symtab_start, *symtab_end;
     117           0 :         size_t i = *idx + 1;
     118             : 
     119           0 :         symtab_start = STAB_TO_SYMSTART(&db_symtab);
     120           0 :         symtab_end = STAB_TO_SYMEND(&db_symtab);
     121             : 
     122           0 :         for (symp = &symtab_start[i]; symp < symtab_end; i++, symp++) {
     123           0 :                 if (ELF_ST_TYPE(symp->st_info) != type)
     124             :                         continue;
     125             : 
     126           0 :                 *idx = i;
     127           0 :                 return symp;
     128             :         }
     129             : 
     130           0 :         return NULL;
     131           0 : }
     132             : 
     133             : /*
     134             :  * For a given function name, return the number of arguments.
     135             :  */
     136             : int
     137           0 : db_ctf_func_numargs(Elf_Sym *st)
     138             : {
     139             :         Elf_Sym                 *symp;
     140             :         uint16_t                *fstart, *fend;
     141             :         uint16_t                *fsp, kind, vlen;
     142           0 :         size_t                   i, idx = 0;
     143             : 
     144           0 :         if (!db_ctf.ctf_found || st == NULL)
     145           0 :                 return -1;
     146             : 
     147           0 :         fstart = (uint16_t *)(db_ctf.data + db_ctf.cth->cth_funcoff);
     148           0 :         fend = (uint16_t *)(db_ctf.data + db_ctf.cth->cth_typeoff);
     149             : 
     150             :         fsp = fstart;
     151           0 :         while (fsp < fend) {
     152           0 :                 symp = db_ctf_idx2sym(&idx, STT_FUNC);
     153           0 :                 if (symp == NULL)
     154             :                         break;
     155             : 
     156           0 :                 kind = CTF_INFO_KIND(*fsp);
     157           0 :                 vlen = CTF_INFO_VLEN(*fsp);
     158           0 :                 fsp++;
     159             : 
     160           0 :                 if (kind == CTF_K_UNKNOWN && vlen == 0)
     161           0 :                         continue;
     162             : 
     163             :                 /* Skip return type */
     164           0 :                 fsp++;
     165             : 
     166             :                 /* Skip argument types */
     167           0 :                 for (i = 0; i < vlen; i++)
     168           0 :                         fsp++;
     169             : 
     170           0 :                 if (symp == st)
     171           0 :                         return vlen;
     172             :         }
     173             : 
     174           0 :         return -1;
     175           0 : }
     176             : 
     177             : /*
     178             :  * Return the length of the type record in the CTF section.
     179             :  */
     180             : uint32_t
     181           0 : 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           0 :         kind = CTF_INFO_KIND(ctt->ctt_info);
     188           0 :         vlen = CTF_INFO_VLEN(ctt->ctt_info);
     189             : 
     190           0 :         if (ctt->ctt_size <= CTF_MAX_SIZE) {
     191           0 :                 size = ctt->ctt_size;
     192             :                 tlen = sizeof(struct ctf_stype);
     193           0 :         } else {
     194           0 :                 size = CTF_TYPE_LSIZE(ctt);
     195             :                 tlen = sizeof(struct ctf_type);
     196             :         }
     197             : 
     198           0 :         switch (kind) {
     199             :         case CTF_K_UNKNOWN:
     200             :         case CTF_K_FORWARD:
     201             :                 break;
     202             :         case CTF_K_INTEGER:
     203           0 :                 tlen += sizeof(uint32_t);
     204           0 :                 break;
     205             :         case CTF_K_FLOAT:
     206           0 :                 tlen += sizeof(uint32_t);
     207           0 :                 break;
     208             :         case CTF_K_ARRAY:
     209           0 :                 tlen += sizeof(struct ctf_array);
     210           0 :                 break;
     211             :         case CTF_K_FUNCTION:
     212           0 :                 tlen += (vlen + (vlen & 1)) * sizeof(uint16_t);
     213           0 :                 break;
     214             :         case CTF_K_STRUCT:
     215             :         case CTF_K_UNION:
     216           0 :                 if (size < CTF_LSTRUCT_THRESH) {
     217           0 :                         for (i = 0; i < vlen; i++) {
     218           0 :                                 tlen += sizeof(struct ctf_member);
     219             :                         }
     220             :                 } else {
     221           0 :                         for (i = 0; i < vlen; i++) {
     222           0 :                                 tlen += sizeof(struct ctf_lmember);
     223             :                         }
     224             :                 }
     225             :                 break;
     226             :         case CTF_K_ENUM:
     227           0 :                 for (i = 0; i < vlen; i++) {
     228           0 :                         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           0 :                 return 0;
     239             :         }
     240             : 
     241           0 :         return tlen;
     242           0 : }
     243             : 
     244             : /*
     245             :  * Return the CTF type associated to an ELF symbol.
     246             :  */
     247             : const struct ctf_type *
     248           0 : db_ctf_type_by_symbol(Elf_Sym *st)
     249             : {
     250             :         Elf_Sym                 *symp;
     251           0 :         uint32_t                 objtoff = db_ctf.cth->cth_objtoff;
     252             :         uint16_t                *dsp;
     253           0 :         size_t                   idx = 0;
     254             : 
     255           0 :         if (!db_ctf.ctf_found || st == NULL)
     256           0 :                 return NULL;
     257             : 
     258           0 :         while (objtoff < db_ctf.cth->cth_funcoff) {
     259           0 :                 dsp = (uint16_t *)(db_ctf.data + objtoff);
     260             : 
     261           0 :                 symp = db_ctf_idx2sym(&idx, STT_OBJECT);
     262           0 :                 if (symp == NULL)
     263             :                         break;
     264           0 :                 if (symp == st)
     265           0 :                         return db_ctf_type_by_index(*dsp);
     266             : 
     267           0 :                 objtoff += sizeof(*dsp);
     268             :         }
     269             : 
     270           0 :         return NULL;
     271           0 : }
     272             : 
     273             : const struct ctf_type *
     274           0 : db_ctf_type_by_name(const char *name, unsigned int kind)
     275             : {
     276             :         struct ctf_header       *cth;
     277             :         const struct ctf_type   *ctt;
     278             :         const char              *tname;
     279             :         uint32_t                 off, toff;
     280             : 
     281           0 :         if (!db_ctf.ctf_found)
     282           0 :                 return (NULL);
     283             : 
     284           0 :         cth = db_ctf.cth;
     285             : 
     286           0 :         for (off = cth->cth_typeoff; off < cth->cth_stroff; off += toff) {
     287           0 :                 ctt = (struct ctf_type *)(db_ctf.data + off);
     288           0 :                 toff = db_ctf_type_len(ctt);
     289           0 :                 if (toff == 0) {
     290           0 :                         db_printf("incorrect type at offset %u", off);
     291           0 :                         break;
     292             :                 }
     293             : 
     294           0 :                 if (CTF_INFO_KIND(ctt->ctt_info) != kind)
     295             :                         continue;
     296             : 
     297           0 :                 tname = db_ctf_off2name(ctt->ctt_name);
     298           0 :                 if (tname == NULL)
     299             :                         continue;
     300             : 
     301           0 :                 if (strcmp(name, tname) == 0)
     302           0 :                         return (ctt);
     303             :         }
     304             : 
     305           0 :         return (NULL);
     306           0 : }
     307             : 
     308             : /*
     309             :  * Return the CTF type corresponding to a given index in the type section.
     310             :  */
     311             : const struct ctf_type *
     312           0 : db_ctf_type_by_index(uint16_t index)
     313             : {
     314           0 :         uint32_t                 offset = db_ctf.cth->cth_typeoff;
     315             :         uint16_t                 idx = 1;
     316             : 
     317           0 :         if (!db_ctf.ctf_found)
     318           0 :                 return NULL;
     319             : 
     320           0 :         while (offset < db_ctf.cth->cth_stroff) {
     321             :                 const struct ctf_type   *ctt;
     322             :                 uint32_t                 toff;
     323             : 
     324           0 :                 ctt = (struct ctf_type *)(db_ctf.data + offset);
     325           0 :                 if (idx == index)
     326           0 :                         return ctt;
     327             : 
     328           0 :                 toff = db_ctf_type_len(ctt);
     329           0 :                 if (toff == 0) {
     330           0 :                         db_printf("incorrect type at offset %u", offset);
     331           0 :                         break;
     332             :                 }
     333           0 :                 offset += toff;
     334           0 :                 idx++;
     335           0 :         }
     336             : 
     337           0 :         return NULL;
     338           0 : }
     339             : 
     340             : /*
     341             :  * Pretty print `addr'.
     342             :  */
     343             : void
     344           0 : db_ctf_pprint(const struct ctf_type *ctt, vaddr_t addr)
     345             : {
     346           0 :         db_addr_t                taddr = (db_addr_t)ctt;
     347             :         const struct ctf_type   *ref;
     348             :         uint16_t                 kind;
     349             :         uint32_t                 eob, toff;
     350             : 
     351           0 :         kind = CTF_INFO_KIND(ctt->ctt_info);
     352           0 :         if (ctt->ctt_size <= CTF_MAX_SIZE)
     353           0 :                 toff = sizeof(struct ctf_stype);
     354             :         else
     355             :                 toff = sizeof(struct ctf_type);
     356             : 
     357           0 :         switch (kind) {
     358             :         case CTF_K_FLOAT:
     359             :         case CTF_K_ENUM:
     360             :         case CTF_K_ARRAY:
     361             :         case CTF_K_FUNCTION:
     362           0 :                 db_printf("%lu", *((unsigned long *)addr));
     363           0 :                 break;
     364             :         case CTF_K_INTEGER:
     365           0 :                 eob = db_get_value((taddr + toff), sizeof(eob), 0);
     366           0 :                 switch (CTF_INT_BITS(eob)) {
     367             :                 case 64:
     368           0 :                         db_printf("0x%llx", *((long long *)addr));
     369           0 :                         break;
     370             :                 default:
     371           0 :                         db_printf("0x%x", *((int *)addr));
     372           0 :                         break;
     373             :                 }
     374             :                 break;
     375             :         case CTF_K_STRUCT:
     376             :         case CTF_K_UNION:
     377           0 :                 db_ctf_pprint_struct(ctt, addr);
     378           0 :                 break;
     379             :         case CTF_K_POINTER:
     380           0 :                 db_ctf_pprint_ptr(ctt, addr);
     381           0 :                 break;
     382             :         case CTF_K_TYPEDEF:
     383             :         case CTF_K_VOLATILE:
     384             :         case CTF_K_CONST:
     385             :         case CTF_K_RESTRICT:
     386           0 :                 ref = db_ctf_type_by_index(ctt->ctt_type);
     387           0 :                 db_ctf_pprint(ref, addr);
     388           0 :                 break;
     389             :         case CTF_K_UNKNOWN:
     390             :         case CTF_K_FORWARD:
     391             :         default:
     392             :                 break;
     393             :         }
     394           0 : }
     395             : 
     396             : void
     397           0 : db_ctf_pprint_struct(const struct ctf_type *ctt, vaddr_t addr)
     398             : {
     399           0 :         const char              *name, *p = (const char *)ctt;
     400             :         const struct ctf_type   *ref;
     401             :         uint32_t                 toff;
     402             :         uint64_t                 size;
     403             :         uint16_t                 i, vlen;
     404             : 
     405           0 :         vlen = CTF_INFO_VLEN(ctt->ctt_info);
     406             : 
     407           0 :         if (ctt->ctt_size <= CTF_MAX_SIZE) {
     408           0 :                 size = ctt->ctt_size;
     409             :                 toff = sizeof(struct ctf_stype);
     410           0 :         } else {
     411           0 :                 size = CTF_TYPE_LSIZE(ctt);
     412             :                 toff = sizeof(struct ctf_type);
     413             :         }
     414             : 
     415           0 :         db_printf("{");
     416           0 :         if (size < CTF_LSTRUCT_THRESH) {
     417             : 
     418           0 :                 for (i = 0; i < vlen; i++) {
     419             :                         struct ctf_member       *ctm;
     420             : 
     421           0 :                         ctm = (struct ctf_member *)(p + toff);
     422           0 :                         toff += sizeof(struct ctf_member);
     423             : 
     424           0 :                         name = db_ctf_off2name(ctm->ctm_name);
     425           0 :                         if (name != NULL)
     426           0 :                                 db_printf("%s = ", name);
     427           0 :                         ref = db_ctf_type_by_index(ctm->ctm_type);
     428           0 :                         db_ctf_pprint(ref, addr + ctm->ctm_offset / 8);
     429           0 :                         if (i < vlen - 1)
     430           0 :                                 db_printf(", ");
     431             :                 }
     432             :         } else {
     433           0 :                 for (i = 0; i < vlen; i++) {
     434             :                         struct ctf_lmember      *ctlm;
     435             : 
     436           0 :                         ctlm = (struct ctf_lmember *)(p + toff);
     437           0 :                         toff += sizeof(struct ctf_lmember);
     438             : 
     439           0 :                         name = db_ctf_off2name(ctlm->ctlm_name);
     440           0 :                         if (name != NULL)
     441           0 :                                 db_printf("%s = ", name);
     442           0 :                         ref = db_ctf_type_by_index(ctlm->ctlm_type);
     443           0 :                         db_ctf_pprint(ref, addr +
     444           0 :                             CTF_LMEM_OFFSET(ctlm) / 8);
     445           0 :                         if (i < vlen - 1)
     446           0 :                                 db_printf(", ");
     447             :                 }
     448             :         }
     449           0 :         db_printf("}");
     450           0 : }
     451             : 
     452             : void
     453           0 : db_ctf_pprint_ptr(const struct ctf_type *ctt, vaddr_t addr)
     454             : {
     455             :         const char              *name, *modif = "";
     456             :         const struct ctf_type   *ref;
     457             :         uint16_t                 kind;
     458             :         unsigned long            ptr;
     459             : 
     460           0 :         ref = db_ctf_type_by_index(ctt->ctt_type);
     461           0 :         kind = CTF_INFO_KIND(ref->ctt_info);
     462             : 
     463           0 :         switch (kind) {
     464             :         case CTF_K_VOLATILE:
     465             :                 modif = "volatile ";
     466           0 :                 ref = db_ctf_type_by_index(ref->ctt_type);
     467           0 :                 break;
     468             :         case CTF_K_CONST:
     469             :                 modif = "const ";
     470           0 :                 ref = db_ctf_type_by_index(ref->ctt_type);
     471           0 :                 break;
     472             :         case CTF_K_STRUCT:
     473             :                 modif = "struct ";
     474           0 :                 break;
     475             :         case CTF_K_UNION:
     476             :                 modif = "union ";
     477           0 :                 break;
     478             :         default:
     479             :                 break;
     480             :         }
     481             : 
     482           0 :         name = db_ctf_off2name(ref->ctt_name);
     483           0 :         if (name != NULL)
     484           0 :                 db_printf("(%s%s *)", modif, name);
     485             : 
     486           0 :         ptr = (unsigned long)db_get_value(addr, sizeof(ptr), 0);
     487             : 
     488           0 :         db_printf("0x%lx", ptr);
     489           0 : }
     490             : 
     491             : static const char *
     492           0 : db_ctf_off2name(uint32_t offset)
     493             : {
     494             :         const char              *name;
     495             : 
     496           0 :         if (CTF_NAME_STID(offset) != CTF_STRTAB_0)
     497           0 :                 return "external";
     498             : 
     499           0 :         if (CTF_NAME_OFFSET(offset) >= db_ctf.cth->cth_strlen)
     500           0 :                 return "exceeds strlab";
     501             : 
     502           0 :         if (db_ctf.cth->cth_stroff + CTF_NAME_OFFSET(offset) >= db_ctf.dlen)
     503           0 :                 return "invalid";
     504             : 
     505           0 :         name = db_ctf.data + db_ctf.cth->cth_stroff + CTF_NAME_OFFSET(offset);
     506           0 :         if (*name == '\0')
     507           0 :                 return NULL;
     508             : 
     509           0 :         return name;
     510           0 : }
     511             : 
     512             : static char *
     513           0 : db_ctf_decompress(const char *buf, size_t size, off_t len)
     514             : {
     515           0 :         z_stream                 stream;
     516             :         char                    *data;
     517             :         int                      error;
     518             : 
     519           0 :         data = malloc(len, M_TEMP, M_WAITOK|M_ZERO|M_CANFAIL);
     520           0 :         if (data == NULL)
     521           0 :                 return NULL;
     522             : 
     523           0 :         memset(&stream, 0, sizeof(stream));
     524           0 :         stream.next_in = (void *)buf;
     525           0 :         stream.avail_in = size;
     526           0 :         stream.next_out = data;
     527           0 :         stream.avail_out = len;
     528             : 
     529           0 :         if ((error = inflateInit(&stream)) != Z_OK) {
     530           0 :                 db_printf("zlib inflateInit failed: %s", zError(error));
     531           0 :                 goto exit;
     532             :         }
     533             : 
     534           0 :         if ((error = inflate(&stream, Z_FINISH)) != Z_STREAM_END) {
     535           0 :                 db_printf("zlib inflate failed: %s", zError(error));
     536           0 :                 inflateEnd(&stream);
     537           0 :                 goto exit;
     538             :         }
     539             : 
     540           0 :         if ((error = inflateEnd(&stream)) != Z_OK) {
     541           0 :                 db_printf("zlib inflateEnd failed: %s", zError(error));
     542           0 :                 goto exit;
     543             :         }
     544             : 
     545           0 :         if (stream.total_out != len) {
     546           0 :                 db_printf("decompression failed: %llu != %llu",
     547             :                     stream.total_out, len);
     548           0 :                 goto exit;
     549             :         }
     550             : 
     551           0 :         return data;
     552             : 
     553             : exit:
     554           0 :         free(data, M_DEVBUF, len);
     555           0 :         return NULL;
     556           0 : }
     557             : 
     558             : /*
     559             :  * pprint <symbol name>
     560             :  */
     561             : void
     562           0 : db_ctf_pprint_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
     563             : {
     564             :         Elf_Sym *st;
     565             :         const struct ctf_type *ctt;
     566             :         int t;
     567             : 
     568           0 :         if (!db_ctf.ctf_found) {
     569           0 :                 db_printf("No CTF data found\n");
     570           0 :                 db_flush_lex();
     571           0 :                 return;
     572             :         }
     573             : 
     574             :         /*
     575             :          * Read the struct name from the debugger input.
     576             :          */
     577           0 :         t = db_read_token();
     578           0 :         if (t != tIDENT) {
     579           0 :                 db_printf("Bad symbol name\n");
     580           0 :                 db_flush_lex();
     581           0 :                 return;
     582             :         }
     583             : 
     584           0 :         if ((st = db_symbol_by_name(db_tok_string, &addr)) == NULL) {
     585           0 :                 db_printf("Symbol not found %s\n", db_tok_string);
     586           0 :                 db_flush_lex();
     587           0 :                 return;
     588             :         }
     589             : 
     590           0 :         if ((ctt = db_ctf_type_by_symbol(st)) == NULL) {
     591           0 :                 modif[0] = '\0';
     592           0 :                 db_print_cmd(addr, 0, 0, modif);
     593           0 :                 db_flush_lex();
     594           0 :                 return;
     595             :         }
     596             : 
     597           0 :         db_printf("%s:\t", db_tok_string);
     598           0 :         db_ctf_pprint(ctt, addr);
     599           0 :         db_printf("\n");
     600           0 : }
     601             : 
     602             : /*
     603             :  * show struct <struct name> [addr]: displays the data starting at addr
     604             :  * (`dot' if unspecified) as a struct of the given type.
     605             :  */
     606             : void
     607           0 : db_ctf_show_struct(db_expr_t addr, int have_addr, db_expr_t count,
     608             :     char *modifiers)
     609             : {
     610             :         const struct ctf_type *ctt;
     611             :         const char *name;
     612             :         uint64_t sz;
     613             :         int t;
     614             : 
     615             :         /*
     616             :          * Read the struct name from the debugger input.
     617             :          */
     618           0 :         t = db_read_token();
     619           0 :         if (t != tIDENT) {
     620           0 :                 db_printf("Bad struct name\n");
     621           0 :                 db_flush_lex();
     622           0 :                 return;
     623             :         }
     624             :         name = db_tok_string;
     625             : 
     626           0 :         ctt = db_ctf_type_by_name(name, CTF_K_STRUCT);
     627           0 :         if (ctt == NULL) {
     628           0 :                 db_printf("unknown struct %s\n", name);
     629           0 :                 db_flush_lex();
     630           0 :                 return;
     631             :         }
     632             : 
     633             :         /*
     634             :          * Read the address, if any, from the debugger input.
     635             :          * In that case, update `dot' value.
     636             :          */
     637           0 :         if (db_expression(&addr)) {
     638           0 :                 db_dot = (db_addr_t)addr;
     639           0 :                 db_last_addr = db_dot;
     640           0 :         } else
     641           0 :                 addr = (db_expr_t)db_dot;
     642             : 
     643           0 :         db_skip_to_eol();
     644             : 
     645             :         /*
     646             :          * Display the structure contents.
     647             :          */
     648           0 :         sz = (ctt->ctt_size <= CTF_MAX_SIZE) ?
     649           0 :             ctt->ctt_size : CTF_TYPE_LSIZE(ctt);
     650           0 :         db_printf("struct %s at %p (%llu bytes) ", name, (void *)addr, sz);
     651           0 :         db_ctf_pprint_struct(ctt, addr);
     652           0 : }

Generated by: LCOV version 1.13