Line 88... |
Line 88... |
struct comp_unit *all_comp_units;
|
struct comp_unit *all_comp_units;
|
|
|
/* Last comp unit in list above. */
|
/* Last comp unit in list above. */
|
struct comp_unit *last_comp_unit;
|
struct comp_unit *last_comp_unit;
|
|
|
|
/* Names of the debug sections. */
|
|
const struct dwarf_debug_section *debug_sections;
|
|
|
/* The next unread compilation unit within the .debug_info section.
|
/* The next unread compilation unit within the .debug_info section.
|
Zero indicates that the .debug_info section has not been loaded
|
Zero indicates that the .debug_info section has not been loaded
|
into a buffer yet. */
|
into a buffer yet. */
|
bfd_byte *info_ptr;
|
bfd_byte *info_ptr;
|
|
|
Line 467... |
Line 470... |
section contents, otherwise use bfd_get_section_contents. Fail if
|
section contents, otherwise use bfd_get_section_contents. Fail if
|
the located section does not contain at least OFFSET bytes. */
|
the located section does not contain at least OFFSET bytes. */
|
|
|
static bfd_boolean
|
static bfd_boolean
|
read_section (bfd * abfd,
|
read_section (bfd * abfd,
|
enum dwarf_debug_section_enum sec,
|
const struct dwarf_debug_section *sec,
|
asymbol ** syms,
|
asymbol ** syms,
|
bfd_uint64_t offset,
|
bfd_uint64_t offset,
|
bfd_byte ** section_buffer,
|
bfd_byte ** section_buffer,
|
bfd_size_type * section_size)
|
bfd_size_type * section_size)
|
{
|
{
|
asection *msec;
|
asection *msec;
|
const char *section_name = dwarf_debug_sections[sec].uncompressed_name;
|
const char *section_name = sec->uncompressed_name;
|
|
|
/* read_section is a noop if the section has already been read. */
|
/* read_section is a noop if the section has already been read. */
|
if (!*section_buffer)
|
if (!*section_buffer)
|
{
|
{
|
msec = bfd_get_section_by_name (abfd, section_name);
|
msec = bfd_get_section_by_name (abfd, section_name);
|
if (! msec)
|
if (! msec)
|
{
|
{
|
section_name = dwarf_debug_sections[sec].compressed_name;
|
section_name = sec->compressed_name;
|
|
if (section_name != NULL)
|
msec = bfd_get_section_by_name (abfd, section_name);
|
msec = bfd_get_section_by_name (abfd, section_name);
|
}
|
}
|
if (! msec)
|
if (! msec)
|
{
|
{
|
(*_bfd_error_handler) (_("Dwarf Error: Can't find %s section."), section_name);
|
(*_bfd_error_handler) (_("Dwarf Error: Can't find %s section."),
|
|
sec->uncompressed_name);
|
bfd_set_error (bfd_error_bad_value);
|
bfd_set_error (bfd_error_bad_value);
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
*section_size = msec->rawsize ? msec->rawsize : msec->size;
|
*section_size = msec->rawsize ? msec->rawsize : msec->size;
|
Line 604... |
Line 609... |
else
|
else
|
offset = read_8_bytes (unit->abfd, buf);
|
offset = read_8_bytes (unit->abfd, buf);
|
|
|
*bytes_read_ptr = unit->offset_size;
|
*bytes_read_ptr = unit->offset_size;
|
|
|
if (! read_section (unit->abfd, debug_str, stash->syms, offset,
|
if (! read_section (unit->abfd, &stash->debug_sections[debug_str],
|
|
stash->syms, offset,
|
&stash->dwarf_str_buffer, &stash->dwarf_str_size))
|
&stash->dwarf_str_buffer, &stash->dwarf_str_size))
|
return NULL;
|
return NULL;
|
|
|
str = (char *) stash->dwarf_str_buffer + offset;
|
str = (char *) stash->dwarf_str_buffer + offset;
|
if (*str == '\0')
|
if (*str == '\0')
|
Line 686... |
Line 692... |
struct abbrev_info *cur_abbrev;
|
struct abbrev_info *cur_abbrev;
|
unsigned int abbrev_number, bytes_read, abbrev_name;
|
unsigned int abbrev_number, bytes_read, abbrev_name;
|
unsigned int abbrev_form, hash_number;
|
unsigned int abbrev_form, hash_number;
|
bfd_size_type amt;
|
bfd_size_type amt;
|
|
|
if (! read_section (abfd, debug_abbrev, stash->syms, offset,
|
if (! read_section (abfd, &stash->debug_sections[debug_abbrev],
|
|
stash->syms, offset,
|
&stash->dwarf_abbrev_buffer, &stash->dwarf_abbrev_size))
|
&stash->dwarf_abbrev_buffer, &stash->dwarf_abbrev_size))
|
return NULL;
|
return NULL;
|
|
|
amt = sizeof (struct abbrev_info*) * ABBREV_HASH_SIZE;
|
amt = sizeof (struct abbrev_info*) * ABBREV_HASH_SIZE;
|
abbrevs = (struct abbrev_info **) bfd_zalloc (abfd, amt);
|
abbrevs = (struct abbrev_info **) bfd_zalloc (abfd, amt);
|
Line 1394... |
Line 1401... |
unsigned int i, bytes_read, offset_size;
|
unsigned int i, bytes_read, offset_size;
|
char *cur_file, *cur_dir;
|
char *cur_file, *cur_dir;
|
unsigned char op_code, extended_op, adj_opcode;
|
unsigned char op_code, extended_op, adj_opcode;
|
bfd_size_type amt;
|
bfd_size_type amt;
|
|
|
if (! read_section (abfd, debug_line, stash->syms, unit->line_offset,
|
if (! read_section (abfd, &stash->debug_sections[debug_line],
|
|
stash->syms, unit->line_offset,
|
&stash->dwarf_line_buffer, &stash->dwarf_line_size))
|
&stash->dwarf_line_buffer, &stash->dwarf_line_size))
|
return NULL;
|
return NULL;
|
|
|
amt = sizeof (struct line_info_table);
|
amt = sizeof (struct line_info_table);
|
table = (struct line_info_table *) bfd_alloc (abfd, amt);
|
table = (struct line_info_table *) bfd_alloc (abfd, amt);
|
Line 1809... |
Line 1817... |
|
|
static bfd_boolean
|
static bfd_boolean
|
read_debug_ranges (struct comp_unit *unit)
|
read_debug_ranges (struct comp_unit *unit)
|
{
|
{
|
struct dwarf2_debug *stash = unit->stash;
|
struct dwarf2_debug *stash = unit->stash;
|
return read_section (unit->abfd, debug_ranges, stash->syms, 0,
|
return read_section (unit->abfd, &stash->debug_sections[debug_ranges],
|
|
stash->syms, 0,
|
&stash->dwarf_ranges_buffer, &stash->dwarf_ranges_size);
|
&stash->dwarf_ranges_buffer, &stash->dwarf_ranges_size);
|
}
|
}
|
|
|
/* Function table functions. */
|
/* Function table functions. */
|
|
|
Line 2715... |
Line 2724... |
}
|
}
|
|
|
/* Locate a section in a BFD containing debugging info. The search starts
|
/* Locate a section in a BFD containing debugging info. The search starts
|
from the section after AFTER_SEC, or from the first section in the BFD if
|
from the section after AFTER_SEC, or from the first section in the BFD if
|
AFTER_SEC is NULL. The search works by examining the names of the
|
AFTER_SEC is NULL. The search works by examining the names of the
|
sections. There are two permissiable names. The first is .debug_info.
|
sections. There are three permissiable names. The first two are given
|
This is the standard DWARF2 name. The second is a prefix .gnu.linkonce.wi.
|
by DEBUG_SECTIONS[debug_info] (whose standard DWARF2 names are .debug_info
|
|
and .zdebug_info). The third is a prefix .gnu.linkonce.wi.
|
This is a variation on the .debug_info section which has a checksum
|
This is a variation on the .debug_info section which has a checksum
|
describing the contents appended onto the name. This allows the linker to
|
describing the contents appended onto the name. This allows the linker to
|
identify and discard duplicate debugging sections for different
|
identify and discard duplicate debugging sections for different
|
compilation units. */
|
compilation units. */
|
#define DWARF2_DEBUG_INFO ".debug_info"
|
|
#define DWARF2_COMPRESSED_DEBUG_INFO ".zdebug_info"
|
|
#define GNU_LINKONCE_INFO ".gnu.linkonce.wi."
|
#define GNU_LINKONCE_INFO ".gnu.linkonce.wi."
|
|
|
static asection *
|
static asection *
|
find_debug_info (bfd *abfd, asection *after_sec)
|
find_debug_info (bfd *abfd, const struct dwarf_debug_section *debug_sections,
|
|
asection *after_sec)
|
{
|
{
|
asection * msec;
|
asection * msec;
|
|
|
msec = after_sec != NULL ? after_sec->next : abfd->sections;
|
msec = after_sec != NULL ? after_sec->next : abfd->sections;
|
|
|
while (msec)
|
while (msec)
|
{
|
{
|
if (strcmp (msec->name, DWARF2_DEBUG_INFO) == 0)
|
if (strcmp (msec->name,
|
|
debug_sections[debug_info].uncompressed_name) == 0)
|
return msec;
|
return msec;
|
|
|
if (strcmp (msec->name, DWARF2_COMPRESSED_DEBUG_INFO) == 0)
|
if (debug_sections[debug_info].compressed_name != NULL
|
|
&& strcmp (msec->name,
|
|
debug_sections[debug_info].compressed_name) == 0)
|
return msec;
|
return msec;
|
|
|
if (CONST_STRNEQ (msec->name, GNU_LINKONCE_INFO))
|
if (CONST_STRNEQ (msec->name, GNU_LINKONCE_INFO))
|
return msec;
|
return msec;
|
|
|
Line 2784... |
Line 2796... |
else
|
else
|
{
|
{
|
asection *sect;
|
asection *sect;
|
bfd_vma last_vma = 0, last_dwarf = 0;
|
bfd_vma last_vma = 0, last_dwarf = 0;
|
bfd_size_type amt;
|
bfd_size_type amt;
|
|
const char *debug_info_name;
|
|
|
|
debug_info_name = stash->debug_sections[debug_info].uncompressed_name;
|
i = 0;
|
i = 0;
|
for (sect = abfd->sections; sect != NULL; sect = sect->next)
|
for (sect = abfd->sections; sect != NULL; sect = sect->next)
|
{
|
{
|
bfd_size_type sz;
|
bfd_size_type sz;
|
int is_debug_info;
|
int is_debug_info;
|
Line 2797... |
Line 2811... |
continue;
|
continue;
|
|
|
/* We need to adjust the VMAs of any .debug_info sections.
|
/* We need to adjust the VMAs of any .debug_info sections.
|
Skip compressed ones, since no relocations could target
|
Skip compressed ones, since no relocations could target
|
them - they should not appear in object files anyway. */
|
them - they should not appear in object files anyway. */
|
if (strcmp (sect->name, DWARF2_DEBUG_INFO) == 0)
|
if (strcmp (sect->name, debug_info_name) == 0)
|
is_debug_info = 1;
|
is_debug_info = 1;
|
else if (CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO))
|
else if (CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO))
|
is_debug_info = 1;
|
is_debug_info = 1;
|
else
|
else
|
is_debug_info = 0;
|
is_debug_info = 0;
|
Line 2833... |
Line 2847... |
continue;
|
continue;
|
|
|
/* We need to adjust the VMAs of any .debug_info sections.
|
/* We need to adjust the VMAs of any .debug_info sections.
|
Skip compressed ones, since no relocations could target
|
Skip compressed ones, since no relocations could target
|
them - they should not appear in object files anyway. */
|
them - they should not appear in object files anyway. */
|
if (strcmp (sect->name, DWARF2_DEBUG_INFO) == 0)
|
if (strcmp (sect->name, debug_info_name) == 0)
|
is_debug_info = 1;
|
is_debug_info = 1;
|
else if (CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO))
|
else if (CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO))
|
is_debug_info = 1;
|
is_debug_info = 1;
|
else
|
else
|
is_debug_info = 0;
|
is_debug_info = 0;
|
Line 3108... |
Line 3122... |
the address SECTION + OFFSET.
|
the address SECTION + OFFSET.
|
Returns TRUE if the line is found without error and fills in
|
Returns TRUE if the line is found without error and fills in
|
FILENAME_PTR and LINENUMBER_PTR. In the case where SYMBOL was
|
FILENAME_PTR and LINENUMBER_PTR. In the case where SYMBOL was
|
NULL the FUNCTIONNAME_PTR is also filled in.
|
NULL the FUNCTIONNAME_PTR is also filled in.
|
SYMBOLS contains the symbol table for ABFD.
|
SYMBOLS contains the symbol table for ABFD.
|
|
DEBUG_SECTIONS contains the name of the dwarf debug sections.
|
ADDR_SIZE is the number of bytes in the initial .debug_info length
|
ADDR_SIZE is the number of bytes in the initial .debug_info length
|
field and in the abbreviation offset, or zero to indicate that the
|
field and in the abbreviation offset, or zero to indicate that the
|
default value should be used. */
|
default value should be used. */
|
|
|
static bfd_boolean
|
static bfd_boolean
|
find_line (bfd *abfd,
|
find_line (bfd *abfd,
|
|
const struct dwarf_debug_section *debug_sections,
|
asection *section,
|
asection *section,
|
bfd_vma offset,
|
bfd_vma offset,
|
asymbol *symbol,
|
asymbol *symbol,
|
asymbol **symbols,
|
asymbol **symbols,
|
const char **filename_ptr,
|
const char **filename_ptr,
|
Line 3148... |
Line 3164... |
bfd_size_type amt = sizeof (struct dwarf2_debug);
|
bfd_size_type amt = sizeof (struct dwarf2_debug);
|
|
|
stash = (struct dwarf2_debug *) bfd_zalloc (abfd, amt);
|
stash = (struct dwarf2_debug *) bfd_zalloc (abfd, amt);
|
if (! stash)
|
if (! stash)
|
return FALSE;
|
return FALSE;
|
|
stash->debug_sections = debug_sections;
|
}
|
}
|
|
|
/* In a relocatable file, 2 functions may have the same address.
|
/* In a relocatable file, 2 functions may have the same address.
|
We change the section vma so that they won't overlap. */
|
We change the section vma so that they won't overlap. */
|
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
|
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
|
Line 3191... |
Line 3208... |
bfd_size_type total_size;
|
bfd_size_type total_size;
|
asection *msec;
|
asection *msec;
|
|
|
*pinfo = stash;
|
*pinfo = stash;
|
|
|
msec = find_debug_info (abfd, NULL);
|
msec = find_debug_info (abfd, debug_sections, NULL);
|
if (msec == NULL)
|
if (msec == NULL)
|
{
|
{
|
char * debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
|
char * debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
|
|
|
if (debug_filename == NULL)
|
if (debug_filename == NULL)
|
Line 3205... |
Line 3222... |
fail more quickly. */
|
fail more quickly. */
|
goto done;
|
goto done;
|
|
|
if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
|
if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
|
|| ! bfd_check_format (debug_bfd, bfd_object)
|
|| ! bfd_check_format (debug_bfd, bfd_object)
|
|| (msec = find_debug_info (debug_bfd, NULL)) == NULL)
|
|| (msec = find_debug_info (debug_bfd,
|
|
debug_sections, NULL)) == NULL)
|
{
|
{
|
if (debug_bfd)
|
if (debug_bfd)
|
bfd_close (debug_bfd);
|
bfd_close (debug_bfd);
|
/* FIXME: Should we report our failure to follow the debuglink ? */
|
/* FIXME: Should we report our failure to follow the debuglink ? */
|
free (debug_filename);
|
free (debug_filename);
|
Line 3228... |
Line 3246... |
read in the section's contents. (The allows us to avoid
|
read in the section's contents. (The allows us to avoid
|
reallocing the data as we add sections to the stash.) If
|
reallocing the data as we add sections to the stash.) If
|
some or all sections are compressed, then do things the slow
|
some or all sections are compressed, then do things the slow
|
way, with a bunch of reallocs. */
|
way, with a bunch of reallocs. */
|
|
|
if (! find_debug_info (debug_bfd, msec))
|
if (! find_debug_info (debug_bfd, debug_sections, msec))
|
{
|
{
|
/* Case 1: only one info section. */
|
/* Case 1: only one info section. */
|
total_size = msec->size;
|
total_size = msec->size;
|
if (! read_section (debug_bfd, debug_info, symbols, 0,
|
if (! read_section (debug_bfd, &stash->debug_sections[debug_info],
|
|
symbols, 0,
|
&stash->info_ptr_memory, &total_size))
|
&stash->info_ptr_memory, &total_size))
|
goto done;
|
goto done;
|
}
|
}
|
else
|
else
|
{
|
{
|
/* Case 2: multiple sections. */
|
/* Case 2: multiple sections. */
|
for (total_size = 0; msec; msec = find_debug_info (debug_bfd, msec))
|
for (total_size = 0;
|
|
msec;
|
|
msec = find_debug_info (debug_bfd, debug_sections, msec))
|
total_size += msec->size;
|
total_size += msec->size;
|
|
|
stash->info_ptr_memory = (bfd_byte *) bfd_malloc (total_size);
|
stash->info_ptr_memory = (bfd_byte *) bfd_malloc (total_size);
|
if (stash->info_ptr_memory == NULL)
|
if (stash->info_ptr_memory == NULL)
|
goto done;
|
goto done;
|
|
|
total_size = 0;
|
total_size = 0;
|
for (msec = find_debug_info (debug_bfd, NULL);
|
for (msec = find_debug_info (debug_bfd, debug_sections, NULL);
|
msec;
|
msec;
|
msec = find_debug_info (debug_bfd, msec))
|
msec = find_debug_info (debug_bfd, debug_sections, msec))
|
{
|
{
|
bfd_size_type size;
|
bfd_size_type size;
|
|
|
size = msec->size;
|
size = msec->size;
|
if (size == 0)
|
if (size == 0)
|
Line 3268... |
Line 3289... |
}
|
}
|
}
|
}
|
|
|
stash->info_ptr = stash->info_ptr_memory;
|
stash->info_ptr = stash->info_ptr_memory;
|
stash->info_ptr_end = stash->info_ptr + total_size;
|
stash->info_ptr_end = stash->info_ptr + total_size;
|
stash->sec = find_debug_info (debug_bfd, NULL);
|
stash->sec = find_debug_info (debug_bfd, debug_sections, NULL);
|
stash->sec_info_ptr = stash->info_ptr;
|
stash->sec_info_ptr = stash->info_ptr;
|
stash->syms = symbols;
|
stash->syms = symbols;
|
stash->bfd_ptr = debug_bfd;
|
stash->bfd_ptr = debug_bfd;
|
}
|
}
|
|
|
Line 3423... |
Line 3444... |
stash));
|
stash));
|
|
|
if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
|
if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
|
== stash->sec->size)
|
== stash->sec->size)
|
{
|
{
|
stash->sec = find_debug_info (stash->bfd_ptr, stash->sec);
|
stash->sec = find_debug_info (stash->bfd_ptr, debug_sections,
|
|
stash->sec);
|
stash->sec_info_ptr = stash->info_ptr;
|
stash->sec_info_ptr = stash->info_ptr;
|
}
|
}
|
|
|
if (found)
|
if (found)
|
goto done;
|
goto done;
|
Line 3444... |
Line 3466... |
/* The DWARF2 version of find_nearest_line.
|
/* The DWARF2 version of find_nearest_line.
|
Return TRUE if the line is found without error. */
|
Return TRUE if the line is found without error. */
|
|
|
bfd_boolean
|
bfd_boolean
|
_bfd_dwarf2_find_nearest_line (bfd *abfd,
|
_bfd_dwarf2_find_nearest_line (bfd *abfd,
|
|
const struct dwarf_debug_section *debug_sections,
|
asection *section,
|
asection *section,
|
asymbol **symbols,
|
asymbol **symbols,
|
bfd_vma offset,
|
bfd_vma offset,
|
const char **filename_ptr,
|
const char **filename_ptr,
|
const char **functionname_ptr,
|
const char **functionname_ptr,
|
unsigned int *linenumber_ptr,
|
unsigned int *linenumber_ptr,
|
unsigned int addr_size,
|
unsigned int addr_size,
|
void **pinfo)
|
void **pinfo)
|
{
|
{
|
return find_line (abfd, section, offset, NULL, symbols, filename_ptr,
|
return find_line (abfd, debug_sections, section, offset, NULL, symbols,
|
functionname_ptr, linenumber_ptr, addr_size,
|
filename_ptr, functionname_ptr, linenumber_ptr, addr_size,
|
pinfo);
|
pinfo);
|
}
|
}
|
|
|
/* The DWARF2 version of find_line.
|
/* The DWARF2 version of find_line.
|
Return TRUE if the line is found without error. */
|
Return TRUE if the line is found without error. */
|
Line 3470... |
Line 3493... |
const char **filename_ptr,
|
const char **filename_ptr,
|
unsigned int *linenumber_ptr,
|
unsigned int *linenumber_ptr,
|
unsigned int addr_size,
|
unsigned int addr_size,
|
void **pinfo)
|
void **pinfo)
|
{
|
{
|
return find_line (abfd, NULL, 0, symbol, symbols, filename_ptr,
|
return find_line (abfd, dwarf_debug_sections, NULL, 0, symbol, symbols,
|
NULL, linenumber_ptr, addr_size,
|
filename_ptr, NULL, linenumber_ptr, addr_size, pinfo);
|
pinfo);
|
|
}
|
}
|
|
|
bfd_boolean
|
bfd_boolean
|
_bfd_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
|
_bfd_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
|
const char **filename_ptr,
|
const char **filename_ptr,
|