/* dwarf.c -- display DWARF contents of a BFD binary file
- Copyright (C) 2005-2020 Free Software Foundation, Inc.
+ Copyright (C) 2005-2021 Free Software Foundation, Inc.
This file is part of GNU Binutils.
{
dwo_type type;
const char * value;
+ dwarf_vma cu_offset;
struct dwo_info * next;
} dwo_info;
}
static void
-add_dwo_info (const char * field, dwo_type type)
+add_dwo_info (const char * value, dwarf_vma cu_offset, dwo_type type)
{
dwo_info * dwinfo = xmalloc (sizeof * dwinfo);
- dwinfo->type = type;
- dwinfo->value = field;
- dwinfo->next = first_dwo_info;
+ dwinfo->type = type;
+ dwinfo->value = value;
+ dwinfo->cu_offset = cu_offset;
+ dwinfo->next = first_dwo_info;
first_dwo_info = dwinfo;
}
static void
-add_dwo_name (const char * name)
+add_dwo_name (const char * name, dwarf_vma cu_offset)
{
- add_dwo_info (name, DWO_NAME);
+ add_dwo_info (name, cu_offset, DWO_NAME);
}
static void
-add_dwo_dir (const char * dir)
+add_dwo_dir (const char * dir, dwarf_vma cu_offset)
{
- add_dwo_info (dir, DWO_DIR);
+ add_dwo_info (dir, cu_offset, DWO_DIR);
}
static void
-add_dwo_id (const char * id)
+add_dwo_id (const char * id, dwarf_vma cu_offset)
{
- add_dwo_info (id, DWO_ID);
+ add_dwo_info (id, cu_offset, DWO_ID);
}
static void
switch (form)
{
case DW_FORM_strp:
- add_dwo_name ((const char *) fetch_indirect_string (uvalue));
+ add_dwo_name ((const char *) fetch_indirect_string (uvalue), cu_offset);
break;
case DW_FORM_GNU_strp_alt:
- add_dwo_name ((const char *) fetch_alt_indirect_string (uvalue));
+ add_dwo_name ((const char *) fetch_alt_indirect_string (uvalue), cu_offset);
break;
case DW_FORM_GNU_str_index:
- add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, FALSE));
+ add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, FALSE), cu_offset);
break;
case DW_FORM_string:
- add_dwo_name ((const char *) orig_data);
+ add_dwo_name ((const char *) orig_data, cu_offset);
break;
default:
warn (_("Unsupported form (%s) for attribute %s\n"),
switch (form)
{
case DW_FORM_strp:
- add_dwo_dir ((const char *) fetch_indirect_string (uvalue));
+ add_dwo_dir ((const char *) fetch_indirect_string (uvalue), cu_offset);
break;
case DW_FORM_GNU_strp_alt:
- add_dwo_dir (fetch_alt_indirect_string (uvalue));
+ add_dwo_dir (fetch_alt_indirect_string (uvalue), cu_offset);
break;
case DW_FORM_line_strp:
- add_dwo_dir ((const char *) fetch_indirect_line_string (uvalue));
+ add_dwo_dir ((const char *) fetch_indirect_line_string (uvalue), cu_offset);
break;
case DW_FORM_GNU_str_index:
- add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, FALSE));
+ add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, FALSE), cu_offset);
break;
case DW_FORM_string:
- add_dwo_dir ((const char *) orig_data);
+ add_dwo_dir ((const char *) orig_data, cu_offset);
break;
default:
warn (_("Unsupported form (%s) for attribute %s\n"),
{
case DW_FORM_data8:
/* FIXME: Record the length of the ID as well ? */
- add_dwo_id ((const char *) (data - 8));
+ add_dwo_id ((const char *) (data - 8), cu_offset);
break;
default:
warn (_("Unsupported form (%s) for attribute %s\n"),
if (rlet == DW_RLE_base_address)
continue;
- print_dwarf_vma (begin + base_address, pointer_size);
- print_dwarf_vma (end + base_address, pointer_size);
+ /* Only a DW_RLE_offset_pair needs the base address added. */
+ if (rlet == DW_RLE_offset_pair)
+ {
+ begin += base_address;
+ end += base_address;
+ }
+
+ print_dwarf_vma (begin, pointer_size);
+ print_dwarf_vma (end, pointer_size);
if (begin == end)
fputs (_("(start == end)"), stdout);
if (*need_col_headers)
{
- static const char *sloc = " LOC";
-
*need_col_headers = 0;
- printf ("%-*s CFA ", eh_addr_size * 2, sloc);
+ printf ("%-*s CFA ", eh_addr_size * 2, " LOC");
for (r = 0; r < *max_regs; r++)
if (fc->col_type[r] != DW_CFA_unreferenced)
return 1;
}
+static int cu_tu_indexes_read = -1; /* Tri-state variable. */
+
/* Load the CU and TU indexes if present. This will build a list of
section sets that we can use to associate a .debug_info.dwo section
with its associated .debug_abbrev.dwo section in a .dwp file. */
static bfd_boolean
load_cu_tu_indexes (void *file)
{
- static int cu_tu_indexes_read = -1; /* Tri-state variable. */
-
/* If we have already loaded (or tried to load) the CU and TU indexes
then do not bother to repeat the task. */
if (cu_tu_indexes_read == -1)
{
free_dwo_info ();
- if (process_debug_info (& debug_displays[info].section, file, abbrev, TRUE, FALSE))
+ if (process_debug_info (& debug_displays[info].section, file, abbrev,
+ TRUE, FALSE))
{
bfd_boolean introduced = FALSE;
dwo_info * dwinfo;
const char * dir = NULL;
const char * id = NULL;
+ const char * name = NULL;
for (dwinfo = first_dwo_info; dwinfo != NULL; dwinfo = dwinfo->next)
{
+ /* Accumulate NAME, DIR and ID fields. */
switch (dwinfo->type)
{
case DWO_NAME:
+ if (name != NULL)
+ warn (_("Multiple DWO_NAMEs encountered for the same CU\n"));
+ name = dwinfo->value;
+ break;
+
+ case DWO_DIR:
+ /* There can be multiple DW_AT_comp_dir entries in a CU,
+ so do not complain. */
+ dir = dwinfo->value;
+ break;
+
+ case DWO_ID:
+ if (id != NULL)
+ warn (_("multiple DWO_IDs encountered for the same CU\n"));
+ id = dwinfo->value;
+ break;
+
+ default:
+ error (_("Unexpected DWO INFO type"));
+ break;
+ }
+
+ /* If we have reached the end of our list, or we are changing
+ CUs, then display the information that we have accumulated
+ so far. */
+ if (name != NULL
+ && (dwinfo->next == NULL
+ || dwinfo->next->cu_offset != dwinfo->cu_offset))
+ {
if (do_debug_links)
{
if (! introduced)
introduced = TRUE;
}
- printf (_(" Name: %s\n"), dwinfo->value);
+ printf (_(" Name: %s\n"), name);
printf (_(" Directory: %s\n"), dir ? dir : _("<not-found>"));
if (id != NULL)
display_data (printf (_(" ID: ")), (unsigned char *) id, 8);
else
- printf (_(" ID: <unknown>\n"));
+ printf (_(" ID: <not specified>\n"));
printf ("\n\n");
}
if (do_follow_links)
- load_dwo_file (filename, dwinfo->value, dir, id);
- break;
-
- case DWO_DIR:
- dir = dwinfo->value;
- break;
-
- case DWO_ID:
- id = dwinfo->value;
- break;
+ load_dwo_file (filename, name, dir, id);
- default:
- error (_("Unexpected DWO INFO type"));
- break;
+ name = dir = id = NULL;
}
}
}
cu_abbrev_map = NULL;
next_free_abbrev_map_entry = 0;
+ free (shndx_pool);
+ shndx_pool = NULL;
+ shndx_pool_size = 0;
+ shndx_pool_used = 0;
+ free (cu_sets);
+ cu_sets = NULL;
+ cu_count = 0;
+ free (tu_sets);
+ tu_sets = NULL;
+ tu_count = 0;
+
+ memset (level_type_signed, 0, sizeof level_type_signed);
+ cu_tu_indexes_read = -1;
+
for (i = 0; i < max; i++)
free_debug_section ((enum dwarf_section_display_enum) i);