15e098073Schristos /* Convert a DWARF location expression to C
25e098073Schristos 
3*1424dfb3Schristos    Copyright (C) 2014-2020 Free Software Foundation, Inc.
45e098073Schristos 
55e098073Schristos    This file is part of GDB.
65e098073Schristos 
75e098073Schristos    This program is free software; you can redistribute it and/or modify
85e098073Schristos    it under the terms of the GNU General Public License as published by
95e098073Schristos    the Free Software Foundation; either version 3 of the License, or
105e098073Schristos    (at your option) any later version.
115e098073Schristos 
125e098073Schristos    This program is distributed in the hope that it will be useful,
135e098073Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
145e098073Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155e098073Schristos    GNU General Public License for more details.
165e098073Schristos 
175e098073Schristos    You should have received a copy of the GNU General Public License
185e098073Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195e098073Schristos 
205e098073Schristos #include "defs.h"
215e098073Schristos #include "dwarf2.h"
22*1424dfb3Schristos #include "dwarf2/expr.h"
23*1424dfb3Schristos #include "dwarf2/loc.h"
24*1424dfb3Schristos #include "dwarf2/read.h"
255e098073Schristos #include "ui-file.h"
265e098073Schristos #include "utils.h"
275e098073Schristos #include "compile-internal.h"
2807163879Schristos #include "compile-c.h"
295e098073Schristos #include "compile.h"
305e098073Schristos #include "block.h"
31*1424dfb3Schristos #include "dwarf2/frame.h"
32*1424dfb3Schristos #include "gdbsupport/gdb_vecs.h"
335e098073Schristos #include "value.h"
34*1424dfb3Schristos #include "gdbarch.h"
355e098073Schristos 
365e098073Schristos 
375e098073Schristos 
385e098073Schristos /* Information about a given instruction.  */
395e098073Schristos 
405e098073Schristos struct insn_info
415e098073Schristos {
425e098073Schristos   /* Stack depth at entry.  */
435e098073Schristos 
445e098073Schristos   unsigned int depth;
455e098073Schristos 
465e098073Schristos   /* Whether this instruction has been visited.  */
475e098073Schristos 
485e098073Schristos   unsigned int visited : 1;
495e098073Schristos 
505e098073Schristos   /* Whether this instruction needs a label.  */
515e098073Schristos 
525e098073Schristos   unsigned int label : 1;
535e098073Schristos 
541c468f90Schristos   /* Whether this instruction is DW_OP_GNU_push_tls_address or
551c468f90Schristos      DW_OP_form_tls_address.  This is a hack until we can add a
561c468f90Schristos      feature to glibc to let us properly generate code for TLS.  */
575e098073Schristos 
585e098073Schristos   unsigned int is_tls : 1;
595e098073Schristos };
605e098073Schristos 
615e098073Schristos /* A helper function for compute_stack_depth that does the work.  This
625e098073Schristos    examines the DWARF expression starting from START and computes
635e098073Schristos    stack effects.
645e098073Schristos 
655e098073Schristos    NEED_TEMPVAR is an out parameter which is set if this expression
665e098073Schristos    needs a special temporary variable to be emitted (see the code
675e098073Schristos    generator).
6807163879Schristos    INFO is a vector of insn_info objects, indexed by offset from the
695e098073Schristos    start of the DWARF expression.
705e098073Schristos    TO_DO is a list of bytecodes which must be examined; it may be
715e098073Schristos    added to by this function.
725e098073Schristos    BYTE_ORDER and ADDR_SIZE describe this bytecode in the obvious way.
735e098073Schristos    OP_PTR and OP_END are the bounds of the DWARF expression.  */
745e098073Schristos 
755e098073Schristos static void
compute_stack_depth_worker(int start,int * need_tempvar,std::vector<struct insn_info> * info,std::vector<int> * to_do,enum bfd_endian byte_order,unsigned int addr_size,const gdb_byte * op_ptr,const gdb_byte * op_end)765e098073Schristos compute_stack_depth_worker (int start, int *need_tempvar,
7707163879Schristos 			    std::vector<struct insn_info> *info,
781c468f90Schristos 			    std::vector<int> *to_do,
795e098073Schristos 			    enum bfd_endian byte_order, unsigned int addr_size,
805e098073Schristos 			    const gdb_byte *op_ptr, const gdb_byte *op_end)
815e098073Schristos {
825e098073Schristos   const gdb_byte * const base = op_ptr;
835e098073Schristos   int stack_depth;
845e098073Schristos 
855e098073Schristos   op_ptr += start;
8607163879Schristos   gdb_assert ((*info)[start].visited);
8707163879Schristos   stack_depth = (*info)[start].depth;
885e098073Schristos 
895e098073Schristos   while (op_ptr < op_end)
905e098073Schristos     {
91c03b94e9Schristos       enum dwarf_location_atom op = (enum dwarf_location_atom) *op_ptr;
925e098073Schristos       uint64_t reg;
935e098073Schristos       int64_t offset;
945e098073Schristos       int ndx = op_ptr - base;
955e098073Schristos 
965e098073Schristos #define SET_CHECK_DEPTH(WHERE)				\
9707163879Schristos       if ((*info)[WHERE].visited)				\
985e098073Schristos 	{						\
9907163879Schristos 	  if ((*info)[WHERE].depth != stack_depth)		\
1005e098073Schristos 	    error (_("inconsistent stack depths"));	\
1015e098073Schristos 	}						\
1025e098073Schristos       else						\
1035e098073Schristos 	{						\
1045e098073Schristos 	  /* Stack depth not set, so set it.  */	\
10507163879Schristos 	  (*info)[WHERE].visited = 1;			\
10607163879Schristos 	  (*info)[WHERE].depth = stack_depth;		\
1075e098073Schristos 	}
1085e098073Schristos 
1095e098073Schristos       SET_CHECK_DEPTH (ndx);
1105e098073Schristos 
1115e098073Schristos       ++op_ptr;
1125e098073Schristos 
1135e098073Schristos       switch (op)
1145e098073Schristos 	{
1155e098073Schristos 	case DW_OP_lit0:
1165e098073Schristos 	case DW_OP_lit1:
1175e098073Schristos 	case DW_OP_lit2:
1185e098073Schristos 	case DW_OP_lit3:
1195e098073Schristos 	case DW_OP_lit4:
1205e098073Schristos 	case DW_OP_lit5:
1215e098073Schristos 	case DW_OP_lit6:
1225e098073Schristos 	case DW_OP_lit7:
1235e098073Schristos 	case DW_OP_lit8:
1245e098073Schristos 	case DW_OP_lit9:
1255e098073Schristos 	case DW_OP_lit10:
1265e098073Schristos 	case DW_OP_lit11:
1275e098073Schristos 	case DW_OP_lit12:
1285e098073Schristos 	case DW_OP_lit13:
1295e098073Schristos 	case DW_OP_lit14:
1305e098073Schristos 	case DW_OP_lit15:
1315e098073Schristos 	case DW_OP_lit16:
1325e098073Schristos 	case DW_OP_lit17:
1335e098073Schristos 	case DW_OP_lit18:
1345e098073Schristos 	case DW_OP_lit19:
1355e098073Schristos 	case DW_OP_lit20:
1365e098073Schristos 	case DW_OP_lit21:
1375e098073Schristos 	case DW_OP_lit22:
1385e098073Schristos 	case DW_OP_lit23:
1395e098073Schristos 	case DW_OP_lit24:
1405e098073Schristos 	case DW_OP_lit25:
1415e098073Schristos 	case DW_OP_lit26:
1425e098073Schristos 	case DW_OP_lit27:
1435e098073Schristos 	case DW_OP_lit28:
1445e098073Schristos 	case DW_OP_lit29:
1455e098073Schristos 	case DW_OP_lit30:
1465e098073Schristos 	case DW_OP_lit31:
1475e098073Schristos 	  ++stack_depth;
1485e098073Schristos 	  break;
1495e098073Schristos 
1505e098073Schristos 	case DW_OP_addr:
1515e098073Schristos 	  op_ptr += addr_size;
1525e098073Schristos 	  ++stack_depth;
1535e098073Schristos 	  break;
1545e098073Schristos 
1555e098073Schristos 	case DW_OP_const1u:
1565e098073Schristos 	case DW_OP_const1s:
1575e098073Schristos 	  op_ptr += 1;
1585e098073Schristos 	  ++stack_depth;
1595e098073Schristos 	  break;
1605e098073Schristos 	case DW_OP_const2u:
1615e098073Schristos 	case DW_OP_const2s:
1625e098073Schristos 	  op_ptr += 2;
1635e098073Schristos 	  ++stack_depth;
1645e098073Schristos 	  break;
1655e098073Schristos 	case DW_OP_const4u:
1665e098073Schristos 	case DW_OP_const4s:
1675e098073Schristos 	  op_ptr += 4;
1685e098073Schristos 	  ++stack_depth;
1695e098073Schristos 	  break;
1705e098073Schristos 	case DW_OP_const8u:
1715e098073Schristos 	case DW_OP_const8s:
1725e098073Schristos 	  op_ptr += 8;
1735e098073Schristos 	  ++stack_depth;
1745e098073Schristos 	  break;
1755e098073Schristos 	case DW_OP_constu:
1765e098073Schristos 	case DW_OP_consts:
1775e098073Schristos 	  op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
1785e098073Schristos 	  ++stack_depth;
1795e098073Schristos 	  break;
1805e098073Schristos 
1815e098073Schristos 	case DW_OP_reg0:
1825e098073Schristos 	case DW_OP_reg1:
1835e098073Schristos 	case DW_OP_reg2:
1845e098073Schristos 	case DW_OP_reg3:
1855e098073Schristos 	case DW_OP_reg4:
1865e098073Schristos 	case DW_OP_reg5:
1875e098073Schristos 	case DW_OP_reg6:
1885e098073Schristos 	case DW_OP_reg7:
1895e098073Schristos 	case DW_OP_reg8:
1905e098073Schristos 	case DW_OP_reg9:
1915e098073Schristos 	case DW_OP_reg10:
1925e098073Schristos 	case DW_OP_reg11:
1935e098073Schristos 	case DW_OP_reg12:
1945e098073Schristos 	case DW_OP_reg13:
1955e098073Schristos 	case DW_OP_reg14:
1965e098073Schristos 	case DW_OP_reg15:
1975e098073Schristos 	case DW_OP_reg16:
1985e098073Schristos 	case DW_OP_reg17:
1995e098073Schristos 	case DW_OP_reg18:
2005e098073Schristos 	case DW_OP_reg19:
2015e098073Schristos 	case DW_OP_reg20:
2025e098073Schristos 	case DW_OP_reg21:
2035e098073Schristos 	case DW_OP_reg22:
2045e098073Schristos 	case DW_OP_reg23:
2055e098073Schristos 	case DW_OP_reg24:
2065e098073Schristos 	case DW_OP_reg25:
2075e098073Schristos 	case DW_OP_reg26:
2085e098073Schristos 	case DW_OP_reg27:
2095e098073Schristos 	case DW_OP_reg28:
2105e098073Schristos 	case DW_OP_reg29:
2115e098073Schristos 	case DW_OP_reg30:
2125e098073Schristos 	case DW_OP_reg31:
2135e098073Schristos 	  ++stack_depth;
2145e098073Schristos 	  break;
2155e098073Schristos 
2165e098073Schristos 	case DW_OP_regx:
2175e098073Schristos 	  op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
2185e098073Schristos 	  ++stack_depth;
2195e098073Schristos 	  break;
2205e098073Schristos 
2215e098073Schristos 	case DW_OP_breg0:
2225e098073Schristos 	case DW_OP_breg1:
2235e098073Schristos 	case DW_OP_breg2:
2245e098073Schristos 	case DW_OP_breg3:
2255e098073Schristos 	case DW_OP_breg4:
2265e098073Schristos 	case DW_OP_breg5:
2275e098073Schristos 	case DW_OP_breg6:
2285e098073Schristos 	case DW_OP_breg7:
2295e098073Schristos 	case DW_OP_breg8:
2305e098073Schristos 	case DW_OP_breg9:
2315e098073Schristos 	case DW_OP_breg10:
2325e098073Schristos 	case DW_OP_breg11:
2335e098073Schristos 	case DW_OP_breg12:
2345e098073Schristos 	case DW_OP_breg13:
2355e098073Schristos 	case DW_OP_breg14:
2365e098073Schristos 	case DW_OP_breg15:
2375e098073Schristos 	case DW_OP_breg16:
2385e098073Schristos 	case DW_OP_breg17:
2395e098073Schristos 	case DW_OP_breg18:
2405e098073Schristos 	case DW_OP_breg19:
2415e098073Schristos 	case DW_OP_breg20:
2425e098073Schristos 	case DW_OP_breg21:
2435e098073Schristos 	case DW_OP_breg22:
2445e098073Schristos 	case DW_OP_breg23:
2455e098073Schristos 	case DW_OP_breg24:
2465e098073Schristos 	case DW_OP_breg25:
2475e098073Schristos 	case DW_OP_breg26:
2485e098073Schristos 	case DW_OP_breg27:
2495e098073Schristos 	case DW_OP_breg28:
2505e098073Schristos 	case DW_OP_breg29:
2515e098073Schristos 	case DW_OP_breg30:
2525e098073Schristos 	case DW_OP_breg31:
2535e098073Schristos 	  op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
2545e098073Schristos 	  ++stack_depth;
2555e098073Schristos 	  break;
2565e098073Schristos 	case DW_OP_bregx:
2575e098073Schristos 	  {
2585e098073Schristos 	    op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
2595e098073Schristos 	    op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
2605e098073Schristos 	    ++stack_depth;
2615e098073Schristos 	  }
2625e098073Schristos 	  break;
2635e098073Schristos 	case DW_OP_fbreg:
2645e098073Schristos 	  op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
2655e098073Schristos 	  ++stack_depth;
2665e098073Schristos 	  break;
2675e098073Schristos 
2685e098073Schristos 	case DW_OP_dup:
2695e098073Schristos 	  ++stack_depth;
2705e098073Schristos 	  break;
2715e098073Schristos 
2725e098073Schristos 	case DW_OP_drop:
2735e098073Schristos 	  --stack_depth;
2745e098073Schristos 	  break;
2755e098073Schristos 
2765e098073Schristos 	case DW_OP_pick:
2775e098073Schristos 	  ++op_ptr;
2785e098073Schristos 	  ++stack_depth;
2795e098073Schristos 	  break;
2805e098073Schristos 
2815e098073Schristos 	case DW_OP_rot:
2825e098073Schristos 	case DW_OP_swap:
2835e098073Schristos 	  *need_tempvar = 1;
2845e098073Schristos 	  break;
2855e098073Schristos 
2865e098073Schristos 	case DW_OP_over:
2875e098073Schristos 	  ++stack_depth;
2885e098073Schristos 	  break;
2895e098073Schristos 
2905e098073Schristos 	case DW_OP_abs:
2915e098073Schristos 	case DW_OP_neg:
2925e098073Schristos 	case DW_OP_not:
2935e098073Schristos 	case DW_OP_deref:
2945e098073Schristos 	  break;
2955e098073Schristos 
2965e098073Schristos 	case DW_OP_deref_size:
2975e098073Schristos 	  ++op_ptr;
2985e098073Schristos 	  break;
2995e098073Schristos 
3005e098073Schristos 	case DW_OP_plus_uconst:
3015e098073Schristos 	  op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
3025e098073Schristos 	  break;
3035e098073Schristos 
3045e098073Schristos 	case DW_OP_div:
3055e098073Schristos 	case DW_OP_shra:
3065e098073Schristos 	case DW_OP_and:
3075e098073Schristos 	case DW_OP_minus:
3085e098073Schristos 	case DW_OP_mod:
3095e098073Schristos 	case DW_OP_mul:
3105e098073Schristos 	case DW_OP_or:
3115e098073Schristos 	case DW_OP_plus:
3125e098073Schristos 	case DW_OP_shl:
3135e098073Schristos 	case DW_OP_shr:
3145e098073Schristos 	case DW_OP_xor:
3155e098073Schristos 	case DW_OP_le:
3165e098073Schristos 	case DW_OP_ge:
3175e098073Schristos 	case DW_OP_eq:
3185e098073Schristos 	case DW_OP_lt:
3195e098073Schristos 	case DW_OP_gt:
3205e098073Schristos 	case DW_OP_ne:
3215e098073Schristos 	  --stack_depth;
3225e098073Schristos 	  break;
3235e098073Schristos 
3245e098073Schristos 	case DW_OP_call_frame_cfa:
3255e098073Schristos 	  ++stack_depth;
3265e098073Schristos 	  break;
3275e098073Schristos 
3285e098073Schristos 	case DW_OP_GNU_push_tls_address:
3291c468f90Schristos 	case DW_OP_form_tls_address:
33007163879Schristos 	  (*info)[ndx].is_tls = 1;
3315e098073Schristos 	  break;
3325e098073Schristos 
3335e098073Schristos 	case DW_OP_skip:
3345e098073Schristos 	  offset = extract_signed_integer (op_ptr, 2, byte_order);
3355e098073Schristos 	  op_ptr += 2;
3365e098073Schristos 	  offset = op_ptr + offset - base;
3375e098073Schristos 	  /* If the destination has not been seen yet, add it to the
3385e098073Schristos 	     to-do list.  */
33907163879Schristos 	  if (!(*info)[offset].visited)
3401c468f90Schristos 	    to_do->push_back (offset);
3415e098073Schristos 	  SET_CHECK_DEPTH (offset);
34207163879Schristos 	  (*info)[offset].label = 1;
3435e098073Schristos 	  /* We're done with this line of code.  */
3445e098073Schristos 	  return;
3455e098073Schristos 
3465e098073Schristos 	case DW_OP_bra:
3475e098073Schristos 	  offset = extract_signed_integer (op_ptr, 2, byte_order);
3485e098073Schristos 	  op_ptr += 2;
3495e098073Schristos 	  offset = op_ptr + offset - base;
3505e098073Schristos 	  --stack_depth;
3515e098073Schristos 	  /* If the destination has not been seen yet, add it to the
3525e098073Schristos 	     to-do list.  */
35307163879Schristos 	  if (!(*info)[offset].visited)
3541c468f90Schristos 	    to_do->push_back (offset);
3555e098073Schristos 	  SET_CHECK_DEPTH (offset);
35607163879Schristos 	  (*info)[offset].label = 1;
3575e098073Schristos 	  break;
3585e098073Schristos 
3595e098073Schristos 	case DW_OP_nop:
3605e098073Schristos 	  break;
3615e098073Schristos 
3625e098073Schristos 	default:
3635e098073Schristos 	  error (_("unhandled DWARF op: %s"), get_DW_OP_name (op));
3645e098073Schristos 	}
3655e098073Schristos     }
3665e098073Schristos 
3675e098073Schristos   gdb_assert (op_ptr == op_end);
3685e098073Schristos 
3695e098073Schristos #undef SET_CHECK_DEPTH
3705e098073Schristos }
3715e098073Schristos 
3725e098073Schristos /* Compute the maximum needed stack depth of a DWARF expression, and
3735e098073Schristos    some other information as well.
3745e098073Schristos 
3755e098073Schristos    BYTE_ORDER and ADDR_SIZE describe this bytecode in the obvious way.
3765e098073Schristos    NEED_TEMPVAR is an out parameter which is set if this expression
3775e098073Schristos    needs a special temporary variable to be emitted (see the code
3785e098073Schristos    generator).
3795e098073Schristos    IS_TLS is an out parameter which is set if this expression refers
3805e098073Schristos    to a TLS variable.
3815e098073Schristos    OP_PTR and OP_END are the bounds of the DWARF expression.
3825e098073Schristos    INITIAL_DEPTH is the initial depth of the DWARF expression stack.
3835e098073Schristos    INFO is an array of insn_info objects, indexed by offset from the
3845e098073Schristos    start of the DWARF expression.
3855e098073Schristos 
3865e098073Schristos    This returns the maximum stack depth.  */
3875e098073Schristos 
3885e098073Schristos static int
compute_stack_depth(enum bfd_endian byte_order,unsigned int addr_size,int * need_tempvar,int * is_tls,const gdb_byte * op_ptr,const gdb_byte * op_end,int initial_depth,std::vector<struct insn_info> * info)3895e098073Schristos compute_stack_depth (enum bfd_endian byte_order, unsigned int addr_size,
3905e098073Schristos 		     int *need_tempvar, int *is_tls,
3915e098073Schristos 		     const gdb_byte *op_ptr, const gdb_byte *op_end,
3925e098073Schristos 		     int initial_depth,
39307163879Schristos 		     std::vector<struct insn_info> *info)
3945e098073Schristos {
3951c468f90Schristos   std::vector<int> to_do;
3965e098073Schristos   int stack_depth, i;
3975e098073Schristos 
39807163879Schristos   info->resize (op_end - op_ptr);
3995e098073Schristos 
4001c468f90Schristos   to_do.push_back (0);
4015e098073Schristos   (*info)[0].depth = initial_depth;
4025e098073Schristos   (*info)[0].visited = 1;
4035e098073Schristos 
4041c468f90Schristos   while (!to_do.empty ())
4055e098073Schristos     {
4061c468f90Schristos       int ndx = to_do.back ();
4071c468f90Schristos       to_do.pop_back ();
4085e098073Schristos 
40907163879Schristos       compute_stack_depth_worker (ndx, need_tempvar, info, &to_do,
4105e098073Schristos 				  byte_order, addr_size,
4115e098073Schristos 				  op_ptr, op_end);
4125e098073Schristos     }
4135e098073Schristos 
4145e098073Schristos   stack_depth = 0;
4155e098073Schristos   *is_tls = 0;
4165e098073Schristos   for (i = 0; i < op_end - op_ptr; ++i)
4175e098073Schristos     {
4185e098073Schristos       if ((*info)[i].depth > stack_depth)
4195e098073Schristos 	stack_depth = (*info)[i].depth;
4205e098073Schristos       if ((*info)[i].is_tls)
4215e098073Schristos 	*is_tls = 1;
4225e098073Schristos     }
4235e098073Schristos 
4245e098073Schristos   return stack_depth + 1;
4255e098073Schristos }
4265e098073Schristos 
4275e098073Schristos 
4285e098073Schristos 
4295e098073Schristos #define GCC_UINTPTR "__gdb_uintptr"
4305e098073Schristos #define GCC_INTPTR "__gdb_intptr"
4315e098073Schristos 
4325e098073Schristos /* Emit code to push a constant.  */
4335e098073Schristos 
4345e098073Schristos static void
push(int indent,string_file * stream,ULONGEST l)43507163879Schristos push (int indent, string_file *stream, ULONGEST l)
4365e098073Schristos {
43707163879Schristos   fprintfi_filtered (indent, stream,
438ed6a76a9Schristos 		     "__gdb_stack[++__gdb_tos] = (" GCC_UINTPTR ") %s;\n",
4395e098073Schristos 		     hex_string (l));
4405e098073Schristos }
4415e098073Schristos 
4425e098073Schristos /* Emit code to push an arbitrary expression.  This works like
4435e098073Schristos    printf.  */
4445e098073Schristos 
44507163879Schristos static void pushf (int indent, string_file *stream, const char *format, ...)
446ed6a76a9Schristos   ATTRIBUTE_PRINTF (3, 4);
447ed6a76a9Schristos 
4485e098073Schristos static void
pushf(int indent,string_file * stream,const char * format,...)44907163879Schristos pushf (int indent, string_file *stream, const char *format, ...)
4505e098073Schristos {
4515e098073Schristos   va_list args;
4525e098073Schristos 
45307163879Schristos   fprintfi_filtered (indent, stream, "__gdb_stack[__gdb_tos + 1] = ");
4545e098073Schristos   va_start (args, format);
45507163879Schristos   stream->vprintf (format, args);
4565e098073Schristos   va_end (args);
45707163879Schristos   stream->puts (";\n");
4585e098073Schristos 
45907163879Schristos   fprintfi_filtered (indent, stream, "++__gdb_tos;\n");
4605e098073Schristos }
4615e098073Schristos 
4625e098073Schristos /* Emit code for a unary expression -- one which operates in-place on
4635e098073Schristos    the top-of-stack.  This works like printf.  */
4645e098073Schristos 
46507163879Schristos static void unary (int indent, string_file *stream, const char *format, ...)
466ed6a76a9Schristos   ATTRIBUTE_PRINTF (3, 4);
467ed6a76a9Schristos 
4685e098073Schristos static void
unary(int indent,string_file * stream,const char * format,...)46907163879Schristos unary (int indent, string_file *stream, const char *format, ...)
4705e098073Schristos {
4715e098073Schristos   va_list args;
4725e098073Schristos 
47307163879Schristos   fprintfi_filtered (indent, stream, "__gdb_stack[__gdb_tos] = ");
4745e098073Schristos   va_start (args, format);
47507163879Schristos   stream->vprintf (format, args);
4765e098073Schristos   va_end (args);
47707163879Schristos   stream->puts (";\n");
4785e098073Schristos }
4795e098073Schristos 
4805e098073Schristos /* Emit code for a unary expression -- one which uses the top two
4815e098073Schristos    stack items, popping the topmost one.  This works like printf.  */
48207163879Schristos static void binary (int indent, string_file *stream, const char *format, ...)
483ed6a76a9Schristos   ATTRIBUTE_PRINTF (3, 4);
4845e098073Schristos 
4855e098073Schristos static void
binary(int indent,string_file * stream,const char * format,...)48607163879Schristos binary (int indent, string_file *stream, const char *format, ...)
4875e098073Schristos {
4885e098073Schristos   va_list args;
4895e098073Schristos 
49007163879Schristos   fprintfi_filtered (indent, stream, "__gdb_stack[__gdb_tos - 1] = ");
4915e098073Schristos   va_start (args, format);
49207163879Schristos   stream->vprintf (format, args);
4935e098073Schristos   va_end (args);
49407163879Schristos   stream->puts (";\n");
49507163879Schristos   fprintfi_filtered (indent, stream, "--__gdb_tos;\n");
4965e098073Schristos }
4975e098073Schristos 
4985e098073Schristos /* Print the name of a label given its "SCOPE", an arbitrary integer
4995e098073Schristos    used for uniqueness, and its TARGET, the bytecode offset
5005e098073Schristos    corresponding to the label's point of definition.  */
5015e098073Schristos 
5025e098073Schristos static void
print_label(string_file * stream,unsigned int scope,int target)50307163879Schristos print_label (string_file *stream, unsigned int scope, int target)
5045e098073Schristos {
50507163879Schristos   stream->printf ("__label_%u_%s", scope, pulongest (target));
5065e098073Schristos }
5075e098073Schristos 
5085e098073Schristos /* Emit code that pushes a register's address on the stack.
5095e098073Schristos    REGISTERS_USED is an out parameter which is updated to note which
5105e098073Schristos    register was needed by this expression.  */
5115e098073Schristos 
5125e098073Schristos static void
pushf_register_address(int indent,string_file * stream,unsigned char * registers_used,struct gdbarch * gdbarch,int regnum)51307163879Schristos pushf_register_address (int indent, string_file *stream,
5145e098073Schristos 			unsigned char *registers_used,
5155e098073Schristos 			struct gdbarch *gdbarch, int regnum)
5165e098073Schristos {
51707163879Schristos   std::string regname = compile_register_name_mangled (gdbarch, regnum);
5185e098073Schristos 
5195e098073Schristos   registers_used[regnum] = 1;
520ed6a76a9Schristos   pushf (indent, stream,
521ed6a76a9Schristos 	 "(" GCC_UINTPTR ") &" COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s",
52207163879Schristos 	 regname.c_str ());
5235e098073Schristos }
5245e098073Schristos 
5255e098073Schristos /* Emit code that pushes a register's value on the stack.
5265e098073Schristos    REGISTERS_USED is an out parameter which is updated to note which
5275e098073Schristos    register was needed by this expression.  OFFSET is added to the
5285e098073Schristos    register's value before it is pushed.  */
5295e098073Schristos 
5305e098073Schristos static void
pushf_register(int indent,string_file * stream,unsigned char * registers_used,struct gdbarch * gdbarch,int regnum,uint64_t offset)53107163879Schristos pushf_register (int indent, string_file *stream,
5325e098073Schristos 		unsigned char *registers_used,
5335e098073Schristos 		struct gdbarch *gdbarch, int regnum, uint64_t offset)
5345e098073Schristos {
53507163879Schristos   std::string regname = compile_register_name_mangled (gdbarch, regnum);
5365e098073Schristos 
5375e098073Schristos   registers_used[regnum] = 1;
5385e098073Schristos   if (offset == 0)
5395e098073Schristos     pushf (indent, stream, COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s",
54007163879Schristos 	   regname.c_str ());
5415e098073Schristos   else
542ed6a76a9Schristos     pushf (indent, stream,
543ed6a76a9Schristos 	   COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s + (" GCC_UINTPTR ") %s",
54407163879Schristos 	   regname.c_str (), hex_string (offset));
5455e098073Schristos }
5465e098073Schristos 
5475e098073Schristos /* Compile a DWARF expression to C code.
5485e098073Schristos 
5495e098073Schristos    INDENT is the indentation level to use.
5505e098073Schristos    STREAM is the stream where the code should be written.
5515e098073Schristos 
5525e098073Schristos    TYPE_NAME names the type of the result of the DWARF expression.
5535e098073Schristos    For locations this is "void *" but for array bounds it will be an
5545e098073Schristos    integer type.
5555e098073Schristos 
5565e098073Schristos    RESULT_NAME is the name of a variable in the resulting C code.  The
5575e098073Schristos    result of the expression will be assigned to this variable.
5585e098073Schristos 
5595e098073Schristos    SYM is the symbol corresponding to this expression.
5605e098073Schristos    PC is the location at which the expression is being evaluated.
5615e098073Schristos    ARCH is the architecture to use.
5625e098073Schristos 
5635e098073Schristos    REGISTERS_USED is an out parameter which is updated to note which
5645e098073Schristos    registers were needed by this expression.
5655e098073Schristos 
5665e098073Schristos    ADDR_SIZE is the DWARF address size to use.
5675e098073Schristos 
5685e098073Schristos    OPT_PTR and OP_END are the bounds of the DWARF expression.
5695e098073Schristos 
5705e098073Schristos    If non-NULL, INITIAL points to an initial value to write to the
5715e098073Schristos    stack.  If NULL, no initial value is written.
5725e098073Schristos 
5735e098073Schristos    PER_CU is the per-CU object used for looking up various other
5745e098073Schristos    things.  */
5755e098073Schristos 
5765e098073Schristos static void
do_compile_dwarf_expr_to_c(int indent,string_file * stream,const char * type_name,const char * result_name,struct symbol * sym,CORE_ADDR pc,struct gdbarch * arch,unsigned char * registers_used,unsigned int addr_size,const gdb_byte * op_ptr,const gdb_byte * op_end,CORE_ADDR * initial,dwarf2_per_cu_data * per_cu,dwarf2_per_objfile * per_objfile)57707163879Schristos do_compile_dwarf_expr_to_c (int indent, string_file *stream,
5785e098073Schristos 			    const char *type_name,
5795e098073Schristos 			    const char *result_name,
5805e098073Schristos 			    struct symbol *sym, CORE_ADDR pc,
5815e098073Schristos 			    struct gdbarch *arch,
5825e098073Schristos 			    unsigned char *registers_used,
5835e098073Schristos 			    unsigned int addr_size,
5845e098073Schristos 			    const gdb_byte *op_ptr, const gdb_byte *op_end,
5855e098073Schristos 			    CORE_ADDR *initial,
586*1424dfb3Schristos 			    dwarf2_per_cu_data *per_cu,
587*1424dfb3Schristos 			    dwarf2_per_objfile *per_objfile)
5885e098073Schristos {
5895e098073Schristos   /* We keep a counter so that labels and other objects we create have
5905e098073Schristos      unique names.  */
5915e098073Schristos   static unsigned int scope;
5925e098073Schristos 
5935e098073Schristos   enum bfd_endian byte_order = gdbarch_byte_order (arch);
5945e098073Schristos   const gdb_byte * const base = op_ptr;
5955e098073Schristos   int need_tempvar = 0;
5965e098073Schristos   int is_tls = 0;
59707163879Schristos   std::vector<struct insn_info> info;
5985e098073Schristos   int stack_depth;
5995e098073Schristos 
6005e098073Schristos   ++scope;
6015e098073Schristos 
60207163879Schristos   fprintfi_filtered (indent, stream, "__attribute__ ((unused)) %s %s;\n",
603ed6a76a9Schristos 		     type_name, result_name);
60407163879Schristos   fprintfi_filtered (indent, stream, "{\n");
6055e098073Schristos   indent += 2;
6065e098073Schristos 
6075e098073Schristos   stack_depth = compute_stack_depth (byte_order, addr_size,
6085e098073Schristos 				     &need_tempvar, &is_tls,
6095e098073Schristos 				     op_ptr, op_end, initial != NULL,
6105e098073Schristos 				     &info);
6115e098073Schristos 
6125e098073Schristos   /* This is a hack until we can add a feature to glibc to let us
6135e098073Schristos      properly generate code for TLS.  You might think we could emit
6145e098073Schristos      the address in the ordinary course of translating
6155e098073Schristos      DW_OP_GNU_push_tls_address, but since the operand appears on the
6165e098073Schristos      stack, it is relatively hard to find, and the idea of calling
6175e098073Schristos      target_translate_tls_address with OFFSET==0 and then adding the
6185e098073Schristos      offset by hand seemed too hackish.  */
6195e098073Schristos   if (is_tls)
6205e098073Schristos     {
6215e098073Schristos       struct frame_info *frame = get_selected_frame (NULL);
6225e098073Schristos       struct value *val;
6235e098073Schristos 
6245e098073Schristos       if (frame == NULL)
6255e098073Schristos 	error (_("Symbol \"%s\" cannot be used because "
6265e098073Schristos 		 "there is no selected frame"),
627*1424dfb3Schristos 	       sym->print_name ());
6285e098073Schristos 
629c03b94e9Schristos       val = read_var_value (sym, NULL, frame);
6305e098073Schristos       if (VALUE_LVAL (val) != lval_memory)
6315e098073Schristos 	error (_("Symbol \"%s\" cannot be used for compilation evaluation "
6325e098073Schristos 		 "as its address has not been found."),
633*1424dfb3Schristos 	       sym->print_name ());
6345e098073Schristos 
6355e098073Schristos       warning (_("Symbol \"%s\" is thread-local and currently can only "
6365e098073Schristos 		 "be referenced from the current thread in "
6375e098073Schristos 		 "compiled code."),
638*1424dfb3Schristos 	       sym->print_name ());
6395e098073Schristos 
64007163879Schristos       fprintfi_filtered (indent, stream, "%s = %s;\n",
6415e098073Schristos 			 result_name,
6425e098073Schristos 			 core_addr_to_string (value_address (val)));
64307163879Schristos       fprintfi_filtered (indent - 2, stream, "}\n");
6445e098073Schristos       return;
6455e098073Schristos     }
6465e098073Schristos 
64707163879Schristos   fprintfi_filtered (indent, stream, GCC_UINTPTR " __gdb_stack[%d];\n",
6485e098073Schristos 		     stack_depth);
6495e098073Schristos 
6505e098073Schristos   if (need_tempvar)
65107163879Schristos     fprintfi_filtered (indent, stream, GCC_UINTPTR " __gdb_tmp;\n");
65207163879Schristos   fprintfi_filtered (indent, stream, "int __gdb_tos = -1;\n");
6535e098073Schristos 
6545e098073Schristos   if (initial != NULL)
655ed6a76a9Schristos     pushf (indent, stream, "%s", core_addr_to_string (*initial));
6565e098073Schristos 
6575e098073Schristos   while (op_ptr < op_end)
6585e098073Schristos     {
659c03b94e9Schristos       enum dwarf_location_atom op = (enum dwarf_location_atom) *op_ptr;
6605e098073Schristos       uint64_t uoffset, reg;
6615e098073Schristos       int64_t offset;
6625e098073Schristos 
66307163879Schristos       print_spaces (indent - 2, stream);
6645e098073Schristos       if (info[op_ptr - base].label)
6655e098073Schristos 	{
6665e098073Schristos 	  print_label (stream, scope, op_ptr - base);
66707163879Schristos 	  stream->puts (":;");
6685e098073Schristos 	}
66907163879Schristos       stream->printf ("/* %s */\n", get_DW_OP_name (op));
6705e098073Schristos 
6715e098073Schristos       /* This is handy for debugging the generated code:
6725e098073Schristos       fprintf_filtered (stream, "if (__gdb_tos != %d) abort ();\n",
6735e098073Schristos 			(int) info[op_ptr - base].depth - 1);
6745e098073Schristos       */
6755e098073Schristos 
6765e098073Schristos       ++op_ptr;
6775e098073Schristos 
6785e098073Schristos       switch (op)
6795e098073Schristos 	{
6805e098073Schristos 	case DW_OP_lit0:
6815e098073Schristos 	case DW_OP_lit1:
6825e098073Schristos 	case DW_OP_lit2:
6835e098073Schristos 	case DW_OP_lit3:
6845e098073Schristos 	case DW_OP_lit4:
6855e098073Schristos 	case DW_OP_lit5:
6865e098073Schristos 	case DW_OP_lit6:
6875e098073Schristos 	case DW_OP_lit7:
6885e098073Schristos 	case DW_OP_lit8:
6895e098073Schristos 	case DW_OP_lit9:
6905e098073Schristos 	case DW_OP_lit10:
6915e098073Schristos 	case DW_OP_lit11:
6925e098073Schristos 	case DW_OP_lit12:
6935e098073Schristos 	case DW_OP_lit13:
6945e098073Schristos 	case DW_OP_lit14:
6955e098073Schristos 	case DW_OP_lit15:
6965e098073Schristos 	case DW_OP_lit16:
6975e098073Schristos 	case DW_OP_lit17:
6985e098073Schristos 	case DW_OP_lit18:
6995e098073Schristos 	case DW_OP_lit19:
7005e098073Schristos 	case DW_OP_lit20:
7015e098073Schristos 	case DW_OP_lit21:
7025e098073Schristos 	case DW_OP_lit22:
7035e098073Schristos 	case DW_OP_lit23:
7045e098073Schristos 	case DW_OP_lit24:
7055e098073Schristos 	case DW_OP_lit25:
7065e098073Schristos 	case DW_OP_lit26:
7075e098073Schristos 	case DW_OP_lit27:
7085e098073Schristos 	case DW_OP_lit28:
7095e098073Schristos 	case DW_OP_lit29:
7105e098073Schristos 	case DW_OP_lit30:
7115e098073Schristos 	case DW_OP_lit31:
7125e098073Schristos 	  push (indent, stream, op - DW_OP_lit0);
7135e098073Schristos 	  break;
7145e098073Schristos 
7155e098073Schristos 	case DW_OP_addr:
71607163879Schristos 	  uoffset = extract_unsigned_integer (op_ptr, addr_size, byte_order);
7175e098073Schristos 	  op_ptr += addr_size;
7185e098073Schristos 	  /* Some versions of GCC emit DW_OP_addr before
7195e098073Schristos 	     DW_OP_GNU_push_tls_address.  In this case the value is an
7205e098073Schristos 	     index, not an address.  We don't support things like
7215e098073Schristos 	     branching between the address and the TLS op.  */
7225e098073Schristos 	  if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
723*1424dfb3Schristos 	    uoffset += per_objfile->objfile->text_section_offset ();
7245e098073Schristos 	  push (indent, stream, uoffset);
7255e098073Schristos 	  break;
7265e098073Schristos 
7275e098073Schristos 	case DW_OP_const1u:
7285e098073Schristos 	  push (indent, stream,
7295e098073Schristos 		extract_unsigned_integer (op_ptr, 1, byte_order));
7305e098073Schristos 	  op_ptr += 1;
7315e098073Schristos 	  break;
7325e098073Schristos 	case DW_OP_const1s:
7335e098073Schristos 	  push (indent, stream,
7345e098073Schristos 		extract_signed_integer (op_ptr, 1, byte_order));
7355e098073Schristos 	  op_ptr += 1;
7365e098073Schristos 	  break;
7375e098073Schristos 	case DW_OP_const2u:
7385e098073Schristos 	  push (indent, stream,
7395e098073Schristos 		extract_unsigned_integer (op_ptr, 2, byte_order));
7405e098073Schristos 	  op_ptr += 2;
7415e098073Schristos 	  break;
7425e098073Schristos 	case DW_OP_const2s:
7435e098073Schristos 	  push (indent, stream,
7445e098073Schristos 		extract_signed_integer (op_ptr, 2, byte_order));
7455e098073Schristos 	  op_ptr += 2;
7465e098073Schristos 	  break;
7475e098073Schristos 	case DW_OP_const4u:
7485e098073Schristos 	  push (indent, stream,
7495e098073Schristos 		extract_unsigned_integer (op_ptr, 4, byte_order));
7505e098073Schristos 	  op_ptr += 4;
7515e098073Schristos 	  break;
7525e098073Schristos 	case DW_OP_const4s:
7535e098073Schristos 	  push (indent, stream,
7545e098073Schristos 		extract_signed_integer (op_ptr, 4, byte_order));
7555e098073Schristos 	  op_ptr += 4;
7565e098073Schristos 	  break;
7575e098073Schristos 	case DW_OP_const8u:
7585e098073Schristos 	  push (indent, stream,
7595e098073Schristos 		extract_unsigned_integer (op_ptr, 8, byte_order));
7605e098073Schristos 	  op_ptr += 8;
7615e098073Schristos 	  break;
7625e098073Schristos 	case DW_OP_const8s:
7635e098073Schristos 	  push (indent, stream,
7645e098073Schristos 		extract_signed_integer (op_ptr, 8, byte_order));
7655e098073Schristos 	  op_ptr += 8;
7665e098073Schristos 	  break;
7675e098073Schristos 	case DW_OP_constu:
7685e098073Schristos 	  op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
7695e098073Schristos 	  push (indent, stream, uoffset);
7705e098073Schristos 	  break;
7715e098073Schristos 	case DW_OP_consts:
7725e098073Schristos 	  op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
7735e098073Schristos 	  push (indent, stream, offset);
7745e098073Schristos 	  break;
7755e098073Schristos 
7765e098073Schristos 	case DW_OP_reg0:
7775e098073Schristos 	case DW_OP_reg1:
7785e098073Schristos 	case DW_OP_reg2:
7795e098073Schristos 	case DW_OP_reg3:
7805e098073Schristos 	case DW_OP_reg4:
7815e098073Schristos 	case DW_OP_reg5:
7825e098073Schristos 	case DW_OP_reg6:
7835e098073Schristos 	case DW_OP_reg7:
7845e098073Schristos 	case DW_OP_reg8:
7855e098073Schristos 	case DW_OP_reg9:
7865e098073Schristos 	case DW_OP_reg10:
7875e098073Schristos 	case DW_OP_reg11:
7885e098073Schristos 	case DW_OP_reg12:
7895e098073Schristos 	case DW_OP_reg13:
7905e098073Schristos 	case DW_OP_reg14:
7915e098073Schristos 	case DW_OP_reg15:
7925e098073Schristos 	case DW_OP_reg16:
7935e098073Schristos 	case DW_OP_reg17:
7945e098073Schristos 	case DW_OP_reg18:
7955e098073Schristos 	case DW_OP_reg19:
7965e098073Schristos 	case DW_OP_reg20:
7975e098073Schristos 	case DW_OP_reg21:
7985e098073Schristos 	case DW_OP_reg22:
7995e098073Schristos 	case DW_OP_reg23:
8005e098073Schristos 	case DW_OP_reg24:
8015e098073Schristos 	case DW_OP_reg25:
8025e098073Schristos 	case DW_OP_reg26:
8035e098073Schristos 	case DW_OP_reg27:
8045e098073Schristos 	case DW_OP_reg28:
8055e098073Schristos 	case DW_OP_reg29:
8065e098073Schristos 	case DW_OP_reg30:
8075e098073Schristos 	case DW_OP_reg31:
8085e098073Schristos 	  dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
8095e098073Schristos 	  pushf_register_address (indent, stream, registers_used, arch,
810c03b94e9Schristos 				  dwarf_reg_to_regnum_or_error
811c03b94e9Schristos 				    (arch, op - DW_OP_reg0));
8125e098073Schristos 	  break;
8135e098073Schristos 
8145e098073Schristos 	case DW_OP_regx:
8155e098073Schristos 	  op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
8165e098073Schristos 	  dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
8175e098073Schristos 	  pushf_register_address (indent, stream, registers_used, arch,
818c03b94e9Schristos 				  dwarf_reg_to_regnum_or_error (arch, reg));
8195e098073Schristos 	  break;
8205e098073Schristos 
8215e098073Schristos 	case DW_OP_breg0:
8225e098073Schristos 	case DW_OP_breg1:
8235e098073Schristos 	case DW_OP_breg2:
8245e098073Schristos 	case DW_OP_breg3:
8255e098073Schristos 	case DW_OP_breg4:
8265e098073Schristos 	case DW_OP_breg5:
8275e098073Schristos 	case DW_OP_breg6:
8285e098073Schristos 	case DW_OP_breg7:
8295e098073Schristos 	case DW_OP_breg8:
8305e098073Schristos 	case DW_OP_breg9:
8315e098073Schristos 	case DW_OP_breg10:
8325e098073Schristos 	case DW_OP_breg11:
8335e098073Schristos 	case DW_OP_breg12:
8345e098073Schristos 	case DW_OP_breg13:
8355e098073Schristos 	case DW_OP_breg14:
8365e098073Schristos 	case DW_OP_breg15:
8375e098073Schristos 	case DW_OP_breg16:
8385e098073Schristos 	case DW_OP_breg17:
8395e098073Schristos 	case DW_OP_breg18:
8405e098073Schristos 	case DW_OP_breg19:
8415e098073Schristos 	case DW_OP_breg20:
8425e098073Schristos 	case DW_OP_breg21:
8435e098073Schristos 	case DW_OP_breg22:
8445e098073Schristos 	case DW_OP_breg23:
8455e098073Schristos 	case DW_OP_breg24:
8465e098073Schristos 	case DW_OP_breg25:
8475e098073Schristos 	case DW_OP_breg26:
8485e098073Schristos 	case DW_OP_breg27:
8495e098073Schristos 	case DW_OP_breg28:
8505e098073Schristos 	case DW_OP_breg29:
8515e098073Schristos 	case DW_OP_breg30:
8525e098073Schristos 	case DW_OP_breg31:
8535e098073Schristos 	  op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
8545e098073Schristos 	  pushf_register (indent, stream, registers_used, arch,
855c03b94e9Schristos 			  dwarf_reg_to_regnum_or_error (arch,
8565e098073Schristos 							op - DW_OP_breg0),
8575e098073Schristos 			  offset);
8585e098073Schristos 	  break;
8595e098073Schristos 	case DW_OP_bregx:
8605e098073Schristos 	  {
8615e098073Schristos 	    op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
8625e098073Schristos 	    op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
8635e098073Schristos 	    pushf_register (indent, stream, registers_used, arch,
864c03b94e9Schristos 			    dwarf_reg_to_regnum_or_error (arch, reg), offset);
8655e098073Schristos 	  }
8665e098073Schristos 	  break;
8675e098073Schristos 	case DW_OP_fbreg:
8685e098073Schristos 	  {
8695e098073Schristos 	    const gdb_byte *datastart;
8705e098073Schristos 	    size_t datalen;
8715e098073Schristos 	    const struct block *b;
8725e098073Schristos 	    struct symbol *framefunc;
8735e098073Schristos 	    char fb_name[50];
8745e098073Schristos 
8755e098073Schristos 	    b = block_for_pc (pc);
8765e098073Schristos 
8775e098073Schristos 	    if (!b)
8785e098073Schristos 	      error (_("No block found for address"));
8795e098073Schristos 
8805e098073Schristos 	    framefunc = block_linkage_function (b);
8815e098073Schristos 
8825e098073Schristos 	    if (!framefunc)
8835e098073Schristos 	      error (_("No function found for block"));
8845e098073Schristos 
8855e098073Schristos 	    func_get_frame_base_dwarf_block (framefunc, pc,
8865e098073Schristos 					     &datastart, &datalen);
8875e098073Schristos 
8885e098073Schristos 	    op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
8895e098073Schristos 
8905e098073Schristos 	    /* Generate a unique-enough name, in case the frame base
8915e098073Schristos 	       is computed multiple times in this expression.  */
8925e098073Schristos 	    xsnprintf (fb_name, sizeof (fb_name), "__frame_base_%ld",
8935e098073Schristos 		       (long) (op_ptr - base));
8945e098073Schristos 
8955e098073Schristos 	    do_compile_dwarf_expr_to_c (indent, stream,
896ed6a76a9Schristos 					GCC_UINTPTR, fb_name,
8975e098073Schristos 					sym, pc,
8985e098073Schristos 					arch, registers_used, addr_size,
8995e098073Schristos 					datastart, datastart + datalen,
900*1424dfb3Schristos 					NULL, per_cu, per_objfile);
9015e098073Schristos 
9025e098073Schristos 	    pushf (indent, stream, "%s + %s", fb_name, hex_string (offset));
9035e098073Schristos 	  }
9045e098073Schristos 	  break;
9055e098073Schristos 
9065e098073Schristos 	case DW_OP_dup:
9075e098073Schristos 	  pushf (indent, stream, "__gdb_stack[__gdb_tos]");
9085e098073Schristos 	  break;
9095e098073Schristos 
9105e098073Schristos 	case DW_OP_drop:
91107163879Schristos 	  fprintfi_filtered (indent, stream, "--__gdb_tos;\n");
9125e098073Schristos 	  break;
9135e098073Schristos 
9145e098073Schristos 	case DW_OP_pick:
9155e098073Schristos 	  offset = *op_ptr++;
916ed6a76a9Schristos 	  pushf (indent, stream, "__gdb_stack[__gdb_tos - %s]",
917ed6a76a9Schristos 		 plongest (offset));
9185e098073Schristos 	  break;
9195e098073Schristos 
9205e098073Schristos 	case DW_OP_swap:
92107163879Schristos 	  fprintfi_filtered (indent, stream,
9225e098073Schristos 			     "__gdb_tmp = __gdb_stack[__gdb_tos - 1];\n");
92307163879Schristos 	  fprintfi_filtered (indent, stream,
9245e098073Schristos 			     "__gdb_stack[__gdb_tos - 1] = "
9255e098073Schristos 			     "__gdb_stack[__gdb_tos];\n");
92607163879Schristos 	  fprintfi_filtered (indent, stream, ("__gdb_stack[__gdb_tos] = "
9275e098073Schristos 					      "__gdb_tmp;\n"));
9285e098073Schristos 	  break;
9295e098073Schristos 
9305e098073Schristos 	case DW_OP_over:
9315e098073Schristos 	  pushf (indent, stream, "__gdb_stack[__gdb_tos - 1]");
9325e098073Schristos 	  break;
9335e098073Schristos 
9345e098073Schristos 	case DW_OP_rot:
93507163879Schristos 	  fprintfi_filtered (indent, stream, ("__gdb_tmp = "
9365e098073Schristos 					      "__gdb_stack[__gdb_tos];\n"));
93707163879Schristos 	  fprintfi_filtered (indent, stream,
9385e098073Schristos 			     "__gdb_stack[__gdb_tos] = "
9395e098073Schristos 			     "__gdb_stack[__gdb_tos - 1];\n");
94007163879Schristos 	  fprintfi_filtered (indent, stream,
9415e098073Schristos 			     "__gdb_stack[__gdb_tos - 1] = "
9425e098073Schristos 			     "__gdb_stack[__gdb_tos -2];\n");
94307163879Schristos 	  fprintfi_filtered (indent, stream, "__gdb_stack[__gdb_tos - 2] = "
9445e098073Schristos 			     "__gdb_tmp;\n");
9455e098073Schristos 	  break;
9465e098073Schristos 
9475e098073Schristos 	case DW_OP_deref:
9485e098073Schristos 	case DW_OP_deref_size:
9495e098073Schristos 	  {
9505e098073Schristos 	    int size;
9515e098073Schristos 	    const char *mode;
9525e098073Schristos 
9535e098073Schristos 	    if (op == DW_OP_deref_size)
9545e098073Schristos 	      size = *op_ptr++;
9555e098073Schristos 	    else
9565e098073Schristos 	      size = addr_size;
9575e098073Schristos 
9585e098073Schristos 	    mode = c_get_mode_for_size (size);
9595e098073Schristos 	    if (mode == NULL)
9605e098073Schristos 	      error (_("Unsupported size %d in %s"),
9615e098073Schristos 		     size, get_DW_OP_name (op));
9625e098073Schristos 
9635e098073Schristos 	    /* Cast to a pointer of the desired type, then
9645e098073Schristos 	       dereference.  */
96507163879Schristos 	    fprintfi_filtered (indent, stream,
9665e098073Schristos 			       "__gdb_stack[__gdb_tos] = "
9675e098073Schristos 			       "*((__gdb_int_%s *) "
9685e098073Schristos 			       "__gdb_stack[__gdb_tos]);\n",
9695e098073Schristos 			       mode);
9705e098073Schristos 	  }
9715e098073Schristos 	  break;
9725e098073Schristos 
9735e098073Schristos 	case DW_OP_abs:
9745e098073Schristos 	  unary (indent, stream,
9755e098073Schristos 		 "((" GCC_INTPTR ") __gdb_stack[__gdb_tos]) < 0 ? "
9765e098073Schristos 		 "-__gdb_stack[__gdb_tos] : __gdb_stack[__gdb_tos]");
9775e098073Schristos 	  break;
9785e098073Schristos 
9795e098073Schristos 	case DW_OP_neg:
9805e098073Schristos 	  unary (indent, stream, "-__gdb_stack[__gdb_tos]");
9815e098073Schristos 	  break;
9825e098073Schristos 
9835e098073Schristos 	case DW_OP_not:
9845e098073Schristos 	  unary (indent, stream, "~__gdb_stack[__gdb_tos]");
9855e098073Schristos 	  break;
9865e098073Schristos 
9875e098073Schristos 	case DW_OP_plus_uconst:
9885e098073Schristos 	  op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
9895e098073Schristos 	  unary (indent, stream, "__gdb_stack[__gdb_tos] + %s",
9905e098073Schristos 		 hex_string (reg));
9915e098073Schristos 	  break;
9925e098073Schristos 
9935e098073Schristos 	case DW_OP_div:
9945e098073Schristos 	  binary (indent, stream, ("((" GCC_INTPTR
9955e098073Schristos 				   ") __gdb_stack[__gdb_tos-1]) / (("
9965e098073Schristos 				   GCC_INTPTR ") __gdb_stack[__gdb_tos])"));
9975e098073Schristos 	  break;
9985e098073Schristos 
9995e098073Schristos 	case DW_OP_shra:
10005e098073Schristos 	  binary (indent, stream,
10015e098073Schristos 		  "((" GCC_INTPTR ") __gdb_stack[__gdb_tos-1]) >> "
10025e098073Schristos 		  "__gdb_stack[__gdb_tos]");
10035e098073Schristos 	  break;
10045e098073Schristos 
10055e098073Schristos #define BINARY(OP)							\
1006ed6a76a9Schristos 	  binary (indent, stream, "%s", "__gdb_stack[__gdb_tos-1] " #OP \
1007ed6a76a9Schristos 				   " __gdb_stack[__gdb_tos]");	\
10085e098073Schristos 	  break
10095e098073Schristos 
10105e098073Schristos 	case DW_OP_and:
10115e098073Schristos 	  BINARY (&);
10125e098073Schristos 	case DW_OP_minus:
10135e098073Schristos 	  BINARY (-);
10145e098073Schristos 	case DW_OP_mod:
10155e098073Schristos 	  BINARY (%);
10165e098073Schristos 	case DW_OP_mul:
10175e098073Schristos 	  BINARY (*);
10185e098073Schristos 	case DW_OP_or:
10195e098073Schristos 	  BINARY (|);
10205e098073Schristos 	case DW_OP_plus:
10215e098073Schristos 	  BINARY (+);
10225e098073Schristos 	case DW_OP_shl:
10235e098073Schristos 	  BINARY (<<);
10245e098073Schristos 	case DW_OP_shr:
10255e098073Schristos 	  BINARY (>>);
10265e098073Schristos 	case DW_OP_xor:
10275e098073Schristos 	  BINARY (^);
10285e098073Schristos #undef BINARY
10295e098073Schristos 
10305e098073Schristos #define COMPARE(OP)							\
10315e098073Schristos 	  binary (indent, stream,					\
10325e098073Schristos 		  "(((" GCC_INTPTR ") __gdb_stack[__gdb_tos-1]) " #OP	\
10335e098073Schristos 		  " ((" GCC_INTPTR					\
10345e098073Schristos 		  ") __gdb_stack[__gdb_tos]))");			\
10355e098073Schristos 	  break
10365e098073Schristos 
10375e098073Schristos 	case DW_OP_le:
10385e098073Schristos 	  COMPARE (<=);
10395e098073Schristos 	case DW_OP_ge:
10405e098073Schristos 	  COMPARE (>=);
10415e098073Schristos 	case DW_OP_eq:
10425e098073Schristos 	  COMPARE (==);
10435e098073Schristos 	case DW_OP_lt:
10445e098073Schristos 	  COMPARE (<);
10455e098073Schristos 	case DW_OP_gt:
10465e098073Schristos 	  COMPARE (>);
10475e098073Schristos 	case DW_OP_ne:
10485e098073Schristos 	  COMPARE (!=);
10495e098073Schristos #undef COMPARE
10505e098073Schristos 
10515e098073Schristos 	case DW_OP_call_frame_cfa:
10525e098073Schristos 	  {
10535e098073Schristos 	    int regnum;
10545e098073Schristos 	    CORE_ADDR text_offset;
10555e098073Schristos 	    LONGEST off;
10565e098073Schristos 	    const gdb_byte *cfa_start, *cfa_end;
10575e098073Schristos 
10585e098073Schristos 	    if (dwarf2_fetch_cfa_info (arch, pc, per_cu,
10595e098073Schristos 				       &regnum, &off,
10605e098073Schristos 				       &text_offset, &cfa_start, &cfa_end))
10615e098073Schristos 	      {
10625e098073Schristos 		/* Register.  */
10635e098073Schristos 		pushf_register (indent, stream, registers_used, arch, regnum,
10645e098073Schristos 				off);
10655e098073Schristos 	      }
10665e098073Schristos 	    else
10675e098073Schristos 	      {
10685e098073Schristos 		/* Another expression.  */
10695e098073Schristos 		char cfa_name[50];
10705e098073Schristos 
10715e098073Schristos 		/* Generate a unique-enough name, in case the CFA is
10725e098073Schristos 		   computed multiple times in this expression.  */
10735e098073Schristos 		xsnprintf (cfa_name, sizeof (cfa_name),
10745e098073Schristos 			   "__cfa_%ld", (long) (op_ptr - base));
10755e098073Schristos 
10765e098073Schristos 		do_compile_dwarf_expr_to_c (indent, stream,
1077ed6a76a9Schristos 					    GCC_UINTPTR, cfa_name,
10785e098073Schristos 					    sym, pc, arch, registers_used,
10795e098073Schristos 					    addr_size,
10805e098073Schristos 					    cfa_start, cfa_end,
1081*1424dfb3Schristos 					    &text_offset, per_cu, per_objfile);
1082ed6a76a9Schristos 		pushf (indent, stream, "%s", cfa_name);
10835e098073Schristos 	      }
10845e098073Schristos 	  }
10855e098073Schristos 
10865e098073Schristos 	  break;
10875e098073Schristos 
10885e098073Schristos 	case DW_OP_skip:
10895e098073Schristos 	  offset = extract_signed_integer (op_ptr, 2, byte_order);
10905e098073Schristos 	  op_ptr += 2;
109107163879Schristos 	  fprintfi_filtered (indent, stream, "goto ");
10925e098073Schristos 	  print_label (stream, scope, op_ptr + offset - base);
109307163879Schristos 	  stream->puts (";\n");
10945e098073Schristos 	  break;
10955e098073Schristos 
10965e098073Schristos 	case DW_OP_bra:
10975e098073Schristos 	  offset = extract_signed_integer (op_ptr, 2, byte_order);
10985e098073Schristos 	  op_ptr += 2;
109907163879Schristos 	  fprintfi_filtered (indent, stream,
11005e098073Schristos 			     "if ((( " GCC_INTPTR
11015e098073Schristos 			     ") __gdb_stack[__gdb_tos--]) != 0) goto ");
11025e098073Schristos 	  print_label (stream, scope, op_ptr + offset - base);
110307163879Schristos 	  stream->puts (";\n");
11045e098073Schristos 	  break;
11055e098073Schristos 
11065e098073Schristos 	case DW_OP_nop:
11075e098073Schristos 	  break;
11085e098073Schristos 
11095e098073Schristos 	default:
11105e098073Schristos 	  error (_("unhandled DWARF op: %s"), get_DW_OP_name (op));
11115e098073Schristos 	}
11125e098073Schristos     }
11135e098073Schristos 
111407163879Schristos   fprintfi_filtered (indent, stream, "%s = __gdb_stack[__gdb_tos];\n",
1115ed6a76a9Schristos 		     result_name);
111607163879Schristos   fprintfi_filtered (indent - 2, stream, "}\n");
11175e098073Schristos }
11185e098073Schristos 
11195e098073Schristos /* See compile.h.  */
11205e098073Schristos 
11215e098073Schristos void
compile_dwarf_expr_to_c(string_file * stream,const char * result_name,struct symbol * sym,CORE_ADDR pc,struct gdbarch * arch,unsigned char * registers_used,unsigned int addr_size,const gdb_byte * op_ptr,const gdb_byte * op_end,dwarf2_per_cu_data * per_cu,dwarf2_per_objfile * per_objfile)112207163879Schristos compile_dwarf_expr_to_c (string_file *stream, const char *result_name,
11235e098073Schristos 			 struct symbol *sym, CORE_ADDR pc,
11245e098073Schristos 			 struct gdbarch *arch, unsigned char *registers_used,
11255e098073Schristos 			 unsigned int addr_size,
11265e098073Schristos 			 const gdb_byte *op_ptr, const gdb_byte *op_end,
1127*1424dfb3Schristos 			 dwarf2_per_cu_data *per_cu,
1128*1424dfb3Schristos 			 dwarf2_per_objfile *per_objfile)
11295e098073Schristos {
1130ed6a76a9Schristos   do_compile_dwarf_expr_to_c (2, stream, GCC_UINTPTR, result_name, sym, pc,
11315e098073Schristos 			      arch, registers_used, addr_size, op_ptr, op_end,
1132*1424dfb3Schristos 			      NULL, per_cu, per_objfile);
11335e098073Schristos }
11345e098073Schristos 
11355e098073Schristos /* See compile.h.  */
11365e098073Schristos 
11375e098073Schristos void
compile_dwarf_bounds_to_c(string_file * stream,const char * result_name,const struct dynamic_prop * prop,struct symbol * sym,CORE_ADDR pc,struct gdbarch * arch,unsigned char * registers_used,unsigned int addr_size,const gdb_byte * op_ptr,const gdb_byte * op_end,dwarf2_per_cu_data * per_cu,dwarf2_per_objfile * per_objfile)113807163879Schristos compile_dwarf_bounds_to_c (string_file *stream,
11395e098073Schristos 			   const char *result_name,
11405e098073Schristos 			   const struct dynamic_prop *prop,
11415e098073Schristos 			   struct symbol *sym, CORE_ADDR pc,
11425e098073Schristos 			   struct gdbarch *arch, unsigned char *registers_used,
11435e098073Schristos 			   unsigned int addr_size,
11445e098073Schristos 			   const gdb_byte *op_ptr, const gdb_byte *op_end,
1145*1424dfb3Schristos 			   dwarf2_per_cu_data *per_cu,
1146*1424dfb3Schristos 			   dwarf2_per_objfile *per_objfile)
11475e098073Schristos {
11485e098073Schristos   do_compile_dwarf_expr_to_c (2, stream, "unsigned long ", result_name,
11495e098073Schristos 			      sym, pc, arch, registers_used,
1150*1424dfb3Schristos 			      addr_size, op_ptr, op_end, NULL, per_cu,
1151*1424dfb3Schristos 			      per_objfile);
11525e098073Schristos }
1153