2 register void *__thread_self
__asm ("g7");
13 # define INTERNAL_SYSCALL_DECL(err) do { } while (0)
14 # define INTERNAL_SYSCALL(name, err, nr, args...) \
16 register unsigned int resultvar; \
18 "movl %1, %%eax\n\t" \
21 : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
23 # define INTERNAL_SYSCALL_ERROR_P(val, err) \
24 ((unsigned int) (val) >= 0xfffff001u)
26 # define ASMFMT_1(arg1) \
28 # define ASMFMT_2(arg1, arg2) \
29 , "b" (arg1), "c" (arg2)
30 # define ASMFMT_3(arg1, arg2, arg3) \
31 , "b" (arg1), "c" (arg2), "d" (arg3)
32 #elif defined __x86_64__
33 # define INTERNAL_SYSCALL_DECL(err) do { } while (0)
34 # define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
36 unsigned long resultvar; \
37 LOAD_ARGS_##nr (args) \
42 : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \
44 # define INTERNAL_SYSCALL(name, err, nr, args...) \
45 INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
46 # define INTERNAL_SYSCALL_ERROR_P(val, err) \
47 ((unsigned long) (val) >= -4095L)
48 # define LOAD_ARGS_0()
51 # define LOAD_ARGS_1(a1) \
52 long int __arg1 = (long) (a1); \
54 # define LOAD_REGS_1 \
55 register long int _a1 asm ("rdi") = __arg1; \
57 # define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1)
58 # define LOAD_ARGS_2(a1, a2) \
59 long int __arg2 = (long) (a2); \
61 # define LOAD_REGS_2 \
62 register long int _a2 asm ("rsi") = __arg2; \
64 # define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2)
65 # define LOAD_ARGS_3(a1, a2, a3) \
66 long int __arg3 = (long) (a3); \
68 # define LOAD_REGS_3 \
69 register long int _a3 asm ("rdx") = __arg3; \
71 # define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3)
72 #elif defined __powerpc__
73 # define INTERNAL_SYSCALL_DECL(err) long int err
74 # define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
76 register long int r0 __asm__ ("r0"); \
77 register long int r3 __asm__ ("r3"); \
78 register long int r4 __asm__ ("r4"); \
79 register long int r5 __asm__ ("r5"); \
80 register long int r6 __asm__ ("r6"); \
81 register long int r7 __asm__ ("r7"); \
82 register long int r8 __asm__ ("r8"); \
83 LOADARGS_##nr(name, args); \
84 __asm__ __volatile__ \
88 "=&r" (r3), "=&r" (r4), "=&r" (r5), \
89 "=&r" (r6), "=&r" (r7), "=&r" (r8) \
91 : "r9", "r10", "r11", "r12", \
92 "cr0", "ctr", "memory"); \
96 # define INTERNAL_SYSCALL(name, err, nr, args...) \
97 INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
98 # define INTERNAL_SYSCALL_ERROR_P(val, err) \
99 ((void) (val), __builtin_expect ((err) & (1 << 28), 0))
100 # define LOADARGS_0(name, dummy) \
102 # define LOADARGS_1(name, __arg1) \
103 long int arg1 = (long int) (__arg1); \
104 LOADARGS_0(name, 0); \
106 # define LOADARGS_2(name, __arg1, __arg2) \
107 long int arg2 = (long int) (__arg2); \
108 LOADARGS_1(name, __arg1); \
110 # define LOADARGS_3(name, __arg1, __arg2, __arg3) \
111 long int arg3 = (long int) (__arg3); \
112 LOADARGS_2(name, __arg1, __arg2); \
114 # define ASM_INPUT_0 "0" (r0)
115 # define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
116 # define ASM_INPUT_2 ASM_INPUT_1, "2" (r4)
117 # define ASM_INPUT_3 ASM_INPUT_2, "3" (r5)
118 #elif defined __ia64__
119 # define DO_INLINE_SYSCALL_NCS(name, nr, args...) \
120 LOAD_ARGS_##nr (args) \
121 register long _r8 asm ("r8"); \
122 register long _r10 asm ("r10"); \
123 register long _r15 asm ("r15") = name; \
126 __asm __volatile ("break 0x100000;;" \
127 : "=r" (_r8), "=r" (_r10), "=r" (_r15) \
129 : "2" (_r15) ASM_ARGS_##nr \
130 : "memory" ASM_CLOBBERS_##nr); \
132 # define INTERNAL_SYSCALL_DECL(err) long int err
133 # define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
135 DO_INLINE_SYSCALL_NCS (name, nr, args) \
138 # define INTERNAL_SYSCALL(name, err, nr, args...) \
139 INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
140 # define INTERNAL_SYSCALL_ERROR_P(val, err) (err == -1)
141 # define LOAD_ARGS_0()
143 # define LOAD_ARGS_1(a1) \
144 long _arg1 = (long) (a1); \
146 # define LOAD_REGS_1 \
147 register long _out0 asm ("out0") = _arg1; \
149 # define LOAD_ARGS_2(a1, a2) \
150 long _arg2 = (long) (a2); \
152 # define LOAD_REGS_2 \
153 register long _out1 asm ("out1") = _arg2; \
155 # define LOAD_ARGS_3(a1, a2, a3) \
156 long _arg3 = (long) (a3); \
158 # define LOAD_REGS_3 \
159 register long _out2 asm ("out2") = _arg3; \
161 # define ASM_OUTARGS_0
162 # define ASM_OUTARGS_1 ASM_OUTARGS_0, "=r" (_out0)
163 # define ASM_OUTARGS_2 ASM_OUTARGS_1, "=r" (_out1)
164 # define ASM_OUTARGS_3 ASM_OUTARGS_2, "=r" (_out2)
166 # define ASM_ARGS_1 ASM_ARGS_0, "3" (_out0)
167 # define ASM_ARGS_2 ASM_ARGS_1, "4" (_out1)
168 # define ASM_ARGS_3 ASM_ARGS_2, "5" (_out2)
169 # define ASM_CLOBBERS_0 ASM_CLOBBERS_1, "out0"
170 # define ASM_CLOBBERS_1 ASM_CLOBBERS_2, "out1"
171 # define ASM_CLOBBERS_2 ASM_CLOBBERS_3, "out2"
172 # define ASM_CLOBBERS_3 ASM_CLOBBERS_4, "out3"
173 # define ASM_CLOBBERS_4 ASM_CLOBBERS_5, "out4"
174 # define ASM_CLOBBERS_5 ASM_CLOBBERS_6, "out5"
175 # define ASM_CLOBBERS_6_COMMON , "out6", "out7", \
176 /* Non-stacked integer registers, minus r8, r10, r15. */ \
177 "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \
178 "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \
179 "r28", "r29", "r30", "r31", \
180 /* Predicate registers. */ \
181 "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \
182 /* Non-rotating fp registers. */ \
183 "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
184 /* Branch registers. */ \
186 # define ASM_CLOBBERS_6 ASM_CLOBBERS_6_COMMON , "b7"
187 #elif defined __s390__
188 # define INTERNAL_SYSCALL_DECL(err) do { } while (0)
189 # define INTERNAL_SYSCALL_DIRECT(name, err, nr, args...) \
191 DECLARGS_##nr(args) \
192 register long _ret asm("2"); \
196 : "i" (__NR_##name) ASMFMT_##nr \
199 # define INTERNAL_SYSCALL_SVC0(name, err, nr, args...) \
201 DECLARGS_##nr(args) \
202 register unsigned long _nr asm("1") = (unsigned long)(__NR_##name); \
203 register long _ret asm("2"); \
207 : "d" (_nr) ASMFMT_##nr \
210 # define INTERNAL_SYSCALL(name, err, nr, args...) \
211 (((__NR_##name) < 256) ? \
212 INTERNAL_SYSCALL_DIRECT(name, err, nr, args) : \
213 INTERNAL_SYSCALL_SVC0(name, err,nr, args))
214 # define INTERNAL_SYSCALL_ERROR_P(val, err) \
215 ((unsigned long) (val) >= -4095UL)
216 # define DECLARGS_0()
217 # define DECLARGS_1(arg1) \
218 register unsigned long gpr2 asm ("2") = (unsigned long)(arg1);
219 # define DECLARGS_2(arg1, arg2) \
221 register unsigned long gpr3 asm ("3") = (unsigned long)(arg2);
222 # define DECLARGS_3(arg1, arg2, arg3) \
223 DECLARGS_2(arg1, arg2) \
224 register unsigned long gpr4 asm ("4") = (unsigned long)(arg3);
226 # define ASMFMT_1 , "0" (gpr2)
227 # define ASMFMT_2 , "0" (gpr2), "d" (gpr3)
228 # define ASMFMT_3 , "0" (gpr2), "d" (gpr3), "d" (gpr4)
229 #elif defined __sparc__
231 # define __INTERNAL_SYSCALL_STRING \
234 " sub %%g0, %%o0, %%o0;" \
236 # define __SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6", \
237 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
238 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
239 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
240 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
243 # define __INTERNAL_SYSCALL_STRING \
245 "bcs,a,pt %%xcc, 1f;" \
246 " sub %%g0, %%o0, %%o0;" \
248 # define __SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6", \
249 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
250 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
251 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
252 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
253 "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \
254 "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", \
257 #define INTERNAL_SYSCALL_DECL(err) do { } while (0)
258 #define INTERNAL_SYSCALL(name, err, nr, args...) \
259 inline_syscall##nr(__INTERNAL_SYSCALL_STRING, __NR_##name, args)
260 #define INTERNAL_SYSCALL_ERROR_P(val, err) \
261 ((unsigned long) (val) >= -515L)
262 # define inline_syscall0(string,name,dummy...) \
264 register long __o0 __asm__ ("o0"); \
265 register long __g1 __asm__ ("g1") = name; \
266 __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \
268 __SYSCALL_CLOBBERS); \
271 # define inline_syscall1(string,name,arg1) \
273 register long __o0 __asm__ ("o0") = (long)(arg1); \
274 register long __g1 __asm__ ("g1") = name; \
275 __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \
276 "0" (__g1), "1" (__o0) : \
277 __SYSCALL_CLOBBERS); \
280 # define inline_syscall2(string,name,arg1,arg2) \
282 register long __o0 __asm__ ("o0") = (long)(arg1); \
283 register long __o1 __asm__ ("o1") = (long)(arg2); \
284 register long __g1 __asm__ ("g1") = name; \
285 __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \
286 "0" (__g1), "1" (__o0), "r" (__o1) : \
287 __SYSCALL_CLOBBERS); \
290 # define inline_syscall3(string,name,arg1,arg2,arg3) \
292 register long __o0 __asm__ ("o0") = (long)(arg1); \
293 register long __o1 __asm__ ("o1") = (long)(arg2); \
294 register long __o2 __asm__ ("o2") = (long)(arg3); \
295 register long __g1 __asm__ ("g1") = name; \
296 __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \
297 "0" (__g1), "1" (__o0), "r" (__o1), \
299 __SYSCALL_CLOBBERS); \
302 #elif defined __alpha__
303 # define INTERNAL_SYSCALL(name, err_out, nr, args...) \
304 INTERNAL_SYSCALL1(name, err_out, nr, args)
305 # define INTERNAL_SYSCALL1(name, err_out, nr, args...) \
306 INTERNAL_SYSCALL_NCS(__NR_##name, err_out, nr, args)
307 # define INTERNAL_SYSCALL_NCS(name, err_out, nr, args...) \
309 long _sc_ret, _sc_err; \
310 inline_syscall##nr(name, args); \
314 # define INTERNAL_SYSCALL_DECL(err) long int err
315 # define INTERNAL_SYSCALL_ERROR_P(val, err) err
316 # define inline_syscall_clobbers \
317 "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", \
318 "$22", "$23", "$24", "$25", "$27", "$28", "memory"
319 # define inline_syscall_r0_asm
320 # define inline_syscall_r0_out_constraint "=v"
321 # define inline_syscall0(name, args...) \
323 register long _sc_0 inline_syscall_r0_asm; \
324 register long _sc_19 __asm__("$19"); \
327 __asm__ __volatile__ \
328 ("callsys # %0 %1 <= %2" \
329 : inline_syscall_r0_out_constraint (_sc_0), \
332 : inline_syscall_clobbers, \
333 "$16", "$17", "$18", "$20", "$21"); \
334 _sc_ret = _sc_0, _sc_err = _sc_19; \
336 # define inline_syscall1(name,arg1) \
338 register long _sc_0 inline_syscall_r0_asm; \
339 register long _sc_16 __asm__("$16"); \
340 register long _sc_19 __asm__("$19"); \
343 _sc_16 = (long) (arg1); \
344 __asm__ __volatile__ \
345 ("callsys # %0 %1 <= %2 %3" \
346 : inline_syscall_r0_out_constraint (_sc_0), \
347 "=r"(_sc_19), "=r"(_sc_16) \
348 : "0"(_sc_0), "2"(_sc_16) \
349 : inline_syscall_clobbers, \
350 "$17", "$18", "$20", "$21"); \
351 _sc_ret = _sc_0, _sc_err = _sc_19; \
353 # define inline_syscall2(name,arg1,arg2) \
355 register long _sc_0 inline_syscall_r0_asm; \
356 register long _sc_16 __asm__("$16"); \
357 register long _sc_17 __asm__("$17"); \
358 register long _sc_19 __asm__("$19"); \
361 _sc_16 = (long) (arg1); \
362 _sc_17 = (long) (arg2); \
363 __asm__ __volatile__ \
364 ("callsys # %0 %1 <= %2 %3 %4" \
365 : inline_syscall_r0_out_constraint (_sc_0), \
366 "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17) \
367 : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17) \
368 : inline_syscall_clobbers, \
369 "$18", "$20", "$21"); \
370 _sc_ret = _sc_0, _sc_err = _sc_19; \
372 # define inline_syscall3(name,arg1,arg2,arg3) \
374 register long _sc_0 inline_syscall_r0_asm; \
375 register long _sc_16 __asm__("$16"); \
376 register long _sc_17 __asm__("$17"); \
377 register long _sc_18 __asm__("$18"); \
378 register long _sc_19 __asm__("$19"); \
381 _sc_16 = (long) (arg1); \
382 _sc_17 = (long) (arg2); \
383 _sc_18 = (long) (arg3); \
384 __asm__ __volatile__ \
385 ("callsys # %0 %1 <= %2 %3 %4 %5" \
386 : inline_syscall_r0_out_constraint (_sc_0), \
387 "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17), \
389 : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), \
391 : inline_syscall_clobbers, "$20", "$21"); \
392 _sc_ret = _sc_0, _sc_err = _sc_19; \
396 char buffer
[32768], data
[32768];
401 readall (int fd
, void *buf
, size_t len
)
403 INTERNAL_SYSCALL_DECL (err
);
408 ret
= INTERNAL_SYSCALL (read
, err
, 3, fd
, buf
, n
);
409 if (INTERNAL_SYSCALL_ERROR_P (ret
, err
))
416 buf
= (char *) buf
+ ret
;
420 return ret
< 0 ? ret
: len
- n
;
424 writeall (int fd
, const void *buf
, size_t len
)
426 INTERNAL_SYSCALL_DECL (err
);
431 ret
= INTERNAL_SYSCALL (write
, err
, 3, fd
, buf
, n
);
432 if (INTERNAL_SYSCALL_ERROR_P (ret
, err
))
439 buf
= (const char *) buf
+ ret
;
443 return ret
< 0 ? ret
: len
- n
;
447 update (const char *filename
)
449 INTERNAL_SYSCALL_DECL (err
);
450 long int fd
= INTERNAL_SYSCALL (open
, err
, 2, filename
, O_RDONLY
);
451 if (INTERNAL_SYSCALL_ERROR_P (fd
, err
))
453 ssize_t ret
= readall (fd
, buffer
, sizeof (buffer
));
454 INTERNAL_SYSCALL (close
, err
, 1, fd
);
455 if (ret
<= 0 || (size_t) ret
== sizeof (buffer
))
457 /* Don't update the file unnecessarily. */
458 if ((size_t) ret
== datasize
&& memcmp (buffer
, data
, datasize
) == 0)
460 size_t len
= strlen (filename
);
461 char tempfilename
[len
+ sizeof (".tzupdate")];
462 memcpy (tempfilename
, filename
, len
);
463 memcpy (tempfilename
+ len
, ".tzupdate", sizeof (".tzupdate"));
465 fd
= INTERNAL_SYSCALL (open
, err
, 3, tempfilename
, O_WRONLY
| O_CREAT
| O_EXCL
, 0600);
466 if (INTERNAL_SYSCALL_ERROR_P (fd
, err
))
468 if (writeall (fd
, data
, datasize
) != datasize
)
471 INTERNAL_SYSCALL (unlink
, err
, 1, tempfilename
);
472 INTERNAL_SYSCALL (close
, err
, 1, fd
);
476 sret
= INTERNAL_SYSCALL (fchmod
, err
, 2, fd
, 0644);
477 if (INTERNAL_SYSCALL_ERROR_P (sret
, err
))
479 INTERNAL_SYSCALL (close
, err
, 1, fd
);
481 sret
= INTERNAL_SYSCALL (rename
, err
, 2, tempfilename
, filename
);
482 if (INTERNAL_SYSCALL_ERROR_P (sret
, err
))
483 INTERNAL_SYSCALL (unlink
, err
, 1, tempfilename
);
489 INTERNAL_SYSCALL_DECL (err
);
490 long int fd
= INTERNAL_SYSCALL (open
, err
, 2, "/etc/sysconfig/clock", O_RDONLY
);
491 if (INTERNAL_SYSCALL_ERROR_P (fd
, err
))
493 ssize_t ret
= readall (fd
, buffer
, sizeof (buffer
) - 1);
494 INTERNAL_SYSCALL (close
, err
, 1, fd
);
495 if (ret
<= 0 || (size_t) ret
== sizeof (buffer
) - 1)
500 while (*p
== ' ' || *p
== '\t') p
++;
501 if (memcmp (p
, "ZONE", 4) == 0)
504 while (*p
== ' ' || *p
== '\t') p
++;
508 while (*p
== ' ' || *p
== '\t') p
++;
511 while (strchr (" \t\n\"", *p
) == NULL
) p
++;
512 const char path
[] = "/usr/share/zoneinfo/";
513 if (p
- q
>= sizeof (zonename
) - sizeof (path
))
515 memcpy (zonename
, path
, sizeof (path
) - 1);
516 memcpy (zonename
+ sizeof (path
) - 1, q
, p
- q
);
520 p
= strchr (p
, '\n');
523 if (*zonename
== '\0')
525 fd
= INTERNAL_SYSCALL (open
, err
, 2, zonename
, O_RDONLY
);
526 if (INTERNAL_SYSCALL_ERROR_P (fd
, err
))
528 ret
= readall (fd
, data
, sizeof (data
));
529 INTERNAL_SYSCALL (close
, err
, 1, fd
);
530 if (ret
<= 0 || (size_t) ret
== sizeof (data
))
532 datasize
= (size_t) ret
;
533 update ("/etc/localtime");
534 update ("/var/spool/postfix/etc/localtime");
538 int __libc_multiple_threads
__attribute__((nocommon
));
539 int __libc_enable_asynccancel (void) { return 0; }
540 void __libc_disable_asynccancel (int x
) { }
541 void __libc_csu_init (void) { }
542 void __libc_csu_fini (void) { }
543 pid_t
__fork (void) { return -1; }
547 int __libc_start_main (int (*main
) (int argc
, char **argv
),
548 int argc
, char **argv
,
549 void (*init
) (void), void (*fini
) (void),
550 void (*rtld_fini
) (void), void * stack_end
)
555 int (*main
) (int, char **, char **, void *);
556 int (*init
) (int, char **, char **, void *);
560 int __libc_start_main (int argc
, char **argv
, char **ev
,
561 void *auxvec
, void (*rtld_fini
) (void),
562 struct startup_info
*stinfo
,
563 char **stack_on_entry
)
566 #if defined __ia64__ || defined __powerpc64__
567 register void *r13
__asm ("r13") = thr_buf
+ 32768;
568 __asm ("" : : "r" (r13
));
569 #elif defined __sparc__
570 register void *g6
__asm ("g6") = thr_buf
+ 32768;
571 __thread_self
= thr_buf
+ 32768;
572 __asm ("" : : "r" (g6
), "r" (__thread_self
));
573 #elif defined __s390__ && !defined __s390x__
574 __asm ("sar %%a0,%0" : : "d" (thr_buf
+ 32768));
575 #elif defined __s390x__
576 __asm ("sar %%a1,%0; srlg 0,%0,32; sar %%a0,0" : : "d" (thr_buf
+ 32768) : "0");
577 #elif defined __powerpc__ && !defined __powerpc64__
578 register void *r2
__asm ("r2") = thr_buf
+ 32768;
579 __asm ("" : : "r" (r2
));
582 argc
= (long)*stack_on_entry
;
583 argv
= stack_on_entry
+ 1;
585 long ret
= main (argc
, argv
);
586 INTERNAL_SYSCALL_DECL (err
);
587 INTERNAL_SYSCALL (exit
, err
, 1, ret
);