This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Add support for call_site and entry_value to dwarf.h and readelf


Hi,

This adds support for the new GNU dwarf extensions call_site
tags and attributes, and entry_value operator. It adds the new
constants to dwarf.h and makes readelf print them out. I haven't
yet thought about how to extend dwarf_getlocation for it.

Patch attached and on the mjw/callsite branch.

After I push this to master I would like to merge master to
the dwarf branch again so known-dwarf.h picks it up and
dwarflint can start recognizing them.

Comments?

Cheers,

Mark
commit 1c309cf9f34216c6af5e1f1ecfe958f2060d7ac4
Author: Mark Wielaard <mjw@redhat.com>
Date:   Tue Mar 22 23:03:31 2011 +0100

    Add support for call_site and entry_value to dwarf.h and readelf.
    
    New tags DW_TAG_GNU_call_site and DW_TAG_GNU_call_site_parameter.
    New attributes DW_AT_GNU_call_site_value,
    DW_AT_GNU_call_site_data_value, DW_AT_GNU_call_site_target,
    DW_AT_GNU_call_site_target_clobbered, DW_AT_GNU_tail_call,
    DW_AT_GNU_all_tail_call_sites, DW_AT_GNU_all_call_sites,
    and DW_AT_GNU_all_source_call_sites.
    New operation DW_OP_GNU_entry_value.

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index fb98e92..0b17461 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,17 @@
+2011-03-22  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Add DW_TAG_GNU_call_site,
+	DW_TAG_GNU_call_site_parameter,
+	DW_AT_GNU_call_site_value,
+	DW_AT_GNU_call_site_data_value,
+	DW_AT_GNU_call_site_target,
+	DW_AT_GNU_call_site_target_clobbered,
+	DW_AT_GNU_tail_call,
+	DW_AT_GNU_all_tail_call_sites,
+	DW_AT_GNU_all_call_sites,
+	DW_AT_GNU_all_source_call_sites,
+	and DW_OP_GNU_entry_value.
+
 2011-03-10  Petr Machata  <pmachata@redhat.com>
 
 	* libdw/dwarf_tag.c (__libdw_findabbrev): Reject requests for
diff --git a/libdw/dwarf.h b/libdw/dwarf.h
index 940ffe3..c0dcbdd 100644
--- a/libdw/dwarf.h
+++ b/libdw/dwarf.h
@@ -128,6 +128,8 @@ enum
     DW_TAG_GNU_template_template_param = 0x4106,
     DW_TAG_GNU_template_parameter_pack = 0x4107,
     DW_TAG_GNU_formal_parameter_pack = 0x4108,
+    DW_TAG_GNU_call_site = 0x4109,
+    DW_TAG_GNU_call_site_parameter = 0x410a,
 
     DW_TAG_hi_user = 0xffff
   };
@@ -277,6 +279,14 @@ enum
     DW_AT_GNU_shared_locks_required = 0x210e,
     DW_AT_GNU_odr_signature = 0x210f,
     DW_AT_GNU_template_name = 0x2110,
+    DW_AT_GNU_call_site_value = 0x2111,
+    DW_AT_GNU_call_site_data_value = 0x2112,
+    DW_AT_GNU_call_site_target = 0x2113,
+    DW_AT_GNU_call_site_target_clobbered = 0x2114,
+    DW_AT_GNU_tail_call = 0x2115,
+    DW_AT_GNU_all_tail_call_sites = 0x2116,
+    DW_AT_GNU_all_call_sites = 0x2117,
+    DW_AT_GNU_all_source_call_sites = 0x2118,
 
     DW_AT_hi_user = 0x3fff
   };
@@ -476,6 +486,7 @@ enum
     DW_OP_GNU_uninit = 0xf0,
     DW_OP_GNU_encoded_addr = 0xf1,
     DW_OP_GNU_implicit_pointer = 0xf2,
+    DW_OP_GNU_entry_value = 0xf3,
 
     DW_OP_lo_user = 0xe0,	/* Implementation-defined range start.  */
     DW_OP_hi_user = 0xff	/* Implementation-defined range end.  */
diff --git a/src/ChangeLog b/src/ChangeLog
index 6ba890f..df53d35 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,21 @@
+2011-03-22  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (dwarf_tag_string): Support DW_TAG_GNU_call_site
+	and DW_TAG_GNU_call_site_parameter.
+	(dwarf_attr_string): Support DW_AT_GNU_call_site_value,
+	DW_AT_GNU_call_site_data_value,
+	DW_AT_GNU_call_site_target,
+	DW_AT_GNU_call_site_target_clobbered,
+	DW_AT_GNU_tail_call,
+	DW_AT_GNU_all_tail_call_sites,
+	DW_AT_GNU_all_call_sites,
+	and DW_AT_GNU_all_source_call_sites.
+	(print_ops): Handle DW_OP_GNU_entry_value.
+	(attr_callback): Handle DW_AT_GNU_call_site_value,
+	DW_AT_GNU_call_site_data_value,
+	DW_AT_GNU_call_site_target,
+	and DW_AT_GNU_call_site_target_clobbered.
+
 2011-03-10  Mark Wielaard  <mjw@redhat.com>
 
 	* elflint.c (check_symtab): Use ebl_check_st_other_bits.
diff --git a/src/readelf.c b/src/readelf.c
index 956d8bd..9cd9d7a 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -3292,6 +3292,14 @@ dwarf_tag_string (unsigned int tag)
 	result = "GNU_formal_parameter_pack";
 	break;
 
+      case DW_TAG_GNU_call_site:
+	result = "DW_TAG_GNU_call_site";
+	break;
+
+      case DW_TAG_GNU_call_site_parameter:
+	result = "DW_TAG_GNU_call_site_parameter";
+	break;
+
       default:
 	if (tag < DW_TAG_lo_user)
 	  snprintf (buf, sizeof buf, gettext ("unknown tag %hx"), tag);
@@ -3550,6 +3558,38 @@ dwarf_attr_string (unsigned int attrnum)
 	result = "GNU_template_name";
 	break;
 
+      case DW_AT_GNU_call_site_value:
+	result = "GNU_call_site_value";
+	break;
+
+      case DW_AT_GNU_call_site_data_value:
+	result = "GNU_call_site_data_value";
+	break;
+
+      case DW_AT_GNU_call_site_target:
+	result = "GNU_call_site_target";
+	break;
+
+      case DW_AT_GNU_call_site_target_clobbered:
+	result = "GNU_call_site_target_clobbered";
+	break;
+
+      case DW_AT_GNU_tail_call:
+	result = "GNU_tail_call";
+	break;
+
+      case DW_AT_GNU_all_tail_call_sites:
+	result = "GNU_all_tail_call_sites";
+	break;
+
+      case DW_AT_GNU_all_call_sites:
+	result = "GNU_all_call_sites";
+	break;
+
+      case DW_AT_GNU_all_source_call_sites:
+	result = "GNU_all_source_call_sites";
+	break;
+
       default:
 	if (attrnum < DW_AT_lo_user)
 	  snprintf (buf, sizeof buf, gettext ("unknown attribute %hx"),
@@ -4018,6 +4058,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
       [DW_OP_implicit_value] = "implicit_value",
       [DW_OP_stack_value] = "stack_value",
       [DW_OP_GNU_implicit_pointer] = "GNU_implicit_pointer",
+      [DW_OP_GNU_entry_value] = "GNU_entry_value",
     };
 
   if (len == 0)
@@ -4282,6 +4323,21 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  offset += 1 + (data - start);
 	  break;
 
+	case DW_OP_GNU_entry_value:
+	  /* Size plus expression block */
+	  start = data;
+	  NEED (1);
+	  get_uleb128 (uleb, data); /* XXX check overrun */
+	  printf ("%*s[%4" PRIuMAX "] %s:\n",
+		  indent, "", (uintmax_t) offset, known[op]);
+	  NEED (uleb);
+	  print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
+		     addrsize, offset_size, uleb, data);
+	  data += uleb;
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
 	default:
 	  /* No Operand.  */
 	  if (op < sizeof known / sizeof known[0] && known[op] != NULL)
@@ -5533,6 +5589,10 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 	case DW_AT_frame_base:
 	case DW_AT_return_addr:
 	case DW_AT_static_link:
+	case DW_AT_GNU_call_site_value:
+	case DW_AT_GNU_call_site_data_value:
+	case DW_AT_GNU_call_site_target:
+	case DW_AT_GNU_call_site_target_clobbered:
 	  notice_listptr (section_loc, &known_loclistptr,
 			  cbargs->addrsize, cbargs->offset_size, num);
 	  if (!cbargs->silent)
@@ -5662,6 +5722,11 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 	case DW_AT_count:
 	case DW_AT_lower_bound:
 	case DW_AT_upper_bound:
+	case DW_AT_GNU_call_site_value:
+	case DW_AT_GNU_call_site_data_value:
+	case DW_AT_GNU_call_site_target:
+	case DW_AT_GNU_call_site_target_clobbered:
+	  putchar ('\n');
 	  print_ops (cbargs->dwflmod, cbargs->dbg,
 		     12 + level * 2, 12 + level * 2,
 		     cbargs->version, cbargs->addrsize, cbargs->offset_size,

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]