aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2023-04-13 22:07:51 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2023-04-13 22:07:51 -0300
commit31bc0d7410572f6e03e3ed9da7c8c6f0d8df23c8 (patch)
tree52e57f16bd3d5c88580fd7e10dd8c0125c772ecb
parentbfa033b07f50a20229f33479c1058a3c7c22453f (diff)
downloaddwarves-31bc0d7410572f6e03e3ed9da7c8c6f0d8df23c8.tar.gz
dwarf_loader: DW_TAG_subroutine_type may have a DW_AT_byte_size
First seen in Go, where DW_TAG_member don't come with a DW_AT_byte_size, so we need to figure it out from its type using tag__byte_size() in class_member__cache_byte_size() so either use the DW_AT_byte size that comes in DW_TAG_subroutine_type or the cu->addr_size to use the pointer size. With this we manage to pretty print this Go class: $ pahole -C runtime._type ../prometheus-uprobes/main struct runtime._type { uintptr size; /* 0 8 */ uintptr ptrdata; /* 8 8 */ uint32 hash; /* 16 4 */ runtime.tflag tflag; /* 20 1 */ uint8 align; /* 21 1 */ uint8 fieldAlign; /* 22 1 */ uint8 kind; /* 23 1 */ func(unsafe.Pointer, unsafe.Pointer) bool equal; /* 24 8 */ uint8 * gcdata; /* 32 8 */ runtime.nameOff str; /* 40 4 */ runtime.typeOff ptrToThis; /* 44 4 */ /* size: 48, cachelines: 1, members: 11 */ /* last cacheline: 48 bytes */ }; At some point we should select how to pretty print this, with a Go formatter and the above C one :-) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--dwarf_loader.c1
-rw-r--r--dwarves.c1
-rw-r--r--dwarves.h1
3 files changed, 3 insertions, 0 deletions
diff --git a/dwarf_loader.c b/dwarf_loader.c
index 07a74a1..ccf3194 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -1286,6 +1286,7 @@ static void ftype__init(struct ftype *ftype, Dwarf_Die *die, struct cu *cu)
assert(tag == DW_TAG_subprogram || tag == DW_TAG_subroutine_type);
#endif
tag__init(&ftype->tag, cu, die);
+ ftype->byte_size = attr_numeric(die, DW_AT_byte_size);
INIT_LIST_HEAD(&ftype->parms);
ftype->nr_parms = 0;
ftype->unspec_parms = 0;
diff --git a/dwarves.c b/dwarves.c
index b43031c..218367b 100644
--- a/dwarves.c
+++ b/dwarves.c
@@ -1136,6 +1136,7 @@ size_t tag__size(const struct tag *tag, const struct cu *cu)
case DW_TAG_reference_type: return cu->addr_size;
case DW_TAG_base_type: return base_type__size(tag);
case DW_TAG_enumeration_type: return tag__type(tag)->size / 8;
+ case DW_TAG_subroutine_type: return tag__ftype(tag)->byte_size ?: cu->addr_size;
}
if (tag->type == 0) { /* struct class: unions, structs */
diff --git a/dwarves.h b/dwarves.h
index f305923..eb1a6df 100644
--- a/dwarves.h
+++ b/dwarves.h
@@ -868,6 +868,7 @@ static inline const char *parameter__name(const struct parameter *parm)
struct ftype {
struct tag tag;
struct list_head parms;
+ size_t byte_size; // First seen in DW_TAG_subroutine_type in a Go CU
uint16_t nr_parms;
uint8_t unspec_parms:1; /* just one bit is needed */
uint8_t optimized_parms:1;