Hi, As I understand, the DWARF tag DW_AT_external is meant to indicate whether a variable/function is accessible from outside an object file(compilation unit) containing a given DWARF DIE - Debugging Information Entry. But it looks like DW_AT_external is also set for variables/functions defined in a different object file, but has a DIE because of linking. See: http://pastebin.com/vFiBWuhh It has a small C++ program - greeting.cpp, with it's output and some DWARF information. As can be seen, the external flag is set for the standard library functions such as - swscanf, ungetwd, or vfwprintf - which are not defined or used in greeting.cpp, but are part of the object file because of linking. This makes it *difficult* to locate the DIEs describing the functions that are defined and/or used in greeting.cpp. Thank you.
The following patch to gcc-4.4.4 seems to fix the issue for DW_AT_subprogram DIEs. $ diff -Naurp gcc-4.4.4/gcc/dwarf2out.c gcc-4.4.4.1/gcc/dwarf2out.c --- gcc-4.4.4/gcc/dwarf2out.c 2010-02-10 20:39:06.000000000 +0530 +++ gcc-4.4.4.1/gcc/dwarf2out.c 2010-08-02 15:16:17.495688080 +0530 @@ -13712,7 +13712,7 @@ gen_subprogram_die (tree decl, dw_die_re { subr_die = new_die (DW_TAG_subprogram, context_die, decl); - if (TREE_PUBLIC (decl)) + if (TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) add_AT_flag (subr_die, DW_AT_external, 1); add_name_and_src_coords_attributes (subr_die, decl); @@ -14163,7 +14163,7 @@ gen_variable_die (tree decl, tree origin add_type_attribute (var_die, type, TREE_READONLY (decl), TREE_THIS_VOLATILE (decl), context_die); - if (TREE_PUBLIC (decl)) + if (TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) add_AT_flag (var_die, DW_AT_external, 1); if (DECL_ARTIFICIAL (decl))
I don't see why any change is needed. If a function (or variable) isn't defined in the current translation unit, then it necessarily has to be accessible from outside of the translation unit containing it.
DW_AT_external is meant to indicate whether a variable/function, that is defined in the compilation unit, is accessible/visible from the outside of it or not. It's a subtle difference between `accessible from' and `accessed from' outside.
I don't see the standard saying that anywhere. "A DW_AT_external attribute, which is a flag, if the name of a variable is visible outside of its enclosing compilation unit." "If the name of the subroutine described by an entry with the tag DW_TAG_subprogram is visible outside of its containing compilation unit, that entry has a DW_AT_external attribute, which is a flag." Nothing says that the variable/function has to be defined in that compilation unit.
Doesn't the wording - visible outside of its containing compilation unit - ring any bells? Secondly, for variables and functions that are not defined in the compilation unit, it doesn't make sense to mark them as - visible/accessible from outside - for, that's more than obvious. Please see: http://gcc.gnu.org/ml/gcc-help/2010-07/msg00266.html There is another same thread on dwarf-discuss list, but the archives are not open for the web. (I think we need a third umpire to pass a reasonable judgement.)
DW_AT_external is correct for anything that has "global" linkage, whether or not is defined. The absence of DW_AT_external, in a DIE that is not inside a DW_TAG_subprogram scope, means that it has "file" linkage, like a "static" variable in C/C++ does. A C++ static member has global linkage, not file linkage. DW_AT_declaration is used for any DIE that is for a non-defining declaration. That is a separate axis of consideration than DW_AT_external, which only about the linkage.
You got me confused. What do you mean - "DW_AT_external is correct for anything that has "global" linkage, whether or not is defined." - ? How do you define "global" linkage, here? DIEs for static variables/functions don't have DW_AT_external set, though you say they've global linkage. Also, how does on locate the DIEs for variables/functions that are listed in the .debug_pubnames section($ eu-readelf -wpubnames <file>). The list of variables/functions that are *defined* in the same compilation unit and are *visible/accessible from outside* of it.
I think you've confused static variables (file scope) with C++ static members (global scope). At any rate, this is not the place to get an education about DWARF. You can use the dwarf-discuss mailing list for those questions. The DIEs you cited are correct for the code. There is no gcc bug here.
Thus, INVALID.
I think we've stepped away from DW_AT_external. This "global" linkage theory is not convincing for why DW_AT_external should be set for variables/functions that are defined outside of the compilation unit.
But surely if (as you suggest) swscanf had a DIE without DW_AT_external that would imply it was private to the compilation unit, which would be wrong. If a non-static function has a DIE, it should include DW_AT_external.
.
(In reply to comment #7) > Also, how does on locate the DIEs for variables/functions that are listed in > the .debug_pubnames section($ eu-readelf -wpubnames <file>). The list of > variables/functions that are *defined* in the same compilation unit and are > *visible/accessible from outside* of it. Can't you look for DIEs which have DW_AT_external and which have a later DW_AT_specification, which completes the earlier non-defining declaration. DW_AT_specification tells you it's defined, DW_AT_external tells you it's visible.
> But surely if (as you suggest) swscanf had a DIE without DW_AT_external that > would imply it was private to the compilation unit, which would be wrong. Hmmn...may be. > DW_AT_specification tells you it's defined, DW_AT_external tells you it's > visible. DW_AT_specification does not seem to be present all the time. It shows up in C++ program, but does not show up in a C program.