https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4fc82fc5bda5360f006c7dff35a5bfd527e66e04

commit 4fc82fc5bda5360f006c7dff35a5bfd527e66e04
Author:     winesync <[email protected]>
AuthorDate: Fri Sep 11 16:57:25 2020 +0200
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Wed Sep 16 10:35:44 2020 +0200

    [WINESYNC] dbghelp: Use Windows API to map ELF files.
    
    Signed-off-by: Jacek Caban <[email protected]>
    Signed-off-by: Alexandre Julliard <[email protected]>
    
    wine commit id a60b3985bf37827fd0b0f7583c31dcf52069b4a8 by Jacek Caban 
<[email protected]>
---
 dll/win32/dbghelp/elf_module.c    | 168 +++++++++++++++++++++-----------------
 dll/win32/dbghelp/image_private.h |   2 +-
 sdk/tools/winesync/dbghelp.cfg    |   2 +-
 3 files changed, 95 insertions(+), 77 deletions(-)

diff --git a/dll/win32/dbghelp/elf_module.c b/dll/win32/dbghelp/elf_module.c
index 96b16fd5c0c..648169b9806 100644
--- a/dll/win32/dbghelp/elf_module.c
+++ b/dll/win32/dbghelp/elf_module.c
@@ -32,16 +32,6 @@
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#include <fcntl.h>
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
 
 #include "dbghelp_private.h"
 #include "winternl.h"
@@ -147,7 +137,9 @@ struct elf_module_info
 const char* elf_map_section(struct image_section_map* ism)
 {
     struct elf_file_map*        fmap = &ism->fmap->u.elf;
-    size_t ofst, size, pgsz = sysconf( _SC_PAGESIZE );
+    SYSTEM_INFO sysinfo;
+    SIZE_T ofst, size;
+    HANDLE mapping;
 
     assert(ism->fmap->modtype == DMT_ELF);
     if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.elf.elfhdr.e_shnum ||
@@ -158,14 +150,24 @@ const char* elf_map_section(struct image_section_map* ism)
     {
         return fmap->target_copy + fmap->sect[ism->sidx].shdr.sh_offset;
     }
-    /* align required information on page size (we assume pagesize is a power 
of 2) */
-    ofst = fmap->sect[ism->sidx].shdr.sh_offset & ~(pgsz - 1);
-    size = ((fmap->sect[ism->sidx].shdr.sh_offset +
-             fmap->sect[ism->sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - 
ofst;
-    fmap->sect[ism->sidx].mapped = mmap(NULL, size, PROT_READ, MAP_PRIVATE,
-                                        fmap->fd, ofst);
-    if (fmap->sect[ism->sidx].mapped == IMAGE_NO_MAP) return IMAGE_NO_MAP;
-    return fmap->sect[ism->sidx].mapped + 
(fmap->sect[ism->sidx].shdr.sh_offset & (pgsz - 1));
+
+    /* align required information on allocation granularity */
+    GetSystemInfo(&sysinfo);
+    ofst = fmap->sect[ism->sidx].shdr.sh_offset & 
~(sysinfo.dwAllocationGranularity - 1);
+    size = fmap->sect[ism->sidx].shdr.sh_offset + 
fmap->sect[ism->sidx].shdr.sh_size - ofst;
+    if (!(mapping = CreateFileMappingW(fmap->handle, NULL, PAGE_READONLY, 0, 
ofst + size, NULL)))
+    {
+        ERR("map creation %p failed %u offset %lu %lu size %lu\n", 
fmap->handle, GetLastError(), ofst, ofst % 4096, size);
+        return IMAGE_NO_MAP;
+    }
+    fmap->sect[ism->sidx].mapped = MapViewOfFile(mapping, FILE_MAP_READ, 0, 
ofst, size);
+    CloseHandle(mapping);
+    if (!fmap->sect[ism->sidx].mapped)
+    {
+        ERR("map %p failed %u offset %lu %lu size %lu\n", fmap->handle, 
GetLastError(), ofst, ofst % 4096, size);
+        return IMAGE_NO_MAP;
+    }
+    return fmap->sect[ism->sidx].mapped + 
(fmap->sect[ism->sidx].shdr.sh_offset & (sysinfo.dwAllocationGranularity - 1));
 }
 
 /******************************************************************
@@ -215,15 +217,11 @@ void elf_unmap_section(struct image_section_map* ism)
     struct elf_file_map*        fmap = &ism->fmap->u.elf;
 
     if (ism->sidx >= 0 && ism->sidx < fmap->elfhdr.e_shnum && 
!fmap->target_copy &&
-        fmap->sect[ism->sidx].mapped != IMAGE_NO_MAP)
+        fmap->sect[ism->sidx].mapped)
     {
-        size_t pgsz = sysconf( _SC_PAGESIZE );
-        size_t ofst = fmap->sect[ism->sidx].shdr.sh_offset & ~(pgsz - 1);
-        size_t size = ((fmap->sect[ism->sidx].shdr.sh_offset +
-                 fmap->sect[ism->sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) 
- ofst;
-        if (munmap((char*)fmap->sect[ism->sidx].mapped, size) < 0)
+        if (!UnmapViewOfFile(fmap->sect[ism->sidx].mapped))
             WARN("Couldn't unmap the section\n");
-        fmap->sect[ism->sidx].mapped = IMAGE_NO_MAP;
+        fmap->sect[ism->sidx].mapped = NULL;
     }
 }
 
@@ -267,7 +265,7 @@ unsigned elf_get_map_size(const struct image_section_map* 
ism)
 
 static inline void elf_reset_file_map(struct image_file_map* fmap)
 {
-    fmap->u.elf.fd = -1;
+    fmap->u.elf.handle = INVALID_HANDLE_VALUE;
     fmap->u.elf.shstrtab = IMAGE_NO_MAP;
     fmap->u.elf.alternate = NULL;
     fmap->u.elf.target_copy = NULL;
@@ -293,12 +291,16 @@ struct elf_map_file_data
 static BOOL elf_map_file_read(struct image_file_map* fmap, struct 
elf_map_file_data* emfd,
                               void* buf, size_t len, off_t off)
 {
+    LARGE_INTEGER li;
+    DWORD bytes_read;
     SIZE_T dw;
 
     switch (emfd->kind)
     {
     case from_file:
-        return pread(fmap->u.elf.fd, buf, len, off) == len;
+        li.QuadPart = off;
+        if (!SetFilePointerEx(fmap->u.elf.handle, li, NULL, FILE_BEGIN)) 
return FALSE;
+        return ReadFile(fmap->u.elf.handle, buf, len, &bytes_read, NULL);
     case from_process:
         return ReadProcessMemory(emfd->u.process.handle,
                                  (void*)((unsigned 
long)emfd->u.process.load_addr + (unsigned long)off),
@@ -339,6 +341,29 @@ static BOOL elf_map_shdr(struct elf_map_file_data* emfd, 
struct image_file_map*
     return TRUE;
 }
 
+static WCHAR *get_dos_file_name(const WCHAR *filename)
+{
+    WCHAR *dos_path;
+    size_t len;
+
+    if (*filename == '/')
+    {
+        char *unix_path;
+        len = WideCharToMultiByte(CP_UNIXCP, 0, filename, -1, NULL, 0, NULL, 
NULL);
+        unix_path = heap_alloc(len * sizeof(WCHAR));
+        WideCharToMultiByte(CP_UNIXCP, 0, filename, -1, unix_path, len, NULL, 
NULL);
+        dos_path = wine_get_dos_file_name(unix_path);
+        heap_free(unix_path);
+    }
+    else
+    {
+        len = lstrlenW(filename);
+        dos_path = heap_alloc((len + 1) * sizeof(WCHAR));
+        memcpy(dos_path, filename, (len + 1) * sizeof(WCHAR));
+    }
+    return dos_path;
+}
+
 /******************************************************************
  *             elf_map_file
  *
@@ -347,53 +372,35 @@ static BOOL elf_map_shdr(struct elf_map_file_data* emfd, 
struct image_file_map*
 static BOOL elf_map_file(struct elf_map_file_data* emfd, struct 
image_file_map* fmap)
 {
     static const BYTE   elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, 
ELFMAG3 };
-    struct stat                statbuf;
     unsigned int        i;
     size_t              tmp, page_mask = sysconf( _SC_PAGESIZE ) - 1;
-    char*               filename;
-    unsigned            len;
-    BOOL                ret = FALSE;
+    WCHAR              *dos_path;
     unsigned char e_ident[EI_NIDENT];
 
-    switch (emfd->kind)
-    {
-    case from_file:
-        len = WideCharToMultiByte(CP_UNIXCP, 0, emfd->u.file.filename, -1, 
NULL, 0, NULL, NULL);
-        if (!(filename = HeapAlloc(GetProcessHeap(), 0, len))) return FALSE;
-        WideCharToMultiByte(CP_UNIXCP, 0, emfd->u.file.filename, -1, filename, 
len, NULL, NULL);
-        break;
-    case from_process:
-        filename = NULL;
-        break;
-    default: assert(0);
-        return FALSE;
-    }
-
     elf_reset_file_map(fmap);
 
     fmap->modtype = DMT_ELF;
-    fmap->u.elf.fd = -1;
+    fmap->u.elf.handle = INVALID_HANDLE_VALUE;
     fmap->u.elf.target_copy = NULL;
 
     switch (emfd->kind)
     {
     case from_file:
-        /* check that the file exists, and that the module hasn't been loaded 
yet */
-        if (stat(filename, &statbuf) == -1 || S_ISDIR(statbuf.st_mode)) goto 
done;
-
-        /* Now open the file, so that we can mmap() it. */
-        if ((fmap->u.elf.fd = open(filename, O_RDONLY)) == -1) goto done;
+        if (!(dos_path = get_dos_file_name(emfd->u.file.filename))) return 
FALSE;
+        fmap->u.elf.handle = CreateFileW(dos_path, GENERIC_READ, 
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+        heap_free(dos_path);
+        if (fmap->u.elf.handle == INVALID_HANDLE_VALUE) return FALSE;
         break;
     case from_process:
         break;
     }
 
     if (!elf_map_file_read(fmap, emfd, e_ident, sizeof(e_ident), 0))
-        goto done;
+        return FALSE;
 
     /* and check for an ELF header */
     if (memcmp(e_ident, elf_signature, sizeof(elf_signature)))
-        goto done;
+        return FALSE;
 
     fmap->addr_size = e_ident[EI_CLASS] == ELFCLASS64 ? 64 : 32;
 
@@ -402,7 +409,7 @@ static BOOL elf_map_file(struct elf_map_file_data* emfd, 
struct image_file_map*
         Elf32_Ehdr elfhdr32;
 
         if (!elf_map_file_read(fmap, emfd, &elfhdr32, sizeof(elfhdr32), 0))
-            goto done;
+            return FALSE;
 
         memcpy(fmap->u.elf.elfhdr.e_ident, elfhdr32.e_ident, EI_NIDENT);
         fmap->u.elf.elfhdr.e_type      = elfhdr32.e_type;
@@ -422,12 +429,12 @@ static BOOL elf_map_file(struct elf_map_file_data* emfd, 
struct image_file_map*
     else
     {
         if (!elf_map_file_read(fmap, emfd, &fmap->u.elf.elfhdr, 
sizeof(fmap->u.elf.elfhdr), 0))
-            goto done;
+            return FALSE;
     }
 
     fmap->u.elf.sect = HeapAlloc(GetProcessHeap(), 0,
                                  fmap->u.elf.elfhdr.e_shnum * 
sizeof(fmap->u.elf.sect[0]));
-    if (!fmap->u.elf.sect) goto done;
+    if (!fmap->u.elf.sect) return FALSE;
 
     for (i = 0; i < fmap->u.elf.elfhdr.e_shnum; i++)
     {
@@ -435,9 +442,9 @@ static BOOL elf_map_file(struct elf_map_file_data* emfd, 
struct image_file_map*
         {
             HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
             fmap->u.elf.sect = NULL;
-            goto done;
+            return FALSE;
         }
-        fmap->u.elf.sect[i].mapped = IMAGE_NO_MAP;
+        fmap->u.elf.sect[i].mapped = NULL;
     }
 
     /* grab size of module once loaded in memory */
@@ -484,21 +491,18 @@ static BOOL elf_map_file(struct elf_map_file_data* emfd, 
struct image_file_map*
         if (!(fmap->u.elf.target_copy = HeapAlloc(GetProcessHeap(), 0, 
fmap->u.elf.elf_size)))
         {
             HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
-            goto done;
+            return FALSE;
         }
         if (!ReadProcessMemory(emfd->u.process.handle, 
emfd->u.process.load_addr, fmap->u.elf.target_copy,
                                fmap->u.elf.elf_size, NULL))
         {
             HeapFree(GetProcessHeap(), 0, fmap->u.elf.target_copy);
             HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
-            goto done;
+            return FALSE;
         }
         break;
     }
-    ret = TRUE;
-done:
-    HeapFree(GetProcessHeap(), 0, filename);
-    return ret;
+    return TRUE;
 }
 
 /******************************************************************
@@ -510,7 +514,7 @@ static void elf_unmap_file(struct image_file_map* fmap)
 {
     while (fmap)
     {
-        if (fmap->u.elf.fd != -1)
+        if (fmap->u.elf.handle != INVALID_HANDLE_VALUE)
         {
             struct image_section_map  ism;
             ism.fmap = fmap;
@@ -519,7 +523,7 @@ static void elf_unmap_file(struct image_file_map* fmap)
                 elf_unmap_section(&ism);
             }
             HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
-            close(fmap->u.elf.fd);
+            CloseHandle(fmap->u.elf.handle);
         }
         HeapFree(GetProcessHeap(), 0, fmap->u.elf.target_copy);
         fmap = fmap->u.elf.alternate;
@@ -934,21 +938,35 @@ static int elf_new_public_symbols(struct module* module, 
const struct hash_table
     return TRUE;
 }
 
-static BOOL elf_check_debug_link(const WCHAR* file, struct image_file_map* 
fmap, DWORD crc)
+static DWORD calc_crc(HANDLE handle)
+{
+    BYTE buffer[8192];
+    DWORD crc = 0;
+    DWORD len;
+
+    SetFilePointer(handle, 0, 0, FILE_BEGIN);
+    while (ReadFile(handle, buffer, sizeof(buffer), &len, NULL) && len)
+        crc = RtlComputeCrc32(crc, buffer, len);
+    return crc;
+}
+
+static BOOL elf_check_debug_link(const WCHAR* file, struct image_file_map* 
fmap, DWORD link_crc)
 {
-    BOOL        ret;
     struct elf_map_file_data    emfd;
+    DWORD crc;
 
     emfd.kind = from_file;
     emfd.u.file.filename = file;
     if (!elf_map_file(&emfd, fmap)) return FALSE;
-    if (!(ret = crc == calc_crc32(fmap->u.elf.fd)))
+
+    crc = calc_crc(fmap->u.elf.handle);
+    if (crc != link_crc)
     {
-        WARN("Bad CRC for file %s (got %08x while expecting %08x)\n",
-             debugstr_w(file), calc_crc32(fmap->u.elf.fd), crc);
+        WARN("Bad CRC for file %s (got %08x while expecting %08x)\n",  
debugstr_w(file), crc, link_crc);
         elf_unmap_file(fmap);
+        return FALSE;
     }
-    return ret;
+    return TRUE;
 }
 
 /******************************************************************
@@ -1290,7 +1308,7 @@ BOOL elf_fetch_file_info(const WCHAR* name, DWORD_PTR* 
base,
     if (!elf_map_file(&emfd, &fmap)) return FALSE;
     if (base) *base = fmap.u.elf.elf_start;
     *size = fmap.u.elf.elf_size;
-    *checksum = calc_crc32(fmap.u.elf.fd);
+    *checksum = calc_crc(fmap.u.elf.handle);
     elf_unmap_file(&fmap);
     return TRUE;
 }
@@ -1386,7 +1404,7 @@ static BOOL elf_load_file_from_fmap(struct process* pcs, 
const WCHAR* filename,
                           sizeof(struct module_format) + sizeof(struct 
elf_module_info));
         if (!modfmt) return FALSE;
         elf_info->module = module_new(pcs, filename, DMT_ELF, FALSE, modbase,
-                                      fmap->u.elf.elf_size, 0, 
calc_crc32(fmap->u.elf.fd));
+                                      fmap->u.elf.elf_size, 0, 
calc_crc(fmap->u.elf.handle));
         if (!elf_info->module)
         {
             HeapFree(GetProcessHeap(), 0, modfmt);
diff --git a/dll/win32/dbghelp/image_private.h 
b/dll/win32/dbghelp/image_private.h
index fd5a7c91d69..2d9b354f7a6 100644
--- a/dll/win32/dbghelp/image_private.h
+++ b/dll/win32/dbghelp/image_private.h
@@ -69,7 +69,7 @@ struct image_file_map
         {
             size_t                      elf_size;
             size_t                      elf_start;
-            int                         fd;
+            HANDLE                      handle;
             const char*                        shstrtab;
             struct image_file_map*      alternate;      /* another ELF file 
(linked to this one) */
             char*                       target_copy;
diff --git a/sdk/tools/winesync/dbghelp.cfg b/sdk/tools/winesync/dbghelp.cfg
index abdb0e40ad3..dc32ebbc6fe 100644
--- a/sdk/tools/winesync/dbghelp.cfg
+++ b/sdk/tools/winesync/dbghelp.cfg
@@ -4,4 +4,4 @@ files:
   include/dbghelp.h: sdk/include/psdk/dbghelp.h
   include/wine/mscvpdb.h: sdk/include/reactos/wine/mscvpdb.h
 tags:
-  wine: d731208602393877709d3bb0bdeb28c80f9719b0
+  wine: a60b3985bf37827fd0b0f7583c31dcf52069b4a8

Reply via email to