2006-01-12 Roland McGrath <roland@redhat.com>
* defs.h [LINUXSPARC] (PERSONALITY0_WORDSIZE, PERSONALITY1_WORDSIZE):
New macros.
[SPARC64] (PERSONALITY2_WORDSIZE): New macro.
[X86_64] (PERSONALITY0_WORDSIZE, PERSONALITY1_WORDSIZE): New macros.
* syscall.c (PERSONALITY0_WORDSIZE): New macro if undefined.
(personality_wordsize): New variable.
(decode_subcall): Use it for size of argument words.
Fixes RH#174354.
diff --git a/defs.h b/defs.h
index a04b78f..1e715cf 100644
--- a/defs.h
+++ b/defs.h
@@ -194,9 +194,12 @@
#ifdef LINUXSPARC
#include <linux/a.out.h>
#include <asm/psr.h>
+#define PERSONALITY0_WORDSIZE 4
+#define PERSONALITY1_WORDSIZE 4
#undef SUPPORTED_PERSONALITIES
#if defined(SPARC64)
#define SUPPORTED_PERSONALITIES 3
+#define PERSONALITY2_WORDSIZE 8
#else
#define SUPPORTED_PERSONALITIES 2
#endif /* SPARC64 */
@@ -205,6 +208,8 @@
#ifdef X86_64
#undef SUPPORTED_PERSONALITIES
#define SUPPORTED_PERSONALITIES 2
+#define PERSONALITY0_WORDSIZE 8
+#define PERSONALITY1_WORDSIZE 4
#endif
#ifdef SVR4
diff --git a/syscall.c b/syscall.c
index f5ce8d1..22893a7 100644
--- a/syscall.c
+++ b/syscall.c
@@ -183,6 +183,19 @@
int current_personality;
+#ifndef PERSONALITY0_WORDSIZE
+# define PERSONALITY0_WORDSIZE sizeof(long)
+#endif
+const int personality_wordsize[SUPPORTED_PERSONALITIES] = {
+ PERSONALITY0_WORDSIZE,
+#if SUPPORTED_PERSONALITIES > 1
+ PERSONALITY1_WORDSIZE,
+#endif
+#if SUPPORTED_PERSONALITIES > 2
+ PERSONALITY2_WORDSIZE,
+#endif
+};;
+
int
set_personality(personality)
int personality;
@@ -628,8 +641,9 @@
int nsubcalls;
enum subcall_style style;
{
- long addr, mask, arg;
+ unsigned long addr, mask;
int i;
+ int size = personality_wordsize[current_personality];
switch (style) {
case shift_style:
@@ -649,10 +663,21 @@
tcp->scno = subcall + tcp->u_arg[0];
addr = tcp->u_arg[1];
for (i = 0; i < sysent[tcp->scno].nargs; i++) {
- if (umove(tcp, addr, &arg) < 0)
- arg = 0;
- tcp->u_arg[i] = arg;
- addr += sizeof(arg);
+ if (size == sizeof(int)) {
+ unsigned int arg;
+ if (umove(tcp, addr, &arg) < 0)
+ arg = 0;
+ tcp->u_arg[i] = arg;
+ }
+ else if (size == sizeof(long)) {
+ unsigned long arg;
+ if (umove(tcp, addr, &arg) < 0)
+ arg = 0;
+ tcp->u_arg[i] = arg;
+ }
+ else
+ abort();
+ addr += size;
}
tcp->u_nargs = sysent[tcp->scno].nargs;
break;