1 /* DWARF 2 location expression support for GDB.
3 Copyright (C) 2003, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
5 Contributed by Daniel Jacobowitz, MontaVista Software, Inc.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
33 #include "exceptions.h"
37 #include "dwarf2expr.h"
38 #include "dwarf2loc.h"
39 #include "dwarf2-frame.h"
41 #include "gdb_string.h"
42 #include "gdb_assert.h"
44 /* A helper function for dealing with location lists. Given a
45 symbol baton (BATON) and a pc value (PC), find the appropriate
46 location expression, set *LOCEXPR_LENGTH, and return a pointer
47 to the beginning of the expression. Returns NULL on failure.
49 For now, only return the first matching location expression; there
50 can be more than one in the list. */
53 find_location_expression (struct dwarf2_loclist_baton *baton,
54 size_t *locexpr_length, CORE_ADDR pc)
57 gdb_byte *loc_ptr, *buf_end;
59 struct objfile *objfile = dwarf2_per_cu_objfile (baton->per_cu);
60 struct gdbarch *gdbarch = get_objfile_arch (objfile);
61 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
62 unsigned int addr_size = dwarf2_per_cu_addr_size (baton->per_cu);
63 CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
64 /* Adjust base_address for relocatable objects. */
65 CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
66 SECT_OFF_TEXT (objfile));
67 CORE_ADDR base_address = baton->base_address + base_offset;
69 loc_ptr = baton->data;
70 buf_end = baton->data + baton->size;
74 if (buf_end - loc_ptr < 2 * addr_size)
75 error (_("find_location_expression: Corrupted DWARF expression."));
77 low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
80 /* A base-address-selection entry. */
83 base_address = dwarf2_read_address (gdbarch,
84 loc_ptr, buf_end, addr_size);
89 high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
92 /* An end-of-list entry. */
93 if (low == 0 && high == 0)
96 /* Otherwise, a location expression entry. */
100 length = extract_unsigned_integer (loc_ptr, 2, byte_order);
103 if (pc >= low && pc < high)
105 *locexpr_length = length;
113 /* This is the baton used when performing dwarf2 expression
115 struct dwarf_expr_baton
117 struct frame_info *frame;
118 struct objfile *objfile;
121 /* Helper functions for dwarf2_evaluate_loc_desc. */
123 /* Using the frame specified in BATON, return the value of register
124 REGNUM, treated as a pointer. */
126 dwarf_expr_read_reg (void *baton, int dwarf_regnum)
128 struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
129 struct gdbarch *gdbarch = get_frame_arch (debaton->frame);
133 regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum);
134 result = address_from_register (builtin_type (gdbarch)->builtin_data_ptr,
135 regnum, debaton->frame);
139 /* Read memory at ADDR (length LEN) into BUF. */
142 dwarf_expr_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr, size_t len)
144 read_memory (addr, buf, len);
147 /* Using the frame specified in BATON, find the location expression
148 describing the frame base. Return a pointer to it in START and
149 its length in LENGTH. */
151 dwarf_expr_frame_base (void *baton, gdb_byte **start, size_t * length)
153 /* FIXME: cagney/2003-03-26: This code should be using
154 get_frame_base_address(), and then implement a dwarf2 specific
156 struct symbol *framefunc;
157 struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
159 /* Use block_linkage_function, which returns a real (not inlined)
160 function, instead of get_frame_function, which may return an
162 framefunc = block_linkage_function (get_frame_block (debaton->frame, NULL));
164 /* If we found a frame-relative symbol then it was certainly within
165 some function associated with a frame. If we can't find the frame,
166 something has gone wrong. */
167 gdb_assert (framefunc != NULL);
169 if (SYMBOL_LOCATION_BATON (framefunc) == NULL)
171 else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs)
173 struct dwarf2_loclist_baton *symbaton;
174 struct frame_info *frame = debaton->frame;
176 symbaton = SYMBOL_LOCATION_BATON (framefunc);
177 *start = find_location_expression (symbaton, length,
178 get_frame_address_in_block (frame));
182 struct dwarf2_locexpr_baton *symbaton;
183 symbaton = SYMBOL_LOCATION_BATON (framefunc);
184 if (symbaton != NULL)
186 *length = symbaton->size;
187 *start = symbaton->data;
194 error (_("Could not find the frame base for \"%s\"."),
195 SYMBOL_NATURAL_NAME (framefunc));
198 /* Helper function for dwarf2_evaluate_loc_desc. Computes the CFA for
199 the frame in BATON. */
202 dwarf_expr_frame_cfa (void *baton)
204 struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
205 return dwarf2_frame_cfa (debaton->frame);
208 /* Using the objfile specified in BATON, find the address for the
209 current thread's thread-local storage with offset OFFSET. */
211 dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
213 struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
215 return target_translate_tls_address (debaton->objfile, offset);
220 /* The number of pieces used to describe this variable. */
223 /* The architecture, used only for DWARF_VALUE_STACK. */
224 struct gdbarch *arch;
226 /* The pieces themselves. */
227 struct dwarf_expr_piece *pieces;
230 /* Allocate a closure for a value formed from separately-described
233 static struct piece_closure *
234 allocate_piece_closure (int n_pieces, struct dwarf_expr_piece *pieces,
235 struct gdbarch *arch)
237 struct piece_closure *c = XZALLOC (struct piece_closure);
239 c->n_pieces = n_pieces;
241 c->pieces = XCALLOC (n_pieces, struct dwarf_expr_piece);
243 memcpy (c->pieces, pieces, n_pieces * sizeof (struct dwarf_expr_piece));
249 read_pieced_value (struct value *v)
254 struct piece_closure *c = (struct piece_closure *) value_computed_closure (v);
255 struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (v));
257 contents = value_contents_raw (v);
258 for (i = 0; i < c->n_pieces; i++)
260 struct dwarf_expr_piece *p = &c->pieces[i];
263 case DWARF_VALUE_REGISTER:
265 struct gdbarch *arch = get_frame_arch (frame);
266 bfd_byte regval[MAX_REGISTER_SIZE];
267 int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch,
269 get_frame_register (frame, gdb_regnum, regval);
270 memcpy (contents + offset, regval, p->size);
274 case DWARF_VALUE_MEMORY:
275 if (p->v.expr.in_stack_memory)
276 read_stack (p->v.expr.value, contents + offset, p->size);
278 read_memory (p->v.expr.value, contents + offset, p->size);
281 case DWARF_VALUE_STACK:
283 gdb_byte bytes[sizeof (ULONGEST)];
285 int addr_size = gdbarch_addr_bit (c->arch) / 8;
286 store_unsigned_integer (bytes, addr_size,
287 gdbarch_byte_order (c->arch),
292 memcpy (contents + offset, bytes, n);
296 case DWARF_VALUE_LITERAL:
299 if (n > p->v.literal.length)
300 n = p->v.literal.length;
301 memcpy (contents + offset, p->v.literal.data, n);
306 internal_error (__FILE__, __LINE__, _("invalid location type"));
313 write_pieced_value (struct value *to, struct value *from)
318 struct piece_closure *c = (struct piece_closure *) value_computed_closure (to);
319 struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (to));
323 set_value_optimized_out (to, 1);
327 contents = value_contents_raw (from);
328 for (i = 0; i < c->n_pieces; i++)
330 struct dwarf_expr_piece *p = &c->pieces[i];
333 case DWARF_VALUE_REGISTER:
335 struct gdbarch *arch = get_frame_arch (frame);
336 int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.expr.value);
337 put_frame_register (frame, gdb_regnum, contents + offset);
340 case DWARF_VALUE_MEMORY:
341 write_memory (p->v.expr.value, contents + offset, p->size);
344 set_value_optimized_out (to, 1);
352 copy_pieced_value_closure (struct value *v)
354 struct piece_closure *c = (struct piece_closure *) value_computed_closure (v);
356 return allocate_piece_closure (c->n_pieces, c->pieces, c->arch);
360 free_pieced_value_closure (struct value *v)
362 struct piece_closure *c = (struct piece_closure *) value_computed_closure (v);
368 /* Functions for accessing a variable described by DW_OP_piece. */
369 static struct lval_funcs pieced_value_funcs = {
372 copy_pieced_value_closure,
373 free_pieced_value_closure
376 /* Evaluate a location description, starting at DATA and with length
377 SIZE, to find the current location of variable VAR in the context
379 static struct value *
380 dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
381 gdb_byte *data, unsigned short size,
382 struct dwarf2_per_cu_data *per_cu)
384 struct value *retval;
385 struct dwarf_expr_baton baton;
386 struct dwarf_expr_context *ctx;
387 struct cleanup *old_chain;
391 retval = allocate_value (SYMBOL_TYPE (var));
392 VALUE_LVAL (retval) = not_lval;
393 set_value_optimized_out (retval, 1);
398 baton.objfile = dwarf2_per_cu_objfile (per_cu);
400 ctx = new_dwarf_expr_context ();
401 old_chain = make_cleanup_free_dwarf_expr_context (ctx);
403 ctx->gdbarch = get_objfile_arch (baton.objfile);
404 ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
406 ctx->read_reg = dwarf_expr_read_reg;
407 ctx->read_mem = dwarf_expr_read_mem;
408 ctx->get_frame_base = dwarf_expr_frame_base;
409 ctx->get_frame_cfa = dwarf_expr_frame_cfa;
410 ctx->get_tls_address = dwarf_expr_tls_address;
412 dwarf_expr_eval (ctx, data, size);
413 if (ctx->num_pieces > 0)
415 struct piece_closure *c;
416 struct frame_id frame_id = get_frame_id (frame);
418 c = allocate_piece_closure (ctx->num_pieces, ctx->pieces, ctx->gdbarch);
419 retval = allocate_computed_value (SYMBOL_TYPE (var),
422 VALUE_FRAME_ID (retval) = frame_id;
426 switch (ctx->location)
428 case DWARF_VALUE_REGISTER:
430 struct gdbarch *arch = get_frame_arch (frame);
431 CORE_ADDR dwarf_regnum = dwarf_expr_fetch (ctx, 0);
432 int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
433 retval = value_from_register (SYMBOL_TYPE (var), gdb_regnum, frame);
437 case DWARF_VALUE_MEMORY:
439 CORE_ADDR address = dwarf_expr_fetch (ctx, 0);
440 int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
442 retval = allocate_value (SYMBOL_TYPE (var));
443 VALUE_LVAL (retval) = lval_memory;
444 set_value_lazy (retval, 1);
446 set_value_stack (retval, 1);
447 set_value_address (retval, address);
451 case DWARF_VALUE_STACK:
453 gdb_byte bytes[sizeof (ULONGEST)];
454 ULONGEST value = (ULONGEST) dwarf_expr_fetch (ctx, 0);
456 size_t n = ctx->addr_size;
458 store_unsigned_integer (bytes, ctx->addr_size,
459 gdbarch_byte_order (ctx->gdbarch),
461 retval = allocate_value (SYMBOL_TYPE (var));
462 contents = value_contents_raw (retval);
463 if (n > TYPE_LENGTH (SYMBOL_TYPE (var)))
464 n = TYPE_LENGTH (SYMBOL_TYPE (var));
465 memcpy (contents, bytes, n);
469 case DWARF_VALUE_LITERAL:
474 retval = allocate_value (SYMBOL_TYPE (var));
475 contents = value_contents_raw (retval);
476 if (n > TYPE_LENGTH (SYMBOL_TYPE (var)))
477 n = TYPE_LENGTH (SYMBOL_TYPE (var));
478 memcpy (contents, ctx->data, n);
483 internal_error (__FILE__, __LINE__, _("invalid location type"));
487 set_value_initialized (retval, ctx->initialized);
489 do_cleanups (old_chain);
494 /* Helper functions and baton for dwarf2_loc_desc_needs_frame. */
496 struct needs_frame_baton
501 /* Reads from registers do require a frame. */
503 needs_frame_read_reg (void *baton, int regnum)
505 struct needs_frame_baton *nf_baton = baton;
506 nf_baton->needs_frame = 1;
510 /* Reads from memory do not require a frame. */
512 needs_frame_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr, size_t len)
514 memset (buf, 0, len);
517 /* Frame-relative accesses do require a frame. */
519 needs_frame_frame_base (void *baton, gdb_byte **start, size_t * length)
521 static gdb_byte lit0 = DW_OP_lit0;
522 struct needs_frame_baton *nf_baton = baton;
527 nf_baton->needs_frame = 1;
530 /* CFA accesses require a frame. */
533 needs_frame_frame_cfa (void *baton)
535 struct needs_frame_baton *nf_baton = baton;
536 nf_baton->needs_frame = 1;
540 /* Thread-local accesses do require a frame. */
542 needs_frame_tls_address (void *baton, CORE_ADDR offset)
544 struct needs_frame_baton *nf_baton = baton;
545 nf_baton->needs_frame = 1;
549 /* Return non-zero iff the location expression at DATA (length SIZE)
550 requires a frame to evaluate. */
553 dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size,
554 struct dwarf2_per_cu_data *per_cu)
556 struct needs_frame_baton baton;
557 struct dwarf_expr_context *ctx;
559 struct cleanup *old_chain;
561 baton.needs_frame = 0;
563 ctx = new_dwarf_expr_context ();
564 old_chain = make_cleanup_free_dwarf_expr_context (ctx);
566 ctx->gdbarch = get_objfile_arch (dwarf2_per_cu_objfile (per_cu));
567 ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
569 ctx->read_reg = needs_frame_read_reg;
570 ctx->read_mem = needs_frame_read_mem;
571 ctx->get_frame_base = needs_frame_frame_base;
572 ctx->get_frame_cfa = needs_frame_frame_cfa;
573 ctx->get_tls_address = needs_frame_tls_address;
575 dwarf_expr_eval (ctx, data, size);
577 in_reg = ctx->location == DWARF_VALUE_REGISTER;
579 if (ctx->num_pieces > 0)
583 /* If the location has several pieces, and any of them are in
584 registers, then we will need a frame to fetch them from. */
585 for (i = 0; i < ctx->num_pieces; i++)
586 if (ctx->pieces[i].location == DWARF_VALUE_REGISTER)
590 do_cleanups (old_chain);
592 return baton.needs_frame || in_reg;
596 dwarf2_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
597 struct agent_expr *ax, struct axs_value *value,
598 gdb_byte *data, int size)
601 error (_("Symbol \"%s\" has been optimized out."),
602 SYMBOL_PRINT_NAME (symbol));
605 && data[0] >= DW_OP_reg0
606 && data[0] <= DW_OP_reg31)
608 value->kind = axs_lvalue_register;
609 value->u.reg = data[0] - DW_OP_reg0;
611 else if (data[0] == DW_OP_regx)
614 read_uleb128 (data + 1, data + size, ®);
615 value->kind = axs_lvalue_register;
618 else if (data[0] == DW_OP_fbreg)
620 /* And this is worse than just minimal; we should honor the frame base
623 LONGEST frame_offset;
626 buf_end = read_sleb128 (data + 1, data + size, &frame_offset);
627 if (buf_end != data + size)
628 error (_("Unexpected opcode after DW_OP_fbreg for symbol \"%s\"."),
629 SYMBOL_PRINT_NAME (symbol));
631 gdbarch_virtual_frame_pointer (gdbarch,
632 ax->scope, &frame_reg, &frame_offset);
633 ax_reg (ax, frame_reg);
634 ax_const_l (ax, frame_offset);
635 ax_simple (ax, aop_add);
637 value->kind = axs_lvalue_memory;
639 else if (data[0] >= DW_OP_breg0
640 && data[0] <= DW_OP_breg31)
646 reg = data[0] - DW_OP_breg0;
647 buf_end = read_sleb128 (data + 1, data + size, &offset);
648 if (buf_end != data + size)
649 error (_("Unexpected opcode after DW_OP_breg%u for symbol \"%s\"."),
650 reg, SYMBOL_PRINT_NAME (symbol));
653 ax_const_l (ax, offset);
654 ax_simple (ax, aop_add);
656 value->kind = axs_lvalue_memory;
659 error (_("Unsupported DWARF opcode 0x%x in the location of \"%s\"."),
660 data[0], SYMBOL_PRINT_NAME (symbol));
663 /* Return the value of SYMBOL in FRAME using the DWARF-2 expression
664 evaluator to calculate the location. */
665 static struct value *
666 locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
668 struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
670 val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size,
676 /* Return non-zero iff we need a frame to evaluate SYMBOL. */
678 locexpr_read_needs_frame (struct symbol *symbol)
680 struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
681 return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size,
685 /* Print a natural-language description of SYMBOL to STREAM. */
687 locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
689 /* FIXME: be more extensive. */
690 struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
691 int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
693 if (dlbaton->size == 1
694 && dlbaton->data[0] >= DW_OP_reg0
695 && dlbaton->data[0] <= DW_OP_reg31)
697 struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
698 struct gdbarch *gdbarch = get_objfile_arch (objfile);
699 int regno = gdbarch_dwarf2_reg_to_regnum (gdbarch,
700 dlbaton->data[0] - DW_OP_reg0);
701 fprintf_filtered (stream,
702 "a variable in register %s",
703 gdbarch_register_name (gdbarch, regno));
707 /* The location expression for a TLS variable looks like this (on a
710 DW_AT_location : 10 byte block: 3 4 0 0 0 0 0 0 0 e0
711 (DW_OP_addr: 4; DW_OP_GNU_push_tls_address)
713 0x3 is the encoding for DW_OP_addr, which has an operand as long
714 as the size of an address on the target machine (here is 8
715 bytes). 0xe0 is the encoding for DW_OP_GNU_push_tls_address.
716 The operand represents the offset at which the variable is within
717 the thread local storage. */
719 if (dlbaton->size > 1
720 && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address)
721 if (dlbaton->data[0] == DW_OP_addr)
723 struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
724 struct gdbarch *gdbarch = get_objfile_arch (objfile);
725 CORE_ADDR offset = dwarf2_read_address (gdbarch,
727 &dlbaton->data[dlbaton->size - 1],
729 fprintf_filtered (stream,
730 "a thread-local variable at offset %s in the "
731 "thread-local storage for `%s'",
732 paddress (gdbarch, offset), objfile->name);
737 fprintf_filtered (stream,
738 "a variable with complex or multiple locations (DWARF2)");
743 /* Describe the location of SYMBOL as an agent value in VALUE, generating
744 any necessary bytecode in AX.
746 NOTE drow/2003-02-26: This function is extremely minimal, because
747 doing it correctly is extremely complicated and there is no
748 publicly available stub with tracepoint support for me to test
749 against. When there is one this function should be revisited. */
752 locexpr_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
753 struct agent_expr *ax, struct axs_value *value)
755 struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
757 dwarf2_tracepoint_var_ref (symbol, gdbarch, ax, value,
758 dlbaton->data, dlbaton->size);
761 /* The set of location functions used with the DWARF-2 expression
763 const struct symbol_computed_ops dwarf2_locexpr_funcs = {
764 locexpr_read_variable,
765 locexpr_read_needs_frame,
766 locexpr_describe_location,
767 locexpr_tracepoint_var_ref
771 /* Wrapper functions for location lists. These generally find
772 the appropriate location expression and call something above. */
774 /* Return the value of SYMBOL in FRAME using the DWARF-2 expression
775 evaluator to calculate the location. */
776 static struct value *
777 loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
779 struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
784 data = find_location_expression (dlbaton, &size,
785 frame ? get_frame_address_in_block (frame)
789 val = allocate_value (SYMBOL_TYPE (symbol));
790 VALUE_LVAL (val) = not_lval;
791 set_value_optimized_out (val, 1);
794 val = dwarf2_evaluate_loc_desc (symbol, frame, data, size,
800 /* Return non-zero iff we need a frame to evaluate SYMBOL. */
802 loclist_read_needs_frame (struct symbol *symbol)
804 /* If there's a location list, then assume we need to have a frame
805 to choose the appropriate location expression. With tracking of
806 global variables this is not necessarily true, but such tracking
807 is disabled in GCC at the moment until we figure out how to
813 /* Print a natural-language description of SYMBOL to STREAM. */
815 loclist_describe_location (struct symbol *symbol, struct ui_file *stream)
817 /* FIXME: Could print the entire list of locations. */
818 fprintf_filtered (stream, "a variable with multiple locations");
822 /* Describe the location of SYMBOL as an agent value in VALUE, generating
823 any necessary bytecode in AX. */
825 loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
826 struct agent_expr *ax, struct axs_value *value)
828 struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
832 data = find_location_expression (dlbaton, &size, ax->scope);
834 error (_("Variable \"%s\" is not available."), SYMBOL_NATURAL_NAME (symbol));
836 dwarf2_tracepoint_var_ref (symbol, gdbarch, ax, value, data, size);
839 /* The set of location functions used with the DWARF-2 expression
840 evaluator and location lists. */
841 const struct symbol_computed_ops dwarf2_loclist_funcs = {
842 loclist_read_variable,
843 loclist_read_needs_frame,
844 loclist_describe_location,
845 loclist_tracepoint_var_ref