kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

dwarf_dump.c (17668B)


      1 /* dwarf_dump.c — structural enumeration of DWARF sections.
      2  *
      3  * Implements the kit_dwarf_*_iter API used by `objdump --dwarf` and
      4  * similar dumpers. Unlike the PC/name-keyed query API, these walk the raw
      5  * .debug_info / .debug_abbrev / .debug_line / .debug_str structure and
      6  * hand back numeric DWARF codes; symbolic rendering is the caller's job.
      7  *
      8  * The iterators are thin cursors over the consumer state already built by
      9  * dwarf_open.c (CUs, abbrev tables) and dwarf_line.c (decoded line rows).
     10  */
     11 
     12 #include <kit/dwarf.h>
     13 #include <stddef.h>
     14 #include <stdint.h>
     15 
     16 #include "core/core.h"
     17 #include "core/heap.h"
     18 #include "debug/dwarf_defs.h"
     19 #include "debug/dwarf_internal.h"
     20 
     21 /* ---- shared helpers --------------------------------------------------- */
     22 
     23 #define DW_ITER_ALLOC(d, T) ((T*)(d)->h->alloc((d)->h, sizeof(T), _Alignof(T)))
     24 
     25 static void dw_iter_free(KitDebugInfo* d, void* p, size_t n) {
     26   if (p) d->h->free(d->h, p, n);
     27 }
     28 
     29 /* Find the CU index whose header sits at `cu_offset`, or UINT32_MAX. */
     30 static u32 dw_cu_index_at(KitDebugInfo* d, u32 cu_offset) {
     31   u32 i;
     32   for (i = 0; i < d->ncus; ++i) {
     33     if (d->cus[i].hdr_offset == cu_offset) return i;
     34   }
     35   return UINT32_MAX;
     36 }
     37 
     38 /* ---- CU iterator ------------------------------------------------------ */
     39 
     40 struct KitDwarfCuIter {
     41   KitDebugInfo* d;
     42   u32 idx;
     43 };
     44 
     45 KitStatus kit_dwarf_cu_iter_new(KitDebugInfo* d, KitDwarfCuIter** out) {
     46   KitDwarfCuIter* it;
     47   if (!out) return KIT_INVALID;
     48   *out = NULL;
     49   if (!d) return KIT_INVALID;
     50   dw_parse_all_cus(d);
     51   it = DW_ITER_ALLOC(d, KitDwarfCuIter);
     52   if (!it) return KIT_NOMEM;
     53   it->d = d;
     54   it->idx = 0;
     55   *out = it;
     56   return KIT_OK;
     57 }
     58 
     59 KitIterResult kit_dwarf_cu_iter_next(KitDwarfCuIter* it, KitDwarfCu* out) {
     60   DwCu* cu;
     61   if (!it || !out) return KIT_ITER_ERROR;
     62   if (it->idx >= it->d->ncus) return KIT_ITER_END;
     63   cu = &it->d->cus[it->idx++];
     64   out->offset = cu->hdr_offset;
     65   out->length = cu->hdr_length;
     66   out->version = cu->version;
     67   out->address_size = cu->address_size;
     68   out->unit_type = cu->unit_type;
     69   out->abbrev_offset = cu->abbrev_offset;
     70   out->is_64bit = cu->is_64bit != 0;
     71   return KIT_ITER_ITEM;
     72 }
     73 
     74 void kit_dwarf_cu_iter_free(KitDwarfCuIter* it) {
     75   if (it) dw_iter_free(it->d, it, sizeof(*it));
     76 }
     77 
     78 /* ---- DIE iterator (depth-first across all CUs) ------------------------ */
     79 
     80 struct KitDwarfDieIter {
     81   KitDebugInfo* d;
     82   u32 cu_idx; /* current CU */
     83   u32 off;    /* cursor into .debug_info */
     84   u32 depth;  /* current nesting level */
     85 };
     86 
     87 KitStatus kit_dwarf_die_iter_new(KitDebugInfo* d, KitDwarfDieIter** out) {
     88   KitDwarfDieIter* it;
     89   if (!out) return KIT_INVALID;
     90   *out = NULL;
     91   if (!d) return KIT_INVALID;
     92   dw_parse_all_cus(d);
     93   it = DW_ITER_ALLOC(d, KitDwarfDieIter);
     94   if (!it) return KIT_NOMEM;
     95   it->d = d;
     96   it->cu_idx = 0;
     97   it->depth = 0;
     98   it->off = d->ncus ? d->cus[0].die_start_off : 0;
     99   *out = it;
    100   return KIT_OK;
    101 }
    102 
    103 KitIterResult kit_dwarf_die_iter_next(KitDwarfDieIter* it, KitDwarfDie* out) {
    104   KitDebugInfo* d;
    105   if (!it || !out) return KIT_ITER_ERROR;
    106   d = it->d;
    107   for (;;) {
    108     DwCu* cu;
    109     DwDie die;
    110     if (it->cu_idx >= d->ncus) return KIT_ITER_END;
    111     cu = &d->cus[it->cu_idx];
    112     if (!dw_read_die(d, cu, &it->off, &die)) {
    113       /* Null entry or end-of-CU: close one level, or advance to the next
    114        * CU when we have unwound back past the root. */
    115       if (it->depth > 0) {
    116         it->depth--;
    117         continue;
    118       }
    119       it->cu_idx++;
    120       it->depth = 0;
    121       if (it->cu_idx < d->ncus) it->off = d->cus[it->cu_idx].die_start_off;
    122       continue;
    123     }
    124     out->offset = die.die_off;
    125     out->cu_offset = cu->hdr_offset;
    126     out->tag = die.abbrev ? die.abbrev->tag : 0;
    127     out->depth = it->depth;
    128     out->has_children = die.abbrev && die.abbrev->has_children;
    129     dw_skip_die_attrs(d, cu, &die, &it->off);
    130     if (die.abbrev && die.abbrev->has_children) it->depth++;
    131     return KIT_ITER_ITEM;
    132   }
    133 }
    134 
    135 void kit_dwarf_die_iter_free(KitDwarfDieIter* it) {
    136   if (it) dw_iter_free(it->d, it, sizeof(*it));
    137 }
    138 
    139 /* ---- DIE attribute iterator ------------------------------------------- */
    140 
    141 struct KitDwarfAttrIter {
    142   KitDebugInfo* d;
    143   const DwCu* cu;
    144   DwAbbrev* abbrev;
    145   u32 attr_idx; /* index into abbrev->attrs */
    146   u32 off;      /* running cursor in .debug_info */
    147 };
    148 
    149 static KitDwarfFormClass dw_form_class(u32 form) {
    150   switch (form) {
    151     case DW_FORM_string:
    152     case DW_FORM_strp:
    153     case DW_FORM_line_strp:
    154     case DW_FORM_strx:
    155     case DW_FORM_strx1:
    156     case DW_FORM_strx2:
    157     case DW_FORM_strx3:
    158     case DW_FORM_strx4:
    159       return KIT_DWARF_FC_STRING;
    160     case DW_FORM_addr:
    161     case DW_FORM_addrx:
    162     case DW_FORM_addrx1:
    163     case DW_FORM_addrx2:
    164     case DW_FORM_addrx3:
    165     case DW_FORM_addrx4:
    166       return KIT_DWARF_FC_ADDR;
    167     case DW_FORM_ref1:
    168     case DW_FORM_ref2:
    169     case DW_FORM_ref4:
    170     case DW_FORM_ref8:
    171     case DW_FORM_ref_udata:
    172     case DW_FORM_ref_addr:
    173     case DW_FORM_ref_sig8:
    174     case DW_FORM_ref_sup4:
    175     case DW_FORM_ref_sup8:
    176       return KIT_DWARF_FC_REF;
    177     case DW_FORM_sdata:
    178       return KIT_DWARF_FC_SDATA;
    179     case DW_FORM_flag:
    180     case DW_FORM_flag_present:
    181       return KIT_DWARF_FC_FLAG;
    182     case DW_FORM_block:
    183     case DW_FORM_block1:
    184     case DW_FORM_block2:
    185     case DW_FORM_block4:
    186     case DW_FORM_exprloc:
    187     case DW_FORM_data16:
    188       return KIT_DWARF_FC_BLOCK;
    189     case DW_FORM_data1:
    190     case DW_FORM_data2:
    191     case DW_FORM_data4:
    192     case DW_FORM_data8:
    193     case DW_FORM_udata:
    194     case DW_FORM_sec_offset:
    195     case DW_FORM_loclistx:
    196     case DW_FORM_rnglistx:
    197     case DW_FORM_implicit_const:
    198       return KIT_DWARF_FC_UDATA;
    199     default:
    200       return KIT_DWARF_FC_UNKNOWN;
    201   }
    202 }
    203 
    204 KitStatus kit_dwarf_attr_iter_new(KitDebugInfo* d, uint32_t die_offset,
    205                                   KitDwarfAttrIter** out) {
    206   KitDwarfAttrIter* it;
    207   DwCu* cu;
    208   DwDie die;
    209   u32 off;
    210   if (!out) return KIT_INVALID;
    211   *out = NULL;
    212   if (!d) return KIT_INVALID;
    213   dw_parse_all_cus(d);
    214   cu = dw_cu_at_die_offset(d, die_offset);
    215   if (!cu) return KIT_NOT_FOUND;
    216   off = die_offset;
    217   if (!dw_read_die(d, cu, &off, &die) || !die.abbrev) return KIT_NOT_FOUND;
    218   it = DW_ITER_ALLOC(d, KitDwarfAttrIter);
    219   if (!it) return KIT_NOMEM;
    220   it->d = d;
    221   it->cu = cu;
    222   it->abbrev = die.abbrev;
    223   it->attr_idx = 0;
    224   it->off = die.attrs_off;
    225   *out = it;
    226   return KIT_OK;
    227 }
    228 
    229 KitIterResult kit_dwarf_attr_iter_next(KitDwarfAttrIter* it,
    230                                        KitDwarfAttr* out) {
    231   DwAbbrevAttr* spec;
    232   DwAttrValue v;
    233   if (!it || !out) return KIT_ITER_ERROR;
    234   if (it->attr_idx >= it->abbrev->nattrs) return KIT_ITER_END;
    235   spec = &it->abbrev->attrs[it->attr_idx++];
    236   dw_read_form(it->d, it->cu, spec->form, spec->implicit_const, &it->off, &v);
    237   out->attr = spec->attr;
    238   out->form = spec->form;
    239   out->form_class = dw_form_class(spec->form);
    240   out->u = v.u;
    241   out->s = v.s;
    242   out->str = v.str ? kit_slice_cstr(v.str) : KIT_SLICE_NULL;
    243   out->block = v.block;
    244   out->block_len = v.block_len;
    245   return KIT_ITER_ITEM;
    246 }
    247 
    248 void kit_dwarf_attr_iter_free(KitDwarfAttrIter* it) {
    249   if (it) dw_iter_free(it->d, it, sizeof(*it));
    250 }
    251 
    252 /* ---- abbrev iterators ------------------------------------------------- */
    253 
    254 struct KitDwarfAbbrevIter {
    255   KitDebugInfo* d;
    256   u32 tbl;  /* index into d->abbrevs */
    257   u32 slot; /* index into table->abbrevs */
    258 };
    259 
    260 /* Ensure every CU's abbrev table is materialized before walking them. */
    261 static void dw_ensure_abbrevs(KitDebugInfo* d) {
    262   u32 i;
    263   dw_parse_all_cus(d);
    264   for (i = 0; i < d->ncus; ++i) dw_abbrev_get(d, d->cus[i].abbrev_offset);
    265 }
    266 
    267 KitStatus kit_dwarf_abbrev_iter_new(KitDebugInfo* d, KitDwarfAbbrevIter** out) {
    268   KitDwarfAbbrevIter* it;
    269   if (!out) return KIT_INVALID;
    270   *out = NULL;
    271   if (!d) return KIT_INVALID;
    272   dw_ensure_abbrevs(d);
    273   it = DW_ITER_ALLOC(d, KitDwarfAbbrevIter);
    274   if (!it) return KIT_NOMEM;
    275   it->d = d;
    276   it->tbl = 0;
    277   it->slot = 0;
    278   *out = it;
    279   return KIT_OK;
    280 }
    281 
    282 KitIterResult kit_dwarf_abbrev_iter_next(KitDwarfAbbrevIter* it,
    283                                          KitDwarfAbbrev* out) {
    284   KitDebugInfo* d;
    285   if (!it || !out) return KIT_ITER_ERROR;
    286   d = it->d;
    287   while (it->tbl < d->nabbrevs) {
    288     DwAbbrevTable* t = &d->abbrevs[it->tbl];
    289     if (it->slot >= t->nabbrevs) {
    290       it->tbl++;
    291       it->slot = 0;
    292       continue;
    293     }
    294     {
    295       DwAbbrev* a = &t->abbrevs[it->slot++];
    296       if (a->code == 0) continue; /* unused slot */
    297       out->table_offset = t->cu_abbrev_offset;
    298       out->code = a->code;
    299       out->tag = a->tag;
    300       out->has_children = a->has_children != 0;
    301       return KIT_ITER_ITEM;
    302     }
    303   }
    304   return KIT_ITER_END;
    305 }
    306 
    307 void kit_dwarf_abbrev_iter_free(KitDwarfAbbrevIter* it) {
    308   if (it) dw_iter_free(it->d, it, sizeof(*it));
    309 }
    310 
    311 struct KitDwarfAbbrevAttrIter {
    312   KitDebugInfo* d;
    313   DwAbbrev* abbrev;
    314   u32 idx;
    315 };
    316 
    317 KitStatus kit_dwarf_abbrev_attr_iter_new(KitDebugInfo* d, uint32_t table_offset,
    318                                          uint64_t code,
    319                                          KitDwarfAbbrevAttrIter** out) {
    320   KitDwarfAbbrevAttrIter* it;
    321   DwAbbrevTable* t;
    322   DwAbbrev* a;
    323   if (!out) return KIT_INVALID;
    324   *out = NULL;
    325   if (!d) return KIT_INVALID;
    326   dw_ensure_abbrevs(d);
    327   t = dw_abbrev_get(d, table_offset);
    328   if (!t) return KIT_NOT_FOUND;
    329   a = dw_abbrev_lookup(t, code);
    330   if (!a) return KIT_NOT_FOUND;
    331   it = DW_ITER_ALLOC(d, KitDwarfAbbrevAttrIter);
    332   if (!it) return KIT_NOMEM;
    333   it->d = d;
    334   it->abbrev = a;
    335   it->idx = 0;
    336   *out = it;
    337   return KIT_OK;
    338 }
    339 
    340 KitIterResult kit_dwarf_abbrev_attr_iter_next(KitDwarfAbbrevAttrIter* it,
    341                                               KitDwarfAbbrevAttr* out) {
    342   DwAbbrevAttr* aa;
    343   if (!it || !out) return KIT_ITER_ERROR;
    344   if (it->idx >= it->abbrev->nattrs) return KIT_ITER_END;
    345   aa = &it->abbrev->attrs[it->idx++];
    346   out->attr = aa->attr;
    347   out->form = aa->form;
    348   out->implicit_const = aa->implicit_const;
    349   return KIT_ITER_ITEM;
    350 }
    351 
    352 void kit_dwarf_abbrev_attr_iter_free(KitDwarfAbbrevAttrIter* it) {
    353   if (it) dw_iter_free(it->d, it, sizeof(*it));
    354 }
    355 
    356 /* ---- line row iterator ------------------------------------------------ */
    357 
    358 struct KitDwarfLineIter {
    359   KitDebugInfo* d;
    360   u32 cu_idx;
    361   u32 row;
    362 };
    363 
    364 KitStatus kit_dwarf_line_iter_new(KitDebugInfo* d, uint32_t cu_offset,
    365                                   KitDwarfLineIter** out) {
    366   KitDwarfLineIter* it;
    367   u32 cu_idx;
    368   if (!out) return KIT_INVALID;
    369   *out = NULL;
    370   if (!d) return KIT_INVALID;
    371   dw_parse_all_cus(d);
    372   cu_idx = dw_cu_index_at(d, cu_offset);
    373   if (cu_idx == UINT32_MAX) return KIT_NOT_FOUND;
    374   if (!d->cus[cu_idx].has_stmt_list) return KIT_NOT_FOUND;
    375   if (!d->lines_built[cu_idx]) dw_build_line(d, cu_idx);
    376   it = DW_ITER_ALLOC(d, KitDwarfLineIter);
    377   if (!it) return KIT_NOMEM;
    378   it->d = d;
    379   it->cu_idx = cu_idx;
    380   it->row = 0;
    381   *out = it;
    382   return KIT_OK;
    383 }
    384 
    385 KitIterResult kit_dwarf_line_iter_next(KitDwarfLineIter* it,
    386                                        KitDwarfLineRow* out) {
    387   DwLineProgram* lp;
    388   DwLineRow* r;
    389   if (!it || !out) return KIT_ITER_ERROR;
    390   lp = &it->d->lines_by_cu[it->cu_idx];
    391   if (it->row >= lp->nrows) return KIT_ITER_END;
    392   r = &lp->rows[it->row++];
    393   out->address = r->address;
    394   out->file_index = r->file_index;
    395   out->line = r->line;
    396   out->column = r->column;
    397   out->is_stmt = r->is_stmt != 0;
    398   out->end_sequence = r->end_sequence != 0;
    399   return KIT_ITER_ITEM;
    400 }
    401 
    402 void kit_dwarf_line_iter_free(KitDwarfLineIter* it) {
    403   if (it) dw_iter_free(it->d, it, sizeof(*it));
    404 }
    405 
    406 KitStatus kit_dwarf_line_file(KitDebugInfo* d, uint32_t cu_offset,
    407                               uint32_t file_index, KitSlice* out) {
    408   u32 cu_idx;
    409   DwLineProgram* lp;
    410   const char* path = NULL;
    411   if (!out) return KIT_INVALID;
    412   *out = KIT_SLICE_NULL;
    413   if (!d) return KIT_INVALID;
    414   dw_parse_all_cus(d);
    415   cu_idx = dw_cu_index_at(d, cu_offset);
    416   if (cu_idx == UINT32_MAX) return KIT_NOT_FOUND;
    417   if (!d->cus[cu_idx].has_stmt_list) return KIT_NOT_FOUND;
    418   if (!d->lines_built[cu_idx]) dw_build_line(d, cu_idx);
    419   lp = &d->lines_by_cu[cu_idx];
    420   if (file_index < lp->nfile_norm && lp->file_norm[file_index])
    421     path = lp->file_norm[file_index];
    422   else if (file_index < lp->nfiles)
    423     path = lp->files[file_index].path;
    424   if (!path) return KIT_NOT_FOUND;
    425   *out = kit_slice_cstr(path);
    426   return KIT_OK;
    427 }
    428 
    429 /* ---- .debug_str iterator ---------------------------------------------- */
    430 
    431 struct KitDwarfStrIter {
    432   KitDebugInfo* d;
    433   u32 off;
    434 };
    435 
    436 KitStatus kit_dwarf_str_iter_new(KitDebugInfo* d, KitDwarfStrIter** out) {
    437   KitDwarfStrIter* it;
    438   if (!out) return KIT_INVALID;
    439   *out = NULL;
    440   if (!d) return KIT_INVALID;
    441   it = DW_ITER_ALLOC(d, KitDwarfStrIter);
    442   if (!it) return KIT_NOMEM;
    443   it->d = d;
    444   it->off = 0;
    445   *out = it;
    446   return KIT_OK;
    447 }
    448 
    449 KitIterResult kit_dwarf_str_iter_next(KitDwarfStrIter* it, KitDwarfStr* out) {
    450   KitDebugInfo* d;
    451   const u8* base;
    452   u32 size, start, n;
    453   if (!it || !out) return KIT_ITER_ERROR;
    454   d = it->d;
    455   base = d->str.data;
    456   size = d->str.size;
    457   if (!base || it->off >= size) return KIT_ITER_END;
    458   start = it->off;
    459   n = 0;
    460   while (it->off < size && base[it->off] != 0) {
    461     it->off++;
    462     n++;
    463   }
    464   if (it->off < size) it->off++; /* step over the NUL */
    465   out->offset = start;
    466   out->str.s = (const char*)(base + start);
    467   out->str.len = n;
    468   return KIT_ITER_ITEM;
    469 }
    470 
    471 void kit_dwarf_str_iter_free(KitDwarfStrIter* it) {
    472   if (it) dw_iter_free(it->d, it, sizeof(*it));
    473 }
    474 
    475 /* ---- symbolic name tables --------------------------------------------
    476  *
    477  * Canonical spellings for the numeric codes the iterators above hand back,
    478  * so every DWARF dumper shares one table instead of copying its own. An
    479  * unrecognized code returns NULL — the caller decides how to render the
    480  * miss (objdump falls back to hex). The covered set matches what the
    481  * dumpers actually emit; extend here when a new code needs a name. */
    482 
    483 const char* kit_dwarf_tag_name(uint32_t tag) {
    484   switch (tag) {
    485     case 0x01:
    486       return "DW_TAG_array_type";
    487     case 0x04:
    488       return "DW_TAG_enumeration_type";
    489     case 0x05:
    490       return "DW_TAG_formal_parameter";
    491     case 0x0b:
    492       return "DW_TAG_lexical_block";
    493     case 0x0d:
    494       return "DW_TAG_member";
    495     case 0x0f:
    496       return "DW_TAG_pointer_type";
    497     case 0x11:
    498       return "DW_TAG_compile_unit";
    499     case 0x13:
    500       return "DW_TAG_structure_type";
    501     case 0x15:
    502       return "DW_TAG_subroutine_type";
    503     case 0x16:
    504       return "DW_TAG_typedef";
    505     case 0x17:
    506       return "DW_TAG_union_type";
    507     case 0x18:
    508       return "DW_TAG_unspecified_parameters";
    509     case 0x1d:
    510       return "DW_TAG_inlined_subroutine";
    511     case 0x21:
    512       return "DW_TAG_subrange_type";
    513     case 0x24:
    514       return "DW_TAG_base_type";
    515     case 0x26:
    516       return "DW_TAG_const_type";
    517     case 0x28:
    518       return "DW_TAG_enumerator";
    519     case 0x2e:
    520       return "DW_TAG_subprogram";
    521     case 0x34:
    522       return "DW_TAG_variable";
    523     case 0x35:
    524       return "DW_TAG_volatile_type";
    525     case 0x37:
    526       return "DW_TAG_restrict_type";
    527     case 0x3b:
    528       return "DW_TAG_unspecified_type";
    529     default:
    530       return NULL;
    531   }
    532 }
    533 
    534 const char* kit_dwarf_attr_name(uint32_t attr) {
    535   switch (attr) {
    536     case 0x01:
    537       return "DW_AT_sibling";
    538     case 0x02:
    539       return "DW_AT_location";
    540     case 0x03:
    541       return "DW_AT_name";
    542     case 0x0b:
    543       return "DW_AT_byte_size";
    544     case 0x0d:
    545       return "DW_AT_bit_size";
    546     case 0x10:
    547       return "DW_AT_stmt_list";
    548     case 0x11:
    549       return "DW_AT_low_pc";
    550     case 0x12:
    551       return "DW_AT_high_pc";
    552     case 0x13:
    553       return "DW_AT_language";
    554     case 0x1b:
    555       return "DW_AT_comp_dir";
    556     case 0x1c:
    557       return "DW_AT_const_value";
    558     case 0x25:
    559       return "DW_AT_producer";
    560     case 0x27:
    561       return "DW_AT_prototyped";
    562     case 0x2f:
    563       return "DW_AT_upper_bound";
    564     case 0x34:
    565       return "DW_AT_artificial";
    566     case 0x37:
    567       return "DW_AT_count";
    568     case 0x38:
    569       return "DW_AT_data_member_location";
    570     case 0x39:
    571       return "DW_AT_decl_column";
    572     case 0x3a:
    573       return "DW_AT_decl_file";
    574     case 0x3b:
    575       return "DW_AT_decl_line";
    576     case 0x3c:
    577       return "DW_AT_declaration";
    578     case 0x3e:
    579       return "DW_AT_encoding";
    580     case 0x3f:
    581       return "DW_AT_external";
    582     case 0x40:
    583       return "DW_AT_frame_base";
    584     case 0x49:
    585       return "DW_AT_type";
    586     case 0x6e:
    587       return "DW_AT_linkage_name";
    588     case 0x88:
    589       return "DW_AT_alignment";
    590     default:
    591       return NULL;
    592   }
    593 }
    594 
    595 const char* kit_dwarf_form_name(uint32_t form) {
    596   switch (form) {
    597     case 0x01:
    598       return "DW_FORM_addr";
    599     case 0x05:
    600       return "DW_FORM_data2";
    601     case 0x06:
    602       return "DW_FORM_data4";
    603     case 0x07:
    604       return "DW_FORM_data8";
    605     case 0x08:
    606       return "DW_FORM_string";
    607     case 0x09:
    608       return "DW_FORM_block";
    609     case 0x0b:
    610       return "DW_FORM_data1";
    611     case 0x0c:
    612       return "DW_FORM_flag";
    613     case 0x0d:
    614       return "DW_FORM_sdata";
    615     case 0x0e:
    616       return "DW_FORM_strp";
    617     case 0x0f:
    618       return "DW_FORM_udata";
    619     case 0x10:
    620       return "DW_FORM_ref_addr";
    621     case 0x11:
    622       return "DW_FORM_ref1";
    623     case 0x12:
    624       return "DW_FORM_ref2";
    625     case 0x13:
    626       return "DW_FORM_ref4";
    627     case 0x14:
    628       return "DW_FORM_ref8";
    629     case 0x15:
    630       return "DW_FORM_ref_udata";
    631     case 0x17:
    632       return "DW_FORM_sec_offset";
    633     case 0x18:
    634       return "DW_FORM_exprloc";
    635     case 0x19:
    636       return "DW_FORM_flag_present";
    637     case 0x1a:
    638       return "DW_FORM_strx";
    639     case 0x1b:
    640       return "DW_FORM_addrx";
    641     case 0x1f:
    642       return "DW_FORM_line_strp";
    643     case 0x21:
    644       return "DW_FORM_implicit_const";
    645     case 0x25:
    646       return "DW_FORM_strx1";
    647     default:
    648       return NULL;
    649   }
    650 }