procter@ recently found that pretty-printing `th0' in ddb(4) was
incorrect.  The global variable is a 'struct timehands' but the CTF
section thought it was a 'struct tcphdr'.  That's because net/tcp_subr.o
contains a local variable with the same name inside tcp_signature().

So the diff below makes ctfconv(1) skip non-global variables.  I looked
at our two base compilers: clang(1) doesn't emit a DW_AT_location for
local variable while gcc(1) sets it to 'location list'.  So the diff
below only consider a variable as global if 'DW_AT_location' is a byte
block.

As a side-effect this speeds up ctfconv(1) a bit :o)

ok?

Index: parse.c
===================================================================
RCS file: /cvs/src/usr.bin/ctfconv/parse.c,v
retrieving revision 1.11
diff -u -p -r1.11 parse.c
--- parse.c     31 Jan 2018 14:47:13 -0000      1.11
+++ parse.c     5 Nov 2019 15:41:48 -0000
@@ -1263,7 +1263,7 @@ parse_variable(struct dwdie *die, size_t
        struct dwaval *dav;
        const char *name = NULL;
        size_t ref = 0;
-       int forward = 0;
+       int forward = 0, global = 0;
 
        SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                switch (dav->dav_dat->dat_attr) {
@@ -1276,6 +1276,18 @@ parse_variable(struct dwdie *die, size_t
                case DW_AT_type:
                        ref = dav2val(dav, psz);
                        break;
+               case DW_AT_location:
+                       switch (dav->dav_dat->dat_form) {
+                       case DW_FORM_block:
+                       case DW_FORM_block1:
+                       case DW_FORM_block2:
+                       case DW_FORM_block4:
+                               global = 1;
+                               break;
+                       default:
+                               break;
+                       }
+                       break;
                default:
                        DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
                        break;
@@ -1283,7 +1295,7 @@ parse_variable(struct dwdie *die, size_t
        }
 
 
-       if (!forward && name != NULL) {
+       if (global && !forward && name != NULL) {
                it = it_new(++oidx, die->die_offset, name, 0, 0, ref, 0,
                    ITF_UNRES|ITF_OBJ);
        }

Reply via email to