reactos/dll/win32/dbghelp/compat.c

397 lines
9.1 KiB
C
Raw Normal View History

* Improve the way we create rossym debug info. The effort results in ~85% *smaller* build folder with ninja all with no code changes. [DBGHELPHOST] * Introduce a self-contained, static library version of dbghelp, in order to leverage its PE DWARF support. Thanks to Jerome Gardou for his work on the compatibility layer, and to Thomas Faber for helping me with the review/improvements. * Unify the new host lib with the existing dll codebase using preprocessor conditions. This prevents code duplication. * Skip as much unneeded functionality as possible when compiling dbghelphost to keep it light and straight to the point. [RSYM] * Introduce the required functions that allow parsing DWARF (using dbghelphost) and using it (along with coff symbols) to create the rossym debug info. Brought to you by Awesome Arty with some bugfixes from Jerome Gardou. Many thanks to Thomas Faber for assisting me with the testing/bug hunting. [CMAKE/GCC] * Introduce a combination of dwarf and debug emission flags that ensure the smallest debug info size among all the possible options we have. * Introduce compressed debug sections that I already included the support for in RosBE 2.1. Thanks to the mingw-w64 folks (Kai Tietz) for the patch. * Don't compress debug sections of C++ modules for now due to a bug in the toolchain that leads to spamming the build at link time with a warning. * Don't run rsym on the RC shared libraries. Thanks to Thomas Faber for spotting this. [DBGHELP] * Update the ros diff to reflect the changes introduced by the dbghelphost unification. svn path=/trunk/; revision=59505
2013-07-18 21:03:01 +00:00
#include "dbghelp_private.h"
void* __HeapAlloc(int heap, int flags, size_t size)
{
void * ret = malloc(size);
if(flags & HEAP_ZERO_MEMORY)
memset(ret, 0, size);
return ret;
}
void* __HeapReAlloc(int heap, DWORD d2, void *slab, SIZE_T newsize)
{
return realloc(slab, newsize);
}
WCHAR* lstrcpynW(WCHAR* lpString1, const WCHAR* lpString2, int iMaxLength)
{
LPWSTR d = lpString1;
const WCHAR* s = lpString2;
UINT count = iMaxLength;
while ((count > 1) && *s)
{
count--;
*d++ = *s++;
}
if (count)
*d = 0;
return lpString1;
}
PIMAGE_NT_HEADERS __RtlImageNtHeader(void *data)
{
PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)data;
PIMAGE_NT_HEADERS NtHeaders;
PCHAR NtHeaderPtr;
if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
NtHeaderPtr = ((PCHAR)data) + DosHeader->e_lfanew;
NtHeaders = (PIMAGE_NT_HEADERS)NtHeaderPtr;
if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
return NULL;
return NtHeaders;
}
PIMAGE_SECTION_HEADER
__RtlImageRvaToSection(
const IMAGE_NT_HEADERS* NtHeader,
PVOID BaseAddress,
ULONG Rva)
{
PIMAGE_SECTION_HEADER Section;
ULONG Va;
ULONG Count;
Count = SWAPW(NtHeader->FileHeader.NumberOfSections);
Section = IMAGE_FIRST_SECTION(NtHeader);
while (Count--)
{
Va = SWAPD(Section->VirtualAddress);
if ((Va <= Rva) && (Rva < Va + SWAPD(Section->SizeOfRawData)))
* Improve the way we create rossym debug info. The effort results in ~85% *smaller* build folder with ninja all with no code changes. [DBGHELPHOST] * Introduce a self-contained, static library version of dbghelp, in order to leverage its PE DWARF support. Thanks to Jerome Gardou for his work on the compatibility layer, and to Thomas Faber for helping me with the review/improvements. * Unify the new host lib with the existing dll codebase using preprocessor conditions. This prevents code duplication. * Skip as much unneeded functionality as possible when compiling dbghelphost to keep it light and straight to the point. [RSYM] * Introduce the required functions that allow parsing DWARF (using dbghelphost) and using it (along with coff symbols) to create the rossym debug info. Brought to you by Awesome Arty with some bugfixes from Jerome Gardou. Many thanks to Thomas Faber for assisting me with the testing/bug hunting. [CMAKE/GCC] * Introduce a combination of dwarf and debug emission flags that ensure the smallest debug info size among all the possible options we have. * Introduce compressed debug sections that I already included the support for in RosBE 2.1. Thanks to the mingw-w64 folks (Kai Tietz) for the patch. * Don't compress debug sections of C++ modules for now due to a bug in the toolchain that leads to spamming the build at link time with a warning. * Don't run rsym on the RC shared libraries. Thanks to Thomas Faber for spotting this. [DBGHELP] * Update the ros diff to reflect the changes introduced by the dbghelphost unification. svn path=/trunk/; revision=59505
2013-07-18 21:03:01 +00:00
return Section;
Section++;
}
* Improve the way we create rossym debug info. The effort results in ~85% *smaller* build folder with ninja all with no code changes. [DBGHELPHOST] * Introduce a self-contained, static library version of dbghelp, in order to leverage its PE DWARF support. Thanks to Jerome Gardou for his work on the compatibility layer, and to Thomas Faber for helping me with the review/improvements. * Unify the new host lib with the existing dll codebase using preprocessor conditions. This prevents code duplication. * Skip as much unneeded functionality as possible when compiling dbghelphost to keep it light and straight to the point. [RSYM] * Introduce the required functions that allow parsing DWARF (using dbghelphost) and using it (along with coff symbols) to create the rossym debug info. Brought to you by Awesome Arty with some bugfixes from Jerome Gardou. Many thanks to Thomas Faber for assisting me with the testing/bug hunting. [CMAKE/GCC] * Introduce a combination of dwarf and debug emission flags that ensure the smallest debug info size among all the possible options we have. * Introduce compressed debug sections that I already included the support for in RosBE 2.1. Thanks to the mingw-w64 folks (Kai Tietz) for the patch. * Don't compress debug sections of C++ modules for now due to a bug in the toolchain that leads to spamming the build at link time with a warning. * Don't run rsym on the RC shared libraries. Thanks to Thomas Faber for spotting this. [DBGHELP] * Update the ros diff to reflect the changes introduced by the dbghelphost unification. svn path=/trunk/; revision=59505
2013-07-18 21:03:01 +00:00
return NULL;
}
PVOID
__RtlImageRvaToVa
(const IMAGE_NT_HEADERS* NtHeader,
PVOID BaseAddress,
ULONG Rva,
PIMAGE_SECTION_HEADER *SectionHeader)
{
PIMAGE_SECTION_HEADER Section = NULL;
if (SectionHeader)
Section = *SectionHeader;
if ((Section == NULL) ||
(Rva < SWAPD(Section->VirtualAddress)) ||
(Rva >= SWAPD(Section->VirtualAddress) + SWAPD(Section->SizeOfRawData)))
* Improve the way we create rossym debug info. The effort results in ~85% *smaller* build folder with ninja all with no code changes. [DBGHELPHOST] * Introduce a self-contained, static library version of dbghelp, in order to leverage its PE DWARF support. Thanks to Jerome Gardou for his work on the compatibility layer, and to Thomas Faber for helping me with the review/improvements. * Unify the new host lib with the existing dll codebase using preprocessor conditions. This prevents code duplication. * Skip as much unneeded functionality as possible when compiling dbghelphost to keep it light and straight to the point. [RSYM] * Introduce the required functions that allow parsing DWARF (using dbghelphost) and using it (along with coff symbols) to create the rossym debug info. Brought to you by Awesome Arty with some bugfixes from Jerome Gardou. Many thanks to Thomas Faber for assisting me with the testing/bug hunting. [CMAKE/GCC] * Introduce a combination of dwarf and debug emission flags that ensure the smallest debug info size among all the possible options we have. * Introduce compressed debug sections that I already included the support for in RosBE 2.1. Thanks to the mingw-w64 folks (Kai Tietz) for the patch. * Don't compress debug sections of C++ modules for now due to a bug in the toolchain that leads to spamming the build at link time with a warning. * Don't run rsym on the RC shared libraries. Thanks to Thomas Faber for spotting this. [DBGHELP] * Update the ros diff to reflect the changes introduced by the dbghelphost unification. svn path=/trunk/; revision=59505
2013-07-18 21:03:01 +00:00
{
Section = RtlImageRvaToSection(NtHeader, BaseAddress, Rva);
* Improve the way we create rossym debug info. The effort results in ~85% *smaller* build folder with ninja all with no code changes. [DBGHELPHOST] * Introduce a self-contained, static library version of dbghelp, in order to leverage its PE DWARF support. Thanks to Jerome Gardou for his work on the compatibility layer, and to Thomas Faber for helping me with the review/improvements. * Unify the new host lib with the existing dll codebase using preprocessor conditions. This prevents code duplication. * Skip as much unneeded functionality as possible when compiling dbghelphost to keep it light and straight to the point. [RSYM] * Introduce the required functions that allow parsing DWARF (using dbghelphost) and using it (along with coff symbols) to create the rossym debug info. Brought to you by Awesome Arty with some bugfixes from Jerome Gardou. Many thanks to Thomas Faber for assisting me with the testing/bug hunting. [CMAKE/GCC] * Introduce a combination of dwarf and debug emission flags that ensure the smallest debug info size among all the possible options we have. * Introduce compressed debug sections that I already included the support for in RosBE 2.1. Thanks to the mingw-w64 folks (Kai Tietz) for the patch. * Don't compress debug sections of C++ modules for now due to a bug in the toolchain that leads to spamming the build at link time with a warning. * Don't run rsym on the RC shared libraries. Thanks to Thomas Faber for spotting this. [DBGHELP] * Update the ros diff to reflect the changes introduced by the dbghelphost unification. svn path=/trunk/; revision=59505
2013-07-18 21:03:01 +00:00
if (Section == NULL)
return NULL;
if (SectionHeader)
*SectionHeader = Section;
}
return (PVOID)((ULONG_PTR)BaseAddress + Rva +
(ULONG_PTR)SWAPD(Section->PointerToRawData) -
* Improve the way we create rossym debug info. The effort results in ~85% *smaller* build folder with ninja all with no code changes. [DBGHELPHOST] * Introduce a self-contained, static library version of dbghelp, in order to leverage its PE DWARF support. Thanks to Jerome Gardou for his work on the compatibility layer, and to Thomas Faber for helping me with the review/improvements. * Unify the new host lib with the existing dll codebase using preprocessor conditions. This prevents code duplication. * Skip as much unneeded functionality as possible when compiling dbghelphost to keep it light and straight to the point. [RSYM] * Introduce the required functions that allow parsing DWARF (using dbghelphost) and using it (along with coff symbols) to create the rossym debug info. Brought to you by Awesome Arty with some bugfixes from Jerome Gardou. Many thanks to Thomas Faber for assisting me with the testing/bug hunting. [CMAKE/GCC] * Introduce a combination of dwarf and debug emission flags that ensure the smallest debug info size among all the possible options we have. * Introduce compressed debug sections that I already included the support for in RosBE 2.1. Thanks to the mingw-w64 folks (Kai Tietz) for the patch. * Don't compress debug sections of C++ modules for now due to a bug in the toolchain that leads to spamming the build at link time with a warning. * Don't run rsym on the RC shared libraries. Thanks to Thomas Faber for spotting this. [DBGHELP] * Update the ros diff to reflect the changes introduced by the dbghelphost unification. svn path=/trunk/; revision=59505
2013-07-18 21:03:01 +00:00
(ULONG_PTR)SWAPD(Section->VirtualAddress));
}
PVOID
__RtlImageDirectoryEntryToData(
PVOID BaseAddress,
BOOLEAN MappedAsImage,
USHORT Directory,
PULONG Size)
{
PIMAGE_NT_HEADERS NtHeader;
ULONG Va;
/* Magic flag for non-mapped images. */
if ((ULONG_PTR)BaseAddress & 1)
{
BaseAddress = (PVOID)((ULONG_PTR)BaseAddress & ~1);
MappedAsImage = FALSE;
}
NtHeader = RtlImageNtHeader(BaseAddress);
if (NtHeader == NULL)
return NULL;
if (Directory >= SWAPD(NtHeader->OptionalHeader.NumberOfRvaAndSizes))
return NULL;
Va = SWAPD(NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress);
if (Va == 0)
return NULL;
*Size = SWAPD(NtHeader->OptionalHeader.DataDirectory[Directory].Size);
if (MappedAsImage || Va < SWAPD(NtHeader->OptionalHeader.SizeOfHeaders))
return (PVOID)((ULONG_PTR)BaseAddress + Va);
/* Image mapped as ordinary file, we must find raw pointer */
* Improve the way we create rossym debug info. The effort results in ~85% *smaller* build folder with ninja all with no code changes. [DBGHELPHOST] * Introduce a self-contained, static library version of dbghelp, in order to leverage its PE DWARF support. Thanks to Jerome Gardou for his work on the compatibility layer, and to Thomas Faber for helping me with the review/improvements. * Unify the new host lib with the existing dll codebase using preprocessor conditions. This prevents code duplication. * Skip as much unneeded functionality as possible when compiling dbghelphost to keep it light and straight to the point. [RSYM] * Introduce the required functions that allow parsing DWARF (using dbghelphost) and using it (along with coff symbols) to create the rossym debug info. Brought to you by Awesome Arty with some bugfixes from Jerome Gardou. Many thanks to Thomas Faber for assisting me with the testing/bug hunting. [CMAKE/GCC] * Introduce a combination of dwarf and debug emission flags that ensure the smallest debug info size among all the possible options we have. * Introduce compressed debug sections that I already included the support for in RosBE 2.1. Thanks to the mingw-w64 folks (Kai Tietz) for the patch. * Don't compress debug sections of C++ modules for now due to a bug in the toolchain that leads to spamming the build at link time with a warning. * Don't run rsym on the RC shared libraries. Thanks to Thomas Faber for spotting this. [DBGHELP] * Update the ros diff to reflect the changes introduced by the dbghelphost unification. svn path=/trunk/; revision=59505
2013-07-18 21:03:01 +00:00
return RtlImageRvaToVa(NtHeader, BaseAddress, Va, NULL);
}
BOOL __GetFileSizeEx(HANDLE file, PLARGE_INTEGER fsize)
{
if (fseek((FILE*)file, 0, 2) == -1)
return FALSE;
fsize->QuadPart = ftell((FILE*)file);
return TRUE;
}
BOOL __CloseHandle(HANDLE handle)
{
fclose(handle);
return TRUE;
}
HANDLE __CreateFileW(
LPCWSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile)
{
char buf[MAX_PATH];
HANDLE res;
WideCharToMultiByte(CP_ACP, 0, lpFileName, -1, buf, MAX_PATH, NULL, NULL);
res = CreateFileA(buf, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
return res;
}
void* __MapViewOfFile(HANDLE file,DWORD d1,DWORD d2,DWORD d3,SIZE_T s)
{
FILE *f = (FILE*)file;
LARGE_INTEGER size;
char *result;
if (file == INVALID_HANDLE_VALUE)
return NULL;
if (!GetFileSizeEx(file, &size))
return NULL;
if (fseek(f, 0, 0) == -1)
return NULL;
result = malloc(size.LowPart);
if (fread(result, 1, size.LowPart, f) != size.LowPart)
{
free(result);
return NULL;
}
return result;
}
BOOL __UnmapViewOfFile(const void* data)
{
free((void *)data);
return TRUE;
}
LPSTR __lstrcpynA(LPSTR d,LPCSTR s,int c)
{
LPSTR r = d;
while(*s && c)
{
*d++ = *s++;
c--;
}
return r;
}
/* From Wine implementation over their unicode library */
INT
__WideCharToMultiByte(UINT page, DWORD flags, LPCWSTR src, INT srclen,
LPSTR dst, INT dstlen, LPCSTR defchar, BOOL *used )
{
int i;
if (!src || !srclen || (!dst && dstlen))
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (srclen < 0) srclen = strlenW(src) + 1;
if(!dstlen)
return srclen;
for(i=0; i<srclen && i<dstlen; i++)
dst[i] = src[i] & 0xFF;
if (used) *used = FALSE;
return i;
}
INT
__MultiByteToWideChar(UINT page, DWORD flags, LPCSTR src, INT srclen,
LPWSTR dst, INT dstlen )
{
int i;
if (!src || !srclen || (!dst && dstlen))
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (srclen < 0) srclen = strlen(src) + 1;
if(!dstlen)
return srclen;
for(i=0; i<srclen && i<dstlen; i++)
dst[i] = src[i];
return i;
}
/* In our case, the provided file path is the one we are looking for */
HANDLE __FindExecutableImageExW(PCWSTR file, PCWSTR path, PWSTR out_buffer, PFIND_EXE_FILE_CALLBACKW x, PVOID y)
{
HANDLE ret = CreateFileW(file, 0, 0, NULL, 0, 0, NULL);
if(ret)
memcpy(out_buffer, file, (strlenW(file) + 1)*sizeof(WCHAR));
return ret;
}
/* printf with temp buffer allocation */
const char *wine_dbg_sprintf( const char *format, ... )
{
static const int max_size = 200;
static char buffer[256];
char *ret;
int len;
va_list valist;
va_start(valist, format);
ret = buffer;
len = vsnprintf( ret, max_size, format, valist );
if (len == -1 || len >= max_size) ret[max_size-1] = 0;
va_end(valist);
return ret;
}
/* default implementation of wine_dbgstr_an */
const char *wine_dbgstr_an( const char *str, int n )
{
static const char hex[16] = "0123456789abcdef";
char *dst, *res;
size_t size;
static char buffer[256];
* Improve the way we create rossym debug info. The effort results in ~85% *smaller* build folder with ninja all with no code changes. [DBGHELPHOST] * Introduce a self-contained, static library version of dbghelp, in order to leverage its PE DWARF support. Thanks to Jerome Gardou for his work on the compatibility layer, and to Thomas Faber for helping me with the review/improvements. * Unify the new host lib with the existing dll codebase using preprocessor conditions. This prevents code duplication. * Skip as much unneeded functionality as possible when compiling dbghelphost to keep it light and straight to the point. [RSYM] * Introduce the required functions that allow parsing DWARF (using dbghelphost) and using it (along with coff symbols) to create the rossym debug info. Brought to you by Awesome Arty with some bugfixes from Jerome Gardou. Many thanks to Thomas Faber for assisting me with the testing/bug hunting. [CMAKE/GCC] * Introduce a combination of dwarf and debug emission flags that ensure the smallest debug info size among all the possible options we have. * Introduce compressed debug sections that I already included the support for in RosBE 2.1. Thanks to the mingw-w64 folks (Kai Tietz) for the patch. * Don't compress debug sections of C++ modules for now due to a bug in the toolchain that leads to spamming the build at link time with a warning. * Don't run rsym on the RC shared libraries. Thanks to Thomas Faber for spotting this. [DBGHELP] * Update the ros diff to reflect the changes introduced by the dbghelphost unification. svn path=/trunk/; revision=59505
2013-07-18 21:03:01 +00:00
if (!((ULONG_PTR)str >> 16))
{
if (!str) return "(null)";
res = buffer;
sprintf( res, "#%04x", LOWORD(str) );
return res;
}
if (n == -1) n = strlen(str);
if (n < 0) n = 0;
size = 10 + min( 300, n * 4 );
dst = res = buffer;
*dst++ = '"';
while (n-- > 0 && dst <= res + size - 9)
{
unsigned char c = *str++;
switch (c)
{
case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
case '\t': *dst++ = '\\'; *dst++ = 't'; break;
case '"': *dst++ = '\\'; *dst++ = '"'; break;
case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
default:
if (c >= ' ' && c <= 126)
*dst++ = c;
else
{
*dst++ = '\\';
*dst++ = 'x';
*dst++ = hex[(c >> 4) & 0x0f];
*dst++ = hex[c & 0x0f];
}
}
}
*dst++ = '"';
if (n > 0)
{
*dst++ = '.';
*dst++ = '.';
*dst++ = '.';
}
*dst++ = 0;
return res;
}
/* default implementation of wine_dbgstr_wn */
const char *wine_dbgstr_wn( const WCHAR *str, int n )
{
char *dst, *res;
size_t size;
static char buffer[256];
if (!((ULONG_PTR)str >> 16))
{
if (!str) return "(null)";
res = buffer;
sprintf( res, "#%04x", LOWORD(str) );
return res;
}
if (n == -1)
{
const WCHAR *end = str;
while (*end) end++;
n = end - str;
}
if (n < 0) n = 0;
size = 12 + min( 300, n * 5 );
dst = res = buffer;
*dst++ = 'L';
*dst++ = '"';
while (n-- > 0 && dst <= res + size - 10)
{
WCHAR c = *str++;
switch (c)
{
case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
case '\t': *dst++ = '\\'; *dst++ = 't'; break;
case '"': *dst++ = '\\'; *dst++ = '"'; break;
case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
default:
if (c >= ' ' && c <= 126)
*dst++ = c;
else
{
*dst++ = '\\';
sprintf(dst,"%04x",c);
dst+=4;
}
}
}
*dst++ = '"';
if (n > 0)
{
*dst++ = '.';
*dst++ = '.';
*dst++ = '.';
}
*dst++ = 0;
return res;
}