[LLDB] [ARM] Use r11 as frame pointer on Windows on ARM
authorMartin Storsjö <martin@martin.st>
Tue, 15 Oct 2019 21:08:28 +0000 (00:08 +0300)
committerMartin Storsjö <martin@martin.st>
Fri, 29 Nov 2019 14:06:17 +0000 (16:06 +0200)
Extend EmulateMOVRdRm to identify "mov r11, sp" in thumb mode as
setting the frame pointer, if r11 is the frame pointer register.

Differential Revision: https://reviews.llvm.org/D70797

lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
lldb/test/Shell/Minidump/Windows/Inputs/arm-fp-unwind.dmp.yaml [new file with mode: 0644]
lldb/test/Shell/Minidump/Windows/Inputs/arm-fp-unwind.exe.yaml [new file with mode: 0644]
lldb/test/Shell/Minidump/Windows/arm-fp-unwind.test [new file with mode: 0644]

index 19a987b..ff142e6 100644 (file)
@@ -850,6 +850,7 @@ uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
 
   /* On Apple iOS et al, the frame pointer register is always r7.
    * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
+   * Windows on ARM, which is in thumb mode, uses r11 though.
    */
 
   uint32_t fp_regnum = 11;
@@ -857,7 +858,7 @@ uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
   if (is_apple)
     fp_regnum = 7;
 
-  if (m_opcode_mode == eModeThumb)
+  if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
     fp_regnum = 7;
 
   return fp_regnum;
@@ -879,6 +880,7 @@ uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
 
   /* On Apple iOS et al, the frame pointer register is always r7.
    * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
+   * Windows on ARM, which is in thumb mode, uses r11 though.
    */
 
   uint32_t fp_regnum = dwarf_r11;
@@ -886,7 +888,7 @@ uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
   if (is_apple)
     fp_regnum = dwarf_r7;
 
-  if (m_opcode_mode == eModeThumb)
+  if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
     fp_regnum = dwarf_r7;
 
   return fp_regnum;
@@ -1343,6 +1345,8 @@ bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
     EmulateInstruction::Context context;
     if (Rd == 13)
       context.type = EmulateInstruction::eContextAdjustStackPointer;
+    else if (Rd == GetFramePointerRegisterNumber() && Rm == 13)
+      context.type = EmulateInstruction::eContextSetFramePointer;
     else
       context.type = EmulateInstruction::eContextRegisterPlusOffset;
     RegisterInfo dwarf_reg;
diff --git a/lldb/test/Shell/Minidump/Windows/Inputs/arm-fp-unwind.dmp.yaml b/lldb/test/Shell/Minidump/Windows/Inputs/arm-fp-unwind.dmp.yaml
new file mode 100644 (file)
index 0000000..330a761
--- /dev/null
@@ -0,0 +1,37 @@
+--- !minidump
+Version:         0xA0BAA793
+Flags:           0x0000000000000800
+Streams:
+  - Type:            ThreadList
+    Threads:
+      - Thread Id:       0x00004034
+        Suspend Count:   0x00000001
+        Priority Class:  0x00000020
+        Environment Block: 0x00000000007E6000
+        Context:         0000000000000000
+        Stack:
+          Start of Memory Range: 0x00000000008FF758
+          Content:         00000000000000
+  - Type:            ModuleList
+    Modules:
+      - Base of Image:   0x0000000000C70000
+        Size of Image:   0x00002000
+        Time Date Stamp: 1574942531
+        Module Name:     'arm-fp-unwind.exe'
+        CodeView Record: ''
+        Reserved0:       0x0000000000008140
+  - Type:            SystemInfo
+    Processor Arch:  ARM
+    Processor Level: 2049
+    Processor Revision: 2564
+    Number of Processors: 8
+    Product type:    1
+    Major Version:   10
+    Build Number:    18362
+    Platform ID:     Win32NT
+    Suite Mask:      0x0100
+    CPU:
+      CPUID:           0xEB8C1004
+  - Type:            MiscInfo
+    Content:         54050000F7010000183800002EB9DF5D00000000000000006C0700002B0100006C0700000400000003000000002000000D000000000000000100000088FFFFFF46004C00450020005300740061006E0064006100720064002000540069006D00650000000000000000000000000000000000000000000000000000000000000000000A000000050004000000000000000000000046004C00450020004400610079006C0069006700680074002000540069006D00650000000000000000000000000000000000000000000000000000000000000000000300000005000300000000000000C4FFFFFF310038003300360032002E003200330039002E00610072006D006600720065002E0031003900680031005F00720065006C0065006100730065005F007300760063005F00700072006F00640031002E003100390030003600320038002D0031003600340031000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064006200670063006F00720065002E0077006F0061002C00310030002E0030002E00310038003300360032002E003100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+...
diff --git a/lldb/test/Shell/Minidump/Windows/Inputs/arm-fp-unwind.exe.yaml b/lldb/test/Shell/Minidump/Windows/Inputs/arm-fp-unwind.exe.yaml
new file mode 100644 (file)
index 0000000..f322906
--- /dev/null
@@ -0,0 +1,92 @@
+--- !COFF
+OptionalHeader:
+  AddressOfEntryPoint: 4097
+  ImageBase:       4194304
+  SectionAlignment: 4096
+  FileAlignment:   512
+  MajorOperatingSystemVersion: 6
+  MinorOperatingSystemVersion: 0
+  MajorImageVersion: 0
+  MinorImageVersion: 0
+  MajorSubsystemVersion: 6
+  MinorSubsystemVersion: 0
+  Subsystem:       IMAGE_SUBSYSTEM_WINDOWS_CUI
+  DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
+  SizeOfStackReserve: 1048576
+  SizeOfStackCommit: 4096
+  SizeOfHeapReserve: 1048576
+  SizeOfHeapCommit: 4096
+  ExportTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  ImportTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  ResourceTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  ExceptionTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  CertificateTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  BaseRelocationTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  Debug:
+    RelativeVirtualAddress: 0
+    Size:            0
+  Architecture:
+    RelativeVirtualAddress: 0
+    Size:            0
+  GlobalPtr:
+    RelativeVirtualAddress: 0
+    Size:            0
+  TlsTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  LoadConfigTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  BoundImport:
+    RelativeVirtualAddress: 0
+    Size:            0
+  IAT:
+    RelativeVirtualAddress: 0
+    Size:            0
+  DelayImportDescriptor:
+    RelativeVirtualAddress: 0
+    Size:            0
+  ClrRuntimeHeader:
+    RelativeVirtualAddress: 0
+    Size:            0
+header:
+  Machine:         IMAGE_FILE_MACHINE_ARMNT
+  Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_32BIT_MACHINE ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    VirtualAddress:  4096
+    VirtualSize:     38
+    SectionData:     2DE90048EB46ADF5007D684600F004F80DF5007DBDE8008800BE01784278415C805C08447047
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            entry
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            other
+    Value:           24
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/lldb/test/Shell/Minidump/Windows/arm-fp-unwind.test b/lldb/test/Shell/Minidump/Windows/arm-fp-unwind.test
new file mode 100644 (file)
index 0000000..35ea7c8
--- /dev/null
@@ -0,0 +1,17 @@
+Test that unwind plans use the frame pointer register correctly.
+
+REQUIRES: arm
+
+RUN: yaml2obj %S/Inputs/arm-fp-unwind.exe.yaml > %T/arm-fp-unwind.exe
+RUN: yaml2obj %S/Inputs/arm-fp-unwind.dmp.yaml > %T/arm-fp-unwind.dmp
+RUN: %lldb -O "settings set target.exec-search-paths %T" \
+RUN:   -c %T/arm-fp-unwind.dmp -o "image show-unwind -a 0x00c71010" -b \
+RUN:   | FileCheck %s
+
+CHECK: Assembly language inspection UnwindPlan:
+CHECK-NEXT: This UnwindPlan originally sourced from EmulateInstructionARM
+CHECK-NEXT: This UnwindPlan is sourced from the compiler: no.
+CHECK-NEXT: This UnwindPlan is valid at all instruction locations: yes.
+CHECK-NEXT: row[0]:    0: CFA=sp +0 =>
+CHECK-NEXT: row[1]:    4: CFA=sp +8 => fp=[CFA-8] lr=[CFA-4]
+CHECK-NEXT: row[2]:    6: CFA=fp +8 => fp=[CFA-8] lr=[CFA-4]