{{위키데이터 속성 추적}}
[[컴퓨터 프로그래밍]]에서 '''트램펄린'''(trampoline)은 프로그램 [[제어 흐름]] [[브랜치 (컴퓨터 과학)|점프]](Jump)와 관련된 다양한 개념을 지칭할 때 사용되는 용어이다.

== 저수준 프로그래밍 ==
저수준 프로그래밍에서 ''트램펄린''은 [[인터럽트]] [[서브루틴|서비스 루틴]]이나 [[입출력]] [[서브루틴|루틴]]의 주소를 가지고 있는 [[주소 공간|메모리 공간]]을 가리키는 말으로, 종종 [[간접 분기|간접 점프]] [[배열|벡터]](Indirect jump vector)라는 용어와 혼용되기도 한다. 트램펄린이라는 용어는 [[제어 흐름|프로그램 컨트롤]]이 트램펄린으로 ''점프''한 직후에 곧바로 다른 루틴의 주소로 다시 ''튕겨나가는'' 과정과 연관성이 있다.

트램펄린은 다음과 같은 다양한 용례가 존재한다:

* [[중앙 처리 장치]](CPU)의 [[인터럽트 벡터]]는 [[컴퓨터 구조|아키텍처]]적인 제약 사항으로 인해 반드시 미리 정해진 [[메모리 주소]]에 위치하여야 하는데, 해당 주소에 ''트램펄린''을 설치하여 실제 기능을 구현하는 [[인터럽트 핸들러]]가 간접적으로 호출되게 하면 이러한 제약 사항을 극복할 수 있다.
* [[대칭형 다중 처리]](Symmetric Multiprocessing, SMP) 컴퓨터에서 [[부트스트랩 (컴퓨팅)|부트스트랩 프로세서]]를 제외한 나머지 프로세서들은 부팅 후 환경 설정이 마무리 된 후에 활성화가 되는데, 이들 프로세서는 운영 체제에 의해 부팅 후에 [[제어 흐름]]이 트램펄린으로 점프되고, 이 트램펄린에서 대기하며 [[스케줄링 (컴퓨팅)|스케줄링]]되는 [[쓰레드]]를 기다린다.

== 고수준 프로그래밍 ==

=== C ===
[[GNU 컴파일러 모음|GCC 컴파일러]]에서 ''트램펄린''은 지역 함수의 [[함수 포인터]]를 구현하기 위해 [[콜 스택|스택]]에 삽입되는 작은 코드 조각을 가리키는 말이다.<ref name="Stackoverflow2"><cite class="citation web">fuz (2011-11-18). [https://stackoverflow.com/questions/8179521/implementation-of-nested-functions "Implementation of nested functions"]. ''[[StackOverflow]]''. [https://web.archive.org/web/20160329071658/http://stackoverflow.com/questions/8179521/implementation-of-nested-functions Archived] from the original on 2016-03-29<span class="reference-accessdate">. Retrieved <span class="nowrap">2018-05-26</span></span>.</cite></ref>

지역 함수가 부모 함수의 지역 변수에 접근하기 위해선 부모 함수의 [[콜 스택|스택 프레임]] 주소, 즉 ''정적 링크 포인터''(Static link pointer)가 필요한데, 지역 함수가 본인의 ''이름''을 통해 직접 호출될 때에는 그 당시의 [[콜 스택|스택]]에서 정적 링크 포인터를 유추할 수 있지만, ''함수 포인터''를 통해 간접적으로 호출될 때에는 이 포인터에 대한 정보를 유추할 수 없다는 문제가 발생한다. 이 문제에 대한 해결책 중 하나로 [[함수 포인터]]를 ''뚱뚱하게'' 만들어 지역 함수의 [[포인터 (프로그래밍)|포인터]]에 부모 함수의 [[콜 스택|스택 프레임]] 주소를 ''첨부''시키는 방법이 있지만 (Fat function pointer),<ref name="GCC_Trampolines2"><cite class="citation web">[http://gcc.gnu.org/onlinedocs/gccint/Trampolines.html "Trampolines for Nested Functions"]. ''Using the GNU Compiler Collection (GCC)''. 2018 [2002]. 18.11. [https://web.archive.org/web/20180527105902/http://gcc.gnu.org/onlinedocs/gccint/Trampolines.html Archived] from the original on 2018-05-27<span class="reference-accessdate">. Retrieved <span class="nowrap">2018-05-26</span></span>.</cite></ref><ref name="GCC_Nested2"><cite class="citation web">[http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html "Nested functions"]. ''Using the GNU Compiler Collection (GCC)''. 2018 [2002]. 6.4. [https://web.archive.org/web/20180527105902/http://gcc.gnu.org/onlinedocs/gccint/Trampolines.html Archived] from the original on 2018-05-27<span class="reference-accessdate">. Retrieved <span class="nowrap">2018-05-26</span></span>.</cite></ref><ref name="Breuel2"><cite class="citation web">Breuel, Thomas M. (2013). [http://www-cs-students.stanford.edu/~blynn/files/lexic.pdf "Lexical Closures for C++"] <span class="cs1-format">(PDF)</span>. [https://web.archive.org/web/20171212030215/http://www-cs-students.stanford.edu/~blynn//files/lexic.pdf Archived] <span class="cs1-format">(PDF)</span> from the original on 2017-12-12<span class="reference-accessdate">. Retrieved <span class="nowrap">2018-05-26</span></span>.</cite></ref> 이 방식은 지역 함수의 [[함수 포인터]]를 일반적인 함수 포인터와 같은 방식으로 다룰 수 없게 만든다는 단점이 있다.<ref>C 언어의 함수 포인터는 함수의 주소 이외에는 어떤 추가 정보도 담고 있지 않다.</ref>

대신 ''트램펄린''을 사용하면 이 단점을 없애면서 정적 링크 포인터 문제를 해결할 수 있는데, 트램펄린을 함수 포인터를 통해 지역 함수를 호출할 때 사용하는 일종의 ''대리자''로서 이용하는 방법이다. 구체적으로 트램펄린은 호출 직후에 정적 링크 포인터를 준비한 후에 바로 원래의 지역 함수로 [[제어 흐름]]을 전달해주는 역할을 하는데, 지역 함수의 주소가 취해질 때에 이 트램펄린의 주소를 대신 제공하면 모든 "[[함수 포인터]]를 통한" 지역 함수 호출이 이 트램펄린을 거쳐 이뤄지도록 할 수 있다.

이 때 트램펄린이 제공하는 정적 링크 포인터는 트램펄린의 코드 자체에 새겨져야 하는데, 함수의 스택 프레임 주소는 [[런타임]]에 동적으로 결정되므로, 트램펄린 코드 역시 런타임에 스택 상에 즉석으로 삽입되어야 한다. 하지만 이 점으로 인해 [[콜 스택|스택]] 전체를 [[메모리 보호|실행 가능한 영역]]으로 만들어야 하는데, 이는 컴퓨터 보안상 스택을 실행 불가능하게 만드는 원칙과 상충된다.

== 실행 불가능한 스택 ==
몇몇 트램펄린의 구현들은 실행 불가능한 스택([[NX 비트|NX 스택]])을 배제시키는 결과를 초래한다. 특히 [[GNU 컴파일러 모음|GCC 컴파일러]]의 경우에는 지역 함수의 [[함수 포인터]]를 구현하기 위해 프로그램 [[런타임|실행 중]]에 [[콜 스택|스택]]에 트램펄린 코드가 주입되도록 하고, 지역 함수가 포인터로 호출이 되는 경우에 이 트램펄린을 경유하여 실행되도록 하는데, 트램펄린이 실행되기 위해선 [[콜 스택|스택 메모리]]의 [[메모리 보호|실행 권한]]이 필요하다. 따라서 실행 불가능한 스택과 지역 함수 기능은 GCC에서는 상호 양립할 수 없는데, 이 점으로 인해 취약점 없는 소프트웨어를 개발하기 위해서는 지역 함수 사용을 지양하도록 권장되고 있다.<ref name="Walton">{{웹 인용|title=C-Based Toolchain Hardening |author-last1=Walton |author-first1=Jeffrey |author-first2=Jim |author-last2=Manico |author-first3=Kevin |author-last3=Wall |date=2018-03-02 |orig-year=2013 |publisher=The Open Web Application Security Project (OWASP) |url=http://www.owasp.org/index.php/C-Based_Toolchain_Hardening#GCC.2FBinutils |access-date=2018-03-02 |url-status=live |archive-url=https://web.archive.org/web/20180527105523/https://www.owasp.org/index.php/C-Based_Toolchain_Hardening |archive-date=2018-05-27}}</ref>

GCC는 <code>-Wtrampoline</code> 옵션을 통해 트램펄린으로 인해 스택이 실행 가능해지는 경우에 컴파일러 경고를 출력하도록 하고 있다.

== 참조 ==

* [[버퍼 오버플로|DLL trampolining]]
* 리트폴린

== 각주 ==
{{각주}}

[[분류:컴퓨터 용어]]