00066 :
00067
00068 This routine adds an entry to
the breakpoint table and returns a handle
00069 to
the breakpoint table entry.
00070
00071 Arguments:
00072
00073 Address - Supplies
the address where to set
the breakpoint.
00074
00075 Return Value:
00076
00077
A value of zero
is returned
if the specified address
is already in
the
00078 breakpoint table, there are no free entries in
the breakpoint table,
the
00079 specified address
is not correctly aligned, or
the specified address
is
00080 not valid. Otherwise,
the index of
the assigned breakpoint table entry
00081 plus one
is returned as
the function value.
00082
00083 --*/
00084
00085 {
00086
00087
KDP_BREAKPOINT_TYPE Content;
00088 ULONG
Index;
00089 BOOLEAN Accessible;
00090 ULONG_PTR Opaque;
00091
00092
00093
00094
00095
00096
00097
00098
if (((ULONG_PTR)Address &
KDP_BREAKPOINT_ALIGN) != 0) {
00099
return 0;
00100 }
00101
00102
00103
00104
00105
00106
00107
for (
Index = 0;
Index < BREAKPOINT_TABLE_SIZE;
Index += 1) {
00108
if ((
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_IN_USE) != 0 &&
00109
KdpBreakpointTable[
Index].
Address == Address) {
00110
00111
if ((
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_NEEDS_REPLACE) != 0) {
00112
00113
00114
00115
00116
00117
00118
KdpBreakpointTable[
Index].
Flags &= ~
KD_BREAKPOINT_NEEDS_REPLACE;
00119
return Index + 1;
00120
00121 }
else {
00122
00123
DPRINT((
"KD: Attempt to set breakpoint %08x twice!\n", Address));
00124
return 0;
00125
00126 }
00127 }
00128 }
00129
00130
00131
00132
00133
00134
for (
Index = 0;
Index < BREAKPOINT_TABLE_SIZE;
Index += 1) {
00135
if (
KdpBreakpointTable[
Index].
Flags == 0) {
00136
break;
00137 }
00138 }
00139
00140
00141
00142
00143
00144
00145
if (
Index == BREAKPOINT_TABLE_SIZE) {
00146
DPRINT((
"KD: ran out of breakpoints!\n"));
00147
return 0;
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
if (
KdpMoveMemory(
00159 (PCHAR)&Content,
00160 (PCHAR)Address,
00161
sizeof(KDP_BREAKPOINT_TYPE) ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00162 Accessible =
FALSE;
00163
00164 }
else {
00165
00166 Accessible =
TRUE;
00167 }
00168
00169
00170
00171
00172
00173
if (Accessible) {
00174
if (
MmDbgWriteCheck((PVOID)Address, &Opaque) !=
NULL) {
00175
MmDbgReleaseAddress((PVOID)Address, Opaque);
00176 }
else {
00177
DPRINT((
"KD: memory not writable!\n"));
00178
return 0;
00179 }
00180 }
00181
00182
#if defined(_IA64_)
00183
if ( Accessible ) {
00184
KDP_BREAKPOINT_TYPE mBuf;
00185 PVOID BundleAddress;
00186
00187
00188
00189
00190
00191
00192
00193
if (((ULONG_PTR)Address & 0xf) != 0) {
00194 (ULONG_PTR)BundleAddress = (ULONG_PTR)Address & ~(0xf);
00195
if (
KdpMoveMemory(
00196 (PCHAR)&mBuf,
00197 (PCHAR)BundleAddress,
00198
sizeof(KDP_BREAKPOINT_TYPE)
00199 ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00200
DPRINT((
"KD: read 0x%08x template failed\n", BundleAddress));
00201
return 0;
00202 }
else {
00203
if (((mBuf & INST_TEMPL_MASK) >> 1) == 0x2) {
00204
if (((ULONG_PTR)Address & 0xf) == 4) {
00205
00206 mBuf &= ~((INST_TEMPL_MASK >> 1) << 1);
00207
KdpBreakpointTable[
Index].
Flags |=
KD_BREAKPOINT_IA64_MOVL;
00208
if (
KdpMoveMemory(
00209 (PCHAR)BundleAddress,
00210 (PCHAR)&mBuf,
00211
sizeof(KDP_BREAKPOINT_TYPE)
00212 ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00213
DPRINT((
"KD: write to 0x%08x template failed\n", BundleAddress));
00214
return 0;
00215 }
00216
else {
00217
00218 }
00219 }
else {
00220
00221
DPRINT((
"KD: illegal to set BP at slot 2 of MOVL at 0x%08x\n", BundleAddress));
00222
return 0;
00223 }
00224 }
00225 }
00226 }
00227
00228
00229
00230
KdpBreakpointTable[
Index].
Address = Address;
00231
KdpBreakpointTable[
Index].
Content = Content;
00232
KdpBreakpointTable[
Index].
Flags &= ~(
KD_BREAKPOINT_STATE_MASK);
00233
KdpBreakpointTable[
Index].
Flags |=
KD_BREAKPOINT_IN_USE;
00234
if (Address < (PVOID)
GLOBAL_BREAKPOINT_LIMIT) {
00235
KdpBreakpointTable[
Index].
DirectoryTableBase =
00236
KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0];
00237 }
00238
switch ((ULONG_PTR)Address & 0xf) {
00239
case 0:
00240 Content = (Content & ~(INST_SLOT0_MASK)) | (
KdpBreakpointInstruction << 5);
00241
break;
00242
00243
case 4:
00244 Content = (Content & ~(INST_SLOT1_MASK)) | (
KdpBreakpointInstruction << 14);
00245
break;
00246
00247
case 8:
00248 Content = (Content & ~(INST_SLOT2_MASK)) | (
KdpBreakpointInstruction << 23);
00249
break;
00250
00251
default:
00252
DPRINT((
"KD: KdpAddBreakpoint bad instruction slot#\n"));
00253
return 0;
00254 }
00255
if (
KdpMoveMemory(
00256 (PCHAR)Address,
00257 (PCHAR)&Content,
00258
sizeof(KDP_BREAKPOINT_TYPE)
00259 ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00260
00261
DPRINT((
"KD: KdpMoveMemory failed writing BP!\n"));
00262
return 0;
00263 }
00264
else {
00265
00266 }
00267
00268 }
else {
00269
KdpBreakpointTable[
Index].
Address = Address;
00270
KdpBreakpointTable[
Index].
Flags &= ~(
KD_BREAKPOINT_STATE_MASK);
00271
KdpBreakpointTable[
Index].
Flags |=
KD_BREAKPOINT_IN_USE;
00272
KdpBreakpointTable[
Index].
Flags |=
KD_BREAKPOINT_NEEDS_WRITE;
00273
KdpOweBreakpoint =
TRUE;
00274
00275
if (Address < (PVOID)
GLOBAL_BREAKPOINT_LIMIT) {
00276
KdpBreakpointTable[
Index].
DirectoryTableBase =
00277
KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0];
00278 }
00279 }
00280
#else
00281
if ( Accessible ) {
00282
KdpBreakpointTable[
Index].
Address = Address;
00283
KdpBreakpointTable[
Index].
Content = Content;
00284
KdpBreakpointTable[
Index].
Flags =
KD_BREAKPOINT_IN_USE;
00285
if (Address < (PVOID)
GLOBAL_BREAKPOINT_LIMIT) {
00286
KdpBreakpointTable[
Index].
DirectoryTableBase =
00287
KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0];
00288 }
00289
if (
KdpMoveMemory(
00290 (PCHAR)Address,
00291 (PCHAR)&KdpBreakpointInstruction,
00292
sizeof(KDP_BREAKPOINT_TYPE)
00293 ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00294
00295
DPRINT((
"KD: KdpMoveMemory failed writing BP!\n"));
00296 }
00297 }
else {
00298
KdpBreakpointTable[
Index].
Address = Address;
00299
KdpBreakpointTable[
Index].
Flags =
KD_BREAKPOINT_IN_USE |
KD_BREAKPOINT_NEEDS_WRITE;
00300
KdpOweBreakpoint =
TRUE;
00301
00302
if (Address < (PVOID)
GLOBAL_BREAKPOINT_LIMIT) {
00303
KdpBreakpointTable[
Index].
DirectoryTableBase =
00304
KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0];
00305 }
00306 }
00307
#endif // IA64
00308
00309
return Index + 1;
00310
00311 }