mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-09 02:37:38 +00:00
* dwarf2read.c (skip_leb128, peek_die_abbrev, skip_one_die)
(skip_children): New functions. (locate_pdi_sibling): Call skip_children.
This commit is contained in:
parent
c7414a01d5
commit
4bb7a0a769
@ -1,3 +1,9 @@
|
||||
2004-03-09 Daniel Jacobowitz <drow@mvista.com>
|
||||
|
||||
* dwarf2read.c (skip_leb128, peek_die_abbrev, skip_one_die)
|
||||
(skip_children): New functions.
|
||||
(locate_pdi_sibling): Call skip_children.
|
||||
|
||||
2004-03-09 Daniel Jacobowitz <drow@mvista.com>
|
||||
|
||||
* arm-tdep.c (arm_use_struct_convention): Look through typedefs.
|
||||
|
187
gdb/dwarf2read.c
187
gdb/dwarf2read.c
@ -734,6 +734,8 @@ static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *);
|
||||
|
||||
static long read_signed_leb128 (bfd *, char *, unsigned int *);
|
||||
|
||||
static char *skip_leb128 (bfd *, char *);
|
||||
|
||||
static void set_cu_language (unsigned int, struct dwarf2_cu *);
|
||||
|
||||
static struct attribute *dwarf2_attr (struct die_info *, unsigned int,
|
||||
@ -937,6 +939,9 @@ static void
|
||||
dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
|
||||
struct dwarf2_cu *cu);
|
||||
|
||||
static char *skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
|
||||
struct dwarf2_cu *cu);
|
||||
|
||||
/* Try to locate the sections we need for DWARF 2 debugging
|
||||
information and return true if we have enough to do something. */
|
||||
|
||||
@ -1765,8 +1770,154 @@ add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr,
|
||||
return info_ptr;
|
||||
}
|
||||
|
||||
/* Locate ORIG_PDI's sibling; INFO_PTR should point to the next DIE
|
||||
after ORIG_PDI. */
|
||||
/* Read the initial uleb128 in the die at INFO_PTR in compilation unit CU.
|
||||
Return the corresponding abbrev, or NULL if the number is zero (indicating
|
||||
an empty DIE). In either case *BYTES_READ will be set to the length of
|
||||
the initial number. */
|
||||
|
||||
static struct abbrev_info *
|
||||
peek_die_abbrev (char *info_ptr, int *bytes_read, struct dwarf2_cu *cu)
|
||||
{
|
||||
bfd *abfd = cu->objfile->obfd;
|
||||
unsigned int abbrev_number;
|
||||
struct abbrev_info *abbrev;
|
||||
|
||||
abbrev_number = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
|
||||
|
||||
if (abbrev_number == 0)
|
||||
return NULL;
|
||||
|
||||
abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
|
||||
if (!abbrev)
|
||||
{
|
||||
error ("Dwarf Error: Could not find abbrev number %d [in module %s]", abbrev_number,
|
||||
bfd_get_filename (abfd));
|
||||
}
|
||||
|
||||
return abbrev;
|
||||
}
|
||||
|
||||
/* Scan the debug information for CU starting at INFO_PTR. Returns a
|
||||
pointer to the end of a series of DIEs, terminated by an empty
|
||||
DIE. Any children of the skipped DIEs will also be skipped. */
|
||||
|
||||
static char *
|
||||
skip_children (char *info_ptr, struct dwarf2_cu *cu)
|
||||
{
|
||||
struct abbrev_info *abbrev;
|
||||
unsigned int bytes_read;
|
||||
|
||||
while (1)
|
||||
{
|
||||
abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
|
||||
if (abbrev == NULL)
|
||||
return info_ptr + bytes_read;
|
||||
else
|
||||
info_ptr = skip_one_die (info_ptr + bytes_read, abbrev, cu);
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan the debug information for CU starting at INFO_PTR. INFO_PTR
|
||||
should point just after the initial uleb128 of a DIE, and the
|
||||
abbrev corresponding to that skipped uleb128 should be passed in
|
||||
ABBREV. Returns a pointer to this DIE's sibling, skipping any
|
||||
children. */
|
||||
|
||||
static char *
|
||||
skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
|
||||
struct dwarf2_cu *cu)
|
||||
{
|
||||
unsigned int bytes_read;
|
||||
struct attribute attr;
|
||||
bfd *abfd = cu->objfile->obfd;
|
||||
unsigned int form, i;
|
||||
|
||||
for (i = 0; i < abbrev->num_attrs; i++)
|
||||
{
|
||||
/* The only abbrev we care about is DW_AT_sibling. */
|
||||
if (abbrev->attrs[i].name == DW_AT_sibling)
|
||||
{
|
||||
read_attribute (&attr, &abbrev->attrs[i],
|
||||
abfd, info_ptr, cu);
|
||||
if (attr.form == DW_FORM_ref_addr)
|
||||
complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
|
||||
else
|
||||
return dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr, cu);
|
||||
}
|
||||
|
||||
/* If it isn't DW_AT_sibling, skip this attribute. */
|
||||
form = abbrev->attrs[i].form;
|
||||
skip_attribute:
|
||||
switch (form)
|
||||
{
|
||||
case DW_FORM_addr:
|
||||
case DW_FORM_ref_addr:
|
||||
info_ptr += cu->header.addr_size;
|
||||
break;
|
||||
case DW_FORM_data1:
|
||||
case DW_FORM_ref1:
|
||||
case DW_FORM_flag:
|
||||
info_ptr += 1;
|
||||
break;
|
||||
case DW_FORM_data2:
|
||||
case DW_FORM_ref2:
|
||||
info_ptr += 2;
|
||||
break;
|
||||
case DW_FORM_data4:
|
||||
case DW_FORM_ref4:
|
||||
info_ptr += 4;
|
||||
break;
|
||||
case DW_FORM_data8:
|
||||
case DW_FORM_ref8:
|
||||
info_ptr += 8;
|
||||
break;
|
||||
case DW_FORM_string:
|
||||
read_string (abfd, info_ptr, &bytes_read);
|
||||
info_ptr += bytes_read;
|
||||
break;
|
||||
case DW_FORM_strp:
|
||||
info_ptr += cu->header.offset_size;
|
||||
break;
|
||||
case DW_FORM_block:
|
||||
info_ptr += read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
|
||||
info_ptr += bytes_read;
|
||||
break;
|
||||
case DW_FORM_block1:
|
||||
info_ptr += 1 + read_1_byte (abfd, info_ptr);
|
||||
break;
|
||||
case DW_FORM_block2:
|
||||
info_ptr += 2 + read_2_bytes (abfd, info_ptr);
|
||||
break;
|
||||
case DW_FORM_block4:
|
||||
info_ptr += 4 + read_4_bytes (abfd, info_ptr);
|
||||
break;
|
||||
case DW_FORM_sdata:
|
||||
case DW_FORM_udata:
|
||||
case DW_FORM_ref_udata:
|
||||
info_ptr = skip_leb128 (abfd, info_ptr);
|
||||
break;
|
||||
case DW_FORM_indirect:
|
||||
form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
|
||||
info_ptr += bytes_read;
|
||||
/* We need to continue parsing from here, so just go back to
|
||||
the top. */
|
||||
goto skip_attribute;
|
||||
|
||||
default:
|
||||
error ("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]",
|
||||
dwarf_form_name (form),
|
||||
bfd_get_filename (abfd));
|
||||
}
|
||||
}
|
||||
|
||||
if (abbrev->has_children)
|
||||
return skip_children (info_ptr, cu);
|
||||
else
|
||||
return info_ptr;
|
||||
}
|
||||
|
||||
/* Locate ORIG_PDI's sibling; INFO_PTR should point to the start of
|
||||
the next DIE after ORIG_PDI. */
|
||||
|
||||
static char *
|
||||
locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr,
|
||||
@ -1782,21 +1933,9 @@ locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr,
|
||||
if (!orig_pdi->has_children)
|
||||
return info_ptr;
|
||||
|
||||
/* Okay, we don't know the sibling, but we have children that we
|
||||
want to skip. So read children until we run into one without a
|
||||
tag; return whatever follows it. */
|
||||
/* Skip the children the long way. */
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct partial_die_info pdi;
|
||||
|
||||
info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu);
|
||||
|
||||
if (pdi.tag == 0)
|
||||
return info_ptr;
|
||||
else
|
||||
info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu);
|
||||
}
|
||||
return skip_children (info_ptr, cu);
|
||||
}
|
||||
|
||||
/* Expand this partial symbol table into a full symbol table. */
|
||||
@ -4950,6 +5089,22 @@ read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return a pointer to just past the end of an LEB128 number in BUF. */
|
||||
|
||||
static char *
|
||||
skip_leb128 (bfd *abfd, char *buf)
|
||||
{
|
||||
int byte;
|
||||
|
||||
while (1)
|
||||
{
|
||||
byte = bfd_get_8 (abfd, (bfd_byte *) buf);
|
||||
buf++;
|
||||
if ((byte & 128) == 0)
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user