DWARF2.1 64-bit support.
This commit is contained in:
parent
7dca057bba
commit
613e165759
2 changed files with 142 additions and 17 deletions
|
@ -1,3 +1,23 @@
|
||||||
|
2000-08-04 Kevin Buettner <kevinb@redhat.com>
|
||||||
|
|
||||||
|
* dwarf2read.c (struct comp_unit_head): Add fields offset_size
|
||||||
|
and initial_length_size. Change type of ``length'' field to long.
|
||||||
|
(read_initial_length, read_offset): New functions.
|
||||||
|
(dwarf2_build_psymtabs_easy): Call read_initial_length() instead
|
||||||
|
of just reading 4 bytes.
|
||||||
|
(read_comp_unit_head): Likewise; also, call read_offset() to
|
||||||
|
fetch the offset instead of just reading 4 bytes.
|
||||||
|
(dwarf_decode_lines): Likewise.
|
||||||
|
(read_comp_unit_head): Fix internal error message so it
|
||||||
|
accurately reflects the function in which the error occurred.
|
||||||
|
(dwarf2_build_psymtabs_hard): Properly account for size of the
|
||||||
|
initial length field in the section.
|
||||||
|
(read_attribute, dwarf2_get_ref_die_offset): Add a case for
|
||||||
|
DW_ORM_ref8.
|
||||||
|
(dwarf2_build_psymtabs_hard, psymtabs_to_symtab_1): Don't
|
||||||
|
assume that the .text section will have index 0 in the
|
||||||
|
section_offsets table.
|
||||||
|
|
||||||
Fri Aug 4 18:00:41 2000 Andrew Cagney <cagney@b1.cygnus.com>
|
Fri Aug 4 18:00:41 2000 Andrew Cagney <cagney@b1.cygnus.com>
|
||||||
|
|
||||||
* remote.c (enum Z_packet_type): Define.
|
* remote.c (enum Z_packet_type): Define.
|
||||||
|
|
139
gdb/dwarf2read.c
139
gdb/dwarf2read.c
|
@ -152,11 +152,14 @@ static unsigned int dwarf_str_size;
|
||||||
translation, looks like this. */
|
translation, looks like this. */
|
||||||
struct comp_unit_head
|
struct comp_unit_head
|
||||||
{
|
{
|
||||||
unsigned int length;
|
unsigned long length;
|
||||||
short version;
|
short version;
|
||||||
unsigned int abbrev_offset;
|
unsigned int abbrev_offset;
|
||||||
unsigned char addr_size;
|
unsigned char addr_size;
|
||||||
unsigned char signed_addr_p;
|
unsigned char signed_addr_p;
|
||||||
|
unsigned int offset_size; /* size of file offsets; either 4 or 8 */
|
||||||
|
unsigned int initial_length_size; /* size of the length field; either
|
||||||
|
4 or 12 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The data in the .debug_line statement prologue looks like this. */
|
/* The data in the .debug_line statement prologue looks like this. */
|
||||||
|
@ -604,6 +607,12 @@ static unsigned long read_8_bytes (bfd *, char *);
|
||||||
static CORE_ADDR read_address (bfd *, char *ptr, const struct comp_unit_head *,
|
static CORE_ADDR read_address (bfd *, char *ptr, const struct comp_unit_head *,
|
||||||
int *bytes_read);
|
int *bytes_read);
|
||||||
|
|
||||||
|
static LONGEST read_initial_length (bfd *, char *,
|
||||||
|
struct comp_unit_head *, int *bytes_read);
|
||||||
|
|
||||||
|
static LONGEST read_offset (bfd *, char *, const struct comp_unit_head *,
|
||||||
|
int *bytes_read);
|
||||||
|
|
||||||
static char *read_n_bytes (bfd *, char *, unsigned int);
|
static char *read_n_bytes (bfd *, char *, unsigned int);
|
||||||
|
|
||||||
static char *read_string (bfd *, char *, unsigned int *);
|
static char *read_string (bfd *, char *, unsigned int *);
|
||||||
|
@ -898,8 +907,12 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
|
||||||
pubnames_ptr = pubnames_buffer;
|
pubnames_ptr = pubnames_buffer;
|
||||||
while ((pubnames_ptr - pubnames_buffer) < dwarf_pubnames_size)
|
while ((pubnames_ptr - pubnames_buffer) < dwarf_pubnames_size)
|
||||||
{
|
{
|
||||||
entry_length = read_4_bytes (abfd, pubnames_ptr);
|
struct comp_unit_head cu_header;
|
||||||
pubnames_ptr += 4;
|
int bytes_read;
|
||||||
|
|
||||||
|
entry_length = read_initial_length (abfd, pubnames_ptr, &cu_header,
|
||||||
|
&bytes_read);
|
||||||
|
pubnames_ptr += bytes_read;
|
||||||
version = read_1_byte (abfd, pubnames_ptr);
|
version = read_1_byte (abfd, pubnames_ptr);
|
||||||
pubnames_ptr += 1;
|
pubnames_ptr += 1;
|
||||||
info_offset = read_4_bytes (abfd, pubnames_ptr);
|
info_offset = read_4_bytes (abfd, pubnames_ptr);
|
||||||
|
@ -923,17 +936,20 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
|
||||||
char *info_ptr, bfd *abfd)
|
char *info_ptr, bfd *abfd)
|
||||||
{
|
{
|
||||||
int signed_addr;
|
int signed_addr;
|
||||||
cu_header->length = read_4_bytes (abfd, info_ptr);
|
int bytes_read;
|
||||||
info_ptr += 4;
|
cu_header->length = read_initial_length (abfd, info_ptr, cu_header,
|
||||||
|
&bytes_read);
|
||||||
|
info_ptr += bytes_read;
|
||||||
cu_header->version = read_2_bytes (abfd, info_ptr);
|
cu_header->version = read_2_bytes (abfd, info_ptr);
|
||||||
info_ptr += 2;
|
info_ptr += 2;
|
||||||
cu_header->abbrev_offset = read_4_bytes (abfd, info_ptr);
|
cu_header->abbrev_offset = read_offset (abfd, info_ptr, cu_header,
|
||||||
info_ptr += 4;
|
&bytes_read);
|
||||||
|
info_ptr += bytes_read;
|
||||||
cu_header->addr_size = read_1_byte (abfd, info_ptr);
|
cu_header->addr_size = read_1_byte (abfd, info_ptr);
|
||||||
info_ptr += 1;
|
info_ptr += 1;
|
||||||
signed_addr = bfd_get_sign_extend_vma (abfd);
|
signed_addr = bfd_get_sign_extend_vma (abfd);
|
||||||
if (signed_addr < 0)
|
if (signed_addr < 0)
|
||||||
internal_error ("dwarf2_build_psymtabs_hard: dwarf from non elf file");
|
internal_error ("read_comp_unit_head: dwarf from non elf file");
|
||||||
cu_header->signed_addr_p = signed_addr;
|
cu_header->signed_addr_p = signed_addr;
|
||||||
return info_ptr;
|
return info_ptr;
|
||||||
}
|
}
|
||||||
|
@ -980,7 +996,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
|
||||||
(long) (beg_of_comp_unit - dwarf_info_buffer));
|
(long) (beg_of_comp_unit - dwarf_info_buffer));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (beg_of_comp_unit + cu_header.length + 4
|
if (beg_of_comp_unit + cu_header.length + cu_header.initial_length_size
|
||||||
> dwarf_info_buffer + dwarf_info_size)
|
> dwarf_info_buffer + dwarf_info_size)
|
||||||
{
|
{
|
||||||
error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0).",
|
error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0).",
|
||||||
|
@ -1014,7 +1030,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
|
||||||
DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
|
DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
|
||||||
DWARF_ABBREV_SIZE (pst) = dwarf_abbrev_size;
|
DWARF_ABBREV_SIZE (pst) = dwarf_abbrev_size;
|
||||||
DWARF_LINE_BUFFER (pst) = dwarf_line_buffer;
|
DWARF_LINE_BUFFER (pst) = dwarf_line_buffer;
|
||||||
baseaddr = ANOFFSET (objfile->section_offsets, 0);
|
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
|
||||||
|
|
||||||
/* Store the function that reads in the rest of the symbol table */
|
/* Store the function that reads in the rest of the symbol table */
|
||||||
pst->read_symtab = dwarf2_psymtab_to_symtab;
|
pst->read_symtab = dwarf2_psymtab_to_symtab;
|
||||||
|
@ -1049,7 +1065,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
|
||||||
also happen.) This happens in VxWorks. */
|
also happen.) This happens in VxWorks. */
|
||||||
free_named_symtabs (pst->filename);
|
free_named_symtabs (pst->filename);
|
||||||
|
|
||||||
info_ptr = beg_of_comp_unit + cu_header.length + 4;
|
info_ptr = beg_of_comp_unit + cu_header.length
|
||||||
|
+ cu_header.initial_length_size;
|
||||||
}
|
}
|
||||||
do_cleanups (back_to);
|
do_cleanups (back_to);
|
||||||
}
|
}
|
||||||
|
@ -1314,7 +1331,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
|
||||||
dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER (pst);
|
dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER (pst);
|
||||||
dwarf_abbrev_size = DWARF_ABBREV_SIZE (pst);
|
dwarf_abbrev_size = DWARF_ABBREV_SIZE (pst);
|
||||||
dwarf_line_buffer = DWARF_LINE_BUFFER (pst);
|
dwarf_line_buffer = DWARF_LINE_BUFFER (pst);
|
||||||
baseaddr = ANOFFSET (pst->section_offsets, 0);
|
baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
|
||||||
cu_header_offset = offset;
|
cu_header_offset = offset;
|
||||||
info_ptr = dwarf_info_buffer + offset;
|
info_ptr = dwarf_info_buffer + offset;
|
||||||
|
|
||||||
|
@ -1362,7 +1379,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
symtab = end_symtab (highpc + baseaddr, objfile, 0);
|
symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
|
||||||
|
|
||||||
/* Set symtab language to language from DW_AT_language.
|
/* Set symtab language to language from DW_AT_language.
|
||||||
If the compilation is from a C file generated by language preprocessors,
|
If the compilation is from a C file generated by language preprocessors,
|
||||||
|
@ -3370,6 +3387,10 @@ read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
|
||||||
DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
|
DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
|
||||||
info_ptr += 4;
|
info_ptr += 4;
|
||||||
break;
|
break;
|
||||||
|
case DW_FORM_ref8:
|
||||||
|
DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
|
||||||
|
info_ptr += 8;
|
||||||
|
break;
|
||||||
case DW_FORM_ref_udata:
|
case DW_FORM_ref_udata:
|
||||||
DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
|
DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
|
||||||
info_ptr += bytes_read;
|
info_ptr += bytes_read;
|
||||||
|
@ -3472,6 +3493,89 @@ read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reads the initial length from a section. The (draft) DWARF 2.1
|
||||||
|
specification allows the initial length to take up either 4 bytes
|
||||||
|
or 12 bytes. If the first 4 bytes are 0xffffffff, then the next 8
|
||||||
|
bytes describe the length and all offsets will be 8 bytes in length
|
||||||
|
instead of 4.
|
||||||
|
|
||||||
|
The value returned via bytes_read should be used to increment
|
||||||
|
the relevant pointer after calling read_initial_length().
|
||||||
|
|
||||||
|
As a side effect, this function sets the fields initial_length_size
|
||||||
|
and offset_size in cu_header to the values appropriate for the
|
||||||
|
length field. (The format of the initial length field determines
|
||||||
|
the width of file offsets to be fetched later with fetch_offset().)
|
||||||
|
|
||||||
|
[ Note: read_initial_length() and read_offset() are based on the
|
||||||
|
document entitled "DWARF Debugging Information Format", revision
|
||||||
|
2.1, draft 4, dated July 20, 2000. This document was obtained
|
||||||
|
from:
|
||||||
|
|
||||||
|
http://reality.sgi.com/dehnert_engr/dwarf/dwarf2p1-draft4-000720.pdf
|
||||||
|
|
||||||
|
This document is only a draft and is subject to change. (So beware.)
|
||||||
|
|
||||||
|
- Kevin, Sept 4, 2000
|
||||||
|
] */
|
||||||
|
|
||||||
|
static LONGEST
|
||||||
|
read_initial_length (bfd *abfd, char *buf, struct comp_unit_head *cu_header,
|
||||||
|
int *bytes_read)
|
||||||
|
{
|
||||||
|
LONGEST retval = 0;
|
||||||
|
|
||||||
|
retval = bfd_get_32 (abfd, (bfd_byte *) buf);
|
||||||
|
|
||||||
|
if (retval == 0xffffffff)
|
||||||
|
{
|
||||||
|
retval = bfd_get_64 (abfd, (bfd_byte *) buf + 4);
|
||||||
|
*bytes_read = 12;
|
||||||
|
if (cu_header != NULL)
|
||||||
|
{
|
||||||
|
cu_header->initial_length_size = 12;
|
||||||
|
cu_header->offset_size = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*bytes_read = 4;
|
||||||
|
if (cu_header != NULL)
|
||||||
|
{
|
||||||
|
cu_header->initial_length_size = 4;
|
||||||
|
cu_header->offset_size = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read an offset from the data stream. The size of the offset is
|
||||||
|
given by cu_header->offset_size. */
|
||||||
|
|
||||||
|
static LONGEST
|
||||||
|
read_offset (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
|
||||||
|
int *bytes_read)
|
||||||
|
{
|
||||||
|
LONGEST retval = 0;
|
||||||
|
|
||||||
|
switch (cu_header->offset_size)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
retval = bfd_get_32 (abfd, (bfd_byte *) buf);
|
||||||
|
*bytes_read = 4;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
retval = bfd_get_64 (abfd, (bfd_byte *) buf);
|
||||||
|
*bytes_read = 8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
internal_error ("read_offset: bad switch");
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
read_n_bytes (bfd *abfd, char *buf, unsigned int size)
|
read_n_bytes (bfd *abfd, char *buf, unsigned int size)
|
||||||
{
|
{
|
||||||
|
@ -3713,13 +3817,13 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
||||||
line_ptr = dwarf_line_buffer + offset;
|
line_ptr = dwarf_line_buffer + offset;
|
||||||
|
|
||||||
/* read in the prologue */
|
/* read in the prologue */
|
||||||
lh.total_length = read_4_bytes (abfd, line_ptr);
|
lh.total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
|
||||||
line_ptr += 4;
|
line_ptr += bytes_read;
|
||||||
line_end = line_ptr + lh.total_length;
|
line_end = line_ptr + lh.total_length;
|
||||||
lh.version = read_2_bytes (abfd, line_ptr);
|
lh.version = read_2_bytes (abfd, line_ptr);
|
||||||
line_ptr += 2;
|
line_ptr += 2;
|
||||||
lh.prologue_length = read_4_bytes (abfd, line_ptr);
|
lh.prologue_length = read_offset (abfd, line_ptr, cu_header, &bytes_read);
|
||||||
line_ptr += 4;
|
line_ptr += bytes_read;
|
||||||
lh.minimum_instruction_length = read_1_byte (abfd, line_ptr);
|
lh.minimum_instruction_length = read_1_byte (abfd, line_ptr);
|
||||||
line_ptr += 1;
|
line_ptr += 1;
|
||||||
lh.default_is_stmt = read_1_byte (abfd, line_ptr);
|
lh.default_is_stmt = read_1_byte (abfd, line_ptr);
|
||||||
|
@ -5512,6 +5616,7 @@ dwarf2_get_ref_die_offset (struct attribute *attr)
|
||||||
case DW_FORM_ref1:
|
case DW_FORM_ref1:
|
||||||
case DW_FORM_ref2:
|
case DW_FORM_ref2:
|
||||||
case DW_FORM_ref4:
|
case DW_FORM_ref4:
|
||||||
|
case DW_FORM_ref8:
|
||||||
case DW_FORM_ref_udata:
|
case DW_FORM_ref_udata:
|
||||||
result = cu_header_offset + DW_UNSND (attr);
|
result = cu_header_offset + DW_UNSND (attr);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue