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);
}