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 #include #include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#include -#ifdef HAVE_SYS_MMAN_H -#include -#endif -#ifdef HAVE_UNISTD_H -# include -#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