강좌 & 팁
vi 소스를 편집하다가 현재의 소스를 긁어다가 웹에 그대로 보여줄 필요가 있을때
프린트 스크린을 누르고 편집을 그림을 오려 붙이고 보여주는건
우리에겐 낡은 방법으로 하기가 싫어집니다.
누구나 그렇겠지만 설마 vi -> html 이 있지 않을까? 하고 생각하셨겠죠?
네.. 있습니다.
명령어 모드에서
:runtime! syntax/2html.vim
:so $VIMRUNTIME/syntax/2html.vim
라고 치면 바다가 갈라지듯 두개의 창으로 분리되면서
한쪽에 html 소스가 보여집니다.
html 형식으로 바뀐 소스를 보실수 있습니다.
그걸 어떻게 쓸꺼냐...?
밥은 스스로 먹어야죠... 어디에 게시를 하건 본인 맘이죠..
아래 쏘스를 보면서 잘 정렬된 코드를 감상하시기 바랍니다.
1 /*
2 * linux/arch/x86_64/ia32/ia32_signal.c
1 /*
2 * linux/arch/x86_64/ia32/ia32_signal.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 *
6 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
7 * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
8 * 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen
9 */
10
11 #include <linux/sched.h>
12 #include <linux/mm.h>
13 #include <linux/smp.h>
14 #include <linux/kernel.h>
15 #include <linux/signal.h>
16 #include <linux/errno.h>
17 #include <linux/wait.h>
18 #include <linux/ptrace.h>
19 #include <linux/unistd.h>
20 #include <linux/stddef.h>
21 #include <linux/personality.h>
22 #include <linux/compat.h>
23 #include <linux/binfmts.h>
24 #include <asm/ucontext.h>
25 #include <asm/uaccess.h>
26 #include <asm/i387.h>
27 #include <asm/ptrace.h>
28 #include <asm/ia32_unistd.h>
29 #include <asm/user32.h>
30 #include <asm/sigcontext32.h>
31 #include <asm/proto.h>
32 #include <asm/vdso.h>
33 #include <asm/sigframe.h>
34 #include <asm/sys_ia32.h>
35
36 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
37
38 #define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \
39 X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
40 X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
41 X86_EFLAGS_CF)
42
43 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
44
45 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
46 {
47 int err = 0;
48
49 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
50 return -EFAULT;
51
52 put_user_try {
53 /* If you change siginfo_t structure, please make sure that
54 this code is fixed accordingly.
55 It should never copy any pad contained in the structure
56 to avoid security leaks, but must copy the generic
57 3 ints plus the relevant union member. */
58 put_user_ex(from->si_signo, &to->si_signo);
59 put_user_ex(from->si_errno, &to->si_errno);
60 put_user_ex((short)from->si_code, &to->si_code);
61
62 if (from->si_code < 0) {
63 put_user_ex(from->si_pid, &to->si_pid);
64 put_user_ex(from->si_uid, &to->si_uid);
65 put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
66 } else {
67 /*
68 * First 32bits of unions are always present:
69 * si_pid === si_band === si_tid === si_addr(LS half)
70 */
71 put_user_ex(from->_sifields._pad[0],
72 &to->_sifields._pad[0]);
73 switch (from->si_code >> 16) {
74 case __SI_FAULT >> 16:
75 break;
76 case __SI_CHLD >> 16:
77 put_user_ex(from->si_utime, &to->si_utime);
78 put_user_ex(from->si_stime, &to->si_stime);
79 put_user_ex(from->si_status, &to->si_status);
80 /* FALL THROUGH */
81 default:
82 case __SI_KILL >> 16:
83 put_user_ex(from->si_uid, &to->si_uid);
84 break;
85 case __SI_POLL >> 16:
86 put_user_ex(from->si_fd, &to->si_fd);
87 break;
88 case __SI_TIMER >> 16:
89 put_user_ex(from->si_overrun, &to->si_overrun);
90 put_user_ex(ptr_to_compat(from->si_ptr),
91 &to->si_ptr);
92 break;
93 /* This is not generated by the kernel as of now. */
94 case __SI_RT >> 16:
95 case __SI_MESGQ >> 16:
96 put_user_ex(from->si_uid, &to->si_uid);
97 put_user_ex(from->si_int, &to->si_int);
98 break;
99 }
100 }
101 } put_user_catch(err);
102
103 return err;
104 }
105
106 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
107 {
108 int err = 0;
109 u32 ptr32;
110
111 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
112 return -EFAULT;
113
114 get_user_try {
115 get_user_ex(to->si_signo, &from->si_signo);
116 get_user_ex(to->si_errno, &from->si_errno);
117 get_user_ex(to->si_code, &from->si_code);
118
119 get_user_ex(to->si_pid, &from->si_pid);
120 get_user_ex(to->si_uid, &from->si_uid);
121 get_user_ex(ptr32, &from->si_ptr);
122 to->si_ptr = compat_ptr(ptr32);
123 } get_user_catch(err);
124
125 return err;
126 }
127
128 asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
129 {
130 mask &= _BLOCKABLE;
131 spin_lock_irq(¤t->sighand->siglock);
132 current->saved_sigmask = current->blocked;
133 siginitset(¤t->blocked, mask);
134 recalc_sigpending();
135 spin_unlock_irq(¤t->sighand->siglock);
136
137 current->state = TASK_INTERRUPTIBLE;
138 schedule();
139 set_restore_sigmask();
140 return -ERESTARTNOHAND;
141 }
142
143 asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
144 stack_ia32_t __user *uoss_ptr,
145 struct pt_regs *regs)
146 {
147 stack_t uss, uoss;
148 int ret, err = 0;
149 mm_segment_t seg;
150
151 if (uss_ptr) {
152 u32 ptr;
153
154 memset(&uss, 0, sizeof(stack_t));
155 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)))
156 return -EFAULT;
157
158 get_user_try {
159 get_user_ex(ptr, &uss_ptr->ss_sp);
160 get_user_ex(uss.ss_flags, &uss_ptr->ss_flags);
161 get_user_ex(uss.ss_size, &uss_ptr->ss_size);
162 } get_user_catch(err);
163
164 if (err)
165 return -EFAULT;
166 uss.ss_sp = compat_ptr(ptr);
167 }
168 seg = get_fs();
169 set_fs(KERNEL_DS);
170 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
171 set_fs(seg);
172 if (ret >= 0 && uoss_ptr) {
173 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
174 return -EFAULT;
175
176 put_user_try {
177 put_user_ex(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp);
178 put_user_ex(uoss.ss_flags, &uoss_ptr->ss_flags);
179 put_user_ex(uoss.ss_size, &uoss_ptr->ss_size);
180 } put_user_catch(err);
181
182 if (err)
183 ret = -EFAULT;
184 }
185 return ret;
186 }
187
188 /*
189 * Do a signal return; undo the signal stack.
190 */
191 #define loadsegment_gs(v) load_gs_index(v)
192 #define loadsegment_fs(v) loadsegment(fs, v)
193 #define loadsegment_ds(v) loadsegment(ds, v)
194 #define loadsegment_es(v) loadsegment(es, v)
195
196 #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
197 #define set_user_seg(seg, v) loadsegment_##seg(v)
198
199 #define COPY(x) { \
200 get_user_ex(regs->x, &sc->x); \
201 }
202
203 #define GET_SEG(seg) ({ \
204 unsigned short tmp; \
205 get_user_ex(tmp, &sc->seg); \
206 tmp; \
207 })
208
209 #define COPY_SEG_CPL3(seg) do { \
210 regs->seg = GET_SEG(seg) | 3; \
211 } while (0)
212
213 #define RELOAD_SEG(seg) { \
214 unsigned int pre = GET_SEG(seg); \
215 unsigned int cur = get_user_seg(seg); \
216 pre |= 3; \
217 if (pre != cur) \
218 set_user_seg(seg, pre); \
219 }
220
221 static int ia32_restore_sigcontext(struct pt_regs *regs,
222 struct sigcontext_ia32 __user *sc,
223 unsigned int *pax)
224 {
225 unsigned int tmpflags, err = 0;
226 void __user *buf;
227 u32 tmp;
228
229 /* Always make any pending restarted system calls return -EINTR */
230 current_thread_info()->restart_block.fn = do_no_restart_syscall;
231
232 get_user_try {
233 /*
234 * Reload fs and gs if they have changed in the signal
235 * handler. This does not handle long fs/gs base changes in
236 * the handler, but does not clobber them at least in the
237 * normal case.
238 */
239 RELOAD_SEG(gs);
240 RELOAD_SEG(fs);
241 RELOAD_SEG(ds);
242 RELOAD_SEG(es);
243
244 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
245 COPY(dx); COPY(cx); COPY(ip);
246 /* Don't touch extended registers */
247
248 COPY_SEG_CPL3(cs);
249 COPY_SEG_CPL3(ss);
250
251 get_user_ex(tmpflags, &sc->flags);
252 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
253 /* disable syscall checks */
254 regs->orig_ax = -1;
255
256 get_user_ex(tmp, &sc->fpstate);
257 buf = compat_ptr(tmp);
258 err |= restore_i387_xstate_ia32(buf);
259
260 get_user_ex(*pax, &sc->ax);
261 } get_user_catch(err);
262
263 return err;
264 }
265
266 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
267 {
268 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
269 sigset_t set;
270 unsigned int ax;
271
272 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
273 goto badframe;
274 if (__get_user(set.sig[0], &frame->sc.oldmask)
275 || (_COMPAT_NSIG_WORDS > 1
276 && __copy_from_user((((char *) &set.sig) + 4),
277 &frame->extramask,
278 sizeof(frame->extramask))))
279 goto badframe;
280
281 sigdelsetmask(&set, ~_BLOCKABLE);
282 spin_lock_irq(¤t->sighand->siglock);
283 current->blocked = set;
284 recalc_sigpending();
285 spin_unlock_irq(¤t->sighand->siglock);
286
287 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
288 goto badframe;
289 return ax;
290
291 badframe:
292 signal_fault(regs, frame, "32bit sigreturn");
293 return 0;
294 }
295
296 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
297 {
298 struct rt_sigframe_ia32 __user *frame;
299 sigset_t set;
300 unsigned int ax;
301 struct pt_regs tregs;
302
303 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
304
305 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
306 goto badframe;
307 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
308 goto badframe;
309
310 sigdelsetmask(&set, ~_BLOCKABLE);
311 spin_lock_irq(¤t->sighand->siglock);
312 current->blocked = set;
313 recalc_sigpending();
314 spin_unlock_irq(¤t->sighand->siglock);
315
316 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
317 goto badframe;
318
319 tregs = *regs;
320 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
321 goto badframe;
322
323 return ax;
324
325 badframe:
326 signal_fault(regs, frame, "32bit rt sigreturn");
327 return 0;
328 }
329
330 /*
331 * Set up a signal frame.
332 */
333
334 static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
335 void __user *fpstate,
336 struct pt_regs *regs, unsigned int mask)
337 {
338 int err = 0;
339
340 put_user_try {
341 put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
342 put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
343 put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
344 put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
345
346 put_user_ex(regs->di, &sc->di);
347 put_user_ex(regs->si, &sc->si);
348 put_user_ex(regs->bp, &sc->bp);
349 put_user_ex(regs->sp, &sc->sp);
350 put_user_ex(regs->bx, &sc->bx);
351 put_user_ex(regs->dx, &sc->dx);
352 put_user_ex(regs->cx, &sc->cx);
353 put_user_ex(regs->ax, &sc->ax);
354 put_user_ex(current->thread.trap_no, &sc->trapno);
355 put_user_ex(current->thread.error_code, &sc->err);
356 put_user_ex(regs->ip, &sc->ip);
357 put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
358 put_user_ex(regs->flags, &sc->flags);
359 put_user_ex(regs->sp, &sc->sp_at_signal);
360 put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
361
362 put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
363
364 /* non-iBCS2 extensions.. */
365 put_user_ex(mask, &sc->oldmask);
366 put_user_ex(current->thread.cr2, &sc->cr2);
367 } put_user_catch(err);
368
369 return err;
370 }
371
372 /*
373 * Determine which stack to use..
374 */
375 static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
376 size_t frame_size,
377 void **fpstate)
378 {
379 unsigned long sp;
380
381 /* Default to using normal stack */
382 sp = regs->sp;
383
384 /* This is the X/Open sanctioned signal stack switching. */
385 if (ka->sa.sa_flags & SA_ONSTACK) {
386 if (sas_ss_flags(sp) == 0)
387 sp = current->sas_ss_sp + current->sas_ss_size;
388 }
389
390 /* This is the legacy signal stack switching. */
391 else if ((regs->ss & 0xffff) != __USER32_DS &&
392 !(ka->sa.sa_flags & SA_RESTORER) &&
393 ka->sa.sa_restorer)
394 sp = (unsigned long) ka->sa.sa_restorer;
395
396 if (used_math()) {
397 sp = sp - sig_xstate_ia32_size;
398 *fpstate = (struct _fpstate_ia32 *) sp;
399 if (save_i387_xstate_ia32(*fpstate) < 0)
400 return (void __user *) -1L;
401 }
402
403 sp -= frame_size;
404 /* Align the stack pointer according to the i386 ABI,
405 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
406 sp = ((sp + 4) & -16ul) - 4;
407 return (void __user *) sp;
408 }
409
410 int ia32_setup_frame(int sig, struct k_sigaction *ka,
411 compat_sigset_t *set, struct pt_regs *regs)
412 {
413 struct sigframe_ia32 __user *frame;
414 void __user *restorer;
415 int err = 0;
416 void __user *fpstate = NULL;
417
418 /* copy_to_user optimizes that into a single 8 byte store */
419 static const struct {
420 u16 poplmovl;
421 u32 val;
422 u16 int80;
423 } __attribute__((packed)) code = {
424 0xb858, /* popl %eax ; movl $...,%eax */
425 __NR_ia32_sigreturn,
426 0x80cd, /* int $0x80 */
427 };
428
429 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
430
431 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
432 return -EFAULT;
433
434 if (__put_user(sig, &frame->sig))
435 return -EFAULT;
436
437 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
438 return -EFAULT;
439
440 if (_COMPAT_NSIG_WORDS > 1) {
441 if (__copy_to_user(frame->extramask, &set->sig[1],
442 sizeof(frame->extramask)))
443 return -EFAULT;
444 }
445
446 if (ka->sa.sa_flags & SA_RESTORER) {
447 restorer = ka->sa.sa_restorer;
448 } else {
449 /* Return stub is in 32bit vsyscall page */
450 if (current->mm->context.vdso)
451 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
452 sigreturn);
453 else
454 restorer = &frame->retcode;
455 }
456
457 put_user_try {
458 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
459
460 /*
461 * These are actually not used anymore, but left because some
462 * gdb versions depend on them as a marker.
463 */
464 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
465 } put_user_catch(err);
466
467 if (err)
468 return -EFAULT;
469
470 /* Set up registers for signal handler */
471 regs->sp = (unsigned long) frame;
472 regs->ip = (unsigned long) ka->sa.sa_handler;
473
474 /* Make -mregparm=3 work */
475 regs->ax = sig;
476 regs->dx = 0;
477 regs->cx = 0;
478
479 loadsegment(ds, __USER32_DS);
480 loadsegment(es, __USER32_DS);
481
482 regs->cs = __USER32_CS;
483 regs->ss = __USER32_DS;
484
485 return 0;
486 }
487
488 int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
489 compat_sigset_t *set, struct pt_regs *regs)
490 {
491 struct rt_sigframe_ia32 __user *frame;
492 void __user *restorer;
493 int err = 0;
494 void __user *fpstate = NULL;
495
496 /* __copy_to_user optimizes that into a single 8 byte store */
497 static const struct {
498 u8 movl;
499 u32 val;
500 u16 int80;
501 u8 pad;
502 } __attribute__((packed)) code = {
503 0xb8,
504 __NR_ia32_rt_sigreturn,
505 0x80cd,
506 0,
507 };
508
509 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
510
511 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
512 return -EFAULT;
513
514 put_user_try {
515 put_user_ex(sig, &frame->sig);
516 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
517 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
518 err |= copy_siginfo_to_user32(&frame->info, info);
519
520 /* Create the ucontext. */
521 if (cpu_has_xsave)
522 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
523 else
524 put_user_ex(0, &frame->uc.uc_flags);
525 put_user_ex(0, &frame->uc.uc_link);
526 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
527 put_user_ex(sas_ss_flags(regs->sp),
528 &frame->uc.uc_stack.ss_flags);
529 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
530 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
531 regs, set->sig[0]);
532 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
533
534 if (ka->sa.sa_flags & SA_RESTORER)
535 restorer = ka->sa.sa_restorer;
536 else
537 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
538 rt_sigreturn);
539 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
540
541 /*
542 * Not actually used anymore, but left because some gdb
543 * versions need it.
544 */
545 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
546 } put_user_catch(err);
547
548 if (err)
549 return -EFAULT;
550
551 /* Set up registers for signal handler */
552 regs->sp = (unsigned long) frame;
553 regs->ip = (unsigned long) ka->sa.sa_handler;
554
555 /* Make -mregparm=3 work */
556 regs->ax = sig;
557 regs->dx = (unsigned long) &frame->info;
558 regs->cx = (unsigned long) &frame->uc;
559
560 loadsegment(ds, __USER32_DS);
561 loadsegment(es, __USER32_DS);
562
563 regs->cs = __USER32_CS;
564 regs->ss = __USER32_DS;
565
566 return 0;
567 }
Wow! This is a great tip! Thanks, guy.