2003-04-13 Daniel Jacobowitz <drow@mvista.com>

* dwarf2expr.c (dwarf2_read_address): Renamed from read_address;
	made non-static.
	(execute_stack_op): All callers updated.
	* dwarf2expr.h: Add prototype for dwarf2_read_address.
	* dwarf2loc.c (find_location_expression): New function.
	(dwarf_expr_frame_base): Call it.
	(dwarf2_evaluate_loc_desc): Handle 0-length location expressions.
	(dwarf2_tracepoint_var_ref): New function, broken out from
	locexpr_tracepoint_var_ref.
	(locexpr_tracepoint_var_ref): Call dwarf2_tracepoint_var_ref.
	Make static.
	(loclist_read_variable, loclist_read_needs_frame): New functions.
	(loclist_describe_location, loclist_tracepoint_var_ref): New
	functions.
	(dwarf2_loclist_funcs): New struct location_funcs.
	* dwarf2loc.h (struct dwarf2_loclist_baton): New type.
	(struct dwarf2_locexpr_baton): Add comments.
	(dwarf2_loclist_funcs): New extern.
	* dwarf2read.c (struct comp_unit_head): Remove DIE member, add
	base_address and base_known.
	(dwarf_loc_buffer): New variable.
	(struct dwarf2_pinfo): Add dwarf_loc_buffer and dwarf_loc_size.
	(DWARF_LOC_BUFFER, DWARF_LOC_SIZE): New macros.
	(dwarf2_has_info): Initialize dwarf_loc_offset.
	(dwarf2_build_psymtabs): Read in .debug_loc.
	(dwarf2_build_psymtabs_hard): Use DWARF_LOC_BUFFER and
	DWARF_LOC_SIZE.
	(psymtab_to_symtab_1): Likewise.  Move base address calculation
	here, from...
	(dwarf2_get_pc_bounds): ... here.  Use the base address from
	cu_header.
	(dwarf2_symbol_mark_computed): Handle location lists.
This commit is contained in:
Daniel Jacobowitz 2003-04-13 15:43:35 +00:00
parent 6aca59a359
commit 0d53c4c49f
6 changed files with 388 additions and 112 deletions

View file

@ -1,3 +1,38 @@
2003-04-13 Daniel Jacobowitz <drow@mvista.com>
* dwarf2expr.c (dwarf2_read_address): Renamed from read_address;
made non-static.
(execute_stack_op): All callers updated.
* dwarf2expr.h: Add prototype for dwarf2_read_address.
* dwarf2loc.c (find_location_expression): New function.
(dwarf_expr_frame_base): Call it.
(dwarf2_evaluate_loc_desc): Handle 0-length location expressions.
(dwarf2_tracepoint_var_ref): New function, broken out from
locexpr_tracepoint_var_ref.
(locexpr_tracepoint_var_ref): Call dwarf2_tracepoint_var_ref.
Make static.
(loclist_read_variable, loclist_read_needs_frame): New functions.
(loclist_describe_location, loclist_tracepoint_var_ref): New
functions.
(dwarf2_loclist_funcs): New struct location_funcs.
* dwarf2loc.h (struct dwarf2_loclist_baton): New type.
(struct dwarf2_locexpr_baton): Add comments.
(dwarf2_loclist_funcs): New extern.
* dwarf2read.c (struct comp_unit_head): Remove DIE member, add
base_address and base_known.
(dwarf_loc_buffer): New variable.
(struct dwarf2_pinfo): Add dwarf_loc_buffer and dwarf_loc_size.
(DWARF_LOC_BUFFER, DWARF_LOC_SIZE): New macros.
(dwarf2_has_info): Initialize dwarf_loc_offset.
(dwarf2_build_psymtabs): Read in .debug_loc.
(dwarf2_build_psymtabs_hard): Use DWARF_LOC_BUFFER and
DWARF_LOC_SIZE.
(psymtab_to_symtab_1): Likewise. Move base address calculation
here, from...
(dwarf2_get_pc_bounds): ... here. Use the base address from
cu_header.
(dwarf2_symbol_mark_computed): Handle location lists.
2003-04-13 Daniel Jacobowitz <drow@mvista.com>
* minsyms.c (install_minimal_symbols): Only switch to gnu-v3 mode

View file

@ -170,13 +170,13 @@ read_sleb128 (unsigned char *buf, unsigned char *buf_end, LONGEST * r)
BUF_END. The address is returned, and *BYTES_READ is set to the
number of bytes read from BUF. */
static CORE_ADDR
read_address (unsigned char *buf, unsigned char *buf_end, int *bytes_read)
CORE_ADDR
dwarf2_read_address (unsigned char *buf, unsigned char *buf_end, int *bytes_read)
{
CORE_ADDR result;
if (buf_end - buf < TARGET_ADDR_BIT / TARGET_CHAR_BIT)
error ("read_address: Corrupted DWARF expression.");
error ("dwarf2_read_address: Corrupted DWARF expression.");
*bytes_read = TARGET_ADDR_BIT / TARGET_CHAR_BIT;
result = extract_address (buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT);
@ -277,7 +277,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
break;
case DW_OP_addr:
result = read_address (op_ptr, op_end, &bytes_read);
result = dwarf2_read_address (op_ptr, op_end, &bytes_read);
op_ptr += bytes_read;
break;
@ -467,9 +467,10 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
(ctx->read_mem) (ctx->baton, buf, result,
TARGET_ADDR_BIT / TARGET_CHAR_BIT);
result = read_address (buf,
buf + TARGET_ADDR_BIT / TARGET_CHAR_BIT,
&bytes_read);
result = dwarf2_read_address (buf,
buf + (TARGET_ADDR_BIT
/ TARGET_CHAR_BIT),
&bytes_read);
}
result = result + offset;
ctx->stack_len = before_stack_len;
@ -528,9 +529,10 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
(ctx->read_mem) (ctx->baton, buf, result,
TARGET_ADDR_BIT / TARGET_CHAR_BIT);
result = read_address (buf,
buf + TARGET_ADDR_BIT / TARGET_CHAR_BIT,
&bytes_read);
result = dwarf2_read_address (buf,
buf + (TARGET_ADDR_BIT
/ TARGET_CHAR_BIT),
&bytes_read);
}
break;
@ -540,9 +542,10 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
int bytes_read;
(ctx->read_mem) (ctx->baton, buf, result, *op_ptr++);
result = read_address (buf,
buf + TARGET_ADDR_BIT / TARGET_CHAR_BIT,
&bytes_read);
result = dwarf2_read_address (buf,
buf + (TARGET_ADDR_BIT
/ TARGET_CHAR_BIT),
&bytes_read);
}
break;

View file

@ -99,5 +99,7 @@ unsigned char *read_uleb128 (unsigned char *buf, unsigned char *buf_end,
ULONGEST * r);
unsigned char *read_sleb128 (unsigned char *buf, unsigned char *buf_end,
LONGEST * r);
CORE_ADDR dwarf2_read_address (unsigned char *buf, unsigned char *buf_end,
int *bytes_read);
#endif

View file

@ -40,6 +40,62 @@
#define DWARF2_REG_TO_REGNUM(REG) (REG)
#endif
/* A helper function for dealing with location lists. Given a
symbol baton (BATON) and a pc value (PC), find the appropriate
location expression, set *LOCEXPR_LENGTH, and return a pointer
to the beginning of the expression. Returns NULL on failure.
For now, only return the first matching location expression; there
can be more than one in the list. */
static char *
find_location_expression (struct dwarf2_loclist_baton *baton,
int *locexpr_length, CORE_ADDR pc)
{
CORE_ADDR base_address = baton->base_address;
CORE_ADDR low, high;
char *loc_ptr, *buf_end;
unsigned int addr_size = TARGET_ADDR_BIT / TARGET_CHAR_BIT, length;
CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
loc_ptr = baton->data;
buf_end = baton->data + baton->size;
while (1)
{
low = dwarf2_read_address (loc_ptr, buf_end, &length);
loc_ptr += length;
high = dwarf2_read_address (loc_ptr, buf_end, &length);
loc_ptr += length;
/* An end-of-list entry. */
if (low == 0 && high == 0)
return NULL;
/* A base-address-selection entry. */
if ((low & base_mask) == base_mask)
{
base_address = high;
continue;
}
/* Otherwise, a location expression entry. */
low += base_address;
high += base_address;
length = extract_unsigned_integer (loc_ptr, 2);
loc_ptr += 2;
if (pc >= low && pc < high)
{
*locexpr_length = length;
return loc_ptr;
}
loc_ptr += length;
}
}
/* This is the baton used when performing dwarf2 expression
evaluation. */
struct dwarf_expr_baton
@ -91,12 +147,28 @@ dwarf_expr_frame_base (void *baton, unsigned char **start, size_t * length)
get_frame_base_address(), and then implement a dwarf2 specific
this_base method. */
struct symbol *framefunc;
struct dwarf2_locexpr_baton *symbaton;
struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
framefunc = get_frame_function (debaton->frame);
symbaton = SYMBOL_LOCATION_BATON (framefunc);
*start = symbaton->data;
*length = symbaton->size;
if (SYMBOL_LOCATION_FUNCS (framefunc) == &dwarf2_loclist_funcs)
{
struct dwarf2_loclist_baton *symbaton;
symbaton = SYMBOL_LOCATION_BATON (framefunc);
*start = find_location_expression (symbaton, length,
get_frame_pc (debaton->frame));
}
else
{
struct dwarf2_locexpr_baton *symbaton;
symbaton = SYMBOL_LOCATION_BATON (framefunc);
*length = symbaton->size;
*start = symbaton->data;
}
if (*start == NULL)
error ("Could not find the frame base for \"%s\".",
SYMBOL_NATURAL_NAME (framefunc));
}
/* Using the objfile specified in BATON, find the address for the
@ -130,6 +202,13 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
struct dwarf_expr_baton baton;
struct dwarf_expr_context *ctx;
if (size == 0)
{
retval = allocate_value (SYMBOL_TYPE (var));
VALUE_LVAL (retval) = not_lval;
VALUE_OPTIMIZED_OUT (retval) = 1;
}
baton.frame = frame;
baton.objfile = objfile;
@ -241,8 +320,55 @@ dwarf2_loc_desc_needs_frame (unsigned char *data, unsigned short size)
return baton.needs_frame;
}
static void
dwarf2_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax,
struct axs_value * value, unsigned char *data,
int size)
{
if (size == 0)
error ("Symbol \"%s\" has been optimized out.",
SYMBOL_PRINT_NAME (symbol));
if (size == 1
&& data[0] >= DW_OP_reg0
&& data[0] <= DW_OP_reg31)
{
value->kind = axs_lvalue_register;
value->u.reg = data[0] - DW_OP_reg0;
}
else if (data[0] == DW_OP_regx)
{
ULONGEST reg;
read_uleb128 (data + 1, data + size, &reg);
value->kind = axs_lvalue_register;
value->u.reg = reg;
}
else if (data[0] == DW_OP_fbreg)
{
/* And this is worse than just minimal; we should honor the frame base
as above. */
int frame_reg;
LONGEST frame_offset;
unsigned char *buf_end;
buf_end = read_sleb128 (data + 1, data + size, &frame_offset);
if (buf_end != data + size)
error ("Unexpected opcode after DW_OP_fbreg for symbol \"%s\".",
SYMBOL_PRINT_NAME (symbol));
TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
ax_reg (ax, frame_reg);
ax_const_l (ax, frame_offset);
ax_simple (ax, aop_add);
ax_const_l (ax, frame_offset);
ax_simple (ax, aop_add);
value->kind = axs_lvalue_memory;
}
else
error ("Unsupported DWARF opcode in the location of \"%s\".",
SYMBOL_PRINT_NAME (symbol));
}
/* Return the value of SYMBOL in FRAME using the DWARF-2 expression
evaluator to calculate the location. */
@ -296,57 +422,13 @@ locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
publicly available stub with tracepoint support for me to test
against. When there is one this function should be revisited. */
void
static void
locexpr_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax,
struct axs_value * value)
{
struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
if (dlbaton->size == 0)
error ("Symbol \"%s\" has been optimized out.",
SYMBOL_PRINT_NAME (symbol));
if (dlbaton->size == 1
&& dlbaton->data[0] >= DW_OP_reg0
&& dlbaton->data[0] <= DW_OP_reg31)
{
value->kind = axs_lvalue_register;
value->u.reg = dlbaton->data[0] - DW_OP_reg0;
}
else if (dlbaton->data[0] == DW_OP_regx)
{
ULONGEST reg;
read_uleb128 (dlbaton->data + 1, dlbaton->data + dlbaton->size,
&reg);
value->kind = axs_lvalue_register;
value->u.reg = reg;
}
else if (dlbaton->data[0] == DW_OP_fbreg)
{
/* And this is worse than just minimal; we should honor the frame base
as above. */
int frame_reg;
LONGEST frame_offset;
unsigned char *buf_end;
buf_end = read_sleb128 (dlbaton->data + 1, dlbaton->data + dlbaton->size,
&frame_offset);
if (buf_end != dlbaton->data + dlbaton->size)
error ("Unexpected opcode after DW_OP_fbreg for symbol \"%s\".",
SYMBOL_PRINT_NAME (symbol));
TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
ax_reg (ax, frame_reg);
ax_const_l (ax, frame_offset);
ax_simple (ax, aop_add);
ax_const_l (ax, frame_offset);
ax_simple (ax, aop_add);
value->kind = axs_lvalue_memory;
}
else
error ("Unsupported DWARF opcode in the location of \"%s\".",
SYMBOL_PRINT_NAME (symbol));
dwarf2_tracepoint_var_ref (symbol, ax, value, dlbaton->data, dlbaton->size);
}
/* The set of location functions used with the DWARF-2 expression
@ -357,3 +439,75 @@ struct location_funcs dwarf2_locexpr_funcs = {
locexpr_describe_location,
locexpr_tracepoint_var_ref
};
/* Wrapper functions for location lists. These generally find
the appropriate location expression and call something above. */
/* Return the value of SYMBOL in FRAME using the DWARF-2 expression
evaluator to calculate the location. */
static struct value *
loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
{
struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
struct value *val;
unsigned char *data;
int size;
data = find_location_expression (dlbaton, &size,
frame ? get_frame_pc (frame) : 0);
if (data == NULL)
error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol));
val = dwarf2_evaluate_loc_desc (symbol, frame, data, size, dlbaton->objfile);
return val;
}
/* Return non-zero iff we need a frame to evaluate SYMBOL. */
static int
loclist_read_needs_frame (struct symbol *symbol)
{
/* If there's a location list, then assume we need to have a frame
to choose the appropriate location expression. With tracking of
global variables this is not necessarily true, but such tracking
is disabled in GCC at the moment until we figure out how to
represent it. */
return 1;
}
/* Print a natural-language description of SYMBOL to STREAM. */
static int
loclist_describe_location (struct symbol *symbol, struct ui_file *stream)
{
/* FIXME: Could print the entire list of locations. */
fprintf_filtered (stream, "a variable with multiple locations");
return 1;
}
/* Describe the location of SYMBOL as an agent value in VALUE, generating
any necessary bytecode in AX. */
static void
loclist_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax,
struct axs_value * value)
{
struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
unsigned char *data;
int size;
data = find_location_expression (dlbaton, &size, ax->scope);
if (data == NULL)
error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol));
dwarf2_tracepoint_var_ref (symbol, ax, value, data, size);
}
/* The set of location functions used with the DWARF-2 expression
evaluator and location lists. */
struct location_funcs dwarf2_loclist_funcs = {
loclist_read_variable,
loclist_read_needs_frame,
loclist_describe_location,
loclist_tracepoint_var_ref
};

View file

@ -24,16 +24,41 @@
/* This header is private to the DWARF-2 reader. It is shared between
dwarf2read.c and dwarf2loc.c. */
/* The symbol location baton type used by the DWARF-2 reader (i.e.
SYMBOL_LOCATION_BATON for a LOC_COMPUTED symbol). */
/* The symbol location baton types used by the DWARF-2 reader (i.e.
SYMBOL_LOCATION_BATON for a LOC_COMPUTED symbol). "struct
dwarf2_locexpr_baton" is for a symbol with a single location
expression; "struct dwarf2_loclist_baton" is for a symbol with a
location list. */
struct dwarf2_locexpr_baton
{
/* Pointer to the start of the location expression. */
unsigned char *data;
/* Length of the location expression. */
unsigned short size;
/* The objfile containing the symbol whose location we're computing. */
struct objfile *objfile;
};
struct dwarf2_loclist_baton
{
/* The initial base address for the location list, based on the compilation
unit. */
CORE_ADDR base_address;
/* Pointer to the start of the location list. */
unsigned char *data;
/* Length of the location list. */
unsigned short size;
/* The objfile containing the symbol whose location we're computing. */
struct objfile *objfile;
};
extern struct location_funcs dwarf2_locexpr_funcs;
extern struct location_funcs dwarf2_loclist_funcs;
#endif

View file

@ -220,9 +220,13 @@ struct comp_unit_head
struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE];
/* Pointer to the DIE associated with the compilation unit. */
/* Base address of this compilation unit. */
struct die_info *die;
CORE_ADDR base_address;
/* Non-zero if base_address has been set. */
int base_known;
};
/* The line number information for a compilation unit (found in the
@ -395,6 +399,7 @@ static char *dwarf_line_buffer;
static char *dwarf_str_buffer;
static char *dwarf_macinfo_buffer;
static char *dwarf_ranges_buffer;
static char *dwarf_loc_buffer;
/* A zeroed version of a partial die for initialization purposes. */
static struct partial_die_info zeroed_partial_die;
@ -511,6 +516,13 @@ struct dwarf2_pinfo
unsigned int dwarf_ranges_size;
/* Pointer to start of dwarf locations buffer for the objfile. */
char *dwarf_loc_buffer;
/* Size of dwarf locations buffer for the objfile. */
unsigned int dwarf_loc_size;
};
#define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
@ -526,6 +538,8 @@ struct dwarf2_pinfo
#define DWARF_MACINFO_SIZE(p) (PST_PRIVATE(p)->dwarf_macinfo_size)
#define DWARF_RANGES_BUFFER(p) (PST_PRIVATE(p)->dwarf_ranges_buffer)
#define DWARF_RANGES_SIZE(p) (PST_PRIVATE(p)->dwarf_ranges_size)
#define DWARF_LOC_BUFFER(p) (PST_PRIVATE(p)->dwarf_loc_buffer)
#define DWARF_LOC_SIZE(p) (PST_PRIVATE(p)->dwarf_loc_size)
/* Maintain an array of referenced fundamental types for the current
compilation unit being read. For DWARF version 1, we have to construct
@ -926,6 +940,7 @@ dwarf2_has_info (bfd *abfd)
dwarf_frame_offset = 0;
dwarf_eh_frame_offset = 0;
dwarf_ranges_offset = 0;
dwarf_loc_offset = 0;
bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
if (dwarf_info_offset && dwarf_abbrev_offset)
@ -1062,6 +1077,14 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
else
dwarf_ranges_buffer = NULL;
if (dwarf_loc_offset)
dwarf_loc_buffer = dwarf2_read_section (objfile,
dwarf_loc_offset,
dwarf_loc_size,
dwarf_loc_section);
else
dwarf_loc_buffer = NULL;
if (mainline
|| (objfile->global_psymbols.size == 0
&& objfile->static_psymbols.size == 0))
@ -1283,6 +1306,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
DWARF_MACINFO_SIZE (pst) = dwarf_macinfo_size;
DWARF_RANGES_BUFFER (pst) = dwarf_ranges_buffer;
DWARF_RANGES_SIZE (pst) = dwarf_ranges_size;
DWARF_LOC_BUFFER (pst) = dwarf_loc_buffer;
DWARF_LOC_SIZE (pst) = dwarf_loc_size;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
/* Store the function that reads in the rest of the symbol table */
@ -1607,6 +1632,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
char *info_ptr;
struct symtab *symtab;
struct cleanup *back_to;
struct attribute *attr;
/* Set local variables from the partial symbol table info. */
offset = DWARF_INFO_OFFSET (pst);
@ -1621,6 +1647,8 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
dwarf_macinfo_size = DWARF_MACINFO_SIZE (pst);
dwarf_ranges_buffer = DWARF_RANGES_BUFFER (pst);
dwarf_ranges_size = DWARF_RANGES_SIZE (pst);
dwarf_loc_buffer = DWARF_LOC_BUFFER (pst);
dwarf_loc_size = DWARF_LOC_SIZE (pst);
baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
cu_header_offset = offset;
info_ptr = dwarf_info_buffer + offset;
@ -1642,8 +1670,32 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
make_cleanup_free_die_list (dies);
/* Find the base address of the compilation unit for range lists and
location lists. It will normally be specified by DW_AT_low_pc.
In DWARF-3 draft 4, the base address could be overridden by
DW_AT_entry_pc. It's been removed, but GCC still uses this for
compilation units with discontinuous ranges. */
cu_header.base_known = 0;
cu_header.base_address = 0;
attr = dwarf_attr (dies, DW_AT_entry_pc);
if (attr)
{
cu_header.base_address = DW_ADDR (attr);
cu_header.base_known = 1;
}
else
{
attr = dwarf_attr (dies, DW_AT_low_pc);
if (attr)
{
cu_header.base_address = DW_ADDR (attr);
cu_header.base_known = 1;
}
}
/* Do line number decoding in read_file_scope () */
cu_header.die = dies;
process_die (dies, objfile, &cu_header);
if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile, &cu_header))
@ -2122,40 +2174,18 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
.debug_renges section. */
unsigned int offset = DW_UNSND (attr);
/* Base address selection entry. */
CORE_ADDR base = 0;
int found_base = 0;
CORE_ADDR base;
int found_base;
int dummy;
unsigned int i;
char *buffer;
CORE_ADDR marker;
int low_set;
/* The applicable base address is determined by (1) the closest
preceding base address selection entry in the range list or
(2) the DW_AT_low_pc of the compilation unit. */
/* ??? Was in dwarf3 draft4, and has since been removed.
GCC still uses it though. */
attr = dwarf_attr (cu_header->die, DW_AT_entry_pc);
if (attr)
{
base = DW_ADDR (attr);
found_base = 1;
}
if (!found_base)
{
attr = dwarf_attr (cu_header->die, DW_AT_low_pc);
if (attr)
{
base = DW_ADDR (attr);
found_base = 1;
}
}
found_base = cu_header->base_known;
base = cu_header->base_address;
buffer = dwarf_ranges_buffer + offset;
/* Read in the largest possible address. */
marker = read_address (obfd, buffer, cu_header, &dummy);
if ((marker & mask) == mask)
@ -7328,26 +7358,53 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
const struct comp_unit_head *cu_header,
struct objfile *objfile)
{
struct dwarf2_locexpr_baton *baton;
/* When support for location lists is added, this will go away. */
if (!attr_form_is_block (attr))
if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
{
dwarf2_complex_location_expr_complaint ();
return;
struct dwarf2_loclist_baton *baton;
baton = obstack_alloc (&objfile->symbol_obstack,
sizeof (struct dwarf2_loclist_baton));
baton->objfile = objfile;
/* We don't know how long the location list is, but make sure we
don't run off the edge of the section. */
baton->size = dwarf_loc_size - DW_UNSND (attr);
baton->data = dwarf_loc_buffer + DW_UNSND (attr);
baton->base_address = cu_header->base_address;
if (cu_header->base_known == 0)
complaint (&symfile_complaints,
"Location list used without specifying the CU base address.");
SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_loclist_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
}
else
{
struct dwarf2_locexpr_baton *baton;
baton = obstack_alloc (&objfile->symbol_obstack,
sizeof (struct dwarf2_locexpr_baton));
baton->objfile = objfile;
baton = obstack_alloc (&objfile->symbol_obstack,
sizeof (struct dwarf2_locexpr_baton));
baton->objfile = objfile;
/* Note that we're just copying the block's data pointer here, not
the actual data. We're still pointing into the dwarf_info_buffer
for SYM's objfile; right now we never release that buffer, but
when we do clean up properly this may need to change. */
baton->size = DW_BLOCK (attr)->size;
baton->data = DW_BLOCK (attr)->data;
SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
if (attr_form_is_block (attr))
{
/* Note that we're just copying the block's data pointer
here, not the actual data. We're still pointing into the
dwarf_info_buffer for SYM's objfile; right now we never
release that buffer, but when we do clean up properly
this may need to change. */
baton->size = DW_BLOCK (attr)->size;
baton->data = DW_BLOCK (attr)->data;
}
else
{
dwarf2_invalid_attrib_class_complaint ("location description",
SYMBOL_NATURAL_NAME (sym));
baton->size = 0;
baton->data = NULL;
}
SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
}
}