server: Check that the prefix type can support the client architecture.
diff --git a/server/object.h b/server/object.h
index 01dc00e..172c3f7 100644
--- a/server/object.h
+++ b/server/object.h
@@ -186,6 +186,7 @@
/* registry functions */
+extern unsigned int get_prefix_cpu_mask(void);
extern void init_registry(void);
extern void flush_registry(void);
diff --git a/server/registry.c b/server/registry.c
index 7f78209..483b064 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -1641,6 +1641,34 @@
return p;
}
+/* get the cpu architectures that can be supported in the current prefix */
+unsigned int get_prefix_cpu_mask(void)
+{
+ /* Allowed server/client/prefix combinations:
+ *
+ * prefix
+ * 32 64
+ * server +------+------+ client
+ * | ok | fail | 32
+ * 32 +------+------+---
+ * | fail | fail | 64
+ * ---+------+------+---
+ * | ok | ok | 32
+ * 64 +------+------+---
+ * | fail | ok | 64
+ * ---+------+------+---
+ */
+ switch (prefix_type)
+ {
+ case PREFIX_64BIT:
+ /* 64-bit prefix requires 64-bit server */
+ return sizeof(void *) > sizeof(int) ? ~0 : 0;
+ case PREFIX_32BIT:
+ default:
+ return ~CPU_64BIT_MASK; /* only 32-bit cpus supported on 32-bit prefix */
+ }
+}
+
/* registry initialisation */
void init_registry(void)
{
diff --git a/server/thread.c b/server/thread.c
index 1c3e5bb..c4deb68 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -1098,6 +1098,7 @@
/* initialize a new thread */
DECL_HANDLER(init_thread)
{
+ unsigned int prefix_cpu_mask = get_prefix_cpu_mask();
struct process *process = current->process;
int reply_fd = thread_get_inflight_fd( current, req->reply_fd );
int wait_fd = thread_get_inflight_fd( current, req->wait_fd );
@@ -1134,9 +1135,12 @@
if (!process->peb) /* first thread, initialize the process too */
{
- if (!CPU_FLAG(req->cpu) || !(supported_cpus & CPU_FLAG(req->cpu)))
+ if (!CPU_FLAG(req->cpu) || !(supported_cpus & prefix_cpu_mask & CPU_FLAG(req->cpu)))
{
- set_error( STATUS_NOT_SUPPORTED );
+ if (!(supported_cpus & CPU_64BIT_MASK))
+ set_error( STATUS_NOT_SUPPORTED );
+ else
+ set_error( STATUS_NOT_REGISTRY_FILE ); /* server supports it but not the prefix */
return;
}
process->unix_pid = current->unix_pid;
@@ -1163,7 +1167,7 @@
reply->tid = get_thread_id( current );
reply->version = SERVER_PROTOCOL_VERSION;
reply->server_start = server_start_time;
- reply->all_cpus = supported_cpus;
+ reply->all_cpus = supported_cpus & prefix_cpu_mask;
return;
error: