| Index: bfd/dwarf2.c
|
| diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
|
| index 577f2783222a0b5eba1c42b7d7ec6e003ca903c6..d31b84939ad47b29643b3d39627bd8d2e28470d9 100644
|
| --- a/bfd/dwarf2.c
|
| +++ b/bfd/dwarf2.c
|
| @@ -405,8 +405,8 @@ create_info_hash_table (bfd *abfd)
|
| {
|
| struct info_hash_table *hash_table;
|
|
|
| - hash_table = (struct info_hash_table *)
|
| - bfd_alloc (abfd, sizeof (struct info_hash_table));
|
| + hash_table = ((struct info_hash_table *)
|
| + bfd_alloc (abfd, sizeof (struct info_hash_table)));
|
| if (!hash_table)
|
| return hash_table;
|
|
|
| @@ -503,7 +503,7 @@ read_section (bfd * abfd,
|
| if (syms)
|
| {
|
| *section_buffer
|
| - = bfd_simple_get_relocated_section_contents (abfd, msec, NULL, syms);
|
| + = bfd_simple_get_relocated_section_contents (abfd, msec, NULL, syms);
|
| if (! *section_buffer)
|
| return FALSE;
|
| }
|
| @@ -522,7 +522,8 @@ read_section (bfd * abfd,
|
| that the client wants. Validate it here to avoid trouble later. */
|
| if (offset != 0 && offset >= *section_size)
|
| {
|
| - (*_bfd_error_handler) (_("Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."),
|
| + (*_bfd_error_handler) (_("Dwarf Error: Offset (%lu)"
|
| + " greater than or equal to %s size (%lu)."),
|
| (long) offset, section_name, *section_size);
|
| bfd_set_error (bfd_error_bad_value);
|
| return FALSE;
|
| @@ -1014,20 +1015,27 @@ struct line_info_table
|
| /* Remember some information about each function. If the function is
|
| inlined (DW_TAG_inlined_subroutine) it may have two additional
|
| attributes, DW_AT_call_file and DW_AT_call_line, which specify the
|
| - source code location where this function was inlined. */
|
| + source code location where this function was inlined. */
|
|
|
| struct funcinfo
|
| {
|
| - struct funcinfo *prev_func; /* Pointer to previous function in list of all functions */
|
| - struct funcinfo *caller_func; /* Pointer to function one scope higher */
|
| - char *caller_file; /* Source location file name where caller_func inlines this func */
|
| - int caller_line; /* Source location line number where caller_func inlines this func */
|
| - char *file; /* Source location file name */
|
| - int line; /* Source location line number */
|
| + /* Pointer to previous function in list of all functions. */
|
| + struct funcinfo *prev_func;
|
| + /* Pointer to function one scope higher. */
|
| + struct funcinfo *caller_func;
|
| + /* Source location file name where caller_func inlines this func. */
|
| + char *caller_file;
|
| + /* Source location line number where caller_func inlines this func. */
|
| + int caller_line;
|
| + /* Source location file name. */
|
| + char *file;
|
| + /* Source location line number. */
|
| + int line;
|
| int tag;
|
| char *name;
|
| struct arange arange;
|
| - asection *sec; /* Where the symbol is defined */
|
| + /* Where the symbol is defined. */
|
| + asection *sec;
|
| };
|
|
|
| struct varinfo
|
| @@ -1248,12 +1256,16 @@ concat_filename (struct line_info_table *table, unsigned int file)
|
| }
|
|
|
| static bfd_boolean
|
| -arange_add (bfd *abfd, struct arange *first_arange,
|
| +arange_add (const struct comp_unit *unit, struct arange *first_arange,
|
| bfd_vma low_pc, bfd_vma high_pc)
|
| {
|
| struct arange *arange;
|
|
|
| - /* If the first arange is empty, use it. */
|
| + /* Ignore empty ranges. */
|
| + if (low_pc == high_pc)
|
| + return TRUE;
|
| +
|
| + /* If the first arange is empty, use it. */
|
| if (first_arange->high == 0)
|
| {
|
| first_arange->low = low_pc;
|
| @@ -1281,7 +1293,7 @@ arange_add (bfd *abfd, struct arange *first_arange,
|
|
|
| /* Need to allocate a new arange and insert it into the arange list.
|
| Order isn't significant, so just insert after the first arange. */
|
| - arange = (struct arange *) bfd_zalloc (abfd, sizeof (*arange));
|
| + arange = (struct arange *) bfd_alloc (unit->abfd, sizeof (*arange));
|
| if (arange == NULL)
|
| return FALSE;
|
| arange->low = low_pc;
|
| @@ -1401,6 +1413,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
|
| unsigned int i, bytes_read, offset_size;
|
| char *cur_file, *cur_dir;
|
| unsigned char op_code, extended_op, adj_opcode;
|
| + unsigned int exop_len;
|
| bfd_size_type amt;
|
|
|
| if (! read_section (abfd, &stash->debug_sections[debug_line],
|
| @@ -1581,15 +1594,15 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
|
| /* Special operand. */
|
| adj_opcode = op_code - lh.opcode_base;
|
| if (lh.maximum_ops_per_insn == 1)
|
| - address += (adj_opcode / lh.line_range)
|
| - * lh.minimum_instruction_length;
|
| + address += (adj_opcode / lh.line_range
|
| + * lh.minimum_instruction_length);
|
| else
|
| {
|
| - address += ((op_index + (adj_opcode / lh.line_range))
|
| - / lh.maximum_ops_per_insn)
|
| - * lh.minimum_instruction_length;
|
| - op_index = (op_index + (adj_opcode / lh.line_range))
|
| - % lh.maximum_ops_per_insn;
|
| + address += ((op_index + adj_opcode / lh.line_range)
|
| + / lh.maximum_ops_per_insn
|
| + * lh.minimum_instruction_length);
|
| + op_index = ((op_index + adj_opcode / lh.line_range)
|
| + % lh.maximum_ops_per_insn);
|
| }
|
| line += lh.line_base + (adj_opcode % lh.line_range);
|
| /* Append row to matrix using current values. */
|
| @@ -1604,8 +1617,8 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
|
| else switch (op_code)
|
| {
|
| case DW_LNS_extended_op:
|
| - /* Ignore length. */
|
| - line_ptr += 1;
|
| + exop_len = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
| + line_ptr += bytes_read;
|
| extended_op = read_1_byte (abfd, line_ptr);
|
| line_ptr += 1;
|
|
|
| @@ -1620,7 +1633,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
|
| low_pc = address;
|
| if (address > high_pc)
|
| high_pc = address;
|
| - if (!arange_add (unit->abfd, &unit->arange, low_pc, high_pc))
|
| + if (!arange_add (unit, &unit->arange, low_pc, high_pc))
|
| goto line_fail;
|
| break;
|
| case DW_LNE_set_address:
|
| @@ -1658,8 +1671,12 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
|
| (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
| line_ptr += bytes_read;
|
| break;
|
| + case DW_LNE_HP_source_file_correlation:
|
| + line_ptr += exop_len - 1;
|
| + break;
|
| default:
|
| - (*_bfd_error_handler) (_("Dwarf Error: mangled line number section."));
|
| + (*_bfd_error_handler)
|
| + (_("Dwarf Error: mangled line number section."));
|
| bfd_set_error (bfd_error_bad_value);
|
| line_fail:
|
| if (filename != NULL)
|
| @@ -1678,15 +1695,15 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
|
| break;
|
| case DW_LNS_advance_pc:
|
| if (lh.maximum_ops_per_insn == 1)
|
| - address += lh.minimum_instruction_length
|
| - * read_unsigned_leb128 (abfd, line_ptr,
|
| - &bytes_read);
|
| + address += (lh.minimum_instruction_length
|
| + * read_unsigned_leb128 (abfd, line_ptr,
|
| + &bytes_read));
|
| else
|
| {
|
| bfd_vma adjust = read_unsigned_leb128 (abfd, line_ptr,
|
| &bytes_read);
|
| - address = ((op_index + adjust) / lh.maximum_ops_per_insn)
|
| - * lh.minimum_instruction_length;
|
| + address = ((op_index + adjust) / lh.maximum_ops_per_insn
|
| + * lh.minimum_instruction_length);
|
| op_index = (op_index + adjust) % lh.maximum_ops_per_insn;
|
| }
|
| line_ptr += bytes_read;
|
| @@ -1719,13 +1736,14 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
|
| break;
|
| case DW_LNS_const_add_pc:
|
| if (lh.maximum_ops_per_insn == 1)
|
| - address += lh.minimum_instruction_length
|
| - * ((255 - lh.opcode_base) / lh.line_range);
|
| + address += (lh.minimum_instruction_length
|
| + * ((255 - lh.opcode_base) / lh.line_range));
|
| else
|
| {
|
| bfd_vma adjust = ((255 - lh.opcode_base) / lh.line_range);
|
| - address += lh.minimum_instruction_length
|
| - * ((op_index + adjust) / lh.maximum_ops_per_insn);
|
| + address += (lh.minimum_instruction_length
|
| + * ((op_index + adjust)
|
| + / lh.maximum_ops_per_insn));
|
| op_index = (op_index + adjust) % lh.maximum_ops_per_insn;
|
| }
|
| break;
|
| @@ -1851,8 +1869,9 @@ lookup_address_in_function_table (struct comp_unit *unit,
|
| {
|
| if (addr >= arange->low && addr < arange->high)
|
| {
|
| - if (!best_fit ||
|
| - ((arange->high - arange->low) < (best_fit->arange.high - best_fit->arange.low)))
|
| + if (!best_fit
|
| + || (arange->high - arange->low
|
| + < best_fit->arange.high - best_fit->arange.low))
|
| best_fit = each_func;
|
| }
|
| }
|
| @@ -1900,8 +1919,8 @@ lookup_symbol_in_function_table (struct comp_unit *unit,
|
| && each_func->name
|
| && strcmp (name, each_func->name) == 0
|
| && (!best_fit
|
| - || ((arange->high - arange->low)
|
| - < (best_fit->arange.high - best_fit->arange.low))))
|
| + || (arange->high - arange->low
|
| + < best_fit->arange.high - best_fit->arange.low)))
|
| best_fit = each_func;
|
| }
|
| }
|
| @@ -1986,8 +2005,8 @@ find_abstract_instance_name (struct comp_unit *unit,
|
| abbrev = lookup_abbrev (abbrev_number, unit->abbrevs);
|
| if (! abbrev)
|
| {
|
| - (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."),
|
| - abbrev_number);
|
| + (*_bfd_error_handler)
|
| + (_("Dwarf Error: Could not find abbrev number %u."), abbrev_number);
|
| bfd_set_error (bfd_error_bad_value);
|
| }
|
| else
|
| @@ -2052,7 +2071,7 @@ read_rangelist (struct comp_unit *unit, struct arange *arange,
|
| base_address = high_pc;
|
| else
|
| {
|
| - if (!arange_add (unit->abfd, arange,
|
| + if (!arange_add (unit, arange,
|
| base_address + low_pc, base_address + high_pc))
|
| return FALSE;
|
| }
|
| @@ -2078,7 +2097,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
|
| can use to set the caller_func field. */
|
| nested_funcs_size = 32;
|
| nested_funcs = (struct funcinfo **)
|
| - bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *));
|
| + bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *));
|
| if (nested_funcs == NULL)
|
| return FALSE;
|
| nested_funcs[nesting_level] = 0;
|
| @@ -2092,6 +2111,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
|
| struct varinfo *var;
|
| bfd_vma low_pc = 0;
|
| bfd_vma high_pc = 0;
|
| + bfd_boolean high_pc_relative = FALSE;
|
|
|
| abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
|
| info_ptr += bytes_read;
|
| @@ -2197,6 +2217,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
|
|
|
| case DW_AT_high_pc:
|
| high_pc = attr.u.val;
|
| + high_pc_relative = attr.form != DW_FORM_addr;
|
| break;
|
|
|
| case DW_AT_ranges:
|
| @@ -2275,9 +2296,12 @@ scan_unit_for_symbols (struct comp_unit *unit)
|
| }
|
| }
|
|
|
| + if (high_pc_relative)
|
| + high_pc += low_pc;
|
| +
|
| if (func && high_pc != 0)
|
| {
|
| - if (!arange_add (unit->abfd, &func->arange, low_pc, high_pc))
|
| + if (!arange_add (unit, &func->arange, low_pc, high_pc))
|
| goto fail;
|
| }
|
|
|
| @@ -2291,8 +2315,8 @@ scan_unit_for_symbols (struct comp_unit *unit)
|
|
|
| nested_funcs_size *= 2;
|
| tmp = (struct funcinfo **)
|
| - bfd_realloc (nested_funcs,
|
| - (nested_funcs_size * sizeof (struct funcinfo *)));
|
| + bfd_realloc (nested_funcs,
|
| + nested_funcs_size * sizeof (struct funcinfo *));
|
| if (tmp == NULL)
|
| goto fail;
|
| nested_funcs = tmp;
|
| @@ -2338,6 +2362,7 @@ parse_comp_unit (struct dwarf2_debug *stash,
|
| bfd_vma low_pc = 0;
|
| bfd_vma high_pc = 0;
|
| bfd *abfd = stash->bfd_ptr;
|
| + bfd_boolean high_pc_relative = FALSE;
|
|
|
| version = read_2_bytes (abfd, info_ptr);
|
| info_ptr += 2;
|
| @@ -2352,23 +2377,29 @@ parse_comp_unit (struct dwarf2_debug *stash,
|
|
|
| if (version != 2 && version != 3 && version != 4)
|
| {
|
| - (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."), version);
|
| + (*_bfd_error_handler)
|
| + (_("Dwarf Error: found dwarf version '%u', this reader"
|
| + " only handles version 2, 3 and 4 information."), version);
|
| bfd_set_error (bfd_error_bad_value);
|
| return 0;
|
| }
|
|
|
| if (addr_size > sizeof (bfd_vma))
|
| {
|
| - (*_bfd_error_handler) (_("Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."),
|
| - addr_size,
|
| - (unsigned int) sizeof (bfd_vma));
|
| + (*_bfd_error_handler)
|
| + (_("Dwarf Error: found address size '%u', this reader"
|
| + " can not handle sizes greater than '%u'."),
|
| + addr_size,
|
| + (unsigned int) sizeof (bfd_vma));
|
| bfd_set_error (bfd_error_bad_value);
|
| return 0;
|
| }
|
|
|
| if (addr_size != 2 && addr_size != 4 && addr_size != 8)
|
| {
|
| - (*_bfd_error_handler) ("Dwarf Error: found address size '%u', this reader can only handle address sizes '2', '4' and '8'.", addr_size);
|
| + (*_bfd_error_handler)
|
| + ("Dwarf Error: found address size '%u', this reader"
|
| + " can only handle address sizes '2', '4' and '8'.", addr_size);
|
| bfd_set_error (bfd_error_bad_value);
|
| return 0;
|
| }
|
| @@ -2376,14 +2407,14 @@ parse_comp_unit (struct dwarf2_debug *stash,
|
| /* Read the abbrevs for this compilation unit into a table. */
|
| abbrevs = read_abbrevs (abfd, abbrev_offset, stash);
|
| if (! abbrevs)
|
| - return 0;
|
| + return 0;
|
|
|
| abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
|
| info_ptr += bytes_read;
|
| if (! abbrev_number)
|
| {
|
| (*_bfd_error_handler) (_("Dwarf Error: Bad abbrev number: %u."),
|
| - abbrev_number);
|
| + abbrev_number);
|
| bfd_set_error (bfd_error_bad_value);
|
| return 0;
|
| }
|
| @@ -2392,7 +2423,7 @@ parse_comp_unit (struct dwarf2_debug *stash,
|
| if (! abbrev)
|
| {
|
| (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."),
|
| - abbrev_number);
|
| + abbrev_number);
|
| bfd_set_error (bfd_error_bad_value);
|
| return 0;
|
| }
|
| @@ -2435,11 +2466,13 @@ parse_comp_unit (struct dwarf2_debug *stash,
|
| /* If the compilation unit DIE has a DW_AT_low_pc attribute,
|
| this is the base address to use when reading location
|
| lists or range lists. */
|
| - unit->base_address = low_pc;
|
| + if (abbrev->tag == DW_TAG_compile_unit)
|
| + unit->base_address = low_pc;
|
| break;
|
|
|
| case DW_AT_high_pc:
|
| high_pc = attr.u.val;
|
| + high_pc_relative = attr.form != DW_FORM_addr;
|
| break;
|
|
|
| case DW_AT_ranges:
|
| @@ -2467,9 +2500,11 @@ parse_comp_unit (struct dwarf2_debug *stash,
|
| break;
|
| }
|
| }
|
| + if (high_pc_relative)
|
| + high_pc += low_pc;
|
| if (high_pc != 0)
|
| {
|
| - if (!arange_add (unit->abfd, &unit->arange, low_pc, high_pc))
|
| + if (!arange_add (unit, &unit->arange, low_pc, high_pc))
|
| return NULL;
|
| }
|
|
|
| @@ -2739,25 +2774,43 @@ static asection *
|
| find_debug_info (bfd *abfd, const struct dwarf_debug_section *debug_sections,
|
| asection *after_sec)
|
| {
|
| - asection * msec;
|
| + asection *msec;
|
| + const char *look;
|
| +
|
| + if (after_sec == NULL)
|
| + {
|
| + look = debug_sections[debug_info].uncompressed_name;
|
| + msec = bfd_get_section_by_name (abfd, look);
|
| + if (msec != NULL)
|
| + return msec;
|
| +
|
| + look = debug_sections[debug_info].compressed_name;
|
| + if (look != NULL)
|
| + {
|
| + msec = bfd_get_section_by_name (abfd, look);
|
| + if (msec != NULL)
|
| + return msec;
|
| + }
|
|
|
| - msec = after_sec != NULL ? after_sec->next : abfd->sections;
|
| + for (msec = abfd->sections; msec != NULL; msec = msec->next)
|
| + if (CONST_STRNEQ (msec->name, GNU_LINKONCE_INFO))
|
| + return msec;
|
|
|
| - while (msec)
|
| + return NULL;
|
| + }
|
| +
|
| + for (msec = after_sec->next; msec != NULL; msec = msec->next)
|
| {
|
| - if (strcmp (msec->name,
|
| - debug_sections[debug_info].uncompressed_name) == 0)
|
| + look = debug_sections[debug_info].uncompressed_name;
|
| + if (strcmp (msec->name, look) == 0)
|
| return msec;
|
|
|
| - if (debug_sections[debug_info].compressed_name != NULL
|
| - && strcmp (msec->name,
|
| - debug_sections[debug_info].compressed_name) == 0)
|
| + look = debug_sections[debug_info].compressed_name;
|
| + if (look != NULL && strcmp (msec->name, look) == 0)
|
| return msec;
|
|
|
| if (CONST_STRNEQ (msec->name, GNU_LINKONCE_INFO))
|
| return msec;
|
| -
|
| - msec = msec->next;
|
| }
|
|
|
| return NULL;
|
| @@ -2831,7 +2884,7 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
|
| }
|
|
|
| amt = i * sizeof (struct adjusted_section);
|
| - p = (struct adjusted_section *) bfd_zalloc (abfd, amt);
|
| + p = (struct adjusted_section *) bfd_alloc (abfd, amt);
|
| if (! p)
|
| return FALSE;
|
|
|
| @@ -2925,8 +2978,8 @@ info_hash_lookup_funcinfo (struct info_hash_table *hash_table,
|
| && addr >= arange->low
|
| && addr < arange->high
|
| && (!best_fit
|
| - || ((arange->high - arange->low)
|
| - < (best_fit->arange.high - best_fit->arange.low))))
|
| + || (arange->high - arange->low
|
| + < best_fit->arange.high - best_fit->arange.low)))
|
| best_fit = each_func;
|
| }
|
| }
|
| @@ -3117,6 +3170,122 @@ stash_find_line_fast (struct dwarf2_debug *stash,
|
| filename_ptr, linenumber_ptr);
|
| }
|
|
|
| +/* Read debug information from DEBUG_BFD when DEBUG_BFD is specified.
|
| + If DEBUG_BFD is not specified, we read debug information from ABFD
|
| + or its gnu_debuglink. The results will be stored in PINFO.
|
| + The function returns TRUE iff debug information is ready. */
|
| +
|
| +bfd_boolean
|
| +_bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
|
| + const struct dwarf_debug_section *debug_sections,
|
| + asymbol **symbols,
|
| + void **pinfo)
|
| +{
|
| + bfd_size_type amt = sizeof (struct dwarf2_debug);
|
| + bfd_size_type total_size;
|
| + asection *msec;
|
| + struct dwarf2_debug *stash = (struct dwarf2_debug *) *pinfo;
|
| +
|
| + if (stash != NULL)
|
| + return TRUE;
|
| +
|
| + stash = (struct dwarf2_debug *) bfd_zalloc (abfd, amt);
|
| + if (! stash)
|
| + return FALSE;
|
| + stash->debug_sections = debug_sections;
|
| +
|
| + *pinfo = stash;
|
| +
|
| + if (debug_bfd == NULL)
|
| + debug_bfd = abfd;
|
| +
|
| + msec = find_debug_info (debug_bfd, debug_sections, NULL);
|
| + if (msec == NULL && abfd == debug_bfd)
|
| + {
|
| + char * debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
|
| +
|
| + if (debug_filename == NULL)
|
| + /* No dwarf2 info, and no gnu_debuglink to follow.
|
| + Note that at this point the stash has been allocated, but
|
| + contains zeros. This lets future calls to this function
|
| + fail more quickly. */
|
| + return FALSE;
|
| +
|
| + if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
|
| + || ! bfd_check_format (debug_bfd, bfd_object)
|
| + || (msec = find_debug_info (debug_bfd,
|
| + debug_sections, NULL)) == NULL)
|
| + {
|
| + if (debug_bfd)
|
| + bfd_close (debug_bfd);
|
| + /* FIXME: Should we report our failure to follow the debuglink ? */
|
| + free (debug_filename);
|
| + return FALSE;
|
| + }
|
| + }
|
| +
|
| + /* There can be more than one DWARF2 info section in a BFD these
|
| + days. First handle the easy case when there's only one. If
|
| + there's more than one, try case two: none of the sections is
|
| + compressed. In that case, read them all in and produce one
|
| + large stash. We do this in two passes - in the first pass we
|
| + just accumulate the section sizes, and in the second pass we
|
| + read in the section's contents. (The allows us to avoid
|
| + reallocing the data as we add sections to the stash.) If
|
| + some or all sections are compressed, then do things the slow
|
| + way, with a bunch of reallocs. */
|
| +
|
| + if (! find_debug_info (debug_bfd, debug_sections, msec))
|
| + {
|
| + /* Case 1: only one info section. */
|
| + total_size = msec->size;
|
| + if (! read_section (debug_bfd, &stash->debug_sections[debug_info],
|
| + symbols, 0,
|
| + &stash->info_ptr_memory, &total_size))
|
| + return FALSE;
|
| + }
|
| + else
|
| + {
|
| + /* Case 2: multiple sections. */
|
| + for (total_size = 0;
|
| + msec;
|
| + msec = find_debug_info (debug_bfd, debug_sections, msec))
|
| + total_size += msec->size;
|
| +
|
| + stash->info_ptr_memory = (bfd_byte *) bfd_malloc (total_size);
|
| + if (stash->info_ptr_memory == NULL)
|
| + return FALSE;
|
| +
|
| + total_size = 0;
|
| + for (msec = find_debug_info (debug_bfd, debug_sections, NULL);
|
| + msec;
|
| + msec = find_debug_info (debug_bfd, debug_sections, msec))
|
| + {
|
| + bfd_size_type size;
|
| +
|
| + size = msec->size;
|
| + if (size == 0)
|
| + continue;
|
| +
|
| + if (!(bfd_simple_get_relocated_section_contents
|
| + (debug_bfd, msec, stash->info_ptr_memory + total_size,
|
| + symbols)))
|
| + return FALSE;
|
| +
|
| + total_size += size;
|
| + }
|
| + }
|
| +
|
| + stash->info_ptr = stash->info_ptr_memory;
|
| + stash->info_ptr_end = stash->info_ptr + total_size;
|
| + stash->sec = find_debug_info (debug_bfd, debug_sections, NULL);
|
| + stash->sec_info_ptr = stash->info_ptr;
|
| + stash->syms = symbols;
|
| + stash->bfd_ptr = debug_bfd;
|
| +
|
| + return TRUE;
|
| +}
|
| +
|
| /* Find the source code location of SYMBOL. If SYMBOL is NULL
|
| then find the nearest source code location corresponding to
|
| the address SECTION + OFFSET.
|
| @@ -3157,17 +3326,16 @@ find_line (bfd *abfd,
|
| bfd_vma found = FALSE;
|
| bfd_boolean do_line;
|
|
|
| - stash = (struct dwarf2_debug *) *pinfo;
|
| + *filename_ptr = NULL;
|
| + if (functionname_ptr != NULL)
|
| + *functionname_ptr = NULL;
|
| + *linenumber_ptr = 0;
|
|
|
| - if (! stash)
|
| - {
|
| - bfd_size_type amt = sizeof (struct dwarf2_debug);
|
| + if (! _bfd_dwarf2_slurp_debug_info (abfd, NULL,
|
| + debug_sections, symbols, pinfo))
|
| + return FALSE;
|
|
|
| - stash = (struct dwarf2_debug *) bfd_zalloc (abfd, amt);
|
| - if (! stash)
|
| - return FALSE;
|
| - stash->debug_sections = debug_sections;
|
| - }
|
| + stash = (struct dwarf2_debug *) *pinfo;
|
|
|
| /* In a relocatable file, 2 functions may have the same address.
|
| We change the section vma so that they won't overlap. */
|
| @@ -3197,110 +3365,11 @@ find_line (bfd *abfd,
|
| addr += section->output_section->vma + section->output_offset;
|
| else
|
| addr += section->vma;
|
| - *filename_ptr = NULL;
|
| - if (! do_line)
|
| - *functionname_ptr = NULL;
|
| - *linenumber_ptr = 0;
|
| -
|
| - if (! *pinfo)
|
| - {
|
| - bfd *debug_bfd;
|
| - bfd_size_type total_size;
|
| - asection *msec;
|
| -
|
| - *pinfo = stash;
|
| -
|
| - msec = find_debug_info (abfd, debug_sections, NULL);
|
| - if (msec == NULL)
|
| - {
|
| - char * debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
|
| -
|
| - if (debug_filename == NULL)
|
| - /* No dwarf2 info, and no gnu_debuglink to follow.
|
| - Note that at this point the stash has been allocated, but
|
| - contains zeros. This lets future calls to this function
|
| - fail more quickly. */
|
| - goto done;
|
| -
|
| - if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
|
| - || ! bfd_check_format (debug_bfd, bfd_object)
|
| - || (msec = find_debug_info (debug_bfd,
|
| - debug_sections, NULL)) == NULL)
|
| - {
|
| - if (debug_bfd)
|
| - bfd_close (debug_bfd);
|
| - /* FIXME: Should we report our failure to follow the debuglink ? */
|
| - free (debug_filename);
|
| - goto done;
|
| - }
|
| - }
|
| - else
|
| - debug_bfd = abfd;
|
| -
|
| - /* There can be more than one DWARF2 info section in a BFD these
|
| - days. First handle the easy case when there's only one. If
|
| - there's more than one, try case two: none of the sections is
|
| - compressed. In that case, read them all in and produce one
|
| - large stash. We do this in two passes - in the first pass we
|
| - just accumulate the section sizes, and in the second pass we
|
| - read in the section's contents. (The allows us to avoid
|
| - reallocing the data as we add sections to the stash.) If
|
| - some or all sections are compressed, then do things the slow
|
| - way, with a bunch of reallocs. */
|
| -
|
| - if (! find_debug_info (debug_bfd, debug_sections, msec))
|
| - {
|
| - /* Case 1: only one info section. */
|
| - total_size = msec->size;
|
| - if (! read_section (debug_bfd, &stash->debug_sections[debug_info],
|
| - symbols, 0,
|
| - &stash->info_ptr_memory, &total_size))
|
| - goto done;
|
| - }
|
| - else
|
| - {
|
| - /* Case 2: multiple sections. */
|
| - for (total_size = 0;
|
| - msec;
|
| - msec = find_debug_info (debug_bfd, debug_sections, msec))
|
| - total_size += msec->size;
|
| -
|
| - stash->info_ptr_memory = (bfd_byte *) bfd_malloc (total_size);
|
| - if (stash->info_ptr_memory == NULL)
|
| - goto done;
|
| -
|
| - total_size = 0;
|
| - for (msec = find_debug_info (debug_bfd, debug_sections, NULL);
|
| - msec;
|
| - msec = find_debug_info (debug_bfd, debug_sections, msec))
|
| - {
|
| - bfd_size_type size;
|
| -
|
| - size = msec->size;
|
| - if (size == 0)
|
| - continue;
|
| -
|
| - if (!(bfd_simple_get_relocated_section_contents
|
| - (debug_bfd, msec, stash->info_ptr_memory + total_size,
|
| - symbols)))
|
| - goto done;
|
| -
|
| - total_size += size;
|
| - }
|
| - }
|
| -
|
| - stash->info_ptr = stash->info_ptr_memory;
|
| - stash->info_ptr_end = stash->info_ptr + total_size;
|
| - stash->sec = find_debug_info (debug_bfd, debug_sections, NULL);
|
| - stash->sec_info_ptr = stash->info_ptr;
|
| - stash->syms = symbols;
|
| - stash->bfd_ptr = debug_bfd;
|
| - }
|
|
|
| /* A null info_ptr indicates that there is no dwarf2 info
|
| (or that an error occured while setting up the stash). */
|
| if (! stash->info_ptr)
|
| - goto done;
|
| + return FALSE;
|
|
|
| stash->inliner_chain = NULL;
|
|
|
| @@ -3330,6 +3399,7 @@ find_line (bfd *abfd,
|
| /* Check the previously read comp. units first. */
|
| for (each = stash->all_comp_units; each; each = each->next_unit)
|
| if ((symbol->flags & BSF_FUNCTION) == 0
|
| + || each->arange.high == 0
|
| || comp_unit_contains_address (each, addr))
|
| {
|
| found = comp_unit_find_line (each, symbol, addr, filename_ptr,
|
| @@ -3343,7 +3413,8 @@ find_line (bfd *abfd,
|
| {
|
| for (each = stash->all_comp_units; each; each = each->next_unit)
|
| {
|
| - found = (comp_unit_contains_address (each, addr)
|
| + found = ((each->arange.high == 0
|
| + || comp_unit_contains_address (each, addr))
|
| && comp_unit_find_nearest_line (each, addr,
|
| filename_ptr,
|
| functionname_ptr,
|
| @@ -3456,7 +3527,7 @@ find_line (bfd *abfd,
|
| }
|
| }
|
|
|
| -done:
|
| + done:
|
| if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
|
| unset_sections (stash);
|
|
|
| @@ -3527,17 +3598,12 @@ _bfd_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
|
| }
|
|
|
| void
|
| -_bfd_dwarf2_cleanup_debug_info (bfd *abfd)
|
| +_bfd_dwarf2_cleanup_debug_info (bfd *abfd, void **pinfo)
|
| {
|
| + struct dwarf2_debug *stash = (struct dwarf2_debug *) *pinfo;;
|
| struct comp_unit *each;
|
| - struct dwarf2_debug *stash;
|
| -
|
| - if (abfd == NULL || elf_tdata (abfd) == NULL)
|
| - return;
|
| -
|
| - stash = (struct dwarf2_debug *) elf_tdata (abfd)->dwarf2_find_line_info;
|
|
|
| - if (stash == NULL)
|
| + if (abfd == NULL || stash == NULL)
|
| return;
|
|
|
| for (each = stash->all_comp_units; each; each = each->next_unit)
|
|
|