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, ®);
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, ®);
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, ®);
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