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:
thorpej 2002-10-18 16:23:47 +00:00
parent 2665f9c68c
commit 1268b2dbc5
8 changed files with 92 additions and 11 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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 ();

View File

@ -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. */

View File

@ -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

View File

@ -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); \
}

View File

@ -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);

View File

@ -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