[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