Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Johnny Cai
wine
Commits
cf51b654
Commit
cf51b654
authored
22 years ago
by
Marcus Meissner
Committed by
Alexandre Julliard
22 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Implemented signal handling for PPC.
parent
cea6df77
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
dlls/ntdll/Makefile.in
+1
-0
1 addition, 0 deletions
dlls/ntdll/Makefile.in
dlls/ntdll/signal_powerpc.c
+511
-0
511 additions, 0 deletions
dlls/ntdll/signal_powerpc.c
with
512 additions
and
0 deletions
dlls/ntdll/Makefile.in
+
1
−
0
View file @
cf51b654
...
...
@@ -109,6 +109,7 @@ C_SRCS = \
string.c
\
sec.c
\
signal_i386.c
\
signal_powerpc.c
\
signal_sparc.c
\
sync.c
\
time.c
\
...
...
This diff is collapsed.
Click to expand it.
dlls/ntdll/signal_powerpc.c
0 → 100644
+
511
−
0
View file @
cf51b654
/*
* PowerPC signal handling routines
*
* Copyright 2002 Marcus Meissner, SuSE Linux AG
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef __powerpc__
#include
"config.h"
#include
"wine/port.h"
#include
<errno.h>
#include
<signal.h>
#include
<stdlib.h>
#include
<stdio.h>
#include
<unistd.h>
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef HAVE_SYSCALL_H
# include <syscall.h>
#else
# ifdef HAVE_SYS_SYSCALL_H
# include <sys/syscall.h>
# endif
#endif
#ifdef HAVE_SYS_VM86_H
# include <sys/vm86.h>
#endif
#ifdef HAVE_SYS_SIGNAL_H
# include <sys/signal.h>
#endif
#include
"ntddk.h"
#include
"winnt.h"
#include
"wine/library.h"
#include
"selectors.h"
/***********************************************************************
* signal context platform-specific definitions
*/
typedef
struct
ucontext
SIGCONTEXT
;
#define HANDLER_DEF(name) void name( int __signal, struct siginfo *__siginfo, SIGCONTEXT *__context )
#define HANDLER_CONTEXT (__context)
#include
"wine/exception.h"
#include
"winnt.h"
#include
"stackframe.h"
#include
"global.h"
#include
"miscemu.h"
#include
"ntddk.h"
#include
"syslevel.h"
#include
"wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
seh
);
typedef
int
(
*
wine_signal_handler
)(
unsigned
sig
);
static
wine_signal_handler
handlers
[
256
];
static
sigset_t
all_sigs
;
/***********************************************************************
* dispatch_signal
*/
inline
static
int
dispatch_signal
(
unsigned
sig
)
{
if
(
handlers
[
sig
]
==
NULL
)
return
0
;
return
handlers
[
sig
](
sig
);
}
/***********************************************************************
* save_context
*
* Set the register values from a sigcontext.
*/
static
void
save_context
(
CONTEXT
*
context
,
const
SIGCONTEXT
*
sigcontext
)
{
#define CX(x,y) context->x = sigcontext->uc_mcontext.regs->y
#define C(x) CX(Gpr##x,gpr[x])
C
(
0
);
C
(
1
);
C
(
2
);
C
(
3
);
C
(
4
);
C
(
5
);
C
(
6
);
C
(
7
);
C
(
8
);
C
(
9
);
C
(
10
);
C
(
11
);
C
(
12
);
C
(
13
);
C
(
14
);
C
(
15
);
C
(
16
);
C
(
17
);
C
(
18
);
C
(
19
);
C
(
20
);
C
(
21
);
C
(
22
);
C
(
23
);
C
(
24
);
C
(
25
);
C
(
26
);
C
(
27
);
C
(
28
);
C
(
29
);
C
(
30
);
C
(
31
);
CX
(
Fill
[
0
],
nip
);
CX
(
Msr
,
msr
);
CX
(
Ctr
,
ctr
);
#undef CX
/* FIXME: fp regs? */
/* FIXME: missing pt_regs ...
unsigned long link;
unsigned long xer;
unsigned long ccr;
unsigned long mq;
unsigned long trap;
unsigned long dar;
unsigned long dsisr;
*/
}
/***********************************************************************
* restore_context
*
* Build a sigcontext from the register values.
*/
static
void
restore_context
(
const
CONTEXT
*
context
,
SIGCONTEXT
*
sigcontext
)
{
#define CX(x,y) sigcontext->uc_mcontext.regs->y = context->x
C
(
0
);
C
(
1
);
C
(
2
);
C
(
3
);
C
(
4
);
C
(
5
);
C
(
6
);
C
(
7
);
C
(
8
);
C
(
9
);
C
(
10
);
C
(
11
);
C
(
12
);
C
(
13
);
C
(
14
);
C
(
15
);
C
(
16
);
C
(
17
);
C
(
18
);
C
(
19
);
C
(
20
);
C
(
21
);
C
(
22
);
C
(
23
);
C
(
24
);
C
(
25
);
C
(
26
);
C
(
27
);
C
(
28
);
C
(
29
);
C
(
30
);
C
(
31
);
CX
(
Fill
[
0
],
nip
);
CX
(
Msr
,
msr
);
CX
(
Ctr
,
ctr
);
#undef CX
}
/***********************************************************************
* save_fpu
*
* Set the FPU context from a sigcontext.
*/
inline
static
void
save_fpu
(
CONTEXT
*
context
,
const
SIGCONTEXT
*
sigcontext
)
{
/* FIXME? */
}
/***********************************************************************
* restore_fpu
*
* Restore the FPU context to a sigcontext.
*/
inline
static
void
restore_fpu
(
CONTEXT
*
context
,
const
SIGCONTEXT
*
sigcontext
)
{
/* FIXME? */
}
/**********************************************************************
* get_fpu_code
*
* Get the FPU exception code from the FPU status.
*/
static
inline
DWORD
get_fpu_code
(
const
CONTEXT
*
context
)
{
DWORD
status
=
0
/* FIXME */
;
if
(
status
&
0x01
)
/* IE */
{
if
(
status
&
0x40
)
/* SF */
return
EXCEPTION_FLT_STACK_CHECK
;
else
return
EXCEPTION_FLT_INVALID_OPERATION
;
}
if
(
status
&
0x02
)
return
EXCEPTION_FLT_DENORMAL_OPERAND
;
/* DE flag */
if
(
status
&
0x04
)
return
EXCEPTION_FLT_DIVIDE_BY_ZERO
;
/* ZE flag */
if
(
status
&
0x08
)
return
EXCEPTION_FLT_OVERFLOW
;
/* OE flag */
if
(
status
&
0x10
)
return
EXCEPTION_FLT_UNDERFLOW
;
/* UE flag */
if
(
status
&
0x20
)
return
EXCEPTION_FLT_INEXACT_RESULT
;
/* PE flag */
return
EXCEPTION_FLT_INVALID_OPERATION
;
/* generic error */
}
/***********************************************************************
* SIGNAL_Unblock
*
* Unblock signals. Called from EXC_RtlRaiseException.
*/
void
SIGNAL_Unblock
(
void
)
{
sigprocmask
(
SIG_UNBLOCK
,
&
all_sigs
,
NULL
);
}
/**********************************************************************
* segv_handler
*
* Handler for SIGSEGV and related errors.
*/
static
HANDLER_DEF
(
segv_handler
)
{
CONTEXT
context
;
EXCEPTION_RECORD
rec
;
DWORD
page_fault_code
=
EXCEPTION_ACCESS_VIOLATION
;
save_context
(
&
context
,
HANDLER_CONTEXT
);
rec
.
ExceptionRecord
=
NULL
;
rec
.
ExceptionFlags
=
EXCEPTION_CONTINUABLE
;
rec
.
ExceptionAddress
=
(
LPVOID
)
HANDLER_CONTEXT
->
uc_mcontext
.
regs
->
nip
;
rec
.
NumberParameters
=
0
;
switch
(
__siginfo
->
si_signo
)
{
case
SIGSEGV
:
switch
(
__siginfo
->
si_code
)
{
case
SEGV_MAPERR
:
case
SEGV_ACCERR
:
rec
.
NumberParameters
=
2
;
rec
.
ExceptionInformation
[
0
]
=
0
;
/* FIXME ? */
rec
.
ExceptionInformation
[
1
]
=
(
DWORD
)
__siginfo
->
si_addr
;
if
(
!
(
page_fault_code
=
VIRTUAL_HandleFault
(
__siginfo
->
si_addr
)))
return
;
rec
.
ExceptionCode
=
page_fault_code
;
break
;
default:
FIXME
(
"Unhandled SIGSEGV/%x
\n
"
,
__siginfo
->
si_code
);
break
;
}
break
;
case
SIGBUS
:
switch
(
__siginfo
->
si_code
)
{
case
BUS_ADRALN
:
rec
.
ExceptionCode
=
EXCEPTION_DATATYPE_MISALIGNMENT
;
break
;
case
BUS_ADRERR
:
case
BUS_OBJERR
:
/* FIXME: correct for all cases ? */
rec
.
NumberParameters
=
2
;
rec
.
ExceptionInformation
[
0
]
=
0
;
/* FIXME ? */
rec
.
ExceptionInformation
[
1
]
=
(
DWORD
)
__siginfo
->
si_addr
;
if
(
!
(
page_fault_code
=
VIRTUAL_HandleFault
(
__siginfo
->
si_addr
)))
return
;
rec
.
ExceptionCode
=
page_fault_code
;
break
;
default:
FIXME
(
"Unhandled SIGBUS/%x
\n
"
,
__siginfo
->
si_code
);
break
;
}
break
;
case
SIGILL
:
switch
(
__siginfo
->
si_code
)
{
case
ILL_ILLOPC
:
/* illegal opcode */
case
ILL_ILLOPN
:
/* illegal operand */
case
ILL_ILLADR
:
/* illegal addressing mode */
case
ILL_ILLTRP
:
/* illegal trap */
case
ILL_COPROC
:
/* coprocessor error */
rec
.
ExceptionCode
=
EXCEPTION_ILLEGAL_INSTRUCTION
;
break
;
case
ILL_PRVOPC
:
/* privileged opcode */
case
ILL_PRVREG
:
/* privileged register */
rec
.
ExceptionCode
=
EXCEPTION_PRIV_INSTRUCTION
;
break
;
case
ILL_BADSTK
:
/* internal stack error */
rec
.
ExceptionCode
=
EXCEPTION_STACK_OVERFLOW
;
break
;
default:
FIXME
(
"Unhandled SIGILL/%x
\n
"
,
__siginfo
->
si_code
);
break
;
}
break
;
}
EXC_RtlRaiseException
(
&
rec
,
&
context
);
restore_context
(
&
context
,
HANDLER_CONTEXT
);
}
/**********************************************************************
* trap_handler
*
* Handler for SIGTRAP.
*/
static
HANDLER_DEF
(
trap_handler
)
{
CONTEXT
context
;
EXCEPTION_RECORD
rec
;
save_context
(
&
context
,
HANDLER_CONTEXT
);
rec
.
ExceptionFlags
=
EXCEPTION_CONTINUABLE
;
rec
.
ExceptionRecord
=
NULL
;
rec
.
ExceptionAddress
=
(
LPVOID
)
__context
->
uc_mcontext
.
regs
->
nip
;
rec
.
NumberParameters
=
0
;
/* FIXME: check if we might need to modify PC */
switch
(
__siginfo
->
si_code
)
{
case
TRAP_BRKPT
:
rec
.
ExceptionCode
=
EXCEPTION_BREAKPOINT
;
break
;
case
TRAP_TRACE
:
rec
.
ExceptionCode
=
EXCEPTION_SINGLE_STEP
;
break
;
}
EXC_RtlRaiseException
(
&
rec
,
&
context
);
restore_context
(
&
context
,
HANDLER_CONTEXT
);
}
/**********************************************************************
* fpe_handler
*
* Handler for SIGFPE.
*/
static
HANDLER_DEF
(
fpe_handler
)
{
CONTEXT
context
;
EXCEPTION_RECORD
rec
;
/*save_fpu( &context, HANDLER_CONTEXT );*/
save_context
(
&
context
,
HANDLER_CONTEXT
);
switch
(
__siginfo
->
si_code
)
{
case
FPE_FLTSUB
:
rec
.
ExceptionCode
=
EXCEPTION_ARRAY_BOUNDS_EXCEEDED
;
break
;
case
FPE_INTDIV
:
rec
.
ExceptionCode
=
EXCEPTION_INT_DIVIDE_BY_ZERO
;
break
;
case
FPE_INTOVF
:
rec
.
ExceptionCode
=
EXCEPTION_INT_OVERFLOW
;
break
;
case
FPE_FLTDIV
:
rec
.
ExceptionCode
=
EXCEPTION_FLT_DIVIDE_BY_ZERO
;
break
;
case
FPE_FLTOVF
:
rec
.
ExceptionCode
=
EXCEPTION_FLT_OVERFLOW
;
break
;
case
FPE_FLTUND
:
rec
.
ExceptionCode
=
EXCEPTION_FLT_UNDERFLOW
;
break
;
case
FPE_FLTRES
:
rec
.
ExceptionCode
=
EXCEPTION_FLT_INEXACT_RESULT
;
break
;
case
FPE_FLTINV
:
default:
rec
.
ExceptionCode
=
EXCEPTION_FLT_INVALID_OPERATION
;
break
;
}
rec
.
ExceptionFlags
=
EXCEPTION_CONTINUABLE
;
rec
.
ExceptionRecord
=
NULL
;
rec
.
ExceptionAddress
=
(
LPVOID
)
__context
->
uc_mcontext
.
regs
->
nip
;
rec
.
NumberParameters
=
0
;
EXC_RtlRaiseException
(
&
rec
,
&
context
);
restore_context
(
&
context
,
HANDLER_CONTEXT
);
/*restore_fpu( &context, HANDLER_CONTEXT );*/
}
/**********************************************************************
* int_handler
*
* Handler for SIGINT.
*/
static
HANDLER_DEF
(
int_handler
)
{
if
(
!
dispatch_signal
(
SIGINT
))
{
EXCEPTION_RECORD
rec
;
CONTEXT
context
;
save_context
(
&
context
,
HANDLER_CONTEXT
);
rec
.
ExceptionCode
=
CONTROL_C_EXIT
;
rec
.
ExceptionFlags
=
EXCEPTION_CONTINUABLE
;
rec
.
ExceptionRecord
=
NULL
;
rec
.
ExceptionAddress
=
(
LPVOID
)
context
.
Fill
[
0
];
rec
.
NumberParameters
=
0
;
EXC_RtlRaiseException
(
&
rec
,
&
context
);
restore_context
(
&
context
,
HANDLER_CONTEXT
);
}
}
/***********************************************************************
* set_handler
*
* Set a signal handler
*/
static
int
set_handler
(
int
sig
,
int
have_sigaltstack
,
void
(
*
func
)()
)
{
struct
sigaction
sig_act
;
sig_act
.
sa_sigaction
=
func
;
sigemptyset
(
&
sig_act
.
sa_mask
);
sigaddset
(
&
sig_act
.
sa_mask
,
SIGINT
);
sigaddset
(
&
sig_act
.
sa_mask
,
SIGALRM
);
sig_act
.
sa_flags
=
SA_RESTART
|
SA_SIGINFO
;
#ifdef SA_ONSTACK
if
(
have_sigaltstack
)
sig_act
.
sa_flags
|=
SA_ONSTACK
;
#endif
return
sigaction
(
sig
,
&
sig_act
,
NULL
);
}
/***********************************************************************
* __wine_set_signal_handler (NTDLL.@)
*/
int
__wine_set_signal_handler
(
unsigned
sig
,
wine_signal_handler
wsh
)
{
if
(
sig
>
sizeof
(
handlers
)
/
sizeof
(
handlers
[
0
]))
return
-
1
;
if
(
handlers
[
sig
]
!=
NULL
)
return
-
2
;
handlers
[
sig
]
=
wsh
;
return
0
;
}
/**********************************************************************
* SIGNAL_Init
*/
BOOL
SIGNAL_Init
(
void
)
{
int
have_sigaltstack
=
0
;
#ifdef HAVE_SIGALTSTACK
struct
sigaltstack
ss
;
if
((
ss
.
ss_sp
=
NtCurrentTeb
()
->
signal_stack
))
{
ss
.
ss_size
=
SIGNAL_STACK_SIZE
;
ss
.
ss_flags
=
0
;
if
(
!
sigaltstack
(
&
ss
,
NULL
))
have_sigaltstack
=
1
;
}
#endif
/* HAVE_SIGALTSTACK */
sigfillset
(
&
all_sigs
);
if
(
set_handler
(
SIGINT
,
have_sigaltstack
,
(
void
(
*
)())
int_handler
)
==
-
1
)
goto
error
;
if
(
set_handler
(
SIGFPE
,
have_sigaltstack
,
(
void
(
*
)())
fpe_handler
)
==
-
1
)
goto
error
;
if
(
set_handler
(
SIGSEGV
,
have_sigaltstack
,
(
void
(
*
)())
segv_handler
)
==
-
1
)
goto
error
;
if
(
set_handler
(
SIGILL
,
have_sigaltstack
,
(
void
(
*
)())
segv_handler
)
==
-
1
)
goto
error
;
#ifdef SIGBUS
if
(
set_handler
(
SIGBUS
,
have_sigaltstack
,
(
void
(
*
)())
segv_handler
)
==
-
1
)
goto
error
;
#endif
#ifdef SIGTRAP
if
(
set_handler
(
SIGTRAP
,
have_sigaltstack
,
(
void
(
*
)())
trap_handler
)
==
-
1
)
goto
error
;
#endif
return
TRUE
;
error:
perror
(
"sigaction"
);
return
FALSE
;
}
/**********************************************************************
* SIGNAL_Reset
*/
void
SIGNAL_Reset
(
void
)
{
sigset_t
block_set
;
/* block the async signals */
sigemptyset
(
&
block_set
);
sigaddset
(
&
block_set
,
SIGALRM
);
sigaddset
(
&
block_set
,
SIGIO
);
sigaddset
(
&
block_set
,
SIGHUP
);
sigaddset
(
&
block_set
,
SIGUSR2
);
sigprocmask
(
SIG_BLOCK
,
&
block_set
,
NULL
);
/* restore default handlers */
signal
(
SIGINT
,
SIG_DFL
);
signal
(
SIGFPE
,
SIG_DFL
);
signal
(
SIGSEGV
,
SIG_DFL
);
signal
(
SIGILL
,
SIG_DFL
);
#ifdef SIGBUS
signal
(
SIGBUS
,
SIG_DFL
);
#endif
#ifdef SIGTRAP
signal
(
SIGTRAP
,
SIG_DFL
);
#endif
}
/**********************************************************************
* __wine_enter_vm86 (NTDLL.@)
*/
void
__wine_enter_vm86
(
CONTEXT
*
context
)
{
MESSAGE
(
"vm86 mode not supported on this platform
\n
"
);
}
/**********************************************************************
* DbgBreakPoint (NTDLL.@)
*/
void
WINAPI
DbgBreakPoint
(
void
)
{
kill
(
getpid
(),
SIGTRAP
);
}
/**********************************************************************
* DbgUserBreakPoint (NTDLL.@)
*/
void
WINAPI
DbgUserBreakPoint
(
void
)
{
kill
(
getpid
(),
SIGTRAP
);
}
#endif
/* __powerpc__ */
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment