• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.text
2.global __clone
3.hidden __clone
4.type __clone, %function
5__clone:
6	# int clone(
7	#    fn,      a = r2
8	#    stack,   b = r3
9	#    flags,   c = r4
10	#    arg,     d = r5
11	#    ptid,    e = r6
12	#    tls,     f = *(r15+160)
13	#    ctid)    g = *(r15+168)
14	#
15	# pseudo C code:
16	# tid = syscall(SYS_clone,b,c,e,g,f);
17	# if (!tid) syscall(SYS_exit, a(d));
18	# return tid;
19
20	# preserve call-saved register used as syscall arg
21	stg  %r6, 48(%r15)
22
23	# create initial stack frame for new thread
24	nill %r3, 0xfff8
25	aghi %r3, -160
26	lghi %r0, 0
27	stg  %r0, 0(%r3)
28
29	# save fn and arg to child stack
30	stg  %r2,  8(%r3)
31	stg  %r5, 16(%r3)
32
33	# shuffle args into correct registers and call SYS_clone
34	lgr  %r2, %r3
35	lgr  %r3, %r4
36	lgr  %r4, %r6
37	lg   %r5, 168(%r15)
38	lg   %r6, 160(%r15)
39	svc  120
40
41	# restore call-saved register
42	lg   %r6, 48(%r15)
43
44	# if error or if we're the parent, return
45	ltgr %r2, %r2
46	bnzr %r14
47
48	# we're the child. call fn(arg)
49	lg   %r1,  8(%r15)
50	lg   %r2, 16(%r15)
51	basr %r14, %r1
52
53	# call SYS_exit. exit code is already in r2 from fn return value
54	svc  1
55