This is the mail archive of the dwarf2@corp.sgi.com mailing list for the dwarf2 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: location lists revisited


> 
> Todd Allen wrote:
> > 
> >    Thinking about how I would implement the DWARF replication approach for
> >    local copies of global variables has brought me back to my original
> >    question about this issue.  I don't think the DWARF replication approach,
> >    alone, will support it.  I'll reiterate the problem with a concrete
> >    example in 3 sources:
> > 
> >       source1.c:
> >          int global;
> > 
> >          function foo()
> >          {
> >             ...
> >             for (; global < ...; global++) {
> >                ... global is used ...
> >             }
> >             ...
> >          }
> > 
> >       source2.c:
> >          extern int global;
> > 
> >          function bar()
> >          {
> >             ...
> >             for (; global < ...; global++) {
> >                ... global is used ...
> >             }
> >             ...
> >          }
> > 
> >       source3.c:
> >          /* Notice no extern int global, nor any include files */
> > 
> >          function unrelated()
> >          {
> >             ...
> >          }
> > 
> >    Because global is used in a loop in both foo() and bar(), local read/write
> >    copies are made in both of those functions.
> > 
> >    That means that in both source1.o and source2.o, a location list will be
> >    generated for global.  In source1.o, it will describe the in-memory
> >    location for most of the .text in that object file, but will describe the
> >    in-register location for the relevant part of foo().  In source2.o, the
> >    location list would either do much the same thing, or because global has a
> >    non-defining declaration there, it might only describe in the in-register
> >    location for the relevant part of bar().
> > 
> >    Either way, how would a debugger stopped in unrelated() determine the
> >    location of global?  Certainly, that's something that DWARF should
> >    support.  (Yes, whether a debugger supports it is a QoI issue, but DWARF
> >    shouldn't stand in the way.)
> 
> Are you suggesting that when you stop in unrelated(), that the value 
> of 'global' is somewhere other than in the global location?  
>

Not at all.  I'm saying, "how does a debugger know which is the global
location?"  Let me be even more explicit with this example by showing an
example DWARF dump for what I at least think is your proposal for how this
should be done:

source1.o:
   DIE (0xb) [] 1
      DW_TAG_compile_unit
      DW_CHILDREN_yes
      DW_AT_low_pc(DW_FORM_addr) 0x1000
      DW_AT_high_pc(DW_FORM_addr) 0x3000
      DW_AT_language(DW_FORM_udata) DW_LANG_C89
      DW_AT_name(DW_FORM_string) "source1.c"

      DIE (0x86) [] 4
         DW_TAG_variable
         DW_CHILDREN_no
         DW_AT_external(DW_FORM_flag) TRUE
         DW_AT_type(DW_FORM_ref_addr) -> int
         DW_AT_name(DW_FORM_string) "global"
         DW_AT_location(DW_FORM_block) [0x1000..0x1080 => DW_OP_addr global,
                                        0x1080..0x2f00 => DW_OP_reg17,
                                        0x2f00..0x3000 => DW_OP_addr global]

      DIE (0x99) [] 2
         DW_TAG_subprogram
         DW_CHILDREN_no
         DW_AT_name(DW_FORM_string) "foo"
         DW_AT_external(DW_FORM_flag) TRUE
         DW_AT_type(DW_FORM_ref_addr) -> int
         DW_AT_low_pc(DW_FORM_addr) 0x1040
         DW_AT_high_pc(DW_FORM_addr) 0x3000

   DIE (0xa0) [] 0
      DW_TAG_padding
      DW_CHILDREN_no

source2.o:
   DIE (0xb) [] 1
      DW_TAG_compile_unit
      DW_CHILDREN_yes
      DW_AT_low_pc(DW_FORM_addr) 0x4000
      DW_AT_high_pc(DW_FORM_addr) 0x7000
      DW_AT_language(DW_FORM_udata) DW_LANG_C89
      DW_AT_name(DW_FORM_string) "source2.c"

      DIE (0x86) [] 4
         DW_TAG_variable
         DW_CHILDREN_no
         DW_AT_declaration(DW_FORM_flag) TRUE
         DW_AT_type(DW_FORM_ref_addr) -> int
         DW_AT_name(DW_FORM_string) "global"
         DW_AT_location(DW_FORM_block) [0x4000..0x4080 => DW_OP_addr global,
                                        0x4080..0x4f00 => DW_OP_reg20,
                                        0x6f00..0x7000 => DW_OP_addr global]

      DIE (0x86) [] 2
         DW_TAG_subprogram
         DW_CHILDREN_no
         DW_AT_name(DW_FORM_string) "bar"
         DW_AT_external(DW_FORM_flag) TRUE
         DW_AT_type(DW_FORM_ref_addr) -> int
         DW_AT_low_pc(DW_FORM_addr) 0x4040
         DW_AT_high_pc(DW_FORM_addr) 0x7000

   DIE (0xa0) [] 0
      DW_TAG_padding
      DW_CHILDREN_no

source3.o:
   DIE (0xb) [] 1
      DW_TAG_compile_unit
      DW_CHILDREN_yes
      DW_AT_low_pc(DW_FORM_addr) 0x8000
      DW_AT_high_pc(DW_FORM_addr) 0xb000
      DW_AT_language(DW_FORM_udata) DW_LANG_C89
      DW_AT_name(DW_FORM_string) "source3.c"

      DIE (0x86) [] 2
         DW_TAG_subprogram
         DW_CHILDREN_no
         DW_AT_name(DW_FORM_string) "unrelated"
         DW_AT_external(DW_FORM_flag) TRUE
         DW_AT_type(DW_FORM_ref_addr) -> int
         DW_AT_low_pc(DW_FORM_addr) 0x8040
         DW_AT_high_pc(DW_FORM_addr) 0xb000

   DIE (0xa6) [] 0
      DW_TAG_padding
      DW_CHILDREN_no

The only two declarations of global described in the DWARF had to be
described with location lists, because in each object in which they appeared,
they were at different locations in various points in those objects.

(Note that I am using your "non-defining declarations can have location
lists" extension here.)  Also, I'm expanding the location lists right in the
dump, because it's easier to understand that way.

So, how does a debugger stopped at a point outside either of those objects
(e.g. at 0x8100), and trying to reference or modify "global" know which
location to use?  Probably, it would want to track down the defining
declaration, but that has a location list, and that list doesn't cover the
current pc.  How does it know which of the locations is the one that's good
for the pc at which it's stopped?

In this example, it probably could make a good guess that it doesn't want the
register.  But that's just a heuristic and I wouldn't want to have to depend
on it.

-- 
Todd Allen
Concurrent Computer Corporation


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]