xref: /openbsd-src/gnu/usr.bin/binutils/gdb/dwarf2expr.c (revision 84a83e238ec8f89c0ce5bb1a5d6f3f5cc1612949)
1b725ae77Skettenis /* Dwarf2 Expression Evaluator
2b725ae77Skettenis    Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
3b725ae77Skettenis    Contributed by Daniel Berlin (dan@dberlin.org)
4b725ae77Skettenis 
5b725ae77Skettenis    This file is part of GDB.
6b725ae77Skettenis 
7b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis    it under the terms of the GNU General Public License as published by
9b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis    (at your option) any later version.
11b725ae77Skettenis 
12b725ae77Skettenis    This program is distributed in the hope that it will be useful,
13b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15b725ae77Skettenis    GNU General Public License for more details.
16b725ae77Skettenis 
17b725ae77Skettenis    You should have received a copy of the GNU General Public License
18b725ae77Skettenis    along with this program; if not, write to the Free Software
19b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
21b725ae77Skettenis 
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis #include "symtab.h"
24b725ae77Skettenis #include "gdbtypes.h"
25b725ae77Skettenis #include "value.h"
26b725ae77Skettenis #include "gdbcore.h"
27b725ae77Skettenis #include "elf/dwarf2.h"
28b725ae77Skettenis #include "dwarf2expr.h"
29b725ae77Skettenis 
30b725ae77Skettenis /* Local prototypes.  */
31b725ae77Skettenis 
32b725ae77Skettenis static void execute_stack_op (struct dwarf_expr_context *,
33b725ae77Skettenis 			      unsigned char *, unsigned char *);
34b725ae77Skettenis 
35b725ae77Skettenis /* Create a new context for the expression evaluator.  */
36b725ae77Skettenis 
37b725ae77Skettenis struct dwarf_expr_context *
new_dwarf_expr_context(void)38b725ae77Skettenis new_dwarf_expr_context (void)
39b725ae77Skettenis {
40b725ae77Skettenis   struct dwarf_expr_context *retval;
41b725ae77Skettenis   retval = xcalloc (1, sizeof (struct dwarf_expr_context));
42b725ae77Skettenis   retval->stack_len = 0;
43b725ae77Skettenis   retval->stack_allocated = 10;
44b725ae77Skettenis   retval->stack = xmalloc (retval->stack_allocated * sizeof (CORE_ADDR));
4511efff7fSkettenis   retval->num_pieces = 0;
4611efff7fSkettenis   retval->pieces = 0;
47b725ae77Skettenis   return retval;
48b725ae77Skettenis }
49b725ae77Skettenis 
50b725ae77Skettenis /* Release the memory allocated to CTX.  */
51b725ae77Skettenis 
52b725ae77Skettenis void
free_dwarf_expr_context(struct dwarf_expr_context * ctx)53b725ae77Skettenis free_dwarf_expr_context (struct dwarf_expr_context *ctx)
54b725ae77Skettenis {
55b725ae77Skettenis   xfree (ctx->stack);
5611efff7fSkettenis   xfree (ctx->pieces);
57b725ae77Skettenis   xfree (ctx);
58b725ae77Skettenis }
59b725ae77Skettenis 
60b725ae77Skettenis /* Expand the memory allocated to CTX's stack to contain at least
61b725ae77Skettenis    NEED more elements than are currently used.  */
62b725ae77Skettenis 
63b725ae77Skettenis static void
dwarf_expr_grow_stack(struct dwarf_expr_context * ctx,size_t need)64b725ae77Skettenis dwarf_expr_grow_stack (struct dwarf_expr_context *ctx, size_t need)
65b725ae77Skettenis {
66b725ae77Skettenis   if (ctx->stack_len + need > ctx->stack_allocated)
67b725ae77Skettenis     {
68b725ae77Skettenis       size_t newlen = ctx->stack_len + need + 10;
69b725ae77Skettenis       ctx->stack = xrealloc (ctx->stack,
70b725ae77Skettenis 			     newlen * sizeof (CORE_ADDR));
71b725ae77Skettenis       ctx->stack_allocated = newlen;
72b725ae77Skettenis     }
73b725ae77Skettenis }
74b725ae77Skettenis 
75b725ae77Skettenis /* Push VALUE onto CTX's stack.  */
76b725ae77Skettenis 
77b725ae77Skettenis void
dwarf_expr_push(struct dwarf_expr_context * ctx,CORE_ADDR value)78b725ae77Skettenis dwarf_expr_push (struct dwarf_expr_context *ctx, CORE_ADDR value)
79b725ae77Skettenis {
80b725ae77Skettenis   dwarf_expr_grow_stack (ctx, 1);
81b725ae77Skettenis   ctx->stack[ctx->stack_len++] = value;
82b725ae77Skettenis }
83b725ae77Skettenis 
84b725ae77Skettenis /* Pop the top item off of CTX's stack.  */
85b725ae77Skettenis 
86b725ae77Skettenis void
dwarf_expr_pop(struct dwarf_expr_context * ctx)87b725ae77Skettenis dwarf_expr_pop (struct dwarf_expr_context *ctx)
88b725ae77Skettenis {
89b725ae77Skettenis   if (ctx->stack_len <= 0)
90b725ae77Skettenis     error ("dwarf expression stack underflow");
91b725ae77Skettenis   ctx->stack_len--;
92b725ae77Skettenis }
93b725ae77Skettenis 
94b725ae77Skettenis /* Retrieve the N'th item on CTX's stack.  */
95b725ae77Skettenis 
96b725ae77Skettenis CORE_ADDR
dwarf_expr_fetch(struct dwarf_expr_context * ctx,int n)97b725ae77Skettenis dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
98b725ae77Skettenis {
99b725ae77Skettenis   if (ctx->stack_len < n)
100b725ae77Skettenis      error ("Asked for position %d of stack, stack only has %d elements on it\n",
101b725ae77Skettenis 	    n, ctx->stack_len);
102b725ae77Skettenis   return ctx->stack[ctx->stack_len - (1 + n)];
103b725ae77Skettenis 
104b725ae77Skettenis }
105b725ae77Skettenis 
10611efff7fSkettenis /* Add a new piece to CTX's piece list.  */
10711efff7fSkettenis static void
add_piece(struct dwarf_expr_context * ctx,int in_reg,CORE_ADDR value,ULONGEST size)10811efff7fSkettenis add_piece (struct dwarf_expr_context *ctx,
10911efff7fSkettenis            int in_reg, CORE_ADDR value, ULONGEST size)
11011efff7fSkettenis {
11111efff7fSkettenis   struct dwarf_expr_piece *p;
11211efff7fSkettenis 
11311efff7fSkettenis   ctx->num_pieces++;
11411efff7fSkettenis 
11511efff7fSkettenis   if (ctx->pieces)
11611efff7fSkettenis     ctx->pieces = xrealloc (ctx->pieces,
11711efff7fSkettenis                             (ctx->num_pieces
11811efff7fSkettenis                              * sizeof (struct dwarf_expr_piece)));
11911efff7fSkettenis   else
12011efff7fSkettenis     ctx->pieces = xmalloc (ctx->num_pieces
12111efff7fSkettenis                            * sizeof (struct dwarf_expr_piece));
12211efff7fSkettenis 
12311efff7fSkettenis   p = &ctx->pieces[ctx->num_pieces - 1];
12411efff7fSkettenis   p->in_reg = in_reg;
12511efff7fSkettenis   p->value = value;
12611efff7fSkettenis   p->size = size;
12711efff7fSkettenis }
12811efff7fSkettenis 
129b725ae77Skettenis /* Evaluate the expression at ADDR (LEN bytes long) using the context
130b725ae77Skettenis    CTX.  */
131b725ae77Skettenis 
132b725ae77Skettenis void
dwarf_expr_eval(struct dwarf_expr_context * ctx,unsigned char * addr,size_t len)133b725ae77Skettenis dwarf_expr_eval (struct dwarf_expr_context *ctx, unsigned char *addr,
134b725ae77Skettenis 		 size_t len)
135b725ae77Skettenis {
136b725ae77Skettenis   execute_stack_op (ctx, addr, addr + len);
137b725ae77Skettenis }
138b725ae77Skettenis 
139b725ae77Skettenis /* Decode the unsigned LEB128 constant at BUF into the variable pointed to
140b725ae77Skettenis    by R, and return the new value of BUF.  Verify that it doesn't extend
141b725ae77Skettenis    past BUF_END.  */
142b725ae77Skettenis 
143b725ae77Skettenis unsigned char *
read_uleb128(unsigned char * buf,unsigned char * buf_end,ULONGEST * r)144b725ae77Skettenis read_uleb128 (unsigned char *buf, unsigned char *buf_end, ULONGEST * r)
145b725ae77Skettenis {
146b725ae77Skettenis   unsigned shift = 0;
147b725ae77Skettenis   ULONGEST result = 0;
148b725ae77Skettenis   unsigned char byte;
149b725ae77Skettenis 
150b725ae77Skettenis   while (1)
151b725ae77Skettenis     {
152b725ae77Skettenis       if (buf >= buf_end)
153b725ae77Skettenis 	error ("read_uleb128: Corrupted DWARF expression.");
154b725ae77Skettenis 
155b725ae77Skettenis       byte = *buf++;
156b725ae77Skettenis       result |= (byte & 0x7f) << shift;
157b725ae77Skettenis       if ((byte & 0x80) == 0)
158b725ae77Skettenis 	break;
159b725ae77Skettenis       shift += 7;
160b725ae77Skettenis     }
161b725ae77Skettenis   *r = result;
162b725ae77Skettenis   return buf;
163b725ae77Skettenis }
164b725ae77Skettenis 
165b725ae77Skettenis /* Decode the signed LEB128 constant at BUF into the variable pointed to
166b725ae77Skettenis    by R, and return the new value of BUF.  Verify that it doesn't extend
167b725ae77Skettenis    past BUF_END.  */
168b725ae77Skettenis 
169b725ae77Skettenis unsigned char *
read_sleb128(unsigned char * buf,unsigned char * buf_end,LONGEST * r)170b725ae77Skettenis read_sleb128 (unsigned char *buf, unsigned char *buf_end, LONGEST * r)
171b725ae77Skettenis {
172b725ae77Skettenis   unsigned shift = 0;
173b725ae77Skettenis   LONGEST result = 0;
174b725ae77Skettenis   unsigned char byte;
175b725ae77Skettenis 
176b725ae77Skettenis   while (1)
177b725ae77Skettenis     {
178b725ae77Skettenis       if (buf >= buf_end)
179b725ae77Skettenis 	error ("read_sleb128: Corrupted DWARF expression.");
180b725ae77Skettenis 
181b725ae77Skettenis       byte = *buf++;
182b725ae77Skettenis       result |= (byte & 0x7f) << shift;
183b725ae77Skettenis       shift += 7;
184b725ae77Skettenis       if ((byte & 0x80) == 0)
185b725ae77Skettenis 	break;
186b725ae77Skettenis     }
187b725ae77Skettenis   if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0)
188b725ae77Skettenis     result |= -(1 << shift);
189b725ae77Skettenis 
190b725ae77Skettenis   *r = result;
191b725ae77Skettenis   return buf;
192b725ae77Skettenis }
193b725ae77Skettenis 
194b725ae77Skettenis /* Read an address from BUF, and verify that it doesn't extend past
195b725ae77Skettenis    BUF_END.  The address is returned, and *BYTES_READ is set to the
196b725ae77Skettenis    number of bytes read from BUF.  */
197b725ae77Skettenis 
198b725ae77Skettenis CORE_ADDR
dwarf2_read_address(unsigned char * buf,unsigned char * buf_end,int * bytes_read)199b725ae77Skettenis dwarf2_read_address (unsigned char *buf, unsigned char *buf_end, int *bytes_read)
200b725ae77Skettenis {
201b725ae77Skettenis   CORE_ADDR result;
202b725ae77Skettenis 
203b725ae77Skettenis   if (buf_end - buf < TARGET_ADDR_BIT / TARGET_CHAR_BIT)
204b725ae77Skettenis     error ("dwarf2_read_address: Corrupted DWARF expression.");
205b725ae77Skettenis 
206b725ae77Skettenis   *bytes_read = TARGET_ADDR_BIT / TARGET_CHAR_BIT;
207b725ae77Skettenis   /* NOTE: cagney/2003-05-22: This extract is assuming that a DWARF 2
208b725ae77Skettenis      address is always unsigned.  That may or may not be true.  */
209b725ae77Skettenis   result = extract_unsigned_integer (buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT);
210b725ae77Skettenis   return result;
211b725ae77Skettenis }
212b725ae77Skettenis 
213b725ae77Skettenis /* Return the type of an address, for unsigned arithmetic.  */
214b725ae77Skettenis 
215b725ae77Skettenis static struct type *
unsigned_address_type(void)216b725ae77Skettenis unsigned_address_type (void)
217b725ae77Skettenis {
218b725ae77Skettenis   switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
219b725ae77Skettenis     {
220b725ae77Skettenis     case 2:
221b725ae77Skettenis       return builtin_type_uint16;
222b725ae77Skettenis     case 4:
223b725ae77Skettenis       return builtin_type_uint32;
224b725ae77Skettenis     case 8:
225b725ae77Skettenis       return builtin_type_uint64;
226b725ae77Skettenis     default:
227b725ae77Skettenis       internal_error (__FILE__, __LINE__,
228b725ae77Skettenis 		      "Unsupported address size.\n");
229b725ae77Skettenis     }
230b725ae77Skettenis }
231b725ae77Skettenis 
232b725ae77Skettenis /* Return the type of an address, for signed arithmetic.  */
233b725ae77Skettenis 
234b725ae77Skettenis static struct type *
signed_address_type(void)235b725ae77Skettenis signed_address_type (void)
236b725ae77Skettenis {
237b725ae77Skettenis   switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
238b725ae77Skettenis     {
239b725ae77Skettenis     case 2:
240b725ae77Skettenis       return builtin_type_int16;
241b725ae77Skettenis     case 4:
242b725ae77Skettenis       return builtin_type_int32;
243b725ae77Skettenis     case 8:
244b725ae77Skettenis       return builtin_type_int64;
245b725ae77Skettenis     default:
246b725ae77Skettenis       internal_error (__FILE__, __LINE__,
247b725ae77Skettenis 		      "Unsupported address size.\n");
248b725ae77Skettenis     }
249b725ae77Skettenis }
250b725ae77Skettenis 
251b725ae77Skettenis /* The engine for the expression evaluator.  Using the context in CTX,
252b725ae77Skettenis    evaluate the expression between OP_PTR and OP_END.  */
253b725ae77Skettenis 
254b725ae77Skettenis static void
execute_stack_op(struct dwarf_expr_context * ctx,unsigned char * op_ptr,unsigned char * op_end)255b725ae77Skettenis execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
256b725ae77Skettenis 		  unsigned char *op_end)
257b725ae77Skettenis {
258b725ae77Skettenis   ctx->in_reg = 0;
259b725ae77Skettenis 
260b725ae77Skettenis   while (op_ptr < op_end)
261b725ae77Skettenis     {
262b725ae77Skettenis       enum dwarf_location_atom op = *op_ptr++;
263b725ae77Skettenis       CORE_ADDR result;
264b725ae77Skettenis       ULONGEST uoffset, reg;
265b725ae77Skettenis       LONGEST offset;
266b725ae77Skettenis       int bytes_read;
267b725ae77Skettenis 
268b725ae77Skettenis       switch (op)
269b725ae77Skettenis 	{
270b725ae77Skettenis 	case DW_OP_lit0:
271b725ae77Skettenis 	case DW_OP_lit1:
272b725ae77Skettenis 	case DW_OP_lit2:
273b725ae77Skettenis 	case DW_OP_lit3:
274b725ae77Skettenis 	case DW_OP_lit4:
275b725ae77Skettenis 	case DW_OP_lit5:
276b725ae77Skettenis 	case DW_OP_lit6:
277b725ae77Skettenis 	case DW_OP_lit7:
278b725ae77Skettenis 	case DW_OP_lit8:
279b725ae77Skettenis 	case DW_OP_lit9:
280b725ae77Skettenis 	case DW_OP_lit10:
281b725ae77Skettenis 	case DW_OP_lit11:
282b725ae77Skettenis 	case DW_OP_lit12:
283b725ae77Skettenis 	case DW_OP_lit13:
284b725ae77Skettenis 	case DW_OP_lit14:
285b725ae77Skettenis 	case DW_OP_lit15:
286b725ae77Skettenis 	case DW_OP_lit16:
287b725ae77Skettenis 	case DW_OP_lit17:
288b725ae77Skettenis 	case DW_OP_lit18:
289b725ae77Skettenis 	case DW_OP_lit19:
290b725ae77Skettenis 	case DW_OP_lit20:
291b725ae77Skettenis 	case DW_OP_lit21:
292b725ae77Skettenis 	case DW_OP_lit22:
293b725ae77Skettenis 	case DW_OP_lit23:
294b725ae77Skettenis 	case DW_OP_lit24:
295b725ae77Skettenis 	case DW_OP_lit25:
296b725ae77Skettenis 	case DW_OP_lit26:
297b725ae77Skettenis 	case DW_OP_lit27:
298b725ae77Skettenis 	case DW_OP_lit28:
299b725ae77Skettenis 	case DW_OP_lit29:
300b725ae77Skettenis 	case DW_OP_lit30:
301b725ae77Skettenis 	case DW_OP_lit31:
302b725ae77Skettenis 	  result = op - DW_OP_lit0;
303b725ae77Skettenis 	  break;
304b725ae77Skettenis 
305b725ae77Skettenis 	case DW_OP_addr:
306b725ae77Skettenis 	  result = dwarf2_read_address (op_ptr, op_end, &bytes_read);
307b725ae77Skettenis 	  op_ptr += bytes_read;
308b725ae77Skettenis 	  break;
309b725ae77Skettenis 
310b725ae77Skettenis 	case DW_OP_const1u:
311b725ae77Skettenis 	  result = extract_unsigned_integer (op_ptr, 1);
312b725ae77Skettenis 	  op_ptr += 1;
313b725ae77Skettenis 	  break;
314b725ae77Skettenis 	case DW_OP_const1s:
315b725ae77Skettenis 	  result = extract_signed_integer (op_ptr, 1);
316b725ae77Skettenis 	  op_ptr += 1;
317b725ae77Skettenis 	  break;
318b725ae77Skettenis 	case DW_OP_const2u:
319b725ae77Skettenis 	  result = extract_unsigned_integer (op_ptr, 2);
320b725ae77Skettenis 	  op_ptr += 2;
321b725ae77Skettenis 	  break;
322b725ae77Skettenis 	case DW_OP_const2s:
323b725ae77Skettenis 	  result = extract_signed_integer (op_ptr, 2);
324b725ae77Skettenis 	  op_ptr += 2;
325b725ae77Skettenis 	  break;
326b725ae77Skettenis 	case DW_OP_const4u:
327b725ae77Skettenis 	  result = extract_unsigned_integer (op_ptr, 4);
328b725ae77Skettenis 	  op_ptr += 4;
329b725ae77Skettenis 	  break;
330b725ae77Skettenis 	case DW_OP_const4s:
331b725ae77Skettenis 	  result = extract_signed_integer (op_ptr, 4);
332b725ae77Skettenis 	  op_ptr += 4;
333b725ae77Skettenis 	  break;
334b725ae77Skettenis 	case DW_OP_const8u:
335b725ae77Skettenis 	  result = extract_unsigned_integer (op_ptr, 8);
336b725ae77Skettenis 	  op_ptr += 8;
337b725ae77Skettenis 	  break;
338b725ae77Skettenis 	case DW_OP_const8s:
339b725ae77Skettenis 	  result = extract_signed_integer (op_ptr, 8);
340b725ae77Skettenis 	  op_ptr += 8;
341b725ae77Skettenis 	  break;
342b725ae77Skettenis 	case DW_OP_constu:
343b725ae77Skettenis 	  op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
344b725ae77Skettenis 	  result = uoffset;
345b725ae77Skettenis 	  break;
346b725ae77Skettenis 	case DW_OP_consts:
347b725ae77Skettenis 	  op_ptr = read_sleb128 (op_ptr, op_end, &offset);
348b725ae77Skettenis 	  result = offset;
349b725ae77Skettenis 	  break;
350b725ae77Skettenis 
351b725ae77Skettenis 	/* The DW_OP_reg operations are required to occur alone in
352b725ae77Skettenis 	   location expressions.  */
353b725ae77Skettenis 	case DW_OP_reg0:
354b725ae77Skettenis 	case DW_OP_reg1:
355b725ae77Skettenis 	case DW_OP_reg2:
356b725ae77Skettenis 	case DW_OP_reg3:
357b725ae77Skettenis 	case DW_OP_reg4:
358b725ae77Skettenis 	case DW_OP_reg5:
359b725ae77Skettenis 	case DW_OP_reg6:
360b725ae77Skettenis 	case DW_OP_reg7:
361b725ae77Skettenis 	case DW_OP_reg8:
362b725ae77Skettenis 	case DW_OP_reg9:
363b725ae77Skettenis 	case DW_OP_reg10:
364b725ae77Skettenis 	case DW_OP_reg11:
365b725ae77Skettenis 	case DW_OP_reg12:
366b725ae77Skettenis 	case DW_OP_reg13:
367b725ae77Skettenis 	case DW_OP_reg14:
368b725ae77Skettenis 	case DW_OP_reg15:
369b725ae77Skettenis 	case DW_OP_reg16:
370b725ae77Skettenis 	case DW_OP_reg17:
371b725ae77Skettenis 	case DW_OP_reg18:
372b725ae77Skettenis 	case DW_OP_reg19:
373b725ae77Skettenis 	case DW_OP_reg20:
374b725ae77Skettenis 	case DW_OP_reg21:
375b725ae77Skettenis 	case DW_OP_reg22:
376b725ae77Skettenis 	case DW_OP_reg23:
377b725ae77Skettenis 	case DW_OP_reg24:
378b725ae77Skettenis 	case DW_OP_reg25:
379b725ae77Skettenis 	case DW_OP_reg26:
380b725ae77Skettenis 	case DW_OP_reg27:
381b725ae77Skettenis 	case DW_OP_reg28:
382b725ae77Skettenis 	case DW_OP_reg29:
383b725ae77Skettenis 	case DW_OP_reg30:
384b725ae77Skettenis 	case DW_OP_reg31:
385b725ae77Skettenis 	  if (op_ptr != op_end && *op_ptr != DW_OP_piece)
386b725ae77Skettenis 	    error ("DWARF-2 expression error: DW_OP_reg operations must be "
387b725ae77Skettenis 		   "used either alone or in conjuction with DW_OP_piece.");
388b725ae77Skettenis 
389b725ae77Skettenis 	  result = op - DW_OP_reg0;
390b725ae77Skettenis 	  ctx->in_reg = 1;
391b725ae77Skettenis 
392b725ae77Skettenis 	  break;
393b725ae77Skettenis 
394b725ae77Skettenis 	case DW_OP_regx:
395b725ae77Skettenis 	  op_ptr = read_uleb128 (op_ptr, op_end, &reg);
396b725ae77Skettenis 	  if (op_ptr != op_end && *op_ptr != DW_OP_piece)
397b725ae77Skettenis 	    error ("DWARF-2 expression error: DW_OP_reg operations must be "
398b725ae77Skettenis 		   "used either alone or in conjuction with DW_OP_piece.");
399b725ae77Skettenis 
400b725ae77Skettenis 	  result = reg;
401b725ae77Skettenis 	  ctx->in_reg = 1;
402b725ae77Skettenis 	  break;
403b725ae77Skettenis 
404b725ae77Skettenis 	case DW_OP_breg0:
405b725ae77Skettenis 	case DW_OP_breg1:
406b725ae77Skettenis 	case DW_OP_breg2:
407b725ae77Skettenis 	case DW_OP_breg3:
408b725ae77Skettenis 	case DW_OP_breg4:
409b725ae77Skettenis 	case DW_OP_breg5:
410b725ae77Skettenis 	case DW_OP_breg6:
411b725ae77Skettenis 	case DW_OP_breg7:
412b725ae77Skettenis 	case DW_OP_breg8:
413b725ae77Skettenis 	case DW_OP_breg9:
414b725ae77Skettenis 	case DW_OP_breg10:
415b725ae77Skettenis 	case DW_OP_breg11:
416b725ae77Skettenis 	case DW_OP_breg12:
417b725ae77Skettenis 	case DW_OP_breg13:
418b725ae77Skettenis 	case DW_OP_breg14:
419b725ae77Skettenis 	case DW_OP_breg15:
420b725ae77Skettenis 	case DW_OP_breg16:
421b725ae77Skettenis 	case DW_OP_breg17:
422b725ae77Skettenis 	case DW_OP_breg18:
423b725ae77Skettenis 	case DW_OP_breg19:
424b725ae77Skettenis 	case DW_OP_breg20:
425b725ae77Skettenis 	case DW_OP_breg21:
426b725ae77Skettenis 	case DW_OP_breg22:
427b725ae77Skettenis 	case DW_OP_breg23:
428b725ae77Skettenis 	case DW_OP_breg24:
429b725ae77Skettenis 	case DW_OP_breg25:
430b725ae77Skettenis 	case DW_OP_breg26:
431b725ae77Skettenis 	case DW_OP_breg27:
432b725ae77Skettenis 	case DW_OP_breg28:
433b725ae77Skettenis 	case DW_OP_breg29:
434b725ae77Skettenis 	case DW_OP_breg30:
435b725ae77Skettenis 	case DW_OP_breg31:
436b725ae77Skettenis 	  {
437b725ae77Skettenis 	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
438b725ae77Skettenis 	    result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0);
439b725ae77Skettenis 	    result += offset;
440b725ae77Skettenis 	  }
441b725ae77Skettenis 	  break;
442b725ae77Skettenis 	case DW_OP_bregx:
443b725ae77Skettenis 	  {
444b725ae77Skettenis 	    op_ptr = read_uleb128 (op_ptr, op_end, &reg);
445b725ae77Skettenis 	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
446b725ae77Skettenis 	    result = (ctx->read_reg) (ctx->baton, reg);
447b725ae77Skettenis 	    result += offset;
448b725ae77Skettenis 	  }
449b725ae77Skettenis 	  break;
450b725ae77Skettenis 	case DW_OP_fbreg:
451b725ae77Skettenis 	  {
452b725ae77Skettenis 	    unsigned char *datastart;
453b725ae77Skettenis 	    size_t datalen;
454b725ae77Skettenis 	    unsigned int before_stack_len;
455b725ae77Skettenis 
456b725ae77Skettenis 	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
457b725ae77Skettenis 	    /* Rather than create a whole new context, we simply
458b725ae77Skettenis 	       record the stack length before execution, then reset it
459b725ae77Skettenis 	       afterwards, effectively erasing whatever the recursive
460b725ae77Skettenis 	       call put there.  */
461b725ae77Skettenis 	    before_stack_len = ctx->stack_len;
462b725ae77Skettenis 	    /* FIXME: cagney/2003-03-26: This code should be using
463b725ae77Skettenis                get_frame_base_address(), and then implement a dwarf2
464b725ae77Skettenis                specific this_base method.  */
465b725ae77Skettenis 	    (ctx->get_frame_base) (ctx->baton, &datastart, &datalen);
466b725ae77Skettenis 	    dwarf_expr_eval (ctx, datastart, datalen);
467b725ae77Skettenis 	    result = dwarf_expr_fetch (ctx, 0);
468b725ae77Skettenis 	    if (ctx->in_reg)
469b725ae77Skettenis 	      result = (ctx->read_reg) (ctx->baton, result);
470b725ae77Skettenis 	    result = result + offset;
471b725ae77Skettenis 	    ctx->stack_len = before_stack_len;
472b725ae77Skettenis 	    ctx->in_reg = 0;
473b725ae77Skettenis 	  }
474b725ae77Skettenis 	  break;
475b725ae77Skettenis 	case DW_OP_dup:
476b725ae77Skettenis 	  result = dwarf_expr_fetch (ctx, 0);
477b725ae77Skettenis 	  break;
478b725ae77Skettenis 
479b725ae77Skettenis 	case DW_OP_drop:
480b725ae77Skettenis 	  dwarf_expr_pop (ctx);
481b725ae77Skettenis 	  goto no_push;
482b725ae77Skettenis 
483b725ae77Skettenis 	case DW_OP_pick:
484b725ae77Skettenis 	  offset = *op_ptr++;
485b725ae77Skettenis 	  result = dwarf_expr_fetch (ctx, offset);
486b725ae77Skettenis 	  break;
487b725ae77Skettenis 
488b725ae77Skettenis 	case DW_OP_over:
489b725ae77Skettenis 	  result = dwarf_expr_fetch (ctx, 1);
490b725ae77Skettenis 	  break;
491b725ae77Skettenis 
492b725ae77Skettenis 	case DW_OP_rot:
493b725ae77Skettenis 	  {
494b725ae77Skettenis 	    CORE_ADDR t1, t2, t3;
495b725ae77Skettenis 
496b725ae77Skettenis 	    if (ctx->stack_len < 3)
497b725ae77Skettenis 	       error ("Not enough elements for DW_OP_rot. Need 3, have %d\n",
498b725ae77Skettenis 		      ctx->stack_len);
499b725ae77Skettenis 	    t1 = ctx->stack[ctx->stack_len - 1];
500b725ae77Skettenis 	    t2 = ctx->stack[ctx->stack_len - 2];
501b725ae77Skettenis 	    t3 = ctx->stack[ctx->stack_len - 3];
502b725ae77Skettenis 	    ctx->stack[ctx->stack_len - 1] = t2;
503b725ae77Skettenis 	    ctx->stack[ctx->stack_len - 2] = t3;
504b725ae77Skettenis 	    ctx->stack[ctx->stack_len - 3] = t1;
505b725ae77Skettenis 	    goto no_push;
506b725ae77Skettenis 	  }
507b725ae77Skettenis 
508*84a83e23Skettenis 	case DW_OP_swap:
509*84a83e23Skettenis 	  {
510*84a83e23Skettenis 	    CORE_ADDR t1, t2;
511*84a83e23Skettenis 
512*84a83e23Skettenis 	    if (ctx->stack_len < 2)
513*84a83e23Skettenis 	       error ("Not enough elements for DW_OP_swap. Need 2, have %d\n",
514*84a83e23Skettenis 		      ctx->stack_len);
515*84a83e23Skettenis 	    t1 = ctx->stack[ctx->stack_len - 1];
516*84a83e23Skettenis 	    t2 = ctx->stack[ctx->stack_len - 2];
517*84a83e23Skettenis 	    ctx->stack[ctx->stack_len - 1] = t2;
518*84a83e23Skettenis 	    ctx->stack[ctx->stack_len - 2] = t1;
519*84a83e23Skettenis 	    goto no_push;
520*84a83e23Skettenis 	  }
521*84a83e23Skettenis 
522b725ae77Skettenis 	case DW_OP_deref:
523b725ae77Skettenis 	case DW_OP_deref_size:
524b725ae77Skettenis 	case DW_OP_abs:
525b725ae77Skettenis 	case DW_OP_neg:
526b725ae77Skettenis 	case DW_OP_not:
527b725ae77Skettenis 	case DW_OP_plus_uconst:
528b725ae77Skettenis 	  /* Unary operations.  */
529b725ae77Skettenis 	  result = dwarf_expr_fetch (ctx, 0);
530b725ae77Skettenis 	  dwarf_expr_pop (ctx);
531b725ae77Skettenis 
532b725ae77Skettenis 	  switch (op)
533b725ae77Skettenis 	    {
534b725ae77Skettenis 	    case DW_OP_deref:
535b725ae77Skettenis 	      {
536b725ae77Skettenis 		char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
537b725ae77Skettenis 		int bytes_read;
538b725ae77Skettenis 
539b725ae77Skettenis 		(ctx->read_mem) (ctx->baton, buf, result,
540b725ae77Skettenis 				 TARGET_ADDR_BIT / TARGET_CHAR_BIT);
541b725ae77Skettenis 		result = dwarf2_read_address (buf,
542b725ae77Skettenis 					      buf + (TARGET_ADDR_BIT
543b725ae77Skettenis 						     / TARGET_CHAR_BIT),
544b725ae77Skettenis 					      &bytes_read);
545b725ae77Skettenis 	      }
546b725ae77Skettenis 	      break;
547b725ae77Skettenis 
548b725ae77Skettenis 	    case DW_OP_deref_size:
549b725ae77Skettenis 	      {
550b725ae77Skettenis 		char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
551b725ae77Skettenis 		int bytes_read;
552b725ae77Skettenis 
553b725ae77Skettenis 		(ctx->read_mem) (ctx->baton, buf, result, *op_ptr++);
554b725ae77Skettenis 		result = dwarf2_read_address (buf,
555b725ae77Skettenis 					      buf + (TARGET_ADDR_BIT
556b725ae77Skettenis 						     / TARGET_CHAR_BIT),
557b725ae77Skettenis 					      &bytes_read);
558b725ae77Skettenis 	      }
559b725ae77Skettenis 	      break;
560b725ae77Skettenis 
561b725ae77Skettenis 	    case DW_OP_abs:
562b725ae77Skettenis 	      if ((signed int) result < 0)
563b725ae77Skettenis 		result = -result;
564b725ae77Skettenis 	      break;
565b725ae77Skettenis 	    case DW_OP_neg:
566b725ae77Skettenis 	      result = -result;
567b725ae77Skettenis 	      break;
568b725ae77Skettenis 	    case DW_OP_not:
569b725ae77Skettenis 	      result = ~result;
570b725ae77Skettenis 	      break;
571b725ae77Skettenis 	    case DW_OP_plus_uconst:
572b725ae77Skettenis 	      op_ptr = read_uleb128 (op_ptr, op_end, &reg);
573b725ae77Skettenis 	      result += reg;
574b725ae77Skettenis 	      break;
575b725ae77Skettenis 	    }
576b725ae77Skettenis 	  break;
577b725ae77Skettenis 
578b725ae77Skettenis 	case DW_OP_and:
579b725ae77Skettenis 	case DW_OP_div:
580b725ae77Skettenis 	case DW_OP_minus:
581b725ae77Skettenis 	case DW_OP_mod:
582b725ae77Skettenis 	case DW_OP_mul:
583b725ae77Skettenis 	case DW_OP_or:
584b725ae77Skettenis 	case DW_OP_plus:
585b725ae77Skettenis 	case DW_OP_shl:
586b725ae77Skettenis 	case DW_OP_shr:
587b725ae77Skettenis 	case DW_OP_shra:
588b725ae77Skettenis 	case DW_OP_xor:
589b725ae77Skettenis 	case DW_OP_le:
590b725ae77Skettenis 	case DW_OP_ge:
591b725ae77Skettenis 	case DW_OP_eq:
592b725ae77Skettenis 	case DW_OP_lt:
593b725ae77Skettenis 	case DW_OP_gt:
594b725ae77Skettenis 	case DW_OP_ne:
595b725ae77Skettenis 	  {
596b725ae77Skettenis 	    /* Binary operations.  Use the value engine to do computations in
597b725ae77Skettenis 	       the right width.  */
598b725ae77Skettenis 	    CORE_ADDR first, second;
599b725ae77Skettenis 	    enum exp_opcode binop;
600b725ae77Skettenis 	    struct value *val1, *val2;
601b725ae77Skettenis 
602b725ae77Skettenis 	    second = dwarf_expr_fetch (ctx, 0);
603b725ae77Skettenis 	    dwarf_expr_pop (ctx);
604b725ae77Skettenis 
605b725ae77Skettenis 	    first = dwarf_expr_fetch (ctx, 0);
606b725ae77Skettenis 	    dwarf_expr_pop (ctx);
607b725ae77Skettenis 
608b725ae77Skettenis 	    val1 = value_from_longest (unsigned_address_type (), first);
609b725ae77Skettenis 	    val2 = value_from_longest (unsigned_address_type (), second);
610b725ae77Skettenis 
611b725ae77Skettenis 	    switch (op)
612b725ae77Skettenis 	      {
613b725ae77Skettenis 	      case DW_OP_and:
614b725ae77Skettenis 		binop = BINOP_BITWISE_AND;
615b725ae77Skettenis 		break;
616b725ae77Skettenis 	      case DW_OP_div:
617b725ae77Skettenis 		binop = BINOP_DIV;
61811efff7fSkettenis                 break;
619b725ae77Skettenis 	      case DW_OP_minus:
620b725ae77Skettenis 		binop = BINOP_SUB;
621b725ae77Skettenis 		break;
622b725ae77Skettenis 	      case DW_OP_mod:
623b725ae77Skettenis 		binop = BINOP_MOD;
624b725ae77Skettenis 		break;
625b725ae77Skettenis 	      case DW_OP_mul:
626b725ae77Skettenis 		binop = BINOP_MUL;
627b725ae77Skettenis 		break;
628b725ae77Skettenis 	      case DW_OP_or:
629b725ae77Skettenis 		binop = BINOP_BITWISE_IOR;
630b725ae77Skettenis 		break;
631b725ae77Skettenis 	      case DW_OP_plus:
632b725ae77Skettenis 		binop = BINOP_ADD;
633b725ae77Skettenis 		break;
634b725ae77Skettenis 	      case DW_OP_shl:
635b725ae77Skettenis 		binop = BINOP_LSH;
636b725ae77Skettenis 		break;
637b725ae77Skettenis 	      case DW_OP_shr:
638b725ae77Skettenis 		binop = BINOP_RSH;
63911efff7fSkettenis                 break;
640b725ae77Skettenis 	      case DW_OP_shra:
641b725ae77Skettenis 		binop = BINOP_RSH;
642b725ae77Skettenis 		val1 = value_from_longest (signed_address_type (), first);
643b725ae77Skettenis 		break;
644b725ae77Skettenis 	      case DW_OP_xor:
645b725ae77Skettenis 		binop = BINOP_BITWISE_XOR;
646b725ae77Skettenis 		break;
647b725ae77Skettenis 	      case DW_OP_le:
648b725ae77Skettenis 		binop = BINOP_LEQ;
649b725ae77Skettenis 		break;
650b725ae77Skettenis 	      case DW_OP_ge:
651b725ae77Skettenis 		binop = BINOP_GEQ;
652b725ae77Skettenis 		break;
653b725ae77Skettenis 	      case DW_OP_eq:
654b725ae77Skettenis 		binop = BINOP_EQUAL;
655b725ae77Skettenis 		break;
656b725ae77Skettenis 	      case DW_OP_lt:
657b725ae77Skettenis 		binop = BINOP_LESS;
658b725ae77Skettenis 		break;
659b725ae77Skettenis 	      case DW_OP_gt:
660b725ae77Skettenis 		binop = BINOP_GTR;
661b725ae77Skettenis 		break;
662b725ae77Skettenis 	      case DW_OP_ne:
663b725ae77Skettenis 		binop = BINOP_NOTEQUAL;
664b725ae77Skettenis 		break;
665b725ae77Skettenis 	      default:
666b725ae77Skettenis 		internal_error (__FILE__, __LINE__,
667b725ae77Skettenis 				"Can't be reached.");
668b725ae77Skettenis 	      }
669b725ae77Skettenis 	    result = value_as_long (value_binop (val1, val2, binop));
670b725ae77Skettenis 	  }
671b725ae77Skettenis 	  break;
672b725ae77Skettenis 
673b725ae77Skettenis 	case DW_OP_GNU_push_tls_address:
674b725ae77Skettenis 	  /* Variable is at a constant offset in the thread-local
675b725ae77Skettenis 	  storage block into the objfile for the current thread and
676b725ae77Skettenis 	  the dynamic linker module containing this expression. Here
677b725ae77Skettenis 	  we return returns the offset from that base.  The top of the
678b725ae77Skettenis 	  stack has the offset from the beginning of the thread
679b725ae77Skettenis 	  control block at which the variable is located.  Nothing
680b725ae77Skettenis 	  should follow this operator, so the top of stack would be
681b725ae77Skettenis 	  returned.  */
682b725ae77Skettenis 	  result = dwarf_expr_fetch (ctx, 0);
683b725ae77Skettenis 	  dwarf_expr_pop (ctx);
684b725ae77Skettenis 	  result = (ctx->get_tls_address) (ctx->baton, result);
685b725ae77Skettenis 	  break;
686b725ae77Skettenis 
687b725ae77Skettenis 	case DW_OP_skip:
688b725ae77Skettenis 	  offset = extract_signed_integer (op_ptr, 2);
689b725ae77Skettenis 	  op_ptr += 2;
690b725ae77Skettenis 	  op_ptr += offset;
691b725ae77Skettenis 	  goto no_push;
692b725ae77Skettenis 
693b725ae77Skettenis 	case DW_OP_bra:
694b725ae77Skettenis 	  offset = extract_signed_integer (op_ptr, 2);
695b725ae77Skettenis 	  op_ptr += 2;
696b725ae77Skettenis 	  if (dwarf_expr_fetch (ctx, 0) != 0)
697b725ae77Skettenis 	    op_ptr += offset;
698b725ae77Skettenis 	  dwarf_expr_pop (ctx);
699b725ae77Skettenis 	  goto no_push;
700b725ae77Skettenis 
701b725ae77Skettenis 	case DW_OP_nop:
702b725ae77Skettenis 	  goto no_push;
703b725ae77Skettenis 
70411efff7fSkettenis         case DW_OP_piece:
70511efff7fSkettenis           {
70611efff7fSkettenis             ULONGEST size;
70711efff7fSkettenis             CORE_ADDR addr_or_regnum;
70811efff7fSkettenis 
70911efff7fSkettenis             /* Record the piece.  */
71011efff7fSkettenis             op_ptr = read_uleb128 (op_ptr, op_end, &size);
71111efff7fSkettenis             addr_or_regnum = dwarf_expr_fetch (ctx, 0);
71211efff7fSkettenis             add_piece (ctx, ctx->in_reg, addr_or_regnum, size);
71311efff7fSkettenis 
71411efff7fSkettenis             /* Pop off the address/regnum, and clear the in_reg flag.  */
71511efff7fSkettenis             dwarf_expr_pop (ctx);
71611efff7fSkettenis             ctx->in_reg = 0;
71711efff7fSkettenis           }
71811efff7fSkettenis           goto no_push;
71911efff7fSkettenis 
720b725ae77Skettenis 	default:
721b725ae77Skettenis 	  error ("Unhandled dwarf expression opcode 0x%x", op);
722b725ae77Skettenis 	}
723b725ae77Skettenis 
724b725ae77Skettenis       /* Most things push a result value.  */
725b725ae77Skettenis       dwarf_expr_push (ctx, result);
726b725ae77Skettenis     no_push:;
727b725ae77Skettenis     }
728b725ae77Skettenis }
729