/*********************************************************************** * add_fd_to_cache * * Caller must hold fd_cache_section. */ static int add_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type, unsigned int access, unsigned int options ) { unsigned int entry, idx = handle_to_index( handle, &entry ); int prev_fd; if (entry >= FD_CACHE_ENTRIES) { FIXME( "too many allocated handles, not caching %p\n", handle ); return 0; } if (!fd_cache[entry]) /* do we need to allocate a new block of entries? */ { if (!entry) fd_cache[0] = fd_cache_initial_block; else { void *ptr = wine_anon_mmap( NULL, FD_CACHE_BLOCK_SIZE * sizeof(struct fd_cache_entry), PROT_READ | PROT_WRITE, 0 ); if (ptr == MAP_FAILED) return 0; fd_cache[entry] = ptr; } } /* store fd+1 so that 0 can be used as the unset value */ prev_fd = interlocked_xchg( &fd_cache[entry][idx].fd, fd + 1 ) - 1; fd_cache[entry][idx].type = type; fd_cache[entry][idx].access = access; fd_cache[entry][idx].options = options; if (prev_fd != -1) close( prev_fd ); return 1; }
static inline void reserve_area( void *addr, size_t size ) { wine_anon_mmap( addr, size, PROT_NONE, MAP_FIXED | MAP_NORESERVE ); wine_mmap_add_reserved_area( addr, size ); }
/* map a builtin dll in memory and fixup RVAs */ static void *map_dll( const IMAGE_NT_HEADERS *nt_descr ) { #ifdef HAVE_MMAP IMAGE_DATA_DIRECTORY *dir; IMAGE_DOS_HEADER *dos; IMAGE_NT_HEADERS *nt; IMAGE_SECTION_HEADER *sec; BYTE *addr; DWORD code_start, data_start, data_end; const size_t page_size = getpagesize(); const size_t page_mask = page_size - 1; int delta, nb_sections = 2; /* code + data */ unsigned int i; size_t size = (sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) + nb_sections * sizeof(IMAGE_SECTION_HEADER)); assert( size <= page_size ); /* module address must be aligned on 64K boundary */ addr = (BYTE *)((nt_descr->OptionalHeader.ImageBase + 0xffff) & ~0xffff); if (wine_anon_mmap( addr, page_size, PROT_READ|PROT_WRITE, MAP_FIXED ) != addr) return NULL; dos = (IMAGE_DOS_HEADER *)addr; nt = (IMAGE_NT_HEADERS *)(dos + 1); sec = (IMAGE_SECTION_HEADER *)(nt + 1); /* Build the DOS and NT headers */ dos->e_magic = IMAGE_DOS_SIGNATURE; dos->e_cblp = 0x90; dos->e_cp = 3; dos->e_cparhdr = (sizeof(*dos)+0xf)/0x10; dos->e_minalloc = 0; dos->e_maxalloc = 0xffff; dos->e_ss = 0x0000; dos->e_sp = 0x00b8; dos->e_lfarlc = sizeof(*dos); dos->e_lfanew = sizeof(*dos); *nt = *nt_descr; delta = (const BYTE *)nt_descr - addr; code_start = page_size; data_start = delta & ~page_mask; data_end = (nt->OptionalHeader.SizeOfImage + delta + page_mask) & ~page_mask; fixup_rva_ptrs( &nt->OptionalHeader.AddressOfEntryPoint, addr, 1 ); nt->FileHeader.NumberOfSections = nb_sections; nt->OptionalHeader.BaseOfCode = code_start; #ifndef _WIN64 nt->OptionalHeader.BaseOfData = data_start; #endif nt->OptionalHeader.SizeOfCode = data_start - code_start; nt->OptionalHeader.SizeOfInitializedData = data_end - data_start; nt->OptionalHeader.SizeOfUninitializedData = 0; nt->OptionalHeader.SizeOfImage = data_end; nt->OptionalHeader.ImageBase = (ULONG_PTR)addr; /* Build the code section */ memcpy( sec->Name, ".text", sizeof(".text") ); sec->SizeOfRawData = data_start - code_start; sec->Misc.VirtualSize = sec->SizeOfRawData; sec->VirtualAddress = code_start; sec->PointerToRawData = code_start; sec->Characteristics = (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ); sec++; /* Build the data section */ memcpy( sec->Name, ".data", sizeof(".data") ); sec->SizeOfRawData = data_end - data_start; sec->Misc.VirtualSize = sec->SizeOfRawData; sec->VirtualAddress = data_start; sec->PointerToRawData = data_start; sec->Characteristics = (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ); sec++; for (i = 0; i < nt->OptionalHeader.NumberOfRvaAndSizes; i++) fixup_rva_dwords( &nt->OptionalHeader.DataDirectory[i].VirtualAddress, delta, 1 ); /* Build the import directory */ dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY]; if (dir->Size) { IMAGE_IMPORT_DESCRIPTOR *imports = (void *)(addr + dir->VirtualAddress); fixup_imports( imports, addr, delta ); } /* Build the resource directory */ dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY]; if (dir->Size) { void *ptr = (void *)(addr + dir->VirtualAddress); fixup_resources( ptr, ptr, delta ); } /* Build the export directory */ dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY]; if (dir->Size) { IMAGE_EXPORT_DIRECTORY *exports = (void *)(addr + dir->VirtualAddress); fixup_exports( exports, addr, delta ); } return addr; #else /* HAVE_MMAP */ return NULL; #endif /* HAVE_MMAP */ }