(ASM_SPEC): New macro.
(TRAMPOLINE_{TEMPLATE,SIZE}, INITIALIZE_TRAMPOLINE): Make major changes to fix numerous bugs. From-SVN: r2874
This commit is contained in:
parent
9353d0a3fb
commit
7981384fa7
@ -41,6 +41,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
|
|
||||||
#define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"
|
#define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"
|
||||||
|
|
||||||
|
/* No point in running CPP on our assembler output. */
|
||||||
|
#define ASM_SPEC "-nocpp"
|
||||||
|
|
||||||
/* Right now Alpha OSF/1 doesn't seem to have debugging or profiled
|
/* Right now Alpha OSF/1 doesn't seem to have debugging or profiled
|
||||||
libraries. */
|
libraries. */
|
||||||
|
|
||||||
@ -808,31 +811,31 @@ extern char *alpha_function_name;
|
|||||||
of a trampoline, leaving space for the variable parts.
|
of a trampoline, leaving space for the variable parts.
|
||||||
|
|
||||||
The trampoline should set the static chain pointer to value placed
|
The trampoline should set the static chain pointer to value placed
|
||||||
into the trampoline and should branch to the specified routine. We
|
into the trampoline and should branch to the specified routine.
|
||||||
use $28 (at) as a temporary. Note that $27 has been set to the
|
Note that $27 has been set to the address of the trampoline, so we can
|
||||||
address of the trampoline, so we can use it for addressability
|
use it for addressability of the two data items. Trampolines are always
|
||||||
of the two data items. Trampolines are always aligned to
|
aligned to FUNCTION_BOUNDARY, which is 64 bits. */
|
||||||
FUNCTION_BOUNDARY, which is 64 bits. */
|
|
||||||
|
|
||||||
#define TRAMPOLINE_TEMPLATE(FILE) \
|
#define TRAMPOLINE_TEMPLATE(FILE) \
|
||||||
{ \
|
{ \
|
||||||
fprintf (FILE, "\tbis $27,$27,$28\n"); \
|
fprintf (FILE, "\tldq $1,24($27)\n"); \
|
||||||
fprintf (FILE, "\tldq $27,16($27)\n"); \
|
fprintf (FILE, "\tldq $27,16($27)\n"); \
|
||||||
fprintf (FILE, "\tldq $1,20($28)\n"); \
|
fprintf (FILE, "\tjmp $31,($27),0\n"); \
|
||||||
fprintf (FILE, "\tjmp $31,0($27),0\n"); \
|
fprintf (FILE, "\tnop\n"); \
|
||||||
fprintf (FILE, "\t.quad 0,0\n"); \
|
fprintf (FILE, "\t.quad 0,0\n"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Length in units of the trampoline for entering a nested function. */
|
/* Length in units of the trampoline for entering a nested function. */
|
||||||
|
|
||||||
#define TRAMPOLINE_SIZE 24
|
#define TRAMPOLINE_SIZE 32
|
||||||
|
|
||||||
/* Emit RTL insns to initialize the variable parts of a trampoline.
|
/* Emit RTL insns to initialize the variable parts of a trampoline.
|
||||||
FNADDR is an RTX for the address of the function's pure code.
|
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. We assume
|
CXT is an RTX for the static chain value for the function. We assume
|
||||||
here that a function will be called many more times than its address
|
here that a function will be called many more times than its address
|
||||||
is taken (e.g., it might be passed to qsort), so we take the trouble
|
is taken (e.g., it might be passed to qsort), so we take the trouble
|
||||||
to initialize the "hint" field in the JMP insn. */
|
to initialize the "hint" field in the JMP insn. Note that the hint
|
||||||
|
field is PC (new) + 4 * bits 13:0. */
|
||||||
|
|
||||||
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
|
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
|
||||||
{ \
|
{ \
|
||||||
@ -840,20 +843,49 @@ extern char *alpha_function_name;
|
|||||||
\
|
\
|
||||||
_addr = memory_address (Pmode, plus_constant ((TRAMP), 16)); \
|
_addr = memory_address (Pmode, plus_constant ((TRAMP), 16)); \
|
||||||
emit_move_insn (gen_rtx (MEM, Pmode, _addr), (FNADDR)); \
|
emit_move_insn (gen_rtx (MEM, Pmode, _addr), (FNADDR)); \
|
||||||
_addr = memory_address (Pmode, plus_constant ((TRAMP), 20)); \
|
_addr = memory_address (Pmode, plus_constant ((TRAMP), 24)); \
|
||||||
emit_move_insn (gen_rtx (MEM, Pmode, _addr), (CXT)); \
|
emit_move_insn (gen_rtx (MEM, Pmode, _addr), (CXT)); \
|
||||||
\
|
\
|
||||||
_temp = expand_shift (RSHIFT_EXPR, Pmode, (FNADDR), \
|
_temp = force_operand (plus_constant ((TRAMP), 12), NULL_RTX); \
|
||||||
|
_temp = expand_binop (DImode, sub_optab, (FNADDR), _temp, _temp, 1, \
|
||||||
|
OPTAB_WIDEN); \
|
||||||
|
_temp = expand_shift (RSHIFT_EXPR, Pmode, _temp, \
|
||||||
build_int_2 (2, 0), NULL_RTX, 1); \
|
build_int_2 (2, 0), NULL_RTX, 1); \
|
||||||
_temp = expand_and (_temp, GEN_INT (0x1fff), 0); \
|
_temp = expand_and (gen_lowpart (SImode, _temp), \
|
||||||
|
GEN_INT (0x3fff), 0); \
|
||||||
\
|
\
|
||||||
_addr = memory_address (SImode, plus_constant ((TRAMP), 12)); \
|
_addr = memory_address (SImode, plus_constant ((TRAMP), 8)); \
|
||||||
_temp1 = force_reg (SImode, gen_rtx (MEM, SImode, _addr)); \
|
_temp1 = force_reg (SImode, gen_rtx (MEM, SImode, _addr)); \
|
||||||
_temp1 = expand_and (_temp, GEN_INT (0xfffe000), NULL_RTX); \
|
_temp1 = expand_and (_temp1, GEN_INT (0xffffc000), NULL_RTX); \
|
||||||
_temp1 = expand_binop (SImode, ior_optab, _temp1, _temp, _temp1, 1, \
|
_temp1 = expand_binop (SImode, ior_optab, _temp1, _temp, _temp1, 1, \
|
||||||
OPTAB_WIDEN); \
|
OPTAB_WIDEN); \
|
||||||
\
|
\
|
||||||
emit_move_insn (gen_rtx (MEM, SImode, _addr), _temp1); \
|
emit_move_insn (gen_rtx (MEM, SImode, _addr), _temp1); \
|
||||||
|
\
|
||||||
|
emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \
|
||||||
|
"__enable_execute_stack"), \
|
||||||
|
0, VOIDmode, 1,_addr, Pmode); \
|
||||||
|
\
|
||||||
|
emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode, \
|
||||||
|
gen_rtvec (1, const0_rtx), 0)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt to turn on access permissions for the stack. */
|
||||||
|
|
||||||
|
#define TRANSFER_FROM_TRAMPOLINE \
|
||||||
|
\
|
||||||
|
void \
|
||||||
|
__enable_execute_stack (addr) \
|
||||||
|
void *addr; \
|
||||||
|
{ \
|
||||||
|
long size = getpagesize (); \
|
||||||
|
long mask = ~(size-1); \
|
||||||
|
char *page = (char *) (((long) addr) & mask); \
|
||||||
|
char *end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
|
||||||
|
\
|
||||||
|
/* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ \
|
||||||
|
if (mprotect (page, end - page, 7) < 0) \
|
||||||
|
perror ("mprotect of trampoline code"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Addressing modes, and classification of registers for them. */
|
/* Addressing modes, and classification of registers for them. */
|
||||||
|
Loading…
Reference in New Issue
Block a user