aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog22
-rw-r--r--gdb/ada-lang.c1
-rw-r--r--gdb/ax-gdb.c22
-rw-r--r--gdb/eval.c24
-rw-r--r--gdb/expprint.c16
-rw-r--r--gdb/expression.h1
-rw-r--r--gdb/minsyms.h9
-rw-r--r--gdb/parse.c81
-rw-r--r--gdb/std-operator.def6
9 files changed, 150 insertions, 32 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 85cd3f9..d34b29a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,27 @@
2017-09-04 Pedro Alves <palves@redhat.com>
+ * ada-lang.c (resolve_subexp): Handle OP_VAR_MSYM_VALUE.
+ * ax-gdb.c (gen_msym_var_ref): New function.
+ (gen_expr): Handle OP_VAR_MSYM_VALUE.
+ * eval.c (evaluate_var_msym_value): New function.
+ * eval.c (evaluate_subexp_standard): Handle OP_VAR_MSYM_VALUE.
+ <OP_FUNCALL>: Extract function name from symbol/minsym and pass it
+ to call_function_by_hand.
+ * expprint.c (print_subexp_standard, dump_subexp_body_standard):
+ Handle OP_VAR_MSYM_VALUE.
+ (union exp_element) <msymbol>: New field.
+ * minsyms.h (struct type): Forward declare.
+ (find_minsym_type_and_address): Declare.
+ * parse.c (write_exp_elt_msym): New function.
+ (write_exp_msymbol): Delete, refactored as ...
+ (find_minsym_type_and_address): ... this new function.
+ (write_exp_msymbol): Reimplement using OP_VAR_MSYM_VALUE.
+ (operator_length_standard, operator_check_standard): Handle
+ OP_VAR_MSYM_VALUE.
+ * std-operator.def (OP_VAR_MSYM_VALUE): New.
+
+2017-09-04 Pedro Alves <palves@redhat.com>
+
* ada-lang.c (ada_evaluate_subexp) <TYPE_CODE_FUNC>: Don't handle
TYPE_GNU_IFUNC specially here. Throw error if return type is
unknown.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 519dfb1..86f09b9 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -3385,6 +3385,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
case OP_LONG:
case OP_DOUBLE:
case OP_VAR_VALUE:
+ case OP_VAR_MSYM_VALUE:
*pos += 4;
break;
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index a72a458..3fdf81a 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -733,6 +733,23 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var)
break;
}
}
+
+/* Generate code for a minimal symbol variable reference to AX. The
+ variable is the symbol MINSYM, of OBJFILE. Set VALUE to describe
+ the result. */
+
+static void
+gen_msym_var_ref (agent_expr *ax, axs_value *value,
+ minimal_symbol *msymbol, objfile *objf)
+{
+ CORE_ADDR address;
+ type *t = find_minsym_type_and_address (msymbol, objf, &address);
+ value->type = t;
+ value->optimized_out = false;
+ ax_const_l (ax, address);
+ value->kind = axs_lvalue_memory;
+}
+
@@ -1964,6 +1981,11 @@ gen_expr (struct expression *exp, union exp_element **pc,
(*pc) += 4;
break;
+ case OP_VAR_MSYM_VALUE:
+ gen_msym_var_ref (ax, value, (*pc)[2].msymbol, (*pc)[1].objfile);
+ (*pc) += 4;
+ break;
+
case OP_REGISTER:
{
const char *name = &(*pc)[2].string;
diff --git a/gdb/eval.c b/gdb/eval.c
index 1ec6751..457e280 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -676,6 +676,25 @@ make_params (int num_types, struct type **param_types)
return type;
}
+/* Helper for evaluating an OP_VAR_MSYM_VALUE. */
+
+static value *
+evaluate_var_msym_value (enum noside noside,
+ struct objfile *objfile, minimal_symbol *msymbol)
+{
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ type *the_type = find_minsym_type_and_address (msymbol, objfile, NULL);
+ return value_zero (the_type, not_lval);
+ }
+ else
+ {
+ CORE_ADDR address;
+ type *the_type = find_minsym_type_and_address (msymbol, objfile, &address);
+ return value_at_lazy (the_type, address);
+ }
+}
+
struct value *
evaluate_subexp_standard (struct type *expect_type,
struct expression *exp, int *pos,
@@ -766,6 +785,11 @@ evaluate_subexp_standard (struct type *expect_type,
return ret;
}
+ case OP_VAR_MSYM_VALUE:
+ (*pos) += 3;
+ return evaluate_var_msym_value (noside,
+ exp->elts[pc + 1].objfile,
+ exp->elts[pc + 2].msymbol);
case OP_VAR_ENTRY_VALUE:
(*pos) += 2;
diff --git a/gdb/expprint.c b/gdb/expprint.c
index 9b8ac4c..4939c01 100644
--- a/gdb/expprint.c
+++ b/gdb/expprint.c
@@ -134,6 +134,13 @@ print_subexp_standard (struct expression *exp, int *pos,
}
return;
+ case OP_VAR_MSYM_VALUE:
+ {
+ (*pos) += 3;
+ fputs_filtered (MSYMBOL_PRINT_NAME (exp->elts[pc + 2].msymbol), stream);
+ }
+ return;
+
case OP_VAR_ENTRY_VALUE:
{
(*pos) += 2;
@@ -876,6 +883,15 @@ dump_subexp_body_standard (struct expression *exp,
SYMBOL_PRINT_NAME (exp->elts[elt + 1].symbol));
elt += 3;
break;
+ case OP_VAR_MSYM_VALUE:
+ fprintf_filtered (stream, "Objfile @");
+ gdb_print_host_address (exp->elts[elt].objfile, stream);
+ fprintf_filtered (stream, ", msymbol @");
+ gdb_print_host_address (exp->elts[elt + 1].msymbol, stream);
+ fprintf_filtered (stream, " (%s)",
+ MSYMBOL_PRINT_NAME (exp->elts[elt + 1].msymbol));
+ elt += 3;
+ break;
case OP_VAR_ENTRY_VALUE:
fprintf_filtered (stream, "Entry value of symbol @");
gdb_print_host_address (exp->elts[elt].symbol, stream);
diff --git a/gdb/expression.h b/gdb/expression.h
index 8fe6b07..9e4ddf5 100644
--- a/gdb/expression.h
+++ b/gdb/expression.h
@@ -64,6 +64,7 @@ union exp_element
{
enum exp_opcode opcode;
struct symbol *symbol;
+ struct minimal_symbol *msymbol;
LONGEST longconst;
DOUBLEST doubleconst;
gdb_byte decfloatconst[16];
diff --git a/gdb/minsyms.h b/gdb/minsyms.h
index e763f62..dc51725 100644
--- a/gdb/minsyms.h
+++ b/gdb/minsyms.h
@@ -20,6 +20,8 @@
#ifndef MINSYMS_H
#define MINSYMS_H
+struct type;
+
/* Several lookup functions return both a minimal symbol and the
objfile in which it is found. This structure is used in these
cases. */
@@ -275,4 +277,11 @@ void iterate_over_minimal_symbols (struct objfile *objf,
CORE_ADDR minimal_symbol_upper_bound (struct bound_minimal_symbol minsym);
+/* Return the type of MSYMBOL, a minimal symbol of OBJFILE. If
+ ADDRESS_P is not NULL, set it to the MSYMBOL's resolved
+ address. */
+
+type *find_minsym_type_and_address (minimal_symbol *msymbol, objfile *objf,
+ CORE_ADDR *address_p);
+
#endif /* MINSYMS_H */
diff --git a/gdb/parse.c b/gdb/parse.c
index abf59d7..83bfa4b 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -256,6 +256,16 @@ write_exp_elt_sym (struct parser_state *ps, struct symbol *expelt)
}
void
+write_exp_elt_msym (struct parser_state *ps, minimal_symbol *expelt)
+{
+ union exp_element tmp;
+
+ memset (&tmp, 0, sizeof (union exp_element));
+ tmp.msymbol = expelt;
+ write_exp_elt (ps, &tmp);
+}
+
+void
write_exp_elt_block (struct parser_state *ps, const struct block *b)
{
union exp_element tmp;
@@ -470,17 +480,17 @@ write_exp_bitstring (struct parser_state *ps, struct stoken str)
write_exp_elt_longcst (ps, (LONGEST) bits);
}
-/* Add the appropriate elements for a minimal symbol to the end of
- the expression. */
+/* Return the type of MSYMBOL, a minimal symbol of OBJFILE. If
+ ADDRESS_P is not NULL, set it to the MSYMBOL's resolved
+ address. */
-void
-write_exp_msymbol (struct parser_state *ps,
- struct bound_minimal_symbol bound_msym)
+type *
+find_minsym_type_and_address (minimal_symbol *msymbol,
+ struct objfile *objfile,
+ CORE_ADDR *address_p)
{
- struct minimal_symbol *msymbol = bound_msym.minsym;
- struct objfile *objfile = bound_msym.objfile;
+ bound_minimal_symbol bound_msym = {msymbol, objfile};
struct gdbarch *gdbarch = get_objfile_arch (objfile);
-
CORE_ADDR addr = BMSYMBOL_VALUE_ADDRESS (bound_msym);
struct obj_section *section = MSYMBOL_OBJ_SECTION (objfile, msymbol);
enum minimal_symbol_type type = MSYMBOL_TYPE (msymbol);
@@ -515,51 +525,54 @@ write_exp_msymbol (struct parser_state *ps,
if (overlay_debugging)
addr = symbol_overlayed_address (addr, section);
- write_exp_elt_opcode (ps, OP_LONG);
- /* Let's make the type big enough to hold a 64-bit address. */
- write_exp_elt_type (ps, objfile_type (objfile)->builtin_core_addr);
- write_exp_elt_longcst (ps, (LONGEST) addr);
- write_exp_elt_opcode (ps, OP_LONG);
-
if (section && section->the_bfd_section->flags & SEC_THREAD_LOCAL)
{
- write_exp_elt_opcode (ps, UNOP_MEMVAL_TLS);
- write_exp_elt_objfile (ps, objfile);
- write_exp_elt_type (ps, objfile_type (objfile)->nodebug_tls_symbol);
- write_exp_elt_opcode (ps, UNOP_MEMVAL_TLS);
- return;
+ /* Skip translation if caller does not need the address. */
+ if (address_p != NULL)
+ *address_p = target_translate_tls_address (objfile, addr);
+ return objfile_type (objfile)->nodebug_tls_symbol;
}
- write_exp_elt_opcode (ps, UNOP_MEMVAL);
+ if (address_p != NULL)
+ *address_p = addr;
+
+ struct type *the_type;
+
switch (type)
{
case mst_text:
case mst_file_text:
case mst_solib_trampoline:
- write_exp_elt_type (ps, objfile_type (objfile)->nodebug_text_symbol);
- break;
+ return objfile_type (objfile)->nodebug_text_symbol;
case mst_text_gnu_ifunc:
- write_exp_elt_type (ps, objfile_type (objfile)
- ->nodebug_text_gnu_ifunc_symbol);
- break;
+ return objfile_type (objfile)->nodebug_text_gnu_ifunc_symbol;
case mst_data:
case mst_file_data:
case mst_bss:
case mst_file_bss:
- write_exp_elt_type (ps, objfile_type (objfile)->nodebug_data_symbol);
- break;
+ return objfile_type (objfile)->nodebug_data_symbol;
case mst_slot_got_plt:
- write_exp_elt_type (ps, objfile_type (objfile)->nodebug_got_plt_symbol);
- break;
+ return objfile_type (objfile)->nodebug_got_plt_symbol;
default:
- write_exp_elt_type (ps, objfile_type (objfile)->nodebug_unknown_symbol);
- break;
+ return objfile_type (objfile)->nodebug_unknown_symbol;
}
- write_exp_elt_opcode (ps, UNOP_MEMVAL);
+}
+
+/* Add the appropriate elements for a minimal symbol to the end of
+ the expression. */
+
+void
+write_exp_msymbol (struct parser_state *ps,
+ struct bound_minimal_symbol bound_msym)
+{
+ write_exp_elt_opcode (ps, OP_VAR_MSYM_VALUE);
+ write_exp_elt_objfile (ps, bound_msym.objfile);
+ write_exp_elt_msym (ps, bound_msym.minsym);
+ write_exp_elt_opcode (ps, OP_VAR_MSYM_VALUE);
}
/* Mark the current index as the starting location of a structure
@@ -884,6 +897,7 @@ operator_length_standard (const struct expression *expr, int endpos,
case OP_DOUBLE:
case OP_DECFLOAT:
case OP_VAR_VALUE:
+ case OP_VAR_MSYM_VALUE:
oplen = 4;
break;
@@ -1840,6 +1854,9 @@ operator_check_standard (struct expression *exp, int pos,
type = SYMBOL_TYPE (symbol);
}
break;
+ case OP_VAR_MSYM_VALUE:
+ objfile = elts[pos + 1].objfile;
+ break;
}
/* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL. */
diff --git a/gdb/std-operator.def b/gdb/std-operator.def
index 4650726..9007dd4 100644
--- a/gdb/std-operator.def
+++ b/gdb/std-operator.def
@@ -132,6 +132,12 @@ OP (OP_VAR_VALUE)
current function. Implemented via DW_OP_entry_value. */
OP (OP_VAR_ENTRY_VALUE)
+/* OP_VAR_MSYM_VALUE takes one struct objfile * in the following
+ element, and one struct minimal_symbol * in the following
+ exp_element, followed by another OP_VAR_MSYM_VALUE, making four
+ exp_elements. */
+OP (OP_VAR_MSYM_VALUE)
+
/* OP_LAST is followed by an integer in the next exp_element.
The integer is zero for the last value printed,
or it is the absolute number of a history element.