mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-24 20:49:43 +00:00
2002-04-04 Daniel Jacobowitz <drow@mvista.com>
* dwarf2read.c (struct function_range): New. (cu_first_fn, cu_last_fn, cu_cached_fn): New. (check_cu_functions): New. (read_file_scope): Initialize global function lists. Call dwarf_decode_line after processing children. (read_func_scope): Add to global function list. (dwarf_decode_lines): Call check_cu_functions everywhere record_line is called. Call record_line with a linenumber of 0 to mark sequence ends.
This commit is contained in:
parent
b0c0ea31a1
commit
5fb290d7a3
@ -1,3 +1,15 @@
|
||||
2002-04-04 Daniel Jacobowitz <drow@mvista.com>
|
||||
|
||||
* dwarf2read.c (struct function_range): New.
|
||||
(cu_first_fn, cu_last_fn, cu_cached_fn): New.
|
||||
(check_cu_functions): New.
|
||||
(read_file_scope): Initialize global function lists.
|
||||
Call dwarf_decode_line after processing children.
|
||||
(read_func_scope): Add to global function list.
|
||||
(dwarf_decode_lines): Call check_cu_functions everywhere
|
||||
record_line is called. Call record_line with a linenumber
|
||||
of 0 to mark sequence ends.
|
||||
|
||||
2002-04-04 Michal Ludvig <mludvig@suse.cz>
|
||||
|
||||
* x86-64-linux-nat.c (child_xfer_memory): x86-64 ptrace() ABI
|
||||
|
118
gdb/dwarf2read.c
118
gdb/dwarf2read.c
@ -256,6 +256,16 @@ struct attribute
|
||||
u;
|
||||
};
|
||||
|
||||
struct function_range
|
||||
{
|
||||
const char *name;
|
||||
CORE_ADDR lowpc, highpc;
|
||||
int seen_line;
|
||||
struct function_range *next;
|
||||
};
|
||||
|
||||
static struct function_range *cu_first_fn, *cu_last_fn, *cu_cached_fn;
|
||||
|
||||
/* Get at parts of an attribute structure */
|
||||
|
||||
#define DW_STRING(attr) ((attr)->u.str)
|
||||
@ -560,6 +570,10 @@ static struct complaint dwarf2_unsupported_const_value_attr =
|
||||
{
|
||||
"unsupported const value attribute form: '%s'", 0, 0
|
||||
};
|
||||
static struct complaint dwarf2_misplaced_line_number =
|
||||
{
|
||||
"misplaced first line number at 0x%lx for '%s'", 0, 0
|
||||
};
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
@ -794,6 +808,10 @@ static struct abbrev_info *dwarf_alloc_abbrev (void);
|
||||
|
||||
static struct die_info *dwarf_alloc_die (void);
|
||||
|
||||
static void initialize_cu_func_list (void);
|
||||
|
||||
static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR);
|
||||
|
||||
/* Try to locate the sections we need for DWARF 2 debugging
|
||||
information and return true if we have enough to do something. */
|
||||
|
||||
@ -1541,6 +1559,12 @@ process_die (struct die_info *die, struct objfile *objfile,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_cu_func_list (void)
|
||||
{
|
||||
cu_first_fn = cu_last_fn = cu_cached_fn = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
read_file_scope (struct die_info *die, struct objfile *objfile,
|
||||
const struct comp_unit_head *cu_header)
|
||||
@ -1633,13 +1657,7 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
|
||||
start_symtab (name, comp_dir, lowpc);
|
||||
record_debugformat ("DWARF 2");
|
||||
|
||||
/* Decode line number information if present. */
|
||||
attr = dwarf_attr (die, DW_AT_stmt_list);
|
||||
if (attr)
|
||||
{
|
||||
line_offset = DW_UNSND (attr);
|
||||
dwarf_decode_lines (line_offset, comp_dir, abfd, cu_header);
|
||||
}
|
||||
initialize_cu_func_list ();
|
||||
|
||||
/* Process all dies in compilation unit. */
|
||||
if (die->has_children)
|
||||
@ -1651,6 +1669,35 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
|
||||
child_die = sibling_die (child_die);
|
||||
}
|
||||
}
|
||||
|
||||
/* Decode line number information if present. */
|
||||
attr = dwarf_attr (die, DW_AT_stmt_list);
|
||||
if (attr)
|
||||
{
|
||||
line_offset = DW_UNSND (attr);
|
||||
dwarf_decode_lines (line_offset, comp_dir, abfd, cu_header);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
|
||||
{
|
||||
struct function_range *thisfn;
|
||||
|
||||
thisfn = (struct function_range *)
|
||||
obstack_alloc (&dwarf2_tmp_obstack, sizeof (struct function_range));
|
||||
thisfn->name = name;
|
||||
thisfn->lowpc = lowpc;
|
||||
thisfn->highpc = highpc;
|
||||
thisfn->seen_line = 0;
|
||||
thisfn->next = NULL;
|
||||
|
||||
if (cu_last_fn == NULL)
|
||||
cu_first_fn = thisfn;
|
||||
else
|
||||
cu_last_fn->next = thisfn;
|
||||
|
||||
cu_last_fn = thisfn;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1674,6 +1721,9 @@ read_func_scope (struct die_info *die, struct objfile *objfile,
|
||||
lowpc += baseaddr;
|
||||
highpc += baseaddr;
|
||||
|
||||
/* Record the function range for dwarf_decode_lines. */
|
||||
add_to_cu_func_list (name, lowpc, highpc);
|
||||
|
||||
if (objfile->ei.entry_point >= lowpc &&
|
||||
objfile->ei.entry_point < highpc)
|
||||
{
|
||||
@ -3908,6 +3958,51 @@ struct directories
|
||||
char **dirs;
|
||||
};
|
||||
|
||||
/* This function exists to work around a bug in certain compilers
|
||||
(particularly GCC 2.95), in which the first line number marker of a
|
||||
function does not show up until after the prologue, right before
|
||||
the second line number marker. This function shifts ADDRESS down
|
||||
to the beginning of the function if necessary, and is called on
|
||||
addresses passed to record_line. */
|
||||
|
||||
static CORE_ADDR
|
||||
check_cu_functions (CORE_ADDR address)
|
||||
{
|
||||
struct function_range *fn;
|
||||
|
||||
/* Find the function_range containing address. */
|
||||
if (!cu_first_fn)
|
||||
return address;
|
||||
|
||||
if (!cu_cached_fn)
|
||||
cu_cached_fn = cu_first_fn;
|
||||
|
||||
fn = cu_cached_fn;
|
||||
while (fn)
|
||||
if (fn->lowpc <= address && fn->highpc > address)
|
||||
goto found;
|
||||
else
|
||||
fn = fn->next;
|
||||
|
||||
fn = cu_first_fn;
|
||||
while (fn && fn != cu_cached_fn)
|
||||
if (fn->lowpc <= address && fn->highpc > address)
|
||||
goto found;
|
||||
else
|
||||
fn = fn->next;
|
||||
|
||||
return address;
|
||||
|
||||
found:
|
||||
if (fn->seen_line)
|
||||
return address;
|
||||
if (address != fn->lowpc)
|
||||
complain (&dwarf2_misplaced_line_number,
|
||||
(unsigned long) address, fn->name);
|
||||
fn->seen_line = 1;
|
||||
return fn->lowpc;
|
||||
}
|
||||
|
||||
static void
|
||||
dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
||||
const struct comp_unit_head *cu_header)
|
||||
@ -4048,6 +4143,7 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
||||
* lh.minimum_instruction_length;
|
||||
line += lh.line_base + (adj_opcode % lh.line_range);
|
||||
/* append row to matrix using current values */
|
||||
address = check_cu_functions (address);
|
||||
record_line (current_subfile, line, address);
|
||||
basic_block = 1;
|
||||
}
|
||||
@ -4061,12 +4157,7 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
||||
{
|
||||
case DW_LNE_end_sequence:
|
||||
end_sequence = 1;
|
||||
/* Don't call record_line here. The end_sequence
|
||||
instruction provides the address of the first byte
|
||||
*after* the last line in the sequence; it's not the
|
||||
address of any real source line. However, the GDB
|
||||
linetable structure only records the starts of lines,
|
||||
not the ends. This is a weakness of GDB. */
|
||||
record_line (current_subfile, 0, address);
|
||||
break;
|
||||
case DW_LNE_set_address:
|
||||
address = read_address (abfd, line_ptr, cu_header, &bytes_read);
|
||||
@ -4103,6 +4194,7 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
||||
}
|
||||
break;
|
||||
case DW_LNS_copy:
|
||||
address = check_cu_functions (address);
|
||||
record_line (current_subfile, line, address);
|
||||
basic_block = 0;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user