This adds support for S_DEFRANGE_REGISTER and S_DEFRANGE_SUBFIELD_REGISTER that describe S_LOCAL.
S_DEFRANGE_REGISTER describes a list of ranges where the value of S_LOCAL (a local variable) is in a register.
S_DEFRANGE_SUBFIELD_REGISTER describes a list of ranges where the value of a subfield is in a register.
204 | S_LOCAL [size = 12] `s` type=0x2478 (S), flags = none 216 | S_DEFRANGE_SUBFIELD_REGISTER [size = 20] register = ECX, may have no name = true, offset in parent = 0 range = [0001:0003,+14), gaps = [] 236 | S_DEFRANGE_SUBFIELD_REGISTER [size = 20] register = DL, may have no name = true, offset in parent = 4 range = [0001:0006,+11), gaps = []
Here s has two fields x(int) and y(char). The two S_DEFRANGE_SUBFIELD_REGISTER say that the value of s.x is in ecx in range [0001:0003,+14) and the value of s.y is in dl in range [0001:0006,+11).
For S_DEFRANGE_SUBFIELD_REGISTER, if we want to describe the location precisely, we need to use dwarf location lists to describe the range and construct a dwarf debug location table, which I'm not sure if it's difficult.
So, I choose to let the range list be the overlap ranges among all range lists. For example, we have 3 S_DEFRANGE_SUBFIELD_REGISTER describing 3 different fields in a structure and they have following range lists. The final range list will be [1,2), [4, 6).
- [0, 3), [4, 8)
- [0, 2), [3, 6)
- [1, 2), [4, 10)
Not needed anymore, I guess?