This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

PATCH: Update DWARF3 decoding ability


Hi Guys,

I am applying the attached patch to update readelf's (and objdump's) ability to display DWARF3 debug information. It adds support for some of the new values defined in the DWARF3 spec. I also updated the dwarf2.h header to mention where the DWARF3 spec can be found on the web, and to put the in proper names for a couple of deprecated strings.

Cheers
  Nick

include/elf/ChangeLog
2007-11-16  Nick Clifton  <nickc@redhat.com>

	* dwarf2.h: Mention the location of the DWARF3 spec on the web.
	(DW_AT_stride_size): Rename to DW_AT_bit_stride.
	(DW_AT_stride): Rename to DW_AT_byte_stride.

binutils/ChangeLog
2007-11-16  Nick Clifton  <nickc@redhat.com>

	* dwarf.c (process_extended_line_op): Add cases for HP extensions
	to the line ops.  Mention if an unknown op code is in the user
	defined range.
	(decode_location_expression): Add cases for HP extensions, the
	DW_OP_GNU_uninit extension and the DW_OP_call_frame_cfa and
	DW_OP_bit_piece DWARF3 operators.
	(read_and_display_attr): Correct list of attributes which can
	reference a location list.
	(read_and_display_attr_value): Add cases for DWARF3 values and HP
	extensions.
	Correct list of attributes which can reference a location list.
	(get_AT_name): Add cases for DWARF3 values and HP and PGI
	extensions.
Index: include/elf/dwarf2.h
===================================================================
RCS file: /cvs/src/src/include/elf/dwarf2.h,v
retrieving revision 1.20
diff -c -3 -p -r1.20 dwarf2.h
*** include/elf/dwarf2.h	18 May 2007 19:42:42 -0000	1.20
--- include/elf/dwarf2.h	16 Nov 2007 15:27:42 -0000
***************
*** 33,39 ****
     by UNIX International.  Copies of this specification are available from
     UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
  
!    This file also now contains definitions from the DWARF 3 specification.  */
  
  /* This file is shared between GCC and GDB, and should not contain
     prototypes.  */
--- 33,40 ----
     by UNIX International.  Copies of this specification are available from
     UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
  
!    This file also now contains definitions from the DWARF 3 specification
!    published Dec 20, 2005, available from: http://dwarf.freestandards.org.  */
  
  /* This file is shared between GCC and GDB, and should not contain
     prototypes.  */
*************** enum dwarf_attribute
*** 275,281 ****
      DW_AT_prototyped = 0x27,
      DW_AT_return_addr = 0x2a,
      DW_AT_start_scope = 0x2c,
!     DW_AT_stride_size = 0x2e,
      DW_AT_upper_bound = 0x2f,
      DW_AT_abstract_origin = 0x31,
      DW_AT_accessibility = 0x32,
--- 276,283 ----
      DW_AT_prototyped = 0x27,
      DW_AT_return_addr = 0x2a,
      DW_AT_start_scope = 0x2c,
!     DW_AT_bit_stride = 0x2e,
! #define DW_AT_stride_size   DW_AT_bit_stride  /* Note: The use of DW_AT_stride_size is deprecated.  */
      DW_AT_upper_bound = 0x2f,
      DW_AT_abstract_origin = 0x31,
      DW_AT_accessibility = 0x32,
*************** enum dwarf_attribute
*** 310,316 ****
      DW_AT_allocated     = 0x4e,
      DW_AT_associated    = 0x4f,
      DW_AT_data_location = 0x50,
!     DW_AT_stride        = 0x51,
      DW_AT_entry_pc      = 0x52,
      DW_AT_use_UTF8      = 0x53,
      DW_AT_extension     = 0x54,
--- 312,319 ----
      DW_AT_allocated     = 0x4e,
      DW_AT_associated    = 0x4f,
      DW_AT_data_location = 0x50,
!     DW_AT_byte_stride        = 0x51,
! #define DW_AT_stride   DW_AT_byte_stride  /* Note: The use of DW_AT_stride is deprecated.  */
      DW_AT_entry_pc      = 0x52,
      DW_AT_use_UTF8      = 0x53,
      DW_AT_extension     = 0x54,
Index: binutils/dwarf.c
===================================================================
RCS file: /cvs/src/src/binutils/dwarf.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 dwarf.c
*** binutils/dwarf.c	31 Oct 2007 16:09:52 -0000	1.19
--- binutils/dwarf.c	16 Nov 2007 15:27:43 -0000
*************** process_extended_line_op (unsigned char 
*** 270,277 ****
        printf (_("%s\n\n"), name);
        break;
  
      default:
!       printf (_("UNKNOWN: length %d\n"), len - bytes_read);
        break;
      }
  
--- 270,316 ----
        printf (_("%s\n\n"), name);
        break;
  
+     /* HP extensions.  */
+     case DW_LNE_HP_negate_is_UV_update:
+       printf ("DW_LNE_HP_negate_is_UV_update");
+       break;
+     case DW_LNE_HP_push_context:
+       printf ("DW_LNE_HP_push_context");
+       break;
+     case DW_LNE_HP_pop_context:
+       printf ("DW_LNE_HP_pop_context");
+       break;
+     case DW_LNE_HP_set_file_line_column:
+       printf ("DW_LNE_HP_set_file_line_column");
+       break;
+     case DW_LNE_HP_set_routine_name:
+       printf ("DW_LNE_HP_set_routine_name");
+       break;
+     case DW_LNE_HP_set_sequence:
+       printf ("DW_LNE_HP_set_sequence");
+       break;
+     case DW_LNE_HP_negate_post_semantics:
+       printf ("DW_LNE_HP_negate_post_semantics");
+       break;
+     case DW_LNE_HP_negate_function_exit:
+       printf ("DW_LNE_HP_negate_function_exit");
+       break;
+     case DW_LNE_HP_negate_front_end_logical:
+       printf ("DW_LNE_HP_negate_front_end_logical");
+       break;
+     case DW_LNE_HP_define_proc:
+       printf ("DW_LNE_HP_define_proc");
+       break;
+       
      default:
!       if (op_code >= DW_LNE_lo_user
! 	  /* The test against DW_LNW_hi_user is redundant due to
! 	     the limited range of the unsigned char data type used
! 	     for op_code.  */
! 	  /*&& op_code <= DW_LNE_hi_user*/)
! 	printf (_("user defined: length %d\n"), len - bytes_read);
!       else
! 	printf (_("UNKNOWN: length %d\n"), len - bytes_read);
        break;
      }
  
*************** decode_location_expression (unsigned cha
*** 892,906 ****
  	  data += 4;
  	  break;
  	case DW_OP_call_ref:
! 	  printf ("DW_OP_call_ref");
  	  break;
  	case DW_OP_form_tls_address:
  	  printf ("DW_OP_form_tls_address");
  	  break;
  
  	  /* GNU extensions.  */
  	case DW_OP_GNU_push_tls_address:
! 	  printf ("DW_OP_GNU_push_tls_address");
  	  break;
  
  	default:
--- 931,988 ----
  	  data += 4;
  	  break;
  	case DW_OP_call_ref:
! 	  /* XXX: Strictly speaking for 64-bit DWARF3 files
! 	     this ought to be an 8-byte wide computation.  */
! 	  printf ("DW_OP_call_ref: <%lx>", (long) byte_get (data, 4) + cu_offset);
! 	  data += 4;
  	  break;
  	case DW_OP_form_tls_address:
  	  printf ("DW_OP_form_tls_address");
  	  break;
+ 	case DW_OP_call_frame_cfa:
+ 	  printf ("DW_OP_call_frame_cfa");
+ 	  break;
+ 	case DW_OP_bit_piece:
+ 	  printf ("DW_OP_bit_piece: ");
+ 	  printf ("size: %lu ", read_leb128 (data, &bytes_read, 0));
+ 	  data += bytes_read;
+ 	  printf ("offset: %lu ", read_leb128 (data, &bytes_read, 0));
+ 	  data += bytes_read;
+ 	  break;
  
  	  /* GNU extensions.  */
  	case DW_OP_GNU_push_tls_address:
! 	  printf ("DW_OP_GNU_push_tls_address or DW_OP_HP_unknown");
! 	  break;
! 	case DW_OP_GNU_uninit:
! 	  printf ("DW_OP_GNU_uninit");
! 	  /* FIXME: Is there data associated with this OP ?  */
! 	  break;
! 
! 	  /* HP extensions.  */
! 	case DW_OP_HP_is_value:
! 	  printf ("DW_OP_HP_is_value");
! 	  /* FIXME: Is there data associated with this OP ?  */
! 	  break;
! 	case DW_OP_HP_fltconst4:
! 	  printf ("DW_OP_HP_fltconst4");
! 	  /* FIXME: Is there data associated with this OP ?  */
! 	  break;
! 	case DW_OP_HP_fltconst8:
! 	  printf ("DW_OP_HP_fltconst8");
! 	  /* FIXME: Is there data associated with this OP ?  */
! 	  break;
! 	case DW_OP_HP_mod_range:
! 	  printf ("DW_OP_HP_mod_range");
! 	  /* FIXME: Is there data associated with this OP ?  */
! 	  break;
! 	case DW_OP_HP_unmod_range:
! 	  printf ("DW_OP_HP_unmod_range");
! 	  /* FIXME: Is there data associated with this OP ?  */
! 	  break;
! 	case DW_OP_HP_tls:
! 	  printf ("DW_OP_HP_tls");
! 	  /* FIXME: Is there data associated with this OP ?  */
  	  break;
  
  	default:
*************** read_and_display_attr_value (unsigned lo
*** 1123,1137 ****
  	case DW_AT_frame_base:
  	  have_frame_base = 1;
  	case DW_AT_location:
  	case DW_AT_data_member_location:
  	case DW_AT_vtable_elem_location:
! 	case DW_AT_allocated:
! 	case DW_AT_associated:
! 	case DW_AT_data_location:
! 	case DW_AT_stride:
! 	case DW_AT_upper_bound:
! 	case DW_AT_lower_bound:
! 	  if (form == DW_FORM_data4 || form == DW_FORM_data8)
  	    {
  	      /* Process location list.  */
  	      unsigned int max = debug_info_p->max_loc_offsets;
--- 1205,1218 ----
  	case DW_AT_frame_base:
  	  have_frame_base = 1;
  	case DW_AT_location:
+ 	case DW_AT_string_length:
+ 	case DW_AT_return_addr:
  	case DW_AT_data_member_location:
  	case DW_AT_vtable_elem_location:
! 	case DW_AT_segment:
! 	case DW_AT_static_link:
! 	case DW_AT_use_location:
!     	  if (form == DW_FORM_data4 || form == DW_FORM_data8)
  	    {
  	      /* Process location list.  */
  	      unsigned int max = debug_info_p->max_loc_offsets;
*************** read_and_display_attr_value (unsigned lo
*** 1153,1159 ****
  	      debug_info_p->num_loc_offsets++;
  	    }
  	  break;
! 	
  	case DW_AT_low_pc:
  	  if (need_base_address)
  	    debug_info_p->base_address = uvalue;
--- 1234,1240 ----
  	      debug_info_p->num_loc_offsets++;
  	    }
  	  break;
! 
  	case DW_AT_low_pc:
  	  if (need_base_address)
  	    debug_info_p->base_address = uvalue;
*************** read_and_display_attr_value (unsigned lo
*** 1262,1270 ****
  	case DW_ATE_signed_char:	printf ("(signed char)"); break;
  	case DW_ATE_unsigned:		printf ("(unsigned)"); break;
  	case DW_ATE_unsigned_char:	printf ("(unsigned char)"); break;
! 	  /* DWARF 2.1 value.  */
  	case DW_ATE_imaginary_float:	printf ("(imaginary float)"); break;
  	case DW_ATE_decimal_float:	printf ("(decimal float)"); break;
  	default:
  	  if (uvalue >= DW_ATE_lo_user
  	      && uvalue <= DW_ATE_hi_user)
--- 1343,1366 ----
  	case DW_ATE_signed_char:	printf ("(signed char)"); break;
  	case DW_ATE_unsigned:		printf ("(unsigned)"); break;
  	case DW_ATE_unsigned_char:	printf ("(unsigned char)"); break;
! 	  /* DWARF 2.1 values:  */
  	case DW_ATE_imaginary_float:	printf ("(imaginary float)"); break;
  	case DW_ATE_decimal_float:	printf ("(decimal float)"); break;
+ 	  /* DWARF 3 values:  */
+ 	case DW_ATE_packed_decimal:	printf ("(packed_decimal)"); break;
+ 	case DW_ATE_numeric_string:	printf ("(numeric_string)"); break;
+ 	case DW_ATE_edited:		printf ("(edited)"); break;
+ 	case DW_ATE_signed_fixed:	printf ("(signed_fixed)"); break;
+ 	case DW_ATE_unsigned_fixed:	printf ("(unsigned_fixed)"); break;
+ 	  /* HP extensions:  */
+ 	case DW_ATE_HP_float80:		printf ("(HP_float80)"); break;
+ 	case DW_ATE_HP_complex_float80:	printf ("(HP_complex_float80)"); break;
+ 	case DW_ATE_HP_float128:	printf ("(HP_float128)"); break;
+ 	case DW_ATE_HP_complex_float128:printf ("(HP_complex_float128)"); break;
+ 	case DW_ATE_HP_floathpintel:	printf ("(HP_floathpintel)"); break;
+ 	case DW_ATE_HP_imaginary_float80:	printf ("(HP_imaginary_float80)"); break;
+ 	case DW_ATE_HP_imaginary_float128:	printf ("(HP_imaginary_float128)"); break;
+ 
  	default:
  	  if (uvalue >= DW_ATE_lo_user
  	      && uvalue <= DW_ATE_hi_user)
*************** read_and_display_attr_value (unsigned lo
*** 1345,1358 ****
      case DW_AT_frame_base:
        have_frame_base = 1;
      case DW_AT_location:
      case DW_AT_data_member_location:
      case DW_AT_vtable_elem_location:
      case DW_AT_allocated:
      case DW_AT_associated:
      case DW_AT_data_location:
      case DW_AT_stride:
      case DW_AT_upper_bound:
!     case DW_AT_lower_bound:
        if (block_start)
  	{
  	  int need_frame_base;
--- 1441,1462 ----
      case DW_AT_frame_base:
        have_frame_base = 1;
      case DW_AT_location:
+     case DW_AT_string_length:
+     case DW_AT_return_addr:
      case DW_AT_data_member_location:
      case DW_AT_vtable_elem_location:
+     case DW_AT_segment:
+     case DW_AT_static_link:
+     case DW_AT_use_location:
+       if (form == DW_FORM_data4 || form == DW_FORM_data8)
+ 	printf (_("(location list)"));
+       /* Fall through.  */
      case DW_AT_allocated:
      case DW_AT_associated:
      case DW_AT_data_location:
      case DW_AT_stride:
      case DW_AT_upper_bound:
!     case DW_AT_lower_bound:      
        if (block_start)
  	{
  	  int need_frame_base;
*************** read_and_display_attr_value (unsigned lo
*** 1366,1374 ****
  	  if (need_frame_base && !have_frame_base)
  	    printf (_(" [without DW_AT_frame_base]"));
  	}
-       else if (form == DW_FORM_data4 || form == DW_FORM_data8)
- 	printf (_("(location list)"));
- 
        break;
  
      default:
--- 1470,1475 ----
*************** get_AT_name (unsigned long attribute)
*** 1458,1476 ****
      case DW_AT_call_column:		return "DW_AT_call_column";
      case DW_AT_call_file:		return "DW_AT_call_file";
      case DW_AT_call_line:		return "DW_AT_call_line";
!       /* SGI/MIPS extensions.  */
!     case DW_AT_MIPS_fde:		return "DW_AT_MIPS_fde";
!     case DW_AT_MIPS_loop_begin:		return "DW_AT_MIPS_loop_begin";
!     case DW_AT_MIPS_tail_loop_begin:	return "DW_AT_MIPS_tail_loop_begin";
!     case DW_AT_MIPS_epilog_begin:	return "DW_AT_MIPS_epilog_begin";
!     case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
!     case DW_AT_MIPS_software_pipeline_depth:
!       return "DW_AT_MIPS_software_pipeline_depth";
!     case DW_AT_MIPS_linkage_name:	return "DW_AT_MIPS_linkage_name";
!     case DW_AT_MIPS_stride:		return "DW_AT_MIPS_stride";
!     case DW_AT_MIPS_abstract_name:	return "DW_AT_MIPS_abstract_name";
!     case DW_AT_MIPS_clone_origin:	return "DW_AT_MIPS_clone_origin";
!     case DW_AT_MIPS_has_inlines:	return "DW_AT_MIPS_has_inlines";
        /* GNU extensions.  */
      case DW_AT_sf_names:		return "DW_AT_sf_names";
      case DW_AT_src_info:		return "DW_AT_src_info";
--- 1559,1610 ----
      case DW_AT_call_column:		return "DW_AT_call_column";
      case DW_AT_call_file:		return "DW_AT_call_file";
      case DW_AT_call_line:		return "DW_AT_call_line";
!     case DW_AT_description:		return "DW_AT_description";
!     case DW_AT_binary_scale:		return "DW_AT_binary_scale";
!     case DW_AT_decimal_scale:		return "DW_AT_decimal_scale";
!     case DW_AT_small:			return "DW_AT_small";
!     case DW_AT_decimal_sign:		return "DW_AT_decimal_sign";
!     case DW_AT_digit_count:		return "DW_AT_digit_count";
!     case DW_AT_picture_string:		return "DW_AT_picture_string";
!     case DW_AT_mutable:			return "DW_AT_mutable";
!     case DW_AT_threads_scaled:		return "DW_AT_threads_scaled";
!     case DW_AT_explicit:		return "DW_AT_explicit";
!     case DW_AT_object_pointer:		return "DW_AT_object_pointer";
!     case DW_AT_endianity:		return "DW_AT_endianity";
!     case DW_AT_elemental:		return "DW_AT_elemental";
!     case DW_AT_pure:			return "DW_AT_pure";
!     case DW_AT_recursive:		return "DW_AT_recursive";
! 
!       /* HP and SGI/MIPS extensions.  */
!     case DW_AT_MIPS_loop_begin:			return "DW_AT_MIPS_loop_begin";
!     case DW_AT_MIPS_tail_loop_begin:		return "DW_AT_MIPS_tail_loop_begin";
!     case DW_AT_MIPS_epilog_begin:		return "DW_AT_MIPS_epilog_begin";
!     case DW_AT_MIPS_loop_unroll_factor: 	return "DW_AT_MIPS_loop_unroll_factor";
!     case DW_AT_MIPS_software_pipeline_depth: 	return "DW_AT_MIPS_software_pipeline_depth";
!     case DW_AT_MIPS_linkage_name:		return "DW_AT_MIPS_linkage_name";
!     case DW_AT_MIPS_stride:			return "DW_AT_MIPS_stride";
!     case DW_AT_MIPS_abstract_name:		return "DW_AT_MIPS_abstract_name";
!     case DW_AT_MIPS_clone_origin:		return "DW_AT_MIPS_clone_origin";
!     case DW_AT_MIPS_has_inlines:		return "DW_AT_MIPS_has_inlines";
! 
!       /* HP Extensions.  */
!     case DW_AT_HP_block_index:			return "DW_AT_HP_block_index";      
!     case DW_AT_HP_actuals_stmt_list:		return "DW_AT_HP_actuals_stmt_list";
!     case DW_AT_HP_proc_per_section:		return "DW_AT_HP_proc_per_section";
!     case DW_AT_HP_raw_data_ptr:			return "DW_AT_HP_raw_data_ptr";
!     case DW_AT_HP_pass_by_reference:		return "DW_AT_HP_pass_by_reference";
!     case DW_AT_HP_opt_level:			return "DW_AT_HP_opt_level";
!     case DW_AT_HP_prof_version_id:		return "DW_AT_HP_prof_version_id";
!     case DW_AT_HP_opt_flags:			return "DW_AT_HP_opt_flags";
!     case DW_AT_HP_cold_region_low_pc:		return "DW_AT_HP_cold_region_low_pc";
!     case DW_AT_HP_cold_region_high_pc:		return "DW_AT_HP_cold_region_high_pc";
!     case DW_AT_HP_all_variables_modifiable:	return "DW_AT_HP_all_variables_modifiable";
!     case DW_AT_HP_linkage_name:			return "DW_AT_HP_linkage_name";
!     case DW_AT_HP_prof_flags:			return "DW_AT_HP_prof_flags";
! 
!       /* One value is shared by the MIPS and HP extensions:  */
!     case DW_AT_MIPS_fde:			return "DW_AT_MIPS_fde or DW_AT_HP_unmodifiable";
!       
        /* GNU extensions.  */
      case DW_AT_sf_names:		return "DW_AT_sf_names";
      case DW_AT_src_info:		return "DW_AT_src_info";
*************** get_AT_name (unsigned long attribute)
*** 1479,1486 ****
--- 1613,1627 ----
      case DW_AT_body_begin:		return "DW_AT_body_begin";
      case DW_AT_body_end:		return "DW_AT_body_end";
      case DW_AT_GNU_vector:		return "DW_AT_GNU_vector";
+ 
        /* UPC extension.  */
      case DW_AT_upc_threads_scaled:	return "DW_AT_upc_threads_scaled";
+ 
+     /* PGI (STMicroelectronics) extensions.  */
+     case DW_AT_PGI_lbase:		return "DW_AT_PGI_lbase";
+     case DW_AT_PGI_soffset:		return "DW_AT_PGI_soffset";
+     case DW_AT_PGI_lstride:		return "DW_AT_PGI_lstride";
+ 
      default:
        {
  	static char buffer[100];

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