From 4f505e46f5d09c79d8ff0c8fef09f12370d13c02 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 15 Dec 2010 23:37:54 +0000 Subject: [PATCH] [CMAKE] - Arty: Add usermode addresses translation support. WIP. svn path=/branches/cmake-bringup/; revision=50033 --- lib/rossym/delete.c | 5 --- lib/rossym/dwarf.h | 4 +- lib/rossym/dwarfinfo.c | 2 +- lib/rossym/dwarfopen.c | 1 + lib/rossym/dwarfpc.c | 11 +++-- lib/rossym/fromfile.c | 13 +++++- lib/rossym/initum.c | 7 ++- lib/rossym/pe.c | 4 ++ lib/rossym/zwfile.c | 14 +++--- ntoskrnl/kdbg/kdb_symbols.c | 89 +++++++++++++++++++++++++++++++++---- 10 files changed, 120 insertions(+), 30 deletions(-) diff --git a/lib/rossym/delete.c b/lib/rossym/delete.c index 32bc9b24f4b..1e6fe8393e2 100644 --- a/lib/rossym/delete.c +++ b/lib/rossym/delete.c @@ -22,11 +22,6 @@ VOID RosSymDelete(PROSSYM_INFO RosSymInfo) { - int i; - for (i = 0; i < RosSymInfo->pe->nsections; i++) { - RtlFreeAnsiString(ANSI_NAME_STRING(&RosSymInfo->pe->sect[i])); - } - RosSymFreeMem(RosSymInfo->pe->sect); dwarfclose(RosSymInfo); } diff --git a/lib/rossym/dwarf.h b/lib/rossym/dwarf.h index 5ece05818a2..04689814bd7 100644 --- a/lib/rossym/dwarf.h +++ b/lib/rossym/dwarf.h @@ -252,7 +252,7 @@ struct DwarfAttrs uchar framebase; uchar friend; uchar highpc; - uchar entrypc; + uchar entrypc; uchar identifiercase; uchar import; uchar inlined; @@ -315,7 +315,7 @@ struct DwarfAttrs DwarfVal framebase; ulong friend; ulong highpc; - ulong entrypc; + ulong entrypc; ulong identifiercase; ulong import; ulong inlined; diff --git a/lib/rossym/dwarfinfo.c b/lib/rossym/dwarfinfo.c index ae704d241ff..cc25499483a 100644 --- a/lib/rossym/dwarfinfo.c +++ b/lib/rossym/dwarfinfo.c @@ -366,7 +366,7 @@ static Parse plist[] = { /* Font Tab 4 */ { DwarfAttrFrameBase, OFFSET(framebase), TBlock|TConstant }, { DwarfAttrFriend, OFFSET(friend), TReference }, { DwarfAttrHighpc, OFFSET(highpc), TAddress }, - { DwarfAttrEntrypc, OFFSET(entrypc), TAddress }, + { DwarfAttrEntrypc, OFFSET(entrypc), TAddress }, { DwarfAttrIdentifierCase, OFFSET(identifiercase), TConstant }, { DwarfAttrImport, OFFSET(import), TReference }, { DwarfAttrInline, OFFSET(inlined), TConstant }, diff --git a/lib/rossym/dwarfopen.c b/lib/rossym/dwarfopen.c index 67279fce0b0..9a5f20c80fa 100644 --- a/lib/rossym/dwarfopen.c +++ b/lib/rossym/dwarfopen.c @@ -40,6 +40,7 @@ dwarfopen(Pe *pe) return d; err: + DPRINT("Failed to open dwarf\n"); free(d->abbrev.data); free(d->aranges.data); free(d->frame.data); diff --git a/lib/rossym/dwarfpc.c b/lib/rossym/dwarfpc.c index 90bbf7249fc..4edb5569ae9 100644 --- a/lib/rossym/dwarfpc.c +++ b/lib/rossym/dwarfpc.c @@ -50,7 +50,7 @@ dwarfpctoline(Dwarf *d, ulong pc, char **cdir, char **dir, char **file, char **f { uchar *prog, *opcount, *end, *dirs; ulong off, unit, len, vers, x, start, lastline; - int i, first, op, a, l, quantum, isstmt, linebase, linerange, opcodebase, nf; + int i, first, firstline, op, a, l, quantum, isstmt, linebase, linerange, opcodebase, nf; char *files, *s; DwarfBuf b; DwarfSym sym; @@ -150,6 +150,7 @@ dwarfpctoline(Dwarf *d, ulong pc, char **cdir, char **dir, char **file, char **f if(trace) werrstr("program @ %lu ... %.*H opbase = %d\n", b.p - d->line.data, b.ep-b.p, b.p, opcodebase); first = 1; while(b.p != nil){ + firstline = 0; op = dwarfget1(&b); if(trace) werrstr("\tline %lu, addr 0x%x, op %d %.10H", cur.line, cur.addr, op, b.p); if(op >= opcodebase){ @@ -162,12 +163,16 @@ dwarfpctoline(Dwarf *d, ulong pc, char **cdir, char **dir, char **file, char **f if(first){ if(cur.addr > pc){ werrstr("found wrong line mapping 0x%x for pc 0x%x", cur.addr, pc); - goto out; + /* This is an overzealous check. gcc can produce discontiguous ranges + and reorder statements, so it's possible for a future line to start + ahead of pc and still find a matching one. */ + /*goto out;*/ + firstline = 1; } first = 0; start = cur.addr; } - if(cur.addr > pc) + if(cur.addr > pc && !firstline) break; if(b.p == nil){ werrstr("buffer underflow in line mapping"); diff --git a/lib/rossym/fromfile.c b/lib/rossym/fromfile.c index fe444c438fa..a1300f40722 100644 --- a/lib/rossym/fromfile.c +++ b/lib/rossym/fromfile.c @@ -20,6 +20,8 @@ #define NDEBUG #include +extern NTSTATUS RosSymStatus; + BOOLEAN RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo) { @@ -30,10 +32,14 @@ RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo) unsigned SymbolTable, NumSymbols; /* Load DOS header */ - DPRINT("About to read file\n"); + if (! RosSymSeekFile(FileContext, 0)) + { + DPRINT1("Could not rewind file\n"); + return FALSE; + } if (! RosSymReadFile(FileContext, &DosHeader, sizeof(IMAGE_DOS_HEADER))) { - DPRINT1("Failed to read DOS header\n"); + DPRINT1("Failed to read DOS header %x\n", RosSymStatus); return FALSE; } if (! ROSSYM_IS_VALID_DOS_HEADER(&DosHeader)) @@ -70,6 +76,7 @@ RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo) DPRINT1("Failed seeking to section headers\n"); return FALSE; } + DPRINT("Alloc section headers\n"); SectionHeaders = RosSymAllocMem(NtHeaders.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER)); if (NULL == SectionHeaders) @@ -178,7 +185,9 @@ RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo) pe->imagebase = pe->loadbase = NtHeaders.OptionalHeader.ImageBase; pe->imagesize = NtHeaders.OptionalHeader.SizeOfImage; pe->loadsection = loaddisksection; + DPRINT("do dwarfopen\n"); *RosSymInfo = dwarfopen(pe); + DPRINT("done %x\n", *RosSymInfo); return TRUE; diff --git a/lib/rossym/initum.c b/lib/rossym/initum.c index c00a13a1e09..5a80fd37eef 100644 --- a/lib/rossym/initum.c +++ b/lib/rossym/initum.c @@ -7,9 +7,12 @@ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com) */ +#define WIN32_NO_STATUS #include #include #include "rossympriv.h" +#define NTOS_MODE_USER +#include #define NDEBUG #include @@ -17,13 +20,13 @@ static PVOID RosSymAllocMemUM(ULONG_PTR Size) { - return HeapAlloc(GetProcessHeap(), 0, Size); + return RtlAllocateHeap(RtlGetProcessHeap(), 0, Size); } static VOID RosSymFreeMemUM(PVOID Area) { - HeapFree(GetProcessHeap(), 0, Area); + RtlFreeHeap(RtlGetProcessHeap(), 0, Area); } VOID diff --git a/lib/rossym/pe.c b/lib/rossym/pe.c index cace420fec2..a00716cd185 100644 --- a/lib/rossym/pe.c +++ b/lib/rossym/pe.c @@ -111,6 +111,10 @@ void pefree(Pe *pe) { for (i = 0; i < pe->nsections; i++) { RtlFreeAnsiString(ANSI_NAME_STRING(&pe->sect[i])); } + for (i = 0; i < pe->nsymbols; i++) { + free(pe->symtab[i].name); + } + free(pe->symtab); free(pe->sect); free(pe); } diff --git a/lib/rossym/zwfile.c b/lib/rossym/zwfile.c index dc89c3e3157..a6ce196c632 100644 --- a/lib/rossym/zwfile.c +++ b/lib/rossym/zwfile.c @@ -15,38 +15,40 @@ #define NDEBUG #include +NTSTATUS RosSymStatus; + BOOLEAN RosSymZwReadFile(PVOID FileContext, PVOID Buffer, ULONG Size) { - NTSTATUS Status; + //NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; - Status = ZwReadFile(*((HANDLE *) FileContext), + RosSymStatus = ZwReadFile(*((HANDLE *) FileContext), 0, 0, 0, &IoStatusBlock, Buffer, Size, 0, 0); - return NT_SUCCESS(Status) && IoStatusBlock.Information == Size; + return NT_SUCCESS(RosSymStatus) && IoStatusBlock.Information == Size; } BOOLEAN RosSymZwSeekFile(PVOID FileContext, ULONG_PTR Position) { - NTSTATUS Status; + //NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; FILE_POSITION_INFORMATION NewPosition; NewPosition.CurrentByteOffset.u.HighPart = 0; NewPosition.CurrentByteOffset.u.LowPart = Position; - Status = ZwSetInformationFile(*((HANDLE *) FileContext), + RosSymStatus = ZwSetInformationFile(*((HANDLE *) FileContext), &IoStatusBlock, (PVOID) &NewPosition, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation); - return NT_SUCCESS(Status); + return NT_SUCCESS(RosSymStatus); } /* EOF */ diff --git a/ntoskrnl/kdbg/kdb_symbols.c b/ntoskrnl/kdbg/kdb_symbols.c index 89c437eaeeb..f021649f12f 100644 --- a/ntoskrnl/kdbg/kdb_symbols.c +++ b/ntoskrnl/kdbg/kdb_symbols.c @@ -29,6 +29,8 @@ IMAGE_SYMBOL_INFO_CACHE, *PIMAGE_SYMBOL_INFO_CACHE; static BOOLEAN LoadSymbols; static LIST_ENTRY SymbolFileListHead; static KSPIN_LOCK SymbolFileListLock; +static PROSSYM_INFO KdbpRosSymInfo; +static ULONG_PTR KdbpImageBase; BOOLEAN KdbpSymbolsInitialized = FALSE; /* FUNCTIONS ****************************************************************/ @@ -124,7 +126,13 @@ BOOLEAN KdbSymPrintAddress( IN PVOID Address) { + PMEMORY_AREA MemoryArea = NULL; + HANDLE FileHandle = NULL; + PROS_SECTION_OBJECT SectionObject; PLDR_DATA_TABLE_ENTRY LdrEntry; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING ModuleFileName; ULONG_PTR RelativeAddress; NTSTATUS Status; ULONG LineNumber; @@ -144,11 +152,79 @@ KdbSymPrintAddress( { DbgPrint("<%wZ:%x (%s:%d (%s))>", &LdrEntry->BaseDllName, RelativeAddress, FileName, LineNumber, FunctionName); + return TRUE; } - else - { - DbgPrint("<%wZ:%x>", &LdrEntry->BaseDllName, RelativeAddress); - } + else if (Address < MmSystemRangeStart) + { + MemoryArea = MmLocateMemoryAreaByAddress(&PsGetCurrentProcess()->Vm, Address); + if (!MemoryArea || MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) + { + goto end; + } + SectionObject = MemoryArea->Data.SectionData.Section; + if (!(SectionObject->AllocationAttributes & SEC_IMAGE)) goto end; + if (SectionObject->ImageSection->ImageBase != KdbpImageBase) + { + if (KdbpRosSymInfo) + { + RosSymDelete(KdbpRosSymInfo); + KdbpRosSymInfo = NULL; + } + + Status = MmGetFileNameForAddress(Address, &ModuleFileName); + if (!NT_SUCCESS(Status)) + goto end; + + InitializeObjectAttributes + (&ObjectAttributes, + &ModuleFileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + if (!NT_SUCCESS + (ZwOpenFile + (&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_NONALERT))) + { + goto end; + } + + if (!RosSymCreateFromFile(&FileHandle, &KdbpRosSymInfo)) + { + KdbpRosSymInfo = NULL; + } + + ZwClose(FileHandle); + KdbpImageBase = SectionObject->ImageSection->ImageBase; + } + + if (KdbpRosSymInfo) + { + RelativeAddress = (ULONG_PTR)Address - KdbpImageBase; + Status = KdbSymGetAddressInformation + (KdbpRosSymInfo, + RelativeAddress, + &LineNumber, + FileName, + FunctionName); + if (NT_SUCCESS(Status)) + { + DbgPrint + ("<%wZ:%x (%s:%d (%s))>", + &SectionObject->FileObject->FileName, + RelativeAddress, FileName, LineNumber, FunctionName); + return TRUE; + } + } + } + +end: + DbgPrint("<%wZ:%x>", &LdrEntry->BaseDllName, RelativeAddress); return TRUE; } @@ -208,8 +284,6 @@ KdbpSymFindCachedFile( PLIST_ENTRY CurrentEntry; KIRQL Irql; - DPRINT("Looking for cached symbol file %wZ\n", FileName); - KeAcquireSpinLock(&SymbolFileListLock, &Irql); CurrentEntry = SymbolFileListHead.Flink; @@ -217,7 +291,6 @@ KdbpSymFindCachedFile( { Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry); - DPRINT("Current->FileName %wZ FileName %wZ\n", &Current->FileName, FileName); if (RtlEqualUnicodeString(&Current->FileName, FileName, TRUE)) { Current->RefCount++; @@ -311,7 +384,6 @@ KdbpSymRemoveCachedFile( } KeReleaseSpinLock(&SymbolFileListLock, Irql); - DPRINT1("Warning: Removing unknown symbol file: RosSymInfo = %p\n", RosSymInfo); } /*! \brief Loads a symbol file. @@ -411,7 +483,6 @@ KdbSymProcessSymbols( LdrEntry->DllBase, (PVOID)(LdrEntry->SizeOfImage + (ULONG_PTR)LdrEntry->DllBase), LdrEntry->PatchInformation); - } VOID