summaryrefslogtreecommitdiffstats
path: root/devel/ltrace/patches/0001-Fix-fetching-of-system-call-arguments-on-i386.patch
blob: 6617f5b4ea8a655563b22504cd92af5638a083a5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
From 5069ef8f498e5189de0789d79485f39b76c621d4 Mon Sep 17 00:00:00 2001
From: Petr Machata <pmachata@redhat.com>
Date: Thu, 24 Oct 2013 14:45:30 +0200
Subject: [PATCH] Fix fetching of system call arguments on i386

Signed-off-by: Ismael Luceno <ismael@iodev.co.uk>
---
 sysdeps/linux-gnu/x86/fetch.c                | 54 +++++++++++++++-----
 1 file changed, 43 insertions(+), 11 deletions(-)

diff --git a/sysdeps/linux-gnu/x86/fetch.c b/sysdeps/linux-gnu/x86/fetch.c
index a3b9eb7d5f1e..6868101ccea0 100644
--- a/sysdeps/linux-gnu/x86/fetch.c
+++ b/sysdeps/linux-gnu/x86/fetch.c
@@ -61,6 +61,7 @@ struct fetch_context
	arch_addr_t stack_pointer;
	size_t ireg;	/* Used-up integer registers.  */
	size_t freg;	/* Used-up floating registers.  */
+	int machine;

	union {
		struct {
@@ -238,21 +239,42 @@ allocate_integer(struct fetch_context *context, struct value *valuep,

	case POOL_SYSCALL:
 #ifdef __x86_64__
-		switch (context->ireg) {
-			HANDLE(0, rdi);
-			HANDLE(1, rsi);
-			HANDLE(2, rdx);
-			HANDLE(3, r10);
-			HANDLE(4, r8);
-			HANDLE(5, r9);
-		default:
-			assert(!"More than six syscall arguments???");
-			abort();
+		if (context->machine == EM_X86_64) {
+			switch (context->ireg) {
+				HANDLE(0, rdi);
+				HANDLE(1, rsi);
+				HANDLE(2, rdx);
+				HANDLE(3, r10);
+				HANDLE(4, r8);
+				HANDLE(5, r9);
+			default:
+				assert(!"More than six syscall arguments???");
+				abort();
+			}
		}
+#endif
+		if (context->machine == EM_386) {
+
+#ifdef __x86_64__
+# define HANDLE32(NUM, WHICH) HANDLE(NUM, r##WHICH)
 #else
-		i386_unreachable();
+# define HANDLE32(NUM, WHICH) HANDLE(NUM, e##WHICH)
 #endif

+			switch (context->ireg) {
+				HANDLE32(0, bx);
+				HANDLE32(1, cx);
+				HANDLE32(2, dx);
+				HANDLE32(3, si);
+				HANDLE32(4, di);
+				HANDLE32(5, bp);
+			default:
+				assert(!"More than six syscall arguments???");
+				abort();
+			}
+#undef HANDLE32
+		}
+
	case POOL_RETVAL:
		switch (context->ireg) {
 #ifdef __x86_64__
@@ -572,6 +594,15 @@ arch_fetch_arg_next_32(struct fetch_context *context, enum tof type,
	size_t sz = type_sizeof(proc, info);
	if (sz == (size_t)-1)
		return -1;
+	if (value_reserve(valuep, sz) == NULL)
+		return -1;
+
+	if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
+		int cls = allocate_integer(context, valuep,
+					   sz, 0, POOL_SYSCALL);
+		assert(cls == CLASS_INTEGER);
+		return 0;
+	}

	allocate_stack_slot(context, valuep, sz, 0, 4);

@@ -704,6 +735,7 @@ arch_fetch_arg_init(enum tof type, struct process *proc,
	struct fetch_context *ctx = malloc(sizeof(*ctx));
	if (ctx == NULL)
		return NULL;
+	ctx->machine = proc->e_machine;

	assert(type != LT_TOF_FUNCTIONR
	       && type != LT_TOF_SYSCALLR);
--
2.23.0