X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fdwarf2expr.c;h=3c81cba3dfc1156c7a6750652901ba0bf5cf5801;hb=3804da7e07a13c14210d79de55ebfe2318421164;hp=1aa6afc282f0bb641eddbd5851cf489519332de6;hpb=595d2e303c0ef1a5cd5af8868c1d41db0050eb29;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c index 1aa6afc282..3c81cba3df 100644 --- a/gdb/dwarf2expr.c +++ b/gdb/dwarf2expr.c @@ -1,6 +1,6 @@ /* DWARF 2 Expression Evaluator. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2020 Free Software Foundation, Inc. Contributed by Daniel Berlin (dan@dberlin.org) @@ -27,6 +27,8 @@ #include "dwarf2.h" #include "dwarf2expr.h" #include "dwarf2loc.h" +#include "gdbsupport/underlying.h" +#include "gdbarch.h" /* Cookie for gdbarch data. */ @@ -87,10 +89,7 @@ dwarf_expr_context::address_type () const /* Create a new context for the expression evaluator. */ dwarf_expr_context::dwarf_expr_context () -: stack (NULL), - stack_len (0), - stack_allocated (10), - gdbarch (NULL), +: gdbarch (NULL), addr_size (0), ref_addr_size (0), offset (0), @@ -99,53 +98,22 @@ dwarf_expr_context::dwarf_expr_context () location (DWARF_VALUE_MEMORY), len (0), data (NULL), - initialized (0), - num_pieces (0), - pieces (NULL) + initialized (0) { - this->stack = XNEWVEC (struct dwarf_stack_value, this->stack_allocated); -} - -/* Clean up a dwarf_expr_context. */ - -dwarf_expr_context::~dwarf_expr_context () -{ - xfree (this->stack); - xfree (this->pieces); -} - -/* Expand the memory allocated stack to contain at least - NEED more elements than are currently used. */ - -void -dwarf_expr_context::grow_stack (size_t need) -{ - if (this->stack_len + need > this->stack_allocated) - { - size_t newlen = this->stack_len + need + 10; - - this->stack = XRESIZEVEC (struct dwarf_stack_value, this->stack, newlen); - this->stack_allocated = newlen; - } } /* Push VALUE onto the stack. */ void -dwarf_expr_context::push (struct value *value, int in_stack_memory) +dwarf_expr_context::push (struct value *value, bool in_stack_memory) { - struct dwarf_stack_value *v; - - grow_stack (1); - v = &this->stack[this->stack_len++]; - v->value = value; - v->in_stack_memory = in_stack_memory; + stack.emplace_back (value, in_stack_memory); } /* Push VALUE onto the stack. */ void -dwarf_expr_context::push_address (CORE_ADDR value, int in_stack_memory) +dwarf_expr_context::push_address (CORE_ADDR value, bool in_stack_memory) { push (value_from_ulongest (address_type (), value), in_stack_memory); } @@ -155,9 +123,10 @@ dwarf_expr_context::push_address (CORE_ADDR value, int in_stack_memory) void dwarf_expr_context::pop () { - if (this->stack_len <= 0) + if (stack.empty ()) error (_("dwarf expression stack underflow")); - this->stack_len--; + + stack.pop_back (); } /* Retrieve the N'th item on the stack. */ @@ -165,11 +134,11 @@ dwarf_expr_context::pop () struct value * dwarf_expr_context::fetch (int n) { - if (this->stack_len <= n) + if (stack.size () <= n) error (_("Asked for position %d of stack, " - "stack only has %d elements on it."), - n, this->stack_len); - return this->stack[this->stack_len - (1 + n)].value; + "stack only has %zu elements on it."), + n, stack.size ()); + return stack[stack.size () - (1 + n)].value; } /* Require that TYPE be an integral type; throw an exception if not. */ @@ -262,69 +231,64 @@ dwarf_expr_context::fetch_address (int n) /* Retrieve the in_stack_memory flag of the N'th item on the stack. */ -int +bool dwarf_expr_context::fetch_in_stack_memory (int n) { - if (this->stack_len <= n) + if (stack.size () <= n) error (_("Asked for position %d of stack, " - "stack only has %d elements on it."), - n, this->stack_len); - return this->stack[this->stack_len - (1 + n)].in_stack_memory; + "stack only has %zu elements on it."), + n, stack.size ()); + return stack[stack.size () - (1 + n)].in_stack_memory; } /* Return true if the expression stack is empty. */ -int +bool dwarf_expr_context::stack_empty_p () const { - return this->stack_len == 0; + return stack.empty (); } /* Add a new piece to the dwarf_expr_context's piece list. */ void dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset) { - struct dwarf_expr_piece *p; - - this->num_pieces++; + this->pieces.emplace_back (); + dwarf_expr_piece &p = this->pieces.back (); - this->pieces - = XRESIZEVEC (struct dwarf_expr_piece, this->pieces, this->num_pieces); + p.location = this->location; + p.size = size; + p.offset = offset; - p = &this->pieces[this->num_pieces - 1]; - p->location = this->location; - p->size = size; - p->offset = offset; - - if (p->location == DWARF_VALUE_LITERAL) + if (p.location == DWARF_VALUE_LITERAL) { - p->v.literal.data = this->data; - p->v.literal.length = this->len; + p.v.literal.data = this->data; + p.v.literal.length = this->len; } else if (stack_empty_p ()) { - p->location = DWARF_VALUE_OPTIMIZED_OUT; + p.location = DWARF_VALUE_OPTIMIZED_OUT; /* Also reset the context's location, for our callers. This is a somewhat strange approach, but this lets us avoid setting the location to DWARF_VALUE_MEMORY in all the individual cases in the evaluator. */ this->location = DWARF_VALUE_OPTIMIZED_OUT; } - else if (p->location == DWARF_VALUE_MEMORY) + else if (p.location == DWARF_VALUE_MEMORY) { - p->v.mem.addr = fetch_address (0); - p->v.mem.in_stack_memory = fetch_in_stack_memory (0); + p.v.mem.addr = fetch_address (0); + p.v.mem.in_stack_memory = fetch_in_stack_memory (0); } - else if (p->location == DWARF_VALUE_IMPLICIT_POINTER) + else if (p.location == DWARF_VALUE_IMPLICIT_POINTER) { - p->v.ptr.die.sect_off = this->len; - p->v.ptr.offset = value_as_long (fetch (0)); + p.v.ptr.die_sect_off = (sect_offset) this->len; + p.v.ptr.offset = value_as_long (fetch (0)); } - else if (p->location == DWARF_VALUE_REGISTER) - p->v.regno = value_as_long (fetch (0)); + else if (p.location == DWARF_VALUE_REGISTER) + p.v.regno = value_as_long (fetch (0)); else { - p->v.value = fetch (0); + p.v.value = fetch (0); } } @@ -406,31 +370,6 @@ base_types_equal_p (struct type *t1, struct type *t2) return TYPE_LENGTH (t1) == TYPE_LENGTH (t2); } -/* A convenience function to call get_base_type and return the result. - DIE is the DIE whose type we need. SIZE is non-zero if this - function should verify that the resulting type has the correct - size. */ - -struct type * -dwarf_expr_context::get_base_type (cu_offset die, int size) -{ - struct type *result; - - if (this->funcs->get_base_type) - { - result = this->funcs->get_base_type (this, die); - if (result == NULL) - error (_("Could not find type for DW_OP_GNU_const_type")); - if (size != 0 && TYPE_LENGTH (result) != size) - error (_("DW_OP_GNU_const_type has different sizes for type and data")); - } - else - /* Anything will do. */ - result = builtin_type (this->gdbarch)->builtin_int; - - return result; -} - /* If funcs->get_addr_index) (this->baton, uoffset); + result = this->get_addr_index (uoffset); result += this->offset; result_val = value_from_ulongest (address_type, result); break; case DW_OP_GNU_const_index: op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); - result = (this->funcs->get_addr_index) (this->baton, uoffset); + result = this->get_addr_index (uoffset); result_val = value_from_ulongest (address_type, result); break; @@ -830,12 +770,13 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_stack_value"); goto no_push; + case DW_OP_implicit_pointer: case DW_OP_GNU_implicit_pointer: { int64_t len; if (this->ref_addr_size == -1) - error (_("DWARF-2 expression error: DW_OP_GNU_implicit_pointer " + error (_("DWARF-2 expression error: DW_OP_implicit_pointer " "is not allowed in frame context")); /* The referred-to DIE of sect_offset kind. */ @@ -850,7 +791,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, this->location = DWARF_VALUE_IMPLICIT_POINTER; dwarf_expr_require_composition (op_ptr, op_end, - "DW_OP_GNU_implicit_pointer"); + "DW_OP_implicit_pointer"); } break; @@ -888,8 +829,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_breg31: { op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); - result = (this->funcs->read_addr_from_reg) (this->baton, - op - DW_OP_breg0); + result = this->read_addr_from_reg (op - DW_OP_breg0); result += offset; result_val = value_from_ulongest (address_type, result); } @@ -898,7 +838,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, { op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); - result = (this->funcs->read_addr_from_reg) (this->baton, reg); + result = this->read_addr_from_reg (reg); result += offset; result_val = value_from_ulongest (address_type, result); } @@ -907,32 +847,35 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, { const gdb_byte *datastart; size_t datalen; - unsigned int before_stack_len; op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); + /* Rather than create a whole new context, we simply - record the stack length before execution, then reset it - afterwards, effectively erasing whatever the recursive - call put there. */ - before_stack_len = this->stack_len; + backup the current stack locally and install a new empty stack, + then reset it afterwards, effectively erasing whatever the + recursive call put there. */ + std::vector saved_stack = std::move (stack); + stack.clear (); + /* FIXME: cagney/2003-03-26: This code should be using get_frame_base_address(), and then implement a dwarf2 specific this_base method. */ - (this->funcs->get_frame_base) (this->baton, &datastart, &datalen); + this->get_frame_base (&datastart, &datalen); eval (datastart, datalen); if (this->location == DWARF_VALUE_MEMORY) result = fetch_address (0); else if (this->location == DWARF_VALUE_REGISTER) - result = (this->funcs->read_addr_from_reg) - (this->baton, - value_as_long (fetch (0))); + result = this->read_addr_from_reg (value_as_long (fetch (0))); else error (_("Not implemented: computing frame " "base using explicit value operator")); result = result + offset; result_val = value_from_ulongest (address_type, result); - in_stack_memory = 1; - this->stack_len = before_stack_len; + in_stack_memory = true; + + /* Restore the content of the original stack. */ + stack = std::move (saved_stack); + this->location = DWARF_VALUE_MEMORY; } break; @@ -954,16 +897,14 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_swap: { - struct dwarf_stack_value t1, t2; - - if (this->stack_len < 2) + if (stack.size () < 2) error (_("Not enough elements for " - "DW_OP_swap. Need 2, have %d."), - this->stack_len); - t1 = this->stack[this->stack_len - 1]; - t2 = this->stack[this->stack_len - 2]; - this->stack[this->stack_len - 1] = t2; - this->stack[this->stack_len - 2] = t1; + "DW_OP_swap. Need 2, have %zu."), + stack.size ()); + + dwarf_stack_value &t1 = stack[stack.size () - 1]; + dwarf_stack_value &t2 = stack[stack.size () - 2]; + std::swap (t1, t2); goto no_push; } @@ -974,23 +915,21 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_rot: { - struct dwarf_stack_value t1, t2, t3; - - if (this->stack_len < 3) + if (stack.size () < 3) error (_("Not enough elements for " - "DW_OP_rot. Need 3, have %d."), - this->stack_len); - t1 = this->stack[this->stack_len - 1]; - t2 = this->stack[this->stack_len - 2]; - t3 = this->stack[this->stack_len - 3]; - this->stack[this->stack_len - 1] = t2; - this->stack[this->stack_len - 2] = t3; - this->stack[this->stack_len - 3] = t1; + "DW_OP_rot. Need 3, have %zu."), + stack.size ()); + + dwarf_stack_value temp = stack[stack.size () - 1]; + stack[stack.size () - 1] = stack[stack.size () - 2]; + stack[stack.size () - 2] = stack[stack.size () - 3]; + stack[stack.size () - 3] = temp; goto no_push; } case DW_OP_deref: case DW_OP_deref_size: + case DW_OP_deref_type: case DW_OP_GNU_deref_type: { int addr_size = (op == DW_OP_deref ? this->addr_size : *op_ptr++); @@ -1000,29 +939,27 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, pop (); - if (op == DW_OP_GNU_deref_type) + if (op == DW_OP_deref_type || op == DW_OP_GNU_deref_type) { - cu_offset type_die; - op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); - type_die.cu_off = uoffset; - type = get_base_type (type_die, 0); + cu_offset type_die_cu_off = (cu_offset) uoffset; + type = get_base_type (type_die_cu_off, 0); } else type = address_type; - (this->funcs->read_mem) (this->baton, buf, addr, addr_size); + this->read_mem (buf, addr, addr_size); /* If the size of the object read from memory is different from the type length, we need to zero-extend it. */ if (TYPE_LENGTH (type) != addr_size) { - ULONGEST result = + ULONGEST datum = extract_unsigned_integer (buf, addr_size, byte_order); buf = (gdb_byte *) alloca (TYPE_LENGTH (type)); store_unsigned_integer (buf, TYPE_LENGTH (type), - byte_order, result); + byte_order, datum); } result_val = value_from_contents_and_address (type, buf, addr); @@ -1220,9 +1157,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, break; case DW_OP_call_frame_cfa: - result = (this->funcs->get_frame_cfa) (this->baton); + result = this->get_frame_cfa (); result_val = value_from_ulongest (address_type, result); - in_stack_memory = 1; + in_stack_memory = true; break; case DW_OP_GNU_push_tls_address: @@ -1237,7 +1174,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, returned. */ result = value_as_long (fetch (0)); pop (); - result = (this->funcs->get_tls_address) (this->baton, result); + result = this->get_tls_address (result); result_val = value_from_ulongest (address_type, result); break; @@ -1283,12 +1220,12 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_bit_piece: { - uint64_t size, offset; + uint64_t size, uleb_offset; /* Record the piece. */ op_ptr = safe_read_uleb128 (op_ptr, op_end, &size); - op_ptr = safe_read_uleb128 (op_ptr, op_end, &offset); - add_piece (size, offset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uleb_offset); + add_piece (size, uleb_offset); /* Pop off the address/regnum, and reset the location type. */ @@ -1309,24 +1246,34 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_call2: { - cu_offset offset; - - offset.cu_off = extract_unsigned_integer (op_ptr, 2, byte_order); + cu_offset cu_off + = (cu_offset) extract_unsigned_integer (op_ptr, 2, byte_order); op_ptr += 2; - this->funcs->dwarf_call (this, offset); + this->dwarf_call (cu_off); } goto no_push; case DW_OP_call4: { - cu_offset offset; - - offset.cu_off = extract_unsigned_integer (op_ptr, 4, byte_order); + cu_offset cu_off + = (cu_offset) extract_unsigned_integer (op_ptr, 4, byte_order); op_ptr += 4; - this->funcs->dwarf_call (this, offset); + this->dwarf_call (cu_off); } goto no_push; + + case DW_OP_GNU_variable_value: + { + sect_offset sect_off + = (sect_offset) extract_unsigned_integer (op_ptr, + this->ref_addr_size, + byte_order); + op_ptr += this->ref_addr_size; + result_val = this->dwarf_variable_value (sect_off); + } + break; + case DW_OP_entry_value: case DW_OP_GNU_entry_value: { uint64_t len; @@ -1335,16 +1282,15 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, op_ptr = safe_read_uleb128 (op_ptr, op_end, &len); if (op_ptr + len > op_end) - error (_("DW_OP_GNU_entry_value: too few bytes available.")); + error (_("DW_OP_entry_value: too few bytes available.")); kind_u.dwarf_reg = dwarf_block_to_dwarf_reg (op_ptr, op_ptr + len); if (kind_u.dwarf_reg != -1) { op_ptr += len; - this->funcs->push_dwarf_reg_entry_value (this, - CALL_SITE_PARAMETER_DWARF_REG, - kind_u, - -1 /* deref_size */); + this->push_dwarf_reg_entry_value (CALL_SITE_PARAMETER_DWARF_REG, + kind_u, + -1 /* deref_size */); goto no_push; } @@ -1356,13 +1302,12 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, if (deref_size == -1) deref_size = this->addr_size; op_ptr += len; - this->funcs->push_dwarf_reg_entry_value (this, - CALL_SITE_PARAMETER_DWARF_REG, - kind_u, deref_size); + this->push_dwarf_reg_entry_value (CALL_SITE_PARAMETER_DWARF_REG, + kind_u, deref_size); goto no_push; } - error (_("DWARF-2 expression error: DW_OP_GNU_entry_value is " + error (_("DWARF-2 expression error: DW_OP_entry_value is " "supported only for single DW_OP_reg* " "or for DW_OP_breg*(0)+DW_OP_deref*")); } @@ -1371,66 +1316,67 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, { union call_site_parameter_u kind_u; - kind_u.param_offset.cu_off = extract_unsigned_integer (op_ptr, 4, - byte_order); + kind_u.param_cu_off + = (cu_offset) extract_unsigned_integer (op_ptr, 4, byte_order); op_ptr += 4; - this->funcs->push_dwarf_reg_entry_value (this, - CALL_SITE_PARAMETER_PARAM_OFFSET, - kind_u, - -1 /* deref_size */); + this->push_dwarf_reg_entry_value (CALL_SITE_PARAMETER_PARAM_OFFSET, + kind_u, + -1 /* deref_size */); } goto no_push; + case DW_OP_const_type: case DW_OP_GNU_const_type: { - cu_offset type_die; int n; const gdb_byte *data; struct type *type; op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); - type_die.cu_off = uoffset; + cu_offset type_die_cu_off = (cu_offset) uoffset; + n = *op_ptr++; data = op_ptr; op_ptr += n; - type = get_base_type (type_die, n); + type = get_base_type (type_die_cu_off, n); result_val = value_from_contents (type, data); } break; + case DW_OP_regval_type: case DW_OP_GNU_regval_type: { - cu_offset type_die; struct type *type; op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); - type_die.cu_off = uoffset; + cu_offset type_die_cu_off = (cu_offset) uoffset; - type = get_base_type (type_die, 0); - result_val = this->funcs->get_reg_value (this->baton, type, reg); + type = get_base_type (type_die_cu_off, 0); + result_val = this->get_reg_value (type, reg); } break; + case DW_OP_convert: case DW_OP_GNU_convert: + case DW_OP_reinterpret: case DW_OP_GNU_reinterpret: { - cu_offset type_die; struct type *type; op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); - type_die.cu_off = uoffset; + cu_offset type_die_cu_off = (cu_offset) uoffset; - if (type_die.cu_off == 0) + if (to_underlying (type_die_cu_off) == 0) type = address_type; else - type = get_base_type (type_die, 0); + type = get_base_type (type_die_cu_off, 0); result_val = fetch (0); pop (); - if (op == DW_OP_GNU_convert) + if (op == DW_OP_convert || op == DW_OP_GNU_convert) result_val = value_cast (type, result_val); else if (type == value_type (result_val)) { @@ -1438,7 +1384,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, } else if (TYPE_LENGTH (type) != TYPE_LENGTH (value_type (result_val))) - error (_("DW_OP_GNU_reinterpret has wrong size")); + error (_("DW_OP_reinterpret has wrong size")); else result_val = value_from_contents (type, @@ -1448,7 +1394,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_push_object_address: /* Return the address of the object we are currently observing. */ - result = (this->funcs->get_object_address) (this->baton); + result = this->get_object_address (); result_val = value_from_ulongest (address_type, result); break; @@ -1469,83 +1415,10 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, if (this->location == DWARF_VALUE_IMPLICIT_POINTER) add_piece (8 * this->addr_size, 0); -abort_expression: this->recursion_depth--; gdb_assert (this->recursion_depth >= 0); } -/* Stub dwarf_expr_context_funcs.get_frame_base implementation. */ - -void -ctx_no_get_frame_base (void *baton, const gdb_byte **start, size_t *length) -{ - error (_("%s is invalid in this context"), "DW_OP_fbreg"); -} - -/* Stub dwarf_expr_context_funcs.get_frame_cfa implementation. */ - -CORE_ADDR -ctx_no_get_frame_cfa (void *baton) -{ - error (_("%s is invalid in this context"), "DW_OP_call_frame_cfa"); -} - -/* Stub dwarf_expr_context_funcs.get_frame_pc implementation. */ - -CORE_ADDR -ctx_no_get_frame_pc (void *baton) -{ - error (_("%s is invalid in this context"), "DW_OP_GNU_implicit_pointer"); -} - -/* Stub dwarf_expr_context_funcs.get_tls_address implementation. */ - -CORE_ADDR -ctx_no_get_tls_address (void *baton, CORE_ADDR offset) -{ - error (_("%s is invalid in this context"), "DW_OP_form_tls_address"); -} - -/* Stub dwarf_expr_context_funcs.dwarf_call implementation. */ - -void -ctx_no_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset) -{ - error (_("%s is invalid in this context"), "DW_OP_call*"); -} - -/* Stub dwarf_expr_context_funcs.get_base_type implementation. */ - -struct type * -ctx_no_get_base_type (struct dwarf_expr_context *ctx, cu_offset die) -{ - error (_("Support for typed DWARF is not supported in this context")); -} - -/* Stub dwarf_expr_context_funcs.push_dwarf_block_entry_value - implementation. */ - -void -ctx_no_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx, - enum call_site_parameter_kind kind, - union call_site_parameter_u kind_u, - int deref_size) -{ - internal_error (__FILE__, __LINE__, - _("Support for DW_OP_GNU_entry_value is unimplemented")); -} - -/* Stub dwarf_expr_context_funcs.get_addr_index implementation. */ - -CORE_ADDR -ctx_no_get_addr_index (void *baton, unsigned int index) -{ - error (_("%s is invalid in this context"), "DW_OP_GNU_addr_index"); -} - -/* Provide a prototype to silence -Wmissing-prototypes. */ -extern initialize_file_ftype _initialize_dwarf2expr; - void _initialize_dwarf2expr (void) {