| <!--===- docs/FAQ.md | |
| Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| See https://llvm.org/LICENSE.txt for license information. | |
| SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| --> | |
| # Frequently Asked Questions (FAQ) | |
| ## Driver | |
| ### Why do I get a warning or an error about an executable stack? | |
| This occurs because Flang's default implementation of pointers to internal procedures requires an executable stack. | |
| An internal procedure has a "host scope", which is the scope in which it is contained. | |
| It can access variables defined in that host scope. | |
| When an internal procedure is referenced from outside its host scope (for example, via a procedure pointer), the implementation must ensure that it can still access variables from the host scope. | |
| By default, Flang achieves this by generating a small piece of code, called a "trampoline", on the stack. | |
| When the procedure is called, this trampoline is executed. | |
| Since the trampoline is on the stack, the stack itself must be executable. | |
| For a more detailed explanation of trampolines, please refer to the [design document](InternalProcedureTrampolines.md). | |
| An executable stack increases the risk and impact of certain classes of security vulnerabilities, such as [stack buffer overflows](https://llsoftsec.github.io/llsoftsecbook/#stack-buffer-overflows). | |
| Therefore, modern linkers often issue a warning or an error if an executable stack is not explicitly requested by the developer. | |
| For instance, the GNU Linker (`ld`) issues a warning while the LLVM Linker (`lld`) emits an error. | |
| :::{note} | |
| The trampoline code generated by Flang is not itself a security risk. | |
| The risk comes from the possibility of executing malicious code that an attacker has placed on the stack. | |
| You should determine whether such risks are appropriate for your software. | |
| ::: | |
| When you use the Flang driver (the `flang` command) to generate executables, you can instruct the linker to enable an executable stack with the `-Wl,-z,execstack` or `-Xlinker -zexecstack` flag. | |
| ```console | |
| $ flang src.f90 -fuse-ld=ld | |
| /path/to/ld: warning: src.o: requires executable stack (because the .note.GNU-stack section is executable) | |
| $ flang src.f90 -fuse-ld=ld -Wl,-z,execstack | |
| $ flang src.f90 -fuse-ld=lld | |
| ld.lld: error: src.o: requires an executable stack, but -z execstack is not specified | |
| flang-22: error: linker command failed with exit code 1 (use -v to see invocation) | |
| $ flang src.f90 -fuse-ld=lld -Wl,-z,execstack | |
| ``` | |
| Since LLVM 23, Flang has a new compiler flag `-fsafe-trampoline`, which is disabled by default and is currently supported on x86-64 and AArch64 targets. | |
| If this is enabled, Flang uses a runtime-managed trampoline pool, with executable code stored separately from writeable per-trampoline data. This does not require an executable stack. | |
| Where supported, we recommend using this flag to reduce the security risk of an executable stack. | |
| The pool capacity is described in the [runtime environment documentation](RuntimeEnvironment.md). |