ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

kdinit.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            ntoskrnl/kd64/kdinit.c
00005  * PURPOSE:         KD64 Initialization Code
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  *                  Stefan Ginsberg (stefan.ginsberg@reactos.org)
00008  */
00009 
00010 /* INCLUDES ******************************************************************/
00011 
00012 #include <ntoskrnl.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* FUNCTIONS *****************************************************************/
00017 
00018 VOID
00019 NTAPI
00020 KdUpdateDataBlock(VOID)
00021 {
00022     /* Update the KeUserCallbackDispatcher pointer */
00023     KdDebuggerDataBlock.KeUserCallbackDispatcher =
00024         (ULONG_PTR)KeUserCallbackDispatcher;
00025 }
00026 
00027 BOOLEAN
00028 NTAPI
00029 KdRegisterDebuggerDataBlock(IN ULONG Tag,
00030                             IN PDBGKD_DEBUG_DATA_HEADER64 DataHeader,
00031                             IN ULONG Size)
00032 {
00033     KIRQL OldIrql;
00034     PLIST_ENTRY NextEntry;
00035     PDBGKD_DEBUG_DATA_HEADER64 CurrentHeader;
00036 
00037     /* Acquire the Data Lock */
00038     KeAcquireSpinLock(&KdpDataSpinLock, &OldIrql);
00039 
00040     /* Loop the debugger data list */
00041     NextEntry = KdpDebuggerDataListHead.Flink;
00042     while (NextEntry != &KdpDebuggerDataListHead)
00043     {
00044         /* Get the header for this entry */
00045         CurrentHeader = CONTAINING_RECORD(NextEntry,
00046                                           DBGKD_DEBUG_DATA_HEADER64,
00047                                           List);
00048 
00049         /*  Move to the next one */
00050         NextEntry = NextEntry->Flink;
00051 
00052         /* Check if we already have this data block */
00053         if ((CurrentHeader == DataHeader) || (CurrentHeader->OwnerTag == Tag))
00054         {
00055             /* Release the lock and fail */
00056             KeReleaseSpinLock(&KdpDataSpinLock, OldIrql);
00057             return FALSE;
00058         }
00059     }
00060 
00061     /* Setup the header */
00062     DataHeader->OwnerTag = Tag;
00063     DataHeader->Size = Size;
00064 
00065     /* Insert it into the list and release the lock */
00066     InsertTailList(&KdpDebuggerDataListHead, (PLIST_ENTRY)&DataHeader->List);
00067     KeReleaseSpinLock(&KdpDataSpinLock, OldIrql);
00068     return TRUE;
00069 }
00070 
00071 BOOLEAN
00072 NTAPI
00073 KdInitSystem(IN ULONG BootPhase,
00074              IN PLOADER_PARAMETER_BLOCK LoaderBlock)
00075 {
00076     BOOLEAN EnableKd, DisableKdAfterInit = FALSE, BlockEnable;
00077     LPSTR CommandLine, DebugLine, DebugOptionStart, DebugOptionEnd;
00078     STRING ImageName;
00079     PLDR_DATA_TABLE_ENTRY LdrEntry;
00080     PLIST_ENTRY NextEntry;
00081     ULONG i, j, Length;
00082     SIZE_T DebugOptionLength;
00083     CHAR NameBuffer[256];
00084     PWCHAR Name;
00085 
00086 #if defined(__GNUC__)
00087     /* Make gcc happy */
00088     BlockEnable = FALSE;
00089 #endif
00090 
00091     /* Check if this is Phase 1 */
00092     if (BootPhase)
00093     {
00094         /* Just query the performance counter */
00095         KeQueryPerformanceCounter(&KdPerformanceCounterRate);
00096         return TRUE;
00097     }
00098 
00099     /* Check if we already initialized once */
00100     if (KdDebuggerEnabled) return TRUE;
00101 
00102     /* Set the Debug Routine as the Stub for now */
00103     KiDebugRoutine = KdpStub;
00104 
00105     /* Disable break after symbol load for now */
00106     KdBreakAfterSymbolLoad = FALSE;
00107 
00108     /* Check if the Debugger Data Block was already initialized */
00109     if (!KdpDebuggerDataListHead.Flink)
00110     {
00111         /* It wasn't...Initialize the KD Data Listhead */
00112         InitializeListHead(&KdpDebuggerDataListHead);
00113 
00114         /* Register the Debugger Data Block */
00115         KdRegisterDebuggerDataBlock(KDBG_TAG,
00116                                     &KdDebuggerDataBlock.Header,
00117                                     sizeof(KdDebuggerDataBlock));
00118 
00119         /* Fill out the KD Version Block */
00120         KdVersionBlock.MajorVersion = (USHORT)((DBGKD_MAJOR_NT << 8) | (NtBuildNumber >> 28));
00121         KdVersionBlock.MinorVersion = (USHORT)(NtBuildNumber & 0xFFFF);
00122 
00123 #ifdef CONFIG_SMP
00124         /* This is an MP Build */
00125         KdVersionBlock.Flags |= DBGKD_VERS_FLAG_MP;
00126 #endif
00127 
00128         /* Save Pointers to Loaded Module List and Debugger Data */
00129         KdVersionBlock.PsLoadedModuleList = (ULONG64)(LONG_PTR)&PsLoadedModuleList;
00130         KdVersionBlock.DebuggerDataList = (ULONG64)(LONG_PTR)&KdpDebuggerDataListHead;
00131 
00132         /* Set protocol limits */
00133         KdVersionBlock.MaxStateChange = DbgKdMaximumStateChange -
00134                                         DbgKdMinimumStateChange;
00135         KdVersionBlock.MaxManipulate = DbgKdMaximumManipulate -
00136                                        DbgKdMinimumManipulate;
00137         KdVersionBlock.Unused[0] = 0;
00138 
00139         /* Link us in the KPCR */
00140         KeGetPcr()->KdVersionBlock =  &KdVersionBlock;
00141     }
00142 
00143     /* Check if we have a loader block */
00144     if (LoaderBlock)
00145     {
00146         /* Get the image entry */
00147         LdrEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink,
00148                                      LDR_DATA_TABLE_ENTRY,
00149                                      InLoadOrderLinks);
00150 
00151         /* Save the Kernel Base */
00152         PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
00153         KdVersionBlock.KernBase = (ULONG64)(LONG_PTR)LdrEntry->DllBase;
00154 
00155         /* Check if we have a command line */
00156         CommandLine = LoaderBlock->LoadOptions;
00157         if (CommandLine)
00158         {
00159             /* Upcase it */
00160             _strupr(CommandLine);
00161 
00162             /* Assume we'll disable KD */
00163             EnableKd = FALSE;
00164 
00165             /* Check for CRASHDEBUG, NODEBUG and just DEBUG */
00166             if (strstr(CommandLine, "CRASHDEBUG"))
00167             {
00168                 /* Don't enable KD now, but allow it to be enabled later */
00169                 KdPitchDebugger = FALSE;
00170             }
00171             else if (strstr(CommandLine, "NODEBUG"))
00172             {
00173                 /* Don't enable KD and don't let it be enabled later */
00174                 KdPitchDebugger = TRUE;
00175             }
00176             else if ((DebugLine = strstr(CommandLine, "DEBUG")) != NULL)
00177             {
00178                 /* Enable KD */
00179                 EnableKd = TRUE;
00180 
00181                 /* Check if there are any options */
00182                 if (DebugLine[5] == '=')
00183                 {
00184                     /* Save pointers */
00185                     DebugOptionStart = DebugOptionEnd = &DebugLine[6];
00186 
00187                     /* Scan the string for debug options */
00188                     for (;;)
00189                     {
00190                         /* Loop until we reach the end of the string */
00191                         while (*DebugOptionEnd != ANSI_NULL)
00192                         {
00193                             /* Check if this is a comma, a space or a tab */
00194                             if ((*DebugOptionEnd == ',') ||
00195                                 (*DebugOptionEnd == ' ') ||
00196                                 (*DebugOptionEnd == '   '))
00197                             {
00198                                 /*
00199                                  * We reached the end of the option or
00200                                  * the end of the string, break out
00201                                  */
00202                                 break;
00203                             }
00204                             else
00205                             {
00206                                 /* Move on to the next character */
00207                                 DebugOptionEnd++;
00208                             }
00209                         }
00210 
00211                         /* Calculate the length of the current option */
00212                         DebugOptionLength = (DebugOptionEnd - DebugOptionStart);
00213 
00214                        /*
00215                         * Break out if we reached the last option
00216                         * or if there were no options at all
00217                         */
00218                        if (!DebugOptionLength) break;
00219 
00220                         /* Now check which option this is */
00221                         if ((DebugOptionLength == 10) &&
00222                             !(strncmp(DebugOptionStart, "AUTOENABLE", 10)))
00223                         {
00224                             /*
00225                              * Disable the debugger, but
00226                              * allow it to be reenabled
00227                              */
00228                             DisableKdAfterInit = TRUE;
00229                             BlockEnable = FALSE;
00230                             KdAutoEnableOnEvent = TRUE;
00231                         }
00232                         else if ((DebugOptionLength == 7) &&
00233                                  !(strncmp(DebugOptionStart, "DISABLE", 7)))
00234                         {
00235                             /* Disable the debugger */
00236                             DisableKdAfterInit = TRUE;
00237                             BlockEnable = TRUE;
00238                             KdAutoEnableOnEvent = FALSE;
00239                         }
00240                         else if ((DebugOptionLength == 6) &&
00241                                  !(strncmp(DebugOptionStart, "NOUMEX", 6)))
00242                         {
00243                             /* Ignore user mode exceptions */
00244                             KdIgnoreUmExceptions = TRUE;
00245                         }
00246 
00247                         /*
00248                          * If there are more options then
00249                          * the next character should be a comma
00250                          */
00251                         if (*DebugOptionEnd != ',')
00252                         {
00253                             /* It isn't, break out  */
00254                             break;
00255                         }
00256 
00257                         /* Move on to the next option */
00258                         DebugOptionEnd++;
00259                         DebugOptionStart = DebugOptionEnd;
00260                     }
00261                 }
00262             }
00263         }
00264         else
00265         {
00266             /* No command line options? Disable debugger by default */
00267             KdPitchDebugger = TRUE;
00268             EnableKd = FALSE;
00269         }
00270     }
00271     else
00272     {
00273         /* Called from a bugcheck or a re-enable. Save the Kernel Base */
00274         KdVersionBlock.KernBase = (ULONG64)(LONG_PTR)PsNtosImageBase;
00275 
00276         /* Unconditionally enable KD */
00277         EnableKd = TRUE;
00278     }
00279 
00280     /* Set the Kernel Base in the Data Block */
00281     KdDebuggerDataBlock.KernBase = (ULONG_PTR)KdVersionBlock.KernBase;
00282 
00283     /* Initialize the debugger if requested */
00284     if ((EnableKd) && (NT_SUCCESS(KdDebuggerInitialize0(LoaderBlock))))
00285     {
00286         /* Now set our real KD routine */
00287         KiDebugRoutine = KdpTrap;
00288 
00289         /* Check if we've already initialized our structures */
00290         if (!KdpDebuggerStructuresInitialized)
00291         {
00292             /* Set the Debug Switch Routine and Retries*/
00293             KdpContext.KdpDefaultRetries = 20;
00294             KiDebugSwitchRoutine = KdpSwitchProcessor;
00295 
00296             /* Initialize the Time Slip DPC */
00297             KeInitializeDpc(&KdpTimeSlipDpc, KdpTimeSlipDpcRoutine, NULL);
00298             KeInitializeTimer(&KdpTimeSlipTimer);
00299             ExInitializeWorkItem(&KdpTimeSlipWorkItem, KdpTimeSlipWork, NULL);
00300 
00301             /* First-time initialization done! */
00302             KdpDebuggerStructuresInitialized = TRUE;
00303         }
00304 
00305         /* Initialize the timer */
00306         KdTimerStart.QuadPart = 0;
00307 
00308         /* Officially enable KD */
00309         KdPitchDebugger = FALSE;
00310         KdDebuggerEnabled = TRUE;
00311 
00312         /* Let user-mode know that it's enabled as well */
00313 #undef KdDebuggerEnabled
00314         SharedUserData->KdDebuggerEnabled = TRUE;
00315 #define KdDebuggerEnabled _KdDebuggerEnabled
00316 
00317         /* Check if the debugger should be disabled initially */
00318         if (DisableKdAfterInit)
00319         {
00320             /* Disable it */
00321             KdDisableDebuggerWithLock(FALSE);
00322 
00323             /*
00324              * Save the enable block state and return initialized
00325              * (the debugger is active but disabled).
00326              */
00327             KdBlockEnable = BlockEnable;
00328             return TRUE;
00329         }
00330 
00331         /* Check if we have a loader block */
00332         if (LoaderBlock)
00333         {
00334             /* Loop boot images */
00335             NextEntry = LoaderBlock->LoadOrderListHead.Flink;
00336             i = 0;
00337             while ((NextEntry != &LoaderBlock->LoadOrderListHead) && (i < 2))
00338             {
00339                 /* Get the image entry */
00340                 LdrEntry = CONTAINING_RECORD(NextEntry,
00341                                              LDR_DATA_TABLE_ENTRY,
00342                                              InLoadOrderLinks);
00343 
00344                 /* Generate the image name */
00345                 Name = LdrEntry->FullDllName.Buffer;
00346                 Length = LdrEntry->FullDllName.Length / sizeof(WCHAR);
00347                 j = 0;
00348                 do
00349                 {
00350                     /* Do cheap Unicode to ANSI conversion */
00351                     NameBuffer[j++] = (CHAR)*Name++;
00352                 } while (j < Length);
00353 
00354                 /* Null-terminate */
00355                 NameBuffer[j] = ANSI_NULL;
00356 
00357                 /* Load symbols for image */
00358                 RtlInitString(&ImageName, NameBuffer);
00359                 DbgLoadImageSymbols(&ImageName,
00360                                     LdrEntry->DllBase,
00361                                     (ULONG_PTR)ZwCurrentProcess());
00362 
00363                 /* Go to the next entry */
00364                 NextEntry = NextEntry->Flink;
00365                 i++;
00366             }
00367         }
00368 
00369         /* Check for incoming breakin and break on symbol load if we have it*/
00370         KdBreakAfterSymbolLoad = KdPollBreakIn();
00371     }
00372     else
00373     {
00374         /* Disable debugger */
00375         KdDebuggerNotPresent = TRUE;
00376     }
00377 
00378     /* Return initialized */
00379     return TRUE;
00380 }

Generated on Sun May 27 2012 04:37:19 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.