]> git.proxmox.com Git - mirror_edk2.git/blame - SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c
BaseTools/Capsule: Do not support -o with --dump-info
[mirror_edk2.git] / SourceLevelDebugPkg / Library / PeCoffExtraActionLibDebug / PeCoffExtraActionLib.c
CommitLineData
18b144ea 1/** @file\r
2 PE/Coff Extra Action library instances.\r
3\r
77695f4d 4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
18b144ea 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php.\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
b422b62c 15#include <PeCoffExtraActionLib.h>\r
18b144ea 16\r
17/**\r
18 Check if the hardware breakpoint in Drx is enabled by checking the Lx and Gx bit in Dr7.\r
77695f4d 19\r
18b144ea 20 It assumes that DebugAgent will set both Lx and Gx bit when setting up the hardware breakpoint.\r
21\r
22\r
23 @param RegisterIndex Index of Dr register. The value range is from 0 to 3.\r
24 @param Dr7 Value of Dr7 register.\r
25\r
26 @return TRUE The hardware breakpoint specified in the Drx is enabled.\r
27 @return FALSE The hardware breakpoint specified in the Drx is disabled.\r
28\r
29**/\r
30BOOLEAN\r
31IsDrxEnabled (\r
32 IN UINT8 RegisterIndex,\r
33 IN UINTN Dr7\r
34 )\r
35{\r
36 return (BOOLEAN) (((Dr7 >> (RegisterIndex * 2)) & (BIT0 | BIT1)) == (BIT0 | BIT1));\r
37}\r
38\r
39/**\r
93c0bdec 40 Common routine to report the PE/COFF image loading/relocating or unloading event.\r
18b144ea 41\r
42 If ImageContext is NULL, then ASSERT().\r
77695f4d 43\r
18b144ea 44 @param ImageContext Pointer to the image context structure that describes the\r
93c0bdec 45 PE/COFF image.\r
46 @param Signature IMAGE_LOAD_SIGNATURE or IMAGE_UNLOAD_SIGNATURE.\r
18b144ea 47\r
48**/\r
49VOID\r
93c0bdec 50PeCoffLoaderExtraActionCommon (\r
51 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
52 IN UINTN Signature\r
18b144ea 53 )\r
54{\r
b422b62c 55 BOOLEAN InterruptState;\r
56 UINTN Dr0;\r
57 UINTN Dr1;\r
58 UINTN Dr2;\r
59 UINTN Dr3;\r
60 UINTN Dr7;\r
61 UINTN Cr4;\r
62 UINTN NewDr7;\r
63 UINT8 LoadImageMethod;\r
64 UINT8 DebugAgentStatus;\r
65 IA32_DESCRIPTOR IdtDescriptor;\r
66 IA32_IDT_GATE_DESCRIPTOR OriginalIdtEntry;\r
67 BOOLEAN IdtEntryHooked;\r
ef530fe7 68 UINT32 RegEdx;\r
18b144ea 69\r
70 ASSERT (ImageContext != NULL);\r
71\r
72 if (ImageContext->PdbPointer != NULL) {\r
73 DEBUG((EFI_D_ERROR, " PDB = %a\n", ImageContext->PdbPointer));\r
74 }\r
75\r
76 //\r
77 // Disable interrupts and save the current interrupt state\r
78 //\r
79 InterruptState = SaveAndDisableInterrupts ();\r
80\r
b422b62c 81 IdtEntryHooked = FALSE;\r
82 LoadImageMethod = PcdGet8 (PcdDebugLoadImageMethod);\r
ef530fe7
MK
83 if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {\r
84 //\r
85 // If the CPU does not support Debug Extensions(CPUID:01 EDX:BIT2)\r
77695f4d 86 // then force use of DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3\r
ef530fe7
MK
87 //\r
88 AsmCpuid (1, NULL, NULL, NULL, &RegEdx);\r
89 if ((RegEdx & BIT2) == 0) {\r
90 LoadImageMethod = DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3;\r
91 }\r
92 }\r
b422b62c 93 AsmReadIdtr (&IdtDescriptor);\r
8cc26df4
JF
94 if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {\r
95 if (!CheckDebugAgentHandler (&IdtDescriptor, SOFT_INT_VECTOR_NUM)) {\r
b422b62c 96 //\r
97 // Do not trigger INT3 if Debug Agent did not setup IDT entries.\r
98 //\r
99 return;\r
100 }\r
8cc26df4
JF
101 } else {\r
102 if (!CheckDebugAgentHandler (&IdtDescriptor, IO_HW_BREAKPOINT_VECTOR_NUM)) {\r
103 //\r
104 // Save and update IDT entry for INT1\r
105 //\r
106 SaveAndUpdateIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry);\r
107 IdtEntryHooked = TRUE;\r
108 }\r
b422b62c 109 }\r
77695f4d 110\r
18b144ea 111 //\r
112 // Save Debug Register State\r
113 //\r
114 Dr0 = AsmReadDr0 ();\r
115 Dr1 = AsmReadDr1 ();\r
116 Dr2 = AsmReadDr2 ();\r
117 Dr3 = AsmReadDr3 ();\r
602adebb 118 Dr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't\r
18b144ea 119 Cr4 = AsmReadCr4 ();\r
120\r
121 //\r
93c0bdec 122 // DR0 = Signature\r
18b144ea 123 // DR1 = The address of the Null-terminated ASCII string for the PE/COFF image's PDB file name\r
124 // DR2 = The pointer to the ImageContext structure\r
125 // DR3 = IO_PORT_BREAKPOINT_ADDRESS\r
126 // DR7 = Disables all HW breakpoints except for DR3 I/O port access of length 1 byte\r
127 // CR4 = Make sure DE(BIT3) is set\r
128 //\r
602adebb 129 AsmWriteDr7 (BIT10);\r
93c0bdec 130 AsmWriteDr0 (Signature);\r
131 AsmWriteDr1 ((UINTN) ImageContext->PdbPointer);\r
132 AsmWriteDr2 ((UINTN) ImageContext);\r
18b144ea 133 AsmWriteDr3 (IO_PORT_BREAKPOINT_ADDRESS);\r
134\r
18b144ea 135 if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {\r
136 AsmWriteDr7 (0x20000480);\r
137 AsmWriteCr4 (Cr4 | BIT3);\r
138 //\r
139 // Do an IN from IO_PORT_BREAKPOINT_ADDRESS to generate a HW breakpoint until the port\r
140 // returns a read value other than DEBUG_AGENT_IMAGE_WAIT\r
141 //\r
142 do {\r
143 DebugAgentStatus = IoRead8 (IO_PORT_BREAKPOINT_ADDRESS);\r
144 } while (DebugAgentStatus == DEBUG_AGENT_IMAGE_WAIT);\r
145\r
146 } else if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {\r
147 //\r
148 // Generate a software break point.\r
149 //\r
150 CpuBreakpoint ();\r
151 }\r
152\r
153 //\r
154 // Restore Debug Register State only when Host didn't change it inside exception handler.\r
77695f4d 155 // E.g.: User halts the target and sets the HW breakpoint while target is\r
18b144ea 156 // in the above exception handler\r
157 //\r
602adebb 158 NewDr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't\r
93c0bdec 159 if (!IsDrxEnabled (0, NewDr7) && (AsmReadDr0 () == 0 || AsmReadDr0 () == Signature)) {\r
160 //\r
161 // If user changed Dr3 (by setting HW bp in the above exception handler,\r
162 // we will not set Dr0 to 0 in GO/STEP handler because the break cause is not IMAGE_LOAD/_UNLOAD.\r
163 //\r
18b144ea 164 AsmWriteDr0 (Dr0);\r
165 }\r
93c0bdec 166 if (!IsDrxEnabled (1, NewDr7) && (AsmReadDr1 () == (UINTN) ImageContext->PdbPointer)) {\r
18b144ea 167 AsmWriteDr1 (Dr1);\r
168 }\r
93c0bdec 169 if (!IsDrxEnabled (2, NewDr7) && (AsmReadDr2 () == (UINTN) ImageContext)) {\r
18b144ea 170 AsmWriteDr2 (Dr2);\r
171 }\r
93c0bdec 172 if (!IsDrxEnabled (3, NewDr7) && (AsmReadDr3 () == IO_PORT_BREAKPOINT_ADDRESS)) {\r
18b144ea 173 AsmWriteDr3 (Dr3);\r
174 }\r
602adebb
BJ
175 if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {\r
176 if (AsmReadCr4 () == (Cr4 | BIT3)) {\r
177 AsmWriteCr4 (Cr4);\r
178 }\r
179 if (NewDr7 == 0x20000480) {\r
180 AsmWriteDr7 (Dr7);\r
181 }\r
182 } else if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {\r
183 if (NewDr7 == BIT10) {\r
184 AsmWriteDr7 (Dr7);\r
185 }\r
18b144ea 186 }\r
187 //\r
b422b62c 188 // Restore original IDT entry for INT1 if it was hooked.\r
189 //\r
190 if (IdtEntryHooked) {\r
191 RestoreIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry);\r
192 }\r
193 //\r
18b144ea 194 // Restore the interrupt state\r
195 //\r
196 SetInterruptState (InterruptState);\r
197}\r
198\r
93c0bdec 199/**\r
200 Performs additional actions after a PE/COFF image has been loaded and relocated.\r
201\r
202 @param ImageContext Pointer to the image context structure that describes the\r
203 PE/COFF image that has already been loaded and relocated.\r
204\r
205**/\r
206VOID\r
207EFIAPI\r
208PeCoffLoaderRelocateImageExtraAction (\r
209 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
210 )\r
211{\r
212 PeCoffLoaderExtraActionCommon (ImageContext, IMAGE_LOAD_SIGNATURE);\r
213}\r
214\r
18b144ea 215/**\r
216 Performs additional actions just before a PE/COFF image is unloaded. Any resources\r
217 that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.\r
218\r
18b144ea 219 @param ImageContext Pointer to the image context structure that describes the\r
220 PE/COFF image that is being unloaded.\r
221\r
222**/\r
223VOID\r
224EFIAPI\r
225PeCoffLoaderUnloadImageExtraAction (\r
226 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
227 )\r
228{\r
93c0bdec 229 PeCoffLoaderExtraActionCommon (ImageContext, IMAGE_UNLOAD_SIGNATURE);\r
18b144ea 230}\r