gccint: Trampolines
1
1 18.11 Trampolines for Nested Functions
1 ======================================
1
1 A "trampoline" is a small piece of code that is created at run time when
1 the address of a nested function is taken. It normally resides on the
1 stack, in the stack frame of the containing function. These macros tell
1 GCC how to generate code to allocate and initialize a trampoline.
1
1 The instructions in the trampoline must do two things: load a constant
1 address into the static chain register, and jump to the real address of
1 the nested function. On CISC machines such as the m68k, this requires
1 two instructions, a move immediate and a jump. Then the two addresses
1 exist in the trampoline as word-long immediate operands. On RISC
1 machines, it is often necessary to load each address into a register in
1 two parts. Then pieces of each address form separate immediate
1 operands.
1
1 The code generated to initialize the trampoline must store the variable
1 parts--the static chain value and the function address--into the
1 immediate operands of the instructions. On a CISC machine, this is
1 simply a matter of copying each address to a memory reference at the
1 proper offset from the start of the trampoline. On a RISC machine, it
1 may be necessary to take out pieces of the address and store them
1 separately.
1
1 -- Target Hook: void TARGET_ASM_TRAMPOLINE_TEMPLATE (FILE *F)
1 This hook is called by 'assemble_trampoline_template' to output, on
1 the stream F, assembler code for a block of data that contains the
1 constant parts of a trampoline. This code should not include a
1 label--the label is taken care of automatically.
1
1 If you do not define this hook, it means no template is needed for
1 the target. Do not define this hook on systems where the block
1 move code to copy the trampoline into place would be larger than
1 the code to generate it on the spot.
1
1 -- Macro: TRAMPOLINE_SECTION
1 Return the section into which the trampoline template is to be
1 placed (⇒Sections). The default value is
1 'readonly_data_section'.
1
1 -- Macro: TRAMPOLINE_SIZE
1 A C expression for the size in bytes of the trampoline, as an
1 integer.
1
1 -- Macro: TRAMPOLINE_ALIGNMENT
1 Alignment required for trampolines, in bits.
1
1 If you don't define this macro, the value of 'FUNCTION_ALIGNMENT'
1 is used for aligning trampolines.
1
1 -- Target Hook: void TARGET_TRAMPOLINE_INIT (rtx M_TRAMP, tree FNDECL,
1 rtx STATIC_CHAIN)
1 This hook is called to initialize a trampoline. M_TRAMP is an RTX
1 for the memory block for the trampoline; FNDECL is the
1 'FUNCTION_DECL' for the nested function; STATIC_CHAIN is an RTX for
1 the static chain value that should be passed to the function when
1 it is called.
1
1 If the target defines 'TARGET_ASM_TRAMPOLINE_TEMPLATE', then the
1 first thing this hook should do is emit a block move into M_TRAMP
1 from the memory block returned by 'assemble_trampoline_template'.
1 Note that the block move need only cover the constant parts of the
1 trampoline. If the target isolates the variable parts of the
1 trampoline to the end, not all 'TRAMPOLINE_SIZE' bytes need be
1 copied.
1
1 If the target requires any other actions, such as flushing caches
1 or enabling stack execution, these actions should be performed
1 after initializing the trampoline proper.
1
1 -- Target Hook: rtx TARGET_TRAMPOLINE_ADJUST_ADDRESS (rtx ADDR)
1 This hook should perform any machine-specific adjustment in the
1 address of the trampoline. Its argument contains the address of
1 the memory block that was passed to 'TARGET_TRAMPOLINE_INIT'. In
1 case the address to be used for a function call should be different
1 from the address at which the template was stored, the different
1 address should be returned; otherwise ADDR should be returned
1 unchanged. If this hook is not defined, ADDR will be used for
1 function calls.
1
1 -- Target Hook: int TARGET_CUSTOM_FUNCTION_DESCRIPTORS
1 This hook should be defined to a power of 2 if the target will
1 benefit from the use of custom descriptors for nested functions
1 instead of the standard trampolines. Such descriptors are created
1 at run time on the stack and made up of data only, but they are
1 non-standard so the generated code must be prepared to deal with
1 them. This hook should be defined to 0 if the target uses function
1 descriptors for its standard calling sequence, like for example
1 HP-PA or IA-64. Using descriptors for nested functions eliminates
1 the need for trampolines that reside on the stack and require it to
1 be made executable.
1
1 The value of the macro is used to parameterize the run-time
1 identification scheme implemented to distinguish descriptors from
1 function addresses: it gives the number of bytes by which their
1 address is misaligned compared with function addresses. The value
1 of 1 will generally work, unless it is already reserved by the
1 target for another purpose, like for example on ARM.
1
1 Implementing trampolines is difficult on many machines because they
1 have separate instruction and data caches. Writing into a stack
1 location fails to clear the memory in the instruction cache, so when the
1 program jumps to that location, it executes the old contents.
1
1 Here are two possible solutions. One is to clear the relevant parts of
1 the instruction cache whenever a trampoline is set up. The other is to
1 make all trampolines identical, by having them jump to a standard
1 subroutine. The former technique makes trampoline execution faster; the
1 latter makes initialization faster.
1
1 To clear the instruction cache when a trampoline is initialized, define
1 the following macro.
1
1 -- Macro: CLEAR_INSN_CACHE (BEG, END)
1 If defined, expands to a C expression clearing the _instruction
1 cache_ in the specified interval. The definition of this macro
1 would typically be a series of 'asm' statements. Both BEG and END
1 are both pointer expressions.
1
1 To use a standard subroutine, define the following macro. In addition,
1 you must make sure that the instructions in a trampoline fill an entire
1 cache line with identical instructions, or else ensure that the
1 beginning of the trampoline code is always aligned at the same point in
1 its cache line. Look in 'm68k.h' as a guide.
1
1 -- Macro: TRANSFER_FROM_TRAMPOLINE
1 Define this macro if trampolines need a special subroutine to do
1 their work. The macro should expand to a series of 'asm'
1 statements which will be compiled with GCC. They go in a library
1 function named '__transfer_from_trampoline'.
1
1 If you need to avoid executing the ordinary prologue code of a
1 compiled C function when you jump to the subroutine, you can do so
1 by placing a special label of your own in the assembler code. Use
1 one 'asm' statement to generate an assembler label, and another to
1 make the label global. Then trampolines can use that label to jump
1 directly to your special assembler code.
1