aboutsummaryrefslogtreecommitdiffstats
path: root/exec
diff options
context:
space:
mode:
authorPo Lu2025-04-15 16:14:14 +0800
committerPo Lu2025-04-15 16:17:14 +0800
commit5bf86e2be0693c579a43759fd1da1651344d401e (patch)
tree689475ec3fc7632cdf63a8796583bcb62f56f878 /exec
parentc3fe19aab90c3da68e9a8a48dbfb011317041d1a (diff)
downloademacs-5bf86e2be0693c579a43759fd1da1651344d401e.tar.gz
emacs-5bf86e2be0693c579a43759fd1da1651344d401e.zip
Port recent Android changes to mips64el
* exec/config-mips.m4.in (DADDI2, DADDI3): Disable at-clobbering by assembler macros expressly. * exec/loader-mips64el.s: Adapt from loader-mipsel.s. * exec/configure.ac (exec_cv_as_daddi): Properly escape reg names. * exec/exec.c (struct exec_jump_command, exec_0): Don't define or set `fpu_mode' if __LP64__. * exec/exec.h (struct exec_tracee): New field `callno'. * exec/trace.c (process_system_call): Always record the current system call number in TRACEE lest it should be required once it has been overwritten upon the syscall's completion. (seccomp_system_call): Likewise. (after_fork): Clear `tracee->callno'.
Diffstat (limited to 'exec')
-rw-r--r--exec/config-mips.m4.in12
-rw-r--r--exec/configure.ac12
-rw-r--r--exec/exec.c9
-rw-r--r--exec/exec.h4
-rw-r--r--exec/loader-mips64el.s317
-rw-r--r--exec/trace.c14
6 files changed, 253 insertions, 115 deletions
diff --git a/exec/config-mips.m4.in b/exec/config-mips.m4.in
index 1c9a4c293a6..4ab395ff2cb 100644
--- a/exec/config-mips.m4.in
+++ b/exec/config-mips.m4.in
@@ -38,7 +38,11 @@ define(`RESTORE', `ifelse(`@MIPS_N32@',`yes',` nop',` addi $sp, 32')')
38define(`FP', `ifelse(`@MIPS_N32@',`yes',`$s8',`$fp')') 38define(`FP', `ifelse(`@MIPS_N32@',`yes',`$s8',`$fp')')
39 39
40dnl For mips64. Some assemblers don't want to assemble `daddi'. 40dnl For mips64. Some assemblers don't want to assemble `daddi'.
41define(`DADDI2', `ifelse(`@DADDI_BROKEN@',`yes',` li $at, $2 41define(`DADDI2', `ifelse(`@DADDI_BROKEN@',`yes',`.set noat
42dadd $1, $1, $at',` daddi $1, $2')') 42li $at, $2
43define(`DADDI3', `ifelse(`@DADDI_BROKEN@',`yes',` li $at, $3 43dadd $1, $1, $at
44dadd $1, $2, $at',` daddi $1, $2, $3')') 44.set at',` daddi $1, $2')')
45define(`DADDI3', `ifelse(`@DADDI_BROKEN@',`yes',`.set noat
46li $at, $3
47dadd $1, $2, $at
48.set at',` daddi $1, $2, $3')')
diff --git a/exec/configure.ac b/exec/configure.ac
index d91049b8d7b..d462a25b9d9 100644
--- a/exec/configure.ac
+++ b/exec/configure.ac
@@ -455,12 +455,12 @@ AS_CASE([$host], [x86_64-*linux*],
455 .section text 455 .section text
456 .global __start 456 .global __start
457__start: 457__start:
458 li $t0, 0 458 li \$t0, 0
459 li $t1, 0 459 li \$t1, 0
460 daddi $t0, $t1, 1 460 daddi \$t0, \$t1, 1
461 daddi $t0, $t1, -1 461 daddi \$t0, \$t1, -1
462 daddi $t0, -1 462 daddi \$t0, -1
463 daddi $t0, 1 463 daddi \$t0, 1
464 464
465_ACEOF 465_ACEOF
466 $AS $ASFLAGS conftest.s -o conftest.$OBJEXT \ 466 $AS $ASFLAGS conftest.s -o conftest.$OBJEXT \
diff --git a/exec/exec.c b/exec/exec.c
index b9c3e4ec92a..b83e34bc1b2 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -231,10 +231,10 @@ struct exec_jump_command
231 /* The value of AT_BASE inside the aux vector. */ 231 /* The value of AT_BASE inside the aux vector. */
232 USER_WORD at_base; 232 USER_WORD at_base;
233 233
234#if defined __mips__ 234#if defined __mips__ && !defined __LP64__
235 /* The FPU mode to apply. Not used when !MIPS_NABI. */ 235 /* The FPU mode to apply. Not used when !MIPS_NABI. */
236 USER_WORD fpu_mode; 236 USER_WORD fpu_mode;
237#endif /* defined __mips__ */ 237#endif /* defined __mips__ && !defined __LP64__ */
238}; 238};
239 239
240 240
@@ -918,6 +918,7 @@ exec_0 (char *name, struct exec_tracee *tracee,
918 USER_WORD header_offset; 918 USER_WORD header_offset;
919 USER_WORD name_len, aligned_len; 919 USER_WORD name_len, aligned_len;
920 struct exec_jump_command jump; 920 struct exec_jump_command jump;
921 /* This also encompasses !__LP64__. */
921#if defined __mips__ && !defined MIPS_NABI 922#if defined __mips__ && !defined MIPS_NABI
922 int fpu_mode; 923 int fpu_mode;
923#endif /* defined __mips__ && !defined MIPS_NABI */ 924#endif /* defined __mips__ && !defined MIPS_NABI */
@@ -1130,9 +1131,9 @@ exec_0 (char *name, struct exec_tracee *tracee,
1130 fpu_mode = FP_FRE; 1131 fpu_mode = FP_FRE;
1131 1132
1132 jump.fpu_mode = fpu_mode; 1133 jump.fpu_mode = fpu_mode;
1133#elif defined __mips__ 1134#elif defined __mips__ && !defined __LP64__
1134 jump.fpu_mode = 0; 1135 jump.fpu_mode = 0;
1135#endif /* defined __mips__ && !defined MIPS_NABI */ 1136#endif /* defined __mips__ && defined MIPS_NABI && !defined __LP64__ */
1136 1137
1137 /* The offset used for at_phdr should be that of the first 1138 /* The offset used for at_phdr should be that of the first
1138 mapping. */ 1139 mapping. */
diff --git a/exec/exec.h b/exec/exec.h
index eee48dfe2ed..d420061ff87 100644
--- a/exec/exec.h
+++ b/exec/exec.h
@@ -152,6 +152,10 @@ struct exec_tracee
152 completion. */ 152 completion. */
153 USER_WORD sp; 153 USER_WORD sp;
154 154
155 /* ID of the system call that is pending completion. This value is
156 not available as the call number is overwritten on success. */
157 USER_WORD callno;
158
155 /* Name of the executable being run. */ 159 /* Name of the executable being run. */
156 char *exec_file; 160 char *exec_file;
157 161
diff --git a/exec/loader-mips64el.s b/exec/loader-mips64el.s
index 1493af3c309..be978d8b18b 100644
--- a/exec/loader-mips64el.s
+++ b/exec/loader-mips64el.s
@@ -15,36 +15,40 @@
15# You should have received a copy of the GNU General Public License 15# You should have received a copy of the GNU General Public License
16# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. 16# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
17 17
18 /* NOTE: this file is presently non-functional. */
19
20include(`config-mips.m4') 18include(`config-mips.m4')
21 19
20/* These "registers" alias a4-a7 and caution must be exercised not
21 to overwrite them when issuing system calls. */
22define(`T4', `$a4')
23define(`T5', `$a5')
24define(`T6', `$a6')
25define(`T7', `$a7')
26
22 .set noreorder # delay slots managed by hand 27 .set noreorder # delay slots managed by hand
23 .set noat # no assembler macros
24 .section .text 28 .section .text
25 .global __start 29 .global __start
26__start: 30__start:
27dnl li $v0, 5034 # SYS_nanosleep 31 ## li $v0, 5034 # SYS_nanosleep
28dnl dla $a0, .timespec # rqtp 32 ## dla $a0, timespec # rqtp
29dnl li $a1, 0 # rmtp 33 ## li $a1, 0 # rmtp
30dnl syscall # syscall 34 ## syscall # syscall
31 ld $s2, ($sp) # original stack pointer 35 ld $s6, ($sp) # original stack pointer
32 DADDI3( $s0, $sp, 16) # start of load area 36 DADDI3( $s0, $sp, 16) # start of load area
33 DADDI2( $sp, -16) # primary fd, secondary fd 37 DADDI2( $sp, -16) # primary fd, secondary fd
34 li $t0, -1 # secondary fd 38 li $t0, -1 # secondary fd
35 sd $t0, 8($sp) # initialize secondary fd 39 sd $t0, 8($sp) # initialize secondary fd
36.next_action: 40next_action:
37 ld $s1, ($s0) # action number 41 ld $s1, ($s0) # action number
38 andi $t0, $s1, 15 # t0 = action number & 15 42 andi $t0, $s1, 15 # t0 = action number & 15
39 beqz $t0, .open_file # open file? 43 beqz $t0, open_file # open file?
40 nop # delay slot 44 nop # delay slot
41 DADDI2( $t0, -3) # t0 -= 3 45 DADDI2( $t0, -3) # t0 -= 3
42 beqz $t0, .rest_of_exec # jump to code 46 beqz $t0, rest_of_exec # jump to code
43 nop # delay slot 47 nop # delay slot
44 li $t1, 1 48 li $t1, 1
45 beq $t0, $t1, .do_mmap_anon # anonymous mmap? 49 beq $t0, $t1, do_mmap_anon # anonymous mmap?
46 nop # delay slot 50 nop # delay slot
47.do_mmap: 51do_mmap:
48 ld $t0, 8($s0) # vm address 52 ld $t0, 8($s0) # vm address
49 ld $t1, 16($s0) # file_offset 53 ld $t1, 16($s0) # file_offset
50 ld $t2, 24($s0) # protection 54 ld $t2, 24($s0) # protection
@@ -52,10 +56,10 @@ dnl syscall # syscall
52 ld $v0, 40($s0) # flags 56 ld $v0, 40($s0) # flags
53 ld $v1, ($sp) # primary fd 57 ld $v1, ($sp) # primary fd
54 andi $s3, $s1, 16 # s1 & 16? 58 andi $s3, $s1, 16 # s1 & 16?
55 beqz $s3, .do_mmap_1 # secondary fd? 59 beqz $s3, do_mmap_1 # secondary fd?
56 nop # delay slot 60 nop # delay slot
57 ld $v1, 8($sp) # secondary fd 61 ld $v1, 8($sp) # secondary fd
58.do_mmap_1: 62do_mmap_1:
59 move $a0, $t0 # syscall arg 63 move $a0, $t0 # syscall arg
60 move $a1, $t3 # syscall arg 64 move $a1, $t3 # syscall arg
61 move $a2, $t2 # syscall arg 65 move $a2, $t2 # syscall arg
@@ -64,21 +68,21 @@ dnl syscall # syscall
64 move $a5, $t1 # syscall arg 68 move $a5, $t1 # syscall arg
65 li $v0, 5009 # SYS_mmap 69 li $v0, 5009 # SYS_mmap
66 syscall # syscall 70 syscall # syscall
67 bne $a3, $zero, .perror # perror? 71 bne $a3, $zero, perror # perror?
68 nop # delay slot 72 nop # delay slot
69 ld $t1, 48($s0) # clear 73 ld $t1, 48($s0) # clear
70 dadd $t0, $a0, $a1 # t0 = end of mapping 74 dadd $t0, $a0, $a1 # t0 = end of mapping
71 dsub $t1, $t0, $t1 # t1 = t0 - clear 75 dsub $t1, $t0, $t1 # t1 = t0 - clear
72.align: 76align:
73 beq $t0, $t1, .continue # already finished 77 beq $t0, $t1, continue # already finished
74 nop # delay slot 78 nop # delay slot
75 andi $t2, $t1, 7 # t1 & 7? 79 andi $t2, $t1, 7 # t1 & 7?
76 bnez $t2, .filld # start filling longs 80 bnez $t2, filld # start filling longs
77 nop # delay slot 81 nop # delay slot
78.filld: 82filld:
79 dsub $t2, $t0, $t1 # t2 = t0 - t1 83 dsub $t2, $t0, $t1 # t2 = t0 - t1
80 sltiu $t2, $t2, 64 # t2 < 64? 84 sltiu $t2, $t2, 64 # t2 < 64?
81 bne $t2, $zero, .fillb # fill bytes 85 bne $t2, $zero, fillb # fill bytes
82 nop # delay slot 86 nop # delay slot
83 sd $zero, ($t1) # zero doubleword 87 sd $zero, ($t1) # zero doubleword
84 DADDI2( $t1, 8) # next doubleword 88 DADDI2( $t1, 8) # next doubleword
@@ -96,140 +100,255 @@ dnl syscall # syscall
96 DADDI2( $t1, 8) # next doubleword 100 DADDI2( $t1, 8) # next doubleword
97 sd $zero, ($t1) # zero doubleword 101 sd $zero, ($t1) # zero doubleword
98 DADDI2( $t1, 8) # next doubleword 102 DADDI2( $t1, 8) # next doubleword
99 j .filld # fill either doubleword or byte 103 j filld # fill either doubleword or byte
100 nop # delay slot 104 nop # delay slot
101.fillb: 105fillb:
102 beq $t0, $t1, .continue # already finished? 106 beq $t0, $t1, continue # already finished?
103 nop # delay slot 107 nop # delay slot
104 sb $zero, ($t1) # clear byte 108 sb $zero, ($t1) # clear byte
105 DADDI2( $t1, 1) # t1++ 109 DADDI2( $t1, 1) # t1++
106.continue: 110continue:
107 DADDI2( $s0, 56) # s0 = next action 111 DADDI2( $s0, 56) # s0 = next action
108 j .next_action # next action 112 j next_action # next action
109 nop # delay slot 113 nop # delay slot
110.do_mmap_anon: 114do_mmap_anon:
111 ld $t0, 8($s0) # vm address 115 ld $t0, 8($s0) # vm address
112 ld $t1, 16($s0) # file_offset 116 ld $t1, 16($s0) # file_offset
113 ld $t2, 24($s0) # protection 117 ld $t2, 24($s0) # protection
114 ld $t3, 32($s0) # length 118 ld $t3, 32($s0) # length
115 ld $v0, 40($s0) # flags 119 ld $v0, 40($s0) # flags
116 li $v1, -1 # fd 120 dli $v1, -1 # fd
117 j .do_mmap_1 # do mmap 121 j do_mmap_1 # do mmap
118 nop # branch delay slot 122 nop # branch delay slot
119.open_file: 123open_file:
120 li $v0, 5002 # SYS_open 124 dli $v0, 5002 # SYS_open
121 DADDI3( $a0, $s0, 8) # start of name 125 DADDI3( $a0, $s0, 8) # start of name
122 move $a1, $zero # flags = O_RDONLY 126 move $a1, $zero # flags = O_RDONLY
123 move $a2, $zero # mode = 0 127 move $a2, $zero # mode = 0
124 syscall # syscall 128 syscall # syscall
125 bne $a3, $zero, .perror # perror 129 bne $a3, $zero, perror # perror
126 nop # delay slot 130 nop # delay slot
127 DADDI2( $s0, 8) # start of string 131 DADDI2( $s0, 8) # start of string
128 move $t3, $s0 # t3 = s0 132 move $t3, $s0 # t3 = s0
129.nextc: 133nextc:
130 lb $t0, ($s0) # load byte 134 lb $t0, ($s0) # load byte
131 DADDI2( $s0, 1) # s0++ 135 DADDI2( $s0, 1) # s0++
132 li $t1, 47 # directory separator `/' 136 dli $t1, 47 # directory separator `/'
133 bne $t0, $t1, .nextc1 # is separator char? 137 bne $t0, $t1, nextc1 # is separator char?
134 nop # delay slot 138 nop # delay slot
135 move $t3, $s0 # t3 = char past separator 139 move $t3, $s0 # t3 = char past separator
136.nextc1: 140nextc1:
137 bnez $t0, .nextc # next character? 141 bnez $t0, nextc # next character?
138 nop # delay slot 142 nop # delay slot
139 DADDI2( $s0, 7) # adjust for round 143 DADDI2( $s0, 7) # adjust for round
140 li $t2, -8 # t2 = -8 144 dli $t2, -8 # t2 = -8
141 and $s0, $s0, $t2 # mask for round 145 and $s0, $s0, $t2 # mask for round
142 andi $t0, $s1, 16 # t1 = s1 & 16 146 andi $t0, $s1, 16 # t1 = s1 & 16
143 move $t1, $sp # address of primary fd 147 move $t1, $sp # address of primary fd
144 beqz $t0, .primary # primary fd? 148 beqz $t0, primary # primary fd?
145 nop # delay slot 149 nop # delay slot
146 DADDI2( $t1, 8) # address of secondary fd 150 DADDI2( $t1, 8) # address of secondary fd
147 sd $v0, ($t1) # store fd 151 sd $v0, ($t1) # store fd
148 j .next_action # next action 152 j next_action # next action
149 nop # delay slot 153 nop # delay slot
150.primary: 154primary:
151 sd $v0, ($t1) # store fd 155 sd $v0, ($t1) # store fd
152 li $v0, 5153 # SYS_prctl 156 dli $v0, 5153 # SYS_prctl
153 li $a0, 15 # PR_SET_NAME 157 dli $a0, 15 # PR_SET_NAME
154 move $a1, $t3 # char past separator 158 move $a1, $t3 # char past separator
155 move $a2, $zero # a2 159 move $a2, $zero # a2
156 move $a3, $zero # a3 160 move $a3, $zero # a3
157 move $a4, $zero # a4 161 move $a4, $zero # a4
158 move $a5, $zero # a5 162 move $a5, $zero # a5
159 syscall # syscall 163 syscall # syscall
160 j .next_action # next action 164 j next_action # next action
161 nop # delay slot 165 nop # delay slot
162.perror: 166perror:
163 move $a0, $v0 # errno 167 move $a0, $v0 # errno
164 li $v0, 5058 # SYS_exit 168 dli $v0, 5058 # SYS_exit
165 syscall # syscall 169 syscall # syscall
166.rest_of_exec: 170rest_of_exec:
167 move $s1, $s2 # original SP 171 move $s1, $s6 # original SP
168 ld $t0, ($s1) # argc 172 ld $t0, ($s1) # argc
169 dsll $t0, $t0, 3 # argc *= 8 173 dsll $t0, $t0, 3 # argc *= 8
170 DADDI2( $t0, 16) # argc += 16 174 DADDI2( $t0, 16) # argc += 16
171 dadd $s1, $s1, $t0 # s1 = start of envp 175 dadd $s1, $s1, $t0 # s1 = start of envp
172.skipenv: 176skip_environ:
173 ld $t0, ($s1) # t0 = *s1 177 /* Locate the auxiliary vector. */
174 DADDI2( $s1, 8) # s1++ 1781: ld $t0, ($s1) # t0 = *s1
175 bne $t0, $zero, .skipenv # skip again 179 bnez $t0, 1b # skip environment entry
176 nop # delay slot 180 daddi $s1, $s1, 8 # s1++
177 dla $t3, .auxvtab # address of auxv table 181 move $s2, $s1 # s2 = end of environment
178.one_auxv: 1821: ld $t0, ($s1) # t0 = s1->a_type
179 ld $t0, ($s1) # t0 = auxv type 183 bnez $t0, 1b # skip auxiliary vector entry
180 li $t1, 10 # t1 = 10 184 daddi $s1, $s1, 16 # (Elf64_auxv_t *) s1++
181 beqz $t0, .finish # is AT_IGNORE? 185 /* Decide how many bytes must be copied and where to
182 nop # delay slot 186 save the file name. Move the stack pointer to a safe
183 sltu $t1, $t0, $t1 # t1 = t0 < num offsets 187 position below any data that must be preserved. */
184 beqz $t1, .next # next auxv 188 ld $t1, 56($s0) # length of string
185 nop # delay slot 189 DADDI2( $t1, 1)
186 dsll $t1, $t0, 2 # t1 = t0 * 4 190 DADDI3( $t2, $s0, 64) # pointer to string
187 dadd $t1, $t3, $t1 # t1 = .auxvtab + t1 191 dsub $t3, $s1, $s6 # number of bytes in vectors
188 lw $t2, ($t1) # t2 = *t1 192 dsub $t0, $s1, $t1 # position of string
189 beqz $t2, .next # skip auxv 193 and $t0, $t0, -16 # align value
190 nop # delay slot 194 dsub $t3, $t0, $t3 # position of argc
191 dadd $t2, $s0, $t2 # t2 = s0 + t2 195 and $t3, $t3, -16 # align value
192 ld $t2, ($t2) # t2 = *t2 196 /* Move the stack pointer and save required information.
193 sd $t2, 8($s1) # set auxv value 197 8($fp) = secondary/interpreter fd.
194.next: 198 0($fp) = primary/executable fd.
195 DADDI2( $s1, 16) # next auxv 199 -8($fp) = cmd->entry
196 j .one_auxv # next auxv 200 -16($fp) = cmd->at_entry
197 nop # delay slot 201 -24($fp) = cmd->at_phent
198.finish: 202 -32($fp) = cmd->at_phnum
199 ld $t0, 8($sp) # secondary fd 203 -40($fp) = cmd->at_phdr
204 -48($fp) = cmd->at_base
205 $sp = copy of string. */
206 move T4, $sp # current sp
207 dsub T5, $t3, $sp # new argc - current sp
208 blt T5, 16, 1f # more than two slots apart
209 dadd $sp, $t3, -16 # $sp = two slots below new argc
210 j 2f # skip copying fds
211 move $sp, T4 # retain current sp
2121: ld T5, (T4) # old primary fd
213 ld T5, ($sp) # save the same
214 ld T5, 8(T4) # old interpreter fd
215 sd T5, 8($sp) # save the same
2162: move $fp, $sp # set base pointer
217 DADDI2( $sp, -48) # command data
218 ld T5, 8($s0) # entry
219 ld T6, 16($s0) # at_entry
220 ld T7, 24($s0) # at_phent
221 ld $t8, 32($s0) # at_phnum
222 sd T5, -8($fp) # save entry
223 ld T5, 40($s0) # at_phdr
224 sd T6, -16($fp) # save at_entry
225 ld T6, 48($s0) # at_base
226 sd T7, -24($fp) # save at_phent
227 sd $t8, -32($fp) # save at_phnum
228 sd T5, -40($fp) # save at_phdr
229 sd T6, -48($fp) # save at_base
230 dsub $sp, $sp, $t1 # space for string
231 /* Save the input string. */
232 dadd T5, $t2, $t1 # end of source ($t2)
233 move T6, $sp # dst
234 move $s0, $t1 # $s0 = length of string
235 /* src = $t2, dst = T6 */
236 bgeu $t2, T5, 2f # there already?
237 nop
2381: lb $t1, ($t2) # $t1 = *$t2
239 DADDI2( $t2, 1) # $t2++
240 DADDI2( T6, 1) # $t6++
241 bltu $t2, T5, 1b
242 sb $t1, -1(T6) # *(T6 - 1) = $t1
2432: move $s3, $sp # copy of string
244 and $sp, $sp, -16 # align stack
245copy_env_and_args:
246 /* Copy argc, argv, and the environment array.
247 T4 = destination, T5 = src, $s2 = src_end */
248 move T4, $t3 # destination of argc
249 move T5, $s6 # original SP
250 bgeu T5, $s2, 2f # there already?
251 nop
2521: ld $t1, (T5) # $t1 = *src
253 DADDI2( T5, 8) # src++
254 DADDI2( T4, 8) # dst++
255 bltu T5, $s2, 1b # src < src_end
256 sd $t1, -8(T4) # *(dst - 8) = $t1
257copy_auxv:
258 /* T4 = destination, T5 = first auxval. */
2592: ld $t1, (T5) # a_type
260 ld $t2, 8(T5) # a_un.a_val
261 DADDI2( T4, 16) # (Elf64_auxv_t *) dst++
262 DADDI2( T5, 16) # (Elf64_auxv_t *) src
263 beqz $t1, 8f # AT_NULL
264 li T6, 3
265 beq $t1, T6, 1f # AT_PHDR
266 li T6, 4
267 beq $t1, T6, 2f # AT_PHENT
268 li T6, 5
269 beq $t1, T6, 3f # AT_PHNUM
270 li T6, 9
271 beq $t1, T6, 4f # AT_ENTRY
272 li T6, 7
273 beq $t1, T6, 5f # AT_BASE
274 li T6, 31
275 beq $t1, T6, 6f # AT_EXECFN
276 nop
277 b 7f
278 nop
2791: b 7f
280 ld $t2, -40($fp)
2812: b 7f
282 ld $t2, -24($fp)
2833: b 7f
284 ld $t2, -32($fp)
2854: b 7f
286 ld $t2, -16($fp)
2875: b 7f
288 ld $t2, -48($fp)
2896: b 7f
290 move $t2, $t0
2917: sd $t1, -16(T4) # dst->a_type
292 j copy_auxv
293 sd $t2, -8(T4) # dst->a_un.a_val
294 /* Copy the final element. */
2958: sd $t1, -16(T4) # dst->a_type
296 sd $t2, -8(T4) # dst->a_un.a_val
297finish:
298 /* Copy the string to its position in auxv
299 (src = $s3, dst = $t0). */
300 dadd $t1, $s3, $s0 # src end
301 bgeu $s3, $t1, 2f # there already?
302 nop
3031: lb $t2, ($s3) # c = *src
304 DADDI2( $s3, 1) # src++
305 DADDI2( $t0, 1) # dst++
306 bltu $s3, $t1, 1b
307 sb $t2, -1($t0) # *(dst - 1) = c
308 /* Save variables. */
3092: move $s6, $t3 # new stack pointer
310 ld $t0, 8($fp) # secondary fd
200 li $t1, -1 # t1 = -1 311 li $t1, -1 # t1 = -1
201 ld $s1, ($sp) # s1 = primary fd 312 ld $s1, ($fp) # s1 = primary fd
313 beq $t0, $t2, finish1 # secondary fd set?
202 li $v0, 5003 # SYS_close 314 li $v0, 5003 # SYS_close
203 beq $t0, $t2, .finish1 # secondary fd set?
204 nop # delay slot
205 move $a0, $t0 # secondary fd 315 move $a0, $t0 # secondary fd
206 syscall # syscall 316 syscall # syscall
207 li $v0, 5003 # SYS_close 317 li $v0, 5003 # SYS_close
208.finish1: 318finish1:
209 move $a0, $s1 # primary fd 319 move $a0, $s1 # primary fd
210 syscall # syscall 320 syscall # syscall
211.jump: 321jump:
212 move $v0, $zero # rtld_fini 322 move $v0, $zero # rtld_fini
213 ld $t0, 8($s0) # entry 323 ld $t9, -8($fp) # entry
214 move $sp, $s2 # restore stack pointer, delay slot 324 move $sp, $s6 # restore stack pointer, delay slot
215 jr $t0 # enter 325 /* Clear at least one page's worth of stack. glibc on mipsel
216 nop # delay slot 326 copies certain fields from the stack to the `link_map'
327 structure representing ld.so, which are not subsequently
328 replaced if otherwise than zero.
217 329
218.auxvtab: 330 XXX: report this glibc bug? */
219 .long 0 # 0 331 DADDI3( $v0, $sp, -4096)
220 .long 0 # 1 332 and $v0, $v0, -4095
221 .long 0 # 2 3331: sd $zero, ($v0) # copy 32 byte blocks
222 .long 40 # 3 AT_PHDR 334 sd $zero, 8($v0)
223 .long 24 # 4 AT_PHENT 335 sd $zero, 16($v0)
224 .long 32 # 5 AT_PHNUM 336 sd $zero, 24($v0)
225 .long 0 # 6 337 DADDI2( $v0, 32)
226 .long 48 # 7 AT_BASE 338 dsub $t0, $sp, $v0 # remainder
227 .long 0 # 8 339 bge $t0, 32, 1b # test remainder
228 .long 16 # 9 AT_ENTRY 340 nop # copy 4 byte blocks
341 beqz $t0, 2f
342 nop
3431: DADDI2( $v0, 4)
344 bltu $v0, $sp, 1b
345 sw $zero, -4($v0)
3462: jr $t9 # enter
347 nop # delay slot
229 348
230.timespec: 349## timespec:
231 .quad 10 350## .quad 10
232 .quad 10 351## .quad 10
233 352
234# Local Variables: 353# Local Variables:
235# asm-comment-char: ?# 354# asm-comment-char: ?#
diff --git a/exec/trace.c b/exec/trace.c
index b0ec602d821..2421785a80a 100644
--- a/exec/trace.c
+++ b/exec/trace.c
@@ -1246,7 +1246,11 @@ process_system_call (struct exec_tracee *tracee)
1246 set, this must be exec, whatever the value of SYSCALL_NUM_REG, 1246 set, this must be exec, whatever the value of SYSCALL_NUM_REG,
1247 which is erased when exec loads another image. */ 1247 which is erased when exec loads another image. */
1248 1248
1249 callno = (!tracee->exec_data ? regs.SYSCALL_NUM_REG : EXEC_SYSCALL); 1249 callno = (!tracee->exec_data
1250 ? (!tracee->waiting_for_syscall
1251 ? regs.SYSCALL_NUM_REG : tracee->callno)
1252 : EXEC_SYSCALL);
1253 tracee->callno = callno;
1250 switch (callno) 1254 switch (callno)
1251 { 1255 {
1252 case EXEC_SYSCALL: 1256 case EXEC_SYSCALL:
@@ -1653,6 +1657,11 @@ seccomp_system_call (struct exec_tracee *tracee)
1653 1657
1654 /* Now dispatch based on the system call. */ 1658 /* Now dispatch based on the system call. */
1655 callno = regs.SYSCALL_NUM_REG; 1659 callno = regs.SYSCALL_NUM_REG;
1660
1661 /* Record the call number, which may be required if one of the
1662 following handlers should arrange for process_system_call to
1663 intercede after the system call completes. */
1664 tracee->callno = callno;
1656 switch (callno) 1665 switch (callno)
1657 { 1666 {
1658 case EXEC_SYSCALL: 1667 case EXEC_SYSCALL:
@@ -1715,7 +1724,7 @@ seccomp_system_call (struct exec_tracee *tracee)
1715 if (rc < 0) 1724 if (rc < 0)
1716 return; 1725 return;
1717 1726
1718 tracee->waiting_for_syscall = !tracee->waiting_for_syscall; 1727 tracee->waiting_for_syscall = true;
1719 break; 1728 break;
1720 1729
1721 default: 1730 default:
@@ -2033,6 +2042,7 @@ after_fork (pid_t pid)
2033 return 1; 2042 return 1;
2034 2043
2035 tracee->pid = pid; 2044 tracee->pid = pid;
2045 tracee->callno = 0;
2036 tracee->next = tracing_processes; 2046 tracee->next = tracing_processes;
2037 tracee->waiting_for_syscall = false; 2047 tracee->waiting_for_syscall = false;
2038 tracee->new_child = false; 2048 tracee->new_child = false;