~ubuntu-branches/ubuntu/utopic/golang/utopic

« back to all changes in this revision

Viewing changes to src/pkg/runtime/signal_linux_386.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2009 The Go Authors. All rights reserved.
2
 
// Use of this source code is governed by a BSD-style
3
 
// license that can be found in the LICENSE file.
4
 
 
5
 
#include "runtime.h"
6
 
#include "defs_GOOS_GOARCH.h"
7
 
#include "signals_GOOS.h"
8
 
#include "os_GOOS.h"
9
 
 
10
 
void
11
 
runtime·dumpregs(Sigcontext *r)
12
 
{
13
 
        runtime·printf("eax     %x\n", r->eax);
14
 
        runtime·printf("ebx     %x\n", r->ebx);
15
 
        runtime·printf("ecx     %x\n", r->ecx);
16
 
        runtime·printf("edx     %x\n", r->edx);
17
 
        runtime·printf("edi     %x\n", r->edi);
18
 
        runtime·printf("esi     %x\n", r->esi);
19
 
        runtime·printf("ebp     %x\n", r->ebp);
20
 
        runtime·printf("esp     %x\n", r->esp);
21
 
        runtime·printf("eip     %x\n", r->eip);
22
 
        runtime·printf("eflags  %x\n", r->eflags);
23
 
        runtime·printf("cs      %x\n", r->cs);
24
 
        runtime·printf("fs      %x\n", r->fs);
25
 
        runtime·printf("gs      %x\n", r->gs);
26
 
}
27
 
 
28
 
/*
29
 
 * This assembler routine takes the args from registers, puts them on the stack,
30
 
 * and calls sighandler().
31
 
 */
32
 
extern void runtime·sigtramp(void);
33
 
extern void runtime·sigreturn(void);    // calls runtime·sigreturn
34
 
 
35
 
void
36
 
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
37
 
{
38
 
        Ucontext *uc;
39
 
        Sigcontext *r;
40
 
        uintptr *sp;
41
 
        SigTab *t;
42
 
 
43
 
        uc = context;
44
 
        r = &uc->uc_mcontext;
45
 
 
46
 
        if(sig == SIGPROF) {
47
 
                runtime·sigprof((uint8*)r->eip, (uint8*)r->esp, nil, gp);
48
 
                return;
49
 
        }
50
 
 
51
 
        t = &runtime·sigtab[sig];
52
 
        if(info->si_code != SI_USER && (t->flags & SigPanic)) {
53
 
                if(gp == nil)
54
 
                        goto Throw;
55
 
                // Make it look like a call to the signal func.
56
 
                // Have to pass arguments out of band since
57
 
                // augmenting the stack frame would break
58
 
                // the unwinding code.
59
 
                gp->sig = sig;
60
 
                gp->sigcode0 = info->si_code;
61
 
                gp->sigcode1 = ((uintptr*)info)[3];
62
 
                gp->sigpc = r->eip;
63
 
 
64
 
                // Only push runtime·sigpanic if r->eip != 0.
65
 
                // If r->eip == 0, probably panicked because of a
66
 
                // call to a nil func.  Not pushing that onto sp will
67
 
                // make the trace look like a call to runtime·sigpanic instead.
68
 
                // (Otherwise the trace will end at runtime·sigpanic and we
69
 
                // won't get to see who faulted.)
70
 
                if(r->eip != 0) {
71
 
                        sp = (uintptr*)r->esp;
72
 
                        *--sp = r->eip;
73
 
                        r->esp = (uintptr)sp;
74
 
                }
75
 
                r->eip = (uintptr)runtime·sigpanic;
76
 
                return;
77
 
        }
78
 
 
79
 
        if(info->si_code == SI_USER || (t->flags & SigNotify))
80
 
                if(runtime·sigsend(sig))
81
 
                        return;
82
 
        if(t->flags & SigKill)
83
 
                runtime·exit(2);
84
 
        if(!(t->flags & SigThrow))
85
 
                return;
86
 
 
87
 
Throw:
88
 
        runtime·startpanic();
89
 
 
90
 
        if(sig < 0 || sig >= NSIG)
91
 
                runtime·printf("Signal %d\n", sig);
92
 
        else
93
 
                runtime·printf("%s\n", runtime·sigtab[sig].name);
94
 
 
95
 
        runtime·printf("PC=%X\n", r->eip);
96
 
        runtime·printf("\n");
97
 
 
98
 
        if(runtime·gotraceback()){
99
 
                runtime·traceback((void*)r->eip, (void*)r->esp, 0, gp);
100
 
                runtime·tracebackothers(gp);
101
 
                runtime·dumpregs(r);
102
 
        }
103
 
 
104
 
        runtime·exit(2);
105
 
}
106
 
 
107
 
void
108
 
runtime·signalstack(byte *p, int32 n)
109
 
{
110
 
        Sigaltstack st;
111
 
 
112
 
        st.ss_sp = p;
113
 
        st.ss_size = n;
114
 
        st.ss_flags = 0;
115
 
        runtime·sigaltstack(&st, nil);
116
 
}
117
 
 
118
 
void
119
 
runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
120
 
{
121
 
        Sigaction sa;
122
 
 
123
 
        runtime·memclr((byte*)&sa, sizeof sa);
124
 
        sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER;
125
 
        if(restart)
126
 
                sa.sa_flags |= SA_RESTART;
127
 
        sa.sa_mask = ~0ULL;
128
 
        sa.sa_restorer = (void*)runtime·sigreturn;
129
 
        if(fn == runtime·sighandler)
130
 
                fn = (void*)runtime·sigtramp;
131
 
        sa.k_sa_handler = fn;
132
 
        runtime·rt_sigaction(i, &sa, nil, 8);
133
 
}
134
 
 
135
 
#define AT_NULL         0
136
 
#define AT_SYSINFO      32
137
 
extern uint32 runtime·_vdso;
138
 
 
139
 
#pragma textflag 7
140
 
void
141
 
runtime·linux_setup_vdso(int32 argc, void *argv_list)
142
 
{
143
 
        byte **argv = &argv_list;
144
 
        byte **envp;
145
 
        uint32 *auxv;
146
 
 
147
 
        // skip envp to get to ELF auxiliary vector.
148
 
        for(envp = &argv[argc+1]; *envp != nil; envp++)
149
 
                ;
150
 
        envp++;
151
 
        
152
 
        for(auxv=(uint32*)envp; auxv[0] != AT_NULL; auxv += 2) {
153
 
                if(auxv[0] == AT_SYSINFO) {
154
 
                        runtime·_vdso = auxv[1];
155
 
                        break;
156
 
                }
157
 
        }
158
 
}