diff options
Diffstat (limited to 'libvtv')
-rw-r--r-- | libvtv/ChangeLog | 47 | ||||
-rw-r--r-- | libvtv/Makefile.am | 34 | ||||
-rw-r--r-- | libvtv/configure.ac | 12 | ||||
-rw-r--r-- | libvtv/configure.tgt | 6 | ||||
-rw-r--r-- | libvtv/vtv_fail.cc | 6 | ||||
-rw-r--r-- | libvtv/vtv_malloc.cc | 25 | ||||
-rw-r--r-- | libvtv/vtv_malloc.h | 7 | ||||
-rw-r--r-- | libvtv/vtv_map.h | 6 | ||||
-rw-r--r-- | libvtv/vtv_rts.cc | 295 | ||||
-rw-r--r-- | libvtv/vtv_utils.cc | 32 |
10 files changed, 463 insertions, 7 deletions
diff --git a/libvtv/ChangeLog b/libvtv/ChangeLog index 671223f5891..7b80282a5f8 100644 --- a/libvtv/ChangeLog +++ b/libvtv/ChangeLog @@ -1,3 +1,50 @@ +2015-01-27 Caroline Tice <cmtice@google.com> + + Committing VTV Cywin/Ming patch for Patrick Wollgast + * libvtv/Makefile.am : Add libvtv.la to toolexeclib_LTLIBRARIES, if + VTV_CYGMIN is set. Define libvtv_la_LIBADD, libvtv_la_LDFLAGS, + libvtv_stubs_la_LDFLAGS and libvtv_stubs_la_SOURCES if VTV_CYGMIN is + set. Add obstac.c to libvtv_la_SOURCES if VTV_CYGMIN is set. + * libvtv/Makefile.in : Regenerate. + * libvtv/aclocal.m4 : Regenerate. + * libvtv/configure : Regenerate. + * libvtv/configure.ac : Add ACX_LT_HOST_FLAGS. Define VTV_CYGMIN. + * libvtv/configure.tgt : (x86_64-*-cygwin*, i?86-*-cygwin*, + x86_64-*-mingw*) + (i?86-*-mingw*): Add to supported targets. + * libvtv/vtv_fail.cc : Skip inclusion of execinfo.h on Cygwin and MinGW. + (log_error_message): Skip calls to backtrace and backtrace_symbols_fd + on Cygwin and MinGW. + * libvtv/vtv_malloc.cc : Include windows.h and skip sys/mman.h + inclusion on Cygwin and MinGW. Add sysconf port on Cygwin and MinGW. + (obstack_chunk_alloc): Exchange call to mmap with call to VirtualAlloc + on Cygwin and MinGW. + (__vtv_malloc_init): Exchange call to sysconf with call to port of + sysconf on Cygwin and MinGW. + * libvtv/vtv_malloc.h : Declare mprotect and define PROT_READ and + PROT_WRITE on Cygwin and MinGW. + * libvtv/map.h : Include stdint.h on MinGW. + * libvtv/rts.cc : Include windows.h, winternl.h and psapi.h, skip + include of execinfo.h, sys/mman.h and link.h on Cygwin and MinGW. Add + port of __fortify_fail on Cygwin and MinGW. Change ElfW (Addr) to + uintptr_t on Cygwin and MinGW. + (read_section_offset_and_length): Add port for Cygwin and MinGW + (iterate_modules): New function. + (vtv_unprotect_vtable_vars): Use iterate_modules instead of + dl_iterate_phdr on Cygwin and MinGW. + (vtv_protect_vtable_vars): Likewise. + (count_all_pages): Likewise. + (dl_iterate_phdr_count_pages): Don't build on Cygwin and MinGW. + * libvtv/utils.cc : Include windows.h and skip execinfo.h inclusion on + Cygwin and MinGW. + (__vtv_open_log): Exchange call to getuid and getpid with + GetCurrentProcessId and adjust call to snprintf accordingly on Cygwin + and MinGW. Adjust calls to mkdir on MinGW. Adjust call to open on + Cygwin and MinGW. + (__vtv_add_to_log): Adjust call to snprintf on Cygwin and MinGW. + (__vtv_log_verification_failure): Don't generate a backtrace on Cygwin + and MinGW. + 2014-12-12 Kyrylo Tkachov <kyrylo.tkachov@arm.com> * testsuite/lib/libvtv.exp: Load target-utils.exp diff --git a/libvtv/Makefile.am b/libvtv/Makefile.am index 886d7e6be8d..2c9fb548d5f 100644 --- a/libvtv/Makefile.am +++ b/libvtv/Makefile.am @@ -38,7 +38,11 @@ AM_CXXFLAGS = $(XCFLAGS) AM_CXXFLAGS += $(LIBSTDCXX_RAW_CXX_CXXFLAGS) AM_CXXFLAGS += -Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end -toolexeclib_LTLIBRARIES = libvtv.la +if VTV_CYGMIN + toolexeclib_LTLIBRARIES = libvtv.la libvtv_stubs.la +else + toolexeclib_LTLIBRARIES = libvtv.la +endif vtv_headers = \ vtv_map.h \ @@ -55,6 +59,11 @@ vtv_sources = \ vtv_utils.cc \ vtv_end.c +vtv_stubs_sources = \ + vtv_start.c \ + vtv_stubs.cc \ + vtv_end.c + libvtv_includedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include # Link in vtv_start and vtv_end. @@ -67,8 +76,29 @@ vtv_end.c: rm -f $@ $(LN_S) $(toplevel_srcdir)/libgcc/vtv_end.c $@ +if VTV_CYGMIN + obstack.c: + rm -f $@ + $(LN_S) $(toplevel_srcdir)/libiberty/obstack.c $@ + + vtv_stubs.cc: + rm -f $@ + $(LN_S) $(toplevel_srcdir)/libstdc++-v3/libsupc++/vtv_stubs.cc $@ +endif + +if VTV_CYGMIN + libvtv_la_LIBADD = -lpsapi + libvtv_la_LDFLAGS = $(lt_host_flags) + libvtv_stubs_la_LDFLAGS = $(lt_host_flags) +endif + if ENABLE_VTABLE_VERIFY +if VTV_CYGMIN + libvtv_la_SOURCES = $(vtv_sources) obstack.c + libvtv_stubs_la_SOURCES = $(vtv_stubs_sources) +else libvtv_la_SOURCES = $(vtv_sources) +endif libvtv_include_HEADERS = $(vtv_headers) else libvtv_la_SOURCES = @@ -78,6 +108,8 @@ endif # Least ordering for dependencies mean linking w/o libstdc++ for as # long as the development of libvtv does not absolutely require it. CXXVTV=$(CC_FOR_TARGET) +CXXLD=$(CC_FOR_TARGET) + LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXXVTV) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) diff --git a/libvtv/configure.ac b/libvtv/configure.ac index 12b4664de2e..f0af8ede0c4 100644 --- a/libvtv/configure.ac +++ b/libvtv/configure.ac @@ -122,6 +122,7 @@ AC_CHECK_TOOL(RANLIB, ranlib, :) # Configure libtool AC_LIBTOOL_DLOPEN AM_PROG_LIBTOOL +ACX_LT_HOST_FLAGS AC_SUBST(enable_shared) AC_SUBST(enable_static) @@ -155,4 +156,15 @@ _EOF ]) fi +case "$target_os" in + cygwin*|mingw32*) + vtv_cygmin="yes" + ;; + *) + vtv_cygmin="no" + ;; +esac + +AM_CONDITIONAL(VTV_CYGMIN, test $vtv_cygmin = yes) + AC_OUTPUT diff --git a/libvtv/configure.tgt b/libvtv/configure.tgt index 046b4152429..00fb4d51ed4 100644 --- a/libvtv/configure.tgt +++ b/libvtv/configure.tgt @@ -26,6 +26,12 @@ case "${target}" in x86_64-*-linux* | i?86-*-linux*) VTV_SUPPORTED=yes ;; + x86_64-*-cygwin* | i?86-*-cygwin*) + VTV_SUPPORTED=yes + ;; + x86_64-*-mingw* | i?86-*-mingw*) + VTV_SUPPORTED=yes + ;; powerpc*-*-linux*) ;; sparc*-*-linux*) diff --git a/libvtv/vtv_fail.cc b/libvtv/vtv_fail.cc index 4f183d8cac2..7e7992267aa 100644 --- a/libvtv/vtv_fail.cc +++ b/libvtv/vtv_fail.cc @@ -46,7 +46,11 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> + +#if !defined (__CYGWIN__) && !defined (__MINGW32__) #include <execinfo.h> +#endif + #include <unistd.h> #include "vtv_utils.h" @@ -102,8 +106,10 @@ log_error_message (const char *log_msg, bool generate_backtrace) { #define STACK_DEPTH 20 void *callers[STACK_DEPTH]; +#if !defined (__CYGWIN__) && !defined (__MINGW32__) int actual_depth = backtrace (callers, STACK_DEPTH); backtrace_symbols_fd (callers, actual_depth, vtv_failures_log_fd); +#endif } } diff --git a/libvtv/vtv_malloc.cc b/libvtv/vtv_malloc.cc index 8aaa636e0e3..4b675f40bdc 100644 --- a/libvtv/vtv_malloc.cc +++ b/libvtv/vtv_malloc.cc @@ -33,7 +33,11 @@ #include <stdlib.h> #include <unistd.h> +#if defined (__CYGWIN__) || defined (__MINGW32__) +#include <windows.h> +#else #include <sys/mman.h> +#endif #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -62,6 +66,18 @@ static void *current_chunk VTV_PROTECTED_VAR = 0; static size_t current_chunk_size VTV_PROTECTED_VAR = 0; static int malloc_initialized VTV_PROTECTED_VAR = 0; +#if defined (__CYGWIN__) || defined (__MINGW32__) +//sysconf(_SC_PAGE_SIZE) port +long sysconf_SC_PAGE_SIZE() +{ + SYSTEM_INFO si; + GetSystemInfo(&si); + long pageSize = (long)si.dwPageSize; + return pageSize; + //return 4096; // standard usermode 32bit pagesize in bytes // FIXME +} +#endif + /* The function goes through and counts all the pages we have allocated so far. It returns the page count. */ @@ -162,8 +178,13 @@ obstack_chunk_alloc (size_t size) VTV_DEBUG_ASSERT ((size & (VTV_PAGE_SIZE - 1)) == 0); void *allocated; +#if defined (__CYGWIN__) || defined (__MINGW32__) + if ((allocated = VirtualAlloc(NULL, size, MEM_RESERVE|MEM_COMMIT, + PAGE_READWRITE)) == 0) +#else if ((allocated = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == 0) +#endif VTV_error (); VTV_DEBUG_ASSERT (((unsigned long) allocated & (VTV_PAGE_SIZE - 1)) == 0); @@ -190,7 +211,11 @@ __vtv_malloc_init (void) if (malloc_initialized) return; +#if defined (__CYGWIN__) || defined (__MINGW32__) + if (VTV_PAGE_SIZE != sysconf_SC_PAGE_SIZE()) +#else if (VTV_PAGE_SIZE != sysconf (_SC_PAGE_SIZE)) +#endif VTV_error (); obstack_chunk_size (&vtv_obstack) = VTV_PAGE_SIZE; diff --git a/libvtv/vtv_malloc.h b/libvtv/vtv_malloc.h index 55f5fe8022b..2af565f6e66 100644 --- a/libvtv/vtv_malloc.h +++ b/libvtv/vtv_malloc.h @@ -95,4 +95,11 @@ extern void __vtv_malloc_stats (void); extern void __vtv_malloc_dump_stats (void); extern int __vtv_count_mmapped_pages (void); +#if defined (__CYGWIN__) || defined (__MINGW32__) +extern "C" int mprotect (void *addr, int len, int prot); + + #define PROT_READ 0x1 + #define PROT_WRITE 0x2 +#endif + #endif /* vtv_malloc.h */ diff --git a/libvtv/vtv_map.h b/libvtv/vtv_map.h index ec058f845f7..91665bc773d 100644 --- a/libvtv/vtv_map.h +++ b/libvtv/vtv_map.h @@ -26,7 +26,13 @@ #define _VTV_MAP_H 1 #include <string.h> + +#ifdef __MINGW32__ +#include <stdint.h> +#include "vtv_utils.h" +#else #include <vtv_utils.h> +#endif inline uint64_t load8bytes (const void *p) diff --git a/libvtv/vtv_rts.cc b/libvtv/vtv_rts.cc index 1af000d8eb5..f5344a00687 100644 --- a/libvtv/vtv_rts.cc +++ b/libvtv/vtv_rts.cc @@ -121,12 +121,20 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> +#if defined (__CYGWIN__) || defined (__MINGW32__) +#include <windows.h> +#include <winternl.h> +#include <psapi.h> +#else #include <execinfo.h> +#endif #include <unistd.h> +#if !defined (__CYGWIN__) && !defined (__MINGW32__) #include <sys/mman.h> -#include <errno.h> #include <link.h> +#endif +#include <errno.h> #include <fcntl.h> #include <limits.h> @@ -143,6 +151,13 @@ #include "vtv-change-permission.h" +#if defined (__CYGWIN__) || defined (__MINGW32__) +// porting: fix link error to libc +void __fortify_fail (const char * msg){ + OutputDebugString(msg); + abort(); +} +#else extern "C" { /* __fortify_fail is a function in glibc that calls __libc_message, @@ -159,6 +174,7 @@ extern "C" { extern void __fortify_fail (const char *) __attribute__((noreturn)); } /* extern "C" */ +#endif /* The following variables are used only for debugging and performance tuning purposes. Therefore they do not need to be "protected". @@ -313,10 +329,17 @@ typedef vtv_set_handle * vtv_set_handle_handle; struct sect_hdr_data { +#if defined (__CYGWIN__) || defined (__MINGW32__) + uintptr_t dlpi_addr; /* The header address in the INFO record, + passed in from dl_iterate_phdr. */ + uintptr_t mp_low; /* Start address of the .vtable_map_vars + section in memory. */ +#else ElfW (Addr) dlpi_addr; /* The header address in the INFO record, passed in from dl_iterate_phdr. */ ElfW (Addr) mp_low; /* Start address of the .vtable_map_vars section in memory. */ +#endif size_t mp_size; /* Size of the .vtable_map_vars section in memory. */ }; @@ -336,8 +359,13 @@ unsigned int num_cache_entries VTV_PROTECTED_VAR = 0; it returns the record for that entry; otherwise it returns NULL. */ +#if defined (__CYGWIN__) || defined (__MINGW32__) +struct sect_hdr_data * +search_cached_file_data (uintptr_t load_addr) +#else struct sect_hdr_data * search_cached_file_data (ElfW (Addr) load_addr) +#endif { unsigned int i; for (i = 0; i < num_cache_entries; ++i) @@ -401,6 +429,130 @@ log_memory_protection_data (char *message) __vtv_add_to_log (log_fd, "%s", message); } +#if defined (__CYGWIN__) || defined (__MINGW32__) +static void +read_section_offset_and_length (char *name, + uintptr_t addr, + const char *sect_name, + int mprotect_flags, + off_t *sect_offset, + WORD *sect_len) +{ + bool found = false; + struct sect_hdr_data *cached_data = NULL; + + /* Check to see if we already have the data for this file. */ + cached_data = search_cached_file_data (addr); + + if (cached_data) + { + *sect_offset = cached_data->mp_low; + *sect_len = cached_data->mp_size; + return; + } + + // check for DOS Header magic bytes + if (*(WORD *)addr == 0x5A4D) + { + int name_len = strlen (sect_name); + int fd = -1; + + /* Attempt to open the binary file on disk. */ + if (strlen (name) == 0) + { + return; + } + else + fd = open (name, O_RDONLY | O_BINARY); + + if (fd != -1) + { + /* Find the section header information in memory. */ + PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)addr; + PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((char *)addr + + pDosHeader->e_lfanew); + PIMAGE_FILE_HEADER pFileHeader = &pNtHeaders->FileHeader; + + DWORD PointerToStringTable = pFileHeader->PointerToSymbolTable + + (pFileHeader->NumberOfSymbols*0x12); + + PIMAGE_SECTION_HEADER sect_hdr = + (PIMAGE_SECTION_HEADER)((char *)&pNtHeaders->OptionalHeader + + pFileHeader->SizeOfOptionalHeader); + + /* Loop through all the section headers, looking for one whose + name is ".vtable_map_vars". */ + + for (int i = 0; i < pFileHeader->NumberOfSections && !found; ++i) + { + char header_name[64]; + + /* Check if we have to get the section name from the COFF string + table. */ + if (sect_hdr[i].Name[0] == '/') + { + if (atoi((const char*)sect_hdr[i].Name+1) == 0) + { + continue; + } + + off_t name_offset = PointerToStringTable + + atoi((const char*)sect_hdr[i].Name+1); + + size_t bytes_read = ReadFromOffset (fd, &header_name, 64, + name_offset); + + VTV_ASSERT (bytes_read > 0); + } + else + { + memcpy (&header_name, sect_hdr[i].Name, + sizeof (sect_hdr[i].Name)); + } + + if (memcmp (header_name, sect_name, name_len) == 0) + { + /* We found the section; get its load offset and + size. */ + *sect_offset = sect_hdr[i].VirtualAddress; + if (sect_hdr[i].Misc.VirtualSize % VTV_PAGE_SIZE != 0) + *sect_len = sect_hdr[i].Misc.VirtualSize + VTV_PAGE_SIZE + - (sect_hdr[i].Misc.VirtualSize % VTV_PAGE_SIZE); + else + *sect_len = sect_hdr[i].Misc.VirtualSize; + found = true; + } + } + close (fd); + } + } + + if (*sect_offset != 0 && *sect_len != 0) + { + /* Calculate the page location in memory, making sure the + address is page-aligned. */ + uintptr_t start_addr = addr + *sect_offset; + *sect_offset = start_addr & ~(VTV_PAGE_SIZE - 1); + *sect_len = *sect_len - 1; + + /* Since we got this far, we must not have found these pages in + the cache, so add them to it. NOTE: We could get here either + while making everything read-only or while making everything + read-write. We will only update the cache if we get here on + a read-write (to make absolutely sure the cache is writable + -- also the read-write pass should come before the read-only + pass). */ + if ((mprotect_flags & PROT_WRITE) + && num_cache_entries < MAX_ENTRIES) + { + vtv_sect_info_cache[num_cache_entries].dlpi_addr = addr; + vtv_sect_info_cache[num_cache_entries].mp_low = *sect_offset; + vtv_sect_info_cache[num_cache_entries].mp_size = *sect_len; + num_cache_entries++; + } + } +} +#else static void read_section_offset_and_length (struct dl_phdr_info *info, const char *sect_name, @@ -547,7 +699,125 @@ read_section_offset_and_length (struct dl_phdr_info *info, } } } +#endif + +#if defined (__CYGWIN__) || defined (__MINGW32__) +/* This function is used to iterate over all loaded modules and searches + for a section called ".vtable_map_vars". The only interaction with + the binary file on disk of the module is to read section names in the + COFF string table. If the module contains a ".vtable_map_vars" section, + read section offset and size from the section header of the loaded module. + Call 'mprotect' on those pages, setting the protection either to + read-only or read-write, depending on what's in data. + The calls to change the protection occur in vtv_unprotect_vtable_vars + and vtv_protect_vtable_vars. */ + +static int +iterate_modules (void *data) +{ + int * mprotect_flags = (int *) data; + off_t map_sect_offset = 0; + WORD map_sect_len = 0; + char buffer[1024]; + const char *map_sect_name = VTV_PROTECTED_VARS_SECTION; + HMODULE hMods[1024]; + HANDLE hProcess; + DWORD cbNeeded; + hProcess = GetCurrentProcess (); + + if (NULL == hProcess) + return 0; + + if (EnumProcessModules (hProcess, hMods, sizeof (hMods), &cbNeeded)) + { + /* Iterate over all loaded modules. */ + for (unsigned int i = 0; i < (cbNeeded / sizeof (HMODULE)); i++) + { + char szModName[MAX_PATH]; + + if (GetModuleFileNameExA (hProcess, hMods[i], szModName, + sizeof (szModName))) + { + map_sect_offset = 0; + map_sect_len = 0; + read_section_offset_and_length (szModName, + (uintptr_t) hMods[i], + map_sect_name, + *mprotect_flags, + &map_sect_offset, + &map_sect_len); + + if (debug_functions) + { + snprintf (buffer, sizeof(buffer), + " Looking at load module %s to change permissions to %s\n", + szModName, + (*mprotect_flags & PROT_WRITE) ? "READ/WRITE" : "READ-ONLY"); + log_memory_protection_data (buffer); + } + + /* See if we actually found the section. */ + if (map_sect_offset && map_sect_len) + { + unsigned long long start; + int result; + + if (debug_functions) + { + snprintf (buffer, sizeof (buffer), + " (%s): Protecting %p to %p\n", + szModName, + (void *) map_sect_offset, + (void *) (map_sect_offset + map_sect_len)); + log_memory_protection_data (buffer); + } + + /* Change the protections on the pages for the section. */ + + start = get_cycle_count (); + result = mprotect ((void *) map_sect_offset, map_sect_len, + *mprotect_flags); + accumulate_cycle_count (&mprotect_cycles, start); + if (result == -1) + { + if (debug_functions) + { + snprintf (buffer, sizeof (buffer), + "Failed called to mprotect for %s error: ", + (*mprotect_flags & PROT_WRITE) ? + "READ/WRITE" : "READ-ONLY"); + log_memory_protection_data (buffer); + perror(NULL); + } + VTV_error(); + } + else + { + if (debug_functions) + { + snprintf (buffer, sizeof (buffer), + "mprotect'ed range [%p, %p]\n", + (void *) map_sect_offset, + (char *) map_sect_offset + map_sect_len); + log_memory_protection_data (buffer); + } + } + increment_num_calls (&num_calls_to_mprotect); + /* num_pages_protected += (map_sect_len + VTV_PAGE_SIZE - 1) + / VTV_PAGE_SIZE; */ + num_pages_protected += (map_sect_len + 4096 - 1) / 4096; + continue; + } + } + } + } + + CloseHandle(hProcess); + + return 0; +} +#else /* This is the callback function used by dl_iterate_phdr (which is called from vtv_unprotect_vtable_vars and vtv_protect_vtable_vars). It attempts to find the binary file on disk for the INFO record @@ -652,6 +922,7 @@ dl_iterate_phdr_callback (struct dl_phdr_info *info, size_t, void *data) return 0; } +#endif /* This function explicitly changes the protection (read-only or read-write) on the vtv_sect_info_cache, which is used for speeding up look ups in the @@ -678,7 +949,7 @@ change_protections_on_phdr_cache (int protection_flag) char * low_address = (char *) &(vtv_sect_info_cache); size_t cache_size = MAX_ENTRIES * sizeof (struct sect_hdr_data); - low_address = (char *) ((unsigned long) low_address & ~(VTV_PAGE_SIZE - 1)); + low_address = (char *) ((uintptr_t) low_address & ~(VTV_PAGE_SIZE - 1)); if (mprotect ((void *) low_address, cache_size, protection_flag) == -1) VTV_error (); @@ -695,7 +966,11 @@ vtv_unprotect_vtable_vars (void) mprotect_flags = PROT_READ | PROT_WRITE; change_protections_on_phdr_cache (mprotect_flags); +#if defined (__CYGWIN__) || defined (__MINGW32__) + iterate_modules ((void *) &mprotect_flags); +#else dl_iterate_phdr (dl_iterate_phdr_callback, (void *) &mprotect_flags); +#endif } /* Protect all the vtable map vars and other side data that is used @@ -708,7 +983,11 @@ vtv_protect_vtable_vars (void) int mprotect_flags; mprotect_flags = PROT_READ; +#if defined (__CYGWIN__) || defined (__MINGW32__) + iterate_modules ((void *) &mprotect_flags); +#else dl_iterate_phdr (dl_iterate_phdr_callback, (void *) &mprotect_flags); +#endif change_protections_on_phdr_cache (mprotect_flags); } @@ -868,7 +1147,7 @@ const unsigned long SET_HANDLE_HANDLE_BIT = 0x2; static inline bool is_set_handle_handle (void * ptr) { - return ((unsigned long) ptr & SET_HANDLE_HANDLE_BIT) + return ((uintptr_t) ptr & SET_HANDLE_HANDLE_BIT) == SET_HANDLE_HANDLE_BIT; } @@ -878,7 +1157,7 @@ is_set_handle_handle (void * ptr) static inline vtv_set_handle * ptr_from_set_handle_handle (void * ptr) { - return (vtv_set_handle *) ((unsigned long) ptr & ~SET_HANDLE_HANDLE_BIT); + return (vtv_set_handle *) ((uintptr_t) ptr & ~SET_HANDLE_HANDLE_BIT); } /* Given a vtable map variable, PTR, this function sets the bit that @@ -888,7 +1167,7 @@ ptr_from_set_handle_handle (void * ptr) static inline vtv_set_handle_handle set_handle_handle (vtv_set_handle * ptr) { - return (vtv_set_handle_handle) ((unsigned long) ptr | SET_HANDLE_HANDLE_BIT); + return (vtv_set_handle_handle) ((uintptr_t) ptr | SET_HANDLE_HANDLE_BIT); } static inline void @@ -1362,6 +1641,7 @@ __VLTVerifyVtablePointer (void ** set_handle_ptr, const void * vtable_ptr) static int page_count_2 = 0; +#if !defined (__CYGWIN__) && !defined (__MINGW32__) static int dl_iterate_phdr_count_pages (struct dl_phdr_info *info, size_t unused __attribute__ ((__unused__)), @@ -1392,6 +1672,7 @@ dl_iterate_phdr_count_pages (struct dl_phdr_info *info, return 0; } +#endif static void count_all_pages (void) @@ -1401,7 +1682,11 @@ count_all_pages (void) mprotect_flags = PROT_READ; page_count_2 = 0; +#if defined (__CYGWIN__) || defined (__MINGW32__) + iterate_modules ((void *) &mprotect_flags); +#else dl_iterate_phdr (dl_iterate_phdr_count_pages, (void *) &mprotect_flags); +#endif page_count_2 += __vtv_count_mmapped_pages (); } diff --git a/libvtv/vtv_utils.cc b/libvtv/vtv_utils.cc index 9cf4b08dc24..ebbeaf51999 100644 --- a/libvtv/vtv_utils.cc +++ b/libvtv/vtv_utils.cc @@ -33,7 +33,12 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#if defined (__CYGWIN__) || defined (__MINGW32__) +#include <windows.h> +#else #include <execinfo.h> +#endif + #include <unistd.h> #include <errno.h> @@ -64,8 +69,12 @@ __vtv_open_log (const char *name) { char log_name[1024]; char log_dir[512]; +#if defined (__CYGWIN__) || defined (__MINGW32__) + pid_t process_id = GetCurrentProcessId (); +#else uid_t user_id = getuid (); pid_t process_id = getpid (); +#endif char *logs_prefix; bool logs_dir_specified = false; int fd = -1; @@ -74,14 +83,29 @@ __vtv_open_log (const char *name) if (logs_prefix && strlen (logs_prefix) > 0) { logs_dir_specified = true; +#ifdef __MINGW32__ + mkdir (logs_prefix); +#else mkdir (logs_prefix, S_IRWXU); +#endif + snprintf (log_dir, sizeof (log_dir), "%s/vtv_logs", logs_prefix); - mkdir (log_dir, S_IRWXU); +#ifdef __MINGW32__ + mkdir (log_dir); +#else + mkdir (log_dir, S_IRWXU); +#endif +#if defined (__CYGWIN__) || defined (__MINGW32__) + snprintf (log_name, sizeof (log_name), "%s_%d_%s", log_dir, + (unsigned) process_id, name); + fd = open (log_name, O_WRONLY | O_APPEND | O_CREAT, S_IRWXU); +#else snprintf (log_name, sizeof (log_name), "%s/%d_%d_%s", log_dir, (unsigned) user_id, (unsigned) process_id, name); fd = open (log_name, O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW, S_IRWXU); +#endif } else fd = dup (2); @@ -125,8 +149,12 @@ __vtv_add_to_log (int log_file, const char * format, ...) va_list ap; va_start (ap, format); +#if defined (__CYGWIN__) || defined (__MINGW32__) + snprintf (output, sizeof (output), "VTV: PID=%ld ", GetCurrentProcessId ()); +#else snprintf (output, sizeof (output), "VTV: PID=%d PPID=%d ", getpid (), getppid ()); +#endif vtv_log_write (log_file, output); vsnprintf (output, sizeof (output), format, ap); vtv_log_write (log_file, output); @@ -151,6 +179,7 @@ __vtv_log_verification_failure (const char *log_msg, bool generate_backtrace) __vtv_add_to_log (vtv_failures_log_fd, "%s", log_msg); +#if !defined (__CYGWIN__) && !defined (__MINGW32__) if (generate_backtrace) { #define STACK_DEPTH 20 @@ -158,4 +187,5 @@ __vtv_log_verification_failure (const char *log_msg, bool generate_backtrace) int actual_depth = backtrace (callers, STACK_DEPTH); backtrace_symbols_fd (callers, actual_depth, vtv_failures_log_fd); } +#endif } |