1#include "defs.h"
2
3#if defined I386 || defined X86_64 || defined X32
4
5# include <asm/ldt.h>
6
7void
8print_user_desc(struct tcb *tcp, long addr)
9{
10	struct user_desc desc;
11
12	if (umove(tcp, addr, &desc) < 0) {
13		tprintf("%lx", addr);
14		return;
15	}
16
17	if (!verbose(tcp)) {
18		tprintf("{entry_number:%d, ...}", desc.entry_number);
19		return;
20	}
21
22	tprintf("{entry_number:%d, "
23		"base_addr:%#08x, "
24		"limit:%d, "
25		"seg_32bit:%d, "
26		"contents:%d, "
27		"read_exec_only:%d, "
28		"limit_in_pages:%d, "
29		"seg_not_present:%d, "
30		"useable:%d}",
31		desc.entry_number,
32		desc.base_addr,
33		desc.limit,
34		desc.seg_32bit,
35		desc.contents,
36		desc.read_exec_only,
37		desc.limit_in_pages,
38		desc.seg_not_present,
39		desc.useable);
40}
41
42SYS_FUNC(modify_ldt)
43{
44	if (entering(tcp)) {
45		tprintf("%ld, ", tcp->u_arg[0]);
46		if (tcp->u_arg[1] == 0
47		    || tcp->u_arg[2] != sizeof(struct user_desc)) {
48			tprintf("%lx", tcp->u_arg[1]);
49		} else {
50			print_user_desc(tcp, tcp->u_arg[1]);
51		}
52		tprintf(", %lu", tcp->u_arg[2]);
53	}
54	return 0;
55}
56
57SYS_FUNC(set_thread_area)
58{
59	if (entering(tcp)) {
60		print_user_desc(tcp, tcp->u_arg[0]);
61	} else {
62		struct user_desc desc;
63
64		if (syserror(tcp) || umove(tcp, tcp->u_arg[0], &desc) < 0) {
65			/* returned entry_number is not available */
66		} else {
67			static char outstr[32];
68
69			sprintf(outstr, "entry_number:%d", desc.entry_number);
70			tcp->auxstr = outstr;
71			return RVAL_STR;
72		}
73	}
74	return 0;
75}
76
77SYS_FUNC(get_thread_area)
78{
79	if (exiting(tcp)) {
80		if (syserror(tcp))
81			tprintf("%lx", tcp->u_arg[0]);
82		else
83			print_user_desc(tcp, tcp->u_arg[0]);
84	}
85	return 0;
86}
87
88#endif /* I386 || X86_64 || X32 */
89
90#if defined(M68K) || defined(MIPS)
91SYS_FUNC(set_thread_area)
92{
93	if (entering(tcp))
94		tprintf("%#lx", tcp->u_arg[0]);
95	return 0;
96
97}
98#endif
99
100#if defined(M68K)
101SYS_FUNC(get_thread_area)
102{
103	return RVAL_HEX;
104}
105#endif
106