server: Implement the various image flags in SECTION_IMAGE_INFORMATION.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2df367a4f7
commit
4a2ad423a6
|
@ -379,7 +379,6 @@ static BOOL query_image_section( int id, const char *dll_name, const IMAGE_NT_HE
|
|||
image.DllCharacteristics, nt_header->OptionalHeader.DllCharacteristics );
|
||||
ok( image.Machine == nt_header->FileHeader.Machine, "%u: Machine wrong %04x / %04x\n", id,
|
||||
image.Machine, nt_header->FileHeader.Machine );
|
||||
todo_wine_if (cor_header)
|
||||
ok( image.LoaderFlags == (cor_header != NULL), "%u: LoaderFlags wrong %08x\n", id, image.LoaderFlags );
|
||||
ok( image.ImageFileSize == file_size || broken(!image.ImageFileSize), /* winxpsp1 */
|
||||
"%u: ImageFileSize wrong %08x / %08x\n", id, image.ImageFileSize, file_size );
|
||||
|
@ -402,12 +401,10 @@ static BOOL query_image_section( int id, const char *dll_name, const IMAGE_NT_HE
|
|||
(cor_header->MajorRuntimeVersion > 2 ||
|
||||
(cor_header->MajorRuntimeVersion == 2 && cor_header->MinorRuntimeVersion >= 5)))
|
||||
{
|
||||
todo_wine
|
||||
ok( S(U(image)).ComPlusILOnly || broken(is_winxp),
|
||||
"%u: wrong ComPlusILOnly flags %02x\n", id, U(image).ImageFlags );
|
||||
if (nt_header->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
|
||||
!(cor_header->Flags & COMIMAGE_FLAGS_32BITREQUIRED))
|
||||
todo_wine
|
||||
ok( S(U(image)).ComPlusNativeReady || broken(is_winxp),
|
||||
"%u: wrong ComPlusNativeReady flags %02x\n", id, U(image).ImageFlags );
|
||||
else
|
||||
|
@ -425,7 +422,6 @@ static BOOL query_image_section( int id, const char *dll_name, const IMAGE_NT_HE
|
|||
{
|
||||
/* winxp doesn't support any of the loader flags */
|
||||
if (!S(U(image)).ImageMappedFlat) is_winxp = TRUE;
|
||||
todo_wine
|
||||
ok( S(U(image)).ImageMappedFlat || broken(is_winxp),
|
||||
"%u: wrong ImageMappedFlat flags %02x\n", id, U(image).ImageFlags );
|
||||
}
|
||||
|
@ -433,7 +429,6 @@ static BOOL query_image_section( int id, const char *dll_name, const IMAGE_NT_HE
|
|||
ok( !S(U(image)).ImageDynamicallyRelocated || broken( S(U(image)).ComPlusILOnly ), /* <= win7 */
|
||||
"%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags );
|
||||
else if (image.ImageContainsCode && !cor_header)
|
||||
todo_wine
|
||||
ok( S(U(image)).ImageDynamicallyRelocated || broken(is_winxp),
|
||||
"%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags );
|
||||
else
|
||||
|
@ -532,7 +527,6 @@ static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header, const IMAG
|
|||
const IMAGE_COR20_HEADER *cor_header = section_data;
|
||||
il_only = (cor_header->Flags & COMIMAGE_FLAGS_ILONLY) != 0;
|
||||
}
|
||||
todo_wine_if (il_only && nt_header->OptionalHeader.SizeOfCode)
|
||||
ok( mod != NULL || broken(il_only), /* <= win7 */
|
||||
"%u: loading failed err %u\n", line, GetLastError() );
|
||||
}
|
||||
|
|
|
@ -522,11 +522,42 @@ static int build_shared_mapping( struct mapping *mapping, int fd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* load the CLR header from its section */
|
||||
static int load_clr_header( IMAGE_COR20_HEADER *hdr, size_t va, size_t size, int unix_fd,
|
||||
IMAGE_SECTION_HEADER *sec, unsigned int nb_sec )
|
||||
{
|
||||
ssize_t ret;
|
||||
size_t map_size, file_size;
|
||||
off_t file_start;
|
||||
unsigned int i;
|
||||
|
||||
if (!va || !size) return 0;
|
||||
|
||||
for (i = 0; i < nb_sec; i++)
|
||||
{
|
||||
if (va < sec[i].VirtualAddress) continue;
|
||||
if (sec[i].Misc.VirtualSize && va - sec[i].VirtualAddress >= sec[i].Misc.VirtualSize) continue;
|
||||
get_section_sizes( &sec[i], &map_size, &file_start, &file_size );
|
||||
if (size >= map_size) continue;
|
||||
if (va - sec[i].VirtualAddress >= map_size - size) continue;
|
||||
file_size = min( file_size, map_size );
|
||||
size = min( size, sizeof(*hdr) );
|
||||
ret = pread( unix_fd, hdr, min( size, file_size ), file_start + va - sec[i].VirtualAddress );
|
||||
if (ret <= 0) break;
|
||||
if (ret < sizeof(*hdr)) memset( (char *)hdr + ret, 0, sizeof(*hdr) - ret );
|
||||
return (hdr->MajorRuntimeVersion > COR_VERSION_MAJOR_V2 ||
|
||||
(hdr->MajorRuntimeVersion == COR_VERSION_MAJOR_V2 &&
|
||||
hdr->MinorRuntimeVersion >= COR_VERSION_MINOR));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* retrieve the mapping parameters for an executable (PE) image */
|
||||
static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_size, int unix_fd )
|
||||
{
|
||||
IMAGE_DOS_HEADER dos;
|
||||
IMAGE_SECTION_HEADER *sec = NULL;
|
||||
IMAGE_COR20_HEADER clr;
|
||||
IMAGE_SECTION_HEADER sec[96];
|
||||
struct
|
||||
{
|
||||
DWORD Signature;
|
||||
|
@ -539,6 +570,7 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
|
|||
} nt;
|
||||
off_t pos;
|
||||
int size;
|
||||
size_t clr_va, clr_size;
|
||||
unsigned int i, cpu_mask = get_supported_cpu_mask();
|
||||
|
||||
/* load the headers */
|
||||
|
@ -578,6 +610,9 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
|
|||
default:
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
clr_va = nt.opt.hdr32.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
|
||||
clr_size = nt.opt.hdr32.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size;
|
||||
|
||||
mapping->image.base = nt.opt.hdr32.ImageBase;
|
||||
mapping->image.entry_point = nt.opt.hdr32.ImageBase + nt.opt.hdr32.AddressOfEntryPoint;
|
||||
mapping->image.map_size = ROUND_SIZE( nt.opt.hdr32.SizeOfImage );
|
||||
|
@ -590,9 +625,14 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
|
|||
mapping->image.contains_code = (nt.opt.hdr32.SizeOfCode ||
|
||||
nt.opt.hdr32.AddressOfEntryPoint ||
|
||||
nt.opt.hdr32.SectionAlignment & page_mask);
|
||||
mapping->image.loader_flags = nt.opt.hdr32.LoaderFlags;
|
||||
mapping->image.header_size = nt.opt.hdr32.SizeOfHeaders;
|
||||
mapping->image.checksum = nt.opt.hdr32.CheckSum;
|
||||
mapping->image.image_flags = 0;
|
||||
if (nt.opt.hdr32.SectionAlignment & page_mask)
|
||||
mapping->image.image_flags |= IMAGE_FLAGS_ImageMappedFlat;
|
||||
if ((nt.opt.hdr32.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) &&
|
||||
mapping->image.contains_code && !(clr_va && clr_size))
|
||||
mapping->image.image_flags |= IMAGE_FLAGS_ImageDynamicallyRelocated;
|
||||
break;
|
||||
|
||||
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
|
||||
|
@ -608,6 +648,9 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
|
|||
default:
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
clr_va = nt.opt.hdr64.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
|
||||
clr_size = nt.opt.hdr64.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size;
|
||||
|
||||
mapping->image.base = nt.opt.hdr64.ImageBase;
|
||||
mapping->image.entry_point = nt.opt.hdr64.ImageBase + nt.opt.hdr64.AddressOfEntryPoint;
|
||||
mapping->image.map_size = ROUND_SIZE( nt.opt.hdr64.SizeOfImage );
|
||||
|
@ -620,9 +663,14 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
|
|||
mapping->image.contains_code = (nt.opt.hdr64.SizeOfCode ||
|
||||
nt.opt.hdr64.AddressOfEntryPoint ||
|
||||
nt.opt.hdr64.SectionAlignment & page_mask);
|
||||
mapping->image.loader_flags = nt.opt.hdr64.LoaderFlags;
|
||||
mapping->image.header_size = nt.opt.hdr64.SizeOfHeaders;
|
||||
mapping->image.checksum = nt.opt.hdr64.CheckSum;
|
||||
mapping->image.image_flags = 0;
|
||||
if (nt.opt.hdr64.SectionAlignment & page_mask)
|
||||
mapping->image.image_flags |= IMAGE_FLAGS_ImageMappedFlat;
|
||||
if ((nt.opt.hdr64.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) &&
|
||||
mapping->image.contains_code && !(clr_va && clr_size))
|
||||
mapping->image.image_flags |= IMAGE_FLAGS_ImageDynamicallyRelocated;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -633,31 +681,36 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
|
|||
mapping->image.machine = nt.FileHeader.Machine;
|
||||
mapping->image.zerobits = 0; /* FIXME */
|
||||
mapping->image.gp = 0; /* FIXME */
|
||||
mapping->image.image_flags = 0; /* FIXME */
|
||||
mapping->image.file_size = file_size;
|
||||
mapping->image.loader_flags = clr_va && clr_size;
|
||||
|
||||
/* load the section headers */
|
||||
|
||||
pos += sizeof(nt.Signature) + sizeof(nt.FileHeader) + nt.FileHeader.SizeOfOptionalHeader;
|
||||
if (nt.FileHeader.NumberOfSections > sizeof(sec)/sizeof(sec[0])) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
size = sizeof(*sec) * nt.FileHeader.NumberOfSections;
|
||||
if (!mapping->size) mapping->size = mapping->image.map_size;
|
||||
else if (mapping->size > mapping->image.map_size) return STATUS_SECTION_TOO_BIG;
|
||||
if (pos + size > mapping->image.map_size) return STATUS_INVALID_FILE_FOR_SECTION;
|
||||
if (pos + size > mapping->image.header_size) mapping->image.header_size = pos + size;
|
||||
if (!(sec = malloc( size ))) goto error;
|
||||
if (pread( unix_fd, sec, size, pos ) != size) goto error;
|
||||
if (pread( unix_fd, sec, size, pos ) != size) return STATUS_INVALID_FILE_FOR_SECTION;
|
||||
|
||||
for (i = 0; i < nt.FileHeader.NumberOfSections && !mapping->image.contains_code; i++)
|
||||
if (sec[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) mapping->image.contains_code = 1;
|
||||
|
||||
if (!build_shared_mapping( mapping, unix_fd, sec, nt.FileHeader.NumberOfSections )) goto error;
|
||||
if (load_clr_header( &clr, clr_va, clr_size, unix_fd, sec, nt.FileHeader.NumberOfSections ) &&
|
||||
(clr.Flags & COMIMAGE_FLAGS_ILONLY))
|
||||
{
|
||||
mapping->image.image_flags |= IMAGE_FLAGS_ComPlusILOnly;
|
||||
if (nt.opt.hdr32.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
|
||||
!(clr.Flags & COMIMAGE_FLAGS_32BITREQUIRED))
|
||||
mapping->image.image_flags |= IMAGE_FLAGS_ComPlusNativeReady;
|
||||
}
|
||||
|
||||
free( sec );
|
||||
return 0;
|
||||
if (!build_shared_mapping( mapping, unix_fd, sec, nt.FileHeader.NumberOfSections ))
|
||||
return STATUS_INVALID_FILE_FOR_SECTION;
|
||||
|
||||
error:
|
||||
free( sec );
|
||||
return STATUS_INVALID_FILE_FOR_SECTION;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static struct ranges *create_ranges(void)
|
||||
|
|
Loading…
Reference in New Issue