/* The TUs that share this DW_AT_stmt_list entry.
This is added to while parsing type units to build partial symtabs,
and is deleted afterwards and not used again. */
- std::vector <signatured_type *> *tus;
+ std::vector<signatured_type *> *tus;
/* The compunit symtab.
Type units in a group needn't all be defined in the same source file,
/* See declaration. */
dwarf2_per_objfile::dwarf2_per_objfile (struct objfile *objfile_,
- const dwarf2_debug_sections *names)
- : objfile (objfile_)
+ const dwarf2_debug_sections *names,
+ bool can_copy_)
+ : objfile (objfile_),
+ can_copy (can_copy_)
{
if (names == NULL)
names = &dwarf2_elf_names;
/* Try to locate the sections we need for DWARF 2 debugging
information and return true if we have enough to do something.
NAMES points to the dwarf2 section names, or is NULL if the standard
- ELF names are used. */
+ ELF names are used. CAN_COPY is true for formats where symbol
+ interposition is possible and so symbol values must follow copy
+ relocation rules. */
int
dwarf2_has_info (struct objfile *objfile,
- const struct dwarf2_debug_sections *names)
+ const struct dwarf2_debug_sections *names,
+ bool can_copy)
{
if (objfile->flags & OBJF_READNEVER)
return 0;
if (dwarf2_per_objfile == NULL)
dwarf2_per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile,
- names);
+ names,
+ can_copy);
return (!dwarf2_per_objfile->info.is_virtual
&& dwarf2_per_objfile->info.s.section != NULL
tu_group = get_type_unit_group (cu, attr);
if (tu_group->tus == nullptr)
- tu_group->tus = new std::vector <signatured_type *>;
+ tu_group->tus = new std::vector<signatured_type *>;
tu_group->tus->push_back (sig_type);
prepare_one_comp_unit (cu, type_unit_die, language_minimal);
return NULL;
}
+ /* Nested subroutines in Fortran get a prefix. */
if (pdi->tag == DW_TAG_enumerator)
/* Enumerators should not get the name of the enumeration as a prefix. */
parent->scope = grandparent_scope;
|| parent->tag == DW_TAG_class_type
|| parent->tag == DW_TAG_interface_type
|| parent->tag == DW_TAG_union_type
- || parent->tag == DW_TAG_enumeration_type)
+ || parent->tag == DW_TAG_enumeration_type
+ || (cu->language == language_fortran
+ && parent->tag == DW_TAG_subprogram
+ && pdi->tag == DW_TAG_subprogram))
{
if (grandparent_scope == NULL)
parent->scope = parent->name;
case DW_TAG_subprogram:
addr = (gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr)
- baseaddr);
- if (pdi->is_external || cu->language == language_ada)
- {
- /* brobecker/2007-12-26: Normally, only "external" DIEs are part
- of the global scope. But in Ada, we want to be able to access
- nested procedures globally. So all Ada subprograms are stored
- in the global scope. */
+ if (pdi->is_external
+ || cu->language == language_ada
+ || (cu->language == language_fortran
+ && pdi->die_parent != NULL
+ && pdi->die_parent->tag == DW_TAG_subprogram))
+ {
+ /* Normally, only "external" DIEs are part of the global scope.
+ But in Ada and Fortran, we want to be able to access nested
+ procedures globally. So all Ada and Fortran subprograms are
+ stored in the global scope. */
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
VAR_DOMAIN, LOC_BLOCK,
if (! pdi->has_children)
return;
- if (cu->language == language_ada)
+ if (cu->language == language_ada || cu->language == language_fortran)
{
pdi = pdi->die_child;
while (pdi != NULL)
SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
TYPE_FIELD_NAME (type, 0) = "<<variants>>";
}
- else if (TYPE_NFIELDS (type) == 1)
+ /* A union with a single anonymous field is probably an old-style
+ univariant enum. */
+ else if (TYPE_NFIELDS (type) == 1 && streq (TYPE_FIELD_NAME (type, 0), ""))
{
- /* We assume that a union with a single field is a univariant
- enum. */
/* Smash this type to be a structure type. We have to do this
because the type has already been recorded. */
TYPE_CODE (type) = TYPE_CODE_STRUCT;
read_type_unit_scope (die, cu);
break;
case DW_TAG_subprogram:
+ /* Nested subprograms in Fortran get a prefix. */
+ if (cu->language == language_fortran
+ && die->parent != NULL
+ && die->parent->tag == DW_TAG_subprogram)
+ cu->processing_has_namespace_info = true;
+ /* Fall through. */
case DW_TAG_inlined_subroutine:
read_func_scope (die, cu);
break;
inside functions to find template arguments (if the name of the
function does not already contain the template arguments).
- For Ada, we need to scan the children of subprograms and lexical
- blocks as well because Ada allows the definition of nested
- entities that could be interesting for the debugger, such as
- nested subprograms for instance. */
+ For Ada and Fortran, we need to scan the children of subprograms
+ and lexical blocks as well because these languages allow the
+ definition of nested entities that could be interesting for the
+ debugger, such as nested subprograms for instance. */
if (last_die->has_children
&& (load_all
|| last_die->tag == DW_TAG_namespace
|| last_die->tag == DW_TAG_interface_type
|| last_die->tag == DW_TAG_structure_type
|| last_die->tag == DW_TAG_union_type))
- || (cu->language == language_ada
+ || ((cu->language == language_ada
+ || cu->language == language_fortran)
&& (last_die->tag == DW_TAG_subprogram
|| last_die->tag == DW_TAG_lexical_block))))
{
unsigned int dummy;
if (DW_BLOCK (attr)->data[0] == DW_OP_addr)
- SYMBOL_VALUE_ADDRESS (sym) =
- read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy);
+ SET_SYMBOL_VALUE_ADDRESS (sym,
+ read_address (objfile->obfd,
+ DW_BLOCK (attr)->data + 1,
+ cu, &dummy));
else
- SYMBOL_VALUE_ADDRESS (sym) =
- read_addr_index_from_leb128 (cu, DW_BLOCK (attr)->data + 1, &dummy);
+ SET_SYMBOL_VALUE_ADDRESS
+ (sym, read_addr_index_from_leb128 (cu, DW_BLOCK (attr)->data + 1,
+ &dummy));
SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
fixup_symbol_section (sym, objfile);
- SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
- SYMBOL_SECTION (sym));
+ SET_SYMBOL_VALUE_ADDRESS (sym,
+ SYMBOL_VALUE_ADDRESS (sym)
+ + ANOFFSET (objfile->section_offsets,
+ SYMBOL_SECTION (sym)));
return;
}
addr = attr_value_as_address (attr);
addr = gdbarch_adjust_dwarf2_addr (gdbarch, addr + baseaddr);
- SYMBOL_VALUE_ADDRESS (sym) = addr;
+ SET_SYMBOL_VALUE_ADDRESS (sym, addr);
}
SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_core_addr;
SYMBOL_DOMAIN (sym) = LABEL_DOMAIN;
SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
attr2 = dwarf2_attr (die, DW_AT_external, cu);
if ((attr2 && (DW_UNSND (attr2) != 0))
- || cu->language == language_ada)
+ || cu->language == language_ada
+ || cu->language == language_fortran)
{
/* Subprograms marked external are stored as a global symbol.
- Ada subprograms, whether marked external or not, are always
- stored as a global symbol, because we want to be able to
- access them globally. For instance, we want to be able
- to break on a nested subprogram without having to
- specify the context. */
+ Ada and Fortran subprograms, whether marked external or
+ not, are always stored as a global symbol, because we want
+ to be able to access them globally. For instance, we want
+ to be able to break on a nested subprogram without having
+ to specify the context. */
list_to_add = cu->get_builder ()->get_global_symbols ();
}
else
}
else if (attr2 && (DW_UNSND (attr2) != 0))
{
- /* Workaround gfortran PR debug/40040 - it uses
- DW_AT_location for variables in -fPIC libraries which may
- get overriden by other libraries/executable and get
- a different address. Resolve it by the minimal symbol
- which may come from inferior's executable using copy
- relocation. Make this workaround only for gfortran as for
- other compilers GDB cannot guess the minimal symbol
- Fortran mangling kind. */
- if (cu->language == language_fortran && die->parent
- && die->parent->tag == DW_TAG_module
- && cu->producer
- && startswith (cu->producer, "GNU Fortran"))
- SYMBOL_ACLASS_INDEX (sym) = LOC_UNRESOLVED;
+ if (SYMBOL_CLASS (sym) == LOC_STATIC
+ && (objfile->flags & OBJF_MAINLINE) == 0
+ && dwarf2_per_objfile->can_copy)
+ {
+ /* A global static variable might be subject to
+ copy relocation. We first check for a local
+ minsym, though, because maybe the symbol was
+ marked hidden, in which case this would not
+ apply. */
+ bound_minimal_symbol found
+ = (lookup_minimal_symbol_linkage
+ (SYMBOL_LINKAGE_NAME (sym), objfile));
+ if (found.minsym != nullptr)
+ sym->maybe_copied = 1;
+ }
/* A variable with DW_AT_external is never static,
but it may be block-scoped. */
return name;
}
return "";
+ case DW_TAG_subprogram:
+ /* Nested subroutines in Fortran get a prefix with the name
+ of the parent's subroutine. */
+ if (cu->language == language_fortran)
+ {
+ if ((die->tag == DW_TAG_subprogram)
+ && (dwarf2_name (parent, cu) != NULL))
+ return dwarf2_name (parent, cu);
+ }
+ return determine_prefix (parent, cu);
case DW_TAG_enumeration_type:
parent_type = read_type_die (parent, cu);
if (TYPE_DECLARED_CLASS (parent_type))