From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5524 invoked by alias); 20 Sep 2009 12:37:00 -0000 Received: (qmail 5511 invoked by uid 22791); 20 Sep 2009 12:36:58 -0000 X-SWARE-Spam-Status: No, hits=-0.8 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_36,J_CHICKENPOX_55,J_CHICKENPOX_57,KAM_STOCKGEN,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 20 Sep 2009 12:36:52 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n8KCapiV007914 for ; Sun, 20 Sep 2009 08:36:51 -0400 Received: from host0.dyn.jankratochvil.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n8KCamcI011987 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Sun, 20 Sep 2009 08:36:50 -0400 Received: from host0.dyn.jankratochvil.net (localhost [127.0.0.1]) by host0.dyn.jankratochvil.net (8.14.3/8.14.3) with ESMTP id n8KCamlG030224 for ; Sun, 20 Sep 2009 14:36:48 +0200 Received: (from jkratoch@localhost) by host0.dyn.jankratochvil.net (8.14.3/8.14.3/Submit) id n8KCam52030223 for gdb-patches@sourceware.org; Sun, 20 Sep 2009 14:36:48 +0200 Date: Sun, 20 Sep 2009 12:37:00 -0000 From: Jan Kratochvil To: gdb-patches@sourceware.org Subject: [patch] Support DW_OP_call2 and DW_OP_call4 (PR 10640) Message-ID: <20090920123647.GA30021@host0.dyn.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-08-17) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-09/txt/msg00641.txt.bz2 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 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 ) (execute_stack_op ): New. * dwarf2expr.h (struct dwarf_expr_context ): New. (struct dwarf_expr_context ): Remove the #if0-ed field. * dwarf2loc.c (struct dwarf_expr_baton ): Remove. (struct dwarf_expr_baton ): 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 ): 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 ): 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 ): New. gdb/testsuite/ 2009-09-20 Jan Kratochvil 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 . */ + +/* 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 /* */ +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 /* */ + .byte 0x23 /* DW_OP_plus_uconst */ + .uleb128 array2-array1 /* */ +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 /* */ + .byte 0x23 /* DW_OP_plus_uconst */ + .uleb128 array3-array1 /* */ +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 . + +# 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"