diff options
8 files changed, 623 insertions, 378 deletions
diff --git a/lldb/examples/python/x86_64_target_definition.py b/lldb/examples/python/x86_64_target_definition.py index 52d17ec0c92..177095dbecd 100644 --- a/lldb/examples/python/x86_64_target_definition.py +++ b/lldb/examples/python/x86_64_target_definition.py @@ -200,63 +200,119 @@ def get_reg_num (reg_num_dict, reg_name): return LLDB_INVALID_REGNUM x86_64_register_infos = [ -{ 'name':'rax' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'rbx' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'rcx' , 'alt-name':'arg4' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'rdx' , 'alt-name':'arg3' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'rsi' , 'alt-name':'arg2' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'rdi' , 'alt-name':'arg1' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'rbp' , 'alt-name':'fp' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'rsp' , 'alt-name':'sp' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'r8' , 'alt-name':'arg5' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'r9' , 'alt-name':'arg6' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'r10' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'r11' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'r12' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'r13' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'r14' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'r15' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'rip' , 'alt-name':'pc' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, -{ 'name':'rflags', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'cs' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'ss' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'ds' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'es' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'fs' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'gs' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'stmm0' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'stmm1' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'stmm2' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'stmm3' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'stmm4' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'stmm5' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'stmm6' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'stmm7' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'fctrl' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'fstat' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'ftag' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'fiseg' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'fioff' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'foseg' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'fooff' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'fop' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, -{ 'name':'xmm0' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm1' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm2' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm3' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm4' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm5' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm6' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm7' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm8' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm9' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm10' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm11' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm12' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm13' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm14' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'xmm15' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, -{ 'name':'mxcsr' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex } +{ 'name':'rax' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, +{ 'name':'rbx' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, +{ 'name':'rcx' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'arg4' }, +{ 'name':'rdx' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'arg3' }, +{ 'name':'rsi' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'arg2' }, +{ 'name':'rdi' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'arg1' }, +{ 'name':'rbp' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'fp' }, +{ 'name':'rsp' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'sp' }, +{ 'name':'r8' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'arg5' }, +{ 'name':'r9' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'arg6' }, +{ 'name':'r10' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, +{ 'name':'r11' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, +{ 'name':'r12' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, +{ 'name':'r13' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, +{ 'name':'r14' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, +{ 'name':'r15' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, +{ 'name':'rip' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'pc' }, +{ 'name':'rflags', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'cs' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'ss' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'ds' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'es' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'fs' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'gs' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'stmm0' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'stmm1' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'stmm2' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'stmm3' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'stmm4' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'stmm5' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'stmm6' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'stmm7' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'fctrl' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'fstat' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'ftag' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'fiseg' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'fioff' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'foseg' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'fooff' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'fop' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +{ 'name':'xmm0' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm1' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm2' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm3' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm4' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm5' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm6' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm7' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm8' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm9' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm10' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm11' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm12' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm13' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm14' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'xmm15' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 }, +{ 'name':'mxcsr' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }, +# Registers that are contained in or composed of one of more other registers +{ 'name':'eax' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rax[31:0]' }, +{ 'name':'ebx' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rbx[31:0]' }, +{ 'name':'ecx' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rcx[31:0]' }, +{ 'name':'edx' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rdx[31:0]' }, +{ 'name':'edi' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rdi[31:0]' }, +{ 'name':'esi' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rsi[31:0]' }, +{ 'name':'ebp' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rbp[31:0]' }, +{ 'name':'esp' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rsp[31:0]' }, +{ 'name':'r8d' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r8[31:0]' }, +{ 'name':'r9d' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r9[31:0]' }, +{ 'name':'r10d' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r10[31:0]' }, +{ 'name':'r11d' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r11[31:0]' }, +{ 'name':'r12d' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r12[31:0]' }, +{ 'name':'r13d' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r13[31:0]' }, +{ 'name':'r14d' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r14[31:0]' }, +{ 'name':'r15d' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r15[31:0]' }, + +{ 'name':'ax' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rax[15:0]' }, +{ 'name':'bx' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rbx[15:0]' }, +{ 'name':'cx' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rcx[15:0]' }, +{ 'name':'dx' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rdx[15:0]' }, +{ 'name':'di' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rdi[15:0]' }, +{ 'name':'si' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rsi[15:0]' }, +{ 'name':'bp' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rbp[15:0]' }, +{ 'name':'sp' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rsp[15:0]' }, +{ 'name':'r8w' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r8[15:0]' }, +{ 'name':'r9w' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r9[15:0]' }, +{ 'name':'r10w' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r10[15:0]' }, +{ 'name':'r11w' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r11[15:0]' }, +{ 'name':'r12w' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r12[15:0]' }, +{ 'name':'r13w' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r13[15:0]' }, +{ 'name':'r14w' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r14[15:0]' }, +{ 'name':'r15w' , 'set':0, 'bitsize':16 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r15[15:0]' }, + +{ 'name':'ah' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rax[15:8]' }, +{ 'name':'bh' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rbx[15:8]' }, +{ 'name':'ch' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rcx[15:8]' }, +{ 'name':'dh' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rdx[15:8]' }, + +{ 'name':'al' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rax[7:0]' }, +{ 'name':'bl' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rbx[7:0]' }, +{ 'name':'cl' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rcx[7:0]' }, +{ 'name':'dl' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rdx[7:0]' }, +{ 'name':'dil' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rdi[7:0]' }, +{ 'name':'sil' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rsi[7:0]' }, +{ 'name':'bpl' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rbp[7:0]' }, +{ 'name':'spl' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'rsp[7:0]' }, +{ 'name':'r8l' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r8[7:0]' }, +{ 'name':'r9l' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r9[7:0]' }, +{ 'name':'r10l' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r10[7:0]' }, +{ 'name':'r11l' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r11[7:0]' }, +{ 'name':'r12l' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r12[7:0]' }, +{ 'name':'r13l' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r13[7:0]' }, +{ 'name':'r14l' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r14[7:0]' }, +{ 'name':'r15l' , 'set':0, 'bitsize':8 , 'encoding':eEncodingUint , 'format':eFormatHex , 'slice': 'r15[7:0]' }, ]; g_target_definition = None @@ -268,7 +324,10 @@ def get_target_definition (): offset = 0 for reg_info in x86_64_register_infos: reg_name = reg_info['name'] - reg_info['offset'] = offset + + # Only fill in the offset if there is no 'slice' in the register info + if 'slice' not in reg_info and 'composite' not in reg_info: + reg_info['offset'] = offset # Set the GCC/DWARF register number for this register if it has one reg_num = get_reg_num(name_to_gcc_dwarf_regnum, reg_name) diff --git a/lldb/source/Interpreter/PythonDataObjects.cpp b/lldb/source/Interpreter/PythonDataObjects.cpp index 2a1f348e14b..da4e085e239 100644 --- a/lldb/source/Interpreter/PythonDataObjects.cpp +++ b/lldb/source/Interpreter/PythonDataObjects.cpp @@ -93,18 +93,22 @@ PythonObject::Str () //---------------------------------------------------------------------- PythonString::PythonString (PyObject *py_obj) : - PythonObject(py_obj) + PythonObject() { + Reset(py_obj); // Use "Reset()" to ensure that py_obj is a string } PythonString::PythonString (const PythonObject &object) : - PythonObject(object.GetPythonObject()) + PythonObject() { + Reset(object.GetPythonObject()); // Use "Reset()" to ensure that py_obj is a string } PythonString::PythonString (const lldb::ScriptInterpreterObjectSP &script_object_sp) : - PythonObject (script_object_sp) + PythonObject() { + if (script_object_sp) + Reset((PyObject *)script_object_sp->GetObject()); // Use "Reset()" to ensure that py_obj is a string } PythonString::PythonString (const char* string) : @@ -158,23 +162,28 @@ PythonString::SetString (const char* string) //---------------------------------------------------------------------- PythonInteger::PythonInteger (PyObject *py_obj) : - PythonObject(py_obj) + PythonObject() { + Reset(py_obj); // Use "Reset()" to ensure that py_obj is a integer type } PythonInteger::PythonInteger (const PythonObject &object) : - PythonObject(object.GetPythonObject()) + PythonObject() { + Reset(object.GetPythonObject()); // Use "Reset()" to ensure that py_obj is a integer type } PythonInteger::PythonInteger (const lldb::ScriptInterpreterObjectSP &script_object_sp) : - PythonObject (script_object_sp) + PythonObject() { + if (script_object_sp) + Reset((PyObject *)script_object_sp->GetObject()); // Use "Reset()" to ensure that py_obj is a string } PythonInteger::PythonInteger (int64_t value) : - PythonObject(PyInt_FromLong(value)) + PythonObject() { + SetInteger (value); } @@ -185,8 +194,11 @@ PythonInteger::~PythonInteger () bool PythonInteger::Reset (PyObject *py_obj) { - if (py_obj && PyInt_Check(py_obj)) - return PythonObject::Reset(py_obj); + if (py_obj) + { + if (PyInt_Check (py_obj) || PyLong_Check(py_obj)) + return PythonObject::Reset(py_obj); + } PythonObject::Reset(NULL); return py_obj == NULL; @@ -196,15 +208,19 @@ int64_t PythonInteger::GetInteger() { if (m_py_obj) - return PyInt_AsLong(m_py_obj); - else - return UINT64_MAX; + { + if (PyInt_Check(m_py_obj)) + return PyInt_AsLong(m_py_obj); + else if (PyLong_Check(m_py_obj)) + return PyLong_AsLongLong(m_py_obj); + } + return UINT64_MAX; } void PythonInteger::SetInteger (int64_t value) { - PythonObject::Reset(PyInt_FromLong(value)); + PythonObject::Reset(PyLong_FromLongLong(value)); } //---------------------------------------------------------------------- @@ -222,19 +238,23 @@ PythonList::PythonList (uint32_t count) : } PythonList::PythonList (PyObject *py_obj) : - PythonObject(py_obj) + PythonObject() { + Reset(py_obj); // Use "Reset()" to ensure that py_obj is a list } PythonList::PythonList (const PythonObject &object) : - PythonObject(object.GetPythonObject()) + PythonObject() { + Reset(object.GetPythonObject()); // Use "Reset()" to ensure that py_obj is a list } PythonList::PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp) : - PythonObject (script_object_sp) + PythonObject() { + if (script_object_sp) + Reset((PyObject *)script_object_sp->GetObject()); // Use "Reset()" to ensure that py_obj is a list } PythonList::~PythonList () @@ -293,17 +313,21 @@ PythonDictionary::PythonDictionary () : PythonDictionary::PythonDictionary (PyObject *py_obj) : PythonObject(py_obj) { + Reset(py_obj); // Use "Reset()" to ensure that py_obj is a dictionary } PythonDictionary::PythonDictionary (const PythonObject &object) : - PythonObject(object.GetPythonObject()) + PythonObject() { + Reset(object.GetPythonObject()); // Use "Reset()" to ensure that py_obj is a dictionary } PythonDictionary::PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp) : - PythonObject (script_object_sp) + PythonObject () { + if (script_object_sp) + Reset((PyObject *)script_object_sp->GetObject()); // Use "Reset()" to ensure that py_obj is a dictionary } PythonDictionary::~PythonDictionary () diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index 4cfe38e5840..37b32419735 100644 --- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -144,7 +144,7 @@ OperatingSystemPython::GetDynamicRegisterInfo () if (!dictionary) return NULL; - m_register_info_ap.reset (new DynamicRegisterInfo (dictionary)); + m_register_info_ap.reset (new DynamicRegisterInfo (dictionary, m_process->GetTarget().GetArchitecture().GetByteOrder())); assert (m_register_info_ap->GetNumRegisters() > 0); assert (m_register_info_ap->GetNumRegisterSets() > 0); } diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index 5caba5c4ccd..dc90b7ae02c 100644 --- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -16,6 +16,9 @@ // Other libraries and framework includes // Project includes #include "lldb/Interpreter/Args.h" +#include "lldb/Core/RegularExpression.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/DataFormatters/FormatManager.h" #ifndef LLDB_DISABLE_PYTHON #include "lldb/Interpreter/PythonDataObjects.h" @@ -29,18 +32,24 @@ DynamicRegisterInfo::DynamicRegisterInfo () : m_sets (), m_set_reg_nums (), m_set_names (), - m_reg_data_byte_size (0) + m_value_regs_map (), + m_invalidate_regs_map (), + m_reg_data_byte_size (0), + m_finalized (false) { } -DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict) : +DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict, ByteOrder byte_order) : m_regs (), m_sets (), m_set_reg_nums (), m_set_names (), - m_reg_data_byte_size (0) + m_value_regs_map (), + m_invalidate_regs_map (), + m_reg_data_byte_size (0), + m_finalized (false) { - SetRegisterInfo (dict); + SetRegisterInfo (dict, byte_order); } DynamicRegisterInfo::~DynamicRegisterInfo () @@ -49,8 +58,10 @@ DynamicRegisterInfo::~DynamicRegisterInfo () size_t -DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict) +DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict, + ByteOrder byte_order) { + assert(!m_finalized); #ifndef LLDB_DISABLE_PYTHON PythonList sets (dict.GetItemForKey("sets")); if (sets) @@ -89,6 +100,12 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict PythonString gcc_pystr("gcc"); PythonString dwarf_pystr("dwarf"); PythonString generic_pystr("generic"); + PythonString slice_pystr("slice"); + PythonString composite_pystr("composite"); + PythonString invalidate_regs_pystr("invalidate-regs"); + +// typedef std::map<std::string, std::vector<std::string> > InvalidateNameMap; +// InvalidateNameMap invalidate_map; for (uint32_t i=0; i<num_regs; ++i) { PythonDictionary reg_info_dict(regs.GetItemAtIndex(i)); @@ -96,6 +113,8 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict { // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }, RegisterInfo reg_info; + std::vector<uint32_t> value_regs; + std::vector<uint32_t> invalidate_regs; bzero (®_info, sizeof(reg_info)); reg_info.name = ConstString (reg_info_dict.GetItemForKeyAsString(name_pystr)).GetCString(); @@ -111,8 +130,168 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict if (reg_info.byte_offset == UINT32_MAX) { - Clear(); - return 0; + // No offset for this register, see if the register has a value expression + // which indicates this register is part of another register. Value expressions + // are things like "rax[31:0]" which state that the current register's value + // is in a concrete register "rax" in bits 31:0. If there is a value expression + // we can calculate the offset + bool success = false; + const char *slice_cstr = reg_info_dict.GetItemForKeyAsString(slice_pystr); + if (slice_cstr) + { + // Slices use the following format: + // REGNAME[MSBIT:LSBIT] + // REGNAME - name of the register to grab a slice of + // MSBIT - the most significant bit at which the current register value starts at + // LSBIT - the least significant bit at which the current register value ends at + static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"); + RegularExpression::Match regex_match(3); + if (g_bitfield_regex.Execute(slice_cstr, ®ex_match)) + { + llvm::StringRef reg_name_str; + std::string msbit_str; + std::string lsbit_str; + if (regex_match.GetMatchAtIndex(slice_cstr, 1, reg_name_str) && + regex_match.GetMatchAtIndex(slice_cstr, 2, msbit_str) && + regex_match.GetMatchAtIndex(slice_cstr, 3, lsbit_str)) + { + const uint32_t msbit = Args::StringToUInt32(msbit_str.c_str(), UINT32_MAX); + const uint32_t lsbit = Args::StringToUInt32(lsbit_str.c_str(), UINT32_MAX); + if (msbit != UINT32_MAX && lsbit != UINT32_MAX) + { + if (msbit > lsbit) + { + const uint32_t msbyte = msbit / 8; + const uint32_t lsbyte = lsbit / 8; + + ConstString containing_reg_name(reg_name_str); + + RegisterInfo *containing_reg_info = GetRegisterInfo (containing_reg_name); + if (containing_reg_info) + { + const uint32_t max_bit = containing_reg_info->byte_size * 8; + if (msbit < max_bit && lsbit < max_bit) + { + m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i); + m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); + m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); + + if (byte_order == eByteOrderLittle) + { + success = true; + reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte; + } + else if (byte_order == eByteOrderBig) + { + success = true; + reg_info.byte_offset = containing_reg_info->byte_offset + msbyte; + } + else + { + assert(!"Invalid byte order"); + } + } + else + { + if (msbit > max_bit) + printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit, max_bit); + else + printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit, max_bit); + } + } + else + { + printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString()); + } + } + else + { + printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit); + } + } + else + { + printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit); + } + } + else + { + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to extract regex matches for parsing the register bitfield regex\n"); + + } + } + else + { + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to match against register bitfield regex\n"); + } + } + else + { + PythonList composite_reg_list (reg_info_dict.GetItemForKey(composite_pystr)); + if (composite_reg_list) + { + const size_t num_composite_regs = composite_reg_list.GetSize(); + if (num_composite_regs > 0) + { + uint32_t composite_offset = UINT32_MAX; + for (uint32_t composite_idx=0; composite_idx<num_composite_regs; ++composite_idx) + { + PythonString composite_reg_name_pystr(composite_reg_list.GetItemAtIndex(composite_idx)); + if (composite_reg_name_pystr) + { + ConstString composite_reg_name(composite_reg_name_pystr.GetString()); + if (composite_reg_name) + { + RegisterInfo *composite_reg_info = GetRegisterInfo (composite_reg_name); + if (composite_reg_info) + { + if (composite_offset > composite_reg_info->byte_offset) + composite_offset = composite_reg_info->byte_offset; + m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); + m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i); + m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); + } + else + { + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString()); + } + } + else + { + printf("error: 'composite' key contained an empty string\n"); + } + } + else + { + printf("error: 'composite' list value wasn't a python string\n"); + } + } + if (composite_offset != UINT32_MAX) + { + reg_info.byte_offset = composite_offset; + success = m_value_regs_map.find(i) != m_value_regs_map.end(); + } + else + { + printf("error: 'composite' registers must specify at least one real register\n"); + } + } + else + { + printf("error: 'composite' list was empty\n"); + } + } + } + + + if (!success) + { + Clear(); + return 0; + } } const int64_t bitsize = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0); if (bitsize == 0) @@ -150,6 +329,7 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict return 0; } + // Fill in the register numbers reg_info.kinds[lldb::eRegisterKindLLDB] = i; reg_info.kinds[lldb::eRegisterKindGDB] = i; reg_info.kinds[lldb::eRegisterKindGCC] = reg_info_dict.GetItemForKeyAsInteger(gcc_pystr, LLDB_INVALID_REGNUM); @@ -159,6 +339,65 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister (generic_cstr); else reg_info.kinds[lldb::eRegisterKindGeneric] = reg_info_dict.GetItemForKeyAsInteger(generic_pystr, LLDB_INVALID_REGNUM); + + // Check if this register invalidates any other register values when it is modified + PythonList invalidate_reg_list (reg_info_dict.GetItemForKey(invalidate_regs_pystr)); + if (invalidate_reg_list) + { + const size_t num_regs = invalidate_reg_list.GetSize(); + if (num_regs > 0) + { + for (uint32_t idx=0; idx<num_regs; ++idx) + { + PythonObject invalidate_reg_object (invalidate_reg_list.GetItemAtIndex(idx)); + PythonString invalidate_reg_name_pystr(invalidate_reg_object); + if (invalidate_reg_name_pystr) + { + ConstString invalidate_reg_name(invalidate_reg_name_pystr.GetString()); + if (invalidate_reg_name) + { + RegisterInfo *invalidate_reg_info = GetRegisterInfo (invalidate_reg_name); + if (invalidate_reg_info) + { + m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]); + } + else + { + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n", invalidate_reg_name.GetCString(), reg_info.name); + } + } + else + { + printf("error: 'invalidate-regs' list value was an empty string\n"); + } + } + else + { + PythonInteger invalidate_reg_num(invalidate_reg_object); + + if (invalidate_reg_num) + { + const int64_t r = invalidate_reg_num.GetInteger(); + if (r != UINT64_MAX) + m_invalidate_regs_map[i].push_back(r); + else + printf("error: 'invalidate-regs' list value wasn't a valid integer\n"); + } + else + { + printf("error: 'invalidate-regs' list value wasn't a python string or integer\n"); + } + } + } + } + else + { + printf("error: 'invalidate-regs' contained an empty list\n"); + } + } + + // Calculate the register offset const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; if (m_reg_data_byte_size < end_reg_offset) m_reg_data_byte_size = end_reg_offset; @@ -176,7 +415,7 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict Finalize (); } #endif - return 0; + return m_regs.size(); } @@ -186,10 +425,22 @@ DynamicRegisterInfo::AddRegister (RegisterInfo ®_info, ConstString ®_alt_name, ConstString &set_name) { + assert(!m_finalized); const uint32_t reg_num = m_regs.size(); reg_info.name = reg_name.AsCString(); assert (reg_info.name); reg_info.alt_name = reg_alt_name.AsCString(NULL); + uint32_t i; + if (reg_info.value_regs) + { + for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i) + m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]); + } + if (reg_info.invalidate_regs) + { + for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i) + m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]); + } m_regs.push_back (reg_info); uint32_t set = GetRegisterSetIndexByName (set_name, true); assert (set < m_sets.size()); @@ -204,12 +455,99 @@ DynamicRegisterInfo::AddRegister (RegisterInfo ®_info, void DynamicRegisterInfo::Finalize () { - for (uint32_t set = 0; set < m_sets.size(); ++set) + if (m_finalized) + return; + + m_finalized = true; + const size_t num_sets = m_sets.size(); + for (size_t set = 0; set < num_sets; ++set) { assert (m_sets.size() == m_set_reg_nums.size()); m_sets[set].num_registers = m_set_reg_nums[set].size(); m_sets[set].registers = &m_set_reg_nums[set][0]; } + + // sort and unique all value registers and make sure each is terminated with + // LLDB_INVALID_REGNUM + + for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(), end = m_value_regs_map.end(); + pos != end; + ++pos) + { + if (pos->second.size() > 1) + { + std::sort (pos->second.begin(), pos->second.end()); + reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end()); + if (unique_end != pos->second.end()) + pos->second.erase(unique_end, pos->second.end()); + } + assert (!pos->second.empty()); + if (pos->second.back() != LLDB_INVALID_REGNUM) + pos->second.push_back(LLDB_INVALID_REGNUM); + } + + // Now update all value_regs with each register info as needed + const size_t num_regs = m_regs.size(); + for (size_t i=0; i<num_regs; ++i) + { + if (m_value_regs_map.find(i) != m_value_regs_map.end()) + m_regs[i].value_regs = m_value_regs_map[i].data(); + else + m_regs[i].value_regs = NULL; + } + + // Expand all invalidation dependencies + for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end(); + pos != end; + ++pos) + { + const uint32_t reg_num = pos->first; + + if (m_regs[reg_num].value_regs) + { + reg_num_collection extra_invalid_regs; + for (const uint32_t invalidate_reg_num : pos->second) + { + reg_to_regs_map::iterator invalidate_pos = m_invalidate_regs_map.find(invalidate_reg_num); + if (invalidate_pos != m_invalidate_regs_map.end()) + { + for (const uint32_t concrete_invalidate_reg_num : invalidate_pos->second) + { + if (concrete_invalidate_reg_num != reg_num) + extra_invalid_regs.push_back(concrete_invalidate_reg_num); + } + } + } + pos->second.insert(pos->second.end(), extra_invalid_regs.begin(), extra_invalid_regs.end()); + } + } + + // sort and unique all invalidate registers and make sure each is terminated with + // LLDB_INVALID_REGNUM + for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end(); + pos != end; + ++pos) + { + if (pos->second.size() > 1) + { + std::sort (pos->second.begin(), pos->second.end()); + reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end()); + if (unique_end != pos->second.end()) + pos->second.erase(unique_end, pos->second.end()); + } + assert (!pos->second.empty()); + if (pos->second.back() != LLDB_INVALID_REGNUM) + pos->second.push_back(LLDB_INVALID_REGNUM); + } + + // Now update all invalidate_regs with each register info as needed + for (size_t i=0; i<num_regs; ++i) + { + if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end()) + m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data(); + else + m_regs[i].invalidate_regs = NULL; + } } size_t @@ -283,4 +621,83 @@ DynamicRegisterInfo::Clear() m_sets.clear(); m_set_reg_nums.clear(); m_set_names.clear(); + m_value_regs_map.clear(); + m_invalidate_regs_map.clear(); + m_reg_data_byte_size = 0; + m_finalized = false; +} + +void +DynamicRegisterInfo::Dump () const +{ + StreamFile s(stdout, false); + const size_t num_regs = m_regs.size(); + s.Printf("%p: DynamicRegisterInfo contains %zu registers:\n", this, num_regs); + for (size_t i=0; i<num_regs; ++i) + { + s.Printf("[%3zu] name = %-10s", i, m_regs[i].name); + s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s", + m_regs[i].byte_size, + m_regs[i].byte_offset, + m_regs[i].encoding, + FormatManager::GetFormatAsCString (m_regs[i].format)); + if (m_regs[i].kinds[eRegisterKindGDB] != LLDB_INVALID_REGNUM) + s.Printf(", gdb = %3u", m_regs[i].kinds[eRegisterKindGDB]); + if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) + s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]); + if (m_regs[i].kinds[eRegisterKindGCC] != LLDB_INVALID_REGNUM) + s.Printf(", gcc = %3u", m_regs[i].kinds[eRegisterKindGCC]); + if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) + s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]); + if (m_regs[i].alt_name) + s.Printf(", alt-name = %s", m_regs[i].alt_name); + if (m_regs[i].value_regs) + { + s.Printf(", value_regs = [ "); + for (size_t j=0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j) + { + s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name); + } + s.Printf("]"); + } + if (m_regs[i].invalidate_regs) + { + s.Printf(", invalidate_regs = [ "); + for (size_t j=0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM; ++j) + { + s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name); + } + s.Printf("]"); + } + s.EOL(); + } + + const size_t num_sets = m_sets.size(); + s.Printf("%p: DynamicRegisterInfo contains %zu register sets:\n", this, num_sets); + for (size_t i=0; i<num_sets; ++i) + { + s.Printf("set[%zu] name = %s, regs = [", i, m_sets[i].name); + for (size_t idx=0; idx<m_sets[i].num_registers; ++idx) + { + s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name); + } + s.Printf("]\n"); + } +} + + + +lldb_private::RegisterInfo * +DynamicRegisterInfo::GetRegisterInfo (const lldb_private::ConstString ®_name) +{ + for (auto ®_info : m_regs) + { + // We can use pointer comparison since we used a ConstString to set + // the "name" member in AddRegister() + if (reg_info.name == reg_name.GetCString()) + { + return ®_info; + } + } + return NULL; } diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h index a11cd333545..a41c77e49f9 100644 --- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -13,6 +13,7 @@ // C Includes // C++ Includes #include <vector> +#include <map> // Other libraries and framework includes // Project includes @@ -24,13 +25,15 @@ class DynamicRegisterInfo public: DynamicRegisterInfo (); - DynamicRegisterInfo (const lldb_private::PythonDictionary &dict); + DynamicRegisterInfo (const lldb_private::PythonDictionary &dict, + lldb::ByteOrder byte_order); virtual ~DynamicRegisterInfo (); size_t - SetRegisterInfo (const lldb_private::PythonDictionary &dict); + SetRegisterInfo (const lldb_private::PythonDictionary &dict, + lldb::ByteOrder byte_order); void AddRegister (lldb_private::RegisterInfo ®_info, @@ -63,6 +66,9 @@ public: ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const; void + Dump () const; + + void Clear(); protected: @@ -74,12 +80,19 @@ protected: typedef std::vector <uint32_t> reg_num_collection; typedef std::vector <reg_num_collection> set_reg_num_collection; typedef std::vector <lldb_private::ConstString> name_collection; + typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map; + + lldb_private::RegisterInfo * + GetRegisterInfo (const lldb_private::ConstString ®_name); reg_collection m_regs; set_collection m_sets; set_reg_num_collection m_set_reg_nums; name_collection m_set_names; + reg_to_regs_map m_value_regs_map; + reg_to_regs_map m_invalidate_regs_map; size_t m_reg_data_byte_size; // The number of bytes required to store all registers + bool m_finalized; }; #endif // lldb_DynamicRegisterInfo_h_ diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 69dae055bb8..61c6a13d2d4 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -697,136 +697,6 @@ GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (uint32_t kind, ui return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num); } -size_t -GDBRemoteDynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict) -{ -#ifndef LLDB_DISABLE_PYTHON - PythonList sets (dict.GetItemForKey("sets")); - if (sets) - { - const uint32_t num_sets = sets.GetSize(); - for (uint32_t i=0; i<num_sets; ++i) - { - PythonString py_set_name(sets.GetItemAtIndex(i)); - ConstString set_name; - if (py_set_name) - set_name.SetCString(py_set_name.GetString()); - if (set_name) - { - RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; - m_sets.push_back (new_set); - } - else - { - Clear(); - return 0; - } - } - m_set_reg_nums.resize(m_sets.size()); - } - PythonList regs (dict.GetItemForKey("registers")); - if (regs) - { - const uint32_t num_regs = regs.GetSize(); - PythonString name_pystr("name"); - PythonString altname_pystr("alt-name"); - PythonString bitsize_pystr("bitsize"); - PythonString offset_pystr("offset"); - PythonString encoding_pystr("encoding"); - PythonString format_pystr("format"); - PythonString set_pystr("set"); - PythonString gcc_pystr("gcc"); - PythonString gdb_pystr("gdb"); - PythonString dwarf_pystr("dwarf"); - PythonString generic_pystr("generic"); - for (uint32_t i=0; i<num_regs; ++i) - { - PythonDictionary reg_info_dict(regs.GetItemAtIndex(i)); - if (reg_info_dict) - { - // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }, - RegisterInfo reg_info; - bzero (®_info, sizeof(reg_info)); - - reg_info.name = ConstString (reg_info_dict.GetItemForKeyAsString(name_pystr)).GetCString(); - if (reg_info.name == NULL) - { - Clear(); - return 0; - } - - reg_info.alt_name = ConstString (reg_info_dict.GetItemForKeyAsString(altname_pystr)).GetCString(); - - reg_info.byte_offset = reg_info_dict.GetItemForKeyAsInteger(offset_pystr, UINT32_MAX); - - if (reg_info.byte_offset == UINT32_MAX) - { - Clear(); - return 0; - } - reg_info.byte_size = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0) / 8; - - if (reg_info.byte_size == 0) - { - Clear(); - return 0; - } - - const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr); - if (format_cstr) - { - if (Args::StringToFormat(format_cstr, reg_info.format, NULL).Fail()) - { - Clear(); - return 0; - } - } - else - { - reg_info.format = (Format)reg_info_dict.GetItemForKeyAsInteger (format_pystr, eFormatHex); - } - - const char *encoding_cstr = reg_info_dict.GetItemForKeyAsString(encoding_pystr); - if (encoding_cstr) - reg_info.encoding = Args::StringToEncoding (encoding_cstr, eEncodingUint); - else - reg_info.encoding = (Encoding)reg_info_dict.GetItemForKeyAsInteger (encoding_pystr, eEncodingUint); - - const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1); - if (set >= m_sets.size()) - { - Clear(); - return 0; - } - - reg_info.kinds[lldb::eRegisterKindLLDB] = i; - reg_info.kinds[lldb::eRegisterKindGDB] = reg_info_dict.GetItemForKeyAsInteger(gdb_pystr , LLDB_INVALID_REGNUM); - reg_info.kinds[lldb::eRegisterKindGCC] = reg_info_dict.GetItemForKeyAsInteger(gcc_pystr , LLDB_INVALID_REGNUM); - reg_info.kinds[lldb::eRegisterKindDWARF] = reg_info_dict.GetItemForKeyAsInteger(dwarf_pystr , LLDB_INVALID_REGNUM); - const char *generic_cstr = reg_info_dict.GetItemForKeyAsString(generic_pystr); - if (generic_cstr) - reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister (generic_cstr); - else - reg_info.kinds[lldb::eRegisterKindGeneric] = reg_info_dict.GetItemForKeyAsInteger(generic_pystr, LLDB_INVALID_REGNUM); - const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; - if (m_reg_data_byte_size < end_reg_offset) - m_reg_data_byte_size = end_reg_offset; - - m_regs.push_back (reg_info); - m_set_reg_nums[set].push_back(i); - - } - else - { - Clear(); - return 0; - } - } - Finalize (); - } -#endif - return 0; -} void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index 319813f4005..7a49d693d44 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -21,23 +21,20 @@ #include "lldb/Core/ConstString.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Target/RegisterContext.h" +#include "Plugins/Process/Utility/DynamicRegisterInfo.h" + #include "GDBRemoteCommunicationClient.h" class ThreadGDBRemote; class ProcessGDBRemote; class StringExtractor; -class GDBRemoteDynamicRegisterInfo +class GDBRemoteDynamicRegisterInfo : + public DynamicRegisterInfo { public: GDBRemoteDynamicRegisterInfo () : - m_regs (), - m_sets (), - m_set_reg_nums (), - m_reg_names (), - m_reg_alt_names (), - m_set_names (), - m_reg_data_byte_size (0) + DynamicRegisterInfo() { } @@ -46,154 +43,8 @@ public: } void - AddRegister (lldb_private::RegisterInfo reg_info, - lldb_private::ConstString ®_name, - lldb_private::ConstString ®_alt_name, - lldb_private::ConstString &set_name) - { - const uint32_t reg_num = (uint32_t)m_regs.size(); - m_reg_names.push_back (reg_name); - m_reg_alt_names.push_back (reg_alt_name); - reg_info.name = reg_name.AsCString(); - assert (reg_info.name); - reg_info.alt_name = reg_alt_name.AsCString(NULL); - uint32_t i; - if (reg_info.value_regs) - { - for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i) - m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]); - m_value_regs_map[reg_num].push_back(LLDB_INVALID_REGNUM); - reg_info.value_regs = m_value_regs_map[reg_num].data(); - } - if (reg_info.invalidate_regs) - { - for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i) - m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]); - m_invalidate_regs_map[reg_num].push_back(LLDB_INVALID_REGNUM); - reg_info.invalidate_regs = m_invalidate_regs_map[reg_num].data(); - } - m_regs.push_back (reg_info); - uint32_t set = GetRegisterSetIndexByName (set_name); - assert (set < m_sets.size()); - assert (set < m_set_reg_nums.size()); - assert (set < m_set_names.size()); - m_set_reg_nums[set].push_back(reg_num); - size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; - if (m_reg_data_byte_size < end_reg_offset) - m_reg_data_byte_size = end_reg_offset; - } - - void - Finalize () - { - for (uint32_t set = 0; set < m_sets.size(); ++set) - { - assert (m_sets.size() == m_set_reg_nums.size()); - m_sets[set].num_registers = m_set_reg_nums[set].size(); - m_sets[set].registers = &m_set_reg_nums[set][0]; - } - } - - size_t - GetNumRegisters() const - { - return m_regs.size(); - } - - size_t - GetNumRegisterSets() const - { - return m_sets.size(); - } - - size_t - GetRegisterDataByteSize() const - { - return m_reg_data_byte_size; - } - - const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex (uint32_t i) const - { - if (i < m_regs.size()) - return &m_regs[i]; - return NULL; - } - - const lldb_private::RegisterSet * - GetRegisterSet (uint32_t i) const - { - if (i < m_sets.size()) - return &m_sets[i]; - return NULL; - } - - uint32_t - GetRegisterSetIndexByName (lldb_private::ConstString &set_name) - { - name_collection::iterator pos, end = m_set_names.end(); - for (pos = m_set_names.begin(); pos != end; ++pos) - { - if (*pos == set_name) - return static_cast<uint32_t>(std::distance (m_set_names.begin(), pos)); - } - - m_set_names.push_back(set_name); - m_set_reg_nums.resize(m_set_reg_nums.size()+1); - lldb_private::RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; - m_sets.push_back (new_set); - return static_cast<uint32_t>(m_sets.size() - 1); - } - - uint32_t - ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const - { - reg_collection::const_iterator pos, end = m_regs.end(); - for (pos = m_regs.begin(); pos != end; ++pos) - { - if (pos->kinds[kind] == num) - return static_cast<uint32_t>(std::distance (m_regs.begin(), pos)); - } - - return LLDB_INVALID_REGNUM; - } - void - Clear() - { - m_regs.clear(); - m_sets.clear(); - m_set_reg_nums.clear(); - m_reg_names.clear(); - m_reg_alt_names.clear(); - m_set_names.clear(); - } - - void HardcodeARMRegisters(bool from_scratch); - size_t - SetRegisterInfo (const lldb_private::PythonDictionary &dict); - -protected: - //------------------------------------------------------------------ - // Classes that inherit from GDBRemoteRegisterContext can see and modify these - //------------------------------------------------------------------ - typedef std::vector <lldb_private::RegisterInfo> reg_collection; - typedef std::vector <lldb_private::RegisterSet> set_collection; - typedef std::vector <uint32_t> reg_num_collection; - typedef std::vector <reg_num_collection> set_reg_num_collection; - typedef std::vector <lldb_private::ConstString> name_collection; - typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map; - - reg_collection m_regs; - set_collection m_sets; - set_reg_num_collection m_set_reg_nums; - name_collection m_reg_names; - name_collection m_reg_alt_names; - name_collection m_set_names; - reg_to_regs_map m_value_regs_map; - reg_to_regs_map m_invalidate_regs_map; - size_t m_reg_data_byte_size; // The number of bytes required to store all registers }; class GDBRemoteRegisterContext : public lldb_private::RegisterContext diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index e44d7a355f3..1b8791c6e74 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -334,7 +334,18 @@ ProcessGDBRemote::ParsePythonTargetDefinition(const FileSpec &target_definition_ if (target_dict) { - if (m_register_info.SetRegisterInfo (target_dict) > 0) + PythonDictionary host_info_dict (target_dict.GetItemForKey("host-info")); + if (host_info_dict) + { + ArchSpec host_arch (host_info_dict.GetItemForKeyAsString(PythonString("triple"))); + + if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture())) + { + GetTarget().SetArchitecture(host_arch); + } + + } + if (m_register_info.SetRegisterInfo (target_dict, GetTarget().GetArchitecture().GetByteOrder()) > 0) { return true; } @@ -522,12 +533,12 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force) if (reg_num == 0) { FileSpec target_definition_fspec = GetGlobalPluginProperties()->GetTargetDefinitionFile (); - - // See if we can get register definitions from a python file - if (ParsePythonTargetDefinition (target_definition_fspec)) + + if (target_definition_fspec) { - m_register_info.Finalize (); - return; + // See if we can get register definitions from a python file + if (ParsePythonTargetDefinition (target_definition_fspec)) + return; } } |