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>
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 @@
 	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 @@
 	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 @@
 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;