Download raw body.
ctfconv fix enum and array encoding, plus some more
Typical yak shave, I wanted to fix something in ddb and ended up in
ctfconv.
The problem at hand is that enums and arrays are not encoded
correctly. On top of that fix dw_at2name() and add DW_AT_noreturn so that
ctfconv -d ctfconv works.
Right now most enums end up with -1 as their value. The problem is that
dav2val() did not handle DW_FORM_udata which is used for enums.
The other problem is that arrays are to aggressively merged together.
Similar to basic types arrays need to compare the number of elements and
only match if the number is the same.
Also it_cmp() should return 0 if no difference is found.
Oh and then there is the nice typedef VOID void; issue with bsd.gdb that
also results in a crash. It seems that the workaround for void needs to
include CTF_K_TYPEDEF as well.
--
:wq Claudio
Index: dw.c
===================================================================
RCS file: /cvs/src/usr.bin/ctfconv/dw.c,v
diff -u -p -r1.5 dw.c
--- dw.c 25 Oct 2021 19:54:29 -0000 1.5
+++ dw.c 20 Feb 2024 15:50:08 -0000
@@ -21,6 +21,7 @@
#include <errno.h>
#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -184,6 +185,7 @@ const char *
dw_at2name(uint64_t at)
{
static const char *dw_attrs[] = { DW_AT_NAMES };
+ static char buf[64];
if (at <= nitems(dw_attrs))
return dw_attrs[at - 1];
@@ -193,7 +195,8 @@ dw_at2name(uint64_t at)
if (at == DW_AT_hi_user)
return "DW_AT_hi_user";
- return NULL;
+ snprintf(buf, sizeof(buf), "#%llu", at);
+ return buf;
}
const char *
Index: dwarf.h
===================================================================
RCS file: /cvs/src/usr.bin/ctfconv/dwarf.h,v
diff -u -p -r1.2 dwarf.h
--- dwarf.h 11 Aug 2017 14:58:56 -0000 1.2
+++ dwarf.h 20 Feb 2024 15:59:49 -0000
@@ -273,6 +273,7 @@
#define DW_AT_const_expr 0x6c
#define DW_AT_enum_class 0x6d
#define DW_AT_linkage_name 0x6e
+#define DW_AT_noreturn 0x87
#define DW_AT_lo_user 0x2000
#define DW_AT_hi_user 0x3fff
@@ -413,6 +414,7 @@
"DW_AT_const_expr", \
"DW_AT_enum_class", \
"DW_AT_linkage_name", \
+ [0x87 - 1] = "DW_AT_noreturn", \
#define DW_FORM_addr 0x01
#define DW_FORM_block2 0x03
Index: parse.c
===================================================================
RCS file: /cvs/src/usr.bin/ctfconv/parse.c,v
diff -u -p -r1.15 parse.c
--- parse.c 26 Dec 2022 18:43:49 -0000 1.15
+++ parse.c 21 Feb 2024 09:59:20 -0000
@@ -50,7 +50,11 @@ struct pool it_pool, im_pool, ir_pool;
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
-#define DPRINTF(x...) do { /*printf(x)*/ } while (0)
+#ifdef DEBUG
+#define DPRINTF(x...) do { printf(x); } while (0)
+#else
+#define DPRINTF(x...) do { ; } while (0)
+#endif
#define VOID_OFFSET 1 /* Fake offset for generating "void" type. */
@@ -329,6 +333,11 @@ it_cmp(struct itype *a, struct itype *b)
(diff = (a->it_size - b->it_size) != 0))
return diff;
+ /* Arrays need to have same number of elements */
+ if ((a->it_type == CTF_K_ARRAY) &&
+ (diff = (a->it_nelems - b->it_nelems) != 0))
+ return diff;
+
/* Match by name */
if (!(a->it_flags & ITF_ANON) && !(b->it_flags & ITF_ANON))
return strcmp(it_name(a), it_name(b));
@@ -341,7 +350,7 @@ it_cmp(struct itype *a, struct itype *b)
if ((a->it_refp != NULL) && (b->it_refp != NULL))
return it_cmp(a->it_refp, b->it_refp);
- return 1;
+ return 0;
}
int
@@ -833,7 +842,7 @@ parse_refers(struct dwdie *die, size_t p
if (it->it_ref == 0 && (it->it_size == sizeof(void *) ||
type == CTF_K_CONST || type == CTF_K_VOLATILE ||
- type == CTF_K_POINTER)) {
+ type == CTF_K_POINTER || type == CTF_K_TYPEDEF)) {
/* Work around GCC/clang not emiting a type for void */
it->it_flags &= ~ITF_UNRES;
it->it_ref = VOID_OFFSET;
@@ -1345,6 +1354,8 @@ dav2val(struct dwaval *dav, size_t psz)
case DW_FORM_sdata:
case DW_FORM_data8:
case DW_FORM_ref8:
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
val = dav->dav_u64;
break;
case DW_FORM_strp:
ctfconv fix enum and array encoding, plus some more