Add an x86_initialize_trampoline() function, similar to GCC 3.3,
change INITIALIZE_TRAMPOLINE() to use it, and apply the following patch to it (which I have already submitted to GCC 3.3): * config/i386/i386.c (x86_initialize_trampoline): Emit a call to __enable_execute_stack with the address of the trampoline if TRANSFER_FROM_TRAMPOLINE is defined. Define a TRANSFER_FROM_TRAMPOLINE suitable for NetBSD targets, to enable stack execution on target machines which can separate exec permissions for a region: * config/netbsd.h (NETBSD_ENABLE_EXECUTE_STACK): Define. * config/alpha/netbsd.h (TRANSFER_FROM_TRAMPOLINE): Define as NETBSD_ENABLE_EXECUTE_STACK. * config/i386/netbsd-elf.h (TRANSFER_FROM_TRAMPOLINE): Ditto. * config/i386/netbsd.h (TRANSFER_FROM_TRAMPOLINE): Ditto. * config/sparc/netbsd-elf-common.h (TRANSFER_FROM_TRAMPOLINE): Ditto. * config/sparc/netbsd.h (TRANSFER_FROM_TRAMPOLINE): Ditto. (A similar patch will be submitted to GCC 3.3.)
This commit is contained in:
parent
2665f9c68c
commit
1268b2dbc5
|
@ -104,6 +104,12 @@ Boston, MA 02111-1307, USA. */
|
|||
/* Show that we need a GP when profiling. */
|
||||
#define TARGET_PROFILING_NEEDS_GP
|
||||
|
||||
|
||||
/* Attempt to enable execute permissions on the stack. */
|
||||
|
||||
#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
|
||||
|
||||
|
||||
#define bsd4_4
|
||||
#undef HAS_INIT_SECTION
|
||||
|
||||
|
|
|
@ -5734,3 +5734,26 @@ memory_address_info (addr, disp_length)
|
|||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Emit RTL insns to initialize the variable parts of a trampoline.
|
||||
FNADDR is an RTX for the address of the function's pure code.
|
||||
CXT is an RTX for the static chain value for the function. */
|
||||
void
|
||||
x86_initialize_trampoline (tramp, fnaddr, cxt)
|
||||
rtx tramp, fnaddr, cxt;
|
||||
{
|
||||
/* Compute offset from the end of the jmp to the target function. */
|
||||
rtx disp = expand_binop (SImode, sub_optab, fnaddr,
|
||||
plus_constant (tramp, 10),
|
||||
NULL_RTX, 1, OPTAB_DIRECT);
|
||||
emit_move_insn (gen_rtx_MEM (QImode, tramp), GEN_INT (0xb9));
|
||||
emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 1)), cxt);
|
||||
emit_move_insn (gen_rtx_MEM (QImode, plus_constant (tramp, 5)),
|
||||
GEN_INT (0xe9));
|
||||
emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 6)), disp);
|
||||
|
||||
#ifdef TRANSFER_FROM_TRAMPOLINE
|
||||
emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
|
||||
0, VOIDmode, 1, tramp, Pmode);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1581,17 +1581,8 @@ do { \
|
|||
FNADDR is an RTX for the address of the function's pure code.
|
||||
CXT is an RTX for the static chain value for the function. */
|
||||
|
||||
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
|
||||
{ \
|
||||
/* Compute offset from the end of the jmp to the target function. */ \
|
||||
rtx disp = expand_binop (SImode, sub_optab, FNADDR, \
|
||||
plus_constant (TRAMP, 10), \
|
||||
NULL_RTX, 1, OPTAB_DIRECT); \
|
||||
emit_move_insn (gen_rtx_MEM (QImode, TRAMP), GEN_INT (0xb9)); \
|
||||
emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 1)), CXT); \
|
||||
emit_move_insn (gen_rtx_MEM (QImode, plus_constant (TRAMP, 5)), GEN_INT (0xe9));\
|
||||
emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 6)), disp); \
|
||||
}
|
||||
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
|
||||
x86_initialize_trampoline ((TRAMP), (FNADDR), (CXT))
|
||||
|
||||
/* Definitions for register eliminations.
|
||||
|
||||
|
@ -2766,6 +2757,7 @@ extern int ix86_can_use_return_insn_p ();
|
|||
extern int small_shift_operand ();
|
||||
extern char *output_ashl ();
|
||||
extern int memory_address_info ();
|
||||
extern void x86_initialize_trampoline ();
|
||||
|
||||
#ifdef NOTYET
|
||||
extern struct rtx_def *copy_all_rtx ();
|
||||
|
|
|
@ -631,6 +631,9 @@ do { \
|
|||
/* Default to pcc-struct-return, because this is the ELF abi and
|
||||
we don't care about compatibility with older gcc versions. */
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 1
|
||||
|
||||
/* Attempt to enable execute permissions on the stack. */
|
||||
#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
|
||||
|
||||
/* Profiling routines, partially copied from i386/osfrose.h. */
|
||||
|
||||
|
|
|
@ -57,6 +57,9 @@
|
|||
/* Don't default to pcc-struct-return, because gcc is the only compiler, and
|
||||
we want to retain compatibility with older gcc versions. */
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 0
|
||||
|
||||
/* Attempt to enable execute permissions on the stack. */
|
||||
#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
|
||||
|
||||
/* i386 netbsd still uses old binutils that don't insert nops by default
|
||||
when the .align directive demands to insert extra space in the text
|
||||
|
|
|
@ -282,3 +282,51 @@ do { \
|
|||
%{static:-static}}"
|
||||
|
||||
#endif /* NETBSD_ELF */
|
||||
|
||||
|
||||
/* Attempt to turn on execute permission for the stack. This may be
|
||||
used by TRANSFER_FROM_TRAMPOLINE of the target needs it (that is,
|
||||
if the target machine can change execute permissions on a page).
|
||||
|
||||
There is no way to query the execute permission of the stack, so
|
||||
we always issue the mprotect() call.
|
||||
|
||||
Note that we go out of our way to use namespace-non-invasive calls
|
||||
here. Unfortunately, there is no libc-internal name for mprotect().
|
||||
|
||||
Also note that no errors should be emitted by this code; it is considered
|
||||
dangerous for library calls to send messages to stdout/stderr. */
|
||||
|
||||
#define NETBSD_ENABLE_EXECUTE_STACK \
|
||||
extern void __enable_execute_stack (void *); \
|
||||
void \
|
||||
__enable_execute_stack (addr) \
|
||||
void *addr; \
|
||||
{ \
|
||||
extern int mprotect (void *, size_t, int); \
|
||||
extern int __sysctl (int *, unsigned int, void *, size_t *, \
|
||||
void *, size_t); \
|
||||
\
|
||||
static int size; \
|
||||
static long mask; \
|
||||
\
|
||||
char *page, *end; \
|
||||
\
|
||||
if (size == 0) \
|
||||
{ \
|
||||
int mib[2]; \
|
||||
size_t len; \
|
||||
\
|
||||
mib[0] = 6; /* CTL_HW */ \
|
||||
mib[1] = 7; /* HW_PAGESIZE */ \
|
||||
len = sizeof (size); \
|
||||
(void) __sysctl (mib, 2, &size, &len, NULL, 0); \
|
||||
mask = ~((long) size - 1); \
|
||||
} \
|
||||
\
|
||||
page = (char *) (((long) addr) & mask); \
|
||||
end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
|
||||
\
|
||||
/* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */ \
|
||||
(void) mprotect (page, end - page, 7); \
|
||||
}
|
||||
|
|
|
@ -64,6 +64,9 @@
|
|||
|
||||
#undef STDC_0_IN_SYSTEM_HEADERS
|
||||
|
||||
/* Attempt to enable execute permissions on the stack. */
|
||||
#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
|
||||
|
||||
/* XXX Redefine this; <sparc/sparc.h> mucks with it. */
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fprintf (stderr, " (%s)", TARGET_NAME);
|
||||
|
|
|
@ -46,3 +46,6 @@
|
|||
|
||||
/* Name the default cpu target */
|
||||
#define TARGET_CPU_DEFAULT TARGET_CPU_sparc
|
||||
|
||||
/* Attempt to enable execute permissions on the stack. */
|
||||
#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
|
||||
|
|
Loading…
Reference in New Issue