[PATCH] D32821: Add DWARF verifiers to verify address ranges are correct and scoped correctly.

Greg Clayton via llvm-commits llvm-commits at lists.llvm.org
Wed May 3 14:17:03 PDT 2017


There should not have been a DW_AT_low_pc on the class type...
> On May 3, 2017, at 2:15 PM, Greg Clayton <clayborg at gmail.com> wrote:
> 
>> 
>> On May 3, 2017, at 1:47 PM, David Blaikie <dblaikie at gmail.com <mailto:dblaikie at gmail.com>> wrote:
>> 
>> 
>> 
>> On Wed, May 3, 2017 at 1:43 PM Greg Clayton via Phabricator <reviews at reviews.llvm.org <mailto:reviews at reviews.llvm.org>> wrote:
>> clayborg added a comment.
>> 
>> One thing to clarify:
>> 
>>   std::vector<RangeInfoType> DieRangeInfos;
>> 
>> is a vector that only gets as deep as the DIE depth. It doesn't get every range for every function, block, or inlined function, it just has a stack of ranges for the _current_ DIE depth.
>> 
>> Which is part of what I'm confused by - I wouldn't expect to see/don't understand why there's any code that special-cases subprograms here. They don't seem special to me.
> 
> They are special because they are top level functions. DW_TAG_subprogram appear at any depth and their parent isn't always a DW_TAG_compile_unit. So we might have DWARF like:
> 
> 0x0000000b: DW_TAG_compile_unit [1] *
>              DW_AT_low_pc( 0x0000000000001000 )
>              DW_AT_high_pc( 0x0000000000003000 )
>              DW_AT_name( "/tmp/main.c" )
> 
> 0x00000020:     DW_TAG_subprogram [2] *
>                  DW_AT_name( "main" )
>                  DW_AT_low_pc( 0x0000000000001000 )
>                  DW_AT_high_pc( 0x0000000000002000 )
> 
> 0x00000035:         DW_TAG_lexical_block [3]  
>                      DW_AT_low_pc( 0x0000000000001100 )
>                      DW_AT_high_pc( 0x0000000000001200 )
> 
> 0x00000046:         NULL
> 
> 0x00000047:     DW_TAG_class_type [4] *
>                  DW_AT_low_pc( 0x0000000000001000 )
>                  DW_AT_name( "Foo" )
> 
> 0x00000054:         DW_TAG_subprogram [2] *
>                      DW_AT_name( "Bar" )
>                      DW_AT_low_pc( 0x0000000000002000 )
>                      DW_AT_high_pc( 0x0000000000003000 )
> 
> 0x00000069:             DW_TAG_lexical_block [3]  
>                          DW_AT_low_pc( 0x0000000000002100 )
>                          DW_AT_high_pc( 0x0000000000002200 )
> 
> 0x0000007a:             NULL
> 
> 0x0000007b:         NULL
> 
> 0x0000007c:     NULL
> 
> When visiting the DW_TAG_subprogram at 0x00000020 we would do:
> 
> Depth = Die.getDepth(); // depth will be 1
> if (!DieRangeInfos[0].Ranges.empty())
>   assert(DieRangeInfos[0].Contains(DieRangeInfos[Depth].Ranges)
> 
> since 0x00000020 is at depth 1
> 
> Our DieRangeInfos stack would be:
> 
> DieRangeInfos[0] = DW_TAG_compile_unit [0x0000000000001000 - 0x0000000000003000)
> DieRangeInfos[1] = DW_TAG_subprogram   [0x0000000000001000 - 0x0000000000002000)
> 
> When visiting the DW_TAG_lexical_block at 0x00000035 we would only check:
> 
> assert(DieRangeInfos[Depth-1].Contains(DieRangeInfos[Depth].Ranges))
> 
> Our DieRangeInfos stack would be:
> 
> DieRangeInfos[0] = DW_TAG_compile_unit [0x0000000000001000 - 0x0000000000003000)
> DieRangeInfos[1] = DW_TAG_subprogram   [0x0000000000001000 - 0x0000000000002000)
> DieRangeInfos[2] = DW_TAG_lexical_block[0x0000000000001100 - 0x0000000000001200)
> 
> When visiting 0x00000054 we would again check against the compile units ranges:
> 
> Depth = Die.getDepth(); // depth will be 2
> if (!DieRangeInfos[0].Ranges.empty())
>   assert(DieRangeInfos[0].Contains(DieRangeInfos[Depth].Ranges)
> 
> DieRangeInfos[0] = DW_TAG_compile_unit [0x0000000000001000 - 0x0000000000003000)
> DieRangeInfos[1] = DW_TAG_class_type
> DieRangeInfos[2] = DW_TAG_subprogram   [0x0000000000002000 - 0x0000000000003000)
> 
> Then visiting 0x00000069 we do:
> 
> assert(DieRangeInfos[Depth-1].Contains(DieRangeInfos[Depth].Ranges))
> 
> DieRangeInfos[0] = DW_TAG_compile_unit [0x0000000000001000 - 0x0000000000003000)
> DieRangeInfos[1] = DW_TAG_class_type
> DieRangeInfos[2] = DW_TAG_subprogram   [0x0000000000002000 - 0x0000000000003000)
> DieRangeInfos[3] = DW_TAG_lexical_block[0x0000000000002100 - 0x0000000000002200)
> 
> 
>> I'd expect an algorithm that starts at the CU DIE and looks for any DIE that has ranges. It wouldn't need special cases for any tag types.
> 
> You only need to verify your range against something your parent. For some, like a DW_TAG_subprogram, it must be in the DW_TAG_compile_unit only if it has ranges. For DW_TAG_lexical_block and DW_TAG_inlined_subroutine, they MUST be in their parents if their ranges are valid.
> 
> It is also possible in other languages to have functions declared inside of functions. In that case you want to only verify against your parent and stop at the DW_TAG_subprogram level. You could have a stack like:
> 
> 
> DieRangeInfos[0] = DW_TAG_compile_unit [0x0000000000001000 - 0x0000000000003000)
> DieRangeInfos[1] = DW_TAG_subprogram   [0x0000000000001000 - 0x0000000000002000)
> DieRangeInfos[2] = DW_TAG_lexical_block[0x0000000000001100 - 0x0000000000001200)
> DieRangeInfos[3] = DW_TAG_subprogram   [0x0000000000003000 - 0x0000000000004000)
> DieRangeInfos[4] = DW_TAG_lexical_block[0x0000000000003100 - 0x0000000000003200)
> 
> You would only want to see if:
> - [4] is in [3]
> - [2] is in [1]
> - [3] and [1] are in [0]
> 
> Make sense?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170503/2d5bf1cf/attachment-0001.html>


More information about the llvm-commits mailing list