@ -75,7 +75,7 @@ struct dwarf_block
bfd_byte * data ;
} ;
struct loadable _section
struct adjusted _section
{
asection * section ;
bfd_vma adj_vma ;
@ -143,11 +143,11 @@ struct dwarf2_debug
use . */
struct funcinfo * inliner_chain ;
/* Number of loadable sections. */
unsigned int loadable _section_count;
/* Number of sections whose VMA we must adjust . */
unsigned int adjusted _section_count;
/* Array of loadable sections. */
struct loadable_section * loadable _sections;
/* Array of sections with adjusted VMA . */
struct adjusted_section * adjusted _sections;
/* Number of times find_line is called. This is used in
the heuristic for enabling the info hash tables . */
@ -237,6 +237,9 @@ struct comp_unit
/* Pointer to dwarf2_debug structure. */
struct dwarf2_debug * stash ;
/* DWARF format version for this unit - from unit header. */
int version ;
/* Address size for this unit - from unit header. */
unsigned char addr_size ;
@ -742,9 +745,20 @@ read_attribute_value (struct attribute *attr,
switch ( form )
{
case DW_FORM_addr :
/* FIXME: DWARF3 draft says DW_FORM_ref_addr is offset_size. */
case DW_FORM_ref_addr :
/* DW_FORM_ref_addr is an address in DWARF2, and an offset in
DWARF3 . */
if ( unit - > version = = 3 )
{
if ( unit - > offset_size = = 4 )
attr - > u . val = read_4_bytes ( unit - > abfd , info_ptr ) ;
else
attr - > u . val = read_8_bytes ( unit - > abfd , info_ptr ) ;
info_ptr + = unit - > offset_size ;
break ;
}
/* FALLTHROUGH */
case DW_FORM_addr :
attr - > u . val = read_address ( unit , info_ptr ) ;
info_ptr + = unit - > addr_size ;
break ;
@ -1705,16 +1719,30 @@ lookup_symbol_in_variable_table (struct comp_unit *unit,
}
static char *
find_abstract_instance_name ( struct comp_unit * unit , bfd_uint64_t die_ref )
find_abstract_instance_name ( struct comp_unit * unit ,
struct attribute * attr_ptr )
{
bfd * abfd = unit - > abfd ;
bfd_byte * info_ptr ;
unsigned int abbrev_number , bytes_read , i ;
struct abbrev_info * abbrev ;
bfd_uint64_t die_ref = attr_ptr - > u . val ;
struct attribute attr ;
char * name = 0 ;
info_ptr = unit - > info_ptr_unit + die_ref ;
/* DW_FORM_ref_addr can reference an entry in a different CU. It
is an offset from the . debug_info section , not the current CU . */
if ( attr_ptr - > form = = DW_FORM_ref_addr )
{
/* We only support DW_FORM_ref_addr within the same file, so
any relocations should be resolved already . */
if ( ! die_ref )
abort ( ) ;
info_ptr = unit - > stash - > sec_info_ptr + die_ref ;
}
else
info_ptr = unit - > info_ptr_unit + die_ref ;
abbrev_number = read_unsigned_leb128 ( abfd , info_ptr , & bytes_read ) ;
info_ptr + = bytes_read ;
@ -1740,7 +1768,7 @@ find_abstract_instance_name (struct comp_unit *unit, bfd_uint64_t die_ref)
name = attr . u . str ;
break ;
case DW_AT_specification :
name = find_abstract_instance_name ( unit , attr . u . val ) ;
name = find_abstract_instance_name ( unit , & attr ) ;
break ;
case DW_AT_MIPS_linkage_name :
name = attr . u . str ;
@ -1902,7 +1930,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
break ;
case DW_AT_abstract_origin :
func - > name = find_abstract_instance_name ( unit , attr . u . val ) ;
func - > name = find_abstract_instance_name ( unit , & attr ) ;
break ;
case DW_AT_name :
@ -2070,9 +2098,9 @@ parse_comp_unit (struct dwarf2_debug *stash,
addr_size = read_1_byte ( abfd , info_ptr ) ;
info_ptr + = 1 ;
if ( version ! = 2 )
if ( version ! = 2 & & version ! = 3 )
{
( * _bfd_error_handler ) ( _ ( " Dwarf Error: found dwarf version '%u', this reader only handles version 2 information. " ) , version ) ;
( * _bfd_error_handler ) ( _ ( " Dwarf Error: found dwarf version '%u', this reader only handles version 2 and 3 information. " ) , version ) ;
bfd_set_error ( bfd_error_bad_value ) ;
return 0 ;
}
@ -2120,6 +2148,7 @@ parse_comp_unit (struct dwarf2_debug *stash,
amt = sizeof ( struct comp_unit ) ;
unit = bfd_zalloc ( abfd , amt ) ;
unit - > abfd = abfd ;
unit - > version = version ;
unit - > addr_size = addr_size ;
unit - > offset_size = offset_size ;
unit - > abbrevs = abbrevs ;
@ -2472,49 +2501,63 @@ find_debug_info (bfd *abfd, asection *after_sec)
return NULL ;
}
/* Unset vmas for loadable sections in STASH. */
/* Unset vmas for adjusted sections in STASH. */
static void
unset_sections ( struct dwarf2_debug * stash )
{
unsigned int i ;
struct loadable _section * p ;
struct adjusted _section * p ;
i = stash - > loadable _section_count;
p = stash - > loadable _sections;
i = stash - > adjusted _section_count;
p = stash - > adjusted _sections;
for ( ; i > 0 ; i - - , p + + )
p - > section - > vma = 0 ;
}
/* Set unique vmas for loadable sections in ABFD and save vmas in
STASH for unset_sections . */
/* Set unique VMAs for loadable and DWARF sections in ABFD and save
VMAs in STASH for unset_sections . */
static bfd_boolean
place_sections ( bfd * abfd , struct dwarf2_debug * stash )
{
struct loadable _section * p ;
struct adjusted _section * p ;
unsigned int i ;
if ( stash - > loadable _section_count ! = 0 )
if ( stash - > adjusted _section_count ! = 0 )
{
i = stash - > loadable _section_count;
p = stash - > loadable _sections;
i = stash - > adjusted _section_count;
p = stash - > adjusted _sections;
for ( ; i > 0 ; i - - , p + + )
p - > section - > vma = p - > adj_vma ;
}
else
{
asection * sect ;
bfd_vma last_vma = 0 ;
bfd_vma last_vma = 0 , last_dwarf = 0 ;
bfd_size_type amt ;
struct loadable _section * p ;
struct adjusted _section * p ;
i = 0 ;
for ( sect = abfd - > sections ; sect ! = NULL ; sect = sect - > next )
{
bfd_size_type sz ;
int is_debug_info ;
if ( sect - > vma ! = 0 )
continue ;
/* We need to adjust the VMAs of any .debug_info sections.
Skip compressed ones , since no relocations could target
them - they should not appear in object files anyway . */
if ( strcmp ( sect - > name , DWARF2_DEBUG_INFO ) = = 0 )
is_debug_info = 1 ;
else if ( CONST_STRNEQ ( sect - > name , GNU_LINKONCE_INFO ) )
is_debug_info = 1 ;
else
is_debug_info = 0 ;
if ( sect - > vma ! = 0 | | ( sect - > flags & SEC_LOAD ) = = 0 )
if ( ! is_debug_info & & ( sect - > flags & SEC_LOAD ) = = 0 )
continue ;
sz = sect - > rawsize ? sect - > rawsize : sect - > size ;
@ -2524,19 +2567,33 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
i + + ;
}
amt = i * sizeof ( struct loadable _section) ;
p = ( struct loadable _section * ) bfd_zalloc ( abfd , amt ) ;
amt = i * sizeof ( struct adjusted _section) ;
p = ( struct adjusted _section * ) bfd_zalloc ( abfd , amt ) ;
if ( ! p )
return FALSE ;
stash - > loadable _sections = p ;
stash - > loadable _section_count = i ;
stash - > adjusted _sections = p ;
stash - > adjusted _section_count = i ;
for ( sect = abfd - > sections ; sect ! = NULL ; sect = sect - > next )
{
bfd_size_type sz ;
int is_debug_info ;
if ( sect - > vma ! = 0 | | ( sect - > flags & SEC_LOAD ) = = 0 )
if ( sect - > vma ! = 0 )
continue ;
/* We need to adjust the VMAs of any .debug_info sections.
Skip compressed ones , since no relocations could target
them - they should not appear in object files anyway . */
if ( strcmp ( sect - > name , DWARF2_DEBUG_INFO ) = = 0 )
is_debug_info = 1 ;
else if ( CONST_STRNEQ ( sect - > name , GNU_LINKONCE_INFO ) )
is_debug_info = 1 ;
else
is_debug_info = 0 ;
if ( ! is_debug_info & & ( sect - > flags & SEC_LOAD ) = = 0 )
continue ;
sz = sect - > rawsize ? sect - > rawsize : sect - > size ;
@ -2544,7 +2601,13 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
continue ;
p - > section = sect ;
if ( last_vma ! = 0 )
if ( is_debug_info )
{
BFD_ASSERT ( sect - > alignment_power = = 0 ) ;
sect - > vma = last_dwarf ;
last_dwarf + = sz ;
}
else if ( last_vma ! = 0 )
{
/* Align the new address to the current section
alignment . */
@ -2552,9 +2615,12 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
+ ~ ( ( bfd_vma ) - 1 < < sect - > alignment_power ) )
& ( ( bfd_vma ) - 1 < < sect - > alignment_power ) ) ;
sect - > vma = last_vma ;
last_vma + = sect - > vma + sz ;
}
else
last_vma + = sect - > vma + sz ;
p - > adj_vma = sect - > vma ;
last_vma + = sect - > vma + sz ;
p + + ;
}