This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB 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] Support DW_OP_call2 and DW_OP_call4 (PR 10640)


Hi,

as GCC discusses its use in PR41343 the patch implements it for GDB.

Tried first to follow the #if0-ed prototype get_subr but it was inconvenient
at least because for LOC_STATIC we would need to evaluation-time construct new
artificial DWARF block.

It has some new overhead due to symbol_hash for all symbol DIEs.  Did not
measure it but I am not aware much how it could be avoided as GDB does not
parse the DWARF blocks while reading them in.

No regressions on {x86_64,x86_64-m32,i686}-fedora11-linux-gnu.


Thanks,
Jan


gdb/
2009-09-20  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Fix PR 10640.
	* dwarf2-frame.c (no_get_tls_address): New comment.
	(no_dwarf_call): New function.
	(execute_stack_op): Set CTX->DWARF_CALL.
	* dwarf2expr.c (execute_stack_op <DW_OP_call2>)
	(execute_stack_op <DW_OP_call4>): New.
	* dwarf2expr.h (struct dwarf_expr_context <dwarf_call>): New.
	(struct dwarf_expr_context <get_subr>): Remove the #if0-ed field.
	* dwarf2loc.c (struct dwarf_expr_baton <objfile>): Remove.
	(struct dwarf_expr_baton <per_cu>): New.
	(dwarf_expr_tls_address): Use PER_CU instead of OBJFILE now.
	(per_cu_dwarf_call, dwarf_expr_dwarf_call): New functions.
	(dwarf2_evaluate_loc_desc): Drop initialization of BATON.OBJFILE.
	Initialize new BATON.PER_CU.  Adjust CTX->GDBARCH initialization for
	this change.  Initialize CTX->DWARF_CALL.
	(struct needs_frame_baton <per_cu>): New field.
	(needs_frame_dwarf_call, locexpr_dwarf_call): New function.
	(dwarf2_loc_desc_needs_frame): Initialize new BATON.PER_CU.  Initialize
	CTX->DWARF_CALL.
	(dwarf2_locexpr_funcs): Include locexpr_dwarf_call.
	* dwarf2loc.h (dwarf2_per_cu_get_die_symbol): New declaration.
	* dwarf2read.c (struct dwarf2_per_cu_data <symbol_hash>): New.
	(set_die_symbol): New function.
	(new_symbol): Call set_die_symbol.
	(struct dwarf2_offset_and_type): Move it above set_die_type.
	(offset_and_type_hash): Rename to ...
	(offset_hash): ... and make it reference only the offset.
	(offset_and_type_eq): Rename to ...
	(offset_eq): ... and make it reference only the offset.
	(set_die_type): Reference the new function names.
	(struct dwarf2_offset_and_symbol, set_die_symbol)
	(dwarf2_per_cu_get_die_symbol): New.
	* symtab.h (struct dwarf_expr_context): New opaque declaration.
	(struct symbol_computed_ops <dwarf_call>): New.

gdb/testsuite/
2009-09-20  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Test PR 10640.
	* gdb.dwarf2/dw2-op-call.exp, gdb.dwarf2/dw2-op-call.S: New.

--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -318,6 +318,8 @@ no_get_frame_cfa (void *baton)
 		  _("Support for DW_OP_call_frame_cfa is unimplemented"));
 }
 
+/* Helper function for execute_stack_op.  */
+
 static CORE_ADDR
 no_get_tls_address (void *baton, CORE_ADDR offset)
 {
@@ -325,6 +327,15 @@ no_get_tls_address (void *baton, CORE_ADDR offset)
 		  _("Support for DW_OP_GNU_push_tls_address is unimplemented"));
 }
 
+/* Helper function for execute_stack_op.  */
+
+static void
+no_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
+{
+  internal_error (__FILE__, __LINE__,
+		  _("Support for DW_OP_call* is invalid in CFI"));
+}
+
 /* Execute the required actions for both the DW_CFA_restore and
 DW_CFA_restore_extended instructions.  */
 static void
@@ -375,6 +386,7 @@ execute_stack_op (gdb_byte *exp, ULONGEST len, int addr_size,
   ctx->get_frame_base = no_get_frame_base;
   ctx->get_frame_cfa = no_get_frame_cfa;
   ctx->get_tls_address = no_get_tls_address;
+  ctx->dwarf_call = no_dwarf_call;
 
   dwarf_expr_push (ctx, initial, initial_in_stack_memory);
   dwarf_expr_eval (ctx, exp, len);
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -848,6 +848,18 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  ctx->initialized = 0;
 	  goto no_push;
 
+	case DW_OP_call2:
+	  result = extract_unsigned_integer (op_ptr, 2, byte_order);
+	  op_ptr += 2;
+	  ctx->dwarf_call (ctx, result);
+	  goto no_push;
+
+	case DW_OP_call4:
+	  result = extract_unsigned_integer (op_ptr, 4, byte_order);
+	  op_ptr += 4;
+	  ctx->dwarf_call (ctx, result);
+	  goto no_push;
+
 	default:
 	  error (_("Unhandled dwarf expression opcode 0x%x"), op);
 	}
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -94,15 +94,14 @@ struct dwarf_expr_context
      DW_OP_GNU_push_tls_address.  */
   CORE_ADDR (*get_tls_address) (void *baton, CORE_ADDR offset);
 
+  /* Execute DW_AT_location expression for the DWARF expression subroutine in
+     the die at DIE_OFFSET in the CU from CTX.  Do not touch STACK while it
+     being passed to and returned from the called DWARF subroutine.  */
+  void (*dwarf_call) (struct dwarf_expr_context *ctx, size_t die_offset);
+
 #if 0
   /* Not yet implemented.  */
 
-  /* Return the location expression for the dwarf expression
-     subroutine in the die at OFFSET in the current compilation unit.
-     The result must be live until the current expression evaluation
-     is complete.  */
-  unsigned char *(*get_subr) (void *baton, off_t offset, size_t *length);
-
   /* Return the `object address' for DW_OP_push_object_address.  */
   CORE_ADDR (*get_object_address) (void *baton);
 #endif
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -115,7 +115,7 @@ find_location_expression (struct dwarf2_loclist_baton *baton,
 struct dwarf_expr_baton
 {
   struct frame_info *frame;
-  struct objfile *objfile;
+  struct dwarf2_per_cu_data *per_cu;
 };
 
 /* Helper functions for dwarf2_evaluate_loc_desc.  */
@@ -211,8 +211,51 @@ static CORE_ADDR
 dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
 {
   struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
+  struct objfile *objfile = dwarf2_per_cu_objfile (debaton->per_cu);
 
-  return target_translate_tls_address (debaton->objfile, offset);
+  return target_translate_tls_address (objfile, offset);
+}
+
+/* Call DWARF subroutine from DW_AT_location of DIE at DIE_OFFSET in current CU
+   (as is PER_CU).  Pass to it and return from it CTX.
+
+   We ignore any failures as DWARF says "If there is no such attribute, then
+   there is no effect." and it would be difficult to distinguish valid and
+   invalid DWARF cases after the DWARF symbol has been read in.  */
+
+static void
+per_cu_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset,
+		   struct dwarf2_per_cu_data *per_cu)
+{
+  struct symbol *sym = dwarf2_per_cu_get_die_symbol (die_offset, per_cu);
+
+  if (sym == NULL)
+    return;
+
+  switch (SYMBOL_CLASS (sym))
+    {
+    case LOC_COMPUTED:
+      if (SYMBOL_COMPUTED_OPS (sym)->dwarf_call == NULL)
+      	error (_("Symbol class of \"%s\" does not support DW_OP_call*"),
+	       SYMBOL_PRINT_NAME (sym));
+
+      SYMBOL_COMPUTED_OPS (sym)->dwarf_call (sym, ctx);
+      break;
+      
+    case LOC_STATIC:
+      dwarf_expr_push (ctx, SYMBOL_VALUE_ADDRESS (sym), 0);
+      break;
+    }
+}
+
+/* Helper interface of per_cu_dwarf_call for dwarf2_evaluate_loc_desc.  */
+
+static void
+dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
+{
+  struct dwarf_expr_baton *debaton = ctx->baton;
+
+  return per_cu_dwarf_call (ctx, die_offset, debaton->per_cu);
 }
 
 struct piece_closure
@@ -395,12 +438,12 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
     }
 
   baton.frame = frame;
-  baton.objfile = dwarf2_per_cu_objfile (per_cu);
+  baton.per_cu = per_cu;
 
   ctx = new_dwarf_expr_context ();
   old_chain = make_cleanup_free_dwarf_expr_context (ctx);
 
-  ctx->gdbarch = get_objfile_arch (baton.objfile);
+  ctx->gdbarch = get_objfile_arch (dwarf2_per_cu_objfile (per_cu));
   ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
   ctx->baton = &baton;
   ctx->read_reg = dwarf_expr_read_reg;
@@ -408,6 +451,7 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
   ctx->get_frame_base = dwarf_expr_frame_base;
   ctx->get_frame_cfa = dwarf_expr_frame_cfa;
   ctx->get_tls_address = dwarf_expr_tls_address;
+  ctx->dwarf_call = dwarf_expr_dwarf_call;
 
   dwarf_expr_eval (ctx, data, size);
   if (ctx->num_pieces > 0)
@@ -496,6 +540,7 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
 struct needs_frame_baton
 {
   int needs_frame;
+  struct dwarf2_per_cu_data *per_cu;
 };
 
 /* Reads from registers do require a frame.  */
@@ -546,6 +591,16 @@ needs_frame_tls_address (void *baton, CORE_ADDR offset)
   return 1;
 }
 
+/* Helper interface of per_cu_dwarf_call for dwarf2_loc_desc_needs_frame.  */
+
+static void
+needs_frame_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
+{
+  struct needs_frame_baton *nf_baton = ctx->baton;
+
+  return per_cu_dwarf_call (ctx, die_offset, nf_baton->per_cu);
+}
+
 /* Return non-zero iff the location expression at DATA (length SIZE)
    requires a frame to evaluate.  */
 
@@ -559,6 +614,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size,
   struct cleanup *old_chain;
 
   baton.needs_frame = 0;
+  baton.per_cu = per_cu;
 
   ctx = new_dwarf_expr_context ();
   old_chain = make_cleanup_free_dwarf_expr_context (ctx);
@@ -571,6 +627,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size,
   ctx->get_frame_base = needs_frame_frame_base;
   ctx->get_frame_cfa = needs_frame_frame_cfa;
   ctx->get_tls_address = needs_frame_tls_address;
+  ctx->dwarf_call = needs_frame_dwarf_call;
 
   dwarf_expr_eval (ctx, data, size);
 
@@ -758,13 +815,28 @@ locexpr_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
 			     dlbaton->data, dlbaton->size);
 }
 
+/* Execute DWARF DW_AT_location block of SYMBOL for STACK of CTX.  */
+
+static void
+locexpr_dwarf_call (struct symbol *symbol, struct dwarf_expr_context *ctx)
+{
+  struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
+  struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
+
+  gdb_assert (ctx->gdbarch == get_objfile_arch (objfile));
+  gdb_assert (ctx->addr_size == dwarf2_per_cu_addr_size (dlbaton->per_cu));
+
+  dwarf_expr_eval (ctx, dlbaton->data, dlbaton->size);
+}
+
 /* The set of location functions used with the DWARF-2 expression
    evaluator.  */
 const struct symbol_computed_ops dwarf2_locexpr_funcs = {
   locexpr_read_variable,
   locexpr_read_needs_frame,
   locexpr_describe_location,
-  locexpr_tracepoint_var_ref
+  locexpr_tracepoint_var_ref,
+  locexpr_dwarf_call
 };
 
 
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -33,6 +33,9 @@ struct objfile *dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *cu);
 /* Return the address size given in the compilation unit header for CU.  */
 CORE_ADDR dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *cu);
 
+struct symbol *dwarf2_per_cu_get_die_symbol (size_t die_offset,
+					     struct dwarf2_per_cu_data *per_cu);
+
 /* The symbol location baton types used by the DWARF-2 reader (i.e.
    SYMBOL_LOCATION_BATON for a LOC_COMPUTED symbol).  "struct
    dwarf2_locexpr_baton" is for a symbol with a single location
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -377,6 +377,9 @@ struct dwarf2_per_cu_data
      it.  */
   htab_t type_hash;
 
+  /* Like type_hash above but map DIE offsets to `struct symbol's.  */
+  htab_t symbol_hash;
+
   /* The partial symbol table associated with this compilation unit,
      or NULL for partial units (which do not have an associated
      symtab).  */
@@ -1151,6 +1154,9 @@ static void free_one_cached_comp_unit (void *);
 static struct type *set_die_type (struct die_info *, struct type *,
 				  struct dwarf2_cu *);
 
+static void set_die_symbol (struct die_info *die, struct symbol *symbol,
+			    struct dwarf2_cu *cu);
+
 static void create_all_comp_units (struct objfile *);
 
 static void load_full_comp_unit (struct dwarf2_per_cu_data *,
@@ -8340,6 +8346,8 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 	    }
 	}
 
+      set_die_symbol (die, sym, cu);
+
       switch (die->tag)
 	{
 	case DW_TAG_label:
@@ -11634,35 +11642,39 @@ dwarf2_free_objfile (struct objfile *objfile)
   /* Everything else should be on the objfile obstack.  */
 }
 
-/* A pair of DIE offset and GDB type pointer.  We store these
-   in a hash table separate from the DIEs, and preserve them
-   when the DIEs are flushed out of cache.  */
-
-struct dwarf2_offset_and_type
-{
-  unsigned int offset;
-  struct type *type;
-};
-
-/* Hash function for a dwarf2_offset_and_type.  */
+/* Hash function for a structure containing `unsigned int' DIE offset as its
+   very first element.  */
 
 static hashval_t
-offset_and_type_hash (const void *item)
+offset_hash (const void *item)
 {
-  const struct dwarf2_offset_and_type *ofs = item;
-  return ofs->offset;
+  const unsigned int *offsetp = item;
+
+  return *offsetp;
 }
 
-/* Equality function for a dwarf2_offset_and_type.  */
+/* Equality function for a structure containing `unsigned int' DIE offset as
+   its very first element.  */
 
 static int
-offset_and_type_eq (const void *item_lhs, const void *item_rhs)
+offset_eq (const void *item_lhs, const void *item_rhs)
 {
-  const struct dwarf2_offset_and_type *ofs_lhs = item_lhs;
-  const struct dwarf2_offset_and_type *ofs_rhs = item_rhs;
-  return ofs_lhs->offset == ofs_rhs->offset;
+  const unsigned int *offsetp_lhs = item_lhs;
+  const unsigned int *offsetp_rhs = item_rhs;
+
+  return *offsetp_lhs == *offsetp_rhs;
 }
 
+/* A pair of DIE offset and GDB type pointer.  We store these
+   in a hash table separate from the DIEs, and preserve them
+   when the DIEs are flushed out of cache.  */
+
+struct dwarf2_offset_and_type
+{
+  unsigned int offset;
+  struct type *type;
+};
+
 /* Set the type associated with DIE to TYPE.  Save it in CU's hash
    table if necessary.  For convenience, return TYPE.  */
 
@@ -11676,8 +11688,8 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
       gdb_assert (cu->per_cu != NULL);
       cu->per_cu->type_hash
 	= htab_create_alloc_ex (cu->header.length / 24,
-				offset_and_type_hash,
-				offset_and_type_eq,
+				offset_hash,
+				offset_eq,
 				NULL,
 				&cu->objfile->objfile_obstack,
 				hashtab_obstack_allocate,
@@ -11694,6 +11706,64 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   return type;
 }
 
+/* A pair of DIE offset and GDB symbol pointer.  We store these
+   in a hash table separate from the DIEs, and preserve them
+   when the DIEs are flushed out of cache.  */
+
+struct dwarf2_offset_and_symbol
+{
+  unsigned int offset;
+  struct symbol *symbol;
+};
+
+/* Set the symbol associated with DIE to SYMBOL.  Save it in PER_CU's hash
+   table.  */
+
+static void
+set_die_symbol (struct die_info *die, struct symbol *symbol, struct dwarf2_cu *cu)
+{
+  struct dwarf2_per_cu_data *per_cu = cu->per_cu;
+  struct dwarf2_offset_and_symbol **slot, ofs;
+
+  gdb_assert (per_cu != NULL);
+
+  if (per_cu->symbol_hash == NULL)
+    per_cu->symbol_hash = htab_create_alloc_ex (cu->header.length / 24,
+						offset_hash,
+						offset_eq,
+						NULL,
+						&cu->objfile->objfile_obstack,
+						hashtab_obstack_allocate,
+						dummy_obstack_deallocate);
+
+  ofs.offset = die->offset;
+  ofs.symbol = symbol;
+  slot = (struct dwarf2_offset_and_symbol **)
+    htab_find_slot_with_hash (per_cu->symbol_hash, &ofs, ofs.offset, INSERT);
+  *slot = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (**slot));
+  **slot = ofs;
+}
+
+/* Find the symbol for DIE at DIE_OFFSET in PER_CU's symbol_hash, or return
+   NULL if DIE does not have a saved symbol.  */
+
+struct symbol *
+dwarf2_per_cu_get_die_symbol (size_t die_offset, struct dwarf2_per_cu_data *per_cu)
+{
+  struct dwarf2_offset_and_symbol *slot, ofs;
+  htab_t symbol_hash = per_cu->symbol_hash;
+
+  if (symbol_hash == NULL)
+    return NULL;
+
+  ofs.offset = die_offset;
+  slot = htab_find_with_hash (symbol_hash, &ofs, ofs.offset);
+  if (slot)
+    return slot->symbol;
+  else
+    return NULL;
+}
+
 /* Find the type for DIE in CU's type_hash, or return NULL if DIE does
    not have a saved type.  */
 
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -32,6 +32,7 @@ struct block;
 struct blockvector;
 struct axs_value;
 struct agent_expr;
+struct dwarf_expr_context;
 
 /* Some of the structures in this file are space critical.
    The space-critical structures are:
@@ -529,6 +530,11 @@ struct symbol_computed_ops
 
   void (*tracepoint_var_ref) (struct symbol *symbol, struct gdbarch *gdbarch,
 			      struct agent_expr *ax, struct axs_value *value);
+
+  /* Execute DW_AT_location expression for the DWARF expression subroutine in
+     the die at DIE_OFFSET in the CU from CTX.  Do not touch STACK while it
+     being passed to and returned from the called DWARF subroutine.  */
+  void (*dwarf_call) (struct symbol *symbol, struct dwarf_expr_context *ctx);
 };
 
 /* Functions used with LOC_REGISTER and LOC_REGPARM_ADDR.  */
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-op-call.S
@@ -0,0 +1,119 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2009 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Test DW_OP_call2 and DW_OP_call4, PR gdb/10640.  */
+
+	.section .data
+array1:	.2byte	1
+array2:	.2byte	2
+array3:	.2byte	3
+
+	.section .debug_info
+.Lcu1_begin:
+	/* CU header */
+	.4byte	.Lcu1_end - .Lcu1_start		/* Length of Compilation Unit */
+.Lcu1_start:
+	.2byte	2				/* DWARF Version */
+	.4byte	.Labbrev1_begin			/* Offset into abbrev section */
+	.byte	4				/* Pointer size */
+
+	/* CU die */
+	.uleb128 1				/* Abbrev: DW_TAG_compile_unit */
+	.ascii	"file1.txt\0"			/* DW_AT_name */
+	.ascii	"GNU C 3.3.3\0"			/* DW_AT_producer */
+	.byte	2				/* DW_LANG_C (C) */
+
+.L2byte_type:
+	.uleb128	2			/* Abbrev: DW_TAG_base_type */
+	.ascii		"2byte\0"		/* DW_AT_name */
+	.byte		2			/* DW_AT_byte_size */
+	.byte		7			/* DW_AT_encoding: DW_ATE_unsigned */
+
+.Larray1:
+	.uleb128	3			/* Abbrev: DW_TAG_variable */
+	.ascii		"array1\0"		/* DW_AT_name */
+	.4byte		.L2byte_type-.Lcu1_begin	/* DW_AT_type */
+	.byte		2f - 1f			/* DW_AT_location */
+1:	.byte		3			/*   DW_OP_addr */
+	.4byte		array			/*     <addr> */
+2:
+
+	.uleb128	3			/* Abbrev: DW_TAG_variable */
+	.ascii		"array2\0"		/* DW_AT_name */
+	.4byte		.L2byte_type-.Lcu1_begin	/* DW_AT_type */
+	.byte		2f - 1f			/* DW_AT_location */
+1:	.byte		0x98			/*   DW_OP_call2 */
+	.2byte		.Larray1-.Lcu1_begin	/*     <current CU offset> */
+	.byte		0x23			/*   DW_OP_plus_uconst */
+	.uleb128	array2-array1		/*     <uconst> */
+2:
+
+	.uleb128	3			/* Abbrev: DW_TAG_variable */
+	.ascii		"array3\0"		/* DW_AT_name */
+	.4byte		.L2byte_type-.Lcu1_begin	/* DW_AT_type */
+	.byte		2f - 1f			/* DW_AT_location */
+1:	.byte		0x99			/*   DW_OP_call4 */
+	.4byte		.Larray1-.Lcu1_begin	/*     <current CU offset> */
+	.byte		0x23			/*   DW_OP_plus_uconst */
+	.uleb128	array3-array1		/*     <uconst> */
+2:
+
+	.byte		0			/* End of children of CU */
+
+.Lcu1_end:
+
+/* Abbrev table */
+	.section .debug_abbrev
+.Labbrev1_begin:
+	.uleb128	1			/* Abbrev code */
+	.uleb128	0x11			/* DW_TAG_compile_unit */
+	.byte		1			/* has_children */
+	.uleb128	0x3			/* DW_AT_name */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0x25			/* DW_AT_producer */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0x13			/* DW_AT_language */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.uleb128	2			/* Abbrev code */
+	.uleb128	0x24			/* DW_TAG_base_type */
+	.byte		0			/* has_children */
+	.uleb128	0x3			/* DW_AT_name */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0xb			/* DW_AT_byte_size */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.uleb128	0x3e			/* DW_AT_encoding */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.uleb128	3			/* Abbrev code */
+	.uleb128	0x34			/* DW_TAG_variable */
+	.byte		0			/* has_children */
+	.uleb128	0x3			/* DW_AT_name */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0x49			/* DW_AT_type */
+	.uleb128	0x13			/* DW_FORM_ref4 */
+	.uleb128	0x2			/* DW_AT_location */
+	.uleb128	0xa			/* DW_FORM_block1 */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-op-call.exp
@@ -0,0 +1,41 @@
+# Copyright 2009 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test DW_OP_call2 and DW_OP_call4, PR gdb/10640.
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+# For now pick a sampling of likely targets.
+if {![istarget *-*-linux*]
+    && ![istarget *-*-gnu*]
+    && ![istarget *-*-elf*]
+    && ![istarget *-*-openbsd*]
+    && ![istarget arm-*-eabi*]
+    && ![istarget powerpc-*-eabi*]} {
+    return 0  
+}
+
+set testfile "dw2-op-call"
+set srcfile ${testfile}.S
+set executable ${testfile}.x
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${executable}" object {nodebug}] != "" } {
+    return -1
+}
+
+clean_restart $executable
+
+gdb_test "p array1" " = 1"
+gdb_test "p array2" " = 2" "array2 using DW_OP_call2"
+gdb_test "p array3" " = 3" "array3 using DW_OP_call4"


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