1130803Smarcel/* DWARF 2 location expression support for GDB. 2130803Smarcel Copyright 2003 Free Software Foundation, Inc. 3130803Smarcel Contributed by Daniel Jacobowitz, MontaVista Software, Inc. 4130803Smarcel 5130803Smarcel This file is part of GDB. 6130803Smarcel 7130803Smarcel This program is free software; you can redistribute it and/or modify 8130803Smarcel it under the terms of the GNU General Public License as published by 9130803Smarcel the Free Software Foundation; either version 2 of the License, or (at 10130803Smarcel your option) any later version. 11130803Smarcel 12130803Smarcel This program is distributed in the hope that it will be useful, but 13130803Smarcel WITHOUT ANY WARRANTY; without even the implied warranty of 14130803Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15130803Smarcel General Public License for more details. 16130803Smarcel 17130803Smarcel You should have received a copy of the GNU General Public License 18130803Smarcel along with this program; if not, write to the Free Software 19130803Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 20130803Smarcel Boston, MA 02111-1307, USA. */ 21130803Smarcel 22130803Smarcel#include "defs.h" 23130803Smarcel#include "ui-out.h" 24130803Smarcel#include "value.h" 25130803Smarcel#include "frame.h" 26130803Smarcel#include "gdbcore.h" 27130803Smarcel#include "target.h" 28130803Smarcel#include "inferior.h" 29130803Smarcel#include "ax.h" 30130803Smarcel#include "ax-gdb.h" 31130803Smarcel#include "regcache.h" 32130803Smarcel#include "objfiles.h" 33130803Smarcel 34130803Smarcel#include "elf/dwarf2.h" 35130803Smarcel#include "dwarf2expr.h" 36130803Smarcel#include "dwarf2loc.h" 37130803Smarcel 38130803Smarcel#include "gdb_string.h" 39130803Smarcel 40130803Smarcel#ifndef DWARF2_REG_TO_REGNUM 41130803Smarcel#define DWARF2_REG_TO_REGNUM(REG) (REG) 42130803Smarcel#endif 43130803Smarcel 44130803Smarcel/* A helper function for dealing with location lists. Given a 45130803Smarcel symbol baton (BATON) and a pc value (PC), find the appropriate 46130803Smarcel location expression, set *LOCEXPR_LENGTH, and return a pointer 47130803Smarcel to the beginning of the expression. Returns NULL on failure. 48130803Smarcel 49130803Smarcel For now, only return the first matching location expression; there 50130803Smarcel can be more than one in the list. */ 51130803Smarcel 52130803Smarcelstatic char * 53130803Smarcelfind_location_expression (struct dwarf2_loclist_baton *baton, 54130803Smarcel size_t *locexpr_length, CORE_ADDR pc) 55130803Smarcel{ 56130803Smarcel CORE_ADDR low, high; 57130803Smarcel char *loc_ptr, *buf_end; 58130803Smarcel unsigned int addr_size = TARGET_ADDR_BIT / TARGET_CHAR_BIT, length; 59130803Smarcel CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); 60130803Smarcel /* Adjust base_address for relocatable objects. */ 61130803Smarcel CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets, 62130803Smarcel SECT_OFF_TEXT (baton->objfile)); 63130803Smarcel CORE_ADDR base_address = baton->base_address + base_offset; 64130803Smarcel 65130803Smarcel loc_ptr = baton->data; 66130803Smarcel buf_end = baton->data + baton->size; 67130803Smarcel 68130803Smarcel while (1) 69130803Smarcel { 70130803Smarcel low = dwarf2_read_address (loc_ptr, buf_end, &length); 71130803Smarcel loc_ptr += length; 72130803Smarcel high = dwarf2_read_address (loc_ptr, buf_end, &length); 73130803Smarcel loc_ptr += length; 74130803Smarcel 75130803Smarcel /* An end-of-list entry. */ 76130803Smarcel if (low == 0 && high == 0) 77130803Smarcel return NULL; 78130803Smarcel 79130803Smarcel /* A base-address-selection entry. */ 80130803Smarcel if ((low & base_mask) == base_mask) 81130803Smarcel { 82130803Smarcel base_address = high; 83130803Smarcel continue; 84130803Smarcel } 85130803Smarcel 86130803Smarcel /* Otherwise, a location expression entry. */ 87130803Smarcel low += base_address; 88130803Smarcel high += base_address; 89130803Smarcel 90130803Smarcel length = extract_unsigned_integer (loc_ptr, 2); 91130803Smarcel loc_ptr += 2; 92130803Smarcel 93130803Smarcel if (pc >= low && pc < high) 94130803Smarcel { 95130803Smarcel *locexpr_length = length; 96130803Smarcel return loc_ptr; 97130803Smarcel } 98130803Smarcel 99130803Smarcel loc_ptr += length; 100130803Smarcel } 101130803Smarcel} 102130803Smarcel 103130803Smarcel/* This is the baton used when performing dwarf2 expression 104130803Smarcel evaluation. */ 105130803Smarcelstruct dwarf_expr_baton 106130803Smarcel{ 107130803Smarcel struct frame_info *frame; 108130803Smarcel struct objfile *objfile; 109130803Smarcel}; 110130803Smarcel 111130803Smarcel/* Helper functions for dwarf2_evaluate_loc_desc. */ 112130803Smarcel 113130803Smarcel/* Using the frame specified in BATON, read register REGNUM. The lval 114130803Smarcel type will be returned in LVALP, and for lval_memory the register 115130803Smarcel save address will be returned in ADDRP. */ 116130803Smarcelstatic CORE_ADDR 117130803Smarceldwarf_expr_read_reg (void *baton, int dwarf_regnum) 118130803Smarcel{ 119130803Smarcel struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton; 120130803Smarcel CORE_ADDR result, save_addr; 121130803Smarcel enum lval_type lval_type; 122130803Smarcel char *buf; 123130803Smarcel int optimized, regnum, realnum, regsize; 124130803Smarcel 125130803Smarcel regnum = DWARF2_REG_TO_REGNUM (dwarf_regnum); 126130803Smarcel regsize = register_size (current_gdbarch, regnum); 127130803Smarcel buf = (char *) alloca (regsize); 128130803Smarcel 129130803Smarcel frame_register (debaton->frame, regnum, &optimized, &lval_type, &save_addr, 130130803Smarcel &realnum, buf); 131130803Smarcel /* NOTE: cagney/2003-05-22: This extract is assuming that a DWARF 2 132130803Smarcel address is always unsigned. That may or may not be true. */ 133130803Smarcel result = extract_unsigned_integer (buf, regsize); 134130803Smarcel 135130803Smarcel return result; 136130803Smarcel} 137130803Smarcel 138130803Smarcel/* Read memory at ADDR (length LEN) into BUF. */ 139130803Smarcel 140130803Smarcelstatic void 141130803Smarceldwarf_expr_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len) 142130803Smarcel{ 143130803Smarcel read_memory (addr, buf, len); 144130803Smarcel} 145130803Smarcel 146130803Smarcel/* Using the frame specified in BATON, find the location expression 147130803Smarcel describing the frame base. Return a pointer to it in START and 148130803Smarcel its length in LENGTH. */ 149130803Smarcelstatic void 150130803Smarceldwarf_expr_frame_base (void *baton, unsigned char **start, size_t * length) 151130803Smarcel{ 152130803Smarcel /* FIXME: cagney/2003-03-26: This code should be using 153130803Smarcel get_frame_base_address(), and then implement a dwarf2 specific 154130803Smarcel this_base method. */ 155130803Smarcel struct symbol *framefunc; 156130803Smarcel struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton; 157130803Smarcel 158130803Smarcel framefunc = get_frame_function (debaton->frame); 159130803Smarcel 160130803Smarcel if (SYMBOL_OPS (framefunc) == &dwarf2_loclist_funcs) 161130803Smarcel { 162130803Smarcel struct dwarf2_loclist_baton *symbaton; 163130803Smarcel symbaton = SYMBOL_LOCATION_BATON (framefunc); 164130803Smarcel *start = find_location_expression (symbaton, length, 165130803Smarcel get_frame_pc (debaton->frame)); 166130803Smarcel } 167130803Smarcel else 168130803Smarcel { 169130803Smarcel struct dwarf2_locexpr_baton *symbaton; 170130803Smarcel symbaton = SYMBOL_LOCATION_BATON (framefunc); 171130803Smarcel *length = symbaton->size; 172130803Smarcel *start = symbaton->data; 173130803Smarcel } 174130803Smarcel 175130803Smarcel if (*start == NULL) 176130803Smarcel error ("Could not find the frame base for \"%s\".", 177130803Smarcel SYMBOL_NATURAL_NAME (framefunc)); 178130803Smarcel} 179130803Smarcel 180130803Smarcel/* Using the objfile specified in BATON, find the address for the 181130803Smarcel current thread's thread-local storage with offset OFFSET. */ 182130803Smarcelstatic CORE_ADDR 183130803Smarceldwarf_expr_tls_address (void *baton, CORE_ADDR offset) 184130803Smarcel{ 185130803Smarcel struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton; 186130803Smarcel CORE_ADDR addr; 187130803Smarcel 188130803Smarcel if (target_get_thread_local_address_p ()) 189130803Smarcel addr = target_get_thread_local_address (inferior_ptid, 190130803Smarcel debaton->objfile, 191130803Smarcel offset); 192130803Smarcel /* It wouldn't be wrong here to try a gdbarch method, too; finding 193130803Smarcel TLS is an ABI-specific thing. But we don't do that yet. */ 194130803Smarcel else 195130803Smarcel error ("Cannot find thread-local variables on this target"); 196130803Smarcel 197130803Smarcel return addr; 198130803Smarcel} 199130803Smarcel 200130803Smarcel/* Evaluate a location description, starting at DATA and with length 201130803Smarcel SIZE, to find the current location of variable VAR in the context 202130803Smarcel of FRAME. */ 203130803Smarcelstatic struct value * 204130803Smarceldwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, 205130803Smarcel unsigned char *data, unsigned short size, 206130803Smarcel struct objfile *objfile) 207130803Smarcel{ 208130803Smarcel CORE_ADDR result; 209130803Smarcel struct value *retval; 210130803Smarcel struct dwarf_expr_baton baton; 211130803Smarcel struct dwarf_expr_context *ctx; 212130803Smarcel 213130803Smarcel if (size == 0) 214130803Smarcel { 215130803Smarcel retval = allocate_value (SYMBOL_TYPE (var)); 216130803Smarcel VALUE_LVAL (retval) = not_lval; 217130803Smarcel VALUE_OPTIMIZED_OUT (retval) = 1; 218130803Smarcel } 219130803Smarcel 220130803Smarcel baton.frame = frame; 221130803Smarcel baton.objfile = objfile; 222130803Smarcel 223130803Smarcel ctx = new_dwarf_expr_context (); 224130803Smarcel ctx->baton = &baton; 225130803Smarcel ctx->read_reg = dwarf_expr_read_reg; 226130803Smarcel ctx->read_mem = dwarf_expr_read_mem; 227130803Smarcel ctx->get_frame_base = dwarf_expr_frame_base; 228130803Smarcel ctx->get_tls_address = dwarf_expr_tls_address; 229130803Smarcel 230130803Smarcel dwarf_expr_eval (ctx, data, size); 231130803Smarcel result = dwarf_expr_fetch (ctx, 0); 232130803Smarcel 233130803Smarcel if (ctx->in_reg) 234130803Smarcel { 235130803Smarcel int regnum = DWARF2_REG_TO_REGNUM (result); 236130803Smarcel retval = value_from_register (SYMBOL_TYPE (var), regnum, frame); 237130803Smarcel } 238130803Smarcel else 239130803Smarcel { 240130803Smarcel retval = allocate_value (SYMBOL_TYPE (var)); 241130803Smarcel VALUE_BFD_SECTION (retval) = SYMBOL_BFD_SECTION (var); 242130803Smarcel 243130803Smarcel VALUE_LVAL (retval) = lval_memory; 244130803Smarcel VALUE_LAZY (retval) = 1; 245130803Smarcel VALUE_ADDRESS (retval) = result; 246130803Smarcel } 247130803Smarcel 248130803Smarcel free_dwarf_expr_context (ctx); 249130803Smarcel 250130803Smarcel return retval; 251130803Smarcel} 252130803Smarcel 253130803Smarcel 254130803Smarcel 255130803Smarcel 256130803Smarcel 257130803Smarcel/* Helper functions and baton for dwarf2_loc_desc_needs_frame. */ 258130803Smarcel 259130803Smarcelstruct needs_frame_baton 260130803Smarcel{ 261130803Smarcel int needs_frame; 262130803Smarcel}; 263130803Smarcel 264130803Smarcel/* Reads from registers do require a frame. */ 265130803Smarcelstatic CORE_ADDR 266130803Smarcelneeds_frame_read_reg (void *baton, int regnum) 267130803Smarcel{ 268130803Smarcel struct needs_frame_baton *nf_baton = baton; 269130803Smarcel nf_baton->needs_frame = 1; 270130803Smarcel return 1; 271130803Smarcel} 272130803Smarcel 273130803Smarcel/* Reads from memory do not require a frame. */ 274130803Smarcelstatic void 275130803Smarcelneeds_frame_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len) 276130803Smarcel{ 277130803Smarcel memset (buf, 0, len); 278130803Smarcel} 279130803Smarcel 280130803Smarcel/* Frame-relative accesses do require a frame. */ 281130803Smarcelstatic void 282130803Smarcelneeds_frame_frame_base (void *baton, unsigned char **start, size_t * length) 283130803Smarcel{ 284130803Smarcel static char lit0 = DW_OP_lit0; 285130803Smarcel struct needs_frame_baton *nf_baton = baton; 286130803Smarcel 287130803Smarcel *start = &lit0; 288130803Smarcel *length = 1; 289130803Smarcel 290130803Smarcel nf_baton->needs_frame = 1; 291130803Smarcel} 292130803Smarcel 293130803Smarcel/* Thread-local accesses do require a frame. */ 294130803Smarcelstatic CORE_ADDR 295130803Smarcelneeds_frame_tls_address (void *baton, CORE_ADDR offset) 296130803Smarcel{ 297130803Smarcel struct needs_frame_baton *nf_baton = baton; 298130803Smarcel nf_baton->needs_frame = 1; 299130803Smarcel return 1; 300130803Smarcel} 301130803Smarcel 302130803Smarcel/* Return non-zero iff the location expression at DATA (length SIZE) 303130803Smarcel requires a frame to evaluate. */ 304130803Smarcel 305130803Smarcelstatic int 306130803Smarceldwarf2_loc_desc_needs_frame (unsigned char *data, unsigned short size) 307130803Smarcel{ 308130803Smarcel struct needs_frame_baton baton; 309130803Smarcel struct dwarf_expr_context *ctx; 310130803Smarcel int in_reg; 311130803Smarcel 312130803Smarcel baton.needs_frame = 0; 313130803Smarcel 314130803Smarcel ctx = new_dwarf_expr_context (); 315130803Smarcel ctx->baton = &baton; 316130803Smarcel ctx->read_reg = needs_frame_read_reg; 317130803Smarcel ctx->read_mem = needs_frame_read_mem; 318130803Smarcel ctx->get_frame_base = needs_frame_frame_base; 319130803Smarcel ctx->get_tls_address = needs_frame_tls_address; 320130803Smarcel 321130803Smarcel dwarf_expr_eval (ctx, data, size); 322130803Smarcel 323130803Smarcel in_reg = ctx->in_reg; 324130803Smarcel 325130803Smarcel free_dwarf_expr_context (ctx); 326130803Smarcel 327130803Smarcel return baton.needs_frame || in_reg; 328130803Smarcel} 329130803Smarcel 330130803Smarcelstatic void 331130803Smarceldwarf2_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax, 332130803Smarcel struct axs_value * value, unsigned char *data, 333130803Smarcel int size) 334130803Smarcel{ 335130803Smarcel if (size == 0) 336130803Smarcel error ("Symbol \"%s\" has been optimized out.", 337130803Smarcel SYMBOL_PRINT_NAME (symbol)); 338130803Smarcel 339130803Smarcel if (size == 1 340130803Smarcel && data[0] >= DW_OP_reg0 341130803Smarcel && data[0] <= DW_OP_reg31) 342130803Smarcel { 343130803Smarcel value->kind = axs_lvalue_register; 344130803Smarcel value->u.reg = data[0] - DW_OP_reg0; 345130803Smarcel } 346130803Smarcel else if (data[0] == DW_OP_regx) 347130803Smarcel { 348130803Smarcel ULONGEST reg; 349130803Smarcel read_uleb128 (data + 1, data + size, ®); 350130803Smarcel value->kind = axs_lvalue_register; 351130803Smarcel value->u.reg = reg; 352130803Smarcel } 353130803Smarcel else if (data[0] == DW_OP_fbreg) 354130803Smarcel { 355130803Smarcel /* And this is worse than just minimal; we should honor the frame base 356130803Smarcel as above. */ 357130803Smarcel int frame_reg; 358130803Smarcel LONGEST frame_offset; 359130803Smarcel unsigned char *buf_end; 360130803Smarcel 361130803Smarcel buf_end = read_sleb128 (data + 1, data + size, &frame_offset); 362130803Smarcel if (buf_end != data + size) 363130803Smarcel error ("Unexpected opcode after DW_OP_fbreg for symbol \"%s\".", 364130803Smarcel SYMBOL_PRINT_NAME (symbol)); 365130803Smarcel 366130803Smarcel TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset); 367130803Smarcel ax_reg (ax, frame_reg); 368130803Smarcel ax_const_l (ax, frame_offset); 369130803Smarcel ax_simple (ax, aop_add); 370130803Smarcel 371130803Smarcel ax_const_l (ax, frame_offset); 372130803Smarcel ax_simple (ax, aop_add); 373130803Smarcel value->kind = axs_lvalue_memory; 374130803Smarcel } 375130803Smarcel else 376130803Smarcel error ("Unsupported DWARF opcode in the location of \"%s\".", 377130803Smarcel SYMBOL_PRINT_NAME (symbol)); 378130803Smarcel} 379130803Smarcel 380130803Smarcel/* Return the value of SYMBOL in FRAME using the DWARF-2 expression 381130803Smarcel evaluator to calculate the location. */ 382130803Smarcelstatic struct value * 383130803Smarcellocexpr_read_variable (struct symbol *symbol, struct frame_info *frame) 384130803Smarcel{ 385130803Smarcel struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); 386130803Smarcel struct value *val; 387130803Smarcel val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size, 388130803Smarcel dlbaton->objfile); 389130803Smarcel 390130803Smarcel return val; 391130803Smarcel} 392130803Smarcel 393130803Smarcel/* Return non-zero iff we need a frame to evaluate SYMBOL. */ 394130803Smarcelstatic int 395130803Smarcellocexpr_read_needs_frame (struct symbol *symbol) 396130803Smarcel{ 397130803Smarcel struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); 398130803Smarcel return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size); 399130803Smarcel} 400130803Smarcel 401130803Smarcel/* Print a natural-language description of SYMBOL to STREAM. */ 402130803Smarcelstatic int 403130803Smarcellocexpr_describe_location (struct symbol *symbol, struct ui_file *stream) 404130803Smarcel{ 405130803Smarcel /* FIXME: be more extensive. */ 406130803Smarcel struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); 407130803Smarcel 408130803Smarcel if (dlbaton->size == 1 409130803Smarcel && dlbaton->data[0] >= DW_OP_reg0 410130803Smarcel && dlbaton->data[0] <= DW_OP_reg31) 411130803Smarcel { 412130803Smarcel int regno = DWARF2_REG_TO_REGNUM (dlbaton->data[0] - DW_OP_reg0); 413130803Smarcel fprintf_filtered (stream, 414130803Smarcel "a variable in register %s", REGISTER_NAME (regno)); 415130803Smarcel return 1; 416130803Smarcel } 417130803Smarcel 418130803Smarcel /* The location expression for a TLS variable looks like this (on a 419130803Smarcel 64-bit LE machine): 420130803Smarcel 421130803Smarcel DW_AT_location : 10 byte block: 3 4 0 0 0 0 0 0 0 e0 422130803Smarcel (DW_OP_addr: 4; DW_OP_GNU_push_tls_address) 423130803Smarcel 424130803Smarcel 0x3 is the encoding for DW_OP_addr, which has an operand as long 425130803Smarcel as the size of an address on the target machine (here is 8 426130803Smarcel bytes). 0xe0 is the encoding for DW_OP_GNU_push_tls_address. 427130803Smarcel The operand represents the offset at which the variable is within 428130803Smarcel the thread local storage. */ 429130803Smarcel 430130803Smarcel if (dlbaton->size > 1 431130803Smarcel && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address) 432130803Smarcel if (dlbaton->data[0] == DW_OP_addr) 433130803Smarcel { 434130803Smarcel int bytes_read; 435130803Smarcel CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1], 436130803Smarcel &dlbaton->data[dlbaton->size - 1], 437130803Smarcel &bytes_read); 438130803Smarcel fprintf_filtered (stream, 439130803Smarcel "a thread-local variable at offset %s in the " 440130803Smarcel "thread-local storage for `%s'", 441130803Smarcel paddr_nz (offset), dlbaton->objfile->name); 442130803Smarcel return 1; 443130803Smarcel } 444130803Smarcel 445130803Smarcel 446130803Smarcel fprintf_filtered (stream, 447130803Smarcel "a variable with complex or multiple locations (DWARF2)"); 448130803Smarcel return 1; 449130803Smarcel} 450130803Smarcel 451130803Smarcel 452130803Smarcel/* Describe the location of SYMBOL as an agent value in VALUE, generating 453130803Smarcel any necessary bytecode in AX. 454130803Smarcel 455130803Smarcel NOTE drow/2003-02-26: This function is extremely minimal, because 456130803Smarcel doing it correctly is extremely complicated and there is no 457130803Smarcel publicly available stub with tracepoint support for me to test 458130803Smarcel against. When there is one this function should be revisited. */ 459130803Smarcel 460130803Smarcelstatic void 461130803Smarcellocexpr_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax, 462130803Smarcel struct axs_value * value) 463130803Smarcel{ 464130803Smarcel struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); 465130803Smarcel 466130803Smarcel dwarf2_tracepoint_var_ref (symbol, ax, value, dlbaton->data, dlbaton->size); 467130803Smarcel} 468130803Smarcel 469130803Smarcel/* The set of location functions used with the DWARF-2 expression 470130803Smarcel evaluator. */ 471130803Smarcelconst struct symbol_ops dwarf2_locexpr_funcs = { 472130803Smarcel locexpr_read_variable, 473130803Smarcel locexpr_read_needs_frame, 474130803Smarcel locexpr_describe_location, 475130803Smarcel locexpr_tracepoint_var_ref 476130803Smarcel}; 477130803Smarcel 478130803Smarcel 479130803Smarcel/* Wrapper functions for location lists. These generally find 480130803Smarcel the appropriate location expression and call something above. */ 481130803Smarcel 482130803Smarcel/* Return the value of SYMBOL in FRAME using the DWARF-2 expression 483130803Smarcel evaluator to calculate the location. */ 484130803Smarcelstatic struct value * 485130803Smarcelloclist_read_variable (struct symbol *symbol, struct frame_info *frame) 486130803Smarcel{ 487130803Smarcel struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); 488130803Smarcel struct value *val; 489130803Smarcel unsigned char *data; 490130803Smarcel size_t size; 491130803Smarcel 492130803Smarcel data = find_location_expression (dlbaton, &size, 493130803Smarcel frame ? get_frame_pc (frame) : 0); 494130803Smarcel if (data == NULL) 495242936Semaste { 496242936Semaste val = allocate_value (SYMBOL_TYPE (symbol)); 497242936Semaste VALUE_LVAL (val) = not_lval; 498242936Semaste VALUE_OPTIMIZED_OUT (val) = 1; 499242936Semaste } 500242936Semaste else 501242936Semaste val = dwarf2_evaluate_loc_desc (symbol, frame, data, size, 502242936Semaste dlbaton->objfile); 503130803Smarcel 504130803Smarcel return val; 505130803Smarcel} 506130803Smarcel 507130803Smarcel/* Return non-zero iff we need a frame to evaluate SYMBOL. */ 508130803Smarcelstatic int 509130803Smarcelloclist_read_needs_frame (struct symbol *symbol) 510130803Smarcel{ 511130803Smarcel /* If there's a location list, then assume we need to have a frame 512130803Smarcel to choose the appropriate location expression. With tracking of 513130803Smarcel global variables this is not necessarily true, but such tracking 514130803Smarcel is disabled in GCC at the moment until we figure out how to 515130803Smarcel represent it. */ 516130803Smarcel 517130803Smarcel return 1; 518130803Smarcel} 519130803Smarcel 520130803Smarcel/* Print a natural-language description of SYMBOL to STREAM. */ 521130803Smarcelstatic int 522130803Smarcelloclist_describe_location (struct symbol *symbol, struct ui_file *stream) 523130803Smarcel{ 524130803Smarcel /* FIXME: Could print the entire list of locations. */ 525130803Smarcel fprintf_filtered (stream, "a variable with multiple locations"); 526130803Smarcel return 1; 527130803Smarcel} 528130803Smarcel 529130803Smarcel/* Describe the location of SYMBOL as an agent value in VALUE, generating 530130803Smarcel any necessary bytecode in AX. */ 531130803Smarcelstatic void 532130803Smarcelloclist_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax, 533130803Smarcel struct axs_value * value) 534130803Smarcel{ 535130803Smarcel struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); 536130803Smarcel unsigned char *data; 537130803Smarcel size_t size; 538130803Smarcel 539130803Smarcel data = find_location_expression (dlbaton, &size, ax->scope); 540130803Smarcel if (data == NULL) 541130803Smarcel error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol)); 542130803Smarcel 543130803Smarcel dwarf2_tracepoint_var_ref (symbol, ax, value, data, size); 544130803Smarcel} 545130803Smarcel 546130803Smarcel/* The set of location functions used with the DWARF-2 expression 547130803Smarcel evaluator and location lists. */ 548130803Smarcelconst struct symbol_ops dwarf2_loclist_funcs = { 549130803Smarcel loclist_read_variable, 550130803Smarcel loclist_read_needs_frame, 551130803Smarcel loclist_describe_location, 552130803Smarcel loclist_tracepoint_var_ref 553130803Smarcel}; 554